我们先讲讲编码器,就比如我们拿手写数字图片,我们输入28*28维图片,通过编码器,使其变成降维后的编码(反应其某些特性),不过因为我们常常不知道这个code应该长什么样,所以无法训练;我们也可以考虑输入一个code,通过解码器,输出图片,但是这个单独也无法训练,于是我们就考虑将2者结合起来一起训练。
我们之前介绍过PCA,我们要求最小化,我们就可以将x与权重矩阵W的乘积送到隐层,得到输出c,再通过乘以W的转置得到,我们使其最接近,这无形中就是形成了编码和解码的部分,隐层输出就是我们要的code,因为隐层的维度比小,也常常叫做瓶颈层
当然,我们的auto-encoder可以是deep的,我们要求前后对称的层神经元数量一样,我们看PCA那个也许就会想,我们的auto-encoder也是对称的矩阵是互为转置的,的确,这可以省一半参数,但实际我们往往不管这些直接train.
以手写数字为例,做了PCA降到30维,我们的输出图片是比较模糊的,但是深层自动解码就清晰多了
我们把784维PCA做到2维再还原,其2维分布是比较混杂的,而深层解码后分布是有较明显界限的
我们可以看下自动解码在文本搜索的应用,Vector Space Model,根据不同的文档,创建不同的向量,当我们要查询的文档,和目标文档有较大相似度(算内积)时,输出对应文档
我们文档向量采用bag-of-word即文档有多少词汇,这个向量就有多少维,然而这种处理并不能实现语义的分析,因为向量每个词的维度是独立的
比如我们处理将2000词的向量处理成2维,效果如右上,而我们通过LSA分成2维时,并没有很好的效果
我们自动编码还可用于图片相似搜索,但是用迈克尔杰克逊的一张图片可能搜索到马蹄铁等诡异的东西
自动相似图片搜索,我们可以采用深度学习,网络足够深,足够多神经元后,编码解码得到的图片如图
我们用多层网络后,我们识别图片就比较近似了,起码都是人= =
我们还可以用auto-encoder来预训练DNN得参数,使得DNN起始参数比较好,比如我们要训练图左侧的神经网络,我们会现在右侧训练784-100-784的encoder,然后留住w1固定(这里要注意的是,784-1000的时候因为是升维,我们可能需要引入L1正则使只能某几维有输出,否则可能直接就把784送过去,其他都是0)
再之后我们训练784-1000-1000-1000的网络,使彼此接近,然后同理留出W2固定
我们训练好各系数后,再用反向传播,微调下各系数(因为各系数本身已经很好了),我们以前经常通过auto-encoder调各层参数,但是现在其实不用auto-encoder也能将参数调的很好了
我们自动解码的衍生有De-noising auto-encoder,其原理时,我们将输入x加入噪声变成x',然后使输出和加噪声前接近,这样我们训练出的模型就具备了去噪声的能力。
还一个是Contractive auto-encoder,思维和上一个类似,是当输入改变时,输出变化比较小
老师还列举了2个不是DNN的模型,有兴趣自己查= =
我们知道CNN有卷积池化,但是用auto-encoder怎么做呢,就是使用反池化,反卷积层使输出和输入接近
我们先讲unpooling,我们都知道池化会将图片缩小,比如4*4的图片经2*2池化后,就变成2*2,其中一种方法就是我们记住原来最大值的位置,反池化时将图片扩大的同时,将对应位置设为池化值,其他置0。keras上面用的方法就是我们不记住原来的位置,直接将对应位置的池化值填4个位置
我们反卷积的过程实际上就是在做卷积,比如下图我们经过权重红绿蓝将5维变成3维,然后想将三维变成5维,就将每个维度乘权重,有叠加的位置相加,其实这个结果就和右侧我们做卷积一样(补上了0位)
我们之前说过encoder有其单独用处,其实decoder也有单独用处,比如我们手写数字,我们输入不同的code就能得到不同的图片,图中是通过红色方框区域等距取点得到的结果,我们为什么只在红色区域取呢,因为我们其他位置可能得不到图片(如果你想得到图片,就需要加上L2正则)
我们正则后,就可以选择大区域,就有了新的图片,而且能发现一定规律,做导游越来越瘦,上到下越来越斜等等