⾃编码器(AutoEncoder)
现代的神经⽹络中,我们的任务常常都是通过隐藏层学习出输⼊或是数据的表达(reprentation),进⽽完成诸如数据压缩,降维,特征提炼等诸多任务。⾃编码器就是帮助我们学习数据表达的⼀种⽅式,实际上现在的深度⽹络可以看成是⾃编码器的堆砌来完成feature
extract的⼯作,再利⽤学习到的feature完成分类或是回归任务。那么如何理解⾃编码器呢?我们已经知道,现在的⼤多神经⽹络都是通过各种⽅式在输⼊与输出之间建⽴映射函数。⽽⾃编码器要学习的是⼀种特殊的映射,即恒等映射,换句话说,它做的⼯作是重建(reconstruct)输⼊。
朴素⾃编码器
⾃编码器最简单的形式,这⾥我们以单隐藏层的⾃编码器为例,输⼊与输出相同,使⽤l2 loss
ist import input_data
大连日语培训from keras.layers import Input, Den, Conv2D, MaxPooling2D, UpSampling2D, Flatten, Reshape
dels import Model
from keras.optimizers import Adam
ularizers import activity_l1oblivion
surburbanimport numpy as np
import matplotlib.pyplot as plt
import keras.backend as K
import tensorflow as tf
mnist = ad_data_ts('../data/MNIST_data', one_hot=True)ending是什么意思
X, _ = ain.images, ain.labels
五一劳动节 英文
inputs = Input(shape=(784,))
h = Den(64, activation='sigmoid')(inputs)
outputs = Den(784)(h)
model = Model(input=inputs, output=outputs)
model.fit(X, X, batch_size=64, nb_epoch=5)
到此我们不禁要问,费了这么⼤功夫我们就折腾出来⼀个恒等映射?这有什么价值?
是的,单纯的恒等映射没有什么⽤处,但的当我们加上约束之后就能挖掘出它的价值所在。⽐如在上⾯的例⼦中,我们⽤将784维的特征向量输⼊,⽽隐藏层只有64个单元。即我们强迫⽹络⽤64维来表达原本784维的信息,⽹络需要进⾏压缩并提炼出⾼维表达以完成encode 过程。这种思想与PCA主成分分析或是CNN中1*1卷积核dimension reduction 都有相通之处。
稀疏⾃编码器
另⼀种添加约束(constraint)的⽅法就是对loss损失函数添加约束,如正则化。下⾯以l1正则化为例给出了实现代码
inputs = Input(shape=(784,))
h = Den(64, activation='sigmoid', activity_regularizer=activity_l1(1e-5))(inputs)
outputs = Den(784)(h)
model = Model(input=inputs, output=outputs)
model.fit(X, X, batch_size=64, nb_epoch=5)
计算隐藏层的mean value 我们得到的结果是0.148664,⽽上⾯的朴素⾃编码器得到的是0.512477,由此可以发现隐藏层的激活程度被抑制了,即神经元之间的连接更稀疏了,因此我们称这种编码器为稀疏⾃编码器
多层⾃编码器
很⾃然地,我们会想到增加⾃编码器中的⽹络层数,这⾥我们增加到3个隐藏层
inputs = Input(shape=(784,))
h = Den(128, activation='relu')(inputs)
encoded = Den(64, activation='relu', activity_regularizer=activity_l1(1e-5))(h)英语学习机
h = Den(128, activation='relu')(encoded)
outputs = Den(784)(h)
model = Model(input=inputs, output=outputs)
model.fit(X, X, batch_size=64, nb_epoch=5)
一切从那本英语书开始的在这些中间层中,我们可以选取任意层来作为我们的数据表达。简单与对称起见,我们常常选择正中间的⼀层
卷积⾃编码器
日语人工翻译把⾃编码器中的全连接层⽤卷积层替代
inputs = Input(shape=(28, 28, 1))
h = Conv2D(4, 3, 3, activation='relu', border_mode='same')(inputs)
encoded = MaxPooling2D((2, 2))(h)
h = Conv2D(4, 3, 3, activation='relu', border_mode='same')(encoded)
h = UpSampling2D((2, 2))(h)
outputs = Conv2D(1, 3, 3, activation='relu', border_mode='same')(h)
model = Model(input=inputs, output=outputs)
benchmark什么意思pile(optimizer='adam', loss='m')
model.fit(X, X, batch_size=64, nb_epoch=5)
总结
从上⾯的例⼦中我们可以看到,⾃编码器实际上就是通过若⼲个隐藏层(hidden layer)实现的,我们通过施加不同的约束来学习我们想要的表达。下⼀篇博客会讲述收缩⾃编码器(CAE),去噪⾃编码器(DAE),变分⾃编码器(VAE)以及条件变分⾃编码器(CVAE)