forked from aymericdamien/TensorFlow-Examples
/
variational_autoencoder.py
81 lines (59 loc) · 2.59 KB
/
variational_autoencoder.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# -*- coding: utf-8 -*-
"""
Varational Auto Encoder Example.
变分自动编码器
"""
from __future__ import division, print_function, absolute_import
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#Import MNIST data
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)
# 基础模块
class Layer:
def __init__(self, input, n_output):
self.input = input
W = tf.Variable(tf.truncated_normal([ int(self.input.get_shape()[1]), n_output ], stddev = 0.001))#tf.shape(input)[0]
b = tf.Variable(tf.constant(0., shape = [ n_output ]))
self.raw_output = tf.matmul(input, W) + b
self.output = tf.nn.relu(self.raw_output)
# 样本集X
n_X = 784 # 28 * 28
n_z = 20 # latent variable count
X = tf.placeholder(tf.float32, shape = [ None, n_X ])
# Encoder
## \mu(X) 采用二层网络
ENCODER_HIDDEN_COUNT = 400
mu = Layer(Layer(X, ENCODER_HIDDEN_COUNT).output, n_z).raw_output
## \Sigma(X) 采用二层网络
log_sigma = Layer(Layer(X, ENCODER_HIDDEN_COUNT).output, n_z).raw_output # 为了训练不出nan? 至少实验的时候,直接让这个网络代表sigma是算不出来的,请高人指点!!!
sigma = tf.exp(log_sigma)
## KLD = D[N(mu(X), sigma(X))||N(0, I)] = 1/2 * sum(sigma_i + mu_i^2 - log(sigma_i) - 1)
KLD = 0.5 * tf.reduce_sum(sigma + tf.pow(mu, 2) - log_sigma - 1, reduction_indices = 1) # reduction_indices = 1代表按照每个样本计算一条KLD
# epsilon = N(0, I) 采样模块
epsilon = tf.random_normal(tf.shape(sigma), name = 'epsilon')
# z = mu + sigma^ 0.5 * epsilon
z = mu + tf.exp(0.5 * log_sigma) * epsilon
# Decoder ||f(z) - X|| ^ 2 重建的X与X的欧式距离,更加成熟的做法是使用crossentropy
def buildDecoderNetwork(z):
# 构建一个二层神经网络,因为二层神经网络可以逼近任何函数
DECODER_HIDDEN_COUNT = 400
layer1 = Layer(z, DECODER_HIDDEN_COUNT)
layer2 = Layer(layer1.output, n_X)
return layer2.raw_output
reconstructed_X = buildDecoderNetwork(z)
reconstruction_loss = tf.reduce_sum(tf.nn.sigmoid_cross_entropy_with_logits(reconstructed_X, X), reduction_indices = 1)
loss = tf.reduce_mean(reconstruction_loss + KLD)
# minimize loss
n_steps = 100000
learning_rate = 0.01
batch_size = 100
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss)
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
for step in xrange(1, n_steps):
batch_x, batch_y = mnist.train.next_batch(batch_size)
_, l = sess.run([ optimizer, loss ], feed_dict = { X: batch_x })
if step % 100 == 0:
print('Step', step, ', Loss:', l)