{ "cells": [ { "cell_type": "markdown", "id": "0", "metadata": {}, "source": [ "# Ray Tune generic black-box optimiser\n", "\n", "[Ray Tune](https://docs.ray.io/en/latest/tune/index.html) is a hyperparameter tuning library primarily developed for machine learning.\n", "However, it is suitable for generic black-box optimisation as well.\n", "For our purpose, it provides an interface for running simulations inside a given *search space* and optimising for a given *loss function* $\\mathcal{L}$ using a given *algorithm*.\n", "It automatically manages checkpointing, logging and, importantly, parallel (or even distributed) computing.\n", "\n", "You can see installation instructions [here](https://docs.ray.io/en/latest/ray-overview/installation.html), but the regular pip install should work for most. Notably, ARM-based macOS support is experimental.\n", "\n", "```console\n", "pip install \"ray[tune,air]\" hyperopt\n", "```\n", "\n", "You can optimise a `mmi1x2` component for a transmission of $|S_{21}|^2 = 0.5$ (50% power) for a given wavelength using MEEP." ] }, { "cell_type": "code", "execution_count": null, "id": "1", "metadata": {}, "outputs": [], "source": [ "from functools import partial\n", "\n", "import gdsfactory as gf\n", "import numpy as np\n", "import ray\n", "import ray.air\n", "import ray.air.session\n", "from gdsfactory.config import PATH\n", "from gdsfactory.generic_tech import get_generic_pdk\n", "from ray import tune\n", "\n", "import gplugins.gmeep as gm\n", "\n", "gf.config.rich_output()\n", "PDK = get_generic_pdk()\n", "PDK.activate()\n", "\n", "tmp = PATH.optimiser\n", "tmp.mkdir(exist_ok=True)" ] }, { "cell_type": "markdown", "id": "2", "metadata": { "lines_to_next_cell": 2 }, "source": [ "## Loss function $\\mathcal{L}$\n", "\n", "The loss function is very important and should be designed to be meaningful for your need.\n", "\n", "The easiest method to optimise for a specific value is to use $L_1$ or $L_2$ (MSE) loss. Different optimisation algorithms might prefer more or less aggressive behaviour close to target, so choose depending on that.\n", "$$\n", "\\begin{align*}\n", " L_1(x) &= |x_\\text{target} - x|, \\\\\n", " L_2(x) &= \\left(x_\\text{target} - x\\right)^2\n", " .\n", "\\end{align*}\n", "$$\n" ] }, { "cell_type": "code", "execution_count": null, "id": "3", "metadata": {}, "outputs": [], "source": [ "def loss_S21_L1(x, target):\n", " r\"\"\"Loss function. Returns :math:`$\\sum_i L_1(x_i)$` and :math:`$x$` as a tuple\"\"\"\n", " return np.abs(target - x), x" ] }, { "cell_type": "markdown", "id": "4", "metadata": {}, "source": [ "Let's select a target of $0.7$ for $S_{21}$" ] }, { "cell_type": "code", "execution_count": null, "id": "5", "metadata": {}, "outputs": [], "source": [ "loss = partial(loss_S21_L1, target=0.5)" ] }, { "cell_type": "markdown", "id": "6", "metadata": {}, "source": [ "## Optimisation settings\n", "\n", "Here we specify the search space, the optimiser and its settings.\n", "\n", "