Saltar al contenido

Cómo optimizar manualmente los modelos de redes neuronales

4 de diciembre de 2020

Red neuronal de aprendizaje profundo Los modelos se ajustan a los datos de entrenamiento utilizando el algoritmo de optimización de descenso de gradiente estocástico.

Las actualizaciones de los pesos del modelo se hacen, usando la retropropagación del algoritmo de error. La combinación del algoritmo de optimización y actualización de pesos fue cuidadosamente elegida y es el enfoque más eficiente conocido para ajustar las redes neuronales.

No obstante, es posible utilizar algoritmos de optimización alternativos para ajustar un modelo de red neuronal a un conjunto de datos de entrenamiento. Este puede ser un ejercicio útil para aprender más sobre el funcionamiento de las redes neuronales y la naturaleza central de la optimización en el aprendizaje aplicado de las máquinas. También puede ser necesario para las redes neuronales con arquitecturas de modelos no convencionales y funciones de transferencia no diferenciables.

En este tutorial, descubrirá cómo optimizar manualmente los pesos de los modelos de redes neuronales.

Después de completar este tutorial, lo sabrás:

  • Cómo desarrollar el pase de inferencia hacia adelante para modelos de redes neuronales desde cero.
  • Cómo optimizar los pesos de un modelo de Perceptrón para la clasificación binaria.
  • Cómo optimizar los pesos de un modelo de Perceptrón Multicapa usando escalada estocástica de colinas.

Empecemos.

Cómo optimizar manualmente los modelos de redes neuronales

Cómo optimizar manualmente los modelos de redes neuronales
Foto de la Oficina de Gestión de Tierras, algunos derechos reservados.

Resumen del Tutorial

Este tutorial está dividido en tres partes; son:

  1. Optimizar las redes neuronales
  2. Optimizar un modelo de Perceptrón
  3. Optimizar un perceptor multicapa

Optimizar las redes neuronales

El aprendizaje profundo o las redes neuronales son un tipo flexible de aprendizaje por máquina.

Son modelos compuestos de nodos y capas inspirados en la estructura y función del cerebro. Un modelo de red neuronal funciona propagando un vector de entrada determinado a través de una o más capas para producir una salida numérica que puede ser interpretada para la clasificación o el modelado predictivo de regresión.

Los modelos se entrenan exponiendo repetidamente el modelo a ejemplos de entrada y salida y ajustando los pesos para minimizar el error de la salida del modelo en comparación con la salida esperada. Esto se llama el algoritmo de optimización de descenso de gradiente estocástico. Los pesos del modelo se ajustan usando una regla específica del cálculo que asigna el error proporcionalmente a cada peso de la red. Esto se llama el algoritmo de retropropagación.

El algoritmo de optimización de descenso de gradiente estocástico con actualizaciones de peso realizadas mediante retropropagación es la mejor manera de entrenar modelos de redes neuronales. Sin embargo, no es la única forma de entrenar una red neuronal.

Es posible utilizar cualquier algoritmo de optimización arbitrario para entrenar un modelo de red neuronal.

Es decir, podemos definir una arquitectura de modelo de red neuronal y utilizar un determinado algoritmo de optimización para encontrar un conjunto de pesos para el modelo que resulte en un mínimo de error de predicción o un máximo de precisión de clasificación.

Se espera que el uso de algoritmos de optimización alternativos sea menos eficiente en promedio que el uso de descenso de gradiente estocástico con retropropagación. No obstante, puede ser más eficiente en algunos casos concretos, como las arquitecturas de red no estándar o las funciones de transferencia no diferencial.

También puede ser un ejercicio interesante para demostrar la naturaleza central de la optimización en el entrenamiento de los algoritmos de aprendizaje de la máquina, y específicamente de las redes neuronales.

A continuación, exploremos cómo entrenar una simple red neural de un solo nodo llamada modelo Perceptrón usando escalada estocástica de colinas.

Optimizar un modelo de Perceptrón

El algoritmo de Perceptrón es el tipo más simple de red neural artificial.

Se trata de un modelo de una sola neurona que puede ser utilizado para problemas de clasificación de dos clases y proporciona la base para el desarrollo posterior de redes mucho más grandes.

En esta sección, optimizaremos los pesos de un modelo de red neural de Perceptrón.

Primero, definamos un problema de clasificación binaria sintética que podamos usar como el foco de la optimización del modelo.

