tiger94me

导航

动手学深度学习-第3章线性神经网络

## 3.1线性回归
回归(regression)是能为一个或多个自变量与因变量之间关系建模的一类方法。
线性回归基于几个简单的假设:
1.自变量和因变量之间的关系是线性的
2.任何噪声都比较正常,如噪声遵循正态分布
仿射变换的特点是通过加权和对特征进行线性变换(linear transformation), 并通过偏置项来进行平移(translation)。

3.1.1基本元素

1.线性模型

\(\hat{y} = \mathbf{w}^\top \mathbf{x} + b\)

2.损失函数

回归问题中最常用的损失函数是平方误差函数。 当样本i的预测值为\(\hat{y}^{(i)}\),
,其相应的真实标签为\(y^{(i)}\)时, 平方误差可以定义为以下公式
\(l^{(i)}(\mathbf{w}, b) = \frac{1}{2} \left(\hat{y}^{(i)} - y^{(i)}\right)^2.\)
image
需计算在训练集个样本上的损失均值(也等价于求和)
\(L(\mathbf{w}, b) =\frac{1}{n}\sum_{i=1}^n l^{(i)}(\mathbf{w}, b) =\frac{1}{n} \sum_{i=1}^n \frac{1}{2}\left(\mathbf{w}^\top \mathbf{x}^{(i)} + b - y^{(i)}\right)^2.\)

3.解析解

线性回归的解可以用一个公式简单地表达出来, 这类解叫作解析解(analytical solution)
\(\mathbf{w}^* = (\mathbf X^\top \mathbf X)^{-1}\mathbf X^\top \mathbf{y}.\)

4. 随机梯度下降

梯度下降最简单的用法是计算损失函数(数据集中所有样本的损失均值) 关于模型参数的导数(在这里也可以称为梯度)。 但实际中的执行可能会非常慢:因为在每一次更新参数之前,我们必须遍历整个数据集。 因此,我们通常会在每次需要计算更新的时候随机抽取一小批样本, 这种变体叫做小批量随机梯度下降(minibatch stochastic gradient descent)。
更新过程:
\((\mathbf{w},b) \leftarrow (\mathbf{w},b) - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \partial_{(\mathbf{w},b)} l^{(i)}(\mathbf{w},b).\)
算法的步骤如下:
(1)初始化模型参数的值,如随机初始化;
(2)从数据集中随机抽取小批量样本且在负梯度的方向上更新参数,并不断迭代这一步骤。
对于平方损失和仿射变换,我们可以明确地写成如下形式:
\(\begin{split}\begin{aligned} \mathbf{w} &\leftarrow \mathbf{w} - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \partial_{\mathbf{w}} l^{(i)}(\mathbf{w}, b) = \mathbf{w} - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \mathbf{x}^{(i)} \left(\mathbf{w}^\top \mathbf{x}^{(i)} + b - y^{(i)}\right),\\ b &\leftarrow b - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \partial_b l^{(i)}(\mathbf{w}, b) = b - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \left(\mathbf{w}^\top \mathbf{x}^{(i)} + b - y^{(i)}\right). \end{aligned}\end{split}\)

5. 用模型进行预测

给定特征估计目标的过程通常称为预测(prediction)或推断(inference)。

3.1.2矢量化加速

通过矩阵运算节省时间

3.1.3. 正态分布与平方损失

正态分布概率密度函数如下:
\(p(x)= \frac{1}{\sqrt{2 \pi \sigma^2}} \exp\left(-\frac{1}{2 \sigma^2}(x- \mu)^2\right).\)
写出通过给定的观测到特定的似然(likelihood):
\(P(y \mid \mathbf{x}) = \frac{1}{\sqrt{2 \pi \sigma^2}} \exp\left(-\frac{1}{2 \sigma^2} (y - \mathbf{w}^\top \mathbf{x} - b)^2\right).\)
根据极大似然估计法,参数w和b的最优值是使整个数据集的似然最大的值:
\(P(\mathbf y \mid \mathbf X) = \prod_{i=1}^{n} p(y^{(i)}|\mathbf{x}^{(i)}).\)
通过最大化似然对数来简化。 优化通常是说最小化而不是最大化。 可以改为最小化负对数似然\(-\log P(\mathbf y \mid \mathbf X)\)。 由此可以得到的数学公式是:
\(-\log P(\mathbf y \mid \mathbf X) = \sum_{i=1}^n \frac{1}{2} \log(2 \pi \sigma^2) + \frac{1}{2 \sigma^2} \left(y^{(i)} - \mathbf{w}^\top \mathbf{x}^{(i)} - b\right)^2.\)

