本文用于学习TensorFlow中对神经网络模型的进一步优化!!!
神经网络的训练过程:
1)前向传播计算预测值,并将预测值与真实值做差;
2)反向传播计算损失函数中对每一个参数的梯度,再根据梯度和学习速率使用梯度下降算法更新每一个参数。
进一步优化神经网络模型的方法:
指数衰减的学习率、加入正则化的损失函数、滑动平均模型。
1. TensorFlow中指数衰减的学习率?
tf.train.exponential_decay() 生成学习率,每完整的过完一遍数据,学习率就减小一次。
先使用较大的学习速率快速衰减到一个比较优的解,然后随着迭代的继续逐步减小学习率。
每一轮优化时使用的速率 = 事先设定的初始学习率*衰减系数^(当前迭代到第几轮/衰减速度(完整的使用一遍训练数据所需要的迭代轮数))
learning_rate = tf.train.exponential_decay( LEARNING_RATE_BASE, global_step, TRAIN_SIZE/BATCH_SIZE, LEARNING_RATE_DECAY )
2.TensorFlow中的L2正则化?
tf.contrib.layers.l2_regularizer(LAMBDA)(weight)
LAMBDA表示模型复杂损失在总损失中的比例
3.TensorFlow中的滑动平均?
原理:在训练神经网络时,不断保持和更新每个参数的滑动平均值,在验证和测试时,参数的值使用其滑动平均值,能有效提高神经网络的准确率。
tf.train.ExponentialMovingAverage() 实现滑动平均模型,使用指数衰减decay来计算变量的移动平均值,用于控制模型的更新速度。
shadow_variable = decay *shadow_variable + (1 - decay) * variable
影子变量shadow_variable为上一轮轮滑动平均的更新变量值,变量variable为当前轮的变量值
apply()方法添加了训练变量的影子副本,并保持了其影子副本中训练变量的移动平均值操作。在每次训练之后调用此操作,更新移动平均值
average()和average_name()方法可以获取影子变量及其名称
import tensorflow as tf #定义一个变量用于计算滑动平均 v1 = tf.Variable( 0, dtype=tf.float32 ) #定义变量模拟神经网络中的迭代轮数,控制衰减率 step = tf.Variable( 0, trainable=False ) #定义一个滑动平均的类,给定初始衰减率和控制衰减率的变量 variable_averages = tf.train.ExponentialMovingAverage( 0.99, step ) #更新变量滑动平均的操作,每次执行这个操作就更新列表中的变量 variable_averages_op = variable_averages.apply( [v1] ) #创建会话 with tf.Session() as sess: #初始化所有变量 init = tf.initialize_all_variables() sess.run( init ) #1.首次滑动平均之后变量的更新值,0*0+0*0=0 print( sess.run( [v1, variable_averages.average(v1)] ) ) #2.更新变量v1的值为5 sess.run( tf.assign(v1, 5) ) #更新v1的滑动平均值0.1*0+0.9*5=0.45,衰减率为min{ 0.99,(1+step)/(10+step)=0.1 }=0.1 sess.run( variable_averages_op ) print( sess.run( [v1, variable_averages.average(v1)] ) ) #3.更新step的值为10000 v1的值为10 sess.run( tf.assign(step, 10000) ) sess.run( tf.assign(v1, 10) ) #更新v1的滑动平均值0.99*4.5+0.01*10, 衰减率为min{ 0.99, (1+10000)/(10+10000)=0.999 }=0.99 sess.run( variable_averages_op ) print( sess.run( [v1, variable_averages.average(v1)] ) ) #4.再次更新v1的滑动平均值0.99*4.555+0.01*10,衰减率为min{ 0.99, (1+10000)/(10+10000)=0.999 }=0.99 sess.run( variable_averages_op ) print( sess.run( [v1, variable_averages.average(v1)] ) )
参考资料:
1. 《TensorFlow实战Google深度学习框架》