深度学习(4)——softmax简洁实现

前言

上一篇blog详细的讲了softmax的具体实现方法,这些有助于我们逐渐入门深度学习,当然我们强大的Pytorch库中就有现成的方法实现softmax,本章就来展示一下使用方法。

具体问题

延用上一章的例子,对图片进行分类,使用fashion_mnist库。

softmax简易实现

用到的库

import torch
from torch import nn
from d2l import torch as d2l

导入数据

batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

初始化模型参数

在线性回归简易实现的blog中有讲到过神经网络的Sequential,它表示多层连接,在softamx中只需要单层,并且用全连接实现,

# PyTorch不会隐式地调整输入的形状。因此,
# 我们在线性层前定义了展平层(flatten),来调整网络输入的形状
#flatten将28*28的二维图像展开成了784长度的一维数组
#输入长度784,输出长度10
net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))

#将权重初始化,均值0,方差0.01
def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)

net.apply(init_weights);

定义损失函数

这里用一句代码就可以实现softmax和交叉熵损失函数:

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

至于原因的话,这里还是放上李沐大神的解释
深度学习(4)——softmax简洁实现_第1张图片

优化算法

这里使用到了和线性回归一样的优化方法:随机梯度下降
这句话就是对模型中的权重进行梯度下降的优化处理,学习率赋值0.1

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

训练

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

train_ch3是上一篇详细实现softmax中写的函数,这里再回忆一下:

def train_ch3(net, train_iter, test_iter, loss, num_epochs, updater):  #@save
    """训练模型"""
    animator = 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_metrics = train_epoch_ch3(net, train_iter, loss, updater)
        test_acc = evaluate_accuracy(net, test_iter)
        animator.add(epoch + 1, train_metrics + (test_acc,))
    train_loss, train_acc = train_metrics
    #assert 断言 false 报错
    assert train_loss < 0.5, train_loss
    assert train_acc <= 1 and train_acc > 0.7, train_acc
    assert test_acc <= 1 and test_acc > 0.7, test_acc

本文中的net用的是神经网络实现的模型,等同于上一篇blog中的y=Xw
一次迭代函数回顾:

def train_epoch_ch3(net, train_iter, loss, updater):  #@save
    """训练模型一个迭代周期"""
    # 将模型设置为训练模式
    if isinstance(net, torch.nn.Module):
        net.train() #要计算梯度
    # 训练损失总和、训练准确度总和、样本数
    metric = Accumulator(3)
    for X, y in train_iter: 
        # 计算梯度并更新参数
        y_hat = net(X)
        l = loss(y_hat, y)
        if isinstance(updater, torch.optim.Optimizer):
            # 使用PyTorch内置的优化器和损失函数
            updater.zero_grad()
            l.mean().backward()
            updater.step()
        else:
            # 使用定制的优化器和损失函数
            # 我们这里会用到小批量随机梯度下降
            l.sum().backward()
            updater(X.shape[0])
        metric.add(float(l.sum()), accuracy(y_hat, y), y.numel())
    # 返回训练损失和训练精度
    return metric[0] / metric[2], metric[1] / metric[2]

那么至此,softmax使用框架的实现就完成了

小结

可以看出框架实现softmax回归是真的快,但搞清楚原理同样的重要。对于一些有点规律的分类问题来说使用softmax回归是个不错的选择,就像本文用的MNIST-FASHION数据集,一张衣服的图片,像素点就集中在那么几块区域,他和鞋子的像素点分布肯定是不同的,这种就是比较有特点的分类问题,softmax就很合适,那么碰到这种问题直接套本文的这些代码就会很快。

你可能感兴趣的:(深度学习,深度学习,人工智能,python)