神经网络包torch.nn
torch.nn是专门为神经网络设计的模块化接口。nn构建于Autograd之上,可以用来定义和运行神经网络。在使用torch.nn时,我们一般使用如下语句进行相关包的引入,并将torch.nn命名为nn作为别名使用。
import torch.nn as nnimport torch.nn.functional as F
除此之外,我们同时引入了nn.functional包,并将其命名为F作为别名使用。nn.functional中包含了神经网络中常用的一些函数(不具有可学习的参数,如ReLU、pool、DropOut等),这些函数可以放在构造函数中,但一般我们不建议放。
自定义一个神经网络
PyTorch中有现成的网络模型,使用时只需要继承nn.Module,并实现它的forward( )方法即可。PyTorch会根据Autograd自动实现backward( )函数。
![cb8e6b3acaff159ee8848ac299418725.png](https://i-blog.csdnimg.cn/blog_migrate/8cb8406c29a8f9107c7fe8ee587e357d.jpeg)
自定义神经网络
继承自nn.Module的子类必须在构造函数中执行父类的构造函数。上述MyNet类的构造函数中分别定义了一个卷积层(conv1d)和一个线性层(f)。其中,卷积层输入通道数为1,输出通道数为6,卷积核大小为3x3;线性层输入特征数为1350,输出特征数为10。
接着实现正向传播函数forward( ),在forward( )函数中主要做了卷积、激活与池化的工作。该函数包含了一些参数的计算方式以及卷积神经网络的概念,后续再详细介绍。
使用该自定义的神经网络,只需要创建对应的对象即可。
![58d1d146a23acd986980b18fc5e3a685.png](https://i-blog.csdnimg.cn/blog_migrate/ab64f42bb6a5c41bec50d80641799e41.jpeg)
实例化自定义神经网络
可以通过该对象的paramters( )方法查看该神经网络的所有可学习参数。
![cd80cf8acf9b753139b2f418a6d1aa1b.png](https://i-blog.csdnimg.cn/blog_migrate/63974d0d82b18b1487267b4aacc7850c.jpeg)
paramters( )方法
通过该对象的named_parameters( )方法查看该神经网络的所有可学习参数以及参数名称。
![1d3dccc59ab052f3c9f75b81cff39484.png](https://i-blog.csdnimg.cn/blog_migrate/32bcd208ea4ab6cd50fb2ab4fc6e6b5a.jpeg)
named_parameters( )方法
为了便于查看输出结果,上述代码不直接输出可学习参数,而是输出可学习参数的size。可以看到,这4个可学习参数分别是卷积层和线性层的权重比、偏斜量。
下面初始化一个Tensor,将其传入前向传播forward( )函数。
![0e02d0ffee829a000df5336578e1bde3.png](https://i-blog.csdnimg.cn/blog_migrate/897b92de178d986a3ce3155b85da2cef.jpeg)
前向传播
forward( )函数的输入与输出都是张量Tensor。
虽然我们自定义的神经网络MyNet中没有写backward( )函数,但是PyTorch会根据Autograd自动实现backward( )函数,因此MyNet对象是可以使反向传播backward( )函数的。在使用backward( )函数前,需要通过使用zero_grad( )方法把所有参数的梯度清零。
![f935d1931824cdc6d3f2452eeaa1e51b.png](https://i-blog.csdnimg.cn/blog_migrate/6b6479599ed9dd18b52e8c97c395820e.jpeg)
梯度清零
由于我们的初始输入张量x设置了requires_grad=True,因此调用backward( )函数后,x的grad属性就得到了更新。
需要注意的是,torch.nn只支持mini-batches,不支持一次只输入一个样本,即每一次输入必须是一个batch。详细来说就是即使只输入一个样本,PyTorch也会对样本进行分批,因此,我们对所有的输入都需要增加一个维度。例如上述的初始输入x,虽然在MyNet中定义的初始张量维度为3维,但我们定义x的时候令x为4维,增加了一个维度,最前面的1就是batch-size。
损失函数
损失函数又叫代价函数,是将随机事件或其有关随机变量的取值映射为非负实数以表示该随机事件的“风险”或“损失”的函数。在实际应用中,损失函数通常作为学习准则与优化问题相联系,即通过最小化损失函数求解与评估模型。
PyTorch的nn模块中预制了常用的损失函数,例如BCELoss、BCEWithLogitsLoss、NLLLoss、CrossEntropyLoss、L1Loss、MSELoss、SmoothL1Loss等。
![783a2f99aabf47d5d65b434f725c158b.png](https://i-blog.csdnimg.cn/blog_migrate/4e7158fc1be7656b2ea37fc95e81eef3.jpeg)
损失函数
上述代码中使用MSELoss( )函数计算均方误差。关于损失函数的相关知识点后续再具体展开介绍,它将贯穿整个神经网络的学习。
优化器optim
在使用反向传播backward( )函数计算所有参赛的梯度之后,需要使用优化方法不断更新神经网络中的权重比和偏斜量。例如常见的随机梯度下降法更新权重的更新策略为:权重=权重-学习率*梯度。
PyTorch提供了优化器相关的模块optim,该模块中包含了大多数的优化方法,如SGD、RMSProp、Adam等。
![ca707dcb264528584fe98e55aa960f6a.png](https://i-blog.csdnimg.cn/blog_migrate/c02342cce8a5a55810bdd2de2f6f557b.jpeg)
优化器
上述代码使用SGD更新对应参数。在实际应用中,我们会不断调用优化器更新参数,直至达到要求为止。
以上内容实现了一个简单的自定义神经网络,其中涉及的神经网络、卷积层、损失函数、优化器等知识点后续详细展开介绍。