使用S型激活函数了解神经网络输出> 1

问题描述

我正在尝试将卷积神经网络与线性模型结合在一起的模型。这是它的简化版本:

from tensorflow.keras import Sequential
from tensorflow.keras.experimental import WideDeepModel,LinearModel
num_classes = 1 ##(0='NO' or 1='YES')

cnn_model.Sequential()
cnn_model.add(Conv1D(20,8,padding='same',activation='relu'))
cnn_model.add(GlobalAveragePooling1D())
cnn_model.add(Dropout(0.6))
cnn_model.add(Dense(num_classes,activation='sigmoid'))

linear_model = LinearModel()
combined_model = WideDeepModel(linear_model,cnn_model)
combined_model.compile(optimizer = ['sgd','adam'],loss = ['mse','binary_crossentropy'],metrics = ['accuracy'])

性能非常好,在我按pval对预测进行排序之前,一切似乎都进行得很好,即使使用 Sigmoid 激活,我也可以看到预测> 1。我以为应该使一切都介于0和1之间,并且线性模型没有激活函数(但是输入都按0-1缩放):

pred = [ 1 if a > threshold else 0 for a in combined_model.predict([dplus_test,X_test])]
pv = combined_model.predict([dplus_test,X_test])
pval = [a[0] for a in pv]
    true    pred    pval    dplus
1633    1   1   1.002850    15.22404
1326    1   1   1.001444    10.34983
1289    1   1   1.001368    10.03043
1371    1   1   1.000986    10.74037
1188    1   1   1.000707    8.902

我检查了数据的另一端,这些预测与我预期的一样,总是> 0。

    true    pred    pval    dplus
145     0   0   0.000463    1.81635
383     0   0   0.001023    3.24982
1053    0   0   0.001365    7.22535

到目前为止,这不是问题,没有崩溃,我对性能感到满意。

我想知道我对S型激活函数的理解是否错误,或者在Combined模型中是否存在某些允许值超过1的东西,以及我是否可以信任这些结果。

解决方法

这是因为您的S形仅在Deep模型的输出上定义,并且WideDeepModel合并两个模型的输出的方式是通过将它们相加(而您的Wide线性模型可以具有任意输出)。由于您在损失中同时包含了msebinary_crossentropy,因此组合模型实际上学会了输出接近预期范围的值。

如果您只有binary_crossentropy,则可能会看到比1大得多的值,因为损耗的公式为-p * log(q),其中q是网络的输出,您可以无限地增加q可以使损失任意小,这在输出有界时不会发生。

WideDeepModel还有一个附加属性activation(请参阅docs),您可以在其中定义整个模型的激活函数。如果要将输出压缩在0和1之间,请将其设置为sigmoid

combined_model = WideDeepModel(linear_model,cnn_model,activation='sigmoid')

最后要说的是,根据我的经验,将均方误差和二进制交叉熵相结合并没有多大意义,实际上,您可以选择其中之一。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...