{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Simple Monotonicity" ] }, { "cell_type": "markdown", "metadata": { "id": "eX2YY8tp5yyk", "tags": [ "hide-cell" ] }, "source": [ "## Prerequisites" ] }, { "cell_type": "markdown", "metadata": { "id": "qEcvoHx-KoFS", "tags": [ "hide-cell" ] }, "source": [ "Add the Congrads package to the current Colab notebook environment and install it." ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 4485, "status": "ok", "timestamp": 1769502168746, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "8KHH-VPLoPbu", "outputId": "a18f74bd-52b9-4387-b1d0-ab608e34441d", "tags": [ "hide-cell" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: congrads==0.3.0 in /usr/local/lib/python3.12/dist-packages (from congrads[examples]==0.3.0) (0.3.0)\n", "Requirement already satisfied: numpy>=1.24.0 in /usr/local/lib/python3.12/dist-packages (from congrads==0.3.0->congrads[examples]==0.3.0) (2.0.2)\n", "Requirement already satisfied: pandas>=1.5.0 in /usr/local/lib/python3.12/dist-packages (from congrads==0.3.0->congrads[examples]==0.3.0) (2.2.2)\n", "Requirement already satisfied: torch>=2.0.0 in /usr/local/lib/python3.12/dist-packages (from congrads==0.3.0->congrads[examples]==0.3.0) (2.9.0+cpu)\n", "Requirement already satisfied: torchvision>=0.15.1 in /usr/local/lib/python3.12/dist-packages (from congrads==0.3.0->congrads[examples]==0.3.0) (0.24.0+cpu)\n", "Requirement already satisfied: tqdm>=4.65.0 in /usr/local/lib/python3.12/dist-packages (from congrads==0.3.0->congrads[examples]==0.3.0) (4.67.1)\n", "Requirement already satisfied: matplotlib>=3.7.0 in /usr/local/lib/python3.12/dist-packages (from congrads[examples]==0.3.0) (3.10.0)\n", "Requirement already satisfied: tensorboard>=2.18.0 in /usr/local/lib/python3.12/dist-packages (from congrads[examples]==0.3.0) (2.19.0)\n", "Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.7.0->congrads[examples]==0.3.0) (1.3.3)\n", "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.7.0->congrads[examples]==0.3.0) (0.12.1)\n", "Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.7.0->congrads[examples]==0.3.0) (4.61.1)\n", "Requirement already satisfied: kiwisolver>=1.3.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.7.0->congrads[examples]==0.3.0) (1.4.9)\n", "Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.7.0->congrads[examples]==0.3.0) (25.0)\n", "Requirement already satisfied: pillow>=8 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.7.0->congrads[examples]==0.3.0) (11.3.0)\n", "Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.7.0->congrads[examples]==0.3.0) (3.3.1)\n", "Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.12/dist-packages (from matplotlib>=3.7.0->congrads[examples]==0.3.0) (2.9.0.post0)\n", "Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.12/dist-packages (from pandas>=1.5.0->congrads==0.3.0->congrads[examples]==0.3.0) (2025.2)\n", "Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.12/dist-packages (from pandas>=1.5.0->congrads==0.3.0->congrads[examples]==0.3.0) (2025.3)\n", "Requirement already satisfied: absl-py>=0.4 in /usr/local/lib/python3.12/dist-packages (from tensorboard>=2.18.0->congrads[examples]==0.3.0) (1.4.0)\n", "Requirement already satisfied: grpcio>=1.48.2 in /usr/local/lib/python3.12/dist-packages (from tensorboard>=2.18.0->congrads[examples]==0.3.0) (1.76.0)\n", "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.12/dist-packages (from tensorboard>=2.18.0->congrads[examples]==0.3.0) (3.10)\n", "Requirement already satisfied: protobuf!=4.24.0,>=3.19.6 in /usr/local/lib/python3.12/dist-packages (from tensorboard>=2.18.0->congrads[examples]==0.3.0) (5.29.5)\n", "Requirement already satisfied: setuptools>=41.0.0 in /usr/local/lib/python3.12/dist-packages (from tensorboard>=2.18.0->congrads[examples]==0.3.0) (75.2.0)\n", "Requirement already satisfied: six>1.9 in /usr/local/lib/python3.12/dist-packages (from tensorboard>=2.18.0->congrads[examples]==0.3.0) (1.17.0)\n", "Requirement already satisfied: tensorboard-data-server<0.8.0,>=0.7.0 in /usr/local/lib/python3.12/dist-packages (from tensorboard>=2.18.0->congrads[examples]==0.3.0) (0.7.2)\n", "Requirement already satisfied: werkzeug>=1.0.1 in /usr/local/lib/python3.12/dist-packages (from tensorboard>=2.18.0->congrads[examples]==0.3.0) (3.1.5)\n", "Requirement already satisfied: filelock in /usr/local/lib/python3.12/dist-packages (from torch>=2.0.0->congrads==0.3.0->congrads[examples]==0.3.0) (3.20.3)\n", "Requirement already satisfied: typing-extensions>=4.10.0 in /usr/local/lib/python3.12/dist-packages (from torch>=2.0.0->congrads==0.3.0->congrads[examples]==0.3.0) (4.15.0)\n", "Requirement already satisfied: sympy>=1.13.3 in /usr/local/lib/python3.12/dist-packages (from torch>=2.0.0->congrads==0.3.0->congrads[examples]==0.3.0) (1.14.0)\n", "Requirement already satisfied: networkx>=2.5.1 in /usr/local/lib/python3.12/dist-packages (from torch>=2.0.0->congrads==0.3.0->congrads[examples]==0.3.0) (3.6.1)\n", "Requirement already satisfied: jinja2 in /usr/local/lib/python3.12/dist-packages (from torch>=2.0.0->congrads==0.3.0->congrads[examples]==0.3.0) (3.1.6)\n", "Requirement already satisfied: fsspec>=0.8.5 in /usr/local/lib/python3.12/dist-packages (from torch>=2.0.0->congrads==0.3.0->congrads[examples]==0.3.0) (2025.3.0)\n", "Requirement already satisfied: mpmath<1.4,>=1.1.0 in /usr/local/lib/python3.12/dist-packages (from sympy>=1.13.3->torch>=2.0.0->congrads==0.3.0->congrads[examples]==0.3.0) (1.3.0)\n", "Requirement already satisfied: markupsafe>=2.1.1 in /usr/local/lib/python3.12/dist-packages (from werkzeug>=1.0.1->tensorboard>=2.18.0->congrads[examples]==0.3.0) (3.0.3)\n" ] } ], "source": [ "!pip install \"congrads[examples]==0.3.0\"" ] }, { "cell_type": "markdown", "metadata": { "id": "LY7X9YeGKtHJ", "tags": [ "hide-cell" ] }, "source": [ "Import the necesary functions and classes." ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "executionInfo": { "elapsed": 1, "status": "ok", "timestamp": 1769502168750, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "SZG3La4arXFL", "tags": [ "hide-cell" ] }, "outputs": [], "source": [ "import torch\n", "from matplotlib import pyplot as plt\n", "from matplotlib.patches import Rectangle\n", "from torch.nn import MSELoss, Module\n", "from torch.optim import Adam\n", "from torch.utils.data import Dataset\n", "from IPython.display import clear_output\n", "\n", "from congrads.callbacks.base import Callback, CallbackManager\n", "from congrads.constraints.base import Constraint\n", "from congrads.constraints.registry import (\n", " ANDConstraint,\n", " ImplicationConstraint,\n", " RankedMonotonicityConstraint,\n", " ScalarConstraint,\n", ")\n", "from congrads.core.congradscore import CongradsCore\n", "from congrads.datasets.registry import SyntheticMonotonicity\n", "from congrads.descriptor import Descriptor\n", "from congrads.metrics import MetricManager\n", "from congrads.networks.registry import MLPNetwork\n", "from congrads.utils.utility import (\n", " CSVLogger,\n", " Seeder,\n", " split_data_loaders,\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "hD3WtPpIKw3H", "tags": [ "hide-cell" ] }, "source": [ "Define utility functions for plotting and other." ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "executionInfo": { "elapsed": 1, "status": "ok", "timestamp": 1769502168753, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "JWNIkGIUKdYj", "tags": [ "hide-cell" ] }, "outputs": [], "source": [ "def plot_regression_epoch(network: Module, dataset: Dataset, device: torch.device):\n", " fig, ax = plt.subplots(figsize=(6, 4))\n", "\n", " network.eval()\n", " with torch.no_grad():\n", " preds = network({\"input\": dataset.inputs.to(device)})[\"output\"].cpu().numpy().flatten()\n", "\n", " # Plot noisy observations\n", " ax.scatter(\n", " dataset.inputs.numpy(),\n", " dataset.targets.numpy(),\n", " color=\"gray\",\n", " alpha=0.6,\n", " edgecolors=\"k\",\n", " s=25,\n", " label=\"Input data\",\n", " )\n", "\n", " # Plot model prediction\n", " ax.plot(dataset.inputs.numpy(), preds, \"r-\", linewidth=2, label=\"Prediction\")\n", "\n", " # Add hatched region\n", " hatched_area = Rectangle(\n", " (0.3, 0), # bottom-left corner\n", " 0.3, # width\n", " 1, # height\n", " facecolor=\"none\",\n", " edgecolor=\"green\",\n", " hatch=\"//\",\n", " linewidth=1,\n", " alpha=0.7,\n", " label=\"Constrained region\",\n", " )\n", " ax.add_patch(hatched_area)\n", "\n", " # Limit axes\n", " ax.set_xlim(0, 1)\n", " ax.set_ylim(0, 1)\n", "\n", " # Titles and labels\n", " ax.set_title(\"Model predictions\")\n", " ax.set_xlabel(\"x\")\n", " ax.set_ylabel(\"y\")\n", " ax.legend()\n", "\n", " return ax\n" ] }, { "cell_type": "markdown", "metadata": { "id": "wCx-6Ljroecz", "tags": [ "hide-cell" ] }, "source": [ "Before starting with the general training procedure, we fix the randomizer seeds and get the device on which we are training our model:\n", "\n", "\n", "\n", "* We have a built-in [Seeder class](https://congrads.readthedocs.io/en/latest/api.html#congrads.utils.Seeder) that will pseudo-randomly fix the seeds of random number generators, Numpy and PyTorch.\n", "* If there is a GPU available, use it. Otherwise fall back to CPU.\n", "\n" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "executionInfo": { "elapsed": 1, "status": "ok", "timestamp": 1769502168755, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "mROd-Y0iobFq", "tags": [ "hide-cell" ] }, "outputs": [], "source": [ "# Set seed for reproducibility\n", "seeder = Seeder(base_seed=42)\n", "seeder.set_reproducible()\n", "\n", "# CUDA for PyTorch\n", "use_cuda = torch.cuda.is_available()\n", "device = torch.device(\"cuda:0\" if use_cuda else \"cpu\")" ] }, { "cell_type": "markdown", "metadata": { "id": "bn3SwXqi-kWK" }, "source": [ "## Problem description\n", "\n", "In this first example, the goal is to demonstrate the usage of the Congrads toolbox for a simple monotonicity example.\n", "\n", "We aim to fit a regression model to a rising trend that shows local sinusoidal oscillations. The goal is to enforce increasing monotonicity in some part of its domain.\n", "\n", "Mathematically: $x_1 \\le x_2 \\in [0.3,\\, 0.6]$, then $f(x_1) \\le f(x_2)$\n", "\n", "![image.png](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfQAAAEsCAIAAAC62dafAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAB9KADAAQAAAABAAABLAAAAADO6/oYAABAAElEQVR4Ae2dB5wURfbHWVgyS1xEQImSJCmSPFFBQJQgcAbMmFAEw4pwwHkkUTEgYCAoBlAMIOqBoGQ4xCOKgbgEyXkJsrCwxP8X6/5l2zPT05N7et589jOfmurq6qpf9/7q9Xuv3ks6f/58DvkIAoKAICAIuAuBnO6ajsxGEBAEBAFB4AICQu7yHAgCgoAg4EIEhNxdeFNlSoKAICAICLnLMyAICAKCgAsREHJ34U2VKQkCgoAgIOQuz4AgIAgIAi5EQMjdhTdVpiQICAKCgJC7PAOCgCAgCLgQASF3F95UmZIgIAgIAkLu8gwIAoKAIOBCBITcXXhTZUqCgCAgCAi5yzMgCAgCgoALERByd+FNlSkJAoKAICDkLs9A7BFISkoaOHCgnXFs3bqVxuPGjbPTOBJtTANg2IwnuAstWLCAc/kO7nQ5SxCwRkDI3RofOfo/BOBTmIjPokWLjKAQMvrSSy+lvm3btsZ6KZsQGDVqVAzXJNNg5GciICDkngh3OWxzzJcv36effmrs7j//+c/OnTvz5s1rrEyc8r/+9a8TJ07Yma8nuV933XWcy7ed06WNIBAoAkLugSKW0O1bt279xRdfnDlzRqMA11911VUXX3yxromXAu8cNnnZYkbJyckseBYNLA7lzJmTc/m2aCOHBIGgEZAHK2joEvHEu+666+DBg7Nnz1aTP3Xq1OTJk++++24TFsePH3/22WdR1yDRV6tWbejQocaEX9nZ2c8880zJkiVTUlJuueUWBH/T6bt27XrooYdKlSrF6TVr1vzggw9MDXz9VLqjhQsXPvbYYyVKlChcuPD9999/+PBh3b5ChQqoj2bOnFm/fv38+fO/8847HDpy5EhaWpoa7WWXXfbKK6+cO3dOn8LRBx54oEiRIkWLFu3cuTM/9SEKnjr3CRMmNGzYsECBAsWKFUMqnzVrFs247po1a3jLuaDYSkpq2rQplZ46dxZOVkoGlpqaeu+994IDzdSHMRQqVIiaDh06UAC9nj17nj179v+P5/j88885F0iZde3atd944w19SAqJiUByYk5bZh0cApDU1Vdf/dlnn91888308N133/3+++933nnnm2++qTuEx6Hs+fPnP/zww1dccQVM2qtXL1hp+PDhqs0jjzwCA7Ik/O1vf5s3b16bNm30uRT27dvXuHFjGPCJJ56AwrgE/Rw9ehT+NTazKHMiRAztpqenjx49etu2bYpG1SlUskTB/l26dGHhycrKuv766xkeNeXKlfvvf//bt2/fPXv2jBgxgvbMpX379pgZunbtWqNGja+//hp+t7j0oEGDuC7zev755/PkybN06VImeOONN9Lbk08+CSk/99xznM665dkJK9ODDz7YoEGDIUOGAALs/MMPP/z000/MRTWGylu1atWoUSMWyzlz5rz++uuVK1d+/PHHOcpyy6SaN2/OysTPdevWce7TTz/teRWpSSAEeHzlIwj4ReDDDz/kv2L58uVvv/024iGcyCm33357s2bNKJQvXx6OVp38+9//puULL7yg+7ztttsg602bNlHz888/c7Rbt276qBL8BwwYoGqg8tKlS2dkZOgGLB4IzuqKW7Zs4XQGo48aC2qQCLC8Uqj6V199lfZTpkxRPxknP2fMmKHPGjx4cMGCBTds2KBr+vTpkytXru3bt1Oj5kIn6ij6qGuvvdY4AIbNT3V048aN6Fg6duwIC+veeAlQZV5BWEV0PQXWP87lmzIDvuiii2rVqoWmSLWZNm0aR/v3769+qkWFNUP95PvKK69kpuonPI7AzvD0USkIAqKW4T9IPgEgcMcdd0BAUE9mZibfnjqZb7/9FnJ86qmndKeoaPhPQwanhqN8G48aRXKaffnll+3ataMAv6sP4irvBytXrtQdWhceffTR3LlzqzYItqjF1UVVTcWKFelQ94AmBL5GhfL/V8to0aIF7IxuhzacyOlKOuYn80IA1+eaCqwEUDl0bFSjs6qZmnn9uWLFiv3797PmaQ0+i2X16tWnT59ubM8LhP7JsH/77Tf1E+keVZhWl+k2UkhkBEQtk8h3P5i5oyqB/rCjIkpDgkjlpl5Qg5QpUwbpXtej0KBMvfqG+9An6KPoRnT5wIEDKLXf/eOjK1UB7jPV+PpZpUoVfQhNCO8BOKfrGshdlykgbv/6669MylhJWV2OMXM6neijxtHqSlXYvHkzU7v88stN9XZ+KnBMnUPuRsdTeN84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)" ] }, { "cell_type": "markdown", "metadata": { "id": "xFnObGpwofNX" }, "source": [ "## Dataset\n", "\n", "The first important step in the training process is interfacing with your data. Our Congrads toolbox is compatible with the standard [PyTorch Dataset class](https://docs.pytorch.org/tutorials/beginner/basics/data_tutorial.html#creating-a-custom-dataset-for-your-files), but requires the data to be returned in a dictionary format.\n", "\n", "We require the returning dictionary to have keys `input` and `target`.\n", "\n", "\n", "* `input` holds data that is provided to the network (model) as input\n", "* `target` holds ground truth data that compared against the predictions to calculate a loss value\n", "\n", "The Congrads toolbox holds a [collection of several predefined datasets](https://congrads.readthedocs.io/en/latest/api.html#module-congrads.datasets) which feature automatic downloading or generate synthetic data.\n", "\n", "\n", "When creating custom datasets, make sure they return data in this format — including the required `input` and `target` keys — while remaining flexible to include any additional keys you need.\n", "\n", "```python\n", "class MyData(Dataset):\n", "\n", " ...\n", "\n", " def __getitem__(self, idx) -> dict:\n", " # The Congrads toolbox expects data in a dictionary format that must include the keys 'input' and 'target'\n", " return {\"input\": self.inputs[idx], \"target\": self.targets[idx]}\n", "```\n", "\n", "We provide a [utility wrapper](https://) that can convert any regular dataset into a dataset that returns a Congrads-compatible dictionary.\n", "\n", "For this example we will use the built-in [SyntheticMonotonicity dataset](https://) and we will split the dataset into training, validation and test sets using another [built-in utility function](https://)." ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "executionInfo": { "elapsed": 3, "status": "ok", "timestamp": 1769502168758, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "sdqTRHEcobTk" }, "outputs": [], "source": [ "# Load and preprocess data\n", "dataset = SyntheticMonotonicity(\n", " n_samples=100,\n", " x_range=(0, 1),\n", " osc_amplitude=0.15,\n", " osc_frequency=20.0,\n", " osc_prob=1.0,\n", " noise_base=0.01,\n", " noise_scale=0.02,\n", " seed=seeder.roll_seed(),\n", ")\n", "loaders = split_data_loaders(\n", " dataset,\n", " loader_args={\"batch_size\": 10, \"shuffle\": True},\n", " valid_loader_args={\"shuffle\": False},\n", " test_loader_args={\"shuffle\": False},\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "foEdZFE2raw2" }, "source": [ "## Network\n", "\n", "After the data is taken care of, we must define a network (model) to train. Our Congrads toolbox is compatible with any [PyTorch-compatible network](https://docs.pytorch.org/tutorials/beginner/basics/buildmodel_tutorial.html#define-the-class), but again requires the forward pass of the model to return a dictionary format.\n", "\n", "Congrads expects the forward pass to update the data dictionary by adding model predictions under the key `output`.\n", "\n", "Congrads provides a limited amount of [pre-built networks](https://congrads.readthedocs.io/en/latest/api.html#module-congrads.networks) including a basis fully connected MLP Network, but you can use any network as long as it meets the above requiremtens. When building your own network, it can be done like this:\n", "\n", "```python\n", "class MyNetwork(nn.Module):\n", "\n", " ...\n", "\n", " def forward(self, data: dict[str, Tensor]):\n", " # Congrads expects the forward pass to update the data dictionary by adding model predictions under the key output.\n", " data[\"output\"] = self.network(data[\"input\"])\n", " return data\n", " ```\n", "\n", " Again, we will use a built in fully connected network for this example, define its dimensions and parameters, and then push it to the correct device." ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "executionInfo": { "elapsed": 3, "status": "ok", "timestamp": 1769502168760, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "cP1XYA8Pra81" }, "outputs": [], "source": [ "# Instantiate network and push to correct device\n", "network = MLPNetwork(n_inputs=1, n_outputs=1, n_hidden_layers=3, hidden_dim=100)\n", "network = network.to(device)" ] }, { "cell_type": "markdown", "metadata": { "id": "b_78GkB1rm40" }, "source": [ "## Descriptor\n", "\n", "Now that we have the dataset and the network defined, we can set up an important feature in the Congrads toolbox, called the `Descriptor`.\n", "\n", "The descriptor describes the data that is used with your network. It allows assigning tags to specific parts of data in the network, in order to easily be able to apply constraints on these parts of data.\n", "\n", "Example:\n", "```python\n", "descriptor = Descriptor()\n", "descriptor.add(\"input\", \"t\", 0, constant=True) # Assigns tag 't' to input data tensor column 0\n", "```\n", "\n", "We have [several flags](https://congrads.readthedocs.io/en/latest/api.html#congrads.descriptor.Descriptor.add) when assigning tags to data:\n", "\n", "* `constant=True` is used for data that is not changing, like input data or extra context data like run identifiers. This data stays constant troughout the training.\n" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "executionInfo": { "elapsed": 0, "status": "ok", "timestamp": 1769502168766, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "UZ3wkjP_rnC2" }, "outputs": [], "source": [ "# Instantiate descriptor\n", "descriptor = Descriptor()\n", "\n", "# Add a constant tag for the input\n", "descriptor.add(\"input\", \"x\", 0, constant=True)\n", "\n", "# Add a tag for the output\n", "descriptor.add(\"output\", \"y\", 0)\n" ] }, { "cell_type": "markdown", "metadata": { "id": "0XqypUaYpFNo" }, "source": [ "## Constraints\n", "\n", "With the help of the descriptor, we can easily reference certain parts of the neural network, and so we can now define our constraints.\n", "\n", "We have [numerous pre-defined constraints](https://congrads.readthedocs.io/en/latest/api.html#module-congrads.constraints) available that allow a variety of options. Some examples:\n", "\n", "\n", "* `ScalarConstraint` allows enforcing that data referenced by a tag should be above or below a certain scalar value\n", "* `ImplicationConstraint` allows conditionally enforcing constraints. If constraint X satisfies, then enforce constraint Y.\n", "* `MonotonicityConstraint` allows enforcing a monotonic behaviour on a certain tag\n", "* `ANDConstraint` allows enforcing a combination of constraints\n", "\n", "With these constraints you can start building up your logic, to start constraining your network predictions.\n", "\n", "When defining constraints, you should always start by assigning the descriptor and the device to the constraints globally so every constraint has access to it.\n", "```python\n", "Constraint.descriptor = descriptor\n", "Constraint.device = device\n", "```\n", "\n", "Then you can create your list of constraints to enforce. For example, the constraints below enforce that `y` must be less than or equal 1 if `x` is greater than 0.5.\n", "\n", "```python\n", "constraints = [\n", " ImplicationConstraint(\n", " head=ScalarConstraint(\"x\", torch.gt, 0.5),\n", " body=ScalarConstraint(\"y\", torch.le, 1.0),\n", " )\n", "]\n", "```\n", "\n", "In this example, we want to enforce a monotonically increasing prediction `y` when the input `x` lays between 0.3 and 0.6 (including).\n", "\n", "The objective: $x_1 \\le x_2 \\in [0.3,\\, 0.6]$, then $f(x_1) \\le f(x_2)$" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 13, "status": "ok", "timestamp": 1769502168780, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "OebxVdwT5r3h", "outputId": "81bd9502-7418-4640-c12a-f4fab56ec093" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/lib/python3.12/dist-packages/congrads/constraints/base.py:216: UserWarning: Rescale factor for constraint y monotonically (ranked) ascending by x is <= 1. The network will favor general loss over the constraint-adjusted loss. Is this intended behavior? Normally, the rescale factor should always be larger than 1.\n", " super().__init__({tag_prediction}, name, enforce, 1.0)\n", "/usr/local/lib/python3.12/dist-packages/congrads/constraints/registry.py:102: UserWarning: Rescale factor for constraint y monotonically (ranked) ascending by x if x >= 0.3 AND x <= 0.6 is <= 1. The network will favor general loss over the constraint-adjusted loss. Is this intended behavior? Normally, the rescale factor should always be larger than 1.\n", " super().__init__(head.tags | body.tags, name, body.enforce, body.rescale_factor)\n" ] } ], "source": [ "# Assign descriptor to constraint base\n", "Constraint.descriptor = descriptor\n", "\n", "# Assign device to constraint base\n", "Constraint.device = device\n", "\n", "# Define constraints\n", "constraints = [\n", " ImplicationConstraint(\n", " head=ANDConstraint(\n", " ScalarConstraint(\"x\", \">=\", 0.3),\n", " ScalarConstraint(\"x\", \"<=\", 0.6),\n", " ),\n", " body=RankedMonotonicityConstraint(\"y\", \"x\"),\n", " ),\n", "]" ] }, { "cell_type": "markdown", "metadata": { "id": "9NDRG60yrh7s" }, "source": [ "## Loss and optimizer\n", "\n", "We also have to define a loss function and an optimizer.\n", "\n", "You can use any [PyTorch loss function](https://docs.pytorch.org/docs/stable/nn.html#loss-functions) that fits your training, or write and implement your own as long as it extends the `nn.Module` class.\n", "\n", "We also provide a built-in [ZeroLoss](https://congrads.readthedocs.io/en/latest/api.html#congrads.utils.ZeroLoss) class that can be used for training without loss. This can be used to train your network only based on the constraints. By using this loss function, it will always output zero and thus focus solely on enforcing the constraints for training.\n", "\n", "You can use any common optimizer such as `Adam` and `SGD`. PyTorch provides a [collection of optimizers](https://docs.pytorch.org/docs/stable/optim.html) to use.\n", "\n", "For this example, we will stick to using MSE loss and the Adam optimizer." ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "executionInfo": { "elapsed": 1, "status": "ok", "timestamp": 1769502168781, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "Lx8FHOHfriLl" }, "outputs": [], "source": [ "# Instantiate loss and optimizer\n", "criterion = MSELoss()\n", "optimizer = Adam(network.parameters(), lr=0.001)" ] }, { "cell_type": "markdown", "metadata": { "id": "mWZVjzpQruk3" }, "source": [ "## Metric manager\n", "\n", "To allow keeping track of constraint satisfaction rates for each individual constraints, as well as the losses and possibly other metrics, we set up a [MetricManager](https://congrads.readthedocs.io/en/latest/api.html#module-congrads.metrics) system.\n", "\n", "The `CongradsCore` requires a metric manager instance, because it registers and stored metrics internally. You can reference the metric manager in callbacks for custom logging or to store and keep track of the metrics." ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "executionInfo": { "elapsed": 14, "status": "ok", "timestamp": 1769502168796, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "Ke7tTBTJru6m" }, "outputs": [], "source": [ "# Initialize metric manager\n", "metric_manager = MetricManager()" ] }, { "cell_type": "markdown", "metadata": { "id": "cvEjQd8sdI0U" }, "source": [ "## Callback manager\n", "\n", "At the moment, we have a callback system in place that allows executing customizable functions at certain points in the training process.\n", "\n", "This can be used to do some custom data transformations, to generate graphs and figures or to do custom logging functionalities.\n", "\n", "Refer to the [Congrads documentation](https://congrads.readthedocs.io/en/latest/) for more info." ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "executionInfo": { "elapsed": 2, "status": "ok", "timestamp": 1769502168797, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "O6Bxp75BdgGp" }, "outputs": [], "source": [ "callback_manager = CallbackManager()" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "executionInfo": { "elapsed": 33, "status": "ok", "timestamp": 1769502168831, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "l0279nibsClA" }, "outputs": [], "source": [ "class PlottingCallback(Callback):\n", " def on_epoch_end(self, data, ctx):\n", " clear_output(wait=True)\n", " plot_regression_epoch(network, dataset, device)\n", " plt.show()\n", " plt.close()" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 9, "status": "ok", "timestamp": 1769502168833, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "6PSSn0MJdrRB", "outputId": "bd7ce4c1-0b71-4ce5-878f-291f891dfa32" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "callback_manager.add(PlottingCallback())" ] }, { "cell_type": "markdown", "metadata": { "id": "YDJt1358r0I7" }, "source": [ "## Core\n", "\n", "The [CongradsCore](https://congrads.readthedocs.io/en/latest/api.html#congrads.core.CongradsCore) is the brain of the toolbox. It orchestrates the functionality of all previously created objects, integrating descriptors, constraints, and optimization strategies to perform constraint-guided gradient descent. Essentially, it manages the full training or evaluation pipeline: preparing input and output tensors, applying constraints, computing gradients, updating model parameters, and generating predictions in a coordinated manner." ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "executionInfo": { "elapsed": 3, "status": "ok", "timestamp": 1769502168833, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "FDGlm9oGr0WE" }, "outputs": [], "source": [ "# Instantiate core\n", "core = CongradsCore(\n", " descriptor=descriptor,\n", " constraints=constraints,\n", " dataloader_train=loaders[0],\n", " dataloader_valid=loaders[1],\n", " dataloader_test=loaders[2],\n", " network=network,\n", " callback_manager=callback_manager,\n", " criterion=criterion,\n", " optimizer=optimizer,\n", " metric_manager=metric_manager,\n", " device=device,\n", " enforce_all=True,\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "HoxB8KH3sCGz" }, "source": [ "Finally, we can start training by running the `core.fit(...)` function. This function allows setting the maximum epochs and callback functions and will start the training process.\n", "\n", "While the Congrads Core implements and abstractizes a standard training loop within, you are not limited to this. Congrads exposes [some static methods](https://congrads.readthedocs.io/en/latest/api.html#congrads.core.CongradsCore.train_step) that you can leverage to implement your own training loop. Particulary useful if you require advanced functionality or are deviating from a standard training procedure." ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 428 }, "executionInfo": { "elapsed": 96299, "status": "ok", "timestamp": 1769502265130, "user": { "displayName": "Wout Rombouts", "userId": "06394371526548571555" }, "user_tz": -60 }, "id": "oJcIDbRqr8ai", "outputId": "9a1241c8-ac2e-4e44-fdfd-0182a1d4a321" }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stderr", "output_type": "stream", "text": [ "Epoch: 100%|██████████| 500/500 [01:36<00:00, 5.19it/s]\n" ] } ], "source": [ "# Start training\n", "core.fit(max_epochs=500)" ] } ], "metadata": { "colab": { "collapsed_sections": [ "eX2YY8tp5yyk" ], "provenance": [], "toc_visible": true }, "kernelspec": { "display_name": "congrads (3.13.7)", "language": "python", "name": "python3" }, "language_info": { "name": "python", "version": "3.13.7" } }, "nbformat": 4, "nbformat_minor": 0 }