xinmeng_wit 发表于 2024-9-24 21:47

《动手学深度学习(PyTorch版)》2、线性神经网络

本帖最后由 xinmeng_wit 于 2024-9-26 20:44 编辑

<p><strong><span style="font-size:18px;">一、线性回归</span></strong></p>

<p><em>回归</em>(regression)是能为一个或多个自变量与因变量之间关系建模的一类方法。 在自然科学和社会科学领域,回归经常用来表示输入和输出之间的关系。</p>

<p>在机器学习领域中的大多数任务通常都与<em>预测</em>(prediction)有关,但不是所有的<em>预测</em>都是回归问题。</p>

<p>线性回归应该大家都比较熟悉了,其数学表达式为:</p>

<div style="text-align: left;"></div>

<p>向量x对应于单个样本的特征,w表示权重,b表示偏置。</p>

<p>也就是将输入的特征x通过线性方程得到估计的输出值。</p>

<p>&nbsp;</p>

<ul>
        <li><strong><span style="font-size:16px;">损失函数</span></strong></li>
</ul>

<p>既然由线性方程得到的是估计值,那么就需要一种方法来评估这个估计值与实际值的接近程度,这个方法就是损失函数。</p>

<p><em>损失函数</em>(loss function)能够量化目标的<em>实际</em>值与<em>预测</em>值之间的差距。 通常我们会选择非负数作为损失,且数值越小表示损失越小,完美预测时的损失为0。 回归问题中最常用的损失函数是平方误差函数。</p>

<p>平方误差可以定义为:</p>

<div style="text-align: left;"></div>

<p><img alt="\hat{y}" src="https://bbs.eeworld.com.cn/gif.latex?%5Chat%7By%7D" />为预测值,y为实际值。</p>

<p>常数1/2不会带来本质的差别,但这样在形式上稍微简单一些 (因为当我们对损失函数求导后常数系数为1)</p>

<div style="text-align: left;"></div>

<p>在训练模型时,我们希望寻找一组参数(w,b), 这组参数能最小化在所有训练样本上的总损失。</p>

<p>特别的一点是像线性回归这样的简单问题存在解析解,但并不是所有的问题都存在解析解。 解析解可以进行很好的数学分析,但解析解对问题的限制很严格,导致它无法广泛应用在深度学习里。</p>

<p>&nbsp;</p>

<ul>
        <li><span style="font-size:16px;"><strong>随机梯度下降</strong></span></li>
</ul>

<p>即使在我们无法得到解析解的情况下,我们仍然可以有效地训练模型。</p>

<p>我们用到一种名为<em>梯度下降</em>(gradient descent)的方法, 这种方法几乎可以优化所有深度学习模型。 它通过不断地在损失函数递减的方向上更新参数来降低误差。</p>

<p>梯度下降最简单的用法是计算损失函数(数据集中所有样本的损失均值) 关于模型参数的导数(在这里也可以称为梯度)。 但实际中的执行可能会非常慢:因为在每一次更新参数之前,我们必须遍历整个数据集。 因此,我们通常会在每次需要计算更新的时候随机抽取一小批样本, 这种变体叫做<em>小批量随机梯度下降</em>(minibatch stochastic gradient descent)。</p>

<p>在每次迭代中,我们首先随机抽样一个小批量B, 它是由固定数量的训练样本组成的。 然后,我们计算小批量的平均损失关于模型参数的导数(也可以称为梯度)。 最后,我们将梯度乘以一个预先确定的正数&eta;,并从当前参数的值中减掉。</p>

<p>我们用下面的数学公式来表示这一更新过程(&part;表示偏导数):</p>

<div style="text-align: left;"></div>

<p>&nbsp;</p>

<p><span style="font-size:18px;"><strong>二、softmax回归</strong></span></p>

<p>前面介绍了线性回归,回归可以用于预测<em>多少</em>的问题。 比如预测房屋被售出价格,或者棒球队可能获得的胜场数,又或者患者住院的天数。</p>

