浅谈深度学习神经网络入门
在深度学习领域中,神经网络无疑是最神秘也是最有力的“武器”,然而很多如我一样的同学,刚开始学习时如大海捞针,不得诀窍,总觉得事倍功半,一方面是因为自己刚刚起步或者一些学科基础较弱,另一方面也是因为缺少有效的入门系统书籍,就我看过的书籍而言,多是以框架为基础立足点,直接进行教学实践,在未弄懂神经网络的工作过程与原理的情况下就开始一知半解写代码。下面针对神经网络的学习,结合我自己的经历,浅谈一下如何入门,由于我也不是这方面的资深工作者,有些地方写的可能有欠缺,大家也请见谅。
一、工具基础——Python
Python是一门十分强大的“学习型”语言,具有强大的函数库支持,在各个研究领域均可作为有效的coding工具,特别在深度学习领域,Python是不可或缺的基础,代码书写效率高且具有深度学习中各种现成的模型,包括神经网络。若有其它语言的学习基础或相关的学习经历你就会发现学习Python是一件特别简单的事,在“面向对象”的思想下,Python实现了高度的代码简化,对深度学习的入门十分有利。
对Python的学习可主要集中在网络教程上,如“菜鸟教程”,“廖雪峰的博客”等,至于学习的书籍,最好是待入门后购买专供你研究领域的相关书籍,如做工程写网站的可购买Tornado、Django等框架的学习书籍,研究深度学习的则可专攻学习sklearn模块或Tensorflow框架,学习Python相关模块的使用。
学习基本的语法后,我们就可以应用Python了,爬虫是个既有趣又有效的应用项目,在获取网络“有效”资源的同时,它也能让你对Python有更深的理解,在我的认知中,Python写爬虫可分为两类,一类是获取网页源码以提取相关信息,多使用正则表达式,如BeautifulSoup、Urlopen等,另一类则是利用自动化调试工具进行信息提取,如Selenium,如果想要抓取Javascript动态加载的内容,即可使用第二种。学习爬虫应用后Python则算是已经入门,对于接下来神经网络的学习算是奠定了工具基础。
二、神经网络入门
下面将结合我自己的学习经历介绍对神经网络的学习入门,举例素材主要来源于我最初应用神经网络所尝试的车牌识别的项目。
1、理解神经网络
神经网络并不复杂,其实就是一系列线性模型与非线性模型的组合,最终还是一系列线性代数的公式,其中的线性模型即可视为矩阵乘,当然其中有输入、权重的区分,非线性模型则为一系列激活函数,通过激活函数,线性模型获得的输出可以进行非线性变换,以保证神经网络提取特征的作用。神经网络在深度学习中属于监督学习的一种,即训练过程中每个输入都对应一个“标记”,该标记标明了输入的位置(目标检测任务)或类别(分类任务),通过不断调整神经网络中的权重值使神经网络的输出不断迫近标记值,最后得到的网络结构与权重的组合即是我们所需要的网络模型。
最初接触神经网络是在机器学习的课堂上,周志华所著《机器学习》中所述的“神经元模型”和“多层感知机”,多层感知机与激活函数的组合就是全连接神经网络,其基本结构如图1所示,转换为数学表达可参见公式(1.1)(1.2)。
图1 简单全连接神经网络(1.1)
(1.2)
公式(1.1) (1.2)表示了隐含层及输出层的计算过程,即为网络输出结果,表示针对每一维度输出的偏移量,表示针对矩阵乘结果的激活函数操作。矩阵的乘加运算过程即为线性计算过程,可看作线性模型的部分,而则是非线性计算部分,Sigmoid函数 是常用的激活函数,其表达式如式(1.3),此外还有许多表现良好的激活函数如ReLU 及其变种,此处不再详述。
(1.3)
线性代数是神经网络学习的最大依仗,若想在此领域有深入的研究,需要良好的线性代数基础,当然,对于初学者来说,只需理解简单的线性计算即可。以上文字叙述了简单的全连接网络的计算过程,当然这只是前向传播部分,后面会解释逆向传播的优化部分。
由简单的全连接网络开始,我们的前辈们不断探索,在不断追求表现性能和效率中,神经网络的结构与计算方式被不断改进和补充,逐步发展出现了卷积神经网络(CNN)、循环神经网络(RNN)、长短期神经网络(LSTM)等优秀的表现良好的网络结构,神经网络是用来进行自动特征提取的,不同的网络结构运算方式不同、激活函数不同,也意味着提取方式不同,理解全连接网络的计算过程是将来学习CNN、RNN等的基础,由于本文针对入门级,对复杂的网络结构的计算方式此处不再进行说明。既然是自动提取特征,那神经网络应该自动筛选出输入中的有效信息并输出我们想要的结果,为达到此目的我们还需要为神经网络定义损失函数以及优化方式。
简单的全连接网络与损失函数、优化方式有机结合在一起,即可构成一个简单的神经网络模型,该模型训练后可自动学习重要特征并输出对的计算结果。损失函数意味着神经网络的输出与真实的标记之间的“距离”,当经过上述简单全连接网络后我们会获得输出,假设当前我们有标记值,那么我们需要一个衡量两者之间“距离”的函数,常用的损失函数有平方损失函数(如式1.4)、交叉熵损失函数(如式1.5)等,之所以需要衡量神经网络输出与标记间距离的损失函数,是因为我们需要在优化过程中有要优化的目标函数,良好的损失函数能够有助于优化过程的进行和实现。
(1.4)
(1.5)
所谓的优化方式即是为了使神经网络输出值与标记值不断迫近而采用的调整权重(上述中表现为)的数学理论。优化过程即是网络逆向传播更新权重的过程。常用的优化方式均是基于梯度下降法,如Adagrad、Adam 算法等,函数的梯度方向表示了函数值增长速度最快的方向,那么和它相反的方向就可以看作是函数值减少速度最快的方向,梯度下降的基本思想就是以一定步长使目标函数朝着梯度下降的方向前进,以不断逼近的最小值。了解具体的优化过程是深入学习神经网络的基础,对于全连接网络的优化其实就是不断反向求取关于的函数的导数,并将其在导数方向的值迭代更新减小,具体的推导过程此处不再详述,以及CNN的逆向传播推导过程,有兴趣的可以自行去查阅,这对今后自行优化网络结构提供了一定的理论基础。
还有一点不得不提,那就是权重的初始化方式,不同的初始化权重可能导致相差较大的收敛速度、表现性能,除了迁移学习,常用的权重初始化方式有Xavier、MSRA等,且搭配合适的激活函数会有更佳的表现效果,入门后可自行学习这些初始化方式的过程和优劣,在刚刚接触神经网络时,使用归一随机化的初始权重即可,另外还有利用迁移学习,直接使用现成的权重进行再训练,这些现成的权重往往是在大量数据集上,如ImageNet迁移学习得到的。
神经网络的工作过程大致如上所述,但其中的网络结构却有诸多种类和变化,与激活函数、优化方式的组合方式也各有不同,在什么场景中选择或定制哪些网络和组合能够达到最好的效果需要更多的理论基础和实践,入门后即可进一步学习神经网络深层次的东西。图2为整理出的神经网络工作过程,图中将神经网络提取特征的部分看做了黑盒子,且分成了回归与分类两种任务,在生成预测结果时常用的是Softmax函数(按一定概率取最大值的索引值)。
2、学习步骤
下面说一下我自己对于入门的学习路线的推进步骤。
(1)多层感知机,懂得其工作过程。
(2)学习激活函数,掌握函数的具体表达式与工作原理。
(3)学习目标函数,重点掌握交叉熵与平方和的表达式。
(4)学习全连接网络,掌握其前向传播过程,并了解基本的参数初始化方法。
(5)学习梯度下降法,结合全连接网络掌握全连接网络使用梯度下降的优化过程、推导过程和具体代码实现。
(6)采用全连接网络,自行完成一个完整的网络模型,包括参数初始化、激活函数、目标函数以及自己写的前向传播与逆向传播过程,并选定示例进行训练,如手写数字识别或简单的回归任务。
(7)学习更加复杂的网络结构,如CNN、RNN等,掌握其前向计算与逆向传播过程。
(8)将(6)中的网络结构换成(7)中所学,完成相同的模型任务,可自行体验性能表现。可自行替换不同的激活函数与初始化方法并观测实验结果。
注:以上步骤需要自己coding完成,利用python中的numpy库,而不要直接使用深度学习的框架。
(9)完成以上步骤后在我看来已算入门,接下来就要学习深度学习框架的使用,可直接使用框架中的函数代替自己coding的计算过程。对于框架来说,还是建议学习Tensorflow,并使用其中的低阶API。
(10)学习更多初始化方法以及迁移学习,学习更多改进的梯度下降方法,如加入动量、SGD的诸多变种算法。
(11)学习更多优秀的网络模型,如提取特征使用的VGG、GoogleNet、ResNet,在目标检测领域的Yolo、SSD等。
(12)在更多的实验中发现和解决问题,如常见的梯度消失问题、过拟合问题,以及经典的解决过拟合的方案Dropout层、Batch Normalization层等等等等。。。
(13)在掌握更多知识的前提下可自己设计网络结构,或作出根本性的创新。