minist数据集训练与测试

项目使用的是pytorch框架

数据集的加载:

注意事项:加载进的数据集并不符合卷积神经网络的训练格式,需要先使用Dataloader进行修改,而且加载时要先利用transform把图片数据转化为tensor张量形式

train_data=torchvision.datasets.MNIST('./data',True,torchvision.transforms.ToTensor(),download=True)
test_data=torchvision.datasets.MNIST('./data',False,torchvision.transforms.ToTensor(),download=True)
train_datasize=len(train_data) #训练集的长度
test_datasize=len(test_data)
print('训练集的长度为:{}'.format(train_datasize))
print('测试集的长度为:{}'.format(test_datasize))
#加载数据集部分
train_dataloader=DataLoader(train_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)

网络的搭建:

搭建网络的过程中,需要先计算好图片的像素点,根据卷积过程的计算公式,计算出输出的数值,如果计算错误会报错

#搭建神经网络:十个分类的网络:minist数据集是黑白图片,单通道,大小是28*28,种类是10个,本次采取2层卷积层和一层全连接层实现
class lf(nn.Module):
    def __init__(self):
        super(lf, self).__init__()
        self.model=nn.Sequential( #原图像的像素点是1*28*28
            nn.Conv2d(1,16,5,1,2), #输入形式的单通道形式,输出通道改为16  像素点为:16*28*28
            nn.MaxPool2d(2),   #像素点为 16*14*14
            nn.Conv2d(16,32,5,1,2), #输出通道改为32通道
            nn.MaxPool2d(2), #像素点为:32*7*7
            nn.Flatten(), #展开后的数据大小为:32*7*7=1568
            nn.Linear(1568,98), #填写98的原因,反照CFR数据训练比例,64除以1024再乘上1568
            nn.Linear(98,10) #输出10类数据,判断概率性
        )
    def  forward(self,x):
        x=self.model(x) #训练网络
        return  x

设置参数:

手动设置学习率,0.03,训练轮数 ,30轮

使用优化器:

选择交叉熵损失函数,适用于多分类问题
优化器选择随机梯度下降法

loss_function=nn.CrossEntropyLoss() #分类问题使用交叉熵损失函数
    optim=torch.optim.SGD(l.parameters(),lr=0.01) #随机梯度下降法优化器,设定学习速率为0.03
    train_step=0 #记录训练的次数
    test_step=0 #记录测试的次数
    epoch=30 #训练十轮

训练网络:

 for i in range(30):
        print('第{}轮训练开始了'.format(i+1))
        for data in train_dataloader: #加载数据,每一轮batch_size都是64张图片
            imgs,target=data #加载的data类型包括图片和标签数值俩钟数据???
            output=l(imgs) #向模型中输入数据,返回的数据由output保存
            loss=loss_function(output,target)   #计算损失函数的损失值
            optim.zero_grad() #每一轮训练都需要梯度清零,否则下一轮的梯度下降将会被上一轮训练的梯度值所影响
            loss.backward() #反向传播,优化模型
            optim.step() #梯度下降

训练过程中注意反向传播,如果没有反向传播的话将不会梯度下降(或者下降效果非常差,试过了)

测试网络:

        with torch.no_grad(): #在此过程中,梯度始终为0,不会改变训练好的模型,可以用于验证模型
            for data in test_dataloader:
                imgs,target=data
                output=l(imgs)
                loss=loss_function(output,target)
                test_loss+=loss #误差累加
                test_step+=1 #测试步骤加一
                writer.add_scalar('test_loss',test_loss,test_step)
                accuracy=(output.argmax(1)==target).sum() #通过argmax函数把张量数据转化为位置信息,“1”表示横向比对,再将位置信息与target的位置信息相匹配,把匹配的结果求和,即可得到正确测试的数量
        #每一轮之后,开始保存模型
                total_accuracy=total_accuracy+accuracy 
                print("整体的测试集的准确率为:{}".format(total_accuracy/test_datasize)) #预测正确的总量除以全部数据量,将得出每一轮训练的准确率
        torch.save(l,'保存模型{}.pth'.format(i+1)) #第一个参数千万不能带括号!!使用实例化的名称即可

总结

所有的讲解都在代码的注释中,以上仅仅是大概的过程

训练板块

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

train_data=torchvision.datasets.MNIST('./data',True,torchvision.transforms.ToTensor(),download=True)
test_data=torchvision.datasets.MNIST('./data',False,torchvision.transforms.ToTensor(),download=True)
train_datasize=len(train_data) #训练集的长度
test_datasize=len(test_data)
print('训练集的长度为:{}'.format(train_datasize))
print('测试集的长度为:{}'.format(test_datasize))
#加载数据集部分
train_dataloader=DataLoader(train_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)

