Martian148's blog Martian148's blog
首页
  • ICPC 算法笔记
  • ICPC 算法题解
  • 体系结构
  • 高等数学
  • 线性代数
  • 概率论与数理统计
  • 具体数学
  • Martian148的奇思妙想
  • 游记
  • 通识课笔记
关于
  • useful 网站
  • 友情链接
  • 分类
  • 归档

Martian148

一只热爱文科的理科生
首页
  • ICPC 算法笔记
  • ICPC 算法题解
  • 体系结构
  • 高等数学
  • 线性代数
  • 概率论与数理统计
  • 具体数学
  • Martian148的奇思妙想
  • 游记
  • 通识课笔记
关于
  • useful 网站
  • 友情链接
  • 分类
  • 归档
  • ACM - ICPC

  • 编程语言

  • 体系结构

  • Web

  • 人工智能

    • 机器学习笔记
    • 《python科学计算入门》学习笔记
    • LLM101 NLP学习笔记
    • 打破信息差,跟着水导学写论文
    • 一个简单的 PyTorch 图像分类器
    • 模型与分词器
  • 计算机网络

  • 数据库

  • 编程工具

  • 计算机科学
  • 人工智能
martian148
2025-08-29

一个简单的 PyTorch 图像分类器

学习了 PyTorch 官方教程中文版后跟着敲了一个图像分类器,能实现 10 中类别的图像分类任务

import torch.nn as nn  
import torch.nn.functional as F  
  
import torch.optim as optim  
  
import torch  
import torchvision  
import torchvision.transforms as transforms  
  
import matplotlib.pyplot as plt  
import numpy as np  
  
class Net(nn.Module):  
    def __init__(self):  
        super(Net, 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, 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 * 5 * 5)  
        x = F.relu(self.fc1(x))  
        x = F.relu(self.fc2(x))  
        x = self.fc3(x)  
        return x  
  
def imshow(img):  
    img = img / 2 + 0.5  
    npimg = img.numpy() # 转化成 numpy 数组  
    plt.imshow(np.transpose(npimg, (1, 2, 0)))  
    plt.show()  
  
  
def main():  
    transform = transforms.Compose([  
        transforms.ToTensor(),  
        transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))  
    ])  
  
    # 下载并构造训练集对象  
    trainset = torchvision.datasets.CIFAR10(root='./data', train=True,  
                                            download=True, transform=transform)  
  
    # 把 trainset 包装成 数据加载器,训练时用它来一批一批取数据。  
    # trainset 是刚才的数据集  
    # batch_size=4 :一次取 4 张图片组成一个 mini-batch。  
    # shuffle=True :每个 epoch 都打乱训练数据,避免模型记住顺序。  
    # num_workers=2 :用 2 个子进程并行加载数据,加快读取速度。  
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,  
                                              shuffle=True, num_workers=2)  
  
    # 和 trainset 类似,不过这里 train=False,所以加载的是 测试集(10000 张图片)。  
    testset = torchvision.datasets.CIFAR10(root='./data', train=False,  
                                           download=True, transform=transform)  
  
    # 把测试集封装成迭代器。  
    testloader = torch.utils.data.DataLoader(testset, batch_size=4,  
                                             shuffle=False, num_workers=2)  
  
    classes = ('plane', 'car', 'bird', 'cat',  
               'deer', 'dog', 'frog', 'horse', 'ship', 'truck')  
  
    net = Net()  
  
    # 定义损失函数为交叉墒损失  
    criterion = nn.CrossEntropyLoss()  
  
    # 自定义优化器  
    optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)  
  
    for epoch in range(10): # 训练两个完整的 epoch        running_loss = 0.0  
        for i, data in enumerate(trainloader, 0): # 获取一个 mini-batch            inputs, labels = data  
            optimizer.zero_grad() # 梯度清零  
            outputs = net(inputs) # 得到神经网络的输出  
            loss = criterion(outputs, labels) # 获取损失函数  
            loss.backward() # 反向传播  
            optimizer.step() # 使用 SGD 优化器来更新参数  
  
            # 打印训练进度  
            running_loss += loss.item() # 累积损失到 running_loss 中  
            if i % 2000 == 1999:  
                print('[%d, %5d] loss: %.3f' %  
                      (epoch + 1, i + 1, running_loss / 2000))  
                running_loss = 0.0 # 清零  
    print('Finished Training') # 结束训练  
  
  
    # dataiter = iter(trainloader)  
    # images, labels = next(dataiter)    #    # imshow(torchvision.utils.make_grid(images))    # print('Ground truth labels: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))    #    # outputs = net(images)    # _, predicted = torch.max(outputs.data, 1) # 通过已经训练好的神经网络进行预测  
    # print('Predicted ', ' '.join('%5s' % classes[predicted[j]] for j in range(4)))  
  
    # 验证数据预测准确性  
    correct, total = 0, 0  
    with torch.no_grad(): # 不计算梯度的上下文环境  
        for data in testloader:  
            images, labels = data  
            outputs = net(images)  
            _, predicted = torch.max(outputs.data, 1) # 找到最大类别的标签就是预测值  
            total += labels.size(0)  
            correct += (predicted == labels).sum().item()  
  
    print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))  
  
if __name__ == '__main__':  
    main()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
打破信息差,跟着水导学写论文
模型与分词器

← 打破信息差,跟着水导学写论文 模型与分词器→

最近更新
01
打破信息差,一条学校不教的计算机学习之路
09-18
02
ICPC2025Online2 E Zero
09-18
03
模型与分词器
09-17
更多文章>
Theme by Vdoing | Copyright © 2024-2025 Martian148 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式