Tensorflow 2.0: soluci贸n de problemas de clasificaci贸n y regresi贸n

    Despu茅s de mucha publicidad, Google finalmente lanz贸 TensorFlow 2.0 que es la 煤ltima versi贸n de la plataforma insignia de aprendizaje profundo de Google. Se han introducido muchas funciones tan esperadas en TensorFlow 2.0. Este art铆culo cubre muy brevemente c贸mo puedes desarrollar modelos simples de clasificaci贸n y regresi贸n con TensorFlow 2.0.

    Clasificaci贸n con Tensorflow 2.0

    Si alguna vez ha trabajado con la biblioteca de Keras, est谩 de enhorabuena. TensorFlow 2.0 ahora usa la API de Keras como su biblioteca predeterminada para entrenar modelos de clasificaci贸n y regresi贸n. Antes de TensorFlow 2.0, una de las principales cr铆ticas a las que se enfrentaban las versiones anteriores de TensorFlow se deb铆a a la complejidad de la creaci贸n del modelo. Anteriormente, necesita unir gr谩ficos, sesiones y marcadores de posici贸n para crear incluso un modelo de regresi贸n log铆stica simple. Con TensorFlow 2.0, la creaci贸n de modelos de clasificaci贸n y regresi贸n se ha convertido en pan comido.

    Entonces, sin m谩s pre谩mbulos, desarrollemos un modelo de clasificaci贸n con TensorFlow.

    El conjunto de datos

    El conjunto de datos para el ejemplo de clasificaci贸n se puede descargar libremente de este enlace. Descarga el archivo en formato CSV. Si abre el archivo CSV descargado, ver谩 que el archivo no contiene ning煤n encabezado. El detalle de las columnas est谩 disponible en Repositorio de Machine Learning de UCI. Le recomendar茅 que lea la informaci贸n del conjunto de datos en detalle desde el enlace de descarga. Resumir茅 brevemente el conjunto de datos en esta secci贸n.

    El conjunto de datos consta b谩sicamente de 7 columnas:

    • precio (el precio de compra del coche)
    • maint (el costo de mantenimiento)
    • puertas (n煤mero de puertas)
    • personas (la capacidad de asientos)
    • lug_capacity (la capacidad del equipaje)
    • seguridad (que tan seguro es el auto)
    • salida (el estado del coche)

    Dadas las primeras 6 columnas, la tarea es predecir el valor de la s茅ptima columna, es decir, la salida. La columna de salida puede tener uno de los tres valores, es decir, “unacc” (inaceptable), “acc” (aceptable), bueno y muy bueno.

    Importaci贸n de bibliotecas

    Antes de importar el conjunto de datos a nuestra aplicaci贸n, necesitamos importar las bibliotecas necesarias.

    import pandas as pd
    import numpy as np
    import tensorflow as tf
    
    import matplotlib.pyplot as plt
    %matplotlib inline
    
    import seaborn as sns
    sns.set(style="darkgrid")
    

    Antes de continuar, quiero que se asegure de tener la 煤ltima versi贸n de TensorFlow, es decir, TensorFlow 2.0. Puedes verificar tu versi贸n de TensorFlow con el siguiente comando:

    print(tf.__version__)
    

    Si no tiene TensorFlow 2.0 instalado, puede actualizar a la 煤ltima versi贸n mediante el siguiente comando:

    $ pip install --upgrade tensorflow
    

    Importar el conjunto de datos

    El siguiente script importa el conjunto de datos. Cambie la ruta a su archivo de datos CSV seg煤n.

    cols = ['price', 'maint', 'doors', 'persons', 'lug_capacity', 'safety','output']
    cars = pd.read_csv(r'/content/drive/My Drive/datasets/car_dataset.csv', names=cols, header=None)
    

    Dado que el archivo CSV no contiene encabezados de columna de forma predeterminada, pasamos una lista de encabezados de columna al pd.read_csv() m茅todo.

    Veamos ahora las primeras 5 filas del conjunto de datos a trav茅s de la head() m茅todo.

    cars.head()
    

    Salida:

    Puede ver las 7 columnas en el conjunto de datos.

    An谩lisis y preprocesamiento de datos

    Analicemos brevemente el conjunto de datos trazando un gr谩fico circular que muestre la distribuci贸n de la salida. La siguiente secuencia de comandos aumenta el tama帽o de trazado predeterminado.

    plot_size = plt.rcParams["figure.figsize"]
    plot_size [0] = 8
    plot_size [1] = 6
    plt.rcParams["figure.figsize"] = plot_size
    

    Y el siguiente script traza el gr谩fico circular que muestra la distribuci贸n de salida.

    cars.output.value_counts().plot(kind='pie', autopct="%0.05f%%", colors=['lightblue', 'lightgreen', 'orange', 'pink'], explode=(0.05, 0.05, 0.05,0.05))
    

    Salida:

    El resultado muestra que la mayor铆a de los autom贸viles (70%) est谩n en condiciones inaceptables mientras que el 20% de los autom贸viles est谩n en condiciones aceptables. La relaci贸n de coches en buen y muy buen estado es muy baja.

    Todas las columnas de nuestro conjunto de datos son categ贸ricas. El aprendizaje profundo se basa en algoritmos estad铆sticos y los algoritmos estad铆sticos funcionan con n煤meros. Por lo tanto, necesitamos convertir la informaci贸n categ贸rica en columnas num茅ricas. Hay varios enfoques para hacer eso, pero uno de los enfoques m谩s comunes es la codificaci贸n one-hot. En la codificaci贸n one-hot, para cada valor 煤nico en la columna categ贸rica, se crea una nueva columna. Para las filas de la columna real donde exist铆a el valor 煤nico, se agrega un 1 a la fila correspondiente de la columna creada para ese valor en particular. Esto puede parecer complejo, pero el siguiente ejemplo lo aclarar谩.

    El siguiente script convierte columnas categ贸ricas en columnas num茅ricas:

    price = pd.get_dummies(cars.price, prefix='price')
    maint = pd.get_dummies(cars.maint, prefix='maint')
    
    doors = pd.get_dummies(cars.doors, prefix='doors')
    persons = pd.get_dummies(cars.persons, prefix='persons')
    
    lug_capacity = pd.get_dummies(cars.lug_capacity, prefix='lug_capacity')
    safety = pd.get_dummies(cars.safety, prefix='safety')
    
    labels = pd.get_dummies(cars.output, prefix='condition')
    

    Para crear nuestro conjunto de caracter铆sticas, podemos fusionar las primeras seis columnas horizontalmente:

    X = pd.concat([price, maint, doors, persons, lug_capacity, safety] , axis=1)
    

    Veamos c贸mo se ve nuestra columna de etiquetas ahora:

    labels.head()
    

    Salida:

    La columna de etiquetas es b谩sicamente una versi贸n codificada en caliente de la columna de salida que ten铆amos en nuestro conjunto de datos. La columna de salida ten铆a cuatro valores 煤nicos: unacc, acc, good y very good. En el conjunto de datos de etiquetas codificadas en caliente, puede ver cuatro columnas, una para cada uno de los valores 煤nicos en la columna de salida. Puede ver 1 en la columna para el valor 煤nico que exist铆a originalmente en esa fila. Por ejemplo, en las primeras cinco filas de la columna de salida, el valor de la columna era unacc. En la columna de etiquetas, puede ver 1 en las primeras cinco filas de la columna condition_unacc.

    Ahora convierta nuestras etiquetas en una matriz numpy, ya que los modelos de aprendizaje profundo en TensorFlow aceptan matriz numpy como entrada.

    y = labels.values
    

    El 煤ltimo paso antes de que podamos entrenar nuestro modelo de clasificaci贸n de TensorFlow 2.0 es dividir el conjunto de datos en conjuntos de entrenamiento y de prueba:

    from sklearn.model_selection import train_test_split
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=42)
    

    Entrenamiento de modelos

    Para entrenar el modelo, importemos las clases de TensorFlow 2.0. Ejecute el siguiente script:

    from tensorflow.keras.layers import Input, Dense, Activation,Dropout
    from tensorflow.keras.models import Model
    

    Como dije anteriormente, TensorFlow 2.0 usa la API de Keras para entrenar el modelo. En el script anterior b谩sicamente importamos Input, Dense, Activationy Dropout clases de tensorflow.keras.layers m贸dulo. Del mismo modo, tambi茅n import la Model clase de la tensorflow.keras.models m贸dulo.

    El siguiente paso es crear nuestro modelo de clasificaci贸n:

    input_layer = Input(shape=(X.shape[1],))
    dense_layer_1 = Dense(15, activation='relu')(input_layer)
    dense_layer_2 = Dense(10, activation='relu')(dense_layer_1)
    output = Dense(y.shape[1], activation='softmax')(dense_layer_2)
    
    model = Model(inputs=input_layer, outputs=output)
    model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=['acc'])
    

    Como puede verse en el gui贸n, el modelo contiene tres capas densas. Las dos primeras capas densas contienen 15 y 10 nodes, respectivamente con relu funci贸n de activaci贸n. La capa densa final contiene 4 nodes (y.shape[1] == 4) y softmax funci贸n de activaci贸n ya que se trata de una tarea de clasificaci贸n. El modelo se entrena usando categorical_crossentropy funci贸n de p茅rdida y adam optimizador. La m茅trica de evaluaci贸n es la precisi贸n.

    El siguiente script muestra el resumen del modelo:

    print(model.summary())
    

    Salida:

    Model: "model"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #
    =================================================================
    input_1 (InputLayer)         [(None, 21)]              0
    _________________________________________________________________
    dense (Dense)                (None, 15)                330
    _________________________________________________________________
    dense_1 (Dense)              (None, 10)                160
    _________________________________________________________________
    dense_2 (Dense)              (None, 4)                 44
    =================================================================
    Total params: 534
    Trainable params: 534
    Non-trainable params: 0
    _________________________________________________________________
    None
    

    Finalmente, para entrenar el modelo ejecute el siguiente script:

    history = model.fit(X_train, y_train, batch_size=8, epochs=50, verbose=1, validation_split=0.2)
    

    El modelo se entrenar谩 durante 50 茅pocas, pero aqu铆 por el bien del espacio, se muestra el resultado de solo las 煤ltimas 5 茅pocas:

    Epoch 45/50
    1105/1105 [==============================] - 0s 219us/sample - loss: 0.0114 - acc: 1.0000 - val_loss: 0.0606 - val_acc: 0.9856
    Epoch 46/50
    1105/1105 [==============================] - 0s 212us/sample - loss: 0.0113 - acc: 1.0000 - val_loss: 0.0497 - val_acc: 0.9856
    Epoch 47/50
    1105/1105 [==============================] - 0s 219us/sample - loss: 0.0102 - acc: 1.0000 - val_loss: 0.0517 - val_acc: 0.9856
    Epoch 48/50
    1105/1105 [==============================] - 0s 218us/sample - loss: 0.0091 - acc: 1.0000 - val_loss: 0.0536 - val_acc: 0.9856
    Epoch 49/50
    1105/1105 [==============================] - 0s 213us/sample - loss: 0.0095 - acc: 1.0000 - val_loss: 0.0513 - val_acc: 0.9819
    Epoch 50/50
    1105/1105 [==============================] - 0s 209us/sample - loss: 0.0080 - acc: 1.0000 - val_loss: 0.0536 - val_acc: 0.9856
    

    Al final de la quincuag茅sima 茅poca, tenemos una precisi贸n de entrenamiento del 100% mientras que la precisi贸n de validaci贸n es del 98.56%, lo cual es impresionante.

    Finalmente, evaluemos el desempe帽o de nuestro modelo de clasificaci贸n en el conjunto de prueba:

    score = model.evaluate(X_test, y_test, verbose=1)
    
    print("Test Score:", score[0])
    print("Test Accuracy:", score[1])
    

    Aqu铆 est谩 el resultado:

    WARNING:tensorflow:Falling back from v2 loop because of error: Failed to find data adapter that can handle input: <class 'pandas.core.frame.DataFrame'>, <class 'NoneType'>
    346/346 [==============================] - 0s 55us/sample - loss: 0.0605 - acc: 0.9740
    Test Score: 0.06045335989359314
    Test Accuracy: 0.9739884
    

    Nuestro modelo alcanza una precisi贸n del 97,39% en el equipo de prueba. Aunque es un poco menor que la precisi贸n de entrenamiento del 100%, sigue siendo muy bueno dado el hecho de que elegimos aleatoriamente el n煤mero de capas y los nodes. Puede agregar m谩s capas al modelo con m谩s nodes y ver si puede obtener mejores resultados en los conjuntos de validaci贸n y prueba.

    Regresi贸n con TensorFlow 2.0

    En el problema de regresi贸n, el objetivo es predecir un valor continuo. En esta secci贸n, ver谩 c贸mo resolver un problema de regresi贸n con TensorFlow 2.0

    El conjunto de datos

    El conjunto de datos de este problema se puede descargar gratuitamente desde este enlace. Descarga el archivo CSV.

    El siguiente script importa el conjunto de datos. No olvide cambiar la ruta a su propio archivo de datos CSV.

    petrol_cons = pd.read_csv(r'/content/drive/My Drive/datasets/petrol_consumption.csv')
    

    Imprimamos las primeras cinco filas del conjunto de datos mediante el head() funci贸n:

    petrol_cons.head()
    

    Salida:

    Puede ver que hay cinco columnas en el conjunto de datos. El modelo de regresi贸n se entrenar谩 en las primeras cuatro columnas, es decir, Petrol_tax, Average_inome, Paved_Highways y Population_Driver_License (%). Se predecir谩 el valor de la 煤ltima columna, es decir, Petrol_Consumption. Como puede ver, no hay un valor discreto para la columna de salida, sino que el valor predicho puede ser cualquier valor continuo.

    Preprocesamiento de datos

    En el paso de preprocesamiento de datos, simplemente dividiremos los datos en caracter铆sticas y etiquetas, y luego dividiremos los datos en conjuntos de prueba y entrenamiento. Finalmente se normalizar谩n los datos. Para problemas de regresi贸n en general y para problemas de regresi贸n con aprendizaje profundo, se recomienda encarecidamente que normalice su conjunto de datos. Finalmente, dado que todas las columnas son num茅ricas, aqu铆 no es necesario realizar una codificaci贸n en caliente de las columnas.

    X = petrol_cons.iloc[:, 0:4].values
    y = petrol_cons.iloc[:, 4].values
    
    from sklearn.model_selection import train_test_split
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
    
    from sklearn.preprocessing import StandardScaler
    
    sc = StandardScaler()
    X_train = sc.fit_transform(X_train)
    X_test = sc.transform(X_test)
    

    En el script anterior, en el conjunto de funciones X, se incluyen las primeras cuatro columnas del conjunto de datos. En el conjunto de etiquetas y, solo se incluye la quinta columna. A continuaci贸n, el conjunto de datos se divide en entrenamiento y tama帽o de prueba a trav茅s del train_test_split m茅todo del sklearn.model_selection m贸dulo. El valor de la test_size El atributo es 0.2, lo que significa que el conjunto de prueba contendr谩 el 20% de los datos originales y el conjunto de entrenamiento consistir谩 en el 80% restante del conjunto de datos original. Finalmente, el StandardScaler clase de la sklearn.preprocessing El m贸dulo se utiliza para escalar el conjunto de datos.

    Entrenamiento de modelos

    El siguiente paso es entrenar nuestro modelo. Este proceso es bastante similar al entrenamiento de la clasificaci贸n. El 煤nico cambio ser谩 en la funci贸n de p茅rdida y el n煤mero de nodes en la capa densa de salida. Dado que ahora estamos prediciendo un 煤nico valor continuo, la capa de salida solo tendr谩 1 node.

    input_layer = Input(shape=(X.shape[1],))
    dense_layer_1 = Dense(100, activation='relu')(input_layer)
    dense_layer_2 = Dense(50, activation='relu')(dense_layer_1)
    dense_layer_3 = Dense(25, activation='relu')(dense_layer_2)
    output = Dense(1)(dense_layer_3)
    
    model = Model(inputs=input_layer, outputs=output)
    model.compile(loss="mean_squared_error" , optimizer="adam", metrics=["mean_squared_error"])
    

    Nuestro modelo consta de cuatro capas densas con 100, 50, 25 y 1 node, respectivamente. Para los problemas de regresi贸n, una de las funciones de p茅rdida m谩s utilizadas es mean_squared_error. El siguiente script imprime el resumen del modelo:

    Model: "model_2"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #
    =================================================================
    input_4 (InputLayer)         [(None, 4)]               0
    _________________________________________________________________
    dense_10 (Dense)             (None, 100)               500
    _________________________________________________________________
    dense_11 (Dense)             (None, 50)                5050
    _________________________________________________________________
    dense_12 (Dense)             (None, 25)                1275
    _________________________________________________________________
    dense_13 (Dense)             (None, 1)                 26
    =================================================================
    Total params: 6,851
    Trainable params: 6,851
    Non-trainable params: 0
    

    Finalmente, podemos entrenar el modelo con el siguiente script:

    history = model.fit(X_train, y_train, batch_size=2, epochs=100, verbose=1, validation_split=0.2)
    

    Aqu铆 est谩 el resultado de las 煤ltimas 5 茅pocas de entrenamiento:

    Epoch 96/100
    30/30 [==============================] - 0s 2ms/sample - loss: 510.3316 - mean_squared_error: 510.3317 - val_loss: 10383.5234 - val_mean_squared_error: 10383.5234
    Epoch 97/100
    30/30 [==============================] - 0s 2ms/sample - loss: 523.3454 - mean_squared_error: 523.3453 - val_loss: 10488.3036 - val_mean_squared_error: 10488.3037
    Epoch 98/100
    30/30 [==============================] - 0s 2ms/sample - loss: 514.8281 - mean_squared_error: 514.8281 - val_loss: 10379.5087 - val_mean_squared_error: 10379.5088
    Epoch 99/100
    30/30 [==============================] - 0s 2ms/sample - loss: 504.0919 - mean_squared_error: 504.0919 - val_loss: 10301.3304 - val_mean_squared_error: 10301.3311
    Epoch 100/100
    30/30 [==============================] - 0s 2ms/sample - loss: 532.7809 - mean_squared_error: 532.7809 - val_loss: 10325.1699 - val_mean_squared_error: 10325.1709
    

    Para evaluar el rendimiento de un modelo de regresi贸n en un conjunto de prueba, una de las m茅tricas m谩s utilizadas es el error cuadr谩tico medio de la ra铆z. Podemos encontrar el error cuadr谩tico medio entre los valores predichos y reales mediante el mean_squared_error clase de la sklearn.metrics m贸dulo. Entonces podemos sacar la ra铆z cuadrada del error cuadr谩tico medio resultante. Mira el siguiente gui贸n:

    from sklearn.metrics import mean_squared_error
    from math import sqrt
    
    pred_train = model.predict(X_train)
    print(np.sqrt(mean_squared_error(y_train,pred_train)))
    
    pred = model.predict(X_test)
    print(np.sqrt(mean_squared_error(y_test,pred)))
    

    El resultado muestra el error cuadr谩tico medio para los conjuntos de entrenamiento y prueba. Los resultados muestran que el rendimiento del modelo es mejor en el conjunto de entrenamiento, ya que el valor de error cuadr谩tico medio del conjunto de entrenamiento es menor. Nuestro modelo est谩 sobreajustado. La raz贸n es obvia, solo ten铆amos 48 registros en el conjunto de datos. Intente entrenar modelos de regresi贸n con un conjunto de datos m谩s grande para obtener mejores resultados.

    50.43599665058207
    84.31961060849562
    

    Conclusi贸n

    TensorFlow 2.0 es la 煤ltima versi贸n de la biblioteca TensorFlow de Google para el aprendizaje profundo. Este art铆culo cubre brevemente c贸mo crear modelos de clasificaci贸n y regresi贸n con TensorFlow 2.0. Para tener una experiencia pr谩ctica, le sugiero que practique los ejemplos que se dan en este art铆culo y trate de crear modelos simples de regresi贸n y clasificaci贸n con TensorFlow 2.0 utilizando algunos otros conjuntos de datos.

     

    Etiquetas:

    Deja una respuesta

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