writer=SummaryWriter('./logs') #可视化训练过程
#搭建神经网络:十个分类的网络:minist数据集是黑白图片,单通道,大小是28*28,种类是10个,本次采取2层卷积层和一层全连接层实现
class lf(nn.Module):
    def __init__(self):
        super(lf, self).__init__()
        self.model=nn.Sequential( #原图像的像素点是1*28*28
            nn.Conv2d(1,16,5,1,2), #输入形式的单通道形式,输出通道改为16  像素点为:16*28*28
            nn.MaxPool2d(2),   #像素点为 16*14*14
            nn.Conv2d(16,32,5,1,2), #输出通道改为32通道
            nn.MaxPool2d(2), #像素点为:32*7*7
            nn.Flatten(), #展开后的数据大小为:32*7*7=1568
            nn.Linear(1568,98), #填写98的原因,反照CFR数据训练比例,64除以1024再乘上1568
            nn.Linear(98,10) #输出10类数据,判断概率性
        )
    def  forward(self,x):
        x=self.model(x) #训练网络
        return  x

if __name__ == '__main__':
    l=lf() #创建网络模型
    loss_function=nn.CrossEntropyLoss() #分类问题使用交叉熵损失函数
    optim=torch.optim.SGD(l.parameters(),lr=0.01) #随机梯度下降法优化器,设定学习速率为0.03
    train_step=0 #记录训练的次数
    test_step=0 #记录测试的次数
    epoch=30 #训练十轮
    l.train() #改为训练网络
    for i in range(30):
        print('第{}轮训练开始了'.format(i+1))
        for data in train_dataloader: #加载数据,每一轮batch_size都是64张图片
            imgs,target=data #加载的data类型包括图片和标签数值俩钟数据???
            output=l(imgs) #向模型中输入数据,返回的数据由output保存
            loss=loss_function(output,target)   #计算损失函数的损失值
            optim.zero_grad() #每一轮训练都需要梯度清零,否则下一轮的梯度下降将会被上一轮训练的梯度值所影响
            loss.backward() #反向传播,优化模型
            optim.step() #梯度下降

            train_step+=1 #训练次数增加
            if train_step%100==0:
                print('训练次数:{},loss:{}'.format(train_step,loss.item()))
                writer.add_scalar('train',loss.item(),train_step) #可视化训练,图像名称,y内容,x内容,显示训练的效果
        print('训练结束了')
        #测试开始
        l.eval() #改为测试网络
        test_loss=0 #误差初始化
        total_accuracy=0
        with torch.no_grad(): #在此过程中,梯度始终为0,不会改变训练好的模型,可以用于验证模型
            for data in test_dataloader:
                imgs,target=data
                output=l(imgs)
                loss=loss_function(output,target)
                test_loss+=loss #误差累加
                test_step+=1 #测试步骤加一
                writer.add_scalar('test_loss',test_loss,test_step)
                accuracy=(output.argmax(1)==target).sum() #通过argmax函数把张量数据转化为位置信息,“1”表示横向比对,再将位置信息与target的位置信息相匹配,把匹配的结果求和,即可得到正确概率
        #每一轮之后,开始保存模型
                total_accuracy=total_accuracy+accuracy
        print("整体的测试集的准确率为:{}".format(total_accuracy/test_datasize))
        torch.save(l,'保存模型{}.pth'.format(i+1)) #第一个参数千万不能带括号!!
        print('-------loss总和为:{}----------'.format(test_loss))

验证板块:

测试的图片的格式必须符合训练好的模型的网络要求输入格式,所以我事先使用opencv把图片灰度化了

import torch
import torchvision.transforms
from PIL import Image
from torch import  nn
img='5.jpg'  #读取单通道的图片,此模型就是适合单通道验证
image=Image.open(img)
print(image)
transform=torchvision.transforms.Compose([torchvision.transforms.Resize((28,28)),torchvision.transforms.ToTensor()]) #修改测试图片的大小及转化为张量形式
image=transform(image)
#需要导入卷积层
class lf(nn.Module):
    def __init__(self):
        super(lf, self).__init__()
        self.model=nn.Sequential( #原图像的像素点是1*28*28
            nn.Conv2d(1,16,5,1,2), #输入形式的单通道形式,输出通道改为16  像素点为:16*28*28
            nn.MaxPool2d(2),   #像素点为 16*14*14
            nn.Conv2d(16,32,5,1,2), #输出通道改为32通道
            nn.MaxPool2d(2), #像素点为:32*7*7
            nn.Flatten(), #展开后的数据大小为:32*7*7=1568
            nn.Linear(1568,98), #填写98的原因,反照CFR数据训练比例,64除以1024再乘上1568
            nn.Linear(98,10) #输出10类数据,判断概率性
        )
    def  forward(self,x):
        x=self.model(x) #训练网络
        return  x
model =torch.load('lf49.pth',map_location=torch.device('cpu')) #加载网络模型,并且把GPU训练的模型映射到cpu上
print(model)
image=torch.reshape(image,(1,1,28,28)) #batch_size=1,输入通道为1 ,大小为28*28,修改输入图片适合卷积层的图像形式
model.eval() #测试模式
output=model(image)
print(output)
print(output.argmax(1)) #横向寻找对应位置,位置0--9,对应数字0--9,打印出相应的位置就是输出相应的分类结果

我测试的图片是车牌号码分割出来的这两张:
在这里插入图片描述
测试结果如下:
minist数据集训练与测试_第1张图片
返回数值5 测试正确

在这里插入图片描述
测试结果如下:
minist数据集训练与测试_第2张图片
返回数值 0,测试正确

你可能感兴趣的:(机器学习,深度学习,神经网络,人工智能)