be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端CUDA的卷积神经网络算法实现

Nightfall

发布日期: 2018-11-18 10:04:48 浏览量: 1056
评分:
star star star star star star star star star star
*转载请注明来自write-bug.com

摘 要

卷积神经网络是近年来人工智能领域取得重大突破的一种重要手段,给出了图像识别、语音识别和自然语言处理领域中关键问题的优化解决方案,尤其适合处理图像方面的任务,如人脸识别和手写体识别。手写数字识别是用卷积神经网络解决的经典问题,采用一般方法训练出来的神经网络达到了97%的识别率,几乎与人类的识别精度一致,但在执行速度上没有人类识别得快。在实际商业应用中不可避免地会遇到数据量过大的问题,如在手写数字识别中有60000条规格为28*28单位像素的训练样本需要训练,这样会导致执行速度较慢,CPU在处理这样包含大量高精度浮点数的任务时,其消耗的时间是不可接受的,在训练期要花费数小时的时间。

针对上述问题,该文将构建be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端CUDA架构的编程环境,采用CUDA/C++编程实现卷积神经网络算法,将卷积神经网络算法应用于手写数字识别问题中,在选择合适的网络模型和相关参数的情况下,利用GPU的高度并发性能,提高卷积神经网络训练数据的速度。通过对GPU实现和CPU实现进行对比实验,验证对卷积神经网络算法进行CUDA并行化训练和识别是可行有效的,实验表明在普通PC机上采用GPU实现的卷积神经网络算法比CPU实现的卷积神经网络算法虽然在准确率上仅提升了0.29%,但在速度上加快了15%。

关键词:CUDA,卷积神经网络,深度学习,并行计算

ABSTRACT

Convolutional neural network is a major breakthrough in the field of artificial intelligence in recent years, an important means of image recognition given to optimize speech recognition and natural language processing solutions, especially for process images tasks, such as human face recognition and handwriting recognition. Handwritten numeral recognition is a classic problem with the convolutional neural network to solve, using the general method of trained neural network reaches 97% recognition rate, with almost the same human recognition accuracy, but the speed of execution without human recognition quickly. In practical commercial applications will inevitably encounter the problem of data overload, as there are 60,000 training sample size is 28 * 28 pixel units need to be trained in digital handwriting recognition, this will result in slower performance, CPU in when processing tasks such contains a lot of high-precision floating-point number, the elapsed time is unacceptable, in the training period to spend a few hours.

To solve these problems, this paper will build a CUDA architecture-based programming environment using CUDA / C ++ programming to implement the convolution neural network algorithm. The convolution neural network algorithm is applied to handwritten numeral recognition problem. After selecting an appropriate network model and related parameters, the use of highly concurrent GPU performance,convolution neural network training to improve the speed of data. Then use the model to achieve the GPU and CPU to complete some comparative tests to verify the fact that using the CUDA to parallel implementing convolution neural network algorithm for training and recognition is feasible and effective,experiments show that on the common PC the neural network algorithm convolution convolution neural network algorithm to achieve GPU than CPU implementations on the speed by 15%, on the accuracy improved 0.29%.

Key words:CUDA, CNN, Deep Learning, Parallel Computing

1 绪论

1.1 深度学习的发展和现状

深度学习(Deep Learning)从2006年Hinton在Science上的论文算起,深度学习发展至今才十年。在这短短几年时间里,深度学习颠覆了语音识别、图像分类、文本理解等众多领域的算法设计思路,渐渐形成了一种从训练数据出发,经过一个端到端(end-to-end)的模型,然后直接输出得到最终结果的一种新模式。这不仅让一切变得更加简单,而且由于深度学习中的每一层都可以为了最终的任务来调整自己,最终实现各层之间的通力合作,因而可以大大提高任务的准确度。随着大数据时代的到来以及GPU等各种更加强大的计算设备的发展,深度学习如虎添翼,可以充分利用各种海量数据(标注数据、弱标注数据或者仅仅数据本身),完全自动地学习到抽象的知识表达,即把原始数据浓缩成某种知识。当然,深度学习不见得是最完美的框架,离最终所谓的智能也还差得很远,而且目前还基本没有理论上的有效性解释。但是无论如何,深度学习之风已经势不可挡。

深度学习本质上其实就是多层神经网络,而神经网络在几十年前大家就开始研究了。神经网络的一层,其实就是一个线性变换加上一个简单的非线性操作,而多层神经网络其实就是多个简单的非线性函数的复合。一层、两层的网络用途比较有限,往往很难刻画输入与输出之间的复杂关系。但是深层的网络,历史上又一直无法进行有效训练。

卷积神经网络在当前的图像识别语音分析领域成为热点,这主要源于卷积神经网络多层次的处理和生物神经网络相似,权值共享等特性减少了网络训练中的参数。深度学习的经典模型卷积神经网络(CNN)其实在上世纪八九十年代就出现了,而且其中LeNet-5模型在简单的手写体识别问题上已经取得了很大的成功。但是当时的计算能力无法支持更大规模的网络,而LeNet-5在复杂物体识别上的表现也并不好。这主要是因为:深层网络由于是高度非线性的,有着太多的局部极值,很难保证能够得到一个可以接受的好的解;优化策略的核心就是梯度下降法,但对于一个深层的网络,它的函数的梯度也非常复杂,于是,误差反向传播算法就经常在参数初始值选择不当的时候产生梯度消失或者梯度爆炸现象,导致优化无法正常进行;数据集过小,对于训练一个深层的网络来说,往往会造成过拟合的问题;计算能力的限制,对于数量众多的参数训练,往往要花费几个月的时间。直到2012年的ImageNet比赛中,Hinton和他的学生Alex等人参赛,把准确率提高到84.7%。当然,他们的成功借助了ImageNet这个足够大的数据集,借助了GPU的强大计算能力,借助了比较深层的CNN网络,借助了随机梯度下降(SGD)和Dropout等优化技巧,借助了训练数据扩充策略(Data Augmentation)。但无论如何,他们靠着深度学习震惊了机器学习领域,从此大量的研究人员开始进入这个领域,一发不可收拾。2013年是89%,2014年是93.4%,截止到2015年5月份,ImageNet数据集的精度已经达到了95%以上,某种程度上跟人的分辨能力相当了。

