【西瓜书笔记】——神经网络

本文对应周志华——《机器学习》第五章·神经网络


1、神经元模型

神经网络是由具有适应性的简单单元组成的广泛并行互联的网络,它的组织能够模拟生物神经系统对真实世界物体所做出的交互反应。

神经元模型:是神经网络最基本的成分。当通过神经元的信息信好超过某一个阈值,那么该神经元就会激活,从而作用于下一个神经元。

M-P神经元模型:神经元连接来自收到来自n个其他神经元传递来的输入信号,与权重结合进行传递。神经元将收到的总输入值与阈值进行比较,利用激活函数(e.g Sigmoid)处理后产生输出。

激活函数:最典型的激活函数是阶跃函数,类似分段函数,0表示非兴奋状态,1表示兴奋状态。但阶跃函数不连续、不光滑,无法表达所有数据的活跃性质,因此常常使用sigmoid函数 1 1 + e − θ T x \frac{1}{1+e^{-θ^Tx}} 1+eθTx1来对数据进行处理。从而把较大范围内变化的输入值挤压到(0, 1)输出值范围内。


2、感知机与多层网络

感知机:由两层神经元组成——输入层和输出层。输入层接受外界信好后传递给输出层,输出层是M-P神经元(阈值逻辑单元)。

权重 w i w_i wi和阈值θ可通过学习得到。调整感知机的权重方式如下:
w i ← w i + Δ w i w_i ← w_i + Δw_i wiwi+Δwi
其中, Δ w i = η ( y − y ^ ) x i , η Δw_i = η(y-\hat{y})x_i,η Δwi=η(yy^)xiη被称为学习率,其范围在(0, 1)之间。从公式中不难发现,评判感知机预测正确与否的方式在于 y ^ = y \hat{y}=y y^=y。如果不相等,则根据错误的程度进行权重调整。

但是,感知机只有输出层一层可以进行激活函数处理,学习能力有限,即只能一刀切。对于线性不可分问题或非线性问题,通常采用多层神经元

多层神经网络:输入层和输出层间有隐含层(隐层),隐层和输出层神经元都拥有激活函数,从而将一刀切问题转化为了平面划分问题

多层前馈神经网络:每层神经元与下一层神经元实现全连接,不存在同层连接和跨层连接。所谓的前馈,并非指信号不能向后传递,而是指网络拓扑结构上不存在环路或回路。隐层的作用在于对上一层神经元的输出结果进行信号加工,最终产生结果由输出层神经元输出。换言之,输入层神经元只负责接受数据,而隐层和输出层包涵功能神经元,对数据进行函数处理。(只包含一个隐层的三层神经网络即可称为多层神经网络)。

神经网络的学习过程,就是根据训练数据来调整神经元之间的连接权值和功能神经元的阈值。因此权值和阈值是神经网络的关键。

【*注】阈值相当于神经元内部的关键参数,而权值相当于不同神经元与不同神经元之间相连关系的重要度。


3、误差逆传播算法(反向传播算法-BP)

当网络层级较多时,产生的权值和阈值就会有许多,而调整阈值和权值的方法,就称作反向传播算法。如果说前馈神经网络的目的是为了得到最合适的预测模型,那么反向传播算法的作用就是反向求解,为了得到最合适的权值和阈值

下面模拟一个3层神经网络的处理流程(输入层、隐层、输出层),其中d个输入单元,h个隐层单元,l个输出单元:

Step1:Input d个样例 xd
Step2:α = sum (输入*(输入单元与隐层间的权值) )作为隐层每个单元接收的输入值
Step3:sigmoid(α - 隐层每个单元的阈值),产生隐层输出β
Step4:γ = sum( β* (隐层每个单元与输出层每个单元间的权值) )作为输出层每个单元接收的输入值
Step5:sigmoid(γ - 输出层每个单元的阈值),产生输出的结果y_hat
Step6:采用均方误差法衡量网络模型的性能:误差E = 1/2 * sum((y_hat - y)^2)
Step7:利用BP算法,反向迭代每一轮重新进行估计:新权值/新阈值 ← 权值/阈值 +Δ

