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
, Activation
y 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.