深度学习在很多学术领域,比非深度学习算法往往有20-30%成绩的提高。很多大公司也逐渐开始出手投资这种算法,并成立自己的深度学习团队,其中投入最大的就是谷歌,2008年6月披露了谷歌脑项目。2014年1月谷歌收购DeepMind,然后2016年3月其开发的Alphago算法在围棋挑战赛中,战胜了韩国九段棋手李世石,证明深度学习设计出的算法可以战胜这个世界上最强的选手。

在硬件方面,Nvidia最开始做显示芯片,但从2006及2007年开始主推用GPU芯片进行通用计算,它特别适合深度学习中大量简单重复的计算量。目前很多人选择Nvidia的CUDA工具包进行深度学习软件的开发。微软从2012年开始,利用深度学习进行机器翻译和中文语音合成工作,其人工智能小娜背后就是一套自然语言处理和语音识别的数据算法。百度在2013年宣布成立百度研究院,其中最重要的就是百度深度学习研究所。Facebook和Twitter也都各自进行了深度学习研究,其中前者携手纽约大学教授Yann Lecun,建立了自己的深度学习算法实验室;2015年10月,Facebook宣布开源其深度学习算法框架,即Torch框架。Twitter在2014年7月收购了Madbits,为用户提供高精度的图像检索服务。

工业与学术界的数据科学家已将GPU用于机器学习以便在各种应用上实现开创性的改进,这些应用包括图像分类、视频分析、语音识别以及自然语言处理等等。尤其是深度学习,人们在这一领域中一直进行大力投资和研究。深度学习是利用复杂的多级深度神经网络来打造一些系统,这些系统能够从海量的未标记训练数据中进行特征检测。

虽然机器学习已经有数十年的历史,但是两个较为新近的趋势促进了机器学习的广泛应用: 海量训练数据的出现以及GPU 计算所提供的强大而高效的并行计算。人们利用 GPU 来训练这些深度神经网络,所使用的训练集大得多,所耗费的时间大幅缩短,占用的数据中心基础设施也少得多。GPU还被用于运行这些机器学习训练模型,以便在云端进行分类和预测,从而在耗费功率更低、占用基础设施更少的情况下能够支持远比从前更大的数据量和吞吐量。

将 GPU 加速器用于机器学习的早期用户包括诸多规模的网络和社交媒体公司,另外还有数据科学和机器学习领域中一流的研究机构。与单纯使用 CPU 的做法相比,GPU 具有数以千计的计算核心、可实现10-100倍应用吞吐量,因此GPU 已经成为数据科学家处理大数据的处理器。

1.2 研究意义

在球技术突飞猛进,人们在日常生活中获取信息越来越方便,同时也产生出了海量的数据信息。在这样的大背景下,人们利用计算机对我们现有的数据通过一些处理得到一定的规律,处理之后我们可以利用学到的规律能够得到数据背后有意义的东西,不仅仅是眼前所见的数据,而是数据包含的真正的意义,这一过程就被称为机器学习。其主要用途就是通过对提供数据的处理,然后找到这个数据的分类,或是对数据进行回归,进行数值的预测。

生活中随处可见机器学习的用途:搜索引擎对搜索结果的排序问题,人们使用搜索人们使用搜索引擎的时候,搜索引擎会记录下人们的搜索习惯,以及人们在搜索结果中点击的内容,经过长时间的累积,搜索引擎就会根据你的日常运用搜索引擎的习惯猜测你所从事的行业,根据这些内容重新排序搜索的结果,将适合你的搜索结果推送给你,这就用到了机器学习; 生活中这样的应用有人脸识别、手写识别、垃圾邮件过滤、购买商品推荐、购买行为预测等等,因此,机器学习对于对于科学来说具有重要意义,是人们必不可少的,对机器学习的研究有深远的意义。

卷积神经网络是目前机器学习领域的热点,因为其网络结构与视觉神经系统中的感受野相似,因此尤为适合处理图像方面的任务。虽然卷积神经网络在准确度等方面有着不错的表现,但在实际运用时不可避免会遇到输入数据量过大,网络层数过大,导致运算速度慢的问题,即使是当前最先进的CPU,其消耗的时间也都是不可接受的。近几年GPU通用并行技术得到了飞速的发展,因为其计算核心的数量远远多于CPU,在高度并行的计算问题上,GPU的计算效率要远高于CPU。CUDA是由英伟达公司推出的GPU通用并行计算平台,不仅提供了一系列API使得开发人员能够绕过GPU的图形API来直接访问GPU的硬件,还提供了一个C语言编译器,使得开发人员能够使用C语言来进行快速的开发。be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端CUDA的代码就可以运行在GPU上,使得卷积神经网络算法在GPU上的开发成为可能。

对于深度学习来说,在输入的数量较大时,运行速度慢。堆砌硬件的方式是有尽头的,出路只有软件方式。GPU的主频没有CPU快,但擅长浮点线性代数处理。需要研究CPU和GPU怎么配合,才能尽可能地提高神经网络的训练速度。

本文将实现be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端CUDA的卷积神经网络算法,加快网络的训练和识别速度,这在现阶段互联网飞速发展,需要处理海量数据的情况下具有重要的意义。

2 人工神经网络和卷积神经网络的结构及算法

2.1 人工神经网络

2.1.1 神经元

感知器在20世纪五、六十年代由科学家Frank Rosenblatt发明,其主要be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端生物学神经系统中神经元的工作原理。人工神经元(Neuron)是构成人工神经网络的基本单元。人工神经元和感知器非常类似,它模拟生物神经元的特性,接受一组输入信号并产生输出。生物神经元有一个阈值,当神经元所获得的输入信号的积累效果超过阈值时,它就处于兴奋状态;否则,处理抑制状态。

人工神经元使用一个非线性的激活函数,输出一个活性值。假定神经元接受n个输入x=(x1,x2,…,xn),用状态z表示一个神经元所获得的输入信号x的加权和,输出为该神经元的活性值a。具体定义如下:

其中,w是n维的权重向量,b是偏置。典型的激活函数有sigmoid型函数、tanh型函数、relu型函数等。

2.1.2 多层前馈网络

