神经网络的优化
1. 模型优化
在入门篇里面,神经网络模型仅仅是 ,也就是 ,现在可以在其之后加上常数项 ,同时再加上激活函数 ,构成 :
常见的激活函数 有,
-
,tensorflow表示为
tf.nn.relu()
-
,tensorflow表示为
tf.nn.sigmoid()
-
,tensorflow表示为
tf.nn.tanh()
2. loss优化
loss函数,也就是损失函数,用来表示真实值 y_
与预测值 y
的差距,也就是训练目标,使得loss越小越好
在入门篇中,损失函数采用的是均方误差法,实际开发中,常用的损失函数有:
- 均方误差:
,
tensorflow表示为tf.reduce_mean(tf.square(y_-y))
- 自定义:根据自身需求,自己定义损失函数,
例如:tf.reduce_sum( tf.where( tf.greater(y,y_), 2*(y-y_), 5*(y_-y) ) )
- 交叉熵:交叉熵表示了二分类问题中两概率分布之间的距离,值越小,距离越近。
,
tensorflow表示为:tf.reduce_mean( y_*tf.log( tf.clip_by_value(y, 1e-12, 1.0) ) )
,其中tf.clip_by_value(y, 1e-12, 1.0) )
保证了y的值在合法范围之内- softmax 函数:在n分类中,为了使n中情况的概率和为1,才能使用交叉熵法。
- 一般代码中直接将softmax和交叉熵合为一句:
tf.reduce_mean( tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=tf.argmax(y_,1)) )
3. 学习率
学习率表示每次参加更新的幅度大小,学习率过大会导致待优化的参数出现震荡不收敛的情况,学习率过小学习速度慢。通俗点讲就是参数值不会一直慢慢往0减小,一下子减太过了。
在入门篇中,我们的学习率设置的为定值0.001。在实际应用中,这种设置为定值肯定是不够好的,往往我们采用指数衰减学习率,也就是随着训练的次数增加,慢慢将学习率自动降低。
数学表达:
更新频率一般设置为 总样本数 / 每次喂入的样本数
也就是一般为跑一遍样本需要的轮数。
代码表示:
当前训练轮数global_step = tf.Variable(0,trainavle=False)
learing_rate = tf.train.exponential_decay(
学习率初始值,
当前训练轮数global_step,
更新频率(多少轮更新一次),
衰减率,
staircase=True/False # 设置是否平滑曲线下降,不然仅当指数部分取整才更新一次
)
4. 滑动平均
滑动平均值称为影子,记录了一段时间内模型中所有参数w和b各自的平均值,这样下次取出模型进行测试的时候可以用平均值代替w和b了,是的模型有更好的泛化能力。
用tensorflow表示为:
ema = tf.train.ExponentialMovingAverage(滑动平均衰减率,当前训练轮数global_step)
ema_op = ema.apply(tf.trainable_variables())
# 下面方法可实现滑动平均与训练过程同步运行
with tf.control_dependencies([train_step, ema_op]):
train_op = tf.no_op(name='train')
5. 正则化解决过拟合问题
过拟合:指训练过度,模型在训练集上的准确率很高,一旦出现新的测试数据,准确率就低了。
正则化:为每个参数w加上权重,引入模型复杂度指标,从而抑制模型噪声,达到减少过拟合的现象。
添加正则化之后,损失函数loss就需要再加一项REGULARIZER*loss(w)
正则化计算方法有两种:
- L1正则化:
- L2正则化:
tensorflow表示分别为:
loss(w) = tf.contrib.layers.l1_regularizer(REGULARIZER)(w)
loss(w) = tf.contrib.layers.l2_regularizer(REGULARIZER)(w)
在tensorflow中的使用:
tf.add_to_collection('losses',loss(w))
loss = 之前的损失函数 + tf.add_n(tf.get_collection('losses'))