我正在尝试使用 tensorflow (V.1.1.0) 在输出层使用单个神经元执行二元分类。下面的代码段对应于我目前使用的损失函数和优化器(灵感来自这里的答案)。
ratio=.034 #minority/population ratio
learning_rate=0.001
class_weight=tf.constant([[ratio,1.0-ratio]],name='unbalanced_ratio') #weight vector, (lab_feed is one_hot labels)
weight_per_label=tf.transpose(tf.matmul(lab_feed,tf.transpose(class_weight)),name='weights_per_label')
xent=tf.multiply(weight_per_label,tf.nn.sigmoid_cross_entropy_with_logits(labels=lab_feed,logits=output),name='loss')
loss=tf.reduce_mean(xent)
optimizer = tf.train.GradientDescentOptimizer(learning_rate = learning_rate,name='GradientDescent').minimize(loss)
然而,我的问题是,由于某种原因,所有实例在历元进展后都被归类为同一类。我必须在中间停止训练还是损失函数有问题?
您误用了 sigmoid 交叉熵,就好像它是 softmax 交叉熵一样。
Sigmoid 交叉熵适用于二元分类——你的问题是二元分类,所以没关系。但是,对于每个二元分类任务,网络的输出应该只有一个通道——在你的例子中,你有一个二元分类任务,所以你的网络应该只有一个输出通道。
要平衡 sigmoid 交叉熵,您需要平衡交叉熵的每个单独部分,即来自正的部分和来自负的部分。这不能像您所做的那样在输出上完成,因为输出已经是正负部分的总和。
希望 tensorflow 中有一个函数可以做到这一点,tf.nn.weighted_cross_entropy_with_logits
. 它的使用类似于tf.nn.sigmoid_cross_entropy
带有一个对应于正类权重的附加参数。
您目前正在做的是在两个不同的通道上使用两个二元分类器,并且只将负样本发送到第一个,将正样本发送到第二个。这不能产生有用的东西。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句