Cómo construir su primera red neuronal para predecir los precios de la vivienda con Keras

¡Una guía paso a paso completa para principiantes para construir su primera red neuronal en un par de líneas de código como un profesional de Deep Learning!

¡Escribir su primera red neuronal se puede hacer con solo un par de líneas de código! En esta publicación, exploraremos cómo usar un paquete llamado Keras para construir nuestra primera red neuronal para predecir si los precios de la vivienda están por encima o por debajo del valor medio. En particular, revisaremos la línea completa de Deep Learning, desde:

  • Explorando y procesando los datos
  • Construyendo y entrenando nuestra red neuronal
  • Visualización de pérdida y precisión
  • Agregar regularización a nuestra red neuronal

¡En solo 20 a 30 minutos, habrá codificado su propia red neuronal tal como lo hubiera hecho un profesional de Deep Learning!

Prerrequisitos:

Esta publicación asume que tienes una computadora portátil Jupyter configurada con un entorno que tiene los paquetes keras, tensorflow, pandas, scikit-learn y matplotlib instalados. Si no lo ha hecho, siga las instrucciones en el tutorial a continuación:

  • Comenzando con Python para Deep Learning y Data Science

Este es un compañero de codificación para el aprendizaje intuitivo profundo, parte 1. Como tal, suponemos que tiene una comprensión intuitiva de las redes neuronales y cómo funcionan, incluidos algunos de los detalles esenciales, como qué es el sobreajuste y las estrategias para abordar ellos. Si necesita un repaso, lea estas introducciones intuitivas:

  • Aprendizaje profundo intuitivo Parte 1a: Introducción a las redes neuronales
  • Aprendizaje profundo intuitivo Parte 1b: Introducción a las redes neuronales

Recursos que necesitas:

El conjunto de datos que usaremos hoy está adaptado de los datos de la competencia Kaggle de predicción del valor de la vivienda de Zillow. Hemos reducido la cantidad de funciones de entrada y hemos cambiado la tarea para predecir si el precio de la vivienda está por encima o por debajo del valor medio. Visite el siguiente enlace para descargar el conjunto de datos modificado a continuación y colóquelo en el mismo directorio que su computadora portátil. El icono de descarga debe estar en la esquina superior derecha.

Descargar conjunto de datos

Opcionalmente, también puede descargar un cuaderno Jupyter anotado que tiene todo el código cubierto en esta publicación: Jupyter Notebook.

Tenga en cuenta que para descargar este cuaderno de Github, debe ir a la página principal y descargar ZIP para descargar todos los archivos:

Y ahora, ¡comencemos!

Explorando y procesando los datos

Antes de codificar cualquier algoritmo ML, lo primero que debemos hacer es poner nuestros datos en un formato que el algoritmo desee. En particular, necesitamos:

  • Lea el archivo CSV (valores separados por comas) y conviértalos en matrices. Las matrices son un formato de datos que nuestro algoritmo puede procesar.
  • Divida nuestro conjunto de datos en las características de entrada (que llamamos x) y la etiqueta (que llamamos y).
  • Escale los datos (llamamos a esto normalización) para que las características de entrada tengan órdenes de magnitud similares.
  • Divida nuestro conjunto de datos en el conjunto de entrenamiento, el conjunto de validación y el conjunto de prueba. Si necesita un repaso de por qué necesitamos estos tres conjuntos de datos, consulte Intuitivo Deep Learning Parte 1b.

¡Vamos a empezar! Desde el tutorial Comenzando con Python para Aprendizaje Profundo y Ciencia de Datos, debería haber descargado el paquete pandas a su entorno. Tendremos que decirle a nuestra computadora portátil que usaremos ese paquete al importarlo. Escriba el siguiente código y presione Alt-Enter en su teclado:

importar pandas como pd

Esto solo significa que si quiero hacer referencia al código en el paquete "pandas", lo haré con el nombre pd. Luego leemos el archivo CSV ejecutando esta línea de código:

df = pd.read_csv ('housepricedata.csv')

