Introducción a TensorFlow – Part 2

Este artículo es una breve introducción a la biblioteca TensorFlow usando el lenguaje de programación Python.

Introducción

TensorFlow es una biblioteca de software de código abierto. TensorFlow fue desarrollado originalmente por investigadores e ingenieros que trabajaban en Google Brain Team dentro de la organización de investigación de inteligencia artificial de Google con el fin de realizar investigaciones de aprendizaje automático y redes neuronales profundas, pero el sistema es lo suficientemente general como para ser aplicable en una amplia variedad de otros dominios como ¡bien!

¡Intentemos primero entender qué significa realmente la palabra TensorFlow !

TensorFlow es básicamente una biblioteca de software para el cálculo numérico que utiliza gráficos de flujo de datos donde:

  • los Nodes en el gráfico representan operaciones matemáticas.
  • Los bordes en el gráfico representan los arreglos de datos multidimensionales (llamados tensores ) comunicados entre ellos. (Tenga en cuenta que el tensor es la unidad central de datos en TensorFlow).

Considere el diagrama que se presenta a continuación:

Aquí, add es un Node que representa la operación de suma. a y b son tensores de entrada y c es el tensor resultante.

¡Esta arquitectura flexible le permite implementar computación en una o más CPU o GPU en una computadora de escritorio, servidor o dispositivo móvil con una sola API!

API de TensorFlow

TensorFlow proporciona varias API (interfaces de programación de aplicaciones). Estos se pueden clasificar en 2 grandes categorías:

  1. API de bajo nivel:
    • completo control de programación
    • recomendado para investigadores de aprendizaje automático
    • proporciona buenos niveles de control sobre los modelos
    • TensorFlow Core es la API de bajo nivel de TensorFlow.
  2. API de alto nivel:
    • construido sobre TensorFlow Core
    • más fácil de aprender y usar que TensorFlow Core
    • hacer que las tareas repetitivas sean más fáciles y consistentes entre diferentes usuarios
    • tf.contrib.learn es un ejemplo de una API de alto nivel.

En este artículo, primero analizamos los conceptos básicos de TensorFlow Core y luego exploramos la API de nivel superior, tf.contrib.learn .

Núcleo TensorFlow

1. Instalación de TensorFlow

Una guía fácil de seguir para la instalación de TensorFlow está disponible aquí:
Instalación de TensorFlow .

Una vez instalado, puede garantizar una instalación exitosa ejecutando este comando en el intérprete de python:

import tensorflow as tf

2. El gráfico computacional

Cualquier programa de TensorFlow Core se puede dividir en dos secciones discretas:

  • Construcción del gráfico computacional. Un gráfico computacional no es más que una serie de operaciones de TensorFlow organizadas en un gráfico de Nodes.
  • Ejecutar el gráfico computacional. Para evaluar realmente los Nodes, debemos ejecutar el gráfico computacional dentro de una sesión . Una sesión encapsula el control y el estado del tiempo de ejecución de TensorFlow.

Ahora, escribamos nuestro primer programa TensorFlow para comprender el concepto anterior:

# importing tensorflow
import tensorflow as tf
  
# creating nodes in computation graph
node1 = tf.constant(3, dtype=tf.int32)
node2 = tf.constant(5, dtype=tf.int32)
node3 = tf.add(node1, node2)
  
# create tensorflow session object
sess = tf.Session()
  
# evaluating node3 and printing the result
print("Sum of node1 and node2 is:",sess.run(node3))
  
# closing the session
sess.close()

Producción:

Sum of node1 and node2 is: 8

