变分自编码(VAE)及代码解读

来源:互联网 发布:非凡软件下载 编辑:程序博客网 时间:2024/06/05 20:03
这几天在看GAN模型的时候,顺便关注了另外一种生成模型——VAE。其实这种生成模型在早几年就有了,而且有了一些应用。著名黑客George Hotz在其开源的自主驾驶项目中就应用到了VAE模型。这其中的具体应用在我上一篇转载的博客comma.ai中有详细介绍。在对VAE基本原理有一个认识后,就开始啃代码了。在代码中最能直观的体现其思想,结合理论来看,有利于理解。理论介绍,网上资料很多,就不赘述了。

          基本网络框架:

                 

          

下面是基于keras的VAE代码解读:(自己加了一层,发现收敛的快一点了,附实验结果)

[html] view plain copy
  1. <span style="font-size:14px;">from __future__ import division  
  2. from __future__ import print_function  
  3. import os.path  
  4.   
  5. import numpy as np  
  6. np.random.seed(1337)  # for reproducibility  
  7.   
  8. import tensorflow as tf  
  9. from tensorflow.examples.tutorials.mnist import input_data  
  10.   
  11. mnist = input_data.read_data_sets('MNIST')  
  12.   
  13. input_dim = 784  
  14. hidden_encoder_dim_1 = 1000  
  15. hidden_encoder_dim_2 = 400  
  16. hidden_decoder_dim = 400  
  17. latent_dim = 20#(latent Variable)  
  18. lam = 0  
  19.   
  20.   
  21. def weight_variable(shape):  
  22.   initial = tf.truncated_normal(shape, stddev=0.001)  
  23.   return tf.Variable(initial)  
  24.   
  25. def bias_variable(shape):  
  26.   initial = tf.constant(0., shape=shape)  
  27.   return tf.Variable(initial)  
  28.   
  29. x = tf.placeholder("float", shape=[None, input_dim])##input x  
  30. l2_loss = tf.constant(0.0)  
  31.   
  32. #encoder1 W b  
  33. W_encoder_input_hidden_1 = weight_variable([input_dim,hidden_encoder_dim_1])##784*1000  
  34. b_encoder_input_hidden_1 = bias_variable([hidden_encoder_dim_1])#1000  
  35. l2_loss += tf.nn.l2_loss(W_encoder_input_hidden_1)  
  36.   
  37. # Hidden layer1 encoder  
  38. hidden_encoder_1 = tf.nn.relu(tf.matmul(x, W_encoder_input_hidden_1) + b_encoder_input_hidden_1)##w*x+b  
  39.   
  40. #encoder2 W b  
  41. W_encoder_input_hidden_2 = weight_variable([hidden_encoder_dim_1,hidden_encoder_dim_2])##1000*400  
  42. b_encoder_input_hidden_2 = bias_variable([hidden_encoder_dim_2])#400  
  43. l2_loss += tf.nn.l2_loss(W_encoder_input_hidden_2)  
  44.   
  45. # Hidden layer2 encoder  
  46. hidden_encoder_2 = tf.nn.relu(tf.matmul(hidden_encoder_1, W_encoder_input_hidden_2) + b_encoder_input_hidden_2)##w*x+b  
  47.   
  48. W_encoder_hidden_mu = weight_variable([hidden_encoder_dim_2,latent_dim])##400*20  
  49. b_encoder_hidden_mu = bias_variable([latent_dim])##20  
  50. l2_loss += tf.nn.l2_loss(W_encoder_hidden_mu)  
  51.   
  52. # Mu encoder=+  
  53. mu_encoder = tf.matmul(hidden_encoder_2, W_encoder_hidden_mu) + b_encoder_hidden_mu##mu_encoder:1*20(1*400 400*20)  
  54.   
  55. W_encoder_hidden_logvar = weight_variable([hidden_encoder_dim_2,latent_dim])##W_encoder_hidden_logvar:400*20  
  56. b_encoder_hidden_logvar = bias_variable([latent_dim])#20  
  57. l2_loss += tf.nn.l2_loss(W_encoder_hidden_logvar)  
  58.   
  59. # Sigma encoder  
  60. logvar_encoder = tf.matmul(hidden_encoder_2, W_encoder_hidden_logvar) + b_encoder_hidden_logvar#logvar_encoder:1*20(1*400 400*20)  
  61.   
  62. # Sample epsilon  
  63. epsilon = tf.random_normal(tf.shape(logvar_encoder), name='epsilon')  
  64.   
  65. # Sample latent variable  
  66. std_encoder = tf.exp(0.5 * logvar_encoder)  
  67. z = mu_encoder + tf.mul(std_encoder, epsilon)##z_mu+epsilon*z_std=z,as decoder's input;z:1*20  
  68.   
  69. W_decoder_z_hidden = weight_variable([latent_dim,hidden_decoder_dim])#W_decoder_z_hidden:20*400    
  70. b_decoder_z_hidden = bias_variable([hidden_decoder_dim])##400  
  71. l2_loss += tf.nn.l2_loss(W_decoder_z_hidden)  
  72.   
  73. # Hidden layer decoder  
  74. hidden_decoder = tf.nn.relu(tf.matmul(z, W_decoder_z_hidden) + b_decoder_z_hidden)##hidden_decoder:1*400(1*20 20*400)  
  75.   
  76. W_decoder_hidden_reconstruction = weight_variable([hidden_decoder_dim, input_dim])##400*784  
  77. b_decoder_hidden_reconstruction = bias_variable([input_dim])  
  78. l2_loss += tf.nn.l2_loss(W_decoder_hidden_reconstruction)  
  79.    
  80. KLD = -0.5 * tf.reduce_sum(1 + logvar_encoder - tf.pow(mu_encoder, 2) - tf.exp(logvar_encoder), reduction_indices=1)##KLD  
  81.   
  82. x_hat = tf.matmul(hidden_decoder, W_decoder_hidden_reconstruction) + b_decoder_hidden_reconstruction##x_hat:1*784(reconstruction x)  
  83.    
  84. BCE = tf.reduce_sum(tf.nn.sigmoid_cross_entropy_with_logits(x_hat, x), reduction_indices=1)##sum cross_entropy  
  85.   
  86. loss = tf.reduce_mean(BCE + KLD)##average value  
  87.   
  88. regularized_loss = loss + lam * l2_loss  
  89.   
  90. loss_summ = tf.scalar_summary("lowerbound", loss)##Record the stored value of loss  
  91. train_step = tf.train.AdamOptimizer(0.01).minimize(regularized_loss)##Optimization Strategy  
  92.   
  93. # add op for merging summary  
  94. summary_op = tf.merge_all_summaries()  
  95.   
  96. # add Saver ops  
  97. saver = tf.train.Saver()  
  98.   
  99. n_steps = int(1e5+1)##step:1000000  
  100. batch_size = 100  
  101.   
  102. with tf.Session() as sess:  
  103.   summary_writer = tf.train.SummaryWriter('experiment',  
  104.                                           graph=sess.graph)##draw graph in tensorboard  
  105.   #if os.path.isfile("save/model.ckpt"):  
  106.    # print("Restoring saved parameters")  
  107.     #saver.restore(sess, "save/model.ckpt")  
  108.   #else:  
  109.    # print("Initializing parameters")  
  110.   sess.run(tf.initialize_all_variables())  
  111.   
  112.   for step in range(1, n_steps):  
  113.     batch = mnist.train.next_batch(batch_size)  
  114.     feed_dict = {x: batch[0]}  
  115.     _, cur_loss, summary_str = sess.run([train_step, loss, summary_op], feed_dict=feed_dict)  
  116.     summary_writer.add_summary(summary_str, step)  
  117.   
  118.     if step % 50 == 0:  
  119.       save_path = saver.save(sess, "save/model.ckpt")  
  120.       print("Step {0} | Loss: {1}".format(step, cur_loss))  
  121.   
  122. # save weights every epoch  
  123.     #if step % 100==0 :   
  124.       # generator.save_weights(  
  125.       #          'mlp_generator_epoch_{0:03d}.hdf5'.format(epoch), True)  
  126.        #critic.save_weights(  
  127.         #        'mlp_critic_epoch_{0:03d}.hdf5'.format(epoch), True)  
  128.   
  129. ##Step 999900 | Loss: 114.41309356689453  
  130. ##Step 999950 | Loss: 115.09370422363281  
  131. ##Step 100000 | Loss: 124.32205200195312 ##Step 99700 | Loss: 116.05304718017578  
  132.   
  133. #1000 encode hidden layer=1 Step 950 | Loss: 159.3329620361328  
  134. #1000 encode hidden layer=2 Step 950 | Loss: 128.81312561035156  
  135. </span>  



变分自编码器参考资料:

1.变分自编码器(Variational Autoencoder, VAE)通俗教程 – 邓范鑫——致力于变革未来的智能技术 http://www.dengfanxin.cn/?p=334

2.VAE variation inference变分推理 清爽介绍 http://mp.weixin.qq.com/s/9lNWkEEOk5vEkJ1f840zxA

3.深度学习变分贝叶斯自编码器(上下) https://zhuanlan.zhihu.com/p/25429082