TensorFlow: 2层前馈神经网络

我正在尝试使用TensorFlow(Python 3版本)实现一个简单的全连接前馈神经网络。该网络有2个输入和1个输出,我试图训练它输出两个输入的异或(XOR)值。我的代码如下:

import numpy as npimport tensorflow as tfsess = tf.InteractiveSession()inputs = tf.placeholder(tf.float32, shape = [None, 2])desired_outputs = tf.placeholder(tf.float32, shape = [None, 1])weights_1 = tf.Variable(tf.zeros([2, 3]))biases_1 = tf.Variable(tf.zeros([1, 3]))layer_1_outputs = tf.nn.sigmoid(tf.matmul(inputs, weights_1) + biases_1)weights_2 = tf.Variable(tf.zeros([3, 1]))biases_2 = tf.Variable(tf.zeros([1, 1]))layer_2_outputs = tf.nn.sigmoid(tf.matmul(layer_1_outputs, weights_2) + biases_2)error_function = -tf.reduce_sum(desired_outputs * tf.log(layer_2_outputs))train_step = tf.train.GradientDescentOptimizer(0.05).minimize(error_function)sess.run(tf.initialize_all_variables())training_inputs = [[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]training_outputs = [[0.0], [1.0], [1.0], [0.0]]for i in range(10000):    train_step.run(feed_dict = {inputs: np.array(training_inputs), desired_outputs: np.array(training_outputs)})print(sess.run(layer_2_outputs, feed_dict = {inputs: np.array([[0.0, 0.0]])}))print(sess.run(layer_2_outputs, feed_dict = {inputs: np.array([[0.0, 1.0]])}))print(sess.run(layer_2_outputs, feed_dict = {inputs: np.array([[1.0, 0.0]])}))print(sess.run(layer_2_outputs, feed_dict = {inputs: np.array([[1.0, 1.0]])}))

看起来很简单,但最后的打印语句显示神经网络的输出与期望的输出相差甚远,无论训练迭代次数或学习率如何。有人能看出我做错了什么吗?

谢谢。

编辑:我还尝试了以下另一种错误函数:

error_function = 0.5 * tf.reduce_sum(tf.sub(layer_2_outputs, desired_outputs) * tf.sub(layer_2_outputs, desired_outputs))

该错误函数是误差平方的总和。它总是导致网络输出精确的0.5值——这是代码中存在错误的另一个迹象。

编辑2:我发现我的代码对AND和OR操作正常,但对XOR操作不行。我现在非常困惑。


回答:

你的代码中存在几个问题。以下我将逐行注释,带你找到解决方案。

注意:XOR不是线性可分的。你需要超过1个隐藏层。

注意:以# [!]开头的行是你出错的地方。

import numpy as npimport tensorflow as tfsess = tf.InteractiveSession()# 一批每个包含2个值的输入inputs = tf.placeholder(tf.float32, shape=[None, 2])# 一批每个包含1个值的输出desired_outputs = tf.placeholder(tf.float32, shape=[None, 1])# [!] 定义第一层的隐藏单元数量HIDDEN_UNITS = 4 # 将2个输入连接到3个隐藏单元# [!] 使用随机数初始化权重,使网络能够学习weights_1 = tf.Variable(tf.truncated_normal([2, HIDDEN_UNITS]))# [!] 每个隐藏单元的偏置是一个单值biases_1 = tf.Variable(tf.zeros([HIDDEN_UNITS]))# 将2个输入连接到每个隐藏单元。添加偏置layer_1_outputs = tf.nn.sigmoid(tf.matmul(inputs, weights_1) + biases_1)# [!] XOR的问题在于函数不是线性可分的# [!] 多层感知器(MLP)可以学习分离非线性可分的点(你可以# 认为它将学习超曲线,而不仅仅是超平面)# [!] 让我们添加一个新层,并将第二层改为输出超过1个值# 将第一层的隐藏单元连接到第二隐藏层的2个隐藏单元weights_2 = tf.Variable(tf.truncated_normal([HIDDEN_UNITS, 2]))# [!] 同上biases_2 = tf.Variable(tf.zeros([2]))# 将隐藏单元连接到第二隐藏层layer_2_outputs = tf.nn.sigmoid(    tf.matmul(layer_1_outputs, weights_2) + biases_2)# [!] 创建新层weights_3 = tf.Variable(tf.truncated_normal([2, 1]))biases_3 = tf.Variable(tf.zeros([1]))logits = tf.nn.sigmoid(tf.matmul(layer_2_outputs, weights_3) + biases_3)# [!] 所选择的错误函数适用于多类分类任务,不适用于XOR.error_function = 0.5 * tf.reduce_sum(tf.sub(logits, desired_outputs) * tf.sub(logits, desired_outputs))train_step = tf.train.GradientDescentOptimizer(0.05).minimize(error_function)sess.run(tf.initialize_all_variables())training_inputs = [[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]training_outputs = [[0.0], [1.0], [1.0], [0.0]]for i in range(20000):    _, loss = sess.run([train_step, error_function],                       feed_dict={inputs: np.array(training_inputs),                                  desired_outputs: np.array(training_outputs)})    print(loss)print(sess.run(logits, feed_dict={inputs: np.array([[0.0, 0.0]])}))print(sess.run(logits, feed_dict={inputs: np.array([[0.0, 1.0]])}))print(sess.run(logits, feed_dict={inputs: np.array([[1.0, 0.0]])}))print(sess.run(logits, feed_dict={inputs: np.array([[1.0, 1.0]])}))

我增加了训练迭代次数,以确保无论随机初始化值如何,网络都能收敛。

经过20000次训练迭代后的输出是:

[[ 0.01759939]][[ 0.97418505]][[ 0.97734243]][[ 0.0310041]]

看起来相当不错。

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注