自编码器是一种将它们的输入复制到输出的神经网络,通过将输入压缩成一种隐藏空间表示,然后再重构这种表示的输出。这种网络由编码器和解码器两种部分组成。
编码器: h = f ( x ) h = f(x) h=f(x)
解码器: r = g ( x ) r=g(x) r=g(x)
自编码器的整体是可以用函数 g ( f ( x ) ) = r g(f(x)) = r g(f(x))=r来描述,我们的目的是想得到 r r r与原始输入 x x x相近。如果直接把输入复制到输出中,是没有任何用处的,所以要迫使自编码器学习训练数据的最有代表性的特征。
from keras.layers import Input, Dense
from keras.models import Model
from keras.datasets import mnist
import numpy as np
import matplotlib.pyplot as plt
# Using Tensroflow backend
(x_train,_), (x_test,_) = mnist.load_data()
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255. ##归一化处理
x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:]))) ##现在样本是60000 784的格式
x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))
encoding_dim = 32 ##设置中间层神经元的个数
input_img = Input(shape=(784,)) ##输入层神经元个数
encoded = Dense(encoding_dim, activation='relu')(input_img) ##编码器输出维度是encoding_dim
decoded = Dense(784, activation='sigmoid')(encoded)
可以查看一下encoded的维度
encoded.shape
# TensorShape([Dimension(None), Dimension(32)])
autoencoder = Model(inputs=input_img, outputs=decoded) ##解码部分
encoder = Model(inputs=input_img, outputs=encoded) ##编码部分
autoencoder.summary()
###############################output###############################
Model: "model_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 784) 0
_________________________________________________________________
dense_1 (Dense) (None, 32) 25120
_________________________________________________________________
dense_2 (Dense) (None, 784) 25872
=================================================================
Total params: 50,992
Trainable params: 50,992
Non-trainable params: 0
_________________________________________________________________
encoded_input = Input(shape=(encoding_dim,)) ##解码器的输入
decoder_layer = autoencoder.layers[-1]
decoder = Model(inputs=encoded_input, outputs=decoder_layer(encoded_input)) ##解码器
# 编译并训练自编码器
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
autoencoder.fit(x_train, x_train, epochs=500, batch_size=256, shuffle=True, validation_data=(x_test, x_test))
查看结果
encode_imgs = encoder.predict(x_test) #对原始的测试图像进行编码
decode_imgs = decoder.predict(encode_imgs) #重构测试图像
n = 10
plt.figure(figsize=(20, 4))
for i in range(n):
ax = plt.subplot(2, n, i+1)
plt.imshow(x_test[i].reshape(28,28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
ax = plt.subplot(2, n, i+1+n)
plt.imshow(decode_imgs[i].reshape(28,28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()