PyTorch en Amazon SageMaker: Crear función basada en red neuronal

0

La optimización es el proceso de encontrar el mínimo (o máximo) de una función que depende de algunas entradas, llamadas variables de diseño. El cliente X tiene el siguiente problema: están a punto de lanzar un nuevo modelo de automóvil diseñado para una máxima eficiencia de combustible. En realidad, miles de parámetros que representan parámetros de ajuste relacionados con el motor, la transmisión, la suspensión, etc. Las combinaciones dan como resultado valores variables de eficiencia de combustible.

Sin embargo, para esta publicación, suponga que quieren medir esta eficiencia ya que los galones de combustible se queman por hora cuando viajan a una velocidad particular, todos los demás parámetros son constantes. Por lo tanto, la “función” a minimizar es “galones de combustible quemados por hora” y la variable de diseño es “velocidad”. Este problema de optimización unidimensional hace la pregunta: “¿A qué velocidad debe conducirse el automóvil para quemar el mínimo?” cantidad de combustible por hora “, que es una versión muy simplificada de los miles de parámetros reales a considerar.

Suponga que la función objetivo (f) se parece a la siguiente función sintética:

f (x) = x Insin (x) + x⋅cos (2x)

Ignorando las unidades en los ejes xey, su tarea es encontrar el mínimo de esta función, indicado por la flecha azul. Incluso cuando se trata de una sola dimensión, no es práctico correr el automóvil sobre cada valor de velocidad (la velocidad es un número real).

Para esta publicación, tiene un presupuesto de 30 experimentos, cada “experimento” consiste en correr el automóvil en una plataforma de prueba a esa velocidad, midiendo y recolectando el valor promedio de combustible quemado por hora. Esto le da 30 valores de combustible quemado, correspondientes a 30 valores de velocidades, y nada más. Tampoco hay garantía de que se haya realizado un experimento al valor de la velocidad indicada por el mínimo (flecha azul en la figura).

Cada experimento puede tardar horas en configurarse. Debido a que no es práctico hacer más de un cierto número de tales experimentos, este tipo de función se llama una costosa función de caja negra. Es costoso porque la función requiere tiempo para devolver un valor, y el recuadro negro ya que los experimentos realizados no pueden escribirse como expresiones matemáticas.

Todo el campo de la investigación de optimización está dirigido a crear algoritmos para resolver este tipo de problemas. En esta publicación, utiliza una red neuronal para aproximar la función (f) anterior. ¡Esta aproximación entrenada de la función, también conocida como “modelo sustituto”, puede usarse en lugar de experimentos reales! Si el modelo entrenado es una buena aproximación de la función real, el modelo se puede usar para predecir el combustible quemado (salida) para cualquier valor de velocidad (entrada).

Enfoque técnico

Para obtener una muestra del cuaderno Jupyter que recorre todos estos pasos, consulte Construir un Optimizador global neuronal profundo .

Dada la función (f), mida el valor de la salida dados los valores de varias entradas. Se crea una red simple de cuatro capas, basada en las recomendaciones en Optimización bayesiana escalable usando redes neuronales profundas :

  1. Capa de entrada (activación de tanh)
  2. Capa 1 oculta (activación de tanh) [19659013] Capa 2 oculta (activación de tanh)
  3. Capa de salida (activación de ReLU)

En PyTorch, esto se puede escribir de la siguiente manera:

 def __init __ (self, D_in, H, D, D_out):
    "" "
    En el constructor, instancia dos módulos nn.Linear y asígnelos como
    variables miembro
    "" "
    super (Net, self) .__ init __ ()
    self.inputlayer = nn.Linear (D_in, H)
    self.middle = nn.Linear (H, H)
    self.lasthiddenlayer = nn. Lineal (H, D)
    self.outputlayer = nn.Linear (D, D_out) 

Donde D_in, H, D y D_out se utilizan para definir los tamaños de matriz de parámetros dentro de la función.

También se requiere que especifique la función de activación para cada neurona y cómo se transforman las entradas en el pase directo:

 def adelante (self, x):
    "" "
    En la función de reenvío, acepte una variable de datos de entrada y regrese
    Una variable de datos de salida. Utilice módulos definidos en el constructor, como
    así como operadores arbitrarios en variables.
    "" "
    y_pred = self.outputlayer (self.PHI (x))
    volver y_pred
    
def PHI (auto, x):
    h_relu = self.inputlayer (x) .tanh ()
    para i en rango (2):
        h_relu = self.middle (h_relu) .tanh ()
    phi = self.lasthiddenlayer (h_relu)
    return phi 

