请选择 进入手机版 | 继续访问电脑版

石家庄老站长

点击联系客服
客服QQ:509006671 客服微信:mengfeiseo
 找回密码
 立即注册
查看: 9|回复: 0

Pytorch Note 4:用于MNIST数据集分类的多层传感器

[复制链接]

1

主题

1

帖子

-7

积分

限制会员

积分
-7
发表于 6 天前 | 显示全部楼层 |阅读模式
文章目录

前言1,火炬相关软件包介绍2,多层探测器构建1。MNIST简介2。下载MNIST数据集3。神经网络层构建1。权重和偏移2。前向计算网络定义3。定义渐变优化器和损失函数设置4。编程完成3,完整的代码程序摘要

前言

复杂的神经网络也由许多神经元组成,在深度学习领域,神经元就是识别器。深度学习通过很多识别器尽可能地学习一个任务的复杂数学表达。神经网络在模拟生物神经元时创造性地引入非线性函数,判断信号是否达到阈值,从而判断信号是否输出,完成信息传递。因此,如果仔细品味以阶段函数为基础的进一步优化、扩张、sigmoid激活函数、Relu、leak  ReLu等,就会发现这一构想的巧妙性和合理性。(大卫亚设,北上广深)。

本节对主要MNIST代码实现、识别器、激活函数等的介绍可以参考这本书,很容易理解,内容详细,非常有阅读价值。

Pdf地址仅供学习参考,如下所示。

链接: 3359 WWE  . lanzous.com/ieoe  2 noazwj。





一、Torch相关包介绍

Torch.nn:完成神经网络的一些相关任务,包括计算机视觉操作中常用的卷积、牵引等部分热API接口的实现。Torch.nn.fubctional:您可以通过比nn更多的接触来修改默认代码。Torch.nn.optim:提供优化器、设置学习率和选择更好的渐变下降方法。Torchvision:电脑视觉化工作工具,提供一般资料集、模型、转换函数等。在实施分类、目标检测、分割等视觉类任务时必不可少。

获取所需的软件包(示例):

Import  torch

Import  torch.nn  as  nn

Importtorch.nn. functional  as  F  .

Import  torch
ass="token punctuation">.optim as optim
from torchvision import datasets,transforms

若提示出错,可使用命令行窗口,进行 conda install 安装。或者在pycharm中进行安装,以pycharm为例:输入要安装的包,点击安装即可。







二、搭建多层感知机
1.MNIST介绍
MNIST简介: 包含0-9 共10个手写数字,每个数字由7000张(高度28*宽度28)的图像,将70k数据,分为了训练集60K,测试集10大小。本节,通过感知机实现对MNIST手写数字的分类。

[color=]代码如下(示例):

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context

2.下载MNIST数据集
如果下载失败,也可使用下载好的数据集,还在目录下:
链接: https://wwe.lanzous.com/b01c9d0sj.
密码:3dii





[color=]代码如下:

‘./data’:设置要保存的下载目录。
train=True:设置要下载的是60k的训练数据集。
download=True:如果当前文件夹没有数据集,则从网上下载。
transforms.ToTensor():下载的数据集为numpy格式,需要转换为张量格式。
transforms.Normalize((0.1307,), (0.3081,):(此项非必要设置项)为了更好的训练结果,因为图像的数据值是0-1之间,将数据值正则花在0左右,对模型梯度下降效果更好。
batch_size=batch_size, shuffle=True:设置批次大小,随机打算数据。
测试集设置类似

#MNIST 数据集
#设置训练的批次大小、学习率、及训练代数
batch_size=200
learning_rate=0.001
epochs=20
#下载数据集
train_loader = torch.utils.data.DataLoader(
    datasets.MNIST('./data', train=True, download=True,
                   transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,))
                   ])),
    batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(
    datasets.MNIST('./data', train=False, download=True, transform=transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1307,), (0.3081,))
    ])),
    batch_size=batch_size, shuffle=True)

3.搭建神经网络层
1.权重和偏置
[color=]代码如下:

w1,b1:第一层网络感知机。输入图像大小是28*28=784,因此输入为784,输出设置为100(这个参数随意设置,可以尝试不同的数目查看效果)因为W要转置所以输入放后面,输出放前面。b1为第一层网络对应的偏置项。
w2, b2:与上叙述类似。
==w3, b3 ==:注意输出要与分类的10个数字类别数一致,其他与上述类似。
requires_grad=True:此项设置为True,表示要对w,b求梯度。

#生成 三个神经网络成,对应感知节分别为第一层100,第二成200,第三层10,即要分类的数目
w1, b1 = torch.randn(100, 784, requires_grad=True),\
         torch.zeros(100, requires_grad=True)
w2, b2 = torch.randn(200, 100, requires_grad=True),\
         torch.zeros(200, requires_grad=True)
w3, b3 = torch.randn(10, 200, requires_grad=True),\
         torch.zeros(10, requires_grad=True)

2.定义前向计算网络
[color=]代码如下:

relu激活函数:确保网络的非线性,实现更好的分类效果。

#定义前向网络计算,每层神经网络输出后增加relu激活函数,确保网络的非线性,实现更好的分类效果
def forward(x):
    x = x@w1.t() + b1
    x = F.relu(x)
    x = x@w2.t() + b2
    x = F.relu(x)
    x = x@w3.t() + b3
    x = F.relu(x)
    return x

3.定义梯度优化器及损失函数设置
[color=]代码如下:

.CrossEntropyLoss():损失采用交叉熵损失函数。
.SGD:采用随机梯度下降,并设置学习率。

#定义优化器,采用SGD随机梯度下降的方式对w1, b1, w2, b2, w3, b3进行优化
optimizer = optim.SGD([w1, b1, w2, b2, w3, b3], lr=learning_rate)
#定义采用交叉熵作为损失函数
criteon = nn.CrossEntropyLoss()

4.完成程序设计
[color=]代码如下:

#设置迭代次数
for epoch in range(epochs):
    for batch_idx, (data, target) in enumerate(train_loader):
        #将数据打平为(批次,高度*宽度),-1代表所有
        data = data.view(-1, 28*28)
               
                #将数据输入到网络中
        cal_data = forward(data)
        #将计算的数据与目标数据求误差损失
        loss = criteon(cal_data, target)
               
                #将梯度值初始化为0
        optimizer.zero_grad()
        #pytorch计算梯度值
        loss.backward()
        #更新梯度值
        optimizer.step()
                #每隔25*batcsize(200) = 5000 打印输出结果
        if batch_idx % 25 == 0:
            print('训练代数: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                       100. * batch_idx / len(train_loader), loss.item()))
        #将测试误差及正确率清0
    test_loss = 0
    correct = 0
    #取测试集数据及目标数据
    for data, target in test_loader:
        data = data.view(-1, 28 * 28)
        logits = forward(data)
        #误差累加
        test_loss += criteon(logits, target).item()
                #取出预测最大值的索引编号,即预测值
        pred = logits.data.argmax(dim=1)
        #统计正确预测的个数
        correct += pred.eq(target.data).sum()
    test_loss /= len(test_loader.dataset)
    #打印输出测试误差及准确率
    print('\n测试集: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))

三、完整代码程序
因为我们自己随机生成的初始化 w1,w2,w3,达到的性能并不好。所以我们可以采用大神何凯明的初始化权重对w1,w2,w3 进行初始化赋值,准确率可以达到90%。小伙伴们可以尝试下,将初始化赋值代码屏蔽,对比查看效果。

[color=]代码如下:

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets,transforms
#MNIST 数据集
#设置训练的批次大小、学习率、及训练代数
batch_size=200
learning_rate=0.001
epochs=20
#下载数据集
train_loader = torch.utils.data.DataLoader(
    datasets.MNIST('./data', train=True, download=True,
                   transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,))
                   ])),
    batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(
    datasets.MNIST('./data', train=False, download=True, transform=transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1307,), (0.3081,))
    ])),
    batch_size=batch_size, shuffle=True)
#生成三层神经网络成,对应感知机分别为第一层100,第二成200,第三层10,即要分类的数目
w1, b1 = torch.randn(100, 784, requires_grad=True),\
         torch.zeros(100, requires_grad=True)
w2, b2 = torch.randn(200, 100, requires_grad=True),\
         torch.zeros(200, requires_grad=True)
w3, b3 = torch.randn(10, 200, requires_grad=True),\
         torch.zeros(10, requires_grad=True)
#采用何凯明大神的初始化权重,准确率更高,权重的合理初始化很重要
torch.nn.init.kaiming_normal_(w1)
torch.nn.init.kaiming_normal_(w2)
torch.nn.init.kaiming_normal_(w3)
#定义前向网络计算,每层神经网络输出后增加relu激活函数,确保网络的非线性,实现更好的分类效果
def forward(x):
    x = x@w1.t() + b1
    x = F.relu(x)
    x = x@w2.t() + b2
    x = F.relu(x)
    x = x@w3.t() + b3
    x = F.relu(x)
    return x
#定义优化器,采用SGD随机梯度下降的方式对w1, b1, w2, b2, w3, b3进行优化
optimizer = optim.SGD([w1, b1, w2, b2, w3, b3], lr=learning_rate)
#定义采用交叉熵作为损失函数
criteon = nn.CrossEntropyLoss()
# 设置迭代次数
for epoch in range(epochs):
    for batch_idx, (data, target) in enumerate(train_loader):
        # 将数据打平为(批次,高度*宽度),-1代表所有
        data = data.view(-1, 28 * 28)
        # 将数据输入到网络中
        cal_data = forward(data)
        # 将计算的数据与目标数据求误差损失
        loss = criteon(cal_data, target)
        # 将梯度值初始化为0
        optimizer.zero_grad()
        # pytorch计算梯度值
        loss.backward()
        # 更新梯度值
        optimizer.step()
        # 每隔25*batcsize(200) = 5000 打印输出结果
        if batch_idx % 25 == 0:
            print('训练代数: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                       100. * batch_idx / len(train_loader), loss.item()))
    # 将测试误差及正确率清0
    test_loss = 0
    correct = 0
    # 取测试集数据及目标数据
    for data, target in test_loader:
        data = data.view(-1, 28 * 28)
        logits = forward(data)
        # 误差累加
        test_loss += criteon(logits, target).item()
        # 取出预测最大值的索引编号,即预测值
        pred = logits.data.argmax(dim=1)
        # 统计正确预测的个数
        correct += pred.eq(target.data).sum()
    test_loss /= len(test_loader.dataset)
    # 打印输出测试误差及准确率
    print('\n测试集: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))

输出结果:




总结
[color=]这一节,我们从底层搭建了一个三层的感知机神经网络,对手写数字数据集MNIST进行训练和测试,达到了92%的正确率。权重的随机初始化,对结果是很重要的,但在torch更高层的API使用中提供了很好的初始化,会在下一节中进行讲解。最后劳烦小伙伴,动手点个赞吧,给予我爆发小宇宙的能量。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|无图版|手机版|小黑屋|石家庄@IT精英团

GMT+8, 2021-4-13 19:32 , Processed in 0.076239 second(s), 27 queries .

Powered by Discuz! X3.4

© 2001-2021 Comsenz Inc.

快速回复 返回顶部 返回列表