压缩去噪利器---自编码器(AutoEncoder)

    Hello,又是一个分享的日子,上期博主介绍了巨人肩膀上的迁移学习(2)---图像回归,并介绍了图像在进入神经网络前的预处理工作。今天博主给大家分享的是深度学习的压缩去噪利器---自编码器(AutoEncoder)

    这一期我们将分别利用CNN卷积神经网路和BP神经网络去搭建4种自编码器。博主也在往期的推文中也介绍了CNN卷积神经网络和BP神经网路的原理,还不熟悉CNN卷积神经网络原理的小伙伴可以翻一下:什么?卷积层会变胖?人工智能之光---CNN卷积神经网络(原理篇),深度学习开端---BP神经网络,这里博主就不进行过多的赘述了。

本文内容概要:

1.自编码器原理

2.多层自编码器

3.卷积自编码器

4.正则自编码器

4.1稀疏自编码器

4.2去噪自编码器

自编码器

 原理                                                                                     

640?wx_fmt=gif

      

自编码器是由nathan hubens提出的一种输入等于输出的神经网络模型,可能大家会疑惑为什么要训练一个这样的模型,毕竟输入等于输出在大家看来就是一件多此一举的事情。这里博主先给大家上一个模型图让大家感受一下。

压缩去噪利器---自编码器(AutoEncoder)_第1张图片

上图是由BP神经网络组成的最简单的自编码器,只有三层结构,中间的隐藏层才是我们所需要关注的地方,以隐藏层为界限,左边为编码器(encoder), 右边为解码器(decoder),所以在训练过程中,输入才能在经过编码后再解码,还原成原来的模样。

对传统机器学习有所了解的小伙伴应该都知道PCA(主成分分析),它是用来对数据进行降维的。不了解的小伙伴也没关系,我们现在学习的自编码器也有这个功能,所以学完之后再看PCA兴许会理解地更加深刻些。

现在我们看回上图,假如我们通过一组数据训练出了我们的自编码器,然后我们拆掉自编码器的解码器(decoder),就可以用剩下的编码器(encoder)来表征我们的数据了。隐藏层的神经元数目远低于输入层,那么就相当于我们用更少的特征(神经元)去表征我们的输入数据,从而达到降维压缩的功能。

接着,我们在文章开头提到过自编码器还有降噪的功能,那它是如何实现这个功能的呢?在此之前博主先给大家介绍下这期使用的数据集----minist手写体,这是keras自带的数据集,如下图。

压缩去噪利器---自编码器(AutoEncoder)_第2张图片

这个数据集就是手写数字0~9的图像集合,上图第一行就是加噪后的手写体数据集,第二行则是原本的手写体数据集。我们把加噪后的数据集当成输入,原本的数据集当做输出,训练一个自编码器,让它在训练过程中学习数据的规律,从而把噪声去掉。这就是博主所说的去噪功能。

到这里,博主就已经把自编码器的原理和功能给大家讲清楚了。接下来,我们更进一步介绍几种有用的自编码器。

  1. 普通自编码器:就是文章开头讲的最简单的自编码器。

  2. 多层自编码器:多个BP神经网络隐藏层组成自编码器。

    压缩去噪利器---自编码器(AutoEncoder)_第3张图片

  3. 积自编码器:由CNN卷积神经网络组成的自编码器

    压缩去噪利器---自编码器(AutoEncoder)_第4张图片

  4. 正则自编码器

    4.1稀疏自编码器:稀疏自编码器就是普通自编码器的隐藏层加一个L1正则项,也就是一个训练惩罚项,这样我们训练出的编码器(encoder)表征的特征更加的稀疏,从而能得到少且有用的特征项。这也是为啥用L1正则项而不用L2正则项的原因。至于L1,L2正则项的原理,博主在之前的推文码前须知---TensorFlow超参数的设置有提及,还不熟悉的小伙伴可以去翻阅一下。

    4.2降噪自编码器:降噪自编码器就是输入换成了加噪的数据集,输出用原数据集去训练的自编码器,目的是习得降噪功能。

