如何为binary_crossentropy,activation = Sigmoid和Activation = softmax指定model.compile?

时间:2019-04-30 22:22:39

标签: python tensorflow keras loss-function activation-function

我正在尝试找出如何将activation=sigmoidactivation=softmax与正确的model.compile()损耗参数进行匹配。特别是与binary_crossentropy关联的内容。

我研究了相关主题并阅读了文档。另外,我已经建立了一个模型并使其与sigmoid一起使用,但没有与softmax一起使用。而且我无法通过“ from_logits”参数使其正常工作。

具体来说,here表示:

  精氨酸:      
      
  • from_logits :是否期望output是对数张量。   默认情况下,我们认为output编码概率分布。
  •   

这对我说,如果您使用sigmoid激活,则需要“ from_logits=True”。对于softmax激活,默认情况下需要“ from_logits=False”。在这里,我假设sigmoid提供了logits,而softmax提供了概率分布。

接下来是一些代码:

model = Sequential()
model.add(LSTM(units=128,
               input_shape=(n_timesteps, n_features), 
               return_sequences=True))
model.add(Dropout(0.3))
model.add(LSTM(units=64, return_sequences=True))
model.add(Dropout(0.3))
model.add(LSTM(units=32))
model.add(Dropout(0.3))
model.add(Dense(16, activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(1, activation='sigmoid'))

请注意,最后一行正在使用sigmoid激活。然后:

model.compile(optimizer=optimizer,
              loss='binary_crossentropy',  
              metrics=['accuracy'])

这可以正常工作,但可以使用默认的“ from_logits = False”,它期望概率分布。

如果我执行以下操作,它将失败:

model.compile(optimizer=optimizer,
              loss='binary_crossentropy',  
              metrics=['accuracy'],
              from_logits=True) # For 'sigmoid' in above Dense

出现此错误消息:

  

ValueError:无效参数“ from_logits”通过TensorFlow后端传递给K.function

如果我尝试将softmax激活用作:

model.add(Dense(1, activation='softmax'))

它运行了,但是我得到了50%的准确性结果。使用sigmoid,我的准确率提高了99%。 (我正在使用一个非常特殊的数据集来调试我的模型,并且期望非常高的准确性。另外,它是一个非常小的数据集,可能会过拟合,但是现在还可以。)

因此,我希望我能够在编译功能中使用“ from_logits”参数。但是它不能识别该参数。

我还想知道为什么它与sigmoid激活一起起作用,而不与softmax激活一起起作用,以及如何使它与softmax激活一起起作用。

谢谢

乔恩

1 个答案:

答案 0 :(得分:1)

要在损失函数中使用from_logits,必须将其传递到BinaryCrossentropy对象初始化中,而不是在模型编译中。

您必须更改此设置:

model.compile(optimizer=optimizer,
              loss='binary_crossentropy',  
              metrics=['accuracy'],
              from_logits=True)

对此:

model.compile(optimizer=optimizer,
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),  
              metrics=['accuracy'])

但是,如果在网络的最后一层中使用softmax或Sigmoid,则不需要不需要from_logits=True。 Softmax和Sigmoid输出介于[0,1]之间的归一化值,在这种情况下,它们被认为是概率。

有关更多信息,请参见此问题:What is the meaning of the word logits in TensorFlow?


现在要解决softmax的50%准确性问题,请从此更改以下代码:

model.add(Dense(1, activation='softmax'))

对此:

model.add(Dense(2, activation='softmax'))  # number of units = number of classes

请记住,当您使用softmax时,您将输出示例属于每个类的概率。因此,每个可能的类都需要一个单位,在二进制分类上下文中将为2个单位。