一、简介
AutoEncoder 自编码算法采用无监督学习方式进行训练,ta是一种尽可能复现输入信号的神经网络,为了实现复现,自编码器就必须捕捉到关键的输入因素,像PCA主成分分析一样,就可可以代表原来的信息的主要成分。
from tensorflow.examples.tutorials.mnist import input_data
import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
def auto_encoder(dimensions=None):
if dimensions is None:
dimensions = [784, 512, 256, 64]
x = tf.compat.v1.placeholder(tf.float32, [None, dimensions[0]], name='X')
encoder = []
current_input = x
for layer_i, n_output in enumerate(dimensions[1:]):
print("currenct_input:",current_input)
n_input = int(current_input.get_shape()[1])
print("n_input:",n_input)
w = tf.compat.v1.Variable(
tf.compat.v1.random_uniform([n_input, n_output], -1.0 / np.sqrt(n_input), 1.0 / np.sqrt(n_input),dtype=tf.float32),
name='W') #
b = tf.compat.v1.Variable(tf.zeros([n_output]), name='b')
encoder.append(w)
output = tf.compat.v1.nn.tanh(tf.matmul(current_input, w) + b)
current_input = output
# 信息表达
z = current_input
encoder.reverse()
# 设置解码。使用相同的权重参数
for layer_i, n_output in enumerate(dimensions[:-1][::-1]):
print("current_input:",current_input)
w = tf.compat.v1.transpose(encoder[layer_i], name='W') #将参数倒置,比如原来 256*64 这里就变为 64 *256
b = tf.compat.v1.Variable(tf.compat.v1.zeros([n_output]), name='b')
output = tf.compat.v1.matmul(current_input, w) + b
current_input = output
# 重构神经网络
y = current_input
# 计算点间差距,返回loss值
cost = tf.compat.v1.reduce_sum(tf.compat.v1.square(y - x), name='cost')
return {'x': x, 'z': z, 'y': y, 'cost': cost}
'''
mean_img shape: (784,)
currenct_input: Tensor("X:0", shape=(?, 784), dtype=float32)
n_input: 784
currenct_input: Tensor("Tanh:0", shape=(?, 256), dtype=float32)
n_input: 256
current_input: Tensor("Tanh_1:0", shape=(?, 64), dtype=float32)
current_input: Tensor("add_2:0", shape=(?, 256), dtype=float32)
'''
模型定义完毕后导入数据运行
def test_minst():
# 读取数据
mnist = input_data.read_data_sets('data/MNIST/', one_hot=True)
mean_img = np.mean(mnist.train.images, axis=0)
print("mean_img shape:",mean_img.shape)
# 设置自编码模型ae
ae = auto_encoder(dimensions=[784, 256, 64])
print("ae :",ae)
# 设置优化函数
learning_rate = 0.001
optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate).minimize(ae['cost'])
sess = tf.compat.v1.Session()
sess.run(tf.compat.v1.global_variables_initializer())
rlog = '../logs/log_ae'
xsum = tf.compat.v1.summary.FileWriter(rlog, sess.graph)
batch_size = 50
n_epochs = 10
for epoch_i in range(n_epochs):
for batch_i in range(mnist.train.num_examples // batch_size):
batch_xs, _ = mnist.train.next_batch(batch_size)
train = np.array([img - mean_img for img in batch_xs])
sess.run(optimizer, feed_dict={ae['x']: train})
print("epoch---",epoch_i,"loss:", sess.run(ae['cost'], feed_dict={ae['x']: mnist.train.images})) # train
# 重构图像
n_examples = 15
test_xs, _ = mnist.test.next_batch(n_examples)
print("test_xs shape:", test_xs.shape)
test_xs_norm = np.array([img - mean_img for img in test_xs])
recon = sess.run(ae['y'], feed_dict={ae['x']: test_xs_norm})
print("recon shape:", recon.shape)
fig, axs = plt.subplots(2, n_examples, figsize=(10, 2))
for example_i in range(n_examples):
axs[0][example_i].imshow(np.reshape(test_xs[example_i, :], (28, 28))) #重新塑性才能画出来
axs[1][example_i].imshow(np.reshape(recon[example_i, :] + mean_img, (28, 28)))
fig.show()
plt.draw()
if __name__ == '__main__':
test_minst()
'''
ae : {'x': <tf.Tensor 'X:0' shape=(?, 784) dtype=float32>, 'z': <tf.Tensor 'Tanh_1:0' shape=(?, 64) dtype=float32>, 'y': <tf.Tensor 'add_3:0' shape=(?, 784) dtype=float32>, 'cost': <tf.Tensor 'cost:0' shape=() dtype=float32>}
epoch--- 0 loss: 856718.6
epoch--- 1 loss: 808166.75
epoch--- 2 loss: 761433.44
epoch--- 3 loss: 748033.06
epoch--- 4 loss: 739432.9
epoch--- 5 loss: 731797.1
epoch--- 6 loss: 723434.9
epoch--- 7 loss: 715355.2
epoch--- 8 loss: 708394.75
epoch--- 9 loss: 706296.4
test_xs shape: (15, 784)
recon shape: (15, 784)
'''
W(784,256)->W_3 (256,784) W_1(256,64)->W_2(64,256) 最后的输出返回到原输入X出计算cost,即X与Y的距离