1.1 激活函数

激活函数(activation function)通过计算加权和并加上偏置来确定神经元是否应该被激活, 它们将输入信号转换为输出的可微运算。 大多数激活函数都是非线性的。 由于激活函数是深度学习的基础,下面简要介绍一些常见的激活函数。

最受欢迎的激活函数是修正线性单元(Rectified linear unit,ReLU), 因为它实现简单,同时在各种预测任务中表现良好。 ReLU提供了一种非常简单的非线性变换。 给定元素x,ReLU函数被定义为该元素与0的最大值:

435e8ecf618a49019e7b7867aef793ae.png

通俗地说,ReLU函数通过将相应的活性值设为0,仅保留正元素并丢弃所有负元素。 为了直观感受一下,我们可以画出函数的曲线图。 正如从图中所看到,激活函数是分段线性的。

当输入为负时,ReLU函数的导数为0,而当输入为正时,ReLU函数的导数为1。 注意,当输入值精确等于0时,ReLU函数不可导。 在此时,我们默认使用左侧的导数,即当输入为0时导数为0。 我们可以忽略这种情况,因为输入可能永远都不会是0。

4bf6e9fea9704acb8c14bd947991b9c8.png

结果:

49796aac01194ebe8914429c6e0a2379.png

66774a9eda974297b2502589847bd185.png

使用ReLU的原因是,它求导表现得特别好:要么让参数消失,要么让参数通过。 这使得优化表现得更好,并且ReLU减轻了困扰以往神经网络的梯度消失问题。

对于一个定义域在R中的输入, sigmoid函数将输入变换为区间(0, 1)上的输出。 因此,sigmoid通常称为挤压函数(squashing function): 它将范围(-inf, inf)中的任意输入压缩到区间(0, 1)中的某个值:

ff169ff337fe4713aef0360b00761474.png

sigmoid函数的导数为下面的公式:

4ffbeaf3b0cf45cfb55a6ae44cdfc7a8.png

下面,我们绘制sigmoid函数及其倒数图像。 注意,当输入接近0时,sigmoid函数接近线性变换。sigmoid函数的导数达到最大值0.25; 而输入在任一方向上越远离0点时,导数越接近0。

eb07200687854ecc95d90514c0b020a0.png

结果:

cee0063142c14e638815512ab83f9d83.png

71a1f0df748749168fbfb52b61fc225e.png

与sigmoid函数类似, tanh(双曲正切)函数也能将其输入压缩转换到区间(-1, 1)上。 tanh函数的公式如下:

903589b07d7042bf8fc616b1601af8ed.png

tanh函数的导数是:

c7db920a53c94a5a9cef4b63ab1b9897.png

下面我们绘制tanh函数及其导数的图像。 注意,当输入在0附近时,tanh函数接近线性变换。 函数的形状类似于sigmoid函数, 不同的是tanh函数关于坐标系原点中心对称。当输入接近0时,tanh函数的导数接近最大值1。 与我们在sigmoid函数图像中看到的类似, 输入在任一方向上越远离0点,导数越接近0。

6da324ce91604572a5e5e3570d7c7c36.png

结果:

c9e33eb398704b3e91b5de973e2d2035.png

c8c7e2d928b24b94a7cb0a1a795f9db0.png

1.2 多层感知机从零开始实现

现在让我们尝试自己实现一个多层感知机。 为了与之前softmax回归获得的结果进行比较, 我们将继续使用Fashion-MNIST图像分类数据集

首先导入所需的包和库:

f9b75c484cba4fe696b8ac4a6f524e27.png

继续使用之前的Fashion-MNIST图像分类数据集:

c84f562aaeab4a1d808e79d3e0a56078.png

bf4d6900b8bb4f428d15d81124a008c4.png

cca279047b8a446d8f54b2030d9d34c0.png

a47cf0d4e31b40a892b6766d7f0a9349.png

0b141d3aa49444ec94382a453c2c7c91.png

Fashion-MNIST中的每个图像由 28×28=784个灰度像素值组成。 所有图像共分为10个类别。 忽略像素之间的空间结构, 我们可以将每个图像视为具有784个输入特征 和10个类的简单分类数据集。 首先,我们将实现一个具有单隐藏层的多层感知机, 它包含256个隐藏单元。 注意,我们可以将这两个变量都视为超参数。 通常,我们选择2的若干次幂作为层的宽度。 因为内存在硬件中的分配和寻址方式,这么做往往可以在计算上更高效。

我们用几个张量来表示我们的参数。 注意,对于每一层我们都要记录一个权重矩阵和一个偏置向量。 跟以前一样,我们要为损失关于这些参数的梯度分配内存。

90e171641dfc4268a91264555ce8ca27.png

