自编码(Auto-encoders)
1、什么是自编码
自编码神经网络是一种无监督的学习算法,可学到输入数据的高效表示。输入数据的这一高效表示称为编码(codings),其维度一般小于输入数据,使得自编码用于降维;自编码器还可作为强大的特征检测器(feature detectors),应用于深度神经网络的预训练。此外,自编码器还可以随机生成与训练数据类似的数据,这被称为生成模型(generative model)。
简单的自编码是一种三层神经网络模型,包括了数据输入层,隐藏层和输出重构层。自编码器接受输入,将其转换为高效的内部表示,然后再输出输入数据的类似物。自编码器通常包含两部分:encoder(也称为识别网络)将输入转换为内部表示,decoder(也称为生成网络)将内部表示转换为输出。同时它让目标值等于输入值,也就是说每个样本的数据想的标签也是x,即y=x。自编码就相当于自己生成标签,而且标签是样本数据本身。
2、自编码的过程
首先,是从输入层到隐藏层的原始数据x的编码过程:
h
=
g
1
(
x
)
h=g_1(x)
h=g1(x)
然后,是从隐藏层到输出层的解码过程:
x
^
=
g
2
(
h
)
\hat{x}=g_2(h)
x^=g2(h)
则数据x的重构误差损失函数为:
J
(
w
,
b
)
=
1
2
m
∑
i
=
1
m
∣
∣
x
^
(
i
)
−
x
(
i
)
∣
∣
2
J(w,b)=\frac{1}{2m}\sum_{i=1}^{m}||\hat{x}{(i)}-x^{(i)}||^2
J(w,b)=2m1i=1∑m∣∣x^(i)−x(i)∣∣2
因此训练完网络之后,随便输入一个测试样本数据x,自编码网络将对x先进行隐藏层的编码,再从隐藏层到输出层完成解码,重构出x。其中,隐藏层可以看作是原始数据x的另外一种特征表达。
3、自编码的意义
自编码神经网络尝试学习一个 h ≈ x h\approx x h≈x的函数,也即是尝试逼近一个恒等函数,从而使得输出x’接近输入x。这样做看上去毫无意义,有什么用处呢?其实当我们给自编码神经网络加入某些限制,比如限定隐藏层神经元的数目,就可以实现类似于PCA等数据降维、数据压缩的特性。假设输入层神经元的个数n大于隐藏层神经元的个数m,这样就迫使自编码神经网络去学习输入数据的压缩表示,就相当于把数据从n维降到了m维。这样自编码神经网络就可以学习出一个跟PCA结果非常相似的输入数据的低维表示,只不过PCA是通过求解特征向量进行降维,是一种线性降维,而自编码是一种非线性降维。注意,输出神经元的个数也是n,因此我们还需要利用这m维的特征向量,去重构n维原始数据。
当自编码的隐藏层比输入层的神经元个数多时,我们可以在神经网络的损失函数的构造上,加入正则化约束项进行稀疏约束,这时候就演化为稀疏自编码了。
稀疏自编码
稀疏性是指如果神经元的输出接近于1时认为它被激活,而输出接近于0时认为它被抑制,那么使得神经元大部分时间都被抑制的限制则被称为稀疏性限制。这里我们的假设的神经元的激活函数是Sigmoid函数。如果使用tanh作为激活函数,当神经元输出为-1时,我们认为神经元是被抑制的。
稀疏自编码就是对隐藏层神经元加入的稀疏约束,是因为我们希望用尽可能少的神经元来表示原始数据x。隐藏层神经元的激活值就相当于原始数据x的另外一种表达方式,因此这种表达是稀疏表达(也就是隐藏层的神经元激活值尽可能多的为0)。
a
j
(
2
)
a_j(2)
aj(2)表示隐藏神经元j的激活度,但是这一表示并没有指出哪一个输入x带来的这一激活度。所以使用
a
j
(
2
)
(
x
)
a_j(2)(x)
aj(2)(x)来表示在给定输入x的情况下,自编码神经网络隐藏层神经元j的激活度。进一步的隐藏层神经元j的平均激活度为(在训练集上取平均):
ρ
^
j
=
1
m
∑
i
=
1
m
[
a
j
(
i
)
(
x
(
i
)
)
]
\hat{\rho}_j=\frac{1}{m}\sum_{i=1}^{m}[a_j^{(i)}(x^{(i)})]
ρ^j=m1i=1∑m[aj(i)(x(i))]
可以近似加入一条限制:
其中,
ρ
^
j
=
ρ
\hat {\rho}_j=\rho
ρ^j=ρ是稀疏性参数,通常是一个接近于0的较小的值(比如为0.05)。也即是想让隐藏层神经元j的平均激活度接近于0.05。为了满足这一条件,隐藏层神经元的活跃度必须接近于0。为了实现这一限制,在优化函数中加入一个额外的正则约束项,而这个正则约束项将惩罚那些 和 有显著不同的情况从而使得隐藏神经元的平均活跃度保持在较小的范围内。构造KL散度作为网络的正则约束项:
K
L
(
ρ
∣
∣
ρ
^
j
)
=
ρ
log
ρ
ρ
^
j
+
(
1
−
ρ
)
log
1
−
ρ
1
−
ρ
^
j
KL(\rho||\hat{\rho}_j)=\rho\log\frac{\rho}{\hat{\rho}_j}+(1-\rho)\log\frac{1-\rho}{1-\hat{\rho}_j}
KL(ρ∣∣ρ^j)=ρlogρ^jρ+(1−ρ)log1−ρ^j1−ρ
最后,网络训练损失函数为:
J
s
p
a
r
s
e
(
w
,
b
)
=
J
(
w
,
b
)
+
β
∑
j
=
1
s
2
K
L
(
ρ
∣
∣
ρ
^
j
)
J_{sparse}(w,b)=J(w,b)+\beta\sum_{j=1}^{s2}KL(\rho||\hat{\rho}_j)
Jsparse(w,b)=J(w,b)+βj=1∑s2KL(ρ∣∣ρ^j)
总之,稀疏自编码就是在原来自编码的损失函数上,加入了稀疏约束项。