深度学习5 keras实现基于卷积的自编码器

747 阅读1分钟

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

关于自编码器没有太多的介绍,基本描述可以查看blog.csdn.net/a486259/art…

更详细的介绍可以查看keras-cn.readthedocs.io/en/latest/l…

基于卷积的自编码器主要数依赖于卷积、池化和上采样实现,可以有效的采集的像素之间的空间依赖,其对于图像数据效果和性能都优于全连接编码器

自编码器的构建流程可以参考:blog.csdn.net/a486259/art…

本文的自编码器只是将全连接改成了卷积网络,保存即可运行

 
from keras.layers.convolutional import Conv2D,MaxPooling2D,UpSampling2D
from keras.layers import 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):
    model = Sequential()
    model.add(Conv2D(16, (3, 3), input_shape=in_shape, padding='same', activation='relu'))
    model.add(Conv2D(8, (3, 3),  padding='same', activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Conv2D(16, (3, 3),  padding='same', activation='relu'))
    model.add(Conv2D(8, (3, 3),  padding='same', activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Conv2D(8, (3, 3),  padding='same', activation='sigmoid'))
    model.summary()
    return model
    
# Decoder
def get_decoder(in_shape=(2,2,4)):
    model = Sequential()
    model.add(Conv2D(8, (3, 3), input_shape=in_shape, padding='same', activation='relu'))
    model.add(Conv2D(16, (3, 3),  padding='same', activation='relu'))
    model.add(UpSampling2D(size=(2, 2)))
    model.add(Conv2D(16, (3, 3),  padding='same', activation='relu'))
    model.add(Conv2D(8, (3, 3),  padding='same', activation='relu'))
    model.add(UpSampling2D(size=(2, 2)))
    model.add(Conv2D(1, (3, 3),  padding='same', activation='sigmoid'))
    model.summary()
    return model
def get_autoencoder(in_shape):
    # Autoencoder
    ae_input = Input(shape=in_shape, name="AE_input")
    encoder=get_encoder(in_shape)
    
    output=encoder.get_layer(index=-1).output_shape
    print(output)
    decoder=get_decoder(output[1:])
    
    ae_encoder_output = encoder(ae_input)
    ae_decoder_output = decoder(ae_encoder_output)
    
    ae = Model(ae_input, ae_decoder_output, name="AE")
    ae.compile(loss="binary_crossentropy", optimizer='adadelta')
    ae.summary()
    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,28,28,1)
    x_test=x_test_orig.reshape(-1,28,28,1)
    return x_train,y_train,x_test,y_test
 
shape=(28,28,1) 
ae,encoder,decoder=get_autoencoder(shape)
x_train,y_train,x_test,y_test=get_data()
# Training AE
ae.fit(x_train, x_train, epochs=20, 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")

训练效果图

image.png

image.png