¿Cómo transformar entradas y extraer salidas útiles en una red neuronal?

9

Así que he estado tratando de entender las redes neuronales desde que encontré el blog de Adam Geitgey sobre aprendizaje automático. He leído todo lo que puedo sobre el tema (que puedo comprender) y creo que entiendo todos los conceptos generales y algunos de los trabajos (a pesar de ser muy débil en matemáticas), neuronas, sinapsis, pesos, funciones de costos, propagación hacia atrás Sin embargo, no he podido encontrar la manera de traducir problemas del mundo real en una solución de red neuronal.

Caso en cuestión, Adam Geitgey da como ejemplo de uso, un sistema de predicción del precio de la vivienda donde se le da un conjunto de datos que contiene No. de dormitorios , Sq. pies , Barrio y el precio de venta que puede entrenar una red neuronal para ser capaz de predecir el precio de una casa. Sin embargo, no llega a implementar realmente una posible solución en código. Lo más cerca que se pone, a modo de ejemplo, es una función básica que demuestra cómo implementar los pesos:

def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
  price = 0

  # a little pinch of this
  price += num_of_bedrooms * 1.0

  # and a big pinch of that
  price += sqft * 1.0

  # maybe a handful of this
  price += neighborhood * 1.0

  # and finally, just a little extra salt for good measure
  price += 1.0

  return price 

Otros recursos parecen centrarse más en las matemáticas y el único ejemplo de código básico que pude encontrar que entiendo (es decir, que no se trata de una base de código de clasificación de imágenes de canto y baile) es una implementación que entrena una red neuronal para ser un XOR puerta que se ocupa solo en 1's y 0's.

Entonces, hay un vacío en mi conocimiento que parece que no puedo cerrar. Si volvemos al problema de predicción del precio de la vivienda , ¿cómo hace uno para que los datos sean adecuados para alimentar una red neuronal? Por ejemplo:

  • No de habitaciones: 3
  • Sq. pies: 2000
  • Barrio: Normaltown
  • Precio de venta: $ 250,000

¿Puedes alimentar 3 y 2000 directamente en la red neuronal porque son números? ¿O necesitas transformarlos en algo más? Del mismo modo, ¿qué pasa con el valor de Normaltown , que es una cadena, cómo se traduce a un valor que una red neuronal puede entender? ¿Puedes elegir un número, como un índice, siempre que sea coherente en todos los datos?

La mayoría de los ejemplos de redes neuronales que he visto pasar entre las capas son 0 a 1 o -1 a 1. Entonces, al final del procesamiento, ¿cómo transforma el valor de salida en algo usable como $ 185,000 ?

Sé que el ejemplo de predicción del precio de la vivienda probablemente no sea un problema particularmente útil dado que se ha simplificado enormemente en solo tres puntos de datos. Pero siento que si pudiera superar este obstáculo y escribir una aplicación extremadamente básica que entrene usando pseudo datos de la vida real y escupe una pseudo respuesta de la vida real, entonces habría roto la parte posterior y podría patear y profundizar en el aprendizaje automático.

David
fuente

Respuestas:

10

Esta es una buena pregunta que luché conmigo mismo cuando intenté codificar un ANN.

A continuación se muestra una buena solución de propósito general, y es la que implementé en mi código para tratar de predecir datos numéricos con buen comportamiento. Si sus datos no se comportan bien (es decir, cargados de valores atípicos), es posible que deba realizar más trabajo normalizando las entradas y salidas. Algunos de los métodos más avanzados se describen aquí .

Nota: Asumiré que está utilizando f (x) = tanh (x) como su función de activación. Si no lo está, aún debería poder razonar sobre cómo normalizar sus datos después de leer esto.

Cómo preparar los datos de entrada:

La idea básica es que desea que una variación significativa en cada parámetro de entrada se refleje en una variación significativa en la activación de la neurona a la que se están alimentando esas entradas. Al observar una gráfica de la derivada de la función de activación tanh (x), verá que la región de pendiente significativa se encuentra a una distancia de uno o dos desde el origen. Esto significa que si la entrada a la función de activación es 2000 o 3000 (valores de x para los que la derivada es despreciablemente pequeña), la salida de la activación será casi idéntica ... por lo que el estado de su neurona será independiente de la diferencia entre 2000 y 3000, y su red nunca producirá ningún poder predictivo a partir de valores en ese rango.

Entonces, si desea ingresar los pies cuadrados de la casa en una neurona, debe normalizar los pies cuadrados para que la red pueda distinguir entre 2000 y 3000. Una forma de hacerlo para que todas las variaciones significativas en su los datos son 'notados' por la neurona es para z-score-normalizar las entradas .

  • Reúna todos sus valores de pies cuadrados (de su conjunto de entrenamiento) y calcule la media y la desviación estándar. Almacene la media y la desviación estándar: necesitará esta información para normalizar los nuevos valores de pies cuadrados durante la prueba.

  • Normalice el vector de los valores de metraje cuadrado restando la media y luego dividiendo el resultado por la desviación estándar (todas las operaciones por elementos, por supuesto). Restar la media centra sus datos en el origen, y dividir por la desviación estándar asegura que la mayor parte esté entre -1 y 1, donde la salida de la neurona es más sensible a su entrada. Esto se llama normalización de puntaje z porque cada valor de entrada se reemplaza por su puntaje z .

  • Haga lo anterior para cada variable de entrada.

Ahora, cuando pones cada valor de entrada a través de una neurona, la salida de la neurona es una activación entre -1 y 1 (mira la imagen de tanh (x)). Dado que esto ya se encuentra en el rango 'sensible' de la función de activación, no necesita preocuparse por alterar la salida de las neuronas de la capa de entrada antes de enviarlas a la primera capa oculta. Simplemente proporcione directamente a las neuronas de capa oculta las salidas de la capa anterior --- podrán manejarlas perfectamente.

Cuando llegas a la última capa (la (s) neurona (s) de salida), lo que obtienes nuevamente es otra activación entre -1 y 1. Debes convertir esto nuevamente en un valor para la casa en cuestión , si ese valor se usará como una predicción en un conjunto de prueba o para calcular el error durante el entrenamiento. Independientemente de cómo lo haga, solo tiene que ser coherente y utilizar el mismo procedimiento de desnormalización en el entrenamiento y las pruebas. Una forma de pensarlo es: cuando la (s) neurona (s) de salida devuelven 1, eso significa que la red está devolviendo el valor máximo posible de la vivienda como su predicción. ¿Cuál debería ser el valor más alto que la red puede estimar? El enfoque correcto aquí simplemente depende de su aplicación. Esto es lo que hice:

  • Calcule la media de la variable de salida [la / cada] y almacénela.
  • Calcule la desviación máxima de la variable de salida de la media. Pitón:MaxDev = max([abs(DataPoint-numpy.mean(TrainingData)) for DataPoint in TrainingData])
  • Cuando la red devuelve salida (s) entre -1 y 1, multiplique la salida por MaxDevy agréguela a la media.

Dos comprobaciones rápidas básicas que puede hacer para ver si su esquema de normalización-renormalización es adecuado (estas son condiciones necesarias, pero quizás no suficientes):

  1. Si todos los valores de entrada son promedio (p. Ej., Número promedio de dormitorios, pies cuadrados promedio, etc.), ¿la salida de la red es igual al promedio de la variable de salida (p. Ej., Valor de la casa)? (Debería ser.)
  2. Si todos los valores de entrada son inusualmente altos / bajos, ¿la salida de la red también es inusualmente alta / baja? (Esto solo funciona si todas las entradas están relacionadas positivamente con la salida ... si algunas de ellas están relacionadas inversamente, tendrá que pensar un poco más).

Observe que el esquema presentado aquí satisface estas dos condiciones.

Tenga en cuenta que este esquema permitiría que su red solo prediga los valores de la casa dentro del rango de valores de la casa en su conjunto de datos de entrenamiento. Dependiendo de la aplicación, este comportamiento puede ser deseable o indeseable.

Por ejemplo: es posible que desee que sea imposible para su red predecir valores negativos de la vivienda. Piensa en cómo harías esto. Desnormalizar la salida para que -1 se asigne a 0.

Si no desea establecer un límite en los valores que su red puede predecir, puede ejecutar la salida de la red a través de una función que asigna el rango [-1,1] a todos los números reales ... ¡como arctanh (x)! Mientras lo haga durante el entrenamiento, su red ajustará sus pesos para acomodar esto.

Espero que esto haya sido útil. Avísame si tienes más preguntas. Mi módulo ANN está en Python, por cierto, por lo que podría tener consejos específicos del idioma.

Marko Bakić
fuente
¡Esto fue muy útil! Cada blog / tutorial que encuentro parece evitar (casi deliberadamente) describir este proceso, pero sí, todo tiene sentido. Me llevará un tiempo digerir correctamente, pero volveré si tengo alguna pregunta de seguimiento. ¡Muy agradecido!
David
Entonces un par de preguntas. Si mi Sq. Los datos de entrenamiento de pies fueron {2000, 800, 850, 550, 2000}, entonces mis entradas de puntaje z para {1900, 1500, 600} serían (si he calculado correctamente) {1.0496, 0.4134, -1.0177}. Entonces, uno de esos valores es> 1 y uno es <-1, ¿qué haría con ellos? ¿Ingresarlos en los nodos de la capa de entrada independientemente o redondearlos a 1 y -1? ¿Por qué 1900 y 600 producen esos valores cuando están dentro del rango 550 - 2000? ¿Es esto solo un truco de los datos porque hay un conjunto de datos tan pequeño?
David
0 0unanorterethmimetrounaXyometrotumetro
Recuerde que las entradas no necesitan estar estrictamente entre 1 y -1. Todo lo que necesita para las entradas es que la mayoría de los datos están en ese rango. Un valor mayor o menor que uno significa que el punto está a más de una desviación estándar de la media, por lo que ese punto está más cerca del extremo superior de los datos. Debería ser un poco raro que sus datos salgan de [-1, 1], aún más raro que salgan de [-2, 2] y extremadamente raro que salgan de [-3, 3]. Mire tanh (x) y verá que el rango sensible no es estrictamente entre -1 y 1, sino que va un poco más allá de eso.
Marko Bakić
Con respecto a la desnormalización de salida, esa desnormalización min-max es lo que hice en mi implementación, y su interpretación es correcta, pero no necesariamente tiene que hacer eso. Podría hacerlo de modo que 1 corresponda al doble del valor máximo de la casa, de esa manera su red podría predecir los valores de la casa por encima de lo que lo entrenó.
Marko Bakić