神经网络优化的方法

一、概述

神经网络训练好之后,只有通过优化才能达到我们想要的效果,也就是我们说的调参,使参数更加准确的更新。
神经网络训练过程一般为两个阶段:

  • 第一个阶段先通过前向传播算法计算得到预测值,并将预测值与真实值作比较,得出两者之间的差距。
  • 第二个阶段通过反向传播算法计算损失函数对每一个参数的梯度,再根据梯度和学习率使用梯度下降算法更新每一个参数。

二、优化网络的方法

1、学习率的优化

每一个参数对目标函数的依赖不同,有的参数已经优化到了极小值附近,有的参数仍然有很大的梯度,所以不能使用统一学习率,学习率太小,会有一个很慢的收敛速度,学习率很大,会使已经优化的差不多的参数不稳定,一般合理的做法是对每一个参数设置不同的学习率。有三种不同自适应学习率优化算法

  • AdaGrad
    AdaGrad算法,独立地适应所有模型参数的学习率,缩放每个参数反比于其所有梯度历史平均值总和的平方根。具有代价函数最大梯度的参数相应地有个快速下降的学习率,而具有小梯度的参数在学习率上有相对较小的下降。
  • RMSProp
    RMSProp算法修改了AdaGrad的梯度积累为指数加权的移动平均,使得其在非凸设定下效果更好。
  • Adam

学习率的独立设置
指数衰减的学习率
指数衰减学习率是先使用较大的学习率来快速得到一个较优的解,然后随着迭代的继续,逐步减小学习率,使得模型在训练后期更加稳定。

tf.train.exponential_decay(learning_rate,global_step,decay_steps,decay_rate,staircase=False,name=None)

参数

初始学习率learning_rate
衰减系数decay_rate
decay_steps控制衰减速度
global_steps当前训练的轮数
staircase:布尔值。如果True,decay_steps代表了迭代多少轮后再更新学习率参数,最终学习函数会成为一个阶梯函数

2、梯度下降的优化

https://blog.csdn.net/itchosen/article/details/77200322
总体思想:
梯度下降是指沿着损失函数的下坡方向(导数增大的反方向)迭代更新参数的方法称为梯度下降法,目的是为了寻找一个参数,使得损失函数值最小。还需要定义一个学习率,是指每次参数移动的幅度,梯度下降法并不能保证被优化的非凸函数达到全局最优点,因为梯度下降最后的结果收到参数初始值的影响,或者只有当损失函数为凸函数时可以达到全局最优点。梯度下降分为以下三个,主要区别在于选取样本的数量

  • 批量梯度下降法(Batch Gradient Descent)

在更新参数时使用所有的样本来进行更新

  • 随机梯度下降法(Stochastic Gradient Descent)

随机梯度下降法,其实和批量梯度下降法原理类似,区别在与求梯度时没有用所有样本的数据,而是仅仅选取一个样本来求梯度

  • 小批量梯度下降法(Mini-batch Gradient Descent)

小批量梯度下降法是批量梯度下降法和随机梯度下降法的折衷,选取一部分样本来更新梯度

随机梯度下降法和批量梯度下降法对比

  • 对于训练速度来说,随机梯度下降法由于每次仅仅采用一个样本来迭代,训练速度很快,而批量梯度下降法在样本量很大的时候,训练速度不能让人满意。
  • 对于准确度来说,随机梯度下降法用于仅仅用一个样本决定梯度方向,导致解很有可能不是最优。SGD通常训练时间更长,但是在好的初始化和学习率调度方案的情况下,结果更可靠。
  • 对于收敛速度来说,由于随机梯度下降法一次迭代一个样本,导致迭代方向变化很大,不能很快的收敛到局部最优解。SGD容易收敛到局部最优,并且在某些情况下可能被困在鞍点(不是最小点也不是最大点)