Tratemos de entender el código anterior:

  • Paso 1: Crear un gráfico computacional
    Al crear un gráfico computacional, nos referimos a definir los Nodes. Tensorflow proporciona diferentes tipos de Nodes para una variedad de tareas. Cada Node toma cero o más tensores como entradas y produce un tensor como salida.
    • En el programa anterior, los Nodes node1 y node2 son del tipo tf.constant . Un Node constante no toma entradas y genera un valor que almacena internamente. Tenga en cuenta que también podemos especificar el tipo de datos del tensor de salida usando el argumento dtype .
      node1 = tf.constant(3, dtype=tf.int32)
      node2 = tf.constant(5, dtype=tf.int32)
      
    • node3 es del tipo tf.add . Toma dos tensores como entrada y devuelve su suma como tensor de salida.
      node3 = tf.add(node1, node2)
      
  • Paso 2: Ejecute el gráfico computacional
    Para ejecutar el gráfico computacional, necesitamos crear una sesión . Para crear una sesión, simplemente hacemos:
    sess = tf.Session()
    

    Ahora, podemos invocar el método de ejecución del objeto de sesión para realizar cálculos en cualquier Node:

    print("Sum of node1 and node2 is:",sess.run(node3))
    

    Aquí, node3 se evalúa, lo que invoca aún más a node1 y node2 . Finalmente, cerramos la sesión usando:

    sess.close()
    

Nota: Otro (y mejor) método para trabajar con sesiones es usar un bloque como este:

with tf.Session() as sess:
    print("Sum of node1 and node2 is:",sess.run(node3))

El beneficio de este enfoque es que no necesita cerrar la sesión explícitamente, ya que se cierra automáticamente una vez que el control sale del alcance de with block.

3. Variables

TensorFlow también tiene Nodes variables que pueden contener datos variables. Se utilizan principalmente para mantener y actualizar los parámetros de un modelo de entrenamiento.

Las variables son búferes en memoria que contienen tensores. Deben inicializarse explícitamente y pueden guardarse en el disco durante y después del entrenamiento. Posteriormente puede restaurar los valores guardados para ejercitar o analizar el modelo.

Una diferencia importante a tener en cuenta entre una constante y una variable es:

El valor de una constante se almacena en el gráfico y su valor se replica dondequiera que se cargue el gráfico. Una variable se almacena por separado y puede residir en un servidor de parámetros.

A continuación se muestra un ejemplo usando Variable :

# importing tensorflow
import tensorflow as tf
  
# creating nodes in computation graph
node = tf.Variable(tf.zeros([2,2]))
  
# running computation graph
with tf.Session() as sess:
  
    # initialize all global variables 
    sess.run(tf.global_variables_initializer())
  
    # evaluating node
    print("Tensor value before addition:\n",sess.run(node))
  
    # elementwise addition to tensor
    node = node.assign(node + tf.ones([2,2]))
  
    # evaluate node again
    print("Tensor value after addition:\n", sess.run(node))

Producción:

Tensor value before addition:
 [[ 0.  0.]
 [ 0.  0.]]
Tensor value after addition:
 [[ 1.  1.]
 [ 1.  1.]]

En el programa anterior:

  • Definimos un Node de tipo Variable y le asignamos un valor inicial.
    node = tf.Variable(tf.zeros([2,2]))
    
  • Para inicializar el Node variable en el alcance de la sesión actual, hacemos:
    sess.run(tf.global_variables_initializer())
    
  • Para asignar un nuevo valor a un Node variable, podemos usar un método de asignación como este:
    node = node.assign(node + tf.ones([2,2]))
    

4. Marcadores de posición

Un gráfico se puede parametrizar para aceptar entradas externas, conocidas como marcadores de posición . Un marcador de posición es una promesa de proporcionar un valor más adelante.

Al evaluar el gráfico que involucra Nodes de marcadores de posición , se pasa un parámetro feed_dict al método de ejecución de la sesión para especificar tensores que proporcionen valores concretos a estos marcadores de posición.

Considere el ejemplo dado a continuación:

# importing tensorflow
import tensorflow as tf
  
# creating nodes in computation graph
a = tf.placeholder(tf.int32, shape=(3,1))
b = tf.placeholder(tf.int32, shape=(1,3))
c = tf.matmul(a,b)
  
