深度学习UFLDL教程翻译之自动编码器

一、自动编码器

目前为止,我们介绍了神经网络在有标签的训练样本的有监督学习中的应用.现在假设我们只有一个未标记的训练集{x(1),x(2),x(3),…},其中x是n维的.自动编码器神经网络是一种采用反向传播的无监督学习算法,让目标值和输入相等,即让y(i)=x(i).

这是一个自动编码器:

自动编码器试图学习函数hW,b(x)≈x.换句话说,它试图学习恒等函数的逼近,使得输出x^与x类似.这个将要学习的恒等函数看起来是个特别无关紧要的函数;但通过在网络中做些限制,例如限制隐藏单元的个数,我们可以发现数据中的有趣结构.具体地说,假设输入x是10*10图像的像素强度值,n=100,然后L2层有s2=50个隐藏单元.注意到y也是100维的.既然只有50个隐藏单元,网络不得不学习输入的一个“压缩”表示,即给定隐藏单元的激活值a(2)只有50维,它必须“重构”100个像素的输入.如果输入是完全随机的,即每个xi与其它特征值是高斯独立同分布的,那么这次压缩任务会非常困难.但是如果数据中包含结构,例如如果一些输入特征是相关的,那么这个算法可以发现这些相关性.事实上,这个简单的编码器经常用于学习低维度表示,很像PCA(主成份分析).

以上的论点是根据隐藏层单元小数目s2.不过即使当隐藏层单元数目大时(也许甚至比输入像素数目还大),通过对网络施加其它限制,我们依旧能发现有趣的结构.特别的,如果我们对隐藏层单元施加“稀疏”的限制,那么我们依旧在数据中能发现有趣的结构,即使隐藏层单元数目多.

非正式地说,我们会认为神经元是“激活的”(或者“点着了”),如果它的输出接近1;或者“未激活”如果它的输出接近0.我们希望限制神经元在大部分时间是未激活的状态.这个讨论假设用的是sigmoid激活函数.如果你使用tanh激活函数,我们会认为神经元是未激活的,如果它的输出接近-1.

回忆一下aj(2)表示自动编码器隐藏单元j的激活值.然而,这样的表示不能搞清楚引起激活值的输入x是什么.这样,我们会用aj(2)(x)表示当网络给定输入是x时该隐藏单元的激活值.

进一步,令

是隐藏单元j的平均激活值(在训练集上取平均).我们可以(近似)实施限制ρ^j=ρ,其中ρ是一个“稀疏参数”,典型值接近0的小值(例如ρ=0.05).换句话说,我们希望每个隐藏单元j的平均激活值接近0.05(假设).为了满足这个限制,隐藏单元的大多数激活值都必须接近0.

为了实现,我们往我们的优化目标添加一个额外的惩罚项,惩罚ρ^j对ρ的偏离程度.惩罚项的许多选择都能得到合理的结果.我们选择以下形式:

这里,s2是隐藏层的神经元数目,下标j对网络中的隐藏单元求和.如果你熟悉KL分解的概念,这个惩罚项就是基于此,也可以写为

其中KL(ρ||ρ^j)=ρlogρ/ρ^j+(1?ρ)log1?ρ/1?ρ^j是伯努力随机变量——平均值ρ和ρ^j间的Kullback-Leibler(KL)分解。KL分解是衡量两个不同的分布有多不同。(如果你之前还没有见过KL分解,别担心;你需要了解的所有东西都在这节中。)

惩罚函数有这样的性质,如果ρ^j=ρ,则KL(ρ||ρ^j)=0,否则会随着ρ^j和ρ的偏离程度单调递增。例如,在下面的图中,我们令ρ=0.2,我们画出关于取一定范围ρ^j,KL(ρ||ρ^j)的值。

我们看到KL分解在ρ^j=ρ处取得最小值0.并随着ρ^j接近0或1而迅速增大(实际上趋于无穷大).因此,最小化这一惩罚项使得ρ^j接近ρ.

我们目前的全局代价函数是

其中J(W,b)之前定义过了,β控制稀疏惩罚项的权重。ρ^j项也(隐性地)依赖W,b,因为它是隐藏单元j的平均激活值,而隐藏单元的激活值依赖参数W和b。

为了让KL分解项包含到你的导数计算中,有一种易于实现的技巧,只需要对你的代码做小的改变。具体而言,之前在第二层(l=2)中,在反向传播过程中你将会计算:

取而代之的是计算

一个微妙的地方是你需要知道ρ^i来计算这项。那么,你就首先需要在所有训练样本计算前向传播,从而计算训练集上的平均激活值,然后再从任一样本中计算反向传播。如果你的训练集足够小,能够很好地满足计算机内存(这对编程任务而言也是一样的),你可以在所有样本上计算前向传播,并将激活值结果保存在内存中然后计算ρ^i。然后你可以用之前计算的激活值在所有样本上计算反向传播。如果你的数据太多内存装不下,你只能浏览所有的样本,在每个样本上计算前向传播然后将激活值累积(求和)然后计算ρ^i(一旦你用激活值ai(2)计算完ρ^i,便丢弃每次计算前向传播的结果)。然后计算完ρ^i后,你再对每个样本做一次前向传播计算以便你能够在那个样本上做反向传播。在后面这种情况,你会在训练集的每个样本计算两次前向传播结束,使得计算效率较差。

以上的算法得到梯度下降的完整推导已经超出了这节的篇幅。不过如果你使用修改后的反向传播实现自动编码器,你将在目标函数Jsparse(W,b)上计算梯度下降。使用导数检验的方法,你也可以自己验证。

二、可视化训练好的自动编码器

训练好(稀疏)自动编码器后,我们想要可视化这个算法学习的函数,并理解它学习了什么。考虑在10×10图像上训练的自动编码器,因此n=100。每个隐藏单元i计算输入的函数:

我们会使用2D图像将通过隐藏单元i计算的函数可视化——依赖参数Wij(1)(这里忽略偏置项)。特别地,我们认为ai(2)是输入x的一些非线性的特征。我们会问:是什么样的输入图像x能让ai(2)最大程度激活?(不是很正式地说,隐藏单元i在寻找什么样的特征?)为了得到这个不是无关紧要的问题的回答,我们需要在x上施加一些限制。如果我们假设输入被||x||2=∑xi2≤1标准化限制,那么我们可以看到(尝试自己完成)最大化地激活隐藏单元i的输入是由按如下方式设置像素xj给定的(对全部100像素而言,j为1到100):

通过将由这些像素强度值填充的图像显示出来,我们可以开始理解隐藏单元i在寻找什么样的特征。

如果我们有一个包含100个(举例)隐藏单元的自动编码器,那么我们的可视化图像将得到100幅这样的图像——一个代表一个隐藏单元。通过检查这100幅图像,我们能尝试理解隐藏单元在学习一个什么集合。

当我们对一个稀疏自编码器这么做(用建立在10×10像素输入上的100个隐藏单元训练),我们会得到如下结果(每个图像10*10代表一个隐藏单元,共100个隐藏单元):

上图中的每个方块展示了(用标准化界定的)输入图像x,它最大化地激活了100个隐藏单元的其中一个。我们发现不同的隐藏单元在学习检测图像中不同位置和方向的边缘。

这些特征,不惊奇地,对于像目标识别和其它视觉任务等是非常有用的。当应用到其它输入领域(例如音频),这个算法同样学习对这些领域有用的表示/特征。

这些学习到的特征是通过训练“白化的”自然图像得到的。白化是去除输入冗余度的预处理步骤,使相邻的像素点变得更不相关。

时间: 2024-12-15 05:07:08

深度学习UFLDL教程翻译之自动编码器的相关文章

深度学习UFLDL教程翻译之PCA白化

一.引入 主成分分析(PCA)是一种降维算法,能大大加速你的无监督特征学习算法.更重要的是,理解PCA能让我们后面实现白化,这是一个对所有算法适用的重要的预处理步骤. 假设你在图像上训练你的算法.不过输入稍微有点冗余,因为图像中相邻的像素值是高度相关的.具体来说,假设我们在16*16的灰度图像块上训练.那么x∈R256是256维的向量,一个特征xj对应着图像中每个像素强度.由于相邻像素之间的相关性,PCA使我们能够以一个维数小得多的输入来近似原输入,而造成误差极小. 二.例子与数学背景 对我们运

Deep Learning 十_深度学习UFLDL教程:Convolution and Pooling_exercise(斯坦福大学深度学习教程)

前言 理论知识:UFLDL教程和http://www.cnblogs.com/tornadomeet/archive/2013/04/09/3009830.html 实验环境:win7, matlab2015b,16G内存,2T机械硬盘 实验内容:Exercise:Convolution and Pooling.从2000张64*64的RGB图片(它是the STL10 Dataset的一个子集)中提取特征作为训练数据集,训练softmax分类器,然后从3200张64*64的RGB图片(它是th

