一、前言
笔者入门深度学习看的是吴恩达的公开课《神经网络和深度学习》。这门公开课纯粹的入门,讲述的东西并不多,主要是以逻辑回归为例子,将逻辑回归使用神经网络的形式表示出来,通过这个例子来讲述前向计算、后向传播、向量化计算等基础知识。因为网上已经有资料是对视频笔记的详细记录,文中不会对视频讲解的每个部分进行阐述,只将自己在学习过程中遇到的难点和重点以笔记的形式记下来。希望能够帮助到各位读者,如果文章有错漏的地方,还请各位读者海涵指正。
二、模型公式说明
我们先把各种符号术语给讲述明白先,视频使用的是逻辑回归作为例子
2.1、输入矩阵
首先是输入矩阵 X
横方向是样本的数量,竖方向是每个样本的特征,一共有个(为了简介,在上面的矩阵中没有表示),对于每个样本都有,即有维特征
2.2、样本标签矩阵
Y
样本的标签矩阵如下,同输入矩阵一样表示样本数量
2.3、假设函数
假设函数
定义如下:
是我们的预测输出。通常希望假设函数
输出的是概率,但线性函数无法做到,我们可以再次基础上加入sigmoid函数
从而使得其变成非线性函数。
2.4、损失函数
我们可以使用平方差来作为损失函数,根据教学所说,这样的损失函数可以使为题成为非凸问题,即可以找到全局最优解
但逻辑回归使用的是对数似然函数来作为损失函数,关于这一点不明白的读者可以参考我的《最大熵模型》一文,所以我们真正使用的损失函数如下
对于单个样本的损失函数如上式所示,一般算法的代价函数是对个样本的损失求和再除以
三、计算图
视频使用计算图
来表示一个神经网络的计算过程,这里不对计算图进行描述,各位读者可以通过视频习得,我们直接讲述逻辑回归的计算图。计算图有前向计算和后向传播 2 个计算过程,单层前向计算过程比较简单,我们这里不做说明,我们主要说明后向计算需要注意的地方及难点。后向传播是为了求出梯度下降的值,我们也不对梯度下降
进行讲述,这部分视频已经有所讲解且思路清晰,这里笔者就不对基础的数学知识进行说明了,我后面也会有别的文章对梯度下降进行讲解
3.1、符号公式
我们先对逻辑回归的公式进行拆解,可以得到如下公式
其中我们需要对函数进行求导,我们直接写出它的求导结论
上面结论可以使用倒置函数
+链式法则
推导而出,详细过程参考附录《Sigmoid函数的求导证明》
3.2、链式法则推导
在讲解计算图的后向传播过程前,我们先简单讲一下链式法则。
链式法则可以让求导变得更加简单,其证明过程如下:
设函数在点的邻域有定义
在点可导 在点可微,即
我们定义有
对应于自变量的一个增量
那么有下面的推导
后面两项
表示一族函数,当Δx趋近0时,这些函数和Δx的比值也趋近于0
可得当时后面两项无穷小
所以在可导且
3.3、单层计算图
3.3.1、单层计算图讲解
如上图所示,单层计算图比较简单,我们可以通过链式法则一步一步求出损失函数对参数和的导数公式,从而使用梯度下降来更新这 2 个参数。
我们最终需要求出的是下面的 2 个导数公式
计算过程请各位读者注意结合3.1小节的《符号公式》
第一步求出损失函数对的导数,根据损失函数的定义和导数的求导法则,可以直接得到
第二步是根据第一步的结果来计算,集合函数的求导公式,可以得到:
第三步同理,跟的过程是一样的
经过上面的推导我们可以得到我们想要的导数公式了,有了上面的公式,我们可以直接使用程序来求我们的参数进行迭代,程序的伪代码如下,作用是完成一轮的迭代计算
For i in m:
3.3.2、向量化单层计算图
上一小节是针对实数进行的求导过程,其缺点在视频中已经有讲解,计算复杂且性能低下。在处理神经网络的过程中我们一般使用矩阵来进行计算,从而加快我们的计算过程,节省时间,这一小节我们将使用矩阵来计算计算图,也就是向量化我们的输入和各种参数,然后通过矩阵计算来得出我们想要的结果。关于向量化以及 python
的广播这里不做讲述,各位读者可以从视频中学习
上面的单层计算图我们可以将表示为一个列向量并表示为(是列向量这个结论是笔者的理解,不知道是否正确。当然了,这个只是向量的表现形式,不必太过纠结,能够理解运算过程即可),同理表示为一个列向量并表示为,一般将输入特征表示为列向量,那么就有
这里是一个行向量,因为进行了转置
向量化参数后我们就可以使用python
的广播更方便的进行运算,对于单层的计算图笔者不多做赘述,简单地在这里记录一下
3.4、多层计算图
多层计算图有一些符号规定我们需要说明一下,使用等来表示第一层的,也就是说上标方括号用来表示第 x 层的值,表示为,其余参数同理。下标表示的是对应节点的值,更一般地我们表示为就是第个节点的值,推广开来即第 n 层的第 m 个节点的值,其余参数同理
关于矩阵的运算请参考附录《矩阵乘法》和《矩阵的运算及其运算规则》
如下图所示,这是一个简单的 2 层逻辑回归计算图,一个输入有 3 个特征,分别是
3.4.1、多层计算图前向计算
node
是第一层,而output
是第二层。第一层的计算公式也在图中表示出来了,一共有 2 个计算,跟我们之前的单层计算图是一样的
需要注意矩阵的点乘和乘是不一样,关于矩阵的点乘和乘参考附录《点乘和矩阵乘》
这里要注意的是是一个列向量,我们的也是一个列向量,两者进行乘法时,我们需要对进行转置得到
那么针对所有的node
我们可以得到下面的公式
接下来我们可以对所有node
的参数表示为一个矩阵,每一行都是对应着node
的参数,比如表示的是node1
的参数,每一行的参数数量都与输入特征的数量相同,在这里例子中我们有 3 个输入,那么这里矩阵每一行就对应 3 个参数。
我们使用(m,n)来表示这个矩阵有m行n列,即维度。那么这里的矩阵就是(4,3)维度即4行3列。
如果我们抽出其中的一行来距离的话,则是
参数同理,但参数的维度是(4,1)
所有的node
组成了第一层,那么对于第一层,我们可以使用矩阵表示为下面的形式,下面的乘是矩阵乘法
我们还需要继续计算我们的函数,这里是对逐个元素进行计算
经过上面的矩阵运算,我们完成了第一层前向计算过程
同理的,output
的计算过程如下,最后的就是我们的输出
从上面可以看出的维度是(1,4),而和而都是(1,1)即一个实数。
最后我们对进行一次计算得到,同理也是对逐个元素进行计算:
在整个计算过程的最后加入损失函数即可简化为如下的图
3.4.2、多层计算图后向传播
后向传播在视频中描述得并不详尽,这里笔者将整个推导过程给各位读者罗列出来。在此之前先需要说明一下我们的激活函数使用的是函数。我们可以先不管激活函数是什么,并不影响这里的理解,后面的章节会简单的说明激活函数
我们依旧按照单层计算图的方法一步一步计算。
第一步
第二步,根据函数的推导公式,直接得到下面的式子,这里的计算结果依旧是一个实数即(1,1)
第三步,这里需要转置的原因是是一个行向量,而我们的是一个列向量,所以需要进行转置从而匹配的维度
另外计算出来的结果是一个(1,4)的矩阵,而也是一个(1,4)的矩阵,这样就能够进行梯度下降的减法计算。到了这里我们就完成了output
层的后向传播运算,接下来我们需要对node
层也就是第一层进行后向传播运算。
第四步,注意一下,因为是一个矩阵,所以是对矩阵的求导,其求导结果也是一个(4,1)维度的矩阵,而也是一个(4,1)维度的矩阵。关于矩阵的求导请参考附录《矩阵求导》。
注意下面的号,这里表示的是矩阵的点乘,也就是两个矩阵相乘就是元素逐个相乘,所以计算出来的结果也是个(4,1)维度的矩阵
为什么使用点乘在后面笔者用一个小节来进行说明
第五步,这里的转置按照笔者的理解依旧是为了匹配维度
我们上面说是一个(4,1)维度的矩阵,我们将表示如下:
而是一个行向量,表示如下:
那么可以得到下面的式子
根据最简单的矩阵乘法规则,一行乘一列
,得出来的是一个(4,3)维度的矩阵,同的维度是一样的。而我们可以直接得到,所以到这里,整个后向传播的求导过程我们完成了,这样我们就能够直接使用求导的结果进行梯度下降来更新参数
3.5、激活函数
线性方程和线程方程的组合还是线性方程,而很多时候模型都是非线性的,我们需要将模型编程非线性模型,而激活函数是为了让模型成为非线性的。
在上一小节的后向传播中,我们注意到我们会对激活函数进行求导,所以激活函数某种程度上也会影响模型的学习效率。
视频中指出了下面几种激活函数:
根据视频概括总结有:
- 总是优于
- 可以使激活函数的梯度总是为 1,避免了当太大时梯度为 0
- 工业界常用作为隐藏层的几乎偶函数
- 函数可以在二分类的输出层中作为激活函数使用
关于激活函数的内容视频讲解得非常清楚,相信给读者可以理解,笔者这里就不多做赘述
3.6、为什么使用点乘
我们在 3.5小节 中的第四步用到了点乘,但为什么是用点乘呢?最直接的看法就是因为两个维度为(4,1)的矩阵无法使用矩阵乘法,但这似乎并不是本质,下面笔者使用一个简单的例子来说明
首先,我们可以直接得到的公式
选择一种特殊的情况,比如我们对进行求导,然后这个导数来求解,公式如下:
公式中上面的花括号(1,1)表示花括号所指定的项的维度是(1,1)即1*1的矩阵,那么对于其他的我们可以得到其他的公式,完整的公式如下:
这个时候让我们尝试将它们使用点乘合并一下,思路很简单,将式子左边的第二项和第三项分别用维度为(4,1)的矩阵表示,式子的右边也用维度(4,1)的矩阵表示。再看看上面的式子,其实式子左右的第二项和第三项就是矩阵各个元素的乘积了,那还不简单,直接使用矩阵的点乘操作来简化就行了,所以可以得到
注意,符号表示的是点乘的意思
附录
Sigmoid函数的求导证明:https://www.jianshu.com/p/d4301dc529d9
Deeplearning课程矩阵维度总结:https://blog.csdn.net/sansherlock/article/details/82262470
矩阵乘法:http://www.ruanyifeng.com/blog/2015/09/matrix-multiplication.html
矩阵的运算及其运算规则:http://www2.edu-edu.com.cn/lesson_crs78/self/j_0022/soft/ch0605.html
矩阵求导:https://blog.csdn.net/daaikuaichuan/article/details/80620518
矩阵点乘和乘法:https://www.cnblogs.com/liuq/p/9330134.html