深度学习—LeNet5_MNIST代码

 

 

 

 

import os
import torch
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision import datasets
import pandas as pd
import openpyxl
import xlwt, xlrd
from xlutils.copy import copy
from openpyxl import load_workbook
##########################################################
# =.准备数据
##########################################################
# 预处理
transfrom = transforms.Compose([
    transforms.Resize(32),
    transforms.ToTensor()
])
# 准备训练集数据和验证集
train_dataset = datasets.MNIST(root='.',transform=transfrom,train=True,download=True)
val_dataset = datasets.MNIST(root='.',transform=transfrom,train=False,download=True)

# 训练集dataloader,验证集dataloader
train_loader = DataLoader(
    dataset=train_dataset,
    batch_size=8,
    shuffle=True
)
val_loader = DataLoader(
    dataset=val_dataset,
    batch_size=8,
    shuffle=False
)
##########################################################
# ==> 2.搭建网络
##########################################################
# 重写nn.Module类,使用自己的网络
from torch import nn
# 实验四:写代码处
# 以下是上节课实现代码,请按照要求实现LeNet5网络
from torch import nn
class My_Net(nn.Module):
    # 初始化
    def __init__(self):
        super(My_Net, self).__init__()
        self.conv1 = nn.Conv2d(in_channels=1,
                               out_channels=6,
                               kernel_size=5,
                               padding=0,
                               stride=1)
        self.tanh1 = nn.Tanh()
        self.max_pool1 = nn.MaxPool2d(kernel_size=2,
                                      stride=2,
                                      padding=0)

        self.conv2 = nn.Conv2d(in_channels=6,
                               out_channels=16,
                               kernel_size=5,
                               padding=0,
                               stride=1)
        self.tanh2 = nn.Tanh()
        self.max_pool2 = nn.MaxPool2d(kernel_size=2,
                                      stride=2,
                                      padding=0)

        self.linear1 = nn.Linear(in_features=400,
                                out_features=120,
                                bias=True)

        self.linear2 = nn.Linear(in_features=120,
                                 out_features=84,
                                 bias=True)
        self.tanh3 = nn.Tanh()

        self.linear3 = nn.Linear(in_features=84,
                                 out_features=10,
                                 bias=True)
    # 定义前向计算过程
    def forward(self, x):
        x = self.conv1(x)
        x = self.tanh1(x)
        x = self.max_pool1(x)

        x = self.conv2(x)
        x = self.tanh2(x)
        x = self.max_pool2(x)
        # 将特征展平(超级重要!!!)
        x = x.view(x.shape[0], -1)
        x = self.linear1(x)
        x = self.linear2(x)
        x = self.tanh3(x)
        x = self.linear3(x)
        return x


# 将网络类实例化,变成对象
net = My_Net()
##########################################################
# ==> 3.定义损失函数,优化器,学习率调整方式
##########################################################
# 3.1损失函数
loss_fn = nn.CrossEntropyLoss() # 使用CE Loss
# 3.2优化器,学习率调整器
from torch import optim
# 使用SGD优化器,初始学习率为0.0001
optimizer = optim.SGD(net.parameters(), lr=0.5)
# 使用StepLR学习率调整方式,每隔5个Epoch学习率变为原来的0.1倍
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)

##########################################################
# ==> 4.进行训练
##########################################################
filname = open('./0.5_8.txt','a+',encoding='utf-8')
# 迭代训练10个Epoch
num_epochs = 20
print("Start Train!")
for epoch in range(1, num_epochs+1):
    train_loss = 0
    train_acc = 0
    val_loss = 0
    val_acc = 0
    # 训练阶段,设为训练状态
    net.train()
    train_confusion_matrix = torch.zeros(10, 10).cuda()  # 训练集混淆矩阵
    val_confusion_matrix = torch.zeros(10, 10).cuda()  # 验证集混淆矩阵
    for batch_index, (imgs,labels) in enumerate(train_loader):
        output = net(imgs)
        loss = loss_fn(output,labels) #计算损失
        optimizer.zero_grad()# 梯度清零
        loss.backward()# 反向传播
        optimizer.step()# 梯度更新
        # 计算精确度
        _,predict = torch.max(output,dim=1)
        if epoch == num_epochs:
            for i in range(8):
                if predict[i] != labels[i]:
                    filname.write(str(predict[i].item())+','+str(labels[i].item())+'\n')
        corec = (predict == labels).sum().item()
        acc = corec / imgs.shape[0]
        train_loss += loss.item()
        train_acc += acc

        for t, p in zip(labels.view(-1), output.argmax(dim=1).view(-1)):
            train_confusion_matrix[t.long(), p.long()] += 1

    # 查看训练集每个类的准确率
    acc_per_class = train_confusion_matrix.diag() / train_confusion_matrix.sum(1)
    acc_per_class = acc_per_class.cpu().numpy()
    print()
    print('train acc_per_class:\n',acc_per_class)
    # 验证阶段
    net.eval()
    for batch_index, (imgs, labels) in enumerate(val_loader):
        output = net(imgs)
        loss = loss_fn(output,labels)
        _, predict = torch.max(output, dim=1)
        corec = (predict == labels).sum().item()
        acc = corec / imgs.shape[0]
        val_loss += loss.item()
        val_acc += acc
        for t, p in zip(labels.view(-1), output.argmax(dim=1).view(-1)):
            val_confusion_matrix[t.long(), p.long()] += 1

    # 查看验证集每个类的准确率
    acc_per_class = val_confusion_matrix.diag() / val_confusion_matrix.sum(1)
    acc_per_class = acc_per_class.cpu().numpy()
    print()
    print('val acc_per_class:\n',acc_per_class)
    scheduler.step()
    # 依次输出当前epoch、总的num_epochs
    # 训练过程中当前epoch的训练损失、训练精确度、验证损失、验证精确度和学习率
    print()
    print(epoch, '/', num_epochs, train_loss/len(train_loader),
          train_acc/len(train_loader), val_loss/len(val_loader),
         val_acc/len(val_loader),optimizer.param_groups[0]['lr'])

 

 

知识产权声明: 本博文中的ppt素材及相关内容和知识产权,均属于河南大学张重生老师所讲授的《深度学习》课程及张重生老师在2025年出版的著作《新一代人工智能 从深度学习到大模型》(机械工业出版社)。特此声明。

真挚地感谢张重生老师在本人于河南大学学习期间的教导。

posted on 2023-03-16 00:11  JevonChao  阅读(56)  评论(0)    收藏  举报