当使用 PyTorch 进行深度学习时,构建网络模型是非常重要的一个环节。下面我们来探讨一下 Pytorch 构建网络模型的四种方法。
方法一:直接继承 nn.Module 类
这是最常用的构建模型的方法。可以创建一个类,继承自 nn.Module 类,并实现他的 forward() 方法。
我们来看一个简单的例子,构建一个具有两个全连接层(linear layer)的网络模型,其中每个线性层的输出都通过 ReLU 激活函数。整个网络的 forward() 方法接受一个输入张量x,返回表示经过网络处理后的输出张量y。
import torch.nn as nn
class TwoLayerNet(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(TwoLayerNet, self).__init__()
self.linear_1 = nn.Linear(input_size, hidden_size)
self.linear_2 = nn.Linear(hidden_size, output_size)
def forward(self, x):
x = nn.ReLU(self.linear_1(x))
y = self.linear_2(x)
return y
在这个例子中,我们继承了 nn.Module 类,并定义了一个模型——TwoLayerNet。在模型构造函数中,我们定义了两个线型层,名为linear_1和linear_2,并传入了他们的形状参数。我们需要注意的是,因为我们使用 PyTorch 中的自动求解器(autograd)而不是手动地编写反向传播算法,这样我们可以在模型中使用任意的可微函数。
接着定义了 forward() 方法,即我们模型处理输入张量 x 的流程。在这个例子中,我们按照先后顺序,使用了两个线型层和激活函数。最后返回输出张量 y。
方法二:使用 Sequential
Sequential 是 PyTorch 提供的一个快速搭建神经网络的方法。对于一些简单模型,因为在创建模型时没有定义forward()方法,所以我们可以直接使用 Sequential 实例来构建模型。
下面举一个例子,创建一个类似于上面示例的神经网络模型,其中无需为模型定义 forward() 方法。 在这个例子中,我们使用的方法与方法一中的相同,但是我们使用的是 Sequential 实例而不是TwoLayerNet类。
model = nn.Sequential(
nn.Linear(input_size, hidden_size),
nn.ReLU(),
nn.Linear(hidden_size, output_size),
)
这个代码中包含了所有的卷积和池化层,如 nn.Conv2d(), nn.MaxPool2d()等,Sequence实例看起来非常简洁明了。使用过程中,在构建模型时,将所有的层实例传入一个Sequential中,就可以直接使用这个 Sequential 工作了。
但是需要注意的是,这个方法只能用来构建没有分支的简单神经网络。而对于一些更复杂的网络结构,还是需要重载 nn.Module 类或继承定义自己的模型类。
方法三:使用 ModuleList
ModuleList 是一个方便地允许将子模块添加到一个其他模块中的工具。 ModuleList 可以包含各种层,比如全连接层、卷积层等等,以及定义了 forward() 方法的子模块。
这里我们给出一个简单的使用ModuleList的例子,包含两个卷积层和一个全连接层。
class ConvNet(nn.Module):
def __init__(self):
super(ConvNet, self).__init__()
self.conv_layers = nn.ModuleList([
nn.Conv2d(in_channels, out_channels, kernel_size, padding),
nn.Conv2d(out_channels, out_channels, kernel_size, padding)
])
self.linear_layers = nn.ModuleList([
nn.Linear(out_channels * image_size * image_size, hidden_size),
nn.Linear(hidden_size, num_classes),
])
self.relu = nn.ReLU()
def forward(self, x):
for layer in self.conv_layers:
x = self.relu(layer(x))
x = x.view(-1, out_channels * image_size * image_size)
for layer in self.linear_layers:
x = self.relu(layer(x))
return x
在这个例子中,我们定义的ConvNet模型包含了多个普通的卷积层和一个全连接层。 我们首先将卷积层实例存储在 self.conv_layers 中,并将全连接层实例存储在 self.linear_layers 中。然后可以看到,在 forward() 方法中,我们遍历了每个卷积层和全连接层,并对输入张量 x 进行相应的处理。注意,在全连接层之间使用了ReLU激活函数。
方法四:使用 ModuleDict
ModuleDict 是一个方便地允许将子模块添加到一个其他模块中的工具。ModuleDict可以包含各种层,比如全连接层、卷积层等等,以及定义了 forward() 方法的子模块。
举一个简单的例子,构建一个类似于前面使用 ModuleList 的 ConvNet 模型。
class ConvNetDict(nn.Module):
def __init__(self):
super(ConvNetDict, self).__init__()
self.conv_layers = nn.ModuleDict({
'conv1': nn.Conv2d(in_channels, out_channels, kernel_size, padding),
'conv2': nn.Conv2d(out_channels, out_channels, kernel_size, padding)
})
self.linear_layers = nn.ModuleDict({
'linear1': nn.Linear(out_channels * image_size * image_size, hidden_size),
'linear2': nn.Linear(hidden_size, num_classes),
})
self.relu = nn.ReLU()
def forward(self, x):
for idx, layer in self.conv_layers.items():
x = self.conv_layers[idx](self.relu(x))
x = x.view(-1, out_channels * image_size * image_size)
for idx, layer in self.linear_layers.items():
x = self.linear_layers[idx](self.relu(x))
return x
在这个例子中,与 ModuleList的例子类似,我们定义了ConvNetDict模型,其中存储了两个卷积层的实例,并将它们存储在我们的ModuleDict实例self.conv_layers中。同样,全连接层又被存储在了self.linear_layers中,之后多余的工作和 ModuleList 的例子一模一样。
以上四种方法具备自己的特定场景和应用,PyTorch的强大之处就在于你有多种方法可以选用,以针对特定任务迅速构建和调整模型。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:pytorch构建网络模型的4种方法 - Python技术站