TensorFlow实战系列3--实现反向传播

 在前向传播的样例程序中,所有变量的取值都是随机的。在使用神经网络解决实际的分类或者回归问题时需要更好地设置参数取值。使用监督学习的方式设置神经网络参数需要有一个标注好的训练数据集。以判断零件是否合格为例,这个标注好的训练数据集就是收集的一批合格零件和一批不合格零件。监督学习最重要的思想就是,在已知答案的标注数据集上,模型给出的预测结果要尽量接近真实的答案。通过调整神经网络中的参数对训练数据进行拟合,可以使得模型对未知的样本提供预测的能力。

 在神经网络优化算法中, 最常用的方法是反向传播算法(backpropagation)。图4 展示了使用反向传播算法训练神经网络的流程图。本文将不过多讲解反向传播的数学公式,而是重点介绍如何通过TensorFlow 实现反向传播的过程。


        图4 使用反向传播优化神经网络的流程图

从图4 中可以看出,通过反向传播算法优化神经网络是一个迭代的过程。在每次迭代的开始,首先需要选取一小部分训练数据,这一小部分数据叫做一个batch。然后,这个batch 的样例会通过前向传播算法得到神经网络模型的预测结果。因为训练数据都是有正确答案标注的,所以可以计算出当前神经网络模型的预测答案与正确答案之间的差距。最后,基于这预测值和真实值之间的差距,反向传播算法会相应更新神经网络参数的取值,使得在这个batch 上神经网络模型的预测结果和真实答案更加接近。通过TensorFlow 实现反向传播算法的第一步是使用TensorFlow 表达一个batch 的数据。在上面的样例中使用了常量来表达过一个样例:

x = tf.constant([[0.7, 0.9]])
但如果每轮迭代中选取的数据都要通过常量来表示,那么TensorFlow的计算图将会太大。因为每生成一个常量,TensorFlow 都会在计算图增加一个节点。一般来说,一个神经网络的训练过程会需要经过几百万轮甚至几亿轮的迭代,这样计算图就会非常大,而且利用率很低。为了避免这个问题,TensorFlow 提供了placeholder 机制用于提供输入数据。placeholder 相当于定义了一个位置,这个位置中的数据在程序运行时再指定。这样在程序中就不需要生成大量常量来提供输入数据,而只需要将数据通过placeholder 传入TensorFlow 计算图。在placeholder 定义时,这个位置上的数据类型是需要指定的。和其他张量一样,placeholder 的类型也是不可以改变的。placeholder 中数据的维度信息可以根据提供的数据推导得出,所以不一定要给出。下面给出了通过placeholder 实现前向传播算法的代码。

x = tf.placeholder(tf.float32, shape=(1, 2), name="input")
# 其他部分定义和上面的样例一样。
print(sess.run(y, feed_dict={x: [[0.7,0.9]]}))
 在调用sess.run 时,我们需要使用feed_dict 来设定x 的取值。在得到一个batch 的前向传播结果之后,需要定义一个损失函数来刻画当前的预测值和真实答案之间的差距。然后通过反向传播算法来调整神经网络参数的取值使得差距可以被缩小。损失函数将在后面的文章中更加详细地介绍。以下代码定义了一个简单的损失函数,并通过TensorFlow 定义了反向传播的算法。

# 定义损失函数来刻画预测值与真实值得差距。
cross_entropy = -tf.reduce_mean(
y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0)))
# 定义学习率。
learning_rate = 0.001
# 定义反向传播算法来优化神经网络中的参数。
train_step =
tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)
 在上面的代码中,cross_entropy 定义了真实值和预测值之间的交叉熵(cross entropy),这是分类问题中一个常用的损失函数。第二行train_step 定义了反向传播的优化方法。目前TensorFlow 支持10 种不同的优化器,读者可以根据具体的应用选择不同的优化算法。比较常用的优化方法有三种:tf.train.GradientDescentOptimizer、class tf.train.AdamOptimizer和tf.train.MomentumOptimizer。



猜你喜欢

转载自blog.csdn.net/tian_qing_lei/article/details/79265187
今日推荐