BLOG

个人博客,记录学习与生活

模型训练方法和参数初始化方法

Published Dec. 9, 2020, 6:01 p.m. by kkk

模型训练方法

规定:

  • $w$为需要更新的参数
  • $g(w)$为在参数为$w$时计算的梯度值
  • $\Delta$为上一次的更新值(的变化)

对于模型的训练,神经网络基本都采用了梯度下降,不同方法的区别在于对于梯度下降的优化,由于梯度下降中,参数更新主要是依赖两个量:学习率和梯度,所以现有方法都是对于学习率和梯度进行了改进和优化。

首先,梯度下降按照按此步长处理的样本批次不同,分为BGD、min-BGD、SGD

对于学习率的改进,有一些是作为学习率设置,有一些是作为独特的一种优化方法,有:

  • 学习率衰减。通常都是按迭代次数,包括分段常数衰减、逆时衰减、指数衰减、自然指数衰减、余弦衰减
  • 学习率预热。指的在最初迭代时,先采用比较小的学习率,是梯度降到一定程度再恢复初始设定的学习率,提高训练稳定性。
  • 学习率周期性调整。有循环学习率(固定周期,相邻周期内学习率分别线性增加和线性减少)和带热重启的随机梯度下降(每个周期内学率进行余弦衰减,下一周期时重新初始为预先设定的值,但比上一周期的初始值小)
  • AdaGrad
  • RMSprop
  • AdaDelta

对于梯度的改进,有:

  • Momentum
  • Nesterov Accelerated Gradient

还有同时对学习率和梯度进行优化

  • Adam
  • Nadam

SGD

最普遍的随机梯度下降,对于参数的更新规则如下: $$ w = w - \alpha g(w) $$

optimizer = keras.optimizers.SGD(learning_rate=0.1)

momentum

在普通的梯度下降上引入动量的概念,即在梯度值上加上一部分上一次的更新值,可以更好的避免局部极值。更新规则如下: $$ w\prime = w + \rho \Delta \\ w = w\prime - \alpha g(w) $$

optimizer = keras.optimizers.SGD(learning_rate=0.1, momentum=True)

Nesterov Accelerated Gradient, NAG

对momentum的改进,一个小变种,将momentum看作两步参数更新操作,将第一步参数的梯度用作第二步的梯度计算。更新规则如下:

$$ w\prime = w + \rho \Delta \\ w = w\prime - \alpha g(w\prime) $$

optimizer = keras.optimizers.SGD(learning_rate=0.1, momentum=True, nesterov=True)

AdaGrad

全称:Adaptive Gradient Algorithm,每次迭代时自适应调整参数的学习率,借鉴了L2正则化思想,$G_t$为每个参数梯度平方的累计值。缺点是经过一定次数迭代学习率就会到很小了,如果没找到最优点,之后也很难再找到。 $$ G_t = \sum_{\tau=1}^t g_\tau \odot g_\tau\\ w = w - \frac{\alpha}{\sqrt{G_t + \epsilon}} \odot g(w) $$

optimizer = keras.optimizers.Adagrad(learning_rate=0.001, initial_accuulator_value=0.1, epsilon=1e-7)

RMSprop

对AdaGrad的改进,对$G_t$的计算进行改进,从累积变为指数衰减平移,计算的是每次梯度平方的指数衰减移动平均(指数衰减平移),$\beta$为衰减率,如果下式中$\beta, 1-\beta$位置都取1,就和AdaGrad相同,$\beta$通常取0.9: $$ G_t = \beta G_{t-1} + (1-\beta) g_t \odot g_t\\\ w = w - \frac{\alpha}{\sqrt{G_t + \epsilon}} \odot g(w) $$

optimizer = keras.optimizers.RMSprop(learning_rate=0.001, rho=0.9, momentum=0.0, epsilon=1e-7, centered=False)

Adadelta

也是对于AdaGrad的改进,相比于AdaGrad,另外引入了对于每次参数更新差值$\Delta$的指数衰减平移: $$ G_t = \sum_{\tau =1}^t g_\tau \odot g_\tau \\ \hat \Delta_{t-1}^2 = \beta_1 \hat\Delta_{t-2}^2 + (1-\beta_1)\Delta_{t-1}\odot \Delta_{t-1} \\ w = w - \frac{\sqrt{\hat\Delta_{t-1}^2+\epsilon}}{\sqrt{G_t + \epsilon}} \odot g(w) $$

optimizer = keras.optimizers.Adadelta(learning_rate=0.001, rho=0.95, epsilon=1e-7)

Adam

本质上就是Momentum和RMSprop的结合。一方面计算梯度平方的指数衰减平移,另一方面计算梯度的指数衰减平移,并且对于指数衰减平均计算公式进行了修正(初始时会具有较大偏差): $$ M_t = \beta_1M_{t-1} + (1-\beta_1)g(w)\\ G_t = \beta_2G_{t-1} + (1-\beta_2)g(w)\odot g(w)\\ \hat M_t = \frac{M_t}{1-\beta_1^t}\\ \hat G_t = \frac{G_t}{1-\beta_2^t}\\ w = w - \frac{\alpha}{\hat G_t + \epsilon}\hat M_t $$

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,标准差为$\sqrt{2/(fan_{in}+fan_{out})}$,其中$fan_{in}, fan_{out}$分别是权重参数中的输入单元个数和输出单元个数

tf.keras.initializers.GlorotNormal()
tf.keras.initializers.glorot_normal()

GlorotUniform

也叫Xavier uniform,具体实现是:

采用均匀分布,上下界区间范围是$[-limit, limit]$,其中$limit = \sqrt{6/(fan_{in} + fan_{out})}$

tf.keras.initializers.GlorotUniform()
tf.keras.initializers.glorot_uniform()

HeNormal

He相对于Glorot,只是去掉了$fan_{out}$,使得参数只与输入层有关,与输出层无关。具体实现是:

采用截断式的正态分布(TruncatedNormal),均值为0,标准差为$\sqrt{2/fan_{in}}$,其中分别是权重参数中的输入单元个数和输出单元个数

tf.keras.initializers.HeNormal()
tf.keras.initializers.he_normal()

HeUniform

具体实现是:

采用均匀分布,上下界区间范围是$[-limit, limit]$,其中$limit = \sqrt{6/fan_{in}}$

tf.keras.initializers.GlorotUniform()
tf.keras.initializers.glorot_uniform()

LecunNormal

Lecun和He,差别只在常系数值。具体实现是:

采用截断式的正态分布(TruncatedNormal),均值为0,标准差为$\sqrt{1/fan_{in}}$,其中分别是权重参数中的输入单元个数和输出单元个数

tf.keras.initializers.LecunNormal()
tf.keras.initializers.lecun_normal()

LecunUniform

具体实现是:

采用均匀分布,上下界区间范围是$[-limit, limit]$,其中$limit = \sqrt{3/fan_{in}}$

tf.keras.initializers.LecunNormal()
tf.keras.initializers.lecun_normal()

VarianceScaling

综合Glorot、He、Lecun等几大初始化方式,给了一个更加方便的调节方式。

如果是正态分布(Truncated或Unruncated),均值仍然为0,方差为$\sqrt{scale/n}$;如果是均匀分布,上下界绝对值相同,绝对值是$\sqrt{3*scale/n}$,其中参数通过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)

Share this post
< Pre: 机器学习激活函数
1249 comments
Similar posts
Add a new comment