前馈神经网络
《Python机器学习与项目实践》
XXX大学
《 Python机器学习与项目实践》 2
教学内容
概念
基本特征
网络模型
应用分析
《 Python机器学习与项目实践》 3
机器学习 ≈ 构建一个映射函数
“猫”
“你好”
“5-5”
“今天天气真不错”“你好”
用户输入 机器
(落子位置)
语音识别
图像识别
围棋
对话系统
《 Python机器学习与项目实践》 4
神经元与感知机
一个生物的神经元的结构分为细胞体和突起两部分,具有联
络和整合输入信息并输出信息的作用。突起包含树突和轴突,
树突用来接收其他的神经元传递过来的信号,其一端连接轴
突用来给其他的神经元传递信号,轴突的末端连接到其他神
经元的树突或轴突上。神经元结构图
感知机的工作原理
《 Python机器学习与项目实践》 5
激活函数
激活函数(Activation Function)是在神经网络中的神经元
上运行的函数,负责将神经元的输入映射到输出端。
激活函数在神经元中是非常重要的。为了增强神经网络的表
示能力和学习能力,激活函数需要具备以下几点性质。
(1)连续可导(允许少数点上不可导)的非线性函数。可
导的激活函数可以直接利用数值优化的方法来学习网络参数。
(2)激活函数及其导数要尽可能的简单,这样有利于提高
网络计算效率。
(3)激活函数的导数的值域要在一个合适的区间内,不能
太大也不能太小,否则会影响训练的效率和稳定性。
《 Python机器学习与项目实践》 6
Sigmoid函数
Sigmoid函数连续且光滑,严格单调,关于(0,)中心对称,
可以将变量映射到(0,1)之间,是一个非常良好的阈值函数。
Sigmoid函数作为激活函数有以下优缺点。
优点:平滑、易于求导。
缺点:
①Sigmoid函数极容易导致梯度消失问题。假设神经元输入Sigmoid函数的值特别大或特别小,那
么对应的梯度约等于0,即使从上一步传导来的梯度较大,该神经元权重和偏置的梯度也会趋近
0,导致参数无法得到有效更新。
②计算费时。在神经网络训练中,常常要计算Sigmoid函数的值,进行幂计算会导致耗时增加。
③Sigmoid函数不是关于原点中心对称的(Zero-centered)。
《 Python机器学习与项目实践》 7
Tanh函数
Tanh函数作为激活函数有以下优缺点。
优点:①平滑、易于求导。②解决了Sigmoid函数收敛变慢
的问题,相对于Sigmoid函数提高了收敛速度。
缺点:①梯度消失问题依然存在。②函数值的计算复杂度高,
是指数级的。
《 Python机器学习与项目实践》 8
ReLU函数
优点:①相比于Sigmoid函数的两端饱和,ReLU函数为左饱和函数,且在x> 0时
导数为1,这在一定程度上缓解了神经网络的梯度消失问题。②没有复杂的指数
运算,计算简单、效率提高。③收敛速度较快,比Sigmoid函数和Tanh函数快很
多。④单侧抑制、宽兴奋边界使得ReLU函数比Sigmoid函数更符合生物学神经激
活机制。
缺点:①输出是非零中心化的,给后一层的神经网络引入偏置偏移,会影响梯
度下降的效率。②ReLU神经元在训练时比较容易“死亡”。
《 Python机器学习与项目实践》 9
Swish函数
Swish函数的主要优点如下。
(1)Swish函数的无界性有助于防止在慢速训练期间梯度
逐渐接近0并导致饱和。
(2)Swish函数的平滑度在优化和泛化中起了重要作用。
《 Python机器学习与项目实践》 10
Softmax函数
Softmax函数常在神经网络输出层中充当激活函数,将输出
层的值通过激活函数映射到(0,1)区间,当前输出可以看作属
于各个分类的概率,从而用来进行多分类。Softmax函数的
映射值越大,则真实类别的可能性越大。
《 Python机器学习与项目实践》 11
前馈神经网络结构
前馈神经网络也经常称为多层感知机(Multi-Layer
Perceptron,MLP),但多层感知机的叫法并不十分合理。
因为前馈神经网络其实是由多层的逻辑回归模型(连续的非
线性函数)组成的,而不是由多层的感知机(不连续的非线
性函数)组成的。
前馈神经网络的结构
《 Python机器学习与项目实践》 12
通用近似定理
神经网络最有价值的地方可能在于,它可以在理论上证明:
一个包含足够多隐藏层神经元的多层前馈神经网络,能以任
意精度逼近任意预定的连续函数。这个定理即通用近似定理
(Universal Approximation Theorem)。这里的Universal也
有人将其翻译成“万能的”。
《 Python机器学习与项目实践》 13
应用到机器学习
根据通用近似定理,神经网络在某种程度上可以作为一个“
万能”函数来使用,可以用来进行复杂的特征转换,或者近
似一个复杂的条件分布。
在机器学习中,输入样本的特征对分类器的影响很大。
以监督学习为例,好的特征可以极大提高分类器的性能。
《 Python机器学习与项目实践》 14
参数学习
在神经网络的学习中,需要寻找最优参数(权重和偏置),
即寻找使损失函数的值尽可能小的参数。为了找到使损失函
数的值尽可能小的参数,首先需要计算参数的梯度(导数),
然后以这个导数为指引,逐步更新参数的值。
《 Python机器学习与项目实践》 15
反向传播算法
反向传播(BackPropagation,BP)算法是目前用来训练神
经网络的常用且有效的算法。反向传播算法的主要思想是:
将训练集数据输入神经网络的输入层,经过隐藏层,最后到
达输出层并输出结果,这是神经网络的前向传播过程。
《 Python机器学习与项目实践》 16
梯度计算
前面已经介绍了神经网络的最终目标,即使所定义的损失函
数的值达到最小。为了使损失函数的值最小,常使用的核心
方法是“梯度法”。
复合函数 的计算图
《 Python机器学习与项目实践》 17
梯度计算
《 Python机器学习与项目实践》 18
网络优化
神经网络的参数学习比线性模型更加困难,当前神经网络模
型的难点主要如下。
(1)优化问题。神经网络模型是一个非凸函数,再加上在
深度神经网络中的梯度消失问题,很难进行优化。另外,深
层神经网络一般参数比较多,训练数据也比较多,这会导致
训练的效率比较低。
(2)泛化问题。因为神经网络的拟合能力强,反而容易在
训练集上产生过拟合。因此在训练深层神经网络时,需要通
过一定的正则化方法来改善网络的泛化能力。
《 Python机器学习与项目实践》 19
优化算法
1.批量梯度下降(Batch Gradient Descent,BGD)
2.随机梯度下降(SGD)
3.小批量梯度下降
《 Python机器学习与项目实践》 20
应用实例
向读者介绍前馈神经网络模型在PyTorch中的简单构建。
关于数据集的准备,本节的示例中使用手写数字的MINIST
数据集。该数据集包含60000个用于训练的示例和10000个用
于测试的示例。
这些数字已经过尺寸标准化并位于图像中心,图像是固定大
小的(28像素×28像素),其值为0~10。
为简单起见,每个图像都被展平并转换为784(28×28)个
特征的一维NumPy数组
《 Python机器学习与项目实践》 21
应用实例
代码实现如下。
1.import torch
2.import as nn
3.import torchvision
4.import as transforms
5.# 配置
6.device=('cuda' if _available() else 'cpu')
7.# 超参数
8.input_size=784
9.hidden_size=500
10.num_classes=10
11.num_epochs=5
12.batch_size=100
13.learning_rate=
14.
15.# 数据集
16.train_dataset=(root='../../data',
17. train=True,
18. transform=(),
19. download=True)
20.
21.test_dataset=(root='../../data',
《 Python机器学习与项目实践》 22
应用实例
22. train=False,
23. transform=())
24.
25.# 引入数据集
26.train_loader=(dataset=train_dataset,
27. batch_size=batch_size,
28. shuffle=True)
29.
30.test_loader=(dataset=test_dataset,
31. batch_size=batch_size,
32. shuffle=False)
33.
34.# 全连接层
35.class NeuralNet():
36. def __init__(self,input_size,hidden_size,num_classes):
37. super(NeuralNet,self).__init__()
38. =(input_size,hidden_size)
39. =()
40. =(hidden_size,num_classes)
《 Python机器学习与项目实践》 23
应用实例
41.
42. def forward(self,x):
43. out=(x)
44. out=(out)
45. out=(out)
46. return out
47.
48.model=NeuralNet(input_size,hidden_size,num_classes).to(device)
49.
50.# 损失与优化
51.criterion=()
52.optimizer=((),lr=learning_rate)
53.
54.# 训练模型
55.total_step=len(train_loader)
56.for epoch in range(num_epochs):
57. for i,(images,labels) in enumerate(train_loader):
58. # Move tensors to the configured device
59. images=(-1,28 * 28).to(device)
60. labels=(device)
《 Python机器学习与项目实践》 24
应用实例
61.
62. # 前向传播和计算损失
63. outputs=model(images)
64. loss=criterion(outputs,labels)
65.
66. # 反向优化
67. _grad()
68. ()
69. ()
70.
71. if (i + 1) % 100 == 0:
72. print('Epoch [{}/{}],Step [{}/{}],Loss: {:.4f}'
73. .format(epoch + 1,num_epochs,i + 1,total_step,()))
74.
《 Python机器学习与项目实践》 25
应用实例
75.# 测试
76.# In test phase,we don't need to compute gradients (for memory efficiency)
77.with _grad():
78. correct=0
79. total=0
80. for images,labels in test_loader:
81. images=(-1,28 * 28).to(device)
82. labels=(device)
83. outputs=model(images)
84. _,predicted=(,1)
85. total += (0)
86. correct += (predicted == labels).sum().item()
87.
88. print('Accuracy of the network on the 10000 test images: {} %'.format(100 * correct / total))
89.
90.# 保存
91.(_dict(),'')