《动手学深度学习》参考答案(第二版)-第三章

《动手学深度学习》参考答案

  最近在学习《动手学深度学习》,结合百度和课后的大家的讨论(侵删),整理出这一份可能并不完全正确的参考答案(菜鸡的做题记录),因为个人水平有限,有错误的地方欢迎在 公众号 联系我,后面我对错误进行更正时候,会在文章末尾鸣谢,在这里先感谢大家了。
  在我的 公众号 中会有 清晰的pdf版本 给到大家,pdf中 代码 可以直接复制实践 ,欢迎大家关注我的 公众号:Hello Neural Networks ,发送神秘代码:d2l3,即可获得本章的pdf版本。(求大佬们关注下吧,公众号关注者人丁稀少,嘤嘤嘤)
  求求关注下我的简书CSDN知乎吧,后面会继续更新答案的,然后还有最近读的一些文章的里面一些创新点和自己的想法都会整理出来的。(求大佬们关注下吧,嘤嘤嘤)

3.线性神经网络

3.1 线性回归

1.假设我们有一些数据x1,…,xn∈R。我们的目标是找到一个常数b,使得最小化∑i(xi−b)2。

①.找到最优值b的解析解。

②.这个问题及其解与正态分布有什么关系?


即求\underset{b}{\mathrm{argmin}}\sum_{i=1}^{n}(x_i-b)^2

\Rightarrow \frac{δ\sum_{i=1}^{n}(x_i-b)^2}{δb}=0

\Rightarrow \sum_{i=1}^{n}(x_i-b)=0

\Rightarrow \sum_{i=1}^{n}x_i-nb=0

\Rightarrow b = \frac{\sum_{i=1}^{n}x_i}{n}


令x_i=b+\epsilon (\epsilon \sim N(0, \sigma^2))

则P(x_i|b)=\frac{1}{\sqrt{2\pi \sigma^2}}exp(-\frac{1}{2\sigma^2}(x^i-b))

\begin{aligned} 则P(x|b)&=\prod_{i=1}^np(x_i|b)\\ &=\prod_{i=1}^n\frac{1}{\sqrt{2\pi \sigma^2}}exp(-\frac{1}{2\sigma^2}(x^i-b))\\ &=(\frac{1}{\sqrt{2\pi \sigma^2}})^nexp(\sum_{i=1}^{n}-\frac{1}{2\sigma^2}(x^i-b)) \end{aligned}

-log(P(x|b))=\frac{n}2log(2\pi \sigma^2)+\sum_{i=1}^{n}\frac{1}{2\sigma^2}(x^i-b)

\begin{aligned} 则\underset{b}{\mathrm{argmax}}P(x|b) &\Rightarrow \underset{b}{\mathrm{argmin}}-log(P(x|b))\\ &\Rightarrow \underset{b}{\mathrm{argmin}}\sum_{i=1}^{n}(x_i-b)^2 \end{aligned}

2.推导出使用平方误差的线性回归优化问题的解析解。为了简化问题,可以忽略偏置bb(我们可以通过向XX添加所有值为1的一列来做到这一点)

①.用矩阵和向量表示法写出优化问题(将所有数据视为单个矩阵,将所有目标值视为单个向量)。

②.计算损失对w的梯度。

③.通过将梯度设为0,求解矩阵方程来找到解析解。

④.什么时候可能比使用随机梯度下降更好?这种方法何时会失效?


令\hat Y = XW,标签表示为Y

其中X \in R^{1 \times n},Y \in R^{1 \times q},W \in R^{n \times q},则\hat Y\in R^{1 \times q}

则Loss=||Y-\hat Y||_2=(Y-XW)^T(Y-XW)


\begin{aligned} Loss&=(Y-XW)^T(Y-XW)\\ &=Y^TY-W^TX^TY-Y^TXW+W^TX^TXW\\ &=Y^TY-2Y^TXW+W^TX^TXW \end{aligned}

