本篇文章以构造一个MLP模型为例,介绍几种构造模型的常见方法。
Module类是nn模块里提供的一个模型构造类,通过继承Module实现MLP的程序如下
class MLP(nn.Module):
def __init__(self):
super(MLP,self).__init__()
self.hidden = nn.Linear(784,256)
self.act = nn.ReLU()
self.output = nn.Linear(256,10)
def forward(self,x):
a = self.act(self.hidden(x))
return self.output(a)
在构造这个模型的过程中,仅仅定义了正向传播。系统将通过自动求梯度而自动生成反向传播所需要的backward函数。下面将MLP类实例化。
X = torch.rand(2,784)
#随即胜场两组样本
net = MLP()
print(net)
net(X)
神经网络结构和正向传播一次的结果:
Module的子类包括:Sequential类、ModuleList类和ModuleDict类
当模型的正向传播为简单串联各个层的计算时,Sequential类可以通过更简单的方式定义模型。Sequential类可以接收一系列子模块作为参数来逐一添加Module的实例。模型的正向传播就是将这些实例按添加顺序逐一计算。
使用Sequential类实现MLP模型,并使用随机生成的样本做一次前向计算。
#构造
net = nn.Sequential(
nn.Linear(784,256),
nn.ReLU(),
nn.Linear(256,10),
)
#输出结果和进行一次前向计算
X = torch.rand(2,784)
print(net)
net(X)
神经网络结构和正向传播一次的结果:
ModuleList接收一个子模块的列表作为输入。并且可以像list那样进行索引、append和extend操作。但不同于一般List的地方是加入到ModuleList里面的所有模块的参数会被自动添加到整个网络。
下面以实例说明如何使用ModuleList类构造MLP模型。
#构造
net = nn.ModuleList([nn.Linear(784,256),nn.ReLU()])
net.append(nn.Linear(256,10))
print(net[-1])
#输出net中最后一个实例
print(net)
神经网络结构:
ModuleDict类接受一个子模块的字典作为输入,也可以类似字典那样进行添加访问操作。
net = nn.ModuleDict({
'linear':nn.Linear(784,256),
'act':nn.ReLU(),
})
#类似字典的访问方法
net['output']=nn.Linear(256,10)
print(net['linear'])
print(net.output)
#输出结构
print(net)
神经网络结构:
上述两种方法各有利弊。下面我们综合使用这两种方法,构造一个复杂的神经网络FancyMLP。在这个神经网络中,我们需要创建常数参数(训练中不被迭代的参数),在前向计算中,还需要使用Tensor的函数和Python控制流并多次调用相同的层。
class FancyMLP(nn.Module):
def __init__(self):
super(FancyMLP, self).__init__()
self.rand_weight = torch.rand((20, 20), requires_grad=False) #常数参数
self.linear = nn.Linear(20, 20)
def forward(self, x):
x = self.linear(x)
# 使用创建的常数参数
x = nn.functional.relu(torch.mm(x, self.rand_weight.data) + 1)
# 复用全连接层。等价于两个全连接层共享参数
x = self.linear(x)
# 控制流,这里我们需要调用item函数来返回标量进行比较
while x.norm().item() > 1:
x /= 2
if x.norm().item() < 0.8:
x *= 10
return x.sum()
class NestMLP(nn.Module):
def __init__(self):
super(NestMLP, self).__init__()
self.net = nn.Sequential(nn.Linear(40, 30), nn.ReLU())
def forward(self, x):
return self.net(x)
net = nn.Sequential(NestMLP(), nn.Linear(30, 20), FancyMLP())
#嵌套调用FancyMLP和Sequential
X = torch.rand(2, 40)
print(net)
net(X)
神经网络结构:
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有