深度学习4 keras实现基于全连接的自动编码器

158 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

自动编码器可以看做一种数据的压缩算法,其压缩和解压缩的函数是通过实现的。

自动编码器=编码器+解码器。编码器的输出既是解码器的输入,解码器输出的shape与编码器输入的shape相同,因此自动编码器其输入和输出的形状是相同的。编码器输出既是自动编码器的编码结果。

自动编码器的结构如下图所示,可以看到编码器的输入与解码器的输出是完全一样的。编码器的输出用于解码器的输入。

b7e8ceadfb43b0559435faac20968b39_42fa6b954fbb19aae817af7145d2d50a.png

自动编码器的特点

  1. 数据相关:自动编码器只能压缩那些与训练数据类似的数据。对于与训练数据不相似的输入无能为力;

  2. 有损压缩:自动编码器解压缩的输出与原来的输入相比在质量上有所不足;

  3. 自动学习:训练自动编码器无需特征标签,其输入与输出相同,可以自动学习编码能力

自动编码器的用途

  1. 数据去噪,类似于全卷积网络,获取解码器的输出。输入数据:带噪声的数据(x)=》输出数据:不带噪声的数据(x)

  2. 数据降维,只获取编码器的输出可以到达数据降维的目的

  3. 特定的压缩任务,与数据降维类似,使用编码器压缩数据,使用解码器解压数据

自编码器的构建

1、工具包的导入

from keras.layers import Dense,Input
import tensorflow
from keras import Model
from keras.models import Sequential
import numpy
import matplotlib.pyplot as plt

2、构建编码器

# Encoder
def get_encoder(in_shape,out_units):
    model = Sequential()
    model.add(Dense(300,input_shape=(in_shape,), activation='relu'))
    model.add(Dense(10, activation='relu'))
    model.add(Dense(out_units, activation='relu'))
    model.summary()
    return model

3、构建解码器

# Decoder
def get_decoder(in_shape,out_units):
    model = Sequential()
    model.add(Dense(10,input_shape=(in_shape,), activation='relu'))
    model.add(Dense(300, activation='relu'))
    model.add(Dense(out_units, activation='sigmoid'))
    return model

4、将编码器与解码器组装成自动编码器

# Autoencoder
def get_autoencoder():
    data_num=784
    feature_num=2
    #定义编码器的输入
    ae_input = Input(shape=(data_num,), name="AE_input")
    
    #获取编码器
    encoder=get_encoder(data_num,feature_num)
    #获取解码器
    decoder=get_decoder(feature_num,data_num)
    
    #使用编码器编码输入得到特征
    ae_encoder_output = encoder(ae_input)
    #使用解码器解码特征得到输出
    ae_decoder_output = decoder(ae_encoder_output)
    #构造自动解码器模型
    ae = Model(ae_input, ae_decoder_output, name="AE")
    ae.summary()
    #编译自动解码器
    ae.compile(loss="binary_crossentropy", optimizer='adam')
    return ae,encoder,decoder

5、定义获取数据的方法

def get_data():
    # Preparing MNIST Dataset
    (x_train_orig, y_train), (x_test_orig, y_test) = tensorflow.keras.datasets.mnist.load_data()
    x_train_orig = x_train_orig.astype("float32") / 255.0
    x_test_orig = x_test_orig.astype("float32") / 255.0
    
    x_train = x_train_orig.reshape((-1, numpy.prod(x_train_orig.shape[1:])))
    x_test = x_test_orig.reshape((-1, numpy.prod(x_test_orig.shape[1:])))
    return x_train,y_train,x_test,y_test

6、训练与使用编码器

ae,encoder,decoder=get_autoencoder()
x_train,y_train,x_test,y_test=get_data()
# Training AE
ae.fit(x_train, x_train, epochs=5088, batch_size=256, shuffle=True, validation_data=(x_test, x_test))
encoded_images = encoder.predict(x_train)
decoded_images = decoder.predict(encoded_images)

7、编码解码结果可视化

decoded_images_orig = numpy.reshape(decoded_images, newshape=(decoded_images.shape[0], 28, 28))
num_images_to_show = 5
for im_ind in range(num_images_to_show):
    plot_ind = im_ind*2 + 1
    rand_ind = numpy.random.randint(low=0, high=x_train.shape[0])
    plt.subplot(num_images_to_show, 2, plot_ind)
    plt.imshow(x_train[rand_ind].reshape((28,28)), cmap="gray")
    plt.subplot(num_images_to_show, 2, plot_ind+1)
    plt.imshow(decoded_images_orig[rand_ind, :, :], cmap="gray")
#清空绘图缓存
plt.figure()
plt.scatter(encoded_images[:, 0], encoded_images[:, 1], c=y_train)
plt.colorbar()

e0ce076fc100a43af3683adae4214573_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E0ODYyNTk=,size_16,color_FFFFFF,t_70.png

全部代码

 
from keras.layers import Dense,Input
import tensorflow
from keras import Model
from keras.models import Sequential
import numpy
import matplotlib.pyplot as plt
 
# Encoder
def get_encoder(in_shape,out_units):
    model = Sequential()
    model.add(Dense(300,input_shape=(in_shape,), activation='relu'))
    model.add(Dense(10, activation='relu'))
    model.add(Dense(out_units, activation='relu'))
    model.summary()
    return model
    
# Decoder
def get_decoder(in_shape,out_units):
    model = Sequential()
    model.add(Dense(10,input_shape=(in_shape,), activation='relu'))
    model.add(Dense(300, activation='relu'))
    model.add(Dense(out_units, activation='sigmoid'))
    return model
def get_autoencoder():
    # Autoencoder
    data_num=784
    feature_num=2
    #定义编码器的输入
    ae_input = Input(shape=(data_num,), name="AE_input")
    
    #获取编码器
    encoder=get_encoder(data_num,feature_num)
    #获取解码器
    decoder=get_decoder(feature_num,data_num)
    
    #使用编码器编码输入得到特征
    ae_encoder_output = encoder(ae_input)
    #使用解码器解码特征得到输出
    ae_decoder_output = decoder(ae_encoder_output)
    #构造自动解码器模型
    ae = Model(ae_input, ae_decoder_output, name="AE")
    ae.summary()
    #编译自动解码器
    ae.compile(loss="binary_crossentropy", optimizer='adam')
    return ae,encoder,decoder
def get_data():
    # Preparing MNIST Dataset
    (x_train_orig, y_train), (x_test_orig, y_test) = tensorflow.keras.datasets.mnist.load_data()
    x_train_orig = x_train_orig.astype("float32") / 255.0
    x_test_orig = x_test_orig.astype("float32") / 255.0
    
    x_train = x_train_orig.reshape((-1, numpy.prod(x_train_orig.shape[1:])))
    x_test = x_test_orig.reshape((-1, numpy.prod(x_test_orig.shape[1:])))
    return x_train,y_train,x_test,y_test
    
ae,encoder,decoder=get_autoencoder()
x_train,y_train,x_test,y_test=get_data()
# Training AE
ae.fit(x_train, x_train, epochs=5088, batch_size=256, shuffle=True, validation_data=(x_test, x_test))
encoded_images = encoder.predict(x_train)
decoded_images = decoder.predict(encoded_images)
 
decoded_images_orig = numpy.reshape(decoded_images, newshape=(decoded_images.shape[0], 28, 28))
num_images_to_show = 5
for im_ind in range(num_images_to_show):
    plot_ind = im_ind*2 + 1
    rand_ind = numpy.random.randint(low=0, high=x_train.shape[0])
    plt.subplot(num_images_to_show, 2, plot_ind)
    plt.imshow(x_train[rand_ind].reshape((28,28)), cmap="gray")
    plt.subplot(num_images_to_show, 2, plot_ind+1)
    plt.imshow(decoded_images_orig[rand_ind, :, :], cmap="gray")
#清空绘图缓存
plt.figure()
plt.scatter(encoded_images[:, 0], encoded_images[:, 1], c=y_train)
plt.colorbar()