机器学习有以下几种常见的分类方法:
机器学习的流程可以简单概括为:提取特征–>建立模型–>确定损失函数和进行优化求解。
提取特征这一步没什么好说的,如果用的是经典的数据集那么特征都是被提取好的,如果要自己提取特定数据的特征那就要具体问题具体分析了。
建立模型这一步,书中介绍传统的机器学习模型有逻辑回归、随机森林等(话说我之前一直以为这些就算是分类器还算不上机器学习来着…);而深度学习的方法有多层感知机(MLP),卷积网络等。模型可以看做是一个函数 Y = f ( X ; W ) Y=f(X;W) Y=f(X;W),函数建立了特征X到标签Y到映射,而W则是模型中的参数。
确定损失函数才能评估一个模型的好坏,可以通过损失函数的值来优化模型。在2.1.3中介绍了一些常见的损失函数。
我们接着对流程中的后两步进行细致一点的说明,假设现在有训练集有N个样本,有 X = { ( x i , y i ) ∣ i = 1 , 2 , . . . , N } X=\{(x_i, y_i)|i=1,2,...,N\} X={(xi,yi)∣i=1,2,...,N},分别为样本特诊及其对应的标签,特征 x i ∈ R d x_i\in R^d xi∈Rd,标签 y i ∈ Y = { 0 , 1 , . . . , K } y_i\in Y=\{0,1,...,K\} yi∈Y={0,1,...,K}是离散的。模型就是要给出 f : R d → R K f:R^d\to R^K f:Rd→RK这样的映射,最后的输出在每个类别上有一个概率 P ( Y ∣ x i ) = f ( x i ; θ ) P(Y|x_i)=f(x_i;\theta) P(Y∣xi)=f(xi;θ),我们要取的就是最大的概率值作为最后模型给出的标签 y i ∗ = a r g m a x ( P ( Y ∣ x i ) ) y_i^*=argmax(P(Y|x_i)) yi∗=argmax(P(Y∣xi)), a r g m a x argmax argmax取到的最大的参数就是最大的概率值。
那么我们前面提到了该如何评估一个模型的好坏,就是要评价我们得到的预测和真实值的差异,即 y i y_i yi和 y i ∗ y_i^* yi∗之间的差异,而且我们需要一个可以量化的方法,这个方法就是定义一个损失函数(Loss Function)。通常用 L ( y , f ( x ; θ ) ) L(y,f(x;\theta)) L(y,f(x;θ))表示,通过最小化损失函数训练模型就是优化求解的过程,可以表示为 θ ∗ = a r g m i n [ 1 N Σ i = 1 N L ( y i , f ( x i ; θ ) ) + λ Φ ( θ ) ] \theta^*=argmin[\frac{1}{N}\Sigma^N_{i=1}L(y_i,f(x_i;\theta))+\lambda\Phi(\theta)] θ∗=argmin[N1Σi=1NL(yi,f(xi;θ))+λΦ(θ)],期中均值函数表示的经验风险函数,L表示的是损失函数, Φ \Phi Φ表示的是正则化项(regularizer)或者惩罚项(penalty term),可以是L1或L2以及其他正则函数。总之过程就是在寻找是的目标函数最小的 θ \theta θ值。
这个过程当然不是一蹴而就的,在训练过程中可能要迭代训练非常多轮直到损失不再变化,这时就称模型已经收敛。这一过程还有两个隐患,一个是训练过程一直用的是训练集,模型可能过拟合,变得只认识训练集而不认识测试集;也可能欠拟合,无论如何也无法在训练集上收敛。
前面提到了训练模型时需要最小化损失函数,那么这个最小化的过程也不是说小就小了,最常用的就是梯度下降算法。
考虑多元函数 f ( x ) f(x) f(x)(带入机器学习过程就是损失函数 L L L),梯度就是对其中每个自变量的偏导数构成的向量,有 f ′ ( x ) = ∇ f ( x ) = [ ∇ f ( x 1 ) , . . . , ∇ f ( x n ) ] T f'(x)=\nabla f(x)=[\nabla f(x_1),...,\nabla f(x_n)]^T f′(x)=∇f(x)=[∇f(x1),...,∇f(xn)]T,考虑 f ( x + Δ x ) = f ( x ) + f ′ ( x ) T Δ x + o ( x ) f(x+\Delta x)=f(x)+f'(x)^T\Delta x+o(x) f(x+Δx)=f(x)+f′(x)TΔx+o(x)。
回顾我们的目标:最小化损失函数。那么就是想要 f ( x + Δ x ) < f ( x ) f(x+\Delta x)
向量的点积可以用二范数来表示, x T y = ∣ ∣ x ∣ ∣ ⋅ ∣ ∣ y ∣ ∣ ⋅ c o s θ x^Ty=||x||·||y||·cos\theta xTy=∣∣x∣∣⋅∣∣y∣∣⋅cosθ。
我们取 Δ x = − α f ′ ( x ) \Delta x=-\alpha f'(x) Δx=−αf′(x)来保证每次更新都会使得原式越来越小。这里 α \alpha α是一个超参数,就是学习率(代码中常出现的 l r lr lr)。
所以梯度下降的过程就是先初始化参数,之后让模型给出预测,计算损失函数,求导得到梯度,最后基于梯度更新,并不断重复直到模型收敛。
随机初始化参数: { θ 0 ( 0 ) , . . . , θ 0 ( k ) } \{\theta_0^{(0)},...,\theta_0^{(k)}\} {θ0(0),...,θ0(k)},计算 L t = L ( Y , f ( X ; Θ t ) ) L_t=L(Y,f(X;\Theta_t)) Lt=L(Y,f(X;Θt)),得到梯度 ∇ Θ t = ∂ L t ∂ Θ t = { ∇ θ t ( 0 ) , . . . , ∇ θ t ( k ) } \nabla \Theta_t=\frac{\partial L_t}{\partial \Theta_t}=\{\nabla \theta_t^{(0)},...,\nabla \theta_t^{(k)}\} ∇Θt=∂Θt∂Lt={∇θt(0),...,∇θt(k)},并更新 Θ t + 1 = { θ t ( 0 ) − α ∇ θ t ( 0 ) , . . . , θ t ( k ) − α ∇ θ t ( k ) } \Theta_{t+1}=\{\theta_t^{(0)}-\alpha \nabla \theta_t^{(0)},...,\theta_t^{(k)}-\alpha \nabla \theta_t^{(k)}\} Θt+1={θt(0)−α∇θt(0),...,θt(k)−α∇θt(k)}。
原理所说的梯度下降算法被称作批梯度下降算法(BGD),其使用了全量的样本进行计算。
使用单一样本近似估计梯度的方法则被称为随机梯度下降(SGD)。具体来说,训练时每次从训练集中随机选择一个样本,计算损失和梯度,进行参数更新。显然其计算复杂度很低,但也有缺陷:虽然单一样本的梯度对全体样本的梯度是一个无偏估计,但仍然存在着偏差和不确定性,收敛速度会更慢。
改进的方法自然就是多选一些样本(但仍然少于全体样本),这样的方法被称作小批量随机梯度下降(mini-batch SGD)。
基本神经元包括三个部分:输入信号,线性组合和非线性激活函数。
z i = Σ j = 1 m w i j x j z_i=\Sigma^m_{j=1}w_{ij}x_j zi=Σj=1mwijxj,这里 x x x是输入信号, w w w是神经元的权值,而 z z z则是输入信号的线性组合。
a i = σ ( z i + b ) a_i=\sigma(z_i+b) ai=σ(zi+b),这里 σ \sigma σ是激活函数, b b b是偏置, a a a就是神经元的输出信号。
对于如图所示的感知器,计算过程可以表示为: f ( x ) = f 2 ( b ( 2 ) + W ( 2 ) ( f 1 ( b ( 1 ) + W ( 1 ) x ) ) ) f(x)=f_2(b^{(2)}+W^{(2)}(f_1(b^{(1)}+W^{(1)}x))) f(x)=f2(b(2)+W(2)(f1(b(1)+W(1)x)))
多层感知器MLP:
不同的就是有多个隐藏层,所以有更一般的MLP信息传播公式:
z ( l ) = W ( l ) ⋅ a ( l − 1 ) + b ( l ) , a ( l ) = σ l ( z ( l ) ) z^{(l)}=W^{(l)}·a^{(l-1)}+b^{(l)},a^{(l)}=\sigma_l(z^{(l)}) z(l)=W(l)⋅a(l−1)+b(l),a(l)=σl(z(l))
每层网络中,可训练的是 { W ( l ) , b ( l ) } \{W^{(l)},b^{(l)}\} {W(l),b(l)}
激活函数的非线性让神经网络可以逼近任何非线性函数,因为注意到神经网络中会先进行线性组合,如果没有非线性元素的引入,那么神经网络最后的结果一定是线性的,表达能力有限。
Sigmoid: σ ( x ) = 1 1 + e − x \sigma(x)=\frac{1}{1+e^{-x}} σ(x)=1+e−x1,常用于二分类器最后一层的激活函数
Tanh: t a n h ( x ) = e x − e − x e x + e − x tanh(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}} tanh(x)=ex+e−xex−e−x
ReLU:$ReLU(x)=\begin{cases} x&\text{if KaTeX parse error: Expected 'EOF', got '}' at position 3: x}̲\ge0 \\ 0& \tex… x < 0} \end{cases}$
输入为负梯度为0,输入为正梯度为1,单侧抑制。可能会导致某个神经元“死亡”。
LeakyReLU:$LeakyReLU(x)=\begin{cases} x&\text{if KaTeX parse error: Expected 'EOF', got '}' at position 3: x}̲>0 \\ \lambda x… x} \le 0 \end{cases}$
λ \lambda λ是一个超参数用来避免神经元“死亡”。
PReLU则就是将LeakyReLU中的 λ \lambda λ变为可训练的参数。
ELU:$ELU(x)=\begin{cases} x&\text{if KaTeX parse error: Expected 'EOF', got '}' at position 3: x}̲\le0 \\ \alpha(… x} < 0 \end{cases}$
输入为负时进行非线性变换,其中 α \alpha α是一个超参数,可以调节梯度为0。
对样本 ( x , y ) (x,y) (x,y),前向传播得到 y ^ \hat y y^,对应损失 L ( y , y ^ ) L(y, \hat y) L(y,y^),参数矩阵梯度 ∇ W ( l ) = ∂ L ( y , y ^ ) ∂ W ( l ) \nabla W^{(l)}=\frac{\partial L(y,\hat y)}{\partial W^{(l)}} ∇W(l)=∂W(l)∂L(y,y^)。
根据链式法则展开参数矩阵梯度有 ∇ W ( l ) = ∂ z ( l ) ∂ W ( l ) ∂ L ( y , y ^ ) ∂ z ( l ) \nabla W^{(l)}=\frac{\partial z^{(l)}}{\partial W^{(l)}}\frac{\partial L(y,\hat y)}{\partial z^{(l)}} ∇W(l)=∂W(l)∂z(l)∂z(l)∂L(y,y^)。
定义 δ ( l ) = ∂ L ( y , y ^ ) ∂ z ( l ) \delta^{(l)}=\frac{\partial L(y,\hat y)}{\partial z^{(l)}} δ(l)=∂z(l)∂L(y,y^)为误差项,其衡量了 z ( l ) z^{(l)} z(l)对损失的影响,可进一步展开得到 δ ( l ) = ∂ a ( l ) ∂ z ( l ) ∂ z ( l + 1 ) ∂ a ( l ) ∂ L ( y , y ^ ) ∂ z ( l + 1 ) \delta^{(l)}=\frac{\partial a^{(l)}}{\partial z^{(l)}}\frac{\partial z^{(l+1)}}{\partial a^{(l)}}\frac{\partial L(y,\hat y)}{\partial z^{(l+1)}} δ(l)=∂z(l)∂a(l)∂a(l)∂z(l+1)∂z(l+1)∂L(y,y^)。
回想: z ( l ) = W ( l ) ⋅ a ( l − 1 ) + b ( l ) , a ( l ) = σ l ( z ( l ) ) z^{(l)}=W^{(l)}·a^{(l-1)}+b^{(l)},a^{(l)}=\sigma_l(z^{(l)}) z(l)=W(l)⋅a(l−1)+b(l),a(l)=σl(z(l))
可继续变换得到: δ ( l ) = σ ′ ( z ( l ) ) ⊙ W ( l + 1 ) T δ ( l + 1 ) \delta^{(l)}=\sigma'(z^{(l)})\odot W^{(l+1)^T}\delta^{(l+1)} δ(l)=σ′(z(l))⊙W(l+1)Tδ(l+1),其中 ⊙ \odot ⊙是Hadamard积。
Hadamard积
可以看到第 l l l和第 l + 1 l+1 l+1层的误差项是相关的,这也是为什么可以反向传播。
(再后续的推导看的就更懵了,没怎么给过程,读了一些其他人的读书笔记发现有人反应这里的推导有误,参考了其他书籍的BP推导发现从一开始符号用的就不一样,所以这部分就先不多写了,等啃明白了BP再回来补。这里给一个个人认为写的比较清晰的推导https://zhuanlan.zhihu.com/p/45190898,其实和书上的思路是一致的,就是书上的过程太简略了…)
梯度消失:Sigmoid和Tanh函数在逼近上下边界的时候梯度会比较小,导致参数更新慢甚至不更新,模型难以训练,称为梯度消失
局部最优:损失函数和参数之间的关系是非凸的,在梯度下降的时候可能陷入局部最优