实验

实验环境                                                                                          

640?wx_fmt=gif

  • Anaconda Python 3.7 

  • Jupyter Notebook

  • Keras

    开发环境安装在之前的推文中已经介绍,还没安装的小伙伴可以翻一下。

  • Python开发环境---Windows与服务器篇

  • Python深度学习开发环境---Keras

 

实验流程                                                                                          

640?wx_fmt=gif

  • 加载图像数据

  • 图像数据预处理  

  • 构建自编码器模型

  • 训练模型

  • 查看模型编解码效果

  • 训练过程可视化

代码                                                                                                 

640?wx_fmt=gif

  •     普通自编码核心代码

input_size = 784	
hidden_size = 128	
code_size = 64	
x = Input(shape=(input_size,))	
h = Dense(hidden_size, activation='relu')(x)	
r = Dense(output_size, activation='sigmoid')(h)	

	
autoencoder = Model(inputs=x, outputs=r)	
autoencoder.compile(optimizer='adam', loss='mse')
  •      多层自编码核心代码

input_size = 784	
hidden_size = 128	
code_size = 64	

	
x = Input(shape=(input_size,))	
hidden_1 = Dense(hidden_size, activation='relu')(x)	
h = Dense(code_size, activation='relu')(hidden_1)	
hidden_2 = Dense(hidden_size, activation='relu')(h)	
r = Dense(input_size, activation='sigmoid')(hidden_2)	

	
autoencoder = Model(inputs=x, outputs=r)	
autoencoder.compile(optimizer='adam', loss='mse')

压缩去噪利器---自编码器(AutoEncoder)_第5张图片

其中, fi是模型预测值,yi是实际值,通过计算两者的均方误差来衡量模型的有效性。

  • 卷积自编码器核心代码

x = Input(shape=(28, 28,1))	

	
# 编码器	
conv1_1 = Conv2D(16, (3, 3), activation='relu', padding='same')(x)	
pool1 = MaxPooling2D((2, 2), padding='same')(conv1_1)	
conv1_2 = Conv2D(8, (3, 3), activation='relu', padding='same')(pool1)	
pool2 = MaxPooling2D((2, 2), padding='same')(conv1_2)	
conv1_3 = Conv2D(8, (3, 3), activation='relu', padding='same')(pool2)	
h = MaxPooling2D((2, 2), padding='same')(conv1_3)	

	

	
# 解码器	
conv2_1 = Conv2D(8, (3, 3), activation='relu', padding='same')(h)	
up1 = UpSampling2D((2, 2))(conv2_1)	
conv2_2 = Conv2D(8, (3, 3), activation='relu', padding='same')(up1)	
up2 = UpSampling2D((2, 2))(conv2_2)	
conv2_3 = Conv2D(16, (3, 3), activation='relu')(up2)	
up3 = UpSampling2D((2, 2))(conv2_3)	
r = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(up3)	

	
autoencoder = Model(inputs=x, outputs=r)	
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')

UpSampling2D:上采样层,与MaxPooling2D相对应。

  • 稀疏自编码器核心代码

input_size = 784	
hidden_size = 32	
output_size = 784	

	
x = Input(shape=(input_size,))	
h = Dense(hidden_size, activation='relu', activity_regularizer=regularizers.l1(10e-5))(x)	
r = Dense(output_size, activation='sigmoid')(h)	

	
autoencoder = Model(inputs=x, outputs=r)	
autoencoder.compile(optimizer='adam', loss='mse')

  • 去噪自编码器核心代码

