【Pytorch图像分割实践|Pytorch自定义层或者模型类】
Pytorch自定义层或者模型类
-
-
- 1.nn.Module
- 2.自定义层ConvBNReLU
- 3.nn.Module与nn.Functional
- 4.nn.Sequential
- 5.自定义模型类LeNet
-
1.nn.Module
nn.Module
是PyTorch
提供的神经网络类,该类中实现了网络各层的定义及前向计算与反向传播机制。在实际使用时,如果想要实现某种神经网络模型,只需自定义模型类的时候继承nn.Module
,然后:- 在自定义类的构造函数
__init__()
中定义模型结构与参数; - 在函数
forward()
中编写网络前向过程即可。
nn.Module
可以自动利用Autograd
机制实现反向传播,不需要自己手动实现。在Module
的搭建时,可以嵌套包含子Module
,这样的代码分布可以使网络更加模块化,从而提升代码的复用性。在实际的应用中,PyTorch
提供了绝大多数的网络层,如全连接、卷积网络中的卷积、池化等,并自动实现前向与反向传播。2.自定义层ConvBNReLU
实现一个自定义层,该层将卷积、BN以及激活函数整合成一个层:
class ConvBNReLU(nn.Module):
# 在构造函数中定义层内的结构
def __init__(self, in_channels, out_channels, ks=3, stride=1, padding=1,dilation=1, groups=1, bias=False):
super(ConvBNReLU, self).__init__()
self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=ks, stride=stride,
padding=padding, dilation=dilation,groups=groups, bias=bias)
self.bn = nn.BatchNorm2d(out_channels)
self.relu = nn.ReLU(inplace=True)
# 在forward方法中定义正向传播步骤
def forward(self, x):
feat = self.conv(x)
feat = self.bn(feat)
feat = self.relu(feat)
return feat
3.nn.Module与nn.Functional
在
PyTorch
中有一个子库为nn.functional
,同样也提供了很多网络层与函数功能,但与nn.Module
不同的是,利用nn.functional
定义的网络层不可自动学习参数,还需要使用nn.Parameter封装。nn.functional
的设计初衷是对于一些不需要学习参数的层,如激活层。总体来看,对于需要学习参数的层,最好使用nn.Module
,对于无参数学习的层,可以使用nn.functional
,当然这两者间并没有严格的好坏之分。4.nn.Sequential
当模型中只是简单的前馈网络时,即上一层的输出直接作为下一层的输入,这时可以采用
nn.Sequential()
模块来快速搭建模型,而不必手动在forward()
函数中一层一层地前向传播。因此,如果想快速搭建模型而不考虑中间过程的话,推荐使用nn.Sequential()
模块。5.自定义模型类LeNet
其实模型类和层类本质是一样的,只是在正向传播过程中最后的输出格式可能会不一样,例如:
- 对于上面的
ConvBNRelu
层,其输出还是特征图的BCHW
格式的Tensor
; - 对于分类任务,其输出往往是一个
1 x num_classes
的Tensor
,每一个元素是对应所属类别的概率或者得分; - 对于分割任务,其输出往往是一个
B num_classes H W
的Tensor
,其宽高与输入大小相同,不过原图每个像素点对应位置的输出是num_classes
维的,表示这个像素属于每一个类的概率或者得分。
LeNet
:# LeNet model
class LeNet(nn.Module):
def __init__(self,num_classes:int=10,init_weights:bool=False):
super(LeNet,self).__init__()
self.features = nn.Sequential(
# conv1
nn.Conv2d(1,6,3),
nn.ReLU(inplace=True),
nn.MaxPool2d(2,2),
# conv2
nn.Conv2d(6,16,3),
nn.ReLU(inplace=True),
nn.MaxPool2d(2,2)
)
self.classifier = nn.Sequential(
nn.Linear(16*6*6,120),
nn.ReLU(inplace=True),
nn.Linear(120,84),
nn.ReLU(inplace=True),
nn.Linear(84,10),
)
def forward(self,x):
B,C,H,W = x.shape
assert H == 32 and W == 32,f"Input image size should be 32x32."
x = self.features(x)
x = torch.flatten(x,1)
x = self.classifier(x)
return x
推荐阅读
- C语言学习|第十一届蓝桥杯省赛 大学B组 C/C++ 第一场
- paddle|动手从头实现LSTM
- pytorch|使用pytorch从头实现多层LSTM
- SG平滑轨迹算法的原理和实现
- 推荐系统论文进阶|CTR预估 论文精读(十一)--Deep Interest Evolution Network(DIEN)
- pytorch|YOLOX 阅读笔记
- Pytorch学习|sklearn-SVM 模型保存、交叉验证与网格搜索
- 前沿论文|论文精读(Neural Architecture Search without Training)
- 联邦学习|【阅读笔记】Towards Efficient and Privacy-preserving Federated Deep Learning
- OpenCV|OpenCV-Python实战(18)——深度学习简介与入门示例