完整对CIFAR10训练

1.训练集和测试集引入

# 训练集和测试集引入
train_data = torchvision.datasets.CIFAR10(root = "E:\\PyCharm_Project\\Pytorch_2.3.1\\ALL_Datasets\\CIFAR10" , train = True , transform = torchvision.transforms.ToTensor() , download = True)
test_data = torchvision.datasets.CIFAR10(root = "E:\\PyCharm_Project\\Pytorch_2.3.1\\ALL_Datasets\\CIFAR10" , train = False , transform = torchvision.transforms.ToTensor() , download = True)

# 打印测试集长度
print("训练集长度为{}".format(len(train_data)))
print("训练集长度为{}".format(len(test_data)))

2.DataLoader

# dataloader
dataloader = DataLoader(dataset = train_data , batch_size = 64 , shuffle = False)
dataloader_test = DataLoader(dataset = test_data , batch_size = 64 , shuffle = False)

3.定义损失函数

# loss
loss = nn.CrossEntropyLoss()

4.优化器

# adam,可以自适应,无需加入lr
learning_rate = 1e-3
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

5.设置记录参数和tensorboard

# 记录数据
total_train_step = 0
total_test_step = 0

# 训练轮数
epoch = 10

# 可视化tensorboard
writer = SummaryWriter('./logs')

6.将模型单独写在一个文件里

import torch
from torch import nn


class Zilliax(nn.Module):
    def __init__(self):
        super(Zilliax,self).__init__()
        self.model = nn.Sequential(
            nn.Conv2d(3,32,5,1,2),
            nn.MaxPool2d(2),
            nn.Conv2d(32,32,5,1,2),
            nn.MaxPool2d(2),
            nn.Conv2d(32,64,5,1,2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(64*4*4 , 64),
            nn.Linear(64,10)
        )


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

model = Zilliax()
# main里面的内容只会在当前文件运行时进入运行
if __name__ == '__main__':

    print(model)
    test = torch.ones((64 ,3 , 32 , 32))
    result = model(test)
    print(result.shape)

 

7.训练测试并进行操作

for i in range(epoch):
    print("第{}轮训练".format(i+1))
    for data in dataloader:
        imgs , labels = data
        outputs = model(imgs)
        loss_train = loss(outputs , labels)
        optimizer.zero_grad()
        loss_train.backward()
        optimizer.step()
        total_train_step += 1
        # 加上.item()就不会打印出tensor(x),而是直接打印出x
        if total_train_step % 100 == 0:
            print("训练次数:{} , loss:{}".format(total_train_step,loss_train.item()))
            writer.add_scalar('train_loss',loss_train.item(),total_train_step)
    # 测试步骤
    total_test_loss = 0
    total_accuracy = 0
    with torch.no_grad():
        for data in dataloader_test:
            imgs , labels = data
            outputs = model(imgs)
            loss_test = loss(outputs , labels)
            total_test_loss += loss_test.item()
            """
            # argmax():处理output里的tensor值,(1)代表横着数据一行为一组,(0)代表竖着数据一列为一组,输出每一组最大值的下标
            outputs 的形状是 (64, 10),对应于一个批次的 64 张图像,每张图像都有 10 个类别的预测分数:
            假设outputs = torch.tensor([
            [1.2, -0.5, 3.0, 0.1, 2.3, -1.0, 0.7, 0.5, 1.1, -0.2],  # 第1个图像
            [0.3, 2.2, -0.4, 1.9, -0.3, 2.7, -1.1, 0.4, 0.2, 1.5],  # 第2个图像
            ......其他62张图像
            则在这个例子中,outputs 的第一行对应第一个图像:
            模型预测它最有可能属于第三个类别(分数是 3.0),其次是第五个类别(分数是 2.3)。
            argmax(1) 会选择最大值的索引,即 2,表示预测的类别是第3类。
            类似地,outputs 的第二行对应第二个图像:
            最大值是 2.7,对应第六个类别。
            argmax(1) 会返回 5,表示预测的类别是第6类。
            于是outputs.argmax(1)就会返回一个tensor([2,5,.......])
            并与label[4,5........]进行对比,对不上为false,对的上为true
            再用.sum()将所有的true = 1, false = 0相加,得到这一组64个图片的正确率
            然后用total_acc加上存储,最终得到50000个01相加之和,除以50000
            
            outputs 是 logits(未归一化的实数),而不是概率,
            Logits 是模型最后一层的输出,它们表示模型对各类别的信心值。由于这些值未归一化,因此它们可以是正数、负数或零。
            概率 是通过对 logits 进行归一化(通常使用 Softmax 函数)后得到的值。
            Softmax 函数将 logits 转换为 [0, 1] 范围内的值,所有类别的概率之和为 1。
            但是在计算准确率时,只关心模型认为哪个类别的得分(logit)最高。
            具体地说,我们使用 argmax 函数找到 logit 值最大的那个类别,认为这是模型的预测。
            在分类任务中,计算正确率时,只需找到得分最高的类别,无需关心这些得分是否经过归一化。
            因此,直接使用 logits 计算准确率是常见且有效的方法。
            """

            acc = (outputs.argmax(1) == labels).sum()
            total_accuracy += acc

        print("第{}轮测试的整体loss集为:{}".format(total_test_step,total_test_loss))
        print("第{}轮测试的整体正确率为:{}".format(total_test_step,total_accuracy/len(test_data)))
        writer.add_scalar('test_loss',total_test_loss,total_test_step)
        writer.add_scalar('test_accuracy',total_accuracy/len(test_data),total_test_step)
        total_test_step += 1
        # 保存每一轮训练的模型
        torch.save(model,"Zilliax_{}.pth".format(i))
        print("save over")




writer.close()

整体代码和可视化结果

Model.py

import torch
from torch import nn


class Zilliax(nn.Module):
    def __init__(self):
        super(Zilliax,self).__init__()
        self.model = nn.Sequential(
            nn.Conv2d(3,32,5,1,2),
            nn.MaxPool2d(2),
            nn.Conv2d(32,32,5,1,2),
            nn.MaxPool2d(2),
            nn.Conv2d(32,64,5,1,2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(64*4*4 , 64),
            nn.Linear(64,10)
        )


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

model = Zilliax()
if __name__ == '__main__':

    print(model)
    test = torch.ones((64 ,3 , 32 , 32))
    result = model(test)
    print(result.shape)

Train.py

import torch
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

from model import *

# 训练集和测试集引入
train_data = torchvision.datasets.CIFAR10(root = "E:\\PyCharm_Project\\Pytorch_2.3.1\\ALL_Datasets\\CIFAR10" , train = True , transform = torchvision.transforms.ToTensor() , download = True)
test_data = torchvision.datasets.CIFAR10(root = "E:\\PyCharm_Project\\Pytorch_2.3.1\\ALL_Datasets\\CIFAR10" , train = False , transform = torchvision.transforms.ToTensor() , download = True)

# 打印测试集长度
print("训练集长度为{}".format(len(train_data)))
print("训练集长度为{}".format(len(test_data)))

# dataloader
dataloader = DataLoader(dataset = train_data , batch_size = 64 , shuffle = False)
dataloader_test = DataLoader(dataset = test_data , batch_size = 64 , shuffle = False)

# loss
loss = nn.CrossEntropyLoss()

# adam,可以自适应,无需加入lr
learning_rate = 1e-3
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

# 记录数据
total_train_step = 0
total_test_step = 0

# 训练轮数
epoch = 10

# 可视化tensorboard
writer = SummaryWriter('./logs')

for i in range(epoch):
    print("第{}轮训练".format(i+1))
    for data in dataloader:
        imgs , labels = data
        outputs = model(imgs)
        loss_train = loss(outputs , labels)
        optimizer.zero_grad()
        loss_train.backward()
        optimizer.step()
        total_train_step += 1
        # 加上.item()就不会打印出tensor(x),而是直接打印出x
        if total_train_step % 100 == 0:
            print("训练次数:{} , loss:{}".format(total_train_step,loss_train.item()))
            writer.add_scalar('train_loss',loss_train.item(),total_train_step)
    # 测试步骤
    total_test_loss = 0
    total_accuracy = 0
    with torch.no_grad():
        for data in dataloader_test:
            imgs , labels = data
            outputs = model(imgs)
            loss_test = loss(outputs , labels)
            total_test_loss += loss_test.item()
            """
            # argmax():处理output里的tensor值,(1)代表横着数据一行为一组,(0)代表竖着数据一列为一组,输出每一组最大值的下标
            outputs 的形状是 (64, 10),对应于一个批次的 64 张图像,每张图像都有 10 个类别的预测分数:
            假设outputs = torch.tensor([
            [1.2, -0.5, 3.0, 0.1, 2.3, -1.0, 0.7, 0.5, 1.1, -0.2],  # 第1个图像
            [0.3, 2.2, -0.4, 1.9, -0.3, 2.7, -1.1, 0.4, 0.2, 1.5],  # 第2个图像
            ......其他62张图像
            则在这个例子中,outputs 的第一行对应第一个图像:
            模型预测它最有可能属于第三个类别(分数是 3.0),其次是第五个类别(分数是 2.3)。
            argmax(1) 会选择最大值的索引,即 2,表示预测的类别是第3类。
            类似地,outputs 的第二行对应第二个图像:
            最大值是 2.7,对应第六个类别。
            argmax(1) 会返回 5,表示预测的类别是第6类。
            于是outputs.argmax(1)就会返回一个tensor([2,5,.......])
            并与label[4,5........]进行对比,对不上为false,对的上为true
            再用.sum()将所有的true = 1, false = 0相加,得到这一组64个图片的正确率
            然后用total_acc加上存储,最终得到50000个01相加之和,除以50000
            
            outputs 是 logits(未归一化的实数),而不是概率,
            Logits 是模型最后一层的输出,它们表示模型对各类别的信心值。由于这些值未归一化,因此它们可以是正数、负数或零。
            概率 是通过对 logits 进行归一化(通常使用 Softmax 函数)后得到的值。
            Softmax 函数将 logits 转换为 [0, 1] 范围内的值,所有类别的概率之和为 1。
            但是在计算准确率时,只关心模型认为哪个类别的得分(logit)最高。
            具体地说,我们使用 argmax 函数找到 logit 值最大的那个类别,认为这是模型的预测。
            在分类任务中,计算正确率时,只需找到得分最高的类别,无需关心这些得分是否经过归一化。
            因此,直接使用 logits 计算准确率是常见且有效的方法。
            """

            acc = (outputs.argmax(1) == labels).sum()
            total_accuracy += acc

        print("第{}轮测试的整体loss集为:{}".format(total_test_step,total_test_loss))
        print("第{}轮测试的整体正确率为:{}".format(total_test_step,total_accuracy/len(test_data)))
        writer.add_scalar('test_loss',total_test_loss,total_test_step)
        writer.add_scalar('test_accuracy',total_accuracy/len(test_data),total_test_step)
        total_test_step += 1
        # 保存每一轮训练的模型
        torch.save(model,"Zilliax_{}.pth".format(i))
        print("save over")



writer.close()

 

 

 

 

 

 

 

 

 

        

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值