Pytorch_Day02_MNIST数据集识别

欢迎来到黄黄自学室

  • MNIST数据集识别
    • 损失函数
    • 非线性函数ReLU
    • 识别步骤
      • 加载数据
      • 构建网络模型
      • 训练
      • 测试
      • 加载包
      • utils.py

亲爱的朋友们!
任何时候都要抬头挺胸收下巴,慢慢追赶!

MNIST数据集识别

损失函数

待识别目标【0、1、2、3、4、5、6、7、8、9】
做标签:采用one-hot编码方式
1>=[0,1,0,0,0,0,0,0,0,0]
5>=[0,0,0,0,0,5,0,0,0,0]

def one_hot(label, depth=10):
    """one_hot编码"""
    out = torch.zeros(label.size(0), depth)
    idx = torch.LongTensor(label).view(-1,1)
    out.scatter_(dim=1, index=idx, value=1)
    return out

采用三个线性函数进行嵌套:
X=[V1,V2,...,V784]X=[V1,V2,...,V784]H1=XW1+b1(b1)H_1=XW_1+b_1 (b_1为偏置)H1[1,d1]H_1维度为[1,d_1]
H2=H1W2+b2H_2=H_1W_2+b_2H2[1,d2]H_2维度为[1,d_2]
H3=H2W3+b3H_3=H_2W_3+b_3 H3[1,d3]H_3维度为[1,d_3]
pred=W3[W2[W1+b1]+b2]+b3pred=W_3*[W_2[W_1+b_1]+b_2]+b_3
其中pred为十维向量,error=(predY)2error=(pred-Y)^2

非线性函数ReLU

在这里插入图片描述ReLU函数
H=relu(XW+b)H=relu(XW+b)
一般最后一层的激活函数不是ReLU,也可以不加激活函数
用梯度下降法找到一组(W,b)使得对于一个新的X,其pred 接近Y
共有三组参数:[W1,W2,W3][W_1,W_2,W_3][b1,b2,b3] [b_1,b_2,b_3]
取概率最大的元素所对应的标签:argmax(pred)

识别步骤

加载数据

# -------------------------------------------- step 1/5 : 加载数据 -------------------------------------------
batch_size = 512
train_loader = torch.utils.data.DataLoader(
    torchvision.datasets.MNIST('mnist_data', train=True, download=True,   #download:如果当前文件没有数据,就要下载
            #加载mnist数据集,给出下载路径  train决定下载的是60k的训练数据,还是10k的测试数据
                                transform = torchvision.transforms.Compose([
                                     torchvision.transforms.ToTensor(),  #转换格式
                                     torchvision.transforms.Normalize(
                                         (0.1307,),(0.3081,))
                                    ])),
    batch_size = batch_size, shuffle = True)  #shuffle 随机打散

test_loader = torch.utils.data.DataLoader(
    torchvision.datasets.MNIST('mnist_data/', train=False, download=True,   #download:如果当前文件没有数据,就要下载
            #加载mnist数据集,给出下载路径  train决定下载的是60k的训练数据,还是10k的测试数据
                                transform = torchvision.transforms.Compose([
                                     torchvision.transforms.ToTensor(),  #转换格式
                                     torchvision.transforms.Normalize(
                                         (0.1307,),(0.3081,))
                                    ])),
    batch_size = batch_size, shuffle = False)  #shuffle 随机打散

从训练集中选一个样本:

x, y = next(iter(train_loader))
print(x.shape, y.shape)

输出为:

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

结果为512张图片,单通道,28行28列,标签也为512个
Normalize归一化处理结果展示:

print(x.shape, y.shape, x.min(), x.max())

输出:

torch.Size([512, 1, 28, 28]) torch.Size([512]) tensor(-0.4242) tensor(2.8215)

最小值和最大值由[0, 1]变为[-0.4242, 2.8215]

构建网络模型

# ------------------------------------ step 2/5 : 定义网络 ------------------------------------
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        # xw+b
        self.fc1 = nn.Linear(28*28, 256)
        self.fc2 = nn.Linear(256,64)
        self.fc3 = nn.Linear(64,10)  #最后的输出要和类别数一样

    def forward(self, x):
        """计算过程"""
        #x:[batch, 1 , 28, 28]
        #H1=relu(xw1+b1)
        x = F.relu(self.fc1(x))    #经过第一层,加入激活函数
        # H2=relu(H1w2+b2)
        x = F.relu(self.fc2(x))
        # H3=H2w3+b3
        x = self.fc3(x)
        return x

训练

 # ------------------------------- step 3/5 : 定义损失函数和优化器进行训练 ------------------------------------
net = Net()
#定义优化器  #net.parameters()会返回[w1,b1,w2,b2,w3,b3]待优化的权值,
optimizer = optim.SGD(net.parameters(),lr=0.01, momentum=0.9)
train_loss = []
for epoch in range(3):    #迭代3次
    for batch_idx, (x,y) in enumerate(train_loader):  #对数据集迭代一次
      # x:[batch, 1 , 28, 28], y=[512]
      x = x.view(x.size(0), 28*28)
      # 把x打平 [batch, 1 , 28, 28]=》[b,784]
      out = net(x)
      #  =>[b,10]
      y_onehot = one_hot(y)
      #loss = 均方误差(out - y_onehot)^2 损失函数
      loss = F.mse_loss(out, y_onehot)

      optimizer.zero_grad()   #梯度清零
      loss.backward()     #计算梯度
      #w'= w -lr*grad
      optimizer.step()   #梯度更新 w,b 的更新

      train_loss.append(loss.item())   #转化为数值类型

      #每隔10个batch打印一下loss
      if batch_idx % 10 == 0:
          print(epoch, batch_idx, loss.item())

plot_curve(train_loss)
#得到了较优的[w1,b1,w2,b2,w3,b3]

输出:

2 110 0.031515102833509445

在这里插入图片描述

测试

# ------------------------------------ step 4/5 : 测试 ------------------------------------
total_corrent = 0
for x,y in test_loader:
    x = x.view(x.size(0), 28*28)
    out = net(x)
    #out :[b,10]  预测值:返回向量中较大的数的索引[0.1,0.8……]返回1
    pred = out.argmax(dim=1)
    #正确值
    corrent = pred.eq(y).sum().float().item()
#pred.eq(y)和真实的y进行比较,对的为1,把对的总个数累加转化为float类型,通过item转化为数值类型
    total_corrent += corrent
total_num = len(test_loader.dataset)
acc = total_corrent / total_num
print('test accuracy:',acc)

#取一个样本进行展示
x,y = next(iter(test_loader))
out = net(x.view(x.size(0), 28*28))
pred = out.argmax(dim=1)
plot_image(x, pred, 'test')

输出:

test accuracy: 0.8861

在这里插入图片描述

加载包

import torch
from torch import nn
from torch.nn import functional as F
from torch import optim
import torchvision
from matplotlib import pyplot as plt
from utils import plot_image,plot_curve, one_hot

utils.py

import torch
from matplotlib import pyplot as plt

def plot_curve(data):
    """绘制下降曲线(loss下降的过程)"""
    fig = plt.figure()
    plt.plot(range(len(data)), data, color = 'red')
    plt.legend(['value'],loc = 'upper right')
    plt.xlabel('step')
    plt.ylabel('value')
    plt.show()

def plot_image(img, label, name):
    """绘制图片"""
    fig = plt.figure()
    for i in range(6):
        plt.subplot(2, 3, i+1)
        plt.tight_layout()
        plt.imshow(img[i][0]*0.3081+0.1307, cmap='gray', interpolation='none')
        plt.title("{}: {}".format(name, label[i].item()))
        plt.xticks([])
        plt.yticks([])
    plt.show()

def one_hot(label, depth=10):
    """one_hot编码"""
    out = torch.zeros(label.size(0), depth)
    idx = torch.LongTensor(label).view(-1,1)
    out.scatter_(dim=1, index=idx, value=1)
    return out

热门文章

暂无图片
编程学习 ·

Linux 练习 - 文本处理三剑客之AWK

1、文件 ip_list.txt 如下格式,请提取 ”.solin.com” 前面的主机名部分并写入到回到该文件中 1 blog.solin.com 2 www.solin.com … 999 study.solin.com [root@centos7 ~]# awk -F "[ .]" {print $2} ip_list.txt >> ip_list.txt2、统计 /etc/fstab 文件中每…
暂无图片
编程学习 ·

【Flutter 实战】简约而不简单的计算器

老孟导读:这是 【Flutter 实战】组件系列文章的最后一篇,其他组件地址:http://laomengit.com/guide/widgets/Text.html,接下来将会讲解动画系列,关注老孟,精彩不断。先看一下效果:大家学习UI编程语言时喜欢用哪个 App 当作第一个练手的项目呢?,我喜欢使用 计算器 ,可…
暂无图片
编程学习 ·

STM32开放式开发环境:释放创造力

市场上涌现各种价格亲民的经济型微控制器,助力新一代开发者创造令人兴奋的新型嵌入式应用。如今的开发工具非常好用,软硬件均呈现模块化趋势,插接安装简单容易,使得产品设计评估和原型开发周期大幅缩短。STM32开放式开发环境是业内独一无二的软硬件开发平台,堆叠式插接电路…
暂无图片
编程学习 ·

[云盘](二)我的文件和共享列表后台实现

后台代码实现我的文件列表Mian读取配置信息解析json登录token(cmd为count)解析jason(cmd不为count)获取用户文件个数获取用户文件列表源码共享文件列表main获取共享文件个数前端分页请求包获得普通共享文件列表共享文件排行榜源码 我的文件列表业务逻辑是,点击我的文件,会…
暂无图片
郑州普通话 ·

学习笔记六——循环神经网络

一、RNN 前馈神经网络:信息往一个方向流动。包括MLP和CNN 循环神经网络:信息循环流动,网络隐含层输出又作为自身输入,包括RNN、LSTM、GAN等。 RNN模型结构如下图所示: 展开之后相当于堆叠多个共享隐含层参数的前馈…
暂无图片
代理记账 ·

学习笔记六——循环神经网络

一、RNN 前馈神经网络:信息往一个方向流动。包括MLP和CNN 循环神经网络:信息循环流动,网络隐含层输出又作为自身输入,包括RNN、LSTM、GAN等。 RNN模型结构如下图所示: 展开之后相当于堆叠多个共享隐含层参数的前馈…
暂无图片
cgfy ·

学习笔记六——循环神经网络

一、RNN 前馈神经网络:信息往一个方向流动。包括MLP和CNN 循环神经网络:信息循环流动,网络隐含层输出又作为自身输入,包括RNN、LSTM、GAN等。 RNN模型结构如下图所示: 展开之后相当于堆叠多个共享隐含层参数的前馈…
暂无图片
coreui ·

Heap Sort 讲解

Heap Sort sorts a group of unordered elements using the Heap data structure. The sorting algorithm using a Min Heap is as follows: Heapify all elements into a Min HeapRecord and delete the top elementPut to top element into an array T that stores all so
暂无图片
未来博客 ·

Heap Sort 讲解

Heap Sort sorts a group of unordered elements using the Heap data structure. The sorting algorithm using a Min Heap is as follows: Heapify all elements into a Min HeapRecord and delete the top elementPut to top element into an array T that stores all so
暂无图片
建站日记 ·

[react] 你觉得react上手快不快?它有哪些限制?

[react] 你觉得react上手快不快?它有哪些限制? 相对vue来说不快。 限制 需要学习JSX需要工程化的配置需要对原生JavaScript有相当的掌握react只是一个UI层面的库,像vue内置了动画处理、keep-alive等功能,react则需要去找第三方库…
暂无图片
mfbz ·

学习笔记六——循环神经网络

一、RNN 前馈神经网络:信息往一个方向流动。包括MLP和CNN 循环神经网络:信息循环流动,网络隐含层输出又作为自身输入,包括RNN、LSTM、GAN等。 RNN模型结构如下图所示: 展开之后相当于堆叠多个共享隐含层参数的前馈…
暂无图片
mfbz ·

AOV网是否存在回路-拓扑排序-C++

拓扑排序是对测试AOV网是否存在回路的方法! 拓扑排序的过程中,由于需要查找所有以某顶点为尾的弧,即找到该顶点的所有出边,故图要采用邻接表的存储方式。但拓扑排序较邻接表的存储方式有一点不同,由于要查找入度为0的点…
暂无图片
珊珊日记 ·

学习笔记六——循环神经网络

一、RNN 前馈神经网络:信息往一个方向流动。包括MLP和CNN 循环神经网络:信息循环流动,网络隐含层输出又作为自身输入,包括RNN、LSTM、GAN等。 RNN模型结构如下图所示: 展开之后相当于堆叠多个共享隐含层参数的前馈…
暂无图片
珊珊日记 ·

AOV网是否存在回路-拓扑排序-C++

拓扑排序是对测试AOV网是否存在回路的方法! 拓扑排序的过程中,由于需要查找所有以某顶点为尾的弧,即找到该顶点的所有出边,故图要采用邻接表的存储方式。但拓扑排序较邻接表的存储方式有一点不同,由于要查找入度为0的点…