自编码网络的原理
-
自编码的目的就是学习到原始数据的精髓,然后将这个精髓送到网络中进行学习,其也可以理解和PCA一样,实现对原始数据进行降维处理。
-
使用了反向传播算法,目标是使输出=输入 ,
-
原始数据A—》B-----》C 其中B代表原始数据的精髓,C是解编码的数据,通过缩小A和C的误差,来实现得到比较准确的B。
-
最终得到B进行接下来的学习。利用中间隐层B对输入A的压缩表达,达到像PCA那样的找到原始信息主成分的效果。
-
传统自编码器被用于去噪,降维或特征学习
-
在深度学习中,自编码器是非常有用的一种无监督学习模型。自编码器由encoder和decoder组成,前者将原始表示编码成隐层表示,后者将隐层表示解码成原始表示,训练目标为最小化重构误差,而且一般而言,隐层的特征维度低于原始特征维度。
-
自编码器只是一种思想,在具体实现中,encoder和decoder可以由多种深度学习模型构成,例如全连接层、卷积层或LSTM等,以下使用Keras来实现用于图像去噪的卷积自编码器。
用自编码器进行图像去噪
#导入包
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
# X shape (60,000 28x28), y shape (10,000, )
(x_train, _), (x_test, y_test) = mnist.load_data()
# 数据预处理,数据归一化
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)
# 压缩特征维度至2维
encoding_dim = 2
# this is our input placeholder
input_img = Input(shape=(784,))
# 编码层 Dense:全连接层
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='tanh')(decoded)
# 构建自编码模型
autoencoder = Model(inputs=input_img, outputs=decoded)
# 构建编码模型
encoder = Model(inputs=input_img, outputs=encoder_output)
# compile autoencoder
autoencoder.compile(optimizer='adam', loss='mse')
# training
autoencoder.fit(x_train, x_train, epochs=20, batch_size=256, shuffle=True)
x:输入数据。如果模型只有一个输入,那么x的类型是numpy
array,如果模型有多个输入,那么x的类型应当为list,list的元素是对应于各个输入的numpy array
y:标签,numpy array
# plotting
encoded_imgs = encoder.predict(x_test)
plt.scatter(encoded_imgs[:, 0], encoded_imgs[:, 1], c=y_test, s=3)
plt.colorbar()
plt.show()
三、程序解读
自编码,简单来说就是把输入数据进行一个压缩和解压缩的过程。
原来有很多特征,压缩成几个来代表原来的数据,解压之后恢复成原来的维度,再和原数据进行比较。
它是一种非监督算法,只需要输入数据,解压缩之后的结果与原数据本身进行比较。
程序的主要功能是把 datasets.mnist 数据的 28*28=784 维的数据,压缩成 2 维的数据,然后在一个二维空间中可视化出分类的效果。
首先,导入数据并进行数据预处理,
本例使用Model模块的Keras的model泛化模型来进行模型搭建,便于我们从模型中间导出数据并进行可视化。
进行模型搭建的时候,注意要进行逐层特征提取,最终压缩至2维,解码的过程要跟编码过程一致相反。
随后对Autoencoder和encoder分别建模,编译、训练。
将编码模型的预测结果通过Matplotlib可视化出来,就可以看到原数据的二维编码结果在二维平面上的聚类效果,还是很明显的。
最后看到可视化的结果,自编码模型可以把这几个数字给区分开来,我们可以用自编码这个过程来作为一个特征压缩的方法,和PCA的功能一样,效果要比它好一些,因为它是非线性的结构。
先看一下最后的结果,使用的是手写数字MNIST数据集,上面一行是添加噪音的图像,下面一行是去噪之后的结果。