前馈神经网络是最早发明的简单人工神经网络。所谓神经网络是指将多个单一神经元连接在一起,将一个神经元的输出作为下一个神经元的输入。包含多个隐藏层的神经网络。如图2-1所示。

使用下面的记号描述网络:

前馈神经网络通过下面公式进行信息传播。将参数矩阵化,使用矩阵-向量运算方式,就可利用线性代数的优势将神经网络快速求解。

2.1.3 BP算法

机器学习中模型预测结果与实际标签的差距的方程叫做代价函数(cost function)。 机器学习训练的目的是找到一系列的参数,使得对于全部训练数据与类别,代价函数的值最小。就手写数字识别来说,对于训练数据有60000的模型,训练目的是使得所有60000条数据的预测与实际差距最小。

对于有一个带标签的固定样本集

共n个样例。可以使用批量梯度下降的方法等优化方法训练神经网络。具体来讲,对于单个样例(x,y),它的代价函数如下:

这是一个方差代价函数。给定一个包含m个样例的数据集,可以定义整体代价函数为:

以上公式中的第一项是一个均方差项。第二项是一个规则化项(也叫权重衰减项),其目的是减少权重的幅度,防止过度拟合现象的发生。自觉地看,规范化的效果是让网络倾向于学习小一点的权重。大的权重只有能够给出代价函数第一项足够的提升时才能允许,换言之,规范化可以当做寻找小的权重和最小化原始的代价函数之间的折中。权重衰减参数用于控制公式中前后两项的相对重要性。

如果使用梯度下降算法来最小化代价函数C(w, b)可以使用下面的方法更新参数:

其中a是学习速率,以上公式中最主要的运算步骤是求解代价函数的偏导数。反向传播算法是一种有效的计算偏导数的方法。

反向传播其实对权重和偏置变化影响代价函数过程的理解。最终级的含义其实就是计算偏导数

为了计算这些值,首先引入一个中间量

表示为第l层第i个神经元上的误差。反向传播将给出计算神经元上误差的流程,然后将其关联到权重和偏置的梯度上。

1.输出层误差的方程

2.使用下一层的误差来表示当前层的误差

3.代价函数关于网络中任意偏置的改变率

4.代价函数关于任何一个权重的改变率

反向传播方程给出了一种计算代价函数梯度的方法。显式地用算法描述为

2.2 卷积神经网络

卷积神经网络(ConvolutionalNeural Networks,CNN)是一种前馈神经网络,是受生物学上的感受野的机制而提出的。在视觉神经系统中,一个神经元的感受野是指视网膜上的特定区域,只有这个区域内的刺激才能够激活该神经元。卷积神经网络在图像处理领域取得了很大的成功,在国际标准的ImageNet数据集上,许多成功的模型都是be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端CNN的。CNN相较于传统的图像处理算法的优点之一在于,避免了对图像复杂的前期预处理过程(提取人工特征等),可以直接输入原始图像。

传统的神经网络都是采用全连接的方式,即输入层到隐藏层的神经元都是全部连接的,这样做将导致参数量巨大,使得网络训练耗时甚至难以训练,而CNN则通过局部连接、权值共享等方法避免这一困难。

2.2.1 局部连接与权值共享

如图2-2所示,左边是全连接,右边是局部连接。

对于一个1000 ×1000的输入图像而言,如果下一个隐藏层的神经元数目为10^6个,采用全连接则有1000× 1000 × 10^6 = 10^12个权值参数,如此数目巨大的参数几乎难以训练;而采用局部连接,隐藏层的每个神经元仅与图像中10 × 10的局部图像相连接,那么此时的权值参数数量为10 × 10 × 10^6 = 10^8,将直接减少4个数量级。

通过权值共享还能进一步减少参数。具体做法是,在局部连接中隐藏层的每一个神经元连接的是一个10 × 10的局部图像,因此有10× 10个权值参数,将这10 × 10个权值参数共享给剩下的神经元,也就是说隐藏层中10^6个神经元的权值参数相同,那么此时不管隐藏层神经元的数目是多少,需要训练的参数就是这 10 × 10个权值参数(卷积核,也称滤波器的大小)。尽管只有这么少的参数,CNN依旧有出色的性能。如果要多提取出一些特征,可以增加多个卷积核,不同的卷积核能够得到图像的不同映射下的特征,称之为特征图(Feature Map)。

2.2.2 网络结构

如图2-3是一个经典的CNN结构,称为LeNet-5网络。

可以看出,CNN中主要有两种类型的网络层,分别是卷积层和池化/采样层(Pooling)。卷积层的作用是提取图像的各种特征;池化层的作用是对原始特征信号进行抽象,从而大幅度减少训练参数,另外还可以减轻模型过拟合的程度。

2.2.3 卷积层

卷积层是卷积核在上一级输入层上通过逐一滑动窗口计算而得,卷积核中的每一个参数都相当于传统神经网络中的权值参数,与对应的局部像素相连接,将卷积核的各个参数与对应的局部像素值相乘之和,(通常还要再加上一个偏置参数),得到卷积层上的结果。如图2-4所示。

2.2.4 采样层

通过卷积层获得了图像的特征之后,理论上可以直接使用这些特征训练分类器(如softmax),但是这样做将面临巨大的计算量的挑战,而且容易产生过拟合的现象。为了进一步降低网络训练参数及模型的过拟合程度,可以对卷积层进行池化/采样(Pooling)处理。池化/采样的方式通常有两种:Max-Pooling,选择Pooling窗口中的最大值作为采样值;Mean-Pooling,将Pooling窗口中的所有值相加取平均,以平均值作为采样值。

3 CUDA平台介绍

3.1 CUDA简介

近几年GPU通用并行技术得到了飞速的发展,因为其计算核心的数量远远多于CPU,在高度并行的计算问题上,GPU的计算效率要远高于CPU。CUDA(ComputeUnified Device Architecture,统一计算设备架构)是由英伟达公司推出的GPU通用并行计算平台,不仅提供了一系列API使得开发人员能够绕过GPU的图形API来直接访问GPU的硬件,还提供了一个C语言编译器,使得开发人员能够使用C语言来进行快速的开发。be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端CUDA的代码就可以运行在GPU上,使得卷积神经网络算法在GPU上的开发成为可能。

