上一节中我们实现了一个多层感知器神经网络用来处理图像分类问题。然而那个神经网络模型还是比较「稚嫩」,我们可以对其稍加修改,实现一定程度上的提升。
原本的神经网络结构如下:
mlp = nn.Sequential(
nn.Flatten(),
nn.Linear(28 * 28 * 1, 256),
nn.Sigmoid(),
nn.Linear(256, 10),
nn.Softmax(dim=1))
我们看到该神经网络中间有一个Sigmoid层,该层网络作为线性层Linear的激活函数,用在多层感知器内时会出现一个问题: 由于sigmoid函数会让输出数值落在0到1之间,因此其后的计算免不了乘上一个小于1的正数,这不利于数值在神经网络中进行传递。
为了处理sigmoid激活函数带来的问题,我们将引入一个新的激活函数relu。
ReLU激活函数
relu激活函数的数学公式如下:
$$ y = \begin{cases} x, & \text{if}\quad x > 0 \\ 0, & \text{if}\quad x \leq 0 \end{cases} $$
当输入数值大于0时relu输出数值本身,当输入数值不大于0时relu输出数值0。
修改神经网络
我们将原本的神经网络模型修改成如下结构:
mlp = nn.Sequential(
nn.Flatten(),
nn.Linear(28 * 28 * 1, 256),
nn.ReLU(inplace=True),
nn.Linear(256, 10),
nn.Softmax(dim=1))
使用nn.ReLU(inplace=True)
替代先前的nn.Sigmoid()
,参数设置inplace=True
会复用上一层网络的输出,通常来说有利于节省存储空间。
重新运行代码训练模型
我们在同之前一样的条件下重新训练这个新的多层感知器。
通过10轮的训练,我们的新模型在测试集上的表现如下:
testing...
loss=1.4900871847249284, accuracy=0.9725
其中损失率loss
为1.490087左右,准确率达到97.25%。
在训练过程中可以发现神经网络的拟合能力有了很大的改善,当模型训练到一半的时候就能达到先前的最终效果,而训练完毕后的模型在测试集上的准确率也有了明显提高。