• 深度学习(五)softmax 回归之:分类算法介绍,如何加载 Fashion-MINIST 数据集


    Softmax 回归

    基本原理

    回归和分类,是两种深度学习常用方法。回归是对连续的预测(比如我预测根据过去开奖列表下次双色球号),分类是预测离散的类别(手写语音识别,图片识别)。

    1699720169075

    现在我们已经对回归的处理有一定的理解了,如何过渡到分类呢?

    假设我们有 n 类,首先我们要编码这些类让他们变成数据。所有类变成一个列向量。

    y = [ y 1 , y 2 , . . . y n ] T y=[y_1,y_2,...y_n]^T y=[y1,y2,...yn]T

    有一个数据属于第 i 类,那么他的列向量就是:

    y = [ 0 , 0 , . . . , 1 , . . . , 0 , 0 ] T y=[0,0,...,1,...,0,0]^T y=[0,0,...,1,...,0,0]T

    也就是只有他所在的那个类的元素=1.

    可以用均方损失训练,通过概率判断最终选用哪一个。

    Softmax 回归就是一种分类方式(回归问题在多分类上的推广)。首先确定输入特征数和输出类别数。比如上图中我们有4个特征和3个可能的类别,那么计算各自概率的公式包括3个线性回归:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    可以看出 Softmax 是全连接的单层神经网络。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    我们让所有输出结果归一化后,从中选择出最大可能的,置信度最高的分类结果。

    image-20231112100423488

    采用 e 的指数可以让值全变为非负。

    用真实的概率向量-我们预测得到的概率向量就是损失。真实值就是只有一个1的列向量。

    交叉熵损失:

    image-20231112101259670

    可见**分类问题,我们不关心对非正确的预测值,只关心正确预测值是否足够大。**因为正确值是只有一个元素为1的列向量。

    常用的损失函数

    L2 Loss:均方损失。

    image-20231112101555142

    L1 Loss:绝对值损失。

    image-20231112101829868

    L2 梯度是一条倾斜直线,对于梯度下降算法等更为合适;L1 是一个跳变,梯度要么 -1 要么 1. 如图是 L1 L2 的梯度。

    image-20231112102551104

    我们可以结合两者,得到一个新的损失函数(鲁棒损失 Huber Robust):

    KaTeX parse error: {equation} can be used only in display mode.

    image-20231112102721527

    图像分类数据集

    MINIST 是一个常用图像分类数据集,但是过于简单。后来的 upgrade 版叫 Fashion-MINIST(服装分类).

    首先,我们研究研究怎么加载训练数据集,以便后面测试算法用。

    # 导包
    %matplotlib inline
    import torch
    import torchvision
    from torch.utils import data
    from torchvision import transforms
    from d2l import torch as d2l
    
    d2l.use_svg_display()
    
    d2l.use_svg_display()
    
    # 下载数据集并读取到内存
    trans = transforms.ToTensor()
    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)	# 测试数据集用于评估性能
    
    # 定义函数用于返回对应索引的标签
    def get_fashion_mnist_labels(labels):  #@save
        """返回Fashion-MNIST数据集的文本标签"""
        text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
                       'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
        return [text_labels[int(i)] for i in labels]
    
    # 图像可视化,让结果看着更直观,比如下面那个绿色图的样子
    def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):  #@save
        """绘制图像列表"""
        figsize = (num_cols * scale, num_rows * scale)
        _, axes = d2l.plt.subplots(num_rows, num_cols, figsize=figsize)
        axes = axes.flatten()
        for i, (ax, img) in enumerate(zip(axes, imgs)):
            if torch.is_tensor(img):
                # 图片张量
                ax.imshow(img.numpy())
            else:
                # PIL图片
                ax.imshow(img)
            ax.axes.get_xaxis().set_visible(False)
            ax.axes.get_yaxis().set_visible(False)
            if titles:
                ax.set_title(titles[i])
        return axes
    
    # 我们先读一点数据集看看啥样的
    X, y = next(iter(data.DataLoader(mnist_train, batch_size=18)))
    show_images(X.reshape(18, 28, 28), 2, 9, titles=get_fashion_mnist_labels(y));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    1699980345931

    # 通过内置数据加载器读取一批量数据,自动随机打乱读取,不需要我们自己定义
    batch_size = 256
    
    def get_dataloader_workers():  #@save
        """使用4个进程来读取数据"""
        return 4
    
    train_iter = data.DataLoader(mnist_train, batch_size, shuffle=True,
                                 num_workers=get_dataloader_workers())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    测量以上用时基本2-3s。

    总结整合以上数据读取过程,代码如下:

    def load_data_fashion_mnist(batch_size, resize=None):  #@save
        """下载Fashion-MNIST数据集,然后将其加载到内存中"""
        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)
        return (data.DataLoader(mnist_train, batch_size, shuffle=True,
                                num_workers=get_dataloader_workers()),
                data.DataLoader(mnist_test, batch_size, shuffle=False,
                                num_workers=get_dataloader_workers()))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    加载图像还可以调整其大小。

  • 相关阅读:
    Python-正则表达式技巧-查找目标字符串-范例
    python requests爬取税务总局税案通报、税务新闻和政策解读
    学习笔记20--汽车运动控制
    Bash基本功能—多命令顺序执行与管道符
    Miniconda、Vscode下载和conda源、pip源设置
    计算机视觉的应用12-卷积神经网络中图像特征提取的可视化研究,让大家理解特征提取的全过程
    vue+elementUI实现指定列的单元格可编辑
    Docker的资源管理控制(CPU、内存、磁盘IO配额)
    vue自定义组件实现v-model双向数据绑定
    【附源码】Python计算机毕业设计魔术教学网站
  • 原文地址:https://blog.csdn.net/jtwqwq/article/details/134471315