我用tensorflow编写了下面的二进制分类程序。无论投入多少,成本一直在归零。我试图调试一个更大的程序,它没有从数据中学习任何东西。我已经缩小了至少一个错误的成本函数总是返回零。给定的程序正在使用一些随机输入,并且存在相同的问题。self.X_train
和self.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()
如果有人能找出我在这方面做错了什么,我可以尝试在我原来的程序中做同样的改变。谢谢!在
softmax_cross_entropy_with_logits
基本上是两个部分的稳定实现:现在在您的例子中,预测是一个单一的值,所以当您对它应用}项变为0。这就是为什么你的成本总是零。在
softmax
时,它将始终是1,而与值(exp(prediction)/exp(prediction) = 1)
无关,因此{要么应用}用于类1。在
sigmoid
以获得介于0或1之间的概率,要么如果使用want to usesoftmax
将标签作为[1, 0]
用于类0,而{唯一的问题是使用的成本无效。
softmax_cross_entropy_with_logits
如果您有两个以上的类,应该使用,因为单个输出的softmax总是返回1,定义如下:所以对于单个数字(一维输出)
^{pr2}$此外,对于softmax输出,TF需要一个热编码标签,因此如果只提供0或1,则有两种可能:
-0*log(1) = 0
-1*log(1) = 0
Tensorflow有一个单独的函数来处理二进制分类,它应用sigmoid代替(注意,对于多个输出的同一个函数将在每个维度上独立应用sigmoid,这是多标签分类所期望的):
只要切换到这个成本,你就可以开始了,你也不必再将任何东西编码为一个热点,因为这个函数是专门为你的用例而设计的。在
唯一缺少的是。。。。您的代码没有实际的训练程序您需要定义优化程序,要求它将损失降至最低,然后在循环中运行训练操作。在你当前的环境下,你只需要反复地预测,网络永远不会改变。在
特别是,请参考Cross Entropy Jungle question on SO,它提供了TF(和其他库)中所有这些不同的helper函数的更详细的描述,这些函数具有不同的需求/用例。在
相关问题 更多 >
编程相关推荐