【问题标题】:Neural network isn't learning for a first few epochs on Keras神经网络在 Keras 的前几个时期没有学习
【发布时间】:2020-02-24 17:36:24
【问题描述】:

我正在使用 TensorFlow 后端在 Keras 上测试简单网络,但在使用 sigmoid 激活函数时遇到了问题

网络在前 5-10 个 epoch 没有学习,然后一切都很好。 我尝试使用初始化器和正则器,但这只会让情况变得更糟。

我是这样使用网络的:

import numpy as np
import keras
from numpy import expand_dims
from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot


# load the image
(x_train, y_train), (x_val, y_val), (x_test, y_test) = netowork2_ker.load_data_shared()

# expand dimension to one sample
x_train = expand_dims(x_train, 2)
x_train = np.reshape(x_train, (50000, 28, 28))
x_train = expand_dims(x_train, 3)

y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)

datagen = ImageDataGenerator(
    rescale=1./255,
    width_shift_range=[-1, 0, 1],
    height_shift_range=[-1, 0, 1],
    rotation_range=10)

epochs = 20
batch_size = 50
num_classes = 10

model = keras.Sequential()
model.add(keras.layers.Conv2D(64, (3, 3), padding='same',
                 input_shape=x_train.shape[1:],
                 activation='sigmoid'))
model.add(keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(keras.layers.Conv2D(100, (3, 3),
                              activation='sigmoid'))
model.add(keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(100,
                             activation='sigmoid'))
#model.add(keras.layers.Dropout(0.5))
model.add(keras.layers.Dense(num_classes,
                             activation='softmax'))

model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

model.fit_generator(datagen.flow(x_train, y_train, batch_size=batch_size),
                    steps_per_epoch=len(x_train) / batch_size, epochs=epochs,
                    verbose=2, shuffle=True)

使用上面的代码,我得到如下结果:

Epoch 1/20 
 - 55s - loss: 2.3098 - accuracy: 0.1036 
Epoch 2/20 
 - 56s - loss: 2.3064 - accuracy: 0.1038
Epoch 3/20 
 - 56s - loss: 2.3068 - accuracy: 0.1025
Epoch 4/20 
 - 56s - loss: 2.3060 - accuracy: 0.1079
...

7 个 epoch(每次都不同),然后损失迅速下降,我在 20 个 epoch 中达到了 0.9623 的准确度。

但是,如果我将激活从 sigmoid 更改为 relu,它的效果很好,并且在第一个 epoch 中给了我 0.5356 的准确度。

这个问题使sigmoid 对我来说几乎无法使用,我想知道,我可以做点什么。这是一个错误还是我做错了什么?

【问题讨论】:

  • 这正是你不应该使用 sigmoids 作为隐藏激活的原因。神经元很可能在开始时“饱和”并且梯度接近于 0,因此(几乎)没有学习发生。一旦网络最终设法离开饱和状态,学习就会很快。 Relu 不会饱和,这就是为什么它通常效果更好。
  • 现代神经网络不使用 sigmoid 激活,你为什么要使用它?
  • 这不是bug,你确实做错了,即在隐藏层中使用sigmoid

标签: python machine-learning keras neural-network deep-learning


【解决方案1】:

激活功能建议:

在实践中,sigmoid 非线性最近已经失宠并且很少使用。 ReLU 是最常见的选择,如果网络中有很大一部分“死”单元,请尝试 Leaky ReLU 和 tanh。永远不要使用 sigmoid。

不使用sigmoid的原因:

sigmoid 神经元的一个非常不受欢迎的特性是,当神经元的激活在 0 或 1 的尾部饱和时,这些区域的梯度几乎为零。此外,Sigmoid 输出不是以零为中心的。

【讨论】:

  • @Дмитрий Шаров,您遇到的问题是练习神经网络时的常见问题。这里有一些关于激活函数的选择以及 sigmoid 性能不佳的建议。
  • 我同意并感谢您的回答,ReLU 通常在我的测试中显示出更好的结果。但是我认为优化器保证每个时期的损失都越来越小,所以我对它如何上升感到困惑。手动创建的网络我从来没有遇到过这个问题
  • @Дмитрий Шаров,我无法从您的评论中理解您的观点“但是我认为优化器保证每个时期的损失都会越来越小,所以我对它如何上升感到困惑”。为什么你会期望交叉熵随着时代的数量而增加。您应该知道分类任务的损失函数的定义始终是解决最小化损失函数的优化问题。
猜你喜欢
  • 2016-07-11
  • 2018-04-10
  • 1970-01-01
  • 2016-05-25
  • 2019-03-15
  • 2011-08-17
  • 2020-10-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多