引言
Auto-encoder 包括两个过程:
- Encoder(编码器)
- Decoder(解码器)
Encoder+Decoder的组合,吴恩达在讲RNN机器翻译的时候就讲到过:“编码网络”(encoder network)做的事情就是对原始数据进行压缩降维,形成一个精简的 f e a t u r e s v e c t o r features\ vector features vector,“解码网络”(decoder network)做的事情就是对压缩过后的 f e a t u r e s v e c t o r features\ vector features vector进行信息提取,输出对应的翻译文本。
但是Encoder和Decoder都是无监督学习;即对于encoder network的学习,我们只能提供输入,不能提供output( f e a t u r e s v e c t o r features\ vector features vector);同理,对于decoder network,只能提供output(正确的翻译文本),不能提供input( f e a t u r e s v e c t o r features\ vector features vector)。
以手写数字识别为例子,如下图;对于上面的Encoder过程,只能提供 i n p u t i m a g e input\ image input image,而对于输出 c o d e code code我们并不能提供;对于下面的Decoder过程,只能提供 o u t p u t i m a g e output\ image output image,而对于输入 c o d e code code我们并不能提供;
因此Encoder和Decoder不能够分开单独训练,需要将它们连接起来,同时对Encoder和Decoder进行训练;此时网络的输入和输出都是我们现有的手写数据集 i a m g e iamge iamge了,压缩后的 f e a t u r e s v e c t o r features\ vector features vector只需要从中间的隐藏层去获取。
之前的PCA降维也可以看作是Auto-encoder,它类似于只有一个linear hidden layer的神经网络;压缩提取的信息 f e a t u r e s v e c t o r features\ vector features vector就是各 c o m p o n e n t component component的权重,输出就是 x ^ \hat{x} x^。( x ^ \hat{x} x^是用 c o m p o n e n t component component近似 x x x的结果,即 x ≈ x ^ x≈\hat{x} x≈x^)
接下来Auto-encoder的训练过程就是最小化 ( x − x ^ ) 2 (x-\hat{x})^2 (x−x^)2,如下图所示:
这里的encode的 W W W和decode W T W^T WT是转置的关系,因为 x ≈ W c = x ^ x≈Wc=\hat{x} x≈Wc=x^,W是正交矩阵, W W T = E WW^T=E WWT=E,所以 W T x ≈ c W^Tx≈c WTx≈c。因此是互为转置的关系。
因为Auto-encoder通常是两头宽中间窄的结构,所以中间的 h i d d e n l a y e r hidden\ layer hidden layer通常叫做瓶颈层(Bottleneck later)。
PCA是具有一个 h i d d e n l a y e r hidden\ layer hidden layer的Auto-encoder,而Deep Auto-encoder是一个具有更多 h i d d e n l a y e r hidden\ layer hidden layer的Auto-encoder。下图就是一个Deep Auto-encoder,中间的 b o t t l e bottle bottle就是瓶颈层,也是压缩后的 f e a t u r e v e c t o r feature\ vector feature vector。
如果按照之前
P
C
A
PCA
PCA的思路,Deep Auto-encoder中的encode的
W
i
W_i
Wi与decoder的
W
i
T
W_i^T
WiT应该一致对应的关系;这可以通过赋予相同的初始值做到,好处在于可以减少一半的参数,有效避免过拟合。
但在实际操作中没必要这样做,可以直接对网络进行训练不用确保encode与decoder的参数要一致。
下图是使用PCA和Deep Auto-encoder对手写数字数据集进行编码和解码的结果,可以看出Deep Auto-encoder的效果会更改一些。
分别使用PCA和Deep Auto-encoder对手写数字数据集将手写数据集降维到2维进行可视化,结果如下:
可以看出,PCA降维的结果不同类别的数据会混杂在一起,而Deep Auto-encoder会将不同类别的数据分开。
De-noising auto-encoder
还有一种auto-encoder叫做De-noising auto-encoder(自动去噪编码器);它与之前的auto-encoder不同在于会对输入加入一些噪音,如下图:
这里需要注意的是,最后的目标是让 x x x和 x ^ \hat{x} x^尽可能的相近,而不是加了噪音后的 x ′ x' x′。这样编码器就会学习到如何过滤噪声这件事。
Text Retrieval
auto-encoder可以应用于Text Retrieval(文本检索)。
在Text Retrieval任务中,会将需要dataset中的文本压缩表示成
V
e
c
t
o
r
S
p
a
c
e
Vector\ Space
Vector Space中的一个
v
e
c
t
o
r
vector
vector;同时将用户检索的词汇
q
u
e
r
y
query
query也压缩表示成
V
e
c
t
o
r
S
p
a
c
e
Vector\ Space
Vector Space中的一个
v
e
c
t
o
r
vector
vector。
然后计算 q u e r y query query和dataset中的文本的相似度,这里的相似度可以使用内积或者余弦相似度(cos-similarity);选取最相似的文本作为检索返回即可。
Text Retrieval的表现好坏与dataset中的文本和 q u e r y query query转换成 v e c t o r vector vector后,是否能够有效的表示原来的的信息相关。
Bag-of-word
其中一种获取 v e c t o r vector vector方法就是Bag-of-word。
v e c t o r vector vector的维度与词汇总数相同,某一维的原始值表示该词汇在文本中出现的次数;此外还可以为各维添加相应的权重,常用词乘上较低的权重,以降低常用词的重要性。
Bag-of-word缺点在于不能捕捉semantic(语义),因为词与词之间是独立,没有联系的。例如不能够捕捉到“台大”和“台湾大学”其实是一个东西。但auto-encoder可以做到这件事。
auto-encoder and Bag-of-word
Bag-of-word直接表示文章的效果不太好,但是可以将它当作auto-encoder的输入,通过auto-encoder压缩来获取有效的 v e c t o r vector vector。
如下图,将Bag-of-word作为encode的输入,为了可视化,这里压缩到2维。
可视化结果如下,每个点都代表一个文本,相同的颜色代表同类型的文本。在进行文本检索时,将用户的检索关键词 q u e r y query query投影到这个二维空间,找出相似度最接近的文本即可。
之前矩阵分解中讲到的LSA对文本进行压缩可视化的结果如下:
可以看出效果并没有那么好。
Similar Image Search
auto-encoder可以应用于Similar Image Search(图像检索)上。
如果对于图像的检索直接使用像素( p i x e l pixel pixel)进行计算,效果会非常的差。如下图,对MJ使用像素来检索最相似的图片,得到的结果并不是并不好。
正确的做法是先使用auto-encoder对图像进行信息提取,压缩成一个 v e c t o r vector vector;在将压缩后的 v e c t o r vector vector作为检索的输入。
encoder过程如下图所示:
对压缩的
v
e
c
t
o
r
vector
vector进行解码,原图与解码后的结果如下图;可以看出压缩后的
v
e
c
t
o
r
vector
vector能够有效的保留原图片的重要信息。
下图是使用压缩后的 v e c t o r vector vector检索到的结果,与之前相比表现显著提升,检索到的都是人脸了。
使用auto-encoder先对图像进行压缩的好处:
- Auto-encoder可以通过降维提取出一张图像中最有用的特征信息,包括pixel与pixel之间的关系
- 降维之后数据的size变小了,这意味着模型所需的参数也变少了,同样的数据量对参数更少的模型来说,可以训练出更精确的结果,一定程度上避免了过拟合的发生
- Auto-encoder是一个无监督学习的方法,数据不需要人工打上标签,这意味着我们只需简单处理就可以获得大量的可用数据
Pre-training DNN
在神经网络的训练中,一般会使用pre-training来初始化参数;Auto-encoder可以应用于神经网络的参数预训练的过程。
重新训练所有权重系数,初始始参数值由之前的模型训练得到,这一过程称为pre-training(预训练);之后,不断调试、优化的过程称为fine-tuning(微调)。
我们要对下图的神经网络进行初始化参数:
流程如下:
首先先对第一层 h i d d e n l a y e r hidden\ layer hidden layer使用Auto-encoder进行预训练:
根据第一层 h i d d e n l a y e r hidden\ layer hidden layer构建一个Auto-encoder模型:
对这个Auto-encoder模型进行训练,得到参数
W
1
W^1
W1,然后固定
W
1
W^1
W1不改动。
需要注意的是,输入 784 784 784升维到 1000 1000 1000再降维到 784 784 784维,这里的升维的过程可能会出现编码前后原封不动的情况。
为此,可以为瓶颈层添加正则项,使瓶颈层的输出值得分布尽可能的分散。
然后根据第二层
h
i
d
d
e
n
l
a
y
e
r
hidden\ layer
hidden layer构建一个Auto-encoder模型:
注意这里得
W
1
W^1
W1是固定不变的,
x
x
x通过
W
1
W^1
W1得到这个Auto-encoder模型的输入。
对这个Auto-encoder模型进行训练,得到参数 W 2 W^2 W2,然后固定 W 2 W^2 W2不改动。
后面同理,根据第三层
h
i
d
d
e
n
l
a
y
e
r
hidden\ layer
hidden layer构建一个Auto-encoder模型:
对这个Auto-encoder模型进行训练,得到参数
W
3
W^3
W3,然后固定
W
3
W^3
W3不改动。
接下来将 W 1 、 W 2 、 W 3 W^1、W^2、W^3 W1、W2、W3用于神经网络参数的预训练,第四层的 W 4 W^4 W4进行随机初始化参数,如下图;接下来需要对整个神经网模型进行反向传播,因为 W 1 、 W 2 、 W 3 W^1、W^2、W^3 W1、W2、W3都是比较好的参数了,在训练过程中只需要进行微调。
W 4 W^4 W4随机初始化的原因:
【个人理解】
前面几层的工作类是于特征提取,例如进行人脸识别,前面几层的工作就是找到人的嘴巴、耳朵和鼻子。
而最后一层是任务的输出,对于Auto-encoder模型来说,最后一层的任务是将前几层提取到的人的嘴巴、耳朵和鼻子组合成一个和输入很像的人脸。
但是神经网络中的任务并不是这个,假设神经网络的任务是识别是否存在人脸;这时候 W 4 W^4 W4也进行预训练,这其实是无效的,因为Auto-encoder模型的任务和神经网络的任务不一样,再训练的过程中还是会进行大幅度的调整。
而对于 W 1 、 W 2 、 W 3 W^1、W^2、W^3 W1、W2、W3,神经网络是可以使用这些参数完成任务的,所以在训练时只需要进行微调。
Auto-encoder for CNN
当我们处理的对象是图片时,那就需要和 C N N CNN CNN打交道了,所以下面讨论Auto-encoder for CNN。
对于神经网络需要编码网络和解码网络,那么对于CNN网络需要卷积层、池化层和反卷积层、反池化层。如下图:
什么是反卷积层(Deconvolution)和反池化层(Unpooling)呢?
Unpooling:
池化的过程是将窗口中最大的值保留其余去除,那么反池化层就是记住保留值的的值和位置,再将值恢复到(放大的)窗口原来的位置,其余被去除的值以0补充 (还有一种做法是其余位置也以保留值来补充);如下图:
Deconvolution:
反卷积层其实就是卷积层。
以一维的卷积和反卷积为例,假设卷积层的输入是5维,卷积核的大小是3;那么卷积层的计算过程(每三个输入都进行一次卷积运算)如下图所示:
可以看到,这是三个值缩成一个值的过程,那么但卷积层就是一个值扩大成三个值的过程(重叠的点采取相加操作),如下图:
我们对上图的输入进行补0操作,如下图;可以看到反卷积层其实就是一个卷积层。
卷积和反卷积的不同点在于:
反卷积需要补零,且反卷积的权重与卷积的权重是相反的( 卷积过程中,依次是橙线、蓝线、绿线,反卷积过程中,依次是绿线、蓝线、橙线)
在实践中,做去卷积操作的时候直接加上一个卷积层就行。
use decoder to generate something
以手写数据集为例,对Auto-encoder训练完后,取出
D
e
c
o
d
e
r
Decoder
Decoder部分,输入
c
o
d
e
code
code是可以得到一张图片的;如下图:
根据这个想法,将手写数据集先压缩降维到二维平面上,可视化结果如下:
然后对红框部分进行均匀采样输入到
N
N
D
e
c
o
d
e
r
NN\ Decoder
NN Decoder中,输出的图片如下图所示:
可以看到产生了很多新的数字图片,左上角有点像0又像2是因为红框的左上角部分并不存在数据样本;那么怎么确保红框选取的位置会有样本点的存在呢?如果红框取在右下角,输出的效果就不会太好了。
为此可以为 c o d e code code添加上正则项,让 c o d e code code的值集中在0附近,然后以0为中心去随机采取样本点即可。