Esta línea de código significa que leeremos el archivo csv "housepricedata.csv" (que debe estar en el mismo directorio que su computadora portátil) y lo almacenaremos en la variable "df". Si queremos averiguar qué hay en df, simplemente escriba df en el cuadro gris y haga clic en Alt-Enter:

df

Su cuaderno debería verse así:

Aquí, puede explorar un poco los datos. Tenemos nuestras características de entrada en las primeras diez columnas:

  • Área del lote (en pies cuadrados)
  • Calidad general (escala del 1 al 10)
  • Condición general (escala del 1 al 10)
  • Área total del sótano (en pies cuadrados)
  • Cantidad de baños completos
  • Número de medios baños
  • Número de habitaciones sobre el suelo
  • Número total de habitaciones sobre el suelo
  • Numero de chimeneas
  • Área de garaje (en pies cuadrados)

En nuestra última columna, tenemos la característica que nos gustaría predecir:

  • ¿El precio de la vivienda está por encima de la mediana o no? (1 para sí y 0 para no)

Ahora que hemos visto cómo se ven nuestros datos, queremos convertirlos en matrices para que nuestra máquina los procese:

conjunto de datos = valores df.

Para convertir nuestro marco de datos en una matriz, simplemente almacenamos los valores de df (accediendo a los valores de df) en la variable "conjunto de datos". Para ver qué hay dentro de esta variable "conjunto de datos", simplemente escriba "conjunto de datos" en un cuadro gris en su cuaderno y ejecute la celda (Alt-Enter):

conjunto de datos

Como puede ver, todo está almacenado en una matriz ahora:

Convertir nuestro marco de datos en una matriz

Ahora dividimos nuestro conjunto de datos en características de entrada (X) y la característica que deseamos predecir (Y). Para hacer esa división, simplemente asignamos las primeras 10 columnas de nuestra matriz a una variable llamada X y la última columna de nuestra matriz a una variable llamada Y. El código para hacer la primera asignación es este:

X = conjunto de datos [:, 0:10]

Esto puede parecer un poco extraño, pero déjame explicarte qué hay dentro de los corchetes. Todo antes de la coma se refiere a las filas de la matriz y todo lo que sigue a la coma se refiere a las columnas de las matrices.

Como no estamos dividiendo las filas, colocamos ":" antes de la coma. Esto significa tomar todas las filas en el conjunto de datos y ponerlo en X.

Queremos extraer las primeras 10 columnas, por lo que el "0:10" después de la coma significa tomar las columnas 0 a 9 y ponerlo en X (no incluimos la columna 10). Nuestras columnas comienzan desde el índice 0, por lo que las primeras 10 columnas son realmente columnas 0 a 9.

Luego asignamos la última columna de nuestra matriz a Y:

Y = conjunto de datos [:, 10]

Ok, ahora hemos dividido nuestro conjunto de datos en características de entrada (X) y la etiqueta de lo que queremos predecir (Y).

El siguiente paso en nuestro procesamiento es asegurarnos de que la escala de las características de entrada sea similar. En este momento, las características como el área de lote están en el orden de los miles, un puntaje de calidad general varía de 1 a 10, y el número de chimeneas tiende a ser 0, 1 o 2.

Esto dificulta la inicialización de la red neuronal, lo que causa algunos problemas prácticos. Una forma de escalar los datos es usar un paquete existente de scikit-learn (que hemos instalado en la publicación Introducción).

Primero tenemos que importar el código que queremos usar:

desde el preprocesamiento de importación sklearn

Esto dice que quiero usar el código en "preprocesamiento" dentro del paquete sklearn. Luego, usamos una función llamada escalador min-max, que escala el conjunto de datos para que todas las características de entrada se encuentren entre 0 y 1 inclusive:

min_max_scaler = preprocesamiento.MinMaxScaler ()
X_scale = min_max_scaler.fit_transform (X)

Tenga en cuenta que elegimos 0 y 1 intencionalmente para ayudar al entrenamiento de nuestra red neuronal. No veremos la teoría detrás de esto. Ahora, nuestro conjunto de datos escalado se almacena en la matriz "X_scale". Si desea ver cómo se ve "X_scale", simplemente ejecute la celda:

X_scale

Su cuaderno Jupyter ahora debería verse un poco así:

Ahora, estamos en nuestro último paso en el procesamiento de los datos, que es dividir nuestro conjunto de datos en un conjunto de entrenamiento, un conjunto de validación y un conjunto de prueba.

Utilizaremos el código de scikit-learn llamado ‘train_test_split’, que, como su nombre indica, divide nuestro conjunto de datos en un conjunto de entrenamiento y un conjunto de prueba. Primero importamos el código que necesitamos:

de sklearn.model_selection import train_test_split

Luego, divida su conjunto de datos de esta manera:

X_train, X_val_and_test, Y_train, Y_val_and_test = train_test_split (X_scale, Y, test_size = 0.3)

Esto le dice a scikit-learn que su tamaño val_and_test será el 30% del conjunto de datos general. El código almacenará los datos divididos en las primeras cuatro variables a la izquierda del signo igual como sugieren los nombres de las variables.

Desafortunadamente, esta función solo nos ayuda a dividir nuestro conjunto de datos en dos. Como queremos un conjunto de validación y un conjunto de prueba por separado, podemos usar la misma función para volver a dividir en val_and_test:

X_val, X_test, Y_val, Y_test = train_test_split (X_val_and_test, Y_val_and_test, test_size = 0.5)

El código anterior dividirá el tamaño val_and_test por igual al conjunto de validación y al conjunto de prueba.

En resumen, ahora tenemos un total de seis variables para nuestros conjuntos de datos que usaremos:

  • X_train (10 funciones de entrada, 70% del conjunto de datos completo)
  • X_val (10 funciones de entrada, 15% del conjunto de datos completo)
  • X_test (10 funciones de entrada, 15% del conjunto de datos completo)
  • Y_train (1 etiqueta, 70% del conjunto de datos completo)
  • Y_val (1 etiqueta, 15% del conjunto de datos completo)
  • Y_test (1 etiqueta, 15% del conjunto de datos completo)

Si desea ver cómo son las formas de las matrices para cada una de ellas (es decir, qué dimensiones son), simplemente ejecute

print (X_train.shape, X_val.shape, X_test.shape, Y_train.shape, Y_val.shape, Y_test.shape)

Así es como debería verse su computadora portátil Jupyter:

Como puede ver, el conjunto de entrenamiento tiene 1022 puntos de datos, mientras que el conjunto de validación y prueba tiene 219 puntos de datos cada uno. Las variables X tienen 10 características de entrada, mientras que las variables Y solo tienen una característica para predecir.

¡Y ahora, nuestros datos finalmente están listos! ¡Uf!

Resumen: al procesar los datos, hemos:

  • Lea el archivo CSV (valores separados por comas) y conviértalos en matrices.
  • Divida nuestro conjunto de datos en las características de entrada y la etiqueta.
  • Escale los datos para que las características de entrada tengan órdenes de magnitud similares.
  • Divida nuestro conjunto de datos en el conjunto de entrenamiento, el conjunto de validación y el conjunto de prueba.

Construyendo y entrenando nuestra primera red neuronal

En Intuitive Deep Learning Part 1a, dijimos que Machine Learning consta de dos pasos. El primer paso es especificar una plantilla (una arquitectura) y el segundo paso es encontrar los mejores números de los datos para completar esa plantilla. Nuestro código de aquí en adelante también seguirá estos dos pasos.

Primer paso: configurar la arquitectura

Lo primero que tenemos que hacer es configurar la arquitectura. Primero pensemos en qué tipo de arquitectura de red neuronal queremos. Supongamos que queremos esta red neuronal:

Arquitectura de red neuronal que usaremos para nuestro problema

En palabras, queremos tener estas capas:

  • Capa oculta 1:32 neuronas, activación de ReLU
  • Capa oculta 2: 32 neuronas, activación de ReLU
  • Capa de salida: 1 neurona, activación sigmoidea

Ahora, necesitamos describir esta arquitectura a Keras. Usaremos el modelo secuencial, lo que significa que simplemente necesitamos describir las capas de arriba en secuencia.

