class CNNCifar(nn.Module):
def __init__(self, args):
super(CNNCifar, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, args.num_classes)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 16 * 5 * 5)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return F.log_softmax(x, dim=1)
CIFAR数据集通常包括CIFAR-10和CIFAR-100,其中CIFAR-10包含10个类别的彩色图像。这个网络结构由两个卷积层和三个全连接层组成。以下是每个部分的详细解释:
初始化部分 __init__
:
-
self.conv1 = nn.Conv2d(3, 6, 5)
: 第一个卷积层,有3个输入通道(彩色图像),6个输出通道,和5x5的卷积核。 -
self.pool = nn.MaxPool2d(2, 2)
: 最大池化层,窗口大小为2x2。这个池化层在后面的卷积层之后重复使用。 -
self.conv2 = nn.Conv2d(6, 16, 5)
: 第二个卷积层,6个输入通道,16个输出通道,和5x5的卷积核。 -
self.fc1 = nn.Linear(16 * 5 * 5, 120)
: 第一个全连接层,有16 * 5 * 5个输入单元和120个输出单元。 -
self.fc2 = nn.Linear(120, 84)
: 第二个全连接层,有120个输入单元和84个输出单元。 -
self.fc3 = nn.Linear(84, args.num_classes)
: 第三个全连接层,有84个输入单元,输出单元数由args.num_classes
确定(例如,CIFAR-10的类别数为10)。
前向传播部分 forward
:
-
x = self.pool(F.relu(self.conv1(x)))
: 输入x首先通过第一个卷积层,然后通过ReLU激活函数,再经过池化层。 -
x = self.pool(F.relu(self.conv2(x)))
: 同样的模式继续,现在通过第二个卷积层。 -
x = x.view(-1, 16 * 5 * 5)
: 改变张量的形状,将其展平以适合全连接层的输入形状。 -
x = F.relu(self.fc1(x))
: 输入通过第一个全连接层并激活。 -
x = F.relu(self.fc2(x))
: 接着通过第二个全连接层并激活。 -
x = self.fc3(x)
: 通过最后一个全连接层。 -
return F.log_softmax(x, dim=1)
: 应用log_softmax激活函数,通常用于多分类问题的最终层,返回对数概率。
这个CNNCifar类定义了一个相对简单但功能齐全的卷积神经网络,适合用于CIFAR数据集。卷积层捕获图像的空间特征,全连接层则执行高级推理和分类。这种架构是神经网络图像分类的典型例子。