# running computation graph
with tf.Session() as sess:
    print(sess.run(c, feed_dict={a:[[3],[2],[1]], b:[[1,2,3]]}))

Producción:

[[3 6 9]
 [2 4 6]
 [1 2 3]]

Tratemos de entender el programa anterior:

  • Definimos los Nodes de marcador de posición a y b así:
    a = tf.placeholder(tf.int32, shape=(3,1))
    b = tf.placeholder(tf.int32, shape=(1,3))
    

    El primer argumento es el tipo de datos del tensor y uno de los argumentos opcionales es la forma del tensor.

  • Definimos otro Node c que hace la operación de multiplicación de arrays ( matmul ). Pasamos los dos Nodes marcadores de posición como argumento.
    c = tf.matmul(a,b)
    
  • Finalmente, cuando ejecutamos la sesión, pasamos el valor de los Nodes de marcador de posición en el argumento feed_dict de sess.run :
    print(sess.run(c, feed_dict={a:[[3],[2],[1]], b:[[1,2,3]]}))
    

    Considere los diagramas que se muestran a continuación para aclarar el concepto:

  • Inicialmente:
  • Después de sess.run:

5. Un ejemplo: modelo de regresión lineal

A continuación se muestra una implementación de un modelo de regresión lineal que utiliza la API principal de TensorFlow.

# importing the dependencies
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
  
# Model Parameters
learning_rate = 0.01
training_epochs = 2000
display_step = 200
  
# Training Data
train_X = np.asarray([3.3,4.4,5.5,6.71,6.93,4.168,9.779,6.182,7.59,2.167,
                         7.042,10.791,5.313,7.997,5.654,9.27,3.1])
train_y = np.asarray([1.7,2.76,2.09,3.19,1.694,1.573,3.366,2.596,2.53,1.221,
                         2.827,3.465,1.65,2.904,2.42,2.94,1.3])
n_samples = train_X.shape[0]
  
# Test Data
test_X = np.asarray([6.83, 4.668, 8.9, 7.91, 5.7, 8.7, 3.1, 2.1])
test_y = np.asarray([1.84, 2.273, 3.2, 2.831, 2.92, 3.24, 1.35, 1.03])
  
# Set placeholders for feature and target vectors
X = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)
  
# Set model weights and bias
W = tf.Variable(np.random.randn(), name="weight")
b = tf.Variable(np.random.randn(), name="bias")
  
# Construct a linear model
linear_model = W*X + b
  
# Mean squared error
cost = tf.reduce_sum(tf.square(linear_model - y)) / (2*n_samples)
  
# Gradient descent
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
  
# Initializing the variables
init = tf.global_variables_initializer()
  
# Launch the graph
with tf.Session() as sess:
    # Load initialized variables in current session
    sess.run(init)
  
    # Fit all training data
    for epoch in range(training_epochs):
  
        # perform gradient descent step
        sess.run(optimizer, feed_dict={X: train_X, y: train_y})
          
        # Display logs per epoch step
        if (epoch+1) % display_step == 0:
            c = sess.run(cost, feed_dict={X: train_X, y: train_y})
            print("Epoch:{0:6} \t Cost:{1:10.4} \t W:{2:6.4} \t b:{3:6.4}".
                  format(epoch+1, c, sess.run(W), sess.run(b)))
              
    # Print final parameter values
    print("Optimization Finished!")
    training_cost = sess.run(cost, feed_dict={X: train_X, y: train_y})
    print("Final training cost:", training_cost, "W:", sess.run(W), "b:", 
          sess.run(b), '\n')
      
    # Graphic display
    plt.plot(train_X, train_y, 'ro', label='Original data')
    plt.plot(train_X, sess.run(W) * train_X + sess.run(b), label='Fitted line')
    plt.legend()
    plt.show()
  
    # Testing the model
    testing_cost = sess.run(tf.reduce_sum(tf.square(linear_model - y)) / (2 * test_X.shape[0]),
                            feed_dict={X: test_X, y: test_y})
      
    print("Final testing cost:", testing_cost)
    print("Absolute mean square loss difference:", abs(training_cost - testing_cost))
  
    # Display fitted line on test data
    plt.plot(test_X, test_y, 'bo', label='Testing data')
    plt.plot(train_X, sess.run(W) * train_X + sess.run(b), label='Fitted line')
    plt.legend()
    plt.show()
