简单来说,卷积层相当于一个特征检测层。每个卷积层有特定数目的通道,每个通道能够检测出图像中的具体特征。需要检测的每个特征常常被叫做核(kernel)或过滤器,它们都有固定大小,通常为3X3。
# 导入需要的包
import torch
import torch.nn as nn
class SimpleNet(nn.Module):
def __init__(self, num_classes=10):
super(SimpleNet, self).__init__()
self.conv1 = nn.Conv2d(in_channels=3, out_channels=12, kernel_size=3, stride=1, padding=1)
self.relu1 = nn.ReLU()
self.conv2 = nn.Conv2d(in_channels=12, out_channels=12, kernel_size=3, stride=1, padding=1)
self.relu2 = nn.ReLU()
self.pool = nn.MaxPool2d(kernel_size=2)
self.conv3 = nn.Conv2d(in_channels=12, out_channels=24, kernel_size=3, stride=1, padding=1)
self.relu3 = nn.ReLU()
self.conv4 = nn.Conv2d(in_channels=24, out_channels=24, kernel_size=3, stride=1, padding=1)
self.relu4 = nn.ReLU()
self.fc = nn.Linear(in_features=16 * 16 * 24, out_features=num_classes)
def forward(self, input):
output = self.conv1(input)
output = self.relu1(output)
output = self.conv2(output)
output = self.relu2(output)
output = self.pool(output)
output = self.conv3(output)
output = self.relu3(output)
output = self.conv4(output)
output = self.relu4(output)
output = output.view(-1, 16 * 16 * 24)
output = self.fc(output)
return output
nn.Conv2d(in_channels=3, out_channels=12, kernel_size=3, stride=1, padding=1)
因为我们的输入为有 3 个通道(红-绿-蓝)的 RGB 图像,我们指明 in_channels 的数量为 3。接着我们想将 12 特征的检测器应用在图像上,所以我们指明 out_channels 的数量为 12。这里我们使用标准大小为 3X3 的核。步幅设定为 1,后面一直是这样,除非你计划缩减图像的维度。将步幅设置为 1,卷积会一次变为 1 像素。最后,我们设定填充(padding)为 1:这样能确保我们的图像以0填充,从而保持输入和输出大小一致。
nn.Conv2d(in_channels=12, out_channels=12, kernel_size=3, stride=1, padding=1)
注意:我们在将最后一个卷积 -ReLU 层中的特征图谱输入图像前,必须把整个图谱压平。最后一层有 24 个输出通道,由于 2X2
的最大池化,在这时我们的图像就变成了16 X 16(32/2 = 16)。我们压平后的图像的维度会是16 x 16 x 24,实现代码如下: |
---|
output = output.view(-1, 16 * 16 * 24)
在我们的线性层中,我们必须指明 input_features 的数目同样为 16 x 16 x 24,out_features 的数目应和我们所希望的类的数量一致。
尚无评论!