则\frac{δL}{δW}=-2X^TY+2X^TXW


令\frac{δL}{δW}=0,得W=(X^TX)^{-1}X^TY

当模型比较简单的时候,通过求W的解析解是比随机梯度下降更好,但是当X^TX不可逆时候这个方法失效
3.假定控制附加噪声ϵ的噪声模型是指数分布。也就是说,p(ϵ)=1/2exp(−|ϵ|)

①.写出模型−logP(y∣X)下数据的负对数似然。

②.你能写出解析解吗?

③.提出一种随机梯度下降算法来解决这个问题。哪里可能出错?(提示:当我们不断更新参数时,在驻点附近会发生什么情况)你能解决这个问题吗?


令y=w^Tx+b+\epsilon,其中p(\epsilon)=\frac{1}2e^{-|\epsilon|}

则通过给定的 x 观测到特定 y 的似然:P(y|x)=\frac{1}2e^{-|y-w^Tx-b|}

\begin{aligned} 则P(y|X)&=\prod_{i=1}^np(y^{(i)}|x^{(i)})\\ &=\prod_{i=1}^n\frac{1}2e^{-|y^{(i)}-w^Tx^{(i)}-b|}\\ &=(\frac{1}2)^ne^{(-\sum_{i=1}^{n}|y^{(i)}-w^Tx^{(i)}-b|)} \end{aligned}

则-logP(y|X)=nlog2+\sum_{i=1}^{n}|y^{(i)}-w^Tx^{(i)}-b|


由①极大似然估计,定义Loss=\sum_{i=1}^{n}|y^{(i)}-w^Tx^{(i)}-b|

参考题2,假设batchsize=1,且将b合并进x中,即求Loss=|Y-XW|

即Loss=sgn(Y-XW)\times (Y-XW)

则\frac{δL}{δW}=-sgn(Y-XW)X^T

令\frac{δL}{δW}=0,其实发现是没有解的,其实也说的通,这种线性绝对值函数在极点是没有导数的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bhbxTqVf-1651918892981)(E:\Figure_1.png)]

③所求得的损失函数其实是L1-loss的形式,在驻点处不可导,梯度下降法可能碰到问题(例如在驻点附近,参数剧烈波动难以收敛),可以采用smooth L1-loss的方法来代替L1-loss会有比较好的效果(即当损失函数小于一定阈值后,就用L2-loss代替L1-loss,即避免了L2-loss在距离驻点较远时梯度太大训练不稳定,也避免了L1-loss在驻点附近参数剧烈波动难以收敛)。

3.2 线性回归的从零开始实现

1.如果我们将权重初始化为零,会发生什么。算法仍然有效吗?

在单层网络中(一层线性回归层),将权重初始化为零时可以的,但是网络层数加深后,在全连接的情况下,在反向传播的时候,由于权重的对称性会导致出现隐藏神经元的对称性,使得多个隐藏神经元的作用就如同1个神经元,算法还是有效的,但是效果不大好。参考:https://zhuanlan.zhihu.com/p/75879624

2.假设你是乔治·西蒙·欧姆,试图为电压和电流的关系建立一个模型。你能使用自动微分来学习模型的参数吗?

可以的,建立模型U=IW+b,然后采集(U,I)的数据集,通过自动微分即可学习W和b的参数。

3.您能基于普朗克定律使用光谱能量密度来确定物体的温度吗?
u_{\lambda}=\frac{8\pi h v^3}{c^3}\frac{1}{e^{hv/kT}-1}
4.如果你想计算二阶导数可能会遇到什么问题?你会如何解决这些问题?

一阶导数的正向计算图无法直接获得,可以通过保存一阶导数的计算图使得可以求二阶导数(create_graph和retain_graph都置为True,保存原函数和一阶导数的正向计算图)。实验如下:

import torch

x = torch.randn((2), requires_grad=True)
y = x**3

dy = torch.autograd.grad(y, x, grad_outputs=torch.ones(x.shape),
                         retain_graph=True, create_graph=True)
