UFLDL 是斯坦福大学 CS294A课程 的教学 wiki。课程设置很科学,按部就班,每次课程都是在上次的基础上增添一些东西,还有做业可让你直观地感觉所学内容。虽然没有涉及 RNN (循环神经网络),但做为 CNN(卷积神经网络)的基础课程仍是很不错的。 若是你对 监督学习、逻辑回归、梯度降低 等基础概念并不熟悉,能够先学习 以前的课程。 关于课程做业的 Python 代码已经放到了 Github 上,点击 课程代码 就能去 Github 查看,代码中的错误和改进欢迎你们指出。python
你们知道如今深度学习在计算机视觉领域全面开花结果,获得了许多以前没法想象的好结果。而就在这以前你们还要花费很大的精力来人工设计特征。这部分学习的 稀疏自编码器 正是向自动学习特征迈出的第一步,也是这门课程的基础。( 下图为做业中的神经网络,左图为输入图像,右图为训练后的输出图像 )git
向量化 是在代码中竟可能地使用向量运算来代替原有 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,它的想法是去除输入特征的相关性。首先将特征变换到无相关性的坐标下,经过相关性系数拉伸,再变换到原先的坐标系,使得特征在原先坐标系下再也不相关。( 对于二维特征,整个过程以下图 )网络
在 Softmax 这部分,咱们使用它来为 稀疏自编码器 自学习到的特征来分类,它的特色是输出向量是归一化的( 和为一 )。不过在以前 MNIST分类问题 中,咱们对每一个输出层的神经元使用了逻辑回归( 每一个输出都是二元分类 )。这就产生了一个问题,何时该使用 Softmax,何时使用逻辑回归呢?架构
Ng 告诉咱们问题的关键在于类别之间是否互斥。好比咱们的手写字符识别问题,每一个数字类别是互斥的,你写的数字不可能既是 1 又是 2。若是你的数据可能既属于分类 A 又 属于分类 B,这时候你就须要使用逻辑回归了。机器学习
这时课程开始渐入正题,Ng 告诉咱们 稀疏自编码器 可以本身学习到局部图像的边缘特征,若是使用中间层的输出做为特征再训练一个稀疏自编码器,这时的隐含层会学习如何去组合边,从而构成轮廓、角等更高阶的特征。再加上稀疏自编码器是无监督学习,因此咱们能够反复使用这种方式来构建更深的网络,并在最后对整个网络进行 微调 来高效地完成深层网络的训练。函数
- 使用输入图像训练稀疏自编码器,得到隐含层的权值
- 将隐含层的输出做为特征训练第二层稀疏自编码器
- 将第二层稀疏自编码器隐含层的输出做为特征,原数据的结果目标值,训练 Softmax 分类器
- 微调 整个网络的权值,完成网络的训练
在先前的网络中,隐含层的每一个神经元链接了全部输入层的神经元。当训练图片增大时,所要学习的权值也不断增多,以致于训练速度慢到不可接受。受 视觉皮层的神经元只感觉局部接受信息 的启发( 同时也是天然图像有其固有特性,也就是说,图像的一部分的统计特性与其余部分是同样的 ),咱们可让隐含层只链接一部分的输入单元来提取特征。
好比输入数据是 96x96 的图片,咱们先随机取这些图片中 8x8 的局部图像,用 稀疏自编码器 学习 100 个特征( 隐含层单元及输入的权值,做业中学习到的特征以下图 )。
不难发现,当我在原图上经过卷积提取特征的时候,只有某些位置的激活是最强烈的,因此咱们使用 池化 来减少冗余。池化 就是在卷积输出的每一个区域,使用均值或者最大值来代替原来的输出,它带来的一个好处是提取的特征对图像的平移不敏感。
经过 Coursera 课程,咱们学习了一些基本的 机器学习 算法,对整个领域有了一个大致的认识。UFLDL 课程在它的基础上更近一步,介绍了深度学习中 CNN 的网络架构和学习方法。有了这些基础就不难理解由 CNN 架构演化而来的各类网络( CNN 架构的演进 )。
对于以后要学习的深度学习知识点,一方面考虑学习一下 RNN( 循环神经网络 ),以及基于这个架构演化的用来处理序列的网络;另外一方面考虑学习不一样的学习方法,好比 强化学习。