首页 > 其他分享 >神经网络入门实战:(十九)完整训练及测试代码,以数据集CIFAR10为例

神经网络入门实战:(十九)完整训练及测试代码,以数据集CIFAR10为例

时间:2024-12-08 20:58:24浏览次数:10  
标签:---------------- loss 训练 为例 CIFAR10 test train 测试代码

完整实操之:CIFAR10数据集的训练与测试

CIFAR10数据集,有50000张训练图片,有10000张测试图片

下方代码中:

  • 训练轮次为 10 轮;
  • batch_size = 6450000/64 = 782(向上取整) ,所以训练一轮就等于训练了 782batch_size 的图片,10 轮就是 7820
  • 最终运行结果展示两个部分:
    • 画出 782batch_size10 轮训练损失减小情况,整合成一条曲线,10 轮总共 7820 个;
    • 画出第一个 batch_size10 轮训练损失减小情况。
  • 最终将训练好的模型保存在本地,命名为 CIFAR10_NET_train10train10 表示经过了 10 轮的训练。

(一)代码一

保存在本地的用于存放神经网络模型的 NN_models.py 文件:

# 此文件用于存放神经网络模型
# 作者:LIANG XIAO
from torch import nn

# CIFAR10的配套网络(加了非线性激活函数)
class CIFAR10_NET(nn.Module):
	def __init__(self):
		super(CIFAR10_NET, self).__init__()
		self.model = nn.Sequential(
			nn.Conv2d(3, 32, 5, padding=2),  # 输入输出尺寸相同,故根据公式计算出padding的值
			nn.MaxPool2d(2, 2),
			nn.ReLU(),  # 添加ReLU激活函数
			nn.Conv2d(32, 32, 5, padding=2),
			nn.MaxPool2d(2, 2),
			nn.ReLU(),  # 添加ReLU激活函数
			nn.Conv2d(32, 64, 5, padding=2),
			nn.MaxPool2d(2, 2),
			nn.ReLU(),  # 添加ReLU激活函数
			nn.Flatten(),
			nn.Linear(1024, 64),
			nn.ReLU(),  # 添加ReLU激活函数
			nn.Linear(64, 10)
		    )

	def forward(self, x):
		x = self.model(x)
		return x

(二)代码二,结合代码一

初步训练代码:

import torch
from torch import nn
import torchvision
from torchvision import transforms
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from NN_models import *


# 检查CUDA是否可用,并设置设备为 GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

dataclass_transform = transforms.Compose([
	transforms.ToTensor(),
])

train_dataset = torchvision.datasets.CIFAR10(root='E:\\4_Data_sets\\species recognition', train=True,transform=dataclass_transform, download=True)
test_dataset = torchvision.datasets.CIFAR10(root='E:\\4_Data_sets\\species recognition', train=False,transform=dataclass_transform, download=True)

# 训练和测试数据集的长度
train_data_size = len(train_dataset)
test_size = len(test_dataset)
print(train_data_size,test_size)

train_dataloader = DataLoader(dataset=train_dataset,batch_size=64)
test_dataloader = DataLoader(dataset=test_dataset,batch_size=64)

# 创建网络模型
CIFAR10_NET_Instance = CIFAR10_NET().to(device)
# 定义损失函数
loss = nn.CrossEntropyLoss()
# 定义优化器
learning_rate = 0.01
optimizer = torch.optim.SGD(CIFAR10_NET_Instance.parameters(), lr=learning_rate, momentum=0.9)

# 开始训练
total_train_step = 0
first_train_step = 0
total_test_step = 0
epoch_sum = 10 # 迭代次数

# 添加tensorboard
writer = SummaryWriter('logs')

