如何为binary_crossentropy、activation=sigmoid和activation=softmax指定model.compile?

Jon*_*Jon 5 python keras tensorflow activation-function loss-function

我正在尝试找出如何匹配activation=sigmoid正确activation=softmaxmodel.compile()损失参数。特别是那些与binary_crossentropy.

我研究了相关主题并阅读了文档。我还建立了一个模型并让它与 一起工作,sigmoid但没有softmax。我无法让它与“ from_logits”参数正常工作。

具体来说,这里说:

参数:
  • from_logits:是否output预期为 Logits 张量。默认情况下,我们认为output编码了概率分布。

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

接下来是一些代码:

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'))
Run Code Online (Sandbox Code Playgroud)

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

model.compile(optimizer=optimizer,
              loss='binary_crossentropy',  
              metrics=['accuracy'])
Run Code Online (Sandbox Code Playgroud)

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

如果我执行以下操作,则会失败:

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

出现此错误消息:

ValueError:无效参数“from_logits”传递给带有 TensorFlow 后端的 K.function

如果我尝试使用 softmax 激活:

model.add(Dense(1, activation='softmax'))
Run Code Online (Sandbox Code Playgroud)

它可以运行,但我得到的准确度结果是 50%。我的准确率达到sigmoid了+99%。(我正在使用一个非常人为的数据集来调试我的模型,并且期望非常高的准确性。此外,它是一个非常小的数据集,并且会过度拟合,但目前还可以。)

所以我希望我应该能够from_logits在编译函数中使用“”参数。但它不识别该参数。

另外我想知道为什么它适用于sigmoid激活而不是softmax激活,以及如何让它与softmax激活一起使用。

谢谢你,

乔恩.

Gab*_*gon 7

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

你必须改变这个:

model.compile(optimizer=optimizer,
              loss='binary_crossentropy',  
              metrics=['accuracy'],
              from_logits=True)
Run Code Online (Sandbox Code Playgroud)

对此:

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

但是,如果您在网络的最后一层使用 softmax 或 sigmoid,则不需要from_logits=TrueSoftmax 和 sigmoid 输出 [0, 1] 之间的归一化值,在这种情况下被视为概率。

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


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

model.add(Dense(1, activation='softmax'))
Run Code Online (Sandbox Code Playgroud)

对此:

model.add(Dense(2, activation='softmax'))  # number of units = number of classes
Run Code Online (Sandbox Code Playgroud)

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