在 PyTorch 中探索经典 CNN 架构:图像识别的强大工具
2023-11-23 15:45:24
经典 CNN 架构:在 PyTorch 中实现图像识别的基石
引言
图像识别,作为计算机视觉领域的核心任务,在从医疗诊断到自动驾驶的广泛应用中发挥着至关重要的作用。卷积神经网络(CNN)已成为应对图像识别挑战的强大方法,其独特的架构使其能够从图像中提取分层特征。本文将指导您使用 PyTorch 这个流行的深度学习框架,在 Python 中实现一些经典的 CNN 架构,让您能够构建强大的图像识别模型。
LeNet-5:手写数字识别的先驱
LeNet-5 是第一个成功应用于手写数字识别的 CNN,它是一个结构简单的网络,由卷积层、池化层和全连接层组成。它成功地证明了 CNN 在图像分类任务中的有效性。
AlexNet:大规模图像分类的突破
AlexNet 是一个更深的架构,包含了更多的卷积层和池化层。它在 ImageNet 大规模视觉识别挑战赛 (ILSVRC) 中取得了突破性的胜利,展示了 CNN 在大规模图像分类中的潜力。
VGGNet:深层卷积网络的探索
VGGNet 以其非常深的架构而闻名,包含了多层堆叠的卷积层和池化层。它在 ImageNet 上取得了出色的性能,证明了深度模型在图像识别任务中的有效性。
ResNet:残差连接带来的训练效率提升
ResNet 是一种突破性的架构,它引入了残差连接,允许梯度直接从网络的浅层传递到深层,从而解决了深层网络的训练问题。这种创新的设计提高了模型的收敛速度和准确性。
在 PyTorch 中实现 CNN
使用 PyTorch 实现这些经典的 CNN 架构非常简单。PyTorch 提供了一个直观且灵活的 API,使您可以轻松地构建和训练神经网络。以下是这些架构的 PyTorch 实现示例:
LeNet-5
import torch
import torch.nn as nn
import torch.nn.functional as F
class LeNet5(nn.Module):
def __init__(self):
super(LeNet5, self).__init__()
self.conv1 = nn.Conv2d(1, 6, 5)
self.pool1 = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.pool2 = nn.MaxPool2d(2, 2)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool1(F.relu(self.conv1(x)))
x = self.pool2(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 x
AlexNet
import torch
import torch.nn as nn
import torch.nn.functional as F
class AlexNet(nn.Module):
def __init__(self):
super(AlexNet, self).__init__()
self.conv1 = nn.Conv2d(3, 96, 11, stride=4)
self.pool1 = nn.MaxPool2d(3, stride=2)
self.conv2 = nn.Conv2d(96, 256, 5, padding=2)
self.pool2 = nn.MaxPool2d(3, stride=2)
self.conv3 = nn.Conv2d(256, 384, 3, padding=1)
self.conv4 = nn.Conv2d(384, 384, 3, padding=1)
self.conv5 = nn.Conv2d(384, 256, 3, padding=1)
self.pool5 = nn.MaxPool2d(3, stride=2)
self.fc1 = nn.Linear(256 * 6 * 6, 4096)
self.fc2 = nn.Linear(4096, 4096)
self.fc3 = nn.Linear(4096, 1000)
def forward(self, x):
x = self.pool1(F.relu(self.conv1(x)))
x = self.pool2(F.relu(self.conv2(x)))
x = F.relu(self.conv3(x))
x = F.relu(self.conv4(x))
x = F.relu(self.conv5(x))
x = self.pool5(x)
x = x.view(-1, 256 * 6 * 6)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
VGGNet
import torch
import torch.nn as nn
import torch.nn.functional as F
class VGGNet(nn.Module):
def __init__(self):
super(VGGNet, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, 3, padding=1),
nn.ReLU(),
nn.Conv2d(64, 64, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2, stride=2),
nn.Conv2d(64, 128, 3, padding=1),
nn.ReLU(),
nn.Conv2d(128, 128, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2, stride=2),
nn.Conv2d(128, 256, 3, padding=1),
nn.ReLU(),
nn.Conv2d(256, 256, 3, padding=1),
nn.ReLU(),
nn.Conv2d(256, 256, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2, stride=2),
nn.Conv2d(256, 512, 3, padding=1),
nn.ReLU(),
nn.Conv2d(512, 512, 3, padding=1),
nn.ReLU(),
nn.Conv2d(512, 512, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2, stride=2),
nn.Conv2d(512, 512, 3, padding=1),
nn.ReLU(),
nn.Conv2d(512, 512, 3, padding=1),
nn.ReLU(),
nn.Conv2d(512, 512, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2, stride=2)
)
self.classifier = nn.Sequential(
nn.Linear(512 * 7 * 7, 4096),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(4096, 4096),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(4096, 1000)
)
def forward(self, x):
x = self.features(x)
x = x.view(-1, 512 * 7 * 7)
x = self.classifier(x)
return x
ResNet
import torch
import torch.nn as nn
import torch.nn.functional as F
class BasicBlock(nn.Module):
def __init__(self, in_channels, out_channels, stride=1):
super(BasicBlock, self).__init__()
self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)
self.bn1