#!/usr/bin/env python # coding: utf-8 # # TensorFlow # # ## Sobre TensoFlow # # [TensorFlow](https://www.tensorflow.org/) es una biblioteca open source desarrollada por Google que nos permite realizar cálculos numéricos usando diagramas de flujo de datos. Los nodos del gráfico representan operaciones matemáticas, mientras que los bordes del gráfico representan los arreglos de datos multidimensionales (tensores) comunicados entre ellos. Esta arquitectura flexible le permite realizar los cálculos en más de un CPU o GPU utilizando la misma API. # # ## ¿Qué es un diagrama de flujo de datos? # # Los diagramas de flujo de datos describen cálculos matemáticos con un gráfico de direcciones de nodos y bordes. Los nodos normalmente implementan operaciones matemáticas, pero también pueden representar los puntos para alimentarse de datos, devolver resultados, o leer / escribir variables persistentes. Los bordes describen las relaciones de entrada / salida entre los nodos. Estos bordes están representados por los arreglos de datos multidimensionales o tensores. El flujo de los tensores a través del gráfico es de donde [TensorFlow](https://www.tensorflow.org/) recibe su nombre. Los nodos se asignan a los dispositivos computacionales y se ejecutan de forma asincronica y en paralelo una vez que todos los tensores en los bordes de entrada están disponibles. # # # ## Operaciones básicas con TensorFlow # In[3]: # importamos librerias import tensorflow as tf import numpy as np import matplotlib.pyplot as plt import matplotlib.cm as cm import seaborn as sns get_ipython().run_line_magic('matplotlib', 'inline') # ### Constantes en TensorFlow # In[3]: # Creación de Constantes # El valor que retorna el constructor es el valor de la constante. # creamos constantes a=2 y b=3 a = tf.constant(2) b = tf.constant(3) # In[4]: # Todo en TensorFlow ocurre dentro de una Sesión # creamos la sesion y realizamos algunas operaciones con las constantes # y lanzamos la sesión with tf.Session() as sess: print("Suma de las constantes: {}".format(sess.run(a+b))) print("Multiplicación de las constantes: {}".format(sess.run(a*b))) print("Constante elevada al cubo: {}".format(sess.run(a**3))) # ### Variables simbólicas en TensorFlow # In[5]: # Utilizando variables simbólicas en los grafos # El valor que devuelve el constructor representa el la salida de la # variable (la entrada de la variable se define en la sesion) # Creamos dos variables de tipo integer a = tf.placeholder(tf.int16) b = tf.placeholder(tf.int16) # In[6]: # Defininimos algunas operaciones con estas variables suma = tf.add(a, b) mult = tf.mul(a, b) # In[7]: # Iniciamos la sesion with tf.Session() as sess: # ejecutamos las operaciones con cualquier imput que quisiésemos print("suma con variables: {}".format(sess.run(suma, feed_dict={a: 4, b: 5}))) print("Multiplicación con variables: {}".format(sess.run(mult, feed_dict={a: 4, b: 5}))) # ### Operaciones con matrices # In[8]: # Creamos las matrices como constantes # matrices de 3x3 matriz1 = tf.constant([[1, 3, 2], [1, 0, 0], [1, 2, 2]]) matriz2 = tf.constant([[1, 0, 5], [7, 5, 0], [2, 1, 1]]) # suma de matrices suma = tf.add(matriz1, matriz2) # producto de matrices mult = tf.matmul(matriz1, matriz2) # In[9]: # lanzamos la sesion with tf.Session() as sess: print("Suma de matrices: \n{}".format(sess.run(suma))) print("Producto de matrices: \n{}".format(sess.run(mult))) # ## Ejemplos de TensorFlow con MNIST dataset # # # ## MNIST dataset # # [MNIST](http://colah.github.io/posts/2014-10-Visualizing-MNIST/) es un simple conjunto de datos para reconocimiento de imágenes por computadora. Se compone de imágenes de dígitos escritos a mano como los siguientes: # # # # Para más información sobre el dataset visitar el siguiente [enlace](http://colah.github.io/posts/2014-10-Visualizing-MNIST/) # In[4]: # importando el dataset from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) # ## Explorando MNIST dataset # In[11]: # forma del dataset 55000 imagenes mnist.train.images.shape # In[88]: # cada imagen es un array de 28x28 con cada pixel # definido como escala de grises. digito1 = mnist.train.images[0].reshape((28, 28)) # In[42]: # visualizando el primer digito plt.imshow(digito1, cmap = cm.Greys) plt.show() # In[18]: # valor correcto mnist.train.labels[0].nonzero()[0][0] # In[12]: # 2da imagen como escala de grises sns.heatmap(mnist.train.images[1].reshape((28, 28)), linewidth=0, xticklabels=False, yticklabels=False) plt.show() # In[19]: # valor correcto mnist.train.labels[1].nonzero()[0][0] # In[82]: # visualizando imagenes de 5 en 5 def visualizar_imagenes(dataset, cant_img): img_linea = 5 lineas = int(cant_img / img_linea) imagenes = [] for i in range(lineas): datos = [] for img in dataset[img_linea* i:img_linea* (i+1)]: datos.append(img.reshape((28,28))) imgs = np.hstack(datos) imagenes.append(imgs) data = np.vstack(imagenes) plt.imshow(data, cmap = cm.Greys ) plt.show() # In[89]: # visualizando los primeros 30 dígitos plt.figure(figsize=(8, 8)) visualizar_imagenes(mnist.train.images, 30) # ## Ejemplo con perceptron multicapa # # Un [peceptron multicapa](https://es.wikipedia.org/wiki/Perceptr%C3%B3n) es una de las redes neuronales más simples. # In[12]: # Parametros learning_rate = 0.001 training_epochs = 15 batch_size = 100 display_step = 1 model_path = "/home/raul/python/notebooks/perceptron.ckpt" logs_path = "/home/raul/python/notebooks/tensorflow_logs/perceptron" # Parametros de la red n_hidden_1 = 256 # 1ra capa de atributos n_hidden_2 = 256 # 1ra capa de atributos n_input = 784 # datos de MNIST(forma img: 28*28) n_classes = 10 # Total de clases a clasificar (0-9 digitos) # input para los grafos x = tf.placeholder("float", [None, n_input], name='DatosEntrada') y = tf.placeholder("float", [None, n_classes], name='Clases') # In[13]: # Creamos el modelo def multilayer_perceptron(x, weights, biases): # Función de activación de la capa escondida layer_1 = tf.add(tf.matmul(x, weights['h1']), biases['b1']) layer_1 = tf.nn.relu(layer_1) # Función de activación de la capa escondida layer_2 = tf.add(tf.matmul(layer_1, weights['h2']), biases['b2']) layer_2 = tf.nn.relu(layer_2) # Salida con activación lineal out_layer = tf.matmul(layer_2, weights['out']) + biases['out'] return out_layer # In[14]: # Definimos los pesos y sesgo de cada capa. weights = { 'h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])), 'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])), 'out': tf.Variable(tf.random_normal([n_hidden_2, n_classes])) } biases = { 'b1': tf.Variable(tf.random_normal([n_hidden_1])), 'b2': tf.Variable(tf.random_normal([n_hidden_2])), 'out': tf.Variable(tf.random_normal([n_classes])) } with tf.name_scope('Modelo'): # Construimos el modelo pred = multilayer_perceptron(x, weights, biases) with tf.name_scope('Costo'): # Definimos las funciones de optimización cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y)) with tf.name_scope('optimizador'): # optimización optimizer = tf.train.AdamOptimizer( learning_rate=learning_rate).minimize(cost) with tf.name_scope('Precision'): # Evaluar el modelo correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1)) # Calcular la precisión accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) # Inicializamos todas las variables init = tf.initialize_all_variables() # Crear sumarización para controlar el costo tf.scalar_summary("Costo", cost) # Crear sumarización para controlar la precisión tf.scalar_summary("Precision", accuracy) # Juntar los resumenes en una sola operación merged_summary_op = tf.merge_all_summaries() # Para guardar el modelo saver = tf.train.Saver() # In[15]: # Lanzamos la sesión with tf.Session() as sess: sess.run(init) # op to write logs to Tensorboard summary_writer = tf.train.SummaryWriter( logs_path, graph=tf.get_default_graph()) # Entrenamiento for epoch in range(training_epochs): avg_cost = 0. total_batch = int(mnist.train.num_examples/batch_size) for i in range(total_batch): batch_x, batch_y = mnist.train.next_batch(batch_size) # Optimización por backprop y funcion de costo _, c, summary = sess.run([optimizer, cost, merged_summary_op], feed_dict={x: batch_x, y: batch_y}) # escribir logs en cada iteracion summary_writer.add_summary(summary, epoch * total_batch + i) # perdida promedio avg_cost += c / total_batch # imprimir información de entrenamiento if epoch % display_step == 0: print("Iteración: {0: 04d} costo = {1:.9f}".format(epoch+1, avg_cost)) print("Optimización Terminada!\n") print("Precisión: {0:.2f}".format(accuracy.eval({x: mnist.test.images, y: mnist.test.labels}))) # guardar el modelo, luego lo podemos cargar con saver.restore save_path = saver.save(sess, model_path) print("Modelo guardado en archivo: {}".format(save_path)) print("Ejecutar el comando:\n", "--> tensorboard --logdir=/home/raul/python/notebooks/tensorflow_logs ", "\nLuego abir http://0.0.0.0:6006/ en el navegador") # ## [Red neuronal convolucional de multiples capas](https://es.wikipedia.org/wiki/Redes_neuronales_convolucionales) # In[16]: # Parametros learning_rate = 0.001 training_iters = 200000 batch_size = 128 display_step = 10 model_path = "/home/raul/python/notebooks/red_conv.ckpt" logs_path = "/home/raul/python/notebooks/tensorflow_logs/red_conv" # Parametros de la red n_input = 784 # datos de MNIST (forma img: 28*28) n_classes = 10 # Total de clases a clasificar (0-9 digitos) dropout = 0.75 # descarte, probabilidad para mantener las unidades # input para los grafos x = tf.placeholder(tf.float32, [None, n_input]) y = tf.placeholder(tf.float32, [None, n_classes]) keep_prob = tf.placeholder(tf.float32) # para descarte # In[17]: # Creando funciones auxiliares y el modelo def conv2d(x, W, b, strides=1): # Conv2D con sesgo y activación relu. x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME') x = tf.nn.bias_add(x, b) return tf.nn.relu(x) def maxpool2d(x, k=2): # MaxPool2D return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1], padding='SAME') # Creando la rede def conv_net(x, weights, biases, dropout): # cambiando la forma de la imagen x = tf.reshape(x, shape=[-1, 28, 28, 1]) # capa de convulción 1 conv1 = conv2d(x, weights['wc1'], biases['bc1']) # Max Pooling conv1 = maxpool2d(conv1, k=2) # capa de convulción 2 conv2 = conv2d(conv1, weights['wc2'], biases['bc2']) # Max Pooling conv2 = maxpool2d(conv2, k=2) # capa de conexiones fc1 = tf.reshape(conv2, [-1, weights['wd1'].get_shape().as_list()[0]]) fc1 = tf.add(tf.matmul(fc1, weights['wd1']), biases['bd1']) fc1 = tf.nn.relu(fc1) # aplicando el descarte fc1 = tf.nn.dropout(fc1, dropout) # Salida, predicción de la clase. out = tf.add(tf.matmul(fc1, weights['out']), biases['out']) return out # In[18]: # Definimos los pesos y sesgo de cada capa. weights = { # 5x5 conv, 1 entrada, 32 salidas 'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32])), # 5x5 conv, 32 entradas, 64 salidas 'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64])), # totalmente conectada, 7*7*64 entradas, 1024 salidas 'wd1': tf.Variable(tf.random_normal([7*7*64, 1024])), # 1024 entradas, 10 salidas (prediccion) 'out': tf.Variable(tf.random_normal([1024, n_classes])) } biases = { 'bc1': tf.Variable(tf.random_normal([32])), 'bc2': tf.Variable(tf.random_normal([64])), 'bd1': tf.Variable(tf.random_normal([1024])), 'out': tf.Variable(tf.random_normal([n_classes])) } # Construcción del modelo pred = conv_net(x, weights, biases, keep_prob) # definiendo las funciones de optimización cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y)) optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost) # Evaluando el modelo correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1)) accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32)) # Inicializando las variables init = tf.initialize_all_variables() # Para guardar el modelo saver = tf.train.Saver() # In[19]: # Lanzando la sesion with tf.Session() as sess: sess.run(init) step = 1 # mantener entrenando hasta alcanzar el maximo de iteraciones while step * batch_size < training_iters: batch_x, batch_y = mnist.train.next_batch(batch_size) # Run optimization op (backprop) sess.run(optimizer, feed_dict={x: batch_x, y: batch_y, keep_prob: dropout}) if step % display_step == 0: # Calcular la perdida y la precisión del lote loss, acc = sess.run([cost, accuracy], feed_dict={x: batch_x, y: batch_y, keep_prob: 1.}) print("Iteración {0:}, perdida = {1:.6f}, Precisión = {2:.5f}" .format(str(step*batch_size), loss, acc)) step += 1 print("Optimización terminada!") # Calcular la precisión sobre el dateset de evaluación. print("Testing Accuracy: {0: .2f}".format( sess.run(accuracy, feed_dict={x: mnist.test.images[:256], y: mnist.test.labels[:256], keep_prob: 1.}))) # guardar el modelo, luego lo podemos cargar con saver.restore save_path = saver.save(sess, model_path) print("Modelo guardado en archivo: {}".format(save_path)) # ## Ejemplo con Regresión Softmax # La [regresión softmax](https://es.wikipedia.org/wiki/Regresi%C3%B3n_log%C3%ADstica_multinomial) es una generalización del clásico modelo de [regresión logística](https://es.wikipedia.org/wiki/Regresi%C3%B3n_log%C3%ADstica) para los casos en que tenemos que clasificar más de dos *clases*. Con [TensorFlow](https://www.tensorflow.org/) se puede implementar de forma muy sencilla. # In[20]: # definimos la variable simbólica para para realizar los computos x = tf.placeholder(tf.float32, [None, 784]) # In[21]: # definimos dos variables para los parámetros y los iniciamos con ceros W = tf.Variable(tf.zeros([784, 10])) b = tf.Variable(tf.zeros([10])) # In[22]: # definimos el modelo de regresion multinominal. y = tf.nn.softmax(tf.matmul(x, W) + b) # ### Entrenamiento # In[23]: # definimos una variable simbólica para los resultados. y_ = tf.placeholder(tf.float32, [None, 10]) # aplicamos entropia cruzada cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1])) # definimos el proceso de entrenamiento aplicando el algoritmo de # gradiente descendiente optimizando al mínimo la entropia cruzada train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy) # iniciamos todas las variables init = tf.initialize_all_variables() # In[24]: # lanzamos la sesion with tf.Session() as sess: sess.run(init) # entrenamos el modelo for i in range(1000): batch_xs, batch_ys = mnist.train.next_batch(100) sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys}) # evaluamos el modelo correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) # imprimimos precision print("Precisión: {0: .2f}".format(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels})))