神经网络中的优化算法最常用反向传播算法和梯度下降算法来调整神经网络中参数的取值。梯度下降算法主要用于优化单个参数的取值,而反向传播算法给出了一个高效的方式在所有参数上使用梯度下降算法,从而使神经网络模型在训练数据上的损失函数尽可能小。反向传播算法是训练神经网络的核心算法,他可以根据定义好的损失函数优化神经网络中参数的取值,从而使神经网络模型在训练数据集上的损失函数达到一个较小值。 神经网络模型中参数的优化过程直接决定了模型的质量,是使用神经网络时非常重要的一步。
假设用表示神经网络中的参数,J(
)表示在给定的参数取值下,训练数据集上损失函数的大小,那么整个优化过程可以抽象为寻找一个参数
,使得J(
)最小。梯度下降算法会迭代式更新参数
,不断沿着梯度的反方向让参数朝着总损失更小的方向更新。
参数的梯度可以通过求偏导数,其梯度为
,那么还需要定义一个学习率
来表示每次参数更新的幅度。那么参数的更新公式为:
.
需要注意的是,梯度下降算法并不能保证被优化的函数达到全局最优解,只有当损失函数是凸函数时,梯度下降算你发才能保证达到全局最优解。同时梯度下降算法的另一个问题就是计算时间太长。为了加速训练过程,可以使用随机梯度下降的算法,这个算法优化的不是全部训练数据上的损失函数,而是在每一轮迭代中,随机优化某一条训练数据上的损失函数。这样使每一轮参数更新的速度大大提高。同时由于随机梯度下降算法每次优化的只是某一条数据上的损失函数,所以他的问题也很明显,在某一条数据上损失函数更小并不代表全部数据损失函数更小,于是随机梯度下优化得到的神经网络甚至可能无法达到局部最优。
为了综合这两种方法,实际应用中每次选取一小部分训练数据的损失函数。这样不仅可以减少迭代次数,每次迭代的时间也会缩短,其具体代码如下:
batch_size=n
#每次读取一小部分数据作为当前的训练数据来执行反向传播算法
x=tf.placeholder(tf.float32,shape=(batch_size,2),name='x-input')
y_=tf.placeholder(tf.float32,shape=(batch_size,1),name='y-input')
#定义神经网络结构和优化算法
loss='''
train_step=tf.train.AdamOptimizer(0.001).minimize(loss)
#训练神经网络
with tf.Session() as sess:
#参数初始化
。。。
#迭代的更新更新
for i in range(STEPS):
#准备batch_size个训练数据。一般将所有的训练数据随机打乱之后在选取可以得到
#更好的 优化效果
current_X,current_y-=...
sess.run(train_step,feed_dict={x:current_X,y_:current_Y})