tlflearn 编码解码器 ——数据降维用

 

# -*- coding: utf-8 -*-

""" Auto Encoder Example.
Using an auto encoder on MNIST handwritten digits.
References:
    Y. LeCun, L. Bottou, Y. Bengio, and P. Haffner. "Gradient-based
    learning applied to document recognition." Proceedings of the IEEE,
    86(11):2278-2324, November 1998.
Links:
    [MNIST Dataset] http://yann.lecun.com/exdb/mnist/
"""
from __future__ import division, print_function, absolute_import

import numpy as np
import matplotlib.pyplot as plt
import tflearn

# Data loading and preprocessing
import tflearn.datasets.mnist as mnist
X, Y, testX, testY = mnist.load_data(one_hot=True)

# Building the encoder
encoder = tflearn.input_data(shape=[None, 784])
encoder = tflearn.fully_connected(encoder, 256)
encoder = tflearn.fully_connected(encoder, 64)

# Building the decoder
decoder = tflearn.fully_connected(encoder, 256)
decoder = tflearn.fully_connected(decoder, 784, activation='sigmoid')

# Regression, with mean square error
net = tflearn.regression(decoder, optimizer='adam', learning_rate=0.001,
                         loss='mean_square', metric=None)

# Training the auto encoder
model = tflearn.DNN(net, tensorboard_verbose=0)
model.fit(X, X, n_epoch=20, validation_set=(testX, testX),
          run_id="auto_encoder", batch_size=256)

# Encoding X[0] for test
print("\nTest encoding of X[0]:")
# New model, re-using the same session, for weights sharing
encoding_model = tflearn.DNN(encoder, session=model.session)
print(encoding_model.predict([X[0]]))

# Testing the image reconstruction on new data (test set)
print("\nVisualizing results after being encoded and decoded:")
testX = tflearn.data_utils.shuffle(testX)[0]
# Applying encode and decode over test set
encode_decode = model.predict(testX)
# Compare original images with their reconstructions
f, a = plt.subplots(2, 10, figsize=(10, 2))
for i in range(10):
    temp = [[ii, ii, ii] for ii in list(testX[i])]
    a[0][i].imshow(np.reshape(temp, (28, 28, 3)))
    temp = [[ii, ii, ii] for ii in list(encode_decode[i])]
    a[1][i].imshow(np.reshape(temp, (28, 28, 3)))
f.show()
plt.draw()
plt.waitforbuttonpress()

运行效果图:

深度学习——keras训练AutoEncoder模型

深度学习——keras训练AutoEncoder模型

安装keras:

先安装anaconda,再运行conda install keras,参照:
http://blog.csdn.net/qq_32329377/article/details/53008019


下载AutoEncoder模型训练代码:

https://github.com/MorvanZhou/tutorials/tree/master/kerasTUT
注意:需给每个文件加# -*- coding: utf-8 -*,否则会出现noASCII错误。


训练代码细解:

自编码,简单来说就是把输入数据进行一个压缩和解压缩的过程。原来有很多特征,压缩成几个来代表原来的数据,解压之后恢复成原来的维度,再和原数据进行比较。它是一种非监督算法,只需要输入数据,解压缩之后的结果与原数据本身进行比较。程序的主要功能是把 datasets.mnist 数据的 28*28=784 维的数据,压缩成 2 维的数据,然后在一个二维空间中可视化出分类的效果。
首先,导入数据并进行数据预处理,本例使用Model模块的Keras的泛化模型来进行模型搭建,便于我们从模型中间导出数据并进行可视化。进行模型搭建的时候,注意要进行逐层特征提取,最终压缩至2维,解码的过程要跟编码过程一致相反。随后对Autoencoder和encoder分别建模,编译、训练。将编码模型的预测结果通过Matplotlib可视化出来,就可以看到原数据的二维编码结果在二维平面上的聚类效果,还是很明显的。

  • 导入相关Python和keras模块(module):