在使用梯度下降时,进行调优的要点

  1. 算法的学习率选择。在前面的算法描述中,我提到取学习率为1,但是实际上取值取决于数据样本,可以多取一些值,从大到小,分别运行算法,看看迭代效果,如果损失函数在变小,说明取值有效,否则要增大学习率。前面说了。学习率太大,会导致迭代过快,甚至有可能错过最优解。学习率太小,迭代速度太慢,很长时间算法都不能结束。所以算法的学习率需要多次运行后才能得到一个较为优的值。

  2. 算法参数的初始值选择。 初始值不同,获得的最小值也有可能不同,因此梯度下降求得的只是局部最小值;当然如果损失函数是凸函数则一定是最优解。由于有局部最优解的风险,需要多次用不同初始值运行算法,关键损失函数的最小值,选择损失函数最小化的初值。

  3. 归一化。由于样本不同特征的取值范围不一样,可能导致迭代很慢,为了减少特征取值的影响,可以对特征数据归一化,这样特征的新期望为0,新方差为1,迭代次数可以大大加快。

一般tensorflow使用优化器来完成梯度下降和自适应学习率,learning_rate学习率,loss损失函数。详见网页1网页2介绍

train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
##梯度下降,使用全部样本更新参数

train_step = tf.train.AdagradOptimizer(learning_rate).minimize(loss)
##实现Adagrad优化器

train_step = tf.train.RMSPropOptimizer(learning_rate)).minimize(loss)
 ##实现RMSProp优化器
 
 train_step = tf.train.AdamOptimizer(learning_rate)).minimize(loss)
 ##实现Adam优化器

3、欠拟合和过拟合的优化

一般有三种方法,详见欠拟合过拟合优化方法1欠拟合过拟合优化方法2

  • Dropout
    为了防止神经网络的过拟合。它的主要思想是让隐藏层的节点在每次迭代时(包括正向和反向传播)有一定几率(keep-prob)失效,这样来预防过拟合。它主要避免对某个节点的强依赖,让反向传播的修正值可以更加平衡的分布到各个参数上
    (1)Dropout只发生在模型的训练阶段,预测、测试阶段则不用Dropout
    (2)Dropout随机删除神经元后,网络变得更小,训练阶段也会提速
    (3)有了dropout,网络不会为任何一个特征加上很高的权重(因为那个特征的输入神经元有可能被随机删除),最终dropout产生了收缩权重平方范数的效果
    (4)Dropout的一大缺点就是损失函数不再被明确定义,所以在训练过程中,损失函数的值并不是单调递减的
    (5)使用时,先关闭Dropout,设置keep-prob为1,使损失函数的值单调递减,然后再打开Dropout

  • Bagging 详见集成学习介绍

  • 正则化方法
    (1)L1正则化
    (2)L2正则化

     #在权重参数上实现L2正则化
     regularizer = tf.contrib.layers.l2_regularizer(0.01)
     regularization = regularizer(weight1)+regularizer(weight2)+regularizer(weight3)
     tf.add_to_collection("losses",regularization)     #加入集合的操作
     
     #get_collection()函数获取指定集合中的所有个体,这里是获取所有损失值
     #并在add_n()函数中进行加和运算
     loss = tf.add_n(tf.get_collection("losses"))#损失包括误差和正则项
     tf.add_to_collection("losses", error_loss)      #加入集合的操作
    
  • 数据和特征方面

1)重新清洗数据,导致过拟合的一个原因也有可能是数据不纯导致的,如果出现了过拟合就需要我们重新清洗数据。

2)增大数据的训练量,还有一个原因就是我们用于训练的数据量太小导致的,训练数据占总数据的比例过小。

3)对于欠拟合,需要添加其他特征项,有时候我们模型出现欠拟合的时候是因为特征项不够导致的,可以添加其他特征项来很好地解决。例如,“组合”、“泛化”、“相关性”三类特征是特征添加的重要手段。添加多项式特征,例如将线性模型通过添加二次项或者三次项使模型泛化能力更强。对于过拟合,需要删掉特征
4)欠拟合也可以降低正则化约束,过拟合也可以增加正则化约束

猜你喜欢

转载自blog.csdn.net/qq_39751437/article/details/88541337