具有对数损失的Tensorflow单S形输出与具有稀疏softmax交叉熵损失的两个线性输出用于二进制分类

ihe*_*eap 5 classification machine-learning tensorflow

我正在尝试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)
Run Code Online (Sandbox Code Playgroud)

在第二种情况下,我有以下内容:

out = tf.layers.dense(prev, 1, activation=tf.sigmoid)
loss = tf.losses.log_loss(labels=y, predictions=out)
Run Code Online (Sandbox Code Playgroud)

张量y0/ 1值的向量; 它不是一个热门的编码.网络在第一种情况下按预期学习,但在第二种情况下不学习.除了这两行之外,其他一切都保持不变.

我不明白为什么第二次设置不起作用.有趣的是,如果我在Keras中表达相同的网络并使用第二个设置,它就可以工作.我是否使用了错误的TensorFlow函数来表达我在第二种情况下的意图?我想生成一个sigmoid输出并使用二进制交叉熵损失来训练一个简单的二元分类器.

我正在使用Python 3.6和TensorFlow 1.4.

是一个用于演示该问题的小型可运行Python脚本.请注意,您需要从Kaggle下载StatOil/C-CORE数据集才能够按原样运行脚本.

谢谢!

All*_*oie 2

对两个输出使用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)
Run Code Online (Sandbox Code Playgroud)

印刷:

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

除了 之外tf.nn.softmax,您还可以使用tf.sigmoid单个 logit,然后将另一个输出设置为 1 减去该值。