以上就是一个多层神经网络的运行过程,Step1 ~ Step6为完整的前向神经网络处理过程,而Step7进入迭代的过程为反向神经网络的处理过程。


BP算法基于梯度下降策略,以目标的负梯度方向对参数进行调整。即对均方误差求解函数,分别对θ、w、λ等进行求导。在给定学习率η的情况下,第k个样例的均方误差函数E有
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 Ek=21j=1l(y^jkyjk)2
而对于sigmoid函数作为激活函数的清空,存在一种特殊规律:
S ′ ( x ) = S ( x ) ⋅ ( 1 − S ( x ) ) S'(x) = S(x)·(1-S(x)) S(x)=S(x)(1S(x))


例如:

1、权值 w w w的校准公式:

Δ w h j = − η ∂ E k ∂ w h j Δw_{hj} = -η\frac{\partial{E_k}}{\partial{w_hj}} Δwhj=ηwhjEk
Δ w h j = − η E ′ Δw_hj = -ηE' Δwhj=ηE。对E就w进行微分计算。经过计算,反向传播算法的校准公式为:
Δ w h j = η y ^ j k ( 1 − y ^ j k ) ( y j k − y ^ j k ) b h Δw_hj = η\hat{y}_j^k(1-\hat{y}_j^k)(y_j^k-\hat{y}_j^k)b_h Δwhj=ηy^jk(1y^jk)(yjky^jk)bh
其中, y ^ j k \hat{y}_j^k y^jk表示第k个样例在输出层第j个神经元上的计算结果


2、输出层阈值 θ θ θ的校准公式:

同样的,以θ为底求导后可得:输出层上第j个神经元的阈值变化为:
Δ θ j = − η ( y ^ j k ( 1 − y ^ j k ) ( y j k − y ^ j k ) ) Δθ_j= -η(\hat{y}_j^k(1-\hat{y}_j^k)(y_j^k-\hat{y}_j^k)) Δθj=η(y^jk(1y^jk)(yjky^jk))


3、连接权 v v v的校准公式

以v为底求导可得:输入层第i个神经元到隐层第j个神经元间的连接权值变化为:
Δ v i h = η b h ( 1 − b h ) x i ∑ j = 1 l w h j y ^ j k ( 1 − y ^ j k ) ( y j k − y ^ j k ) Δv_{ih} = ηb_h(1-b_h)x_i\sum_{j=1}^{l}w_{hj}\hat{y}_j^k(1-\hat{y}_j^k)(y_j^k-\hat{y}_j^k) Δvih=ηbh(1bh)xij=1lwhjy^jk(1y^jk)(yjky^jk)


4、隐层阈值 λ λ λ的校准公式

以λ为底求导可得:隐层第h个神经元内部的阈值变化为:
Δ λ h = − η b h ( 1 − b h ) ∑ j = 1 l w h j y ^ j k ( 1 − y ^ j k ) ( y j k − y ^ j k ) Δλ_h = -ηb_h(1-b_h)\sum_{j=1}^{l}w_{hj}\hat{y}_j^k(1-\hat{y}_j^k)(y_j^k-\hat{y}_j^k) Δλh=ηbh(1bh)j=1lwhjy^jk(1y^jk)(yjky^jk)


学习率η控制着算法每一轮迭代中的更新步长。步长太大容易振荡,而步长太小的话收敛速度又会过慢。有时会使用 η w 、 η θ 、 η λ 、 η v η_w、η_θ、η_λ、η_v ηwηθηληv会使用不同的η来进行梯度下降处理,并非要求η一定要恒定不变,反向传播处理不同的对象时可使用不同的η值。通常设置η=0.1
BP算法的工作流程

	Step1:将输入示例提供给输入层神经元
	Step2:逐层前传信号,知道产生输出层的结果
	Step3:计算输出层的误差
	Step4:将误差逆向传播至隐层神经元
	Step5:根据隐层神经元的误差对连接权值和阈值进行调整
	Step6:迭代循环过程,直到到达某种终止条件。