3.2 CUDA编程

3.2.1 CUDA的执行模型

在 CUDA 的架构下,一个程序分为两个部份:host 端和 device 端。Host 端是指在 CPU 上执行的部份,而device 端则是在显示芯片上执行的部份。Device 端的程序又称为kernel。通常 host 端程序会将数据准备好后,复制到显卡的内存中,再由显示芯片执行 device 端程序,完成后再由host 端程序将结果从显卡的内存中取回。一个完整的CUDA程序是由一系列的设备端kernel核函数并行步骤和主机端串行处理步骤共同组成的。在这个模型中,CPU与GPU协同工作,CPU负责进行逻辑性强的事物处理和串行计算,GPU则专注于执行高度线程化的并形处理任务。

Kernel不是一个完整的程序,而只是其中的一个关键并行计算步骤。Kernel以一个网格(Grid)的形式,每个网格由若干个线程块(block)组成,每一个线程块又由若干个线程(thread)组成。如图3-1所示。

3.2.2 常用函数及用法

1.核函数的声明与执行

要写在显示芯片上执行的程序。在 CUDA 中,在函数前面加上__global__ 表示这个函式是要在显示芯片上执行的。在显示芯片上执行的程序有一些限制,首先最明显的一个限制,不能有传回值,一般把计算结构返回值写在函数的指针类型参数中。

在CUDA中,要执行一个核函数,可以使用语法:

函数名称<<>>(参数…);

2.全局内存的使用

GPU的全局内存之所以是全局内存,主要是因为GPU与CPU都可以对它进行写操作,任何设备都可以通过PCI-E总线对其进行访问。在多GPU系统同,GPU之间可以不通过CPU直接将数据从一块GPU卡传输到另一块GPU卡上。

使用cudaMalloc函数开辟一块全局内存空间。使用cudaMemcpy函数可以把CPU上的数据传输到GPU的全局内存上或者相反方向。

3.3 CUDA开发环境搭建

在MAC OS X系统上完成CUDA7.5的安装及环境配置的步骤如下:

4 数据方阵化处理及网络模型设计

4.1 数据方阵化

4.1.1 手写数字数据库MNIST介绍

手写数字库很容易建立,但是总会很浪费时间。Google实验室的Corinna Cortes和纽约大学柯朗研究所的Yann LeCun建有一个手写数字数据库,训练库有60,000张手写数字图像,测试库有10,000张。由来自约250个不同个体的手写数据组成,并且保证训练样本集和测试集的书写者不存在交集。神经网络并未在训练的时候遇到过与测试集相似的手写数字,由此可见测试集的健壮性。用该测试集可以判断经过训练的网络的识别能力。MNIST数据库共有4个文件,每个样本集都包含图像文件和标签文件。图像中每个像素用灰度表示,值在0~255之间,图像的数据存储格式如表4-1所示:

地址偏移 数据长度(字节) 描述
0000 4 2051 magic number
0004 4 60000 样本总数目
0008 4 28 样本行数
0012 4 28 样本列数
0016 1 0~255 像素值

标签文件中每个标签值范围为0~9,标签文件的存储格式如表4-2所示:

地址偏移 数据长度(字节) 描述
0000 4 2049 magic number
0004 4 60000 样本总数目
0008 1 0~9 标签值

样本的读取过程:由表4-2可知样本大小为28*28,每784个字节便对应着一个样本图像的全部像素值。如图4-1显示了读取图像文件。

4.1.1 手写数字数据库MNIST的数据方阵化

GPU比CPU更适合处理浮点数据,尤其是需要大量计算资源的浮点数矩阵运算。为了将数据能用于GPU运算,需要提前将用于神经网络的训练数据和测试数据进行预处理。本文中采取的方法是,对于图像文件中每个像素值做归一化处理,从0-255的整数数值范围映射到0-1的单精度浮点数值范围。本文将定义一个二进制文件格式tensor,用于存放用于训练和测试神经网络的数据集,将文件元信息,包括文件名、数值类型、类型占的字节数、维度信息等,以及图像或标签的数据按位存放到tensor文件中。本文构建的神经网络将以tensor格式的文件作为输入数据层读取的文件。

Tesnor 文件格式:

1.Header部分

  • type_id:1字节(例如图4-2中开头的01);
  • sizeof:4字节(例如图4-2中的04 00 00 00);
  • len_name:4字节(例如图4-2中的11 00 00 00);
  • name:len_name 字节 (例如图4-3中的选中部分);

  • nbDims:4字节,存储维度数的信息(例如图4-4中的选中部分);

  • dims:nbDims*4字节,存储维度数据信息(例如图4-5中的选中部分);

2.Content:部分

以sizeof为单位大小存储的图像数据(例如图4-6中的选中部分)。

4.2 网络模型设计

本文的CNN框架是部署在GPU上的,训练周期以秒为单位,比传统的训练更快,这样就可以探索更大的参数空间,研究各种结构的影响,选择出合适的网络模型。本文以手写数字识别为例,选取合适的网络结构模型和相关参数。

本文选择MNIST数据集全部的60000个样本作为训练样本,在训练和测试处理之前提前将其转化成适合在GPU上处理的格式。对于训练阶段来说,在输入层初始化时以每一个样本为单位对整个输入层的样本数据做打乱处理,以提高网络的泛化能力。本程序采取的打乱处理的方法是,生成一个大小为60000的数组,数组中的元素是0-59999之间不重复的随机整数序列,然后对样本图片数据集合和样本标签集,按照同样的位置重新排列,这样可以保证样本图片数据和样本标签仍然是正确对应的。对于测试阶段,为了防止产生随机误差,没有使用打乱输入层的处理,而是从经过预处理的文件中按照固有的顺序依次读出1000张图片数据作为测试样本,以对训练好权重和偏置的网络模型进行验证损失(loss)和准确度(eval)。在神经网络训练和测试过程中可以通过json文件分别对优化算法、学习速率、训练次数、网络结构及每层单独的参数等参数进行配置,程序会读取这个配置文件初始化训练模型和网络模型。

4.2.1 网络结构

在LeNet-5网络结构的基础上,稍加改动,主要变量包括卷积层的数量、卷积核的数量、全连接层的数量、全连接神经元的个数,通过对比实验结果,找到最合适的网络结构模型。

1.实验设计

如表4-3所示,共设计了4种对比实验。CNN-1与CNN-2对比验证增加卷积层是否会对网络模型的分类结果和识别率有所影响;CNN-1与CNN-3对比验证增加全连接层是否会对网络模型的分类结果和识别率有所影响;CNN-3和CNN-4对比验证卷积层中卷积核的数量是否会对网络模型的分类结果和识别率有所影响。

网络名称 C1 S1 C2 S2 FC1 FC2 FC3
CNN-1 20 20 50 50 500 \ 10
CNN-2 20 20 \ \ 500 \ 10
CNN-3 20 20 50 50 500 100 10
CNN-4 10 10 20 20 500 100 10

2.实验结果

网络名称 CNN-1 CNN-2 CNN-3 CNN-4
测试识别率 97.53% 96.36% 97.66% 97.24%

实验图4-7对60000条训练数据集按每批次50条数据进行一次迭代,共迭代2400次,也就是说对总的训练数据集进行了2次迭代周期。图中上部分表示神经网络的损失值虽迭代次数的变化情况,下半部分表示。表4-4是对于训练后的神经网络进行10000条测试数据进行预测后的平均值。结论:

  • 从图4-7和表4-4可以看出CNN-3的网络结构,与其他几种网络结构相比在本文中是识别率最高。
  • 从CNN-1和CNN-2的对比结果来看,增加一层卷积层确实可以提高网络的识别率。
  • 从CNN-1和CNN-3的对比结果来看,增加一层全连接层确实可以提高网络的识别率。
  • 从CNN-3和CNN-4的对比结果来看,卷积核的数量确实会影响网络的识别率,卷积核数量多的往往识别率较高。

4.2.2 权重初始化方式

1.实验设计

在选择CNN-3网络结构的基础上,调整全连接层权重的初始化方式,分别采用以下三种方式,以观察对网络的分类结果和识别率有所影响。具体设计如表4-5所示。

  • Constant:给权重设置一个固定的参数。
  • Gaussian:权重随机初始化为均值等于0标准差为可配置的正态分布。
  • Xavier:是改进版的Gaussian。
配置名 权重初始化的类型
Constant Constant 0.01
Gaussian Gaussian 0.01
Xavier Xavier \

2.实验结果

不同初始化方式经过训练后的网络识别率如下表所示。

配置名 Constant Gaussian Xavier
测试识别率 11.35% 93.06% 97.66%

实验的训练和测试方法与4.2.1节的实验方法相同,从中可以得出结论:

  • Xavier初始化权重方式对于训练神经网络最为有效。
  • Gaussian方法虽然最后也能达到较高的识别率,但是学习非常缓慢。
  • Constant方式采用固定值初始化权重,几乎无法再训练的过程中学习到任何特征。

4.2.3 激活函数的选择

1.实验设计

在选择CNN-3网络结构的基础上,使用Xavier方式初始化各层权重和偏置参数,然后对全连接层后的激活函数分别采用以下三种方式:Sigmoid、ReLU、Tanh,以观察对网络的分类结果和识别率有所影响。具体设计如表4-7所示。

配置名
Sigmoid Sigmoid
Tanh Tanh
ReLU ReLU

2.实验结果

配置名 Sigmoid Tanh ReLU
测试识别率 95.46% 97.58% 97.66%

实验的训练和测试方法与4.2.1节的实验方法相同,从表4-8和图4-9可以看出激活函数为ReLU时,测试数据集的平均识别率最高,在训练的迭代过程中损失值也较快到达较低值,学习地较快。

4.2.4 实验总结

经过上述的三个实验,分别选择了网络结构、权重初始化方式、激活函数。从而选出了对于手写数字来说最佳的网络结构为CNN-3,权重初始化方式为Xavier,激活函数为ReLU。

5 卷积神经网络并行化设计及实现

5.1 be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端CUDA的卷积神经网络的训练过程

卷积神经网络的训练过程和多层前馈神经网络相似,采用的是有监督的训练方式,利用反向误差信号传导,不断调整每一层的权重和偏置参数,以达到训练的目的。样本集是数据向量和期望的标签组成的向量对形式。卷积神经网络最后输出层输出的值与期望值做损失函数计算得到误差值,并将误差值通过BP算法传回到各层,在大量的输入、输出映射关系中不断反复这一过程,从而学习到正确的权重参数信息。卷积神经网络不需要对数据提前手动地提取特征值、筛选特征等操作,其会在反向传播中不断调整卷积核的参数,学习到正确的提取图像特征的方式,这一过程是在大量数据的驱动下自动学习完成的。神经网络的训练示意图如图5-1所示:

5.1.1 网络初始化

1.Solver初始化

Solver负责全局协调调度,网络的前馈和反向传播计算梯度,然后更新权重参数以最小化损失函数值。读取配置文件,选择合适的优化函数,设定学习策略、学习速率、权重衰减参数等控制参数。Solver类从配置文件中读取上面提到的各项参数,作为自身的成员变量存储在内存,在后续的权值更新中会用到这些参数。

2.网络结构初始化

Net类负责从配置文件中读取网络结构,将其抽象表示为数据结构。本程序网络中各种类型的层抽象成Layer,其输出输入用Response表示,Net维护一个列表vector用于按顺序存放网络中的各层。如图5-2所示为从配置文件中读取的网络结果示意图,其中正方形表示层的种类和在配置文件中的命名,椭圆形表示各层的输入输出Response,箭头表示数据流动的方向。

3.分配内存

网络的数据流向都在GPU中进行,在前向传播进行之前需要为每个层(Layer)和响应(Response)分配内存。在网络结构初始化后,这些内存的大小都是不变的。本文使用GPU的全局内存,需要使用cudaMalloc函数分配内存。

4.权重和偏置初始化

在网络前向传播之前还需要对每一层的权重和偏置进行初始化。初始化的方式在配置文件中可调。为了使得网络中信息更好的流动,每一层输出的方差应该尽量相等。

5.1.2 网络前向传播过程

