【深度学习】经典的深度学习模型-01 开山之作:CNN卷积神经网络LeNet-5

【深度学习】经典的深度学习模型-01 开山之作:CNN卷积神经网络LeNet-5

Note: 草稿状态,持续更新中,如果有感兴趣,欢迎关注。。。

0. 论文信息

@article{lecun1998gradient,

title={Gradient-based learning applied to document recognition},

author={LeCun, Yann and Bottou, L{'e}on and Bengio, Yoshua and Haffner, Patrick},

journal={Proceedings of the IEEE},

volume={86},

number={11},

pages={2278--2324},

year={1998},

publisher={Ieee}

}

基于梯度的学习在文档识别中的应用

LeNet-5 是一个经典的卷积神经网络(CNN)架构,由 Yann LeCun 等人在 1998 年提出,主要用于手写数字识别任务,特别是在 MNIST 数据集上。

LeNet-5 的设计对后来的卷积神经网络研究产生了深远影响,该模型具有以下几个特点:

  1. 卷积层:LeNet-5 包含多个卷积层,每个卷积层后面通常会跟一个池化层(Pooling Layer),用于提取图像特征并降低特征图的空间维度。

  2. 池化层:在卷积层之后,LeNet-5 使用池化层来降低特征图的空间分辨率,减少计算量,并增加模型的抽象能力。

  3. 全连接层:在卷积和池化层之后,LeNet-5 包含几个全连接层,用于学习特征之间的复杂关系。

  4. 激活函数:LeNet-5 使用了 Sigmoid 激活函数,这是一种早期的非线性激活函数,用于引入非线性,使得网络可以学习复杂的模式。

  5. Dropout:尽管原始的 LeNet-5 并没有使用 Dropout,但后来的研究者在改进模型时加入了 Dropout 技术,以减少过拟合。

  6. 输出层:LeNet-5 的输出层通常使用 Softmax 激活函数,用于进行多分类任务,输出每个类别的概率。

虽然站在2024年看LeNet-5 的模型结构相对简单,但是时间回拨到1998年,彼时SVM这类算法为主的时代,LeNet-5的出现,不仅证明了卷积神经网络在图像识别任务中的有效性,而且为后续深度神经网络研究的发展带来重要启迪作用,使得我们有幸看到诸如 AlexNet、VGGNet、ResNet 等模型的不断推成出新。

2. 论文摘要

3. 研究背景

4. 算法模型

5. 实验效果

6. 代码实现

以MNIST手写字图像识别问题为例子,采用LeNet5模型进行分类,代码如下:

dart 复制代码
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")


# Define the LeNet-5 model
class LeNet5(nn.Module):
    def __init__(self):
        super(LeNet5, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, 5)  # 1 input image channel, 6 output channels, 5x5 kernel
        self.pool = nn.MaxPool2d(2, 2)  # pool with window 2x2, stride 2
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 4 * 4, 120)  # 16*4*4 = 256
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    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 * 4 * 4)  # flatten the tensor
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

# # Initialize the network
# net = LeNet5()

# Initialize the network on GPU
net = LeNet5().to(device)

# Define loss function and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

# Data loading
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])

train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)

train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=1000, shuffle=False)

# Train the network
for epoch in range(10):  # loop over the dataset multiple times
    running_loss = 0.0
    for i, data in enumerate(train_loader, 0):
        # for cpu
        # inputs, labels = data
        # for gpu
        inputs, labels = data[0].to(device), data[1].to(device)
        optimizer.zero_grad()

        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        if i % 2000 == 1999:  # print every 2000 mini-batches
            print(f'[{epoch + 1}, {i + 1}] loss: {running_loss / 2000:.3f}')
            running_loss = 0.0

print('Finished Training')

# Test the network on the test data
correct = 0
total = 0
with torch.no_grad():
    for data in test_loader:
        # # for cpu
        # images, labels = data
        # for gpu
        images, labels = data[0].to(device), data[1].to(device)
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f'Accuracy of the network on the 10000 test images: {100 * correct / total:.2f}%')

注意:这里使用GPU做简单加速。如果没有GPU,可以关闭对应代码,替换为相应的CPU代码即可。

程序运行后结果如下:

可以看到,在测试数据上的准确率为98.33%!

7. 问题及优化

相关推荐
人生百态,人生如梦2 分钟前
情感交互仿生人从技术到落地构想1——技术交流贴(2026.7)
人工智能·机器人·人机交互·交互
skywalk81633 分钟前
TRAE AI 创造力大赛 - 趣赢分析器
人工智能·trae
广凌股份(广凌科技)7 分钟前
广凌基建管理一体化解决方案:从立项报建到验收归档的全周期闭环管控
大数据·人工智能
延凡科技22 分钟前
数字孪生全域智慧园区综合可视化运营平台|延凡科技智园视界解决方案
数据库·人工智能·物联网·数据可视化
SelectDB技术团队23 分钟前
大规模集群治理:Apache Doris / SelectDB 的 CCR 无感升级、Colocate Join 与 Bitmap 精确去重
大数据·数据库·人工智能·agent·olap·selectdb·集群治理
GeekArch28 分钟前
第5讲:嵌入式场景二范式决策树:什么情况快写、什么情况严写
人工智能·stm32·单片机·mcu·物联网·决策树·机器学习
MobotStone29 分钟前
AI写的代码看着全对、逻辑也自洽,为什么就是“不是我们想要的”?
人工智能
火山引擎开发者社区30 分钟前
Agent 时代的 Serverless 入口:veFaaS CLI 实战
人工智能
aneasystone本尊33 分钟前
学习 OpenMontage 的工具发现与打分选择器
人工智能
火山引擎开发者社区35 分钟前
Computer Use Agent 新能力上线,开启企业电脑自动化的新范式
人工智能