关于训练

参数和超参数

回顾有监督学习:

给定训练数据{(xi,yi),i=1,,n}i.i.d.\{(x_i,y_i),i=1,\cdots,n\}\quad \mathrm{i.i.d.}来自同一分布DD

找到y=f(x)Hy=f(x)\in \mathscr{H}

s.t.f\mathrm{s.t.}\quad f能在测试集(i.i.d.\mathrm{i.i.d.}来自同一分布DD)上表现良好

需要通过损失函数(loss function):
L(f)=E(x,y)D[l(f,x,y)] L(f)=\mathbb{E}_{(x,y)\sim D}[l(f,x,y)]
来衡量模型的数据处理能力。即衡量ff是否在测试集上表现良好。这就需要找到一个y=f(x)Hy=f(x)\in \mathscr{H},最小化loss值:
L^(f)=1ni=1nl(f,xi,yi) \hat{L}(f)=\dfrac1n\sum_{i=1}^nl(f,x_i,y_i)
训练完成后得到的loss值并不一定尽如人意:

  1. 有可能ff在训练集上表现良好,但在测试集上表现较差。
  2. 甚至ff在训练集上表现也较差。

对于第一种情况,可能是模型过拟合了,需要调整参数,或者进行正则化;第二种情况则可能是欠拟合,此时可能不仅需要调参,甚至需要重新设计网络。

如果出现欠拟合的问题,可能遇到的问题是large bias,即偏差较大。可能是参数没有训练好,也有可能是模型本身不够强。此时的解决方案为:

  1. 在输入中增加更多的特征(比如区分男女性,可以不仅仅靠身高的高矮来判断,还可以同时考虑头发长度、穿衣打扮等)
  2. 使用更复杂的、表达能力更强的模型

如果出现过拟合的问题,可能遇到的问题是large variance,即方差较大。此时泛化能力弱,模型可能学出了训练集上的噪声。此时的解决方案:

  1. 增加训练集的数据量。(这个方法虽然很有效,但并不总是实用。比如有些病灶图像,由于疾病罕见,能获得的图像本就很少,因此难以通过收集增加数据量,此时可以考虑图像增强,人为增加数据量。)
  2. 正则化,但可能增加bias的误差。

当模型简单的时候,bias会比较大,而variance较小;反之模型复杂的时候,bias会比较小,而variance较大。

参数和超参数

(Model Design + Hyperparameters) -> Model Parameters

模型设计包括:层数、**函数、优化等

超参数包括:学习率、Dropout等

参数包括:权重、偏置等

实际训练过程中:选择超参数;训练模型;评估性能;改进超参数,构成了一个循环,直到模型能满足要求,循环结束。

设置数据

将所有的数据都作为训练集来训练模型,这种做法是欠妥的,因为这样得到的模型势必会出现过拟合的问题。如果将一部分数据作为测试集,剩下的数据作为训练集,这种做法依然会出现模型过拟合的问题。

更好的做法是,将数据分成训练集、评估(validation)集和测试集三部分。平估集用来确定超参数。常用的划分比例为6:2:26:2:2或者7:2:17:2:1

对于上述方法,如果数据集本身较小,那么60%60\%的数据也不够用于模型训练,此时考虑第四种方法,即交叉检验(Cross-Validation):将训练数据集分成若干个folds,每次选取一个fold作为评估集,来选取超参数,剩下的作为训练集。如下图所示:

人工智能导论复习整理(五)

最后,将得到的结果平均起来就是最终的模型。这种方法尤其适合小数据集。

梯度下降法

当我们为一个具体的问题设计了一个模型以及评估策略后,所有的机器学习问题都可以形式化为一个最优化问题。优化问题中只有少部分问题可以得到解析解(如通过最小二乘法得到一个真实的解),很大一部分问题只能通过迭代的方式求解,其中最常用的就是梯度下降法和牛顿法。神经网络优化算法,大体都是使用了梯度下降法的框架。

梯度的概念建立在偏导数与方向导数之上。方向导数反映了函数沿某一个方向上的变化率,而梯度就是函数变化最快的那个方向。

以二维平面为例,假设有一函数f(x)f(x),如果它的导数f(x)>0f'(x)>0,那么f(x)f(x)单调递增,即减小xx的值就能减小f(x)f(x)的值,反之亦然。所以,将xx向导数相反的方向移动,就能减小f(x)f(x)。这就是梯度下降

在机器学习中,我们的目标是优化参数,也就是找到使得loss function取值最小的那些参数值。要找到这样的值可以通过迭代的方式实现。

以一个参数ww为例,要求w=argminwL(w)w^*=arg\min \limits_{w} L(w)。首先要随机给定一个初始值w0w^0,一般取在(0,1)(0,1)之间。然后计算dLdww=w0\dfrac{\mathbb{d}L}{\mathbb{d}w}|_{w=w^0},随后就能得到w1,w1w0ηdLdww=w0w^1,\quad w^1\leftarrow w^0-\eta\dfrac{\mathbb{d}L}{\mathbb{d}w}|_{w=w^0} ,其中η\eta是学习率。因为参数移动的方向是梯度的反方向,所以前面的式子中用的是减号。

如果有两个参数w,bw,b,问题就变成了求得wb=argminw,bL(w,b)w^*,b^*=arg\min \limits_{w,b} L(w,b)。解决方法和之前相同,只不过原先求的是导数,现在求的是偏导数。首先要随机给定一个初始值w0b0w^0,b^0,一般取在(0,1)(0,1)之间。然后计算Lww=w0,b=b0,Lbw=w0,b=b0\dfrac{\partial L}{\partial w}|_{w=w^0,b=b^0},\dfrac{\partial L}{\partial b}|_{w=w^0,b=b^0},随后就能得到w1,b1,w1w0ηLww=w0,b=b0,b1b0ηLbw=w0,b=b0w^1,b^1,\quad w^1\leftarrow w^0-\eta\dfrac{\partial L}{\partial w}|_{w=w^0,b=b^0},b^1\leftarrow b^0-\eta\dfrac{\partial L}{\partial b}|_{w=w^0,b=b^0} 。用L=[LwLb]\nabla L = \begin{bmatrix}\dfrac{\partial L}{\partial w}\\\dfrac{\partial L}{\partial b}\end{bmatrix}表示梯度向量。直到L(θt)0θ\nabla L(\theta^t)\approx0,\quad \theta为参数,停止计算。

由于上述过程计算过于复杂,为简化计算,采用随机梯度下降(Stochastic Gradient Descent)

随机梯度下降:随机选取一个样本XnX_n,计算这个样本的loss值,来更新当前的参数。这样使得更新速度变快,但是更新可能存在随机化,即不够稳定。

而梯度下降要计算完所有的样本之后才计算一个loss值,再更新参数,速度太慢了。

Mini-batch SGD

将训练样本划分成若干个batches,每一个batches都称为一个Mini-batch。一个Mini-batch里会有若干个训练样本。每个batch内计算一遍所有样本的loss值,计算完后进行一次更新;所有的Mini-batches对权重更新完后,再进行一次迭代,直到收敛。

这里的超参数包括Mini-batch size,如何减小学习率,迭代何时停止。

假设一共有2000020000个样本,每个Mini-batch里有100100个样本,那就一共有200200个Mini-batch。当参数更新完200200次后,这就成为一个epoch。一次epoch要将每一个样本都用完,一个epoch之后会紧接着运行下一个epoch。

当Mini-batch size=1时,就变成随机梯度下降了。

Mini-batch SGD的速度不会比随机梯度下降慢太多,同时更稳定;且batch增加了随机性,使得模型更容易跳出局部最优。

调参的过程中,会遇到的问题,比如局部最优、鞍点、平台等。为了解决这一问题,参考物理问题,在梯度下降中加入冲量(Momentum)

人工智能导论复习整理(五)

此时,在原先Lw\dfrac{\partial L}{\partial w}的基础上加上Momentum\text{Momentum},即Lw+Momentum\dfrac{\partial L}{\partial w}+\text{Momentum}

此时计算如下:

假设起点是θ0\theta^0,冲量是v0=0v^0=0,计算θ0\theta^0处的梯度,以及移动后的冲量v1=λv0ηL(θ0)v^1=\lambda v^0-\eta\nabla L(\theta^0)。于是运动到θ1=θ0+v1\theta^1=\theta^0+v^1处。然后计算计算θ1\theta^1处的梯度,以及移动后的冲量v2v^2。一直到L(θt)0\nabla L(\theta^t)\approx0为参数,停止计算。

观察发现:
v0=0v1=ηL(θ0)v2=ληL(θ0)ηL(θ1) v^0=0\\ v^1=-\eta\nabla L(\theta^0)\\ v^2=-\lambda\eta\nabla L(\theta^0)-\eta\nabla L(\theta^1)\\ \vdots
冲量实际上是梯度变换的加权和。

冲量的优化:
W=Wαvdwb=bαvdb W=W-\alpha v_{\mathbb{d}w}\\ b=b-\alpha v_{\mathbb{d}b}
其中α\alpha是学习率。vdw,vdbv_{\mathbb{d}w},v_{\mathbb{d}b}计算如下:
vdw=βvdw+(1β)dWvdb=βvdb+(1β)db v_{\mathbb{d}w} = \beta v_{\mathbb{d}w}+(1-\beta) \mathbb{d}W\\ v_{\mathbb{d}b} = \beta v_{\mathbb{d}b}+(1-\beta) \mathbb{d}b
β\beta也是一个超参数,一般设置为0.90.9