总而言之,首先需要计算的是 y p r e d i c t y_{predict} ypredict,然后对连接权值、权值、隐层阈值、输出层阈值进行梯度下降计算,达到终止条件后确定各系数,从而得到最优的前馈神经网络

显然,BP算法的目的是要最小化训练集D上的累积误差。正如第k个样例的训练误差为 E k E_k Ek一样,累计误差就是指所有的样例的误差之和 E = 1 m ∑ k = 0 k E k E = \frac{1}{m}\sum_{k=0}^{k}{E_k} E=m1k=0kEk


不过,标准的BP算法一次只能针对一个训练样本更新连接权值和阈值,从而导致其参数更新频繁,且不同样例进行更新的效果可能出现抵消现象。

因此借鉴了该方法得到了基于累计误差最小化的更新规则,即累计误差逆传播。该方法读取整个训练集D一遍后才对参数进行更新,从而节省了计算时间,提升了效率。

【*注】面对庞大的数据计算量时,往往先采用累计误差逆传播方法对参数进行范围上的先处理,当累计误差下降到一定程度后,改用标准BP算法对部分参数进行优化。这样的方式更加合理。


BP神经网络易造成过拟合,因此常用①早停和②正则化两种方式来避免。

早停:将数据集划分成训练集和验证集,其中训练集用来计算梯度、更新连接权和阈值,而验证集则用来估计误差。若训练集误差降低,而验证集误差提升则停止训练,返回最小验证集误差对应的连接权和阈值

正则化:在误差目标函数中增加一个用于描述网络复杂度的部分,例如:
E = δ 1 m ∑ k = 1 m E k + ( 1 − δ ) ∑ i w i 2 E = δ\frac{1}{m}\sum_{k=1}^{m}E_k +(1-δ)\sum_{i}w_i^2 E=δm1k=1mEk+(1δ)iwi2
上述公式中添加了 δ 和 ( 1 − λ ) ∑ i w i 2 δ和(1-λ)\sum_{i}w_i^2 δ(1λ)iwi2来作为描述网络复杂度的部分


4、全局最小与局部极小

利用前馈计算得到的E作为表示神经网络在训练集上的整体误差,显然其是关于连接权值w和阈值θ的函数。而反向传播计算的过程则是一个寻优过程,旨在寻找一组最优参数使E最小

该过程自然就涉及到最优、局部极小和全局最小的求解问题。
局部极小:在某个指定邻域范围内,存在任意E(w,θ)>E(w*,θ*),则称w* 和theta*是局部极小值。
全局最小:在整个样本空间中,最小误差E对应的w和θ值。

显然如果样本空间中,梯度为零,只要其误差函数值小于所有相邻点的值,那么其对应的w和θ必然为局部最小点。因此可能存在多个局部最小点,但全局最小点却唯一

梯度下降法:利用负梯度方向下降速度最快的特点,对整个函数空间进行搜索求最优解。当剃度为零时,则找到一个局部最优点,根据该局部最优点是否唯一,确定其是否为全局最小。

为了避免求得多个局部极小点,从而导致陷入局部极小而无法找到全局最小点的问题,采用如下的启发式策略来应对:
1、采用多组参数值同时初始化神经网络(等于在开局的时候选择不同的参数值来进行模型训练,等于在同一个区域内沿不同方向进行搜索,最终都能找到各自方向上的最优点

2、模拟退火技术。所谓的退火机制,就是指每一步允许出现比当前解更差的结果,接受次优解从而保证算法的稳定。(类似于悔棋,每次将处理步骤退回至前一步,然后沿另一个方向重新搜索

3、使用随机梯度下降。即便到达局部极小点,其也可能因为计算的参数设定、步长等因素,让深陷极小点的函数继续计算,从而从极小点中”爬“出来。


5、常见神经网络模型

5.1 RBF网络

RBF网络(径向基函数网络)是一个单隐层前馈神经网络,使用径向基函数作为隐层激活函数,而输出层则是对隐层神经元输出的线性组合。
φ ( x ) = ∑ i = 1 q w i ρ ( x , c i ) \varphi(x)=\sum_{i=1}^{q}w_i\rho(x,c_i) φ(x)=i=1qwiρ(x,ci)
高斯径向基函数指的是样本x到数据中心ci之间欧式距离的单调函数
ρ ( x , c i ) = e − β i ∣ ∣ x − c i ∣ ∣ 2 ρ(x, c_i) = e^{-β_i||x-c_i||^2} ρ(x,ci)=eβixci2
需要对数据进行聚类处理,从而得到数据中心ci。再利用BP算法求最优w和β。


5.2 ART网络

竞争学习(CL-competitive learning)是神经网络中一种常用的无监督学习策略。网络的输出神经元相互竞争,每一刻仅有一个竞争获胜的神经元被激活,其他神经元状态被抑制

ART(自适应谐振理论)网络是竞争学习的重要代表。该神经网络由1、比较层;2、识别层;3、识别阈值;4、重置模块构成。该网络结构的优点在于可以进行增量学习和在线学习


5.3 SOM网络

SOM-自组织映射网络也是竞争学习无监督神经网络中的一种。它通过将高维输入数据映射到低维空间,保证拓扑结构的同时将高维空间中相似样本点映射到网络输出层中的邻近神经元

SOM的输出层神经元按照矩阵形式排列,每个单元都有一个权向量。目的就是找到最合适的权向量。首先计算样本自身携带的权向量间距,最近的神经元作为最佳匹配单元,然后补断调整邻近神经元的权向量,迭代收敛过程。


5.4 级联相关网络

级联相关网络是结构自适应网络(构造性神经网络)的重要代表。因为其网络结构并非像一般的神经网络一样是预先固定的,而是在不断的计算训练中寻找最优的网络结构。一般开始时网络只有输入层和输出层,但随之可以不断增加隐层的神经单元改善网络结构。该网络的优点在于因为无需提前预设网络层数、隐层但愿数,从而训练速度快,但在数据量较小时易陷入过拟合。


5.5 Elman网络

递归神经网络是指允许网络种出现环形结构,从而让一些神经元的输出反馈回来作为输入信号继续进入网络计算。

Elman网络便是最常用的递归神经网络之一。其结构与多层前馈神经网络类似,但是隐层神经元的输出被反馈回来与下一时刻的输入层神经元提供的信号一起,作为隐层神经元在下一时刻的输入(相当于计算完后的结果再流入隐层计算一遍)。通常也是采用sigmoid函数+BP算法的方法来实现。


5.6 Boltzmann机

Boltzmann机是一种基于能量的模型,该网络层级分为显层(输入和输出)和隐层(数据的内在表达)。其间的神经元都是布尔型,非0即1,设置向量si∈{0, 1}表示某个神经元的状态,也由w和θ分别作为连接权和阈值参数,公式如下:
E ( s ) = − ∑ i = 1 n − 1 ∑ j = i + 1 n w i j s i s j − ∑ i = 1 n θ i s i E(s) = -\sum_{i=1}^{n-1}\sum_{j=i+1}^{n}w_{ij}s_is_j-\sum_{i=1}^{n}θ_is_i E(s)=i=1n1j=i+1nwijsisji=1nθisi


6、常用的激活函数

首先先介绍两种在激活函数选择时常见的问题:

梯度消失:这本质上是由于激活函数的选择导致的, 最简单的sigmoid函数为例,在函数的两端梯度求导结果非常小(饱和区),导致后向传播过程中由于多次用到激活函数的导数值使得整体的乘积梯度结果变得越来越小,也就出现了梯度消失的现象。

梯度爆炸:同理,出现在激活函数处在激活区,而且权重W过大的情况下。但是梯度爆炸不如梯度消失出现的机会多。

6.1 Sigmoid函数

σ ( x ) = 1 1 + e − x \sigma(x) = \frac{1}{1+e^{-x}} σ(x)=1+ex1
目前是最普遍的激活函数,值域在(0, 1)之间。缺点是:1、会产生梯度弥散;2、图像并不能关于原点对称;3、计算e-x时候比较耗时。


6.2 ReLU函数

线性整流函数,也被称为线性修正单元:
【西瓜书笔记】——神经网络_第1张图片
f ( x ) = m a x ( 0 , x ) f(x) = max(0,x) f(x)=max(0,x)
或写为
f ( x ) = { x , x > 0 λ x , x ≤ 0 f(x) =\begin{cases}x, &x> 0 \cr λx, &x≤0\end{cases} f(x)={x,λx,x>0x0
优点:解决部分弥散的问题,且收敛速度较快。
缺点:依旧没有完全解决梯度弥散的问题,且在x<0时的神经元安等于死亡状态无法被利用。

6.2.1 LeakyReLu函数

改造了普通的ReLU函数,避免了x<0时的神经死亡现象:
f ( x ) = m a x ( 0 , x ) + β ∗ m i n ( 0 , x ) f(x)=max(0,x)+β*min(0,x) f(x)=max(0,x)+βmin(0,x)
其中β是一个小的非零数。


6.3 Tanh函数(双曲正切)

【西瓜书笔记】——神经网络_第2张图片
t a n h x = s i n h x c o s h x = e x − e − x e x + e − x tanhx=\frac{sinhx}{coshx}=\frac{e^x-e^{-x}}{e^x+e^{-x}} tanhx=coshxsinhx=ex+exexex
优点:解决了原点不对称的问题,且比Sigmoid快。
缺点:依旧没有解决梯度弥散的问题。


6.4 MaxOUT

提倡使用maxout方法,克服了ReLU的缺点,涉及的参数较多,本质上是在输出结果上又加了一层。
m a x ( w 1 T x + b 1 , w 2 T x + b 2 ) max(w_1^Tx+b_1, w_2^Tx+b_2) max(w1Tx+b1,w2Tx+b2)


代码实现

1.利用keras实现简单的多层前馈神经网络

程序实现:

#利用keras实现

from keras.models import Sequential
#dense用来表示全连接层
from keras.layers import Dense
import numpy as np

#定义一个numpy随机种子函数
np.random.seed(7)

#载入数据集,用delimiter确定以什么符号为分割
dataset = np.loadtxt('路径.csv', delimiter=",")

#读取X和Y
X = dataset[:, 某几列是输入]
Y = dataset[:, 最后一列是标签]

#初始化Sequential模型
model = Sequential()

#【创建隐层】包含16个隐含单元,激活函数为ReLU,input_dim为输入维度
model.add(Dense(16, input_dim=8, init='uniform', activation='relu'))

#【创建隐层】包含8个隐含单元,激活哈数为ReLU
model.add(Dense(8, init='uniform',activation='relu'))

#【创建输出层】
model.add(Dense(1, init='uniform',activation='sigmoid'))



#定义模型的损失函数类型、标准化过程、评判标准
model.compile(loss='binary_crossentropy', optimizer = 'adam', metrics=['accuracy'])

#开始拟合/训练模型,定义迭代周期150次
model.fit(X, Y, nb_epoch=150, batch_size=10)

scores = model.evaluate(X, Y)

print('%s:%.2f%%' % (model.metrics_names[1], scores[1] * 100))

你可能感兴趣的:(西瓜书)