Keras为简单的二进制分类提供了意外的输出

时间:2017-09-22 08:01:43

标签: neural-network keras

这是一个简单的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,验证准确度如何最大化并且训练准确度最低?

1 个答案:

答案 0 :(得分:1)

sigmoid之后使用sigmoid是一个非常糟糕的主意。例如。在paper中,我们写了sigmoid遭受所谓的饱和问题的原因。此外 - 当您在sigmoid之后使用sigmoid时,您实际上会将网络的整体饱和度推向空中。要理解原因 - 请注意第一层的输出始终来自区间(0, 1)。当binary_crossentropy尝试将此输出(转换为线性变换)尽可能接近+/- inf时,这会使您的网络具有极高的权重。这可能会导致您完全不稳定。

为了解决您的问题,我只会留下一个sigmoid的图层,因为您的问题具有线性分离属性。

<强>更新 正如@Daniel所提到的 - 当你拆分包含两个例子的数据集时,你最终在数据集中有一个例子而在验证集中有一个例子。这导致了这种奇怪的行为。