【问题标题】:tensorflow neural network model based on mnist with two outputs基于mnist的具有两个输出的tensorflow神经网络模型
【发布时间】:2017-04-21 12:08:25
【问题描述】:

我想训练一个具有 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}))

【问题讨论】:

    标签: python neural-network tensorflow


    【解决方案1】:

    你的网络有一些“奇怪”的东西,比如你的中间层有 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 被设计为使用 input 到 softmax,而不是输出。所以你的成本函数是不正确的。相反,您想像这样引用y_logits,目前您计算y

     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_) )
    

    【讨论】:

    • 谢谢。我现在正在尝试这个。正如我最初测试的那样,至少结果并不总是相同的。我认为有些事情进展顺利,但我很快就会更具体地知道。非常感谢。
    • @DLiebman:很可能你还有其他可以用建议做的事情,仅仅是因为你是新手,而且神经网络有很多细节需要在一切正常之前完成——相关,因为您在相对较低的级别实施。如果您最初的问题已解决,但您仍有其他问题,最好收集有关这些新问题的更多信息并提出一个全新的问题。
    • 那么我应该对y 做点什么吗?它只在correct_prediction 中使用?
    • @DLiebman y 是用于预测的变量。在您的脚本中测试它。在生产中,它是网络的输出,您将使用它来对新图像进行分类。
    • 此链接指向我的下一个问题...stackoverflow.com/questions/41019116/…
    【解决方案2】:

    隐藏层初始化后,您计算了隐藏层的softmax 的logits:y_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”作为输出。您可以考虑使用少数过采样或欠采样技术来解决人口不平衡问题。

    【讨论】:

    • 我也发现了 - 但这不是 OP 问题的原因。
    • @NeilSlater 如果没有看到训练数据,您将不知道 OP 的实际问题。此外,如果人口不平衡不是问题,那么接下来要做的就是超参数优化。 一步一个脚印。
    • 是的,我同意,但是选择 softmax 并没有你建议的那么严重——中间有 softmax 的网络应该可以正常工作,尽管这是一个奇怪的选择。 OP 的网络根本无法运行。
    • @NeilSlater 我同意。有偏差的分类输出可能是由于许多潜在问题造成的。权重对称是另一个问题,你在其他评论中提到过。 0.5 的学习率在我看来也有点高。我会使用指数衰减的较小值(0.1 或更小)。
    • ...而且,我仍然不会使用softmax 作为隐藏层的激活函数。
    猜你喜欢
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    • 2019-11-26
    • 2019-07-14
    • 2018-02-28
    相关资源
    最近更新 更多