In [20]:
import tensorflow as tf
import numpy as np
class Autoencoder:
def __init__(self, input_dim, hidden_dim, epoch=250, learning_rate=0.001):
self.epoch = epoch # Numero de ciclos para aprender
self.learning_rate = learning_rate #Hiper parametro para el optimizador (RMSProppOptimizer en este caso)
# Capa de entrada (Input X que es el Dataset). shape=[None,input_dim] significa que en vez de None puede haber cualquier numero ahi (para poder hacer batch)
x = tf.placeholder(dtype=tf.float32, shape=[None, input_dim])
# Definir variables y operador del encoder (Del Input a la Hidden Layer)
with tf.name_scope('encode'):
weights = tf.Variable(tf.random_normal([input_dim, hidden_dim], dtype=tf.float32), name='weights')
biases = tf.Variable(tf.zeros([hidden_dim]), name='biases')
encoded = tf.nn.tanh(tf.matmul(x,weights) + biases)
# Definir variables y operador del decoder (De la Hidden Layer al Output)
with tf.name_scope('decode'):
weights = tf.Variable(tf.random_normal([hidden_dim, input_dim], dtype=tf.float32), name='weights')
biases = tf.Variable(tf.zeros([hidden_dim]), name='biases')
decoded = tf.nn.tanh(tf.matmul(encoded,weights) + biases)
# Asignar a variables de la clase para que otro metodos de ella las puedan usar
self.x = x
self.encoded = encoded
self.decoded = decoded
# Funcion de costo (diferencia entre el output del autoencoder y el output esperado
# que en este caso es el propio input)
self.loss = tf.sqrt(tf.reduce_mean(tf.square(tf.subtract(self.x,self.decoded))))
# Definir el optimizador a utilizar y salvar los parametros que se iran aprendiendo en cada epoch
self.train_op = tf.train.RMSPropOptimizer(self.learning_rate).minimize(self.loss)
self.saver = tf.train.Saver()
def train(self, data):
num_samples = len(data)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(self.epoch):
for j in range(num_samples): # Entrenat la red sample por sample durante i epoch's
l, _ = sess.run([self.loss, self.train_op], feed_dict={self.x: [data[j]]})
if i%10==0: # Solo imprimir como va la red cada 10 iteraciones (Vigilar como desciende el error!)
print("Epoch {}: loss = {}".format(i,l))
self.saver.save(sess, './checkpoints/autoencoder_model.ckpt')
def test(self, data): #Data es un solo ejemplo (nunca antes visto) que entrara a la red y esta dara el resultado (que debe de ser el propio input si se entreno correctamente)
with tf.Session() as sess:
self.saver.restore(sess, './checkpoints/autoencoder_model.ckpt')
hidden,reconstructed = sess.run([self.encoded, self.decoded], feed_dict={self.x: data})
print('input', data)
print('compressed',hidden)
print('reconstructed',reconstructed)
return reconstructed
In [21]:
from sklearn import datasets
hidden_dim = 1
data = datasets.load_iris().data
input_dim = len(data[0])
ae = Autoencoder(input_dim, hidden_dim,epoch=500)
ae.train(data)
ae.test([[ 5.0 ,3.9, 2.4, 1.2]])
Out[21]: