人工智能发展两大学派:
- 数理学派(代表:支持向量机)
- 仿生学派(代表:神经网络),其核心为模拟人类大脑对于世界的认识【连接主义】
人工神经网络(Artificial Neural Network)
- 起源:1943年,McCulloch - Pitts(MCP)神经元模型
- 数学形式:y=φ(i=1∑mωixi+b)=φ(i=1∑mω⊤x+b);
- 神经元本质为线性组合+非线性变换
感知器(Perceptron)
- 1958年由Frank Rosenblatt提出,由此掀起神经网络的第一次研究热潮。
- 模型描述:
- 输入:若干样本{(xi,yi)}i=1N,其中yi=±1;
- 目标:找到权重ω和偏置b,使yi=sgn(ω⊤xi+b)【类似支持向量机模型】
训练过程
- 随机选择ω和b
- 取一个训练样本(x,y),如果(ω⊤x+b)y<0,那么ω=ω+yx,b=b+y
- 若ω⊤x+b>0,y=−1⟹ω=ω−x,b=b−1
- 若ω⊤x+b<0,y=+1⟹ω=ω+x,b=b+1
注:参数更新可设置学习率α,即ω=ω+αyx,b=b+αy。
- 再取另一个(x,y),回到2,如此循环
- 终止条件:所有样本均不满足2的条件,则退出循环,训练结束。
- Rosenblatt已证明:只要数据线性可分,则感知器算法一定可以收敛(达到终止条件)。
简单证明
设权重向量(包括偏置)为ω~=(ω1),样本为x~=(x1)(保证二者维度相同)。假设存在一个理想分类超平面ω~∗满足{∥ω~∗∥=1yi(ω~∗⊤)xi≥r>0(r为间隔常数),则:
- 当样本被错分时,参数更新:ω~t+1=ω~t+αyix~i,则
ω~∗⊤ω~t+1=ω~∗⊤ω~t+αyiω~∗⊤x~i≥ω~∗⊤ω~t+αr
故迭代T次后,ω~∗⊤ω~T≥Tαr。
- 而权重的模长增长有界:
∥w~t+1∥2=∥w~t∥2+2αyiw~t⊤x~i+α2∥x~i∥2≤∥w~t∥2+α2∥x~i∥2≤∥w~t∥2+α2R2
第一个不等号是因为错分样本yiw~t⊤x~i<0,而第二个不等号则是因为样本范数有界。因此∥ω~T∥2≤Tα2R2。
- 综上可得
Tαr≤ω~∗⊤ω~T≤∥ω~T∥≤TαR⟹T≤r2R2
即经过有限步参数更新后就会到达终止条件。
import numpy as np
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
iris = load_iris() # 数据集
X = iris.data[:100, [0, 1]] # 样本
y = np.where(iris.target[:100] == 0, -1, 1) # 标签
scaler = StandardScaler() # 数据标准化
X = scaler.fit_transform(X)
# 初始化参数
learning_rate = 0.1
w = np.zeros(X.shape[1])
b = 0
# 感知机辅助函数
def sign(x, w, b):
return np.dot(x, w) + b
# 感知机训练
is_wrong = False
epoch = 0
while not is_wrong:
wrong_count = 0
for i in range(len(X)):
xi = X[i]
yi = y[i]
if yi * sign(xi, w, b) <= 0: # 分类错误
w = w + learning_rate * yi * xi
b = b + learning_rate * yi
wrong_count += 1
epoch += 1
if wrong_count == 0:
is_wrong = True
print(f'Training finished after {epoch} epochs!')
可视化:

- 与SVM相比,感知器只是找到了一个可分离样本的线性超平面,总体效果不如支持向量机。
- 但其首次建立了机器学习的算法框架,且每次训练只需要一个样本数据,消耗资源很少,故这种训练方式被保留到了现代深度神经网络的训练过程中。
- 相比之下,支持向量机算法的内存与时间消耗就较大,因而难以处理大规模数据。
前馈(多层)神经网络
- 1969年,人工智能的先驱M.Minsky出版《感知器》一书。在书中,他举了几十个非线性可分的例子(如识别连通图和非连通图,异或问题等),用数学证明其无法用感知器解决。由于Minsky在学术界的地位和影响,其悲观论点影响极大,人工智能陷入第一次寒冬。
- 在第一次AI寒冬中,科学家们仍然不断探索,提出了多层感知机的概念,并尝试将其作用于非线性可分问题中(比如加上非线性映射)。
- 最终,在1986年,Rumelhart、Hinton和Williams提出了反向传播(Back Propagation,BP)算法,使多层神经网络的训练成为可能。
- 一个两层的神经网络示意图如下:
- 其中z1,z2,y为三个神经元,φ(∗)为激活函数。
- 普适逼近定理(Universal Approximation Theorem):如果非线性函数是阶跃函数,那么三层神经网络可以模拟任意的非线性函数。【20世纪90年代初被证明】
简单解释
一种证明思路(不大严谨,实际证明需要结合实分析知识):
- 先证明三层网络可以以任意精度逼近任意紧致区域的指示函数(即解决任意二分类问题);【隐藏层可以形成任意凸多边形区域的组合】
- 然后利用连续函数可以用有限个指示函数的线性组合(如简单函数)一致逼近这一性质证明。
- 下面我们进行前馈神经网络数据传递的推导。首先,我们约定以下记号:
| 记号 |
含义 |
| L |
神经网络的层数 |
| Ml |
第l层神经元的个数 |
| φl(⋅) |
第l层神经元的激活函数 |
| W(l)∈RMl×Ml−1 |
第l−1层到第l层的权重矩阵 |
| b(l)∈RMl |
第l−1层到第l层的偏置 |
| z(l)∈RMl |
第l层神经元的净输入(净活性值) |
| a(l)∈RMl |
第l层神经元的输出(活性值) |
- 那么可以建立以下递推关系:
{z(l)=W(l)a(l−1)+b(l)a(l)=φ(z(l))
约定a(0)=x(即输入),最终输出为a(L)。
反向传播:梯度下降算法
- 对于给定训练集D={x(n),y(n)}n=1N,前馈神经网络在D上的结构化风险函数为
R(W,b)=N1i=1∑NL(y(n),y^(n))+21λ∥W∥F2
其中y^(n)为X(n)经过前馈神经网络后的预测值,∥W∥F2表示矩阵W的Frobenius范数(即所有元素平方和的平方根)。
- 参数更新公式:
W(l)b(l)←W(l)−α∂W(l)∂R(W,b)←b(l)−α∂b(l)∂R(W,b)
- 反向传播梯度计算公式:
∂z(l)∂L∂a(l)∂L∂W(l)∂L∂b(l)∂L=∂a(l)∂L⊙φ′(z(l))=(W(l+1))⊤∂z(l+1)∂L=∂z(l)∂L⋅(a(l−1))⊤=∂z(l)∂L
其中⊙表示逐元素相乘,∂z(l)∂L也称为误差项,记作δ(l)。
- 综上,反向梯度的递推式为:
δ(l)=φl′(z(l))⊙((W(l+1))⊤δ(l+1))
激活函数
按发现/使用时间排序:
- Sigmoid型函数
- Logistic函数:σ(x)=1+e−x1;
- 双曲正切Tanh函数:tanh(x)=ex+e−xex−e−x。
- Sigmoid激活函数也可用于解决二分类问题(放在神经网络最后一层);对于多分类问题,则使用Softmax激活函数Softmax(zi)=∑j=1nezjezi,输出概率式的结果。
- 主要问题:当x较大时,梯度容易消失
- Softplus函数(ReLU函数平滑版本)
Softplus(x)=log(1+ex)
- ReLU函数(Rectified Linear Unit,修正线性单元)【仍然为主流使用】
ReLU(x)={x,x≥00,x<0=max(0,x)
- 优点:计算上更加高效、生物学合理性(单侧抑制、宽兴奋边界)、在一定程度上缓解梯度消失问题;
- 缺点(死亡ReLU问题):神经元在训练过程中可能因输入长期为负,导致其输出恒为0且梯度无法更新,从而永久失去学习能力。
- 带泄露的ReLU函数(Leaky ReLU)
LeakyReLU(x)={x,x>0γx,x≤0=max(0,x)+γmin(0,x)
- ELU(指数线性单元)函数
ELU(x)={x,x>0α(ex−1),x≤0
- 优点:在原点处函数连续,这样能够加快函数收敛。
- 变体1(SELU):对函数整体乘以缩放因子λ,可以使每一层的输出均值和方差能够自动趋于稳定。
- GELU(高斯误差线性单元)函数【BERT,Transformer使用】
GELU(x)=xΦ(x)
其中Φ(⋅)是标准正态分布的累积分布函数。
- 另一个类似的激活函数是Swish函数:Swish(x)=xσ(x)。
深度神经网络及其优化
- 在BP算法提出后不久,SVM的出现加上神经网络梯度消失的问题导致神经网络再次陷入低谷。
- 深度神经网络是层数比较多的神经网络,具有强大的特征提取的能力。但其也面临以下挑战:
- 难以找到最优解
- 存在多个局部最优解(受超参数初始化影响)
- 存在鞍点(不同方向梯度符号不同)
- 可能有平坦局部解,对某些超参数的微小扰动不敏感
- 训练困难
- 训练效果不稳定
- 存在过拟合问题(模型过于复杂,参数量远大于数据量)
- 泛化能力差
优化算法
- 随机梯度下降(Stochastic Gradient Descent,SGD)
- 核心:每次用一小部分数据(称为Mini-batch)更新模型【一个Epoch训练次数=总样本数/batch size】
- 与Batch GD相比,虽然收敛速度慢一些(梯度方向存在噪声),但可以大量节省消耗空间,提高训练效率
- 动量法(Momentum)【让SGD更稳定】
- 核心:给梯度加惯性
- 公式:Δθt=ρΔθt−1−αgt
- 其中gt为第t次梯度,ρ为动量因子(通常设为0.9),α为学习率。
- AdaGrad和RMSProp【解决不同维度梯度大小不同,SGD易走“之字形”的问题】
- 核心:不同维度用不同学习率,梯度大的维度学习率小一点
- AdaGrad:使用之前所有的梯度
Gt=τ=1∑tgτ⊙gτ⟹Δθt=−Gt+ϵα⊙gt
其中Gt为梯度各个分量的平方和组成的向量按时间累积求和。
- RMDProp:只看最近的梯度,采用滑动平均
Gt=βGt−1+(1−β)gt⊙gt=(1−β)τ=1∑tβt−τgτ⊙gτ
其中β为衰减率,一般取0.9。Δθt更新公式同上。
- Adam(Adaptive Moment Estimation):动量法+RMSProp
- 滑动平均:
{Mt=β1Mt−1+(1−β1)gtGt=β2Gt−1+(1−β2)gt⊙gt
- 偏差修正:
⎩⎨⎧M^t=1−β1tMtG^t=1−β2tGt
- 更新:
Δθt=−G^t+ϵαMt^
其他优化方法
- 数据预处理(如Z-score)
- 使不同维度数据范围相同,为参数初始化和训练提供稳定基础
- 参数初始化
- 设d为神经网络某一层的神经元个数,则对这一层的参数(W,b),由以下初始化方法:
- Xavier初始化(适用sigmoid激活函数):从(−d1,d1)中随机取值;
- Kaiming初始化(适用ReLU):从N(0,d2)中随机取值【现代深度学习使用】
- 批量归一化(Batch Normalization)
- 在训练过程中,每一层输出的分布不断变化,后面层需要不断适应,这会导致训练不稳定、收敛慢。我们希望数据落在激活函数最敏感的区域,因此我们把每一层的输出“重新拉回稳定范围”。
- 核心:对每个mini-batch进行标准化:x^=σ^Bx−μ^B【放在线性层z(l)和激活层a(l)之间】
- 但如果每次都做标准化,模型的表达能力可能被限制,故再引入两个参数让模型决定是否对数据进行缩放/平移:y=γx^+β
- 正则化(Regularization)
- 如果模型过于复杂,会导致过拟合。故最简单的方法可以限制参数不要太大。常见正则化方法如下:
- Ridge:使用二阶范数限制,可以让权重尽量小,但不一定为0;
- Lasso:使用一阶范数限制,可把一些权重直接变成0;
- 提前停止(Early Stopping):使用验证集来测试每一次迭代的参数在验证集上是否最优。如果在验证集上的错误率不再下降,就停止迭代
- Dropout:每次SGD更新时以概率p随机移除神经元,对保留神经元的权重乘上1−p1补偿。【相当于训练了很多个子网络,再取平均】
- 2006年,Hinton团队在论文中使用分层预训练有效解决了深层神经网络训练困难的问题,并正式提出“深度学习”这一概念,将神经网络重新拉回大众视野。
- 2012年AlexNet的成功进一步推动深度神经网络的发展,开启深度学习热潮至今。