BP 网络的mnist数据集识别 01

该博客介绍了如何使用PyTorch搭建一个简单的神经网络模型,对MNIST数据集的手写数字进行识别。首先加载MNIST训练集和测试集,设置批次大小,然后定义一个全连接网络结构,包含Softmax激活函数。接着,定义损失函数为MSELoss,使用SGD优化器进行训练。在训练和测试过程中,计算并输出准确率。博客着重于理解PyTorch的网络构建和训练流程。
摘要由CSDN通过智能技术生成
import numpy as np
from torch import nn,optim
from torch.autograd import Variable
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import torch
# 训练集
'''
root='./' 就是数据集存放的位置,./就是数据集在相同的目录下
train=True, 表示的是训练集的数据
transform=transforms.ToTensor(), 就是把他载入进来的数据转变成totensor
download=True 是否要下载数据这里True表示,是要下载数据

可能会出现一个错误,就是如果没有提前准备数据,让他自己在网上下载,可能程序就会报错
'''
train_dataset = datasets.MNIST(root='./',
                              train=True,
                              transform=transforms.ToTensor(),
                              download=True)
# 测试集
test_dataset = datasets.MNIST(root='./',
                              train=False,
                              transform=transforms.ToTensor(),
                              download=True)
# 批次大小
# 每一次训练传入多少个数据,每次传入64个数据
batch_size = 64

# 装载训练集
'''
train_loader【相当于数据生成器】 = DataLoader(dataset=train_dataset,数据来源于训练集
                         batch_size=batch_size,批次是多少传入进来
                         shuffle=True)这个True是代表同意把训练集打乱
'''
train_loader = DataLoader(dataset=train_dataset,
                         batch_size=batch_size,
                         shuffle=True)

# 装载训练集
test_loader = DataLoader(dataset=test_dataset,
                         batch_size=batch_size,
                         shuffle=True)
'''
数据生成器的使用方法是在循环里面进行使用

训练集的数据进来会得到一个data 
data包含两个值 数据input和标签label

torch.Size([64, 1, 28, 28])

64张图片 黑白通道数是1,彩色通道数是3 28*28的图片
'''

for i,data in enumerate(train_loader):
    inputs,labels = data
    print(inputs.shape)#打印数据的形状
    print(labels.shape)#打印标签的形状
    break #这里只循环一次,只看一个批次的数据和形状,每个批次数据一样
# 定义网络结构

'''
class Net(nn.Module): 先定义一个类
    def __init__(self): 然后进行初始化
        super(Net, self).__init__() 先对父类进行初始化 都是固定的格式 下面才是定义网络
        self.fc1 = nn.Linear(784,10) 定义一个有784个输入 10个输出的神经网络 没有隐藏层
        self.softmax = nn.Softmax(dim=1) 激活函数  dim=1 意思是对他的第一个维度【维度是从0开始的 (64,10) 对10进行概率计算】进行概率分析
        
    def forward(self,x): 前项传递的网络计算 生成器得到的数据是4位的数据[64, 1, 28, 28]
        我们要把思维的数据变成两维的数据  在全连接层做计算的时候 只能是两位的数据进行计算
        # ([64, 1, 28, 28])->(64,784)
        x = x.view【形状的变换】(x.size()【获得数据的形状】[0]【第0个值是64】, -1【这个-1表示自动匹配 变成784  1*28*28=784】)
        x = self.fc1(x) 变成两位的数据赋值给x
        x = self.softmax(x) 再把数据给softmax
        return x 返回这个判断的值
'''
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(784,10)
        self.softmax = nn.Softmax(dim=1)
        
    def forward(self,x):
        # ([64, 1, 28, 28])->(64,784)
        x = x.view(x.size()[0], -1)
        x = self.fc1(x)
        x = self.softmax(x)
        return x
LR = 0.5
# 定义模型
model = Net()
# 定义代价函数
mse_loss = nn.MSELoss() # MSE均方误差
# 定义优化器 把模型的参数和学习率传进来
optimizer = optim.SGD(model.parameters(), LR) # SGD随机梯度下降法
def train():
    for i,data in enumerate(train_loader):
        # 获得一个批次的数据和标签
        inputs, labels = data
        #  把数据传给模型  获得模型预测结果(64,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【生成一些64行10列的0】(inputs.shape[0],10).scatter(1【对前面的第一个维度也就是10进行杜热编码】, labels, 1)
        '''
        one_hot = torch.zeros(inputs.shape[0],10).scatter(1, labels, 1)
        # 计算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(test_loader):
        # 获得一个批次的数据和标签
        inputs, labels = data
        # 获得模型预测结果(64,10)
        out = model(inputs)
        # 获得最大值,以及最大值所在的位置
        _, predicted = torch.max(out, 1) # 1表示第一个维度 out表示最大的概率是多少不需要知道
        # 预测正确的数量     64个值和64个值进行一一对比
        correct += (predicted == labels).sum()
        #correct.item()/len(test_dataset) 预测正确的数量除以总的数量
    print("Test acc:{0}".format(correct.item()/len(test_dataset)))
for epoch in range(10):
    print('epoch:',epoch)
    train()
    test()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值