一、设置学习率
通过指数衰减的方法设置梯度下降算法中的学习率。既可以让模型在训练的前期快速接近较优解,又可以模型在后期波动不大。
1.实现功能
随着迭代轮数增加一次,学习率降低一次。
decayed_learning_rate = learning_rate * decay_rate ^ (global_step / decay_steps)
'''
decayed_learning_rate表示每轮迭代所使用的学习率,
learning_rate为初始学习率,
decay_rate为衰减系数,
decay_steps通常为完整使用一遍训练数据所需要的迭代轮数:即:总数/batch_size。
'''
2.用tensorflow实现
learning_rate = tf.train.exponential_decay(learning_rate, global_step, decay_step, decay_rate, staircase=False, name=None)
'''
learning_rate: 当前的学习速率
global_step:当前的学习步数,等同于我们将 batch 放入学习器的次数
decay_steps:每轮学习的步数,decay_steps = sample_size/batch 即样本总数除以每个batch的大小
decay_rate:表示衰减的比率,即下一次学习率=当前学习率×衰减比率。
staircase:Boolean类型,默认是False表示衰减的学习率是连续的,如果是True代表衰减的学习率是一个离散的间隔。
返回值:一个标量类型的学习率。
'''
3.演示代码
import tensorflow as tf
from numpy.random import RandomState
if __name__ == "__main__":
#设置每次跌打数据的大小
batch_size = 8
#定义输入节点
x = tf.placeholder(tf.float32,shape=(None,1),name="x_input")
#定义预测值的输出节点
y_ = tf.placeholder(tf.float32,shape=(None,1),name="y_output")
#定义参数变量
w = tf.Variable(50.,trainable=True)
# 定义神经网络的传播过程
y = x * w
#定义损失函数
loss = tf.reduce_sum(tf.square(y-y_))
#定义global_step
global_step = tf.Variable(0,trainable=False)
#通过指数衰减函数来生成学习率
learing_rate = tf.train.exponential_decay(0.1,global_step,100,0.96,staircase=False)
'''调用'''#使用梯度下降算法来最优化损失值
learing_step = tf.train.GradientDescentOptimizer(learing_rate).minimize(loss,global_step)
#随机产生一个数据集
rdm = RandomState(1)
#设置数据集的大小
dataset_size = 200
#产生输入数据
X = rdm.rand(dataset_size,1)
#定义真实的输出数据Y,
Y = [x1 + rdm.rand()/5.0 - 0.05 for x1 in X]
#训练模型
with tf.Session() as sess:
#初始化所有的参数
all_init = tf.initialize_all_variables()
sess.run(all_init)
#设置迭代次数
STEPS = 5000
for i in range(STEPS):
start = (i * batch_size) % batch_size
end = min(start+batch_size,dataset_size)
#训练模型
sess.run(fetches=learing_step,feed_dict={x:X[start:end],y_:Y[start:end]})
#没迭代100次输出一次参数值
if i % 100 == 0:
print("w:%f,learing_rate:%f"%(w.eval(session=sess),learing_rate.eval(session=sess)))
二、过拟合问题
1.基本思想
正则化:通过限制权重的大小,使得模型不能任意拟合训练数据中的随机噪音。
(1)L1正则化
(2)L2正则化
2.用tensorflow实现L2正则化
w = tf.Variable(tf.random_normal([2, 1], stddev=1, seed=1))
y = tf.matmul(x, w)
loss = tf.reduce_mean(tf.square(y_ - y))+
tf.contrib.layers.l2_regularizer(lambda)(w)
'''
第一部分 均方误差损失函数
第二部分 正则化:防止模型过度模拟噪声数据
lambda 正则化项权重 即上述中的λ。
w 为需要计算正则化损失的参数
'''
计算方法
3.演示代码
regularizer = tf.contrib.layers.l2_regularizer(REGULARIZATION_RATE)
regularization = regularizer(weights1) + regularizer(weights2)
loss = cross_entropy_mean + regularization
learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE, global_step, mnist.train.num_examples / BATCH_SIZE,LEARNING_RATE_DECAY)
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
三、滑动平均模型
1.功能
增加模型健壮性:在采用梯度下降算法训练神经网络时,使用滑动平均模型在很多应用中都可以在一定程度上提高最终模型在测试数据上的表现。其实就是更好的训练出来参数。
2.用tensorflow实现功能
tf.train.ExponentialMovingAverage(decay, num_updates=None, zero_debias=False,name="ExponentialMovingAverage")
'''
decay:实数类型,衰减率。
num_updates:可选,设置这个参数之后,将会通过min(decay, (1 + num_updates) / (10 + num_updates))函数,从中选择最小值做为衰减率。
返回值:ExponentialMovingAverage对象,通过对象调用apply()方法可以通过滑动平均模型来更新参数。
'''
计算公式:shadow_variable = decay * shadow_variable + (1-decay) * variable
计算公式中的第一个shadow_variable为平滑后的变量,第二个shadow_variable为影子变量,也就是变量未更新的值,variable是变量现在的值
3.演示代码
import tensorflow as tf
#定义一个变量用于计算滑动平均,初值为0
test1 = tf.Variable(0,dtype=tf.float32)
#模拟神经网络迭代轮数,动态控制衰减率min(decay, (1 + num_updates) / (10 + num_updates))
num_updates = tf.Variable(0,dtype=tf.float32)
#定义衰减率
DECAY = 0.99
#滑动平均操作
Moving_average = tf.train.ExponentialMovingAverage(DECAY,num_updates)
#更新test1
Moving_average_op = Moving_average.apply([test1])
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
#第一次打印出初始值,滑动平均值,输出值应该为[0,0]
print(sess.run([test1,Moving_average.average(test1)]))
#更新test1
sess.run(tf.assign(test1,3))
sess.run(Moving_average_op)
#第二次打印初始值,滑动平均值,输出值应该为[3,0],滑动平均值计算0*0.1+0.9*3=2.7
print(sess.run([test1,Moving_average.average(test1)]))
#更新test2与num_updates
sess.run(tf.assign(test1,5))
sess.run(tf.assign(num_updates,90))
sess.run(Moving_average_op)
#第三次打印初始值,滑动平均值,输出值应该为[3,0],滑动平均值计算2.7*0.91+5*0.09
print(sess.run([test1,Moving_average.average(test1)]))