Deep Learning 12_深度学习UFLDL教程:Sparse Coding_exercise(斯坦福大学深度学习教程)

前言 理论知识:UFLDL教程.Deep learning:二十六(Sparse coding简单理解).Deep learning:二十七(Sparse coding中关于矩阵的范数求导).Deep learning:二十九(Sparse coding练习) 实验环境:win7, matlab2015b,16G内存,2T机械硬盘 本节实验比较不好理解也不好做,我看很多人最后也没得出好的结果,所以得花时间仔细理解才行. 实验内容:Exercise:Sparse Coding.从10张512*51

Deep Learning九之深度学习UFLDL教程:linear decoder_exercise(斯坦福大学深度学习教程)

前言 实验内容:Exercise:Learning color features with Sparse Autoencoders.即:利用线性解码器,从100000张8*8的RGB图像块中提取彩色特征,这些特征会被用于下一节的练习 理论知识:线性解码器和http://www.cnblogs.com/tornadomeet/archive/2013/04/08/3007435.html 实验基础说明: 1.为什么要用线性解码器,而不用前面用过的栈式自编码器等?即:线性解码器的作用? 这一点,Ng

Deep Learning 十一_深度学习UFLDL教程:数据预处理(斯坦福大学深度学习教程)

理论知识:UFLDL数据预处理和http://www.cnblogs.com/tornadomeet/archive/2013/04/20/3033149.html 数据预处理是深度学习中非常重要的一步!如果说原始数据的获得,是深度学习中最重要的一步,那么获得原始数据之后对它的预处理更是重要的一部分. 1.数据预处理的方法: ①数据归一化: 简单缩放:对数据的每一个维度的值进行重新调节,使其在 [0,1]或[ − 1,1] 的区间内 逐样本均值消减:在每个样本上减去数据的统计平均值,用于平稳的数

从统计学角度来看深度学习(2):自动编码器和自由能

从统计学角度来看深度学习(2):自动编码器和自由能 原文链接:http://blog.shakirm.com/2015/03/a-statistical-view-of-deep-learning-ii-auto-encoders-and-free-energy/ 作者:Shakir Mohamed  翻译:钟琰    审校:何通    编辑:王小宁 本文得到了原英文作者Shakir Mohamed的授权同意,由钟琰翻译.何通审校.感谢他们的支持和帮助. 基于前馈深度神经网络的判别模型已经在许多

基于TensorFlow的深度学习系列教程 2——常量Constant

前面介绍过了Tensorflow的基本概念,比如如何使用tensorboard查看计算图.本篇则着重介绍和整理下Constant相关的内容. 基于TensorFlow的深度学习系列教程 1--Hello World! 常量的概念 在tensorflow中,数据分为几种类型: 常量Constant.变量Variable.占位符Placeholder.其中: 常量:用于存储一些不变的数值,在计算图创建的时候,调用初始化方法时,直接保存在计算图中 变量:模型训练的参数,比如全连接里面的W和bias 占

Linux 搭建深度学习环境教程

Linux 搭建深度学习环境教程 Notes: ? 开门见山:使用 Anaconda 直接搞定 Linux Nvidia 驱动这个千年难题 ? 重点: 关于这个问题,今天我来总结一篇专治头疼的药方:只需要安装 Anaconda ,使用 conda 安装 Pytorch 或者 Tensorflow-gpu 即可. conda 会自动帮助我们安装好几乎所有必需的驱动,可谓是一键式安装,简直是我等"菜鸡"们的福音!!! I Love Anaconda ?????? 1. Linux 发行版选

深度学习UFLDL老教程笔记1 稀疏自编码器Ⅱ

稀疏自编码器的学习结构: 稀疏自编码器Ⅰ: 神经网络 反向传导算法 梯度检验与高级优化 稀疏自编码器Ⅱ: 自编码算法与稀疏性 可视化自编码器训练结果 Exercise: Sparse Autoencoder 自编码算法与稀疏性 已经讨论了神经网络在有监督学习中的应用,其中训练样本是有类别标签的(x_i,y_i). 自编码神经网络是一种无监督学习算法,它使用了反向传播算法,并让目标值等于输入值x_i = y_i . 下图是一个自编码神经网络的示例. 一次autoencoder学习,结构三层:输入层