for i in range(epoch_sum):
	print("------------第 {} 轮训练开始了------------:".format(i+1))

	# 训练步骤开始
	for data in train_dataloader:
		imgs, labels = data
		imgs, labels = imgs.to(device), labels.to(device)  # 将数据和目标移动到GPU
		outputs = CIFAR10_NET_Instance(imgs)
		loss_real = loss(outputs, labels) # 这里的损失变量 loss_real,千万别和损失函数 loss 相同,否则会报错!
		optimizer.zero_grad()
		loss_real.backward()
		optimizer.step()

		total_train_step += 1
		# 表示第一轮训练结束,取每一轮的第一个batch_size来看看训练效果,这里的782是通过计算得出来的
		if total_train_step % 782 == 0:
			first_train_step += 1
			print("训练次数为:{}, loss为:{}".format(total_train_step, loss_real)) # 此训练次数非训练轮次,而是训练到第几个batch_size了
			writer.add_scalar('first_batch_size', loss_real.item(), first_train_step)
		writer.add_scalar('total_batch_size', loss_real.item(), total_train_step)


	# 每训练一轮,就使用测试集看看训练效果
	total_test_loss = 0
	with torch.no_grad():
		for data in test_dataloader:
			imgs, labels = data
			imgs, labels = imgs.to(device), labels.to(device)
			outputs = CIFAR10_NET_Instance(imgs)
			loss_fake = loss(outputs, labels)
			total_test_loss += loss_fake.item()
	print("# # 整体测试集上的LOSS为:{}".format(total_test_loss))

writer.close()

torch.save(CIFAR10_NET_Instance,"E:\\5_NN_model\\CIFAR10_NET_train10")
print("模型已保存!!")

运行结果

在这里插入图片描述

在这里插入图片描述

(三)代码三,结合代码一

Tips☆: 训练模型的输出,是一个二维张量,第几行表示第几个 batch_size 样本;列表示每个样本识别成某种类别的概率,CIFAR10 的配套网络模型输出如下:

# batch_size = 64,类别为10,所以行数为64,列数为10。
tensor([[ 0.0377,  0.0153, 0.0289, 0.1006, 0.1039, 0.1300, 0.0667, 0.0739, 0.0362, 0.0660],
        [ 0.0406,  0.0162, 0.0250, 0.0995, 0.0990, 0.1308, 0.0637, 0.0725, 0.0351, 0.0714],
        [ 0.0341,  0.0162, 0.0297, 0.1037, 0.1007, 0.1342, 0.0674, 0.0733, 0.0366, 0.0693],
        [ 0.0367,  0.0144, 0.0289, 0.1066, 0.1045, 0.1290, 0.0714, 0.0734, 0.0344, 0.0662],
        ...
        [ 0.0388,  0.0150, 0.0261, 0.0996, 0.1034, 0.1307, 0.0662, 0.0720, 0.0358, 0.0707]], device='cuda:0', grad_fn=<AddmmBackward0>)

所以,使用 torch.argmax 函数时,通常设置 dim=1 (第二个维度,行)。

完整训练及测试代码

此代码中会加入各种各样的小知识点。

import torch
from torch import nn
import torchvision
from torchvision import transforms
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from NN_models import *
from PIL import Image
import time


# 检查CUDA是否可用,并设置设备为 GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

dataclass_transform = transforms.Compose([
	transforms.ToTensor(),
])

train_dataset = torchvision.datasets.CIFAR10(root='E:\\4_Data_sets\\species recognition', train=True,transform=dataclass_transform, download=True)
test_dataset = torchvision.datasets.CIFAR10(root='E:\\4_Data_sets\\species recognition', train=False,transform=dataclass_transform, download=True)

# 训练和测试数据集的长度
train_data_size = len(train_dataset)
test_size = len(test_dataset)
print(train_data_size,test_size)

train_dataloader = DataLoader(dataset=train_dataset,batch_size=64)
test_dataloader = DataLoader(dataset=test_dataset,batch_size=64)

# 创建网络模型
CIFAR10_NET_Instance = CIFAR10_NET().to(device)
# 定义损失函数
loss = nn.CrossEntropyLoss()
# 定义优化器
learning_rate = 0.01
optimizer = torch.optim.SGD(CIFAR10_NET_Instance.parameters(), lr=learning_rate, momentum=0.9)

# 开始训练
total_train_step = 0
first_train_step = 0
total_test_step = 0
epoch_sum = 15 # 迭代次数

# 添加tensorboard
writer = SummaryWriter('logs')

start_time = time.time()
last_epoch_time = time.time() # 记录开始训练的时间

for i in range(epoch_sum):
	print("----------------第 {} 轮训练开始了----------------:".format(i+1))

	# 训练步骤开始
	for data in train_dataloader:
		imgs, labels = data
		imgs, labels = imgs.to(device), labels.to(device)  # 将数据和目标移动到GPU
		outputs = CIFAR10_NET_Instance(imgs)
		loss_real = loss(outputs, labels) # 这里的损失变量 loss_real,千万别和损失函数 loss 相同,否则会报错!
		optimizer.zero_grad()
		loss_real.backward()
		optimizer.step() # 更新模型参数

		total_train_step += 1
		# 表示第一轮训练结束,取每一轮的第一个batch_size来看看训练效果
		if total_train_step % 782 == 0:
			first_train_step += 1
			print("训练次数为:{}, loss为:{}".format(total_train_step, loss_real)) # 此训练次数非训练轮次
			# 每轮测试结束之后,计算训练的准确率,就拿第一个batch_size来看看准确率
			outputs_B = torch.argmax(outputs, dim=1)
			outputs_C = (labels == outputs_B).sum()  # True默认为1,False默认为0
			accuracy = (outputs_C.item() / len(outputs_B)) * 100
			accuracy = round(accuracy, 2)  # 2表示保留两位小数(四舍五入)
			print(f"训练正确率为:{accuracy}%")

			writer.add_scalar('first_batch_size', loss_real.item(), first_train_step)
		writer.add_scalar('total_batch_size', loss_real.item(), total_train_step)

	# 每训练一轮,就使用测试集看看训练效果
	total_test_loss = 0
	with torch.no_grad():
		for data in test_dataloader:
			imgs, labels = data
			imgs, labels = imgs.to(device), labels.to(device)
			outputs = CIFAR10_NET_Instance(imgs)
			loss_fake = loss(outputs, labels)
			total_test_loss += loss_fake.item()
	print("整体测试集上的LOSS为:{}".format(total_test_loss))

	one_epoch_time = time.time()  # 记录训练一次的时间
	one_cost_time = one_epoch_time - last_epoch_time
	print(f"训练此轮需要的时间为:{one_cost_time}")
	last_epoch_time = one_epoch_time
	one_epoch_time = 0

end_time = time.time()
total_time = end_time - start_time
print(f"训练总计需要的时间为:{total_time}")

writer.close()


# 从本地拿出一张图片,看看模型的效果
test_image = Image.open("E:\\4_Data_sets\\others\\horse.jpg")
## 如果这个图片原本是png格式(有四个通道,RGBA,A为透明度),那么使用以下一行代码,只保留其RGB通道
#test_image = test_image.convert('RGB')

test_transforms = transforms.Resize([32,32])
test_image = test_transforms(test_image)
test_image_tensor = dataclass_transform(test_image)
print(test_image_tensor.shape)
test_image_tensor1 = torch.reshape(test_image_tensor, (1,3,32,32))  # 别忘记了!!!!!!!!
test_image_tensor1 = test_image_tensor1.to(device)
test_output = CIFAR10_NET_Instance(test_image_tensor1)
class_image = test_output.argmax(dim=1)
print(f"此图类别为:{class_image.item()}")

torch.save(CIFAR10_NET_Instance,"E:\\5_NN_model\\CIFAR10_NET_train10")
print("模型已保存!!")

运行结果:

Files already downloaded and verified
Files already downloaded and verified
50000 10000
----------------第 1 轮训练开始了----------------:
训练次数为:782, loss为:1.789782166481018
训练正确率为:37.5%
整体测试集上的LOSS为:255.33262872695923
训练此轮需要的时间为:19.126623153686523
----------------第 2 轮训练开始了----------------:
训练次数为:1564, loss为:1.5714988708496094
训练正确率为:43.75%
整体测试集上的LOSS为:198.84848326444626
训练此轮需要的时间为:14.118300914764404
----------------第 3 轮训练开始了----------------:
训练次数为:2346, loss为:1.2563223838806152
训练正确率为:56.25%
整体测试集上的LOSS为:174.16079074144363
训练此轮需要的时间为:14.806405305862427
----------------第 4 轮训练开始了----------------:
训练次数为:3128, loss为:1.1637380123138428
训练正确率为:50.0%
整体测试集上的LOSS为:156.08686345815659
训练此轮需要的时间为:14.412073135375977
----------------第 5 轮训练开始了----------------:
训练次数为:3910, loss为:0.8806682825088501
训练正确率为:62.5%
整体测试集上的LOSS为:155.79341107606888
训练此轮需要的时间为:14.46046495437622
----------------第 6 轮训练开始了----------------:
训练次数为:4692, loss为:0.6021975874900818
训练正确率为:81.25%
整体测试集上的LOSS为:159.8323387503624
训练此轮需要的时间为:14.461666107177734
----------------第 7 轮训练开始了----------------:
训练次数为:5474, loss为:0.6927397847175598
训练正确率为:75.0%
整体测试集上的LOSS为:171.83318477869034
训练此轮需要的时间为:14.535284042358398
----------------第 8 轮训练开始了----------------:
训练次数为:6256, loss为:0.40469425916671753
训练正确率为:87.5%
整体测试集上的LOSS为:178.93722027540207
训练此轮需要的时间为:18.05676531791687
----------------第 9 轮训练开始了----------------:
训练次数为:7038, loss为:0.6831881403923035
训练正确率为:68.75%
整体测试集上的LOSS为:184.60061931610107
训练此轮需要的时间为:15.902337789535522
----------------第 10 轮训练开始了----------------:
训练次数为:7820, loss为:0.2611675262451172
训练正确率为:93.75%
整体测试集上的LOSS为:196.9536812901497
训练此轮需要的时间为:14.7198965549469
----------------第 11 轮训练开始了----------------:
训练次数为:8602, loss为:0.38262906670570374
训练正确率为:81.25%
整体测试集上的LOSS为:185.48081707954407
训练此轮需要的时间为:14.651979684829712
----------------第 12 轮训练开始了----------------:
训练次数为:9384, loss为:0.12091360986232758
训练正确率为:93.75%
整体测试集上的LOSS为:198.3158984184265
训练此轮需要的时间为:14.581665277481079
----------------第 13 轮训练开始了----------------:
训练次数为:10166, loss为:0.2111598700284958
训练正确率为:93.75%
整体测试集上的LOSS为:225.97497355937958
训练此轮需要的时间为:14.554025411605835
----------------第 14 轮训练开始了----------------:
训练次数为:10948, loss为:0.13422876596450806
训练正确率为:100.0%
整体测试集上的LOSS为:221.3252665400505
训练此轮需要的时间为:14.511592149734497
----------------第 15 轮训练开始了----------------:
训练次数为:11730, loss为:0.18214434385299683
训练正确率为:93.75%
整体测试集上的LOSS为:214.04039084911346
训练此轮需要的时间为:14.598362445831299
训练总计需要的时间为:227.4974422454834
torch.Size([3, 32, 32])
此图类别为:7
模型已保存!!

Process finished with exit code 0

类别 7 是马。


上一篇下一篇
神经网络入门实战(十八)待发布

标签:----------------,loss,训练,为例,CIFAR10,test,train,测试代码
From: https://blog.csdn.net/qq_51409113/article/details/144331610