模型性能

欠拟合问题

上文提到过如果模型无法很好地在训练集上运作,可能要重新设计网络,但这种做法费时费力,一般会先采取别的措施:

  1. 选取新的**函数
  2. 调整学习率
  3. Batch Normalization

选取新的**函数

模型性能差,可能是因为在训练过程中梯度消失了,即**函数过早饱和。因此,这种情况下可以选取别的**函数。

调整学习率

由于θi=θi1ηL(θi1)\theta^i=\theta^{i-1}-\eta \nabla L(\theta^{i-1}),可见学习率也会影响到参数,是一个非常重要的超参数。

人工智能导论复习整理(五)

从上图可以明显看到,选取合适的学习率的重要性,若选取的太小,学习过程会变得很慢,若是太大,则有可能学不到目标值。

实验过程中,一般看不到上图,实际可见的类似下图,对下图进行分析:

人工智能导论复习整理(五)

从图中可以看到loss值总体一直在下降,但是下降缓慢,说明学习率的选取没有问题,但是过于小了,且loss值上下振荡很厉害,可见batch size的选取过小。

不同的学习率对于模型的影响如下:

人工智能导论复习整理(五)

有一种学习率的选取方法是每隔几个epoch之后减少一次学习率。训练刚开始,由于参数距离目标值尚远,可以使用较大的学习率,但是几轮epoch之后,参数值接近目标值了,此时就需要减小学习率了。一种减小方式是:ηt=ηt+1\eta^t=\dfrac {\eta} {\sqrt{t+1}}

普通的梯度下降:wt+1wtηtgtw^{t+1}\leftarrow w^t-\eta^tg^t,其中gt=L(θt)wg^t=\dfrac{\partial L(\theta^t)}{\partial w}

Adagradwt+1wtηtσtgtw^{t+1}\leftarrow w^t-\dfrac{\eta^t}{\sigma^t} g^t,其中σt\sigma^t与参数相关。σt=1t+1i=0t(gi)2\sigma^t=\sqrt{\dfrac1{t+1}\sum_{i=0}{t}(g^i)^2}。最终,wt+1wtηi=0t(gi)2gtw^{t+1}\leftarrow w^t-\dfrac{\eta}{\sqrt{\sum_{i=0}^t(g^i)^2}} g^t

Adagrad解决了不同参数下设定不同学习率的问题。

RMSPropwt+1wtησtgtw^{t+1}\leftarrow w^t-\dfrac{\eta}{\sigma^t} g^tσt=α(σt1)2+(1α)(gt)2\sigma^t=\sqrt{\alpha(\sigma^{t-1})^2+(1-\alpha)(g^t)^2}α\alpha一般取0.90.90.990.99

(可以应对更加复杂的学习率的变化问题,比如梯度大时,将学习率设置的较小,梯度小时,将学习率设置的较大。)

权重更新公式:
W=WαdWsdw+ϵb=bαdbsdb+ϵ W=W-\alpha \dfrac{\mathbb{d}W}{\sqrt{s_{\mathbb{d}w}}+\epsilon}\\ b=b-\alpha \dfrac{\mathbb{d}b}{\sqrt{s_{\mathbb{d}b}}+\epsilon}
vdw,vdbv_{\mathbb{d}w},v_{\mathbb{d}b}计算如下:
sdw=βsdw+(1β)dW2sdb=βsdb+(1β)db2 s_{\mathbb{d}w} = \beta s_{\mathbb{d}w}+(1-\beta) \mathbb{d}W^2\\ s_{\mathbb{d}b} = \beta s_{\mathbb{d}b}+(1-\beta) \mathbb{d}b^2
Adam:RMSProp+Momentum

Batch Normalization

Feature Scaling(数据预处理):让不同的数据的分布尽量相同。

数据归一化:对于每个数据样本,都包含nn个数据维度,计算每一个维度ii的数据的平均值mim_i和标准差σi\sigma_i。那么,对于样本rr的第ii维的数据进行操作xirxirmiσix^r_i\leftarrow\dfrac{x_i^r-m_i}{\sigma_i},使得数据服从均值为00,方差为11的正态分布。

经过归一化后的数据再进行梯度下降,此时收敛会快很多。

Batch Normalization

每个batch都会有输出ziz^i,求出它们的平均值μ\mu和标准差σ\sigma,得到z~i\widetilde{z}^i。再通过z^i=γz~i+β\hat{z}^i=\gamma\odot\widetilde{z}^i+\beta将数据经评议和所发还原到原来的scaling。μ\muσ\sigma是根据ziz^i计算得到,而γ\gammaβ\beta是通过学习得到的。这样可以减小层与层之间的影响。通常会运用在**函数前。