dy2 = torch.autograd.grad(dy, x, grad_outputs=torch.ones(x.shape))

dy_ = 3*x**2
dy2_ = 6*x

print("======================================================")
print(dy, dy_)
print("======================================================")
print(dy2, dy2_)
======================================================
(tensor([1.4400, 4.7441], grad_fn=<MulBackward0>),) tensor([1.4400, 4.7441], grad_fn=<MulBackward0>)
======================================================
(tensor([-4.1569,  7.5451]),) tensor([-4.1569,  7.5451], grad_fn=<MulBackward0>)

关于create_graph和retain_graph的参考:https://zhuanlan.zhihu.com/p/84890656

5.为什么在squared_loss函数中需要使用reshape函数?

以防y^和y,一个是行向量、一个是列向量,使用reshape,可以确保shape一样。

6.尝试使用不同的学习率,观察损失函数值下降的快慢。

①学习率过大前期下降很快,但是后面不容易收敛;

②学习率过小损失函数下降会很慢。

7.如果样本个数不能被批量大小整除,data_iter函数的行为会有什么变化?

报错。

3.3 线性回归的简洁实现

1.如果将小批量的总损失替换为小批量损失的平均值,你需要如何更改学习率?

将学习率除以batchsize。

2.查看深度学习框架文档,它们提供了哪些损失函数和初始化方法?用Huber损失代替原损失。

其实Huber损失可以用torch自带的函数解决:

torch.nn.SmoothL1Loss()

当然,也可以自己写:

import torch.nn as nn
import torch.nn.functional as F

class HuberLoss(nn.Module):
    def __init__(self, sigma):
        super(HuberLoss, self).__init__()
        self.sigma = sigma
    def forward(self, y, y_hat):
        if F.l1_loss(y, y_hat) > self.sigma:
            loss = F.l1_loss(y, y_hat) - self.sigma/2
        else:
            loss = (1/(2*self.sigma))*F.mse_loss(y, y_hat)
        
        return loss

3.你如何访问线性回归的梯度?

net[0].weight.grad
net[0].bias.grad

假如是多层网络,可以用一个self.xxx=某层,然后在外面通过net.xxx.weight.grad和net.xxx.bias.grad把梯度给拿出来。

3.4 softmax回归

1.我们可以更深入地探讨指数族与softmax之间的联系。

①.计算softmax交叉熵损失l(y,y)l(y,y)的二阶导数。

②.计算softmax(o)softmax(o)给出的分布方差,并与上面计算的二阶导数匹配。


由书中可知:\frac{l(y,\hat y)}{δ_{oj}}=softmax(o)_j-y_j

\begin{aligned} 则\frac{l(y,\hat y)}{δ_{oj}δ_{oj}}&=\frac{softmax(o)_j-y_j}{δ_{oj}}\\ &=\frac{softmax(o)_j}{δ_{oj}}\\ &=exp(o_j)\frac{1}{\sum_{k=1}^qexp(o_k)}-\frac{exp(o_j)}{(\sum_{k=1}^qexp(o_k))^2}exp(o_j)\\ &=\frac{exp(o_j)}{\sum_{k=1}^qexp(o_k)}(1-\frac{exp(o_j)}{\sum_{k=1}^qexp(o_k)})\\ &=softmax(o)_j(1-softmax(o)_j) \end{aligned}

\begin{aligned} 则\frac{l(y,\hat y)}{δ_{oj}δ_{oi}}&=\frac{softmax(o)_j-y_j}{δ_{oi}}\\ &=\frac{softmax(o)_j}{δ_{oi}}\\ &=-\frac{exp(o_j)}{(\sum_{k=1}^qexp(o_k))^2}exp(o_i)\\ &=-\frac{exp(o_j)}{\sum_{k=1}^qexp(o_k)}\frac{exp(o_i)}{\sum_{k=1}^qexp(o_k)}\\ &=-softmax(o)_j\times softmax(o)_i \end{aligned}