为了确保我们对模型的细节了如指掌, 我们将实现ReLU激活函数, 而不是直接调用内置的relu函数。

3aa776ccf1124acb9e14a8b3d334b2b4.png

因为我们忽略了空间结构, 所以我们使用reshape将每个二维图像转换为一个长度为num_inputs的向量。 只需几行代码就可以实现我们的模型。

11ebc451438948ecb1693c0d2e38903b.png

 

由于我们已经从零实现过softmax函数,因此在这里我们直接使用高级API中的内置函数来计算softmax和交叉熵损失。

83b3225c225f4da1b353311a50fb719b.png

幸运的是,多层感知机的训练过程与softmax回归的训练过程完全相同。 可以直接调用d2l包的train_ch3函数,将迭代周期数设置为10,并将学习率设置为0.1.

1f50257b8ba64a69a21b1221c21cbd22.png

结果:

bd0ce0c3d2f348bea2ae08bbe4a1b7a8.png

为了对学习到的模型进行评估,我们将在一些测试数据上应用这个模型。

79b4980ab91143aabc507fa9ed6256c7.png

结果:

8bbbd3b3aa634a54984bdd4195ab3b34.png

1.3 模型选择、欠拟合和过拟合

在机器学习中,我们通常在评估几个候选模型后选择最终的模型。 这个过程叫做模型选择。 有时,需要进行比较的模型在本质上是完全不同的(比如,决策树与线性模型)。 又有时,我们需要比较不同的超参数设置下的同一类模型。

当我们比较训练和验证误差时,我们要注意两种常见的情况。 首先,我们要注意这样的情况:训练误差和验证误差都很严重, 但它们之间仅有一点差距。 如果模型不能降低训练误差,这可能意味着模型过于简单(即表达能力不足), 无法捕获试图学习的模式。 此外,由于我们的训练和验证误差之间的泛化误差很小, 我们有理由相信可以用一个更复杂的模型降低训练误差。 这种现象被称为欠拟合(underfitting)。

另一方面,当我们的训练误差明显低于验证误差时要小心, 这表明严重的过拟合(overfitting)。 注意,过拟合并不总是一件坏事。 特别是在深度学习领域,众所周知, 最好的预测模型在训练数据上的表现往往比在保留(验证)数据上好得多。 最终,我们通常更关心验证误差,而不是训练误差和验证误差之间的差距。

我们现在可以通过多项式拟合来探索这些概念。给定x,我们将使用以下三阶多项式来生成训练和测试数据的标签:

3139634cfd994e478409ef5432e888f0.png

噪声项eq?%5Cepsilon服从均值为0且标准差为0.1的正态分布。 我们将为训练集和测试集各生成100个样本。

同样,存储在poly_features中的单项式由gamma函数重新缩放, 其中Γ(n)=(n−1)!。 从生成的数据集中查看一下前2个样本, 第一个值是与偏置相对应的常量特征。

6def73099bde4c96bbd4e393d843b5cb.png

432a16b8e1674c10be2f31c786ee809b.png

结果:

7708e715d9d64f1d88d5100606fbc266.png

让我们实现一个函数来评估模型在给定数据集上的损失。

c662002745114232b6c690e67674de5f.png

现在定义训练函数。

49e778237732476ea071fd6e05500e05.png

我们将首先使用三阶多项式函数,它与数据生成函数的阶数相同。 结果表明,该模型能有效降低训练损失和测试损失。 学习到的模型参数也接近真实值w=[5,1.2,−3.4,5.6]。

1356011cb355419c85c90b7c15b88fc5.png

结果:

6b67b4517e2341f8bb442376506bf8e4.png

c2d91e25e266494490cce761f0b5d444.png

让我们再看看线性函数拟合,减少该模型的训练损失相对困难。 在最后一个迭代周期完成后,训练损失仍然很高。 当用来拟合非线性模式(如这里的三阶多项式函数)时,线性模型容易欠拟合。

a9b1019495684607bdb9cd2583d26294.png

结果:

452c9f83d9234d0ba278db46e21aa981.png

049bb97914334174a374c02e090db012.png

现在,让我们尝试使用一个阶数过高的多项式来训练模型。 在这种情况下,没有足够的数据用于学到高阶系数应该具有接近于零的值。 因此,这个过于复杂的模型会轻易受到训练数据中噪声的影响。 虽然训练损失可以有效地降低,但测试损失仍然很高。 结果表明,复杂模型对数据造成了过拟合。

de815055a7724a18bd28070923b15419.png

结果:

1be959a5c80245a2aad48b1d46e7c1af.png

f3b0bf42e3ae446f80de6fe8f77aeee3.png

 

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