1.在class中一层一层定义
对于前馈传播网络,如果每次都写复杂的forward函数会有些麻烦,有两种简化方式:
ModuleList, Sequential.
2. 使用Sequential
Sequential是一个特殊的Module,包含几个子Module,前向传播时会将输入一层接一层地传递下去。
2.1 给每一层取名字
net1 = nn.Sequential()
net1.add_module(‘conv’, nn.Conv2d(3,3,3))
net1.add_module(‘bn1’, nn.BatchNorm2d(3))
net1.add_module(‘relu’, nn.ReLU())
2.2 不给每一层取名字
net2 = nn.Sequential(
nn.Conv2d(3,3,3),
nn.BatchNorm2d(3),
nn.ReLU()
)
2.3
from collections import OrderedDict
net3 = nn.Sequential(OrderedDict([
(‘conv’, nn.Conv2d(3,3,3)),
(‘bn1’, nn.BatchNorm2d(3)),
(‘relu’, nn.ReLU())
]))
3.ModuleList
ModuleList也是一个特殊的Module,可以包含几个子Module,可以像用list一样使用它,
但不能直接把输入传给ModuleList,因为没有重载forward方法
ModuleList是Module的子类,当在Module中使用它时,就能自动识别为子Module
modellist = nn.ModuleList([
nn.Conv2d(3,3,3),
nn.BatchNorm2d(3),
nn.ReLU()
])
4. layer的简化实现
nn.Module 中的大多数layer在nn.functional中都有一个与之相对应的函数。
如果模型有可学习的参数,最好用nn.Module,否则都可以
激活函数,池化函数没有可学习的参数,将它们用函数代替,这样可以不用放置在构造函数中
dropout尽管也没有可学习的参数,但在训练和测试两个阶段的行为有所差别,使用nn.Module
对象能够通过model.eval操作加以区分