在高斯噪声的假设下,最小化均方误差等价于对线性模型的极大似然估计。

3. 1.4. 从线性回归到深度网络

可以将线性回归模型视为仅由单个人工神经元组成的神经网络,或称为单层神经网络。
image

每个输入都与每个输出(在本例中只有一个输出)相连, 我们将这种变换 称为全连接层(fully-connected layer)或称为稠密层(dense layer)

3.2线性回归的实现

在启智AI开台上,编程实现。
执行以下循环:
初始化参数
重复以下训练,直到完成
计算梯度 \(\mathbf{g} \leftarrow \partial_{(\mathbf{w},b)} \frac{1}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} l(\mathbf{x}^{(i)}, y^{(i)}, \mathbf{w}, b)\)
更新参数 \((\mathbf{w}, b) \leftarrow (\mathbf{w}, b) - \eta \mathbf{g}\)
在每个迭代周期(epoch)中,我们使用data_iter函数遍历整个数据集, 并将训练数据集中所有样本都使用一次(假设样本数能够被批量大小整除)。 这里的迭代周期个数num_epochs和学习率lr都是超参数,分别设为3和0.03。 设置超参数很棘手,需要通过反复试验进行调整。
在机器学习中,我们通常不太关心恢复真正的参数,而更关心如何高度准确预测参数。
是在复杂的优化问题上,随机梯度下降通常也能找到非常好的解

3.3 线性回归的简洁实现

通过深度学习框架的高级API来实现我们的模型只需要相对较少的代码。 我们不必单独分配参数、不必定义我们的损失函数,也不必手动实现小批量随机梯度下降。

  • 通过调用net(X)生成预测并计算损失l(前向传播)。

  • 通过进行反向传播来计算梯度。

  • 通过调用优化器来更新模型参数。

点击查看代码
import numpy as np
import numpy as np
import torch
from torch.utils import data
from d2l import torch as d2l

from torch import nn

true_w1=torch.tensor([2,8.])
true_b1=4.2
features,labels =d2l.synthetic_data(true_w1,true_b1,1000)

def load_array(data_arrays,batch_size,is_train=True):
    dataset=data.TensorDataset(*data_arrays)
    return data.DataLoader(dataset,batch_size,shuffle=is_train)

batch_size =10
data_iter=load_array((features,labels),batch_size)

net = nn.Sequential(nn.Linear(2,1))

net[0].weight.data.normal_(0,0.01)
net[0].bias.data.fill_(0)

loss=nn.MSELoss()

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

num_epochs=3
for epoch in range(num_epochs):
    for X,y in data_iter:
        l=loss(net(X),y)
        trainer.zero_grad()
        l.backward()
        trainer.step()
    l=loss(net(features),labels)
#     w = net[0].weight.data
#     print('w的估计误差:', true_w - w.reshape(true_w.shape))
#     b = net[0].bias.data
#     print('b的估计误差:', true_b - b)
    print(f'epoch{epoch+1}, loss {l:f}')

3.4 softmax回归

使用深度学习框架的高级API简洁实现线性回归。

3.4.1分类问题

分类问题不与类别之间的自然顺序有关,标签的表达采用独热编码。独热编码是一个向量,它的分量和类别一样多。类别对应的分量设置为1,其他 所有分量设置为0。

3.4.2网络架构

为了估计所有可能类别的条件概率,我们需要一个有多个输出的模型,每个类别对应一个输出。
\(\begin{split}\begin{aligned} o_1 &= x_1 w_{11} + x_2 w_{12} + x_3 w_{13} + x_4 w_{14} + b_1,\\ o_2 &= x_1 w_{21} + x_2 w_{22} + x_3 w_{23} + x_4 w_{24} + b_2,\\ o_3 &= x_1 w_{31} + x_2 w_{32} + x_3 w_{33} + x_4 w_{34} + b_3. \end{aligned}\end{split}\)
image

3.4.3. 全连接层的参数开销

对于任何具有个输入d和个输出q的全连接层, 参数开销为O(dq),
可以将d个输入转换为q个输出的成本可以减少到O(dq/n)

