![PyTorch深度学习应用实战](https://wfqqreader-1252317822.image.myqcloud.com/cover/410/52842410/b_52842410.jpg)
3-4 神经网络层
上一节运用自动微分实现一条简单线性回归线的求解,然而神经网络是多条回归线的组合,并且每一条回归线可能需再乘上非线性的Activation Function,假如使用自动微分函数逐一定义每条公式,层层串连,程序可能需要很多个循环才能完成。所以为了简化程序开发的复杂度,PyTorch直接建构了各种各样的神经层(Layer)函数,可以使用神经层组合神经网络的结构,我们只需要专注在算法的设计即可,轻松不少。
神经网络是多个神经层组合而成的,如下图,包括输入层(Input Layer)、隐藏层(Hidden Layer)及输出层(Output Layer),其中隐藏层可以有任意多层,广义来说,隐藏层大于或等于两层,即称为深度(Deep)学习。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P51_3390.jpg?sign=1739560874-ZZSWVpqqcOjJPld4ciXliuicofaVrCYr-0-5da431294802239e1449a73492b90b74)
图3.11 神经网络示意图
PyTorch提供十多类神经层,每一类别又有很多种神经层,都定义在torch.nn命名空间下,可参阅官网说明[2]。
首先介绍完全神经层(Linear Layers),参阅图3.11,即上一层神经层的每一个神经元(图中的圆圈)都连接到下一层神经层的每一个神经元,所以也称为完全连接层,又分为Linear、Bilinear、LazyLinear等,可参阅维基百科[3],接下来开始实操完全连接层。
范例1.进行试验,熟悉完全连接层的基本用法。
下列程序代码请参考【03_04_完全连接层.ipynb】。
(1)载入套件。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P51_3398.jpg?sign=1739560874-NYxdlWA8WcPgCRLhiN6WEneaBx1zLEGv-0-c5c37134da6858e48cb49af8ab20443d)
(2)产生随机随机数的输入数据,输出二维数据。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P51_3405.jpg?sign=1739560874-qEvJrp0vxTfNbtOfUbfQd4sxWFTBzFWv-0-c12aaff50cf1c1d2355db5ecc82a1803)
(3)建立神经层,Linear参数依次为:
输入神经元个数。
输出神经元个数。
是否产生偏差项(bias)。
设备:None、CPU(‘cpu’)或GPU(‘cuda’)。
数据类型。
Linear神经层的转换为y=xAT+b,y为输出,x为输入。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P52_3430.jpg?sign=1739560874-D6MQK7n8zFIrQ7xlSHqdmYP7TQdCN9Cn-0-13953c41e6dc5f88647c30c7454f9707)
(4)神经层计算:未训练Linear就是执行矩阵内积,维度(128, 20) @ (20, 30)=(128, 30)。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P52_3437.jpg?sign=1739560874-QTmCKSfgRIW7ENZfYYbHjqBhN2SggHOw-0-ba521f11ae7d83c7941493b0a64f0a06)
执行结果:torch.Size([128, 30])。
再测试Bilinear神经层,Bilinear有两个输入神经元个数,转换为
(1)建立神经层。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P52_3445.jpg?sign=1739560874-h5G2jKVkgMcZbr6BJiJlBQJuQvOTcyeH-0-e52f71daf9d5c9eec2234fb93f31173e)
(2)Bilinear神经层计算:未训练Linear就是执行矩阵内积,维度(128, 20) @ (20,40)+(128, 30) @ (20, 40)=(128, 40)。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P52_3452.jpg?sign=1739560874-n8AQB8RIInozaRHdKlfOgpD6yvSTJWDS-0-f63dc9fd891d18769d142db37d289ec4)
执行结果:torch.Size([128, 40])。
范例2.引进完全连接层,估算简单线性回归的参数w、b。
下列程序代码请参考【03_05_简单线性回归_神经层.ipynb】。
(1)载入套件。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P52_3459.jpg?sign=1739560874-8NeVySxLzJK6c87eGYD53bsrjSHfxtIg-0-3df5be53ad82f2c88ed3f29cde42bd96)
(2)产生随机数据,与上一节范例相同。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P52_3466.jpg?sign=1739560874-KYWwps3P4Tc6W9Sb7R1nHI8w6kJyuXEX-0-a97edf0eeaca941a679e8c02effed832)
(3)定义模型函数:导入神经网络模型,简单的顺序型模型内含Linear神经层及扁平层(Flatten),扁平层参数设定哪些维度要转成一维,设定范围参数为(0, -1)可将所有维度转成一维。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P52_3473.jpg?sign=1739560874-a98wLjEb6KEjmtEnsA7TqHgAMt6ggHij-0-fb78c8422e3910fe116a7982f8ceb89a)
测试扁平层如下,Flatten()预设范围参数为(1, -1),故结果为二维,通常第一维为笔数,第二维为分类的预测答案。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P53_3493.jpg?sign=1739560874-VPo8NP6Q3plLJyDEkD5oDC0oY8nn3y9x-0-1d87e6679b2ce50e3035442821594264)
执行结果:torch.Size([32, 288])。
(4)定义训练函数。
定义模型:神经网络仅使用一层完全连接层,而且输入只有一个神经元,即x,输出也只有一个神经元,即y。偏差项(bias)默认值为True,除了一个神经元输出外,还会有一个偏差项,设定其实就等于y=wx+b。
定义损失函数:直接使用MSELoss函数取代MSE公式。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P53_3500.jpg?sign=1739560874-AK6GBlhIQXF5sQlFcZe2AnUdwuUj3KGP-0-fd0a7ed6406243a3ea50f0d6eaae74a9)
(5)使用循环,反复进行正向/反向传导的训练。
计算MSE:改为loss_fn(y_pred, y)。
梯度重置:改由model.zero_grad()取代w、b逐一设定。
权重更新:改用model.parameters取代w、b逐一更新。
model[0].weight、model[0].bias可取得权重、偏差项。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P53_3507.jpg?sign=1739560874-dnTFUUora8cRu5iV0fUQGO2CwYGhgsb2-0-90391d42da8ee2fc5d48bf381a653c8f)
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P53_3512.jpg?sign=1739560874-MtxyqHkwZo8uKZZ2NEjd5byLcc22gSjF-0-66b52ab38b9ef5203328ab3684404841)
(6)执行训练。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P53_3519.jpg?sign=1739560874-fov5q36yiRcOw0kkjY31gUtzpBvirs37-0-ed5f5d37145ab347498b0a9ed1cf81d4)
执行结果:w=0.847481906414032, b=3.2166433334350586。
(7)以NumPy验证。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P54_3539.jpg?sign=1739560874-2aROMGTpFhbX38NcJ1xziK8NdKwFs9Xc-0-5d1f6656a20c74bdf74a594e9f5a4c3e)
执行结果与答案非常相近。
w=0.8510051491073364, b=4.517198474698629。
(8)显示回归线。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P54_3546.jpg?sign=1739560874-AXuZELtZHREkPutJl3t7m8e8ftqKWriA-0-1e3918fde7d6aa085cdd2882a33036e0)
执行结果。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P54_3553.jpg?sign=1739560874-WyMaveCDdWm4YAeSezGsXQ5Qyp4XELs3-0-64fdaee608c03c72ffabee71c935f47b)
(9)NumPy模型绘图验证。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P54_3556.jpg?sign=1739560874-m0jryIulfKE80sPlt515FMWGQtxDoZiD-0-95cc9c95d244fb02699f5357f31d9310)
执行结果非常相近。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P54_3563.jpg?sign=1739560874-bM3eNua0taVUyFnAxqqbnrLSCg9d3G2q-0-ae7baea152e18d9e039cd012948fc62b)
(10)损失函数绘图。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P54_3566.jpg?sign=1739560874-06WeiZ3GsnxUt63HsW7QFAOM1KGSPDnS-0-143c2b0b616dc0d0df91d58364464c89)
执行结果:在第25个执行周期左右就已经收敛。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P55_3586.jpg?sign=1739560874-qfwjIY2rLwDoKPSsdxY2dD0KUOkJ442w-0-31507c35198132405b07e20458d67699)
范例3.接着我们再进一步,引进优化器(Optimizer),操控学习率,参阅图3.9。
这里仅列出与范例2的差异,完整程序请参见程序【03_06_简单线性回归_神经层_优化器.ipynb】。
(1)定义训练函数。
定义优化器:之前为固定的学习率,改用Adam优化器,会采取动态衰减(Decay)的学习率,参见第8行。PyTorch提供多种优化器,第4章会详细说明。
梯度重置:改由优化器(Optimizer)控制,optimizer.zero_grad()取代model.zero_grad(),参见第19行。
权重更新:改用optimizer.step()取代,w、b逐一更新,参见第25行。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P55_3589.jpg?sign=1739560874-EnmLR6FRN5L2jIpcs39m92HqU8bQP1t7-0-8605af4e2d876e7b680e374e9afd3bbb)
(2)训练结果与范例2相同,注意,若出现w或b=nan,损失等于无穷大(inf),表示梯度下降可能错过最小值,继续往下寻找,碰到这种情况,可调低学习率。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P56_3609.jpg?sign=1739560874-8UA5Q82xudebTQqHqIizKuuA1LdM2r3O-0-12559de974c6e9891c7853c384ee6689)
范例4.除了回归之外,也可以处理分类(Classification)的问题,数据集采用Scikit-Learn套件内建的鸢尾花(Iris)。
下列程序代码请参考【03_07_IRIS分类.ipynb】。
(1)载入套件。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P56_3612.jpg?sign=1739560874-W4nPIXeROKZE7OXFf61f0aDt3R1Q75UL-0-5847b69e4891360439e3ca775b440727)
(2)载入IRIS数据集:有花萼长/宽、花瓣长/宽共4个特征。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P56_3619.jpg?sign=1739560874-tIElwm0ymVrIHESZTgf5iXtejpGUzqh2-0-c2aff35d99bb34e3ae9a69b350de9065)
执行结果。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P56_3626.jpg?sign=1739560874-KpRqI44wSzRAfuHvHTz2yx2qeptqM62U-0-79be11763e50fae3a2444d95fade9c5f)
(3)数据分割成训练及测试数据,测试数据占20%。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P56_3633.jpg?sign=1739560874-LyhXFzWpBGZ6myLCJ2l2RZSt8n1hM7lN-0-c76faa197dca4c396018ec3b0b26ab66)
(4)进行one-hot encoding转换:y变成3个变量,代表3个品种的概率。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P56_3640.jpg?sign=1739560874-Vc53HYuX2EDWDzMTSUeqluhH8vKbJ7Ys-0-789017c1d057f2dd8ab420420b0e0654)
也可以使用PyTorch函数。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P56_3647.jpg?sign=1739560874-5W7ywNS7NVWCOQURHc4AkXbGdkzH8axm-0-e45ad5bfa06fa2793a9e8f20d6de776e)
(5)转成PyTorch Tensor。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P57_3667.jpg?sign=1739560874-cqV1D0Qginuu7ETu703LCygVeRksJvQS-0-c2ba8c25a2d7aadf798d843aed932db9)
(6)建立神经网络模型。
Linear(4, 3):4个输入特征;3个品种预测值。
Softmax激励函数会将预测值转为概率形式。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P57_3674.jpg?sign=1739560874-hcPWOlPIObOFmqW7nzwprLNdqCDTOgoj-0-1478944cbb380fd112cdf26395c7718f)
(7)定义损失函数、优化器:与之前相同。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P57_3681.jpg?sign=1739560874-TRpz0V7Y2dvlhIytWXpPY1PVyzKZ795P-0-9d6e8817b118984ab568620797414355)
(8)训练模型:第9~10行比较实际值与预测值相等的笔数,并转为百分比。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P57_3688.jpg?sign=1739560874-kXz0GAEWX2YLLP74yIF5rM5PaJp6oNkw-0-d8d4498acc914d3863436455c58d01da)
(9)绘制训练过程的损失及准确率趋势图。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P57_3695.jpg?sign=1739560874-Bdg4bb1AUNlMySreRozdQkWwEoBbGyKS-0-dfc774443981c4fbb875369f586b6bc5)
执行结果:在第400个执行周期左右就已经收敛。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P58_3715.jpg?sign=1739560874-EIKVHE1imwQIuGv7kU1HN9OVK6xiaLM9-0-ac2b2ce1bd2d02add06ead5ae33b3e9e)
(10)模型评估:评估测试数据的准确度。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P58_3718.jpg?sign=1739560874-7MNLYUTYEv2lMktLFvVUUpjYgi6ZTTi8-0-92d97f744ddbc2ffa6b37726f730d456)
执行结果:准确率100%,不过,数据分割是随机抽样,每次结果均不相同。