人工神经网络是机器学习领域和神经网络领域的交叉部分。它试图模仿人脑的工作方式,通过构建类似于神经元之间连接的网络来进行学习和预测。
1.神经元模型
神经元(neuron)模型是神经网络中的基本单元,它在生物学中对应于神经元。当神经元的输入信号达到某个阈值时,它会触发并发送化学物质,这个过程称为兴奋。这些化学物质可以传递到与该神经元连接的其他神经元,引发它们的兴奋或抑制。这种连接方式构成了神经网络的基础。在机器学习中,神经网络通过学习和优化这些连接的权重,以实现对特定任务的自动学习和预测。
1.1 M-P神经元
单个M-P神经元模型包括三个主要部分:输入、激活函数(activation function)和输出。输入代表了神经元的输入信号,激活函数根据输入信号的强度和神经元的阈值来决定是否触发神经元,输出则是神经元触发的结果。输出公式如下:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> y = f ( ∑ i = 1 n w i x i − θ ) y=f\left(\sum_{i=1}^{n}{w_ix_i-\theta}\right) </math>y=f(i=1∑nwixi−θ)
图1.1神经元模型
<math xmlns="http://www.w3.org/1998/Math/MathML"> x i ( i = 1 , 2 , ... , n ) x_i\ (i=1,2,\ldots,n) </math>xi (i=1,2,...,n) 神经元输入, <math xmlns="http://www.w3.org/1998/Math/MathML"> w i ( i = 1 , 2 , ... , n ) w_i\ (i=1,2,\ldots,n) </math>wi (i=1,2,...,n) 神经元连接权重 <math xmlns="http://www.w3.org/1998/Math/MathML"> θ \theta </math>θ 阈值 <math xmlns="http://www.w3.org/1998/Math/MathML"> f f </math>f 激活函数,当 <math xmlns="http://www.w3.org/1998/Math/MathML"> f f </math>f为sgn(阶跃函数,一种非线性函数,可以将输入映射到输出,输出值只有0和1两种可能)时为感知机,当 <math xmlns="http://www.w3.org/1998/Math/MathML"> f f </math>f为Sigmoid时为对数几率回归。 虽然sgn属于理性型激活函数(它的输出值0和1对应神经元的"抑制"和"兴奋"),但是它不具备连续性,因此使用sigmoid作为激活函数(还有一种比sigmoid函数还要适合的是ReLU函数,暂时挖个坑)
1.2多个M-P神经元
多个M-P神经元则是将多个M-P神经元模型连接在一起,形成更复杂的神经网络。每个神经元都可以接收来自其他神经元的输入,并根据激活函数和权重来决定是否触发以及输出的结果。
2.感知机与多层网络
2.1感知机
感知机由两层神经元组成,分别成为输入层和输出层。感知机通过"权重"和"阈值"来实现简单的逻辑运算,而"和"就可以通过学习来获得。 感知机的模型如下:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> y = f ( ∑ i = 1 n w i x i − θ ) = f ( w T x − θ ) y=f\left(\sum_{i=1}^{n}{w_ix_i-\theta}\right)=f\left(w^Tx-\theta\right) </math>y=f(i=1∑nwixi−θ)=f(wTx−θ)
若感知机的激活函数为阶跃函数则表示为:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> y = ε ( w T x − θ ) = { 1 , w T x − θ ≥ 0 ; 0 , w T x − θ < 0. y = \varepsilon(w^Tx-\theta) = \begin{cases} 1, & w^Tx-\theta \geq 0; \\ 0, & w^Tx-\theta < 0. \end{cases} </math>y=ε(wTx−θ)={1,0,wTx−θ≥0;wTx−θ<0.
感知机模型可以看作 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n维空间中的超平面,这是因为感知机通过将输入特征映射到 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n维空间,将输入数据分成两个类别。这个超平面可以将特征空间分成两部分,一部分是正例区域,另一部分是反例区域。感知机模型通过计算输入数据与超平面的距离,判断数据点属于哪个类别。
实现分类的原理是,当输入数据点位于超平面的正侧时,感知机被激活,输出为1;当输入数据点位于超平面的负侧时,感知机被抑制,输出为0。因此,感知机模型可以看作是一个简单的二元分类器,它通过计算输入数据点与超平面的距离来进行分类。
2.1.1感知机学习策略
给定一个数据集 <math xmlns="http://www.w3.org/1998/Math/MathML"> T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } T={\{\left(x_1,y_1\right),\left(x_2,y_2\right),...,\left(x_N,y_N\right)}\} </math>T={(x1,y1),(x2,y2),...,(xN,yN)} 其中 <math xmlns="http://www.w3.org/1998/Math/MathML"> x i ∈ R n , y i ∈ 0 , 1 , i = 1 , 2 , . . . , N . x_i\in\mathbb{R}^n,\ y_i\in{0,1}\ ,\ i=1,\ 2,\ ..\ .\ ,\ N.\ </math>xi∈Rn, yi∈0,1 , i=1, 2, .. . , N. 如果存在某个超平面 <math xmlns="http://www.w3.org/1998/Math/MathML"> w T x + θ = 0 \ w^Tx+\theta=0\ </math> wTx+θ=0 对所有 <math xmlns="http://www.w3.org/1998/Math/MathML"> y i = 1 y_i=1 </math>yi=1的样本 <math xmlns="http://www.w3.org/1998/Math/MathML"> x i x_i </math>xi有 <math xmlns="http://www.w3.org/1998/Math/MathML"> w T x + θ ≥ 0 w^Tx+\theta\geq0\ </math>wTx+θ≥0 ;对所有 <math xmlns="http://www.w3.org/1998/Math/MathML"> y i = 0 y_i=0 </math>yi=0的样本 <math xmlns="http://www.w3.org/1998/Math/MathML"> x i x_i </math>xi有 <math xmlns="http://www.w3.org/1998/Math/MathML"> w T x + θ < 0 w^Tx+\theta<0 </math>wTx+θ<0,则称数据集 <math xmlns="http://www.w3.org/1998/Math/MathML"> T T </math>T线性可分,否则为线性不可分。
现在把线性可分的数据集 <math xmlns="http://www.w3.org/1998/Math/MathML"> T T </math>T丢给感知机,而感知机的target 是求得对数据集 <math xmlns="http://www.w3.org/1998/Math/MathML"> T T </math>T中的正负样本完全被正确划分的分离超平面 <math xmlns="http://www.w3.org/1998/Math/MathML"> w T x − θ = 0 w^Tx-\theta=0 </math>wTx−θ=0. 假设误分类样本集合 <math xmlns="http://www.w3.org/1998/Math/MathML"> M ⊆ T M\subseteq T </math>M⊆T, 对于它的任意样本 <math xmlns="http://www.w3.org/1998/Math/MathML"> ( x , y ) ∈ M \left(x,y\right)\in M </math>(x,y)∈M, 当出现以下情况:
模型输出值 | 样本真实标记 | |
---|---|---|
<math xmlns="http://www.w3.org/1998/Math/MathML"> w T x − θ ≥ 0 w^Tx-\theta\geq0 </math>wTx−θ≥0 | <math xmlns="http://www.w3.org/1998/Math/MathML"> y ^ = 1 \hat{y}=1 </math>y^=1 | <math xmlns="http://www.w3.org/1998/Math/MathML"> y = 0 y=0 </math>y=0 |
<math xmlns="http://www.w3.org/1998/Math/MathML"> w T x − θ < 0 w^Tx-\theta<0 </math>wTx−θ<0 | <math xmlns="http://www.w3.org/1998/Math/MathML"> y ^ = 0 \hat{y}=0 </math>y^=0 | <math xmlns="http://www.w3.org/1998/Math/MathML"> y = 1 y=1 </math>y=1 |
那么 <math xmlns="http://www.w3.org/1998/Math/MathML"> ( y ^ − y ) ( w T x − θ ) ≥ 0 (\hat{y}-y)(w^Tx-\theta)\geq0 </math>(y^−y)(wTx−θ)≥0公式恒成立
于是损失函数的定义:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> L ( w , θ ) = ∑ x ∈ M ( y ^ − y ) ( w T x − θ ) . \mathcal{L}(w,\theta)=\sum_{x\in M}{(\hat{y}-y)(w^Tx-\theta)}. </math>L(w,θ)=x∈M∑(y^−y)(wTx−θ).
2.1.2感知机学习算法
通常,权重和阈值可通过学习获得,阈值看作固定输入为-0.1的哑结点(dummy node) 对应的连接权重 <math xmlns="http://www.w3.org/1998/Math/MathML"> w n + 1 w_{n+1} </math>wn+1, 这可以把权重和阈值的学习简化为权重的学习, 即 <math xmlns="http://www.w3.org/1998/Math/MathML"> w T x i − θ = w T x i . w^Tx_i-\theta=w^Tx_i\ . </math>wTxi−θ=wTxi . 设感知机输出为 <math xmlns="http://www.w3.org/1998/Math/MathML"> y ^ \hat{y} </math>y^, 它的权重调整为 <math xmlns="http://www.w3.org/1998/Math/MathML"> w i ← w i + Δ w i , w_i\gets w_i+\Delta w_i,\ \ </math>wi←wi+Δwi, 其中 <math xmlns="http://www.w3.org/1998/Math/MathML"> Δ w i = − η ( y ^ − y ) x i = η ( y − y ^ ) x i , \Delta w_i=-\eta(\hat{y}-y)x_i=\eta(y-\hat{y})x_i , </math>Δwi=−η(y^−y)xi=η(y−y^)xi, <math xmlns="http://www.w3.org/1998/Math/MathML"> η ∈ ( 0 , 1 ) \eta\in(0,1) </math>η∈(0,1)为学习率,如果感知机对 <math xmlns="http://www.w3.org/1998/Math/MathML"> ( x , y ) (x,y) </math>(x,y)预测正确,感知机不会发生变化,否则对权重调整(取决于错误程度)。
线性可分与线性不可分问题
"与"、"或"、"非"等逻辑问题是线性可分的,这意味着可以通过一条直线(在高维空间中可能是超平面)将不同的类别分开。感知机模型就是基于这种线性可分性进行工作的。
然而,并非所有的问题都是线性可分的。有些问题可能需要复杂的决策边界,这无法通过单层感知机模型来解决。这时,就需要引入多层功能神经元,通过非线性变换,学习更复杂的决策边界。这样的模型称为多层感知机或多层神经网络。
2.2多层网络
多层网络层数更多,包括输入层、输出层与隐藏层,输出层与隐藏层都拥有激活函数。一种常见的多层网络是多层前馈神经网络,其结构包括输入层、隐藏层(至少一层)、输出层,各层之间全连接,但无层内连接以及跨层连接。
图2.1单隐层前馈网络
图2.2双隐层前馈网络
3.误差逆传播算法
误差逆传播(error BackPropagation, BP)算法是一种在神经网络中用于训练模型的算法。其基本思想是通过计算输出层与目标值之间的误差,然后反向传播这个误差,对神经网络的权重和偏置进行调整,以最小化误差。
BP算法的工作流程大致如下:
- 前向传播:输入样本从输入层进入网络,经过隐藏层计算后,得到输出层的输出结果。
- 计算误差:将输出层的输出结果与真实标签进行比较,计算出误差。
- 误差反向传播:将计算出的误差从输出层向隐藏层反向传播,传播过程中会对每一层的权重和偏置进行调整。
- 更新参数:通过优化算法,如梯度下降法,根据反向传播过来的误差,调整网络中的权重和偏置。
以单隐层前馈网络为例:
图2.3 BP网络、算法的变量符号
给定一个数据集 <math xmlns="http://www.w3.org/1998/Math/MathML"> D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) } D={\{\left(x_1,y_1\right),\left(x_2,y_2\right),...,\left(x_m,y_m\right)}\} </math>D={(x1,y1),(x2,y2),...,(xm,ym)} 其中 <math xmlns="http://www.w3.org/1998/Math/MathML"> x i ∈ R d , y i ∈ R l . x_i\in\mathbb{R}^d,\ y_i\in\mathbb{R}^l\ . </math>xi∈Rd, yi∈Rl . 图2.3中的单隐层前馈网络包含 <math xmlns="http://www.w3.org/1998/Math/MathML"> d d </math>d个输入神经元, <math xmlns="http://www.w3.org/1998/Math/MathML"> l l </math>l个输出神经元, <math xmlns="http://www.w3.org/1998/Math/MathML"> q q </math>q个隐藏层神经元。
该多层前馈网络结构的输入层第 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i个神经元与隐藏层第 <math xmlns="http://www.w3.org/1998/Math/MathML"> h h </math>h个神经元的连接权为 <math xmlns="http://www.w3.org/1998/Math/MathML"> v i h v_{ih} </math>vih;隐藏层的第 <math xmlns="http://www.w3.org/1998/Math/MathML"> h h </math>h个神经元与输出层第 <math xmlns="http://www.w3.org/1998/Math/MathML"> j j </math>j个神经元的连接权为 <math xmlns="http://www.w3.org/1998/Math/MathML"> w h j w_{hj} </math>whj; 隐藏层的第 <math xmlns="http://www.w3.org/1998/Math/MathML"> h h </math>h个神经元的阈值记作 <math xmlns="http://www.w3.org/1998/Math/MathML"> γ h \gamma_h </math>γh,所接收到的输入为 <math xmlns="http://www.w3.org/1998/Math/MathML"> α h = ∑ i = 1 d v i h x i \alpha_h=\sum_{i=1}^{d}{v_{ih}x_i} </math>αh=∑i=1dvihxi; 输出层第 <math xmlns="http://www.w3.org/1998/Math/MathML"> j j </math>j个神经元的阈值记作 <math xmlns="http://www.w3.org/1998/Math/MathML"> θ j \theta_j </math>θj,所接收到的输入为 <math xmlns="http://www.w3.org/1998/Math/MathML"> β j = ∑ h = 1 q w h j b i \beta_j=\sum_{h=1}^{q}{w_{hj}b_i} </math>βj=∑h=1qwhjbi.
假设隐藏层和输出层神经元使用Sigmoid函数 <math xmlns="http://www.w3.org/1998/Math/MathML"> f ( x ) = 1 1 + e − x f\left(x\right)=\frac{1}{1+e^{-x}} </math>f(x)=1+e−x1, 该函数的性质 <math xmlns="http://www.w3.org/1998/Math/MathML"> f ′ ( x ) = f ( x ) ( 1 − f ( x ) ) . f'(x)=\ f(x)(1-\ f(x)). </math>f′(x)= f(x)(1− f(x)). 对于训练例 <math xmlns="http://www.w3.org/1998/Math/MathML"> ( x k , y k ) (x_k,y_k) </math>(xk,yk),设此神经网络输出为 <math xmlns="http://www.w3.org/1998/Math/MathML"> y ^ = ( y ^ 1 k , y ^ 2 k , . . . , y ^ l k ) , \hat{y}=({\hat{y}}_1^k,{\hat{y}}_2^k,...,{\hat{y}}_l^k), </math>y^=(y^1k,y^2k,...,y^lk),也就是 <math xmlns="http://www.w3.org/1998/Math/MathML"> y ^ j k = f ( β j − θ j ) , {\hat{y}}j^k=f(\beta_j-\theta_j), </math>y^jk=f(βj−θj),它在训练例的均方误差为 <math xmlns="http://www.w3.org/1998/Math/MathML"> E k = 1 2 ∑ j = 1 l ( y ^ j k − y j k ) 2 . E_k=\frac{1}{2}\sum{j=1}^{l}{({\hat{y}}_j^k-y_j^k)}^2. </math>Ek=21∑j=1l(y^jk−yjk)2.
BP算法基于的梯度下降策略
BP算法基于的梯度下降策略是一种优化算法,用于最小化损失函数,通过迭代计算损失函数对模型参数的梯度,并沿着梯度的反方向更新参数,以达到降低损失函数值 (最小化训练集上的累计误差 <math xmlns="http://www.w3.org/1998/Math/MathML"> E = 1 m ∑ k = 1 m E k E=\frac{1}{m}\sum_{k=1}^{m}E_k </math>E=m1∑k=1mEk ) 的目的。
梯度下降策略在BP算法中的作用主要有两个方面:
1.参数优化: 梯度下降策略通过计算损失函数对模型参数的梯度,指导参数沿着损失函数减小的方向进行更新。通过迭代计算梯度并更新参数,可以使得模型逐渐逼近最优解,即最小化损失函数。
2.避免局部极小值: 在训练神经网络时,有可能会陷入局部极小值,导致模型性能不佳。梯度下降策略通过引入动量项等技术,可以帮助算法逃离局部极小值,继续寻找更好的解,从而提高模型的泛化能力。
以隐藏层到输出层的连接权 <math xmlns="http://www.w3.org/1998/Math/MathML"> w h j w_{hj} </math>whj为例,对于误差 <math xmlns="http://www.w3.org/1998/Math/MathML"> E k E_k </math>Ek给定学习率 <math xmlns="http://www.w3.org/1998/Math/MathML"> η \eta </math>η,推导式如下:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> Δ w h j = − η ∂ E k ∂ w h j \Delta w_{hj} = -\eta \frac{\partial E_k}{\partial w_{hj}} </math>Δwhj=−η∂whj∂Ek
<math xmlns="http://www.w3.org/1998/Math/MathML"> w h j w_{hj} </math>whj将会影响输出层第 <math xmlns="http://www.w3.org/1998/Math/MathML"> j j </math>j个神经元的所接收到的输入 <math xmlns="http://www.w3.org/1998/Math/MathML"> β j \beta_j </math>βj,然后是输出值 <math xmlns="http://www.w3.org/1998/Math/MathML"> y ^ j k {\hat{y}}j^k </math>y^jk,最后是均方误差 <math xmlns="http://www.w3.org/1998/Math/MathML"> E k E_k </math>Ek,公式如下:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> ∂ E k ∂ w h j = ∂ E k ∂ y ^ j k ⋅ ∂ y ^ j k ∂ β j ⋅ ∂ β j ∂ w h j \frac{\partial E_k}{\partial w{hj}}=\frac{\partial E_k}{\partial{\hat{y}}_j^k}\cdot\frac{\partial{\hat{y}}j^k}{\partial\beta_j}\cdot\frac{\partial\beta_j}{\partial w{hj}} </math>∂whj∂Ek=∂y^jk∂Ek⋅∂βj∂y^jk⋅∂whj∂βj
根据 <math xmlns="http://www.w3.org/1998/Math/MathML"> β j \beta_j </math>βj的定义,得出 <math xmlns="http://www.w3.org/1998/Math/MathML"> ∂ β j ∂ w h j = b h \frac{\partial\beta_j}{\partial w_{hj}}=b_h </math>∂whj∂βj=bh 根据 <math xmlns="http://www.w3.org/1998/Math/MathML"> y ^ j k {\hat{y}}_j^k </math>y^jk和 <math xmlns="http://www.w3.org/1998/Math/MathML"> E k E_k </math>Ek得到输出层神经元的梯度项 <math xmlns="http://www.w3.org/1998/Math/MathML"> g i g_i </math>gi:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> g j = − ∂ E k ∂ y ^ j k ⋅ ∂ y ^ j k ∂ β j = − ( y ^ j k − y j k ) f ′ ( β j − θ j ) = y ^ j k ( 1 − y ^ j k ) ( y j k − y ^ j k ) g_j=-\frac{\partial E_k}{\partial{\hat{y}}_j^k}\cdot\frac{\partial{\hat{y}}_j^k}{\partial\beta_j}=-({\hat{y}}_j^k-y_j^k)f'(\beta_j-\theta_j)={\hat{y}}_j^k(1-{\hat{y}}_j^k)(y_j^k-{\hat{y}}_j^k) </math>gj=−∂y^jk∂Ek⋅∂βj∂y^jk=−(y^jk−yjk)f′(βj−θj)=y^jk(1−y^jk)(yjk−y^jk)
计算隐藏层神经元的梯度项 <math xmlns="http://www.w3.org/1998/Math/MathML"> e h e_h </math>eh:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> e h = − ∂ E k ∂ b h ⋅ ∂ b h ∂ α h = − ∑ j = 1 l ∂ E k ∂ β j ⋅ ∂ β j ∂ α h f ′ ( α h − γ h ) = ∑ j = 1 l w h j g j f ′ ( α h − γ h ) = b h ( 1 − b h ) ∑ j = 1 l w h j g j \begin{aligned} e_h &= -\frac{\partial E_k}{\partial b_h}\cdot\frac{\partial b_h}{\partial\alpha_h} \\ &= -\sum_{j=1}^{l}\frac{\partial E_k}{\partial\beta_j}\cdot\frac{\partial\beta_j}{\partial\alpha_h}f'(\alpha_h-\gamma_h) \\ &= \sum_{j=1}^{l}{w_{hj}g_jf'(\alpha_h-\gamma_h)} \\ &= b_h(1-b_h)\sum_{j=1}^{l}{w_{hj}g_j} \end{aligned} </math>eh=−∂bh∂Ek⋅∂αh∂bh=−j=1∑l∂βj∂Ek⋅∂αh∂βjf′(αh−γh)=j=1∑lwhjgjf′(αh−γh)=bh(1−bh)j=1∑lwhjgj
将 <math xmlns="http://www.w3.org/1998/Math/MathML"> g j g_j </math>gj和 <math xmlns="http://www.w3.org/1998/Math/MathML"> ∂ β j ∂ w h j \frac{\partial\beta_j}{\partial w_{hj}} </math>∂whj∂βj代入 <math xmlns="http://www.w3.org/1998/Math/MathML"> ∂ E k ∂ w h j \frac{\partial E_k}{\partial w_{hj}} </math>∂whj∂Ek得到BP算法的 <math xmlns="http://www.w3.org/1998/Math/MathML"> w h j w_{hj} </math>whj的更新公式 <math xmlns="http://www.w3.org/1998/Math/MathML"> ∆ w h j = η g j b h ∆w_{hj}=ηg_jb_h </math>∆whj=ηgjbh ,类似的还有 <math xmlns="http://www.w3.org/1998/Math/MathML"> ∆ θ i = − η g j ∆θ_i=-ηg_j </math>∆θi=−ηgj , <math xmlns="http://www.w3.org/1998/Math/MathML"> ∆ v i h = η e h x i ∆v_{ih}=ηe_hx_i </math>∆vih=ηehxi , <math xmlns="http://www.w3.org/1998/Math/MathML"> ∆ γ h = − η e h ∆γ_h=-ηe_h </math>∆γh=−ηeh .
为什么使用BP算法? 主要有以下几点原因:
- 有效性:该算法能够在多层神经网络中有效地进行训练,通过逐层反向传播误差,使得网络的输出结果逐渐逼近真实值。
- 通用性:BP算法可用于多种类型的神经网络,如多层感知机、卷积神经网络等,具有很强的通用性。
- 优化性能:与其他优化算法相比,BP算法在训练神经网络时通常表现出更好的性能。
需要注意的是,BP算法虽然常用且有效,但并非万能。在某些情况下,如遇到局部最优解、梯度消失等问题时,可能需要结合其他优化技术或算法来进行训练。
4.总结
在神经网络中,每个神经元接收来自其他神经元的输入,然后将这些输入与自身的权重相乘,再通过一个激活函数处理,最后输出一个结果。这个过程会在网络中反复进行,每一层的输出都会作为下一层的输入,直到最后的输出层得出预测结果。
神经网络在训练过程中,会根据预测结果与真实结果的差距调整权重,以便在下一次预测时得出更准确的结果。这个过程通常使用反向传播算法实现,即根据误差反向调整权重。
神经网络的结构和层次可以根据任务的不同进行调整,例如,深度神经网络就是包含多层隐藏层的神经网络。而且,神经网络可以处理各种类型的数据,包括图像、文本和数值数据等,使其在机器学习领域具有广泛的应用。
参考资料
[1] 周志华《机器学习》,第五章5.1、5.2和5.3
[2]【吃瓜教程】《机器学习公式详解》(南瓜书)与西瓜书公式推导直播合集