<p>事实上,我们也对<em>分类</em>问题感兴趣:不是问&ldquo;多少&rdquo;,而是问&ldquo;哪一个&rdquo;。</p>

<p>softmax回归的出现就能帮助我们解决分类相关的问题。</p>

<p>softmax函数额表达式如下:</p>

<div style="text-align: left;"></div>

<p>尽管softmax是一个非线性函数,但softmax回归的输出仍然由输入特征的仿射变换决定。 因此,softmax回归是一个<em>线性模型</em>(linear model)。</p>

<p>softmax的损失函数如下:</p>

<div style="text-align: left;"></div>

<p>&nbsp;</p>

<p><strong><span style="font-size:18px;">三、图像分类数据集</span></strong></p>

<p>MNIST数据集&nbsp;(<a href="https://zh-v2.d2l.ai/chapter_references/zreferences.html#id90" title="LeCun, Y., Bottou, L., Bengio, Y., Haffner, P., &amp; others. (1998). Gradient-based learning applied to document recognition. Proceedings of the IEEE, 86(11), 2278–2324.">LeCun&nbsp;<em>et al.</em>, 1998</a>)&nbsp;是图像分类中广泛使用的数据集之一,但作为基准数据集过于简单。 我们将使用类似但更复杂的Fashion-MNIST数据集&nbsp;(<a href="https://zh-v2.d2l.ai/chapter_references/zreferences.html#id189" title="Xiao, H., Rasul, K., &amp; Vollgraf, R. (2017). Fashion-mnist: a novel image dataset for benchmarking machine learning algorithms. arXiv preprint arXiv:1708.07747.">Xiao&nbsp;<em>et al.</em>, 2017</a>)。</p>

<p>Fashion-MNIST由10个类别的图像组成, 每个类别由<em>训练数据集</em>(train dataset)中的6000张图像 和<em>测试数据集</em>(test dataset)中的1000张图像组成。 因此,训练集和测试集分别包含60000和10000张图像。 测试数据集不会用于训练,只用于评估模型性能。</p>

<p>每个输入图像的高度和宽度均为28像素。 数据集由灰度图像组成,其通道数为1。 为了简洁起见,本书将高度h像素、宽度w像素图像的形状记为h&times;w或(h,w)。</p>

<p>Fashion-MNIST中包含的10个类别,分别为t-shirt(T恤)、trouser(裤子)、pullover(套衫)、dress(连衣裙)、coat(外套)、sandal(凉鞋)、shirt(衬衫)、sneaker(运动鞋)、bag(包)和ankle boot(短靴)。 以下函数用于在数字标签索引及其文本名称之间进行转换。</p>

<p>数据集的加载及可视化代码如下:</p>

<pre>
<code class="language-python">
import torch
import torchvision
from torch.utils import data
from torchvision import transforms
from d2l import torch as d2l

d2l.use_svg_display()

# 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式,
# 并除以255使得所有像素的数值均在0~1之间
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)

len(mnist_train), len(mnist_test)

def get_fashion_mnist_labels(labels):#@save
    """返回Fashion-MNIST数据集的文本标签"""
    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
                   'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
    return 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)
    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))
d2l.plt.show()

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

def load_data_fashion_mnist(batch_size, resize=None):#@save
    """下载Fashion-MNIST数据集,然后将其加载到内存中"""
    trans =
    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()))

train_iter, test_iter = load_data_fashion_mnist(32, resize=64)
for X, y in train_iter:
    print(X.shape, X.dtype, y.shape, y.dtype)
    break</code></pre>

<p>运行结果:</p>

<div style="text-align: left;"></div>

<p>后面将基于该数据集做分类相关的实验,本次就先到这里。</p>

<p>&nbsp;</p>

<p>&nbsp;</p>
页: [1]
查看完整版本: 《动手学深度学习(PyTorch版)》2、线性神经网络