MNIST手写数字集在几乎所有的神经网络和深度学习的教程上都会被拿来作为入门级的例子,通过构建一个三层的BP神经网络,读者可以很容易地理解神经网络的机构和基本原理,同时因为该数据集中每个样本的很小(28×28),识别目标也很少(0~9),神经网络的训练速度非常快。在前面的文章中为大家介绍了用Numpy一步步构建BP神经网络的方法,通过这样一个过程可以让读者对BP网络的原理有深刻的认识,但是需要编写的代码量较大,当我们在进行深度学习时,神经网络层数逐渐增多,网络结构也会越来越复杂,用Numpy手动实现一个神经网络的难度非常大,因此使用一个成熟的深度学习框架非常必要。
Keras+TensorFlow是最适合入门的深度学习框架,使用Keras提供的API,用户可以把全部注意力放在网络结构的设计上,不需要关心层与层之间数据的复杂计算,让用户专注于深度学习本身,而不是计算等细枝末节。想要用Numpy编写完整的BP神经网络,你必须对前向传播和反向传播的过程非常熟悉,并掌握必要的高等数学知识,即使一个最简单的BP神经网络,代码量也会高达78行,对深度学习的初学者来说,门槛还是比较高的。
使用Keras+TensorFlow的深度学习框架,构建神经网络就像搭积木一样简单。每层网络就像是积木里的模块,你只需为每层网络设置好神经元的数量,选择合适的激活函数即可。本文在Jupyter notebook中使用Keras完整实现一个简单神经网络,并用它完成在样本集上的训练和测试集的检测。整个过程可以分为以下几个步骤:
数据集的加载和预处理
我们使用的MNIST数据集已内置到Keras中,首次使用会自动下载,大小约为11M,如果下载速度过慢请将Anaconda3的更新源设置为清华镜像源,具体步骤请自行百度。数据集包含训练数据和测试数据两部分,两者都是由图像和标签两部分组成。每条数据都是一张28×28的灰度图像,为方便计算,我们需要将二维的图像转换为一维的数组。长度为784的一维数组中的每一个数字都在0~255的范围内,为了使参数收敛,我们还需要将这些数字的范围缩小到0~1之间。
标签的准备
训练样本集中样本的数量为6000,标签为长度为6000的一维数组。每一个样本都是一个长度为784的一维数组,经过各个层的运算,最后输出一个长度为10的一维数组,数组中每一个数字的取值范围都在0~1之间,表示该样本是对应数字的概率。因此我们需要对标签进行向量化,将长度为6000的一维标签数组扩充为6000×10的矩阵。标签向量化的方法有两种,本文使用Keras内置的to_categorical( )函数。
神经网络的构建
神经网络的输入是长度为784的数组,输出是长度为10的数组,我们可以设计一个包含3个全连接层(Dense)的网络结构,前两层是隐藏层,神经元个数都是512,激活函数使用ReLU,最后一层为输出层,神经元个数为10,激活函数使用softmax。为了降低过拟合,可以在不同的层之间添加dropout正则化。以下是神经网络的构建代码,是不是非常简洁易懂?
整个构建过程就像是搭积木,我们将各层线性堆叠在一起,不用关心数据在各层之间是如何传递计算的,因为Keras已经为我们实现了这一切。使用model.summary()函数可以打印出神经网络的概略信息,包括每一层的类型、输出形状、参数数量。
网络的编译、训练和测试
与构建的过程类似,编译、训练和测试都可以通过调用Keras的内置函数来实现,我们需要做的就是根据需要选择损失函数、优化器、迭代次数、每批样本个数等参数。
代码运行结果如下图所示,经过20次迭代,神经网络的准确率达到了98.16%。使用GTX 1060显卡,每次迭代的计算时间约为1秒,而如果使用CPU(i5 8500),每次迭代的计算时间约为8秒,GPU在深度学习上的速度优势非常明显。
总结
本文是对前文搭建的Win10+Python3.7+Keras+CUDA10.1深度学习开发环境的验证,因此对一些重要概念(如dropout正则化、优化器等等)一带而过,这些内容将在后续的文章中详细介绍。文中代码已上传到网盘,获取下载方式请在下方留言。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.