手写数字识别 (卷积神经网络)
hello hello~ ,这里是 code袁~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹
🦁作者简介:一名喜欢分享和记录学习的在校大学生
💥个人主页:code袁的博客
💥 个人QQ:2647996100
🐯 个人wechat:code8896
code袁系列专栏导航
1.《毕业设计与课程设计》本专栏分享一些毕业设计的源码以及项目成果。🥰🥰🥰
2.《微信小程序开发》本专栏从基础到入门的一系开发流程,并且分享了自己在开发中遇到的一系列问题。🤹🤹🤹
3.《vue开发系列全程线路》本专栏分享自己的vue的学习历程。非常期待和您一起在这个小小的互联网世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨
代码
1.Pytorch_mnist.py
import torch
import torchvision.datasets as datasets
import torchvision.transforms as transforms
# 数据的分批加载
import torch.utils.data as data_utils
import matplotlib.pyplot as plt
import osfrom CNN import CNN
# from mnist_test import loss_test# 解决OpenMP库冲突问题
os.environ['KMP_DUPLICATE_LIB_OK']='True'## 数据记载##
## transform=transforms.ToTensor() 数据格式转化为张量
train_data=datasets.MNIST(root='mnist', train=True, download=True, transform=transforms.ToTensor())# 测试数据
test_data=datasets.MNIST(root='mnist', train=False, download=True, transform=transforms.ToTensor())#### 数据的分批加载###
### batch_size 一次加载的数据
### huffle 打乱数据 提高模型的泛化能力
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=True)## 创建实例
cnn=CNN()
# 检查是否有可用的CUDA设备
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f'Using device: {device}')
cnn=cnn.to(device)#### 交叉熵损失函数###
loss_func=torch.nn.CrossEntropyLoss()#### 优化函数###
optimizer=torch.optim.Adam(cnn.parameters(), lr=0.001)# 存储每个epoch的准确率用于绘图
train_accuracies = []
test_accuracies = []
epochs_list = []#### 训练过程 数据准备→前向传播→计算损失→反向传播→参数更新 #####
for epoch in range(3):#### 训练集验证 ###correct_train = 0total_train = 0for index,(images,labels) in enumerate(train_loader):images=images.to(device)labels=labels.to(device)## 前向传播outputs=cnn(images)## 传入输出层和真实节点计算损失函数,labels 真实值loss=loss_func(outputs,labels)## 清空梯度 PyTorch 会累积梯度,所以每次迭代前需要清零optimizer.zero_grad()## 进行反向传播 损失值计算所有可训练参数的梯度loss.backward()# 执行参数更新optimizer.step()# 计算训练准确率_, predicted = torch.max(outputs.data, 1)total_train += labels.size(0)correct_train += (predicted == labels).sum().item()print('当前的轮次是{},当前批次为{}/{},损失函数loss={}'.format(epoch+1,index+1,len(train_data)//64,loss.item()))train_accuracy = 100 * correct_train / total_traintrain_accuracies.append(train_accuracy)##### 测试集验证###loss_test=0rightValue=0total_test = 0for index2,(images,labels) in enumerate(test_loader):images = images.to(device)labels = labels.to(device)outputs=cnn(images)# 计算当前批次的损失,并累加到总损失 loss_test 中loss_test+=loss_func(outputs,labels)# pred 存储最大值所在的索引_,pred=outputs.max(1)## 把两个张量中的每个元素进行对比的比较,如果相等就返回true pred==labels pred==labels 逐元素比较预测标签和真实标签rightValue+=(pred==labels).sum().item()total_test += labels.size(0)print('当前的轮次是{},当前批次为{}/{},损失函数loss={},准确率为{}'.format(epoch+1,index2+1,len(test_data)//64,loss_test,rightValue/len(test_data)))test_accuracy = 100 * rightValue / total_testtest_accuracies.append(test_accuracy)epochs_list.append(epoch + 1)print('Epoch [{}/{}], Train Accuracy: {:.2f}%, Test Accuracy: {:.2f}%'.format(epoch+1, 10, train_accuracy, test_accuracy))## 保存数据
torch.save(cnn, f'model/mnist_cnn.pth')# 绘制训练过程准确率变化图
plt.figure(figsize=(10, 6))
plt.plot(epochs_list, train_accuracies, 'o-', label='train_acc', color='green')
plt.plot(epochs_list, test_accuracies, 's-', label='test_acc', color='red')
plt.xlabel('Epoch')
plt.ylabel('ACC (%)')
# plt.title('训练过程中训练集和测试集准确率变化情况')
plt.legend()
plt.grid(True, alpha=0.3)
plt.xticks(epochs_list)plt.tight_layout()
plt.savefig('training_progress.png', dpi=300, bbox_inches='tight')
plt.show()print("准确率变化图已保存为 'training_progress.png'")
2.CNN.py
import torch### 简单卷积神经网络(CNN)模型
class CNN(torch.nn.Module): ### 继承自torch.nn.Module yTorch 中所有神经网络模块的基类def __init__(self):# 继承父类super(CNN,self).__init__()## 卷积操作self.conv=torch.nn.Sequential(# 1 卷积操作卷积层 卷积核大小 5x5,padding=2 保持卷积后特征图大小不变torch.nn.Conv2d(in_channels=1,out_channels=32,kernel_size=5,padding=2),# 归一化BN层 加速训练收敛并防止过拟合torch.nn.BatchNorm2d(32),# 激活层 Relu 引入非线性,使网络能学习更复杂的特征torch.nn.ReLU(),# 最大池化 特征图尺寸缩小一半torch.nn.MaxPool2d(2))## 全连接操作self.fc=torch.nn.Linear(in_features=14*14*32,out_features=10)# 前向操作def forward(self,x):out=self.conv(x)# 将图像数据展开成一维的 输入的张量(n,c,w,h) 卷积输出的多维特征图展平为一维向量out=out.view(out.size(0),-1)out=self.fc(out)return out
3.效果
🎉写在最后
🍻伙伴们,如果你已经看到了这里,觉得这篇文章有帮助到你的话不妨点赞👍或 Star ✨支持一下哦!手动码字,如有错误,欢迎在评论区指正💬~
你的支持就是我更新的最大动力💪~