大概几个月前就知道吴恩达大神在网易云课堂开课了,一直没有时间(拖延症晚期患者)系统的学习,这次趁着开博热潮尚未褪去,系统的学习一遍Ng大神的讲座实乃不二选择。
深度学习大概是在近三四年逐渐炙手可热的一种算法模型,本质上深度学习就是神经网络构成的,从上世纪五六十年代开始,神经网络一直是学者研究的内容,但相比于传统计算模型,神经网络的参数繁多,严重受阻于计算机硬件处理能力导致算法效率低下,同时存在着一系列算法本身问题例如过拟合,梯度消失等等。近些年,随着半导体硬件(老本行)的发展,计算速度指数级提升,参数训练慢的问题已经得到解决。同时,在AI前景的诱导下,各种新型的结构的提出也使得深度学习蓬勃发展。
Logistic回归是基于线性回归的一种常用分类方法(详细原理在这儿),它最大的优势在与模型简单,可解释性高,输出分类结果的同时还能输出分类的概率值。当然缺点也很多,简单即意味着效果嘛有点差(当然也分场景)。Logistic回归虽然简单,但是却是机器学习以及深度学习中算法的雏形,最经典的神经网络中每个节点的计算其实就是Logistic回归。所以从神经网络的角度再次理解logistic回归就有一种从哪里来到哪里去的感觉。
神经网络的最基本单元如下图所示。
这个标准三层神经网络主要结构包含三层,输入层L1,隐含层L2,输出层L3。中间的连线是各层之间的依赖关系,每一个圆圈成为一个neuron(神经元) ,构成这个神经元的最经典的计算就是logistic回归。所以说logistic回归可以看做是不包括输入层和隐含层的神经网络。
神经网络的主要计算过程其实还是最优化原理的那一套,即给定一个目标函数(cost function),使用梯度下降(或者其他方法)对参数进行迭代计算,使得最终的输出值不断逼近真实值,从而训练出适合训练数据的神经网络。在神经网络的梯度下降过程中,每一轮参数的迭代都可以归纳为两个过程:
- 向前计算损失函数值
- 向后计算参数的梯度(即求导数)
向前和向后这两个过程真是太妙了,把原本数值参数的变化用图的方式动态推演了出来,十分形象。向前过程就是顺着神经网络搭建的过程,一个个逐步计算,最终得到当前的模型输出值,从而能够计算出神经网络的损失函数。向后过程其实是求导法则中的链式法则:
这个很简单,它最大的作用是把计算导数的过程分成了层级,从外向里每一层递进就是神经网络从输出端向输出端递进求导的过程。
用上面的向前向后过程来看logistic回归的训练过程就非常简单了。
以输入数据维度2为例,我们把logistic回归的过程拆分成如下所示
对于这个图,我们就使用上面所说的前向后向计算法进行参数的迭代。
因为梯度下降的迭代(这里特指批量梯度下降)是嵌套两层的,先是对每一条样本数据进行学习,对梯度的下降和损失函数的减少进行累积,这是内循环。外循环是对参数和损失函数进行更新,会乘以一个学习率。我们从两个层次进行前向后向过程的计算。
内循环过程
内循环中,每一条数据分别经过一次前向和一次后向,最终得到结果
dz = a - y
外循环过程
外循环是在内循环执行完之后的后处理过程,做一个增量除以样本个数的操作,并且把前一个外循环的参数值减去这一堆内循环计算的增量与学习率的乘积,最终实现了参数的更新。
完整过程如下图所示。
J = 0, d𝑤1 = 0, d𝑤2 = 0, db = 0
for i = 1 to m:
𝑧(𝑖) = 𝑤𝑇𝑥(𝑖) + 𝑏
𝑎(𝑖) = 𝜎(𝑧(𝑖))
𝐽 += − 𝑦(𝑖)log 𝑎(𝑖) + (1 − 𝑦(𝑖)) log(1 − 𝑎(𝑖))
d𝑧(𝑖) = 𝑎(𝑖) −𝑦(𝑖)
d𝑤1 += 𝑥1(𝑖)d𝑧(𝑖)
d𝑤2 += 𝑥2(𝑖)d𝑧(𝑖)
db += d𝑧(𝑖)
J = J/m, d𝑤1 = d𝑤1/m, d𝑤2 = d𝑤2/m
db = db/m
𝑤1 =𝑤1 -∂d𝑤1
𝑤2 =𝑤2 -∂d𝑤2
当然在这个版块的后半段,Andrew Ng不忘告诉我们,如果你傻傻的按照for循环来实现这个代码,机器会崩溃的。所以为了提升效率,我们按照python里的numpy计算方式对上述过程进行向量化改进,把for循环浓缩成向量的乘积形式,如果再利用GPU的并行计算能力,那简直6的飞起了。
总而言之,logistic回归还是一种非常重要的基础分类算法,利用深度学习过程重新理解logistic回归,不仅过目难忘,而且对于理解更复杂算法十分有益。
终于写完了第一篇正式博客,过程有点累,干扰有点多,但是完成的一瞬间非常开心。下一次希望能写的更好,更多的呈现一些不了解的内容。