import numpy as np  
np.random.seed(1337)  # for reproducibility  

from keras.datasets import mnist  
from keras.models import Model #泛型模型  
from keras.layers import Dense, Input  
import matplotlib.pyplot as plt  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

需要注意的是,如果在Ubuntu下我们使用的远程命令行方式,因为在远程命令行的环境下显示不了图形界面,所以需要加入下面的两行代码(且需放在import matplotlib.pyplot as plt前),否则会运行报错。但是在Ubuntu的图形化界面下(比如,远程桌面或VNC Viewer)不需要。

import matplotlib  
matplotlib.use('Agg')
  • 1
  • 2
  • 加载数据集
# x shape (60,000 28x28), y shape (10,000, )
(x_train, _), (x_test, y_test) = mnist.load_data()
  • 1
  • 2
  • 数据预处理
# data pre-processing
x_train = x_train.astype('float32') / 255. - 0.5       # minmax_normalized
x_test = x_test.astype('float32') / 255. - 0.5         # minmax_normalized
x_train = x_train.reshape((x_train.shape[0], -1))
x_test = x_test.reshape((x_test.shape[0], -1))
print(x_train.shape)
print(x_test.shape)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 压缩特征维度至2维
encoding_dim = 2
  • 1

接下来就是建立encodeddecoded,再用 autoencoder 把二者组建在一起。训练时用 autoencoder

  • 建立编码层
encoded = Dense(128, activation='relu')(input_img)  
encoded = Dense(64, activation='relu')(encoded)  
encoded = Dense(10, activation='relu')(encoded)  
encoder_output = Dense(encoding_dim)(encoded)
  • 1
  • 2
  • 3
  • 4

encoded 用4层 Dense 全联接层,激活函数用 relu,输入的维度就是前一步定义的 input_img
接下来定义下一层,它的输出维度是64,输入是上一层的输出结果。
在最后一层,我们定义它的输出维度就是想要的 encoding_dim=2

  • 建立解码层
decoded = Dense(10, activation='relu')(encoder_output)  
decoded = Dense(64, activation='relu')(decoded)  
decoded = Dense(128, activation='relu')(decoded)  
decoded = Dense(784, activation='tanh')(decoded) 
  • 1
  • 2
  • 3
  • 4

解压的环节,它的过程和压缩的过程是正好相反的。相对应层的激活函数也是一样的,不过在解压的最后一层用到的激活函数是 tanh。 因为输入值是由 -0.5 到 0.5 这个范围,在最后一层用这个激活函数的时候,它的输出是 -1 到 1,可以是作为一个很好的对应。

  • 构建自编码模型
autoencoder = Model(inputs=input_img, outputs=decoded)
  • 1

直接用 Model 这个模块来组建模型,输入就是图片,输出是解压的最后的结果。

  • 模型组建
encoder = Model(inputs=input_img, outputs=encoder_output) 
  • 1

由 784维压缩到 2维,输入是图片,输出是压缩环节的最后结果。

  • 编译模型
autoencoder.compile(optimizer='adam', loss='mse')  
  • 1

优化器用的是 adam,损失函数用的是 mse

  • 训练模型
autoencoder.fit(x_train, x_train, epochs=20, batch_size=256, shuffle=True)  
  • 1

由于autocoder是一个压缩和解压的过程,所以它的输入和输出是一样的,都是训练集x。

  • 可视化
encoded_imgs = encoder.predict(x_test)  
plt.scatter(encoded_imgs[:, 0], encoded_imgs[:, 1], c=y_test, s=3)  
plt.colorbar()  
plt.show() 
  • 1
  • 2
  • 3
  • 4

终端操作:
ubuntu上:
打开到代码目录:

cd ~/keras/tutorials/kerasTUT
  • 1

开始训练:

python 9-Autoencoder_example.py
  • 1

训练结果图:

这里写图片描述

