|
| 1 | +import pandas as pd |
| 2 | +import tensorflow as tf |
| 3 | +import numpy as np |
| 4 | +import datetime |
| 5 | +import os |
| 6 | +import matplotlib.pyplot as plt |
| 7 | +from data_preprocessing import preprocess |
| 8 | +from sklearn.utils import shuffle |
| 9 | + |
| 10 | + |
| 11 | +# Parameters |
| 12 | +input_dim = 28 |
| 13 | +hidden_size1 = 100 |
| 14 | +hidden_size2 = 100 |
| 15 | +z_dim = 20 |
| 16 | + |
| 17 | +batch_size = 100 |
| 18 | +n_epochs = 1000 |
| 19 | +learning_rate = 0.001 |
| 20 | +beta1 = 0.9 |
| 21 | +results_path = './autoencoders/Results/Standard_AE' |
| 22 | +saved_model_path = results_path + '/Saved_models/' |
| 23 | + |
| 24 | +# Placeholders for input data and the targets |
| 25 | +x_input = tf.placeholder(dtype=tf.float32, shape=[batch_size, input_dim], name='Input') |
| 26 | +x_target = tf.placeholder(dtype=tf.float32, shape=[batch_size, input_dim], name='Target') |
| 27 | +decoder_input = tf.placeholder(dtype=tf.float32, shape=[1, z_dim], name='Decoder_input') |
| 28 | + |
| 29 | + |
| 30 | +def dense(x, n1, n2, name): |
| 31 | + """ |
| 32 | + Used to create a dense layer. |
| 33 | + :param x: input tensor to the dense layer |
| 34 | + :param n1: no. of input neurons |
| 35 | + :param n2: no. of output neurons |
| 36 | + :param name: name of the entire dense layer.i.e, variable scope name. |
| 37 | + :return: tensor with shape [batch_size, n2] |
| 38 | + """ |
| 39 | + with tf.variable_scope(name, reuse=None): |
| 40 | + weights = tf.get_variable("weights", shape=[n1, n2], |
| 41 | + initializer=tf.random_normal_initializer(mean=0., stddev=0.01)) |
| 42 | + bias = tf.get_variable("bias", shape=[n2], initializer=tf.constant_initializer(0.0)) |
| 43 | + out = tf.add(tf.matmul(x, weights), bias, name='matmul') |
| 44 | + return out |
| 45 | + |
| 46 | + |
| 47 | +# The Encoder of the network |
| 48 | +def encoder(x, reuse=False): |
| 49 | + """ |
| 50 | + Encode part of the autoencoder |
| 51 | + :param x: input to the autoencoder |
| 52 | + :param reuse: True -> Reuse the encoder variables, False -> Create or search of variables before creating |
| 53 | + :return: tensor which is the hidden latent variable of the autoencoder. |
| 54 | + """ |
| 55 | + if reuse: |
| 56 | + tf.get_variable_scope().reuse_variables() |
| 57 | + with tf.name_scope('Encoder'): |
| 58 | + e_dense_1 = tf.nn.relu(dense(x, input_dim, hidden_size1, 'e_dense_1')) |
| 59 | + e_dense_2 = tf.nn.relu(dense(e_dense_1, hidden_size1, hidden_size2, 'e_dense_2')) |
| 60 | + latent_variable = dense(e_dense_2, hidden_size2, z_dim, 'e_latent_variable') |
| 61 | + return latent_variable |
| 62 | + |
| 63 | + |
| 64 | +# The Decoder of the network |
| 65 | +def decoder(x, reuse=False): |
| 66 | + """ |
| 67 | + Decoder part of the autoencoder |
| 68 | + :param x: input to the decoder |
| 69 | + :param reuse: True -> Reuse the decoder variables, False -> Create or search of variables before creating |
| 70 | + :return: tensor which should ideally be the input given to the encoder. |
| 71 | + """ |
| 72 | + if reuse: |
| 73 | + tf.get_variable_scope().reuse_variables() |
| 74 | + with tf.name_scope('Decoder'): |
| 75 | + d_dense_1 = tf.nn.relu(dense(x, z_dim, hidden_size2, 'd_dense_1')) |
| 76 | + d_dense_2 = tf.nn.relu(dense(d_dense_1, hidden_size2, hidden_size1, 'd_dense_2')) |
| 77 | + output = tf.nn.sigmoid(dense(d_dense_2, hidden_size1, input_dim, 'd_output')) |
| 78 | + return output |
| 79 | + |
| 80 | + |
| 81 | +def train(train_model=True, train_data=None, test_data=None): |
| 82 | + """ |
| 83 | + Used to train the autoencoder by passing in the necessary inputs. |
| 84 | + :param train_model: True -> Train the model, False -> Load the latest trained model and show the reconstructed variables. |
| 85 | + """ |
| 86 | + with tf.variable_scope(tf.get_variable_scope()): |
| 87 | + encoder_output = encoder(x_input) |
| 88 | + decoder_output = decoder(encoder_output) |
| 89 | + |
| 90 | + with tf.variable_scope(tf.get_variable_scope()): |
| 91 | + reconstructed_variables = decoder(decoder_input, reuse=True) |
| 92 | + |
| 93 | + # Loss |
| 94 | + loss = tf.reduce_mean(tf.square(x_target - decoder_output)) |
| 95 | + |
| 96 | + # Optimizer |
| 97 | + optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate, beta1=beta1).minimize(loss) |
| 98 | + init = tf.global_variables_initializer() |
| 99 | + |
| 100 | + # Saving the model |
| 101 | + saver = tf.train.Saver() |
| 102 | + step = 0 |
| 103 | + with tf.Session() as sess: |
| 104 | + sess.run(init) |
| 105 | + if train_model: |
| 106 | + |
| 107 | + for i in range(n_epochs): |
| 108 | + train_data = shuffle(train_data) |
| 109 | + # break the train data df into chunks of size batch_size |
| 110 | + train_df = [train_data[x:x + batch_size] for x in range(0, train_data.shape[0], batch_size)] |
| 111 | + count = 0 |
| 112 | + for batch in train_df: |
| 113 | + if batch.shape[0] == batch_size: |
| 114 | + count += 1 |
| 115 | + sess.run(optimizer, feed_dict={x_input: batch, x_target: batch}) |
| 116 | + |
| 117 | + if count % 50 == 0: |
| 118 | + batch_loss = sess.run([loss], feed_dict={x_input: batch, x_target: batch}) |
| 119 | + print("Loss: {}".format(batch_loss)) |
| 120 | + print("Epoch: {}, iteration: {}".format(i, count)) |
| 121 | + step += 1 |
| 122 | + saver.save(sess, save_path=saved_model_path, global_step=step) |
| 123 | + print("Model Trained!") |
| 124 | + |
| 125 | + print("Saved Model Path: {}".format(saved_model_path)) |
| 126 | + else: |
| 127 | + all_results = os.listdir(results_path) |
| 128 | + all_results.sort() |
| 129 | + saver.restore(sess, |
| 130 | + save_path=tf.train.latest_checkpoint(results_path + '/' + all_results[-1] + '/Saved_models/')) |
0 commit comments