Epoch:   200      Cost:    0.1715      W: 0.426      b:-0.4371
Epoch:   400      Cost:    0.1351      W:0.3884      b:-0.1706
Epoch:   600      Cost:    0.1127      W:0.3589      b:0.03849
Epoch:   800      Cost:   0.09894      W:0.3358      b:0.2025
Epoch:  1000      Cost:   0.09047      W:0.3176      b:0.3311
Epoch:  1200      Cost:   0.08526      W:0.3034      b:0.4319
Epoch:  1400      Cost:   0.08205      W:0.2922      b:0.5111
Epoch:  1600      Cost:   0.08008      W:0.2835      b:0.5731
Epoch:  1800      Cost:   0.07887      W:0.2766      b:0.6218
Epoch:  2000      Cost:   0.07812      W:0.2712      b:  0.66
Optimization Finished!
Final training cost: 0.0781221 W: 0.271219 b: 0.65996 



Final testing cost: 0.0756337
Absolute mean square loss difference: 0.00248838


Tratemos de entender el código anterior.

  • En primer lugar, definimos algunos parámetros para entrenar nuestro modelo, como:
    learning_rate = 0.01
    training_epochs = 2000
    display_step = 200
    
  • Luego, definimos los Nodes de marcador de posición para la función y el vector de destino.
    X = tf.placeholder(tf.float32)
    y = tf.placeholder(tf.float32)
    
  • Luego, definimos Nodes variables para peso y sesgo.
    W = tf.Variable(np.random.randn(), name="weight")
    b = tf.Variable(np.random.randn(), name="bias")
    
  • linear_model es un Node operativo que calcula la hipótesis para el modelo de regresión lineal.
    linear_model = W*X + b
    
  • La pérdida (o costo) por descenso de gradiente se calcula como el error cuadrático medio y su Node se define como:
    cost = tf.reduce_sum(tf.square(linear_model - y)) / (2*n_samples)
    
  • Finalmente, tenemos el Node optimizador que implementa el Algoritmo de Descenso de Gradiente.
    optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
    
  • Ahora, los datos de entrenamiento se ajustan al modelo lineal aplicando el algoritmo de descenso de gradiente. La tarea se repite training_epochs número de veces. En cada época, realizamos el paso de descenso de gradiente así:
    sess.run(optimizer, feed_dict={X: train_X, y: train_y})
    
  • Después de cada número de épocas de display_step , imprimimos el valor de la pérdida actual que se encuentra usando:
    c = sess.run(cost, feed_dict={X: train_X, y: train_y})
    
  • El modelo se evalúa en datos de prueba y testing_cost se calcula usando:
    testing_cost = sess.run(tf.reduce_sum(tf.square(linear_model - y)) / (2 * test_X.shape[0]),
                              feed_dict={X: test_X, y: test_y})
    

tf.contrib.aprender

tf.contrib.learn es una biblioteca TensorFlow de alto nivel que simplifica la mecánica del aprendizaje automático, incluido lo siguiente:

  • ejecutando bucles de entrenamiento
  • ejecutando bucles de evaluación
  • gestionar conjuntos de datos
  • manejo de la alimentacion

Intentemos ver la implementación de la regresión lineal en los mismos datos que usamos anteriormente usando tf.contrib.learn .

# importing the dependencies
import tensorflow as tf
import numpy as np
  
# declaring list of features
features = [tf.contrib.layers.real_valued_column("X")]
  
