这是一个简单的keras神经网络,试图映射1-> 1和2-> 0(二进制分类)
X = [[1] , [2]]
Y = [[1] , [0]]
from keras.callbacks import History
history = History()
from keras import optimizers
inputDim = len(X[0])
print('input dim' , inputDim)
model = Sequential()
model.add(Dense(1, activation='sigmoid', input_dim=inputDim))
model.add(Dense(1, activation='sigmoid'))
sgd = optimizers.SGD(lr=0.009, decay=1e-10, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy', optimizer=sgd , metrics=['accuracy'])
model.fit(X,Y , validation_split=0.1 , verbose=2 , callbacks=[history] , epochs=20,batch_size=32)
使用SGD优化器:
optimizers.SGD(lr = 0.009,衰变= 1e-10,动量= 0.9,nesterov = True)
纪元20的输出:
Epoch 20/20
0s - loss: 0.5973 - acc: 1.0000 - val_loss: 0.4559 - val_acc: 0.0000e+00
如果我使用adam optomizer:
sgd = optimizers.adam(lr=0.009, decay=1e-10)
纪元20的输出:
Epoch 20/20
0s - loss: 1.2140 - acc: 0.0000e+00 - val_loss: 0.2930 - val_acc: 1.0000
在adam和sgd优化器之间切换似乎会反转acc和val_acc的值。 val_acc = 1使用adam但是acc为0,验证准确度如何最大化并且训练准确度最低?
答案 0 :(得分:1)
在sigmoid
之后使用sigmoid
是一个非常糟糕的主意。例如。在paper中,我们写了sigmoid
遭受所谓的饱和问题的原因。此外 - 当您在sigmoid
之后使用sigmoid
时,您实际上会将网络的整体饱和度推向空中。要理解原因 - 请注意第一层的输出始终来自区间(0, 1)
。当binary_crossentropy
尝试将此输出(转换为线性变换)尽可能接近+/- inf
时,这会使您的网络具有极高的权重。这可能会导致您完全不稳定。
为了解决您的问题,我只会留下一个sigmoid
的图层,因为您的问题具有线性分离属性。
<强>更新强> 正如@Daniel所提到的 - 当你拆分包含两个例子的数据集时,你最终在数据集中有一个例子而在验证集中有一个例子。这导致了这种奇怪的行为。