10-8 变分自编码
使用变分自编码模型进行模拟MNIST数据的生成。
程序:
#1 引入库,定义占位符
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from scipy.stats import norm
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/data/") # , one_hot=True)
n_input = 784
n_hidden_1 = 256
n_hidden_2 = 2
x = tf.placeholder(tf.float32, [None, n_input])
zinput = tf.placeholder(tf.float32, [None, n_hidden_2])
'''----------------------------------------------------'''
#3 定义学习参数
weights = {
'w1': tf.Variable(tf.truncated_normal([n_input, n_hidden_1],
stddev=0.001)),
'b1': tf.Variable(tf.zeros([n_hidden_1])),
'mean_w1': tf.Variable(tf.truncated_normal([n_hidden_1, n_hidden_2],
stddev=0.001)),
'log_sigma_w1': tf.Variable(tf.truncated_normal([n_hidden_1, n_hidden_2],
stddev=0.001)),
'w2': tf.Variable(tf.truncated_normal([n_hidden_2, n_hidden_1],
stddev=0.001)),
'b2': tf.Variable(tf.zeros([n_hidden_1])),
'w3': tf.Variable(tf.truncated_normal([n_hidden_1, n_input],
stddev=0.001)),
'b3': tf.Variable(tf.zeros([n_input])),
'mean_b1': tf.Variable(tf.zeros([n_hidden_2])),
'log_sigma_b1': tf.Variable(tf.zeros([n_hidden_2]))
}
'''----------------------------------------------------'''
#3 定义网络结构
h1 = tf.nn.relu(tf.add(tf.matmul(x, weights['w1']), weights['b1']))
z_mean = tf.add(tf.matmul(h1, weights['mean_w1']), weights['mean_b1'])
z_log_sigma_sq = tf.add(tf.matmul(h1, weights['log_sigma_w1']), weights['log_sigma_b1'])
# sample from gaussian distribution
eps = tf.random_normal(tf.stack([tf.shape(h1)[0], n_hidden_2]), 0, 1, dtype=tf.float32)
z = tf.add(z_mean, tf.multiply(tf.sqrt(tf.exp(z_log_sigma_sq)), eps))
h2 = tf.nn.relu(tf.matmul(z, weights['w2']) + weights['b2'])
reconstruction = tf.matmul(h2, weights['w3']) + weights['b3']
h2out = tf.nn.relu(tf.matmul(zinput, weights['w2']) + weights['b2'])
reconstructionout = tf.matmul(h2out, weights['w3']) + weights['b3']
'''-----------------------------------------------------------------'''
#4 构建模型的反向传播
# cost
reconstr_loss = 0.5 * tf.reduce_sum(tf.pow(tf.subtract(reconstruction, x), 2.0))
latent_loss = -0.5 * tf.reduce_sum(1 + z_log_sigma_sq
- tf.square(z_mean)
- tf.exp(z_log_sigma_sq), 1)
cost = tf.reduce_mean(reconstr_loss + latent_loss)
optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(cost)
'''------------------------------------------------------------------'''
#5 设置参数,进行训练
training_epochs = 50#迭代50次
batch_size = 128
display_step = 3
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for epoch in range(training_epochs):
avg_cost = 0.
total_batch = int(mnist.train.num_examples / batch_size)
# 遍历全部数据集
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size) # 取数据
# Fit training using batch data
_, c = sess.run([optimizer, cost], feed_dict={x: batch_xs})
# c = autoencoder.partial_fit(batch_xs)
# 显示训练中的详细信息
if epoch % display_step == 0:
print("Epoch:", '%04d' % (epoch + 1), "cost=", "{:.9f}".format(c))
print("完成!")
# 测试
print("Result:", cost.eval({x: mnist.test.images}))
print("*******************************************")
'''------------------------------------------------'''
# 可视化结果
show_num = 10
pred = sess.run(
reconstruction, 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(pred[i], (28, 28)))
plt.draw()
pred = sess.run(
z, feed_dict={x: mnist.test.images})
# x_test_encoded = encoder.predict(x_test, batch_size=batch_size)
plt.figure(figsize=(6, 6))
plt.scatter(pred[:, 0], pred[:, 1], c=mnist.test.labels)
plt.colorbar()
plt.show()
'''--------------------------------------------------------------'''
#6 高斯分布取样,生成模拟数据
# display a 2D manifold of the digits
n = 15 # figure with 15x15 digits
digit_size = 28
figure = np.zeros((digit_size * n, digit_size * n))
grid_x = norm.ppf(np.linspace(0.05, 0.95, n))
grid_y = norm.ppf(np.linspace(0.05, 0.95, n))
for i, yi in enumerate(grid_x):
for j, xi in enumerate(grid_y):
z_sample = np.array([[xi, yi]])
x_decoded = sess.run(reconstructionout, feed_dict={zinput: z_sample})
digit = x_decoded[0].reshape(digit_size, digit_size)
figure[i * digit_size: (i + 1) * digit_size,
j * digit_size: (j + 1) * digit_size] = digit
plt.figure(figsize=(10, 10))
plt.imshow(figure, cmap='Greys_r')
plt.show()
结果:
Epoch: 0001 cost= 2744.592773438
Epoch: 0004 cost= 2456.219238281
Epoch: 0007 cost= 2295.185546875
Epoch: 0010 cost= 2341.728027344
Epoch: 0013 cost= 2118.935302734
Epoch: 0016 cost= 2081.728027344
Epoch: 0019 cost= 2129.306640625
Epoch: 0022 cost= 2011.723144531
Epoch: 0025 cost= 1976.819580078
Epoch: 0028 cost= 2151.753173828
Epoch: 0031 cost= 1970.840820312
Epoch: 0034 cost= 2066.989013672
Epoch: 0037 cost= 2045.359375000
Epoch: 0040 cost= 2048.726562500
Epoch: 0043 cost= 1971.170898438
Epoch: 0046 cost= 2090.793457031
Epoch: 0049 cost= 1956.484130859
完成!
Result: 158223.56
*******************************************
10-9 条件变分自编码
使用条件变分自编码模型,通过制定标签输入生成对应类别的MNIST模拟数据。
程序:
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from scipy.stats import norm
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/data/", one_hot=True)
n_labels = 10
n_input = 784
n_hidden_1 = 256
n_hidden_2 = 2
#1 添加标签占位符
x = tf.placeholder(tf.float32, [None, n_input])
y = tf.placeholder(tf.float32, [None, n_labels])
zinput = tf.placeholder(tf.float32, [None, n_hidden_2])
'''----------------------------------------------------'''
#2 添加输入全连接权重
weights = {
'w1': tf.Variable(tf.truncated_normal([n_input, n_hidden_1],
stddev=0.001)),
'b1': tf.Variable(tf.zeros([n_hidden_1])),
'wlab1': tf.Variable(tf.truncated_normal([n_labels, n_hidden_1],
stddev=0.001)),
'blab1': tf.Variable(tf.zeros([n_hidden_1])),
'mean_w1': tf.Variable(tf.truncated_normal([n_hidden_1 * 2, n_hidden_2],
stddev=0.001)),
'log_sigma_w1': tf.Variable(tf.truncated_normal([n_hidden_1 * 2, n_hidden_2],
stddev=0.001)),
'w2': tf.Variable(tf.truncated_normal([n_hidden_2 + n_labels, n_hidden_1],
stddev=0.001)),
'b2': tf.Variable(tf.zeros([n_hidden_1])),
'w3': tf.Variable(tf.truncated_normal([n_hidden_1, n_input],
stddev=0.001)),
'b3': tf.Variable(tf.zeros([n_input])),
'mean_b1': tf.Variable(tf.zeros([n_hidden_2])),
'log_sigma_b1': tf.Variable(tf.zeros([n_hidden_2]))
}
'''----------------------------------------------------'''
#3 修改模型,将标签输出接入编码
h1 = tf.nn.relu(tf.add(tf.matmul(x, weights['w1']), weights['b1']))
hlab1 = tf.nn.relu(tf.add(tf.matmul(y, weights['wlab1']), weights['blab1']))
hall1 = tf.concat([h1, hlab1], 1) # 256*2
z_mean = tf.add(tf.matmul(hall1, weights['mean_w1']), weights['mean_b1'])
z_log_sigma_sq = tf.add(tf.matmul(hall1, weights['log_sigma_w1']), weights['log_sigma_b1'])
'''------------------------------------------------------------'''
#4 修改模型将标签接入解码
# sample from gaussian distribution
eps = tf.random_normal(tf.stack([tf.shape(h1)[0], n_hidden_2]), 0, 1, dtype=tf.float32)
z = tf.add(z_mean, tf.multiply(tf.sqrt(tf.exp(z_log_sigma_sq)), eps))
zall = tf.concat([z, y], 1)
h2 = tf.nn.relu(tf.matmul(zall, weights['w2']) + weights['b2'])
reconstruction = tf.matmul(h2, weights['w3']) + weights['b3']
zinputall = tf.concat([zinput, y], 1)
h2out = tf.nn.relu(tf.matmul(zinputall, weights['w2']) + weights['b2'])
reconstructionout = tf.matmul(h2out, weights['w3']) + weights['b3']
'''--------------------------------------------------------------'''
# cost
reconstr_loss = 0.5 * tf.reduce_sum(tf.pow(tf.subtract(reconstruction, x), 2.0))
latent_loss = -0.5 * tf.reduce_sum(1 + z_log_sigma_sq
- tf.square(z_mean)
- tf.exp(z_log_sigma_sq), 1)
cost = tf.reduce_mean(reconstr_loss + latent_loss)
optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(cost)
training_epochs = 50
batch_size = 128
display_step = 3
'''--------------------------------------------'''
#5 修改session中的feed部分
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for epoch in range(training_epochs):
avg_cost = 0.
total_batch = int(mnist.train.num_examples / batch_size)
# 遍历全部数据集
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size) # 取数据
# Fit training using batch data
_, c = sess.run([optimizer, cost], feed_dict={x: batch_xs, y: batch_ys})
# c = autoencoder.partial_fit(batch_xs)
# 显示训练中的详细信息
if epoch % display_step == 0:
print("Epoch:", '%04d' % (epoch + 1), "cost=", "{:.9f}".format(c))
print("完成!")
# 测试
print("Result:", cost.eval({x: mnist.test.images, y: mnist.test.labels}))
'''----------------------------------------------------------'''
#6 运行模型生成模拟数据
# 根据图片模拟生成图片
show_num = 10
pred = sess.run(
reconstruction, feed_dict={x: mnist.test.images[:show_num], y: mnist.test.labels[: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(pred[i], (28, 28)))
plt.draw()
# 根据label模拟生产图片可视化结果
show_num = 10
z_sample = np.random.randn(10, 2)
pred = sess.run(
reconstructionout, feed_dict={zinput: z_sample, y: mnist.test.labels[: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(pred[i], (28, 28)))
plt.draw()
结果:
Epoch: 0001 cost= 2328.727294922
Epoch: 0004 cost= 1815.671508789
Epoch: 0007 cost= 1895.735351562
Epoch: 0010 cost= 1781.059570312
Epoch: 0013 cost= 1962.250366211
Epoch: 0016 cost= 1698.589233398
Epoch: 0019 cost= 1727.575683594
Epoch: 0022 cost= 1681.909423828
Epoch: 0025 cost= 1852.812988281
Epoch: 0028 cost= 1757.616210938
Epoch: 0031 cost= 1612.345458984
Epoch: 0034 cost= 1790.543457031
Epoch: 0037 cost= 1642.631835938
Epoch: 0040 cost= 1671.140869141
Epoch: 0043 cost= 1689.603393555
Epoch: 0046 cost= 1653.314697266
Epoch: 0049 cost= 1814.113037109
完成!
Result: 133801.08