神经网络算法实践
钟汉昌 19057011 2023年2月
第一部分 fashion_mnist数据集
在图像识别领域,有一个著名的手写数字数据集叫做mnist,随着研究的深入,一个算法可以在mnist数据集上表现好已经不稀奇了。由此,一家德国的时尚科技公司Zalando旗下的研究部门提供了fashion_minst,作为替代mnist的图像数据集。fashion_minst包含来自10种类别的共7万张不同商品的正面图片。
fashion_mnist数据集的大小、格式和训练集/测试集的划分与mnist数据集完全一致,都是60000/10000的训练集/测试集划分,28x28的灰度图片。因此,以mnist数据集为基础编写的算法,可以不改动任何代码,直接改用fashion_mnist测试算法性能。本代码通过keras包导入fashion_mnist数据集,并将训练集的前3张图片展示出来。
每个图像都是元素为0~255的整数值的28x28矩阵,每个图像都有一个相应的值为0~9的类别数据(蓝色)
第二部分 两层前馈神经网络模型
2.1 数据和模型准备工作
用于识别的两层前馈神经网络是把28x28的图像数据当作长度为784的向量处理。因此,要用代码把60000x28x28的数组转换为60000x28的数组。同时,要把输入值转换为0~1的float值,把输出值用keras包的函数转换为1-of-K(哑编码)表示法的编码。
以上完成了数据准备工作,接下来考虑核心的网络模型。
使用keras的Sequential(序贯模型)定义了model,并定义了中间层和输出层。
2.2 训练模型
(一)参数解释
verbose为日志显示参数,verbose=1为输出进度条记录(默认为1)。因此,以上代码运行后会显示每轮训练的评估值,并在最后显示根据测试数据评估的交叉熵误差(Test loss)、正确率(Test accuracy)和计算时间(Computation time)。
通常,每次更新时对误差函数的梯度计算都是以整个数据集为对象进行的,但如果数据量很大,计算就会非常花时间。在这种情况下,可以使用只根据部分数据计算误差函数梯度,即随机梯度法。一次更新使用的数据的大小叫作批大小(batch_size)。一般的梯度法即使碰到较浅的极小值,也会陷入泥潭无法脱身。而随机梯度法如果碰到较浅的极小值,依然有可能从容脱身。轮数(epochs)是决定训练的更新次数的参数。
(二)结果分析
结果显示,计算机大约4.09秒就计算完成了。输出信息表明模型对81.12%的测试数据回答正确,这个结果显然是不理想的。
不过在改善模型前,还需确认是否发生了过拟合(overfitting),即为了得到一致假设而使假设变得过度严格。可以理解成想要估计到每个点而使得拟合曲线拐来拐去。为了确认是否发生了过拟合,需要观察测试数据的误差随时间的变化情况。
由于测试数据的误差也是单调减小的,所以可以判断没有发生过拟合。正确率也顺利地提高了。
显示在右下角的数字是网络的输出。蓝色横线表示的是识别错误的数据
第三部分 改进后的模型——终极神经网络UNN
3.1 激活函数
以前人们常用Sigmoid函数作为激活函数,近年来ReLU(Rectified Linear Unit, 线性整流函数)作为激活函数非常受欢迎。2015年Yann LeCun、Yoshua Bengio和Geoffrey Hinton三人在《自然》杂志发表论文,其中将ReLU评为最好的激活函数。
将刚才网络中间层的激活函数换为ReLU并运行
正确率由使用Sigmoid时的81.12%提高到了83.99%。有大约2.87%的提升。
至此已经知道,简单的前馈网络模型的正确率约83%,离目标还比较遥远。那么如何使得正确率更上一层楼呢?增加中间层神经元是一个可行的方法,不过有更根本的问题需要解决。这个模型实际上忽视了输入是二维图像,根本没有使用二维空间信息。网络构造是全连接型 的,所有输入元素与不相邻的输入元素在数学式上完全平等。
3.2 空间过滤器
空间信息是直线、弯曲的曲线、圆形及四边形等表示形状的信息。可以使用被称为空间过滤器的图像处理方法来提炼这样的形状信息。移动图像,求出图像的一部分与过滤器元素的乘积之和,直至完成在整个图像上的计算,这样的计算称为卷积计算(convolution)
再次读取fashion_mnist数据,格式上做修改。
对训练数据应用检测纵边和横边的2个过滤器,实际上通过改变过滤器数值,还可以实现识别斜边、图像平滑化、识别细微部分等各种各样的处理。不过,上图中的过滤器的设计是所有元素之和为0。这样一来,没有任何空间构造的值全部相同的部分就会转换为0,而过滤器想要抽取的具有构造的部分会被转换为大于0的值,最终把0作为检测基准即可,非常方便。
原图白为0,黑为1,应用横向过滤器把横线下侧的值变为大值,应用纵向过滤器会把纵线左侧的值变为大值
然而,应用过滤器之后,输出图像的大小比原来小了一圈,这在有些场景下就不太方便。比如连续应用各种过滤器时,图像会越来越小。针对这个问题,可以通过填充(padding)来解决。填充是在应用过滤器之前,使用0等固定值在图像周围附加元素的方法。
除了填充之外,与过滤器有关的参数还有步长。之前过滤器都是错开1个间隔移动的,其实任意的间隔都可以,这个间隔被称为步长(stride)。步长越长,输出图像越小。当通过库使用卷积网络时,填充和步长值会被作为参数传入。
3.3 卷积神经网络
使用了过滤器的神经网络称为卷积神经网络(Convolution Neural Network,CNN)。
通过向过滤器嵌入不同的数值,可以进行各种图像处理,而CNN可以学习过滤器本身。先创建1个使用了8个过滤器的简单的CNN。对输入图像应用8个大小为3x3、填充为1、步长为1的过滤器。由于1个过滤器的输出为28x28的数组,所以全部输出合在一起是28x28x8的三维数组,把它展开为一维的长度为6272的数组,并与10个输出层神经元全连接。
向model中增加了卷积层Conv2D()。“8, (3,3)”的意思是使用了8个3x3过滤器。padding = 'same' 的意思是增加1个使输出大小不变的填充。input_shape = (28, 28, 1) 是输入图像大小,最后一个参数黑白图像为1,彩色图像为3。除此之外,还指定了偏置输入为默认值,每个过滤器被分配1个偏置变量。在训练开始前,过滤器的初始值是随机设置的,而偏置的初始值被设置为0。
卷积层的输出是四维的,其形式为“(小批量大小, 过滤器数量,输出图像的高度,输出图像的高度)”。在把这个数据作为输入传给之后的输出层(Dense层)之前,必须先将其转换为二维的形式“(小批量大小, 过滤器数量 x 输出图像的高度 x 输出图像的宽度)”。这个转换通过model.add(Flatten())进行。
卷积神经网络计算大约花费35.6秒,正确率居然达到了87.30%,与之前的两层ReLU网络的正确率83.10%相比,改善非常显著。
下面通过代码看一下经过学习的8个过滤器
能够比较明显地看出,第4个过滤器似乎识别了横线下侧的边,第6个过滤器似乎识别了横线上侧的边。这种能够自动学习得到过滤器的能力真让人着迷(amazing)。
3.4 池化
通过卷积层,我们得以利用二维图像拥有的特征,但是在图像识别的情况下,模型要尽量不受图像平移的影响,这一点很重要。假如输入是一个平移后的图像,即使只平移1个像素,各个数组也将完全改变。在人眼看来几乎完全相同的输入,网络却会识别为完全不同的结果。在使用CNN时也会碰到这个问题。解决这个问题的一种方法就是池化处理。
以2x2的最大池化(max pooling)举例。这种方法着眼于输入图像内的2x2的小区域,并输出区域内最大的数值。然后以步长2来平移小区域,重复同样的处理。最终输出图像的长和宽的大小将变为输入图像的一半。除了最大池化之外,还有平均池化(average pooling)的方法。这种方法中小区域的输出值是区域内数值的平均值。
3.5 Dropout
Nitish Srivastava,Geoffrey Hinton等人在发表的论文中提出了一种名为Dropout的改善网络学习的方法。在许多应用场景中,这个方法都带来了较好的效果。Dropout在训练时以概率p(p<1)随机选择输入层的单元和中间层的神经元,并使其他神经元无效。无效的神经元被当作不存在,然后在这样的状态下进行训练。为每个小批量重新选择神经元,重复这个过程。
训练完成后,在进行预测时使用全部的神经元。由于在训练时仅使用了以概率p选择的神经元,所以在预测时使用全部神经元会使输出变大(1/p)倍。为了更符合逻辑,需要将权重变小,因此在预测时,将应用了Dropout的层的输出的权重乘以p(由于p小于1,所以会变小)。DRopout方法会分别训练多个网络,并在预测时取多个网络的平均值,因此具有综合了多个网络的预测值的效果。
3.6 终极神经网络UNN
在卷积神经网络中引入池化和Dropout,并增加层数,构建一个具备各种特性的网络。首先,第1层和第2层是连续的卷积层。第1层卷积层使用了16个过滤器,那么输出就是16张26x26的图像(没有填充),可以看作26x26x16的三维数组的数据。下一层对这个三维数据进行卷积。1个3x3的过滤器实质上被定义3x3x16的数组,输出为24x24的二维数组(没有填充)。分别分配了16个不同的过滤器,在对它们分别进行处理后,将输出汇总。第2层卷积层有32个这样的大小为3x3x16的过滤器。因此,输出为24x24x32的三维数组。如果不算偏置,那么用于定义过滤器的参数数量为3x3x16x32。
经过第3层的2x2的最大池化层之后,图像大小缩小了一半,变为12x12。之后的第4层又是卷积层,该层的过滤器有64个,参数数量为3x3x32x64。在第5层再次进行最大池化之后,图像大小变为5x5。之后的第6层是神经元数量为128个的全连接层,最后的第7层是输出为10个的全连接层。第5层和第6层还引入了Dropout。
终极神经网络终于使得正确率达到了90%以上,来到了92.28%。这个终极神经网络是为了尝试所有技术而设计的,事实上应该还可以创建出更加简单且正确率更高的网络。不过,通过实验,也可看出在处理比fashion_mnist图像大小还要大的自然图像,以及必须处理多个类别时,层的深化、卷积、池化和Dropout等技术必定会发挥更强大的作用。