x = Input(shape=(28, 28, 1))	

	
# 编码器	
conv1_1 = Conv2D(32, (3, 3), activation='relu', padding='same')(x)	
pool1 = MaxPooling2D((2, 2), padding='same')(conv1_1)	
conv1_2 = Conv2D(32, (3, 3), activation='relu', padding='same')(pool1)	
h = MaxPooling2D((2, 2), padding='same')(conv1_2)	
# 解码器	
conv2_1 = Conv2D(32, (3, 3), activation='relu',padding='same')(h)	
up1 = UpSampling2D((2, 2))(conv2_1)	
conv2_2 = Conv2D(32, (3, 3), activation='relu', padding='same')(up1)	
up2 = UpSampling2D((2, 2))(conv2_2)	

	
r = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(up2)	

	
autoencoder = Model(inputs=x, outputs=r)	
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')	

	
epochs = 3	
batch_size = 128	

	
history = autoencoder.fit(X_train_noisy,  # 加噪数据集	
                          X_train,   # 原数据集	
                          batch_size=batch_size,	
                          epochs=epochs, verbose=1,	
                     validation_data=(X_test_noisy, X_test))
  • 参数

    Dense: 全连接层。

    CNN2D:2维卷积神经网络,常用于处理图像。

    Dropout: 以一定概率放弃两层之间的一些神经元链接,防止过拟合,可以加在网络层与层之间。

    optimizer: 优化器,梯度下降的优化方法

    这些都在之前的推文中有所介绍,小伙伴们可以去翻阅一下。

    码前须知---TensorFlow超参数的设置

    activation: 激励函数,‘linear’一般用在回归任务的输出层,而‘softmax’一般用在分类任务的输出层

        

        validation_split 切分一定比例的训练集作为验证集

  • epochs 与 batch_size:前者是迭代次数,后者是用来更新梯度的批数据的大小,iteration = epochs / batch_size, 也就是完成一个epoch需要跑多少个batch。这这两个参数可以用控制变量法来调参,控制一个参数,调另外一个,看损失曲线的变化。

    小伙伴们可以去keras官网查看更多的参数含义与用途,博主也会在后续的课程中通过实验的方法将这些参数涉及进来,让大家的知识点串联起来。

        

Keras官网

https://keras.io/

  • Git链接

代码

https://github.com/ChileWang0228/DeepLearningTutorial/blob/master/AutoEncoder/AutoEncoder.ipynb

训练结果                                                                                             

640?wx_fmt=gif

  • 普通自编码器

    解码效果

压缩去噪利器---自编码器(AutoEncoder)_第6张图片

        训练过程

压缩去噪利器---自编码器(AutoEncoder)_第7张图片

  • 多层自编码器

    解码效果

    压缩去噪利器---自编码器(AutoEncoder)_第8张图片

    训练过程

    压缩去噪利器---自编码器(AutoEncoder)_第9张图片

  • 卷积自编码器

    解码效果

压缩去噪利器---自编码器(AutoEncoder)_第10张图片

        训练过程

压缩去噪利器---自编码器(AutoEncoder)_第11张图片

  • 稀疏自编码器

    解码效果

    压缩去噪利器---自编码器(AutoEncoder)_第12张图片

        训练过程

压缩去噪利器---自编码器(AutoEncoder)_第13张图片

  • 去噪自编码器

    解码效果

压缩去噪利器---自编码器(AutoEncoder)_第14张图片

    

    训练过程

压缩去噪利器---自编码器(AutoEncoder)_第15张图片

代码实践视频                                                                                          

640?wx_fmt=gif

视频卡顿?bilibili值得拥有~(っ•̀ω•́)っ✎⁾⁾ 我爱学习

https://www.bilibili.com/video/av61286570/

总结

640?wx_fmt=gif

        好了,到这里,我们就已经将自编码器的知识点讲完了。大家在掌握了整个流程之后,就可以在博主的代码上修修补补,训练自己的自编码器模型了。

       下一期,博主给大家介绍常见的激励函数和损失函数,敬请期待吧~

        如果本期推文有用,那就点个赞吧,你们的点赞是博主持续更新的动力,感谢每一位小伙伴的关注~

图片来源于网络,侵删

    

留言

640?wx_fmt=gif

博主刚弄的一个留言功能,欢迎各位小伙伴踊跃留言~smiley_13.png

压缩去噪利器---自编码器(AutoEncoder)_第16张图片

压缩去噪利器---自编码器(AutoEncoder)_第17张图片

xmorient

你可能感兴趣的:(压缩去噪利器---自编码器(AutoEncoder))