Tutorial de red neuronal de TensorFlow

    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.

     

    Etiquetas:

    Deja una respuesta

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