En la función de tren, use el error cuadrático medio como la función de pérdida y use el optimizador Adam:

 self.network = Net (características, self.H, self.D, 1) # aquí suponemos que D_out = 1
loss_fn = torch.nn.MSELoss (size_average = True)
optimizador = torch.optim.Adam (self.network.parameters (), lr = self.init_learning_rate)

Para recopilar datos de los experimentos, muestree la función f (x) = x⋅sin (x) + x⋅cos (2x) en puntos aleatorios. En la figura siguiente, la línea punteada negra representa todos los valores de f (x) en ese rango de x (aquí, 0 a 10), y los puntos rojos representan los 30 puntos muestreados.

Para reiterar, el objetivo del La red debe utilizar los datos de entrenamiento (valores de los ejes x e y correspondientes a los puntos de datos muestreados) para aprender a aproximar la función. Siempre que la red neuronal haya aprendido una buena aproximación de la función original f (x), puede usar el modelo entrenado para predecir los valores de las salidas, entradas dadas, sin ejecutar un experimento costoso o que requiera mucho tiempo.

Si está interesado en los detalles más técnicos, consulte Optimización bayesiana escalable mediante redes neuronales profundas . En resumen, se agrega un regresor lineal bayesiano a la última capa oculta de una red neuronal profunda. Esto da como resultado una regresión de base adaptativa, una técnica estadística bien establecida que se escala linealmente en el número de observaciones. Estas “funciones básicas” se parametrizan utilizando los pesos y sesgos de la red neuronal profunda. Finalmente, la media y la varianza de la predicción se pueden calcular utilizando las fórmulas (4) y (5) en el documento de optimización bayesiana escalable. Entonces, no solo está obteniendo una aproximación de funciones, sino también la incertidumbre asociada con los puntos predichos.

Dado el pequeño tamaño del vector de entrada, entrena el modelo en una instancia de notebook con el núcleo conda36_pytorch. Le recomiendo que recurra a la capacitación distribuida utilizando Amazon SageMaker en lugar de la capacitación local cuando corresponda. El siguiente comando inicia el proceso de entrenamiento:

 deepgaussian.train (DOE, yvalues) 

En PyTorch, el ciclo de entrenamiento se implementa de la siguiente manera:

 para t en rango (self.num_epochs):
    y_pred = self.network (self.X)
    pérdida = pérdida_fn (y_pred.view (-1), self.Y.view (-1))
    optimizer.zero_grad ()
    pérdida.atrás ()
    optimizer.step () 

Obtenga el siguiente resultado que indica que la red ha sido entrenada:

 La ​​optimización finalizó con éxito.
         Valor actual de la función: 6.652170
         Iteraciones: 49
         Evaluaciones de funciones: 99 

Finalmente, graficar el modelo sustituto usando un conjunto de valores de prueba (xtest), como sigue:

 media, var = deepgaussian.predict (x_test)
plt.figure (figsize = (20,10))
plt.rcParams.update ({'font.size': 22})
plt.plot (DOE, yvalues, "ro", label = 'Puntos de muestra', markersize = 10)
plt.plot (xtest [:,0]fvals, "k--", label = 'Función real')
plt.plot (xtest [:,0]mean, "blue", label = 'Función sustituta')
plt.fill_between (xtest [:, 0]mean + np.sqrt (var), mean - np.sqrt (var), color = "orange", alpha = 0.4, label = '+ / - Variance')
plt.grid ()
plt.legend ()
plt.show () 

Obtiene la siguiente imagen:

Como puede ver, la red ha aprendido la forma de la función f (x) con precisión, y también asocia cierta incertidumbre con cada señalar que se usa para la predicción. Aquí, las líneas azules son medios de predicción y la banda naranja es la incertidumbre asociada con cada una de las predicciones.

Conclusión

En este punto, el modelo puede usarse para predecir cualquier número de valores de salida experimentales dentro de un intervalo de confianza , sin realizar realmente el experimento. Lo que es más útil es usar un paquete de optimización para encontrar el valor de entrada óptimo que corresponde al valor mínimo de f (x). Para comenzar, vea los paquetes scipy.optimize o inspyred.

Por último, este es un ejemplo de inicio que se ejecuta localmente en una instancia de notebook. Comience ahora lanzando la consola Amazon SageMaker y explorando la capacitación distribuida en Amazon Sagemaker . Para trabajos de optimización a gran escala, considere realizar una capacitación distribuida en Amazon SageMaker enviando el script PyTorch al Estimador de Amazon SageMaker Pytorch .

 

Deja un comentario

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