文章借鉴https://morvanzhou.github.io/tutorials/machine-learning/keras/2-6-autoencoder/

 

 其他示例:见:https://blog.csdn.net/qq_36829947/article/details/79079537 原文,代码有缺失!

“自编码”是一种数据压缩算法,其中压缩和解压缩功能是1)数据特定的,2)有损的,3)从例子中自动学习而不是由人工设计。此外,在几乎所有使用术语“自动编码器”的情况下,压缩和解压缩功能都是用神经网络来实现的。

1)自动编码器是特定于数据的,这意味着它们只能压缩类似于他们所训练的数据。这与例如MPEG-2音频层III(MP3)压缩算法不同,后者通常只保留关于“声音”的假设,而不涉及特定类型的声音。在面部图片上训练的自动编码器在压缩树的图片方面做得相当差,因为它将学习的特征是面部特定的。

2)自动编码器是有损的,这意味着与原始输入相比,解压缩的输出会降低(类似于MP3或JPEG压缩)。这与无损算术压缩不同。

3)自动编码器是从数据实例中自动学习的,这是一个有用的属性:这意味着很容易培养算法的特定实例,在特定类型的输入上运行良好。它不需要任何新的工程,只需要适当的培训数据。

要构建一个自动编码器,需要三件事情:编码函数,解码函数和数据压缩表示与解压缩表示(即“丢失”函数)之间的信息损失量之间的距离函数。编码器和解码器将被选择为参数函数(通常是神经网络),并且相对于距离函数是可微分的,因此可以优化编码/解码函数的参数以最小化重构损失,使用随机梯度下降。这很简单!而且你甚至不需要理解这些词语在实践中开始使用自动编码器。

 

什么是自动编码器的好处?

今天自动编码器的两个有趣的实际应用是数据去噪数据可视化的降通过适当的维度和稀疏性约束,自动编码器可以学习比PCA或其他基本技术更有趣的数据投影。
对于2D的数据可视化,t-SNE(读作tee-snee)或许是目前最好的算法,但通常还是需要原数据的维度相对低一些。所以,可视化高维数据的一个好办法是首先使用自编码器将维度降低到较低的水平(如32维),然后再使用t-SNE将其投影在2D平面上。


二、使用Keras建立简单的自编码器

1. 单隐含层自编码器

建立一个全连接的编码器和解码器。也可以单独使用编码器和解码器,在此使用Keras的函数式模型API即Model可以灵活地构建自编码器。

50个epoch后,看起来我们的自编码器优化的不错了,损失val_loss: 0.1037。

 

[python] view plain copy
 
  1. fromimport fromimport fromimport import import ) /   
  2. ) /   
  3. :])))  
  4. :])))  
  5. print print   
  6. ,))  
  7. )(input_img)  
  8. , activation=)(encoded)  
  9. ]  
  10. 'adadelta')  
  11. , batch_size=,   
  12. , validation_data=(x_test, x_test))  
  13.     
  14. 20))  
  15. forin , n, i + )  
  16. ))  
  17. )  
  18. )  
  19. , n, i +  + n)  
  20. ))  
  21. )  
  22. )  
  23. plt.show()  


2. 稀疏自编码器、深层自编码器

 

为码字加上稀疏性约束。如果我们对隐层单元施加稀疏性约束的话,会得到更为紧凑的表达,只有一小部分神经元会被激活。在Keras中,我们可以通过添加一个activity_regularizer达到对某层激活值进行约束的目的。

encoded = Dense(encoding_dim, activation='relu',activity_regularizer=regularizers.activity_l1(10e-5))(input_img)

把多个自编码器叠起来即加深自编码器的深度,50个epoch后,损失val_loss:0.0926,比1个隐含层的自编码器要好一些。

 

