为什么二进制Keras CNN总是预测1?
我想用Keras CNN构建一个二元分类器。 我有大约6000行的输入数据,看起来像这样:为什么二进制Keras CNN总是预测1?
>> print(X_train[0])
[[[-1.06405307 -1.06685851 -1.05989663 -1.06273152]
[-1.06295958 -1.06655996 -1.05969803 -1.06382503]
[-1.06415248 -1.06735609 -1.05999593 -1.06302975]
[-1.06295958 -1.06755513 -1.05949944 -1.06362621]
[-1.06355603 -1.06636092 -1.05959873 -1.06173742]
[-1.0619655 -1.06655996 -1.06039312 -1.06412326]
[-1.06415248 -1.06725658 -1.05940014 -1.06322857]
[-1.06345662 -1.06377347 -1.05890365 -1.06034568]
[-1.06027557 -1.06019084 -1.05592469 -1.05537518]
[-1.05550398 -1.06038988 -1.05225064 -1.05676692]]]
>>> print(y_train[0])
[1]
然后,我已经通过这种方式建立一个CNN:
model = Sequential()
model.add(Convolution1D(input_shape = (10, 4),
nb_filter=16,
filter_length=4,
border_mode='same'))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dropout(0.2))
model.add(Convolution1D(nb_filter=8,
filter_length=4,
border_mode='same'))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(64))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dense(1))
model.add(Activation('softmax'))
reduce_lr = ReduceLROnPlateau(monitor='val_acc', factor=0.9, patience=30, min_lr=0.000001, verbose=0)
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
history = model.fit(X_train, y_train,
nb_epoch = 100,
batch_size = 128,
verbose=0,
validation_data=(X_test, y_test),
callbacks=[reduce_lr],
shuffle=True)
y_pred = model.predict(X_test)
但它返回下列信息:
>> print(confusion_matrix(y_test, y_pred))
[[ 0 362]
[ 0 608]]
它总是预测因为您的网络输出。你有一个密集的层与一个神经元,与Softmax激活。 Softmax通过每个输出的指数之和进行归一化。由于有一个输出,唯一可能的输出是1.0。
对于二元分类器,您可以使用带有“binary_crossentropy”损失的sigmoid激活,或在最后一层放置两个输出单位,继续使用softmax并将损失更改为categorical_crossentropy。
谢谢!像魅力一样工作!:) sigmoid + binary和softmax + categorical之间有什么区别吗? – harrison4
@ harrison4理论上它们是相同的,但实际上存在差异,至少我做过的一些测试显示softmax是优越的。 –
从记录上来看,在我的测试中,用略深的建筑,我有: 乙状结肠+ binary_crossentropy: 'val_acc = 0.9422' 'val_loss = 0.16' 'val_rmse = 0.0909' SOFTMAX + sparse_categorical_crossentropy: ' val_acc = 0.9409' 'val_loss = 0.1725' 'val_rmse = 0.68' 似乎sigmoid执行一点(不是很少在rmse)更好。 – bio
约2/3的时间是正确的;我看到输入数据接近常数-1.06。如果这适用于所有数据,那么它可能只是因为它不能分割输入空间并优化哪个类最多,因为这是最好的选择(尽管我认为你的标准化调用可能会解决这个问题)。我无法验证,没有一个工作的例子。 Uvar
干杯!我试着将学习率从0.001改为0.1,但我得到了相同的输出。 :(还有其他想法吗? – harrison4