使用 sigmoid 激活函数理解神经网络输出 >1

Understanding neural network output >1 with sigmoid activation function

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

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 27=] 激活,我认为应该将所有东西都带到 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

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

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

这是因为您的 sigmoid 仅在 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')

另外最后一点,根据我的经验,像这样结合均方误差和二元交叉熵没有多大意义,在实践中你会选择一个或另一个。