pytorch基础入门(三):MNIST数据识别

import numpy as np
from torch import nn,optim
from torch.autograd import Variable
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch

# 训练集
# roo = './'表示放在跟程序相同位置,transform 将数据转换为tensor,download表示是否下载数据集
train_dataset = datasets.MNIST(root = './',
                                train=True,
                                transform=transforms.ToTensor(),
                                download=True)
# 测试集                                
test_dataset = datasets.MNIST(root = './',
                                train=False,
                                transform=transforms.ToTensor(),
                                download=True)
                                
Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to ./MNIST\raw\train-images-idx3-ubyte.gz



  0%|          | 0/9912422 [00:00<?, ?it/s]


Extracting ./MNIST\raw\train-images-idx3-ubyte.gz to ./MNIST\raw

Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz to ./MNIST\raw\train-labels-idx1-ubyte.gz



  0%|          | 0/28881 [00:00<?, ?it/s]


Extracting ./MNIST\raw\train-labels-idx1-ubyte.gz to ./MNIST\raw

Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to ./MNIST\raw\t10k-images-idx3-ubyte.gz



  0%|          | 0/1648877 [00:00<?, ?it/s]


Extracting ./MNIST\raw\t10k-images-idx3-ubyte.gz to ./MNIST\raw

Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to ./MNIST\raw\t10k-labels-idx1-ubyte.gz



  0%|          | 0/4542 [00:00<?, ?it/s]


Extracting ./MNIST\raw\t10k-labels-idx1-ubyte.gz to ./MNIST\raw

# 设置批次大小
batch_size = 64     # 每次训练传入多少数据(64)

# 装载训练集
# 创建了一个数据生成器,数据来源于前面的训练集,shuffle表示生成数据之前,是否要将数据顺序打乱,(把train_dataset打乱,然后每次给一个批次的数据)
train_loader = DataLoader(dataset=train_dataset,    
                          batch_size= batch_size,
                          shuffle= True)
# 装载测试集
test_loader = DataLoader(dataset=test_dataset,    
                          batch_size= batch_size,
                          shuffle= True)                       

# 查看一次循环的数据和标签  
# torch.Size([64, 1, 28, 28]) 每次获得64个数据,1表示通道数(灰度图),28*28是图片像素大小
# torch.Size([64])  label是图像标签,64表示里面有64个值
for i,data in enumerate(train_loader):
    input,labels = data
    print(input,input.shape)
    print(labels,labels.shape)
    break

tensor([[[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]],


[[[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
…,
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.]]],


[[[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
…,
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.]]],


…,


[[[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
…,
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.]]],


[[[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
…,
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.]]],


[[[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
…,
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.],
[0., 0., 0., …, 0., 0., 0.]]]]) torch.Size([64, 1, 28, 28])
tensor([3, 0, 5, 4, 7, 4, 3, 8, 1, 3, 6, 6, 9, 4, 7, 6, 5, 2, 7, 4, 6, 0, 6, 4,
3, 7, 6, 1, 7, 5, 5, 1, 2, 2, 3, 5, 0, 4, 8, 4, 3, 0, 7, 9, 6, 7, 2, 0,
6, 9, 2, 3, 7, 7, 7, 9, 1, 0, 0, 1, 7, 7, 1, 0]) torch.Size([64])

# 定义网络结构
class Net(nn.Module):
    def __init__(self) -> None:
        super(Net,self).__init__()  # 对父类进行初始化(固定格式)
        # 自己的网络结构
        self.fc1 = nn.Linear(784,10)    # 784个输入,10个输出简单神经网络,没有隐藏层
        self.softmax = nn.Softmax(dim = 1)  # dim = 1 表示对第一个维度计算它的概率值 例:(64,10),就是对10进行转换
    #前向传递网络计算
    def forward(self,x):
        # 得到的是四维数据变成两维数据 [64, 1, 28, 28]  -> (64,784)
        # 在全连接层进行数据计算时只能是两维数据
        x = x.view(x.size()[0],-1)  #x.size()是数据的形状[64, 1, 28, 28],x.size()[0]就是64,所以第0个维度是64;-1表示自动匹配,第一个维度就是1*28*28=784
        x = self.fc1(x)
        x = self.softmax(x)
        return x

LR = 0.5 # 学习率
# 定义模型
model = Net()
# 定义代价函数
mse_loss = nn.MSELoss()
# 定义优化器
optimizer = optim.SGD(model.parameters(),LR)
# 模型训练的函数
def train():
    for i,data in enumerate(train_loader):
        # 获得一个批次的数据和标签
        inputs,labels = data
        # 获得模型预测结果(64,10)(64是一个批次大小,10是10个输出概率值)
        out = model(inputs)
        # to onehot,把数据标签变成独热编码
        # (64)->(64,1)
        labels = labels.reshape(-1,1)
        # tensor.scatter(dim, index, src) 
        # dim:对哪个维度进行独热编码
        # index:要将src中对应的值放到tensor的哪个位置。
        # src:插入index的数值 
        one_hot = torch.zeros(inputs.shape[0],10).scatter(1,labels,1)  #torch.zeros(64,10)生成64行0列全是0的矩阵 
        print(one_hot)
        # 计算loss,mes_loss的两个数据的shape要一致
        loss = mse_loss(out, one_hot)
        # 梯度清0
        optimizer.zero_grad()
        # 计算梯度
        loss.backward()
        # 修改权值
        optimizer.step()
# 模型测试的函数
def test():
    correct = 0
    for i,data in enumerate(train_loader):
        # 获得一个批次的数据和标签
        inputs,labels = data
        # 获得模型预测结果(64,10)(64是一个批次大小,10是10个输出概率值)
        out = model(inputs)
        # 获得最大值,以及最大值所在的位置
        _, predicted = torch.max(out, 1)
        # 预测正确的数量
        correct += (predicted == labels).sum()
    print("Test acc:{0}".format(correct.item()/len(test_dataset)))
# 训练十次
for epoch in range(10):
    print('epoch:',epoch)
    train()
    test()
epoch: 0
Test acc:0.8883
epoch: 1
Test acc:0.9026
epoch: 2
Test acc:0.9058
epoch: 3
Test acc:0.9116
epoch: 4
Test acc:0.9137
epoch: 5
Test acc:0.9154
epoch: 6
Test acc:0.9169
epoch: 7
Test acc:0.9184
epoch: 8
Test acc:0.9202
epoch: 9
Test acc:0.9208
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值