具有对数损失的 TensorFlow 单 sigmoid 输出与具有稀疏 softmax 交叉熵损失的两个线性输出,用于二进制分类
Posted
技术标签:
【中文标题】具有对数损失的 TensorFlow 单 sigmoid 输出与具有稀疏 softmax 交叉熵损失的两个线性输出,用于二进制分类【英文标题】:Tensorflow single sigmoid output with log loss vs two linear outputs with sparse softmax cross entropy loss for binary classification 【发布时间】:2018-05-23 04:40:33 【问题描述】:我正在尝试在 TensorFlow 中实现二进制分类器。如果我在最后一层有两个普通输出(即没有激活)并使用tf.losses.sparse_softmax_cross_entropy
,我的网络会按预期进行训练。但是,如果我将输出层更改为使用tf.sigmoid
激活生成单个输出并使用tf.losses.log_loss
作为损失函数,我的网络不会训练(即损失/准确性没有提高)。
这是我的输出层/损失函数在第一个(即工作)案例中的样子:
out = tf.layers.dense(prev, 2)
loss = tf.losses.sparse_softmax_cross_entropy(labels=y, logits=out)
在第二种情况下,我有以下内容:
out = tf.layers.dense(prev, 1, activation=tf.sigmoid)
loss = tf.losses.log_loss(labels=y, predictions=out)
张量y
是0
/1
值的向量;它不是单热编码的。在第一种情况下,网络按预期学习,但在第二种情况下则不然。除了这两行之外,其他一切都保持不变。
我不明白为什么第二个设置不起作用。有趣的是,如果我在 Keras 中表达相同的网络并使用第二种设置,它就可以工作。在第二种情况下,我是否使用了错误的 TensorFlow 函数来表达我的意图?我想产生一个单一的 sigmoid 输出并使用二元交叉熵损失来训练一个简单的二元分类器。
我正在使用 Python 3.6 和 TensorFlow 1.4。
Here 是一个小型、可运行的 Python 脚本,用于演示该问题。请注意,您需要从 Kaggle 下载 StatOil/C-CORE 数据集才能按原样运行脚本。
谢谢!
【问题讨论】:
我也遇到了同样的问题。 Sigmoid 和 log_loss 在 keras 中有效,但在 tensorflow 中没有学习发生。但是, sparse_softmax_cross_entropy 似乎有效。你找出问题所在了吗? 很遗憾没有。我仍然有兴趣了解我们为什么会看到这个问题。 【参考方案1】:在两个输出上使用sigmoid
激活不会给出概率分布:
import tensorflow as tf
import tensorflow.contrib.eager as tfe
tfe.enable_eager_execution()
start = tf.constant([[4., 5.]])
out_dense = tf.layers.dense(start, units=2)
print("Logits (un-transformed)", out_dense)
out_sigmoid = tf.layers.dense(start, units=2, activation=tf.sigmoid)
print("Elementwise sigmoid", out_sigmoid)
out_softmax = tf.nn.softmax(tf.layers.dense(start, units=2))
print("Softmax (probability distribution)", out_softmax)
打印:
Logits (un-transformed) tf.Tensor([[-3.64021587 6.90115976]], shape=(1, 2), dtype=float32)
Elementwise sigmoid tf.Tensor([[ 0.94315267 0.99705648]], shape=(1, 2), dtype=float32)
Softmax (probability distribution) tf.Tensor([[ 0.05623185 0.9437682 ]], shape=(1, 2), dtype=float32)
您也可以在单个 logit 上使用 tf.sigmoid
而不是 tf.nn.softmax
,然后将另一个输出设置为减去该值。
【讨论】:
我没有在两个输出上使用tf.sigmoid
。我在单个输出上使用它并使用tf.losses.log_loss
计算损失。
哈,没错。所以tf.losses.log_loss
需要一个单热编码向量,但这与标量分布情况的稀疏标记相同。但问题是什么? tf.losses.log_loss(labels=[[label]], predictions=[[prediction_scalar]])
等同于 sparse_softmax_cross_entropy(labels=[[label]], logits=[[1. - prediction_scalar, prediction_scalar]])
和 label in [0, 1]
。以上是关于具有对数损失的 TensorFlow 单 sigmoid 输出与具有稀疏 softmax 交叉熵损失的两个线性输出,用于二进制分类的主要内容,如果未能解决你的问题,请参考以下文章
为什么逻辑回归损失函数不用均方损失/二元逻辑回归的损失函数适合采用对数损失函数
自定义损失函数 Tensorflow / Keras 惩罚相对距离