有E(o)=\sum_{j=1}^q\frac{o_jexp(o_j)}{\sum_{k=1}^qexp(o_k)}

有E(o^2)=\sum_{j=1}^q\frac{o_j^2exp(o_j)}{\sum_{k=1}^qexp(o_k)}

\begin{aligned} Var(o)&=E(o^2)-E^2(o)\\ &=\sum_{j=1}^q\frac{o_j^2exp(o_j)}{\sum_{k=1}^qexp(o_k)}-(\sum_{j=1}^q\frac{o_jexp(o_j)}{\sum_{k=1}^qexp(o_k)})^2\\ &=\frac{\sum_{j=1}^qo_j^2exp(o_j)}{\sum_{k=1}^qexp(o_k)}-(\frac{\sum_{j=1}^qo_jexp(o_j)}{\sum_{k=1}^qexp(o_k)})^2\\ &=\frac{\sum_{j=1}^qo_j^2exp(o_j)\sum_{k=1}^qexp(o_k)-(\sum_{j=1}^q o_j exp(o_j))^2}{(\sum_{k=1}^qexp(o_k))^2}\\ &=\frac{\sum_{j=1}^qo_j^2exp(o_j)\sum_{k=1}^qexp(o_k)-(\sum_{j=1}^q o_j exp(o_j))^2}{(\sum_{k=1}^qexp(o_k))^2}\\ &=\begin{cases} \frac{\sum_{i=1}^{q/2}\sum_{j=q/2,j≠i}^{q}(o_i-o_j)^2exp(o_i)exp(o_j)}{(\sum_{k=1}^qexp(o_k))^2}, & \text {if $q$ is even} \\ \frac{\sum_{i=1}^{(q+1)/2}\sum_{j=(q+1)/2,j≠i}^{q}(o_i-o_j)^2exp(o_i)exp(o_j)}{(\sum_{k=1}^qexp(o_k))^2}, & \text{if $q$ is odd} \end{cases}\\ &=\begin{cases} \sum_{i=1}^{q/2}\sum_{j=q/2,j≠i}^{q}(o_i-o_j)^2softmax(o_i)softmax(o_j), & \text {if $q$ is even} \\ \sum_{i=1}^{(q+1)/2}\sum_{j=(q+1)/2,j≠i}^{q}(o_i-o_j)^2softmax(o_i)softmax(o_j), & \text{if $q$ is odd} \end{cases}\\ \end{aligned}

这个式子什么意思呢,假如说q=2,那么我们假设o_1=x,o_2=y

Var(o)=(x-y)^2softmax(x)softmax(y)

再假如说q=3,那么我们假设o_1=x,o_2=y,o_3=z

Var(o)=(x-y)^2softmax(x)softmax(y)+(x-z)^2softmax(x)softmax(z)+(y-z)^2softmax(y)softmax(z)

2.假设我们有三个类发生的概率相等,即概率向量是(1/3,1/3,1/3)(1/3,1/3,1/3)。

①.如果我们尝试为它设计二进制代码,有什么问题?

②.你能设计一个更好的代码吗?提示:如果我们尝试编码两个独立的观察结果会发生什么?如果我们联合编码n个观测值怎么办?

哈夫曼编码?

3.softmax是对上面介绍的映射的误称(虽然深度学习领域中很多人都使用这个名字)。真正的softmax被定义为 RealSoftMax(a,b)=log(exp(a)+exp(b)) 。

①.证明 RealSoftMax(a,b)>max(a,b) 。

②.证明 λ^(−1)RealSoftMax(λa,λb)>max(a,b) 成立,前提是 λ>0 。

③.证明对于 λ→∞ ,有 λ−1RealSoftMax(λa,λb)→max(a,b) 。

④.soft-min会是什么样子?

⑤.将其扩展到两个以上的数字。


设a \geq b(因为对称,所以证明一个另外一个也成立)

证RealSoftMax(a,b)>max(a,b)

即证:log(exp(a)+exp(b))>a

\because exp(b) > 0

\therefore log(exp(a)+exp(b)) > log(exp(a))=a

即log(exp(a)+exp(b))>a


设a \geq b(因为对称,所以证明一个另外一个也成立)

证λ^{-1} RealSoftMax(λa,λb)>max(a,b),(λ>0)

即证:λ^{-1}log(exp(λa)+exp(λb))>a

\because exp(λb) > 0

\therefore λ^{-1}log(exp(λa)+exp(λb)) > λ^{-1}log(exp(λa))=λ^{-1}λa=a

即λ^{-1} RealSoftMax(λa,λb)>max(a,b),(λ>0)


设a \geq b(因为对称,所以证明一个另外一个也成立)

证λ^{-1} RealSoftMax(λa,λb)\rightarrow max(a,b),(λ\rightarrow ∞)

即证:λ^{-1}log(exp(λa)+exp(λb))\rightarrow a,(λ\rightarrow ∞)

情况一:a>b
\because exp(λa) >> exp(λb)

\therefore λ^{-1}log(exp(λa)+exp(λb)) \rightarrow λ^{-1}log(exp(λa))=λ^{-1}λa=a

即λ^{-1} RealSoftMax(λa,λb)\rightarrow max(a,b)

情况二:a=b
λ^{-1}log(exp(λa)+exp(λb)) = λ^{-1}log(2exp(λa))=λ^{-1}log2+λ^{-1}λa=λ^{-1}log2+a

\because λ\rightarrow ∞,λ^{-1}\rightarrow 0

\therefore λ^{-1}log2+a \rightarrow a

即λ^{-1} RealSoftMax(λa,λb)\rightarrow max(a,b)

④softmin(x)=softmax(-x),参考torch.nn.functional.softmin()


RealSoftMax(x_1,x_2,...,x_n)=log(exp(x_1)+exp(x_2)+...+exp(x_n))

3.5 图像分类数据集

1.减少batch_size(如减少到1)是否会影响读取性能?

会使得读取变慢。

2.数据迭代器的性能非常重要。你认为当前的实现足够快吗?探索各种选择来改进它。

3.查阅框架的在线API文档。还有哪些其他数据集可用?

ImageNet,Qmnist,Kinetics-400...

3.6 softmax回归的从零开始实现

1.在本节中,我们直接实现了基于数学定义softmax运算的softmax函数。这可能会导致什么问题?提示:尝试计算 exp(50) 的大小。
如果网络参数初始化不恰当,或者输入有数值较大的噪音,基于数学定义的softmax运算可能造成溢出,因为分母要计算多个exp的值求和,解决方法可以参考log_softmax。

2.本节中的函数 cross_entropy 是根据交叉熵损失函数的定义实现的。这个实现可能有什么问题?提示:考虑对数的值域。
y^中若某行最大的值也接近0的话,loss的值也可能造成溢出,可以参考nllloss和log_softmax一起使用。

3.你可以想到什么解决方案来解决上述两个问题?
参考nllloss和log_softmax一起使用。

4.返回概率最大的标签总是一个好主意吗?例如,医疗诊断场景下你会这样做吗?
返回最大概率标签不总是个好主意,医疗诊断场景也有尽可能避免小概率事件的发生。

5.假设我们希望使用softmax回归来基于某些特征预测下一个单词。词汇量大可能会带来哪些问题?
词汇量大意味着class的类别很多,这容易带来两个问题。一是造成较大的计算压力,二是所有的单词所得概率容易很接近0,单词间概率差别不大,很难判断应该输出哪个结果。

3.7 softmax回归的简洁实现

1.尝试调整超参数,例如批量大小、迭代周期数和学习率,并查看结果。

2.增加迭代周期的数量。为什么测试精度会在一段时间后降低?我们怎么解决这个问题?

这可能是过拟合现象,可以通过L2正则化、dropout等方法解决。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容