基于MNIST的张量流神经网络模型,具有两个输出



我想训练一个有 12 个输入和 2 个输出的神经网络。在这里,我有一个简单的张量流神经网络,它有两个输出。当我运行代码时,它总是始终提供一个输出。也就是说,如果两个输出标记为"l1"和"l2",则模型始终选择"l1"作为其输出。这是我的输入有问题(它在"l1"和"l2"之间变化不够大)还是选择仅使用两个输出的问题?这是我的问题。如果是后者,我该怎么做才能解决这个问题?我的模型应该检测照片中的肤色。("L1"=肤色,"L2"=非肤色)。我不确定这是否有意义。它改编自 mnist 示例,但该代码有十个输出。

def nn_setup(self):
input_num = 4 * 3
mid_num = 3
output_num = 2
x = tf.placeholder(tf.float32, [None, input_num])
W_1 = tf.Variable(tf.zeros([input_num, mid_num]))
b_1 = tf.Variable(tf.zeros([mid_num]))
y_mid = tf.nn.softmax(tf.matmul(x,W_1) + b_1)
W_2 = tf.Variable(tf.zeros([mid_num, output_num]))
b_2 = tf.Variable(tf.zeros([output_num]))
y = tf.nn.softmax(tf.matmul(y_mid, W_2) + b_2)
y_ = tf.placeholder(tf.float32, [None, output_num])
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y, y_))
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy) 
init = tf.initialize_all_variables()
self.sess = tf.Session()
self.sess.run(init)
for i in range(1000):
batch_xs, batch_ys = self.get_nn_next_train()
self.sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
self.nn_test.images, self.nn_test.labels = self.get_nn_next_test()
print(self.sess.run(accuracy, feed_dict={x: self.nn_test.images, y_: self.nn_test.labels}))

你的网络有一些"奇怪"的事情,比如在你的中间层有softmax。

您可以在您的实施中找到两个主要问题。


1. 权重初始化

W_1 = tf.Variable(tf.zeros([input_num, mid_num]))
W_2 = tf.Variable(tf.zeros([mid_num, output_num]))

这会将权重初始化为相同。因此,它们将具有相同的梯度值,并且在每一步中都以相同的方式更改。

通过这样做,您实际上已经创建了一个网络,每层中都有一个神经元(然后复制该神经元以创建您使用的层矩阵)。

使用不同的初始值,通常取一个小的随机矩阵,如下所示:

W_1 = tf.Variable(tf.random_normal([input_num, mid_num], stddev=0.5))

通常,图层越大,标准差越小。您也不必出于偏见而这样做,但如果您愿意,您可以这样做。

这不会解决您的网络的所有问题,但它至少应该开始从输入数据中计算不同的值并进行一些训练。


2. 成本函数的使用

您错误地使用了此损失函数:

cross_entropy = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(y, y_) )

。因为softmax_cross_entropy_with_logits被设计为与 SoftMax 的输入一起使用,而不是输出。因此,您的成本函数不正确。相反,您希望引用当前计算yy_logits

y_logits = tf.matmul(y_mid, W_2) + b_2
y = tf.nn.softmax(y_logits)

那么你的交叉熵将是

cross_entropy = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(y_logits, y_) )

隐藏层初始化后,您已经计算了隐藏层的对数softmaxy_mid = tf.nn.softmax(tf.matmul(x,W_1) + b_1)。在分类问题中,应将softmax应用于从输出图层获得的值。尝试如下操作:y_mid = tf.nn.relu(tf.matmul(x,W_1) + b_1)计算隐藏层的激活,并查看分类是否得到改善。如果这不能解决您的问题,请检查训练数据中的"l1"和"l2"总体。如果您的训练数据高度偏向"l1",您将始终获得"l1"作为输出。您可以考虑少数族裔过度抽样或样技术来解决总体不平衡问题。

最新更新