Podemos usar la función make_classification() para definir un problema de clasificación binaria con 1.000 filas y cinco variables de entrada.

En el ejemplo que figura a continuación se crea el conjunto de datos y se resume la forma de los mismos.

Ejecutando el ejemplo se imprime la forma del conjunto de datos creados, confirmando nuestras expectativas.

A continuación, necesitamos definir un modelo de Perceptrón.

El modelo de Perceptrón tiene un solo nodo que tiene un peso de entrada para cada columna del conjunto de datos.

Cada entrada se multiplica por su correspondiente peso para obtener una suma ponderada y luego se añade un peso de sesgo, como un coeficiente de intercepción en un modelo de regresión. Esta suma ponderada se llama activación. Finalmente, la activación se interpreta y se utiliza para predecir la etiqueta de clase, 1 para una activación positiva y 0 para una activación negativa.

Antes de optimizar los pesos del modelo, debemos desarrollar el modelo y nuestra confianza en cómo funciona.

Comencemos por definir una función para interpretar la activación del modelo.

Esto se llama la función de activación, o la función de transferencia; este último nombre es más tradicional y es mi preferencia.

El transferencia() La función de abajo toma la activación del modelo y devuelve una etiqueta de clase, clase=1 para una activación positiva o cero y clase=0 para una activación negativa. Esto se llama una función de transferencia de pasos.

A continuación, podemos desarrollar una función que calcula la activación del modelo para una determinada fila de datos de entrada del conjunto de datos.

Esta función tomará la fila de datos y los pesos del modelo y calculará la suma ponderada de la entrada con la adición del peso del sesgo. El activar() La función de abajo implementa esto.

Nota: Estamos usando listas Python simples y un estilo de programación imperativo en lugar de arreglos NumPy o compresiones de listas intencionalmente para hacer el código más legible para los principiantes de Python. Siéntanse libres de optimizarlo y publicar su código en los comentarios de abajo.

A continuación, podemos usar el activar() y transferencia() funciona conjuntamente para generar una predicción para una fila de datos dada. El predict_row() La función de abajo implementa esto.

A continuación, podemos llamar al predict_row() para cada fila en un conjunto de datos dado. El predict_dataset() La función de abajo implementa esto.

De nuevo, estamos usando intencionadamente un estilo de codificación simple e imperativo para la legibilidad en lugar de las compresiones de la lista.

Finalmente, podemos usar el modelo para hacer predicciones sobre nuestro conjunto de datos sintéticos para confirmar que todo funciona correctamente.

Podemos generar un conjunto aleatorio de pesos modelo usando la función rand().

Recordemos que necesitamos un peso para cada entrada (cinco entradas en este conjunto de datos) más un peso extra para el peso del sesgo.

Podemos usar estos pesos con el conjunto de datos para hacer predicciones.

Podemos evaluar la exactitud de la clasificación de estas predicciones.

Eso es todo.

Podemos unir todo esto y demostrar nuestro sencillo modelo de Perceptrón para la clasificación. El ejemplo completo se enumera a continuación.

Recomendado:  Las organizaciones de tecnología negra crecen en medio de los llamados a la justicia racial

La ejecución del ejemplo genera una predicción para cada ejemplo en el conjunto de datos de entrenamiento y luego imprime la precisión de la clasificación para las predicciones.

Nota: Sus resultados pueden variar dada la naturaleza estocástica del algoritmo o el procedimiento de evaluación, o las diferencias en la precisión numérica. Considere ejecutar el ejemplo unas cuantas veces y compare el resultado promedio.

Se esperaría una precisión de alrededor del 50 por ciento dado un conjunto de pesos aleatorios y un conjunto de datos con un número igual de ejemplos en cada clase, y eso es aproximadamente lo que vemos en este caso.

Ahora podemos optimizar los pesos del conjunto de datos para lograr una buena precisión en este conjunto de datos.

Primero, tenemos que dividir el conjunto de datos en trenes y conjuntos de pruebas. Es importante retener algunos datos no utilizados en la optimización del modelo para que podamos preparar una estimación razonable del rendimiento del modelo cuando se utilice para hacer predicciones sobre nuevos datos.

Utilizaremos el 67 por ciento de los datos para el entrenamiento y el 33 por ciento restante como un conjunto de pruebas para evaluar el rendimiento del modelo.

A continuación, podemos desarrollar un algoritmo de escalada de colinas estocástico.

