如何设计二进制分类器以在Keras中输出1和-1

时间:2017-11-29 23:28:25

标签: keras

我正在Keras中设计一个二进制分类器,预计会为每个输入输出1-1。如果输出为01,我可以使用binary_crossentropy作为丢失函数。当我将输出更改为1-1时,我认为故事不会改变,但性能不佳。这是否意味着损失函数binary_crossentropy仅适用于01标签?

我知道存在另一种解决此问题的方法,因为即使对于01情况,最后一层的输出确实是0和{{1 }}。所以我可以对输出进行重新缩放以满足1-1的要求,但是如果我能想出一种简单输出1-1的方法,那么会更好。

2 个答案:

答案 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 ^之间的差异。 Cross Entropy

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,以使所有不正确的激活上的梯度无效,从而为过程增加稳定性。

你可以:

  1. 使用tanh激活([-1,1]范围内的输出)和mse丢失:
  2. 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]
    
    1. 训练sigmoid并缩放你的logits。这对我来说似乎更合理:
    2. 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输出都要好得多。