Skip to content

Instantly share code, notes, and snippets.

@grt1st
Last active October 20, 2017 17:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grt1st/77beb11e719918a312832d05637888fa to your computer and use it in GitHub Desktop.
Save grt1st/77beb11e719918a312832d05637888fa to your computer and use it in GitHub Desktop.
VAE_in_tensorflow
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import tensorflow as tf\n",
"\n",
"import matplotlib.pyplot as plt\n",
"%matplotlib inline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"导入我们的MNIST数据。"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Extracting /home/grt1st/data/train-images-idx3-ubyte.gz\n",
"Extracting /home/grt1st/data/train-labels-idx1-ubyte.gz\n",
"Extracting /home/grt1st/data/t10k-images-idx3-ubyte.gz\n",
"Extracting /home/grt1st/data/t10k-labels-idx1-ubyte.gz\n"
]
}
],
"source": [
"# Import MNIST data\n",
"from tensorflow.examples.tutorials.mnist import input_data\n",
"mnist = input_data.read_data_sets(\"/home/grt1st/data/\", one_hot=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"下面我们导入参数,包括学习率、训练周期、批次大小、展示步数。"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# Parameters\n",
"learning_rate = 0.001\n",
"training_epochs = 101\n",
"batch_size = 100\n",
"display_step = 5"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"下面是神经网络参数:两个隐藏层神经元数量、中间向量维度、输入维度。"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# Network Parameters\n",
"n_hidden_1 = 500\n",
"n_hidden_2 = 500\n",
"n_z = 20\n",
"n_input = 784 # MNIST data input (img shape: 28*28)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"定义我们隐藏层的函数。"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# func\n",
"transfer_func = tf.nn.softplus#tf.nn.relu"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"定义输入。"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# tf Graph input (only pictures)\n",
"X = tf.placeholder(tf.float32, [None, n_input])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"生成具有如下特性的权重的方法:\n",
"> 为了使得网络中信息更好的流动,每一层输出的方差应该尽量相等"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"def xavier_init(fan_in, fan_out, constant=1):\n",
" \"\"\" Xavier initialization of network weights\"\"\"\n",
" # https://stackoverflow.com/questions/33640581/how-to-do-xavier-initialization-on-tensorflow\n",
" low = -constant*np.sqrt(6.0/(fan_in + fan_out))\n",
" high = constant*np.sqrt(6.0/(fan_in + fan_out))\n",
" return tf.random_uniform((fan_in, fan_out),\n",
" minval=low, maxval=high,\n",
" dtype=tf.float32)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"生成权重和偏置。"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"weights = {\n",
" \"recognition_h1\": tf.Variable(xavier_init(n_input, n_hidden_1)),\n",
" \"recognition_h2\": tf.Variable(xavier_init(n_hidden_1, n_hidden_2)),\n",
" \"recognition_out_mean\": tf.Variable(xavier_init(n_hidden_2, n_z)),\n",
" \"recognition_out_log\": tf.Variable(xavier_init(n_hidden_2, n_z)),\n",
" \"generator_h1\": tf.Variable(xavier_init(n_z, n_hidden_1)),\n",
" \"generator_h2\": tf.Variable(xavier_init(n_hidden_1, n_hidden_2)),\n",
" \"generator_out_mean\": tf.Variable(xavier_init(n_hidden_2, n_input)),\n",
" \"generator_out_log\": tf.Variable(xavier_init(n_hidden_2, n_input)),\n",
"}\n",
"\n",
"biases = {\n",
" \"recognition_b1\": tf.Variable(tf.zeros([n_hidden_1], dtype=tf.float32)),\n",
" \"recognition_b2\": tf.Variable(tf.zeros([n_hidden_2], dtype=tf.float32)),\n",
" \"recognition_out_mean\": tf.Variable(tf.zeros([n_z], dtype=tf.float32)),\n",
" \"recognition_out_log\": tf.Variable(tf.zeros([n_z], dtype=tf.float32)),\n",
" \"generator_b1\": tf.Variable(tf.zeros([n_hidden_1], dtype=tf.float32)),\n",
" \"generator_b2\": tf.Variable(tf.zeros([n_hidden_2], dtype=tf.float32)),\n",
" \"generator_out_mean\": tf.Variable(tf.zeros([n_input], dtype=tf.float32)),\n",
" \"generator_out_log\": tf.Variable(tf.zeros([n_input], dtype=tf.float32)),\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"定义编码与解码结构,这里我们分别称为**识别网络**与**生成网络**。"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"def recognition_network(x):\n",
" layer_1 = transfer_func(tf.add(tf.matmul(x, weights[\"recognition_h1\"]), biases[\"recognition_b1\"]))\n",
" layer_2 = transfer_func(tf.add(tf.matmul(layer_1, weights[\"recognition_h2\"]), biases[\"recognition_b2\"]))\n",
"\n",
" z_mean = tf.add(tf.matmul(layer_2, weights[\"recognition_out_mean\"]), biases[\"recognition_out_mean\"])\n",
" z_log = tf.add(tf.matmul(layer_2, weights[\"recognition_out_log\"]), biases[\"recognition_out_log\"])\n",
"\n",
" return z_mean, z_log\n",
"\n",
"def generator_network(x):\n",
" layer_1 = transfer_func(tf.add(tf.matmul(x, weights[\"generator_h1\"]), biases[\"generator_b1\"]))\n",
" layer_2 = transfer_func(tf.add(tf.matmul(layer_1, weights[\"generator_h2\"]), biases[\"generator_b2\"]))\n",
"\n",
" x_reconstr_mean = tf.nn.sigmoid(tf.add(tf.matmul(layer_2, weights[\"generator_out_mean\"]), biases[\"generator_out_mean\"]))\n",
"\n",
" return x_reconstr_mean"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"定义图运算,其中z为中间变量。"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"z_mean, z_log = recognition_network(X)\n",
"\n",
"eps = tf.random_normal((batch_size, n_z), 0, 1, dtype=tf.float32)\n",
"\n",
"# z = mu + sigma*epsilon\n",
"z = tf.add(z_mean, tf.multiply(tf.sqrt(tf.exp(z_log)), eps))\n",
"\n",
"x_reconstr_mean = generator_network(z)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"构建损失函数。"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"# 重建损失:负对数概率,伯努利分布下的输入\n",
"reconstr_loss = -tf.reduce_sum(X * tf.log(1e-10 + x_reconstr_mean) + (1 - X) * tf.log(1e-10 + 1 - x_reconstr_mean), 1)\n",
"\n",
"# 潜在损失\n",
"latent_loss = -0.5 * tf.reduce_sum(1 + z_log - tf.square(z_mean) - tf.exp(z_log), 1)\n",
"\n",
"cost = tf.reduce_mean(reconstr_loss + latent_loss)\n",
"\n",
"optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"定义一个生成方法。"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"def generate(session, z_mu=None):\n",
" \"\"\" Generate data by sampling from latent space.\n",
"\n",
" If z_mu is not None, data for this point in latent space is\n",
" generated. Otherwise, z_mu is drawn from prior in latent \n",
" space. \n",
" \"\"\"\n",
" if z_mu is None:\n",
" z_mu = np.random.normal(size=n_z)\n",
" # Note: This maps to mean of distribution, we could alternatively\n",
" # sample from Gaussian distribution\n",
" return session.run(x_reconstr_mean, feed_dict={z: z_mu})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"下面我们定义会话,开始执行图运算,并且尝试生成结果,进行对比。"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 0001 cost= 139.998687744\n",
"Epoch: 0006 cost= 107.300872803\n",
"Epoch: 0011 cost= 109.067909241\n",
"Epoch: 0016 cost= 105.136840820\n",
"Epoch: 0021 cost= 101.577850342\n",
"Epoch: 0026 cost= 97.175224304\n",
"Epoch: 0031 cost= 98.057365417\n",
"Epoch: 0036 cost= 96.567695618\n",
"Epoch: 0041 cost= 99.282241821\n",
"Epoch: 0046 cost= 97.937873840\n",
"Epoch: 0051 cost= 97.013824463\n",
"Epoch: 0056 cost= 98.554000854\n",
"Epoch: 0061 cost= 99.762924194\n",
"Epoch: 0066 cost= 95.410614014\n",
"Epoch: 0071 cost= 97.338882446\n",
"Epoch: 0076 cost= 93.218643188\n",
"Epoch: 0081 cost= 95.388572693\n",
"Epoch: 0086 cost= 96.031211853\n",
"Epoch: 0091 cost= 96.252563477\n",
"Epoch: 0096 cost= 92.667602539\n",
"Epoch: 0101 cost= 98.643463135\n",
"Optimization Finished!\n"
]
},
{
"data": {
"image/png": "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\nsjxRCaqTjgBuu+22Qvnee++ttCk/mavepKtvfetbhfIOO+xQadNLC9KkFCsa+SrOd4FfAq+StFzS\nkWQD5S2Sfg/slZfN2m6Qr+JM7ruUmP/MrHnrFKA2ui3P62q9EnilpJ9LulnSDKxpjhXWTQN8FWeg\nOAEdihWDnrlGRHWOd+bNg73XrB0GOBpdFRE7t7DrscB0YA9gKnCDpFdHxJ9a2Oeo5Vhh3dZPrGg1\nTkATsaLlCU1mndbkhKYVwLSa8tS8rtZyYH5ErI6IPwK/IxtAZtaDmpzQ1JFYMaqWPxw3blyh3Mji\n+s8++2yl7swzz2xbnwYzd+7cSt2+++5bKP+f//N/Km0+/vGPF8ozZ5avhPSGFqbXLwSmS9qKbKAc\nDBxaanMFcAjwLUmTyS79VG9e2agyfvz4QvkDH/hApc26665bKL/wwguVNhdeeGGhXG+BhjVr1jTT\nxcrnXXTRRZU2r3/96wvlI444otJmiy22KJT322+/Spvvf//7zXRx2KUWK0ZVcrXe1MyAiYg1ko4G\nrgLGAHMiYrGkU4FFETE/3/ZWSXcBLwCfjIhH29h1MxtGKcUKJ1dLWitfDI+IBcCCUt3JNa8D+ET+\nY2Y9LLVY4eRqyUtp1RUzS1dKscLJ1ZKX0oAxs3SlFCtGVXJ99atfXSi/853vHPQ99Z54c+2117at\nT4N58MEHK3UHHnhgobxw4cJKm7333rtQ3nHHHSttbr/99hZ713kRUXeyiFmnTJ48uVCuN3bGji2G\nziVLllTalJ961ezkpUasXr26Ujdr1qxC+U1velOlTXlCU72Jj1dccUWhnOp4TC1WjKrkar0ppaNR\nM0tXSrHCydWSltqTLswsTanFCidXS15KA8bM0pVSrBhVybW8KH4jli5d2v6OtKh8H/bpp5+utNlm\nm20K5VNOOaXSpnzvtt59m25L7WjURr6pU6cWyuuvv36lTfn+6WWXXVZp8/jjj7e3Y0P0yCOPFMq3\n3HJLpc1GG21UKJfvwUJ1UY168SYFqcWKUZVcrTelNGDMLF0pxQonV0teSgPGzNKVUqxwcrWkpXap\nx8zSlFqsaOR5rnMkPSzpzpq6UyStkHR7/rNPZ7tpo1mTT8WxYeZYYd2WUpxo5Mx1LvA14Dul+rMj\n4ott75ENWb0vsJcnNNV72sXEiRML5ccee6y9HWuD1I5GbUBzGQGxYssttyyUx4wZU2nzzDPPFMq/\n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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7efc721ebd68>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Initializing the variables\n",
"init = tf.global_variables_initializer()\n",
"\n",
"with tf.Session() as sess:\n",
" sess.run(init)\n",
" total_batch = int(mnist.train.num_examples / batch_size)\n",
" # Training cycle\n",
" for epoch in range(training_epochs):\n",
" avg_cost = 0\n",
" # Loop over all batches\n",
" for i in range(total_batch):\n",
" batch_xs, batch_ys = mnist.train.next_batch(batch_size)\n",
" # Run optimization op (backprop) and cost op (to get loss value)\n",
" _, c = sess.run([optimizer, cost], feed_dict={X: batch_xs})\n",
" avg_cost += c / mnist.train.num_examples * batch_size\n",
" # Display logs per epoch step\n",
" if epoch % display_step == 0:\n",
" print(\"Epoch:\", '%04d' % (epoch + 1),\n",
" \"cost=\", \"{:.9f}\".format(c))\n",
"\n",
" print(\"Optimization Finished!\")\n",
" \n",
" \n",
" # generator\n",
" x_sample = mnist.test.next_batch(100)[0]\n",
" x_reconstruct = sess.run(x_reconstr_mean, feed_dict={X: x_sample})\n",
"\n",
" plt.figure(figsize=(8, 12))\n",
" for i in range(5):\n",
" plt.subplot(5, 2, 2 * i + 1)\n",
" plt.imshow(x_sample[i].reshape(28, 28), vmin=0, vmax=1, cmap=\"gray\")\n",
" plt.title(\"Test input\")\n",
" plt.colorbar()\n",
" plt.subplot(5, 2, 2 * i + 2)\n",
" plt.imshow(x_reconstruct[i].reshape(28, 28), vmin=0, vmax=1, cmap=\"gray\")\n",
" plt.title(\"Reconstruction\")\n",
" plt.colorbar()\n",
" plt.tight_layout()"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"grt1st 2017-10-21 \n",
"\n",
"CPython 3.6.2\n",
"IPython 6.1.0\n",
"\n",
"numpy 1.13.1\n",
"scikit-learn 0.19.0\n",
"tensorflow 1.3.0\n",
"\n",
"compiler : GCC 7.1.1 20170630\n",
"system : Linux\n",
"release : 4.13.7-1-ARCH\n",
"machine : x86_64\n",
"processor : \n",
"CPU cores : 8\n",
"interpreter: 64bit\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/usr/lib/python3.6/site-packages/watermark/watermark.py:151: DeprecationWarning: Importing scikit-learn as `scikit-learn` has been depracated and will not be supported anymore in v1.7.0. Please use the package name `sklearn` instead.\n",
" DeprecationWarning)\n"
]
}
],
"source": [
"%load_ext watermark\n",
"%watermark -a \"grt1st\" -d -v -m -p numpy,scikit-learn,tensorflow"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
# Import MNIST data
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/home/grt1st/data/", one_hot=True)
# Parameters
learning_rate = 0.001
training_epochs = 101
batch_size = 100
display_step = 5
# Network Parameters
n_hidden_1 = 500
n_hidden_2 = 500
n_z = 20
n_input = 784 # MNIST data input (img shape: 28*28)
# func
transfer_func = tf.nn.relu#tf.nn.softplus
# tf Graph input (only pictures)
X = tf.placeholder(tf.float32, [None, n_input])
def xavier_init(fan_in, fan_out, constant=1):
""" Xavier initialization of network weights"""
# https://stackoverflow.com/questions/33640581/how-to-do-xavier-initialization-on-tensorflow
low = -constant*np.sqrt(6.0/(fan_in + fan_out))
high = constant*np.sqrt(6.0/(fan_in + fan_out))
return tf.random_uniform((fan_in, fan_out),
minval=low, maxval=high,
dtype=tf.float32)
weights = {
"recognition_h1": tf.Variable(xavier_init(n_input, n_hidden_1)),
"recognition_h2": tf.Variable(xavier_init(n_hidden_1, n_hidden_2)),
"recognition_out_mean": tf.Variable(xavier_init(n_hidden_2, n_z)),
"recognition_out_log": tf.Variable(xavier_init(n_hidden_2, n_z)),
"generator_h1": tf.Variable(xavier_init(n_z, n_hidden_1)),
"generator_h2": tf.Variable(xavier_init(n_hidden_1, n_hidden_2)),
"generator_out_mean": tf.Variable(xavier_init(n_hidden_2, n_input)),
"generator_out_log": tf.Variable(xavier_init(n_hidden_2, n_input)),
}
biases = {
"recognition_b1": tf.Variable(tf.zeros([n_hidden_1], dtype=tf.float32)),
"recognition_b2": tf.Variable(tf.zeros([n_hidden_2], dtype=tf.float32)),
"recognition_out_mean": tf.Variable(tf.zeros([n_z], dtype=tf.float32)),
"recognition_out_log": tf.Variable(tf.zeros([n_z], dtype=tf.float32)),
"generator_b1": tf.Variable(tf.zeros([n_hidden_1], dtype=tf.float32)),
"generator_b2": tf.Variable(tf.zeros([n_hidden_2], dtype=tf.float32)),
"generator_out_mean": tf.Variable(tf.zeros([n_input], dtype=tf.float32)),
"generator_out_log": tf.Variable(tf.zeros([n_input], dtype=tf.float32)),
}
def recognition_network(x):
layer_1 = transfer_func(tf.add(tf.matmul(x, weights["recognition_h1"]), biases["recognition_b1"]))
layer_2 = transfer_func(tf.add(tf.matmul(layer_1, weights["recognition_h2"]), biases["recognition_b2"]))
z_mean = tf.add(tf.matmul(layer_2, weights["recognition_out_mean"]), biases["recognition_out_mean"])
z_log = tf.add(tf.matmul(layer_2, weights["recognition_out_log"]), biases["recognition_out_log"])
return z_mean, z_log
def generator_network(x):
layer_1 = transfer_func(tf.add(tf.matmul(x, weights["generator_h1"]), biases["generator_b1"]))
layer_2 = transfer_func(tf.add(tf.matmul(layer_1, weights["generator_h2"]), biases["generator_b2"]))
x_reconstr_mean = tf.nn.sigmoid(tf.add(tf.matmul(layer_2, weights["generator_out_mean"]), biases["generator_out_mean"]))
return x_reconstr_mean
z_mean, z_log = recognition_network(X)
eps = tf.random_normal((batch_size, n_z), 0, 1, dtype=tf.float32)
# z = mu + sigma*epsilon
z = tf.add(z_mean, tf.multiply(tf.sqrt(tf.exp(z_log)), eps))
x_reconstr_mean = generator_network(z)
# 重建损失:负对数概率,伯努利分布下的输入
reconstr_loss = -tf.reduce_sum(X * tf.log(1e-10 + x_reconstr_mean) + (1 - X) * tf.log(1e-10 + 1 - x_reconstr_mean), 1)
# 潜在损失
latent_loss = -0.5 * tf.reduce_sum(1 + z_log - tf.square(z_mean) - tf.exp(z_log), 1)
cost = tf.reduce_mean(reconstr_loss + latent_loss)
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
'''
# Initializing the tensor flow variables
init = tf.global_variables_initializer()
# Launch the session
self.sess = tf.InteractiveSession()
self.sess.run(init)
'''
def generate(session, z_mu=None):
""" Generate data by sampling from latent space.
If z_mu is not None, data for this point in latent space is
generated. Otherwise, z_mu is drawn from prior in latent
space.
"""
if z_mu is None:
z_mu = np.random.normal(size=n_z)
# Note: This maps to mean of distribution, we could alternatively
# sample from Gaussian distribution
return session.run(x_reconstr_mean, feed_dict={z: z_mu})
# Initializing the variables
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
total_batch = int(mnist.train.num_examples / batch_size)
# Training cycle
for epoch in range(training_epochs):
avg_cost = 0
# Loop over all batches
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
# Run optimization op (backprop) and cost op (to get loss value)
_, c = sess.run([optimizer, cost], feed_dict={X: batch_xs})
avg_cost += c / mnist.train.num_examples * batch_size
# Display logs per epoch step
if epoch % display_step == 0:
print("Epoch:", '%04d' % (epoch + 1),
"cost=", "{:.9f}".format(c))
print("Optimization Finished!")
x_sample = mnist.test.next_batch(100)[0]
x_reconstruct = sess.run(x_reconstr_mean, feed_dict={X: x_sample})
plt.figure(figsize=(8, 12))
for i in range(5):
plt.subplot(5, 2, 2 * i + 1)
plt.imshow(x_sample[i].reshape(28, 28), vmin=0, vmax=1, cmap="gray")
plt.title("Test input")
plt.colorbar()
plt.subplot(5, 2, 2 * i + 2)
plt.imshow(x_reconstruct[i].reshape(28, 28), vmin=0, vmax=1, cmap="gray")
plt.title("Reconstruction")
plt.colorbar()
#plt.tight_layout()
plt.show()
plt.draw()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment