我正在使用TensorFlow 2.0中的Keras进行二进制分类,这种密集网络具有二进制交叉熵损失。
出于调试目的,我尝试首先对模型进行过拟合,并发现怪异的行为:无论是在上一个密集层init中使用sigmoid还是在没有任何激活的情况下初始化此最后一层,并分别添加sigmoid激活,都会产生不同的丢失结果的模型。
我找不到在tf / keras中的哪个地方指出,如果模型的最后一层只是S型,BinaryCrossentropy(from_logits=True)
损失将在没有S型的情况下进行计算。或者,如果对以下结果还有其他解释。
据我了解,BinaryCrossentropy(from_logits=True)
期望logits-在这种情况下是密集层的输出,无需任何激活。这是发布代码打印的第一个示例。由于没有激活,只有神经元的权重只有= 1,因此预测与输入以及损失相同。
在第二个变体中,我在构造函数中使用了未激活的密集层,但是我将sigmoid激活添加为“单独层”,并在这种情况下BCE不采用logit而是设置BinaryCrossentropy(from_logits=False)
来计算(“概率”), sigmoid(logits)
作为输入。模型预测的输出(概率)等于1,这很有意义。但是,我希望Keras采取这种可能性,将其改回logit并计算损失source。由于计算的不精确性(tf source),我发现BCE不能通过非logit计算出比15.3332高的损失,但在这种情况下,它可以计算。
在最后一种情况下(代码的打印)显示了预期的行为,即激活是在密集层的初始化中进行的,无论输入/输出大于16的大小,损耗都会被限制为15.3332。 >
我的假设是,在第二种情况下,损失是根据密集层输出的对数计算出来的,而不是模型的输出。
from tensorflow.python.keras.layers import Input, Dense
from tensorflow.python.keras.activations import sigmoid
from tensorflow.python.keras.models import Model
from tensorflow.python.keras.losses import BinaryCrossentropy
import numpy as np
x_train = np.array([[10000]])
y_train = [0]
inp = Input(x_train.shape[1])
out = Dense(1, trainable=False, use_bias=False)(inp)
model = Model(inp, out)
model.get_layer('dense').set_weights([np.array([[1]])])
model.compile(optimizer='adam', loss=BinaryCrossentropy(from_logits=True))
print('\nFrom logits=True, no activation')
model.fit(x_train, y_train, epochs=1)
print('Prediction:')
print(model.predict(x_train))
inp = Input(x_train.shape[1])
out = Dense(1, trainable=False, use_bias=False)(inp)
out = sigmoid(out)
model = Model(inp, out)
model.get_layer('dense_1').set_weights([np.array([[1]])])
model.compile(optimizer='adam', loss=BinaryCrossentropy(from_logits=False))
print('\nFrom logits=False, separate sigmoid')
model.fit(x_train, y_train, epochs=1)
print('Prediction:')
print(model.predict(x_train))
inp = Input(x_train.shape[1])
out = Dense(1, trainable=False, use_bias=False, activation='sigmoid')(inp)
model = Model(inp, out)
model.get_layer('dense_2').set_weights([np.array([[1]])])
model.compile(optimizer='adam', loss=BinaryCrossentropy(from_logits=False))
print('\nFrom logits=False, sigmoid in dense')
model.fit(x_train, y_train, epochs=1)
print('Prediction:')
print(model.predict(x_train))
From logits=True, no activation
1/1 [==============================] - 0s 17ms/sample - loss: 1000.0000
Prediction:
[[1000.]]
From logits=False, separate sigmoid
Train on 1 samples
1/1 [==============================] - 0s 15ms/sample - loss: 1000.0000
Prediction:
[[1.]]
From logits=False, sigmoid in dense
Train on 1 samples
1/1 [==============================] - 0s 17ms/sample - loss: 15.3332
Prediction:
[[1.]]