相关文章

  • 使用外站题目与数据(以洛谷和Loj为例)
    本食用方法以[NOIP2024]树上查询为例一、题目仅介绍洛谷食用方法在洛谷页面首先确保你有洛谷账号(非常重要,没有账号测试样例无法下载!)在左侧侧边栏点击“题库”,进入洛谷主题库进入题目P11364请点击题面右上角复制Markdown标签随后回到洛谷题面页面,查看并记......
  • C#实现一个HttpClient集成通义千问-测试代码入手学习参数配置
    测试代码入手学习参数配置准备测试代码修改配置效果:修改消息内容测试流式输出设置流式输出的参数视频教程准备测试代码我们学习从测试代码开始,选择一个模型选择的大模型:通义千问2-VL-开源版-7B然后再API示例中,找到C#的示例代码测试代码:usingSystem.Net.Http.H......
  • Git如何将本地代码上传到远端仓库(以gitee为例)
    ......
  • 鼠标键盘游戏手柄的测试代码
    #include"QtWidgetsApplication2.h"#include<windows.h>#include<QDebug>#include<QVBoxLayout>QtWidgetsApplication2::QtWidgetsApplication2(QWidget*parent):QFrame(parent){ui.setupUi(this); //init();}QtWidget......
  • CAD 二次开发入门与实践:以 C# 为例
    摘要: 本文详细介绍了如何使用C#进行CAD软件的二次开发。首先阐述了CAD二次开发的概念、意义与应用场景,接着深入探讨了开发环境的搭建,包括CAD相关API的引用与C#开发工具的配置。随后重点讲解了基于C#的CAD二次开发的核心技术,如基本图形绘制、图层管理、块操作......
  • 你是如何测试代码的性能的?都有用到哪些工具?
    作为大型语言模型,我不会直接“运行”或“测试”代码,但我可以提供关于前端代码性能测试方法和工具的信息,并帮助你理解如何使用它们。前端性能测试主要关注以下几个方面:加载性能:页面加载速度有多快?运行时性能:页面交互有多流畅?动画是否卡顿?内存使用:页面消耗多少内存?是......
  • 【CameraPoseRefinement】以BARF为例介绍三维重建中的位姿优化
    Introduction在计算机视觉三维重建中,求解3D场景的表示和定位给定的相机帧的相机位姿是两个非常重要的任务,这两个问题互为依赖,一方面,恢复3D场景的表示需要使用已知的相机位姿进行观察;另一方面,定位相机需要来自特征点的可靠对应。错误的相机位姿会对重建的输出和性能产生一系列负......
  • 高效处理 iOS 应用中的大规模礼物数据:以直播项目为例(1-礼物池)
    引言在现代iOS应用开发中,处理大规模数据是一个常见的挑战。尤其实在直播项目中,礼物面板作为展示用户互动的重要部分,通常需要实时显示海量的礼物数据。这些数据不仅涉及到不同的区域、主播的动态差异,还需要保证高效的加载与渲染,以提供流畅的用户体验。本篇博客将以直播应用中......
  • 以Deformable_DETR为例说明训练过程
    以Deformable_DETR为例说明使用服务器训练过程下载程序文件根据论文提供的github地址fundamentalvision/Deformable-DETR:DeformableDETR:DeformableTransformersforEnd-to-EndObjectDetection.下载zip到本地租用服务器在autodl平台租用服务器,申请账号氪金之后去市场......
  • 以学校数据模型为例,掌握在DAS下使用GaussDB
    @目录题目具体操作一、表的创建二、表数据的插入三、数据查询目的:这里以学校数据库模型为例,介绍GaussDB数据库、表等常见操作,以及SQL语法使用的介绍。题目假设A市B学校为了加强对学校的管理,引入了华为GaussDB数据库。在B学校里,主要涉及的对象有学生、教师、班级、院系和课程......