笔者对深度学习的强大能力以及应用的广泛性早有所耳闻,但一直没有系统地学习和理解其实现的原理和方法,《深度学习入门-基于Python的理论与实现》一书以十分浅显易懂的语言介绍了深度学习的原理并利用只基于numpy和matplotlib库的python代码进行了简单的实现,读来获益匪浅,衷心推荐大家前去阅读。
该学习笔记忽略代码实现等繁复过程,只总结书中提到的深度学习的原理,希望和我一样对深度学习感兴趣的读者可以管中窥豹,获得对深度学习浅显的理解。
(一)感知机
深度学习的起源算法是感知机(“朴素感知机”),它可以接受多个输入信号,输出一个信号,这里以接受两个信号的感知机为例。其原理如图2所示,
其中权重和阈值分别取(0.5,0.5,0.8),(-0.5,-0.5,-0.7),(0.5,0.5,-0.2)时可以实现与门,与非门和或门(取值不唯一)。但其有很大局限性,比如无法实现异或门,但可以通过“叠加层”来实现,添加一层中间变量,分别为与非门和或门的输出变量,两中间变量再通过与门得到最终的输出变量即可实现异或门,这就是多层感知机。理论上多层感知机可以进行非常复杂的表示,甚至构建出计算机。
(二)神经网络
就连接方式而言,神经网络与多层感知机没有分别,我们仍以图3为例,把每个变量节点叫做神经元,最左一层叫做输入层,最右一层为输出层(可以有多个输出变量),中间的为隐藏层。对图2中的公式进行简单改写,
b称为偏置参数,可以将其理解为一个内置的输入变量,权重为1,最终输出结果y为输入变量与权重的乘积和再应用一阶跃函数,这里的阶跃函数就起到激活函数的作用。类似地,我们也可以采用其他激活函数,如sigmoid函数,ReLU(Rectified Linear Unit)函数等,图5展示了这两种激活函数的公式和对应图像。
下面我们以此为基础构建一个三层的神经网络,如图6所示,
其中权重的上标为层号,下标为后一层变量序号+前一层变量序号;偏置的上标为层号,下标为后一层变量的序号,第0层到第1层的计算公式已由矩阵乘法的方式给出,以此类推,第1层到第2层,第2层到输出层的公式也可以写出,通过这种方式我们将信号输入网络后得到了输出信号,完成了神经网络的前向处理(forward)过程。对于隐藏层,我们利用激活函数来处理输入信号的总和,类似地,对输出层得到的信号和,我们也可以添加一函数来进行处理,回归问题一般采用恒等函数,分类问题则多采用softmax函数,softmax函数可以将输出值进行归一化,因而可以理解为不同类输出的概率大小,这里添加常数C是为了处理溢出问题。
现在我们假设学习已全部结束(权重参数已经完成了更新),应用这些参数完成神经网络的“推理处理”(也叫“前向传播”,forward propagation)。应用MNIST手写数字图像集(代码实现见书P70),将每一个图像读取成像素值向量(输入层),经过神经网络处理后输出一十维向量,经softmax函数处理后对应值为该标签的概率,获取概率值最大的标签与图像本来的标签对比即可评价该模型的识别精度(accuracy,这里为识别成功的图像占所有被识别图像的比例)。
最后,在该例子中对将输入图像的各个像素值除以255限定在[0,1]之间,这种把数据限定在某个范围内的处理称为正规化(normalization),对神经网络的输入数据进行某种既定的转换称为预处理(pre-processing)。图8展示的是对一张输入图像的处理流程,现考虑打包输入多张图像,以图6的计算公式为例,一组数据的输入为1*3的向量,N组数据的输入即为N*3的矩阵,经过矩阵乘法后得到N*3的输出矩阵(MNIST的例子中为N*10的输出矩阵),这样的方式称为批(batch)处理,能够实现高速的运算。
(三)神经网络的学习
神经网络最重要的特征就是能从数据中学习,将数据分为训练数据和测试数据(监督数据)两部分,利用训练数据更新出最佳的权重参数,再利用测试数据评价该模型的泛化能力。那如何评估权重参数是否是最佳呢?你可能会说可以利用上节所介绍的识别精度,识别精度最高的那组参数就是最有效的,但该值是离散的,无法进行求导更新参数等操作,因而需要引入损失函数(loss function)来进行评价。
常用的损失函数为均方误差和交叉熵误差。监督数据tk采用one-hot表示,即正确解标签为1,其余均为0(例如手写数字图像标签为“3”,则表示为[0,0,0,1,0...]),yk为神经网络的输出,对多个数据的交叉熵误差公式也易写出,有时学习数据过多我们需要从中进行抽样来“近似”全部数据,这种方式称为mini-batch学习。
有了损失函数以后,我们再来看如何根据损失函数来更新权重参数。
这里仍以图6的三层神经网络为例,损失函数E是两输出变量的函数,进而可以写成权重参数和偏置参数的函数,利用数值微分的方法可以求出函数对神经网络参数的导数,采取梯度法(gradient method)更新参数,重复该过程就可以不断朝损失函数的极小值(局部最小值,该点的梯度为0)前进了。其中学习率(learning rate)是人工设定的,而不是在学习过程中获得的,这样的参数称为超参数,一般来说需要尝试多个值来寻找效果最佳的设定。
最后,我们来总结一下具体的实现过程,首先从数据中随机抽样得到"mini batch",应用我们设计好的神经网络计算损失函数和对各参数的偏导,梯度下降法更新参数至最佳,再利用这些参数计算从数据集中另外取出的测试数据的识别精度来评估学习得到的模型的泛化能力。图11直观地展示了该流程并绘制了训练数据和测试数据的识别精度随循环步数的变化曲线(见书P118)。
至此,深度学习最基本的框架已经被建立起来,本书剩余部分的内容主要是如何改进各个步骤来加快运算速度,提升识别精度,比如利用误差反向传播法代替数值微分法高效计算梯度,采用不同的参数更新方式,设置合理的权重初值等学习技巧,对卷积神经网络(CNN)以及深度学习前沿现状的介绍等。这些将在后续的学习笔记《从零开始理解深度学习(二)》中进行总结,希望觉得有用处的小伙伴们点赞收藏+关注,从此不再迷路!