我正在Keras中设计一个二进制分类器,预计会为每个输入输出1
和-1
。如果输出为0
或1
,我可以使用binary_crossentropy
作为丢失函数。当我将输出更改为1
和-1
时,我认为故事不会改变,但性能不佳。这是否意味着损失函数binary_crossentropy
仅适用于0
和1
标签?
我知道存在另一种解决此问题的方法,因为即使对于0
和1
情况,最后一层的输出确实是0
和{{1 }}。所以我可以对输出进行重新缩放以满足1
和-1
的要求,但是如果我能想出一种简单输出1
和-1
的方法,那么会更好。
答案 0 :(得分:1)
你是对的,binary_corssentropy
仅适用于0和1标签。假设这两个类是猫和狗,这里我们有一个标记为cat的观测数据X1,我们可以将标签视为地面真值类概率y =(1.0,0)T,注意概率分布中的第一个元素表示输入数据为1类的概率,在这种情况下绝对是cat。并且模型预测了不同的分布,比如y ^ =(0.8,0.2),我们需要调整参数以使y ^更接近y。我们使用binary_crossentropy
来衡量y和y ^之间的差异。
H(y,y ^)是交叉熵。
我使用带有Tensorflow的Keras作为后端,我发现在Keras中tf.nn.sigmoid_cross_entropy_with_logits被称为bechind binary_crossentropy
。
根据张量流的sigmoid_cross_entropy简介中的公式,标签应该只是一个范围为(0,1)的实数,标签代表地面真实概率分布,通常在观察中概率为0和1。
希望它有所帮助。答案 1 :(得分:1)
交叉熵使用以下事实:目标向量y中的所有元素(除了一个)都是0,以使所有不正确的激活上的梯度无效,从而为过程增加稳定性。
你可以:
tanh
激活([-1,1]范围内的输出)和mse
丢失:x = Input(...)
y = Dense(128, activation='relu')(x)
y = Dense(128, activation='relu')(y)
y = Dense(1, activation='tanh')(y)
model = Model(inputs=x, outputs=y)
model.compile(optimizer='adam', loss='mse')
# train model using labels in {-1, 1}
# outputs values are in [-1, 1]
x = Input(...)
y = Dense(128, activation='relu')(x)
y = Dense(128, activation='relu')(y)
y = Dense(1, activation='sigmoid')(y)
model = Model(inputs=x, outputs=y)
model.compile(optimizer='adam', loss='binary_crossentropy')
# train model using labels in {0, 1}
z = Lambda(lambda _y: _y / 2 + .5)(y)
model = Model(inputs=x, outputs=z)
# outputs values are in [-1, 1]
注意:如果您尝试使用Siamese网络区分空间中的两件事(例如,区分两个图像是否包含相同的对象),那么请查看{{的对比度损失定义3}}。我的经验是,它比任何sigma
/ tanh
输出都要好得多。