对于以十为单位的二元分类,代价函数总是返回零

2024-06-06 12:22:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我用tensorflow编写了下面的二进制分类程序。无论投入多少,成本一直在归零。我试图调试一个更大的程序,它没有从数据中学习任何东西。我已经缩小了至少一个错误的成本函数总是返回零。给定的程序正在使用一些随机输入,并且存在相同的问题。self.X_trainself.y_train最初是从文件中读取的,函数{}有更多层组成前馈神经网络。在

import numpy as np
import tensorflow as tf

class annClassifier():

    def __init__(self):

        with tf.variable_scope("Input"):
             self.X = tf.placeholder(tf.float32, shape=(100, 11))

        with tf.variable_scope("Output"):
            self.y = tf.placeholder(tf.float32, shape=(100, 1))

        self.X_train = np.random.rand(100, 11)
        self.y_train = np.random.randint(0,2, size=(100, 1))

    def predict(self):

        with tf.variable_scope('OutputLayer'):
            weights = tf.get_variable(name='weights',
                                      shape=[11, 1],
                                      initializer=tf.contrib.layers.xavier_initializer())
            bases = tf.get_variable(name='bases',
                                    shape=[1],
                                    initializer=tf.zeros_initializer())
            final_output = tf.matmul(self.X, weights) + bases

        return final_output

    def train(self):

        prediction = self.predict()
        cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=self.y))

        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())         
            print(sess.run(cost, feed_dict={self.X:self.X_train, self.y:self.y_train}))


with tf.Graph().as_default():
    classifier = annClassifier()
    classifier.train()

如果有人能找出我在这方面做错了什么,我可以尝试在我原来的程序中做同样的改变。谢谢!在


Tags: self程序tfdefaswithnptrain
2条回答

softmax_cross_entropy_with_logits基本上是两个部分的稳定实现:

softmax = tf.nn.softmax(prediction)
cost = -tf.reduce_mean(labels * tf.log(softmax), 1)

现在在您的例子中,预测是一个单一的值,所以当您对它应用softmax时,它将始终是1,而与值(exp(prediction)/exp(prediction) = 1)无关,因此{}项变为0。这就是为什么你的成本总是零。在

要么应用sigmoid以获得介于0或1之间的概率,要么如果使用want to use softmax将标签作为[1, 0]用于类0,而{}用于类1。在

唯一的问题是使用的成本无效。softmax_cross_entropy_with_logits如果您有两个以上的类,应该使用,因为单个输出的softmax总是返回1,定义如下:

softmax(x)_i = exp(x_i) / SUM_j exp(x_j)

所以对于单个数字(一维输出)

^{pr2}$

此外,对于softmax输出,TF需要一个热编码标签,因此如果只提供0或1,则有两种可能:

  1. 真正的标签是0,所以成本是-0*log(1) = 0
  2. 真正的标签是1,所以成本是-1*log(1) = 0

Tensorflow有一个单独的函数来处理二进制分类,它应用sigmoid代替(注意,对于多个输出的同一个函数将在每个维度上独立应用sigmoid,这是多标签分类所期望的):

tf.sigmoid_cross_entropy_with_logits

只要切换到这个成本,你就可以开始了,你也不必再将任何东西编码为一个热点,因为这个函数是专门为你的用例而设计的。在

唯一缺少的是。。。。您的代码没有实际的训练程序您需要定义优化程序,要求它将损失降至最低,然后在循环中运行训练操作。在你当前的环境下,你只需要反复地预测,网络永远不会改变。在

特别是,请参考Cross Entropy Jungle question on SO,它提供了TF(和其他库)中所有这些不同的helper函数的更详细的描述,这些函数具有不同的需求/用例。在

相关问题 更多 >