用Pytorch实现MNIST数据集分类(持续修改中)

1.定义数据初始化

image_size=(224,224)
import torchvision .transforms as transforms
transform=transforms .Compose ([
    transforms.ToTensor (),
    transforms .RandomHorizontalFlip (),
    transforms .Resize (image_size ),
    transforms.Lambda(lambda x: x.repeat(3,1,1)),
    transforms.Normalize((0.1307,),(0.3081,))     #第一个小括号里表示的是平均值,第二个小括号里面表示的是标准差,每个括号里有几个数就表示有几个通道,因为MNIST数据集里面的是灰度图片,只有一个通道,所以每个小括号只需写一个数
])

2.导入数据集

import torchvision .datasets
mnist_train=torchvision .datasets.MNIST(root='~',train=True,download=True,transform =transform )       #导入训练集 ~保存到当前位置
mnist_val=torchvision .datasets .MNIST (root='~',train= False ,download= True ,transform= transform )  #导入验证集 False说明是用于测试的数据
print(len(mnist_train.classes)) #查看训练集的类别数
print(len(mnist_val.classes))  #查看验证集的类别数

3.制作DataLoader

from torch .utils .data import DataLoader   #DataLoader是用来包装数据的工具,可以进行批训练
trainloader=DataLoader(mnist_train ,batch_size=64,shuffle=True,num_workers=2) #shuffle作用是,是否打乱数据
valloader=DataLoader(mnist_val ,batch_size=64,shuffle=True,num_workers=2)

4.调用ResNet18 model

import torchvision .models as models
import torch
model =models.resnet18(pretrained=True)
model.fc=torch.nn.Linear(512,10)  #将ResNet18最后一层的输出改成18个,神经网络的output layer中神经元的个数,要与数据类别数一致
print(model)

5.定义优化器

import torch
import torch.nn.init as init
for name,module in model._modules.items() :
    if (name=='fc'):
        init.kaiming_uniform_(module.weight,a=0,mode='fan_in')

6.调用GPU

device=torch.device("cuda:0" if torch.cuda.is_available() else"cpu") #cuda:0表示调用的是第一块GPU,通过该变数字的大小来调整调用那块GPU
#调用多块GOU用下面三行代码
# import torch.nn
# if torch.cuda.device_count()>1:
#     model=torch.nn.DataParallel(model)
print(device)

7.定义准确率函数

import torch
def accuracy(pred,target): #定义两个变量,预测值和真实值
    pred_label=torch .argmax(pred,1)  #返回每张照片10个预测值里面最大数的标签
    correct=sum(pred_label==target).to(torch .float ) #如果这个标签等于真实标签,则将数值转化为个数,转化为float类型并返回给correct
    #acc=correct/float(len(pred))
    return correct,len(pred)#返回正确的个数和总个数

8.定义字典来存放数据

acc={'train':[],"val":[]}  #用来存放训练模式和验证模式的准确率
loss_all={'train':[],"val":[]} #用来存放训练模式和验证模式的损失函数

9.开始训练和验证

"""设为训练模式"""
    model.train()
    train_correctnum,train_prednum,train_total_loss=0.,0.,0.
    for images,labels in train_loader : 
        images,labels=images.to(device),labels.to(device) 
        outputs=model(images)
        loss=F.cross_entropy(outputs ,labels )
        optimizer.zero_grad() 
        train_total_loss += loss.item()
        loss.backward()
        optimizer .step()

        correctnum,prednum=accuracy(outputs,labels )
        train_correctnum += correctnum
        train_prednum+=prednum

"""设为验证模式""" 
 model.eval()
    valid_correctnum,valid_prednum,valid_total_loss=0.,0.,0.
#     with torch .no_grad():
    for images,labels in valid_loader:
        images,labels=images.to(device),labels.to(device)     
        outputs=model (images )
        loss=F.cross_entropy(outputs ,labels )
        valid_total_loss += loss.item()

        correctnum,prednum=accuracy(outputs,labels )
        valid_correctnum += correctnum
        valid_prednum+=prednum
        
    """求平均损失"""
    train_loss = train_total_loss/len(train_loader) 
    valid_loss = valid_total_loss/len(valid_loader)
            
    """将损失存入字典"""
    loss_all['train'].append(train_loss ) 
    loss_all['val'].append(valid_loss)
    """将准确率存入字典"""
    acc['train'].append(train_correctnum/train_prednum)
    acc['val'].append(valid_correctnum/valid_prednum)

    print('train_loss:{:.6f} \t valid_loss:{:.6f}'.format(train_loss,valid_loss))
    print('train_acc:{:.6f} \t valid_acc:{:.6f}'.format(train_correctnum/train_prednum,valid_correctnum/ valid_prednum))
        

10.训练结果

在这里插入图片描述

11.绘制loss 和acc曲线

import matplotlib.pyplot as plt
plt.ylim((0, 0.6))
plt.xlim((0, 10)) 
plt.plot(loss_all['train'] ,color='orange')
plt.plot(loss_all['val'],color='blue' )
plt.title('loss function')
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

在这里插入图片描述

plt.ylim((0.8, 1))
plt.xlim((0, 10))
plt.plot(acc['train'] ,color='orange')
plt.plot(acc['val'],color='blue' )
plt.title('accuracy rate')
plt.xlabel('epoch')
plt.ylabel('accuracy')

在这里插入图片描述

12.完整代码

"""""""""""""""""""数据初始化"""""""""""""""""""""""""""
image_size=(224,224)
import torchvision .transforms as transforms
transform=transforms .Compose ([
    transforms.ToTensor (),
    transforms .RandomHorizontalFlip (),
    transforms .Resize (image_size ),
    transforms.Lambda(lambda x: x.repeat(3,1,1)),
    transforms.Normalize((0.1307,),(0.3081,))
])
"""""""""""""""""""导入数据集"""""""""""""""""""
import torchvision .datasets
mnist_train=torchvision .datasets.MNIST(root='~',train=True,download=True,transform =transform )       #导入训练集 ~保存到当前位置
mnist_val=torchvision .datasets .MNIST (root='~',train= False ,download= True ,transform= transform )  #导入验证集 False说明是用于测试的数据
print(len(mnist_train.classes))
print(len(mnist_val.classes))

"""""""""""""""制作DataLoader"""""""""""""""""""""
from torch .utils .data import DataLoader   #DataLoader是用来包装数据的工具,可以进行批训练
trainloader=DataLoader(mnist_train ,batch_size=64,shuffle=True,num_workers=2)
valloader=DataLoader(mnist_val ,batch_size=64,shuffle=True,num_workers=2)

"""""""""""""""""""调用model"""""""""""""""""""
import torchvision .models as models
import torch
model =models.resnet18(pretrained=True)
model.fc=torch.nn.Linear(512,10)
print(model)

""""""""""""""""""""""调用GPU"""""""""""""""""""""""""""""
device=torch.device("cuda:0" if torch.cuda.is_available() else"cpu")
# import torch.nn
# if torch.cuda.device_count()>1:
#     model=torch.nn.DataParallel(model)
print(device)

"""""""""""""""计算准确率"""""""""""""""
import torch
def accuracy(pred,target):
    pred_label=torch .argmax(pred,1)  #返回每张照片131个预测值里面最大数的标签
    correct=sum(pred_label==target).to(torch .float ) #如果这个标签等于真实标签,则将数值转化为个数,转化为float类型并返回给correct
    return correct,len(pred)#返回正确的个数

acc={'train':[],"val":[]}
loss_all={'train':[],"val":[]}

"""""""""""""""""验证和训练"""""""""""""""
model.to(device)
for epoch in range(10): 
    print("epoch",epoch+1,":***************************")   
    
    model.train()
    train_correctnum,train_prednum,train_total_loss=0.,0.,0.
    for images,labels in train_loader : 
        images,labels=images.to(device),labels.to(device) 
        outputs=model(images)
        loss=F.cross_entropy(outputs ,labels )
        optimizer.zero_grad() 
        train_total_loss += loss.item()
        loss.backward()
        optimizer .step()

        correctnum,prednum=accuracy(outputs,labels )
        train_correctnum += correctnum
        train_prednum+=prednum
        
    model.eval()
    valid_correctnum,valid_prednum,valid_total_loss=0.,0.,0.
#     with torch .no_grad():
    for images,labels in valid_loader:
        images,labels=images.to(device),labels.to(device)     
        outputs=model (images )
        loss=F.cross_entropy(outputs ,labels )
        valid_total_loss += loss.item()

        correctnum,prednum=accuracy(outputs,labels )
        valid_correctnum += correctnum
        valid_prednum+=prednum
            
    """求平均损失"""
    train_loss = train_total_loss/len(train_loader) 
    valid_loss = valid_total_loss/len(valid_loader)
            
    """将损失存入字典"""
    loss_all['train'].append(train_loss ) 
    loss_all['val'].append(valid_loss)
    """将准确率存入字典"""
    acc['train'].append(train_correctnum/train_prednum)
    acc['val'].append(valid_correctnum/valid_prednum)

    print('train_loss:{:.6f} \t valid_loss:{:.6f}'.format(train_loss,valid_loss))
    print('train_acc:{:.6f} \t valid_acc:{:.6f}'.format(train_correctnum/train_prednum,valid_correctnum/ valid_prednum)) 

"""""""""""""""""绘图"""""""""""""""""""""
import matplotlib.pyplot as plt
plt.ylim((0, 0.6))
plt.xlim((0, 10)) 
plt.plot(loss_all['train'] ,color='orange')
plt.plot(loss_all['val'],color='blue' )
plt.title('loss function')
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()


plt.ylim((0.8, 1))
plt.xlim((0, 10))
plt.plot(acc['train'] ,color='orange')
plt.plot(acc['val'],color='blue' )
plt.title('accuracy rate')
plt.xlabel('epoch')
plt.ylabel('accuracy')

        

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tomorrow;

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值