UFLDL:稀疏自编码器

吴恩达的 CS294A 是一门很好的深度学习入门课程,打算接下来的学习以这个课程的内容为主。UFLDL Tutorial 是 CS294A 课程的 wiki 页,包含了课程讲义和做业。若是你对 监督学习逻辑回归梯度降低 等基础概念并不熟悉,能够先学习 以前的课程php

关于课程做业的 Python 代码已经放到了 Github 上,点击 课程代码 就能去 Github 查看( 没法访问 Github 的话能够点击 Coding 查看 ),代码中的错误和改进欢迎你们指出。git

稀疏自编码器

你们知道如今深度学习在计算机视觉领域全面开花结果,获得了许多以前没法想象的好结果。而就在这以前你们还要花费很大的精力来人工设计特征。下面要学习的 稀疏自编码器 正是向自动学习特征迈出的第一步。( 下图为做业中的神经网络,左图为输入图像,右图为训练后的输出图像 )github

稀疏自编码器 的基本模型是一个三层的神经网络,在学习时让网络输出的目标值接近于输入的图像自己,从而学习图像中的特征。直接学习一个恒等函数的话没有什么意义,因此咱们要对隐含层作出一些限制,好比减少神经元的个数,网络就会被迫压缩数据并尝试重建输入图像。当咱们加入惩罚让神经元在大部分状况下都不激活的时候,网络可以学习到十分有趣的边缘特征。隐含层的神经元在观察到输入图像中某个特定角度的边缘特征时才会被激活( 这和神经科学发现的人类视觉皮层V1中的神经元的激活方式类似 )。

代价函数

根据机器学习的通常模式,首先给出 稀疏自编码器 的代价函数:web

J_{sparse}(W,b)= \frac{1}{m}\sum\limits_{i=1}^{m}\big(\frac{1}{2}||h_{W,b}(x^{(i)})-y^{(i)}||^2\big)
+ \frac{\lambda}{2}\sum\limits_{l=1}^{L-1}\sum\limits_{i=1}^{s_l}\sum\limits_{j=1}^{s_{l+1}}\big(\Theta_{ji}^{(l)}\big)^2 \\
+ \beta\sum\limits_{j=1}^{s_2}KL(\rho||\hat\rho_j)

比起熟悉的前两项,代价函数新增了对于隐含层的惩罚,式中 s_2 表示隐含层的神经元个数。\hat\rho_j 表示 隐含层神经元 j 对于全部训练数据的平均激活度,\hat\rho_j=\sum\limits_{i=1}^{m}\big[a_j^{(2)}(x^{(i)})\big]( 注意这里的 a_j^{(2)}(x) 表示一个函数,值为数据 x 对应的 a_j^{(2)} ),\rho\hat\rho_j 的目标值,目的就是以前说的让神经元在大多数时间不激活。算法

按照 Ng 的说法,新的惩罚项有多种函数能够选择,而这里用来衡量 \rho\hat\rho_j 差别的度量为 KL \ divergence 又称为 相对熵,定义为:网络

KL(P||Q) = \sum\limits_{i}P(i)log\Big(\frac{Q(i)}{P(i)}\Big)

它所度量的是两个几率分布间的距离( 我也不是太懂,有机会再作深刻的研究 )。 有了代价函数,接下来看下原先的反向传播算法有什么变化~机器学习

梯度降低

在以前 反向传播算法 课程中已经说过它该算法的两个重点,一个是它的目的:更快速地计算代价函数的梯度,另外一个是它的计算依赖于多元函数求导的链式法则。函数

因为代价函数的增长项直接为隐含层的函数,因此隐含层的偏差:学习

\delta^{(2)}_j = \frac{\partial J_{sparse}}{\partial z^{(2)}_j} = \frac{\partial J}{\partial z^{(2)}_j} + \frac{\partial KL}{\partial z^{(2)}_j}

其中后一项可化为:优化

\frac{\partial KL}{\partial z^{(2)}_j}= \sum\limits_{k=1}^{s_{2}} \frac{\partial KL}{\partial a_k^{(2)}} \frac{\partial a_k^{(2)}}{\partial z^{(2)}_j} = \beta\Big(-\frac{\rho}{\hat\rho_j}+\frac{1-\rho}{1-\hat\rho_j}\Big)g'(z^{(2)}_j)

所以 反向传播算法 中的 \delta^{(2)}_j 计算变为:

\delta^{(2)}_j = \Big(\sum\limits_{k=1}^{s_3} \Theta_{kj}^{(2)} \delta^{(3)}_k +\Big(-\frac{\rho}{\hat\rho_j}+\frac{1-\rho}{1-\hat\rho_j}\Big)\Big)a_j^{(2)} (1-a_j^{(2)})

其他的计算都和原先的算法相同。 搞定代价函数和梯度计算,剩下的就是调用带优化的梯度降低算法了~

可视化

最后稍微提下课程做业,它让咱们在 10 张风景图片中随机取 10000 个 8x8 的局部图,而后让稀疏自编码器学习其中的特征。神经网络的隐含层神经元个数为 25,输入输出维度都为 64。下图为每一个隐含层神经元对应的输入层权重,大体可当作该神经元检测到这种特征时会被激活。( tip: 做业中的学习算法和梯度检查函数在以前的课程中都写过,所以能够直接拿来用。 )

So~,稀疏自编码器的内容就是这些了,谢谢你们耐心阅读。

P.S. 封面图为猴子视觉皮层 V1 区的方向柱