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:
- 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.
- 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)
- 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 .
- 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