参考
自编码器是神经网络的一种,是一种无监督学习方法,使用了反向传播算法,目标是使输出=输入。 自编码器内部有隐藏层 ,可以产生编码表示输入。1986 年Rumelhart 提出。
自编码器主要作用在于通过复现输出而捕捉可以代表输入的重要因素,利用中间隐层对输入的压缩表达,达到像PCA那样的找到原始信息主成分的效果。
传统自编码器被用于降维或特征学习。 近年来,自编码器与潜变量模型理论的联系将自编码器带到了生成式建模的前沿。
构建一个两层降维的自编码网络,提取图像特征,并使用特征重新构建图像
由784--->256--->128--->256--->784
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# 导入 MINST 数据集
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
# 网络模型参数
learning_rate = 0.01
n_hidden_1 = 256 # 第一层256个节点
n_hidden_2 = 128 # 第二层128个节点
n_input = 784 # MNIST data 输入 (img shape: 28*28)
# 占位符
x = tf.placeholder("float", [None, n_input])#输入
y = x #输出
#学习参数
weights = {
'encoder_h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),
'encoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),
'decoder_h1': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_1])),
'decoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_input])),
}
biases = {
'encoder_b1': tf.Variable(tf.zeros([n_hidden_1])),
'encoder_b2': tf.Variable(tf.zeros([n_hidden_2])),
'decoder_b1': tf.Variable(tf.zeros([n_hidden_1])),
'decoder_b2': tf.Variable(tf.zeros([n_input])),
}
# 编码
def encoder(x):
layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']),biases['encoder_b1']))
layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['encoder_h2']), biases['encoder_b2']))
return layer_2
# 解码
def decoder(x):
layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']),biases['decoder_b1']))
layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['decoder_h2']),biases['decoder_b2']))
return layer_2
#输出的节点
encoder_out = encoder(x)
pred = decoder(encoder_out)
# 使用平方差为cost
cost = tf.reduce_mean(tf.pow(y - pred, 2))
optimizer = tf.train.RMSPropOptimizer(learning_rate).minimize(cost)
# 训练参数
training_epochs = 20 #一共迭代20次
batch_size = 256 #每次取256个样本
display_step = 5 #迭代5次输出一次信息
# 启动绘话
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
total_batch = int(mnist.train.num_examples/batch_size)
# 开始训练
for epoch in range(training_epochs):#迭代
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)#取数据
_, c = sess.run([optimizer, cost], feed_dict={x: batch_xs})# 训练模型
if epoch % display_step == 0:# 现实日志信息
print("Epoch:", '%04d' % (epoch+1),"cost=", "{:.9f}".format(c))
print("完成!")
# 测试
correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
# 计算错误率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
print ("Accuracy:", 1-accuracy.eval({x: mnist.test.images, y: mnist.test.images}))
# 可视化结果
show_num = 10
reconstruction = sess.run(
pred, feed_dict={x: mnist.test.images[:show_num]})
f, a = plt.subplots(2, 10, figsize=(10, 2))
for i in range(show_num):
a[0][i].imshow(np.reshape(mnist.test.images[i], (28, 28)))
a[1][i].imshow(np.reshape(reconstruction[i], (28, 28)))
plt.show()
基本上还原了图像信息
自编码提取图像二维特征,并利用二维特征还原图片,由于sigmoid函数特性,无法使用更深的层,这里只做4层压缩
784--->256--->64--->16--->2--->16--->64--->256--->784
在编码的最后一层,没有进行sigmoid变换,以为生成的二维数据已经变得极为主要,少一些变换可以最大化的保存原有特征,
这个二维特征可以对图像进行分类
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# 导入 MINST 数据集
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
# 参数设置
learning_rate = 0.01
# hidden layer settings
n_hidden_1 = 256
n_hidden_2 = 64
n_hidden_3 = 16
n_hidden_4 = 2
n_input = 784 # MNIST data 输入 (img shape: 28*28)
# tf Graph输入
x = tf.placeholder("float", [None, n_input])
y = x
weights = {
'encoder_h1': tf.Variable(tf.random_normal([n_input, n_hidden_1], )),
'encoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2], )),
'encoder_h3': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_3], )),
'encoder_h4': tf.Variable(tf.random_normal([n_hidden_3, n_hidden_4], )),
'decoder_h1': tf.Variable(tf.random_normal([n_hidden_4, n_hidden_3], )),
'decoder_h2': tf.Variable(tf.random_normal([n_hidden_3, n_hidden_2], )),
'decoder_h3': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_1], )),
'decoder_h4': tf.Variable(tf.random_normal([n_hidden_1, n_input], )),
}
biases = {
'encoder_b1': tf.Variable(tf.zeros([n_hidden_1])),
'encoder_b2': tf.Variable(tf.zeros([n_hidden_2])),
'encoder_b3': tf.Variable(tf.zeros([n_hidden_3])),
'encoder_b4': tf.Variable(tf.zeros([n_hidden_4])),
'decoder_b1': tf.Variable(tf.zeros([n_hidden_3])),
'decoder_b2': tf.Variable(tf.zeros([n_hidden_2])),
'decoder_b3': tf.Variable(tf.zeros([n_hidden_1])),
'decoder_b4': tf.Variable(tf.zeros([n_input])),
}
def encoder(x):
layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']),
biases['encoder_b1']))
layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['encoder_h2']),
biases['encoder_b2']))
layer_3 = tf.nn.sigmoid(tf.add(tf.matmul(layer_2, weights['encoder_h3']),
biases['encoder_b3']))
layer_4 = tf.add(tf.matmul(layer_3, weights['encoder_h4']),
biases['encoder_b4'])
return layer_4
def decoder(x):
layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']),
biases['decoder_b1']))
layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['decoder_h2']),
biases['decoder_b2']))
layer_3 = tf.nn.sigmoid(tf.add(tf.matmul(layer_2, weights['decoder_h3']),
biases['decoder_b3']))
layer_4 = tf.nn.sigmoid(tf.add(tf.matmul(layer_3, weights['decoder_h4']),
biases['decoder_b4']))
return layer_4
# 构建模型
encoder_op = encoder(x)
y_pred = decoder(encoder_op) # 784 Features
cost = tf.reduce_mean(tf.pow(y - y_pred, 2))
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost)
# 训练
training_epochs = 20 # 20 Epoch 训练
batch_size = 256
display_step = 1
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
total_batch = int(mnist.train.num_examples / batch_size)
# 启动循环开始训练
for epoch in range(training_epochs):
# 遍历全部数据集
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
_, c = sess.run([optimizer, cost], feed_dict={x: batch_xs})
# 显示训练中的详细信息
if epoch % display_step == 0:
print("Epoch:", '%04d' % (epoch + 1),
"cost=", "{:.9f}".format(c))
print("完成!")
# 可视化结果
show_num = 10
encode_decode = sess.run(
y_pred, feed_dict={x: mnist.test.images[:show_num]})
# 将样本对应的自编码重建图像一并输出比较
f, a = plt.subplots(2, 10, figsize=(10, 2))
for i in range(show_num):
a[0][i].imshow(np.reshape(mnist.test.images[i], (28, 28)))
a[1][i].imshow(np.reshape(encode_decode[i], (28, 28)))
plt.show()
aa = [np.argmax(l) for l in mnist.test.labels] # 将onehot编码转成一般编码
encoder_result = sess.run(encoder_op, feed_dict={x: mnist.test.images})
plt.scatter(encoder_result[:, 0], encoder_result[:, 1], c=aa) # mnist.test.labels)
plt.colorbar()
plt.show()
转载至链接:https://my.oschina.net/ahaoboy/blog/1924383