Tutorial de red neuronal de TensorFlow

T

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

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.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias para su correcto funcionamiento. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad