Pytorch: 优化器、损失函数与深度神经网络框架
Copyright: Jingmin Wei, Pattern Recognition and Intelligent System, School of Artificial and Intelligence, Huazhong University of Science and Technology
文章目录
本教程不商用,仅供学习和参考交流使用,如需转载,请联系本人。
这章内容非常重要,需要大家有一定的机器学习基础,尤其是梯度下降法和损失函数,没有这方面基础,又不太看得懂教程的可以去看如下几个知识点:梯度下降法,随机梯度下降法,均方误差,交叉熵,Logistic Regression,模型的过拟合与欠拟合。
Reference
优化器
梯度下降是所有机器学习算法的基础,没有这方面经验的同学可以自己查阅相关资料,深入理解背后的数学知识和优化思想。
https://ruder.io/optimizing-gradient-descent/ 是个非常好用的优化器算法索引链接,大家可以用这个链接去找不同的优化器原理。
梯度下降(GD)
在深度学习网络中,通常需要设计一个模型的损失函数来约束我们的训练过程,如针对分类问题可以使用交叉嫡损失,针对回归问题可以使用均方根误差损失等。模型的训练并不是漫无目的的,而是朝着最小化损失函数的方向去训练,这时就会用到梯度下降类的算法。
梯度下降法(gradient descent)是一个阶最优化算法, 是通过函数当前点对应梯度(或者是近似梯度)的反方向,使用规定步长距离进行迭代搜索,从而找到一一个函数的局部极小值的算法,最好的情况是希望找到全局极小值。
优化问题:考虑无约束问题 m i n i m i z e f ( x ) minimize\ f(x) minimize f(x) 。给定初始点 x ( 0 ) x^{(0)} x(0) ,寻找序列 x ( 1 ) , x ( 2 ) ⋯ x^{(1)},x^{(2)}\cdots x(1),x(2)⋯ 使函数沿着该序列单调递减。
f ( x ( 0 ) ) ⩾ f ( x ( 1 ) ) ⩾ f ( x ( 2 ) ) ⩾ ⋯ f(x^{(0)})\geqslant f(x^{(1)})\geqslant f(x^{(2)})\geqslant \cdots f(x(0))⩾f(x(1))⩾f(x(2))⩾⋯
梯度下降即构造这样的序列,使函数最终达到一个较为满意的最小值点
梯度下降法是典型的迭代法之一,这类方法的核心,即为如何定义从上一个点到下一个点的规则,一般利用一阶导数(梯度)或者二阶导数(黑塞矩阵)。
原理:假设当前点为 x ( k ) x^{(k)} x(k) ,则下一个点为 x ( k + 1 ) = x ( k ) + t Δ x ( k ) , Δ x ( k ) = − ∇ f ( x ( k ) ) x^{(k+1)}=x^{(k)}+t\Delta x^{(k)}, \quad\Delta x^{(k)}=-\nabla f(x^{(k)}) x(k+1)=x(k)+tΔx(k),Δx(k)=−∇f(x(k)) 。
定义:下降方向。如果 ∃ t \exist\ t ∃ t 使得 f ( x 0 + t v ) < f ( x 0 ) f(x_0+tv)<f(x_0) f(x0+tv)<f(x0) ,则 v v v 为 f f f 在 x 0 x_0 x0 的下降方向。
泰勒展开: f ( x k + Δ x ) − f ( x k ) = ( Δ f ( x ) ) T Δ x + o ( ∣ ∣ Δ x ∣ ∣ ) f(x_k+\Delta x)-f(x_k)=(\Delta f(x))^T\Delta x+o(||\Delta x||) f(xk+Δx)−f(xk)=(Δf(x))TΔx+o(∣∣Δx∣∣)
保证移动到下一个点时,函数值减小,则有:
Δ x > 0 , ∇ f ( x k ) ⩽ 0 ⇔ Δ x T ∇ f ( x k ) ⩽ 0 ( T a y l o r ) ⇔ − ∇ f ( x k ) T ∇ f ( x k ) ( 令 Δ x = ∇ f ( X k ) ) = − ∣ ∣ ∇ f ( x k ) ∣ ∣ 2 2 ⩽ 0 \begin{aligned} &\Delta x>0,\nabla f(x_k)\leqslant0\\ &\Leftrightarrow \Delta x^T\ \nabla f(x_k)\leqslant0\ (Taylor)\\ &\Leftrightarrow -\nabla {f(x_k)}^T \ \nabla f(x_k)\ (令\Delta x=\nabla f(X_k))\\ &=-\bigl||\nabla f(x_k) |\bigr|_2^2\leqslant0 \end{aligned} Δx>0,∇f(xk)⩽0⇔ΔxT ∇f(xk)⩽0 (Taylor)⇔−∇f(xk)T ∇f(xk) (令Δx=∇f(Xk))=−∣∣∣∇f(xk)∣∣∣22⩽0
定理:对于连续可导函数 f f f ,如果 v T ∇ f ( x 0 ) < 0 v^T \nabla f(x_0)<0 vT∇f(x0)<0 ,则 v v v 为下降方向。
f ( x ( k + 1 ) ) = f ( x ( k ) + t Δ x ) = f ( x ( k ) + t ∇ f ( x ( k ) ) T Δ x ) = f ( x ( k ) − t ∣ ∣ ∇ f ( x ( k ) ) ∣ ∣ ) \begin{aligned} f(x^{(k+1)})&=f(x^{(k)}+t\Delta x)\\ &=f(x^{(k)}+t\nabla f(x^{(k)})^T\Delta x)\\ &=f(x^{(k)}-t\bigl||\nabla f(x^{(k)})|\bigr|) \end{aligned} f(x(k+1))=f(x(k)+tΔx)=f(x(k)+t∇f(x(k))TΔx)=f(x(k)−t∣∣∣∇f(x(k))∣∣∣)
夹角: Δ x T ∇ f ( x k ) = ∣ ∣ Δ x ∣ ∣ ⋅ ∣ ∣ f ( x k ) ∣ ∣ ⋅ cos θ \Delta x^T\ \nabla f(x_k)=||\Delta x||\cdot||f(x_k)||\cdot\cos\theta ΔxT ∇f(xk)=∣∣Δx∣∣⋅∣∣f(xk)∣∣⋅cosθ 。则 θ = π \theta=\pi θ=π ,即负梯度方向时,函数值下降得是最快的。
步长 t t t (学习率)是用来保证 x + Δ x x+\Delta x x+Δx 在 x x x 的邻域内,从而可以忽略泰勒公式中的 o ( ∣ ∣ Δ x ∣ ∣ ) o(||\Delta x||) o(∣∣Δx∣∣) 项。
迭代终止条件:函数的梯度值为 0 0 0 或接近 0 0 0 ,此时认为已经达到了极值点。
算法过程:( e p s eps eps 为人工指定的接近 0 0 0 的正数, N N N 为最大迭代次数)
i n i t x 0 , k = 0 w h i l e ∣ ∣ ∇ f ( x k ) > e p s ∣ ∣ a n d K < N : . . . x k + 1 = x k − t ∇ f ( x + k ) . . . k = k + 1 e n d w h i l e \begin{aligned} &init\ x_0,k=0\\ &while\ ||\nabla f(x_k)>eps||\ and\ K<N:\\ &...x_{k+1}=x_k-t\nabla f(x+k)\\ &...k=k+1\\ &end\ while \end{aligned} init x0,k=0while ∣∣∇f(xk)>eps∣∣ and K<N:...xk+1=xk−t∇f(x+k)...k=k+1end while
最速下降
它的思想和梯度下降法类似,但是每次需要计算最佳步长 t ∗ t^* t∗ 。
步长确定: t ( k ) = arg min t ⩾ 0 f ( x ( k ) − t ∇ f ( x ( k ) ) ) t^{(k)}=\arg\min_{t\geqslant0}f(x^{(k)}-t\nabla f(x^{(k)})) t(k)=argmint⩾0f(x(k)−t∇f(x(k))) 。
两种优化方法,第一种是取多个典型值,然后分别计算他们的目标函数值,确定最优值。第二种方法是以 t t t 为自变量,直接求上式的逐点,对于有些情况可以得到解析解。这类方法也成为直线搜索,它沿着某一确定的方向在直线上寻找最优步长。
随机梯度下降(SGD)
在使用梯度下降算法时,每次更新参数都需要使用所有的样本。如果对所有的样本均计算一次最后取梯度平均值,当样本总量特别大时,对算法的速度和效率影响非常大。所以就有了随机梯度下降(stochastic gradient descent, SGD)算法,它是对梯度下降法算法的一种改进,即每次只使用部分样本来计算梯度。
在机器学习和深度学习中,SGD 通常指小批随机梯度下降(mini-batch gradient descent)算法,即每次只随机取一部分样本( M ≪ N M\ll N M≪N )进行优化, 样本的数量一般是 2 2 2 的整数次幂,取值范围一般是 32 ∼ 256 32\sim256 32∼256 ,以保证计算精度的同时提升计算速度,是优化深度学习网络中最常用的一类算法。
本质上,即损失从整体样本的平均损失,变成了这个 batch 样本的损失:
L ( w ) = 1 N ∑ i = 1 N L ( w , x i , y i ) → L ( w ) = 1 M ∑ i = 1 M L ( w , x i , y i ) L(w)=\frac{1}{N}\sum_{i=1}^NL(w,x_i,y_i)\rightarrow\\ L(w)=\frac{1}{M}\sum_{i=1}^ML(w,x_i,y_i) L(w)=N1i=1∑NL(w,xi,yi)→L(w)=M1i=1∑ML(w,xi,yi)
SGD 算法及其一些变种,是深度学习中应用最多的一类算法。其在训练过程中,通常会使用一个固定的学习率进行训练。即:
g t = ∇ θ t − 1 f ( θ t − 1 ) θ t = − η ⋅ g t g_t=\nabla_{\theta_{t-1}}f(\theta_{t-1})\\ \theta_t=-\eta\cdot g_t gt=∇θt−1f(θt−1)θt