3.4.4. softmax运算

优化参数以最大化观测数据的概率
softmax函数能够将未规范化的预测变换为非负数并且总和为1,同时让模型保持 可导的性质。
\(\hat{\mathbf{y}} = \mathrm{softmax}(\mathbf{o})\quad \text{其中}\quad \hat{y}_j = \frac{\exp(o_j)}{\sum_k \exp(o_k)}\)
尽管softmax是一个非线性函数,但softmax回归的输出仍然由输入特征的仿射变换决定。 因此,softmax回归是一个线性模型(linear model)。

3.4.5. 小批量样本的矢量化

为了提高计算效率并且充分利用GPU,我们通常会对小批量样本的数据执行矢量计算。
由于中的每一行代表一个数据样本, 那么softmax运算可以按行(rowwise)执行: 对于的每一行,我们先对所有项进行幂运算,然后通过求和对它们进行标准化。

3.4.6. 损失函数

使用最大似然估计
估计值与实际值进行比较:
$ P(Y|X))= \prod_{i=1}^n P(\mathbf{y}^{(i)} \mid \mathbf{x}^{(i)}) . $

最大化P(Y|X),相当于最小化负对数似然:
$ -logP(\mathbf{Y} \mid \mathbf{X})= \sum_{i=1}^n -\log P( \mathbf{y}^{(i)}\mid \mathbf{x}^{(i)} )
= \sum_{i=1}^n l(\mathbf{y}^{(i)}, \hat{\mathbf{y}}^{(i)}), $

其中,对于任何标签y和模型预测\(\hat{y}\),损失函数为:
\(l(y,\hat{y})=-\sum_{(j=1)}^q{y}_jlog\hat{y}_j.\)

由于y是一个长度为的独热编码向量, 所以除了一个项以外的所有项j都消失了

\(\begin{split}\begin{aligned} l(\mathbf{y}, \hat{\mathbf{y}}) &= - \sum_{j=1}^q y_j \log \frac{\exp(o_j)}{\sum_{k=1}^q \exp(o_k)} \\ &= \sum_{j=1}^q y_j \log \sum_{k=1}^q \exp(o_k) - \sum_{j=1}^q y_j o_j\\ &= \log \sum_{k=1}^q \exp(o_k) - \sum_{j=1}^q y_j o_j. \end{aligned}\end{split}\)
考虑相对于任何未规范化的预测的导数,我们得到:
\(\partial_{o_j} l(\mathbf{y}, \hat{\mathbf{y}}) = \frac{\exp(o_j)}{\sum_{k=1}^q \exp(o_k)} - y_j = \mathrm{softmax}(\mathbf{o})_j - y_j.\)

3.4.7. 信息论基础

信息论(information theory)涉及编码、解码、发送以及尽可能简洁地处理信息或数据。
$ H[P]=\sum_j -P(j)\log P(j).$

根据信息论的基本定理,对于一个从分布 \(P\) 中独立抽取的符号序列,其平均编码长度 \(L\) 不能小于熵 \(H(P)\)。如果采用一种比熵更紧凑的编码方法,那么编码后的序列长度将小于熵,而这意味着存在一些抽取的符号无法被完全识别和恢复。因此,为了保证数据能够被正确编码和解码,至少需要 \(H(P)\) 个纳特的编码长度来保证信息无损地传输。

更具体地说,熵是衡量随机变量不确定性的度量,用来衡量在某一确定分布 \(P\) 中选择一个符号时所包含的平均信息量。假设 \(X\) 是从分布 \(P\) 中选择的一个符号,则熵 \(H(P)\) 定义为:

\[H(P) = -\sum_{x \in X} P(x) \log_2 P(x) \]

其中,\(P(x)\) 表示该符号出现的概率,\(\log_2 P(x)\) 表示以2为底,\(P(x)\)的对数。熵表示在给定分布 \(P\) 的情况下,需要多少二进制数来表示每个符号,从而确保每个符号都能被正确编码和解码。

因此,至少需要 \(H(P)\) 个纳特的编码长度来对从分布 \(P\) 中随机抽取的数据进行编码。这是为了确保编码的可靠性,避免信息丢失或解码错误,并同时保持编码长度的最小化。

3.4.8. 模型预测和评估

posted on 2023-03-23 07:34  学到老必须的  阅读(58)  评论(0编辑  收藏  举报