El algoritmo de optimización requiere una función objetiva para optimizar. Debe tomar un conjunto de pesos y devolver una puntuación que debe ser minimizada o maximizada correspondiente a un modelo mejor.

En este caso, evaluaremos la exactitud del modelo con un conjunto determinado de pesos y devolveremos la exactitud de la clasificación, que debe ser maximizada.

El objetivo() La siguiente función implementa esto, dado el conjunto de datos y un conjunto de pesos, y devuelve la precisión del modelo

A continuación, podemos definir el algoritmo de escalada de colinas estocástico.

El algoritmo requerirá una solución inicial (por ejemplo, pesos aleatorios) e irá haciendo iterativamente pequeños cambios en la solución y comprobando si da lugar a un modelo de mejor rendimiento. La cantidad de cambios realizados en la solución actual se controla mediante un tamaño_paso hiperparámetro. Este proceso continuará durante un número fijo de iteraciones, también proporcionadas como hiperparámetro.

El escalada de colinas() La función que figura a continuación implementa esto, tomando como argumentos el conjunto de datos, la función objetiva, la solución inicial y los hiperparámetros y devuelve el mejor conjunto de pesos encontrados y el rendimiento estimado.

Podemos entonces llamar a esta función, pasando un conjunto de pesos como solución inicial y el conjunto de datos de entrenamiento como el conjunto de datos para optimizar el modelo contra.

Finalmente, podemos evaluar el mejor modelo en el conjunto de datos de la prueba y reportar el rendimiento.

Enlazando todo esto, el ejemplo completo de optimización de los pesos de un modelo de Perceptrón en el conjunto de datos de optimización binaria sintética se enumera a continuación.

Al ejecutar el ejemplo se informará del número de iteración y la precisión de la clasificación cada vez que se produzca una mejora en el modelo.

Recomendado:  Descenso de gradiente con impulso de Nesterov desde cero

Al final de la búsqueda, se informa del rendimiento del mejor conjunto de pesos en el conjunto de datos de entrenamiento y se calcula e informa del rendimiento del mismo modelo en el conjunto de datos de prueba.

Nota: Sus resultados pueden variar dada la naturaleza estocástica del algoritmo o el procedimiento de evaluación, o las diferencias en la precisión numérica. Considere ejecutar el ejemplo unas cuantas veces y compare el resultado promedio.

En este caso, podemos ver que el algoritmo de optimización encontró un conjunto de pesos que alcanzaba una precisión de alrededor del 88,5 por ciento en el conjunto de datos de entrenamiento y de alrededor del 81,8 por ciento en el conjunto de datos de prueba.

Ahora que estamos familiarizados con la forma de optimizar manualmente los pesos de un modelo de Perceptrón, veamos cómo podemos ampliar el ejemplo para optimizar los pesos de un modelo de Perceptrón Multicapa (MLP).

Optimizar un perceptor multicapa

Un modelo de Perceptrón Multicapa (MLP) es una red neuronal con una o más capas, donde cada capa tiene uno o más nodos.

Es una extensión de un modelo de Perceptrón y es quizás el modelo de red neural (aprendizaje profundo) más utilizado.

En esta sección, nos basaremos en lo que aprendimos en la sección anterior para optimizar los pesos de los modelos MLP con un número arbitrario de capas y nodos por capa.

Primero, desarrollaremos el modelo y lo probaremos con pesos aleatorios, luego usaremos la escalada estocástica para optimizar los pesos del modelo.

Cuando se utilizan los MLP para la clasificación binaria, es común utilizar una función de transferencia sigmoidea (también llamada función logística) en lugar de la función de transferencia escalonada utilizada en el Perceptrón.

Esta función produce un valor real entre 0-1 que representa una distribución de probabilidad binomial, por ejemplo, la probabilidad de que un ejemplo pertenezca a la clase=1. El transferencia() La función de abajo implementa esto.

Podemos usar el mismo activar() de la sección anterior. Aquí, la usaremos para calcular la activación de cada nodo en una capa dada.

El predict_row() debe ser reemplazada por una versión más elaborada.

La función toma una fila de datos y la red y devuelve la salida de la red.

Definiremos nuestra red como una lista de listas. Cada capa será una lista de nodos y cada nodo será una lista o matriz de pesos.

Para calcular la predicción de la red, simplemente enumeramos las capas, luego enumeramos los nodos, y luego calculamos la salida de activación y transferencia para cada nodo. En este caso, utilizaremos la misma función de transferencia para todos los nodos de la red, aunque no tiene por qué ser así.

