Optimización bayesiana con PyTorch y Ax

En un post pasado presentamos la optimización Bayesiana y las dos nuevas herramientas abiertas de Facebook, Ax y BoTorch. Ax es una herramienta de alto nivel para gestionar experimentos adaptativos y BoTorch una librería de optimización bayesiana.

En este post vamos a ver un ejemplo de uso de Ax para gestionar un problema básico de optimización bayesana.

Un proceso de optimización bayesiana tendría los siguientes pasos (definidos a partir de este excelente tutorial):

  • Definimos un proceso gaussiano previo (prior) para la función objetivo f.
  • Observamos f en n0 puntos iniciales y fijamos n= n0.
  • Cuando n ≤ N:
    • Se actualiza la distribución de probabilidad posterior de f usando los datos disponibles.
    • Se selecciona xn como una maximizador de la función de adquisición sobre x, donde la función de adquisición se calcula usando la distribución de probabilidad actual.
    • Se evalúa yn=f(xn).
    • Se incrementa n.
  • Se devuelve el punto evaluado con una mayor f(x) o el punto con la mayor media posterior.

Para implementar un modelo de optimización bayesiana en PyTorch, el tipo de librería que usemos va a depender del grado de control que queramos tener sobre las diferentes fases del ciclo.

Si queremos tener un control total y gestionar nosotros el ciclo hay que utilizar directamente BoTorch. Sin embargo, si queremos centrarnos en las partes principales del modelo y no gestionar el ciclo es mejor utilizar Ax.

Ax nos ofrece tres APIs (Loop, Service, and Developer) de experimentación secuencial que se diferencian en el nivel de customización. Loop es la más sencilla de usar y Developer la más customizable.

A continuación vamos a ver un ejemplo en Colab usando la API  Loop y el método optimize, que realiza todos los pasos de la optimización bayesiana y devuelve los parámetros optimizados. Cuando llamamos a optimize tenemos que especificar, entre otros:

  • Los parámetros o conjunto factible del modelo y su rango de variación.
  • La función de evaluación o función objetivo a utilizar, que tendremos que definir a parte o en la propia llamada. Hemos definido la función de Rosenbrock, mínimo en (1, 1), y una función convexa con mínimo en (0.4, 0.7).
  • Si es un problema de minimización o maximización.
  • El nombre del objetivo y del experimento.
  • El número de iteraciones del ciclo N.

A continuación vemos el código utilizado en el ejemplo:

from ax import optimize

def rosenbrock_function(parameterization):
  x=parameterization.get(f"x{1}")
  y=parameterization.get(f"x{2}")
  z = (1-x)**2 + 100*(y-x**2)**2
  return z

def convex_function(parameterization):
  x=parameterization.get(f"x{1}")
  y=parameterization.get(f"x{2}")
  z = (x-0.4)**2 + (y-0.7)**2
  return z

best_parameters, best_values, experiment, model = optimize(
  parameters=[
   {
   "name": "x1",
   "type": "range",
   "bounds": [-3.0, 3.0],
   },
   {
   "name": "x2",
   "type": "range",
   "bounds": [-3.0, 3.0],
   },
  ],
  experiment_name="test",
  objective_name="Rosenbrock",
  evaluation_function=rosenbrock_function,
  minimize=True,
  total_trials=30,
)

Una vez ejecutado el modelo usando las dos funciones de evaluación, nos devuelve los mejores parámetros encontrados.

Optimización bayesiana con Ax

Como se puede ver y es lógico, con la función de Rosenbrock el modelo tarda más en coverger al mínimo (1, 1) que con una función convexa típica.

Hemos visto en este ejemplo como las herramientas Ax y BoTorch de Facebook facilitan en gran medida todo el proceso de despliegue y desarrollo de la optimización bayesiana.

Deja un comentario

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

Orgullosamente ofrecido por WordPress | Tema: Baskerville 2 por Anders Noren.

Subir ↑

A %d blogueros les gusta esto: