softmax回归的简洁实现【动手学深度学习】

整理自:《动手学深度学习》

import numpy as np
import torch,torchvision
from torch.utils import data
from torchvision import transforms
from d2l import torch as d2l

1. 获取数据集

使用torchvision库自带的经典数据集Fashion-MNST。下载后将其加载到内存中。

通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式,并除以255使得所有像素的数值均在0到1之间。

def load_data_fashion_mnist(batch_size, resize=None):
    trans = [transforms.ToTensor()]
    if resize:
        trans.insert(0, transforms.Resize(resize))
    trans = transforms.Compose(trans)
    mnist_train = torchvision.datasets.FashionMNIST(
        root="data",          """下载到哪个文件夹"""
        train=True,           """训练集还是测试集"""
        transform=trans,      """转换格式"""
        download=True         """是否下载到本地"""
    )
    mnist_test = torchvision.datasets.FashionMNIST(
        root="data", 
        train=False, 
        transform=trans,
        download=True
    )
    train_dl = data.DataLoader(mnist_train, batch_size, shuffle=True, num_workers=4)
    test_dl = data.DataLoader(mnist_test, batch_size, shuffle=True, num_workers=4)
    """num_workers是cpu多线程读入内存"""
    return (train_dl, test_dl)
train_iter, test_iter = load_data_fashion_mnist(32,resize=64)
for X,y in train_iter:
    print(X.shape,X.dtype)
    print(y.shape,y.dtype)
    break

2. 定义模型

PyTorch不会隐式地调整输⼊的形状。因此,我们在线性层前定义了展平层(flatten),来调整⽹络输⼊的形状

这里的net是已经封装好的模型,所有功能都有。

backward后,自动求导都存到了net里,step()后theta自动更新到net里,再次调用net就是训练好的模型。

所以同样是loss( y, net(X) )这个函数,训练前的值和训练后的值就不一样。

net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))
"""初始化参数,就是初始化theta的过程,从这个点开始梯度下降"""
def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01) '''均值0和标准差0.01随机初始化权重'''

net.apply(init_weights);

3. 损失函数

如果训练时画的图不显示,则使用后一个reduction='none'

reduction是计算模式,有三种选择:

1. reduction = mean, 会对N个样本的loss进行平均之后返回标量,(默认)

2. reduction = sum,   会对N个样本的loss求和后返回标量

3. reduction = none, 表示直接返回n个样本的loss返回向量

loss = nn.CrossEntropyLoss()
or
loss = nn.CrossEntropyLoss(reduction='none')

4. 优化算法

trainer = torch.optim.SGD(net.parameters(), lr=0.1)

5.训练

为了方便画图,分成两个函数。

5.1 整个数据集的小批次训练

def train_epoch_ch3(net, train_iter, loss, trainer):
    metric = d2l.Accumulator(3)
    for X,y in train_iter:
        y_hat = net(X)
        l = loss(y_hat, y)
        trainer.zero_grad()
        l.mean().backward()
        trainer.step()
        metric.add(float(l.sum()), d2l.accuracy(y_hat,y), y.numel())
    '''返回训练损失和训练精度'''
    return metric[0]/metric[2], metric[1]/metric[2]

5.2 画图, 和多次扫描数据集训练

def train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer):
    '''动态画图实例'''
    animator = d2l.Animator(xlabel='epoch', xlim=[1,num_epochs], ylim=[0.3,0.9],legend=['train loss', 'train acc', 'test acc'])
    
    for epoch in range(num_epochs):
        '''训练,顺便返回损失和精度'''
        train_metirc = train_epoch_ch3(net, train_iter, loss, trainer)
        '''记录训练过程中的测试集准确度'''
        test_acc = d2l.evaluate_accuracy(net, test_iter)
        animator.add(epoch+1, train_metirc+(test_acc,))

正式开始

num_epochs = 10
train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值