在测试阶段,是没有μ\muσ\sigma的,理想的做法是使用的μ\muσ\sigma是训练时得到的值,但实际操作中使用的是测试中求得的μ\muσ\sigma的值的平均值。

优点在于:

  1. 减少训练时间,解决了梯度消失/爆炸等问题。
  2. 对初始值的依赖较少。(不太会受局部最优解影响)
  3. 降低对于正则化的需求。

过拟合问题

Early Stopping

及时停止训练,避免过拟合,可以在训练过程中,借助验证集来测试,如果验证集的loss值在某个点不降反升了,此时应该停止训练。

Regularization(正则化)

在原先的loss函数上增加一项正则项,即L(θ)=L(θ)+λ12θ2,θ={w1,w2,}L'(\theta)=L(\theta)+\lambda\dfrac12||\theta||_2,\theta=\{w_1,w_2,\cdots\}

L2正则化:θ2=(w1)2+(w2)2+||\theta||_2=(w_1)^2+(w_2)^2+\cdots,此时一般不考虑bias。

那么对应的梯度为:KaTeX parse error: Undefined control sequence: \part at position 8: \dfrac{\̲p̲a̲r̲t̲ ̲L'}{\part w}=\d…

权重的更新变成了::KaTeX parse error: Undefined control sequence: \part at position 34: …w^t-\eta\dfrac{\̲p̲a̲r̲t̲ ̲L'}{\part w}=w^…

1ηλ)wt(1-\eta\lambda)w^t这一项随着tt的增大,会无限接近00

同理,采用L1正则化:θ1=w1+w2+||\theta||_1=|w_1|+|w_2|+\cdots,损失函数变为L(θ)=L(θ)+λθ1,θ={w1,w2,}L'(\theta)=L(\theta)+\lambda||\theta||_1,\theta=\{w_1,w_2,\cdots\}

那么对应的梯度为:KaTeX parse error: Undefined control sequence: \part at position 8: \dfrac{\̲p̲a̲r̲t̲ ̲L'}{\part w}=\d…

权重的更新变成了::KaTeX parse error: Undefined control sequence: \part at position 34: …w^t-\eta\dfrac{\̲p̲a̲r̲t̲ ̲L'}{\part w}=w^…

wtηλsgn(wt)w^t-\eta\lambda\text{sgn}(w^t)这一项随着tt的增大,也会无限接近00

Dropout

训练过程中,每次更新参数的时候,每个神经元有pp的概率会被丢弃。因此,每修正一次参数,都会得到一个新的神经网络。

测试时,则无需再dropout。如果如果训练时dropout rate的值设为pp,那么测试时所有的权重都要乘以1p1-p

dropout用到了集成学习的思想,“三个臭皮匠赛过诸葛亮”。集成学习应用的就是这种想法。单个模型可能很弱,但是将这些很弱的模型结合起来求平均,最终的神经网络表现会更佳。虽然dropout的训练过程中,每个minibatch对应的网络都不相同,但都是完整网络的一个子网络。

如何选择合适的超参数

超参数是模型训练之前人为给定的一些参数,如dropout rate、学习率、batch size等。超参数定义了关于模型更高层次的概念,如模型复杂性、学习能力等。一般超参数都是根据经验来设定,因此只能通过不断地尝试,来确定某个场景下,超参数的给定值。

目前,有四种主要的策略来选取合适的超参数:

  1. Babysitting:完全手动调整,耗时
  2. Grid Search:列出每个超参数的可能取值,排列组合后测每个组合的正确率,选择正确率较高的一组数值。这种做法会面临组合爆炸的问题,即便采用并行计算,计算效率仍然很低。因此主要适用于超参数个数小于等于44的场景。
  3. Random Search:能以更少的迭代次数找到更优的解,但是不能保证找到最优的超参数的值。
  4. Automatic Hyperparameter Tuning(贝叶斯优化)

过不断地尝试,来确定某个场景下,超参数的给定值。

目前,有四种主要的策略来选取合适的超参数:

  1. Babysitting:完全手动调整,耗时
  2. Grid Search:列出每个超参数的可能取值,排列组合后测每个组合的正确率,选择正确率较高的一组数值。这种做法会面临组合爆炸的问题,即便采用并行计算,计算效率仍然很低。因此主要适用于超参数个数小于等于44的场景。
  3. Random Search:能以更少的迭代次数找到更优的解,但是不能保证找到最优的超参数的值。
  4. Automatic Hyperparameter Tuning(贝叶斯优化)

除了第一种是人工调参,后三种都是机器调参。

相关文章: