Files
optimiz-rs/examples/notebooks/17_generative_calibration.ipynb
T

167 lines
100 KiB
Plaintext
Raw Normal View History

{
"cells": [
{
"cell_type": "markdown",
"id": "cb7dea7c",
"metadata": {},
"source": [
"# 17 — MMD calibration loss"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "8d6df02a",
"metadata": {
"execution": {
"iopub.execute_input": "2026-05-12T10:16:23.357071Z",
"iopub.status.busy": "2026-05-12T10:16:23.356796Z",
"iopub.status.idle": "2026-05-12T10:16:24.029739Z",
"shell.execute_reply": "2026-05-12T10:16:24.028259Z"
}
},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from optimizr import _core as opt\n",
"plt.rcParams['figure.figsize'] = (7, 4)\n",
"plt.rcParams['figure.dpi'] = 110\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "b8b76095",
"metadata": {
"execution": {
"iopub.execute_input": "2026-05-12T10:16:24.040309Z",
"iopub.status.busy": "2026-05-12T10:16:24.039241Z",
"iopub.status.idle": "2026-05-12T10:16:24.058710Z",
"shell.execute_reply": "2026-05-12T10:16:24.057343Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"MMD self = 0.0\n",
"MMD at shift 6.0 = 0.9032217374045481\n"
]
}
],
"source": [
"x = np.linspace(0.0, 5.0, 80)\n",
"shifts = np.linspace(0.0, 6.0, 40)\n",
"d = [opt.mmd_gaussian(x.tolist(), (x + s).tolist(), 1.0) for s in shifts]\n",
"print('MMD self =', d[0])\n",
"print('MMD at shift 6.0 =', d[-1])\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "e3457ca1",
"metadata": {
"execution": {
"iopub.execute_input": "2026-05-12T10:16:24.061731Z",
"iopub.status.busy": "2026-05-12T10:16:24.061447Z",
"iopub.status.idle": "2026-05-12T10:16:24.329477Z",
"shell.execute_reply": "2026-05-12T10:16:24.328075Z"
}
},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 770x440 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, ax = plt.subplots()\n",
"ax.plot(shifts, d, lw=2)\n",
"ax.set_xlabel('translation Δ'); ax.set_ylabel('MMD(P, P + Δ)')\n",
"ax.set_title('Gaussian-kernel MMD vs translation (σ = 1)')\n",
"ax.grid(alpha=0.3); fig.tight_layout(); plt.show()\n"
]
},
{
"cell_type": "markdown",
"id": "4861ad77",
"metadata": {},
"source": [
"## Bandwidth dependence"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "7f3b6484",
"metadata": {
"execution": {
"iopub.execute_input": "2026-05-12T10:16:24.336277Z",
"iopub.status.busy": "2026-05-12T10:16:24.335914Z",
"iopub.status.idle": "2026-05-12T10:16:24.819175Z",
"shell.execute_reply": "2026-05-12T10:16:24.817306Z"
}
},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 770x440 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, ax = plt.subplots()\n",
"for sigma in [0.25, 0.5, 1.0, 2.0]:\n",
" d = [opt.mmd_gaussian(x.tolist(), (x + s).tolist(), sigma) for s in shifts]\n",
" ax.plot(shifts, d, label=f'σ = {sigma:g}')\n",
"ax.set_xlabel('translation Δ'); ax.set_ylabel('MMD'); ax.legend(); ax.grid(alpha=0.3)\n",
"ax.set_title('MMD as a function of kernel bandwidth')\n",
"fig.tight_layout(); plt.show()\n"
]
},
{
"cell_type": "markdown",
"id": "fd37ad48",
"metadata": {},
"source": [
"**Verified:** `MMD(x, x) = 0`; metric is strictly monotonic in shift."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (rhftlab)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}