我尝试构建一个简单的多层感知机(MLP),它包含一个输入层(2个神经元)、一个隐藏层(5个神经元)和一个输出层(1个神经元)。我计划使用[[0., 0.], [0., 1.], [1., 0.], [1., 1.]]
来训练和输入,以获得期望的输出[0., 1., 1., 0.]
(逐元素)。
不幸的是,我的代码无法运行。不管我尝试什么,我总是遇到维度错误。这真是令人沮丧 :/ 我觉得我遗漏了什么,但就是找不出问题所在。
为了提高可读性,我还将代码上传到了pastebin:代码
有什么想法吗?
import tensorflow as tf###################### preparation stuff ####################### define input and output datainput_data = [[0., 0.], [0., 1.], [1., 0.], [1., 1.]] # XOR inputoutput_data = [0., 1., 1., 0.] # XOR output# create a placeholder for the input# None indicates a variable batch size for the input# one input's dimension is [1, 2]n_input = tf.placeholder(tf.float32, shape=[None, 2])# number of neurons in the hidden layerhidden_nodes = 5################# hidden layer #################b_hidden = tf.Variable(0.1) # hidden layer's bias neuronW_hidden = tf.Variable(tf.random_uniform([hidden_nodes, 2], -1.0, 1.0)) # hidden layer's weight matrix # initialized with a uniform distributionhidden = tf.sigmoid(tf.matmul(W_hidden, n_input) + b_hidden) # calc hidden layer's activation################# output layer #################W_output = tf.Variable(tf.random_uniform([hidden_nodes, 1], -1.0, 1.0)) # output layer's weight matrixoutput = tf.sigmoid(tf.matmul(W_output, hidden)) # calc output layer's activation############# learning #############cross_entropy = tf.nn.sigmoid_cross_entropy_with_logits(output, n_input) # calc cross entropy between current # output and desired outputloss = tf.reduce_mean(cross_entropy) # mean the cross_entropyoptimizer = tf.train.GradientDescentOptimizer(0.1) # take a gradient descent for optimizing with a "stepsize" of 0.1train = optimizer.minimize(loss) # let the optimizer train##################### initialize graph #####################init = tf.initialize_all_variables()sess = tf.Session() # create the session and therefore the graphsess.run(init) # initialize all variables# train the networkfor epoch in xrange(0, 201): sess.run(train) # run the training operation if epoch % 20 == 0: print("step: {:>3} | W: {} | b: {}".format(epoch, sess.run(W_hidden), sess.run(b_hidden)))
编辑: 我仍然在遇到错误 :/
hidden = tf.sigmoid(tf.matmul(n_input, W_hidden) + b_hidden)
输出 line 27 (...) ValueError: Dimensions Dimension(2) and Dimension(5) are not compatible
。将这一行改为:
hidden = tf.sigmoid(tf.matmul(W_hidden, n_input) + b_hidden)
似乎可以工作,但随后错误出现在:
output = tf.sigmoid(tf.matmul(hidden, W_output))
告诉我: line 34 (...) ValueError: Dimensions Dimension(2) and Dimension(5) are not compatible
将语句改为:
output = tf.sigmoid(tf.matmul(W_output, hidden))
也抛出异常: line 34 (...) ValueError: Dimensions Dimension(1) and Dimension(5) are not compatible
。
编辑2: 我真的不明白这一点。难道hidden
不应该是W_hidden x n_input.T
吗,因为在维度上这应该是(5, 2) x (2, 1)
?如果我转置n_input
,hidden
仍然可以工作(我甚至不明白为什么它在没有转置的情况下也能工作)。然而,output
仍然抛出错误,但这个操作在维度上应该是(1, 5) x (5, 1)
?!
回答:
(0) 包含错误输出是有帮助的 – 这也是一个有用的东西,因为它确实准确地指出了你遇到的形状问题所在。
(1) 形状错误的出现是因为你在两个矩阵乘法中都把参数顺序反了,并且tf.Variable
的顺序也反了。一般规则是,对于具有input_size, output_size
的层的权重应该是[input_size, output_size]
,矩阵乘法应该是tf.matmul(input_to_layer, weights_for_layer)
(然后加上偏置,偏置的形状是[output_size]
)。
所以在你的代码中,
W_hidden = tf.Variable(tf.random_uniform([hidden_nodes, 2], -1.0, 1.0))
应该改为:
W_hidden = tf.Variable(tf.random_uniform([2, hidden_nodes], -1.0, 1.0))
并且
hidden = tf.sigmoid(tf.matmul(W_hidden, n_input) + b_hidden)
应该改为tf.matmul(n_input, W_hidden)
;而
output = tf.sigmoid(tf.matmul(W_output, hidden))
应该改为tf.matmul(hidden, W_output)
(2) 一旦你修复了这些错误,你的运行需要提供一个feed_dict:
sess.run(train)
应该改为:
sess.run(train, feed_dict={n_input: input_data})
至少,我认为这是你试图实现的目标。