Tensorflow 神经网络优化
指数衰减学习率
学习率 learning_rate:表示了每次参数更新的幅度大小。学习率过大,会导致待优化的参数在最小值附近波动,不收敛;学习率过小,会导致待优化的参数收敛缓慢。
在训练过程中,参数的更新向着损失函数梯度下降的方向。
参数的更新公式为:
Wn+1 = Wn - learning_rate▽(loss)
假设损失函数为 loss = (w + 1)^2。梯度是损失函数 loss 的导数为 ∇=2w+2。如参数初值为 5,学习
率为 0.2,则参数和损失函数更新如下:
1 次 参数 w:5 5 - 0.2 * (2 * 5 + 2) = 2.6
2 次 参数 w:2.6 - 0.2 * (2 * 2.6 + 2) = 1.16
3 次 参数 w:1.16 – 0.2 * (2 * 1.16 + 2) = 0.296
4 次 参数 w:0.296 ...
损失函数 loss = (w + 1)2的图像为:
由图可知,损失函数 loss 的最小值会在(-1,0)处得到,此时损失函数的导数为 0,得到最终参数 w =-1。
随着损失函数值的减小,w 无限趋近于-1,模型计算推测出最优参数 w = -1
学习率的设置学习率过大,会导致待优化的参数在最小值附近波动,不收敛;学习率过小,会导致待优化的参数收敛缓慢。
损失函数 loss 值缓慢下降,w 值也在小幅度变化,收敛缓慢。
指数衰减学习率:学习率随着训练轮数变化而动态更新
学习率计算公式如下:
Learning_rate=LEARNING_RATE_BASE*LEARNING_RATE_DECAY^global_step/learning_rate_batch_size
Learning_rate_batch_size=总样本数/batch_size
用 Tensorflow 的函数表示为:
global_step = tf.Variable(0, trainable=False)
learning_rate=tf.train.exponential_decay(LEARNING_RATE_BASE,global_step, LEARNING_RATE_STEP, LEARNING_RATE_DECAY, staircase=True/False)
其中,LEARNING_RATE_BASE 为学习率初始值,LEARNING_RATE_DECAY 为学习率衰减率,global_step 记录了当前训练轮数,为不可训练型参数。学习率 learning_rate 更新频率为输入数据集总样本数除以每次喂入样本数。若 staircase 设置为 True 时,表示 global_step/learning rate step 取整数,学习率阶梯型衰减;若 staircase 设置为 false 时,学习率会是一条平滑下降的曲线。
滑动平均
滑动平均:记录了一段时间内模型中所有参数 w 和 b 各自的平均值。利用滑动平均值可以增强模的泛化能力。
滑动平均值(影子)计算公式:
影子 = 衰减率 * 影子 +(1 - 衰减率)* 参数
其中,衰减率 = min{movingaavgDECAY,1+轮数/10+轮数} 影子初值=参数初值
用 Tesnsorflow 函数表示为:
ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step)
其中,MOVING_AVERAGE_DECAY 表示滑动平均衰减率,一般会赋接近 1 的值,global_step 表示当前训练了多少轮。
ema_op = ema.apply(tf.trainable_variables())
其中,ema.apply()函数实现对括号内参数求滑动平均,tf.trainable_variables()函数实现把所有
待训练参数汇总为列表。
查看模型中参数的平均值,可以用 ema.average()函数。
例如:
在神经网络模型中,将 MOVING_AVERAGE_DECAY 设置为 0.99,参数 w1 设置为 0,w1 的滑动平均值设置为 0。
①开始时,轮数 global_step 设置为 0,参数 w1 更新为 1,则 w1 的滑动平均值为:
w1 滑动平均值=min(0.99,1/10)*0+(1– min(0.99,1/10)*1 = 0.9
③ 当轮数 global_step 设置为 100 时,参数 w1 更新为 10,以下代码 global_step 保持为 100,每次执行滑动平均操作影子值更新,则滑动平均值变为:
w1 滑动平均值=min(0.99,101/110)*0.9+(1– min(0.99,101/110)*10 = 0.826+0.818=1.644
③再次运行,参数 w1 更新为 1.644,则滑动平均值变为:
w1 滑动平均值=min(0.99,101/110)*1.644+(1– min(0.99,101/110)*10 = 2.328
④再次运行,参数 w1 更新为 2.328,则滑动平均值:
w1 滑动平均值=2.956
正则化
过拟合:神经网络模型在训练数据集上的准确率较高,在新的数据进行预测或分类时准确率较低,说明模型的泛化能力差。
正则化:在损失函数中给每个参数 w 加上权重,引入模型复杂度指标,从而抑制模型噪声,减小过拟合。
使用正则化后,损失函数 loss 变为两项之和:
loss = loss(y 与 y_) + REGULARIZER*loss(w)
其中,第一项是预测结果与标准答案之间的差距,如交叉熵、均方误差等;第二项是正则化计算结果。
正则化计算方法:
① L1 正则化:loss(L1)=∑i|wi|
用 Tesnsorflow 函数表示:loss(w) = tf.contrib.layers.l1_regularizer(REGULARIZER)(w)
② L2 正则化:loss(L2)=∑i|wi|²
用 Tesnsorflow 函数表示:loss(w) = tf.contrib.layers.l2_regularizer(REGULARIZER)(w)
用 Tesnsorflow 函数实现正则化:
tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(regularizer)(w)
loss = cem + tf.add_n(tf.get_collection('losses'))
正则化、指数衰减学习率、滑动平均方法的设置
①正则化项 regularization
当在前向传播过程中即 forward.py 文件中,设置正则化参数 regularization 为1 时,则表明在反向传播过程中优化模型参数时,需要在损失函数中加入正则化项。
结构如下:
首先,需要在前向传播过程即 forward.py 文件中加入
if regularizer != None: tf.add_to_collection('losses',
tf.contrib.layers.l2_regularizer(regularizer)(w))
其次,需要在反向传播过程即 backword.py 文件中加入
ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=tf.argmax(y_, 1))
cem = tf.reduce_mean(ce)
loss = cem + tf.add_n(tf.get_collection('losses'))
其中,tf.nn.sparse_softmax_cross_entropy_with_logits()表示 softmax()函数与交叉熵一起使用。
②指数衰减学习率
在训练模型时,使用指数衰减学习率可以使模型在训练的前期快速收敛接近较优解,又可以保证模型在训练后期不会有太大波动。
运用指数衰减学习率,需要在反向传播过程即 backword.py 文件中加入:
learning_rate = tf.train.exponential_decay(
LEARNING_RATE_BASE,
global_step,
LEARNING_RATE_STEP, LEARNING_RATE_DECAY,
staircase=True)
③滑动平均
在模型训练时引入滑动平均可以使模型在测试数据上表现的更加健壮。需要在反向传播过程即 backword.py 文件中加入:
ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,
global_step)
ema_op = ema.apply(tf.trainable_variables())
with tf.control_dependencies([train_step, ema_op]):
train_op = tf.no_op(name='train')