自编码器是一个无监督的应用,它使用反向传播来更新参数,它最终的目标是让输出等于输入。数学上的表达为,f(x) = x,f 为自编码器,x 为输入数据。
自编码器会先将输入数据压缩到一个较低维度的特征,然后利用这个较低维度的特征重现输入的数据,重现后的数据就是自编码器的输出。所以,从本质上来说,自编码器就是一个压缩算法。
自编码器由 3 个部分组成:
- 编码器(Encoder):用于数据压缩。
- 压缩特征向量(Compressed Feature Vector):被编码器压缩后的特征。压缩特征向量也是人工神经网络中的一层,它的维度就是我们要将数据压缩到的维度,是一个超参,我们要提前设定。
- 解码器(Decoder):用于数据解码。编码器与解码器就是之前讲的多层感知机,也可以用卷积实现。
如下图
有三点需要注意
- 自编码器只能压缩与训练数据相似的数据。比如我们用 MNIST手写数字训练集来训练自编码器,那它只能压缩手写数字相关的数据,如果用来压缩手写数字以外的数据,表现就会很差;
- 自编码器解压缩的结果只能接近输入,并不完全一样。所以它是一个有损的压缩算法;
- 自编码器是一个无监督学习的算法。我们不需要对数据做任何标注,只需要把原始数据扔给它就可以了,它会自动挖掘数据中的潜在结构模式。
9.1 自编码器的网络架构
可以看到,这种自编码器是一层层堆叠起来的,所以又称为堆叠式自编码器。
首先我们会有 3 个维度的输入 x 通过编码器,然后生成 1 个有两个维度的压缩特征向量。解码器会将这两个维度的特征向量恢复到 3 个维度的 x’,然后输出。其中编码器与解码器是对称的。
整个过程的宗旨只有一个:输出的 x’无限接近输入 x。
对于一个自编码器,会有 3 个超参需要设定:
- 压缩特征向量的神经元的个数:也就是压缩后的维度。神经元的个数越少则代表有更重的压缩。
- 层的个数:自编码器的结构可以按照我们的想法任意设定。
- 每一层中神经元的个数。
9.2自编码器的实现
如何训练一个自编码器呢?只需要以下几个步骤:
- 构造一个编码器和解码器;
- 设定一个损失函数来衡量输出 x’与输入 x 的差距;
- 选择一个优化方法,来更新参数,例如随机梯度下降算法(SGD)。
我们把上面 3 步再具体一些。
- 我们有数据集 D:D={x1,x2,…,xi,…,xm},其中 xi=(xi,1,xi,2,…,xi,n)。
- 编码器为 y=h(x),y 是上图中的压缩特征向量。
- 解码器为 x’=f(y)=f(h(x))。
如果输入的数据是数值型,则利用均方误差(MSE)来衡量输出 x’与输入 x 之间的差距;如果输入的数据是离散型,则利用交叉熵损失来衡量输出 x’与输入 x 之间的差距。h(x)与 f(y)的参数会通过我们设定好的优化方法进行更新。
自编码器的网络结构非常容易控制,只要增加网络的层数、每一层的节点数以及压缩向量的长度就让网络变得更加强大。
增加这些超参会让自编码器学习到更加复杂的压缩编码模型,但同时也会带来一定的问题。太复杂的网络有可能让网络变得非常容易过拟合,并且网络也很难学习到输入数据的潜在特征,只会学到将输入数据拷贝到输出这样一种单纯的恒等变换。模型过拟合的时候,在训练集上会有非常优秀的表现,但是遇到训练集以外的数据就不会有很好的效果。
所以大部分自编码器都故意保留了一个比较小的压缩特征向量。那除了保留一个较小的压缩特征向量之外,接下来我们看看还有没有其他方法可以让自编码器更加专注地发现数据中的潜在结构
9.3 降噪自编码器
降噪自编码器是在训练时,在输入的数据中加入随机噪音,在最后输出的时候恢复到没有噪音的状态的一种编码器。
上图的第一行为原始图片,第二行为对应有噪声的图片。训练时,我们把第二行图片作为输入,第一行的原始图片作为输出。
因为输入的数据中加入了随机噪音,就避免了网络只学习到简单的将输入复制到输出的这种恒等变换,强制让自编码器学习如何剔除数据中的噪音,然后再恢复到没有噪音的状态。这样就能让它更加专注地挖掘数据中的潜在结构模式。
9.4 稀疏自编码器
在损失函数中加一个惩罚项,在训练时就可以让自编码器只有一小部分节点被激活,这样我们就得到一个稀疏自编码器了。
这样通过限制自编码器中神经元的输出,只让很小的一部分神经元有非 0 的输出,也可以说是只激活一小部分的神经元。迫使自编码器将输入与一部分节点联系起来,从而让它发现数据中更有价值的结构。即使压缩特征向量中有很多节点,有这种约束的自动编码器也可以很好地工作,因为它只让一部分节点被激活。
第一章讲的L1 范数即可实现这种稀疏的约束。
可以发现,我们的 L1 正则约束确实对压缩特征向量起到了效果,大部分时候的输出都是 0。而标准的自编码器的压缩特征向量的输出相对平缓一些。
9.5 使用场景
对于压缩应用来说,因为自编码器对训练数据有非常强的依赖,这也让它能难作为一个通用的压缩算法被使用。
所以自编码器主要有以下两个用途:数据降噪;降维处理。