UFLDL:斯坦福大学深度学习课程总结

UFLDL 是斯坦福大学 CS294A课程 的教学 wiki。课程设置很科学,按部就班,每次课程都是在上次的基础上增添一些东西,还有做业可让你直观地感觉所学内容。虽然没有涉及 RNN (循环神经网络),但做为 CNN(卷积神经网络)的基础课程仍是很不错的。 若是你对 监督学习逻辑回归梯度降低 等基础概念并不熟悉,能够先学习 以前的课程。 关于课程做业的 Python 代码已经放到了 Github 上,点击 课程代码 就能去 Github 查看,代码中的错误和改进欢迎你们指出。python

稀疏自编码器

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

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

对于 稀疏自编码器 详细的学习方法,能够参考 上一篇文章

向量化

向量化 是在代码中竟可能地使用向量运算来代替原有 For 循环。因为可以使用向量运算的库一般对向量运算进行过优化,因此能够大大加速代码的执行速度。github

举一段 反向传播 算法中的例子,它的做用是对于每一组数据运行反向传播并累计偏差。web

for i in range(m):
        d3 = (a3[i] - data[i]) * a3[i] * (1.0 - a3[i])
        d2 = (np.dot(d3,Theta2)[1:] + beta * sparsity_delta) * a2[i][1:] * (1.0 - a2[i][1:])
        delta1 = delta1 + np.dot(d2.reshape(-1,1),a1[[i]])
        delta2 = delta2 + np.dot(d3.reshape(-1,1),a2[[i]])
复制代码

wiki 中有建议将这段代码向量化,不过没有给出具体的伪代码。笔者原觉得最后只剩这部分没改的话对效率也不会有十分大的影响,但事实是向量化以后,学习速度获得了明显的提高 Orz。( 这个章节对于后面的课程能够说是必须的,由于最痛苦的事莫过于学习速度很慢,你的代码又有问题须要从新学习 )算法

d3 = (a3 - data) * a3 * (1.0 - a3)
    d2 = (np.dot(d3, Theta2)[:,1:] + beta * sparsity_delta) * a2[:,1:] * (1.0 - a2[:,1:])
    delta1 = np.dot(d2.T, a1)
    delta2 = np.dot(d3.T, a2)
复制代码

做业将 稀疏自编码器 使用在 MNIST 数据集上,学习到了颇有意思的边缘特征。spring

预处理

课程中使用的预处理为 ZCA Whitening,它的想法是去除输入特征的相关性。首先将特征变换到无相关性的坐标下,经过相关性系数拉伸,再变换到原先的坐标系,使得特征在原先坐标系下再也不相关。( 对于二维特征,整个过程以下图 )网络

事实证实这也是一种视网膜处理图像的粗糙模型。具体而言,当你的眼睛感知图像时,因为一幅图像中相邻的部分在亮度上十分相关,大多数临近的“像素”在眼中被感知为相近的值。所以,若是人眼须要分别传输每一个像素值(经过视觉神经)到大脑中,会很是不划算。取而代之的是,视网膜进行一个与 ZCA 中类似的去相关操做 ( 这是由视网膜上的 ON-型 和 OFF-型 光感觉器细胞将光信号转变为神经信号完成的 )。由此获得对输入图像的更低冗余的表示,并将它传输到大脑。

Softmax

Softmax 这部分,咱们使用它来为 稀疏自编码器 自学习到的特征来分类,它的特色是输出向量是归一化的( 和为一 )。不过在以前 MNIST分类问题 中,咱们对每一个输出层的神经元使用了逻辑回归( 每一个输出都是二元分类 )。这就产生了一个问题,何时该使用 Softmax,何时使用逻辑回归呢?架构

Ng 告诉咱们问题的关键在于类别之间是否互斥。好比咱们的手写字符识别问题,每一个数字类别是互斥的,你写的数字不可能既是 1 又是 2。若是你的数据可能既属于分类 A 又 属于分类 B,这时候你就须要使用逻辑回归了。机器学习

增长深度

这时课程开始渐入正题,Ng 告诉咱们 稀疏自编码器 可以本身学习到局部图像的边缘特征,若是使用中间层的输出做为特征再训练一个稀疏自编码器,这时的隐含层会学习如何去组合边,从而构成轮廓、角等更高阶的特征。再加上稀疏自编码器是无监督学习,因此咱们能够反复使用这种方式来构建更深的网络,并在最后对整个网络进行 微调 来高效地完成深层网络的训练。函数

上图是做业中训练的网络,它的整个训练步骤以下:

  1. 使用输入图像训练稀疏自编码器,得到隐含层的权值
  2. 将隐含层的输出做为特征训练第二层稀疏自编码器
  3. 将第二层稀疏自编码器隐含层的输出做为特征,原数据的结果目标值,训练 Softmax 分类器
  4. 微调 整个网络的权值,完成网络的训练

大图像处理

在先前的网络中,隐含层的每一个神经元链接了全部输入层的神经元。当训练图片增大时,所要学习的权值也不断增多,以致于训练速度慢到不可接受。受 视觉皮层的神经元只感觉局部接受信息 的启发( 同时也是天然图像有其固有特性,也就是说,图像的一部分的统计特性与其余部分是同样的 ),咱们可让隐含层只链接一部分的输入单元来提取特征。

好比输入数据是 96x96 的图片,咱们先随机取这些图片中 8x8 的局部图像,用 稀疏自编码器 学习 100 个特征( 隐含层单元及输入的权值,做业中学习到的特征以下图 )。

而后使用每一个隐含层神经元,对原图的每一个部分作特征提取( 这个过程至关于对原图像作 卷积 的操做,以下图 )。对于每张 96x96 的图像,咱们将获得 100 个 89x89 的卷积特征图像,用于后续处理。

不难发现,当我在原图上经过卷积提取特征的时候,只有某些位置的激活是最强烈的,因此咱们使用 池化 来减少冗余。池化 就是在卷积输出的每一个区域,使用均值或者最大值来代替原来的输出,它带来的一个好处是提取的特征对图像的平移不敏感。

通过上述 卷积池化 的处理,特征数量已经大幅减小。最后咱们使用这些特征来训练 Softmax 分类器。

后续

经过 Coursera 课程,咱们学习了一些基本的 机器学习 算法,对整个领域有了一个大致的认识。UFLDL 课程在它的基础上更近一步,介绍了深度学习中 CNN 的网络架构和学习方法。有了这些基础就不难理解由 CNN 架构演化而来的各类网络( CNN 架构的演进 )。

对于以后要学习的深度学习知识点,一方面考虑学习一下 RNN( 循环神经网络 ),以及基于这个架构演化的用来处理序列的网络;另外一方面考虑学习不一样的学习方法,好比 强化学习

相关文章
相关标签/搜索