En las redes con más de una capa, la salida de la capa anterior se utiliza como entrada a cada nodo de la capa siguiente. La salida de la última capa de la red es entonces devuelta.

El predict_row() La función de abajo implementa esto.

Eso es todo.

Finalmente, necesitamos definir una red para usar.

Por ejemplo, podemos definir un MLP con una sola capa oculta con un solo nodo de la siguiente manera:

Esto es prácticamente un Perceptrón, aunque con una función de transferencia de sigmoides. Bastante aburrido.

Definamos un MLP con una capa oculta y una capa de salida. La primera capa oculta tendrá 10 nodos, y cada nodo tomará el patrón de entrada del conjunto de datos (por ejemplo, cinco entradas). La capa de salida tendrá un solo nodo que toma las entradas de las salidas de la primera capa oculta y luego da salida a una predicción.

Podemos usar el modelo para hacer predicciones sobre el conjunto de datos.

Antes de calcular la precisión de la clasificación, debemos redondear las predicciones a las etiquetas de clase 0 y 1.

Enlazando todo esto, el ejemplo completo de evaluación de un MLP con pesos iniciales aleatorios en nuestro conjunto de datos de clasificación binaria sintética se enumera a continuación.

La ejecución del ejemplo genera una predicción para cada ejemplo en el conjunto de datos de entrenamiento, y luego imprime la precisión de la clasificación para las predicciones.

Nota: Sus resultados pueden variar dada la naturaleza estocástica del algoritmo o el procedimiento de evaluación, o las diferencias en la precisión numérica. Considere ejecutar el ejemplo unas cuantas veces y compare el resultado promedio.

Una vez más, esperaríamos una precisión de alrededor del 50 por ciento dado un conjunto de pesos aleatorios y un conjunto de datos con un número igual de ejemplos en cada clase, y eso es aproximadamente lo que vemos en este caso.

A continuación, podemos aplicar el algoritmo de escalada de colinas estocástica al conjunto de datos.

Es muy parecido a aplicar la escalada al modelo Perceptrón, excepto que en este caso, un escalón requiere una modificación de todos los pesos de la red.

Para ello, desarrollaremos una nueva función que crea una copia de la red y muta cada peso en la red mientras hace la copia.

Recomendado:  La agilidad y la resiliencia son vitales para los modelos de negocio digitales primero

El paso() La función de abajo implementa esto.

Modificar todo el peso de la red es agresivo.

Un paso menos agresivo en el espacio de búsqueda podría ser hacer un pequeño cambio en un subconjunto de los pesos del modelo, quizás controlado por un hiperparámetro. Esto se deja como una extensión.

Podemos entonces llamar a esto nuevo paso() de la función de escalada().

A continuación se presenta el ejemplo completo de aplicación de la escalada estocástica de colinas para optimizar los pesos de un modelo MLP para la clasificación binaria.

Al ejecutar el ejemplo se informará del número de iteración y la precisión de la clasificación cada vez que se produzca una mejora en el modelo.

Al final de la búsqueda, se informa del rendimiento del mejor conjunto de pesos en el conjunto de datos de entrenamiento y se calcula e informa del rendimiento del mismo modelo en el conjunto de datos de prueba.

Nota: Sus resultados pueden variar dada la naturaleza estocástica del algoritmo o el procedimiento de evaluación, o las diferencias en la precisión numérica. Considere ejecutar el ejemplo unas cuantas veces y compare el resultado promedio.

En este caso, podemos ver que el algoritmo de optimización encontró un conjunto de pesos que alcanzaba una precisión de alrededor del 87,3 por ciento en el conjunto de datos de entrenamiento y de alrededor del 85,1 por ciento en el conjunto de datos de prueba.

Más lecturas

Esta sección proporciona más recursos sobre el tema si desea profundizar en él.

Tutoriales

APIs

Resumen

En este tutorial, descubriste cómo optimizar manualmente los pesos de los modelos de redes neuronales.

Específicamente, aprendiste:

  • Cómo desarrollar el pase de inferencia hacia adelante para modelos de redes neuronales desde cero.
  • Cómo optimizar los pesos de un modelo de Perceptrón para la clasificación binaria.
  • Cómo optimizar los pesos de un modelo de Perceptrón Multicapa usando escalada estocástica de colinas.

¿Tiene alguna pregunta?
Haga sus preguntas en los comentarios de abajo y haré lo posible por responder.