Tensorflow: 损失值与准确率不一致

我正在使用Tensorflow构建一个简单的单隐藏层神经网络。

对于输入,每行数据对应10个答案。每行的前两个元素是正确的,即与真实标签相同。相反,最后8个元素与真实标签相反。

例如,

[1, 1, 0, 0, 0, 0, 0, 0, 0, 0], 正确答案是1[0, 0, 1, 1, 1, 1, 1, 1, 1, 1], 正确答案是0[0, 0, 1, 1, 1, 1, 1, 1, 1, 1], 正确答案是0[1, 1, 0, 0, 0, 0, 0, 0, 0, 0], 正确答案是1

我希望我的神经网络能够学习到前两个元素/特征总是给出正确的结果。因此,我希望网络对前两个特征赋予更大的权重。然而,网络总是在某个损失值上卡住。

更有趣的是,准确率被定义为正确预测的标签占总标签数的比例。损失函数是使用sigmoid函数计算的,即$y * log(logit) + (1-y) * log(1-logit)$。有时候,随着损失的减少,准确率会增加。例如,

epoch是: 0 损失是: 7.661093 准确率是: 1.0 epoch是: 100 损失是: 7.579134 准确率是: 0.54545456 epoch是: 200 损失是: 7.5791006 准确率是: 0.54545456 

我认为网络应该能够不断增加前两个元素的权重,直到它能完全预测出正确的标签。

请问有人能告诉我应该怎么做才能让网络正确预测标签,而不是卡住吗?

我的代码如下:

import tensorflow as tfimport numpy as npclass SigmoidNeuralNetwork():    def __init__(self, learning_rate, training_data, correct_labels, epoch_number):        self.learning_rate = learning_rate        self.training_data = training_data        self.correct_labels = correct_labels        self.X = tf.placeholder(tf.float32)        self.y = tf.placeholder(tf.float32)        self.feature_num = len(self.training_data[0])        self.sample_num = len(self.training_data)        self.W = tf.Variable(tf.random_uniform([self.feature_num, 1], -1.0, 1.0), dtype=tf.float32)        self.b = tf.Variable([0.0])        self.epoch_number = epoch_number    def launch_network(self):        db = tf.matmul(self.X, tf.reshape(self.W, [-1, 1])) + self.b        hyp = tf.sigmoid(db)        cost0 = self.y * tf.log(tf.clip_by_value(hyp, 1e-10, 1.0))        cost1 = (1 - self.y) * tf.log(tf.clip_by_value((1 - hyp), 1e-10, 1.0))        cost = (cost0 + cost1) / float(self.sample_num)        loss = -tf.reduce_sum(cost)        optimizer = tf.train.GradientDescentOptimizer(learning_rate=self.learning_rate)        train = optimizer.minimize(loss)        #        new_train_X = self.training_data.astype(np.float32)        output = tf.add(tf.matmul(new_train_X, self.W), self.b)        prediction = tf.sigmoid(output)        predicted_class = tf.greater(prediction, 0.5)        ground_labels = tf.reshape(tf.equal(self.y, 1.0), predicted_class.shape)        correct = tf.equal(predicted_class, ground_labels)        accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))        #        init = tf.global_variables_initializer()        sess = tf.Session()        sess.run(init)        for epoch in range(self.epoch_number):            _, loss_val, accuracy_val = sess.run([train, loss, accuracy], {self.X: self.training_data, self.y: self.correct_labels})            if epoch % 100 == 0:                print "epoch是: ", epoch, "损失是: ", loss_val, " 准确率是: ", accuracy_val                # print "权重是: ", sess.run(self.W).flatten()train_data = np.array([    [1, 1, 0, 0, 0, 0, 0, 0, 0, 0],    [0, 0, 1, 1, 1, 1, 1, 1, 1, 1],    [0, 0, 1, 1, 1, 1, 1, 1, 1, 1],    [1, 1, 0, 0, 0, 0, 0, 0, 0, 0],    [0, 0, 1, 1, 1, 1, 1, 1, 1, 1],    [0, 0, 1, 1, 1, 1, 1, 1, 1, 1],    [0, 0, 1, 1, 1, 1, 1, 1, 1, 1],    [1, 1, 0, 0, 0, 0, 0, 0, 0, 0],    [1, 1, 0, 0, 0, 0, 0, 0, 0, 0],    [0, 0, 1, 1, 1, 1, 1, 1, 1, 1],    [1, 1, 0, 0, 0, 0, 0, 0, 0, 0]])correct_answers = np.array([1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1])sigmoid_network = SigmoidNeuralNetwork(learning_rate=0.01, training_data=train_data, correct_labels=correct_answers,                                       epoch_number=10000)sigmoid_network.launch_network()

回答:

问题是什么?

原帖作者写道:

我认为网络应该能够不断增加前两个元素的权重,直到它能完全预测出正确的标签。

你完全正确。

请问有人能告诉我应该怎么做才能让网络正确预测标签,而不是卡住吗?

问题出在launch_network()函数中:

def launch_network(self):    db = tf.matmul(self.X, tf.reshape(self.W, [-1, 1])) + self.b    hyp = tf.sigmoid(db)    cost0 = self.y * tf.log(tf.clip_by_value(hyp, 1e-10, 1.0))    ... (略) ...

请注意,dbhyp的形状都是(self.sample_num, 1)(二维),但self.y(即correct_answers)的形状是(self.sample_num,)(一维)。

在第五行计算cost0时,你进行了self.y * tf.log(...hyp...)的乘法操作。因此,结果的形状变成了(self.sample_num, self.sample_num),而不是(self.sample_num, 1)

解决方案建议

最简单的解决方案是将correct_answers的形状改为(self.sample_num, 1)(二维),而不是(self.sample_num,)(一维),如下所示:

correct_answers = np.array([1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1])[:,np.newaxis]

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注