pytorch基于LeNet的Fashion-MNIST数据集分类

一、Fashion-MNIST数据集

Fashion-MNIST包含了各种不同类型的时尚物品的灰度图像,每张图像尺寸为28X28,该数据集共包含70000张图片,其中训练集共60000张,测试集10000张。数据集一共有十个类别,分别为T-shirt(T恤)、Trouser、Pullover、Dress、Coat、Sandal、Shirt、Sneaker、Bag、Ankle boot。

二、LeNet

LeNet,它是最早发布的卷积神经网络之一,因其在计算机视觉任务中的高效性能而受到广泛关注。 这个模型是由AT&T贝尔实验室的研究员Yann LeCun在1989年提出的(并以其命名),目的是识别图像 (LeCun et al., 1998)中的手写数字。
模型结构图:
在这里插入图片描述
每个卷积块中的基本单元是一个卷积层、一个sigmoid激活函数和平均汇聚层。每个卷积层使用卷积核和一个sigmoid激活函数。这些层将输入映射到多个二维特征输出,通常同时增加通道的数量。第一卷积层有6个输出通道,而第二个卷积层有16个输出通道。每个
池操作(步幅2)通过空间下采样将维数减少4倍。卷积的输出形状由批量大小、通道数、高度、宽度决定。
为了将卷积块的输出传递给全连接层,需要在小批量中展平每个样本。即将四维输入转换成全连接层所期望的二维输入。这里的二维表示的第一个维度索引小批量中的样本,第二个维度给出每个样本的平面向量表示。LeNet的稠密块有三个全连接层,分别有120、84和10个输出。
LeNet简化版模型:
在这里插入图片描述

三、训练和测试模型

import torch
import torchvision.datasets
from torch import nn
from torch.utils.data import DataLoader
from matplotlib import pyplot as plt


#准备数据集
train_data=torchvision.datasets.FashionMNIST('./data',train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_data=torchvision.datasets.FashionMNIST('./data',train=False,transform=torchvision.transforms.ToTensor(),download=True)

train_data_size=len(train_data)
test_data_size=len(test_data)

print(train_data_size)
print(test_data_size)

#使用DataLoader加载数据   组合了数据集(dataset) + 采样器(sampler)
train_dataloader=DataLoader(train_data,batch_size=64,drop_last=True)
test_dataloader=DataLoader(test_data,batch_size=64,drop_last=True)

#定义模型
class LeNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.models=nn.Sequential(
            nn.Conv2d(1,6,5,padding=2),nn.Sigmoid(),
            nn.MaxPool2d(2,stride=2),
            nn.Conv2d(6,16,5),nn.Sigmoid(),
            nn.MaxPool2d(2,stride=2),
            nn.Flatten(),
            nn.Linear(16*5*5,120),
            nn.Sigmoid(),
            nn.Linear(120,84),
            nn.Sigmoid(),
            nn.Linear(84,10)
        )
    def forward(self,x):
        x=self.models(x)
        return x


net=LeNet()
#定义损失函数和优化器
loss_fn=nn.CrossEntropyLoss()

optimizer=torch.optim.SGD(net.parameters(),lr=0.9)

#设置训练参数
epoch=10
total_train_step=0
train_loss_list=[]
total_accuracy_list=[]
total_loss_list=[]
x=[]

#训练模型
for i in range(epoch):
    print(f'第{i+1}轮训练开始')
    # 设置成训练模式
    train_loss=0
    net.train()
    for data in train_dataloader:
        imgs,targets=data
        outputs=net(imgs)
        #计算损失
        loss=loss_fn(outputs,targets)
        # train_loss += loss.item()
        optimizer.zero_grad()
        #计算梯度
        loss.backward()

        #更新参数
        optimizer.step()
        total_train_step+=1
        # if total_train_step%100==0:
        #     print(f'训练次数{total_train_step},Loss:{loss.item()}')

    #测试模型
    total_test_loss = 0
    total_accuracy=0
    net.eval()
    with torch.no_grad():
        for data in test_dataloader:
            imgs,targets=data
            outputs=net(imgs)
            loss=loss_fn(outputs,targets)
            total_test_loss+=loss.item()
            accuracy=(outputs.argmax(1)==targets).sum()
            total_accuracy+=accuracy

    print(f'整体上的测试损失:{total_test_loss/test_data_size}')
    print(f'整体上的测试精度:{total_accuracy/test_data_size}')
    total_loss_list.append(total_test_loss/test_data_size)
    total_accuracy_list.append(total_accuracy/test_data_size)

    #保存模型
    torch.save(net,f'model{i}.pth')
#可视化
x=range(1,11)
plt.xticks(range(0,12,2))
plt.plot(x,total_accuracy_list,label="test acc")
plt.plot(x,total_loss_list,label="test loss")
plt.xlabel("epoch")
plt.legend()
plt.show()

四、预测

import os

import torch
import torchvision.transforms
from PIL import Image
from torch import nn
from matplotlib import pyplot as plt

#1.定义模型
class LeNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.models=nn.Sequential(
            nn.Conv2d(1,6,5,padding=2),nn.Sigmoid(),
            nn.MaxPool2d(2,stride=2),
            nn.Conv2d(6,16,5),nn.Sigmoid(),
            nn.MaxPool2d(2,stride=2),
            nn.Flatten(),
            nn.Linear(16*5*5,120),
            nn.Sigmoid(),
            nn.Linear(120,84),
            nn.Sigmoid(),
            nn.Linear(84,10)
        )
    def forward(self,x):
        x=self.models(x)
        return x

#2.加载与训练好的模型
model=torch.load("model9.pth")

#3.定义类别标签
classes=['T-shirt','Trouser','Pullover','Dress','Coat','Sandal','Shirt','Sneaker','Bag','Ankle boot']

#4.获取图片的全路径
img_root="images"
#获取图片文件夹下所有图片的名称
file_name=os.listdir(img_root)
file_path=[]
for name in file_name:
    file_path.append(os.path.join(img_root,name))

#5.预测
for path in file_path:
    #打开图片
    imagePIL=Image.open(path)
    #三通道图像转换成一通道,黑白图形
    image_gray=imagePIL.convert("L")
    #将PIL图片转换成tensor格式并转换成转换成模型输入图片的大小 28X28
    transform=torchvision.transforms.Compose([torchvision.transforms.Resize((28,28)),
                                              torchvision.transforms.ToTensor()])
    imageTensor=transform(image_gray)
    #调整图片的维度,与模型相对应
    imageTensor=torch.reshape(imageTensor,(1,1,28,28))
    #设置为预测模式
    model.eval()
    with torch.no_grad():
        output=model(imageTensor)
        #获取预测类别
        predict_class=classes[output.argmax(1)]
        #获取类别的概率
        predict_probability =torch.softmax(output, dim=1).numpy()[0][output.argmax(1)]
        print(predict_class)
        # 绘制原始图片和显示预测的值

        plt.imshow(image_gray)
        plt.title("predict:{}".format(predict_class))
        plt.text(5, 45, "probability {}:{}".format(predict_class, predict_probability), bbox=dict(fc='red'))
        plt.show()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值