对于张量流中的二进制分类,成本函数总是返回零

ANA*_*N S 3 python artificial-intelligence machine-learning neural-network tensorflow

我在tensorflow中编写了以下二进制分类程序,它是错误的.无论输入是什么,成本都会一直返回到零.我正在尝试调试一个没有从数据中学到任何东西的大型程序.我已经将至少一个bug缩小到成本函数,总是返回零.给定的程序使用一些随机输入并且具有相同的问题.self.X_train并且self.y_train最初应该从文件中读取并且该函数self.predict()具有形成前馈神经网络的更多层.

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

如果有人能够弄清楚我在做错了什么,我可以尝试在我的原始程序中进行相同的更改.非常感谢!

lej*_*lot 7

唯一的问题是使用的无效成本.softmax_cross_entropy_with_logits如果有,应使用超过两班,为SOFTMAX单个输出的总是返回1,因为它被定义为:

softmax(x)_i = exp(x_i) / SUM_j exp(x_j)
Run Code Online (Sandbox Code Playgroud)

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

softmax(x) = exp(x) / exp(x) = 1
Run Code Online (Sandbox Code Playgroud)

此外,对于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
Run Code Online (Sandbox Code Playgroud)

只需切换到这个成本,你就可以了,你也不必将任何东西编码为单热,因为这个功能仅用于你的用例.

唯一遗漏的是......你的代码没有你需要定义优化器的实际训练例程,要求它最小化损失,然后在循环中运行一个训练操作.在您当前的设置中,您只是尝试一遍又一遍地预测,网络永远不会改变.

特别是请参考关于SO的Cross Entropy Jungle问题,它提供了TF(和其他库)中具有不同要求/用例的所有这些不同辅助函数的更详细描述.