模型训练方法
规定:
为需要更新的参数
#card=math&code=g%28w%29)为在参数为
时计算的梯度值
为上一次的更新值(的变化)
对于模型的训练,神经网络基本都采用了梯度下降,不同方法的区别在于对于梯度下降的优化,由于梯度下降中,参数更新主要是依赖两个量:学习率和梯度,所以现有方法都是对于学习率和梯度进行了改进和优化。
首先,梯度下降按照按此步长处理的样本批次不同,分为BGD、min-BGD、SGD。
对于学习率的改进,有一些是作为学习率设置,有一些是作为独特的一种优化方法,有:
- 学习率衰减。通常都是按迭代次数,包括分段常数衰减、逆时衰减、指数衰减、自然指数衰减、余弦衰减
- 学习率预热。指的在最初迭代时,先采用比较小的学习率,是梯度降到一定程度再恢复初始设定的学习率,提高训练稳定性。
- 学习率周期性调整。有循环学习率(固定周期,相邻周期内学习率分别线性增加和线性减少)和带热重启的随机梯度下降(每个周期内学率进行余弦衰减,下一周期时重新初始为预先设定的值,但比上一周期的初始值小)
- AdaGrad
- RMSprop
- AdaDelta
对于梯度的改进,有:
- Momentum
- Nesterov Accelerated Gradient
还有同时对学习率和梯度进行优化:
- Adam
- Nadam
SGD
最普遍的随机梯度下降,对于参数的更新规则如下:
%0A#card=math&code=w%20%3D%20w%20-%20%5Calpha%20g%28w%29%0A)
optimizer = keras.optimizers.SGD(learning_rate=0.1)
momentum
在普通的梯度下降上引入动量的概念,即在梯度值上加上一部分上一次的更新值,可以更好的避免局部极值。更新规则如下:
%0A#card=math&code=w%5Cprime%20%3D%20w%20%2B%20%5Crho%20%5CDelta%20%5C%5C%5C%5C%0Aw%20%3D%20w%5Cprime%20-%20%5Calpha%20g%28w%29%0A)
optimizer = keras.optimizers.SGD(learning_rate=0.1, momentum=True)
Nesterov Accelerated Gradient, NAG
对momentum的改进,一个小变种,将momentum看作两步参数更新操作,将第一步参数的梯度用作第二步的梯度计算。更新规则如下:
%0A#card=math&code=w%5Cprime%20%3D%20w%20%2B%20%5Crho%20%5CDelta%20%5C%5C%5C%5C%0Aw%20%3D%20w%5Cprime%20-%20%5Calpha%20g%28w%5Cprime%29%0A)
optimizer = keras.optimizers.SGD(learning_rate=0.1, momentum=True, nesterov=True)
AdaGrad
全称:Adaptive Gradient Algorithm,每次迭代时自适应调整参数的学习率,借鉴了L2正则化思想,为每个参数梯度平方的累计值。缺点是经过一定次数迭代学习率就会到很小了,如果没找到最优点,之后也很难再找到。
%0A#card=math&code=Gt%20%3D%20%5Csum%7B%5Ctau%3D1%7D%5Et%20g%5Ctau%20%5Codot%20g%5Ctau%5C%5C%5C%5C%0Aw%20%3D%20w%20-%20%5Cfrac%7B%5Calpha%7D%7B%5Csqrt%7BG_t%20%2B%20%5Cepsilon%7D%7D%20%5Codot%20g%28w%29%0A)
optimizer = keras.optimizers.Adagrad(learning_rate=0.001, initial_accuulator_value=0.1, epsilon=1e-7)
RMSprop
对AdaGrad的改进,对的计算进行改进,从累积变为指数衰减平移,计算的是每次梯度平方的指数衰减移动平均(指数衰减平移),
为衰减率,如果下式中
位置都取1,就和AdaGrad相同,
通常取0.9:
%20gt%20%5Codot%20g_t%5C%5C%5C%5C%5C%0Aw%20%3D%20w%20-%20%5Cfrac%7B%5Calpha%7D%7B%5Csqrt%7BG_t%20%2B%20%5Cepsilon%7D%7D%20%5Codot%20g(w)%0A#card=math&code=G_t%20%3D%20%5Cbeta%20G%7Bt-1%7D%20%2B%20%281-%5Cbeta%29%20g_t%20%5Codot%20g_t%5C%5C%5C%5C%5C%0Aw%20%3D%20w%20-%20%5Cfrac%7B%5Calpha%7D%7B%5Csqrt%7BG_t%20%2B%20%5Cepsilon%7D%7D%20%5Codot%20g%28w%29%0A)
optimizer = keras.optimizers.RMSprop(learning_rate=0.001, rho=0.9, momentum=0.0, epsilon=1e-7, centered=False)
Adadelta
也是对于AdaGrad的改进,相比于AdaGrad,另外引入了对于每次参数更新差值的指数衰减平移:
%5CDelta%7Bt-1%7D%5Codot%20%5CDelta%7Bt-1%7D%20%5C%5C%5C%5C%0Aw%20%3D%20w%20-%20%5Cfrac%7B%5Csqrt%7B%5Chat%5CDelta%7Bt-1%7D%5E2%2B%5Cepsilon%7D%7D%7B%5Csqrt%7BG_t%20%2B%20%5Cepsilon%7D%7D%20%5Codot%20g(w)%0A#card=math&code=G_t%20%3D%20%5Csum%7B%5Ctau%20%3D1%7D%5Et%20g%5Ctau%20%5Codot%20g%5Ctau%20%5C%5C%5C%5C%0A%5Chat%20%5CDelta%7Bt-1%7D%5E2%20%3D%20%5Cbeta_1%20%5Chat%5CDelta%7Bt-2%7D%5E2%20%2B%20%281-%5Cbeta1%29%5CDelta%7Bt-1%7D%5Codot%20%5CDelta%7Bt-1%7D%20%5C%5C%5C%5C%0Aw%20%3D%20w%20-%20%5Cfrac%7B%5Csqrt%7B%5Chat%5CDelta%7Bt-1%7D%5E2%2B%5Cepsilon%7D%7D%7B%5Csqrt%7BG_t%20%2B%20%5Cepsilon%7D%7D%20%5Codot%20g%28w%29%0A)
optimizer = keras.optimizers.Adadelta(learning_rate=0.001, rho=0.95, epsilon=1e-7)
Adam
本质上就是Momentum和RMSprop的结合。一方面计算梯度平方的指数衰减平移,另一方面计算梯度的指数衰减平移,并且对于指数衰减平均计算公式进行了修正(初始时会具有较大偏差):
g(w)%5C%5C%5C%5C%0AGt%20%3D%20%5Cbeta_2G%7Bt-1%7D%20%2B%20(1-%5Cbeta2)g(w)%5Codot%20g(w)%5C%5C%5C%5C%0A%5Chat%20M_t%20%3D%20%5Cfrac%7BM_t%7D%7B1-%5Cbeta_1%5Et%7D%5C%5C%5C%5C%0A%5Chat%20G_t%20%3D%20%5Cfrac%7BG_t%7D%7B1-%5Cbeta_2%5Et%7D%5C%5C%5C%5C%0Aw%20%3D%20w%20-%20%5Cfrac%7B%5Calpha%7D%7B%5Chat%20G_t%20%2B%20%5Cepsilon%7D%5Chat%20M_t%0A#card=math&code=M_t%20%3D%20%5Cbeta_1M%7Bt-1%7D%20%2B%20%281-%5Cbeta1%29g%28w%29%5C%5C%5C%5C%0AG_t%20%3D%20%5Cbeta_2G%7Bt-1%7D%20%2B%20%281-%5Cbeta_2%29g%28w%29%5Codot%20g%28w%29%5C%5C%5C%5C%0A%5Chat%20M_t%20%3D%20%5Cfrac%7BM_t%7D%7B1-%5Cbeta_1%5Et%7D%5C%5C%5C%5C%0A%5Chat%20G_t%20%3D%20%5Cfrac%7BG_t%7D%7B1-%5Cbeta_2%5Et%7D%5C%5C%5C%5C%0Aw%20%3D%20w%20-%20%5Cfrac%7B%5Calpha%7D%7B%5Chat%20G_t%20%2B%20%5Cepsilon%7D%5Chat%20M_t%0A)
optimizer = keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-7, amsgrad=False)
Nadam
在Adam中引入了Nsterov Accelerated Gradient。
optimizer = keras.optimizers.Nadam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-7)
Ftrl
用的比较少的一个优化算法,Google研究员提出的,在论文Ad Click Prediction: a View from the Trenches
,基本可知其应用场景。
optimizer = keras.optimizers.Ftrl(
learning_rate=0.001,
learning_rate_power=-0.5,
initial_accumulator_value=0.1,
l1_regularization_strength=0.0,
l2_regularization_strength=0.0,
name="Ftrl",
l2_shrinkage_regularization_strength=0.0,
beta=0.0)
模型初始化方法
在keras中,每个初始化方式有两种命名放心,实现和功能都相同,一种是类似Java中的单词首字母大写,另外一种是Python中的驼峰式,单词之间用单个下划线进行分割。
RandomNormal
通过正态分布进行产生。
tf.keras.initializers.RandomNormal(mean=0, stddev=1.)
tf.keras.initializers.random_normal(mean=0, stddev=1.)
TruncatedNormal,与RandomNormal的区别是,超过两个标准差的数据将被剔除重新生成:
tf.keras.initializers.TruncatedNormal(mean=0, stddev=1.)
tf.keras.initializers.truncated_normal(mean=0, stddev=1.)
RandomUniform
通过均匀分布进行产生
tf.keras.initializers.RandomUniform(minval=-0.05, maxval=0.05, seed=None)
tf.keras.initializers.random_uniform(minval=-0.05, maxval=0.05, seed=None)
Zeros
全0初始化,最简单直接的操作了,基本只用在bias
上
tf.keras.initializers.Zeros()
tf.keras.initializers.zeros()
Ones
说到Zeros,就不得不说另一种很直接的方式,初始值都置为1:
tf.keras.initializers.Ones()
tf.keras.initializers.ones()
Constanct
指定一常数作为初始化参数的所有值
tf.keras.initializers.Constant(value=0)
tf.keras.initializers.constant(value=0)
GlorotNormal
也叫Xavier normal,具体实现是:
采用截断式的正态分布(TruncatedNormal),均值为0,标准差为%7D#card=math&code=%5Csqrt%7B2%2F%28fan%7Bin%7D%2Bfan%7Bout%7D%29%7D),其中
分别是权重参数中的输入单元个数和输出单元个数
tf.keras.initializers.GlorotNormal()
tf.keras.initializers.glorot_normal()
GlorotUniform
也叫Xavier uniform,具体实现是:
采用均匀分布,上下界区间范围是,其中
%7D#card=math&code=limit%20%3D%20%5Csqrt%7B6%2F%28fan%7Bin%7D%20%2B%20fan%7Bout%7D%29%7D)
tf.keras.initializers.GlorotUniform()
tf.keras.initializers.glorot_uniform()
HeNormal
He相对于Glorot,只是去掉了,使得参数只与输入层有关,与输出层无关。具体实现是:
采用截断式的正态分布(TruncatedNormal),均值为0,标准差为,其中分别是权重参数中的输入单元个数和输出单元个数
tf.keras.initializers.HeNormal()
tf.keras.initializers.he_normal()
HeUniform
具体实现是:
采用均匀分布,上下界区间范围是,其中
tf.keras.initializers.GlorotUniform()
tf.keras.initializers.glorot_uniform()
LecunNormal
Lecun和He,差别只在常系数值。具体实现是:
采用截断式的正态分布(TruncatedNormal),均值为0,标准差为,其中分别是权重参数中的输入单元个数和输出单元个数
tf.keras.initializers.LecunNormal()
tf.keras.initializers.lecun_normal()
LecunUniform
具体实现是:
采用均匀分布,上下界区间范围是,其中
tf.keras.initializers.LecunNormal()
tf.keras.initializers.lecun_normal()
VarianceScaling
综合Glorot、He、Lecun等几大初始化方式,给了一个更加方便的调节方式。
如果是正态分布(Truncated或Unruncated),均值仍然为0,方差为;如果是均匀分布,上下界绝对值相同,绝对值是
,其中参数通过API进行调节。keras中,Glorot、He、Lecun的几个初始化方式都是以VarianceScaling为父类实现的。
'''
scale: 缩放值
mode: fan_in, fan_out, fan_avg,分别是输入层值、输出层值、输入输出层值的均值
distribution: 选择的分布,可选值为:truncated_normal, untruncated_normal, uniform
'''
tf.keras.initializers.VarianceScaling(
scale=0.1, mode='fan_in', distribution='uniform')
tf.keras.initializers.variance_scaling(
scale=0.1, mode='fan_in', distribution='uniform')
Identity
将权重参数初始化为单位矩阵,由于形状不是方阵,只是使主对角线上元素为1(最小维度值构成的方阵为单位矩阵)
tf.keras.initializers.Identity()
tf.keras.initializers.identity()
Orthogonal
将权重参数初始化为正交矩阵,其中维数上的一侧正交(例如,如果行数少于列数,那么输出矩阵中行是正交的)
tf.keras.initializers.Orthogonal(gain=1.0, seed=None)
tf.keras.initializers.orthogonal(gain=1.0, seed=None)