# creating a linear regression estimator
estimator = tf.contrib.learn.LinearRegressor(feature_columns=features)
  
# training and test data
train_X = np.asarray([3.3,4.4,5.5,6.71,6.93,4.168,9.779,6.182,7.59,2.167,
                         7.042,10.791,5.313,7.997,5.654,9.27,3.1])
train_y = np.asarray([1.7,2.76,2.09,3.19,1.694,1.573,3.366,2.596,2.53,1.221,
                         2.827,3.465,1.65,2.904,2.42,2.94,1.3])
test_X = np.asarray([6.83, 4.668, 8.9, 7.91, 5.7, 8.7, 3.1, 2.1])
test_y = np.asarray([1.84, 2.273, 3.2, 2.831, 2.92, 3.24, 1.35, 1.03])
  
# function to feed dict of numpy arrays into the model for training
input_fn = tf.contrib.learn.io.numpy_input_fn({"X":train_X}, train_y, 
                                              batch_size=4, num_epochs=2000)
  
# function to feed dict of numpy arrays into the model for testing
test_input_fn = tf.contrib.learn.io.numpy_input_fn({"X":test_X}, test_y)
  
# fit training data into estimator
estimator.fit(input_fn=input_fn)
  
# print value of weight and bias
W = estimator.get_variable_value('linear/X/weight')[0][0]
b = estimator.get_variable_value('linear/bias_weight')[0]
print("W:", W, "\tb:", b)
  
# evaluating the final loss
train_loss = estimator.evaluate(input_fn=input_fn)['loss']
test_loss = estimator.evaluate(input_fn=test_input_fn)['loss']
print("Final training loss:", train_loss)
print("Final testing loss:", test_loss)
W: 0.252928     b: 0.802972
Final training loss: 0.153998
Final testing loss: 0.0777036

Tratemos de entender el código anterior.

  • La forma y el tipo de array de características se declara mediante una lista. Cada elemento de la lista define la estructura de una columna. En el ejemplo anterior, solo tenemos 1 característica que almacena valores reales y se le ha dado un nombre X .
    features = [tf.contrib.layers.real_valued_column("X")]
    
  • Entonces, necesitamos un estimador. Un estimador no es más que un modelo predefinido con muchos métodos y parámetros útiles. En el ejemplo anterior, usamos un estimador de modelo de regresión lineal.
    estimator = tf.contrib.learn.LinearRegressor(feature_columns=features)
    
  • Para propósitos de entrenamiento, necesitamos usar una función de entrada que sea responsable de alimentar datos al estimador durante el entrenamiento. Toma los valores de la columna de características como diccionario. Se pueden especificar muchos otros parámetros como el tamaño del lote, el número de épocas, etc.
    input_fn = tf.contrib.learn.io.numpy_input_fn({"X":train_X}, 
                  train_y, batch_size=4, num_epochs=2000)
    
  • Para ajustar los datos de entrenamiento al estimador, simplemente usamos el método de ajuste del estimador en el que la función de entrada se pasa como argumento.
    estimator.fit(input_fn=input_fn)
    
  • Una vez que se completa el entrenamiento, podemos obtener el valor de diferentes variables usando el método de estimador get_variable_value . Puede obtener una lista de todas las variables utilizando el método get_variable_names .
    W = estimator.get_variable_value('linear/X/weight')[0][0]
    b = estimator.get_variable_value('linear/bias_weight')[0]
    
  • El error/pérdida cuadrática media se puede calcular como:
    train_loss = estimator.evaluate(input_fn=input_fn)['loss']
    test_loss = estimator.evaluate(input_fn=test_input_fn)['loss']
    

¡Esto nos lleva al final de este artículo de Introducción a TensorFlow !

Desde aquí, puede intentar explorar este tutorial: MNIST para principiantes de ML .

Este artículo es una contribución de Nikhil Kumar . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo usando contribuya.geeksforgeeks.org o envíe su artículo por correo a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *