AlexNet网络模型

AlexNet网络参数详解

在这里插入图片描述
我们以FashionMNIST作为数据集,因此下面的模型代码是在所用的数据集基础上有所调整,输入部分是灰色图因此是1227227的,目标是做10分类,因此最后一层全连接层的输出通道为10.
值得注意的是:

每一层的卷积之后都需要用激活函数来进行激活。
全连接层是否有激活函数,是由网络结构决定的。
#模型搭建完整代码
import torch
from torch import nn
from torchsummary import summary  #输入,出特征图大小,以及网络层数的一些细节
import torch.nn.functional as F    #便于dropout操作,防止过拟合

class AlexNet(nn.Module):     #继承nn里面的一些库
    #初始化定义一些网络层,初始化
    def __init__(self):
        super(AlexNet,self).__init__()  #开始搭建前向传播的一些网络层
        self.ReLU = nn.ReLU()   #名字可以自己去取,尽可能知道是干什么的即可,()不要少
        #在原理讲解时候,数据集是彩色(RGB)的,即三通道的,这里的数据集是灰色的,因此输入通道数是1
        self.c1 = nn.Conv2d(in_channels=1,out_channels=96,kernel_size=11,stride=4)
        #用的是最大池化,需要注意,不存在通道数的改变,只关注,感受野,步长,填充大小即可
        self.s2 = nn.MaxPool2d(kernel_size=3,stride=2)
        self.c3 = nn.Conv2d(in_channels=96,out_channels=256,kernel_size=5,padding=2)
        self.s4 = nn.MaxPool2d(kernel_size=3, stride=2)
        self.c5 = nn.Conv2d(in_channels=256,out_channels=384,kernel_size=3,padding=1)
        self.c6 = nn.Conv2d(in_channels=384, out_channels=384, kernel_size=3, padding=1)
        self.c7 = nn.Conv2d(in_channels=384, out_channels=256, kernel_size=3, padding=1)
        self.s8 = nn.MaxPool2d(kernel_size=3, stride=2)
        self.flatten = nn.Flatten()
        self.f1 = nn.Linear(6*6*256,4096)
        self.f2 = nn.Linear(4096, 4096)
        self.f3 = nn.Linear(4096, 10)    ##这里是因为要做的是10分类,因此输出通道数为10,可以根据自己的目的进行改变 
    ##前向传播过程,串起来所有的神经网络
    def forward(self,x):
        ##特征提取的过程
        x = self.ReLU(self.c1(x))    #先经过卷积层,后经过激活函数输出
        x = self.s2(x)           #经过池化层输出的特征图
        x = self.ReLU(self.c3(x))
        x = self.s4(x)
        x = self.ReLU(self.c5(x))
        x = self.ReLU(self.c6(x))
        x = self.ReLU(self.c7(x))
        x = self.s8(x)
        ##经过全连接层部分,网络原理提到前两层的全连接层是用ReLU激活函数的,还有dropout操作随机神经元失活
        x = self.flatten(x)
        x = self.ReLU(self.f1(x))
        x = F.dropout(x,0.5)     #设置一定的比例,防止过拟合
        x = self.ReLU(self.f2(x))
        x = F.dropout(x, 0.5)
        x = self.f3(x)
        return x    #前向传播结束后的输出


#写一个主函数测试一下,是否跑通了
if __name__ == "__main__":
    device = torch.device("cuda" if torch.cuda.is_available() else 'cpu')
    model = AlexNet().to(device)     #将实例化之后的代码放入到设备中
    print(summary(model,(1,227,227)))       #放入模型及输入的维度,打印输入输出特征图的尺寸,以及网络结构的参数   

self.ReLU = nn.ReLU() 这里的括号一定不能少
如果少了,便会出现下面的报错;
补充:
在 PyTorch 中,nn.ReLU 可以以两种方式使用:

  1. 作为函数使用:直接调用 nn.ReLU() 作为函数,它将对输入张量逐元素地应用 ReLU 激活函数。这种方式不需要实例化,直接使用即可。
  2. 作为模块实例化:通过 nn.ReLU()(注意没有括号)实例化成一个模块对象,这个对象可以被保存、加载或重复使用。当你实例化它时,你可以将它赋给一个变量,然后在模型的 forward 方法中使用这个变量来调用 ReLU 激活函数。
  3. self.ReLU = nn.ReLU 与 self.ReLU = nn.ReLU()
    ● self.ReLU = nn.ReLU:这种方式是将 nn.ReLU 作为一个类引用赋值给了 self.ReLU。这实际上并没有创建 ReLU 的实例,而是将类本身赋给了变量。在 PyTorch 中,这样使用是不正确的,因为当你尝试调用 self.ReLU(x) 时,PyTorch 会期望一个模块实例,而不是类本身。
    ● self.ReLU = nn.ReLU():这种方式创建了 nn.ReLU 的一个实例,并将其赋值给了 self.ReLU。这样,你就可以在模型的 forward 方法中使用 self.ReLU(x) 来对输入 x 应用 ReLU 激活函数。
    正确用法
    在你的 AlexNet 类中,如果你想使用 ReLU 激活函数,你应该这样定义和使用它:
class AlexNet(nn.Module):
    def __init__(self):
        super(AlexNet, self).__init__()
        self.relu = nn.ReLU()  # 实例化 ReLU
        # ... 其他层的定义 ...

    def forward(self, x):
        x = self.relu(self.c1(x))  # 使用实例化的 ReLU
        # ... 其他操作 ...

或者,如果你想直接使用它作为函数,可以省略实例化步骤:

class AlexNet(nn.Module):
    def __init__(self):
        super(AlexNet, self).__init__()
        # ... 其他层的定义 ...

    def forward(self, x):
        x = nn.ReLU(self.c1(x))  # 直接使用 ReLU 作为函数
        # ... 其他操作 ...

在大多数情况下,直接使用 nn.ReLU 作为函数调用是更简洁和常见的做法。实例化通常在你需要保存模型状态或在模型中多次使用相同配置的激活函数时使用。也就是调用库的某个函数的时候记得加括号进行实例化,否则在进行使用会报错。

TypeError: max_pool2d(): argument 'input' (position 1) must be Tensor, not ReLU

上面没有报错情况下,便会得到网络的各层的情况,及参数的总数。
在这里插入图片描述
记住现在的参数总量,下一篇文章,有一个奇怪的问题,不知道是什么原因?
模型训练的代码
需要在之前的LeNet-5网络基础上进行稍微的改变即可。
下面的地方进行修改即可,路径改成自己的

导入库,数据的大小,权重地址,模型实例化,需要注意的是batch size需要根据自己的显卡情况进行调整
from model import AlexNet

train_data = FashionMNIST(root='./data',
                              train=True,
                              transform=transforms.Compose((transforms.Resize(size=227), transforms.ToTensor())),
                              download=True)

torch.save(best_model_wts, 'C:/Users/mcg/Desktop/LeNet/best_model.pth')

AlexNet = AlexNet()

train_process = train_model_process(AlexNet,train_dataloader,val_dataloader,20) 

下面是改之后的完整训练代码

#加载数据,并进行可视化,loss,准确率等的展示
import copy
import time

import pandas as pd
import torch
from torchvision.datasets import FashionMNIST
from torchvision import transforms
import torch.utils.data as Data
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
#从model.py导入我们的模型
from model import AlexNet