[python] view plain copy
 
  1. import 1337  
  2. fromimport fromimport  
  3. fromimport import # X shape (60,000 28x28), y shape (10,000, )   # 数据预处理   ) /           
  4. ) /           
  5. ], -))    
  6. ], -))    
  7. print print # 压缩特征维度至2维       
  8. # this is our input placeholder   ,))    
  9. # 编码层   , activation=)(input_img)    
  10. , activation=)(encoded)    
  11. , activation=)(encoded)    
  12. # 解码层   , activation=)(encoder_output)    
  13. , activation=)(decoded)    
  14. , activation=)(decoded)    
  15. , activation=)(decoded)    
  16. # 构建自编码模型   # 构建编码模型   # compile autoencoder   'adam')    
  17. # training   , batch_size=, shuffle=)    
  18. # plotting   ], encoded_imgs[:, ], c=y_test,s=)    
  19. # use Matplotlib (don't ask) import     
  20. 20))  
  21. forin   
  22. , n, i + )  
  23. ))  
  24. )  
  25. )  
  26.   
  27. , n, i +  + n)  
  28. ))  
  29. )  
  30. )  
  31. plt.show()    


 

3. 卷积自编码器:用卷积层构建自编码器

当输入是图像时,使用卷积神经网络是更好的。卷积自编码器的编码器部分由卷积层和MaxPooling层构成,MaxPooling负责空域下采样。而解码器由卷积层和上采样层构成。50个epoch后,损失val_loss: 0.1018。


 

[python] view plain copy
 
  1. fromimport fromimport fromimport import import fromimport ))    
  2. , (), activation=, padding=)(input_img)    
  3. ), padding=)(x)    
  4. , (), activation=, padding=)(x)    
  5. ), padding=)(x)    
  6. , (), activation=, padding=)(x)    
  7. ), padding=)(x)    
  8. , (), activation=, padding=)(encoded)    
  9. ))(x)    
  10. , (), activation=, padding=)(x)    
  11. ))(x)    
  12. , (), activation=)(x)    
  13. ))(x)    
  14. , (), activation=, padding=)(x)    
  15. 'adadelta')    
  16. # 打开一个终端并启动TensorBoard,终端中输入 tensorboard --logdir=/autoencoder   , batch_size=,    
  17. , validation_data=(x_test, x_test),    
  18. )])    
  19. decoded_imgs = autoencoder.predict(x_test)    


UpSampling2D

上采样,扩大矩阵,可以用于复原图像等。



keras.layers.convolutional.UpSampling2D(size=(2, 2), data_format=None)

将数据的行和列分别重复size[0]和size[1]次 



 

4. 使用自动编码器进行图像去噪

我们把训练样本用噪声污染,然后使解码器解码出干净的照片,以获得去噪自动编码器。首先我们把原图片加入高斯噪声,然后把像素值clip到0~1。

ps:去噪自编码器(denoisingautoencoder, DAE)是一类接受损坏数据作为输入,并训练来预测原始未被损坏数据作为输出的自编码器。


 

[python] view plain copy
 
  1. #去噪 自编码器 fromimport fromimport fromimport import import fromimport ) /     
  2. ) /     
  3. ))    
  4. ))    
  5.     
  6. , scale=, size=x_train.shape)     
  7. , scale=, size=x_test.shape)     
  8. )    
  9. )    
  10. print print ))    
  11. 3233'relu''same' 22'same' 3233'relu''same' 22'same' 3233'relu''same' 22 3233'relu''same' 22 133'sigmoid''same' 'adam''binary_crossentropy' # 打开一个终端并启动TensorBoard,终端中输入 tensorboard --logdir=/autoencoder   , batch_size=,    
  12. , validation_data=(x_test_noisy, x_test),    
  13. , write_graph=)])    
  14. 306  
  15. 10 forin ,n,i+)    
  16. ,))  
  17.   
  18. )        
  19. )        
  20. ,n,i++n)  
  21. ,))  
  22. )  
  23. )  
  24. ,n,i++*n)  
  25. ,))  
  26. )  
  27. )  
  28. plt.show()  
个人分类: 深度学习
posted @ 2018-06-01 15:16  bonelee  阅读(515)  评论(0编辑  收藏  举报