pytorch实战第3章 分类问题

3.1手写数字图片数据集

  1. MNIST数据集:0~9共10个数字,每种数字有7000张图片.共70000张,其中60000张作为训练集,10000张图片作为测试集.每张图片大小为28*28.灰度图片
import torch
from torch import nn
from torch.nn import functional  # 导入网络层函数子库
from torch import optim  # 导入优化器
import torchvision  # 导入视觉库
from matplotlib import pyplot as plt
from utils import plot_image, plot_curve, one_hot
import torch.utils.data
import matplotlib as mpl
mpl.use('TkAgg')


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()

batch_size = 512  # 批大小
# 训练数据集
train_data = torchvision.datasets.MNIST('mnist-data', train=True, download=True,
                                        transform=torchvision.transforms.Compose(
                                            # 图片的预处理步骤:  1. 转化为张量  2.标准化
                                            [torchvision.transforms.ToTensor(),
                                             torchvision.transforms.Normalize((0.5,), (0.5,))
                                             ]))
# 测试数据集
test_data = torchvision.datasets.MNIST('mnist-data', train=False, download=True,
                                       transform=torchvision.transforms.Compose(
                                           [torchvision.transforms.ToTensor(),
                                            # torchvision.transforms.Normalize((0.5,), (0.5,))
                                            ]))

# 创建Dataloader对象,为方便批量形式训练,随机打乱顺序
train_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, shuffle=True)

# 加载一个批数据
x, y = next(iter(train_loader))  # torch.Size([512, 1, 28, 28]) torch.Size([512]) tensor(-1.) tensor(1.)
print(x.shape, y.shape, x.min(), x.max())
plot_image(x, y, 'Image')

坑1:长按Ctrl无法进入DataLoader类中:

添加:import torch.utils.data

坑2:matplotlib在报错:vars()参数必须有__dict__属性

import matplotlib as mpl
mpl.use('TkAgg')

3.2模型构建

  1. 数字之间存在天然的大小比较关系, 数字编码并不能适合分类网络的输出
  2. .一般采用独热编码(One-hot),但是其非常稀疏(Sparse),相对于数字编码来说占用较多的存储空间,因此一般在存储时还是采用数字编码方式,仅在计算时转化为One-hot编码.

torch.scatter()

#A.scatter_(dim, index, B) # 基本用法, tensor A 被就地scatter到 tensor B

在这里插入图片描述
https://www.cnblogs.com/simpleminds/p/16291635.html

## 在torch里面,view函数相当于numpy的reshape
def one_hot(label,depth=0):  # depth表示类别数目
    out = torch.zeros(label.size(0),depth)  # 4*10列
    idx = torch.LongTensor(label).view(-1,1)  # [0;1;2;3]
    out.scatter_(dim=1,index=idx,value=1)
    return out
y = torch.tensor([0,1,2,3])
y = one_hot(y,depth=10)
print(y)

3.3误差计算

  1. 分类问题一般使用交叉熵
  2. 本次使用MSE

3.4真的解决了吗?

3.6表达能力

3.7优化方法

这时就是深度学习框架发明的意义所在,借助于自动求导(Autograd)技术,深度学习框
架在计算神经网络每层的输出以及损失函数的过程中,会内部构建神经网络的计算图模
型,并自动完成误差对任意参数𝜃的偏导数𝜕ℒ
𝜕𝜃的计算,用户只需要搭建出网络结构,送入数
据,梯度将自动完成计算和更新,使用起来非常便捷高效,甚至连梯度下降算法也不需要
用户手动编写,交给 PyTorch 提供的优化器 optim 即可

3.8手写数字图片识别体验

# 利用Sequential容器封装3个网络层,前网络的输出默认作为下一层的输入
model = nn.Sequential(
    #1. 创建第一层,输入784,输出256
    nn.Linear(28*28,256),
    nn.ReLU(),   # 激活函数
    #2.创建第二层,输入256,输出128
    nn.Linear(256,128),
    nn.ReLU(), # 激活函数
    # 3.创建第三层,输入128,输出10
    nn.Linear(128,10)
)
# 创建优化器,并传递需要优化的参数列表
# 设置学习率
optimizer = optim.SGD(model.parameters(),lr=0.01, momentum=0.9)
train_loss = []
for epoch in range(5): # 训练5轮  所有训练数据迭代一遍叫做一个Epoch
    for batch_idx,(x,y) in enumerate(train_loader): # 按批迭代数据
        # x = [b,1,28,28],y:[512]
        # 打平操作
        x = x.view(x.size(0),28*28)
        # 送入网络模型 => [b,10]
        out = model(x)
        y_onehot = one_hot(y)
        #计算loss
        loss = F.mse_loss(out,y_onehot)
        # 在计算参数的梯度之前,通常需要清零梯度信息
        optimizer.zero_grad()
        # 计算模型中所有参数的梯度信息,这些梯度信息自动保存在每个张量的grad成员变量中
        loss.backward()  # 方向传播,计算所有参数的梯度
        # w`= w - lr * grad
        optimizer.step() # 根据梯度下降算法更新参数
        train_loss.append(loss.item())

        if batch_idx % 10==0:
            print(epoch, batch_idx, loss.item())

plot_curve(train_loss)

3.8.1网络搭建

3.8.2模型训练

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值