【发布时间】: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