经过CNN-3网络的初始化后,建立了一个7层网络(不包括输入层)。在输入层将训练样本大小为28*28的像素矩阵作为神经网络的输入层,用20个5*5的卷积核对原图像进行卷积运算得到20个具有不同特征的卷积层C1,每个大小为24*24,这些就是经过不同过滤器提取的特征。然后对C1层按2*2的局部求最大值得到20个12*12的降采样层S1,这一步在保证特征数据的情况下,又减少了参数。然后进行第二次卷积和降采样操作,最后得到50个4*4的特征图。然后将这些特征图重构成一层神经元进行全连接,最后一层神经元的输出个数为10,就是对应的手写数字的10个类别。将最终产生的预测结果与标准值进行比对,得出损失值。其中在前向传播过程过程中包含大量的矩阵运算,可以采用CUDA的并行化策略进行加速。

5.1.3 网络的反向传播过程

在网络前向传播中产生的损失值,将使用BP算法,逐层反馈。每一层的误差和权重偏置的梯度都在内存中保持,直到更新过程。

5.1.4 网络的权值和偏置更新过程

当反向传播过程完成后,每一层的权重和偏置的梯度也已经算出,这时就可以使用不同的学习策略和优化策略对权重和偏置进行更新。因为每一层的各个神经元都是独立的,所以可以采用CUDA的并行化策略进行加速。

5.1.5 保存训练结果

当训练的次数达到指定值,训练完毕,将每一层有权重和偏置信息的写入二进制文件中,其文件结构与tensor类似。这样在识别过程中,当网络初始化成功后,只需要将这些权重参数信息读入到网络中,就可以进行前向传播,从而对测试数据集进行预测。

5.2 并行化分析及实现

5.2.1 并行化分析

1.be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端神经网络结构的并行

be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端神经网络结构的并行方案是指在GPU上把每一层的n个神经元节点设置成n个线程,每个线程负责计算一个神经元。

本文定义了一个宏,方便对一个任务数为n的并行任务,定位到GPU上的线程索引,从而使每个线程都能执行独立的任务,完成并行计算的任务。

  1. #define CUDA_KERNEL_LOOP(i, n) \
  2. for (int i = blockIdx.x * blockDim.x + threadIdx.x; \
  3. i < (n); \
  4. i += blockDim.x * gridDim.x)

其中,blockDim.x*gridDim.x表示的是该线程格所有线程的数量,n表示核函数总共要处理的元素个数, 有时候,n会大于blockDim.x*gridDim.x,因此并不能一个线程处理一个元素, 由此通过上面的方法,让一个线程串行(for循环)处理几个元素。

根据硬件将线程块的数量限制为不超过65535。每个线程块中的线程数量也有限制,最大的线程数量不能超过设备属性结构中maxThreadsPerBlock域的值(一般是512)。本文设置CUDA运行时在每个线程块中创建的线程数量固定为512,设置设备在执行kernel核函数执行的并行线程块数量最大为2880,实际的线程块的大小设置根据任务数N,通过下面的函数完成:

  1. int CUDA_GET_BLOCKS(const size_t N) {
  2. return min(2880, int((N + size_t(512) - 1) / 512));
  3. }

比如下面的例子,通过并行化的方法为ptr_GPU所指向GPU内存的2000个元素赋值为1。

  1. Kernel_set_value<<<FECNN_GET_BLOCKS(2000),512>>>(2000,ptr_GPU,1);
  2. __global__ void Kernel_set_value(int N, float* GPUdst, float value){
  3. CUDA_KERNEL_LOOP(index,N){
  4. GPUdst[index] = value;
  5. }
  6. }

2.be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端矩阵乘法的并行运算

卷积神经网络中有很多计算都是矩阵与向量之间、矩阵之间的运算,而矩阵运算具有并行特征,CUDA非常适合做矩阵运算,因此如果在GPU上执行计算过程,可以达到提高计算速度的目的。本文使用CUDA cuBLAS库中用于矩阵并行计算的函数cublasSgemm()。

5.2.2 梯度下降算法的实现

  • 步骤1:根据在json文件中配置的学习速率变化的策略选择合适的学习速率

  • 步骤2:在Solver调用solve方法,迭代网络结构中每一层,找到需要训练的层,即含有权重和偏置信息的层,分别对这些需要的层调用update_solver方法,传入Solver从配置文件中读取的有关优化方法的参数及当前的学习速率

  • 步骤3:调用update_solver方法选择合适的优化方法,本文程序目前支持SGD随机批量梯度下降算法。最近比较流行的方法还有AdaDelta、AdaGrad、Adam等

  • 步骤4:调用CUDA的Kernel核方法,通过并行处理来加快速度。这里采用的并行策略是,每一层权重参数和偏置参数数量很多,因为对这些参数的运算又是可以独立进行的,采取并行化的方式将大大加快速度。在进行一层权重的梯度下降计算时,设置任务数N为权重参数的个数。梯度信息存储在gradients变量中

  1. __global__ void Kernel_update_SGDL2(size_t N,
  2. int nNets, float decay, float momentum, float lr,
  3. const float* weights, float* gradients){
  4. CUDA_KERNEL_LOOP(idx,N){
  5. float w = weights[idx];
  6. float h = gradients[idx];
  7. float g = decay * w;
  8. //加上对应的diff部分
  9. g += gradients[N*k+idx];
  10. gradients[idx] = momentum * h + lr * g;
  11. }
  12. }
  • 步骤5:权重和偏置更新。迭代网络结构的每一层,调用该层的update方法,判断是否需要更新权重、偏置信息,调用Kernel核方法通过并行运算,加速权重更新的速度。这里的总任务数为该层权重或偏置的总数
  1. bsa2b(weight_numel, weight_histGPU, weight_dataGPU);
  2. void bsa2b(size_t N, float* a, float* b){
  3. Kernel_bsa2b<<<FECNN_GET_BLOCKS(N), 512>>>(N,a,b);
  4. }
  5. __global__ void Kernel_bsa2b(int num, float* a, float* b){
  6. CUDA_KERNEL_LOOP(index,num){
  7. b[index] -= a[index];
  8. }
  9. }

5.2.3 全连接层的前馈和反馈实现

