TensorFlow es una biblioteca de c贸digo abierto para aplicaciones de Machine Learning. Es el sistema de segunda generaci贸n de Google Brain, despu茅s de reemplazar el DistBelief de origen cercano, y Google lo utiliza tanto para aplicaciones de investigaci贸n como de producci贸n. Las aplicaciones de TensorFlow se pueden escribir en algunos lenguajes: Python, Go, Java y C. Esta publicaci贸n se preocupa por su versi贸n de Python y analiza la instalaci贸n de la biblioteca, los componentes b谩sicos de bajo nivel y la construcci贸n de una red neuronal de avance desde cero. para realizar el aprendizaje en un conjunto de datos real.
La duraci贸n del entrenamiento de las redes neuronales de aprendizaje profundo suele ser un cuello de botella en escenarios m谩s complejos. Dado que las redes neuronales, pero tambi茅n otros algoritmos ML, funcionan principalmente con multiplicaciones de matrices, es mucho m谩s r谩pido ejecutarlas en Unidades de procesamiento gr谩fico (GPU), en lugar de en Unidades centrales de procesamiento (CPU) est谩ndar.
TensorFlow admite tanto CPU como GPU, y Google incluso ha producido su propio hardware especializado para computaci贸n en la nube, llamado Unidad de procesamiento de tensor (TPU), que produce el Mejor presentaci贸n entre las diferentes unidades de procesamiento.
Instalaci贸n
Contenido
Si bien las TPU solo est谩n disponibles en la nube, la instalaci贸n de TensorFlow en una computadora local puede apuntar a una arquitectura de procesamiento tanto de CPU como de GPU. Para utilizar la versi贸n de GPU, su computadora debe tener una tarjeta gr谩fica NVIDIA y tambi茅n satisfacer algunas m谩s requisitos.
B谩sicamente, hay al menos 5 opciones diferentes para la instalaci贸n, usando: virtualenv, pip, Docker, Anaconda e instalaci贸n desde la fuente.
- La instalaci贸n con virtualenv y Docker nos permite instalar TensorFlow en un entorno separado, aislado de sus otras bibliotecas de Python.
- Anaconda es una distribuci贸n de Python que contiene un gran conjunto de bibliotecas para inform谩tica cient铆fica, incluido TensorFlow.
- pip se considera el instalador “nativo” de los paquetes de Python sin utilizar entornos separados.
- Por 煤ltimo, la instalaci贸n desde la fuente pasa por Git, y es la mejor manera de seleccionar una versi贸n de software en particular, siendo la versi贸n estable actual de TensorFlow la r1.4 (en el momento de escribir este art铆culo).
La forma m谩s com煤n y f谩cil de instalar es a trav茅s de virtualenv y pip, por lo que se explicar谩n en esta publicaci贸n.
Si ha usado Python por un tiempo, probablemente sepa pip. As铆 es como puede obtenerlo en una m谩quina Ubuntu:
# Install pip
sudo apt-get install python-pip python-dev # Python 2.7
sudo apt-get install python3-pip python3-dev # Python 3.x
Las siguientes l铆neas explican la instalaci贸n de TensorFlow en una m谩quina con Ubuntu y Mac OSX:
# CPU support
pip install tensorflow # Python 2.7
pip3 install tensorflow # Python 3.x
# GPU support
pip install tensorflow-gpu # Python 2.7
pip3 install tensorflow-gpu # Python 3.x
Los comandos anteriores tambi茅n funcionar谩n en una m谩quina con Windows, pero solo para las versiones Python 3.5.xy 3.6.x.
La instalaci贸n de TensorFlow en un entorno separado se puede realizar a trav茅s de virtualenv o conda (que es parte de Anaconda). El proceso en general sigue las mismas l铆neas anteriores, solo que esta vez primero necesita crear y activar un nuevo entorno con:
virtualenv --system-site-packages ~/tensorflow
source ~/tensorflow/bin/activate
Esto mantendr谩 todos los paquetes necesarios separados de los que ha instalado globalmente en su sistema.
Componentes de la API principal
Hay varias API disponibles para programar TensorFlow. El nivel m谩s bajo se conoce como N煤cleo y trabaja con los componentes b谩sicos: Tensores, Gr谩ficos y Sesiones.
API de nivel superior, como tf.estimator
, est谩n construidos para simplificar el flujo de trabajo y automatizar procesos como administraci贸n de conjuntos de datos, aprendizaje, evaluaci贸n, etc. De todos modos, conocer las caracter铆sticas principales de la biblioteca es vital para crear aplicaciones de aprendizaje de vanguardia.
El objetivo de la API principal es construir un gr谩fico computacional que contenga una serie de operaciones organizadas en un gr谩fico de nodes. Cada node puede tener m煤ltiples tensores (la estructura de datos b谩sica) como entradas y realiza operaciones sobre ellas para calcular una salida, que luego puede representar una entrada a otros nodes en una red de m煤ltiples capas. Este tipo de arquitectura es adecuada para aplicaciones de Machine Learning, como redes neuronales.
Tensores
Los tensores son la estructura de datos b谩sica en TensorFlow que almacena datos en cualquier cantidad de dimensiones, similar a las matrices multidimensionales en NumPy. Hay tres tipos b谩sicos de tensores: constantes, variables y marcadores de posici贸n.
- Las constantes son un tipo inmutable de tensores. Podr铆an verse como nodes sin entradas, generando un 煤nico valor que almacenan internamente.
- Las variables son tipos mutables de tenosrs cuyo valor puede cambiar durante la ejecuci贸n de un gr谩fico. En las aplicaciones de ML, las variables suelen almacenar los par谩metros que deben optimizarse (por ejemplo, los pesos entre los nodes de una red neuronal). Las variables deben inicializarse antes de ejecutar el gr谩fico llamando expl铆citamente a una operaci贸n especial.
- Los marcadores de posici贸n son tensores que almacenan datos de fuentes externas. Representan una “promesa” de que se proporcionar谩 un valor cuando se ejecute el gr谩fico. En las aplicaciones de Machine Learning, los marcadores de posici贸n se utilizan normalmente para introducir datos en el modelo de aprendizaje.
Las siguientes l铆neas dan un ejemplo de los tres tipos de tensor:
import tensorflow as tf
tf.reset_default_graph()
# Define a placeholder
a = tf.placeholder("float", name="pholdA")
print("a:", a)
# Define a variable
b = tf.Variable(2.0, name="varB")
print("b:", b)
# Define a constant
c = tf.constant([1., 2., 3., 4.], name="consC")
print("c:", c)
a: Tensor("pholdA:0", dtype=float32)
b: <tf.Variable 'varB:0' shape=() dtype=float32_ref>
c: Tensor("consC:0", shape=(4,), dtype=float32)
Tenga en cuenta que los tensores no contienen un valor en este punto, y sus valores solo podr铆an estar disponibles cuando el gr谩fico se ejecuta en una sesi贸n.
Gr谩ficos
En este punto, el gr谩fico solo contiene tensores de 谩rbol que no est谩n conectados. Ejecutemos algunas operaciones en nuestros tensores:
d = a * b + c
d
<tf.Tensor 'add:0' shape=<unknown> dtype=float32>
La salida resultante es nuevamente un tensor llamado ‘agregar’, y nuestro modelo ahora se ve como en la imagen de abajo. Puede explorar su gr谩fico, as铆 como otros par谩metros, utilizando la funci贸n incorporada de TensorFlow TensorBoard.
Figura 1: El gr谩fico de TensorFlow que consta de una multiplicaci贸n y una suma.
Otra herramienta 煤til para explorar su gr谩fico es la siguiente, que imprime todas las operaciones en 茅l.
# call the default graph
graph = tf.get_default_graph()
# print operations in the graph
for op in graph.get_operations():
print(op.name)
pholdA
varB/initial_value
varB
varB/Assign
varB/read
consC
mul
add
Sesiones
Finalmente, nuestro gr谩fico debe ejecutarse dentro de una sesi贸n. Tenga en cuenta que las variables se inicializan de antemano, mientras que el tensor de marcador de posici贸n recibe valores concretos a trav茅s del feed_dict
atributo.
# Initialize variables
init = tf.global_variables_initializer()
# Run a session and calculate d
sess = tf.Session()
sess.run(init)
print(sess.run(d, feed_dict={a: [[0.5], [2], [3]]}))
sess.close()
[[ 2. 3. 4. 5.]
[ 5. 6. 7. 8.]
[ 7. 8. 9. 10.]]
El ejemplo anterior es una simplificaci贸n considerable de un modelo de aprendizaje. De cualquier manera, mostr贸 c贸mo el b谩sico tf
Los componentes se pueden combinar en un gr谩fico y ejecutar en una sesi贸n. Adem谩s, ilustr贸 c贸mo se ejecutan las operaciones en tensores de diferentes formas.
En la siguiente secci贸n usaremos la API principal para construir una red neuronal para el Machine Learning en datos reales.
Un modelo de red neuronal
En esta parte, construimos una red neuronal de avance desde cero utilizando los componentes principales de TensorFlow. Comparamos tres arquitecturas de una red neuronal, que variar谩n en el n煤mero de nodes en una sola capa oculta.
Conjunto de datos de iris
Usamos lo simple Conjunto de datos de iris, que consta de 150 ejemplos de plantas, cada una con sus 4 dimensiones (utilizadas como caracter铆sticas de entrada) y su tipo (el valor de salida que debe predecirse). Una planta puede pertenecer a uno de los tres tipos posibles (setosa, virginica y versicolor). Primero descarguemos los datos del sitio web de TensorFlow: se dividen en subconjuntos de entrenamiento y prueba con 120 y 30 ejemplos cada uno.
# Import the needed libraries
import numpy as np
import pandas as pd
import tensorflow as tf
import urllib.request as request
import matplotlib.pyplot as plt
# Download dataset
IRIS_TRAIN_URL = "http://download.tensorflow.org/data/iris_training.csv"
IRIS_TEST_URL = "http://download.tensorflow.org/data/iris_test.csv"
names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'species']
train = pd.read_csv(IRIS_TRAIN_URL, names=names, skiprows=1)
test = pd.read_csv(IRIS_TEST_URL, names=names, skiprows=1)
# Train and test input data
Xtrain = train.drop("species", axis=1)
Xtest = test.drop("species", axis=1)
# Encode target values into binary ('one-hot' style) representation
ytrain = pd.get_dummies(train.species)
ytest = pd.get_dummies(test.species)
Modelo y aprendizaje
La forma de las capas de entrada y salida de nuestra red neuronal corresponder谩 a la forma de los datos, es decir, la capa de entrada contendr谩 cuatro neuronas que representan las cuatro caracter铆sticas de entrada, mientras que la capa de salida contendr谩 tres neuronas debido a los tres bits utilizados para codificar. una especie de planta en un uno caliente estilo. Por ejemplo, la especie ‘setosa’ podr铆a codificarse con un vector [1, 0, 0], la ‘virginica’ con [0, 1, 0]etc.
Seleccionamos tres valores para el n煤mero de neuronas en la capa oculta: 5, 10 y 20, lo que da como resultado tama帽os de red de (4-5-3), (4-10-3) y (4-20-3). Esto significa que nuestra primera red, por ejemplo, tendr谩 4 neuronas de entrada, 5 neuronas “ocultas” y 3 neuronas de salida.
Figura 2: Nuestra red neuronal de avance de tres capas.
El siguiente c贸digo define una funci贸n en la que creamos el modelo, definimos una funci贸n de p茅rdida que debe minimizarse y ejecutamos una sesi贸n con 2000 iteraciones para aprender los pesos 贸ptimos W_1
y W_2
. Como se mencion贸 anteriormente, las matrices de entrada y salida se alimentan a tf.placeholder
los tensores y los pesos se representan como variables porque sus valores cambian en cada iteraci贸n. La funci贸n de p茅rdida se define como el error cuadr谩tico medio entre nuestra predicci贸n y_est
y el tipo de especie real y
, y la funci贸n de activaci贸n que usamos es sigmoideo. los create_train_model
La funci贸n devuelve los pesos aprendidos e imprime el valor final de la funci贸n de p茅rdida.
# Create and train a tensorflow model of a neural network
def create_train_model(hidden_nodes, num_iters):
# Reset the graph
tf.reset_default_graph()
# Placeholders for input and output data
X = tf.placeholder(shape=(120, 4), dtype=tf.float64, name="X")
y = tf.placeholder(shape=(120, 3), dtype=tf.float64, name="y")
# Variables for two group of weights between the three layers of the network
W1 = tf.Variable(np.random.rand(4, hidden_nodes), dtype=tf.float64)
W2 = tf.Variable(np.random.rand(hidden_nodes, 3), dtype=tf.float64)
# Create the neural net graph
A1 = tf.sigmoid(tf.matmul(X, W1))
y_est = tf.sigmoid(tf.matmul(A1, W2))
# Define a loss function
deltas = tf.square(y_est - y)
loss = tf.reduce_sum(deltas)
# Define a train operation to minimize the loss
optimizer = tf.train.GradientDescentOptimizer(0.005)
train = optimizer.minimize(loss)
# Initialize variables and run session
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
# Go through num_iters iterations
for i in range(num_iters):
sess.run(train, feed_dict={X: Xtrain, y: ytrain})
loss_plot[hidden_nodes].append(sess.run(loss, feed_dict={X: Xtrain.as_matrix(), y: ytrain.as_matrix()}))
weights1 = sess.run(W1)
weights2 = sess.run(W2)
print("loss (hidden nodes: %d, iterations: %d): %.2f" % (hidden_nodes, num_iters, loss_plot[hidden_nodes][-1]))
sess.close()
return weights1, weights2
Ok, creemos las tres arquitecturas de red y tracemos la funci贸n de p茅rdida sobre las iteraciones.
# Run the training for 3 different network architectures: (4-5-3) (4-10-3) (4-20-3)
# Plot the loss function over iterations
num_hidden_nodes = [5, 10, 20]
loss_plot = {5: [], 10: [], 20: []}
weights1 = {5: None, 10: None, 20: None}
weights2 = {5: None, 10: None, 20: None}
num_iters = 2000
plt.figure(figsize=(12,8))
for hidden_nodes in num_hidden_nodes:
weights1[hidden_nodes], weights2[hidden_nodes] = create_train_model(hidden_nodes, num_iters)
plt.plot(range(num_iters), loss_plot[hidden_nodes], label="nn: 4-%d-3" % hidden_nodes)
plt.xlabel('Iteration', fontsize=12)
plt.ylabel('Loss', fontsize=12)
plt.legend(fontsize=12)
loss (hidden nodes: 5, iterations: 2000): 31.82
loss (hidden nodes: 10, iterations: 2000): 5.90
loss (hidden nodes: 20, iterations: 2000): 5.61
<matplotlib.legend.Legend at 0x123b157f0>
Figura 3: La funci贸n de p茅rdida durante 2000 iteraciones para diferentes arquitecturas de red.
Podemos ver que la red con 20 neuronas ocultas tarda m谩s en llegar al m铆nimo, lo que se debe a su mayor complejidad. La red con 5 neuronas ocultas se atasca en un m铆nimo local y no dar谩 buenos resultados.
De todos modos, para un conjunto de datos tan simple como Iris, incluso la red peque帽a con 5 neuronas ocultas deber铆a poder aprender un buen modelo. En nuestro caso, fue solo un evento aleatorio que el modelo se atasc贸 en un m铆nimo local, y no suceder铆a muy a menudo si ejecutamos el c贸digo una y otra vez.
Evaluaci贸n del modelo
Finalmente, evaluemos nuestros modelos. Usamos los pesos aprendidos W_1
y W_2
y propagar hacia adelante los ejemplos del conjunto de prueba. La m茅trica de precisi贸n se define como el porcentaje de ejemplos predichos correctamente.
# Evaluate models on the test set
X = tf.placeholder(shape=(30, 4), dtype=tf.float64, name="X")
y = tf.placeholder(shape=(30, 3), dtype=tf.float64, name="y")
for hidden_nodes in num_hidden_nodes:
# Forward propagation
W1 = tf.Variable(weights1[hidden_nodes])
W2 = tf.Variable(weights2[hidden_nodes])
A1 = tf.sigmoid(tf.matmul(X, W1))
y_est = tf.sigmoid(tf.matmul(A1, W2))
# Calculate the predicted outputs
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
y_est_np = sess.run(y_est, feed_dict={X: Xtest, y: ytest})
# Calculate the prediction accuracy
correct = [estimate.argmax(axis=0) == target.argmax(axis=0)
for estimate, target in zip(y_est_np, ytest.as_matrix())]
accuracy = 100 * sum(correct) / len(correct)
print('Network architecture 4-%d-3, accuracy: %.2f%%' % (hidden_nodes, accuracy))
Network architecture 4-5-3, accuracy: 90.00%
Network architecture 4-10-3, accuracy: 96.67%
Network architecture 4-20-3, accuracy: 96.67%
En general, logramos lograr una precisi贸n bastante alta con una red neuronal de alimentaci贸n directa simple, lo que es especialmente sorprendente si se usa un conjunto de datos bastante peque帽o.
Puede echar un vistazo a un ejemplo a煤n m谩s simple usando la API de alto nivel de TensorFlow aqu铆.
Recursos
Este tutorial solo cubri贸 una peque帽a fracci贸n de lo que puede hacer TensorFlow. A continuaci贸n, se incluyen algunos recursos excelentes para obtener m谩s informaci贸n sobre TensorFlow y el aprendizaje profundo en general:
Conclusiones
En esta publicaci贸n, presentamos la biblioteca de TensorFlow para el Machine Learning, proporcionamos gu铆as breves para la instalaci贸n, presentamos los componentes b谩sicos de la API central de bajo nivel de TensorFlow: tensores, gr谩ficos y sesiones, y finalmente creamos un modelo de red neuronal para la clasificaci贸n de datos reales del Conjunto de datos de iris.
En general, podr铆a llevar alg煤n tiempo comprender la filosof铆a de codificaci贸n de TensorFlow, ya que es una biblioteca simb贸lica, pero una vez que se familiariza con los componentes Core, resulta bastante conveniente para crear aplicaciones de Machine Learning. En esta publicaci贸n usamos la API Core de bajo nivel para presentar los componentes b谩sicos y tener un control completo del modelo, pero generalmente es mucho m谩s simple usar una API de nivel superior, como tf.estimator
, o incluso una biblioteca externa, como Keras.