![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=1739115786-7q5PyQViHgbCLM4LxXCwrT2sL8mLklOC-0-d133f3b253b75409defa932d3575e34b)
图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=1739115786-j5xGoDqSjOjfqp19njxcMGjer8mpm91n-0-c5a81a8853630e71623c4e6edb8d3814)
(2)产生随机随机数的输入数据,输出二维数据。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P51_3405.jpg?sign=1739115786-sL1dDnj8USeRbBAP5Y2AsFvoo8G5mLFj-0-f310054f25bf8bc116e0261e2e753ccf)
(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=1739115786-HXBPl7dS47zAhSE43uHNijstWnd8UNai-0-cae4f931b4c93efe4d5cc2d2ab7ebd89)
(4)神经层计算:未训练Linear就是执行矩阵内积,维度(128, 20) @ (20, 30)=(128, 30)。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P52_3437.jpg?sign=1739115786-ovBY6rEQGYDVCAzFVAtT7L6xOf1sMxT0-0-c89f8e2c16ec39993dec0601987817fa)
执行结果:torch.Size([128, 30])。
再测试Bilinear神经层,Bilinear有两个输入神经元个数,转换为
(1)建立神经层。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P52_3445.jpg?sign=1739115786-YQ5o6BzrlMqslhq9C7EAnN4SvPjQzwp6-0-6f0e7789b0f17b1b7891ab8796e9c366)
(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=1739115786-fNhB2SyPD39mXWiqMcVuWx2aPVkyi5ha-0-a5ec7192b27912ff7aef44f7f96e7f34)
执行结果: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=1739115786-9NpRpYdMBMKFjieeBQrDz0sfVnaqsSTQ-0-860e8f399359ace53df4389b23158680)
(2)产生随机数据,与上一节范例相同。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P52_3466.jpg?sign=1739115786-hZi0rVEa4qxkkvaIpa2MsGpfuFxNUDY6-0-ea45d6e5599ee686aeee4652e0eb1f1c)
(3)定义模型函数:导入神经网络模型,简单的顺序型模型内含Linear神经层及扁平层(Flatten),扁平层参数设定哪些维度要转成一维,设定范围参数为(0, -1)可将所有维度转成一维。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P52_3473.jpg?sign=1739115786-0AdeTBC63mOvWwJjHdWMpp58qz8VSghe-0-23afc9cd5aae78ab7727788cdff117e4)
测试扁平层如下,Flatten()预设范围参数为(1, -1),故结果为二维,通常第一维为笔数,第二维为分类的预测答案。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P53_3493.jpg?sign=1739115786-xs5XpkgVFkNLpgubVkDQ2SQ9qYaYx1eY-0-5851dc6c4f06e66e6136a20314c7e1c7)
执行结果: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=1739115786-IIyHph9P8tRyjzfeRU8awOdvLKxqvgTM-0-a54e7cb40153ce627e85d45038eedaf9)
(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=1739115786-TQnKVWoK7DRZga5SSCUpjCTCeTSwVBUU-0-ab4eae0d54192eede3832c026508e329)
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P53_3512.jpg?sign=1739115786-iMXSU39uO4qRhz3EQIzEaj0Yy8kql4Qx-0-cea29bb666dc031ffb1d4d2d68e155e7)
(6)执行训练。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P53_3519.jpg?sign=1739115786-VYQuwMMi6iB2hihayRHGJ9NtKbyVBwLt-0-8647bc99c0820d1d8628dd27ba407e3c)
执行结果:w=0.847481906414032, b=3.2166433334350586。
(7)以NumPy验证。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P54_3539.jpg?sign=1739115786-TTnbzBEkvgaeyzc9UHIes9vgiXpo6XDj-0-05eb5a3b4eaf6657c79d7a1d29312f43)
执行结果与答案非常相近。
w=0.8510051491073364, b=4.517198474698629。
(8)显示回归线。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P54_3546.jpg?sign=1739115786-vj7PR6TL7uXVcdjB4qprKrfWywrRYZST-0-aa856d8f309261dd4182a2964335e92b)
执行结果。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P54_3553.jpg?sign=1739115786-xqaLkGL0uyp8cpAW4fKhTvDMu84S51V4-0-87360bfb9be80117f982b304cc478967)
(9)NumPy模型绘图验证。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P54_3556.jpg?sign=1739115786-bNpD23dSFPnk1ZmAVLgBBGSpwmccSEKQ-0-b6221e8a2bdd5b544418357ded61c51f)
执行结果非常相近。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P54_3563.jpg?sign=1739115786-6TMulgKqJ2dIeRfnfWY3l4vUJGOiGxtc-0-abf4046104187816bb511fcf51cfad68)
(10)损失函数绘图。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P54_3566.jpg?sign=1739115786-Cpd2bShT3ezZ0YzQ2SGEb7nmkTkKgLcK-0-ff10ed1f832e6f4753ad638f740aa837)
执行结果:在第25个执行周期左右就已经收敛。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P55_3586.jpg?sign=1739115786-1P5V3x8VjooEvd1DwS21ryJBk3ojgE0R-0-2396b1a1044f724d2d17d3baa3a0882d)
范例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=1739115786-6Jy2JUa9QEjrnfOktfM07QQcQs0I6LsF-0-f4021809eb1d57cdc834d9364911012b)
(2)训练结果与范例2相同,注意,若出现w或b=nan,损失等于无穷大(inf),表示梯度下降可能错过最小值,继续往下寻找,碰到这种情况,可调低学习率。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P56_3609.jpg?sign=1739115786-cGiy9WKPLxHsTkX2oWCb3FGSjTbiCd0x-0-59ec6e94652017ed609eadd306ffa670)
范例4.除了回归之外,也可以处理分类(Classification)的问题,数据集采用Scikit-Learn套件内建的鸢尾花(Iris)。
下列程序代码请参考【03_07_IRIS分类.ipynb】。
(1)载入套件。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P56_3612.jpg?sign=1739115786-yu2XjdTyhoZhyN3EBubLrv5G90Hb0f3F-0-2e81fdcf60840feeea59f0fbf469d7f5)
(2)载入IRIS数据集:有花萼长/宽、花瓣长/宽共4个特征。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P56_3619.jpg?sign=1739115786-rKkyJfQeDqITpq0ivtkMUWYE30FmjfaT-0-ed675c8b3fed51ca13eee717c19b5ca2)
执行结果。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P56_3626.jpg?sign=1739115786-Eg18vfkusqNtccNiK68c8ZRFlpN0eloH-0-370414aba8f3644c3dfa909cfe04f93a)
(3)数据分割成训练及测试数据,测试数据占20%。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P56_3633.jpg?sign=1739115786-B4PfTnWdLnjOKGEz7hKImDoQ6yogLnMp-0-b8a988b1e056f037d1a0cef91aa9b069)
(4)进行one-hot encoding转换:y变成3个变量,代表3个品种的概率。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P56_3640.jpg?sign=1739115786-R1MgxMDUK8hWQH27QuUIRdVizJLmJe3W-0-a9343c268c31472745a0c7d6475bc91f)
也可以使用PyTorch函数。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P56_3647.jpg?sign=1739115786-20MX3k3j2SC0wKUhH3eOooy5z4G0Pfxs-0-9e87fb9e1ecf78cdc26869a915babe5a)
(5)转成PyTorch Tensor。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P57_3667.jpg?sign=1739115786-JA4GfGQ80XdO6nMZOWMhCMKo0J78pw60-0-c5bcc2dff7cab73589165f3d94bf76b2)
(6)建立神经网络模型。
Linear(4, 3):4个输入特征;3个品种预测值。
Softmax激励函数会将预测值转为概率形式。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P57_3674.jpg?sign=1739115786-l1nknwmgpChe93zO2JqD7ngfUrter7fy-0-ce42e7afa72af756dd200ad0c13cd120)
(7)定义损失函数、优化器:与之前相同。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P57_3681.jpg?sign=1739115786-iLgkgNrmFwyJJamE3UQ1TbHNAk43Xjv4-0-675a4cf8aacd025be97e0d17f151debc)
(8)训练模型:第9~10行比较实际值与预测值相等的笔数,并转为百分比。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P57_3688.jpg?sign=1739115786-YkaDBxN0Twj3UZBtOK2aQLex5XYXQpYD-0-a369acf7f42992b6be8ae508469c79dc)
(9)绘制训练过程的损失及准确率趋势图。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P57_3695.jpg?sign=1739115786-7xffGgUNptgVkD8LYLpl9W9GSAFBWetb-0-8916ff9d9ce94cbdcdd2b231b204b61c)
执行结果:在第400个执行周期左右就已经收敛。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P58_3715.jpg?sign=1739115786-hWGiBFqFlm405YKKklntKeN25i1WZWZv-0-f96186fd7bad111f55e54f6311c2958c)
(10)模型评估:评估测试数据的准确度。
![](https://epubservercos.yuewen.com/128DEE/31397898903670606/epubprivate/OEBPS/Images/Figure-P58_3718.jpg?sign=1739115786-XVrJ58b57y7kds3DnF7hCMhEz23II0SF-0-2e4a8ae47476e8a33f1586da824457a2)
执行结果:准确率100%,不过,数据分割是随机抽样,每次结果均不相同。