全连接层有权重和偏置作用在输入数据上,通过加权运算产生输出。在这一层上,包含非常多的计算,而这些计算可以通过矩阵运算的方式并行化,从而加快运算速度。本程序使用be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端CUDA的cuBLAS基础线性计算子程序,其中提供了并行进行矩阵运算的函数cublasSgemm。

1.前馈实现

先对批量的输入数据矩阵与权重数据矩阵调用cublasSgemm函数计算出输出数据矩阵,然后在其加上偏置,同样也是矩阵运算。

  1. cublasSgemm(cublasHandle, CUBLAS_OP_T, CUBLAS_OP_N,
  2. num_output, num_items, num_input, // M,N,K
  3. 1, weight_dataGPU, num_input, // A [M,K]
  4. in[i]->dataGPU, num_input, // B [K,N]
  5. 0, out[i]->dataGPU, num_output); // C [M,N]

2.反馈实现

  • 步骤1:计算误差。
  1. cublasSgemm(cublasHandle, CUBLAS_OP_N, CUBLAS_OP_N,
  2. num_input, num_items, num_output,
  3. 1, weight_dataGPU, num_input,
  4. out[i]->diffGPU, num_output,
  5. 1, in[i]->diffGPU, num_input);
  • 步骤2:计算梯度值。
  1. float beta = 1;
  2. cublasSgemm(cublasHandle, CUBLAS_OP_N, CUBLAS_OP_T,
  3. num_input, num_output, num_items,
  4. 1, in[i]->dataGPU, num_input,
  5. out[i]->diffGPU, num_output,
  6. &beta, weight_diffGPU, num_input);

5.2.4 Softmax回归算法的实现

Softmax回归其实就相当于多类别情况下的逻辑回归。Softmax层可以看做是一个特殊的激活函数层,首先计算带权输入

然后使用softmax函数作用在

如图5-3所示。根据这个函数,第j个神经元的激活值就是:

其中,分母中的求和是在所有的输出神经元上进行的。可以看出,softmax层的输出是一些相加为1整数的集合,换言之,softmax层的输出可以被看做是一个概率分布。在很多问题中,能够将输出激活值理解为网络对于正确输出为j的概率的估计是非常方便的。所以,比如在MNIST分类问题中,可以将解释成网络估计正确数字分类为j的概率。

下面给出softmax层的正向传导实现。

  • 步骤1:归一化处理。设置总任务数为批处理batchsize的大小。调用kernel_channel_max,对于每个批次,找到当前层神经元中最大的值,存储在由中间变量scale_data指针指向的GPU内存地址,此时中间变量scale_data中每个元素为某一批次中选出的最大值。然后设置总任务数为数据的总长度count,调用kernel_channel_subtract,对每个神经元的输出减去该层的神经元中的最大值。下面列举其中的核函数。
  1. __global__ void kernel_channel_max(int num, int channels,float* data, float* out) {
  2. CUDA_KERNEL_LOOP(index, num) {
  3. float maxval = -FLT_MAX;
  4. for (int c = 0; c < channels; ++c) {
  5. maxval = max(data[index * channels + c], maxval);
  6. }
  7. out[index] = maxval;
  8. }
  9. }
  10. __global__ void kernel_channel_subtract(int count,int num, int channels,
  11. float* channel_max, float* data) {
  12. CUDA_KERNEL_LOOP(index, count) {
  13. int n = index / channels;
  14. data[index] -= channel_max[n];
  15. }
  16. }
  • 步骤2:对每个神经元的输入做exp函数计算,然后计算神经元输出的每个类别所代表的概率。用中间变量scale_data保存每个批次中所有神经元输出值经过exp运算后的总和。下面是其中用到的核函数。
  1. __global__ void kernel_exp(int count,float* data, float* out) {
  2. CUDA_KERNEL_LOOP(index, count) {
  3. out[index] = exp(data[index]);
  4. }
  5. }
  6. __global__ void kernel_channel_sum(int num, int channels,
  7. float* data, float* channel_sum) {
  8. CUDA_KERNEL_LOOP(index, num) {
  9. int n = index;
  10. StorageT sum = 0;
  11. for (int c = 0; c < channels; ++c) {
  12. sum += data[n * channels + c];
  13. }
  14. channel_sum[index] = sum;
  15. }
  16. }
  17. __global__ void kernel_channel_div(int count,int num,int channels,
  18. float* channel_sum, float* data) {
  19. CUDA_KERNEL_LOOP(index, count) {
  20. int n = index / channels;
  21. data[index] /= channel_sum[n];
  22. }
  23. }

5.3 对比实验

在第4章中已经通过实验选择出了,针对手写数字识别率较高的卷积神经网络模型CNN-3和相关参数,权重初始化方式为Xavier,激活函数为ReLU。本章将使用手写数字数据集MNIST对使用CUDA实现的卷积神经网络算法与深度学习框架Caffe的C++实现做一个性能上的对比,以验证使用CUDA并行化卷积神经网络确实能够提高训练速度。其中,Caffe的全称是Convolutional Architecture for Fast Feature Embedding,它是一个清晰、高效的深度学习框架。其优势是上手快,模型与相应优化都是以文本形式而非代码形式给出,社区好,可以通过BSD-2参与开发与讨论。

实验的软件硬件环境如表5-1所示。实验先比较CPU和GPU实现的神经网络在不同的训练周期下训练完相同数量的数据所需的时间,这里以读完60000条MNIST训练数据集为一次训练周期,其他实验条件与第4章中的实验相同。然后对10000条MNIST测试数据进行验证识别率,实验结果如表5-2所示。

硬件条件 CPU: 2.3 GHz Intel Core i7 内存: 16 GB 1600 MHz DDR3 GPU: NVIDIA GeForce GT 750M 显存: 2GB
软件条件 开发环境:Eclipse CUDA: Toolkit7.5, cublas 编语言: C++, CUDA C
迭代时间 GPU训练时间 GPU测试准确度 CPU训练时间 CPU测试准确度
2 74.477s 97.67% 89.14s 97.32%
4 146.751s 98.32% 176.94s 97.96%
8 300.299s 98.65% 355.71s 98.36%

