Tensorflow不会收敛于XOR

时间:2017-02-11 05:14:12

标签: python machine-learning tensorflow neural-network artificial-intelligence

我尝试编写一个简单的XOR神经网络,但它永远不会收敛

我创建了一个带有2个输入,2个隐藏节点和1个输出的NN。

我使用第一个隐藏层和最后一个softmax来获取输出。

理论上它应该学会如何解决它并收敛?

import tensorflow as tf

sess = tf.InteractiveSession()

# define placeholder for input and output
x_ = tf.placeholder(tf.float32, shape=[4,2], name="x-input")
y_ = tf.placeholder(tf.float32, shape=[4,1], name="y-input")

# Configure weights and layers
W = tf.Variable(tf.random_uniform([2, 2], -.01, .01))
b = tf.Variable(tf.random_uniform([2], -.01, .01))
hidden  = tf.nn.relu(tf.matmul(x_,W) + b) # first layer.

W2 = tf.Variable(tf.random_uniform([2,1], -.1, .1))
b2 = tf.Variable(tf.zeros([1]))
hidden2 = tf.matmul(hidden, W2 + b2)
y = tf.nn.softmax(hidden2)

# Training function
cross_entropy = -tf.reduce_sum(y_*tf.log(hidden2))
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(cross_entropy)

XOR_X = [[0,0],[0,1],[1,0],[1,1]]
XOR_Y = [[0],[1],[1],[0]]

init = tf.global_variables_initializer()
sess.run(init)
# Train on the input data
for i in range(100):
    sess.run([cross_entropy, train_step], feed_dict={x_: XOR_X, y_: XOR_Y})
    print ('W1', sess.run(W))
    print('Output ', sess.run(y, feed_dict={x_: XOR_X, y_: XOR_Y}))

1 个答案:

答案 0 :(得分:0)

错误......

  1. W2权重应介于-1和1之间,因为它们不使用ReLu。此外,第一层权重使用ReLu,因此我将它们设置为阳性以尝试避免死神经元。

  2. Softmax毫无意义,除非它是1个热矢量图层。 Sigmoid更有意义。阅读Softmax如何工作有助于解决问题。

  3. 减少总和应该在y not hidden2

  4. 上完成
  5. hidden2 = tf.matmul(hidden, W2 + b2)括号错误。应为hidden2 = tf.matmul(hidden, W2) + b2

  6. -Log作为错误函数仅在您尝试将输出设置为1而不是0时才有效。这是因为-log(1)= 0,而-log(0)时为无穷大。这会鼓励输出变为1但不是0.如果你试图将输出推送到0表示一个输入而1表示另一个输入,则输出为1热点矢量。

  7. 隐藏层中的2个神经元确实有效。但它很容易受初始化的随机性影响。使用额外的神经元(10而不是2)可以减少初始化错误。

  8. 以下代码有效。它使用成本函数,有助于收敛到0和1,用于不同的输入。

    import tensorflow as tf
    sess = tf.InteractiveSession()
    
    # define placeholder for input, None as first argument means tensor can be any length
    x_ = tf.placeholder(tf.float32, shape=[4,2], name="x-input")
    y_ = tf.placeholder(tf.float32, shape=[4,1], name="y-input")
    
    # Configure weights and layers
    W = tf.Variable(tf.random_uniform([2, 10], 0.001, .01))
    b = tf.Variable(tf.zeros([10]))
    hidden  = tf.nn.relu(tf.matmul(x_,W) + b) # first layer.
    
    W2 = tf.Variable(tf.random_uniform([10,1], -1, 1))
    b2 = tf.Variable(tf.zeros([1]))
    hidden2 = tf.matmul(hidden, W2) + b2
    y = tf.nn.sigmoid(hidden2)
    
    # Training function + data
    cost = tf.reduce_mean(( (y_ * tf.log(y)) +
    ((1 - y_) * tf.log(1.0 - y)) ) * -1)
    train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cost)
    
    XOR_X = [[0,0],[0,1],[1,0],[1,1]]
    XOR_Y = [[0],[1],[1],[0]]
    
    init = tf.global_variables_initializer()
    sess.run(init)
    # Train on the input data
    for i in range(100000):
        sess.run(train_step, feed_dict={x_: XOR_X, y_: XOR_Y})
        if i % 2000 == 0:
            print ('W1', sess.run(W))
            print('Output ', sess.run(y, feed_dict={x_: XOR_X, y_: XOR_Y}))