Primero, importemos el código necesario de Keras:

de keras.models import Sequential
de keras.layers import Dense

Luego, especificamos que en nuestro modelo secuencial de Keras así:

modelo = secuencial ([
    Denso (32, activación = 'relu', input_shape = (10,)),
    Denso (32, activación = 'relu'),
    Denso (1, activación = 'sigmoide'),
])

¡Y así, el fragmento de código anterior ha definido nuestra arquitectura! El código anterior se puede interpretar así:

modelo = secuencial ([...])

Esto dice que almacenaremos nuestro modelo en la variable "modelo", y lo describiremos secuencialmente (capa por capa) entre corchetes.

Denso (32, activación = 'relu', input_shape = (10,)),

Tenemos nuestra primera capa como una capa densa con 32 neuronas, activación de ReLU y la forma de entrada es 10 ya que tenemos 10 características de entrada. Tenga en cuenta que "Denso" se refiere a una capa totalmente conectada, que es lo que usaremos.

Denso (32, activación = 'relu'),

Nuestra segunda capa también es una capa densa con 32 neuronas, activación ReLU. Tenga en cuenta que no tenemos que describir la forma de entrada ya que Keras puede inferir de la salida de nuestra primera capa.

Denso (1, activación = 'sigmoide'),

Nuestra tercera capa es una capa densa con 1 neurona, activación sigmoidea.

¡Y así, hemos escrito nuestra arquitectura modelo (plantilla) en código!

Segundo paso: completar los mejores números

Ahora que tenemos nuestra arquitectura especificada, necesitamos encontrar los mejores números para ella. Antes de comenzar nuestro entrenamiento, tenemos que configurar el modelo por

  • Decirle qué algoritmo desea usar para hacer la optimización
  • Diciéndole qué función de pérdida usar
  • Decirle qué otras métricas desea rastrear aparte de la función de pérdida

Configurar el modelo con estas configuraciones requiere que llamemos a la función model.compile, de esta manera:

model.compile (optimizador = 'sgd',
              pérdida = 'binary_crossentropy',
              métricas = ['precisión'])

Ponemos la siguiente configuración dentro de los corchetes después de model.compile:

optimizador = 'sgd'

"Sgd" se refiere al descenso de gradiente estocástico (aquí, se refiere al descenso de gradiente de mini lotes), que hemos visto en Intuitivo Deep Learning Parte 1b.

pérdida = 'binary_crossentropy'

La función de pérdida para las salidas que toman los valores 1 o 0 se llama entropía cruzada binaria.

métricas = ['precisión']

Por último, queremos realizar un seguimiento de la precisión además de la función de pérdida. Ahora, una vez que ejecutamos esa celda, ¡estamos listos para entrenar!

La capacitación sobre los datos es bastante sencilla y requiere que escribamos una línea de código:

hist = model.fit (X_train, Y_train,
          batch_size = 32, epochs = 100,
          validation_data = (X_val, Y_val))

La función se llama "ajuste" ya que estamos ajustando los parámetros a los datos. Tenemos que especificar en qué datos estamos entrenando, que es X_train e Y_train. Luego, especificamos el tamaño de nuestro mini lote y cuánto tiempo queremos entrenarlo (épocas). Por último, especificamos cuáles son nuestros datos de validación para que el modelo nos diga cómo lo estamos haciendo en los datos de validación en cada punto. Esta función generará un historial, que guardaremos bajo la variable hist. Usaremos esta variable un poco más tarde cuando lleguemos a la visualización.

¡Ahora, ejecuta la celda y mira cómo se entrena! Su cuaderno Jupyter debería verse así:

¡Ahora puedes ver que el modelo está entrenando! Al observar los números, debería poder ver cómo disminuye la pérdida y aumenta la precisión con el tiempo. En este punto, puede experimentar con los hiperparámetros y la arquitectura de red neuronal. Vuelva a ejecutar las celdas para ver cómo ha cambiado su entrenamiento cuando modificó los hiperparámetros.

Una vez que esté satisfecho con su modelo final, podemos evaluarlo en el conjunto de prueba. Para encontrar la precisión en nuestro conjunto de pruebas, ejecutamos este fragmento de código:

model.evaluate (X_test, Y_test) [1]

La razón por la que tenemos el índice 1 después de la función model.evaluate es porque la función devuelve la pérdida como el primer elemento y la precisión como el segundo elemento. Para obtener solo la precisión, simplemente acceda al segundo elemento (que está indexado por 1, ya que el primer elemento comienza su indexación desde 0).

Debido a la aleatoriedad en la forma en que hemos dividido el conjunto de datos, así como a la inicialización de los pesos, los números y el gráfico diferirán ligeramente cada vez que ejecutamos nuestro cuaderno. Sin embargo, debe obtener una precisión de prueba entre 80% y 95% si ha seguido la arquitectura que especifiqué anteriormente.

Evaluando en el set de prueba

¡Y ahí lo tienes, has codificado tu primera red neuronal y la has entrenado! ¡Felicidades!

Resumen: la codificación de nuestra primera red neuronal requirió solo unas pocas líneas de código:

  • Especificamos la arquitectura con el modelo secuencial de Keras.
  • Especificamos algunas de nuestras configuraciones (optimizador, función de pérdida, métricas para rastrear) con model.compile
  • Entrenamos nuestro modelo (encontramos los mejores parámetros para nuestra arquitectura) con los datos de entrenamiento con model.fit
  • Evaluamos nuestro modelo en el conjunto de prueba con model.evaluate

Visualización de pérdida y precisión

En Intuitive Deep Learning Part 1b, hablamos sobre el sobreajuste y algunas técnicas de regularización. ¿Cómo sabemos si nuestro modelo está actualmente sobreajustado?

Lo que podríamos querer hacer es graficar la pérdida de entrenamiento y la pérdida de val sobre el número de épocas pasadas. Para mostrar algunos gráficos agradables, utilizaremos el paquete matplotlib. Como de costumbre, tenemos que importar el código que deseamos usar:

importar matplotlib.pyplot como plt

Luego, queremos visualizar la pérdida de entrenamiento y la pérdida de validación. Para hacerlo, ejecute este fragmento de código:

plt.plot (hist.history ['pérdida'])
plt.plot (hist.history ['val_loss'])
plt.title ('Pérdida de modelo')
plt.ylabel ('Pérdida')
plt.xlabel ('Época')
plt.legend (['Tren', 'Val'], loc = 'arriba a la derecha')
plt.show ()

Explicaremos cada línea del fragmento de código anterior. Las dos primeras líneas dicen que queremos graficar la pérdida y val_loss. La tercera línea especifica el título de este gráfico, "Pérdida de modelo". La cuarta y quinta línea nos dice cómo se deben etiquetar los ejes y y x respectivamente. La sexta línea incluye una leyenda para nuestro gráfico, y la ubicación de la leyenda estará en la esquina superior derecha. Y la séptima línea le dice al cuaderno Jupyter que muestre el gráfico.

Su cuaderno Jupyter debería verse así:

Un gráfico de pérdida de modelo que debería ver en su cuaderno Jupyter

Podemos hacer lo mismo para trazar nuestra precisión de entrenamiento y precisión de validación con el siguiente código:

plt.plot (hist.history ['acc'])
plt.plot (hist.history ['val_acc'])
plt.title ('Precisión del modelo')
plt.ylabel ('Precisión')
plt.xlabel ('Época')
plt.legend (['Tren', 'Val'], loc = 'abajo a la derecha')
plt.show ()

Debería obtener un gráfico que se parezca un poco a esto:

Trazado de precisión del modelo para conjunto de entrenamiento y validación

Dado que las mejoras en nuestro modelo para el conjunto de entrenamiento se parecen a las mejoras en el conjunto de validación, no parece que el sobreajuste sea un gran problema en nuestro modelo.

Resumen: Usamos matplotlib para visualizar la pérdida y precisión de entrenamiento y validación a lo largo del tiempo para ver si hay un sobreajuste en nuestro modelo.

Agregar regularización a nuestra red neuronal

En aras de introducir la regularización en nuestra red neuronal, formulemos con una red neuronal que se sobreajustará en nuestro conjunto de entrenamiento. Llamaremos a este Modelo 2.

model_2 = Secuencial ([
    Denso (1000, activación = 'relu', input_shape = (10,)),
    Denso (1000, activación = 'relu'),
    Denso (1000, activación = 'relu'),
    Denso (1000, activación = 'relu'),
    Denso (1, activación = 'sigmoide'),
])
model_2.compile (optimizador = 'adam',
              pérdida = 'binary_crossentropy',
              métricas = ['precisión'])
hist_2 = model_2.fit (X_train, Y_train,
          batch_size = 32, epochs = 100,
          validation_data = (X_val, Y_val))

Aquí, hemos creado un modelo mucho más grande y hemos usado el optimizador Adam. Adam es uno de los optimizadores más comunes que utilizamos, que agrega algunos ajustes al descenso de gradiente estocástico para que alcance la función de pérdida más baja más rápido. Si ejecutamos este código y trazamos los gráficos de pérdida para hist_2 usando el código a continuación (tenga en cuenta que el código es el mismo, excepto que usamos "hist_2" en lugar de "hist"):

plt.plot (hist_2.history ['pérdida'])
plt.plot (hist_2.history ['val_loss'])
plt.title ('Pérdida de modelo')
plt.ylabel ('Pérdida')
plt.xlabel ('Época')
plt.legend (['Tren', 'Val'], loc = 'arriba a la derecha')
plt.show ()

Tenemos una trama como esta:

Curvas de pérdida para el modelo sobre-ajustado

Esta es una clara señal de sobreajuste. La pérdida de entrenamiento está disminuyendo, pero la pérdida de validación está muy por encima de la pérdida de entrenamiento y está aumentando (más allá del punto de inflexión de la época 20). Si trazamos la precisión usando el siguiente código:

plt.plot (hist_2.history ['acc'])
plt.plot (hist_2.history ['val_acc'])
plt.title ('Precisión del modelo')
plt.ylabel ('Precisión')
plt.xlabel ('Época')
plt.legend (['Tren', 'Val'], loc = 'abajo a la derecha')
plt.show ()

Podemos ver una divergencia más clara entre el tren y la precisión de validación también:

Precisión de entrenamiento y validación para nuestro modelo de sobreajuste

Ahora, probemos algunas de nuestras estrategias para reducir el sobreajuste (además de cambiar nuestra arquitectura de nuevo a nuestro primer modelo). Recuerde de la Parte 1b de aprendizaje profundo intuitivo que introdujimos tres estrategias para reducir el ajuste excesivo.

De los tres, incorporaremos aquí la regularización y el abandono de L2. La razón por la que no agregamos paradas tempranas aquí es porque después de haber usado las dos primeras estrategias, la pérdida de validación no toma la forma de U que vemos arriba y, por lo tanto, la parada temprana no será tan efectiva.

Primero, importemos el código que necesitamos para la regularización y abandono de L2:

desde keras.layers import Dropout
de keras regularizadores de importación

Luego especificamos nuestro tercer modelo así:

model_3 = Secuencial ([
    Denso (1000, activación = 'relu', kernel_regularizer = regularizers.l2 (0.01), input_shape = (10,)),
    Abandono (0.3),
    Denso (1000, activación = 'relu', kernel_regularizer = regularizers.l2 (0.01)),
    Abandono (0.3),
    Denso (1000, activación = 'relu', kernel_regularizer = regularizers.l2 (0.01)),
    Abandono (0.3),
    Denso (1000, activación = 'relu', kernel_regularizer = regularizers.l2 (0.01)),
    Abandono (0.3),
    Denso (1, activación = 'sigmoide', kernel_regularizer = regularizers.l2 (0.01)),
])

¿Puedes ver las diferencias entre el Modelo 3 y el Modelo 2? Hay dos diferencias principales:

Diferencia 1: para agregar la regularización L2, tenga en cuenta que hemos agregado un poco de código adicional en cada una de nuestras capas densas de esta manera:

kernel_regularizer = regularizers.l2 (0.01)

Esto le dice a Keras que incluya los valores al cuadrado de esos parámetros en nuestra función de pérdida general, y los pondere en 0.01 en la función de pérdida.

Diferencia 2: para agregar Dropout, agregamos una nueva capa como esta:

Abandono (0.3),

Esto significa que las neuronas en la capa anterior tienen una probabilidad de 0.3 de abandono durante el entrenamiento. Compílelo y ejecútelo con los mismos parámetros que nuestro Modelo 2 (el sobreajustado):

model_3.compile (optimizador = 'adam',
              pérdida = 'binary_crossentropy',
              métricas = ['precisión'])
hist_3 = model_3.fit (X_train, Y_train,
          batch_size = 32, epochs = 100,
          validation_data = (X_val, Y_val))

Y ahora, tracemos los gráficos de pérdida y precisión. Notará que la pérdida es mucho mayor al comienzo, y eso se debe a que hemos cambiado nuestra función de pérdida. Para trazar de modo que la ventana se amplíe entre 0 y 1.2 para la pérdida, agregamos una línea de código adicional (plt.ylim) al trazar:

plt.plot (hist_3.history ['pérdida'])
plt.plot (hist_3.history ['val_loss'])
plt.title ('Pérdida de modelo')
plt.ylabel ('Pérdida')
plt.xlabel ('Época')
plt.legend (['Tren', 'Val'], loc = 'arriba a la derecha')
plt.ylim (arriba = 1.2, abajo = 0)
plt.show ()

Obtendremos un gráfico de pérdidas similar a este:

Puede ver que la pérdida de validación coincide mucho más con nuestra pérdida de entrenamiento. Tracemos la precisión con un fragmento de código similar:

plt.plot (hist_3.history ['acc'])
plt.plot (hist_3.history ['val_acc'])
plt.title ('Precisión del modelo')
plt.ylabel ('Precisión')
plt.xlabel ('Época')
plt.legend (['Tren', 'Val'], loc = 'abajo a la derecha')
plt.show ()

Y obtendremos una trama como esta:

En comparación con nuestro modelo en el Modelo 2, hemos reducido sustancialmente el sobreajuste. Y así es como aplicamos nuestras técnicas de regularización para reducir el sobreajuste al conjunto de entrenamiento.

Resumen: para lidiar con el sobreajuste, podemos codificar las siguientes estrategias en nuestro modelo, cada una con aproximadamente una línea de código:

  • Regularización L2
  • Abandonar

Si visualizamos la pérdida y precisión del entrenamiento / validación, ¡podemos ver que estas adiciones han ayudado a lidiar con el sobreajuste!

Resumen consolidado:

En esta publicación, hemos escrito el código de Python para:

  • Explore y procese los datos
  • Construye y entrena nuestra red neuronal
  • Visualizar pérdida y precisión
  • Agregar regularización a nuestra red neuronal

¡Hemos pasado por muchas cosas, pero no hemos escrito demasiadas líneas de código! Construir y entrenar nuestra red neuronal solo ha tomado alrededor de 4 a 5 líneas de código, y experimentar con diferentes arquitecturas de modelos es solo una simple cuestión de intercambiar en diferentes capas o cambiar diferentes hiperparámetros. Keras ha hecho que sea mucho más fácil construir nuestras redes neuronales, y continuaremos usándolo para aplicaciones más avanzadas en visión por computadora y procesamiento de lenguaje natural.

Qué sigue: en nuestro próximo Coding Companion Part 2, exploraremos cómo codificar nuestras propias Redes neuronales convolucionales (CNN) para hacer el reconocimiento de imágenes.

Asegúrese de obtener primero una comprensión intuitiva de las CNN aquí: Aprendizaje profundo intuitivo Parte 2: CNN para visión artificial

Sobre el Autor:

Hola, soy Joseph! Recientemente me gradué de la Universidad de Stanford, donde trabajé con Andrew Ng en el Grupo de aprendizaje automático de Stanford. Quiero hacer que los conceptos de aprendizaje profundo sean lo más intuitivos y fáciles de entender para todos, lo que ha motivado mi publicación: aprendizaje profundo intuitivo.