我正在基于Tensorflow的MNIST初学者模板开发一个网络。基本上,我试图实现一个简单的逻辑回归,其中10个连续变量预测一个二元结果,因此我的输入是0到1之间的10个值,我的目标变量(代码中的Y_train和Y_test)是1或0。
我的主要问题是无论我运行多少训练集,准确率都没有变化——无论是运行100步还是31240步,准确率都是0.276667。此外,当我从softmax切换到简单的matmul来生成我的Y值时,我得到的准确率是0.0,这表明我的x*W + b计算可能有问题。输入读取没有问题。
我想知道的是a)是否因为我的代码错误而导致我没有正确计算Y值,b)如果不是这样的话,是否可能我需要实现one_hot向量——即使我的输出已经是0或1的形式。如果是后者,我在生成目标值向量时应该在哪里包含one_hot=TRUE函数?谢谢!
import numpy as npimport tensorflow as tftrain_data = np.genfromtxt("TRAINDATA2.txt", delimiter=" ")train_input = train_data[:, :10]train_input = train_input.reshape(31240, 10)X_train = tf.placeholder(tf.float32, [31240, 10])train_target = train_data[:, 10]train_target = train_target.reshape(31240, 1)Y_train = tf.placeholder(tf.float32, [31240, 1])test_data = np.genfromtxt("TESTDATA2.txt", delimiter = " ")test_input = test_data[:, :10]test_input = test_input.reshape(7800, 10)X_test = tf.placeholder(tf.float32, [7800, 10])test_target = test_data[:, 10]test_target = test_target.reshape(7800, 1)Y_test = tf.placeholder(tf.float32, [7800, 1])W = tf.Variable(tf.zeros([10, 1]))b = tf.Variable(tf.zeros([1]))Y_obt = tf.nn.softmax(tf.matmul(X_train, W) + b)Y_obt_test = tf.nn.softmax(tf.matmul(X_test, W) + b)cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=Y_obt, labels=Y_train)train_step = tf.train.GradientDescentOptimizer(0.05).minimize(cross_entropy)sess = tf.InteractiveSession()tf.global_variables_initializer().run()for _ in range(31240): sess.run(train_step, feed_dict={X_train: train_input, Y_train:train_target})correct_prediction = tf.equal(tf.round(Y_obt_test), Y_test)accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))print(sess.run(accuracy, feed_dict={X_test : test_input, Y_test: test_target}))
回答:
由于你将值映射到一个元素的目标,你不应该使用softmax交叉熵,因为softmax操作将输入转换为概率分布,所有概率的总和等于1。由于你的目标只有一个元素,它每次只会输出1,因为这是将输入转换为概率分布的唯一可能方式。你应该改用tf.nn.sigmoid_cross_entropy_with_logits()
(用于二元分类),并从Y_obt
中移除softmax,并将其转换为tf.sigmoid()
用于Y_obt_test
。
另一种方法是将你的目标进行one-hot编码,并使用具有两个元素输出的网络。在这种情况下,你应该使用tf.nn.softmax_cross_entropy_with_logits()
,但要从Y_obt
中移除tf.nn.softmax()
,因为softmax交叉熵期望未缩放的logits(https://www.tensorflow.org/api_docs/python/tf/nn/softmax_cross_entropy_with_logits)。对于Y_obt_test
,在这种情况下当然不应移除它。
另一件事:使用cross_entropy = tf.reduce_mean(tf.sigmoid_cross_entropy_...)
来计算交叉熵的平均值可能会有所帮助。