《动手学》打卡挑战-task01

简介

ElitesAI·动手学深度学习PyTorch版
《动手学深度学习PyTorch版》在线书籍
本部分为Task01:线性回归Softmax与分类模型多层感知机,在深度学习当中比较基础的几个小知识点,下面分开来讲述。

线性回归

什么是线性回归?举个例子,给你多栋房屋的真实出售价格和它们对应的面积和房龄,你通过一个数学公式来表示它们的关系,不需要考虑太多,会先给出一个数学公式:

如果你脑子里第一反应是给出这个公式,那么恭喜你,是个可造之材, 线性回归表示着输出和各个输入之间是线性关系。 接下来就是第二问,这个数学公式中的未知数的数值怎么来?从深度学习方面来说,我们需要做到以下方面:

1
收集数据->模型建立->训练模型->数据预测->模型评估

数据集的概念

以房屋数据集为例,该数据集被称为训练数据集(training data set)训练集(training set),一栋房屋被称为一个样本(sample),其真实售出价格叫作标签(label),用来预测标签的两个因素叫作特征(feature)特征用来表征样本的特点。

优化函数-随机梯度下降

当模型和损失函数形式较为简单时,其误差最小化问题的解可以直接用公式表达出来。这类解叫作解析解(analytical solution)。然而,大多数深度学习模型并没有解析解,只能通过优化算法有限次迭代模型参数来尽可能降低损失函数的值。这类解叫作数值解(numerical solution)

在求数值解的优化算法中,`小批量随机梯度下降(mini-batch stochastic gradient descent)在深度学习中被广泛使用。它的算法很简单:先选取一组模型参数的初始值,如随机选取;接下来对参数进行多次迭代,使每次迭代都可能降低损失函数的值。在每次迭代中,先随机均匀采样一个由固定数目训练数据样本所组成的小批量(mini-batch)$\mathcal{B}$,然后求小批量中数据样本的平均损失有关模型参数的导数(梯度),最后用此结果与预先设定的一个正数的乘积作为模型参数在本次迭代的减小量。

学习率: $\eta$代表在每次优化中,能够学习的步长的大小
批量大小: $\mathcal{B}$是小批量计算中的批量大小batch size

总结一下,优化函数的有以下两个步骤:

  • (i)初始化模型参数,一般来说使用随机初始化;
  • (ii)我们在数据上迭代多次,通过在负梯度方向移动参数来更新每个参数。

PyTorch代码

softmax和分类模型

上面提到,线性回归是基于连续的输出,如果我们要的输出不是连续的,而是离散的呢?就像是要输出0或者1,这种离散的值呢?一个简单的办法是将输出值$o_i$当作预测类别是$i$的置信度,并将值最大的输出所对应的类作为预测输出,即输出 $\underset{i}{\arg\max} o_i$。例如,如果$o_1,o_2,o_3$分别为$0.1,10,0.1$,由于$o_2$最大,那么预测类别为2,其代表猫。
但是直接使用输出层的输出有两个问题:

1. 一方面,由于输出层的输出值的范围不确定,我们难以直观上判断这些值的意义。例如,刚才举的例子中的输出值10表示“很置信”图像类别为猫,因为该输出值是其他两类的输出值的100倍。但如果$o_1=o_3=10^3$,那么输出值10却又表示图像类别为猫的概率很低。
2. 另一方面,由于真实标签是离散值,这些离散值与不确定范围的输出值之间的误差难以衡量。

softmax运算符(softmax operator)解决了以上两个问题。它通过下式将输出值变换成值为正且和为1的概率分布:

其中

因此,分类模型在回归模型的基础上,添加了softmax运算符,使之回归模型成为了分类模型,但值得注意的是,在损失函数当中,其损失值的计算是拿标签值与softmax之后的值进行计算,例如有猫、狗两个种类,我们预测出来的猫和狗的概率分别为0.3、0.7,而实际上的标签是猫,即:猫的概率为,狗的概率为0.因此其交叉熵损失函数(cross entropy)的值为$\frac{(1-0.3)^2}{2}=0.245$

交叉熵损失函数

对于样本$i$,我们构造向量$\boldsymbol{y}^{(i)}\in \mathbb{R}^{q}$ ,使其第$y^{(i)}$(样本$i$类别的离散数值)个元素为1,其余为0。这样我们的训练目标可以设为使预测概率分布$\boldsymbol{\hat y}^{(i)}$尽可能接近真实的标签概率分布$\boldsymbol{y}^{(i)}$。

  • 平方损失估计

然而,想要预测分类结果正确,我们其实并不需要预测概率完全等于标签概率。例如,在图像分类的例子里,如果$y^{(i)}=3$,那么我们只需要$\hat{y}^{(i)}_3$比其他两个预测值$\hat{y}^{(i)}_1$和$\hat{y}^{(i)}_2$大就行了。即使$\hat{y}^{(i)}_3$值为0.6,不管其他两个预测值为多少,类别预测均正确。而平方损失则过于严格,例如$\hat y^{(i)}_1=\hat y^{(i)}_2=0.2$比$\hat y^{(i)}_1=0, \hat y^{(i)}_2=0.4$的损失要小很多,虽然两者都有同样正确的分类预测结果。

改善上述问题的一个方法是使用更适合衡量两个概率分布差异的测量函数。其中,交叉熵(cross entropy)是一个常用的衡量方法:

其中带下标的$y_j^{(i)}$是向量$\boldsymbol y^{(i)}$中非0即1的元素,需要注意将它与样本$i$类别的离散数值,即不带下标的$y^{(i)}$区分。在上式中,我们知道向量$\boldsymbol y^{(i)}$中只有第$y^{(i)}$个元素$y^{(i)}{y^{(i)}}$为1,其余全为0,于是$H(\boldsymbol y^{(i)}, \boldsymbol {\hat y}^{(i)}) = -\log \hat y_{y^{(i)}}^{(i)}$。也就是说,交叉熵只关心对正确类别的预测概率,因为只要其值足够大,就可以确保分类结果正确。当然,遇到一个样本有多个标签时,例如图像里含有不止一个物体时,我们并不能做这一步简化。但即便对于这种情况,交叉熵同样只关心对图像中出现的物体类别的预测概率。

假设训练数据集的样本数为$n$,交叉熵损失函数定义为

其中$\boldsymbol{\Theta}$代表模型参数。同样地,如果每个样本只有一个标签,那么交叉熵损失可以简写成$\ell(\boldsymbol{\Theta}) = -(1/n) \sum_{i=1}^n \log \hat y_{y^{(i)}}^{(i)}$。从另一个角度来看,我们知道最小化$\ell(\boldsymbol{\Theta})$等价于最大化$\exp(-n\ell(\boldsymbol{\Theta}))=\prod_{i=1}^n \hat y_{y^{(i)}}^{(i)}$,即最小化交叉熵损失函数等价于最大化训练数据集所有标签类别的联合预测概率。

PyTorch代码

多层感知机

多层感知机就是含有至少一个隐藏层的由全连接层组成的神经网络,且每个隐藏层的输出通过激活函数进行变换。多层感知机的层数和各隐藏层中隐藏单元个数都是超参数。以单隐藏层为例并沿用本节之前定义的符号,多层感知机按以下方式计算输出:

其中$\phi$表示激活函数。

关于激活函数的选择

ReLu函数是一个通用的激活函数,目前在大多数情况下使用。但是,ReLU函数只能在隐藏层中使用。
用于分类器时,sigmoid函数及其组合通常效果更好。由于梯度消失问题,有时要避免使用sigmoid和tanh函数。
在神经网络层数较多的时候,最好使用ReLu函数,ReLu函数比较简单计算量少,而sigmoid和tanh函数计算量大很多。
在选择激活函数的时候可以先选用ReLu函数如果效果不理想可以尝试其他激活函数。

PyTorch代码

0%