【问题标题】:Problems implementing an XOR gate with Neural Nets in Tensorflow在 Tensorflow 中使用神经网络实现 XOR 门的问题
【发布时间】:2016-02-18 06:32:27
【问题描述】:

我想做一个简单的神经网络,它应该只实现 XOR 门。我在 python 中使用 TensorFlow 库。 对于异或门,我训练的唯一数据是完整的真值表,应该足够了吧?过度优化是我期望很快发生的事情。代码的问题是 weightsbiases 没有更新。不知何故,它仍然为我提供了 100% 的准确度,偏差和权重为零。

x = tf.placeholder("float", [None, 2])
W = tf.Variable(tf.zeros([2,2]))
b = tf.Variable(tf.zeros([2]))

y = tf.nn.softmax(tf.matmul(x,W) + b)

y_ = tf.placeholder("float", [None,1])


print "Done init"

cross_entropy = -tf.reduce_sum(y_*tf.log(y))
train_step = tf.train.GradientDescentOptimizer(0.75).minimize(cross_entropy)

print "Done loading vars"

init = tf.initialize_all_variables()
print "Done: Initializing variables"

sess = tf.Session()
sess.run(init)
print "Done: Session started"

xTrain = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
yTrain = np.array([[1], [0], [0], [0]])


acc=0.0
while acc<0.85:
  for i in range(500):
      sess.run(train_step, feed_dict={x: xTrain, y_: yTrain})


  print b.eval(sess)
  print W.eval(sess)


  print "Done training"


  correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))

  accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

  print "Result:"
  acc= sess.run(accuracy, feed_dict={x: xTrain, y_: yTrain})
  print acc

B0 = b.eval(sess)[0]
B1 = b.eval(sess)[1]
W00 = W.eval(sess)[0][0]
W01 = W.eval(sess)[0][1]
W10 = W.eval(sess)[1][0]
W11 = W.eval(sess)[1][1]

for A,B in product([0,1],[0,1]):
  top = W00*A + W01*A + B0
  bottom = W10*B + W11*B + B1
  print "A:",A," B:",B
  # print "Top",top," Bottom: ", bottom
  print "Sum:",top+bottom

我正在学习http://tensorflow.org/tutorials/mnist/beginners/index.md#softmax_regressions 的教程 在最后的 for 循环中,我将结果从矩阵中打印出来(如链接中所述)。

谁能指出我的错误以及我应该做些什么来解决它?

【问题讨论】:

    标签: python neural-network tensorflow


    【解决方案1】:

    您的程序存在一些问题。

    第一个问题是您正在学习的函数不是 XOR - 它是 NOR。行:

    xTrain = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
    yTrain = np.array([[1], [0], [0], [0]])
    

    ...应该是:

    xTrain = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
    yTrain = np.array([[0], [1], [1], [0]])
    

    下一个大问题是您设计的网络isn't capable of learning XOR。您需要使用非线性函数(例如 tf.nn.relu() 并定义至少一层来学习 XOR 函数。例如:

    x = tf.placeholder("float", [None, 2])
    W_hidden = tf.Variable(...)
    b_hidden = tf.Variable(...)
    hidden = tf.nn.relu(tf.matmul(x, W_hidden) + b_hidden)
    
    W_logits = tf.Variable(...)
    b_logits = tf.Variable(...)
    logits = tf.matmul(hidden, W_logits) + b_logits
    

    另一个问题是将权重初始化为零将prevent your network from training。通常,你应该随机初始化你的权重,并且你的偏差为零。这是一种流行的方法:

    HIDDEN_NODES = 2
    
    W_hidden = tf.Variable(tf.truncated_normal([2, HIDDEN_NODES], stddev=1./math.sqrt(2)))
    b_hidden = tf.Variable(tf.zeros([HIDDEN_NODES]))
    
    W_logits = tf.Variable(tf.truncated_normal([HIDDEN_NODES, 2], stddev=1./math.sqrt(HIDDEN_NODES)))
    b_logits = tf.Variable(tf.zeros([2]))
    

    将它们放在一起,并使用 TensorFlow 例程进行交叉熵(为方便起见,使用单热编码 yTrain),这是一个学习 XOR 的程序:

    import math
    import tensorflow as tf
    import numpy as np
    
    HIDDEN_NODES = 10
    
    x = tf.placeholder(tf.float32, [None, 2])
    W_hidden = tf.Variable(tf.truncated_normal([2, HIDDEN_NODES], stddev=1./math.sqrt(2)))
    b_hidden = tf.Variable(tf.zeros([HIDDEN_NODES]))
    hidden = tf.nn.relu(tf.matmul(x, W_hidden) + b_hidden)
    
    W_logits = tf.Variable(tf.truncated_normal([HIDDEN_NODES, 2], stddev=1./math.sqrt(HIDDEN_NODES)))
    b_logits = tf.Variable(tf.zeros([2]))
    logits = tf.matmul(hidden, W_logits) + b_logits
    
    y = tf.nn.softmax(logits)
    
    y_input = tf.placeholder(tf.float32, [None, 2])
    
    cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits, y_input)
    loss = tf.reduce_mean(cross_entropy)
    
    train_op = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
    
    init_op = tf.initialize_all_variables()
    
    sess = tf.Session()
    sess.run(init_op)
    
    xTrain = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
    yTrain = np.array([[1, 0], [0, 1], [0, 1], [1, 0]])
    
    for i in xrange(500):
      _, loss_val = sess.run([train_op, loss], feed_dict={x: xTrain, y_input: yTrain})
    
      if i % 10 == 0:
        print "Step:", i, "Current loss:", loss_val
        for x_input in [[0, 0], [0, 1], [1, 0], [1, 1]]:
          print x_input, sess.run(y, feed_dict={x: [x_input]})
    

    请注意,这可能不是计算 XOR 最有效的神经网络,因此欢迎提出调整参数的建议!

    【讨论】:

    • 非常感谢您的详细回复。这很有帮助!
    • 现在是全加器吗?
    • 不完全,因为它没有模拟进位输出位。半加器有两个输出位(总和和进位输出),因此您需要 4 个输出类(假设您使用我在这里使用的输出类的 one-hot 编码)。对于全加器,您还需要对第三个输入进行建模。不过,这两个都应该是对我发布的代码的简单补充。
    • 将随机变量初始化的 stddev 设置为 1./sqrt(2) 是否有特殊原因?
    • 本意是进行 Glorot-Bengio 初始化,但我可能记错了公式。这是相关论文的链接:jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf
    猜你喜欢
    • 2017-11-15
    • 2023-03-24
    • 2016-11-28
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    • 2019-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多