一.引言:
AutoEncoder-自编码是神经网络中常见的无监督学习,其目的一般为提取原始目标中的关键信息,类似于降维与主成分分析,但又不完全相同,其原理是用输入信息作为输出信息训练模型,最终提取中间的关键信息作为输入信息的抽象表达。
二.实现:
导入依赖:
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, Input
1.数据准备
这里采用常见的mnist手写数字识别数据作为输入信息,x_train是60000x28x28的原始数据,这里先做数据归一化,然后通过reshape转换为60000 x 784的数据形式
(x_train, x_test), (x_test, y_test) = mnist.load_data()
# 1.简单归一处理
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
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)
2.定义压缩维度
encoding_dim = 2
3.定义AutoEncoder模型并训练
输入层的784根据上面准备数据(60000x784)而来,模型分为两个部分,编码层进行信息压缩,将原始图像数据抽象到 encoding_dim 的维度,随后解码层根据抽象的编码进行解压重新获取 784维的向量。自编码的精髓就是用自己学习自己,但最终一般只留下编码层,因为编码层可以根据给定数据对原始数据做出抽象。所以自编码模型autoencoder的输出是解码得到的最终784维的结果,而编码层则只保留了 encoding_dim 的输出。
input_img = Input(shape=(784,))
# 编码层
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)
# 解码层
decoded = Dense(10, activation='relu')(encoder_output)
decoded = Dense(64, activation='relu')(decoded)
decoded = Dense(128, activation='relu')(decoded)
decoded = Dense(784, activation='relu')(decoded)
# 构建自编码模型
autoencoder = Model(inputs=input_img, outputs=decoded)
# 构建编码模型
encoder = Model(inputs=input_img, outputs=encoder_output)
# 编译模型
autoencoder.compile(optimizer='rmsprop', loss='mse')
# 训练模型
autoencoder.fit(x_train, x_train, epochs=20, batch_size=256, shuffle=True)
4.查看自编码器对数据的抽象能力
# 2D绘图
encoded_imgs = encoder.predict(x_test)
print(encoded_imgs.shape,x_test.shape,y_test.shape)
plt.scatter(encoded_imgs[:, 0], encoded_imgs[:, 1], c=y_test, s=3)
plt.title("Dim=2")
plt.colorbar()
plt.show()
eoncoding_dim为2时,可以看到模型具备一定对数据的分类能力

5.查看3D情况下模型的信息提取能力
fig = plt.figure()
ax = fig.gca(projection='3d')
# ax = fig.add_subplot(111, projection='3d')
ax.scatter(encoded_imgs[:, 0], encoded_imgs[:, 1], encoded_imgs[:, 2], c=y_test, s=3, alpha=0.5)
plt.show()
encoding_dim改为3时,可以看到混在一起的点变少了,因为模型有更多的维度去学习和表达

三.总结:
AutoEncoder算是深度学习入门的基础算法, 通过编码层实现了对原始输入信息的压缩或者说是精炼。除了调整 encoding_dim,编码层解码层的激活函数,是否添加正则化系数 ergularizers 以及优化器和损失函数都可以进行调整,通过不同参数可以看到图像不同的映射趋势,只不过更高维的数据很难直观的观察。
更多推荐算法相关深度学习:深度学习导读专栏