如表5-2所示,将卷积神经网络CPU的实现与GPU实现的训练时间和识别率做了比较,从表中可以看出GPU实现相比于CPU实现的训练时间有了一定的加速作用,在迭代周期为8时,加快了15%,准确率也有了提升,提高了0.29%,说明使用GPU并行计算对卷积神经网络有加速效果。实验结果表明,本文设计的be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端CUDA实现的卷积神经网络在保证识别率高的条件下能够加快神经网络的训练时间。

6 结论

卷积神经网络,是深度学习领域研究的热门,尤其适合应用在图像分类和识别问题上。为了得到更高的识别率,神经网络需要大量的数据集进行训练,这个过程将非常耗时,目前有不少的研究在用GPU对卷积神经网络的训练和识别过程进行加速,以解决训练时间长的问题。本文设计并实现了be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端CUDA的卷积神经网络算法,利用CUDA并行处理能力,提升了算法的性能,并以MNIST手写数字作为实验,将CPU实现与GPU实现做了对比,得出结论。

通过这次毕业设计,我学到了很多,之前对于机器学习不太了解,都要从头开始学,这对于我的学习能力是一个考验。此次毕设我用到了很多知识,例如用javascript做原型demo,用C++面向对象的知识设计神经网络的计算框架,用matlab做矩阵数据的处理,用python做实验图等,让我将理论知识应用到实践中。总的来说,这是一次对我意志力、学习能力的考验,是对我编程技能和解决问题能力的一次提升,会对我将来学习和工作生活有非常大的帮助。

参考文献

[1] Y. LeCun, L.Bottou, Y. Bengio, and P. Haffner. Gradient-based learning applied to documentrecognition[J].Proceedings of the IEEE, 1998.11.

[2] Schmidhuber, Jürgen. Deep learning in neural networks: Anoverview[J], Neural Networks, 2015:85-117.

[3] Zeiler,Matthew D. ADADELTA: an adaptive learning rate method[J], arXiv preprint arXiv,2012.

[4] Bottou, Léon. Stochastic gradient descent tricks[J], NeuralNetworks,Springer Berlin Heidelberg, 2012.

[5] A. Krizhevsky,I. Sutskever, and G. Hinton. ImageNet Classification with Deep ConvolutionalNeural Networks[J], Advances in Neural Information Processing Systems, 2012.

[6] J. Duchi, E.Hazan, and Y. Singer. Adaptive Subgradient Methods for Online Learning andStochastic Optimization[J], The Journal of Machine Learning Research, 2011.

[7] I. Sutskever,J. Martens, G. Dahl, and G. Hinton. On the Importance of Initialization andMomentum in Deep Learning[J], Proceedings of the 30th International Conferenceon Machine Learning, 2013.

[8] Jason Sanders,Edward Kandrot. CUDA by Example: An Introduction to General-Purpose GPUProgramming[M]. Addison-Wesley Professional, 2010.

[9] Nvidiadeveloper home [EB/OL]. https://developer.nvidia.com/, 2016-03.

[10] The MNISTDatabase of Handwritten Digits[DB].
http://yann.lecun.com/exdb/mnist/

[11] SUN Xiangyu,FENG Baiming, YANG Pengfei. Parallelization of BP algorithm and exampleverification based on CUDA. Computer Engineering and Applications, 2013, 49(23): 31-34.

[12] 董长虹.Matlab神经网络与应用[M].北京: 国防工业出版社,2007.9:1-13.

[13] MichaelNielsen. Neural Networks and Deep Learning[EB/OL]. http://neuralnetworksanddeeplearning.com/,2016-03.

[14] Fei-FeiLi,Andrej Karpathy. CS231n Convolutional Neural Networks for VisualRecognition[EB/OL]. http://cs231n.stanford.edu/, 2016-03.

[15] Andrew Ng,Jiquan Ngiam,Chuan Yu Foo, Yifan Mai,Caroline Suen. UFLDL教程 [EB/OL]. http://deeplearning.stanford.edu/wiki/index.php/UFLDL_Tutorial,2016-03.

[16] 张佳康,陈庆奎.be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端CUDA技术的卷积神经网络识别算法[J].计算机工程,2010,15:179-181.

[17] 刘进锋,郭雷.神经网络前向传播在GPU上的实现[J].微型机与应用,2011,18:69-71+75.

[18] 韩晓雪. be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端人工神经网络和GPU加速的手写数字识别并行算法[D].大连理工大学,2009.

[19] 刘荷苇. be365体育在线投注_365BET能赢钱吗_手机365体育投注客户端CUDA编程的神经网络手写数字识别[D].西南交通大学,2013.

[20] Jia Yangqing,Evan Shelhamer, Jeff Donahue. Caffe: Convolutional architecture for fastfeature embedding[J], ACM, 2014.

[21] 斯坦利?李普曼,约瑟?拉乔伊,芭芭拉?默,王刚,杨巨峰. C++ Primer中文版(第5版)[M].北京:电子工业出版社,2013.9.

[22] Zeiler,Matthew D., and Rob Fergus. Visualizing and understanding convolutional networks[J], Computer vision–ECCV 2014,Springer International Publishing, 2014.

[23] He, Kaiming,et al. Deep Residual Learning for Image Recognition[J], arXiv preprintarXiv, 2015.

[24] Girshick,Ross, et al. Region-based convolutional networks for accurate object detection and segmentation[J], Pattern Analysis and Machine Intelligence, 2016:142-158.

[25] Szegedy,Christian, et al. Going deeper with convolutions[J], Proceedings of theIEEE Conference on Computer Vision and Pattern Recognition, 2015.

[26] Long,Jonathan, Evan Shelhamer, and Trevor Darrell. Fully convolutional networks forsemantic segmentation[J], Proceedings of the IEEE Conference on ComputerVision and Pattern Recognition, 2015.

[27] Simonyan,Karen, and Andrew Zisserman. Very deep convolutional networks for large-scaleimage recognition[J], arXiv preprint arXiv,2014.

[28] Bergstra,James, and Yoshua Bengio. Random search for hyper-parameter optimization[J],The Journal of Machine Learning Research,2012: 281-305.

上传的附件 cloud_download 程序代码及文档-毕业设计.7z ( 30.94mb,?16次下载 )
error_outline 下载需要16点积分
eject