手写数字识别

虽然但是还是没学懂,不明白原理但是好像照葫芦画瓢也能运行,能实现测试集的正常测试,代码如下
(其实主要都是copliot写的(大悲))

CNN类

import torch
class CNN(torch.nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = torch.nn.Sequential(
            #1.卷积操作卷积层
            torch.nn.Conv2d(
                in_channels=1,  
                out_channels=16,  
                kernel_size=5,  
                stride=1,  
                padding=2  
            ),
            #2.归一化BN层
            torch.nn.BatchNorm2d(16),
            #3.激活层 Relu函数
            torch.nn.ReLU(inplace=True),
            #4.池化层 最大池化
            torch.nn.MaxPool2d(kernel_size=2, stride=2),
            #5.丢弃层 Dropout
            torch.nn.Dropout(p=0.2)
            )
        
        self.conv2 = torch.nn.Sequential(
            torch.nn.Conv2d(16, 32, kernel_size=5),
            torch.nn.ReLU(inplace=True),
            torch.nn.MaxPool2d(kernel_size=2, stride=2)
        )
        self.flatten_features = self._get_flatten_features((1, 28, 28))
        self.fc1 = torch.nn.Linear(in_features = 50 * 4 * 4, out_features = 10)
        # self.fc2 = torch.nn.Linear(120, 84)
        # self.fc3 = torch.nn.Linear(84, 10)

    def _get_flatten_features(self, input_size):
        """计算卷积层输出展平后的特征数量"""
        with torch.no_grad():
            x = torch.zeros(1, *input_size)  
            x = self.conv1(x)
            x = self.conv2(x)
            return x.numel()  

    def forward(self, x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = x.view(x.size(0), -1)
        x = self.fc1(x)
        # x = self.fc2(x)
        # x = self.fc3(x)
        return x

pytorch_mnist.py文件

import torch
import torchvision.datasets as dataset
import torchvision.transforms as transforms
import torch.utils.data as data_utils
from CNN import CNN

#######数据加载########

train_data = dataset.MNIST(
    root='mnist', 
    train=True, 
    transform=transforms.ToTensor(), 
    download=True
)

test_data = dataset.MNIST(
    root='mnist',
    train=False,
    transform=transforms.ToTensor(),
    download=True
)

# print('train_data:', train_data)
# print('test_data:', test_data)

#########分批加载##########
train_loader = data_utils.DataLoader(dataset=train_data, batch_size=64, shuffle=True)
test_loader = data_utils.DataLoader(dataset=test_data, batch_size=64, shuffle=False)

print('train_loader:', train_loader)
print('test_loader:', test_loader)
# for index, value in enumerate(train_loader):
#     print('index:', index)
#     print('value:', value)
#     break

cnn = CNN()
#如果安装了显卡加速,可以放到cuda上运行,会比在CPU运行会快一点
cnn = cnn.cuda() 



#############损失函数#########利用交叉熵损失函数进行运算
loss_function = torch.nn.CrossEntropyLoss()

##########优化器############利用随机梯度下降进行优化
optimizer = torch.optim.SGD(cnn.parameters(), lr=0.01, momentum=0.9) #如需精确lr=0.001

for epoch in range(10): 
    for index, (images, label) in enumerate(train_loader):
        # print('index:', index)
        # print('images:', images.shape)
        # print('label:', label.shape)
        images = images.cuda()  
        label = label.cuda()
        #上面两行可写可不写

        #前向传播
        outputs = cnn(images)

        #传入输出层节点和真实标签来计算损失函数
        loss = loss_function(outputs, label)

        #先清空梯度
        optimizer.zero_grad()
        #反向传播           
        loss.backward()
        #更新参数
        optimizer.step()
        print("当前批次为{}/{},loss为{}".format(epoch+1,index+1, len(train_loader), loss.item()))
        
        ###########测试##############
        loss_test = 0.0
        for index, (images, label) in enumerate(test_loader):
            images = images.cuda()
            label = label.cuda()
            outputs = cnn(images)
            test_loss = loss_function(outputs, label)
            _, predicted = torch.max(outputs.data, 1)
            total = label.size(0)
            correct = (predicted == label).sum().item()
            print('测试集准确率为:{}%'.format(100 * correct / total))

torch.save(cnn, f"model/mnist_model.pkl")
posted @ 2025-03-30 23:39  坚毅勤奋诚朴健美  阅读(27)  评论(0)    收藏  举报