#训练集和验证集的定义,名称尽可能一目了然,用于处理训练集和验证集
def train_val_data_process():
    ##数据加载进来,transforms.Compose((transforms.Resize(size=28),大小设置按照模型的输入要求来,AlexNet网络的大小是227
    train_data = FashionMNIST(root='./data',
                              train=True,
                              transform=transforms.Compose((transforms.Resize(size=227), transforms.ToTensor())),
                              download=True)
    #把数据集划分为训练集和验证集=8:2
    train_data,val_data = Data.random_split(train_data,[round(0.8*len(train_data)),round(0.2*len(train_data))])
    #先放入数据,一批次数量(数据量比较小,6G运存应该是够的),shuffle是否打乱数据,进程是8,电脑垃圾的话,就改小一点
    train_dataloader = Data.DataLoader(dataset=train_data,
                                       batch_size=32,
                                       shuffle=True,
                                       num_workers=2)
    ##最好训练和验证集的操作是一样的
    val_dataloader = Data.DataLoader(dataset=val_data,
                                       batch_size=32,
                                       shuffle=True,
                                       num_workers=2)
    return train_dataloader , val_dataloader   #返回训练集和验证集

    #模型训练过程,传入模型,训练,验证集,训练的轮次
def train_model_process(model,train_dataloader,val_dataloader,num_epochs):
    #设定训练所用到的设备,有GPU用GPU,没有GPU用CPU
    #告诉设备情况,这一步用到了torch,就需要在前面进行导入,就是这么一个过程,一开始不知道都用那些库,写着需要了就进行导入
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    #使用Adam优化器,便于后续的参数进行更新的,lr表示为学习率,Adam可以理解是梯度下降法的一种优化改良
    optimizer = torch.optim.Adam(model.parameters(),lr=0.001)
    #定义损失函数,在分类问题中一般损失函数用交叉熵损失函数,回归一般用均方差损失函数,来利用损失值来更新参数w和b
    criterion = nn.CrossEntropyLoss()
    #将模型放入到训练设备中
    model = model.to(device)

    #复制当前模型的参数,w,b会有一个初始化的值,随着反向传播的进行,w,b在进行不断的更新。后续把 best_model_wts保存下来(也即是权重)后续测试时可以进行加载

    best_model_wts = copy.deepcopy(model.state_dict())
    ##初始化参数
    ##最高准确度,初始化为0,后续会覆盖掉
    best_acc = 0.0

    #训练集损失值列表,改的地方
    # 训练集损失值列表
    train_loss_all = []
    # 验证集损失值列表
    val_loss_all = []
    # 训练集精度值列表
    train_acc_all = []
    # 验证集精度值/准确度列表
    val_acc_all = []
    #保存当前时间,方便知道一轮会用时多久,time.time()不要自己全部手敲,会报错,就time.等弹出选择即可
    since = time.time()

    #利用循环进行训练,打印信息的阶段
    for epoch in range(num_epochs):
        print("Epoch{}/{}".format(epoch,num_epochs-1))   #减1的原因在于,是从0开始99结束,共100轮(如果以100为例情况下)
        print("-"*10)

    #初始化参数,方便每一轮的开始值都是0,从而可以计算每一轮的loss和准确率,需要计算平均loss值,就需要定义样本数量
        #训练集损失函数
        train_loss = 0.0
        #训练集准确度
        train_corrects = 0
        # 验证集损失函数
        val_loss = 0.0
        # 验证集准确度
        val_corrects = 0

        #定义该轮次的训练集样本数量
        train_num = 0
        #验证集样本数量
        val_num = 0

        #取数据过程,模型和数据需要放在同一个设备,否则会出错
        #对每一个mini-batch训练和计算
        for step, (b_x, b_y) in enumerate(train_dataloader):
            #将特征放入到训练设备中
            b_x = b_x.to(device)
            #将标签值放入到训练设备中
            b_y = b_y.to(device)
            #设置模型的训练模式
            model.train()

            #前向传播过程,输入为一个batch,输出为一个batch中对应的预测,output不是最终的结果而是一个向量
            output = model(b_x)

            #使用softmax取概率最大的作为标签,查找每一行中最大值对应的行标(类别)
            pre_lab = torch.argmax(output,dim=1)
            #利用模型的输出和标签来计算损失,不是通过softmax之后的结果和标签计算哦
            loss = criterion(output,b_y)

            #每一轮开始前将梯度初始化为0,防止梯度累计从而对参数更新产生干扰,只有这样每一轮结束之后才能更新参数w和b
            optimizer.zero_grad()
            #反向传播计算
            loss.backward()
            #根据网络反向传播的梯度信息来更新网络参数,以起到降低loss值函数计算值的作用,利用Adam优化器进行更新参数
            optimizer.step()
            #对损失函数进行累加
            train_loss += loss.item() * b_x.size(0)
            #如果预测正确,则准确度train_corrects+1
            train_corrects += torch.sum(pre_lab == b_y.data)
            #当前该轮次用于训练的样本数量
            train_num += b_x.size(0)

            #模型验证代码部分撰写,基本和训练过程是差不多的操作,是不参与模型的训练,单纯计算loss和准确度,没有反向传播过程
            # 对每一个mini-batch训练和计算,直到最后一批次结束,意味着一轮结束。
        for step, (b_x, b_y) in enumerate(val_dataloader):
            #将特征放入到验证设备中
             b_x = b_x.to(device)
           #将标签值放入到验证设备中
             b_y = b_y.to(device)
            #设置模型的评估模式
             model.eval()
            #前向传播过程,输入为一个batch,输出为一个batch中对应的预测
             output = model(b_x)
              # 使用softmax取概率最大的作为标签,查找每一行中最大值对应的行标(类别)
             pre_lab = torch.argmax(output, dim=1)
             # 利用模型的输出和标签来计算损失,不是通过softmax之后的结果和标签计算哦
            ##相比较于训练过程,是没有反向传播,梯度更新,参数更新的过程。
             loss = criterion(output, b_y)
              #对损失函数进行累加,批次的平均loss*批次数量
             val_loss += loss.item() * b_x.size(0)
             #如果预测正确,则准确度train_corrects+1
             val_corrects += torch.sum(pre_lab == b_y.data)
             #当前用于评估/评估的样本数量
             val_num += b_x.size(0)

              #计算并保存每一次迭代(轮次epoch?)的平均loss和准确度,后续需要进行打印或者绘图
        train_loss_all.append(train_loss / train_num)
        #计算并保存训练集的准确率
        train_acc_all.append(train_corrects.double().item() / train_num)
        # 计算并保存验证集的loss值
        val_loss_all.append(val_loss / val_num)
        # 计算并保存验证集的准确率
        val_acc_all.append(val_corrects.double().item() / val_num)

              ##将上述结果进行打印[-1]表示取当前轮次的数值,print缩进的话,把内部训练的每一次都会进行打印的。
        print('{} Train Loss: {:.4f} Train Acc: {:.4f}'.format(epoch,train_loss_all[-1],train_acc_all[-1]))
        print('{} Val Loss: {:.4f} Val  Acc: {:.4f}'.format(epoch,val_loss_all[-1], val_acc_all[-1]))

        #寻找最高准确度(当前准确度和最佳准确度进行比较,有点排序算法的感觉)
        if val_acc_all[-1] > best_acc:
              #保存当前的最高准确度
               best_acc = val_acc_all[-1]
               #在当前最高的准确度情况下,保存对应的模型权重
               best_model_wts = copy.deepcopy(model.state_dict())
            #训练耗费的时间
        time_use = time.time() - since
        print("训练和验证耗费的时间{:.0f}m{:.0f}s".format(time_use//60,time_use%60))

    #选择最优参数
    #加载最高准确率下的模型参数,并进行保存到一个文件地址,项目文件夹下产生一个best_model.pth,.pth是权重的独特后缀
    #model.load_state_dict(best_model_wts),这行代码是没有用的。下面的两种保存权重方法都是可以的,权重的路径改一下,别一下跑到LeNet的去了
    torch.save(best_model_wts, 'C:/Users/mcg/Desktop/AlexNet/best_model.pth')
    #torch.save(model.state_dict(best_model_wts), 'C:/Users/mcg/Desktop/LeNet/best_model.pth')
    #原先的,这样是不行的,torch.save(model.load_state_dict(best_model_wts),'C:/Users/mcg/Desktop/LeNet/best_model.pth')

    #将训练的数值保存为一种文件格式,最重要的就是训练完之后,会保存最优模型的权重。
    train_process = pd.DataFrame(data={"epoch":range(num_epochs),
                                       "train_loss_all":train_loss_all,
                                       "val_loss_all":val_loss_all,
                                       "train_acc_all":train_acc_all,
                                       "val_acc_all": val_acc_all})
    return train_process
#2024年7月22日继续学习
##定义一个绘制loss和acc的绘制图的函数,将train_process作为输入传进去
def matplot_acc_loss(train_process):
    plt.figure(figsize=(12,4))     #设置图形的大小
    plt.subplot(1,2,1)        #子图可以按照matlab的画法进行理解
    plt.plot(train_process["epoch"], train_process.train_loss_all, 'ro-' , label = "train loss")    #绘制训练集损失曲线,并加上曲线等设置
    plt.plot(train_process["epoch"], train_process.val_loss_all, 'bs-', label="val loss")  # 绘制验证集损失曲线,并加上曲线等设置
    plt.legend()  #标签
    plt.xlabel("epoch")
    plt.ylabel("loss")

    plt.subplot(1, 2, 2)  # 子图可以按照matlab的画法进行理解
    plt.plot(train_process["epoch"], train_process.train_acc_all, 'ro-', label="train acc")  # 绘制训练集损失曲线,并加上曲线等设置
    plt.plot(train_process["epoch"], train_process.val_acc_all, 'bs-', label="val acc")  # 绘制验证集损失曲线,并加上曲线等设置
    plt.legend()  # 图例
    plt.xlabel("epoch")
    plt.ylabel("acc")
    plt.legend()  # 图例
    plt.show()    #绘制

#对数据开始训练
#主函数,开始运行所有的代码   注意点1:双等号。2.要有冒号:
if __name__ == "__main__":
     #将模型进行实例化,如果后续是别的模型呢?from model import LeNet,先进行搭建我们的model.py,进而将model导入进去,然后在下面进行实例化。将模型放到训练代码就可以了。有个别的模型可能数据的预处理需要改一点。
     AlexNet = AlexNet()
     #加载数据集,分为训练集和验证集
     train_dataloader,val_dataloader = train_val_data_process()
     #将训练集,验证集,模型,和训练次数放进训练代码中,
     train_process = train_model_process(AlexNet,train_dataloader,val_dataloader,20)    #自己进行设定训练的次数,假如这里的训练次数是20轮,并保留中间值
     ##绘制损失和准确率的图形
     matplot_acc_loss(train_process)

这一部分训练过程中任务管理器的情况:
在这里插入图片描述
训练的结果:
9 Train Loss: 0.2275 Train Acc: 0.9177
19 Val Loss: 0.3436 Val Acc: 0.8927

训练和验证耗费的时间70m43s(20轮)

在这里插入图片描述
从图中可以看出,稍微有一点点的过拟合
原因
1:神经网络的参数比较多,比较大,导致可能过拟合了
2.数据原本是28X28,现在把它拉大到227X227,可能有些信息被破坏了。
训练完之后,会产生一个best_model.pth 文件
进而进行模型的测试
在这里插入图片描述在这里插入图片描述
模型测试的时候,要加载模型测试的函数呢,否则,不会报错,但没有结果显示,记住哦,测试的时候。
模型推理,单张分类的时候,就不需要加载模型测试的函数哦。
模型测试部分的代码,不含每一张类别的具体情况

import torch   #用不用都先导入进来
import torch.utils.data as Data    #导入数据处理的库
from torchvision import transforms
from torchvision.datasets import FashionMNIST    #导入我们所用的数据集
from model import AlexNet   #导入需要测试的模型

##数据就处理好了。
##导入数据进行模型的测试,从模型训练的代码拿一部分,改改即可,batch_size=1,希望是一张一张的去进行测试,不需要什么进程,改为num_workers=0即可
def test_data_process():
    ##数据加载进来,transforms.Compose((transforms.Resize(size=28),大小设置按照模型的输入要求来
    test_data = FashionMNIST(root='./data',
                              train=False,
                              transform=transforms.Compose((transforms.Resize(size=227), transforms.ToTensor())),
                              download=True)

    #先放入数据,一批次数量(数据量比较小,6G运存应该是够的),shuffle是否打乱数据,进程是8,电脑垃圾的话,就改小一点
    test_dataloader = Data.DataLoader(dataset=test_data,
                                       batch_size=1,
                                       shuffle=True,
                                       num_workers=0)

    return test_dataloader

##测试,只需要导入模型和数据集,得到一个测试的结果即可
def test_model_process(model,test_dataloader):
    #设定测试用到的设备,有GPU用GPU,没有GPU用CPU
    device = "cuda" if torch.cuda.is_available() else "cpu"
    #将模型放入到测试设备当中
    model = model.to(device)
    #初始化模型参数,准确度即可,虽然已经知道测试的数据集有10000张,但为了后续不知道张数的情况下,也能进行测试。
    test_corrects = 0.0
    test_num = 0

    ##开始模型的测试,不存在反向传播,因此将梯度置为0,只有前向传播,不计算梯度,从而节省内存,加快运行速度
    with torch.no_grad():
        #直接一批次一批次的获取就好了。
        for test_data_x,test_data_y in test_dataloader:
            #将特征放入到测试设备中
            test_data_x = test_data_x.to(device)
            #将标签也放入到测试设备中
            test_data_y = test_data_y.to(device)
            #模型测试状态
            model.eval()
            #前向传播过程,输入为测试数据集,输出为对每个样本的预测值,它其实是一个10*1的矩阵,并不能看出结果来,需要经过一个softmax得到结果。最大概率对应的下标
            output = model(test_data_x)
             #预测的类别,查找每一行中最大值对应的行标
            pre_lab = torch.argmax(output,dim=1)
            #预测的结果和标签一样+1,如果预测正确,则 test_corrects加1,直到循环结束
            test_corrects += torch.sum(pre_lab == test_data_y.data)
            #将所有的测试样本进行累加
            test_num += test_data_x.size(0)

    #计算测试准确率,不在循环里面哦,注意缩进
    test_acc = test_corrects.double().item() / test_num

    print("测试的准确率为:" ,  test_acc)


#主函数进行运行程序
if __name__ == "__main__" :
    #加载模型
    model = AlexNet()
    #torch.load('best_model.pth')加载训练好的模型参数,权重以字符串的形式, model.load_state_dict模型训练化,将实例化之后的模型加载上权重,规定的做法

    model.load_state_dict(torch.load('best_model.pth'))
    #导入测试集的数据集,加载测试数据
    test_dataloader = test_data_process()
    #加载模型测试的函数
    test_model_process(model, test_dataloader)

结果:
在这里插入图片描述
想要知道每一类的识别情况
需要进行模型推理,需要注意的是,这一部分需要注释掉加载模型测试的函数。

import torch   #用不用都先导入进来
import torch.utils.data as Data    #导入数据处理的库
from torchvision import transforms
from torchvision.datasets import FashionMNIST    #导入我们所用的数据集
from model import AlexNet   #导入需要测试的模型

##数据就处理好了。
##导入数据进行模型的测试,从模型训练的代码拿一部分,改改即可,batch_size=1,希望是一张一张的去进行测试,不需要什么进程,改为num_workers=0即可
def test_data_process():
    ##数据加载进来,transforms.Compose((transforms.Resize(size=28),大小设置按照模型的输入要求来
    test_data = FashionMNIST(root='./data',
                              train=False,
                              transform=transforms.Compose((transforms.Resize(size=227), transforms.ToTensor())),
                              download=True)

    #先放入数据,一批次数量(数据量比较小,6G运存应该是够的),shuffle是否打乱数据,进程是8,电脑垃圾的话,就改小一点
    test_dataloader = Data.DataLoader(dataset=test_data,
                                       batch_size=1,
                                       shuffle=True,
                                       num_workers=0)

    return test_dataloader

##测试,只需要导入模型和数据集,得到一个测试的结果即可
def test_model_process(model,test_dataloader):
    #设定测试用到的设备,有GPU用GPU,没有GPU用CPU
    device = "cuda" if torch.cuda.is_available() else "cpu"
    #将模型放入到测试设备当中
    model = model.to(device)
    #初始化模型参数,准确度即可,虽然已经知道测试的数据集有10000张,但为了后续不知道张数的情况下,也能进行测试。
    test_corrects = 0.0
    test_num = 0

    ##开始模型的测试,不存在反向传播,因此将梯度置为0,只有前向传播,不计算梯度,从而节省内存,加快运行速度
    with torch.no_grad():
        #直接一批次一批次的获取就好了。
        for test_data_x,test_data_y in test_dataloader:
            #将特征放入到测试设备中
            test_data_x = test_data_x.to(device)
            #将标签也放入到测试设备中
            test_data_y = test_data_y.to(device)
            #模型测试状态
            model.eval()
            #前向传播过程,输入为测试数据集,输出为对每个样本的预测值,它其实是一个10*1的矩阵,并不能看出结果来,需要经过一个softmax得到结果。最大概率对应的下标
            output = model(test_data_x)
             #预测的类别,查找每一行中最大值对应的行标
            pre_lab = torch.argmax(output,dim=1)
            #预测的结果和标签一样+1,如果预测正确,则 test_corrects加1,直到循环结束
            test_corrects += torch.sum(pre_lab == test_data_y.data)
            #将所有的测试样本进行累加
            test_num += test_data_x.size(0)

    #计算测试准确率,不在循环里面哦,注意缩进
    test_acc = test_corrects.double().item() / test_num

    print("测试的准确率为:" ,  test_acc)


#主函数进行运行程序
if __name__ == "__main__" :
    #加载模型
    model = AlexNet()
    #torch.load('best_model.pth')加载训练好的模型参数,权重以字符串的形式, model.load_state_dict模型训练化,将实例化之后的模型加载上权重,规定的做法

    model.load_state_dict(torch.load('best_model.pth'))
    #导入测试集的数据集,加载测试数据
    test_dataloader = test_data_process()
    #加载模型测试的函数
    # test_model_process(model, test_dataloader)
##进行模型推理过程
    #设定测试所用到的设备,有GPU用GPU,没有就用CPU
    device = "cuda" if torch.cuda.is_available() else 'cpu'
    model = model.to(device)
    #使用列表取值的形式设置类别
    classes= ['T-shirt/top','Trouser','Pullover','Dress','Coat','Sandal','Shirt','Sneaker','Bag','Ankel boot']
    #测试部分,没有梯度,不存在反向传播
    with torch.no_grad():
        for b_x,b_y in test_dataloader:
            b_x = b_x.to(device)
            b_y = b_y.to(device)

            #设置模型为验证模式
            model.eval()
            output = model(b_x)
            ##10个通过神经元得到数值,经过softmax函数获得对应的概率,从而获得最大值的下标
            #ToTensor()将数据格式转换为张量的形式,只有张量的数据格式,才可以去做梯度运算,反向传播等
            pre_lab = torch.argmax(output, dim=1)
            # pre_lab.item()表示将张量中的数值取出来,以便做其他的操作(比如通过列表设置的类别,取整型方便运算,张量形式是没法进行的。
            result = pre_lab.item()
            label = b_y.item()
            #不仅打印数值,更应该打印出对应的类别,推理之前设置有列表,用下标指向类别
            print("预测值:", classes[result], "------", "真实值:",classes[label])

推理结果情况:
在这里插入图片描述
小结:
train.py需要改的,导入模型,输入尺寸,数据处理部分,模型实例化
test.py记得单纯只求准确率就加载模型测试的函数哦
每一张的识别的类别情况,就需要注释掉加载模型测试的函数,把模型推理的部分拿出来。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值