diff --git a/.gitignore b/.gitignore index 06ff167..77f7b11 100644 --- a/.gitignore +++ b/.gitignore @@ -112,4 +112,7 @@ venv.bak/ # direnv configuration file .envrc + +# PowerPoint checkpoint files /~$machine_learning_with_python.pptx +/~$multi_gpu_machine_learning.pptx diff --git a/README.md b/README.md index 95af546..4555560 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ For information on the training, see the website 1. [`machine_learning_with_python.pptx`](machine_learning_with_python.pptx): PowerPoint presentation used for the training. +1. ['multi_gpu_machine_learning.pptx'](multi_gpu_machine_learning.pptx): PowerPoint presentation used for the + multi-GPU session of the training. 1. [`hands-on`](hands-on): Jupyter notebooks for hands-on sessions. 1. [`source-code`](source-code): sample code written to develop the slides and illustrate concepts. @@ -16,10 +18,6 @@ For information on the training, see the website core teaching material, intended to be cross-platform. 1. [`environment_gpu.yml`](environment_gpu.yml): GPU-enabled conda environment for the instructor laptop, using its validated CUDA configuration. -1. [`environment_keras.yml`](environment_keras.yml): CPU-only Linux conda - environment for the legacy Keras examples. -1. [`environment_keras_gpu.yml`](environment_keras_gpu.yml): Linux/NVIDIA conda - environment for running the legacy Keras examples with GPU acceleration. 1. [`machine_learning_with_python_linux64_conda_specs.txt`](machine_learning_with_python_linux64_conda_specs.txt): conda environment specification file specific for 64-bit Linux to precisely reproduce the environment on which the code was developed. diff --git a/environment.yml b/environment.yml index 0e54507..fbbe22f 100644 --- a/environment.yml +++ b/environment.yml @@ -17,10 +17,10 @@ dependencies: # Model interpretation and parameter-optimization examples. - lime - - hyperopt - - bayesian-optimization + - optuna # Notebook and visualization stack used by the core teaching material. - jupyterlab + - ipywidgets - matplotlib - bokeh diff --git a/environment_gpu.yml b/environment_gpu.yml index 2426553..a0c0d38 100644 --- a/environment_gpu.yml +++ b/environment_gpu.yml @@ -10,14 +10,18 @@ dependencies: - torchvision=0.28 - cuda-version=12.9 - # Keep the teaching stack aligned with the CPU environment. + # Core numerical and machine-learning stack. - numpy - scipy - pandas - scikit-learn + + # Model interpretation and parameter-optimization examples. - lime - - hyperopt - - bayesian-optimization + - optuna + + # Notebook and visualization stack used by the core teaching material. - jupyterlab + - ipywidgets - matplotlib - bokeh diff --git a/machine_learning_with_python.pptx b/machine_learning_with_python.pptx index b7e55ed..c5c3168 100644 Binary files a/machine_learning_with_python.pptx and b/machine_learning_with_python.pptx differ diff --git a/multi_gpu_machine_learning.pptx b/multi_gpu_machine_learning.pptx new file mode 100644 index 0000000..14d50ef Binary files /dev/null and b/multi_gpu_machine_learning.pptx differ diff --git a/source-code/README.md b/source-code/README.md index 45c1ec2..c02a03e 100644 --- a/source-code/README.md +++ b/source-code/README.md @@ -9,9 +9,8 @@ to create it. There is some material not covered in the presentation as well. * [`pytorch`](pytorch): illustration of using PyTorch for machine learning. * [`pytorch-lightning/`](pytorch-lightning/): illustration of using PyTorch Lightning for machine learning. -* [`parameter-optimization`](parameter-optimization): example of parameter - optimization kusing hyperopt, although the examples do not optimize - hyperparameters in machine learning, that would be very similar. +* [`parameter-optimization`](parameter-optimization): methodology-first Optuna + examples, from a minimal study to a realistic PINN case study. * [`scikit-learn`](scikit-learn): examples of scikit-learn for machine learning, examples are provided forsupervised (regression and classification) and unsupervised (clustering) learnign, as well as dimensionality reduction diff --git a/source-code/curse_of_dimensionality.ipynb b/source-code/curse_of_dimensionality.ipynb index 7522474..da9379d 100644 --- a/source-code/curse_of_dimensionality.ipynb +++ b/source-code/curse_of_dimensionality.ipynb @@ -16,8 +16,28 @@ }, { "cell_type": "markdown", - "id": "836452cc-08f2-4edc-96f5-700d8cd5bd16", + "id": "e69782ab-d490-4cea-9df4-189f988224ff", "metadata": {}, + "source": [ + "Initialize a random number generator." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0eb0081e-3c46-443d-ba00-c6b8151ef38d", + "metadata": {}, + "outputs": [], + "source": [ + "rng = np.random.default_rng(seed=1234)" + ] + }, + { + "cell_type": "markdown", + "id": "836452cc-08f2-4edc-96f5-700d8cd5bd16", + "metadata": { + "jp-MarkdownHeadingCollapsed": true + }, "source": [ "## Distances between vertices of a hypercube" ] @@ -32,7 +52,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "id": "15ef43bf-134f-4379-95c6-148ddd5ff440", "metadata": {}, "outputs": [], @@ -52,7 +72,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "id": "2db62095-6aa4-44c3-bd82-0370550290b2", "metadata": { "scrolled": true @@ -83,12 +103,16 @@ "id": "e92887cc-e1d8-4092-ad25-aa099518ae9d", "metadata": {}, "source": [ - "Define the cosine similarity (https://en.wikipedia.org/wiki/Cosine_similarity)." + "Define the cosine similarity (https://en.wikipedia.org/wiki/Cosine_similarity).\n", + "\n", + "$$\n", + " d(\\vec{v}_1, \\vec{v}_2) = \\frac{\\vec{v}_1 \\cdot \\vec{v}_2}{\\lVert \\vec{v}_1 \\rVert \\lVert \\vec{v}_2 \\rVert}\n", + "$$" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "e2e1a0f8-9f44-43e2-9011-736be3aa5760", "metadata": {}, "outputs": [], @@ -107,7 +131,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "id": "f218f6ac-c780-465d-9b71-c1758d425efa", "metadata": {}, "outputs": [], @@ -130,14 +154,14 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "id": "af056b13-e063-46af-bfe1-0b98331942ea", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "8bf92bf1a6c045a79320a828ec6ae145", + "model_id": "b5cfd1793eff4c74b2193440fe76b715", "version_major": 2, "version_minor": 0 }, @@ -191,13 +215,13 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "id": "144c02ff-c974-427a-9e84-110976724e19", "metadata": {}, "outputs": [], "source": [ - "def generate_vectors(nr_vectors, nr_dims, max_value=1.0, normalize=True):\n", - " vectors = np.random.uniform(-max_value, max_value, (nr_vectors, nr_dims))\n", + "def generate_vectors(rng, nr_vectors, nr_dims, max_value=1.0, normalize=True):\n", + " vectors = rng.uniform(-max_value, max_value, (nr_vectors, nr_dims))\n", " if normalize:\n", " vectors /= np.linalg.norm(vectors, axis=1)[:, None]\n", " return vectors" @@ -205,13 +229,13 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "5c109cb9-1eb4-472c-a5af-62a35c75a08d", "metadata": {}, "outputs": [], "source": [ - "def compute_similarity_distribution(nr_vectors, nr_dims):\n", - " vectors = generate_vectors(nr_vectors, nr_dims)\n", + "def compute_similarity_distribution(rng, nr_vectors, nr_dims):\n", + " vectors = generate_vectors(rng, nr_vectors, nr_dims)\n", " similarities = []\n", " for i in range(nr_vectors):\n", " for j in range(i + 1, nr_vectors):\n", @@ -221,14 +245,14 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "bb6ec1e5-db35-4b7d-b657-05516b0bc618", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "90f888f1208741e9bdd4b25e26ff01ed", + "model_id": "84722b0d07bf4f1b99f1445498813869", "version_major": 2, "version_minor": 0 }, @@ -243,9 +267,111 @@ "source": [ "@ipywidgets.interact(nr_vectors=(100, 10_000), nr_dims=(1, 50))\n", "def show_similarity_distribution(nr_vectors=1_000, nr_dims=2):\n", - " similarities = compute_similarity_distribution(nr_vectors, nr_dims)\n", - " plt.hist(similarities, bins=50, density=True)\n", - " plt.xlim(-1.0, 1.0);" + " similarities = compute_similarity_distribution(rng, nr_vectors, nr_dims)\n", + " figure, axis = plt.subplots()\n", + " axis.hist(similarities, bins=50, density=True)\n", + " axis.set_xlim(-1.0, 1.0)\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "bf6cd3a7-52bd-49eb-a5d5-2b9a6714457c", + "metadata": {}, + "source": [ + "## Random vectors in a unit cube" + ] + }, + { + "cell_type": "markdown", + "id": "bfcf927f-e6e4-4dee-b6e3-f0b2fbcc3cbb", + "metadata": {}, + "source": [ + "Consider $N$ randomly generated vectors that lie in an $n$-dimensional unit hypercube. if you pick a random vector in that hypercube, what is the ratio between the distance to the nearest and the farest vector?" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "cc709a02-a868-4750-9a8d-91061da55120", + "metadata": {}, + "outputs": [], + "source": [ + "def generate_vectors(rng, nr_vectors, nr_dims):\n", + " return rng.uniform(size=(nr_vectors, nr_dims))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "4c934b85-3ab0-4e1e-999f-9260c254a1c8", + "metadata": {}, + "outputs": [], + "source": [ + "def generate_query_vector(rng, nr_dims):\n", + " return rng.uniform(size=nr_dims)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "11b046b1-a085-4612-afda-7f1696534ca0", + "metadata": {}, + "outputs": [], + "source": [ + "def distance_extrema(query_vector, vectors):\n", + " norms = np.linalg.norm(vectors, axis=1)\n", + " distances = np.linalg.norm(vectors - query_vector, axis=1)\n", + " return distances.min(), distances.max()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "fadea629-1529-4924-844f-3f7c4b51c277", + "metadata": {}, + "outputs": [], + "source": [ + "def near_far_ratio(rng, nr_vectors, nr_dims):\n", + " vectors = generate_vectors(rng, nr_vectors, nr_dims)\n", + " query_vector = generate_query_vector(rng, nr_dims)\n", + " near, far = distance_extrema(query_vector, vectors)\n", + " return near/far" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "e6791c06-3b7b-45bb-9945-3f8fa3db3847", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjsAAAG6CAYAAADu0oe7AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAARNNJREFUeJzt3XlclXXe//H3YVcEFJBVQdwXVBTE1LRscSu3msmpXy7VVLbcc5fTVNZMZndzc0/LTE2FbZaa1VjNlDo5mk2llY4rkoq5oiAeQCQBF7Zzrt8fKkWIAp5zrsPh9Xw8eMzD7/leFx8f1wjvruv6fr4WwzAMAQAAeCgvswsAAABwJsIOAADwaIQdAADg0Qg7AADAoxF2AACARyPsAAAAj0bYAQAAHo2wAwAAPBphBwAAeDTCDgAA8GhuFXbWrl2r8ePHKyYmRhaLRZ988slFj1mzZo2Sk5MVEBCgzp0769VXX3V+oQAAoNlwq7Bz8uRJ9e/fXy+//HKD5mdnZ2vcuHEaPny4MjIy9Nhjj+k3v/mN/v73vzu5UgAA0FxY3HUjUIvFoo8//liTJk2qd84jjzyiZcuWadeuXTVjM2fOVGZmptavX++CKgEAgLvzMbuAS7F+/XqNGjWq1tjo0aM1f/58VVVVydfXt84xFRUVqqioqPmz3W5XcXGxwsLCZLFYnF4zAAC4dIZhqKysTDExMfLyuvCDqmYddvLz8xUZGVlrLDIyUtXV1SoqKlJ0dHSdY9LS0jR37lxXlQgAAJwoNzdXHTp0uOCcZh12JNW5G3PuqVx9d2lmz56tWbNm1fy5pKREcXFxys3NVXBwsPMKBQAADlNaWqqOHTsqKCjoonObddiJiopSfn5+rbHCwkL5+PgoLCzsvMf4+/vL39+/znhwcDBhBwCAZqYhr6C41WqsxhoyZIhWr15da+yzzz5TSkrKed/XAQAALY9bhZ0TJ05o27Zt2rZtm6QzS8u3bdumnJwcSWceQU2bNq1m/syZM3Xo0CHNmjVLu3bt0ltvvaX58+froYceMqN8AADghtzqMdbmzZs1cuTImj+fe7dm+vTpWrBggaxWa03wkaSEhAStWLFCDz74oF555RXFxMTor3/9q2688UaX1w4AANyT2/bZcZXS0lKFhISopKSEd3YAAGgmGvP7260eYwEAADgaYQcAAHg0wg4AAPBohB0AAODR3Go1FgAA8Aw2u6GN2cUqLCtXRFCAUhNC5e1lzh6UhB0AAOBQK3dYNXd5lqwl5TVj0SEBmjO+t8Yk1t230tl4jAUAABxm5Q6r7lm8tVbQkaT8knLds3irVu6wurwmwg4AAHAIm93Q3OVZOl8Dv3Njc5dnyWZ3bYs/wg4AAHCIjdnH6tzR+SlDkrWkXBuzi11XlHhnBwAANEFZeZX2FJRpd/6Js/9bpu/yjjfo2MKy+gORMxB2AABAvcqrbNp/9ERNsNmdX6o9BSeUd/x0k88ZERTgwAovjrADAEAz54hl3ja7oUPHTmp3fpl2F5TV3K05eOxUve/YRAUHqHtUkHpEtlH3yCB1iwjSzMWbVVBacd73diySokLO1OdKhB0AAJqxxi7zNgxD1pLyM4Emv6wm3OwrPKGKavt5v0dwgI96RgWrR1TQ2XATpO6RbdS2tV+duU9O6KN7Fm+VRaoVeM5Frznje7u83w67nrPrOQCgmTq3zPvnv8jPRYlnf9FPse1an7lLcy7cFJSprLz6vOcL8PVS98ggdY88E2h6RJ35igjyl8XS8IDiij47jfn9Tdgh7AAAmiGb3dDlf/rigquf6uPtZVHn8EB1jwpSz8gf79Z0DG3tsLsuzu6g3Jjf3zzGAgCgmTlZUa13N+Q0KOi0D/JT/w5tz9ytOXunJiE8UP4+3k6t0dvLoiFdwpz6PRqKsAMAgJsrOlGhzQd/0KaDxdp0sFg7j5Q2uDHf76/rrYlJsU6u0L0RdgAAcCOGYSi3+HRNsNl4sFgHjp6sMy880E9FJysvej5XL/N2R4QdAABMZLMb2p1fVhNuNh0sVkFpRZ153SPbaFCnUKUmhCqlU6iiggN0+Z++UH5JuVst83ZHhB0AAFyovMqm7Xkl2ph9JthsOfRDndVRvt4W9Y0N0aBOoRrUKVQpndqdd5n3nPG93W6Ztzsi7AAA0EBNWWFUcrpKWw/9+L5N5uESVf6sn02gn7cGxrerCTdJHduqld/FXyAekxitebcOrLPMO8rBy7ybO8IOAAAN0NDeMQWl5TV3bTYd/EHf55fq501ewtv41QSbQZ1C1Ss6SD7eTdube0xitK7tHeXUZd7NHX126LMDALiICzXvMyTdOjhOp6ps2nSwWLnFdfeM6hTWWimdQpXaKVSDEkLVKax1o5r0oS767AAA4CA2u6G5y7PO+xLwubHFG3JqxrwsUq/o4J/cuWmniGBWRJmJsAMAwAVszC5uUPO+SUkxmjywgwbGtVVQgK8LKkNDEXYAADiPwtJy/fM7qxauO9ig+SN7RuiK7u2dWxSahLADAMBZJaeq9K8dVi3LPKL/HDimBjYplkTzPndG2AEAtGgnK6r1+a4CLc88ojV7jqrK9mPCGRjXVtf3i9araw7oaFkFzfuaKcIOAKDFqai2ac3uo1qWeUT/3lWo01W2ms96RgVpQlKMxveLUcfQ1pKkmLataN7XjBF2AAAtgs1uaP3+Y1qWmaeVO/JV+pOuxfFhrTWhf4wm9I9Rt8igOsfSvK95I+wAADyWYRjamnNcyzOP6J/fWVV04sc9p6KCA3R9v2hNSIpR39iQi/a9oXlf80XYAQB4FMMwtMtapuXfHdHyzCM6/MOPTf7atfbV2L7RmtA/RqmdQuXVyKDi7WXRkC5hji4ZTkbYAQB4hINFJ7Us84iWZR7RvsITNeOBft4a1SdKE/rH6PJu4fJt4rYMaL4IOwAAt9SQTTfzS8r1z+/OBJzvDpfUjPv5eGlkj/aa0D9WV/WMaNCmmvBchB0AgNu50KabqQlhZ3rhbDuijQeLazbZ9PayaFjXcE3oH6NRfSIVTBdjnEXYAQC4lfo23bSWlGvm4q3ysqhWs79BndppQv8Yje0brfA2/i6tFc0DYQcA4DYutOnmOXZD6h0dpIlJsbq+f4xi27ZyWX1ongg7AAC30dBNN/9wfR9WRaHBeCUdAOAWik9WNnjTzcKyiwci4Bzu7AAATHX4h1N68+tsLdmUW2vbhgth0000BmEHAGCK7/NL9dqaA1qWeUS2s28c94kJUt7xcpWcqmLTTTgMYQcA4DKGYWjTwR/06pr9+uL7wprxYV3DdM8VXTWsa5hW7cxn0004FGEHAOB0druhz3cV6NU1+7U157gkyWKRxiVGa+YVXdS3Q0jNXDbdhKMRdgAATlNZbdfSbXl6be2Bmi0c/Hy8dOPADrprRGclhAee9zg23YQjEXYAAA53oqJaf9uYo/nfZNfcnQny99GtQ+J127BODXrBmE034SiEHQCAwxw7UaEF6w5q0fpDKjldJUmKCPLX7Zcn6JbBcWzhAFMQdgAAlyy3+JTe+PqAlmzKVUW1XZLUOTxQd43orMkDY+Xvw0acMA9hBwDQZFlHSvXqmv36dLu1Zvl4/w4hmnlFF43qE8U7NnALhB0AQKMYhqH/HCjWq2v2a82eozXjI7q318wrOmtI5zBZLIQcuA/CDgCgQex2Q59lFWjemv3KzD0uSfKySNf1i9HdIzorMTbkwicATELYAYAWzmY3LrjEu6Lapk8yziwfP3D0pCTJ38dLN6V01J3DOysurLVZpQMNQtgBgBZs5Q5rneZ90Web9w3rGq73zy4fLyitkCQFB/ho2pBOmjGsk8Lb+JtVNtAohB0AaKFW7rDqnsVb6+xBZS0p18zFWxXg66XyqjMrq6KCA3TH5Qm6eXCc2vjzqwPNC/+PBYAWyGY3NHd51nk32zynvMquhPDWuufKrpqUFCs/Hy+X1Qc4EmEHAFqgjdnFtR5d1eePk/pqaNdwF1QEOA8xHQBaoMKyiwcdSTp6osLJlQDOR9gBgBbmh5OV+mxnfoPmNmQPK8Dd8RgLAFqIkxXVmv9Ntt5Ye0BlFdUXnGuRFBVyZhk60NwRdgDAw1VU2/Tehhy9/MU+HTtZKUnqHR2skT3bK/3L/ZJU60Xlcx125ozvzXYP8AiEHQDwUDa7oY8z8vSX1XuUd/y0JKlTWGvNGtVD1/eNlpeXRX1jQ+r02Yk622dnTGK0WaUDDuV2YSc9PV3PPvusrFar+vTpoxdeeEHDhw+vd/67776rZ555Rnv37lVISIjGjBmj5557TmFhYS6sGgDch2EYWrWzQM9/tlt7C09IkiKD/fXfV3fXL1M6yNf7x9c1xyRG69reURfsoAw0dxbDMC7UZsGllixZoqlTpyo9PV3Dhg3Ta6+9pjfffFNZWVmKi4urM/+bb77RFVdcob/85S8aP3688vLyNHPmTHXr1k0ff/xxg75naWmpQkJCVFJSouDgYEf/lQDApdbtK9KfVu2u2bsqpJWv7r2yi6YP7aQAX29ziwMcqDG/v90q7AwePFgDBw7UvHnzasZ69eqlSZMmKS0trc785557TvPmzdP+/ftrxl566SU988wzys3NbdD3JOwA8ASZucf17Krd+mZfkSSpla+37rg8QXeO6KyQVr4mVwc4XmN+f7vN0vPKykpt2bJFo0aNqjU+atQorVu37rzHDB06VIcPH9aKFStkGIYKCgr00Ucf6brrrqv3+1RUVKi0tLTWFwA0V/sKT+iexVs08ZVv9c2+Ivl6WzRjaCetfXikHhrdg6ADyI3e2SkqKpLNZlNkZGSt8cjISOXnn78fxNChQ/Xuu+9qypQpKi8vV3V1tSZMmKCXXnqp3u+TlpamuXPnOrR2AHC1vOOn9eLne/TRlsOyG5LFIk0eEKsHr+mujqHsQg78lNvc2TnHYqn9UpxhGHXGzsnKytJvfvMbPfHEE9qyZYtWrlyp7OxszZw5s97zz549WyUlJTVfDX3cBQDu4NiJCj21PEsjn/1KH2w+E3Su7R2plf89Qn++KYmgA5yH29zZCQ8Pl7e3d527OIWFhXXu9pyTlpamYcOG6Xe/+50kqV+/fgoMDNTw4cP19NNPKzq67rJJf39/+fv7O/4vAABOVFZepTe/ztabXx/QyUqbJOmyzqF6eExPDYxrZ3J1gHtzm7Dj5+en5ORkrV69WpMnT64ZX716tSZOnHjeY06dOiUfn9p/BW/vM6sN3Oi9awBosvIqmxb/55Be+XKffjhVJUnqGxui343uoeHdwuu98w3gR24TdiRp1qxZmjp1qlJSUjRkyBC9/vrrysnJqXksNXv2bOXl5WnRokWSpPHjx+vOO+/UvHnzNHr0aFmtVj3wwANKTU1VTEyMmX8VALgk1Ta7/r71sF78fK+OnG341zk8UA+N7qGxiVGEHKAR3CrsTJkyRceOHdNTTz0lq9WqxMRErVixQvHx8ZIkq9WqnJycmvkzZsxQWVmZXn75Zf32t79V27ZtddVVV+lPf/qTWX8FALgkhmHoXzvy9dxnu3Xg6ElJUnRIgB64pptuHNhBPt5u96ol4Pbcqs+OGeizA8BVbHaj3k7FhmHo671FenbVbm3PK5EktWvtq/tGdtWtl8XTEBD4mcb8/narOzsA4KlW7rDW2YMq+uweVJHBAXpm5W6tP3BMkhTo5607hnfWncMTFBRAnxzgUhF2AMDJVu6w6p7FW/Xz2+jWknLNXLy15s9+3l76f5fF6b6RXRXehlWjgKMQdgDAiWx2Q3OXZ9UJOj/3i4GxeuDa7urQjj45gKPxphsAONHG7OJaj67qc2NyR4IO4CSEHQBwosKyiwedxswD0HiEHQBwIn+fhv2YjQgKcHIlQMvFOzsA4ASGYejDLYf1x0+zLjjPIikq5MwydADOQdgBAAc7cPSEHvt4u/5zoFiSFNu2lfKOn5ZFqvWi8rkeyHPG967ptwPA8Qg7AOAgldV2vbZmv176cp8qq+0K8PXSg9d01+2XJ+jfuwrq9NmJOttnZ0xi3U2LATgOYQcAHGDzwWLN/sd27S08IUka0b29/jgpUR1Dz6ywGpMYrWt7R9XbQRmA8xB2AOASlJyu0p9Wfq/3NpzZty8s0E9PjO+tCf1j6mzW6e1l0ZAuYWaUCbRohB0AaALDMLRie76eXL5TR8sqJElTUjpq9rieatvaz+TqAPwUYQcAGunwD6f0xNKd+uL7QklS5/BA/XFyX+7aAG6KsAMADWSzG1qw7qCe/2y3TlXa5Ott0T1XdtW9V3ZhV3LAjRF2AKABduSVaPY/tmt7XokkaVCndvrfyX3VLTLI5MoAXAxhBwAu4FRltf6yeo/mf5MtuyEFBfjosXG9NCWlo7xYSQU0C4QdAKjHl98X6vef7FDe8dOSpOv7ReuJ8b3Z2gFoZgg7APAzR8sq9NQ/s7Q884ikMx2Q/2dSH13VM9LkygA0BWEHAM6y2w19sDlX/7til0rLq+VlkW4flqAHr+2uQH9+XALNFf96AUDSvsIyPfaPHdp48Mx+VomxwUqb3E99O4SYXBmAS0XYAdCiVVTblP7lfqV/tU9VNkOtfL3121HdNWNoJ/l4e5ldHgAHIOwAaLH+c+CYHvt4uw4cPSlJGtmjvf5nUqI6tGttcmUAHImwA6DFKTlVpbR/7dLfNuVKksLb+OvJCb11Xd/oOvtZAWj+CDsAPJLNbtTZYdzLIi3/zqqnlu9U0YlKSdLNqXF6dExPhbT2NbliAM5C2AHgcVbusGru8ixZS8prxtoH+at9G39lWUslSV0j2ijthr4a1CnUrDIBuAhhB4BHWbnDqnsWb5Xxs/GjZRU6WlYhHy+LfnN1N919RWf5+7CfFdASEHYAeAyb3dDc5Vl1gs5PtQv0030ju8qbrR6AFoN1lQA8xsbs4lqPrs7naFmFNmYXu6giAO6AsAPAYxSWXTjoNHYeAM9A2AHgMRq6QScbeQItC2EHgMfo3D7wgu/iWCRFh5xZhg6g5SDsAPAIpyqrddeizbLZz/968rkINGd8b15OBloYwg6AZq/aZtf972Uo83CJ2rX21ZMTeis6pPajqqiQAM27daDGJEabVCUAs7D0HECzZhiG/rB0h774vlD+Pl56c/ogJce309TLOtXpoMwdHaBlIuwAaNZe+mKf3t+YKy+L9NebByg5vp0kydvLoiFdwkyuDoA74DEWgGbrg825+vPqPZKkuRP6aHSfKJMrAuCOCDsAmqWvdhdq9j+2S5LuubKLpg7pZG5BANwWYQdAs7P9cInufXerbHZDkwfE6uHRPcwuCYAbI+wAaFZyjp3SbQs26lSlTZd3Ddefbuwni4UXjwHUj7ADoNkoPlmp6W9vVNGJSvWKDta8WwfKz4cfYwAujJ8SAJqF05U23bFwk7KLTiq2bSstuG2QggJ8zS4LQDNA2AHg9mx2Q7/5W4Yyco4rpJWvFt4+SJHB7G8FoGEIOwDcmmEYmrNsh1ZnFcjPx0tvTk9R14ggs8sC0IwQdgC4tfSv9mvxf3JksUgvTknSoE5s4gmgcQg7ANzWP7Ye1rOrdkuSnri+t8b2ZV8rAI1H2AHglr7ee1QPf/SdJOmuEZ1127AEkysC0FwRdgC4nZ1HSnTP4q2qthsa3z9Gj47paXZJAJoxwg4At5JbfEoz3t6kExXVGtI5TM/9sp+82K0cwCUg7ABwG8dPVWrG2xt1tKxCPSKD9OrUZPn7eJtdFoBmjrADwC2UV9n064Wbtf/oSUWHBGjB7YMU0oqmgQAuHWEHgOlsdkMP/G2bNh/6QUEBPlp4e6qiQ1qZXRYAD0HYAWAqwzD0P//M0sqd+fLz9tIb01LUPZKmgQAch7ADwFSvrz2gBesOSpKev6m/LuscZm5BADwOYQeAaZZuy1Pav76XJP3+ul4a3z/G5IoAeCLCDgBTrNtXpIc+zJQk3T4sQb8e3tnkigB4KsIOAJfbZS3V3e9sUZXN0HV9o/X763qZXRIAD0bYAeBSecdPa8bbG1VWUa3UhFA9f1N/mgYCcCrCDgCXKTlVpRlvbVRBaYW6RbTRG1NTFOBL00AAzkXYAeAS5VU23fnOZu0tPKHIYH8tuD1VIa1pGgjA+dwu7KSnpyshIUEBAQFKTk7W119/fcH5FRUVevzxxxUfHy9/f3916dJFb731louqBdAQdruh336YqY3ZxWrj76O3Z6Qqti1NAwG4ho/ZBfzUkiVL9MADDyg9PV3Dhg3Ta6+9prFjxyorK0txcXHnPeamm25SQUGB5s+fr65du6qwsFDV1dUurhzAhfxxxS59+p1Vvt4WvTY1Wb1jgs0uCUALYjEMwzC7iHMGDx6sgQMHat68eTVjvXr10qRJk5SWllZn/sqVK/WrX/1KBw4cUGhoaJO+Z2lpqUJCQlRSUqLgYH4AA4725tcH9PSnuyRJL/4qSROTYk2uCIAnaMzvb7d5jFVZWaktW7Zo1KhRtcZHjRqldevWnfeYZcuWKSUlRc8884xiY2PVvXt3PfTQQzp9+nS936eiokKlpaW1vgA4xz+/O1ITdB4d25OgA8AUbvMYq6ioSDabTZGRkbXGIyMjlZ+ff95jDhw4oG+++UYBAQH6+OOPVVRUpHvvvVfFxcX1vreTlpamuXPnOrx+ALX958AxzVpypmng9CHxunsETQMBmMNt7uycY7HU7rdhGEadsXPsdrssFoveffddpaamaty4cfrzn/+sBQsW1Ht3Z/bs2SopKan5ys3NdfjfAWjp9hSU6a5Fm1Vps2t0n0g9Mb5Pvf+OAcDZ3ObOTnh4uLy9vevcxSksLKxzt+ec6OhoxcbGKiQkpGasV69eMgxDhw8fVrdu3eoc4+/vL39/f8cWD7RgNruhjdnFKiwrV0RQgDqGttL0tzaqtLxaKfHt9OKvBsibpoEATOQ2YcfPz0/JyclavXq1Jk+eXDO+evVqTZw48bzHDBs2TB9++KFOnDihNm3aSJL27NkjLy8vdejQwSV1Ay3Zyh1WzV2eJWtJec2Yj5dF1XZDndsH6o1pNA0EYD63eow1a9Ysvfnmm3rrrbe0a9cuPfjgg8rJydHMmTMlnXkENW3atJr5t9xyi8LCwnTbbbcpKytLa9eu1e9+9zvdfvvtatWKHh6AM63cYdU9i7fWCjqSVG0/s8Dz9mEJahfoZ0ZpAFCL29zZkaQpU6bo2LFjeuqpp2S1WpWYmKgVK1YoPj5ekmS1WpWTk1Mzv02bNlq9erX+67/+SykpKQoLC9NNN92kp59+2qy/AtAi2OyG5i7P0oX6Vrzy5T7dnBrHIywApnOrPjtmoM8O0Hjr9x/TzW/856Lz3r/zMg3pEuaCigC0NM2yzw6A5qOwrPzikxoxDwCcibADoNEiggIcOg8AnImwA6DRUhNC1b5N/S0cLJKiQwKUmtC0bVwAwJEIOwAa7UR5tbzq+elx7nXkOeN783IyALdA2AHQKFU2u+57b6sKSivUtrWvIoJq3+GJCgnQvFsHakxitEkVAkBtbrX0HIB7MwxDTy7bqW/2Fam1n7fe/fVg9YwKrtVBOTUhlDs6ANwKYQdAgy1Yd1DvbsiRxSK9MCVJfWLObNXC8nIA7swhj7GKiorqjO3fv98RpwbgJr7cXaj/+WeWJOnRMT01qk+UyRUBQMM4JOwMGzZMf/vb3ySduc39/PPP17ufFYDmZ3d+mf7rvQzZDemXyR1014jOZpcEAA3mkLCzdu1affDBB5o4caIuv/xyHTp0SBs2bHDEqQGYrOhEhe5YuEknKqqVmhCqP07uK4uFd3IANB8OCTsREREaPHiwdu3aJavVqrFjxyowMNARpwZgoopqm2a+s0WHfzit+LDWeu3WZPn5sIgTQPPikJ9aQ4YM0dGjR/Xdd9/pyy+/1AsvvKDp06c74tQATGIYhmb/fbs2H/pBQQE+mj99ELuYA2iWHLIa6y9/+YuGDBkiSYqPj9eqVas0f/58R5wagEnSv9qvf2TkydvLovT/N1BdI9qYXRIANIlDws65oFNQUKCKigpJ0rXXXuuIUwMwwb+2W/Xsqt2SpCcn9NHwbu1NrggAms4hj7E++eQT9erVS126dNHo0aOVkJDAaiygmdp+uEQPfrBNkjRjaCdNvSze3IIA4BI5JOw88cQT2rBhg7p27apdu3Zp/fr1SkpKcsSpAbhQfkm5fr1ok8qr7Lqie3v9/rpeZpcEAJfMIWHH399fwcHBkqTKykqlpqYqMzPTEacG4CKnKqv160WbVFBaoW4RbfTSLQPk483KKwDNn0Pe2YmOjtbx48c1fvx4jRs3TmFhYWrfnmf8QHNhtxuatSRTO/JKFRrop7dmDFJwgK/ZZQGAQ1gMwzAcecKvvvpKZWVlGj16tPz83H+ZamlpqUJCQlRSUlJzdwpoaZ5Z+b3Sv9ovP28vvXfnYKV0CjW7JAC4oMb8/nbInZ39+/fr5Zdf1sGDB2Wz2WQYht544w0tW7bMEacH4ER/33JY6V+d2cvu/27sS9AB4HEcEnYmTZqk+++/XzfddJO8vHjGDzQXmw4Wa/Y/tkuS7hvZRTcM7GByRQDgeA4JO4GBgbr77rsdcSoALpJz7JTufmeLKm12jU2M0m+v7WF2SQDgFA4JO7Nnz9Yjjzyia665Rv7+/jXjI0aMcMTpAThYaXmV7li4ScUnK5UYG6znb+ovLy829wTgmRwSdlatWqWvvvpK+/btq3mMZbFYCDuAG6q22XX/exnaW3hCkcH+enPaILX2c8iPAgBwSw75CbdmzRrt3LlTFgv/ZQi4u6c/3aW1e44qwNdLb04bpKiQALNLAgCncsjbxKmpqdq/f78jTgXAid5Zf1AL1h2UJL0wJUl9O4SYWxAAuIBD7uxkZGQoMTFRPXr0kL+/vwzDkMVi0caNGx1xegAO8PXeo3pyeZYk6Xeje2hMYrTJFQGAazgk7CxdutQRpwHgJPsKT+jed7fKZjd0w8BY3XtlF7NLAgCXaXDYGTp0qJKSkpSUlKT+/furX79+atWqlSQpPp5dkQF3VXyyUncs3KSy8mqlxLdT2g19eb8OQIvS4LAzceJEZWZm6sUXX9SePXskSV27dlX//v1rhaDoaG6NA+6istqumYu36NCxU+oY2kqvTU2Wv4+32WUBgEs1aW+sLVu2aOLEiRoxYoR8fX21devWmtVY4eHhKigocEatTsHeWPBUhmHo4Y++04dbDivI30d/v3eoukcGmV0WADiE0/fGuuuuu/TKK69o4sSJNWMrVqzQXXfdpRkzZjTllAAc7PW1B/ThlsPyskgv3TKAoAOgxWrS0vNdu3apX79+tcbGjRun9PR0bdiwwSGFAWi6VTvz9X8rv5ckPXF9b13ZI8LkigDAPE0KO4MHD9arr75aZ7xv377KyMi45KIANN3OIyV64G/bZBjSrZfFafrQTmaXBACmatJjrPT0dF122WUqKCjQrFmzlJiYqMrKSj333HMKDAx0dI0AGqiwtFy/XrhZp6tsGt4tXHPG92HlFYAWr0lhp1evXtqwYYPuv/9+JSUlydfXV3a7XT4+Ppo/f76jawTQAOVVNt25aLOsJeXq0j5QL98yUL7eDmmSDgDNWpObCvbs2VOff/65cnJytG3bNnl5eSk5OZml54AJ7HZDv/0wU5mHS9Suta/emjFIIa18zS4LANxCo8LOY489pkmTJik1NbVmLC4uTnFxcQ4vDEDDvfDvvfr0O6t8vS169dZkxYfxOBkAzmnUPW6r1arrr79e0dHRuuuuu/Tpp5+qoqLCWbUBaICl2/L013/vlST9cXJfDe4cZnJFAOBeGhV23n77bRUUFOiDDz5Q27Zt9dvf/lbh4eG64YYbtGDBAhUVFTmrTgDnseXQD/rdR99Jku6+orNuSulockUA4H6a1EH5p3bt2qXly5dr6dKl2rx5swYPHqwJEybo5ptvVmxsrKPqdBo6KKM5sdkNbcwuVmFZuSwWae6ynTp2skrX9o7Ua7cmy8uLlVcAWobG/P6+5LDzU4WFhVq+fLmWLVum4cOH66GHHnLUqZ2GsIPmYuUOq+Yuz5K1pLzWeGzbVvrswREK9G/yegMAaHZMCzvNEWEHzcHKHVbds3ir6vvH+uqtAzUmkZWQAFoOp++NdT7ffvutDh48KJvNVjM2bdo0R50eaLFsdkNzl2fVG3QskuYuz9K1vaPkzWMsAKjDIWHn5ptvVn5+vgYMGCBvb29Jomsr4CAbs4vrPLr6KUOStaRcG7OLNaQLK7EA4OccEnYyMzOVlZXliFMB+JnCsvqDTlPmAUBL45Be8qmpqdq7d68jTgXgZyKCAhw6DwBaGofc2dm2bZsSExPVs2dP+fv7yzAMWSwWbdy40RGnB1q01IRQhQX66djJyvN+bpEUFRKg1IRQ1xYGAM2EQ8LO0qVL64zxzg7gGHbDUIDv+W/CnvtXNmd8b15OBoB6XFLYmTp1qt555x394he/OG+44c4OcOnmf5OtvOPlauPvo0A/bxWU/bhFS1RIgOaM782ycwC4gEsKO88884wk6aOPPnJIMQBqyy0+pRc+3yNJmjuhjyYNiK3poBwRdObRFXd0AODCLinsREef+a/J+Ph4hxQD4EeGYegPS3eovMquIZ3DdMPAWFksFpaXA0AjOeSdnf379+ull17SoUOHajUVXLZsmSNOD7RIK7bn66vdR+Xn7aWnJyfyHhwANJFDws6kSZN0//33a8qUKfLycshqdqBFKy2v0pPLd0qS7h3ZRV3atzG5IgBovhwSdgIDA3X33Xc74lQAJD27creOllWoc3ig7rmyi9nlAECz5pCwM3v2bD3yyCO65ppr5O/vXzM+YsQIR5weaFG25vygxRsOSZKenpwofx9vkysCgObNIWFn1apV+uqrr7Rv376ax1gWi4WwAzRSlc2ux/6xXYYh3Tiwg4Z2CTe7JABo9hwSdtasWaOdO3fyAiVwid7+Nlvf55epXWtfPX5dL7PLAQCP4LC9sfbv3++IUwEtVm7xKf1l9Zk95h4b10uhgX4mVwQAnsEhd3YyMjKUmJioHj16sDcW0ASGYeiJpTt0usqmwQmh+kVyB7NLAgCP0eCwM3ToUCUlJSkpKUn9+/dXv3791KpVK0nn3xurqdLT0/Xss8/KarWqT58+euGFFzR8+PCLHvftt9/qiiuuUGJiorZt2+awegBX+NeOfH25+6h8vS364+S+PBIGAAdqcNiZOHGiMjMz9eKLL2rPnjPt67t27ar+/fvXCkHnuio3xZIlS/TAAw8oPT1dw4YN02uvvaaxY8cqKytLcXFx9R5XUlKiadOm6eqrr1ZBQUGTvz9ghtLyKj257ExPnXuu7KquEfTUAQBHshiGYTT2oC1btmjixIkaMWKEfH19tXXr1poXlMPDw5scOAYPHqyBAwdq3rx5NWO9evXSpEmTlJaWVu9xv/rVr9StWzd5e3vrk08+adSdndLSUoWEhKikpETBwcFNqhu4FE8s3aFF6w8pITxQ//rv4QrwZak5AFxMY35/N+kF5bvuukuvvPKK3nvvPS1cuFDbt2/XP//5T0VHR+vOO+9sUtGVlZXasmWLRo0aVWt81KhRWrduXb3Hvf3229q/f7/mzJnToO9TUVGh0tLSWl+AWbblHtc7/znTU+ePkxIJOgDgBE0KO7t27VK/fv1qjY0bN07p6enasGFDkwopKiqSzWZTZGRkrfHIyEjl5+ef95i9e/fq0Ucf1bvvvisfn4Y9kUtLS1NISEjNV8eOHZtUL3Cpqm12zT7bU+eGAbEa2pWeOgDgDE0KO4MHD9arr75aZ7xv377KyMi4pIJ+/mLmuZVdP2ez2XTLLbdo7ty56t69e4PPP3v2bJWUlNR85ebmXlK9QFO9/e1B7bKWqi09dQDAqZq09Dw9PV2XXXaZCgoKNGvWLCUmJqqyslLPPfecAgMDm1RIeHi4vL2969zFKSwsrHO3R5LKysq0efNmZWRk6P7775ck2e12GYYhHx8fffbZZ7rqqqvqHOfv719rSwvADId/OKU/rz7zov9jY3sprA3/nwQAZ2lS2OnVq5c2bNig+++/X0lJSfL19ZXdbpePj4/mz5/fpEL8/PyUnJys1atXa/LkyTXjq1ev1sSJE+vMDw4O1vbt22uNpaen64svvtBHH32khISEJtUBOJthGJqzdKdOV9mUmhCqX6bQUwcAnKnJTQV79uypzz//XDk5Odq2bZu8vLyUnJx8SUvPZ82apalTpyolJUVDhgzR66+/rpycHM2cOVPSmUdQeXl5WrRokby8vJSYmFjr+IiICAUEBNQZB9zJqp35+vf3hfL1tuh/JyfSUwcAnOySOyjHxcVdsAdOY0yZMkXHjh3TU089JavVqsTERK1YsULx8fGSJKvVqpycHId8L8AMZeVVmnO2p87MK7qoa0SQyRUBgOdrUp8dT0KfHbjSk8t2asG6g+oU1lorHxjBUnMAaCKn99kB0HiZuce1cP1BSdLTk/oSdADARQg7gAv8tKfO5AGxurwbPXUAwFUIO4ALLFh3UFnWUoW0oqcOALgaYQdwsrzjp2t66swe21Ph9NQBAJci7ABOdKanzg6dqrRpUKd2uimF7UkAwNUIO4ATrdpZoM93neup01deXvTUAQBXI+wATnKiolpPnu2pc9eIzuoWSU8dADADYQdwkuc/26380nLFhbbWf13VzexyAKDFIuwATvDd4eNauO6gJOnpSYn01AEAExF2AAerttn12MfbZTekiUkxGtG9vdklAUCLRtgBHGzh+kPakVeq4AAf/f663maXAwAtHmEHcKAjx0/r+c92S5IeHdtL7YPoqQMAZiPsAA705LKdOlVpU3J8O/1qED11AMAdEHYAB1m1M1+fZRXIx4ueOgDgTgg7gAP8vKdOjyh66gCAuyDsAA7w58/2yFpSro6hreipAwBuhrADXKIdeSVasC5bkvQ/ExPVyo+eOgDgTgg7wCWw2Q3N/seZnjrj+8foyh4RZpcEAPgZwg5wCRatP6jteSUKCvDRH67vZXY5AIDzIOwATWQtOa3nVp3rqdNTEUEBJlcEADgfwg7QRE8u26mTlTYNjGurmwfFmV0OAKAehB2gCVZnFWjVzrM9dW6gpw4AuDPCDtBIJyuqNWfpDknSr4d3Vs+oYJMrAgBcCGEHaKS/rN6jIyXl6tCulf77anrqAIC7I+wAjbAjr0RvfXu2p84keuoAQHNA2AEayGY39NjHZ3rqXNcvWiPpqQMAzQJhB2igd9Yf1HeHSxTk76M51/c2uxwAQAMRdoAGyC8p13Of7ZEkPTy2pyKC6akDAM0FYQdogLnLd+pERbWSOrbV/0ulpw4ANCc+ZhcAuCOb3dDG7GIVlpUrt/iU/rUjX95eFqXRUwcAmh3CDvAzK3dYNXd5lqwl5bXGr+oZoV7R9NQBgOaGx1jAT6zcYdU9i7fWCTqS9HlWgVbusJpQFQDgUhB2gLNsdkNzl2fJuMCcucuzZLNfaAYAwN0QdoCzNmYXn/eOzjmGJGtJuTZmF7uuKADAJSPsAGcVltUfdJoyDwDgHgg7wFkRQQ3rndPQeQAA90DYAc5KTQhV21a+9X5ukRQdEqDUhFDXFQUAuGSEHeCsrTk/6ERF9Xk/O9dZZ8743vKmzw4ANCuEHUDSoWMnddeizaq2G0rq2FZRP9sOIiokQPNuHagxidEmVQgAaCqaCqLFKzlVpdsXbNIPp6rUNzZE7995mfx8vGo6KEcEnXl0xR0dAGieCDto0apsdt3z7hbtP3pS0SEBenN6ilr5eUuShnQJM7k6AIAj8BgLLZZhGPrDJzu0bv8xBfp5a/70QYpkN3MA8DiEHbRYb3x9QH/blCsvi/TXmweodwz7XgGAJyLsoEVauSNfaf/6XpL0++t66+pekSZXBABwFsIOWpzth0v0wJIMGYY09bJ43Task9klAQCciLCDFsVaclp3LNyk8iq7RnRvrznje8tiYZUVAHgywg5ajJMV1bpjwWYVllWoe2QbvXzLAPl4808AADwdP+nRItjshv77bxnKspYqvI2f5k8fpOCA+reGAAB4DsIOWoT/XbFLn+8qlJ+Pl16flqKOoa3NLgkA4CKEHXi8xf85pPnfZEuSnv9lfw2Ma2dyRQAAVyLswKOt3XNUc5btlCT99truGt8/xuSKAACuRtiBx9pTUKb73t0qm93QDQNidf9VXc0uCQBgAsIOPFLRiQrdvmCTyiqqldopVGk39mWJOQC0UIQdeJzyKpvuXLRZh384rfiw1np1arL8fbzNLgsAYBLCDjyK3W7ooQ8zlZFzXMEBPnprxiCFBvqZXRYAwESEHXiUFz7fo39+Z5WPl0WvTk1Wl/ZtzC4JAGAywg48xscZh/XXL/ZJkv53cl8N7RJuckUAAHdA2IFH2JhdrEc+2i5JmnlFF900qKPJFQEA3AVhB83ewaKTuvudzaq02TWmT5QeHt3D7JIAAG6EsINmreRUlW5fuEk/nKpSvw4h+suUJHl5scQcAPAjtws76enpSkhIUEBAgJKTk/X111/XO/cf//iHrr32WrVv317BwcEaMmSIVq1a5cJqYabKartmLt6iA0dPKjokQG9OS1ErP5aYAwBqc6uws2TJEj3wwAN6/PHHlZGRoeHDh2vs2LHKyck57/y1a9fq2muv1YoVK7RlyxaNHDlS48ePV0ZGhosrh6sZhqE/fLJD6w8cU6Cft+ZPH6SI4ACzywIAuCGLYRiG2UWcM3jwYA0cOFDz5s2rGevVq5cmTZqktLS0Bp2jT58+mjJlip544okGzS8tLVVISIhKSkoUHBzcpLrheq+t2a+0f30vL4v05vQUXdUz0uySAAAu1Jjf325zZ6eyslJbtmzRqFGjao2PGjVK69ata9A57Ha7ysrKFBoaWu+ciooKlZaW1vpC87Jyh1X/t/J7SdIfru9N0AEAXJDbhJ2ioiLZbDZFRtb+xRUZGan8/PwGneP555/XyZMnddNNN9U7Jy0tTSEhITVfHTuyRLk5+e7wcT2wZJsMQ5p6WbxmDO1kdkkAADfnNmHnnJ9v1mgYRoM2cHz//ff15JNPasmSJYqIiKh33uzZs1VSUlLzlZube8k1wzWOHD+tXy/crPIqu67o3l5zxvdmc08AwEX5mF3AOeHh4fL29q5zF6ewsLDO3Z6fW7Jkie644w59+OGHuuaaay4419/fX/7+/pdcL1zrREW17li4WYVlFeoRGaSXbxkgH2+3y+oAADfkNr8t/Pz8lJycrNWrV9caX716tYYOHVrvce+//75mzJih9957T9ddd52zy4QJbHZDv3k/Q7uspQpv46f5M1IUFOBrdlkAgGbCbe7sSNKsWbM0depUpaSkaMiQIXr99deVk5OjmTNnSjrzCCovL0+LFi2SdCboTJs2TS+++KIuu+yymrtCrVq1UkhIiGl/DzjWHz/dpS++L5S/j5den5aiDu1am10SAKAZcauwM2XKFB07dkxPPfWUrFarEhMTtWLFCsXHx0uSrFZrrZ47r732mqqrq3XffffpvvvuqxmfPn26FixY4Ory4QTvrD+ot77NliQ9f1N/DYxrZ3JFAIDmxq367JiBPjvua82eo7p9wSbZ7IYeGtVd91/VzeySAABuoln22QF+and+me5/d6tsdkM3DIzVfSO7ml0SAKCZIuzA7Rwtq9DtCzaprKJaqZ1ClXZDX5aYAwCazK3e2UHLY7Mb2phdrMKyckUEBahfhxDduWiz8o6fVqew1nptarL8fdjcEwDQdIQdmGblDqvmLs+StaS8ZizA10vlVXaFtPLV/BmD1C7Qz8QKAQCegLADU6zcYdU9i7fq52/Hl1fZJUm3DeukLu3buL4wAIDH4Z0duJzNbmju8qw6QeenlmzKlc3eohcKAgAchLADl9uYXVzr0dX5WEvKtTG72EUVAQA8GWEHLldYduGg09h5AABcCGEHLhcRFODQeQAAXAhhBy6XmhCqyKD6d563SIoOCVBqQqjrigIAeCzCDlyustqu1v7n751zrnXgnPG95e1FI0EAwKUj7MClqm123f/eVmUXnVIrXy+Ft6ndRycqJEDzbh2oMYnRJlUIAPA09NmByxiGocc+3q5/f18ofx8vvXPHYA2Ia1erg3JqQih3dAAADkXYgcs8/9kefbD5sLws0ks3D1BKpzPv5AzpEmZyZQAAT8ZjLLjEwnUH9fKX+yRJf5zcV6P6RJlcEQCgpSDswOk+/c6qJ5fvlCQ9eE133ZwaZ3JFAICWhLADp1q//5geXLJNhiH9v8Fx+s3VXc0uCQDQwhB24DRZR0p116LNqrTZNaZPlJ6amCiLhZePAQCuRdiBU+QWn9L0tzeqrKJaqZ1C9cKvklhlBQAwBWEHDnfsRIWmv7VRR8sq1CMySG9MT1GA7/mbCAIA4GyEHTjUqcpq3b5wsw4UnVRs21ZaeHuqQlr5ml0WAKAFI+zAYapsdt377lZl5h5X29a+Wnj7IEWFsJknAMBchB04hGEYevTv2/XV7qMK8PXS/OmD1DUiyOyyAAAg7MAx/rRyt/6+9bC8vSx65ZaBSo5vZ3ZJAABIIuzAAd76JluvrtkvSUq7oa+u7hVpckUAAPyIsINLsjzziP7n0yxJ0u9G99BNKR1NrggAgNoIO2iyb/cVadYHZ7ojTxsSr3uv7GJ2SQAA1EHYQZPsyCvR3e9sUZXN0Li+UZozvg/dkQEAbomwg0bLOXZKM97epBMV1bqsc6j+fBPdkQEA7ouwg0YpOlGhaW9tUNGJCvWKDtbr0+iODABwb4QdNNjJimrdvmCTDh47daY78m2DFBxAd2QAgHsj7KBBKqvtmrl4i747XKJ2rX216I5URQTTHRkA4P4IO7gou93Qwx9l6uu9RWrl6623ZgxSl/ZtzC4LAIAGIezgov5v5ff6ZNsR+XhZlH7rQA2IozsyAKD5IOzggt78+oBeX3tAkvSnG/tpZI8IkysCAKBxCDuo19JteXr6012SpEfG9NSNyR1MrggAgMYj7OC8vt57VA99mClJum1YJ828orPJFQEA0DSEHdSx/XCJZp7tjjy+f4z+cF1vuiMDAJotwg5qOVh0UjPe3qiTlTYN6xqm537ZT150RwYANGOEHdQ4WlahaW9t1LGTleoTE6xXb02Wvw/dkQEAzRthB5KkExXVum3BRuUUn1LH0FZ6+7ZBCqI7MgDAAxB2cKY78jtbtCOvVGGBfnrn9sGKCKI7MgDAMxB2Wji73dBDH2bqm31Fau3nrbdvG6RO4YFmlwUAgMMQdlowwzD09Ke7tCzzTHfkV29NVr8Obc0uCwAAh/IxuwC4js1uaGN2sQrLyhURFKBtuT/orW+zJUnP/bK/RnRvb3KFAAA4HmGnhVi5w6q5y7NkLSmv89nj43pp0oBYE6oCAMD5CDstwModVt2zeKuMej7vGNrKpfUAAOBKvLPj4Wx2Q3OXZ9UbdCyS5i7Pks1e3wwAAJo3wo6H25hdfN5HV+cYkqwl5dqYXey6ogAAcCEeY3kowzCUkXtc6V/ta9D8wrL6AxEAAM0ZYcfD7D96Qksz8rQ084gOHTvV4ONoIggA8FSEHQ9QWFquZZlHtHTbEW3PK6kZb+XrrVG9I7R2b5GOn6o673s7FklRIQFKTQh1Wb0AALgSYaeZKiuv0sod+Vq67YjW7S/SufeLvb0sGtEtXJMGxOra3pFq7edTsxrLItUKPOf2Mp8zvre82dkcAOChCDvNSGW1XWv2HNUnGXn6fFeBKqrtNZ8NjGurSQNidV3faIW18a913JjEaM27dWCdPjtRIQGaM763xiRGu+zvAACAqxF23JzdbmjzoR/0ybY8rdhu1fFTVTWfdWkfqElJsZqYFKu4sNYXPM+YxGhd2zuqVgfl1IRQ7ugAADweYcdN7c4v0yfb8rRs2xHlHT9dMx4R5K8J/WM0aUCs+sQEy2JpeFjx9rJoSJcwZ5QLAIDbIuy4kSPHT2tZ5hF9kpGn7/PLasaD/H00JjFKkwbE6rLOYdyNAQCgEQg7TvDzDTcv9Lio5FSVVuyw6pOMPG08WCzj7BvEvt4WjewRoUkDYnVVzwgF+Hq78G8AAIDnIOw42Pk23Iz+2YvA5VU2ffF9oT7JyNNXu4+q0vbji8aDE0I1aUCsxiVGK6S1r8vrBwDA07hd2ElPT9ezzz4rq9WqPn366IUXXtDw4cPrnb9mzRrNmjVLO3fuVExMjB5++GHNnDnThRX/qL4NN/NLynXP4q3676u7Ke/4aa3cka+yiuqaz3tGBWnSgFhN6B+jmLZsygkAgCO5VdhZsmSJHnjgAaWnp2vYsGF67bXXNHbsWGVlZSkuLq7O/OzsbI0bN0533nmnFi9erG+//Vb33nuv2rdvrxtvvNGltV9ow81zYy/8e2/NWGzbVpqQFKNJSbHqERXkkhoBAGiJLIZhuM1214MHD9bAgQM1b968mrFevXpp0qRJSktLqzP/kUce0bJly7Rr166asZkzZyozM1Pr169v0PcsLS1VSEiISkpKFBwc3OTa1+8/ppvf+M9F513dK0J3j+iilPh28uJFYwAAmqQxv7/dZtfzyspKbdmyRaNGjao1PmrUKK1bt+68x6xfv77O/NGjR2vz5s2qqqo67zEVFRUqLS2t9eUIDd1Ic0L/GKUmhBJ0AABwEbcJO0VFRbLZbIqMjKw1HhkZqfz8/PMek5+ff9751dXVKioqOu8xaWlpCgkJqfnq2LGjQ+pv6EaabLgJAIBruU3YOefnTfIMw7hg47zzzT/f+DmzZ89WSUlJzVdubu4lVnxGakKookMCVF+lFp1ZlcWGmwAAuJbbhJ3w8HB5e3vXuYtTWFhY5+7NOVFRUeed7+Pjo7Cw83cK9vf3V3BwcK0vR/D2smjO+N6SVCfwsOEmAADmcZuw4+fnp+TkZK1evbrW+OrVqzV06NDzHjNkyJA68z/77DOlpKTI19f1PWrObbgZFVL7UVVUSIDm3TqQDTcBADCBWy09nzVrlqZOnaqUlBQNGTJEr7/+unJycmr65syePVt5eXlatGiRpDMrr15++WXNmjVLd955p9avX6/58+fr/fffN+3vwIabAAC4F7cKO1OmTNGxY8f01FNPyWq1KjExUStWrFB8fLwkyWq1Kicnp2Z+QkKCVqxYoQcffFCvvPKKYmJi9Ne//tXlPXZ+jg03AQBwH27VZ8cMjuqzAwAAXKdZ9tkBAABwBsIOAADwaIQdAADg0Qg7AADAoxF2AACARyPsAAAAj0bYAQAAHo2wAwAAPJpbdVA2w7meiqWlpSZXAgAAGurc7+2G9EZu8WGnrKxMktSxY0eTKwEAAI1VVlamkJCQC85p8dtF2O12HTlyREFBQbJYHLtZ56BBg7Rp0yaHntMR523s8Q2df7F5F/q8sZ+VlpaqY8eOys3NdattPrjmDf+8MZ+56/WWuOaN+Zxr7rzzmnW9Lzanvs8c8XPdMAyVlZUpJiZGXl4Xfiunxd/Z8fLyUocOHZxybm9vb6f8I73U8zb2+IbOv9i8C33e1M+Cg4Pd6gch17zhnzflM3e73hLXvDGfc82dd16zrvfF5tT3maN+rl/sjs45vKDsRPfdd59bnrexxzd0/sXmXejzpn7mbrjmDf+ca+7c83LNnccdr7lZ1/tic+r7zNXXu8U/xkLzxG71LQvXu+Xhmrc8zrzm3NlBs+Tv7685c+bI39/f7FLgAlzvlodr3vI485pzZwcAAHg07uwAAACPRtgBAAAejbADAAA8GmEHAAB4NMIOAADwaIQdeJzJkyerXbt2+sUvfmF2KXCB3NxcXXnllerdu7f69eunDz/80OyS4GRlZWUaNGiQkpKS1LdvX73xxhtmlwQXOHXqlOLj4/XQQw81+liWnsPjfPnllzpx4oQWLlyojz76yOxy4GRWq1UFBQVKSkpSYWGhBg4cqN27dyswMNDs0uAkNptNFRUVat26tU6dOqXExERt2rRJYWFhZpcGJ3r88ce1d+9excXF6bnnnmvUsdzZgccZOXKkgoKCzC4DLhIdHa2kpCRJUkREhEJDQ1VcXGxuUXAqb29vtW7dWpJUXl4um80m/rvds+3du1fff/+9xo0b16TjCTtwK2vXrtX48eMVExMji8WiTz75pM6c9PR0JSQkKCAgQMnJyfr6669dXygcxpHXfPPmzbLb7erYsaOTq8alcMQ1P378uPr3768OHTro4YcfVnh4uIuqR2M54no/9NBDSktLa3INhB24lZMnT6p///56+eWXz/v5kiVL9MADD+jxxx9XRkaGhg8frrFjxyonJ8fFlcJRHHXNjx07pmnTpun11193Rdm4BI645m3btlVmZqays7P13nvvqaCgwFXlo5Eu9XovXbpU3bt3V/fu3ZtehAG4KUnGxx9/XGssNTXVmDlzZq2xnj17Go8++mitsS+//NK48cYbnV0iHKyp17y8vNwYPny4sWjRIleUCQe6lH/n58ycOdP44IMPnFUiHKgp1/vRRx81OnToYMTHxxthYWFGcHCwMXfu3EZ9X+7soNmorKzUli1bNGrUqFrjo0aN0rp160yqCs7UkGtuGIZmzJihq666SlOnTjWjTDhQQ655QUGBSktLJZ3ZKXvt2rXq0aOHy2vFpWvI9U5LS1Nubq4OHjyo5557TnfeeaeeeOKJRn0fH4dVDDhZUVGRbDabIiMja41HRkYqPz+/5s+jR4/W1q1bdfLkSXXo0EEff/yxBg0a5Opy4QANuebffvutlixZon79+tW8C/DOO++ob9++ri4XDtCQa3748GHdcccdMgxDhmHo/vvvV79+/cwoF5eooT/XLxVhB82OxWKp9WfDMGqNrVq1ytUlwckudM0vv/xy2e12M8qCE13omicnJ2vbtm0mVAVnudjP9XNmzJjRpPPzGAvNRnh4uLy9veuk/cLCwjr/VQDPwDVvebjmLYurrjdhB82Gn5+fkpOTtXr16lrjq1ev1tChQ02qCs7ENW95uOYti6uuN4+x4FZOnDihffv21fw5Oztb27ZtU2hoqOLi4jRr1ixNnTpVKSkpGjJkiF5//XXl5ORo5syZJlaNS8E1b3m45i2LW1zvpi0eA5zjyy+/NCTV+Zo+fXrNnFdeecWIj483/Pz8jIEDBxpr1qwxr2BcMq55y8M1b1nc4XqzNxYAAPBovLMDAAA8GmEHAAB4NMIOAADwaIQdAADg0Qg7AADAoxF2AACARyPsAAAAj0bYAQAAHo2wAwAAPBphBwAAeDTCDgAA8GiEHQAeZ9++fbJYLPr000919dVXq3Xr1urRo4c2bNhgdmkATEDYAeBxMjMzZbFY9Pzzz+v3v/+9MjMzFRcXp0cffdTs0gCYgLADwONkZmYqJCRES5Ys0ciRI9WtWzdNmjRJR48eNbs0ACYg7ADwOJmZmRo/frzat29fM3bgwAF17drVxKoAmIWwA8DjZGZmasiQIbXGMjIylJSUZE5BAExF2AHgUUpKSnTo0CENGDCg1vi2bdsIO0ALRdgB4FEyMzPl7e2t/v3714wdOnRIP/zwA2EHaKEIOwA8SmZmpnr27KlWrVrVjGVkZKht27bq1KmTeYUBMI3FMAzD7CIAAACchTs7AADAoxF2AACARyPsAAAAj0bYAQAAHo2wAwAAPBphBwAAeDTCDgAA8GiEHQAA4NEIOwAAwKMRdgAAgEcj7AAAAI9G2AEAAB7t/wM4nRiELpSymQAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "nr_vectors = 10_000\n", + "dims = np.logspace(1, 13, 13, base=2).astype(np.int32)\n", + "figure, axis = plt.subplots()\n", + "axis.plot(dims, [near_far_ratio(rng, nr_vectors=nr_vectors, nr_dims=nr_dims) for nr_dims in dims], 'o-')\n", + "axis.set_xscale('log')\n", + "axis.set_xlabel('$n$')\n", + "axis.set_ylabel(r'$d_{\\mathrm{min}}/d_{\\mathrm{max}}$');" + ] + }, + { + "cell_type": "markdown", + "id": "2ff17692-22ce-41a7-83b1-aa47e2ae4c31", + "metadata": {}, + "source": [ + "In high dimensions, the nearest and the farest point from the query vector are at almost equal distance." ] }, { @@ -268,36 +394,36 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 16, "id": "8dc266a8-7e60-4a87-91c6-2e1657b08e1f", "metadata": {}, "outputs": [], "source": [ - "def compute_fraction(dim, nr_points):\n", - " points = np.random.uniform(-1.0, 1.0, size=(nr_points, dim))\n", + "def compute_fraction(rng, dim, nr_points):\n", + " points = rng.uniform(-1.0, 1.0, size=(nr_points, dim))\n", " return np.sum(np.where(np.sum(points**2, axis=1) < 1.0, 1, 0))/points.shape[0]" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 17, "id": "b573687a-a468-4395-8b80-63f21a9a4414", "metadata": {}, "outputs": [], "source": [ "dims = list(range(1, 16))\n", - "ratios = [compute_fraction(dim, 10_000_000) for dim in dims]" + "ratios = [compute_fraction(rng, dim, 10_000_000) for dim in dims]" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 18, "id": "0948847e-154a-452e-80fa-b0da0c95f870", "metadata": {}, "outputs": [ { "data": { - "image/png": "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bdu2JicJrAceeEDXXnutfvzjH5sdJeCWLl2qAQMG6Oabb1ZcXJz69eunl156yexYATNs2DB9/PHH2r59uyRpw4YNWrVqla655hqTk5kjNzdXhYWFGjlyZO22qKgoXX755fr8889NTGYej8cjm80WNqObUvXFqMePH6+HHnpIPXv2NDtOQIX1BTqtzDAMTZs2TcOGDVN6errZcQLmH//4h7KysvTVV1+ZHcUUu3bt0ty5czVt2jT95je/0dq1azV58mRFRUVpwoQJZsdrdtOnT5fH49HFF18sh8Mhr9erP/7xj7r11lvNjmaKwsJCSVJ8fHyd7fHx8crLyzMjkqnKysr061//WrfddpslL1jZmMcff1xOp1OTJ082O0rAUXIs6uc//7m+/vprrVq1yuwoAbNnzx5NmTJFH330kVwul9lxTOHz+TRgwAA99thjkqR+/fpp8+bNmjt3bliUnEWLFmnBggV688031bNnT+Xk5Gjq1KlKSkrSHXfcYXY809hstjr3DcOot83qKisrdcstt8jn82nOnDlmxwmY9evX6+mnn1ZWVlbY/TeXOPDYkn7xi19o6dKl+vTTT9WpUyez4wTM+vXrVVRUpIyMDDmdTjmdTi1fvlzPPPOMnE6nvF6v2RGbXWJionr06FFnW/fu3ZWfn29SosB66KGH9Otf/1q33HKLevXqpfHjx+vBBx/UrFmzzI5mioSEBEnfj+jUKCoqqje6Y2WVlZUaO3ascnNzlZmZGVajOCtXrlRRUZFSUlJqfy/m5eXpl7/8pTp37mx2vGbHSI6FGIahX/ziF1qyZIk+++wzpaWlmR0poK666ipt3Lixzra77rpLF198saZPny6Hw2FSssAZOnRovWUDtm/frtTUVJMSBdbx48dlt9f9t5vD4bD0KeSnk5aWpoSEBGVmZqpfv36SpIqKCi1fvlyPP/64yekCo6bgfPvtt/r000/Vrl07syMF1Pjx4+sdn3j11Vdr/Pjxuuuuu0xKFTiUHAt54IEH9Oabb+q9995TTExM7b/e3G63oqOjTU7X/GJiYuodf9SyZUu1a9cubI5LevDBBzVkyBA99thjGjt2rNauXasXX3xRL774otnRAmLMmDH64x//qJSUFPXs2VPZ2dl66qmndPfdd5sdrdkcO3ZMO3bsqL2fm5urnJwctW3bVikpKZo6daoee+wxde3aVV27dtVjjz2mFi1a6LbbbjMxtf+c7v0nJSXppptuUlZWlv71r3/J6/XW/l5s27atIiMjzYrtV2f6GfhhsYuIiFBCQoK6desW6KiBZ/LZXfAjSQ3eXnnlFbOjmSbcTiE3DMN4//33jfT0dCMqKsq4+OKLjRdffNHsSAFTXFxsTJkyxUhJSTFcLpfRpUsX4+GHHzbKy8vNjtZsPv300wb/v7/jjjsMw6g+jXzmzJlGQkKCERUVZVx22WXGxo0bzQ3tR6d7/7m5uY3+Xvz000/Nju43Z/oZ+KFwOoXcZhiGEaA+BQAAEDAceAwAACyJkgMAACyJkgMAACyJkgMAACyJkgMAACyJkgMAACyJkgMAACyJkgMAACyJkgMAACyJkgPA8v70pz9p8ODBZscAEGCUHACWt2HDBvXp08fsGAACjJIDwPI2bNigvn37mh0DQIBRcgBYytatW/WjH/1I0dHR6tevn9atW6ft27czkgOEIUoOAMv45ptvNGjQIA0YMECbNm3S7373O/30pz+VYRjq3bu32fEABJjNMAzD7BAA4A9XXXWVkpKS9Pe//71226233qqsrCxt27bNxGQAzOA0OwAA+ENeXp4++eQTZWVl1dkeERHBVBUQppiuAmAJOTk5cjqd6tWrV53tWVlZHHQMhClKDgBLsNvt8vl8qqioqN22bNkybd68mZIDhClKDgBLyMjIUEREhH71q19p165dWrp0qe69915JYroKCFMceAzAMhYsWKAZM2aotLRU/fr106BBg/TSSy/pwIEDZkcDYAJKDgAAsCSmqwAAgCVRcgAAgCVRcgAAgCVRcgAAgCVRcgAAgCVRcgAAgCVRcgAAgCVRcgAAgCVRcgAAgCVRcgAAgCVRcgAAgCX9f4tiHiLJcqQZAAAAAElFTkSuQmCC", + "image/png": "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N998s/HQQw/V23bbbbcZ48ePNymRd0kyli5dWnff7XYbcXFxxq9//eu6bWVlZYbD4TDeeustExK2rLPff2M2btxoSDL27dvnnVBe1tT3YP/+/UbHjh2N7Oxso3Pnzsbvfvc7r2czAyM5AczpdEqSoqOjTU7iXY899phuvvlmff/73zc7itctW7ZMgwYN0p133qmYmBgNGDBAb7/9ttmxvGbEiBH697//rZ07d0qSvv76a61du1Y33XSTycnMkZOTo4KCAo0ePbpum91u17XXXqt169aZmMw8TqdTFoslaEY3peqLUd933316+umn1bt3b7PjeFVQX6AzkBmGoalTp2rEiBFKSUkxO47X/PnPf1ZGRoa++uors6OYYs+ePZozZ46mTp2qn//859q4caOeeOIJ2e12TZgwwex4Le6ZZ56R0+lUjx49ZLPZ5HK59Ktf/Ur33HOP2dFMUVBQIEmKjY2ttz02Nlb79u0zI5KpysrK9Oyzz+ree+8NyAtWNuXll19WSEiInnjiCbOjeB0lJ0D95Cc/0TfffKO1a9eaHcVr8vLy9OSTT+rTTz9VeHi42XFM4Xa7NWjQIL300kuSpAEDBmjr1q2aM2dOUJScxYsXa8GCBVq4cKF69+6trKwsTZkyRQkJCbr//vvNjmcai8VS775hGA22BbrKykrdfffdcrvdmj17ttlxvGbz5s16/fXXlZGREXT/zSUOPA5Ijz/+uJYtW6bPP/9cnTp1MjuO12zevFmFhYVKTU1VSEiIQkJCtGrVKv3+979XSEiIXC6X2RFbXHx8vHr16lVvW8+ePZWbm2tSIu96+umn9eyzz+ruu+9Wnz59dN999+mpp57SzJkzzY5miri4OEmnR3RqFRYWNhjdCWSVlZW66667lJOTo/T09KAaxVmzZo0KCwuVlJRU93tx3759+ulPf6ouXbqYHa/FMZITQAzD0OOPP66lS5fqiy++UHJystmRvOqGG27Qli1b6m178MEH1aNHDz3zzDOy2WwmJfOe4cOHN1g2YOfOnercubNJibzr5MmTslrr/9vNZrMF9Cnk55KcnKy4uDilp6drwIABkqSKigqtWrVKL7/8ssnpvKO24OzatUuff/652rVrZ3Ykr7rvvvsaHJ9444036r777tODDz5oUirvoeQEkMcee0wLFy7Uxx9/rMjIyLp/vTkcDkVERJicruVFRkY2OP6odevWateuXdAcl/TUU09p2LBheumll3TXXXdp48aNmjt3rubOnWt2NK9IS0vTr371KyUlJal3797KzMzUa6+9poceesjsaC2mtLRU3333Xd39nJwcZWVlKTo6WklJSZoyZYpeeuklde/eXd27d9dLL72kVq1a6d577zUxteec6/0nJCTojjvuUEZGhv7+97/L5XLV/V6Mjo5WWFiYWbE96nw/A2cXu9DQUMXFxenKK6/0dlTvM/nsLniQpEZv7777rtnRTBNsp5AbhmEsX77cSElJMex2u9GjRw9j7ty5ZkfymuLiYuPJJ580kpKSjPDwcKNr167G9OnTjfLycrOjtZjPP/+80f/v77//fsMwqk8jnzFjhhEXF2fY7XbjmmuuMbZs2WJuaA861/vPyclp8vfi559/bnZ0jznfz8DZgukUcothGIaX+hQAAIDXcOAxAAAISJQcAAAQkCg5AAAgIFFyAABAQKLkAACAgETJAQAAAYmSAwAAAhIlBwAABCRKDgAACEiUHAAB79e//rWGDh1qdgwAXkbJARDwvv76a/Xr18/sGAC8jJIDIOB9/fXX6t+/v9kxAHgZJQdAQNm+fbu+973vKSIiQgMGDNCmTZu0c+dORnKAIETJARAwduzYoSFDhmjQoEHKzs7Wc889px/+8IcyDEN9+/Y1Ox4AL7MYhmGYHQIAPOGGG25QQkKC/vSnP9Vtu+eee5SRkaFvv/3WxGQAzBBidgAA8IR9+/bps88+U0ZGRr3toaGhTFUBQYrpKgABISsrSyEhIerTp0+97RkZGRx0DAQpSg6AgGC1WuV2u1VRUVG3bcWKFdq6dSslBwhSlBwAASE1NVWhoaH62c9+pj179mjZsmV6+OGHJYnpKiBIceAxgICxYMECTZs2TSdOnNCAAQM0ZMgQvf322zp8+LDZ0QCYgJIDAAACEtNVAAAgIFFyAABAQKLkAACAgETJAQAAAYmSAwAAAhIlBwAABCRKDgAACEiUHAAAEJAoOQAAICBRcgAAQECi5AAAgID0/wEOIiAkb8boDQAAAABJRU5ErkJggg==", "text/plain": [ "
" ] @@ -307,9 +433,10 @@ } ], "source": [ - "plt.plot(dims, ratios, 'o-');\n", - "plt.xlabel('$d$');\n", - "plt.ylabel('$R_d$');" + "figure, axis = plt.subplots()\n", + "axis.plot(dims, ratios, 'o-')\n", + "axis.set_xlabel('$d$')\n", + "axis.set_ylabel('$R_d$');" ] }, { @@ -333,7 +460,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 19, "id": "39a74319-d990-4bff-8016-e4b3d6656ac7", "metadata": {}, "outputs": [], @@ -344,13 +471,13 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 20, "id": "8027123a-5f0f-4d98-92e1-69a480c50e7c", "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjkAAAGxCAYAAACA4KdFAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAASwxJREFUeJzt3Xl4U2XCxuFfku7QBgt0g4IFRSg7RbAIggrIIiPjAsoIAi7gp6IwOsigIjjK6IjiMuDCoOMCgyuCg2hHZZOdUmRHoVCU1rJIW8Buyfn+CA3UFqzQ5mR57uvKlZPTk+RJKfThfc9iMQzDQERERMTPWM0OICIiIlITVHJERETEL6nkiIiIiF9SyRERERG/pJIjIiIifkklR0RERPySSo6IiIj4pSCzA5jJ6XRy4MABIiMjsVgsZscRERGRKjAMg4KCAhISErBazzxeE9Al58CBAyQmJpodQ0RERM7B/v37adiw4Rm/HtAlJzIyEnB9k6KiokxOIyIiIlWRn59PYmKi+/f4mQR0ySmbooqKilLJERER8TG/tauJdjwWERERv6SSIyIiIn5JJUdERET8UkDvkyMiIr7H4XBQUlJidgypQcHBwdhstvN+HZUcERHxCYZhkJOTw9GjR82OIh5Qp04d4uLizus8dio5IiLiE8oKTkxMDBERETqJq58yDIMTJ06Qm5sLQHx8/Dm/lkqOiIh4PYfD4S44devWNTuO1LDw8HAAcnNziYmJOeepK+14LCIiXq9sH5yIiAiTk4inlP1Zn8/+Vyo5IiLiMzRFFTiq489a01XVzOE0WJt5hNyCQmIiw+iUFI3Nqr+UIiIinuY1IznLli1jwIABJCQkYLFYmD9//m8+Z+nSpaSkpBAWFkaTJk145ZVXaj7oWSzekk3Xp7/iltdXc/9/Mrjl9dV0fforFm/JNjWXiIjI6YYPH87AgQPP6zWWLFmCxWLx6qPdvKbkHD9+nLZt2/Lyyy9XafvMzEz69etHt27d2LhxI3/9618ZM2YMH374YQ0nrdziLdnc/U462XmF5dbn5BVy9zvpKjoiIl7C4TRYtfswn2T8yKrdh3E4DbMjSQ3xmumqvn370rdv3ypv/8orr9CoUSOmT58OQIsWLVi/fj3PPvssN9xwQw2lrJzDaTB54TbK/ppYcNLduoklzvYYgAWYvHAbvZLjNHUlImKixVuymbxwW7n/kMbbw5g0IJk+rc79UGXxTl4zkvN7rVq1it69e5dbd80117B+/foz7oldVFREfn5+uVt1WJt5xP0XxoqTuSFP8mbIP+htXQeAAWTnFbI280i1vJ+IiPx+Zo24f/DBB7Ru3Zrw8HDq1q1Lz549OX78OOvWraNXr17Uq1cPu91O9+7dSU9PL/dci8XCq6++yrXXXktERAQtWrRg1apVfP/99/To0YNatWqRmprK7t273c95/PHHadeuHa+++iqJiYlERERw0003nXVayTAMnnnmGZo0aUJ4eDht27blgw8+KLfNokWLaNasGeHh4Vx55ZXs3bu3Or9NNcJnS05OTg6xsbHl1sXGxlJaWsqhQ4cqfc7UqVOx2+3uW2JiYrVkyS049RfGiZX1zmYAPB78b2rxS6XbiYiI5/x6xP10ZesmL9xW7VNX2dnZ3HLLLYwcOZLt27ezZMkSrr/+egzDoKCggNtuu43ly5ezevVqLr74Yvr160dBQUG513jiiScYNmwYGRkZNG/enCFDhjBq1CgmTJjA+vXrAbj33nvLPef777/nvffeY+HChSxevJiMjAzuueeeM+Z85JFHeOONN5g5cyZbt25l7Nix3HrrrSxduhSA/fv3c/3119OvXz8yMjK44447ePjhh6v1e1UTvGa66lz8+vAywzAqXV9mwoQJjBs3zv04Pz+/WopOTGRYuccvlf6RAdZVNLbmMi7oA54oHVrpdiIi4hmnj7hX5vQR99Sm1XeywezsbEpLS7n++utp3LgxAK1btwbgqquuKrftq6++ygUXXMDSpUu59tpr3etHjBjBoEGDABg/fjypqak8+uijXHPNNQDcf//9jBgxotxrFRYW8u9//5uGDRsC8NJLL9G/f3+mTZtGXFxcuW2PHz/Oc889x1dffUVqaioATZo0YcWKFbz66qt0796dmTNn0qRJE55//nksFguXXHIJmzdv5umnn66ub1WN8NmRnLi4OHJycsqty83NJSgo6IxnwwwNDSUqKqrcrTp0Soom3h5GWbUqIoRHSkcCMNy2mNaWPcTbXYeTi4iI51V1JL26R9zbtm3L1VdfTevWrbnpppt4/fXX+fnnn13vlZvL6NGjadasmXuG4dixY2RlZZV7jTZt2riXy2YwyopS2brCwsJyu2A0atTIXXAAUlNTcTqd7Ny5s0LGbdu2UVhY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ySd5+OGHue222wBo0qQJTzzxBH/5y1+YNGkS//vf//j222/JzMwkMTERgLfffpuWLVuybt06Lr30UgCKi4t5++23qV+/PgBfffUVmzdvJjc31z319OyzzzJ//nw++OAD7rrrLmrXrk1QUJA7b2XmzJnDwYMHWbduHdHR0QBcdNFF7q+3bduWtm3buh//7W9/4+OPP2bBggXce++9VfreVQdNV3mDzqNd/zPI+RZ2f2l2GhER8YA2bdq4l+Pj4wHIzc0FXFNZU6ZMoXbt2u7bnXfeSXZ2NidOnGD79u0kJia6Cw5AcnIyderUYfv27e51jRs3dhecstc9duwYdevWLffamZmZ7N69u8rZMzIyaN++vbvg/Nrx48f5y1/+4s5Uu3ZtduzYQVZWVpXfozpoJMcb1KoLKcNh9QxY/hxc1NPsRCIi3i84wjWqYsb7VsfLBAe7ly0nR/DLpnucTieTJ0/m+uuvr/C8sLAwDMNwP+d0v15fq1b5ESen00l8fHy5Ka0yderUqXL28PDws379oYce4vPPP+fZZ5/loosuIjw8nBtvvJHiYs8eSayS4y1S74W1r8G+b+BABiS0MzuRiIh3s1iqPG1kppCQEByO33dgSYcOHdi5c2e5KaDTJScnk5WVxf79+92jOdu2bSMvL48WLVqc9XVzcnIICgriwgsvPOe8bdq0YdasWRw5cqTS0Zzly5czfPhw/vjHPwKufXTKdrj2JE1XeQt7A0ge6Fpe84qpUUREpPpceOGFrFmzhr1793Lo0CH3aM3ZPPbYY7z11ls8/vjjbN26le3btzNv3jweeeQRAHr27EmbNm3405/+RHp6OmvXrmXYsGF0796djh07nvF1e/bsSWpqKgMHDuTzzz9n7969rFy5kkceeYT169e782ZmZpKRkcGhQ4coKiqq8Dq33HILcXFxDBw4kG+++YY9e/bw4YcfsmrVKsC1f85HH31ERkYGmzZtYsiQIVX63NVNJcebXHa3637Lh3As19wsIiJSLR588EFsNhvJycnUr1+/SvulXHPNNXz66aekpaVx6aWXctlll/Hcc8/RuHFj4NTh3BdccAFXXHEFPXv2pEmTJsybN++sr2uxWFi0aBFXXHEFI0eOpFmzZtx8883s3buX2NhYAG644Qb69OnDlVdeSf369Zk7d26F1wkJCeGLL74gJiaGfv360bp1a/7+97+7j+B6/vnnueCCC+jSpQsDBgzgmmuuoUOHDr/3W3feLIZhGB5/Vy+Rn5+P3W4nLy+PqKgos+O4zOoJP6yDHhNOXa1cRCTAFRYWkpmZSVJSEmFhYWbHEQ842595VX9/ayTH23Qe7bpf9y8orThEKCIiIlWjkuNtkq+DyAQ4ngtbPjI7jYiIiM9SyfE2tmDodIdrec1M1xk9RURE5HdTyfFGKSMgKAyyN0HWarPTiIiI+CSVHG8UEQ1tBrmW18w0N4uIiBcJ4GNlAk51/Fmr5Hirsh2Qt38KR/ebm0VExGRlZwc+ccKEC3KKKcr+rE8/M/TvpTMee6vYlpDUHTKXwvp/Qc/HzU4kImIam81GnTp13Nd2ioiIqPSyBuL7DMPgxIkT5ObmUqdOHfe5d86FSo4363Snq+RsfAd6/BWCQsxOJCJimrKrYpcVHfFvderUOeuV0KtCJcebNesDkfFQkA07PoVWFS/UJiISKCwWC/Hx8cTExFBSUmJ2HKlBwcHB5zWCU0Ylx5vZgqHDMFj6NKyfrZIjIoJr6qo6fgGK/9OOx96uwzCwWGHvcji4y+w0IiIiPkMlx9vZG7qmrQA2vGlqFBEREV+ikuMLOo503We8CyW/mJtFRETER6jk+IKmV0GdRlB4FLZ+bHYaERERn6CS4wusNkgZ7lpeP9vUKCIiIr5CJcdXtB8K1iD4YR1kf2t2GhEREa+nkuMrasdAiwGu5Q1vmJtFRETEB6jk+JKyHZC/fQ+KjpmbRURExMup5PiSC7tBdBMoPgbb5pudRkRExKup5PgSiwXa3+paTn/b3CwiIiJeTiXH17Qd4joD8v7VOgOyiIjIWajk+JqoeLi4t2t5o0ZzREREzkQlxxe1H+q63zQXHLoSr4iISGVUcnxRs2ugVgwcPwi7Pjc7jYiIiFdSyfFFtmBoe7NrWVNWIiIilVLJ8VVlU1bffQH52eZmERER8UIqOb6qfjNIvAwMJ2yaY3YaERERr6OS48s6nBzN2fgOGIa5WURERLyMSo4vSx4IIbXhyB7Y943ZaURERLyKSo4vC60Nra53LWdoykpEROR0Kjm+rt2fXPdb5+uinSIiIqdRyfF1iZ1dF+0sOQ7bF5idRkRExGuo5Pg6iwXaDXEta8pKRETETSXHH7S5GbDA3uXw8z6z04iIiHgFlRx/UCcRkq5wLW/6j7lZREREvIRXlZwZM2aQlJREWFgYKSkpLF++/Kzbv/vuu7Rt25aIiAji4+MZMWIEhw8f9lBaL1M2ZbVpjs6ZIyIigheVnHnz5vHAAw8wceJENm7cSLdu3ejbty9ZWVmVbr9ixQqGDRvG7bffztatW3n//fdZt24dd9xxh4eTe4kWA1znzPl5L2StMjuNiIiI6bym5Dz33HPcfvvt3HHHHbRo0YLp06eTmJjIzJkzK91+9erVXHjhhYwZM4akpCS6du3KqFGjWL9+/Rnfo6ioiPz8/HI3vxFSC1oOdC1nvGtqFBEREW/gFSWnuLiYDRs20Lt373Lre/fuzcqVKyt9TpcuXfjhhx9YtGgRhmHw008/8cEHH9C/f/8zvs/UqVOx2+3uW2JiYrV+DtO1dU1ZGVs/Yc2O/XyS8SOrdh/G4dT0lYiIBB6vKDmHDh3C4XAQGxtbbn1sbCw5OTmVPqdLly68++67DB48mJCQEOLi4qhTpw4vvfTSGd9nwoQJ5OXluW/79++v1s9hukapnKiViKW4gLlvzeD+/2Rwy+ur6fr0VyzeoiuVi4hIYPGKklPGYrGUe2wYRoV1ZbZt28aYMWN47LHH2LBhA4sXLyYzM5PRo0ef8fVDQ0OJiooqd/Mni7f9xKtHOwFwo22pe31OXiF3v5OuoiMiIgHFK0pOvXr1sNlsFUZtcnNzK4zulJk6dSqXX345Dz30EG3atOGaa65hxowZzJ49m+zswPtl7nAaTF64jQ+d3QDoYt1GPK4jzcomqyYv3KapKxERCRheUXJCQkJISUkhLS2t3Pq0tDS6dOlS6XNOnDiB1Vo+vs1mA1wjQIFmbeYRsvMK+cGIYY2zOVaLwUDbqSuTG0B2XiFrM4+YF1JERMSDvKLkAIwbN45Zs2Yxe/Zstm/fztixY8nKynJPP02YMIFhw4a5tx8wYAAfffQRM2fOZM+ePXzzzTeMGTOGTp06kZCQYNbHME1uQaF7+SOHazTnj7blnBrHqbidiIiIPwsyO0CZwYMHc/jwYaZMmUJ2djatWrVi0aJFNG7cGIDs7Oxy58wZPnw4BQUFvPzyy/z5z3+mTp06XHXVVTz99NNmfQRTxUSGuZc/c3RiStCbNLP+SEvLXrYaSZVuJyIi4s8sRiDO7ZyUn5+P3W4nLy/P53dCdjgNuj79FTl5hRjAy8Evcq1tNbNL+zCldBgWIM4exorxV2GzVr4zt4iIiC+o6u9vr5mukvNjs1qYNCAZAAvwkaMrAANsKwnCAcCkAckqOCIiEjBUcvxIn1bxzLy1A3H2MJY523DIiKK+JZ8/1N7BzFs70KdVvNkRRUREPMZr9smR6tGnVTy9kuNYm3mEvG/+QL097/DsJduxquCIiEiA0UiOH7JZLaQ2rUvTnq6LlVp3LoLCPJNTiYiIeJZKjj+Lbwf1LoHSQti2wOw0IiIiHqWS488sFmh7s2t503/MzSIiIuJhKjn+rs0gwAL7VsDRrN/cXERExF+o5Pg7e0NIcp0BmW/nmZtFRETEg1RyAkGbk1NW374HgXvuRxERCTAqOYGgxQAICoNDuyA7w+w0IiIiHqGSEwjCouCSfq7lb98zN4uIiIiHqOQEijaDXfebPwBHqblZREREPEAlJ1BcdDVE1IXjubBnidlpREREapxKTqCwBUOrG1zLOspKREQCgEpOICmbstrxKRQdMzeLiIhIDVPJCSQNUiC6CZScgB3/NTuNiIhIjVLJCSQWy6nRnG91mQcREfFvKjmBps0g1/2eJVCQY2oUERGRmqSSE2iim0DDTmA4YcuHZqcRERGpMSo5gahsNEdXJhcRET+mkhOIWl4P1iDI+RZyd5idRkREpEao5ASiWnXhol6u5c26zIOIiPgnlZxAVTZl9e374HSam0VERKQGqOQEqkv6Qkgk5GXB/tVmpxEREal2KjmBKjgckq9zLesyDyIi4odUcgJZ2ZTV1o+htMjcLCIiItVMJSeQXdgVIhOgMA+++8LsNCIiItVKJSeQWW3QWlcmFxER/6SSE+jKrmW163P45aipUURERKqTSk6gi20FMcngKIZtn5idRkREpNqo5AQ6i+W0c+boxIAiIuI/VHIEWt/kut+3Ao7uNzeLiIhINVHJEbA3hAu7uZZ1mQcREfETKjnicvqUlWGYm0VERKQaqOSIS4s/gC0UDu6AnM1mpxERETlvKjniEl4HLunjWtY5c0RExA+o5MgpbW523W9+H5wOc7OIiIicJ5UcOeWinhB+ARz7CTKXmp1GRETkvKjkyClBIdDyeteyzpkjIiI+TiVHyiu7zMO2BVB83NwsIiIi50ElR8pL7AQXXAglx2HHIrPTiIiInDOVHCnPYjk1mqOjrERExIep5EhFZSVn91dwLNfcLCIiIudIJUcqqtsUGnQEwwFbPjQ7jYiIyDlRyZHKlY3mbPqPuTlERETOkUqOVK7V9WANguwMOLjL7DQiIiK/m0qOVK5WPdfJAQG+1WiOiIj4HpUcOTP3UVbvgdNpbhYREZHfSSVHzuySvhBqh7z9sO8bs9OIiIj8Lio5cmbB4dDyOteypqxERMTHqOTI2ZVdmXzbAij5xdwsIiIiv4NKjpxdo1SwN4KifNipyzyIiIjvUMmRs7Naoa3OmSMiIr5HJUd+W9mU1fdf6jIPIiLiM1Ry5LfVuwgapOgyDyIi4lNUcqRq2t7iuteUlYiI+AivKjkzZswgKSmJsLAwUlJSWL58+Vm3LyoqYuLEiTRu3JjQ0FCaNm3K7NmzPZQ2wLQ87TIPuTvMTiMiIvKbvKbkzJs3jwceeICJEyeyceNGunXrRt++fcnKyjrjcwYNGsSXX37Jv/71L3bu3MncuXNp3ry5B1MHkFp14eLeruVNc83NIiIiUgUWwzAMs0MAdO7cmQ4dOjBz5kz3uhYtWjBw4ECmTp1aYfvFixdz8803s2fPHqKjo6v0HkVFRRQVFbkf5+fnk5iYSF5eHlFRUef/Ifzdtk/gvWEQmQBjt4DVZnYiEREJQPn5+djt9t/8/e0VIznFxcVs2LCB3r17l1vfu3dvVq5cWelzFixYQMeOHXnmmWdo0KABzZo148EHH+SXX858wrqpU6dit9vdt8TExGr9HH6vWR8IqwMFByBzqdlpREREzsorSs6hQ4dwOBzExsaWWx8bG0tOTk6lz9mzZw8rVqxgy5YtfPzxx0yfPp0PPviAe+6554zvM2HCBPLy8ty3/fv3V+vn8HtBodD6RtdyhqasRETEuwWZHeB0Foul3GPDMCqsK+N0OrFYLLz77rvY7XYAnnvuOW688Ub++c9/Eh4eXuE5oaGhhIaGVn/wQNJ2CKybBdsXQmE+hGmaT0REvJNXjOTUq1cPm81WYdQmNze3wuhOmfj4eBo0aOAuOODah8cwDH744YcazRvQGnSAes2g9BfXPjoiIiJeyitKTkhICCkpKaSlpZVbn5aWRpcuXSp9zuWXX86BAwc4duyYe92uXbuwWq00bNiwRvMGNIvltHPmaMpKRES8l1eUHIBx48Yxa9YsZs+ezfbt2xk7dixZWVmMHj0acO1PM2zYMPf2Q4YMoW7duowYMYJt27axbNkyHnroIUaOHFnpVJVUozaDAQvs+wZ+3mt2GhERkUp5TckZPHgw06dPZ8qUKbRr145ly5axaNEiGjduDEB2dna5c+bUrl2btLQ0jh49SseOHfnTn/7EgAEDePHFF836CIHD3gCadHct6wzIIiLipbzmPDlmqOpx9lKJTfPg47vgggthTIZrGktERMQDfOo8OeKDWlwLIbVd01VZq81OIyIiUoFKjpybkFqQPNC1vGmOqVFEREQqo5Ij567dyaOsts6H4hOmRhEREfk1lRw5d426QJ3GUJTvOjmgiIiIF1HJkXNntUK7P7mWM94xN4uIiMivqOTI+Wl3C2CBzGXw8z6z04iIiLip5Mj5qdMIkq5wLesMyCIi4kVUcuT8tb/VdZ/xLjid5mYRERE5SSVHzl/zayE0Co5mwb4VZqcREREBVHKkOoREQKvrXcsb3zU3i4iIyEkqOVI92p2cstr2CRTmmZtFREQElRypLg07Qr1mUPoLbP3Y7DQiIiIqOVJNLJZT58zRlJWIiHgBlRypPm1vBosNfljLxvS1fJLxI6t2H8bhDNgL3YuIiImCzA4gfiQyjtzYrsTkLGXNRy/y91LXta3i7WFMGpBMn1bxJgcUEZFAopEcqTaLt2TzaFYHAG6wLSOIUgBy8gq5+510Fm/JNjOeiIgEGJUcqRYOp8Hkhdv40tmeg0YU9S15XGXdCEDZZNXkhds0dSUiIh6jkiPVYm3mEbLzCikliA8d3QEYbFvi/roBZOcVsjbziCn5REQk8KjkSLXILSh0L89z9ACghzWDOA6fcTsREZGapJIj1SImMsy9nGnEs8bZHJvF4EbbsjNuJyIiUpPOueRkZWVVZw7xcZ2Soom3h2E5+fg/pVcCrikrC04suI6y6pQUbVZEEREJMOdccoYNG0ZSUhJXXHEF9957L6+99hqrV6/m+PHj1ZlPfITNamHSgGQALMBnzk7kG+EkWg/SxboNgEkDkrFZLWd5FRERkepzziVnyZIlZGZm8sc//pH9+/fz/fff88gjj2C327nkkkuqM6P4iD6t4pl5awfi7GEUEsonjssBuC1sGTNv7aDz5IiIiEed98kA33rrLTZu3Oh+/MUXXzBnzpzzfVnxUX1axdMrOY61mUco2h8CS/5HL8taLE1CzY4mIiIB5rx3PA4LC2Pnzp3ux71792bLli3n+7Liw2xWC6lN69KjRy+Ia4PFUQzfzjM7loiIBJjzHsmZNWsWN910E1deeSVt2rRh69at1ZFL/EWHYbDoQUh/CzqPdl3IU0RExAPOeySnZcuWrF27lssuu4zMzEwSExP57LPPqiOb+IPWN0FQGORugx/WmZ1GREQCyO8aydm3bx87d+6kdevWxMef2ok0LCyMW265hQMHDpCQkFDtIcWHhdeBltfDpjmw/g1I7GR2IhERCRBVHsmZO3cuF110EX369KFp06a8/fbbgKv4/P3vf6dz5840atSoxoKKD+s40nW/9SP45Wdzs4iISMCocsl54oknuO+++9i8eTO9evXi7rvvZuLEiTRt2pQ333yTTp068dFHH9VkVvFVDTtCbCsoLYRN/zE7jYiIBAiLYRhVuix0aGgou3btonHjxvzwww80atSIHj168M9//pMWLVrUdM4akZ+fj91uJy8vj6ioKLPj+Le1r7t2QK53CdyzRjsgi4jIOavq7+8qj+SUlJQQHh4OQMOGDQkPD+fZZ5/12YIjHtZmMATXgkM7IWuV2WlERCQA/K6jq+bMmcOOHTtcT7RaueCCC2oklPihsChofYNref1sc7OIiEhAqHLJ6dq1K5MmTaJly5bUq1ePwsJCXnjhBd577z22bdtGaWlpTeYUf5AywnW/7RM4ftjcLCIi4veqfAj5smXLAPjuu+/YsGED6enpbNiwgbfeeoujR48SHBzMJZdcwrfffltjYcXHNegA8W0he5PrkPIu95mdSERE/NjvPuPxxRdfzMUXX8zNN9/sXpeZmcn69evLXcNKpFIdR8LC+13nzEm9Vzsgi4hIjany0VX+SEdXmaDoGExrDsUFMGwBNOludiIREfEx1X50lUi1CK0NbW5yLa//l7lZRETEr6nkiOddeofrfvunkH/A3CwiIuK3VHLE82JbQuPLwXDAhjfNTiMiIn5KJUfMUTaas/4NKC02N4uIiPgllRwxR4sBUDsOjufC9gVmpxERET+kkiPmsAVDynDX8rpZpkYRERH/pJIj5kkZDtYg17WscraYnUZERPyMSo6YJyreNW0FsO51c7OIiIjfUckRc116p+v+2/fgl6OmRhEREf+ikiPmatwFYpKh5ARkzDE7jYiI+BGVHDGXxXLqcPJ1s8DpNDePiIj4DZUcMV+bwRBqhyO7YfeXZqcRERE/oZIj5gutDR2GupZXzzA3i4iI+A2V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IiLil1RyRERExC+p5IiIiIhfUskRERERv6SSIyIiIn5JJUdERET8kkqOiPi9v//976SmppodQ0Q8TCVHRPzepk2baNu2rdkxRMTDVHJExO9t2rSJdu3amR1DRDxMJUdE/Mr27dvp0aMH4eHhtG/fnvXr17Nr1y6N5IgEIJUcEfEbO3bsoHPnznTs2JEtW7bw2GOPcd1112EYBm3atDE7noh4mMUwDMPsECIi1eHqq68mISGBt99+273ulltuIT09nZ07d5qYTETMEGR2ABGR6rBv3z6++uor0tPTy60PDg7WVJVIgNJ0lYj4hYyMDIKCgmjdunW59enp6drpWCRAqeSIiF+wWq04nU6Ki4vd6xYtWsTWrVtVckQClEqOiPiFlJQUgoODefDBB9mzZw8LFizgzjvvBNB0lUiA0o7HIuI33nnnHSZMmMDx48dp3749nTt35vXXX+fgwYNmRxMRE6jkiIiIiF/SdJWIiIj4JZUcERER8UsqOSIiIuKXVHJERETEL6nkiIiIiF9SyRERERG/pJIjIiIifkklR0RERPySSo6IiIj4JZUcERER8UsqOSIiIuKX/h+lA4GnBHytzgAAAABJRU5ErkJggg==", + "image/png": "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", "text/plain": [ "
" ] @@ -360,11 +487,12 @@ } ], "source": [ - "plt.plot(dims, ratios, 'o', label='sampled');\n", - "plt.xlabel('$d$');\n", - "plt.ylabel('$R_d$');\n", - "plt.plot(d, R_d, label='theoretical');\n", - "plt.legend();" + "figure, axis = plt.subplots()\n", + "axis.plot(d, R_d, label='theoretical')\n", + "axis.plot(dims, ratios, 'o', label='sampled')\n", + "axis.set_xlabel('$d$')\n", + "axis.set_ylabel('$R_d$')\n", + "axis.legend();" ] }, { @@ -374,6 +502,144 @@ "source": [ "It is clear that the ration rapidly drops to 0 with increasing dimension $d$. So although the hypersphere touches the hypercube in $2^d$ points, its volume is nevertheless much smaller." ] + }, + { + "cell_type": "markdown", + "id": "a44e977d-14b4-4b57-b04a-f51b5a91b871", + "metadata": {}, + "source": [ + "## Random vectors with normally distriibuted components" + ] + }, + { + "cell_type": "markdown", + "id": "f6dd26cc-6c5d-4842-8422-e1bbce2e008e", + "metadata": {}, + "source": [ + "What is the average distance of a vector to the origin? The vector has $d$ components, each drawn independently from an idential normal distribution." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "f5f5325f-4ee4-4b87-8680-da3a0d592e92", + "metadata": {}, + "outputs": [], + "source": [ + "def generate_vectors(rng, nr_vectors, nr_dims):\n", + " return rng.normal(size=(nr_vectors, nr_dims))" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "43d1f824-6753-4a2c-8643-d9845f649c10", + "metadata": {}, + "outputs": [], + "source": [ + "def compute_distance_distribution(vectors):\n", + " return np.linalg.norm(vectors, axis=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "2e66504b-d81e-4ade-a16b-f4b8a01f5f45", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ecb2b1f0e15f4c2085b3aaf196477f38", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(IntSlider(value=1000, description='nr_vectors', max=10000, min=100), IntSlider(value=2, …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "@ipywidgets.interact(nr_vectors=(100, 10_000), nr_dims=(1, 50))\n", + "def show_distance_distribution(nr_vectors=1_000, nr_dims=2):\n", + " vectors = generate_vectors(rng, nr_vectors, nr_dims)\n", + " distribution = compute_distance_distribution(vectors)\n", + " figure, axis = plt.subplots()\n", + " axis.hist(distribution, bins=50, density=True)\n", + " axis.set_xlim(0.0, 10.0)\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "800e2131-f0eb-442a-b9f8-8e09e5395ffa", + "metadata": {}, + "source": [ + "This might be counter intuitive at a first glance. You might have expected that the vectors would be close to the origin, but in fact, they form a \"shell\" around the origin at a distance that increases with the dimension $d$." + ] + }, + { + "cell_type": "markdown", + "id": "da2122a5-677a-4a0b-9a01-f1fdabc21613", + "metadata": {}, + "source": [ + "You can also plot the average distance as a function of the dimensionality $d$." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "e21d8b8a-7311-4e97-a0c8-697b2a8eb3f3", + "metadata": {}, + "outputs": [], + "source": [ + "def compute_average_distance(rng, nr_vectors, nr_dims):\n", + " vectors = generate_vectors(rng, nr_vectors, nr_dims)\n", + " distribution = compute_distance_distribution(vectors)\n", + " return distribution.mean()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "59a95dcc-1f39-4c7f-90fe-b25d16ac360d", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAGxCAYAAABMeZ2uAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAUXRJREFUeJzt3Xd4VGX6xvHvTCqBJBB6IIQEEIyEIigEFEQBKQq21UX9AbJ2rCwquNZVAVFXXHdVUJdmQRRFdhUURIJU6S2U0BJK6JBJIW3m/P6YJBJIIAMzOZPJ/bmuXDJnzjl5OAHm9j3veV6LYRgGIiIiIl7IanYBIiIiImVRUBERERGvpaAiIiIiXktBRURERLyWgoqIiIh4LQUVERER8VoKKiIiIuK1/M0u4FI4HA4OHjxIaGgoFovF7HJERESkHAzDICMjg8jISKzW84+ZVOqgcvDgQaKioswuQ0RERC7Cvn37aNy48Xn3qdRBJTQ0FHD+RsPCwkyuRkRERMrDZrMRFRVV/Dl+PpU6qBTd7gkLC1NQERERqWTKM21Dk2lFRETEaymoiIiIiNdSUBERERGvVannqJSX3W4nPz/f7DLkAgIDAy/4mJqIiFQtPh1UDMPg0KFDnDp1yuxSpBysVisxMTEEBgaaXYqIiHgJnw4qRSGlXr16hISEqCmcFytq3peWlkaTJk30sxIREcCHg4rdbi8OKbVr1za7HCmHunXrcvDgQQoKCggICDC7HBER8QI+OyGgaE5KSEiIyZVIeRXd8rHb7SZXIiIi3sJng0oR3UKoPPSzEhGRs/nsrR8RERG5BA47pCyDzMNQoz5EdwGrX4WXoaAiIiIiJSXNgXnPge3gH9vCIqHPmxA3oEJL8flbP77IYrFc1JeIiMgFJc2BmYNLhhQAW5pze9KcCi1HQaWSSUtL4/PPP8cwDJe/REREzsthd46kUNpnRuG2eaOc+1UQBZVKZu7cufTp08fsMkRExBelLDt3JKUEA2wHnPtVEAWVSubEiRNERESYXYaIiPiizMPu3c8NFFQqkezsbGrUqGF2GSIi4qtq1Hfvfm5galBp2rRpqZM+hw8fbmZZXmvBggX07NmzXPuOGzeOhIQED1ckIiK+oMDu4IeNafxpLhw0InCUOa3RAmGNnI8qVxBTH09etWpViS6kmzdvplevXvzpT38ysSrvlZyczIAB5XssbMOGDbRt29bDFYmISGWWnp3Pl6tSmbZsLwfTcwB4w38I//J/FwMLlhKTagufHu0zrkL7qZgaVOrWrVvi9bhx42jWrBndu3c3qSLvUlBQgL+/80dkGAZWa/kHwDZs2MATTzzhqdJERKQS23kkkynL9jBrzQFO5zsHDGpXD+SeztHc2/kGLPuuLKOPyrgK76PiNQ3f8vLy+OyzzxgxYkSZPT9yc3PJzc0tfm2z2SqqvArlcDh47bXXyMrKYvz48QCsXLmSq6++utT9t27dyiOPPMLKlStp1aoVH3/8MTt27NCIioiIFDMMg9+Sj/GfpXtYtP1o8fZWDUIZdk0MA9pGEhxQOFISNwBa9Vdn2jPNnj2bU6dOMXTo0DL3GTt2LK+++mrFFWUSi8XCiBEj6NGjR/G2FStWlDpCsm3bNjp16sSDDz7Ip59+ysaNGxk4cCCGYdCmTZuKLFtERMxWStv70wXw7br9TF66l51HMgGwWKDn5fUZ1jWGzrERpQ8QWP0g5toK/g2cy2uCyqeffkrfvn2JjIwsc5/Ro0czYsSI4tc2m42oqKhyfw/DMIqHuCpStQA/lzrDWiwWQkNDiY2NZdu2bbRq1Qq73V7qrZ/hw4czcOBA3n77bQCaNWvGzJkzWbt2LdWrV3fb70FERLxcKW3vbYH1eCVvMN/mXAlAjSB//tSxMUO7NCW6duX4jPCKoJKSksKCBQv49ttvz7tfUFAQQUFBF/19TufbiXvpp4s+/mIl/f1GQgJdv9QDBw7k+++/JygoiGbNmp3zfkpKCgsXLmTt2rUltgcEBOi2j4hIVVLU9v6sjrI1co/wNm8TEvYcsd0G8aeOjQkNDjCnxovkFX1UJk+eTL169ejfv7/ZpXiV/v37M3fuXH7++Wd69ep1zvvr16/H39+f+Pj4EtvXrl1Lu3btKqhKERExlcOOMfc5jFLa3lstzlH614I/Y1iXJpUupIAXjKg4HA4mT57MkCFDip9w8ZRqAX4k/f1Gj36Psr7vxahZsyaBgYGkpKSUehvHarXicDjIy8srvnY//vgjW7ZsUVAREakCMnLyWfzzd/TPKLvtveXMtvdeMOfEVaYHlQULFpCamsqwYcM8/r0sFstF3YIx080330xAQOkJuEOHDgQEBDBy5EhGjhzJ5s2beeSRRwB060dExIcdOHWaKUv3MOP3ffTI30D/wHIcVIFt793J9E/t3r17a2Xf87jnnnvKnIgbGRnJJ598wujRo5kxYwbt27dnyJAhfPzxxzRq1KiCKxURkYtSypM6ZT0GvGHfKT5ZsocfN6VhL2wf61+rAZwux/epwLb37mQxKnFKsNlshIeHk56eTlhYWIn3cnJy2LNnDzExMQQHB5tUobhCPzMRqXJKeVLH2VjtzeLGanaHwfykw3y6ZDer9p4s3q1r89rcf00s3ZtHYP1nPNjSOHsyrZPFec6nNpnSB6U05/v8PpvpIyoiIiJVUhlP6mBLg5mDybltMjMy2vGfpXtJPZENQICfhZvbRnL/NbHERZ7xAd/nzcJzWc46nzlt791JQUVERKSiOezOkZRSR0Ccz++c/Pav/D3nPRxYCa8WwL2dmzA4oSn1w0oZcY4bAHdO85q29+6koCIiIlLRUpaVDBRnsQANOc6AmnvpcN0Abr+y0YUfBvGitvfupKAiIiJS0cr5BM4/+jXA2ia6/Of1krb37uQVDd9ERESqkrxqdcu1nzW0gYcr8X4KKiIiIhUkPTuff/+6k2tn5HDQiMBR5nO3Fghr5Lx1U8Xp1o+IiIiH7T+ZzX+W7GXGqlSy85yL4/6zxv2MLXgLg8LuscUq/5M67qSgIiIi4iGbD6QzafFufjijQVurBqE82C2Wm9r0xbIj3ief1HEnBRURERE3MgyDxB1HmbR4N8t2HS/efk3zOjzYLZZrW9T5o+O4jz6p404KKiIiIm6QV+BgzoaDfLx4N9sPZwDgZ7Vwc5uG3H9tLK0bhZd+oA8+qeNOCipSLkOHDuXUqVPMnj37os+xaNEievTowcmTJ6lZs6bbahMRMZMtJ58vVqYyeekeDttyAage6Megq5tw3zUxNKpZzeQKKzcFlfJwYcEoERGpAhx2jm35ld/WbmbObgeJuS1wYKVeaBD3dY3h7k5NCK8WYHaVPkFB5ULKsWCUiIhUHQeXf0XIL3+jTsFRbgVutcDRarVJvvIFOvYdSqC/On+4k67m+RQtGHV2m+PCBaNImuORb/vNN98QHx9PtWrVqF27Nj179iQrK4tVq1bRq1cv6tSpQ3h4ON27d2ft2rUljrVYLEycOJGbbrqJkJAQLr/8cpYvX87OnTu57rrrqF69OgkJCezatav4mFdeeYV27doxceJEoqKiCAkJ4U9/+hOnTp0qs0bDMBg/fjyxsbFUq1aNtm3b8s0335TY58cff+Syyy6jWrVq9OjRg71797rzMomIVKg1KSf44IN3aTDvQcLyj5Z4r45xgi5rRhC4438mVee7FFTKcoEFowCYN8q5nxulpaUxaNAghg0bxtatW1m0aBG33XYbhmGQkZHBkCFD+O2331ixYgUtWrSgX79+ZGRklDjHa6+9xuDBg1m/fj2tWrXi7rvv5qGHHmL06NGsXr0agMcee6zEMTt37mTmzJn897//Zd68eaxfv57hw4eXWecLL7zA5MmT+fDDD9myZQtPP/009957L4mJiQDs27eP2267jX79+rF+/Xruv/9+Ro0a5dZrJSLiaYZhsHDbYf700TL+9OFSbjn8TwCslpL7WTz4uVDV6dZPWS6wYBQYYDvg3M+Ns7XT0tIoKCjgtttuIzraub5DfHw8ANdff32JfSdOnEitWrVITEzkpptuKt5+3333ceeddwLw3HPPkZCQwIsvvsiNN94IwJNPPsl9991X4lw5OTlMnTqVxo0bA/D+++/Tv39/3nnnHRo0KNnCOSsri3/84x8sXLiQhIQEAGJjY1myZAkTJ06ke/fufPjhh8TGxvLuu+9isVho2bIlmzZt4s0333TXpRIR8Zh8u4P/bjjIxMQ/nuC5xn87kZYT5znKM58LVZ2CSlnKuWBUufcrp7Zt23LDDTcQHx/PjTfeSO/evbnjjjuoVasWR44c4aWXXmLhwoUcPnwYu91OdnY2qampJc7Rpk2b4l/Xr18f+CPsFG3LycnBZrMRFhYGQJMmTYpDCkBCQgIOh4Pt27efE1SSkpLIycmhV69eJbbn5eXRvn17ALZu3Urnzp3/6BVQeE4REW+WnVfAV6v28clvezhw6jQANYL8uadTEx6tkw4/luMkbv5cqOoUVMpSo7579ysnPz8/5s+fz7Jly/j55595//33+dvf/sbKlSsZPnw4R48eZcKECURHRxMUFERCQgJ5eXklzhEQ8MdM86KgUNo2h8NRZh1F+5wZNIoUHffDDz/QqFGjEu8FBQUBzuFSEZHK4mRWHlOX72Xqsr2czM4HoE6NIO7r2pR7O0c7n+DZc6x8J3Pz50JVp6BSluguzqd7bGmUPk/F4nzfAwtGWSwWunbtSteuXXnppZeIjo7mu+++47fffuODDz6gX79+gHMeyLFj5fyLcwGpqakcPHiQyMhIAJYvX47VauWyyy47Z9+4uDiCgoJITU2le/fupZ4vLi7unJ4rK1ascEutIiLusv9kNp/8toevVu3jdL5zbkl07RAe7BbL7Vc2JjjgjFYUJn4uVGUKKmWx+jkfQZ45GOcCURWzYNTKlSv55Zdf6N27N/Xq1WPlypUcPXqUyy+/nObNmzN9+nQ6duyIzWbjmWeeoVo19zQSCg4OZsiQIbz99tvYbDaeeOIJ7rzzznNu+wCEhoYycuRInn76aRwOB9dccw02m41ly5ZRo0YNhgwZwsMPP8w777zDiBEjeOihh1izZg1TpkxxS60iIpdq+6EMJibu4vsNB4vX4GndKIyHuzejb+uG+J09WxZM+1yo6hRUziduANw5rUIXjAoLC2Px4sVMmDABm81GdHQ077zzDn379qVBgwY8+OCDtG/fniZNmjBmzBhGjhzplu/bvHnz4qd0Tpw4Qb9+/fjggw/K3P+1116jXr16jB07lt27d1OzZk2uvPJKnn/+ecA552XWrFk8/fTTfPDBB1x99dWMGTOGYcOGuaVeERGXOexs//0nFq3exK8HrfzuaIUDK12b1+aR7s3p2rx2qbe7SzDhc6GqsxiVeDKBzWYjPDyc9PT04kmhRXJyctizZw8xMTEEBwdf2jfy8c60r7zyCrNnz2b9+vWm1uHWn5mISCHDMEha+Dn1l75MHccft8tP+tclvftrNL12kOsn9fHPBU873+f32TSiUh5aMEpEpNJxOAx+TjrMup+m8pxtjHPjGQMmtQqOUeuXR6B2dddHQvS5UGEUVERExKcU9UD5YNEudh+xsSToI+DcJm3OOSYWZ5O2Vv01IuKl1JlWeOWVV0y/7SMicqly8u1MX5FCj7cXMWLmBnYeyaR7cDKRlhOlhJQiZzRpE6+kERUREanUMnML+GJlCh//toejGbkA1K4eyF+ujeG+sAwoz7JsatLmtXw+qFTiucJVjn5WIuKKk1l5TFm2lynL9pJ+2tmkLTI8mIe6N+POjlFUC/SDPWnlO5matHktnw0qRZ1Ys7Oz3dZrRDyrqMOun5/uE4tI2Y7Ycvj4t918vjKV7Dxnk7bYOtV55LpmDGzXiED/M2Y1qElbpeezQcXPz4+aNWty5MgRAEJCQi78fLyYxuFwcPToUUJCQvD399k/liJyMQofBT5+KJXvdhbw9rY65BQuUBzXMIzhPZrTp3UDNWnzUT79iVDUVbUorIh3s1qtNGnSRIFSRP6QNIf8H54lICuN2sD9QD//CD6v8ygd+w3husvqqkmbj/PZhm9nstvt5OfnV2BlcjECAwOxWvUgmog47V/2FY1+fhDDKPlosYHFORZy5zTXQoaatHkNNXw7i5+fn+Y9iIhUEpsPpPP+gm28vHsUBuf2P7FcbP8TNWmrlKpEUBEREe+3LvUk7y/cycJtR+hsTSIy8MR59j6j/4nCh09TUBEREVOt2nuCf/6SzG/JznV4rBbo19QCBy9wIKj/SRWgoCIiIhXOMAyW7z7OP39JZsVu58iJn9XCbe0b8WiP5sRkhMHUcpxI/U98noKKiIhUGMMwWJx8jPd/SWZ1ykkAAvws3NEhikeva0ZURIhzxwj1PxEnBRUREfE4wzD4ZesR3l+YzIb96QAE+lv581VRPNy9GZE1z2rMqf4nUkhBRURE3K/wUWBHxiFWHwvgtU012ZSWBUBwgJV7OkXzYLdY6ocFl30O9T8RqkgfFRERqUBJczDmPYfljHBx0IhgnDGUhgl38sC1sdSpEVT+86n/ic9RHxURETGFY8v3WL4ewtnzShpaTvCe5V0s0e2hxuWunVT9T6o0tQEVEZFL5nAY/LBhP8e/eRrDMDi7qb2l8It5o5wjJCLlpBEVERG5aA6Hwbwth3hvQTK1jq6kf+BxzkkpxdSkTVynoCIiIi5zOAx+2nKI935JZtuhDADuDLKV72A1aRMXKKiIiEi5ORwGPycdZsKCHcUBJTTIn/uuieHBqBCY8c8Ln0RN2sQFCioiInJBhuEMKO8tSCYpzTlyUiPIn2FdmzLsmhhqhgSCo5matInbmT6Z9sCBA9x7773Url2bkJAQ2rVrx5o1a8wuS0REKAwoWw5x0/tLeGj6GpLSbFQP9OOxHs1Z8lwPRvRu6Qwp8EeTNuDciSpq0iYXx9QRlZMnT9K1a1d69OjB3LlzqVevHrt27aJmzZpmliUiUuUVdZKd8MsONh9wjqBUD/RjaNem3H9NLLWqB5Z+oJq0iZuZGlTefPNNoqKimDx5cvG2pk2bmleQiEhV5rBjpCxly/ZkPk/K5asjUTiwEhLox9AuTXng2vMElDPFDYBW/dWkTdzC1M60cXFx3Hjjjezfv5/ExEQaNWrEo48+ygMPPFDq/rm5ueTm5ha/ttlsREVFqTOtiMglMpK+J/d/zxKcfah4W5oRwYqWz9J94F+IKE9AESknVzrTmjpHZffu3Xz44Ye0aNGCn376iYcffpgnnniCadOmlbr/2LFjCQ8PL/6Kioqq4IpFRHzPjl8/h5mDCcw6VGJ7A8tJbt0xmoiUeSZVJmLyiEpgYCAdO3Zk2bJlxdueeOIJVq1axfLly8/ZXyMqIiLusy71JO/+vJVx++6hASewltqorfBJnac26daNuE2lWeunYcOGxMXFldh2+eWXM2vWrFL3DwoKIijIhYWsRETkHEkHbfxj/nYWbD1CZ2sSkYEnzrO3usmKuUwNKl27dmX79u0ltu3YsYPo6GiTKhIR8V07j2Ty7oId/LAxDQCrBW6OtcL+chysbrJiElODytNPP02XLl0YM2YMd955J7///juTJk1i0qRJZpYlIuJTUo9nM+GXHcxedwBH4c3+m9tG8lTPFjTLDIOp5TiJusmKSUwNKldddRXfffcdo0eP5u9//zsxMTFMmDCBe+65x8yyRER8Qlr6ad5fuJOZq/ZRUJhQesfV5+lel3F5w8J5AbW7qJuseDVTJ9NeKlcm44iIVBVHM3L5YNFOPl+ZSl6BA4Bul9Xlr70uo21UzXMPSJoDMwcXvjjzI6Fwdu2d09SoTdyq0kymFRER9zmVncfExbuZsnQvp/PtAFwdE8HI3i25Oiai7APVTVa8mIKKiEgll5GTz6dL9vDpb3vIyC0AoG1UTZ7p3ZKuzWtjsZT63HFJ6iYrXkpBRUSkksrJt/P58t0s//V/hOQe4wpqktHgKp7ufTk3XF6vfAHlTFY/PYIsXkdBRUSkkrE7DL5du591P03jsbxP+IvlBBR2uDcckVh4Eyy6XSO+QUFFRKSSMAyDn5MO8/ZP24k9tpAPAyYUz3ctYrGlOSfGagKs+AgFFRGRSmD5ruO8OW8b6/edwoqD6cHTsXBOTsH51I4F5o1yzjnRHBOp5BRURES82OYD6Yz/aTuLdxwFoFqAH6/Ep9Mg6fh5jlLbe/EdCioiIl5o77Es3pm/g/9ucD4u7G+1cHenJjx2fXPq7f0fJJXjJGp7Lz5AQUVExIscseXw3i/JfHVGN9mB7SIZ0esyomtXd+5U3nb2ansvPkBBRUTEC6Sfzmdi4i7+s3QPOfnObrI9WtZl5I0tuSIyvOTO0Wp7L1WHgoqIiIly8u1MWbaXDxftIv10PgBXNqnJc31a0Sm2dukHWf2gz5uFbe8tlNr2vs84TaQVn6CgIiJigoL8fBIXzGHR6o0kn65BhqMVl9UP45kbW9GzPM3a1PZeqggFFRGRCmQYBht+nk7kile4wTjODQCBkB1cn6Deb+EX58K8ErW9lypAQUVEpIKsSz3JL99+woiTrzs3nDFoEpJzBL4eAhYXG7Wp7b34OAUVEREPSzmexfiftjN34wGWBH0AgPWcOztq1CZSGgUVEREPOZmVxz8XJvPZihTy7QadrduItJw4zxFq1CZyNgUVERE3y8m3M3npXj5YtJOMnAIAul1WlzHN68PCcpxAjdpEiimoiIi4icNh8N26A7zz83YOpucAENcwjNH9WnFti7qwJ7d8J1KjNpFiCioiIm6wJPkYY37cSlKaDYDI8GD+2rslt7ZvhLVoQooatYm4TEFFROQSbE2zMXbutuJFA0OD/Hm0R3Pu69qU4ICzJsSqUZuIyxRUREQuQlr6ad75eQez1u7HMCDAz8K9naN5/PoWRFQPLPtANWoTcYmCioiIC2w5+Xy0aBefLtlDboFzTZ7+bRry7I0t/1g08ELUqE2k3BRURETKocDuYMbve0mc/z3Vco7RnpoY0Z0Z1b817ZvUcv2EatQmUi4KKiIiF5C44yiLZn/CA1mTuNdyAgrv7BinI7Fkvgnodo2IpyioiIiUYeeRDN74YSuByT/wYcCEEi3vASy2NOfE2DtdbHsvIuWmoCIicpaTWXlMWLCDz1amYjjsLA2ahsVyTk5Bbe9FPE9BRUSkUF6Bg+krUnhvwQ5shR1lh8ccpmGa2t6LmEVBRUSqPMMw+GXrEd74cSt7jmUB0KpBKC/dFEeX04tgVjlOorb3Ih6hoCIiVdrWNBuv/5DE0p3HAahTI5CRvVvyp45R+FktsKec7ezV9l7EIxRURKRKOpqRyz/mb+erVftwGBDob+Uv18Tw6HXNCA0O+GNHtb0XMZWCioj4Noe9RGO1nMhOTF6+j3//upPMXOc8lP7xDRnVtxVRESHnHq+29yKmUlAREd+VNOecVvU2arM+7//IdFxNm8bhvHhTHFc1jTj/edT2XsQ0FsMwShvLrBRsNhvh4eGkp6cTFhZmdjki4k2S5hSOgpT8J85hgMUCKzpOoFO/oX+sbFweZ43OqO29yMVx5fNbIyoi4nscdpj3HAbGOb1PrBYwsJCw4y3oNxhwIWio7b1IhbOaXYCIiLsV7FkKtoOlNGhzspzZ+0REvJqCioj4lGU7jzH+m0Xl21m9T0S8nm79iIhPOHDqNG/8kMSPmw7R2VqteOHA81LvExGvp6AiIpVaTr6diYm7+TBxJzn5DqwWaHl1bxy7/oM1Q71PRCo7BRURqZQMw+CnLYd5/Yck9p88DcDVMRG8OuAKLm8YBknqfSLiCxRURKTS2Xkkg1f/m8RvyccAaBAWzPP9L+fmNg2xWAqDiHqfiPiEiwoqu3btYvLkyezatYv33nuPevXqMW/ePKKiorjiiivcXaOICAAZOfm8tyCZKcv2UuAwCPSz8mC3WB7t0YyQwFL+OYsbAK36q/eJSCXm8lM/iYmJxMfHs3LlSr799lsyMzMB2LhxIy+//LLbCxQRcTgMvl69jx5vJ/LJkj0UOAx6Xl6P+SO6MfLGlqWHlCJFvU/i73D+VyFFpFJxeURl1KhRvP7664wYMYLQ0NDi7T169OC9995za3EiIhv2neLlOVtYv+8UALF1qvPizXH0aFnP3MJEpEK4HFQ2bdrEF198cc72unXrcvz4cbcUJSJVnMNO+rZEfli2njm77Wx0tKJ6YACP39CCYV1jCPRXCyiRqsLloFKzZk3S0tKIiYkpsX3dunU0atTIbYWJSNVk3/I9OXOeITz3MHcDdwfCSf+6WPq+Sc0OzcwuT0QqmMv/W3L33Xfz3HPPcejQISwWCw6Hg6VLlzJy5EgGDx7siRpFpIpIXTID69eDqZZTsmNsrYJj1PzvX5wLDYpIleJyUHnjjTdo0qQJjRo1IjMzk7i4OLp160aXLl144YUXPFGjiPg4W04+r8zeQMD80RiGc+HAkgr7oMwb5VxwUESqDJeDSkBAAJ9//jnJycnMnDmTzz77jG3btjF9+nT8/FybTf/KK69gsVhKfDVo0MDVkkSkkjIMg+/XH+D6txPZ9vvPNLScKCWkFO+thQRFqqCLbvgWGxtLbGzsJRdwxRVXsGDBguLXroYdEamcdh3N5KXvN7N0p3MS/i3hpyG3HAdqIUGRKsXloHLHHXfQsWNHRo0aVWL7W2+9xe+//87XX3/tWgH+/uUeRcnNzSU3949/yWw2m0vfS0TMdzrPzr9/3cnExbvItxsE+Vt5rEdzHoquAZ+9c+ETaCFBkSrlohq+9e/f/5ztffr0YfHixS4XkJycTGRkJDExMfz5z39m9+7dZe47duxYwsPDi7+ioqJc/n4iYp6F2w7T691E/vXrTvLtBj1a1mX+0915/IYWBMZe42xvT1n3fiwQ1kgLCYpUMS4HlczMTAIDz10/PSAgwOURjk6dOjFt2jR++uknPv74Yw4dOkSXLl3K7McyevRo0tPTi7/27dvnavkiYoIDp07z4LTVDJuymv0nT9MwPJiP7r2S/wy9iia1Q5w7Wf2gz5uFR5wdVrSQoEhV5XJQad26NV999dU522fMmEFcXJxL5+rbty+333478fHx9OzZkx9++AGAqVOnlrp/UFAQYWFhJb5ExHvl2x1MTNxFz3cS+TnpMP5WCw91i2XBiO70aX3GAoJFihYSDGtYcntYpHO7FhIUqXJcnqPy4osvcvvtt7Nr1y6uv/56AH755Re+/PJLl+ennK169erEx8eTnJx8SecREfOt3H2cF7/fzI7DzvXArmpai9dviadlg9DzH6iFBEXkDC4HlQEDBjB79mzGjBnDN998Q7Vq1WjTpg0LFiyge/ful1RMbm4uW7du5dprr72k84iICRx2SFmG7dh+Ptucy9vba+PASkT1QEb3bcXtVzbGWvazxyUVLSQoIlWexTAMw6xvPnLkSG6++WaaNGnCkSNHeP3110lMTGTTpk1ER0df8HibzUZ4eDjp6em6DSRipqQ5GPOew2I7WLzpoBHBwqZ/pf+dD1Kr+rnz2kSk6nLl8/ui+6jk5eVx5MgRHA5Hie1NmjQp9zn279/PoEGDOHbsGHXr1qVz586sWLGiXCFFRLxE0hyMmYMp7h5bqKHlJPemvAApTTS3REQumssjKsnJyQwbNoxly0p2hzQMA4vFgt1ece2tNaIiYq68vHxy346jeu6RMjrKWpwTYZ/apDkmIlLMoyMqQ4cOxd/fn//97380bFjKrH0RqRLWpZ7ki6++4K28I2W3Pjmz7b3mnIjIRXA5qKxfv541a9bQqlUrT9QjIl4uM7eAt3/aztTle7nZchDKM/1Ebe9F5CK5HFTi4uI4duyYJ2oRES/3y9bDvDh7MwfTcwBo2aI5pJbjQLW9F5GL5HLDtzfffJNnn32WRYsWcfz4cWw2W4kvEfE9RzNyeeyLtfxl6moOpucQFVGNacOuZvjQwWp7LyIe5fJkWqvVmW3OnpuiybQivscwDL5evZ83ftxK+ul8rBa4/9pYnurZgpDAwgHZpDkwc3DREWccXfhvhDrKishZPDqZ9tdff73owkSk8thzLIvnv93E8t3OtbeuiAxj3G1tiG8cXnLHorb3856DM/qoEBbpXJtHIUVELoGpDd8ulUZURNygsKNsUbv6/Mad+XhpCu8tSCa3wEFwgJWne17GX66Jwd/vPHeLzzqP2t6LSFkqpOFbdnY2qamp5OXlldjepk2biz2liFS0pDnnjIScstRhQ+695Dqu5prmdRhza/wfKxyfj9rei4gHuBxUjh49yn333cfcuXNLfb8i56iIyCUonltSclC1tuMYHwZOYGXHCXTu30+9kkTEVC4/9fPUU09x8uRJVqxYQbVq1Zg3bx5Tp06lRYsWzJkzxxM1ioi7OezOkRTOvfNrtYAFCwk73sJiOM49VkSkArk8orJw4UK+//57rrrqKqxWK9HR0fTq1YuwsDDGjh1L//79PVGniLhTyrKSE1/PYlFHWRHxEi6PqGRlZVGvXj0AIiIiOHr0KADx8fGsXbvWvdWJiEds25lcvh3VUVZETOZyUGnZsiXbt28HoF27dkycOJEDBw7w0Ucf0bBhQ7cXKCLuk5GTz+hvN/HKr8fLd4A6yoqIyVy+9fPUU0+RlpYGwMsvv8yNN97I559/TmBgIFOmTHF3fSLiJr8lH2XUrE0cOHUaK61ID6hLWP4x522ecxSueqyOsiJiskvuo5Kdnc22bdto0qQJderUcVdd5aI+KiIXlpGTz5gft/Hl785FeaIiqjH+9rYk5C5VR1kRMYUrn98u3/r5+9//TnZ2dvHrkJAQrrzySqpXr87f//5316sVEY9ZknyMPhN+Kw4pQxKimfdkNxKa1f6jo2zYWbdswyIVUkTEa7g8ouLn50daWlrxhNoix48fp169elrrR8QLlDmK0qz2uTuro6yIVDCPdqYtWnzwbBs2bCAiIsLV04mImy1JPsZzszZy4NRpAAYnRPNcn1ZUDyrjr7s6yoqIFyt3UKlVqxYWiwWLxcJll11WIqzY7XYyMzN5+OGHPVKkiFxYZm4BY37cyhcr/xhFefP2NnRpVrFzx0RE3KncQWXChAkYhsGwYcN49dVXCQ//YwXVwMBAmjZtSkJCgkeKFJHzc3kURUSkkij3v2JDhgwBICYmhq5du+Lvr38ARcx29ihK41rVGH+HRlFExHe4nDZCQ0PZunUr8fHxAHz//fdMnjyZuLg4XnnlFQIDA91epIicxWFn07K5fJO4ht1ZIVhpxT2dYxjVV6MoIuJbXP4X7aGHHmLUqFHEx8eze/du7rrrLm677Ta+/vprsrOzmTBhggfKFJEieZtmc3rOM8TnHyEeIBByQxoQdNlbENTa7PJERNzK5T4qO3bsoF27dgB8/fXXdO/enS+++IIpU6Ywa9Ysd9cnImdIXTKDgFlDCM07UmJ7UPZhZ/O2JK1gLiK+xeWgYhgGDodz6fcFCxbQr18/AKKiojh27Jh7qxMRAOwOg49+3UHA/NEYBljP6RBQ2A5p3ihnXxQRER/hclDp2LEjr7/+OtOnTycxMZH+/fsDsGfPHurX1wJmIu62/2Q2gz5ewaL539PQcqKUkFLEANsBZ/M2EREf4XJQmTBhAmvXruWxxx7jb3/7G82bNwfgm2++oUsXLWAm4i6GYfDt2v30nfAbv+85QZS/rXwHZh72bGEiIhXokhclLJKTk4Ofnx8BAQHuOF25qIW++KpT2Xn8bfZmftjoXKm8Q3QtPuiSTf3vbr/wwUP+p06zIuLVPNpCvyzBwcHuOpVIlbYk+Rgjv97AIVsO/lYLT97Qgkeua4a/xYBfIsGWRsnVjotYnAsKRmtkU0R8R7mCSkREBDt27KBOnTrFrfTLcuLECbcVJ1KV5OTbeeun7Xy6ZA8AsXWq8+5d7WgbVfOPnfq86Xy6Bwslw0rh38k+47SgoIj4lHIFlXfffZfQ0FAA9UkR8YCkgzae/mo92w9nAHBPpyb8rf/lhASe9Vc0bgDcOQ3mPQe2g39sD4t0hpS4ARVYtYiI57ltjooZNEdFKjuHw+CTJbt5+6cd5Nkd1KkRyPg72nB9qws8QeewO5/uyTwMNeo7b/doJEVEKgm3z1Gx2cr5tAEoMIiU08FTp/nrzA0s330cgJ6X12fc7fHUqRF04YOtfpowKyJVQrmCSs2aNc87L+VMdruaTYmU6oxRkCWH/Bi+NJj0HAfVAvx46eY4/nxVVLn/nomIVBXlCiq//vpr8a/37t3LqFGjGDp0KAkJCQAsX76cqVOnMnbsWM9UKVLZJc0pMa/kGmCuEcG0eo9w1+DhxNSpbm59IiJeyuU5KjfccAP3338/gwYNKrH9iy++YNKkSSxatMid9Z2X5qhIpZA0B2YOxsDgzPES5188C5Y7p2kSrIhUKa58frvcmXb58uV07NjxnO0dO3bk999/d/V0Ir7NYceY99w5IQWcDxRbQOvziIich8tBJSoqio8++uic7RMnTiQqKsotRYn4ivRtiVhsB88JKX/Q+jwiIufjcmfad999l9tvv52ffvqJzp07A7BixQp27drFrFmz3F6gSGW1fNdxfpiVyOvl2Vnr84iIlMrlEZV+/fqRnJzMwIEDOXHiBMePH2fgwIHs2LGDfv36eaJGkUrF7jCYsGAH93yygp2na5TvoBpaeVxEpDQXtdZP48aNeeONN9xdi0ild9iWw5Mz1rFit3MpiaZX9sSR+h+sGVqfR0TkYrhtUUKRqm7R9iP8deYGjmflUT3QjzdujeeW9o0gSevziIhcLJdv/YhISfl2B+PmbmPo5FUcz8ojrmEY/338GmdIgT/W5wlrWPLAsEjndj2aLCJSJo2oiFyC/SezeeLLdaxNPQXA4IRonu93OcEBZ42QxA2AVv21Po+IiIsUVEQu0s9bDvHMNxtJP51PaLA/b93Rhj6tG5Z9gNbnERFx2UUFlYKCAhYtWsSuXbu4++67CQ0N5eDBg4SFhVGjRjmfchCppHIL7Iybu43JS/cC0DaqJv8a1J6oiBBzCxMR8UEuz1FJSUkhPj6egQMHMnz4cI4ePQrA+PHjGTly5EUXMnbsWCwWC0899dRFn0PE0/Yey+L2D5cVh5QHu8Xy9UMJCikiIh7iclB58skn6dixIydPnqRatWrF22+99VZ++eWXiypi1apVTJo0iTZt2lzU8SIVYc6Gg9z0/hI2H7BRKySA/wztyPP9LifQX3PSRUQ8xeVbP0uWLGHp0qUEBgaW2B4dHc2BAwdcLiAzM5N77rmHjz/+mNdfL1cPT5EKlZNv59X/JvHl76kAXN00gvcGtaNheLULHCkiIpfK5f8VdDgc2O3nLqC2f/9+QkNDXS5g+PDh9O/fn549e15w39zcXGw2W4kvEU9KPZrBS+99RNbqGXS2JvFEjxi+eKCTQoqISAVxeUSlV69eTJgwgUmTJgFgsVjIzMzk5ZdfdrmF/owZM1i7di2rVq0q1/5jx47l1VdfdbVkkYuyacF06i55mfEch6IBxC3/gag31ftERKSCWAzDKK2vd5kOHjxIjx498PPzIzk5mY4dO5KcnEydOnVYvHgx9erVK9d59u3bR8eOHfn5559p27YtANdddx3t2rVjwoQJpR6Tm5tLbm5u8WubzUZUVBTp6emEhYW58tsQKZPDYTDv60n0SXoWAGuJpY8LX6hRm4jIRbPZbISHh5fr89vloAJw+vRpvvzyS9auXYvD4eDKK6/knnvuKTG59kJmz57Nrbfeip/fHw2v7HY7FosFq9VKbm5uifdK48pvVKQ8bDn5/HXGWl7d82cacOKskFKkcH2epzapYZuIyEXweFBxh4yMDFJSUkpsu++++2jVqhXPPfccrVu3vuA5FFTEnXYczuCh6Wuof2IVMwLLMbF7yP/UwE1E5CK48vnt8hyVOXPmlLrdYrEQHBxM8+bNiYmJueB5QkNDzwkj1atXp3bt2uUKKSLu9MPGNJ75ZgPZeXa61ciCgnIclHnY43WJiFR1LgeVW265BYvFwtkDMUXbLBYL11xzDbNnz6ZWrVpuK1TEEwrsDt76eTsTE3cD0LV5bUZ06QYz373wwTXqe7g6ERFx+fHk+fPnc9VVVzF//nzS09NJT09n/vz5XH311fzvf/9j8eLFHD9+/KK61C5atKjMibQi7nY8M5chk38vDikPdY9l6n1XE96qu3MOCqVOUHFuD2vkXFRQREQ8yuURlSeffJJJkybRpcsf/0jfcMMNBAcH8+CDD7JlyxYmTJjAsGHD3FqoiDtt3H+KRz5by4FTpwkJ9OOtO9rSv80ZCwr2eRNmDsYZVs4cPSwML33GaSKtiEgFcHlEZdeuXaVOfAkLC2P3buf/mbZo0YJjx45denUiHjBz9T7u+Gg5B06dJqZOdWYP71oypIDz0eM7p0HYWdvDIvVosohIBXJ5RKVDhw4888wzTJs2jbp16wJw9OhRnn32Wa666ioAkpOTady4sXsrFblEeQUOXv3vFj5f6WyF3/Py+vzjrraEBQeUfkDcAGjVH1KWOSfO1qjvvN2jkRQRkQrjclD59NNPGThwII0bNyYqKgqLxUJqaiqxsbF8//33gHP9nhdffNHtxYpcrEPpOTzy+RrWpZ7CYoERPS9jeI/mWEtvlPIHq58eQRYRMdFF9VExDIOffvqJHTt2YBgGrVq1olevXlitFbuKrPqoSHms3H2c4V+s5VhmHmHB/rw3qD09Wpavg7KIiLhfpWj45g4KKnI+hmEwZdle3vhhKwUOg1YNQpn4fx2Irl3d7NJERKo0jzZ8A8jKyiIxMZHU1FTy8vJKvPfEE09czClF3MdhJ3fXEr76dRU/7TVwOFoxsF1jxt3WhmqBml8iIlKZuBxU1q1bR79+/cjOziYrK4uIiAiOHTtGSEgI9erVU1ARcyXNwf7jswRlpjEYGBwIWUH1CWnzFpbA9mZXJyIiLnJ5UsnTTz/NzTffzIkTJ6hWrRorVqwgJSWFDh068Pbbb3uiRpHySZqDMXMwlsy0Epur5x7BMnMIJJW+/IOIiHgvl4PK+vXr+etf/4qfnx9+fn7k5uYSFRXF+PHjef755z1Ro8iFOezk/PcZDMMo5Q914TSseaPAYa/gwkRE5FK4HFQCAgKwWJyPdNavX5/UVGdPivDw8OJfi1QkwzD44X+zCD59iLKfNjbAdsDZE0VERCoNl+eotG/fntWrV3PZZZfRo0cPXnrpJY4dO8b06dOJj4/3RI0iZcq3O3jp+y1krd5A/8ByHKAVj0VEKhWXR1TGjBlDw4bOtuKvvfYatWvX5pFHHuHIkSNMmjTJ7QWKlCX9dD73TV7Fl7+ncoSa5TtIKx6LiFQqLo2oGIZB3bp1ueKKKwCoW7cuP/74o0cKEzmflONZDJuyil1HswgJ9OP+O++Bn/8DtjRKLiJYxOJcp0crHouIVCoujagYhkGLFi3Yv3+/p+oRuaBVe09wy7+XsutoFg3Dg/n64QR6to50rngMFK9wXEwrHouIVFYuBRWr1UqLFi04fvy4p+oROa/v1u3nno9XcjI7n/hG4Xw/vCtXRIY739SKxyIiPsflybTjx4/nmWee4cMPP6R169aeqEnkHIZh8O78Hfxz4U4A+lzRgH/c1ZaQwLP+CGvFYxERn+LyWj+1atUiOzubgoICAgMDqVatWon3T5w44dYCz0dr/VQNOfl2Rn69gf9tdDZye7h7M569seWFVz4WERGv5NG1fiZMmHCxdYm47GhGLg9OX8261FP4Wy2MuS2eOztGmV2WiIhUEJeDypAhQzxRh8g5th/KYNiUVRw4dZrwagF8dG8HEprVNrssERGpQC73UQHYtWsXL7zwAoMGDeLIkSMAzJs3jy1btri1OKm6Fm0/wu0fLuPAqdM0rR3Cd492UUgREamCXA4qiYmJxMfHs3LlSr799lsyMzMB2LhxIy+//LLbC5SqZ9ryvQybsorM3AI6xUTw3aNdia1bw+yyRETEBC4HlVGjRvH6668zf/58AgP/6Fneo0cPli9f7tbipGqxOwxembOFl77fgsOAOzo0ZvpfOlGrenl644uIiC9yeY7Kpk2b+OKLL87ZXrduXfVXkYuWk2/n6S/XcHJbIgOsp7j+qngGDrgCi99F3Z0UEREf4XJQqVmzJmlpacTExJTYvm7dOho1auS2wqTqyMwt4OOJE3jx+L+JDCx8vH0DsOdVZ7dZNWoTEamyXP7f1bvvvpvnnnuOQ4cOYbFYcDgcLF26lJEjRzJ48GBP1Cg+7HhmLu//6x2ePP4aDTirB48tDWYOhqQ55hQnIiKmczmovPHGGzRp0oRGjRqRmZlJXFwc3bp1o0uXLrzwwgueqFF81IFTp7nroyUMsX0EFji3f1thL8J5o8Bhr+jyRETEC7jcmbbIrl27WLduHQ6Hg/bt29OiRQt313ZB6kxbee08ksn/fbqS6Iy1zAh8/cIHDPkfxFzr+cJERMTjPNqZNjExke7du9OsWTOaNWt20UVK1bVh3ymGTv6dk9n59K95GnLKcVDmYY/XJSIi3sflWz+9evWiSZMmjBo1is2bN3uiJvFhS3ce4+6PV3AyO5+2jcN5YmA5R0lq1PdsYSIi4pVcDioHDx7k2Wef5bfffqNNmza0adOG8ePHs3//fk/UJz5k3uY07pu8iqw8O12b1+bzBzoT1rIbhEUCZS0waIGwRs4VkEVEpMpxOajUqVOHxx57jKVLl7Jr1y7uuusupk2bRtOmTbn++us9UaP4gBm/p/Lo52vJszvoc0UD/jP0KmoE+YPVz/kIMnBuWCl83Weccz8REalyLnoybRG73c7cuXN58cUX2bhxI3Z7xT2docm0lcNHibsYN3cbAIOujuL1W+LxO/sRn6Q5MO85sB38Y1tYI2dIUR8VERGf4tHJtEWWLl3K559/zjfffENOTg4DBgxgzJgxF3s68UGGYTB27jYmLd4NwCPXNePZG1tisZRymyduALTqDynLnBNna9R33u7RSIqISJXmclB5/vnn+fLLLzl48CA9e/ZkwoQJ3HLLLYSEhHiiPqmkCuwORn+7ia/XOOcu/a3f5TzQLfb8B1n99AiyiIiU4HJQWbRoESNHjuSuu+6iTp06nqhJKrmcfDtPfLmOn5MOY7XAuNvbcGfHKLPLEhGRSsjloLJs2TJP1CE+IiMnnwemrWbF7hME+lt5f1B7bryigdlliYhIJXXRc1SSkpJITU0lLy+vxPYBAzTxsao6lpnL0Mm/s/mAjRpB/nw8uCMJzWqbXZaIiFRiLgeV3bt3c+utt7Jp0yYsFgtFDw0VTZCsyKd+xAs47JCyjOOHU3lj0QmSTjWldvVgpg67mtaNws2uTkREKjmX+6g8+eSTxMTEcPjwYUJCQtiyZQuLFy+mY8eOLFq0yAMlitdKmgMTWsPUm6g971HezXmB5cFP8kOvkwopIiLiFi6PqCxfvpyFCxdSt25drFYrVquVa665hrFjx/LEE0+wbt06T9Qp3iZpDswcjIFRok1bPU5gmfcghAWr/4mIiFwyl0dU7HY7NWrUAJxdag8edDboio6OZvv27e6tTryTww7znjsnpABYKOwfOG+Ucz8REZFL4PKISuvWrdm4cSOxsbF06tSJ8ePHExgYyKRJk4iNvUCfDPENKcvAdrDM1XnAANsB537qiyIiIpfA5aDywgsvkJWVBcDrr7/OTTfdxLXXXkvt2rX56quv3F6geJ/DB1Mo11rGmYc9XYqIiPg4l4PKjTfeWPzr2NhYkpKSOHHiBLVq1Sq9Nbr4lJTjWbz563E+KM/ONcoVZ0RERMp00X1UzhQREeGO04iX23cim0GTVnAoM5aj1WpTxzjxx5yUEiwQFulcq0dEROQSuDyZVqqmA6dOM+jjFRxMzyGmbiiBN79VOEfl3Om0gHPVYy0oKCIil8jUoPLhhx/Spk0bwsLCCAsLIyEhgblz55pZkpQiLf00gyatYP/J08TUqc6XD3Qm/Mrb4c5pENaw5M5hkc7tejRZRETcwC23fi5W48aNGTduHM2bNwdg6tSpDBw4kHXr1nHFFVeYWZoUOmzL4e6PV5J6IpsmESF88UAn6oUFO9+MGwCt+juf7sk87JyTEt1FIykiIuI2FqOoB76XiIiI4K233uIvf/nLOe/l5uaSm5tb/NpmsxEVFUV6ejphYWEVWWaVcDQjlz9PWs6uo1k0rlWNrx5KoFHNamaXJSIilZzNZiM8PLxcn99eM0fFbrczY8YMsrKySEhIKHWfsWPHEh4eXvwVFRVVwVVWHcczc7n74xXsOppFZHgwXz7QWSFFREQqnOkjKps2bSIhIYGcnBxq1KjBF198Qb9+/UrdVyMqFeNkVh6DPl7BtkMZNAgL5quHOhNdu7rZZYmIiI9wZUTF1DkqAC1btmT9+vWcOnWKWbNmMWTIEBITE4mLiztn36CgIIKCgkyosupIz87n3k9Xsu1QBvVCg/jigU4KKSIiYhrTR1TO1rNnT5o1a8bEiRMvuK8riUwuzJaTz72frGTj/nTq1AhkxoOdaV4v1OyyRETEx1TKOSpFDMMocXtHKkZGTj5D/vM7G/enE1E9kM/vV0gRERHzmXrr5/nnn6dv375ERUWRkZHBjBkzWLRoEfPmzTOzrConK7eA+yavYl3qKWqGBPDZXzrRsoFCioiImM/UoHL48GH+7//+j7S0NMLDw2nTpg3z5s2jV69eZpZVpWTnFTBsyipWp5wkLNifz/7SibhI3UYTERHvYGpQ+fTTT8389lVeTr6d+6euZuWeE4QG+TP9L51o3Sjc7LJERESKed0cFakYOfl2Hpi2mmW7jlM90I8pw66mbVRNs8sSEREpQUGlCiqwOxj++Vp+Sz5GSGFI6RBdy+yyREREzqGgUsUYhsEr328ka8cibg9cztc32rmqiW73iIiIdzK94ZtUrPmzPubRTWOJDDxRuOF9WBkJfd7UisciIuJ1NKJShaydN5Wem56hASdKvmFLg5mDIWmOOYWJiIiUQUGlili79xgNl78CgNVy9ruFzYnnjQKHvSLLEhEROS8FlSog9Xg2H02bTkPLiVJCShEDbAcgZVlFliYiInJeCio+7lR2HkOn/E5wzrHyHZB52LMFiYiIuEBBxYflFth5aPoadh/Nwl69XvkOqlHfs0WJiIi4QEHFRxmGwehZm1i55wQ1gvx5/L7BEBYJlHXvxwJhjSC6S0WWKSIicl4KKj5qwoJkvl13AD+rhQ/uuZJWkbWcjyAD54aVwtd9xoHVryLLFBEROS8FFR80a81+3vslGYA3bmlNt8vqOt+IGwB3ToOwhiUPCIt0blcfFRER8TJq+OZjlu86zqhvNwLwyHXN+PPVTUruEDcAWvV3Pt2Tedg5JyW6i0ZSRETEKymo+JCdRzJ4aPpq8u0GN7VpyDO9W5a+o9UPYq6t2OJEREQugm79+IhjmbncN2UVtpwCOkTX4u0/tcVadtMUERGRSkFBxQfk5Nu5f+pq9p04TXTtED4e3JHgAN3KERGRyk9BpZJzOAye/mo96/edomZIAJOHXkVE9UCzyxIREXELBZVKbty8bczdfIhAPyuT/q8jsXVrmF2SiIiI2yioVGKfrUhh0uLdALz1pzZcHRNhckUiIiLupaBSSf267Qgvfb8ZgL/2uoyB7RqZXJGIiIj7KahUQlsOpvPYF2txGHBHh8Y8dn1zs0sSERHxCAWVSiYt/TTDpqwiK89Ol2a1GXNrPBaLHkMWERHfpKBSiWTmFjBsymoO23JpUa8GH97bgUB//QhFRMR36VOukjAM52PIW9Ns1KkRxH+GXkV4tQCzyxIREfEoBZVKYuqyvcxPOkygn5VPhnQkKiLE7JJEREQ8TkGlEkg6aGPMj9sAeL5fK9pF1TS3IBERkQqioOLlsvMKePzLtRTYCxje9CBDQlfDnt/AYTe7NBEREY/T6sle7tU5STQ//itfBE+n/qHj8G3hG2GR0OdNiBtgan0iIiKepBEVL/bfDQc5tXYWHwZMoB7HS75pS4OZgyFpjjnFiYiIVAAFFS+170Q2L3y7gZcDpmGxwLmdUgznf+aN0m0gERHxWQoqXijf7uCJGeu4PH8zkZYTpYSUIgbYDkDKsgqsTkREpOIoqHihCQt2sC71FE0CbeU7IPOwZwsSERExiYKKl1m28xgfLNoFwK3XdijfQTXqe7AiERER8yioeJHjmbk89dV6DAMGXR1FQo+bnU/3lHnzxwJhjSC6S0WWKSIiUmEUVLyEYRg8881GjmTk0rxeDV666Qqw+jkfQQbODSuFr/uMc+4nIiLigxRUvMSUZXtZuO0Igf5W3h/UnmqBheEjbgDcOQ3CGpY8ICzSuV19VERExIep4ZsX2HwgnbGFLfJf6H85lzcMK7lD3ABo1d/5dE/mYeeclOguGkkRERGfp6BisqzcAp74ch15dge94urzf52jS9/R6gcx11ZscSIiIibTrR+TvTJnC7uPZdEgLJjxt7fBYim7a4qIiEhVo6Biou/XH+DrNfuxWmDCn9tRq3qg2SWJiIh4FQUVk6Qez+aF7zYD8Nj1LegcW9vkikRERLyPgooJilrkZ+QW0DG6Fk9c39zskkRERLySgooJ/jF/B+v3nSIs2J8Jf26Hv59+DCIiIqXRJ2QFW5J8jI8SnS3y37y9DY1rhZhckYiIiPdSUKlAxzJzeXqms0X+3Z2a0De+4YUPEhERqcIUVCqIw2Ew8usNHM3I5bL6NXixf5zZJYmIiHg9U4PK2LFjueqqqwgNDaVevXrccsstbN++3cySPGbysr0s2n6UIH8r7w+68o8W+SIiIlImU4NKYmIiw4cPZ8WKFcyfP5+CggJ69+5NVlaWmWW53eYD6YybuxWAF26Ko2WDUJMrEhERqRxMbaE/b968Eq8nT55MvXr1WLNmDd26dTOpKvfKyi3g8S/XkW83uPGK+tzbqYnZJYmIiFQaXrXWT3p6OgARERGlvp+bm0tubm7xa5vNViF1XYq3ftrOnmNZNAwP5k21yBcREXGJ10ymNQyDESNGcM0119C6detS9xk7dizh4eHFX1FRURVcpWt2H83ksxUpAIy/ow01Q9QiX0RExBVeE1Qee+wxNm7cyJdfflnmPqNHjyY9Pb34a9++fRVYoevGzt1GgcPghlb1uLZFXbPLERERqXS84tbP448/zpw5c1i8eDGNGzcuc7+goCCCgoIqsLKLt2L3cX5JSqOL33beaHES9uRAdBew6mkfERGR8jI1qBiGweOPP853333HokWLiImJMbMct3E4DH759hOWBH1EpOUEzC98IywS+rwJcQNMrU9ERKSyMPXWz/Dhw/nss8/44osvCA0N5dChQxw6dIjTp0+bWdYl+/3HKYzOGEMDTpR8w5YGMwdD0hxzChMREalkLIZhGKZ98zKegJk8eTJDhw694PE2m43w8HDS09MJCwtzc3UX53ROHrZxrahrHMda6m/P4hxZeWqTbgOJiEiV5Mrnt+m3fnzNvB9ncSvHocynkA2wHYCUZRBzbUWWJiIiUul4zVM/vuBIRg7L1ieVb+fMw54tRkRExAcoqLjRu/OT2VdQzltQNep7thgREREf4BWPJ/uC7Ycy+GpVKhityAtpQGD2YaC0W1uFc1Siu1R0iSIiIpWORlTcZMyPW3EYcGPrSAJveqtw69kTVQpf9xmnibQiIiLloKDiBot3HCVxx1EC/CyM6tvK2SflzmkQ1rDkjmGRzu3qoyIiIlIuuvVziewOgzE/bgVgcEJTomtXd74RNwBa9Xc+3ZN52DknRZ1pRUREXKKgcom+Xr2PbYcyCK8WwOPXNy/5ptVPjyCLiIhcAt36uQRZuQW8M38HAI9f31yrI4uIiLiZgsolmJi4i6MZuUTXDmFwQlOzyxEREfE5CioXKS39NJN+2w3AqD6tCPTXpRQREXE3fbpepLd/2kFOvoOrmtaiT+sGZpcjIiLikxRULsLmA+l8u24/AH/rH1fm4ooiIiJyaRRUXGQYBm/8sBXDgAFtI2kXVdPskkRERHyWgoqLftl6hOW7jxPob+XZPi3NLkdERMSnKai4IN/uYMxcZ3O3YV1jaFwrxOSKREREfJuCigu+/D2V3UeziKgeyKM9mpldjoiIiM9TUCknW04+ExYkA/B0zxaEBQeYXJGIiIjvU1App3//upMTWXk0q1udQVc3MbscERGRKkFBpRz2nchm8pK9ADzf73L8/XTZREREKoI+ccth/E/bybM76NKsNte3qmd2OSIiIlWGgsoFrEs9yX83HMRigb/1v1zN3URERCqQgsp5GIbB6z84H0e+/crGXBEZbnJFIiIiVYuCynnM3XyINSknqRbgx8jeau4mIiJS0RRUypBbYGfc3G0APNAtlgbhwSZXJCIiUvUoqJRh+vIUUk9kUzc0iIe6xZpdjoiISJWkoFKKk1l5/PMXZ3O3kb0vo3qQv8kViYiIVE0KKqWYvHQPtpwCWjUI5Y4OUWaXIyIiUmVpqKAUj/ZoTrVAf9o2DsfPqseRRUREzKKgUorgAD8euU6LDoqIiJhNt35ERETEaymoiIiIiNfSrZ/SOOyQsgwyD0ON+hDdBax+ZlclIiJS5SionC1pDsx7DmwH/9gWFgl93oS4AebVJSIiUgXp1s+ZkubAzMElQwqALc25PWmOOXWJiIhUUQoqRRx250gKRilvFm6bN8q5n4iIiFQIBZUiKcvOHUkpwQDbAed+IiIiUiEUVIpkHnbvfiIiInLJFFSK1Kjv3v1ERETkkimoFInu4ny6h7Ja5lsgrJFzPxEREakQCipFrH7OR5CBc8NK4es+49RPRUREpAIpqJwpbgDcOQ3CGpbcHhbp3K4+KiIiIhVKDd/OFjcAWvVXZ1oREREvoKBSGqsfxFxrdhUiIiJVnm79iIiIiNdSUBERERGvpaAiIiIiXktBRURERLyWqUFl8eLF3HzzzURGRmKxWJg9e7aZ5YiIiIiXMTWoZGVl0bZtW/71r3+ZWYaIiIh4KVMfT+7bty99+/Yt9/65ubnk5uYWv7bZbJ4oS0RERLxEpZqjMnbsWMLDw4u/oqKizC5JREREPKhSBZXRo0eTnp5e/LVv3z6zSxIREREPqlSdaYOCgggKCip+bRgGoFtAIiIilUnR53bR5/j5VKqgcraMjAwA3QISERGphDIyMggPDz/vPpU6qERGRrJv3z5CQ0OxWCzYbDaioqLYt28fYWFhZpdXZei6m0PX3Ry67ubQdTeHp667YRhkZGQQGRl5wX1NDSqZmZns3Lmz+PWePXtYv349ERERNGnS5ILHW61WGjdufM72sLAw/UE2ga67OXTdzaHrbg5dd3N44rpfaCSliKlBZfXq1fTo0aP49YgRIwAYMmQIU6ZMMakqERER8RamBpXrrruuXBNpREREpGqqVI8nX0hQUBAvv/xyiSeDxPN03c2h624OXXdz6Lqbwxuuu8XQkIaIiIh4KZ8aURERERHfoqAiIiIiXktBRURERLyWgoqIiIh4LZ8JKh988AExMTEEBwfToUMHfvvtN7NL8jmLFy/m5ptvJjIyEovFwuzZs0u8bxgGr7zyCpGRkVSrVo3rrruOLVu2mFOsjxg7dixXXXUVoaGh1KtXj1tuuYXt27eX2EfX3f0+/PBD2rRpU9zkKiEhgblz5xa/r2vueWPHjsVisfDUU08Vb9N194xXXnkFi8VS4qtBgwbF75t93X0iqHz11Vc89dRT/O1vf2PdunVce+219O3bl9TUVLNL8ylZWVm0bduWf/3rX6W+P378eP7xj3/wr3/9i1WrVtGgQQN69epVvCaTuC4xMZHhw4ezYsUK5s+fT0FBAb179yYrK6t4H11392vcuDHjxo1j9erVrF69muuvv56BAwcW/+Osa+5Zq1atYtKkSbRp06bEdl13z7niiitIS0sr/tq0aVPxe6Zfd8MHXH311cbDDz9cYlurVq2MUaNGmVSR7wOM7777rvi1w+EwGjRoYIwbN654W05OjhEeHm589NFHJlTom44cOWIARmJiomEYuu4VqVatWsYnn3yia+5hGRkZRosWLYz58+cb3bt3N5588knDMPRn3ZNefvllo23btqW+5w3XvdKPqOTl5bFmzRp69+5dYnvv3r1ZtmyZSVVVPXv27OHQoUMlfg5BQUF0795dPwc3Sk9PByAiIgLQda8IdrudGTNmkJWVRUJCgq65hw0fPpz+/fvTs2fPEtt13T0rOTmZyMhIYmJi+POf/8zu3bsB77julXr1ZIBjx45ht9upX79+ie3169fn0KFDJlVV9RRd69J+DikpKWaU5HMMw2DEiBFcc801tG7dGtB196RNmzaRkJBATk4ONWrU4LvvviMuLq74H2ddc/ebMWMGa9euZdWqVee8pz/rntOpUyemTZvGZZddxuHDh3n99dfp0qULW7Zs8YrrXumDShGLxVLitWEY52wTz9PPwXMee+wxNm7cyJIlS855T9fd/Vq2bMn69es5deoUs2bNYsiQISQmJha/r2vuXvv27ePJJ5/k559/Jjg4uMz9dN3dr2/fvsW/jo+PJyEhgWbNmjF16lQ6d+4MmHvdK/2tnzp16uDn53fO6MmRI0fOSYDiOUUzxPVz8IzHH3+cOXPm8Ouvv9K4cePi7brunhMYGEjz5s3p2LEjY8eOpW3btrz33nu65h6yZs0ajhw5QocOHfD398ff35/ExET++c9/4u/vX3xtdd09r3r16sTHx5OcnOwVf94rfVAJDAykQ4cOzJ8/v8T2+fPn06VLF5OqqnpiYmJo0KBBiZ9DXl4eiYmJ+jlcAsMweOyxx/j2229ZuHAhMTExJd7Xda84hmGQm5ura+4hN9xwA5s2bWL9+vXFXx07duSee+5h/fr1xMbG6rpXkNzcXLZu3UrDhg294897hUzZ9bAZM2YYAQEBxqeffmokJSUZTz31lFG9enVj7969ZpfmUzIyMox169YZ69atMwDjH//4h7Fu3TojJSXFMAzDGDdunBEeHm58++23xqZNm4xBgwYZDRs2NGw2m8mVV16PPPKIER4ebixatMhIS0sr/srOzi7eR9fd/UaPHm0sXrzY2LNnj7Fx40bj+eefN6xWq/Hzzz8bhqFrXlHOfOrHMHTdPeWvf/2rsWjRImP37t3GihUrjJtuuskIDQ0t/gw1+7r7RFAxDMP497//bURHRxuBgYHGlVdeWfz4prjPr7/+agDnfA0ZMsQwDOdjbC+//LLRoEEDIygoyOjWrZuxadMmc4uu5Eq73oAxefLk4n103d1v2LBhxf+e1K1b17jhhhuKQ4ph6JpXlLODiq67Z9x1111Gw4YNjYCAACMyMtK47bbbjC1bthS/b/Z1txiGYVTM2I2IiIiIayr9HBURERHxXQoqIiIi4rUUVERERMRrKaiIiIiI11JQEREREa+loCIiIiJeS0FFREREvJaCioiIiHgtBRURERHxWgoqIlIpjBs3joSEBLPLEJEKpqAiIpXChg0baNu2rdlliEgFU1ARkUphw4YNtGvXzuwyRKSCKaiIiNfZunUr1113HdWqVaN9+/asXr2aHTt2aERFpApSUBERr7Jt2zY6depEx44d2bx5My+99BIDBw7EMAzatGljdnkiUsEshmEYZhchIlLkhhtuIDIykunTpxdvGzRoEGvXrmX79u0mViYiZvA3uwARkSIpKSksXLiQtWvXltgeEBCg2z4iVZRu/YiI11i/fj3+/v7Ex8eX2L527VpNpBWpohRURMRrWK1WHA4HeXl5xdt+/PFHtmzZoqAiUkUpqIiI1+jQoQMBAQGMHDmS3bt3M2fOHB544AEA3foRqaI0mVZEvMpnn33G6NGjycrKon379nTq1ImPP/6Yo0ePml2aiJhAQUVERES8lm79iIiIiNdSUBERERGvpaAiIiIiXktBRURERLyWgoqIiIh4LQUVERER8VoKKiIiIuK1FFRERETEaymoiIiIiNdSUBERERGvpaAiIiIiXuv/Acqi+LekuU7gAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "nr_vectors = 1_000\n", + "dims = np.arange(2, 51, 2)\n", + "average_distances = [\n", + " compute_average_distance(rng, nr_vectors, dim) for dim in dims\n", + "]\n", + "figure, axis = plt.subplots()\n", + "axis.plot(dims, np.sqrt(dims), label=r'$\\sqrt{d}$')\n", + "axis.plot(dims, average_distances, 'o', label='sampled')\n", + "axis.set_xlabel('$d$')\n", + "axis.set_ylabel('average distance')\n", + "axis.legend();" + ] + }, + { + "cell_type": "markdown", + "id": "7c374d5e-1c6c-4ec5-8197-685ab4d13e35", + "metadata": {}, + "source": [ + "It should not come as a surprise that the average distance scales with $\\sqrt{d}$." + ] } ], "metadata": { @@ -392,7 +658,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.9" + "version": "3.12.11" } }, "nbformat": 4, diff --git a/source-code/keras/README.md b/source-code/keras/README.md index ac09870..5fc108b 100644 --- a/source-code/keras/README.md +++ b/source-code/keras/README.md @@ -15,6 +15,10 @@ machine learning tasks. 1. `mnist_cnn.pbs`: example PBS script to exectute the `mnist_cnn.ipynb` notebook in batch as a job. 1. `Flatland`: machine learning adventures in Flatland. +1. [`environment_keras.yml`](environment_keras.yml): CPU-only Linux conda + environment for the legacy Keras examples. +1. [`environment_keras_gpu.yml`](environment_keras_gpu.yml): Linux/NVIDIA conda + environment for running the legacy Keras examples with GPU acceleration. ## References Excellent [tutorial](https://github.com/leriomaggio/deep-learning-keras-tensorflow). diff --git a/environment_keras.yml b/source-code/keras/environment_keras.yml similarity index 100% rename from environment_keras.yml rename to source-code/keras/environment_keras.yml diff --git a/environment_keras_gpu.yml b/source-code/keras/environment_keras_gpu.yml similarity index 100% rename from environment_keras_gpu.yml rename to source-code/keras/environment_keras_gpu.yml diff --git a/source-code/parameter-optimization/JuliaJobs/Makefile b/source-code/parameter-optimization/JuliaJobs/Makefile deleted file mode 100644 index a396e25..0000000 --- a/source-code/parameter-optimization/JuliaJobs/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -CXX = g++ -CXXFLAGS = -fopenmp -std=c++14 -O2 -g -Wall -Wextra -LDLIBS = -lm - -all: julia_omp.exe - -%.exe: %.o - $(CXX) $(CXXFLAGS) -o $@ $^ $(LDLIBS) - -clean: - $(RM) $(wildcard *.exe) $(wildcard *.o) - $(RM) core $(wildcard core.*) diff --git a/source-code/parameter-optimization/JuliaJobs/README.md b/source-code/parameter-optimization/JuliaJobs/README.md deleted file mode 100644 index 8f96dcf..0000000 --- a/source-code/parameter-optimization/JuliaJobs/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# JuliaJobs - -Illustration of optimizing application parameters by running jobs. - -## What is it? - - 1. `julia_omp.cpp`: C++ application that compute the Julia set - fractal, using OpenMP for parallelization. The parallel - for-loop schedule is `runtime`, and hence can be controled - using the `OMP_SCHEDULE` environment variable. Timing - information is writting to standard error. - 1. `Makefile`: make file to build the Julia set application. - 1. `julia.pbs`: PBS script to run the Julia set applciation - as a job. - 1. `julia_optimize.py`: Python script to find optimal OpenMP - schedule, chunk size and number of threads for the Julia set - application. diff --git a/source-code/parameter-optimization/JuliaJobs/julia.pbs b/source-code/parameter-optimization/JuliaJobs/julia.pbs deleted file mode 100644 index f09cf1b..0000000 --- a/source-code/parameter-optimization/JuliaJobs/julia.pbs +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env bash -#PBS -A lp_sys -#PBS -l pmem=2gb -#PBS -l walltime=00:05:00 -#PBS -j oe - -cd $PBS_O_WORKDIR - -source switch_to_2018a -module load foss - -# verify that OpenMP environment variables have been passed -# using -v options -if [[ -z "$schedule" ]] -then - (>&2 echo "### error: OpenMP schedule not set") - exit 1 -fi -if [[ -z "$chunk" ]] -then - (>&2 echo "### error: OpenMP chunk not set") - exit 1 -fi - -OMP_SCHEDULE="${schedule},${chunk}" -(>&2 echo "### info: OMP_SCHEDULE=\'${OMP_SCHEDULE}\'") - -if [[ -z "$OMP_NUM_THREADS" ]] -then - (>&2 echo "### error: OpenMP number of threads not set") - exit 2 -else - (>&2 echo "### info: OMP_NUM_THREADS=\'${OMP_NUM_THREADS}\'") -fi - -# ensure the executable is op to date -make all -if [[ $? -ne 0 ]] -then - (>&2 echo "### error: make failed") - exit 3 -fi - -# determine time file name -time_file="julia.pbs.time${PBS_JOBID/\.*/}" - -# run application on a sufficiently large matrix, disregarding -# output, timing information is writting to a file -for i in $(seq 3) -do - ./julia_omp.exe 4096 > /dev/null 2>> "${time_file}" -done diff --git a/source-code/parameter-optimization/JuliaJobs/julia_omp.cpp b/source-code/parameter-optimization/JuliaJobs/julia_omp.cpp deleted file mode 100644 index b7ee2a6..0000000 --- a/source-code/parameter-optimization/JuliaJobs/julia_omp.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include -#include -#include -#include -#include -#include - -using namespace std; -using my_time_t = chrono::nanoseconds; - -using cmplx = complex; - -valarray coordinates(float min_coord, float max_coord, - size_t steps); -valarray z_values(const valarray& x_coords, - const valarray& y_coords); -valarray iterate_zs(valarray& zs, const complex& c, - size_t max_iters); -void print_results(const valarray& ns); - -int main(int argc, char *argv[]) { - const cmplx c(-0.62772, - 0.42193); - const float x1 {-1.8}; - const float x2 {1.8}; - const float y1 {-1.8}; - const float y2 {1.8}; - const size_t max_iters {255}; - size_t steps {100}; - if (argc > 1) - steps = stoi(argv[1]); - valarray x_coords = coordinates(x1, x2, steps); - valarray y_coords = coordinates(y1, y2, steps); - valarray zs = z_values(x_coords, y_coords); - auto start_time = chrono::steady_clock::now(); - valarray ns = iterate_zs(zs, c, max_iters); - auto end_time = chrono::steady_clock::now(); - auto duration = chrono::duration_cast(end_time - start_time); - cerr << duration.count()*1.0e-9 << endl; - print_results(ns); - return 0; -} - -valarray coordinates(float min_coord, float max_coord, - size_t steps) { - valarray coords(steps); - const float step {(max_coord - min_coord)/steps}; - float value {min_coord}; - for (size_t i = 0; i < steps; i++) { - coords[i] = value; - value += step; - } - return coords; -} - -valarray z_values(const valarray& x_coords, - const valarray& y_coords) { - valarray zs(x_coords.size()*y_coords.size()); - size_t i {0}; - for (auto y: y_coords) - for (auto x: x_coords) { - complex z(x, y); - zs[i++] = z; - } - return zs; -} - -int iterate_z(cmplx z, const cmplx& c, size_t max_iters) { - size_t n {0}; - const complex z_in {z}; - while (abs(z) < 2.0 && n++ < max_iters) - z = z*z + c; - return n; -} - -valarray iterate_zs(valarray& zs, const complex& c, - size_t max_iters) { - valarray ns(zs.size()); -#pragma omp parallel for schedule(runtime) - for (size_t i = 0; i < zs.size(); i++) - ns[i] = iterate_z(zs[i], c, max_iters); - return ns; -} - -void print_results(const valarray& ns) { - size_t steps = ((size_t) sqrt(ns.size()) + 0.1); - size_t count {0}; - for (auto n: ns) { - cout << n; - if (++count % steps == 0) - cout << endl; - else - cout << " "; - } -} diff --git a/source-code/parameter-optimization/JuliaJobs/julia_optimize.py b/source-code/parameter-optimization/JuliaJobs/julia_optimize.py deleted file mode 100755 index 10246db..0000000 --- a/source-code/parameter-optimization/JuliaJobs/julia_optimize.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python - -from argparse import ArgumentParser -from pathlib import Path -import subprocess -import sys -import time -from hyperopt import fmin, hp, STATUS_OK, tpe, Trials - - -def function(params): - schedule, chunk, ppn = params - # chunk is given as a floating point number - chunk = int(chunk) - # ppn ranges from 0 to 35 (inclusive) - ppn = 1 + int(ppn) - omp_env = (f'schedule={schedule},chunk={int(chunk)},' + - f'OMP_NUM_THREADS={ppn}') - cmd = ['qsub', '-l', f'nodes=1:ppn={ppn}:haswell', - '-v', omp_env, 'julia.pbs'] - process = subprocess.run(cmd, stdout=subprocess.PIPE, - encoding='utf8') - job_id, *_ = process.stdout.split('.') - print(f'### info: submitted job {job_id}', file=sys.stderr) - output_file = Path(f'julia.pbs.o{job_id}') - while not output_file.exists(): - time.sleep(3) - print(f'### info: job {job_id} finished', file=sys.stderr) - runtimes = list() - with open(f'julia.pbs.time{job_id}', 'r') as time_file: - for line in time_file: - runtimes.append(float(time_file.readline())) - runtime = sum(runtimes)/len(runtimes) - return { - 'loss': runtime, 'schedule': schedule, 'chunk': chunk, - 'ppn': ppn, 'job_id': job_id, 'status': STATUS_OK, - 'time': time.strftime('%Y-%m-%d %H:%M:%S'), - } - - -def optimize(max_evals, max_ppn): - space = hp.choice('schedule', [ - ('static', hp.qloguniform('chunk_s', 2, 11, 10), - hp.randint('ppn_s', max_ppn)), - ('dynamic', hp.qloguniform('chunk_d', 2, 11, 10), - hp.randint('ppn_d', max_ppn)), - ('guided', hp.qloguniform('chunk_g', 2, 11, 10), - hp.randint('ppn_g', max_ppn)), - ]) - trials = Trials() - best = fmin(function, space=space, algo=tpe.suggest, - max_evals=max_evals, trials=trials) - return best, trials - - -def main(): - arg_parser = ArgumentParser(description='optimize external ' - 'process') - arg_parser.add_argument('--max-ppn', type=int, default=20, - help='maximum number of cores to use') - arg_parser.add_argument('--max-evals', type=int, - default=100, help='maximum evals') - arg_parser.add_argument('--trials', required=True, - help='file to save trials') - options = arg_parser.parse_args() - _, trials = optimize(options.max_evals, options.max_ppn) - with open(options.trials, 'w') as trials_file: - print('schedule,chunk,ppn,job_id,runtime', - file=trials_file) - for trial in trials.results: - schedule = trial['schedule'] - chunk = trial['chunk'] - ppn = trial['ppn'] - job_id = trial['job_id'] - runtime = trial['loss'] - print(f'{schedule},{chunk:d},{ppn:d},' - f'({job_id}),{runtime}', file=trials_file) - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/source-code/parameter-optimization/JuliaProcesses/Makefile b/source-code/parameter-optimization/JuliaProcesses/Makefile deleted file mode 100644 index a396e25..0000000 --- a/source-code/parameter-optimization/JuliaProcesses/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -CXX = g++ -CXXFLAGS = -fopenmp -std=c++14 -O2 -g -Wall -Wextra -LDLIBS = -lm - -all: julia_omp.exe - -%.exe: %.o - $(CXX) $(CXXFLAGS) -o $@ $^ $(LDLIBS) - -clean: - $(RM) $(wildcard *.exe) $(wildcard *.o) - $(RM) core $(wildcard core.*) diff --git a/source-code/parameter-optimization/JuliaProcesses/README.md b/source-code/parameter-optimization/JuliaProcesses/README.md deleted file mode 100644 index 1284e03..0000000 --- a/source-code/parameter-optimization/JuliaProcesses/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# JuliaProcesses - -Illustration of optimizing application parameters by running -processes. - -## What is it? - - 1. `julia_omp.cpp`: C++ application that compute the Julia set - fractal, using OpenMP for parallelization. The parallel - for-loop schedule is `runtime`, and hence can be controled - using the `OMP_SCHEDULE` environment variable. Timing - information is writting to standard error. - 1. `Makefile`: make file to build the Julia set application. - 1. `julia_optimize.py`: Python script to find optimal OpenMP - schedule, chunk size and number of threads for the Julia set - application. - 1. `julia_gcc.pbs`: PBS script to optimize the Julia set - applciation parameters as a job (GCC compiler). - 1. `julia_intel.pbs`: PBS script to optimize the Julia set - applciation parameters as a job (Intel compiler). diff --git a/source-code/parameter-optimization/JuliaProcesses/julia_gcc.pbs b/source-code/parameter-optimization/JuliaProcesses/julia_gcc.pbs deleted file mode 100644 index ae14a1a..0000000 --- a/source-code/parameter-optimization/JuliaProcesses/julia_gcc.pbs +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -#PBS -A lp_sys -#PBS -l nodes=1:ppn=24:haswell -#PBS -l pmem=2gb -#PBS -l walltime=03:00:00 -#PBS -j oe -#PBS -m ae -#PBS -M geertjan.bex@uhasselt.be - -cd $PBS_O_WORKDIR - -source switch_to_2018a -module load foss - -# ensure the executable is op to date -make CXX=g++ CXXFLAGS='-fopenmp -std=c++14 -O2' clean all -if [[ $? -ne 0 ]] -then - (>&2 echo "### error: make failed") - exit 1 -fi - -module load conda -source activate hyperopt - -./julia_optimize.py --max-ppn 20 --max-evals 100 \ - --trials trials_gcc.txt diff --git a/source-code/parameter-optimization/JuliaProcesses/julia_intel.pbs b/source-code/parameter-optimization/JuliaProcesses/julia_intel.pbs deleted file mode 100644 index d770048..0000000 --- a/source-code/parameter-optimization/JuliaProcesses/julia_intel.pbs +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -#PBS -A lp_sys -#PBS -l nodes=1:ppn=24:haswell -#PBS -l pmem=2gb -#PBS -l walltime=03:00:00 -#PBS -j oe -#PBS -m ae -#PBS -M geertjan.bex@uhasselt.be - -cd $PBS_O_WORKDIR - -source switch_to_2018a -module load intel - -# ensure the executable is op to date -make CXX=icpc CXXFLAGS='-qopenmp -std=c++14 -O2' clean all -if [[ $? -ne 0 ]] -then - (>&2 echo "### error: make failed") - exit 1 -fi - -module load conda -source activate hyperopt - -./julia_optimize.py --max-ppn 20 --max-evals 100 \ - --trials trials_intel.txt diff --git a/source-code/parameter-optimization/JuliaProcesses/julia_omp.cpp b/source-code/parameter-optimization/JuliaProcesses/julia_omp.cpp deleted file mode 100644 index b7ee2a6..0000000 --- a/source-code/parameter-optimization/JuliaProcesses/julia_omp.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include -#include -#include -#include -#include -#include - -using namespace std; -using my_time_t = chrono::nanoseconds; - -using cmplx = complex; - -valarray coordinates(float min_coord, float max_coord, - size_t steps); -valarray z_values(const valarray& x_coords, - const valarray& y_coords); -valarray iterate_zs(valarray& zs, const complex& c, - size_t max_iters); -void print_results(const valarray& ns); - -int main(int argc, char *argv[]) { - const cmplx c(-0.62772, - 0.42193); - const float x1 {-1.8}; - const float x2 {1.8}; - const float y1 {-1.8}; - const float y2 {1.8}; - const size_t max_iters {255}; - size_t steps {100}; - if (argc > 1) - steps = stoi(argv[1]); - valarray x_coords = coordinates(x1, x2, steps); - valarray y_coords = coordinates(y1, y2, steps); - valarray zs = z_values(x_coords, y_coords); - auto start_time = chrono::steady_clock::now(); - valarray ns = iterate_zs(zs, c, max_iters); - auto end_time = chrono::steady_clock::now(); - auto duration = chrono::duration_cast(end_time - start_time); - cerr << duration.count()*1.0e-9 << endl; - print_results(ns); - return 0; -} - -valarray coordinates(float min_coord, float max_coord, - size_t steps) { - valarray coords(steps); - const float step {(max_coord - min_coord)/steps}; - float value {min_coord}; - for (size_t i = 0; i < steps; i++) { - coords[i] = value; - value += step; - } - return coords; -} - -valarray z_values(const valarray& x_coords, - const valarray& y_coords) { - valarray zs(x_coords.size()*y_coords.size()); - size_t i {0}; - for (auto y: y_coords) - for (auto x: x_coords) { - complex z(x, y); - zs[i++] = z; - } - return zs; -} - -int iterate_z(cmplx z, const cmplx& c, size_t max_iters) { - size_t n {0}; - const complex z_in {z}; - while (abs(z) < 2.0 && n++ < max_iters) - z = z*z + c; - return n; -} - -valarray iterate_zs(valarray& zs, const complex& c, - size_t max_iters) { - valarray ns(zs.size()); -#pragma omp parallel for schedule(runtime) - for (size_t i = 0; i < zs.size(); i++) - ns[i] = iterate_z(zs[i], c, max_iters); - return ns; -} - -void print_results(const valarray& ns) { - size_t steps = ((size_t) sqrt(ns.size()) + 0.1); - size_t count {0}; - for (auto n: ns) { - cout << n; - if (++count % steps == 0) - cout << endl; - else - cout << " "; - } -} diff --git a/source-code/parameter-optimization/JuliaProcesses/julia_optimize.py b/source-code/parameter-optimization/JuliaProcesses/julia_optimize.py deleted file mode 100755 index afbbd98..0000000 --- a/source-code/parameter-optimization/JuliaProcesses/julia_optimize.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python - -from argparse import ArgumentParser -import os -import subprocess -import sys -import time -from hyperopt import fmin, hp, STATUS_OK, tpe, Trials - - -def function(params): - schedule, chunk, ppn = params - # chunk is given as a floating point number - chunk = int(chunk) - # ppn ranges from 0 to 35 (inclusive) - ppn = 1 + int(ppn) - environ = os.environ.copy() - environ['OMP_SCHEDULE'] = f'{schedule},{chunk}' - environ['OMP_NUM_THREADS'] = f'{ppn}' - cmd = ['./julia_omp.exe 4096'] - runtimes = list() - for _ in range(3): - process = subprocess.run(cmd, stderr=subprocess.PIPE, - stdout=subprocess.PIPE, - env=environ, shell=True, - encoding='utf8') - runtimes.append(float(process.stderr)) - runtime = sum(runtimes)/len(runtimes) - return { - 'loss': runtime, 'schedule': schedule, 'chunk': chunk, - 'ppn': ppn, 'status': STATUS_OK, - 'time': time.strftime('%Y-%m-%d %H:%M:%S'), - } - - -def optimize(max_evals, max_ppn): - space = hp.choice('schedule', [ - ('static', hp.qloguniform('chunk_s', 2, 11, 10), - hp.randint('ppn_s', max_ppn)), - ('dynamic', hp.qloguniform('chunk_d', 2, 11, 10), - hp.randint('ppn_d', max_ppn)), - ('guided', hp.qloguniform('chunk_g', 2, 11, 10), - hp.randint('ppn_g', max_ppn)), - ]) - trials = Trials() - best = fmin(function, space=space, algo=tpe.suggest, - max_evals=max_evals, trials=trials) - return best, trials - - -def main(): - arg_parser = ArgumentParser(description='optimize external ' - 'process') - arg_parser.add_argument('--max-ppn', type=int, default=20, - help='maximum number of cores to use') - arg_parser.add_argument('--max-evals', type=int, - default=100, help='maximum evals') - arg_parser.add_argument('--trials', required=True, - help='file to save trials') - options = arg_parser.parse_args() - _, trials = optimize(options.max_evals, options.max_ppn) - with open(options.trials, 'w') as trials_file: - print('schedule,chunk,ppn,runtime', file=trials_file) - for trial in trials.results: - schedule = trial['schedule'] - chunk = trial['chunk'] - ppn = trial['ppn'] - runtime = trial['loss'] - print(f'{schedule},{chunk:d},{ppn:d},{runtime}', - file=trials_file) - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/source-code/parameter-optimization/JuliaProcesses/trials_gcc.txt b/source-code/parameter-optimization/JuliaProcesses/trials_gcc.txt deleted file mode 100644 index 6fe4f21..0000000 --- a/source-code/parameter-optimization/JuliaProcesses/trials_gcc.txt +++ /dev/null @@ -1,101 +0,0 @@ -schedule,chunk,ppn,runtime -static,30,12,1.5917266666666665 -static,4860,2,8.171240000000001 -guided,670,15,2.3501399999999997 -guided,33600,18,1.94371 -static,10,20,0.973173 -static,2020,3,5.548903333333333 -guided,38720,9,3.6095133333333336 -static,170,17,1.12221 -guided,20,19,1.8704866666666664 -dynamic,1540,16,1.1803033333333333 -guided,13590,4,7.890280000000001 -guided,640,19,1.8747300000000002 -static,17440,1,16.3079 -dynamic,30,8,2.340626666666667 -static,640,4,4.144383333333333 -static,1190,15,1.2598833333333332 -dynamic,20,12,1.6445566666666667 -guided,5270,19,1.8640433333333333 -static,20,2,8.202146666666666 -static,310,8,2.2976733333333335 -static,110,17,1.1303633333333334 -static,10,20,0.9763526666666668 -static,10,20,0.973322 -dynamic,40390,13,1.44515 -static,40,20,0.9681323333333335 -static,60,11,1.7311266666666667 -static,40,16,1.2161833333333334 -dynamic,27980,6,2.931623333333333 -static,10,5,3.529426666666667 -static,90,13,1.6347733333333334 -static,20,18,1.0730633333333335 -static,330,19,1.0033966666666665 -static,10,10,1.9039966666666668 -dynamic,320,4,4.171130000000001 -static,40,7,2.605306666666667 -static,39790,9,2.0867400000000003 -guided,10,10,3.4001 -static,20,20,0.9695423333333334 -static,200,6,2.9567533333333333 -guided,90,20,1.7312066666666668 -dynamic,3290,18,1.0509233333333334 -static,80,20,0.9635616666666666 -guided,1690,1,16.29733333333333 -static,580,20,0.9542913333333333 -static,3770,14,1.3494266666666668 -dynamic,180,9,2.0659433333333332 -guided,80,12,2.78943 -static,520,16,1.1848299999999998 -static,1370,12,1.5966033333333334 -guided,90,3,10.3038 -dynamic,10740,19,0.9967216666666667 -static,10780,1,16.294133333333335 -static,2910,20,0.955419 -static,4950,3,5.553296666666665 -guided,2880,11,3.0660833333333333 -static,55950,19,1.02436 -dynamic,90,3,5.532123333333334 -static,2840,4,4.151026666666667 -static,10990,11,1.7155166666666668 -static,1090,15,1.4147833333333333 -dynamic,10,14,1.51847 -guided,360,2,8.16883 -static,6740,18,1.0579033333333332 -static,26170,2,8.168726666666666 -static,1730,8,2.2887466666666665 -static,340,20,0.9530979999999999 -static,800,20,0.953858 -static,810,20,0.9551963333333333 -static,390,20,0.9521623333333333 -static,210,17,1.11862 -static,350,10,1.88314 -static,150,5,3.52176 -static,440,6,2.951776666666667 -static,770,9,2.0785533333333333 -static,250,13,1.4535900000000002 -dynamic,6450,1,16.303933333333333 -static,2040,20,0.9535973333333333 -guided,20,7,4.4362200000000005 -static,2180,14,1.3496966666666665 -static,1400,7,2.5986233333333333 -static,130,20,0.9636043333333334 -dynamic,1210,11,1.7037366666666667 -static,7790,3,5.505356666666667 -guided,10040,14,2.4466666666666668 -static,440,1,16.301933333333334 -static,60,4,4.228196666666666 -static,280,12,1.5717033333333335 -dynamic,60,5,3.476433333333334 -guided,300,8,4.170116666666666 -static,1040,20,0.9560566666666667 -static,2080,8,2.3060466666666666 -static,100,15,1.2734233333333334 -dynamic,550,7,2.565443333333333 -static,30,16,1.2011066666666668 -guided,59540,17,2.06512 -static,4170,2,8.17 -static,180,20,0.9616233333333333 -static,2840,11,1.70801 -dynamic,17680,10,1.8717233333333334 -static,18120,17,1.1260466666666666 diff --git a/source-code/parameter-optimization/JuliaProcesses/trials_intel.txt b/source-code/parameter-optimization/JuliaProcesses/trials_intel.txt deleted file mode 100644 index 67d8c42..0000000 --- a/source-code/parameter-optimization/JuliaProcesses/trials_intel.txt +++ /dev/null @@ -1,101 +0,0 @@ -schedule,chunk,ppn,runtime -guided,3020,20,0.589315 -dynamic,13470,2,4.812006666666666 -guided,70,3,3.226713333333333 -static,550,16,0.7631010000000001 -static,40,6,1.8621333333333334 -dynamic,400,11,0.925716 -dynamic,30,13,0.802422 -guided,29140,20,0.6024636666666666 -guided,35040,19,0.6036973333333333 -dynamic,20280,1,8.33697 -static,20,6,1.9154733333333336 -guided,2620,6,1.8101233333333333 -guided,90,8,1.3360599999999998 -static,370,12,1.0066 -dynamic,2990,10,1.0134766666666666 -dynamic,10,5,2.1214600000000003 -guided,47270,15,0.779528 -dynamic,120,7,1.43082 -static,600,11,1.0966466666666665 -guided,30,5,2.0578066666666666 -guided,3550,20,0.5780103333333334 -guided,2270,20,0.5677493333333333 -guided,810,2,4.78434 -guided,6120,11,0.990568 -guided,420,16,0.6978840000000001 -guided,9260,4,2.53411 -guided,520,13,0.8616229999999999 -guided,1210,12,0.902005 -guided,12120,9,1.24013 -guided,280,10,1.1416866666666667 -guided,2070,1,8.338323333333333 -guided,200,17,0.6597876666666668 -static,42510,9,1.32843 -guided,17200,7,1.5280666666666667 -guided,4850,14,0.8144893333333334 -static,59190,19,0.653917 -guided,1320,20,0.5649243333333333 -dynamic,55350,9,1.1257566666666667 -guided,10,18,0.6439823333333333 -static,7810,10,1.1946899999999998 -guided,1250,20,0.581125 -dynamic,2080,6,1.63648 -guided,130,20,0.5859943333333333 -static,5650,3,3.5127200000000003 -dynamic,10,20,0.5997933333333333 -guided,1380,16,0.6813666666666666 -guided,570,10,1.1465733333333334 -static,80,4,2.6526566666666667 -dynamic,50,15,0.6972223333333334 -guided,7110,20,0.5779263333333334 -guided,40,18,0.620548 -dynamic,370,8,1.2520299999999998 -guided,2310,3,3.16793 -static,5210,7,1.6401633333333334 -guided,21120,20,0.5948866666666667 -guided,230,11,0.988111 -dynamic,2690,14,0.7293083333333333 -guided,3680,19,0.629715 -guided,10,8,1.3253133333333336 -static,10,18,0.7046943333333333 -guided,830,2,4.78555 -guided,57170,15,0.76663 -dynamic,12000,16,0.6470966666666667 -guided,70,6,1.7808166666666665 -static,16170,5,2.2223400000000004 -guided,7630,20,0.5824773333333333 -guided,13080,20,0.5657359999999999 -guided,39980,5,2.1055533333333334 -guided,24880,20,0.590386 -guided,13160,4,2.4379266666666664 -guided,1710,13,0.8712396666666667 -guided,3480,20,0.5877116666666667 -guided,5040,9,1.25018 -guided,890,7,1.5846166666666666 -guided,10370,1,8.335666666666667 -guided,300,17,0.6679476666666666 -guided,2930,12,0.9426863333333334 -guided,440,14,0.786128 -dynamic,57580,4,2.42371 -static,140,17,0.7328313333333333 -guided,30960,3,3.2276900000000004 -guided,15630,20,0.5811926666666667 -guided,1860,19,0.6137353333333334 -dynamic,120,3,3.261153333333333 -guided,130,6,1.7619733333333334 -static,1950,8,1.4486066666666666 -guided,5130,8,1.3433833333333336 -guided,1510,15,0.7391843333333333 -guided,1100,20,0.5852953333333333 -dynamic,30,12,0.8659466666666665 -static,1720,20,0.6286459999999999 -guided,750,16,0.7050063333333334 -guided,2390,2,4.784576666666666 -guided,55720,5,2.0777433333333337 -dynamic,940,19,0.5477673333333333 -dynamic,1030,19,0.558353 -dynamic,1180,19,0.549424 -dynamic,1340,19,0.5454396666666667 -dynamic,1090,19,0.5546893333333333 -dynamic,6420,19,0.5501726666666666 diff --git a/source-code/parameter-optimization/README.md b/source-code/parameter-optimization/README.md index b29e684..4afab4d 100644 --- a/source-code/parameter-optimization/README.md +++ b/source-code/parameter-optimization/README.md @@ -1,21 +1,20 @@ -# Parameter Optimization +# Parameter optimization + +Hyperparameter optimization is the process of finding the best hyperparameters +for a machine learning model. Hyperparameters are parameters that are set +before training a model and can significantly affect the performance of the +model. + +Optuna is a Python framework for automated hyperparameter optimization. -Here a number of implementations of algorithms to find optimal -values a in parameter space are explored. ## What is it? - 1. `parameter_optimization.ipynb`: Jupyter notebook - illustrating the hyperopt and the BayianOptimization module. - 1. `continuous_process.py`: Python script that takes x and y - y values as `--x` and `--y` options, and prints the value of - the function to optimize to standard output. - 1. `hyperopt_imize.py`: Illustrates using the hyperopt TPE - algorithm to optimize the parameters for an application, i.e., - `continuous_process.py`. - 1. `JuliaJobs`: illustration of optimizing application - parameters by running jobs and using the result. - 1. `JuliaProcesses`: illustration of optimizing application - parameters by running processes. - 1. `optuna`: illustrations of using Optuna for hyperparameter - optimization. +1. `simple.py`: minimal script showing the objective/study/trial workflow. +1. `experiments.ipynb`: methodology-first introduction to Optuna, including a + controlled comparison of stochastic samplers and a machine-learning example + with separate validation and test data. +1. `parameterized_heat_equation_optimization.ipynb`: advanced case study using + a parameterized heat-equation PINN. It compares random search with Optuna, + confirms a shortlist across fresh training seeds, and reserves a final audit + suite until after model selection. diff --git a/source-code/parameter-optimization/continuous_process.py b/source-code/parameter-optimization/continuous_process.py deleted file mode 100755 index 849ed61..0000000 --- a/source-code/parameter-optimization/continuous_process.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python - -from argparse import ArgumentParser -from math import cos, exp, pi, sqrt -import sys - - -def function(x, y): - x0, y0 = 1.2, 0.7 - r = sqrt((x - x0)**2 + (y - y0)**2) - return 1.0 - abs(cos(2.0*pi*r))*exp(-r) - - -def main(): - arg_parser = ArgumentParser(description='function to ' - 'optimize') - arg_parser.add_argument('--x', type=float, help='x value') - arg_parser.add_argument('--y', type=float, help='y value') - arg_parser.add_argument('--all', action='store_true', - help='print 2D function values') - options = arg_parser.parse_args() - if options.all: - n = 500 - x_min, y_min, x_max, y_max = -3.0, -3.0, 3.0, 3.0 - delta_x, delta_y = (x_max - x_min)/n, (y_max - y_min)/n - for i in range(500): - for j in range(500): - value = function(x_min + i*delta_x, - y_min + j*delta_y) - print(f'{value:<15.5e}', end='') - print() - else: - print(f'{function(options.x, options.y):15.5e}') - return 0 - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/source-code/parameter-optimization/experiments.ipynb b/source-code/parameter-optimization/experiments.ipynb new file mode 100644 index 0000000..ef69282 --- /dev/null +++ b/source-code/parameter-optimization/experiments.ipynb @@ -0,0 +1,707 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "title-and-objectives", + "metadata": {}, + "source": [ + "# Hyperparameter optimization with Optuna\n", + "\n", + "Optuna is a framework for organizing and automating parameter searches. This notebook uses it as a concrete implementation of a more durable idea: **hyperparameter optimization is an experiment whose design determines what its result means**.\n", + "\n", + "After working through the notebook, you should be able to:\n", + "\n", + "- distinguish an objective, parameter, trial, study, sampler, and search budget;\n", + "- define a small search space and inspect the complete trial history;\n", + "- compare stochastic search strategies using equal budgets and repeated runs;\n", + "- keep model selection on validation data separate from final evaluation on test data.\n", + "\n", + "The notebook takes roughly 25--30 minutes. It requires NumPy, Matplotlib, and Optuna from the course environment. Its outputs are intentionally omitted: restart the kernel and run all cells so that the narrative and results come from one clean execution." + ] + }, + { + "cell_type": "markdown", + "id": "terminology", + "metadata": {}, + "source": [ + "## The optimization experiment\n", + "\n", + "Optuna uses the following terminology:\n", + "\n", + "| Term | Meaning |\n", + "| --- | --- |\n", + "| parameter | A value selected by the search, such as a learning rate |\n", + "| search space | The allowed values and distributions for all parameters |\n", + "| trial | One parameter configuration and its resulting objective value |\n", + "| objective | The function that evaluates one trial |\n", + "| study | The collection of trials for one optimization task |\n", + "| sampler | The strategy that proposes parameter values |\n", + "| budget | The limit on trials, elapsed time, or computational resources |\n", + "\n", + "Optuna minimizes or maximizes the value returned by the objective. It does not decide whether that value is scientifically meaningful." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "imports", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "NumPy 2.5.2; Optuna 4.9.0\n" + ] + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import optuna\n", + "\n", + "optuna.logging.set_verbosity(optuna.logging.WARNING)\n", + "print(f\"NumPy {np.__version__}; Optuna {optuna.__version__}\")" + ] + }, + { + "cell_type": "markdown", + "id": "minimal-example", + "metadata": {}, + "source": [ + "## 1. A minimal Optuna study\n", + "\n", + "We start with a deterministic function whose minimum is known. This isolates the mechanics of Optuna from the complications of fitting a model." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "quadratic-function", + "metadata": {}, + "outputs": [], + "source": [ + "def quadratic(x, y):\n", + " return (x - 2.0) ** 2 + (y + 3.0) ** 2\n", + "\n", + "\n", + "def quadratic_objective(trial):\n", + " x = trial.suggest_float(\"x\", -10.0, 10.0)\n", + " y = trial.suggest_float(\"y\", -10.0, 10.0)\n", + " return quadratic(x, y)" + ] + }, + { + "cell_type": "markdown", + "id": "minimal-study-explanation", + "metadata": {}, + "source": [ + "The `Trial` passed to the objective proposes values from the declared search space. A `Study` records every proposed configuration and returned value. We specify TPE explicitly rather than relying on Optuna's current default, and seed it so this sequential demonstration is reproducible.\n", + "\n", + "A fixed number of trials is a **budget**, not a guarantee that the mathematical optimum will be found." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "run-minimal-study", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Best observed value: 1.02625\n", + "Best observed parameters: {'x': 1.1034167295957777, 'y': -3.4715771380493887}\n", + "Known optimum: x=2, y=-3, value=0\n" + ] + } + ], + "source": [ + "quadratic_study = optuna.create_study(\n", + " direction=\"minimize\",\n", + " sampler=optuna.samplers.TPESampler(seed=2025),\n", + ")\n", + "quadratic_study.optimize(quadratic_objective, n_trials=40)\n", + "\n", + "print(f\"Best observed value: {quadratic_study.best_value:.6g}\")\n", + "print(f\"Best observed parameters: {quadratic_study.best_params}\")\n", + "print(\"Known optimum: x=2, y=-3, value=0\")" + ] + }, + { + "cell_type": "markdown", + "id": "inspect-history", + "metadata": {}, + "source": [ + "Do not inspect only the winner. The complete history is needed to diagnose the search and compare strategies." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "trial-history", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'number': 31,\n", + " 'value': 1.026246557899583,\n", + " 'x': 1.1034167295957777,\n", + " 'y': -3.4715771380493887,\n", + " 'state': 'COMPLETE'},\n", + " {'number': 23,\n", + " 'value': 2.024211801609553,\n", + " 'x': 0.5777505322469563,\n", + " 'y': -3.0376597010840083,\n", + " 'state': 'COMPLETE'},\n", + " {'number': 18,\n", + " 'value': 2.636132474515999,\n", + " 'x': 0.768842970504853,\n", + " 'y': -1.9415176698495697,\n", + " 'state': 'COMPLETE'},\n", + " {'number': 33,\n", + " 'value': 3.7605811197154817,\n", + " 'x': 1.3696266132917447,\n", + " 'y': -1.166094191882951,\n", + " 'state': 'COMPLETE'},\n", + " {'number': 35,\n", + " 'value': 4.049780962232426,\n", + " 'x': 1.4639167806599174,\n", + " 'y': -1.060310400044791,\n", + " 'state': 'COMPLETE'}]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def trial_record(trial):\n", + " return {\n", + " \"number\": trial.number,\n", + " \"value\": trial.value,\n", + " **trial.params,\n", + " \"state\": trial.state.name,\n", + " }\n", + "\n", + "\n", + "quadratic_trials = [trial_record(trial) for trial in quadratic_study.trials]\n", + "sorted(quadratic_trials, key=lambda record: record[\"value\"])[:5]" + ] + }, + { + "cell_type": "markdown", + "id": "stochastic-search", + "metadata": {}, + "source": [ + "## 2. Comparing stochastic search strategies\n", + "\n", + "One successful run is not evidence that one sampler is generally better. We need:\n", + "\n", + "- the same search space and objective;\n", + "- the same number of trials per run;\n", + "- multiple recorded seeds;\n", + "- a performance measure defined before looking at the results.\n", + "\n", + "`RandomSampler` proposes each configuration independently. `TPESampler` starts by gathering observations and then uses the completed trials to propose values that appear more promising. Adaptive sampling can use a limited budget more efficiently, but it can also concentrate on an attractive local region.\n", + "\n", + "The next objective has a broad local basin and a narrow, deeper global basin. It is deliberately small and artificial: its purpose is to make sampler behavior visible." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "two-basin-definition", + "metadata": {}, + "outputs": [], + "source": [ + "SEARCH_LOW, SEARCH_HIGH = -10.0, 10.0\n", + "GLOBAL_BASIN_THRESHOLD = 1.0\n", + "\n", + "\n", + "def two_basin_function(x, y, narrow_scale=0.5):\n", + " broad_basin = 7.0 * np.exp(-0.05 * ((x + 3.0) ** 2 + (y - 5.0) ** 2))\n", + " narrow_basin = 10.0 * np.exp(\n", + " -narrow_scale * ((x - 7.0) ** 2 + (y + 3.0) ** 2)\n", + " )\n", + " return 10.0 - broad_basin - narrow_basin\n", + "\n", + "\n", + "def plot_landscape(ax, points=None, title=None):\n", + " coordinates = np.linspace(SEARCH_LOW, SEARCH_HIGH, 201)\n", + " x_grid, y_grid = np.meshgrid(coordinates, coordinates)\n", + " values = two_basin_function(x_grid, y_grid)\n", + " image = ax.contourf(x_grid, y_grid, values, levels=30, cmap=\"Greys\")\n", + " if points is not None:\n", + " points = np.asarray(points)\n", + " ax.scatter(points[:, 0], points[:, 1], s=18, c=\"tab:red\", edgecolor=\"white\")\n", + " ax.set(xlabel=\"x\", ylabel=\"y\", title=title, aspect=\"equal\")\n", + " return image" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "show-two-basin-landscape", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeYAAAGICAYAAACUbUPlAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQAAYMBJREFUeJztnQnYTeX6/29z6mQsM5mikmSoKGQ6xpAGKaUklRzNAyJDA03SPJGQMkRHHXEOmiNpVhQS3kgkQ4OM+399n35r/9e7rL33Gvca9vdzXft697v2Gp699lrPd93Dcz8FEolEQgghhBASCgoG3QBCCCGE/H8ozIQQQkiIoDATQgghIYLCTAghhIQICjMhhBASIijMhBBCSIigMBNCCCEhgsJMCCGEhIicFeYff/xRJkyYID/99JNEga+++kq1d9++fWnXW7p0qUydOjVr7XLbjnfeeUdeeeUVyTZhOU9+Xw/Ef37++Wf1W6BPsUteXp7aFvvIdnv8OLbf5ytnSESc/fv3JyZMmJCYOHFi4uDBg5a3mz9/PiqeJd5+++1EFBgzZoxq744dO9KuN3DgwETJkiWz1i637ejdu3eicuXKiWwTlvPk9/VA/Of9999XvwX6FLu88cYbalvsI9vt8ePYfp+vXKGwRJzXX39drrrqKvW+YsWK0qlTp6CbRCLAmWeeKQUL5qzDiJDAqFChgvTr10+qVq3KXyEFkRdmuEQaNGggf/31l3pPYSZWuOSSS9SLEJJdateurfpqElNhRozkv//9rzz11FOyZ88eue2221T8onz58rb2s3//flm8eLFs375dmjRpInXr1s33OWIhCxYskC5duki5cuVUXHTjxo1y3nnnScmSJdU63333nXz++ecIDcipp54qJ554Yr59fPHFF/LJJ5+o9wUKFJASJUpI48aNpWbNmqZtWrJkiaxbt05q1aolzZo1Ey/I1EaNrVu3ykcffSS///671KtXTz34OP0edkC8//3335eiRYtK69atk+fWybFxHWDd3bt3q3OI9QoVKpQvxrx27Vq57LLLksvwu6INF198sfzyyy/y9ttvq23QltKlS2dsv9X2OTmO0+vBze9lp51Ov/u7774rhQsXlu7du6uYP9Y/66yzZOXKlepaxTXaqFEjte2OHTvkgw8+UH+rVaum1itSpIj6bO/evWr7pk2bysknn5w8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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(5, 4))\n", + "image = plot_landscape(ax, title=\"A broad local basin and a narrow global basin\")\n", + "fig.colorbar(image, ax=ax, label=\"objective value\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "prediction-prompt", + "metadata": {}, + "source": [ + "### Predict before running\n", + "\n", + "With 100 trials, which strategy do you expect to reach the narrow global basin more often: independent random sampling or adaptive TPE sampling? What behavior of the landscape supports your prediction?\n", + "\n", + "Also decide why comparing only the best Random run with the best TPE run would be misleading." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "search-experiment-functions", + "metadata": {}, + "outputs": [], + "source": [ + "def two_basin_objective(trial):\n", + " x = trial.suggest_float(\"x\", SEARCH_LOW, SEARCH_HIGH)\n", + " y = trial.suggest_float(\"y\", SEARCH_LOW, SEARCH_HIGH)\n", + " return two_basin_function(x, y)\n", + "\n", + "\n", + "def run_repeated_searches(sampler_factory, seeds, n_trials):\n", + " runs = []\n", + " for seed in seeds:\n", + " study = optuna.create_study(\n", + " direction=\"minimize\", sampler=sampler_factory(seed)\n", + " )\n", + " study.optimize(two_basin_objective, n_trials=n_trials)\n", + " trial_values = np.array([trial.value for trial in study.trials])\n", + " runs.append(\n", + " {\n", + " \"seed\": seed,\n", + " \"best_value\": study.best_value,\n", + " \"best_x\": study.best_params[\"x\"],\n", + " \"best_y\": study.best_params[\"y\"],\n", + " \"best_so_far\": np.minimum.accumulate(trial_values),\n", + " }\n", + " )\n", + " return runs" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "run-search-experiment", + "metadata": {}, + "outputs": [], + "source": [ + "SEEDS = tuple(range(20))\n", + "TRIALS_PER_RUN = 100\n", + "\n", + "random_runs = run_repeated_searches(\n", + " lambda seed: optuna.samplers.RandomSampler(seed=seed),\n", + " SEEDS,\n", + " TRIALS_PER_RUN,\n", + ")\n", + "tpe_runs = run_repeated_searches(\n", + " lambda seed: optuna.samplers.TPESampler(seed=seed),\n", + " SEEDS,\n", + " TRIALS_PER_RUN,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "summarize-search-experiment", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Random {'runs': 20, 'global-basin hits': 1, 'hit rate': 0.05, 'median best value': 3.06324447156503, 'best observed value': 0.1119235414416}\n", + "TPE {'runs': 20, 'global-basin hits': 0, 'hit rate': 0.0, 'median best value': 3.010889234960509, 'best observed value': 3.00012710147129}\n" + ] + } + ], + "source": [ + "def summarize_runs(runs):\n", + " best_values = np.array([run[\"best_value\"] for run in runs])\n", + " hits = best_values < GLOBAL_BASIN_THRESHOLD\n", + " return {\n", + " \"runs\": len(runs),\n", + " \"global-basin hits\": int(hits.sum()),\n", + " \"hit rate\": float(hits.mean()),\n", + " \"median best value\": float(np.median(best_values)),\n", + " \"best observed value\": float(best_values.min()),\n", + " }\n", + "\n", + "\n", + "for name, runs in ((\"Random\", random_runs), (\"TPE\", tpe_runs)):\n", + " print(name, summarize_runs(runs))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "plot-search-experiment", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABV8AAAGbCAYAAADTFeChAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQAA8QhJREFUeJzsnQeY3NTVhs+UrfZ61713Y2ObYqqN6S1gqmmhmG4T4A8JPdQQWmgh9JbQWyAhhN5MD705dIML7t1e79reOu1/vrto0Y6nSBpJI8187z7zzI5GXZp7dL577jmBRCKREEIIIYQQQgghhBBCCCG2ErR3dYQQQgghhBBCCCGEEEIovhJCCCGEEEIIIYQQQohDMPKVEEIIIYQQQgghhBBCHIDiKyGEEEIIIYQQQgghhDgAxVdCCCGEEEIIIYQQQghxAIqvhBBCCCGEEEIIIYQQ4gAUXwkhhBBCCCGEEEIIIcQBKL4SQgghhBBCCCGEEEKIA1B8Jb7lhRdekMMPP1zWr1/fPu2hhx6S4447Torx2Ik9FMs9VKzHSwixxqmnnip33nmnq6fvq6++kvPOO0+OPPJIOf/8813dth/47LPP1LPA7NmzpdD417/+pY4tEonke1cIIcQzfPPNN6pt/O6771zbZiKRkEceeUR+85vfqG2/9NJLrm3bL9xwww1y5pln5ns3iMcJ53sHiP8fjvECd999t/Ts2XOjeS666CLlGAwaNEhuuukm27b9448/ytNPPy333HOPVFVVqWlffvmlPPPMM1LopDr2dESjUXnrrbfkP//5j6xevVrOPvts2XHHHdPOD4P64osvyoYNG2Ts2LEybdo06dGjR877DKH44Ycfls8//1x93nbbbeWkk06STp06Wd4PPAw8+OCD8sEHH8iwYcOU0evcuXOHedasWSO//e1v5fLLL5dNN900637meg/9/e9/V/uDY/UDxfKbISRXzjnnHFm4cGH755KSEunXr5/ssssuctBBB0kgEHDsJJ988smy/fbby2mnnSb5Am1yS0uLa8fw7bffKjuB5Q477DDp1q2b5W0XKkuWLFHPAhCoN9lkE9PLz58/Xy2rEQwGpaamRrbeems55phjpEuXLpIvvv/+e3VssVhM/dYIIQT89NNP8oc//KHDyYAvNHjwYNVujRw50rET9cUXX8i1114rV199tSGfwglWrFih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9vXstttuiX79+iXWrVvXPs/ixYsT3bp1U9tetWpV+/Qzzzwz0alTp6z7XVtbm6isrExce+217dNOOOGERGlpaeKaa67pMO/ee++dGDp0qMkzY892zBx7Np566im1zBNPPLHRd7FYTH2Ha5LM//73P/Wd/hjMgHXjOu+4444bfbfffvupdd99992m9yMSiahzc91116nPn3zySSIQCCS+/vrrxAcffKDug9mzZyfmz5+fuOCCCxK/+c1vEi+//HLW/U11D5m5Zqeeeqo63lQYvee17eE3pdHU1KTe8TvafvvtOyy/fPnyRDgcVsdp9n40+pshpNjBb6+qqipx2GGHqdeBBx6YGD58uHq98sorHeZdu3ZtomvXrolJkyYl4vF4h+k9evRI/N///Z/6fOutt6p2S9/GgxUrVqj2UKN79+6JqVOnGt5X/KbxW0e7qYH2Zdy4cYlNNtmkfd1Lly5NlJWVqePR8+qrr6r2VmtfQf/+/VXblLydzp07J7799tv2aStXrlTrPP/88zvMa/YY0C5im6mOraKiosOxoX287bbb1D4/88wzHeY/9thjEyUlJeo5BeB7zLfnnnsmotFo+3wnnXRSok+fPupc6KdPmzYtUVNTk2hubs64v48//rha76OPPtphOmwupn/44YcZl8e9Mn78+PbPDz/8sFruvvvu6zAf7ifcH/pjwbMCbKLGnXfeqaZ/+eWXGbep2dWrrrqqw/RLL71UTcd6sqHZn9tvv719Gs5heXl54pZbbukw7w477ND+XKix7bbbqt9QY2Nj+7Q5c+YkunTpovZBs30Atq9v376J+vr69mmrV69W9xbOgX77uAfvuOOO9mkNDQ3K/m633XaJm2++uX061o/f6imnnJL1WLX1Xn/99R2WB7h2u+6660bLXHLJJeo49NfHzPkhhHTks88+U7+pzTbbrN0e77XXXsoW4f9ly5Z1mF9rS5P9H7TVmA7/AWy11VaJww8/fKPTrV/fCy+8oJZ57733TPleaBv0bQC2ielXXnll+7SbbrpJTcM29Bx11FHKJ1iwYIH6/Prrr6v53n777Y22g/Ogt194xsB0vY02ewxo4zA/2rJUx7bzzju3HxvsU0tLS2LrrbdWfo3+2QbPBmhrsY8aBx98sGoLNT8QrF+/Xj1rwTbo7QracNiF008/Pes+wz/r1auXsg969t1338Sm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WD+axkFvMbPVjydlENzo373neC5koxdd9dgSahe6PG1jOrB27L+0b2rWrBnBLQ/p3S56l4EjnbGj5wV6qzSurn3qRVm9+Kr0p/Zp9GHwpO0sXrzY3nb04rM+p+143n9q3en4mONYZnrxR8dwjufYOsbTux1oY57T2IvtO+p4zqaqV6/uxSfBkV781cmGju1TUzpoXMer9unF4l8hQ1dY15XLdPXGBQsWWIMHD7YiIyOtVatWBXrXgmYl+rCwMOuNN96w1q1bZ3/s3LnTXubs2bPWddddZ7Vs2dJauHChNXDgQFOHa9eutULd5cuXzSp606dPT/f62LFjrdjYWLM67dy5c83KyK1bt7ZCUXJyslWtWjWrffv21meffWZNmTLFKlGiRLrVy0+cOGGVKVPGuuuuu6xFixaZlQZ1hVZd2THUpKSkWDfddJNVq1Yt03YWL15s2k7hwoWtAwcOpPvuxsfHW++88441a9Ysq2LFimY16VDw448/muPUkCFDrIiICPtx68yZM/Yyw4cPtwoUKGBNmjTJmjlzplWuXDnrvvvuS/c5npRBYOhKpLa/qx4/2rVrZ37//vvv7WXo372nfZOuNDxjxgzr008/Ncdh7c+nTp3q079fXnHs2DGrVKlSVtu2bU3f1Lt3bysmJsbavHlzoHct1zh9+rRVo0YN680337Q+//xza+LEiVbp0qWthg0bmnMoOJeUlGQ/BsbFxVlPPfWU+T0xMdFeZt++fWbF5vvvv9+0z27dupk+TVd4RujScyFb28mXL58Zt+nveu5k89NPP5m20r17d9N29NxH29Kvv/4a0H0PZj169DDjk3nz5pmHjlmuueYa69tvvw30rgUl7Se1v+zbt69pY3fffbfpT7VfhWc2bNhgNWjQwJo8ebK1bNkyM/bT/uDxxx+nCt04fPiwOebNnj3bxGneffdd8/z333+3l1m+fLk5/33++edNjLBRo0YmXqNxC0+F6X88D9WGDr26PmLECHOlXWd29OrVy34LdKjTunCWWFhn1r3++uv253orrtbh9u3bzXR3vSVay4Q6vW25UaNG8sILL5ik6xlTEcyaNctctdIy/fv3D7mZwo6JrUeNGiWbNm0ys11bt25t8g463hanMz21jWluyFKlSknfvn1D9nYKvfo2fvx4+e6778yVYs0zpTkZM6ZKmT59unz88cdmVpGm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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def plot_progress(ax, runs, label):\n", + " histories = np.vstack([run[\"best_so_far\"] for run in runs])\n", + " trial_numbers = np.arange(1, histories.shape[1] + 1)\n", + " lower, median, upper = np.quantile(histories, [0.1, 0.5, 0.9], axis=0)\n", + " ax.plot(trial_numbers, median, label=label)\n", + " ax.fill_between(trial_numbers, lower, upper, alpha=0.2)\n", + "\n", + "\n", + "fig, axes = plt.subplots(1, 3, figsize=(14, 4), constrained_layout=True)\n", + "for name, runs in ((\"Random\", random_runs), (\"TPE\", tpe_runs)):\n", + " plot_progress(axes[0], runs, name)\n", + "axes[0].axhline(GLOBAL_BASIN_THRESHOLD, color=\"black\", linestyle=\"--\", label=\"global-basin threshold\")\n", + "axes[0].set(xlabel=\"trial\", ylabel=\"best objective so far\", title=\"Median and 10--90% interval\")\n", + "axes[0].legend()\n", + "\n", + "for ax, name, runs in zip(axes[1:], (\"Random\", \"TPE\"), (random_runs, tpe_runs)):\n", + " best_points = [(run[\"best_x\"], run[\"best_y\"]) for run in runs]\n", + " plot_landscape(ax, best_points, f\"Best point from each {name} run\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "interpret-search-experiment", + "metadata": {}, + "source": [ + "### Interpret the evidence\n", + "\n", + "1. Which sampler reached the global basin in more of these runs?\n", + "2. Do the median curves and the hit rates support the same conclusion?\n", + "3. Would quadrupling the number of trials per run answer the same question as quadrupling the number of repeated runs?\n", + "\n", + "
\n", + "Discussion\n", + "\n", + "The hit rate measures reliability under the stated 100-trial budget; the best single run does not. The median curve describes typical progress, but it can hide rare successes in the narrow basin, so it complements rather than replaces the hit rate. More trials per run investigate performance under a larger search budget. More repeated runs estimate the variability and hit rate at the existing budget more precisely. They answer different questions.\n", + "\n", + "This small experiment is not a general benchmark. TPE uses previous trials to concentrate its search, which can help on many objectives but can also draw attention towards the broad local basin. Sampler performance depends on the landscape, parameter types, dimensionality, budget, and degree of parallelism.\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "hyperparameter-optimization", + "metadata": {}, + "source": [ + "## 3. From function optimization to hyperparameter optimization\n", + "\n", + "For machine learning, the objective is normally an estimate of performance on **validation data**, not performance on the training data and not performance on the final test data. Every trial influences model selection, so every trial must remain blind to the test set.\n", + "\n", + "We use a small synthetic regression problem so that the model and evidence split remain visible and the example needs no data download. Polynomial degree controls model flexibility; regularization controls how strongly non-constant coefficients are shrunk. Both are hyperparameters because training does not estimate them.\n", + "\n", + "A single train/validation/test split keeps the example short. Cross-validation or repeated validation would usually provide stronger evidence for a real study." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "prepare-ml-data", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train=144, validation=48, test=48\n" + ] + } + ], + "source": [ + "data_rng = np.random.default_rng(2025)\n", + "features = np.linspace(-1.0, 1.0, 240)\n", + "signal = 0.5 + 1.5 * features - 2.0 * features**2 + np.sin(5.0 * features)\n", + "targets = signal + data_rng.normal(loc=0.0, scale=0.3, size=features.size)\n", + "\n", + "indices = data_rng.permutation(features.size)\n", + "train_indices = indices[:144]\n", + "validation_indices = indices[144:192]\n", + "test_indices = indices[192:]\n", + "\n", + "train_features, train_targets = features[train_indices], targets[train_indices]\n", + "validation_features = features[validation_indices]\n", + "validation_targets = targets[validation_indices]\n", + "test_features, test_targets = features[test_indices], targets[test_indices]\n", + "\n", + "print(\n", + " f\"train={len(train_targets)}, validation={len(validation_targets)}, \"\n", + " f\"test={len(test_targets)}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "validation-objective-explanation", + "metadata": {}, + "source": [ + "The objective below varies one structural and one regularizing hyperparameter. Degree is sampled as an integer; the regularization strength spans several orders of magnitude and is therefore sampled on a logarithmic scale.\n", + "\n", + "The fitted model is deterministic for fixed data and hyperparameters. For a stochastic learner, the training seed would also have to be controlled or repeated." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "validation-objective", + "metadata": {}, + "outputs": [], + "source": [ + "def polynomial_features(features, degree):\n", + " return np.column_stack([features**power for power in range(degree + 1)])\n", + "\n", + "\n", + "def fit_polynomial(features, targets, degree, regularization):\n", + " design = polynomial_features(features, degree)\n", + " penalty = np.eye(degree + 1)\n", + " penalty[0, 0] = 0.0 # Do not regularize the intercept.\n", + " return np.linalg.solve(\n", + " design.T @ design + regularization * penalty,\n", + " design.T @ targets,\n", + " )\n", + "\n", + "\n", + "def predict_polynomial(features, coefficients):\n", + " return polynomial_features(features, len(coefficients) - 1) @ coefficients\n", + "\n", + "\n", + "def root_mean_squared_error(observed, predicted):\n", + " return float(np.sqrt(np.mean((observed - predicted) ** 2)))\n", + "\n", + "\n", + "def validation_objective(trial):\n", + " degree = trial.suggest_int(\"degree\", 1, 15)\n", + " regularization = trial.suggest_float(\n", + " \"regularization\", 1.0e-8, 1.0e2, log=True\n", + " )\n", + " coefficients = fit_polynomial(\n", + " train_features, train_targets, degree, regularization\n", + " )\n", + " predictions = predict_polynomial(validation_features, coefficients)\n", + " return root_mean_squared_error(validation_targets, predictions)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "run-hyperparameter-study", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Best validation RMSE: 0.374\n", + "Selected hyperparameters: {'degree': 5, 'regularization': 4.660416628589115e-05}\n" + ] + } + ], + "source": [ + "model_study = optuna.create_study(\n", + " direction=\"minimize\",\n", + " sampler=optuna.samplers.TPESampler(seed=27182, n_startup_trials=10),\n", + ")\n", + "model_study.optimize(validation_objective, n_trials=40)\n", + "\n", + "print(f\"Best validation RMSE: {model_study.best_value:.3f}\")\n", + "print(f\"Selected hyperparameters: {model_study.best_params}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "inspect-model-study", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'number': 27,\n", + " 'value': 0.3740798647846128,\n", + " 'degree': 5,\n", + " 'regularization': 4.660416628589115e-05,\n", + " 'state': 'COMPLETE'},\n", + " {'number': 17,\n", + " 'value': 0.37408043705649047,\n", + " 'degree': 5,\n", + " 'regularization': 3.965750537819765e-05,\n", + " 'state': 'COMPLETE'},\n", + " {'number': 31,\n", + " 'value': 0.37408299940803746,\n", + " 'degree': 5,\n", + " 'regularization': 9.019760617729943e-06,\n", + " 'state': 'COMPLETE'},\n", + " {'number': 32,\n", + " 'value': 0.3740830376869889,\n", + " 'degree': 5,\n", + " 'regularization': 8.567670844549773e-06,\n", + " 'state': 'COMPLETE'},\n", + " {'number': 23,\n", + " 'value': 0.3740832297900218,\n", + " 'degree': 5,\n", + " 'regularization': 6.301286512517622e-06,\n", + " 'state': 'COMPLETE'}]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model_trials = [trial_record(trial) for trial in model_study.trials]\n", + "sorted(model_trials, key=lambda record: record[\"value\"])[:5]" + ] + }, + { + "cell_type": "markdown", + "id": "final-evaluation", + "metadata": {}, + "source": [ + "### Final evaluation\n", + "\n", + "Only after selecting a configuration do we combine the training and validation data, fit one final model, and evaluate it once on the test data. The test RMSE estimates the performance of the **entire selection procedure**, not merely the winning fitted model." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "evaluate-test-data", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Final test RMSE: 0.309\n" + ] + } + ], + "source": [ + "final_features = np.concatenate((train_features, validation_features))\n", + "final_targets = np.concatenate((train_targets, validation_targets))\n", + "\n", + "final_coefficients = fit_polynomial(\n", + " final_features,\n", + " final_targets,\n", + " model_study.best_params[\"degree\"],\n", + " model_study.best_params[\"regularization\"],\n", + ")\n", + "test_predictions = predict_polynomial(test_features, final_coefficients)\n", + "test_rmse = root_mean_squared_error(test_targets, test_predictions)\n", + "print(f\"Final test RMSE: {test_rmse:.3f}\")" + ] + }, + { + "cell_type": "markdown", + "id": "diagnosis-exercise", + "metadata": {}, + "source": [ + "### Diagnose the experimental design\n", + "\n", + "For each proposal, decide whether it preserves a defensible final evaluation. Explain your decision.\n", + "\n", + "1. Return training RMSE from the Optuna objective because it is less noisy.\n", + "2. Return test RMSE from the objective so that Optuna optimizes the quantity ultimately reported.\n", + "3. If the final test RMSE is disappointing, enlarge the search space and repeat the study against the same test set.\n", + "4. Replace the single validation split with cross-validation while keeping the test set untouched.\n", + "\n", + "
\n", + "Solution\n", + "\n", + "1. No. Training error rewards configurations that fit the observed training data and does not estimate generalization.\n", + "2. No. Repeatedly using test performance makes the test set part of model selection, so it no longer supplies independent evidence.\n", + "3. No, not if the same test result influences the redesign. The revised procedure needs genuinely external test evidence, or the reported result must explicitly acknowledge that the original test data became development data.\n", + "4. Yes. Cross-validation can reduce dependence on one validation split, although it increases computation and does not remove the need for an untouched test set.\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "takeaways", + "metadata": {}, + "source": [ + "## Takeaways\n", + "\n", + "- Optuna manages trials; it does not make an invalid objective meaningful.\n", + "- Define the search space, evidence split, metric, and budget before examining results.\n", + "- Compare stochastic strategies over repeated runs with equal budgets, and report typical behavior as well as rare successes.\n", + "- Keep the test set outside the optimization loop and use it only after selecting a configuration.\n", + "- Record seeds, software versions, trial histories, failures, and resource budgets. Exact reproducibility becomes harder with stochastic objectives or parallel and distributed execution.\n", + "\n", + "The [parameterized heat-equation PINN optimization notebook](parameterized_heat_equation_optimization.ipynb) applies these principles to a more realistic and more expensive case.\n", + "\n", + "Further reading:\n", + "\n", + "- [Optuna: first optimization](https://optuna.readthedocs.io/en/stable/tutorial/10_key_features/001_first.html)\n", + "- [Optuna: samplers and pruning](https://optuna.readthedocs.io/en/stable/tutorial/10_key_features/003_efficient_optimization_algorithms.html)\n", + "- [Optuna FAQ: reproducibility](https://optuna.readthedocs.io/en/stable/faq.html#how-can-i-obtain-reproducible-optimization-results)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.14.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/source-code/parameter-optimization/hyperopt_imize.py b/source-code/parameter-optimization/hyperopt_imize.py deleted file mode 100755 index d7cca33..0000000 --- a/source-code/parameter-optimization/hyperopt_imize.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python - -from argparse import ArgumentParser -from hyperopt import fmin, hp, STATUS_OK, tpe, Trials -import subprocess -import sys -import time - - -def function(params): - x, y = params - cmd = ['./continuous_process.py', '--x', str(x), - '--y', str(y)] - process = subprocess.run(cmd, stdout=subprocess.PIPE, - encoding='utf8') - return { - 'loss': float(process.stdout), 'time': time.time(), - 'x': x, 'y': y, 'status': STATUS_OK, - } - - -def optimize(max_evals): - space = (hp.uniform('x', -3.0, 3.0), - hp.uniform('y', -3.0, 3.0)) - trials = Trials() - best = fmin(function, space=space, algo=tpe.suggest, - max_evals=max_evals, trials=trials) - return best, trials - - -def main(): - arg_parser = ArgumentParser(description='optimize external ' - 'process') - arg_parser.add_argument('--max-evals', type=int, - default=100, help='maximum evals') - arg_parser.add_argument('--trials', action='store_true', - help='display trials') - options = arg_parser.parse_args() - best, trials = optimize(options.max_evals) - if options.trials: - print('x y value') - for trial in trials: - x = trial['result']['x'] - y = trial['result']['y'] - value = -trial['result']['loss'] - print(f'{x:6.3f} {y:6.3f} {value:10.3e}') - x, y = best['x'], best['y'] - value = function((x, y))['loss'] - print(f'# best: f({x:6.3f}, {y:6.3f}) = {-value:10.3e}') - return 0 - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/source-code/parameter-optimization/optuna/README.md b/source-code/parameter-optimization/optuna/README.md deleted file mode 100644 index 9322a29..0000000 --- a/source-code/parameter-optimization/optuna/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Optuna - -Optuna is a Python framework for automated hyperparameter optimization. - - -## what is it? - -1. `simple.py`: very simple example of how to use Optuna to optimize a function. -1. `experiments.ipynb`: some experiments on more complicated function optimization. diff --git a/source-code/parameter-optimization/optuna/experiments.ipynb b/source-code/parameter-optimization/optuna/experiments.ipynb deleted file mode 100644 index f991475..0000000 --- a/source-code/parameter-optimization/optuna/experiments.ipynb +++ /dev/null @@ -1,643 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "106e36cd-8aeb-4314-af5c-9870b95321f1", - "metadata": {}, - "source": [ - "# Requirements" - ] - }, - { - "cell_type": "code", - "execution_count": 121, - "id": "9b71fd5c-27fe-49f9-b25a-16a7ad994996", - "metadata": {}, - "outputs": [], - "source": [ - "import collections\n", - "import functools\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import optuna" - ] - }, - { - "cell_type": "markdown", - "id": "46938664-f34b-43cf-ae56-6db40808301a", - "metadata": {}, - "source": [ - "# Example 1" - ] - }, - { - "cell_type": "markdown", - "id": "d165e58d-b747-472b-8e16-fb1f7239652c", - "metadata": {}, - "source": [ - "## Target function" - ] - }, - { - "cell_type": "code", - "execution_count": 84, - "id": "ec4dc603-ecbc-433e-af5c-673337ee29d2", - "metadata": {}, - "outputs": [], - "source": [ - "def func(x, y):\n", - " x_0, y_0 = 5.0, 7.0\n", - " return 1.0 - (np.cos((x - x_0)*(y - y_0))*np.exp(-0.05*((x - x_0)**2 + (y - y_0)**2)))" - ] - }, - { - "cell_type": "code", - "execution_count": 85, - "id": "e4d60ff4-3b1c-4156-b553-96f2a1507bc4", - "metadata": {}, - "outputs": [], - "source": [ - "def visualize_func(func):\n", - " x = np.linspace(-10.0, 10.0, 101)\n", - " y = np.linspace(-10.0, 10.0, 101)\n", - " X, Y = np.meshgrid(x, y)\n", - " Z = func(X, Y)\n", - " plt.imshow(Z, cmap='Grays');" - ] - }, - { - "cell_type": "code", - "execution_count": 86, - "id": "ae743c78-448c-4166-aeab-db5ff1a320d9", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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bABABAr/pfbaa6/ZypUrbdGiRfbtb3/bnn32WfvGN75hlZWVdsMNN1hbW5uZmdXU1KSOq6mpsR07dnR7ziVLltiiRYtK2x0dHTRsH2B9Xc06a/i/78bISqHlz6XdHJpSy5831N2osrqffBk0I7rvctRraDemH4qt19RjffeTduVr/b777rvdXsOsax35c2naJr23d955p/RZu7h0eLrv5qqurk7t025ZT+tBt/0Q9KzVzEOrKeix/rxZZfD0XvRef//735c+a+ozrcMxY8aUPuuz0G0/pWLPnj2pffrM/XM888wzU/v0XfLdj/55m3WtB38df99Zqxz0VeGN2tGjR2369OnW3NxsZmYXXnihbd261VauXGk33HBD6Xvd/Y9QT/GXysrKLvM6AABQhXc/jhs3zs4777zU384991zbuXOnmZnV1taamZV+sR3X3t7e5dcbAAB5FN6oXXzxxbZt27bU315++WWbNGmSmZnV19dbbW2ttba2lvYfOnTI1q9fbzNnziy6OACAQaTw7sfbbrvNZs6cac3NzXbNNdfYs88+aw899JA99NBDZnas27GxsdGam5utoaHBGhoarLm52UaOHGnz5s0rujgYYFnD9L2sOFlo+H9W3MzTofg+jqIxFD2PjwNo6iAVWnrEX0djEDq61+8PxdB0W+tPYzNvv/12j2XQGIqPseg1dYqEj7H4uJ1Z1+fkY00aZ9I68/WiS6yEhvTrM80zpF+PDQ3p1zL5etG0U6H4oaYW0zr09ZuVsszH5zSeqdfx74PWg8bq/HX034iW11/X/7vVGHRRCm/ULrroIvvRj35kS5YssTvvvNPq6+ttxYoVdt1115W+s3jxYjt48KAtWLDA9u7dazNmzLB169YxRw0A0C9lSWh81VVX2VVXXdXj/oqKCmtqarKmpqZyXB4AMEiR+xEAEA2WnkHh+hM3C/F999qPr9f0sRCNi4SWvNA4mW77mEpoiY3utr1Q+iKNNfg4msZMNNbhy6TzkP7whz+ktv11dRkdPxfKLB1T03iLj8XodULptszS96P3omXyMSyNX+m2f+b6nPS8vkxZywn5559VBl9erc9QjCr0nHT/GWeckdp3fHT5cf656fw3fc/8dbQMGsv1MUG9F+VjbL5OyhVT45caACAaNGoAgGjQ/Yjc8qxmnWdfniz9KpTeKLTStVl66HXWMH2f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e++90nfuueeepKqqKvnhD3+YbNmyJfnSl76UjBs3Luno6BjAkg+MZ599Njn77LOTj3/848nChQtLf6eOkuSdd95JJk2alHz1q19N/ud//ifZvn178tRTTyWvvPJK6TuDvZ7uuuuuZPTo0cl//Md/JNu3b0/+9V//NfnQhz6UrFixovSdwVZHP/nJT5KlS5cmP/zhDxMzS370ox+l9vemPm666abkrLPOSlpbW5Pnn38+ufTSS5NPfOITyeHDh3OV5aRt1P7sz/4suemmm1J/mzJlSnLHHXcMUIk+ONrb2xMzS9avX58kSZIcPXo0qa2tTe65557Sd/74xz8m1dXVyfe///2BKuaA2L9/f9LQ0JC0trYms2bNKjVq1NExt99+e3LJJZf0uJ96SpIrr7wy+frXv57629y5c5Prr78+SRLqSBu13tTHu+++m5xyyinJY489VvrO7t27kyFDhiQ//elPc13/pOx+PHTokG3atCm10KiZ2Zw5c3pcaHQw2bdvn5mZjRo1ysx6t3jrYHHzzTfblVde2SXPKHV0zJNPPmnTp0+3L37xizZ27Fi78MIL7eGHHy7tp57MLrnkEvvZz35mL7/8spmZ/frXv7ZnnnnGPv/5z5sZdaTKtXh0T8qynlq57dmzx44cOdLtYqQ9LTQ6WCRJYosWLbJLLrnEpk6dama9W7x1MHjsscfs+eeft40bN3bZRx0d89prr9nKlStt0aJF9u1vf9ueffZZ+8Y3vmGVlZV2ww03UE9mdvvtt9u+fftsypQpNnToUDty5Ijdfffddu2115oZ75Iq1+LRPTkpG7Xj+rIYaexuueUW+81vfmPPPPNMl32Dub527dplCxcutHXr1nVZWdgbzHVkdmyV5enTp1tzc7OZmV144YW2detWW7lypd1www2l7w3menr88cft0UcftbVr19r5559vmzdvtsbGRqurq7P58+eXvjeY66g7RS8e3ZOTsvtxzJgxNnTo0C4tuF+MdDC69dZb7cknn7Rf/OIXNn78+NLf/eKt3mCqr02bNll7e7tNmzbNhg0bZsOGDbP169fbP/zDP9iwYcNK9TCY68jMbNy4cXbeeeel/nbuueeWVm7mXTL71re+ZXfccYd9+ctftgsuuMC+8pWv2G233WYtLS1mRh2p3tSHXzy6p+/01knZqJ166qk2bdo0a21tTf29tbW116tnxyRJErvlllvsiSeesJ///OdWX1+f2u8Xbz3u+OKtg6W+LrvsMtuyZYtt3ry59N/06dPtuuuus82bN9vkyZMHfR2ZmV188cVdpoO8/PLLNmnSJDPjXTIzO3DggA0Zkv6fzqFDh5aG9FNHab2pD7949HHHF4/OXWd9Gt7yAXB8SP8jjzySvPTSS0ljY2Ny2mmnJa+//vpAF+2E+5u/+Zukuro6+eUvf5m89dZbpf8OHDhQ+s4999yTVFdXJ0888USyZcuW5Nprr416iHFv+NGPSUIdJcmx6Q7Dhg1L7r777uR3v/td8i//8i/JyJEjk0cffbT0ncFeT/Pnz0/OOuus0pD+J554IhkzZkyyePHi0ncGWx3t378/eeGFF5IXXnghMbNk+fLlyQsvvFCaYtWb+rjpppuS8ePHJ0899VTy/PPPJ5/5zGcG15D+JEmSf/zHf0wmTZqUnHrqqcmnPvWp0hD2wcbMuv1v1apVpe8cPXo0+e53v5vU1tYmlZWVyac//elky5YtA1foDwBt1KijY3784x8nU6dOTSorK5MpU6YkDz30UGr/YK+njo6OZOHChcnEiROT4cOHJ5MnT06WLl2adHZ2lr4z2OroF7/4Rbf/GzR//vwkSXpXHwcPHkxuueWWZNSoUcmIESOSq666Ktm5c2fusrCeGgAgGidlTA0AgO7QqAEAokGjBgCIBo0aACAaNGoAgGjQqAEAokGjBgCIBo0aACAaNGoAgGjQqAEAokGjBgCIxv8BGFC43W8nhVQAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "visualize_func(func)" - ] - }, - { - "cell_type": "markdown", - "id": "0fb65dde-dff5-4180-b943-06d881f0779e", - "metadata": {}, - "source": [ - "## Optimization" - ] - }, - { - "cell_type": "markdown", - "id": "60f844ef-7f01-4acf-95cc-45537f122e93", - "metadata": {}, - "source": [ - "Increase the log level to avoid a flood of info-level messages, i.e., a message per optim" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "id": "628c1d5a-b86a-4658-8f1e-764a8174f5ad", - "metadata": {}, - "outputs": [], - "source": [ - "optuna.logging.set_verbosity(optuna.logging.WARNING)" - ] - }, - { - "cell_type": "markdown", - "id": "ad476faf-3bf5-46a8-b615-87679418050b", - "metadata": {}, - "source": [ - "Wrap the function to optimize into an objective function that takes a `trial` object as a parameter." - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "id": "6488e59f-4817-4c91-ad99-7c31a83cf670", - "metadata": {}, - "outputs": [], - "source": [ - "def objective(trial):\n", - " x = trial.suggest_float('x', -10.0, 10.0)\n", - " y = trial.suggest_float('y', -10.0, 10.0)\n", - " return func(x, y)" - ] - }, - { - "cell_type": "markdown", - "id": "5347c78b-df02-4e03-b6da-1bce5380e652", - "metadata": {}, - "source": [ - "Set up a study." - ] - }, - { - "cell_type": "code", - "execution_count": 71, - "id": "72434395-2905-460a-b9fe-f867c6d7de02", - "metadata": {}, - "outputs": [], - "source": [ - "study = optuna.create_study(direction='minimize')" - ] - }, - { - "cell_type": "markdown", - "id": "f48e8531-7243-4038-a4ea-2a2167bc8575", - "metadata": {}, - "source": [ - "Use the study to optimize the parameters, `x` and `y` in this case." - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "id": "d13e38a7-3ad2-4179-b04a-c5985999b548", - "metadata": {}, - "outputs": [], - "source": [ - "study.optimize(objective, n_trials=500)" - ] - }, - { - "cell_type": "markdown", - "id": "ae9f42a5-f69a-4089-8e29-33963a00d8fa", - "metadata": {}, - "source": [ - "Display the best value and the corresponding values of the parameters `x` and `y`." - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "id": "0ddeae42-2649-4fa3-ad33-5b51b770fc87", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " Value: 0.0003461049669315486\n", - " Params:\n", - " x: 4.967603273980602\n", - " y: 7.076241340970131\n" - ] - } - ], - "source": [ - "print(f' Value: {study.best_trial.value}')\n", - "print(' Params:')\n", - "for key, value in study.best_trial.params.items():\n", - " print(f' {key}: {value}')" - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "id": "4a62b1a5-f082-4989-baf6-306b3f6fd62b", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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AwAiUPg3tVdffdVWrVplixcvtu9+97v29NNP27e+9S2rrKy0a6+91tra2szMrKamJnVcTU2N7dixo9tzLl261BYvXlza7ujooGH7EOvratZZw/99N0ZWCi1/Lu3m0JRa/ryh7kaV1f3ky6AZ0X2Xo15DuzH9UGy9ph7ru5+0K1/r99133+32GmZd68ifS9M26b298847pZ+1i0uHp/tururq6tQ+7Zb1tB502w9Bz1rNPLSagh7rz5tVBk/vRe/1D3/4Q+lnTX2mdThmzJjSz/osdNtPqXjrrbdS+/SZ++d46qmnpvbpu+S7H/3zNutaD/46/r6zVjnoq8IbtcOHD9uMGTOsubnZzMzOOecc27p1q61atcquvfba0ue6+49QT/GXysrKLvM6AABQhXc/jhs3zs4888zU78444wzbuXOnmZnV1taamZW+sR3V3t7e5dsbAAB5FN6onXfeebZt27bU71566SWbNGmSmZnV19dbbW2ttba2lvYfPHjQNmzYYLNmzSq6OACAQaTw7sebbrrJZs2aZc3NzXbFFVfY008/bffdd5/dd999Znak27GxsdGam5utoaHBGhoarLm52UaOHGlXXXVV0cXBAMsapu9lxclCw/+z4maeDsX3cRSNoeh5fBxAUwep0NIj/joag9DRvX5/KIam21p/Gpt5++23eyyDxlB8jEWvqVMkfIzFx+3Muj4nH2vSOJPWma8XXWIlNKRfn2meIf16bGhIv5bJ14umnQrFDzW1mNahr9+slGU+PqfxTL2Ofx+0HjRW56+jfyNaXn9d/3erMeiiFN6onXvuufaTn/zEli5darfeeqvV19fbypUr7eqrry59ZsmSJXbgwAFbsGCB7dmzx2bOnGnr169njhoAoF/KktD40ksvtUsvvbTH/RUVFdbU1GRNTU3luDwAYJAi9yMAIBosPYPC9SduFuL77rUfX6/pYyEaFwkteaFxMt32MZXQEhvdbXuh9EUaa/BxNI2ZaKzDl0nnIf3xj39Mbfvr6jI6fi6UWTqmpvEWH4vR64TSbZml70fvRcvkY1gav9Jt/8z1Oel5fZmylhPyzz+rDL68Wp+hGFXoOen+U045JbXv6Ojyo/xz0/lv+p7562gZNJbrY4J6L8rH2HydlCumxjc1AEA0aNQAANGg+xG55VnNOs++PFn6VSi9UWila7P00OusYfo+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jRgxwqZMmWK33nprKvHwYKujD9Xi0clx6uGHH05OOOGE5P77709efPHFZNGiRclJJ52U7NixY6CLdsx9/vOfT1avXp288MILyebNm5NLLrkkmThxYvLee++VPnPHHXckVVVVyY9//ONky5YtyVe+8pVk3LhxSUdHxwCWfGA8/fTTyeTJk5NPfvKTyaJFi0q/p46S5J133kkmTZqUfP3rX0/+53/+J9m+fXvy2GOPJS+//HLpM4O9nm677bZk9OjRyX/8x38k27dvT/7t3/4t+chHPpKsXLmy9JnBVkc///nPk2XLliU//vGPEzNLfvKTn6T296Y+rr/++uS0005LWltbk+eeey654IILkk996lPJBx98kKssx22j9hd/8RfJ9ddfn/rd1KlTk1tuuWWASvTh0d7enphZsmHDhiRJkuTw4cNJbW1tcscdd5Q+86c//Smprq5OfvjDHw5UMQfEvn37koaGhqS1tTWZPXt2qVGjjo64+eabk/PPP7/H/dRTklxyySXJN7/5zdTv5s2bl1xzzTVJklBH2qj1pj7efffd5IQTTkgefvjh0md2796dDBkyJPnFL36R6/rHZffjwYMHbdOmTamFRs3M5s6d2+NCo4PJ3r17zcxs1KhRZta7xVsHixtuuMEuueSSLnlGqaMj1q1bZzNmzLAvf/nLNnbsWDvnnHPs/vvvL+2nnszOP/98++Uvf2kvvfSSmZn95je/saeeesq+8IUvmBl1pMq1eHRPyrKeWrm99dZbdujQoW4XI+1podHBIkkSW7x4sZ1//vk2bdo0M+vd4q2DwcMPP2zPPfecPfPMM132UUdHvPrqq7Zq1SpbvHixffe737Wnn37avvWtb1llZaVde+211JOZ3XzzzbZ3716bOnWqDR061A4dOmS33367XXnllWbGu6TKtXh0T47LRu2ovixGGruFCxfab3/7W3vqqae67BvM9bVr1y5btGiRrV+/vsvKwt5griOzI6ssz5gxw5qbm83M7JxzzrGtW7faqlWr7Nprry19bjDX0yOPPGIPPfSQrV271s466yzbvHmzNTY2Wl1dnc2fP7/0ucFcR90pevHonhyX3Y9jxoyxoUOHdmnB/WKkg9GNN95o69ats8cff9zGjx9f+r1fvNUbTPW1adMma29vt+nTp9uwYcNs2LBhtmHDBvvHf/xHGzZsWKkeBnMdmZmNGzfOzjzzzNTvzjjjjNLKzbxLZt/5znfslltusa9+9at29tln29e+9jW76aabrKWlxcyoI9Wb+vCLR/f0md46Lhu1E0880aZPn26tra2p37e2tvZ69eyYJEliCxcutEcffdR+9atfWX19fWq/X7z1qKOLtw6W+rrwwgtty5Yttnnz5tK/GTNm2NVXX22bN2+2KVOmDPo6MjM777zzukwHeemll2zSpElmxrtkZrZ//34bMiT9n86hQ4eWhvRTR2m9qQ+/ePRRRxePzl1nfRre8iFwdEj/Aw88kLz44otJY2NjctJJJyWvvfbaQBftmPvbv/3bpLq6OnniiSeSN998s/Rv//79pc/ccccdSXV1dfLoo48mW7ZsSa688sqohxj3hh/9mCTUUZIcme4wbNiw5Pbbb09+//vfJ//6r/+ajBw5MnnooYdKnxns9TR//vzktNNOKw3pf/TRR5MxY8YkS5YsKX1msNXRvn37kueffz55/vnnEzNLVqxYkTz//POlKVa9qY/rr78+GT9+fPLYY48lzz33XPJXf/VXg2tIf5IkyT/90z8lkyZNSk488cTkM5/5TGkI+2BjZt3+W716dekzhw8fTr7//e8ntbW1SWVlZfLZz3422bJly8AV+kNAGzXq6Iif/exnybRp05LKyspk6tSpyX333ZfaP9jrqaOjI1m0aFEyceLEZPjw4cmUKVOSZcuWJZ2dnaXPDLY6evzxx7v9b9D8+fOTJOldfRw4cCBZuHBhMmrUqGTEiBHJpZdemuzcuTN3WVhPDQAQjeMypgYAQHdo1AAA0aBRAwBEg0YNABANGjUAQDRo1AAA0aBRAwBEg0YNABANGjUAQDRo1AAA0aBRAwBE4/8A8xfSI/1ms3kAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.imshow(Z, cmap='Grays')\n", - "plt.plot(\n", - " [5.0*study.best_trial.params['x'] + 50.0],\n", - " [5.0*study.best_trial.params['y'] + 50.0],\n", - " 'ro',\n", - " markersize=2\n", - ");" - ] - }, - { - "cell_type": "markdown", - "id": "902de243-ebf7-4df1-ac09-70bcec4e21c9", - "metadata": {}, - "source": [ - "## Robustness" - ] - }, - { - "cell_type": "markdown", - "id": "62418c86-cc44-4e07-8893-568bec199e7d", - "metadata": {}, - "source": [ - "How different are results of independent runs of the optimization mechanism." - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "id": "11741e9a-2e06-439a-83ac-0866c638842e", - "metadata": {}, - "outputs": [], - "source": [ - "nr_tries = 10\n", - "xs, ys = [], []\n", - "for _ in range(nr_tries):\n", - " study = optuna.create_study(direction='minimize')\n", - " study.optimize(objective, n_trials=100)\n", - " xs.append(study.best_trial.params['x'])\n", - " ys.append(study.best_trial.params['y'])" - ] - }, - { - "cell_type": "code", - "execution_count": 80, - "id": "7d29ff6a-d795-4406-9d3b-903c9161057f", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "image/png": "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bTrppJO0Zs2a3JyNG2+8UWPHjtWHPvQh7dq1S6eddpruuOMO5qgBAIakdKO2cOHC5GiVhoYGtbe3q729fcDPHH744brpppt00003lb18TmNjo770pS/1mSCLv6KODgz1VIw6KkYdFRvuOmrI6j2eEgCAEUJCYwBAZdCoAQAqg0YNAFAZNGoAgMqgUQMAVMZB3ah97WtfU1tbmw4//HDNnTtXP//5z0e6SCOis7NTJ554oiZMmKApU6bonHPO0aZNm3KfOZDFW0eTzs5ONTQ0aMmSJbXfUUe9tm7dqgsuuECTJk3S+PHj9c53vlPr1q2r7R/t9fTKK6/oi1/8otra2jRu3DjNmjVLV199dS7x8Giro9fU4tHZQeruu+/ODj300OzWW2/NHnvssezyyy/PjjjiiOzpp58e6aK96t773vdmt99+e/boo49m69evz84444xsxowZ2UsvvVT7zHXXXZdNmDAh+/a3v51t2LAh+/CHP5xNnTo127FjxwiWfGQ8+OCD2VFHHZW9/e1vzy6//PLa76mjLHvhhReymTNnZh//+Mez//3f/802b96c/fjHP86eeOKJ2mdGez1dc8012aRJk7If/OAH2ebNm7P//M//zF73utdlK1eurH1mtNXRD3/4w2z58uXZt7/97UxS9p3vfCe3/0Dq45JLLsmOPPLIrKurK3v44YezU089NXvHO96RvfLKK6XKctA2an/zN3+TXXLJJbnfHXPMMdlVV101QiV67ejp6ckkZWvXrs2yLMv27duXtbS0ZNddd13tM3/+85+zpqam7Otf//pIFXNE7Ny5M5s9e3bW1dWVLViwoNaoUUe9Pv/5z2ennHLKgPuppyw744wzsk9+8pO535177rnZBRdckGUZdeSN2oHUx4svvpgdeuih2d133137zNatW7NDDjkk+9GPflTq+gdl9+OePXu0bt263EKjkrRo0aIBFxodTbZv3y5JmjhxoqQDW7x1tLj00kt1xhln9MkzSh31Wr16tebNm6cPfvCDmjJlik444QTdeuuttf3Uk3TKKafoJz/5iR5//HFJ0i9/+Uvdf//9ev/73y+JOnLDtXj0QIZlPbXh9vzzz2vv3r39LkY60EKjo0WWZVq6dKlOOeUUzZkzR9KBLd46Gtx99916+OGH9dBDD/XZRx31+u1vf6ubb75ZS5cu1Re+8AU9+OCD+sxnPqPGxkZdeOGF1JOkz3/+89q+fbuOOeYYjRkzRnv37tW1116rj370o5J4l9xwLR49kIOyUdtvMIuRVt1ll12mX/3qV7r//vv77BvN9bVlyxZdfvnlWrNmTZ+VhaPRXEdS7yrL8+bNU0dHhyTphBNO0MaNG3XzzTfrwgsvrH1uNNfTt771Ld11111atWqVjjvuOK1fv15LlixRa2urLrrootrnRnMd9afei0cP5KDsfpw8ebLGjBnTpwWPi5GORp/+9Ke1evVq3XvvvZo2bVrt93Hx1mg01de6devU09OjuXPnauzYsRo7dqzWrl2rr3zlKxo7dmytHkZzHUnS1KlT9ba3vS33u2OPPba2cjPvkvS5z31OV111lT7ykY/o+OOP18c+9jFdccUV6uzslEQduQOpj7h49ECfOVAHZaN22GGHae7cuerq6sr9vqur64BXz66SLMt02WWX6Z577tFPf/pTtbW15fbHxVv3279462ipr9NOO00bNmzQ+vXra//mzZun888/X+vXr9esWbNGfR1J0sknn9xnOsjjjz+umTNnSuJdkqSXX35ZhxyS/0/nmDFjakP6qaO8A6mPuHj0fvsXjy5dZ4Ma3vIasH9I/2233ZY99thj2ZIlS7Ijjjgie+qpp0a6aK+6f/iHf8iampqy++67L3vuuedq/15++eXaZ6677rqsqakpu+eee7INGzZkH/3oRys9xPhAxNGPWUYdZVnvdIexY8dm1157bfab3/wm+4//+I9s/Pjx2V133VX7zGivp4suuig78sgja0P677nnnmzy5MnZlVdeWfvMaKujnTt3Zo888kj2yCOPZJKyFStWZI888khtitWB1Mcll1ySTZs2Lfvxj3+cPfzww9nf/d3fja4h/VmWZf/6r/+azZw5MzvssMOyd73rXbUh7KONpH7/3X777bXP7Nu3L/vSl76UtbS0ZI2Njdm73/3ubMOGDSNX6NcAb9Soo17f//73szlz5mSNjY3ZMccck91yyy25/aO9nnbs2JFdfvnl2YwZM7LDDz88mzVrVrZ8+fJs9+7dtc+Mtjq69957+/1v0EUXXZRl2YHVx65du7LLLrssmzhxYjZu3LjszDPPzJ555pnSZWE9NQBAZRyUMTUAAPpDowYAqAwaNQBAZdCoAQAqg0YNAFAZNGoAgMqgUQMAVAaNGgCgMmjUAACVQaMGAKgMGjUAQGX8P42rKGETFVsAAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.imshow(Z, cmap='Grays')\n", - "plt.plot(\n", - " [5.0*x + 50.0 for x in xs],\n", - " [5.0*y + 50.0 for y in ys],\n", - " 'ro',\n", - " markersize=2\n", - ");" - ] - }, - { - "cell_type": "markdown", - "id": "2d309f80-5a3d-4864-9a2d-5465ade7b205", - "metadata": {}, - "source": [ - "# Example 2" - ] - }, - { - "cell_type": "markdown", - "id": "8ee22b00-e730-4edd-8617-5e0e2542cf9f", - "metadata": {}, - "source": [ - "## Target function" - ] - }, - { - "cell_type": "code", - "execution_count": 106, - "id": "644139cc-c2c7-4236-bed3-d15037cf7ca6", - "metadata": {}, - "outputs": [], - "source": [ - "def gauss_holes(x, y, holes):\n", - " x_1, y_1, a_1, s_1 = holes[0][0], holes[0][1], 7.0, 0.05\n", - " x_2, y_2, a_2, s_2 = holes[1][0], holes[1][1], 10.0, 0.5\n", - " g_1 = a_1*np.exp(-s_1*((x - x_1)**2 + (y - y_1)**2))\n", - " g_2 = a_2*np.exp(-s_2*((x - x_2)**2 + (y - y_2)**2))\n", - " return 10.0 - g_1 - g_2" - ] - }, - { - "cell_type": "code", - "execution_count": 113, - "id": "30305247-8bba-4d5b-a50b-b4b565f2ed34", - "metadata": {}, - "outputs": [], - "source": [ - "holes = [(-3.0, 5.0), (7.0, -3.0)]" - ] - }, - { - "cell_type": "code", - "execution_count": 114, - "id": "274977df-4fad-4c47-867d-372b522596fa", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "image/png": "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9cILL+jHP/6xmpubc86bm7decWXz1rHSXrfeeqsOHz6sQ4cOZX8WLVqku+++W4cOHdK8efPGfBtJ0s033zxkOsjbb7+tuXPnSuK7JElnzpzRuHG5/3SOHz8+O6SfNsqVT3uYm0dfcWXzaO82K2h4yyhwZUj/P/zDP0RvvfVW1NraGk2ZMiX6n//5n3JXreT++q//Oqqrq4t++tOfRu+++27258yZM9kyjz76aFRXVxe98MIL0eHDh6O77ror6CHG+TBHP0YRbRRFl6c7TJgwIXrkkUei//qv/4r+6Z/+KaqpqYmee+65bJmx3k5r1qyJrr766uyQ/hdeeCGaMWNGtHHjxmyZsdZGp06dit58883ozTffjCRF27dvj958883sFKt82uO+++6LZs+eHf3whz+M3njjjejP/uzPxtaQ/iiKom9961vR3Llzo0mTJkUf+chHskPYxxpJw/4888wz2TKXLl2Kvv71r0cNDQ1RJpOJ/vRP/zQ6fPhw+So9CtidGm102fe+971o/vz5USaTia677rpo165dOefHejv19/dHGzZsiObMmRNNnjw5mjdvXrR58+ZoYGAgW2astdFPfvKTYf8NWrNmTRRF+bXH2bNno/Xr10fTpk2Lqquro0984hPRiRMnvOvCfmoAgGBUZE4NAIDh0KkBAIJBpwYACAadGgAgGHRqAIBg0KkBAIJBpwYACAadGgAgGHRqAIBg0KkBAIJBpwYACMb/ATn4sLga9G+aAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "visualize_func(functools.partial(gauss_holes, holes=holes))" - ] - }, - { - "cell_type": "markdown", - "id": "bc1cb297-d080-41a7-844b-ec83a6c95346", - "metadata": {}, - "source": [ - "## Samplers" - ] - }, - { - "cell_type": "markdown", - "id": "0007187b-e5b1-4d85-acb8-6fb276f5b90d", - "metadata": {}, - "source": [ - "### Default" - ] - }, - { - "cell_type": "code", - "execution_count": 170, - "id": "61060d7a-414b-4e6e-a1b2-4184e30fafb9", - "metadata": {}, - "outputs": [], - "source": [ - "nr_tries = 20\n", - "xs, ys = [], []\n", - "for _ in range(nr_tries):\n", - " study = optuna.create_study(direction='minimize')\n", - " study.optimize(\n", - " lambda trial: functools.partial(\n", - " gauss_holes,\n", - " holes=holes)(trial.suggest_float('x', -10.0, 10.0), trial.suggest_float('y', -10.0, 10.0)),\n", - " n_trials=200\n", - " )\n", - " xs.append(study.best_trial.params['x'])\n", - " ys.append(study.best_trial.params['y'])" - ] - }, - { - "cell_type": "code", - "execution_count": 171, - "id": "f2441321-f7d2-4f78-8227-8410a1b279c8", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "visualize_func(functools.partial(gauss_holes, holes=holes))\n", - "plt.plot(\n", - " [5.0*x + 50.0 for x in xs],\n", - " [5.0*y + 50.0 for y in ys],\n", - " 'ro',\n", - " markersize=2\n", - ");" - ] - }, - { - "cell_type": "code", - "execution_count": 180, - "id": "dbec700b-9ce4-4ab6-ab13-579d2b07522d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Counter({(-3.0, 5.0): 19})" - ] - }, - "execution_count": 180, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "counter = collections.Counter()\n", - "for x, y in zip(xs, ys):\n", - " if np.isclose(x, holes[0][0], atol=3.0) and np.isclose(y, holes[0][1], atol=3.0):\n", - " counter[holes[0]] += 1\n", - " elif np.isclose(x, holes[1][0], atol=0.1) and np.isclose(y, holes[1][1], atol=0.1):\n", - " counter[holes[1]] += 1\n", - "counter" - ] - }, - { - "cell_type": "markdown", - "id": "7107093a-f37d-411b-9f0a-3ae612c963df", - "metadata": {}, - "source": [ - "### TPESampler" - ] - }, - { - "cell_type": "code", - "execution_count": 181, - "id": "e9316a5f-830e-4868-80da-58918b994383", - "metadata": {}, - "outputs": [], - "source": [ - "nr_tries = 20\n", - "xs, ys = [], []\n", - "for _ in range(nr_tries):\n", - " study = optuna.create_study(direction='minimize', sampler=optuna.samplers.TPESampler())\n", - " study.optimize(\n", - " lambda trial: functools.partial(\n", - " gauss_holes,\n", - " holes=holes)(trial.suggest_float('x', -10.0, 10.0), trial.suggest_float('y', -10.0, 10.0)),\n", - " n_trials=200\n", - " )\n", - " xs.append(study.best_trial.params['x'])\n", - " ys.append(study.best_trial.params['y'])" - ] - }, - { - "cell_type": "code", - "execution_count": 182, - "id": "83a522a9-a117-4f31-8790-53705ed19055", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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jNR3q1at0i9/+Uu9/vrrQ85VcnsdPXpUq1ev1q5duzRu3LgRy1VyG0kXNt6dO3euOjo6JEmzZ8/WgQMHtGXLFt19993pcpXcTs8//7yee+45bd++XVdffbX27duntrY2NTU1afny5elyldxGw0l68+iRlGX4cfLkyaqurh7Sg4c3I61E999/v3bu3KlXXnlF06ZNSz8e3rw1rJLaa+/evert7dWcOXM0evRojR49Wt3d3fr7v/97jR49Ot0OldxGkjR16lR98pOfzHjsqquu0pEjRyTxXZKkb3/723rwwQf1la98Rddcc42++tWv6pvf/KY6Ozsl0UambNojvHn0SGWyVZad2tixYzVnzhx1dXVlPN7V1ZX17tk+CYJAq1at0gsvvKCf//znamlpyTgf3rz1ooubt1ZKe91www3av3+/9u3bl/6ZO3eu7rzzTu3bt08zZ86s+DaSpOuuu27IdJD3339fM2bMkMR3SZJOnjypUaMy/+msrq5OD+mnjTJl0x7hzaMvurh5tHOb5TS8pQRcHNL/D//wD8F7770XtLW1BePHjw/+93//t9hVK7i//uu/Durr64NXX301+PDDD9M/J0+eTJd55JFHgvr6+uCFF14I9u/fH9xxxx1eDzHORnj0YxDQRkFwYbrD6NGjg4cffjj4n//5n+Cf/umfgtra2uC5555Ll6n0dlq+fHlw2WWXpYf0v/DCC8HkyZODNWvWpMtUWhsdP348ePvtt4O33347kBRs2rQpePvtt9NTrLJpj3vvvTeYNm1a8NOf/jR46623gj//8z+vrCH9QRAETzzxRDBjxoxg7NixwWc/+9n0EPZKI2nYn2eeeSZd5vz588H3vve9oLGxMUilUsHnPve5YP/+/cWrdAkwOzXa6IKXXnopmDVrVpBKpYIrr7wy2Lp1a8b5Sm+n/v7+YPXq1cH06dODcePGBTNnzgzWrVsXDAwMpMtUWhu98sorw/4btHz58iAIsmuPU6dOBatWrQomTpwY1NTUBF/84heDI0eOONeF/dQAAN4oy5waAADDoVMDAHiDTg0A4A06NQCAN+jUAADeoFMDAHiDTg0A4A06NQCAN+jUAADeoFMDAHiDTg0A4I3/BynECVHSqh/KAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "visualize_func(functools.partial(gauss_holes, holes=holes))\n", - "plt.plot(\n", - " [5.0*x + 50.0 for x in xs],\n", - " [5.0*y + 50.0 for y in ys],\n", - " 'ro',\n", - " markersize=2\n", - ");" - ] - }, - { - "cell_type": "code", - "execution_count": 183, - "id": "48d1ebc6-5dc9-488c-bcf3-d213eff46c2c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Counter({(-3.0, 5.0): 18, (7.0, -3.0): 2})" - ] - }, - "execution_count": 183, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "counter = collections.Counter()\n", - "for x, y in zip(xs, ys):\n", - " if np.isclose(x, holes[0][0], atol=3.0) and np.isclose(y, holes[0][1], atol=3.0):\n", - " counter[holes[0]] += 1\n", - " elif np.isclose(x, holes[1][0], atol=0.1) and np.isclose(y, holes[1][1], atol=0.1):\n", - " counter[holes[1]] += 1\n", - "counter" - ] - }, - { - "cell_type": "markdown", - "id": "43db0d23-8fd3-41e7-8976-fae830334220", - "metadata": {}, - "source": [ - "### RandomSampler" - ] - }, - { - "cell_type": "code", - "execution_count": 184, - "id": "10e3e0bb-8bc0-4528-91a7-7f392f17f02f", - "metadata": {}, - "outputs": [], - "source": [ - "nr_tries = 20\n", - "xs, ys = [], []\n", - "for _ in range(nr_tries):\n", - " study = optuna.create_study(direction='minimize', sampler=optuna.samplers.RandomSampler())\n", - " study.optimize(\n", - " lambda trial: functools.partial(\n", - " gauss_holes,\n", - " holes=holes)(trial.suggest_float('x', -10.0, 10.0), trial.suggest_float('y', -10.0, 10.0)),\n", - " n_trials=200\n", - " )\n", - " xs.append(study.best_trial.params['x'])\n", - " ys.append(study.best_trial.params['y'])" - ] - }, - { - "cell_type": "code", - "execution_count": 185, - "id": "57d0886d-7d35-4c9d-b935-c857b46d5fff", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "visualize_func(functools.partial(gauss_holes, holes=holes))\n", - "plt.plot(\n", - " [5.0*x + 50.0 for x in xs],\n", - " [5.0*y + 50.0 for y in ys],\n", - " 'ro',\n", - " markersize=2\n", - ");" - ] - }, - { - "cell_type": "code", - "execution_count": 186, - "id": "4a5eb390-6763-400b-bc8c-9964a774738c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Counter({(-3.0, 5.0): 10})" - ] - }, - "execution_count": 186, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "counter = collections.Counter()\n", - "for x, y in zip(xs, ys):\n", - " if np.isclose(x, holes[0][0], atol=3.0) and np.isclose(y, holes[0][1], atol=3.0):\n", - " counter[holes[0]] += 1\n", - " elif np.isclose(x, holes[1][0], atol=0.1) and np.isclose(y, holes[1][1], atol=0.1):\n", - " counter[holes[1]] += 1\n", - "counter" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "32bc40c0-f493-4654-99c4-d9b14c0641fa", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "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.13.5" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/source-code/parameter-optimization/parameter_optimization.ipynb b/source-code/parameter-optimization/parameter_optimization.ipynb deleted file mode 100644 index 2b0307d..0000000 --- a/source-code/parameter-optimization/parameter_optimization.ipynb +++ /dev/null @@ -1,883 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Optimization using hyperopt and BaysianOptimization" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Common imports for all sections." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T14:52:33.848125Z", - "start_time": "2018-12-22T14:52:33.796833Z" - } - }, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "%matplotlib inline\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, - "source": [ - "## Function to optimize" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hidden": true - }, - "source": [ - "Define the function to minimize." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T17:10:17.670693Z", - "start_time": "2018-12-22T17:10:17.618853Z" - }, - "hidden": true - }, - "outputs": [], - "source": [ - "def function(x, y):\n", - " x0, y0 = 1.2, 0.7\n", - " r = np.sqrt((x - x0)**2 + (y - y0)**2)\n", - " return 1.0 - np.abs(np.cos(2.0*np.pi*r))*np.exp(-r)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hidden": true - }, - "source": [ - "Visualize the function." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T17:10:19.724038Z", - "start_time": "2018-12-22T17:10:19.688429Z" - }, - "hidden": true - }, - "outputs": [], - "source": [ - "x = np.linspace(-3.0, 3.0, 101)\n", - "y = np.linspace(-3.0, 3.0, 101)\n", - "X, Y = np.meshgrid(x, y)\n", - "data = function(X, Y)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T17:15:25.972634Z", - "start_time": "2018-12-22T17:15:25.457959Z" - }, - "hidden": true - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "_ = plt.imshow(data, origin='lower')\n", - "_ = plt.xticks(np.linspace(0, 100, 7, dtype=np.int32), np.linspace(-3.0, 3.0, 7))\n", - "_ = plt.yticks(np.linspace(0, 100, 7, dtype=np.int32), np.linspace(-3.0, 3.0, 7))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## hyperopt" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Required imports." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T18:12:20.566589Z", - "start_time": "2018-12-22T18:12:20.547048Z" - }, - "scrolled": true - }, - "outputs": [], - "source": [ - "from hyperopt import fmin, hp, rand, STATUS_OK, tpe, Trials\n", - "from hyperopt.pyll.stochastic import sample\n", - "import time" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Sample space" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Define the optimization space. The two parameters are $x$ and $y$, and the sample points should be uniformly distributed in the intervals $x \\in [-3, 3]$ and $y \\in [-3, 3]$." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T17:20:40.898954Z", - "start_time": "2018-12-22T17:20:40.862618Z" - } - }, - "outputs": [], - "source": [ - "space = (hp.uniform('x', -3.0, 3.0), hp.uniform('y', -3.0, 3.0))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can sample the space using the `sample` method, e.g.," - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T17:21:08.286212Z", - "start_time": "2018-12-22T17:21:08.249040Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(1.2705149475081843, 2.9511352623203617)\n", - "(1.5987647157267206, -0.7543124296677615)\n", - "(0.889061703588971, 1.124895269215477)\n", - "(0.28101486839536527, 1.2672777984597383)\n", - "(2.0650550342215706, 1.4610177583744397)\n" - ] - } - ], - "source": [ - "for _ in range(5):\n", - " print(sample(space))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, - "source": [ - "### Objective function" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hidden": true - }, - "source": [ - "The `sample` function returns tuples of $x$ and $y$ values, so the obje ctive function should take a tuple as argument. Having a dictionary as a return type, rather than simply the value makes it easier to retrieve information from the `Trials` object that can be passed to `fmin`." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T17:30:04.023466Z", - "start_time": "2018-12-22T17:30:03.997062Z" - }, - "hidden": true - }, - "outputs": [], - "source": [ - "def objective(values):\n", - " return {\n", - " 'loss': function(values[0], values[1]),\n", - " 'x': values[0], 'y': values[1],\n", - " 'status': STATUS_OK, 'time': time.time(),\n", - " }" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hidden": true - }, - "source": [ - "A `Trials` object keeps track of the optimization process, so that it can be visualized or otherwise inspected when the optimization is done." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, - "source": [ - "### Trials" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hidden": true - }, - "source": [ - "Define a function that takes a `Trial` object, and returns two numpy arrays with the $x$ and $y$ coordinates of the sample points." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T17:47:44.244621Z", - "start_time": "2018-12-22T17:47:44.225292Z" - }, - "hidden": true - }, - "outputs": [], - "source": [ - "def sample_trace(trials):\n", - " x = np.empty(len(trials))\n", - " y = np.empty(len(trials))\n", - " for i, result in enumerate(trials.results):\n", - " x[i] = result['x']\n", - " y[i] = result['y']\n", - " return x, y" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Tree of Parzen estimators (TPE)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T17:30:08.789140Z", - "start_time": "2018-12-22T17:30:08.770722Z" - } - }, - "outputs": [], - "source": [ - "trials = Trials()" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T17:30:11.343393Z", - "start_time": "2018-12-22T17:30:09.517214Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "100%|███████████████████████████████████████████████████████████| 100/100 [00:00<00:00, 723.99trial/s, best loss: 0.3872706142114245]\n" - ] - } - ], - "source": [ - "best = fmin(objective, max_evals=100, space=space,\n", - " algo=tpe.suggest, trials=trials)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T17:30:32.504405Z", - "start_time": "2018-12-22T17:30:32.477951Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.7162563408135711 0.6542161024067286\n" - ] - } - ], - "source": [ - "print(best['x'], best['y'])" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T17:47:45.381283Z", - "start_time": "2018-12-22T17:47:45.370990Z" - } - }, - "outputs": [], - "source": [ - "sample_x, sample_y = sample_trace(trials)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T17:50:47.041208Z", - "start_time": "2018-12-22T17:50:45.775466Z" - } - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "def scale(z):\n", - " return (3.0 + z)*101.0/6.0\n", - "\n", - "_ = plt.imshow(data, origin='lower')\n", - "_ = plt.plot(scale(sample_x), scale(sample_y), 'k.', label='sample points')\n", - "_ = plt.plot((scale(best['x']), ), (scale(best['y']), ), 'ro', label='best value')\n", - "_ = plt.xticks(np.linspace(0, 100, 7, dtype=np.int32), np.linspace(-3.0, 3.0, 7))\n", - "_ = plt.yticks(np.linspace(0, 100, 7, dtype=np.int32), np.linspace(-3.0, 3.0, 7))\n", - "_ = plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Random search" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T18:14:31.498188Z", - "start_time": "2018-12-22T18:14:31.486271Z" - } - }, - "outputs": [], - "source": [ - "trials = Trials()" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T18:14:58.626794Z", - "start_time": "2018-12-22T18:14:58.303409Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "100%|██████████████████████████████████████████████████████████| 100/100 [00:00<00:00, 3182.93trial/s, best loss: 0.4471734199442068]\n" - ] - } - ], - "source": [ - "best = fmin(objective, max_evals=100, space=space,\n", - " algo=rand.suggest, trials=trials)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T18:15:02.496798Z", - "start_time": "2018-12-22T18:15:02.487516Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.9369298489451197 0.39120676050733394\n" - ] - } - ], - "source": [ - "print(best['x'], best['y'])" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T18:15:04.819242Z", - "start_time": "2018-12-22T18:15:04.806963Z" - } - }, - "outputs": [], - "source": [ - "sample_x, sample_y = sample_trace(trials)" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T18:15:06.965222Z", - "start_time": "2018-12-22T18:15:06.094650Z" - } - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "def scale(z):\n", - " return (3.0 + z)*101.0/6.0\n", - "\n", - "_ = plt.imshow(data, origin='lower')\n", - "_ = plt.plot(scale(sample_x), scale(sample_y), 'k.', label='sample points')\n", - "_ = plt.plot((scale(best['x']), ), (scale(best['y']), ), 'ro', label='best value')\n", - "_ = plt.xticks(np.linspace(0, 100, 7, dtype=np.int32), np.linspace(-3.0, 3.0, 7))\n", - "_ = plt.yticks(np.linspace(0, 100, 7, dtype=np.int32), np.linspace(-3.0, 3.0, 7))\n", - "_ = plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Although both the TPE and random search found the global optimum, it is clear that the TPE algorithm samples the parameter space in a more intelligent way." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Parameter space with choices" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The space below represents the parameter space for an OpenMP parallel for loop schedule (static, dynamic or guided) and the chunck size for each." - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-23T13:28:47.560899Z", - "start_time": "2018-12-23T13:28:47.535430Z" - } - }, - "outputs": [], - "source": [ - "space = hp.choice('schedule', [\n", - " ('static', hp.qloguniform('chunk', 2, 11, 10)),\n", - " ('dynamics', hp.qloguniform('chunk', 2, 11, 10)),\n", - " ('guided', hp.qloguniform('chunk', 2, 11, 10)),\n", - "])" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-23T13:28:48.869086Z", - "start_time": "2018-12-23T13:28:48.851203Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "('dynamics', 40.0)\n", - "('guided', 10.0)\n", - "('guided', 5320.0)\n", - "('dynamics', 10.0)\n", - "('guided', 560.0)\n" - ] - } - ], - "source": [ - "for _ in range(5):\n", - " print(sample(space))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "heading_collapsed": true - }, - "source": [ - "## BaysianOptimizer" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hidden": true - }, - "source": [ - "Required imports." - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T21:58:06.982084Z", - "start_time": "2018-12-22T21:58:05.789329Z" - }, - "hidden": true - }, - "outputs": [], - "source": [ - "from bayes_opt import BayesianOptimization" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hidden": true - }, - "source": [ - "Define the objective function." - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T22:04:25.880183Z", - "start_time": "2018-12-22T22:04:25.866248Z" - }, - "hidden": true - }, - "outputs": [], - "source": [ - "def objective(x, y):\n", - " return -function(x, y)" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T22:04:26.329642Z", - "start_time": "2018-12-22T22:04:26.320629Z" - }, - "hidden": true - }, - "outputs": [], - "source": [ - "param_bounds = {'x': (-3.0, 3.0), 'y': (-3.0, 3.0)}" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T22:13:33.613565Z", - "start_time": "2018-12-22T22:13:33.593673Z" - }, - "hidden": true - }, - "outputs": [], - "source": [ - "optimizer = BayesianOptimization(f=objective, pbounds=param_bounds, random_state=1234)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T22:19:29.124060Z", - "start_time": "2018-12-22T22:13:34.202124Z" - }, - "hidden": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "| iter | target | x | y |\n", - "-------------------------------------------------\n", - "| \u001b[0m1 \u001b[0m | \u001b[0m-0.9551 \u001b[0m | \u001b[0m-1.851 \u001b[0m | \u001b[0m0.7327 \u001b[0m |\n", - "| \u001b[95m2 \u001b[0m | \u001b[95m-0.8939 \u001b[0m | \u001b[95m-0.3736 \u001b[0m | \u001b[95m1.712 \u001b[0m |\n", - "| \u001b[0m3 \u001b[0m | \u001b[0m-0.9122 \u001b[0m | \u001b[0m1.68 \u001b[0m | \u001b[0m-1.364 \u001b[0m |\n", - "| \u001b[0m4 \u001b[0m | \u001b[0m-0.9028 \u001b[0m | \u001b[0m-0.2245 \u001b[0m | \u001b[0m-0.8474 \u001b[0m |\n", - "| \u001b[0m5 \u001b[0m | \u001b[0m-0.9142 \u001b[0m | \u001b[0m1.691 \u001b[0m | \u001b[0m-1.365 \u001b[0m |\n", - "| \u001b[0m6 \u001b[0m | \u001b[0m-0.9707 \u001b[0m | \u001b[0m-0.1963 \u001b[0m | \u001b[0m1.8 \u001b[0m |\n", - "| \u001b[95m7 \u001b[0m | \u001b[95m-0.8689 \u001b[0m | \u001b[95m-0.471 \u001b[0m | \u001b[95m1.664 \u001b[0m |\n", - "| \u001b[0m8 \u001b[0m | \u001b[0m-0.8957 \u001b[0m | \u001b[0m-0.5939 \u001b[0m | \u001b[0m1.773 \u001b[0m |\n", - "| \u001b[0m9 \u001b[0m | \u001b[0m-0.9045 \u001b[0m | \u001b[0m-0.4766 \u001b[0m | \u001b[0m1.492 \u001b[0m |\n", - "| \u001b[0m10 \u001b[0m | \u001b[0m-0.8889 \u001b[0m | \u001b[0m-0.6737 \u001b[0m | \u001b[0m1.595 \u001b[0m |\n", - "| \u001b[0m11 \u001b[0m | \u001b[0m-0.9828 \u001b[0m | \u001b[0m-2.453 \u001b[0m | \u001b[0m2.113 \u001b[0m |\n", - "| \u001b[0m12 \u001b[0m | \u001b[0m-0.8836 \u001b[0m | \u001b[0m1.322 \u001b[0m | \u001b[0m-1.361 \u001b[0m |\n", - "| \u001b[0m13 \u001b[0m | \u001b[0m-0.9277 \u001b[0m | \u001b[0m1.394 \u001b[0m | \u001b[0m-1.114 \u001b[0m |\n", - "| \u001b[0m14 \u001b[0m | \u001b[0m-0.9467 \u001b[0m | \u001b[0m-0.07426 \u001b[0m | \u001b[0m-1.267 \u001b[0m |\n", - "| \u001b[0m15 \u001b[0m | \u001b[0m-0.9938 \u001b[0m | \u001b[0m1.312 \u001b[0m | \u001b[0m-1.557 \u001b[0m |\n", - "| \u001b[0m16 \u001b[0m | \u001b[0m-0.9594 \u001b[0m | \u001b[0m0.2099 \u001b[0m | \u001b[0m2.795 \u001b[0m |\n", - "| \u001b[95m17 \u001b[0m | \u001b[95m-0.8635 \u001b[0m | \u001b[95m1.224 \u001b[0m | \u001b[95m-1.261 \u001b[0m |\n", - "| \u001b[95m18 \u001b[0m | \u001b[95m-0.863 \u001b[0m | \u001b[95m1.048 \u001b[0m | \u001b[95m-1.267 \u001b[0m |\n", - "| \u001b[0m19 \u001b[0m | \u001b[0m-0.9425 \u001b[0m | \u001b[0m1.066 \u001b[0m | \u001b[0m-1.102 \u001b[0m |\n", - "| \u001b[0m20 \u001b[0m | \u001b[0m-0.8666 \u001b[0m | \u001b[0m2.612 \u001b[0m | \u001b[0m1.516 \u001b[0m |\n", - "| \u001b[0m21 \u001b[0m | \u001b[0m-0.9954 \u001b[0m | \u001b[0m-2.676 \u001b[0m | \u001b[0m-1.904 \u001b[0m |\n", - "| \u001b[0m22 \u001b[0m | \u001b[0m-0.987 \u001b[0m | \u001b[0m-1.367 \u001b[0m | \u001b[0m-1.916 \u001b[0m |\n", - "| \u001b[0m23 \u001b[0m | \u001b[0m-0.9095 \u001b[0m | \u001b[0m1.031 \u001b[0m | \u001b[0m-1.408 \u001b[0m |\n", - "| \u001b[95m24 \u001b[0m | \u001b[95m-0.784 \u001b[0m | \u001b[95m2.455 \u001b[0m | \u001b[95m1.561 \u001b[0m |\n", - "| \u001b[0m25 \u001b[0m | \u001b[0m-0.7904 \u001b[0m | \u001b[0m2.383 \u001b[0m | \u001b[0m1.478 \u001b[0m |\n", - "| \u001b[95m26 \u001b[0m | \u001b[95m-0.7765 \u001b[0m | \u001b[95m2.317 \u001b[0m | \u001b[95m1.627 \u001b[0m |\n", - "| \u001b[0m27 \u001b[0m | \u001b[0m-0.875 \u001b[0m | \u001b[0m2.426 \u001b[0m | \u001b[0m1.788 \u001b[0m |\n", - "| \u001b[0m28 \u001b[0m | \u001b[0m-0.961 \u001b[0m | \u001b[0m2.165 \u001b[0m | \u001b[0m1.529 \u001b[0m |\n", - "| \u001b[0m29 \u001b[0m | \u001b[0m-0.7932 \u001b[0m | \u001b[0m2.424 \u001b[0m | \u001b[0m1.637 \u001b[0m |\n", - "| \u001b[0m30 \u001b[0m | \u001b[0m-0.7831 \u001b[0m | \u001b[0m2.478 \u001b[0m | \u001b[0m1.344 \u001b[0m |\n", - "| \u001b[0m31 \u001b[0m | \u001b[0m-0.7888 \u001b[0m | \u001b[0m2.534 \u001b[0m | \u001b[0m1.183 \u001b[0m |\n", - "| \u001b[0m32 \u001b[0m | \u001b[0m-0.9749 \u001b[0m | \u001b[0m2.371 \u001b[0m | \u001b[0m1.177 \u001b[0m |\n", - "| \u001b[0m33 \u001b[0m | \u001b[0m-0.8163 \u001b[0m | \u001b[0m2.679 \u001b[0m | \u001b[0m1.244 \u001b[0m |\n", - "| \u001b[0m34 \u001b[0m | \u001b[0m-0.883 \u001b[0m | \u001b[0m2.436 \u001b[0m | \u001b[0m1.787 \u001b[0m |\n", - "| \u001b[0m35 \u001b[0m | \u001b[0m-0.8641 \u001b[0m | \u001b[0m0.5867 \u001b[0m | \u001b[0m-1.156 \u001b[0m |\n", - "| \u001b[0m36 \u001b[0m | \u001b[0m-0.9447 \u001b[0m | \u001b[0m0.2742 \u001b[0m | \u001b[0m-1.744 \u001b[0m |\n", - "| \u001b[95m37 \u001b[0m | \u001b[95m-0.774 \u001b[0m | \u001b[95m2.55 \u001b[0m | \u001b[95m1.296 \u001b[0m |\n", - "| \u001b[0m38 \u001b[0m | \u001b[0m-0.7754 \u001b[0m | \u001b[0m2.653 \u001b[0m | \u001b[0m1.043 \u001b[0m |\n", - "| \u001b[0m39 \u001b[0m | \u001b[0m-0.8512 \u001b[0m | \u001b[0m2.803 \u001b[0m | \u001b[0m0.9027 \u001b[0m |\n", - "| \u001b[0m40 \u001b[0m | \u001b[0m-0.8578 \u001b[0m | \u001b[0m2.537 \u001b[0m | \u001b[0m0.8138 \u001b[0m |\n", - "| \u001b[0m41 \u001b[0m | \u001b[0m-0.7949 \u001b[0m | \u001b[0m2.184 \u001b[0m | \u001b[0m1.89 \u001b[0m |\n", - "| \u001b[0m42 \u001b[0m | \u001b[0m-0.9182 \u001b[0m | \u001b[0m2.145 \u001b[0m | \u001b[0m2.087 \u001b[0m |\n", - "| \u001b[0m43 \u001b[0m | \u001b[0m-0.8878 \u001b[0m | \u001b[0m0.5029 \u001b[0m | \u001b[0m-0.7962 \u001b[0m |\n", - "| \u001b[0m44 \u001b[0m | \u001b[0m-0.7742 \u001b[0m | \u001b[0m2.209 \u001b[0m | \u001b[0m1.783 \u001b[0m |\n", - "| \u001b[0m45 \u001b[0m | \u001b[0m-0.8504 \u001b[0m | \u001b[0m2.543 \u001b[0m | \u001b[0m0.8059 \u001b[0m |\n", - "| \u001b[0m46 \u001b[0m | \u001b[0m-0.7747 \u001b[0m | \u001b[0m2.682 \u001b[0m | \u001b[0m0.5753 \u001b[0m |\n", - "| \u001b[0m47 \u001b[0m | \u001b[0m-0.8777 \u001b[0m | \u001b[0m2.514 \u001b[0m | \u001b[0m0.5181 \u001b[0m |\n", - "| \u001b[0m48 \u001b[0m | \u001b[0m-0.8863 \u001b[0m | \u001b[0m2.847 \u001b[0m | \u001b[0m0.6209 \u001b[0m |\n", - "| \u001b[0m49 \u001b[0m | \u001b[0m-0.8227 \u001b[0m | \u001b[0m2.757 \u001b[0m | \u001b[0m0.4069 \u001b[0m |\n", - "| \u001b[0m50 \u001b[0m | \u001b[0m-0.8159 \u001b[0m | \u001b[0m2.007 \u001b[0m | \u001b[0m1.82 \u001b[0m |\n", - "| \u001b[0m51 \u001b[0m | \u001b[0m-0.785 \u001b[0m | \u001b[0m2.472 \u001b[0m | \u001b[0m1.345 \u001b[0m |\n", - "| \u001b[0m52 \u001b[0m | \u001b[0m-0.9624 \u001b[0m | \u001b[0m1.705 \u001b[0m | \u001b[0m1.867 \u001b[0m |\n", - "| \u001b[0m53 \u001b[0m | \u001b[0m-0.9249 \u001b[0m | \u001b[0m2.768 \u001b[0m | \u001b[0m0.08601 \u001b[0m |\n", - "| \u001b[0m54 \u001b[0m | \u001b[0m-0.8028 \u001b[0m | \u001b[0m-0.2591 \u001b[0m | \u001b[0m1.244 \u001b[0m |\n", - "| \u001b[0m55 \u001b[0m | \u001b[0m-0.8026 \u001b[0m | \u001b[0m-0.1472 \u001b[0m | \u001b[0m1.07 \u001b[0m |\n", - "| \u001b[0m56 \u001b[0m | \u001b[0m-0.784 \u001b[0m | \u001b[0m2.456 \u001b[0m | \u001b[0m1.561 \u001b[0m |\n", - "| \u001b[0m57 \u001b[0m | \u001b[0m-0.8425 \u001b[0m | \u001b[0m-0.3702 \u001b[0m | \u001b[0m1.039 \u001b[0m |\n", - "| \u001b[0m58 \u001b[0m | \u001b[0m-0.8549 \u001b[0m | \u001b[0m-0.02238 \u001b[0m | \u001b[0m1.258 \u001b[0m |\n", - "| \u001b[0m59 \u001b[0m | \u001b[0m-0.9809 \u001b[0m | \u001b[0m-0.05312 \u001b[0m | \u001b[0m0.8384 \u001b[0m |\n", - "| \u001b[0m60 \u001b[0m | \u001b[0m-0.9846 \u001b[0m | \u001b[0m2.951 \u001b[0m | \u001b[0m-2.974 \u001b[0m |\n", - "| \u001b[0m61 \u001b[0m | \u001b[0m-0.9958 \u001b[0m | \u001b[0m-2.971 \u001b[0m | \u001b[0m-0.3454 \u001b[0m |\n", - "| \u001b[0m62 \u001b[0m | \u001b[0m-0.9924 \u001b[0m | \u001b[0m1.403 \u001b[0m | \u001b[0m-2.995 \u001b[0m |\n", - "| \u001b[0m63 \u001b[0m | \u001b[0m-0.9815 \u001b[0m | \u001b[0m-0.2748 \u001b[0m | \u001b[0m-2.993 \u001b[0m |\n", - "| \u001b[0m64 \u001b[0m | \u001b[0m-0.97 \u001b[0m | \u001b[0m-1.373 \u001b[0m | \u001b[0m2.99 \u001b[0m |\n", - "| \u001b[0m65 \u001b[0m | \u001b[0m-0.9808 \u001b[0m | \u001b[0m2.984 \u001b[0m | \u001b[0m-1.331 \u001b[0m |\n", - "| \u001b[0m66 \u001b[0m | \u001b[0m-0.9521 \u001b[0m | \u001b[0m-1.45 \u001b[0m | \u001b[0m-0.5396 \u001b[0m |\n", - "| \u001b[95m67 \u001b[0m | \u001b[95m-0.4278 \u001b[0m | \u001b[95m1.172 \u001b[0m | \u001b[95m0.2834 \u001b[0m |\n", - "| \u001b[95m68 \u001b[0m | \u001b[95m-0.3863 \u001b[0m | \u001b[95m1.092 \u001b[0m | \u001b[95m0.2312 \u001b[0m |\n", - "| \u001b[0m69 \u001b[0m | \u001b[0m-0.4349 \u001b[0m | \u001b[0m1.016 \u001b[0m | \u001b[0m0.3306 \u001b[0m |\n", - "| \u001b[0m70 \u001b[0m | \u001b[0m-0.9237 \u001b[0m | \u001b[0m-0.5129 \u001b[0m | \u001b[0m-0.5793 \u001b[0m |\n", - "| \u001b[0m71 \u001b[0m | \u001b[0m-0.6205 \u001b[0m | \u001b[0m0.9768 \u001b[0m | \u001b[0m0.1166 \u001b[0m |\n", - "| \u001b[0m72 \u001b[0m | \u001b[0m-0.4174 \u001b[0m | \u001b[0m1.091 \u001b[0m | \u001b[0m0.2892 \u001b[0m |\n", - "| \u001b[0m73 \u001b[0m | \u001b[0m-0.5181 \u001b[0m | \u001b[0m1.24 \u001b[0m | \u001b[0m0.1174 \u001b[0m |\n", - "| \u001b[0m74 \u001b[0m | \u001b[0m-0.395 \u001b[0m | \u001b[0m1.141 \u001b[0m | \u001b[0m0.2011 \u001b[0m |\n", - "| \u001b[0m75 \u001b[0m | \u001b[0m-0.3973 \u001b[0m | \u001b[0m0.8182 \u001b[0m | \u001b[0m0.472 \u001b[0m |\n", - "| \u001b[0m76 \u001b[0m | \u001b[0m-0.9614 \u001b[0m | \u001b[0m-0.3499 \u001b[0m | \u001b[0m-0.1895 \u001b[0m |\n", - "| \u001b[0m77 \u001b[0m | \u001b[0m-0.6383 \u001b[0m | \u001b[0m0.8683 \u001b[0m | \u001b[0m0.6587 \u001b[0m |\n", - "| \u001b[0m78 \u001b[0m | \u001b[0m-0.9611 \u001b[0m | \u001b[0m2.12 \u001b[0m | \u001b[0m-2.247 \u001b[0m |\n", - "| \u001b[0m79 \u001b[0m | \u001b[0m-0.6127 \u001b[0m | \u001b[0m0.6587 \u001b[0m | \u001b[0m0.3941 \u001b[0m |\n", - "| \u001b[0m80 \u001b[0m | \u001b[0m-0.3879 \u001b[0m | \u001b[0m0.8481 \u001b[0m | \u001b[0m0.3619 \u001b[0m |\n", - "| \u001b[0m81 \u001b[0m | \u001b[0m-0.462 \u001b[0m | \u001b[0m0.9029 \u001b[0m | \u001b[0m0.4355 \u001b[0m |\n", - "| \u001b[0m82 \u001b[0m | \u001b[0m-0.3881 \u001b[0m | \u001b[0m1.488 \u001b[0m | \u001b[0m0.3056 \u001b[0m |\n", - "| \u001b[0m83 \u001b[0m | \u001b[0m-0.7543 \u001b[0m | \u001b[0m1.675 \u001b[0m | \u001b[0m0.2273 \u001b[0m |\n", - "| \u001b[0m84 \u001b[0m | \u001b[0m-0.6216 \u001b[0m | \u001b[0m1.477 \u001b[0m | \u001b[0m0.5039 \u001b[0m |\n", - "| \u001b[0m85 \u001b[0m | \u001b[0m-0.3868 \u001b[0m | \u001b[0m1.381 \u001b[0m | \u001b[0m0.2708 \u001b[0m |\n", - "| \u001b[0m86 \u001b[0m | \u001b[0m-0.4399 \u001b[0m | \u001b[0m1.452 \u001b[0m | \u001b[0m0.2191 \u001b[0m |\n", - "| \u001b[0m87 \u001b[0m | \u001b[0m-0.9987 \u001b[0m | \u001b[0m0.5812 \u001b[0m | \u001b[0m-1.461 \u001b[0m |\n", - "| \u001b[0m88 \u001b[0m | \u001b[0m-0.4871 \u001b[0m | \u001b[0m1.407 \u001b[0m | \u001b[0m0.3738 \u001b[0m |\n", - "| \u001b[0m89 \u001b[0m | \u001b[0m-0.9935 \u001b[0m | \u001b[0m-2.049 \u001b[0m | \u001b[0m-3.0 \u001b[0m |\n", - "| \u001b[0m90 \u001b[0m | \u001b[0m-0.9527 \u001b[0m | \u001b[0m3.0 \u001b[0m | \u001b[0m3.0 \u001b[0m |\n", - "| \u001b[0m91 \u001b[0m | \u001b[0m-0.9933 \u001b[0m | \u001b[0m-2.97 \u001b[0m | \u001b[0m0.9588 \u001b[0m |\n", - "| \u001b[0m92 \u001b[0m | \u001b[0m-0.399 \u001b[0m | \u001b[0m0.908 \u001b[0m | \u001b[0m0.2844 \u001b[0m |\n", - "| \u001b[0m93 \u001b[0m | \u001b[0m-0.998 \u001b[0m | \u001b[0m-3.0 \u001b[0m | \u001b[0m3.0 \u001b[0m |\n", - "| \u001b[0m94 \u001b[0m | \u001b[0m-0.9761 \u001b[0m | \u001b[0m1.359 \u001b[0m | \u001b[0m2.982 \u001b[0m |\n", - "| \u001b[0m95 \u001b[0m | \u001b[0m-0.997 \u001b[0m | \u001b[0m-3.0 \u001b[0m | \u001b[0m-3.0 \u001b[0m |\n", - "| \u001b[0m96 \u001b[0m | \u001b[0m-0.9556 \u001b[0m | \u001b[0m-1.52 \u001b[0m | \u001b[0m1.704 \u001b[0m |\n", - "| \u001b[0m97 \u001b[0m | \u001b[0m-0.3995 \u001b[0m | \u001b[0m0.7049 \u001b[0m | \u001b[0m0.5839 \u001b[0m |\n", - "| \u001b[0m98 \u001b[0m | \u001b[0m-0.6577 \u001b[0m | \u001b[0m0.5701 \u001b[0m | \u001b[0m0.8002 \u001b[0m |\n", - "| \u001b[0m99 \u001b[0m | \u001b[0m-0.987 \u001b[0m | \u001b[0m-2.238 \u001b[0m | \u001b[0m-1.043 \u001b[0m |\n", - "| \u001b[0m100 \u001b[0m | \u001b[0m-0.9522 \u001b[0m | \u001b[0m0.7846 \u001b[0m | \u001b[0m1.908 \u001b[0m |\n", - "| \u001b[0m101 \u001b[0m | \u001b[0m-0.9913 \u001b[0m | \u001b[0m-1.13 \u001b[0m | \u001b[0m-2.999 \u001b[0m |\n", - "| \u001b[0m102 \u001b[0m | \u001b[0m-0.975 \u001b[0m | \u001b[0m0.5554 \u001b[0m | \u001b[0m-2.619 \u001b[0m |\n", - "| \u001b[0m103 \u001b[0m | \u001b[0m-0.9807 \u001b[0m | \u001b[0m-1.064 \u001b[0m | \u001b[0m0.4291 \u001b[0m |\n", - "=================================================\n" - ] - } - ], - "source": [ - "optimizer.maximize(n_iter=100, init_points=3)" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T22:23:17.823780Z", - "start_time": "2018-12-22T22:23:17.814070Z" - }, - "hidden": true, - "scrolled": true - }, - "outputs": [], - "source": [ - "best = optimizer.max" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": { - "ExecuteTime": { - "end_time": "2018-12-22T22:23:36.826169Z", - "start_time": "2018-12-22T22:23:36.174979Z" - }, - "hidden": true - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "def scale(z):\n", - " return (3.0 + z)*101.0/6.0\n", - "\n", - "best_x = best['params']['x']\n", - "best_y = best['params']['y']\n", - "_ = plt.imshow(data, origin='lower')\n", - "_ = plt.plot((scale(best_x), ), (scale(best_y), ), 'ro', label='best value')\n", - "_ = plt.xticks(np.linspace(0, 100, 7, dtype=np.int32), np.linspace(-3.0, 3.0, 7))\n", - "_ = plt.yticks(np.linspace(0, 100, 7, dtype=np.int32), np.linspace(-3.0, 3.0, 7))" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "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.8" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/source-code/parameter-optimization/parameterized_heat_equation_optimization.ipynb b/source-code/parameter-optimization/parameterized_heat_equation_optimization.ipynb new file mode 100644 index 0000000..a693ed4 --- /dev/null +++ b/source-code/parameter-optimization/parameterized_heat_equation_optimization.ipynb @@ -0,0 +1,1326 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "title", + "metadata": {}, + "source": [ + "# Methodologically sound hyperparameter optimization for a PINN\n", + "\n", + "This notebook uses the parameterized heat-equation PINN as a realistic case study in hyperparameter optimization. The emphasis is not on finding a spectacular architecture. It is on designing a comparison whose result can be interpreted.\n", + "\n", + "## Learning objectives\n", + "\n", + "After working through this notebook, you should be able to:\n", + "\n", + "- distinguish fitting, validation, confirmation, and final audit evidence;\n", + "- state an optimization objective and computational budget before starting a search;\n", + "- implement a transparent random-search baseline before using an optimization framework;\n", + "- explain why one noisy best trial is not yet a reliable model choice;\n", + "- compare configurations across common, fresh training seeds;\n", + "- report accuracy, variability, model size, and runtime without pretending they are interchangeable.\n", + "\n", + "The default experiment is intentionally small and normally takes roughly one to three minutes on a recent CPU. It needs PyTorch, NumPy, Matplotlib, and Optuna from the [course environment](../../environment.yml)." + ] + }, + { + "cell_type": "markdown", + "id": "goal", + "metadata": {}, + "source": [ + "## 1. Goal and experimental contract\n", + "\n", + "We vary three hyperparameters:\n", + "\n", + "- network width;\n", + "- number of hidden layers;\n", + "- Adam learning rate.\n", + "\n", + "The **declared selection metric** is the mean relative $L^2$ solution error over a fixed validation suite. The analytical solution is used only for evaluation, never for fitting. In a problem without an analytical solution, this role would need trustworthy observations or an independently verified numerical solution. Optimizing the training residual would be weaker: a small local residual does not guarantee a small solution error.\n", + "\n", + "Every search trial receives the same number of optimizer updates and collocation points. This controls the sample and update budget, but it is **not** an equal wall-clock or floating-point-operation budget: wider and deeper networks cost more. We therefore report parameter count and runtime alongside error rather than quietly treating them as equivalent.\n", + "\n", + "The workflow is fixed before any results are seen:\n", + "\n", + "1. Search with one common training seed and a fixed validation suite.\n", + "2. Re-evaluate a short list with several fresh, common seeds.\n", + "3. Select by mean confirmation validation error.\n", + "4. Consult the audit suite exactly once, after the choice is frozen.\n", + "\n", + "Using common seeds makes configuration comparisons less noisy. It does not eliminate stochasticity or prove that the winner is universally best." + ] + }, + { + "cell_type": "markdown", + "id": "setup", + "metadata": {}, + "source": [ + "## 2. Setup\n", + "\n", + "All choices that affect the experiment are collected here. Reducing epochs or trials is legitimate for a demonstration, but changing them after seeing results creates a different experiment. CPU is the default because this small, derivative-heavy workload does not automatically benefit from a GPU." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "imports", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:01:07.150779Z", + "iopub.status.busy": "2026-08-17T09:01:07.150644Z", + "iopub.status.idle": "2026-08-17T09:01:08.654544Z", + "shell.execute_reply": "2026-08-17T09:01:08.653544Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PyTorch 2.13.0; Optuna 4.9.0\n" + ] + } + ], + "source": [ + "import math\n", + "import statistics\n", + "import time\n", + "from dataclasses import dataclass\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import optuna\n", + "import torch\n", + "from torch import nn\n", + "\n", + "optuna.logging.set_verbosity(optuna.logging.WARNING)\n", + "print(f\"PyTorch {torch.__version__}; Optuna {optuna.__version__}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "configuration", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:01:08.656173Z", + "iopub.status.busy": "2026-08-17T09:01:08.655965Z", + "iopub.status.idle": "2026-08-17T09:01:08.666420Z", + "shell.execute_reply": "2026-08-17T09:01:08.665504Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Using device: cpu\n" + ] + } + ], + "source": [ + "@dataclass(frozen=True)\n", + "class ProblemConfig:\n", + " x_min: float = 0.0\n", + " x_max: float = 1.0\n", + " t_min: float = 0.0\n", + " t_max: float = 1.0\n", + " coefficient_min: float = -1.0\n", + " coefficient_max: float = 1.0\n", + " kappa_min: float = 0.05\n", + " kappa_max: float = 0.20\n", + "\n", + " def input_bounds(self):\n", + " lower = torch.tensor([\n", + " self.x_min, self.t_min, self.coefficient_min,\n", + " self.coefficient_min, self.kappa_min,\n", + " ])\n", + " upper = torch.tensor([\n", + " self.x_max, self.t_max, self.coefficient_max,\n", + " self.coefficient_max, self.kappa_max,\n", + " ])\n", + " return lower, upper\n", + "\n", + "\n", + "@dataclass(frozen=True)\n", + "class ExperimentConfig:\n", + " width_options: tuple[int, ...] = (8, 16, 32, 64)\n", + " hidden_layers_min: int = 1\n", + " hidden_layers_max: int = 4\n", + " learning_rate_min: float = 3.0e-4\n", + " learning_rate_max: float = 4.0e-3\n", + " trials_per_method: int = 8\n", + " search_epochs: int = 400\n", + " confirmation_epochs: int = 1_200\n", + " collocation_batch_size: int = 256\n", + " validation_case_count: int = 10\n", + " audit_case_count: int = 10\n", + " evaluation_n_x: int = 41\n", + " evaluation_n_t: int = 21\n", + " common_search_seed: int = 20_260_817\n", + " random_search_seed: int = 31_415\n", + " optuna_sampler_seed: int = 27_182\n", + " validation_case_seed: int = 16_180\n", + " audit_case_seed: int = 14_142\n", + " confirmation_seeds: tuple[int, ...] = (10_007, 10_009, 10_037)\n", + " use_cuda: bool = False\n", + "\n", + "\n", + "@dataclass(frozen=True)\n", + "class ModelConfig:\n", + " width: int\n", + " hidden_layers: int\n", + " learning_rate: float\n", + "\n", + "\n", + "problem = ProblemConfig()\n", + "experiment = ExperimentConfig()\n", + "using_cuda = experiment.use_cuda and torch.cuda.is_available()\n", + "device = torch.device(\"cuda\" if using_cuda else \"cpu\")\n", + "print(f\"Using device: {device}\")" + ] + }, + { + "cell_type": "markdown", + "id": "problem", + "metadata": {}, + "source": [ + "## 3. Define the problem and model family\n", + "\n", + "We solve\n", + "\n", + "$$\n", + "\\frac{\\partial u}{\\partial t}=\\kappa\\frac{\\partial^2 u}{\\partial x^2},\n", + "\\qquad\n", + "u(x,0)=a_1\\sin(\\pi x)+a_2\\sin(2\\pi x),\n", + "$$\n", + "\n", + "with $u(0,t)=u(1,t)=0$. The network input is $(x,t,a_1,a_2,\\kappa)$. A hard-constrained trial solution satisfies the initial and boundary conditions for every network configuration, so architecture comparisons are not confounded by different loss-term weights.\n", + "\n", + "This duplicates a small amount of code from the [parameterized heat-equation PINN notebook](../pinns/parameterized_heat_equation.ipynb) so the experiment is self-contained and reproducible from top to bottom." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "model", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:01:08.667948Z", + "iopub.status.busy": "2026-08-17T09:01:08.667810Z", + "iopub.status.idle": "2026-08-17T09:01:08.672846Z", + "shell.execute_reply": "2026-08-17T09:01:08.672129Z" + } + }, + "outputs": [], + "source": [ + "def initial_profile(x, a1, a2, *, x_min, x_max):\n", + " scaled_x = (x - x_min) / (x_max - x_min)\n", + " return (\n", + " a1 * torch.sin(math.pi * scaled_x)\n", + " + a2 * torch.sin(2.0 * math.pi * scaled_x)\n", + " )\n", + "\n", + "\n", + "def exact_solution(inputs, problem):\n", + " # Evaluation reference only: never called by the fitting loop.\n", + " x, t, a1, a2, kappa = inputs.unbind(dim=1)\n", + " length = problem.x_max - problem.x_min\n", + " elapsed_time = t - problem.t_min\n", + " first_rate = (math.pi / length) ** 2\n", + " second_rate = (2.0 * math.pi / length) ** 2\n", + " profile_1 = initial_profile(\n", + " x, a1, torch.zeros_like(a2),\n", + " x_min=problem.x_min, x_max=problem.x_max,\n", + " )\n", + " profile_2 = initial_profile(\n", + " x, torch.zeros_like(a1), a2,\n", + " x_min=problem.x_min, x_max=problem.x_max,\n", + " )\n", + " return (\n", + " torch.exp(-kappa * first_rate * elapsed_time) * profile_1\n", + " + torch.exp(-kappa * second_rate * elapsed_time) * profile_2\n", + " )\n", + "\n", + "\n", + "class ParametricHeatPINN(nn.Module):\n", + " def __init__(self, problem, *, width, hidden_layers):\n", + " super().__init__()\n", + " layers = [nn.Linear(5, width), nn.Tanh()]\n", + " for _ in range(hidden_layers - 1):\n", + " layers.extend([nn.Linear(width, width), nn.Tanh()])\n", + " layers.append(nn.Linear(width, 1))\n", + " self.network = nn.Sequential(*layers)\n", + "\n", + " input_lower, input_upper = problem.input_bounds()\n", + " self.register_buffer(\"input_lower\", input_lower)\n", + " self.register_buffer(\"input_upper\", input_upper)\n", + "\n", + " def forward(self, inputs):\n", + " x, t, a1, a2, _ = inputs.unbind(dim=1)\n", + " scaled_inputs = 2.0 * (\n", + " (inputs - self.input_lower)\n", + " / (self.input_upper - self.input_lower)\n", + " ) - 1.0\n", + " starting_profile = initial_profile(\n", + " x, a1, a2,\n", + " x_min=self.input_lower[0],\n", + " x_max=self.input_upper[0],\n", + " )\n", + " correction = self.network(scaled_inputs).squeeze(dim=1)\n", + " constraint_factor = (\n", + " (t - self.input_lower[1])\n", + " * (x - self.input_lower[0])\n", + " * (self.input_upper[0] - x)\n", + " )\n", + " return starting_profile + constraint_factor * correction" + ] + }, + { + "cell_type": "markdown", + "id": "fit-functions", + "metadata": {}, + "source": [ + "## 4. Separate fitting from evaluation\n", + "\n", + "The fitting loop sees only newly sampled collocation points and the differential equation. It never sees validation or audit solution values. An explicit random-number generator makes the collocation stream independent of how many random numbers a particular architecture consumes during weight initialization." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "fit-helpers", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:01:08.674333Z", + "iopub.status.busy": "2026-08-17T09:01:08.674207Z", + "iopub.status.idle": "2026-08-17T09:01:08.678654Z", + "shell.execute_reply": "2026-08-17T09:01:08.677782Z" + } + }, + "outputs": [], + "source": [ + "def seed_model_initialization(seed):\n", + " torch.manual_seed(seed)\n", + " if torch.cuda.is_available():\n", + " torch.cuda.manual_seed_all(seed)\n", + "\n", + "\n", + "def random_parameters(n, problem, device, *, generator):\n", + " coefficient_width = problem.coefficient_max - problem.coefficient_min\n", + " a1 = problem.coefficient_min + coefficient_width * torch.rand(\n", + " n, device=device, generator=generator\n", + " )\n", + " a2 = problem.coefficient_min + coefficient_width * torch.rand(\n", + " n, device=device, generator=generator\n", + " )\n", + " kappa = problem.kappa_min + (\n", + " problem.kappa_max - problem.kappa_min\n", + " ) * torch.rand(n, device=device, generator=generator)\n", + " return a1, a2, kappa\n", + "\n", + "\n", + "def sample_collocation_points(n, problem, device, *, generator):\n", + " x = problem.x_min + (problem.x_max - problem.x_min) * torch.rand(\n", + " n, device=device, generator=generator\n", + " )\n", + " t = problem.t_min + (problem.t_max - problem.t_min) * torch.rand(\n", + " n, device=device, generator=generator\n", + " )\n", + " a1, a2, kappa = random_parameters(\n", + " n, problem, device, generator=generator\n", + " )\n", + " return torch.column_stack([x, t, a1, a2, kappa]).requires_grad_(True)\n", + "\n", + "\n", + "def physics_residual(model, inputs):\n", + " u = model(inputs)\n", + " first_derivatives = torch.autograd.grad(\n", + " u, inputs, grad_outputs=torch.ones_like(u), create_graph=True\n", + " )[0]\n", + " du_dx = first_derivatives[:, 0]\n", + " du_dt = first_derivatives[:, 1]\n", + " d2u_dx2 = torch.autograd.grad(\n", + " du_dx, inputs, grad_outputs=torch.ones_like(du_dx), create_graph=True\n", + " )[0][:, 0]\n", + " return du_dt - inputs[:, 4] * d2u_dx2" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "evaluation-helpers", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:01:08.680079Z", + "iopub.status.busy": "2026-08-17T09:01:08.679956Z", + "iopub.status.idle": "2026-08-17T09:01:08.684646Z", + "shell.execute_reply": "2026-08-17T09:01:08.683881Z" + } + }, + "outputs": [], + "source": [ + "def make_parameter_cases(seed, n_cases, problem, *, min_coefficient_norm=0.35):\n", + " rng = np.random.default_rng(seed)\n", + " cases = []\n", + " while len(cases) < n_cases:\n", + " a1 = rng.uniform(problem.coefficient_min, problem.coefficient_max)\n", + " a2 = rng.uniform(problem.coefficient_min, problem.coefficient_max)\n", + " if math.hypot(a1, a2) < min_coefficient_norm:\n", + " continue\n", + " kappa = rng.uniform(problem.kappa_min, problem.kappa_max)\n", + " cases.append((float(a1), float(a2), float(kappa)))\n", + " return tuple(cases)\n", + "\n", + "\n", + "def make_evaluation_inputs(case, problem, device, *, n_x, n_t):\n", + " a1, a2, kappa = case\n", + " x = torch.linspace(problem.x_min, problem.x_max, n_x, device=device)\n", + " t = torch.linspace(problem.t_min, problem.t_max, n_t, device=device)\n", + " tt, xx = torch.meshgrid(t, x, indexing=\"ij\")\n", + " return torch.column_stack([\n", + " xx.ravel(), tt.ravel(),\n", + " torch.full_like(xx.ravel(), a1),\n", + " torch.full_like(xx.ravel(), a2),\n", + " torch.full_like(xx.ravel(), kappa),\n", + " ])\n", + "\n", + "\n", + "def score_cases(model, cases, problem, experiment, device):\n", + " relative_errors = []\n", + " model.eval()\n", + " with torch.inference_mode():\n", + " for case in cases:\n", + " inputs = make_evaluation_inputs(\n", + " case, problem, device,\n", + " n_x=experiment.evaluation_n_x,\n", + " n_t=experiment.evaluation_n_t,\n", + " )\n", + " prediction = model(inputs)\n", + " reference = exact_solution(inputs, problem)\n", + " relative_error = (\n", + " torch.linalg.vector_norm(prediction - reference)\n", + " / torch.linalg.vector_norm(reference)\n", + " )\n", + " relative_errors.append(relative_error.item())\n", + " return {\n", + " \"mean\": statistics.fmean(relative_errors),\n", + " \"standard_deviation\": statistics.stdev(relative_errors),\n", + " \"maximum\": max(relative_errors),\n", + " \"per_case\": tuple(relative_errors),\n", + " }" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "run-configuration", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:01:08.686042Z", + "iopub.status.busy": "2026-08-17T09:01:08.685923Z", + "iopub.status.idle": "2026-08-17T09:01:08.690491Z", + "shell.execute_reply": "2026-08-17T09:01:08.689619Z" + } + }, + "outputs": [], + "source": [ + "def run_configuration(\n", + " model_config, *, training_seed, epochs, problem, experiment,\n", + " validation_cases, device,\n", + "):\n", + " seed_model_initialization(training_seed)\n", + " model = ParametricHeatPINN(\n", + " problem,\n", + " width=model_config.width,\n", + " hidden_layers=model_config.hidden_layers,\n", + " ).to(device)\n", + " collocation_generator = torch.Generator(device=device)\n", + " collocation_generator.manual_seed(training_seed + 1)\n", + " optimizer = torch.optim.Adam(\n", + " model.parameters(), lr=model_config.learning_rate\n", + " )\n", + "\n", + " if device.type == \"cuda\":\n", + " torch.cuda.synchronize()\n", + " start_time = time.perf_counter()\n", + " final_physics_loss = math.nan\n", + " model.train()\n", + " for _ in range(epochs):\n", + " inputs = sample_collocation_points(\n", + " experiment.collocation_batch_size, problem, device,\n", + " generator=collocation_generator,\n", + " )\n", + " optimizer.zero_grad(set_to_none=True)\n", + " residual = physics_residual(model, inputs)\n", + " loss = residual.square().mean()\n", + " loss.backward()\n", + " optimizer.step()\n", + " final_physics_loss = loss.item()\n", + "\n", + " if device.type == \"cuda\":\n", + " torch.cuda.synchronize()\n", + " elapsed_seconds = time.perf_counter() - start_time\n", + " validation = score_cases(\n", + " model, validation_cases, problem, experiment, device\n", + " )\n", + " parameter_count = sum(parameter.numel() for parameter in model.parameters())\n", + " return {\n", + " \"model\": model,\n", + " \"validation\": validation,\n", + " \"parameter_count\": parameter_count,\n", + " \"elapsed_seconds\": elapsed_seconds,\n", + " \"final_physics_loss\": final_physics_loss,\n", + " }\n", + "\n", + "\n", + "def config_label(config):\n", + " return (\n", + " f\"width={config.width}, layers={config.hidden_layers}, \"\n", + " f\"lr={config.learning_rate:.2e}\"\n", + " )\n", + "\n", + "\n", + "def config_key(config):\n", + " return (config.width, config.hidden_layers, config.learning_rate)" + ] + }, + { + "cell_type": "markdown", + "id": "validation-suite", + "metadata": {}, + "source": [ + "## 5. Fix the validation suite\n", + "\n", + "The validation cases are fixed before searching. Cases with an almost-zero initial condition are excluded because relative error becomes unstable when the reference norm is nearly zero. This is a metric-domain decision, not a removal of inconvenient model failures.\n", + "\n", + "These cases are independent evaluation points inside the parameter domain. Calling them wholly 'unseen' would be misleading: fitting continuously samples the same domain and may encounter nearby points, although it never receives their exact solution values.\n", + "\n", + "Only the audit seed is declared at this stage. The audit cases themselves are not generated or evaluated until model selection is complete." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "make-validation-suite", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:01:08.692340Z", + "iopub.status.busy": "2026-08-17T09:01:08.692164Z", + "iopub.status.idle": "2026-08-17T09:01:08.702384Z", + "shell.execute_reply": "2026-08-17T09:01:08.701469Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fixed validation suite ranges:\n", + " a1 : -0.811 to 0.836\n", + " a2 : -0.935 to 0.703\n", + " kappa: 0.051 to 0.179\n" + ] + } + ], + "source": [ + "validation_cases = make_parameter_cases(\n", + " experiment.validation_case_seed,\n", + " experiment.validation_case_count,\n", + " problem,\n", + ")\n", + "validation_array = np.asarray(validation_cases)\n", + "print(\"Fixed validation suite ranges:\")\n", + "for name, values in zip((\"a1\", \"a2\", \"kappa\"), validation_array.T):\n", + " print(f\" {name:5s}: {values.min(): .3f} to {values.max(): .3f}\")" + ] + }, + { + "cell_type": "markdown", + "id": "random-search", + "metadata": {}, + "source": [ + "## 6. Establish a transparent random-search baseline\n", + "\n", + "Random search makes the mechanics visible: sample a configuration, fit it under the declared budget, evaluate it on validation cases, and retain the record. It is also a meaningful baseline for judging whether a more elaborate search strategy helped.\n", + "\n", + "All candidates use the same fitting seed during this exploratory search. That is a deliberate variance-reduction device, not evidence that one seed is sufficient for the final comparison." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "random-search-code", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:01:08.703902Z", + "iopub.status.busy": "2026-08-17T09:01:08.703704Z", + "iopub.status.idle": "2026-08-17T09:01:19.820809Z", + "shell.execute_reply": "2026-08-17T09:01:19.819568Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 0 width=8, layers=1, lr=1.09e-03 val=1.121e+00 time=1.35s\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 1 width=64, layers=4, lr=2.80e-03 val=9.910e-02 time=1.73s\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 2 width=64, layers=4, lr=5.15e-04 val=1.908e-01 time=1.74s\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 3 width=32, layers=1, lr=1.86e-03 val=5.049e-01 time=1.02s\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 4 width=8, layers=1, lr=2.52e-03 val=7.258e-01 time=1.17s\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 5 width=64, layers=2, lr=3.02e-04 val=8.843e-01 time=1.26s\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 6 width=64, layers=1, lr=3.65e-04 val=1.129e+00 time=0.99s\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 7 width=32, layers=1, lr=1.18e-03 val=8.864e-01 time=0.90s\n" + ] + } + ], + "source": [ + "def sample_model_config(rng, experiment):\n", + " log_learning_rate = rng.uniform(\n", + " math.log(experiment.learning_rate_min),\n", + " math.log(experiment.learning_rate_max),\n", + " )\n", + " return ModelConfig(\n", + " width=int(rng.choice(experiment.width_options)),\n", + " hidden_layers=int(rng.integers(\n", + " experiment.hidden_layers_min,\n", + " experiment.hidden_layers_max + 1,\n", + " )),\n", + " learning_rate=float(math.exp(log_learning_rate)),\n", + " )\n", + "\n", + "\n", + "random_generator = np.random.default_rng(experiment.random_search_seed)\n", + "random_records = []\n", + "for trial_number in range(experiment.trials_per_method):\n", + " model_config = sample_model_config(random_generator, experiment)\n", + " result = run_configuration(\n", + " model_config,\n", + " training_seed=experiment.common_search_seed,\n", + " epochs=experiment.search_epochs,\n", + " problem=problem,\n", + " experiment=experiment,\n", + " validation_cases=validation_cases,\n", + " device=device,\n", + " )\n", + " record = {\n", + " \"method\": \"random\",\n", + " \"trial\": trial_number,\n", + " \"config\": model_config,\n", + " \"validation_mean\": result[\"validation\"][\"mean\"],\n", + " \"validation_standard_deviation\": result[\"validation\"][\"standard_deviation\"],\n", + " \"validation_maximum\": result[\"validation\"][\"maximum\"],\n", + " \"parameter_count\": result[\"parameter_count\"],\n", + " \"elapsed_seconds\": result[\"elapsed_seconds\"],\n", + " \"final_physics_loss\": result[\"final_physics_loss\"],\n", + " }\n", + " random_records.append(record)\n", + " print(\n", + " f\"{trial_number:2d} {config_label(model_config):42s} \"\n", + " f\"val={record['validation_mean']:.3e} \"\n", + " f\"time={record['elapsed_seconds']:.2f}s\"\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "inspect-random", + "metadata": {}, + "source": [ + "### Check what the objective hides\n", + "\n", + "The scalar objective is required by the search algorithm, but it is not the whole result. Compare mean and worst-case validation error, last-batch physics loss, parameter count, and runtime. A configuration can look attractive under one criterion and poor under another." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "random-search-plot", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:01:19.823446Z", + "iopub.status.busy": "2026-08-17T09:01:19.822994Z", + "iopub.status.idle": "2026-08-17T09:01:20.213508Z", + "shell.execute_reply": "2026-08-17T09:01:20.212732Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "trial mean error worst case last-batch loss parameters time\n", + " 1 9.910e-02 1.685e-01 3.586e-02 12929 1.73s\n", + " 2 1.908e-01 5.964e-01 4.440e-01 12929 1.74s\n", + " 3 5.049e-01 1.482e+00 1.228e+00 225 1.02s\n", + " 4 7.258e-01 2.014e+00 1.961e+00 57 1.17s\n", + " 5 8.843e-01 2.297e+00 2.960e+00 4609 1.26s\n", + " 7 8.864e-01 2.298e+00 2.971e+00 225 0.90s\n", + " 0 1.121e+00 2.790e+00 4.225e+00 57 1.35s\n", + " 6 1.129e+00 2.763e+00 4.468e+00 449 0.99s\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, axes = plt.subplots(1, 2, figsize=(11, 4))\n", + "axes[0].scatter(\n", + " [record[\"parameter_count\"] for record in random_records],\n", + " [record[\"validation_mean\"] for record in random_records],\n", + ")\n", + "axes[0].set(\n", + " xscale=\"log\", yscale=\"log\", xlabel=\"trainable parameters\",\n", + " ylabel=r\"mean validation relative $L^2$ error\",\n", + " title=\"Accuracy versus model size\",\n", + ")\n", + "axes[1].scatter(\n", + " [record[\"elapsed_seconds\"] for record in random_records],\n", + " [record[\"validation_mean\"] for record in random_records],\n", + ")\n", + "axes[1].set(\n", + " yscale=\"log\", xlabel=\"training time (s)\",\n", + " ylabel=r\"mean validation relative $L^2$ error\",\n", + " title=\"Accuracy versus measured cost\",\n", + ")\n", + "fig.tight_layout()\n", + "\n", + "print(\"trial mean error worst case last-batch loss parameters time\")\n", + "for record in sorted(random_records, key=lambda item: item[\"validation_mean\"]):\n", + " print(\n", + " f\"{record['trial']:5d} {record['validation_mean']:.3e} \"\n", + " f\"{record['validation_maximum']:.3e} \"\n", + " f\"{record['final_physics_loss']:.3e} \"\n", + " f\"{record['parameter_count']:7d} \"\n", + " f\"{record['elapsed_seconds']:5.2f}s\"\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "optuna", + "metadata": {}, + "source": [ + "## 7. Replace candidate generation with Optuna\n", + "\n", + "Only candidate generation changes. The model, fitting budget, training seed, validation suite, and objective remain identical. This isolation is important: changing the search method and the experiment at the same time would make the comparison uninterpretable.\n", + "\n", + "The TPE sampler begins with four startup trials before using its observations to guide later proposals. Eight trials are enough to illustrate the workflow, not enough to establish that TPE is generally superior to random search.\n", + "\n", + "Pruning is deliberately disabled. Every candidate receives the declared budget, so an architecture that learns slowly is not silently compared with another architecture that trained longer. Pruning can save computation, but it introduces an additional policy that must itself be justified and validated." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "optuna-objective", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:01:20.215222Z", + "iopub.status.busy": "2026-08-17T09:01:20.215077Z", + "iopub.status.idle": "2026-08-17T09:01:20.219010Z", + "shell.execute_reply": "2026-08-17T09:01:20.218019Z" + } + }, + "outputs": [], + "source": [ + "def optuna_objective(\n", + " trial, *, problem, experiment, validation_cases, device\n", + "):\n", + " model_config = ModelConfig(\n", + " width=trial.suggest_categorical(\n", + " \"width\", list(experiment.width_options)\n", + " ),\n", + " hidden_layers=trial.suggest_int(\n", + " \"hidden_layers\",\n", + " experiment.hidden_layers_min,\n", + " experiment.hidden_layers_max,\n", + " ),\n", + " learning_rate=trial.suggest_float(\n", + " \"learning_rate\",\n", + " experiment.learning_rate_min,\n", + " experiment.learning_rate_max,\n", + " log=True,\n", + " ),\n", + " )\n", + " result = run_configuration(\n", + " model_config,\n", + " training_seed=experiment.common_search_seed,\n", + " epochs=experiment.search_epochs,\n", + " problem=problem,\n", + " experiment=experiment,\n", + " validation_cases=validation_cases,\n", + " device=device,\n", + " )\n", + " trial.set_user_attr(\"validation_standard_deviation\", result[\"validation\"][\"standard_deviation\"])\n", + " trial.set_user_attr(\"validation_maximum\", result[\"validation\"][\"maximum\"])\n", + " trial.set_user_attr(\"parameter_count\", result[\"parameter_count\"])\n", + " trial.set_user_attr(\"elapsed_seconds\", result[\"elapsed_seconds\"])\n", + " trial.set_user_attr(\"final_physics_loss\", result[\"final_physics_loss\"])\n", + " return result[\"validation\"][\"mean\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "run-optuna", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:01:20.221010Z", + "iopub.status.busy": "2026-08-17T09:01:20.220867Z", + "iopub.status.idle": "2026-08-17T09:01:29.974602Z", + "shell.execute_reply": "2026-08-17T09:01:29.973638Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 0 width=32, layers=3, lr=1.43e-03 val=1.534e-01 time=1.21s\n", + " 1 width=8, layers=4, lr=1.10e-03 val=4.756e-01 time=1.27s\n", + " 2 width=64, layers=3, lr=1.43e-03 val=1.100e-01 time=1.41s\n", + " 3 width=16, layers=4, lr=6.66e-04 val=4.021e-01 time=1.37s\n", + " 4 width=64, layers=1, lr=3.29e-03 val=2.453e-01 time=1.01s\n", + " 5 width=64, layers=1, lr=3.50e-04 val=1.133e+00 time=1.05s\n", + " 6 width=64, layers=2, lr=3.56e-03 val=9.329e-02 time=1.27s\n", + " 7 width=32, layers=2, lr=3.96e-03 val=1.225e-01 time=1.10s\n" + ] + } + ], + "source": [ + "sampler = optuna.samplers.TPESampler(\n", + " seed=experiment.optuna_sampler_seed, n_startup_trials=4\n", + ")\n", + "study = optuna.create_study(direction=\"minimize\", sampler=sampler)\n", + "study.optimize(\n", + " lambda trial: optuna_objective(\n", + " trial,\n", + " problem=problem,\n", + " experiment=experiment,\n", + " validation_cases=validation_cases,\n", + " device=device,\n", + " ),\n", + " n_trials=experiment.trials_per_method,\n", + ")\n", + "\n", + "optuna_records = []\n", + "for trial in study.trials:\n", + " model_config = ModelConfig(**trial.params)\n", + " record = {\n", + " \"method\": \"TPE\",\n", + " \"trial\": trial.number,\n", + " \"config\": model_config,\n", + " \"validation_mean\": trial.value,\n", + " **trial.user_attrs,\n", + " }\n", + " optuna_records.append(record)\n", + " print(\n", + " f\"{trial.number:2d} {config_label(model_config):42s} \"\n", + " f\"val={trial.value:.3e} \"\n", + " f\"time={record['elapsed_seconds']:.2f}s\"\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "compare-searches", + "metadata": {}, + "source": [ + "## 8. Compare searches under the same trial budget\n", + "\n", + "The best-so-far curve answers a narrow question: how quickly did each run find a low validation score under this particular search seed and budget? It does not establish an ordering of search algorithms. That would require repeated searches, not merely repeated model training." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "compare-searches-plot", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:01:29.976472Z", + "iopub.status.busy": "2026-08-17T09:01:29.976322Z", + "iopub.status.idle": "2026-08-17T09:01:30.145573Z", + "shell.execute_reply": "2026-08-17T09:01:30.144700Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "random: width=64, layers=4, lr=2.80e-03; validation=9.910e-02\n", + "TPE : width=64, layers=2, lr=3.56e-03; validation=9.329e-02\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def best_so_far(records):\n", + " values = np.asarray([record[\"validation_mean\"] for record in records])\n", + " return np.minimum.accumulate(values)\n", + "\n", + "\n", + "fig, ax = plt.subplots(figsize=(7, 4))\n", + "trial_numbers = np.arange(1, experiment.trials_per_method + 1)\n", + "ax.plot(trial_numbers, best_so_far(random_records), marker=\"o\", label=\"random\")\n", + "ax.plot(trial_numbers, best_so_far(optuna_records), marker=\"o\", label=\"Optuna TPE\")\n", + "ax.set(\n", + " yscale=\"log\", xlabel=\"completed trials\",\n", + " ylabel=r\"best mean validation relative $L^2$ error\",\n", + " title=\"Best score found under an equal trial budget\",\n", + ")\n", + "ax.legend()\n", + "fig.tight_layout()\n", + "\n", + "for method, records in ((\"random\", random_records), (\"TPE\", optuna_records)):\n", + " best_record = min(records, key=lambda record: record[\"validation_mean\"])\n", + " print(\n", + " f\"{method:6s}: {config_label(best_record['config'])}; \"\n", + " f\"validation={best_record['validation_mean']:.3e}\"\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "confirmation", + "metadata": {}, + "source": [ + "## 9. Confirm a shortlist across fresh seeds\n", + "\n", + "Selecting the single best exploratory trial would reward luck. We take the three best distinct configurations across both searches and train each from scratch with the same three fresh seeds and a larger epoch budget. Sharing confirmation seeds creates paired comparisons: every configuration faces the same sources of training randomness.\n", + "\n", + "The larger epoch budget is declared for every shortlisted configuration. Applying it only to the apparent winner would confound configuration with training effort." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "make-shortlist", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:01:30.147803Z", + "iopub.status.busy": "2026-08-17T09:01:30.147650Z", + "iopub.status.idle": "2026-08-17T09:01:30.152173Z", + "shell.execute_reply": "2026-08-17T09:01:30.151212Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Shortlist chosen without audit evidence:\n", + " C1: width=64, layers=2, lr=3.56e-03\n", + " C2: width=64, layers=4, lr=2.80e-03\n", + " C3: width=64, layers=3, lr=1.43e-03\n" + ] + } + ], + "source": [ + "all_search_records = sorted(\n", + " random_records + optuna_records,\n", + " key=lambda record: record[\"validation_mean\"],\n", + ")\n", + "shortlist = []\n", + "seen_configurations = set()\n", + "for record in all_search_records:\n", + " key = config_key(record[\"config\"])\n", + " if key in seen_configurations:\n", + " continue\n", + " seen_configurations.add(key)\n", + " shortlist.append(record[\"config\"])\n", + " if len(shortlist) == 3:\n", + " break\n", + "\n", + "print(\"Shortlist chosen without audit evidence:\")\n", + "for index, model_config in enumerate(shortlist, start=1):\n", + " print(f\" C{index}: {config_label(model_config)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "run-confirmation", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:01:30.153588Z", + "iopub.status.busy": "2026-08-17T09:01:30.153456Z", + "iopub.status.idle": "2026-08-17T09:02:10.845425Z", + "shell.execute_reply": "2026-08-17T09:02:10.844125Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "candidate mean validation ± seed SD parameters mean time\n", + "C1 6.144e-02 ± 1.87e-02 4609 3.88s\n", + "C2 5.619e-02 ± 3.31e-03 12929 5.15s\n", + "C3 6.376e-02 ± 8.62e-03 8769 4.51s\n" + ] + } + ], + "source": [ + "confirmation_records = []\n", + "confirmation_runs = {}\n", + "for candidate_number, model_config in enumerate(shortlist, start=1):\n", + " runs = []\n", + " for training_seed in experiment.confirmation_seeds:\n", + " result = run_configuration(\n", + " model_config,\n", + " training_seed=training_seed,\n", + " epochs=experiment.confirmation_epochs,\n", + " problem=problem,\n", + " experiment=experiment,\n", + " validation_cases=validation_cases,\n", + " device=device,\n", + " )\n", + " run_record = {\n", + " \"candidate\": candidate_number,\n", + " \"config\": model_config,\n", + " \"training_seed\": training_seed,\n", + " \"validation_mean\": result[\"validation\"][\"mean\"],\n", + " \"elapsed_seconds\": result[\"elapsed_seconds\"],\n", + " \"parameter_count\": result[\"parameter_count\"],\n", + " \"model\": result[\"model\"],\n", + " }\n", + " runs.append(run_record)\n", + " confirmation_records.append(run_record)\n", + " confirmation_runs[config_key(model_config)] = runs\n", + "\n", + "confirmation_summary = []\n", + "for candidate_number, model_config in enumerate(shortlist, start=1):\n", + " runs = confirmation_runs[config_key(model_config)]\n", + " scores = [run[\"validation_mean\"] for run in runs]\n", + " summary = {\n", + " \"candidate\": candidate_number,\n", + " \"config\": model_config,\n", + " \"mean\": statistics.fmean(scores),\n", + " \"standard_deviation\": statistics.stdev(scores),\n", + " \"minimum\": min(scores),\n", + " \"maximum\": max(scores),\n", + " \"parameter_count\": runs[0][\"parameter_count\"],\n", + " \"mean_time\": statistics.fmean(\n", + " run[\"elapsed_seconds\"] for run in runs\n", + " ),\n", + " }\n", + " confirmation_summary.append(summary)\n", + "\n", + "print(\"candidate mean validation ± seed SD parameters mean time\")\n", + "for summary in confirmation_summary:\n", + " print(\n", + " f\"C{summary['candidate']:<8d}\"\n", + " f\"{summary['mean']:.3e} ± {summary['standard_deviation']:.2e}\"\n", + " f\" {summary['parameter_count']:7d}\"\n", + " f\" {summary['mean_time']:6.2f}s\"\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "confirmation-plot", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:02:10.847272Z", + "iopub.status.busy": "2026-08-17T09:02:10.847097Z", + "iopub.status.idle": "2026-08-17T09:02:11.023266Z", + "shell.execute_reply": "2026-08-17T09:02:11.022060Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "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4XO3a9fO9vLLL5vH279/v+2RRx6xZc2a1bZ27Vq396uz98Sd15ja++3q67+VlD5rqb2nGzZsMM+t/wv6Wb9w4YLtxx9/tOXJkyfRYzij61N6P/r3728e9/HHH7fNnTvXdvbsWdunn36abLu4uDizz55//nlbaGiobd26dY51w4cPN+129rhPP/207aeffjLv1+LFi225cuWy9ejRI9G2Vu8/a9YsW1BQkG3gwIG2o0eP2g4fPmx75plnbA899JB5XP1MpaZixYrmM6SfndjYWNu///5rGzlyZKLPkKv739XtdF9rm7Wd2uZDhw6Zz5GzNrvSPt1e76fH11ux79tOnTo59u2KFStsJUqUsFWvXt127do1p/dL7TOQ2ufIlfZ7+r648zlZsGCB+T/o2rWr2V96HNDjju43/c5QV65csYWHh9teeeWVRP/3ERERZrvdu3c7lpcuXdocU1zZ1/q+LFq0yLTviy++MI81c+ZM8x32yy+/mOVfffWV+UxMmTIl0WN48r/vynvlyj5zlX7v6mfXXXreoMd6bcetvPvuu2a/6XHSmfj4ePMaKleu7HY7/BGBBdKcHhz1n3LhwoUubb9582azfcIDrNKDsR54EwYBenKm/9B6wpTwwFa8eHFzkmglsNADugYOCdlPwPRAm9BHH31klnfs2DHR8qlTp5rlO3fuvOXrHjFihC1nzpweBxajR482y/744w+ngZ39ceyv4cEHH0y03V9//WWWT58+PdV22u/fqFGjZOs8CSxcaYcGefpF7y32527SpEmi5Xpio5+Hxo0bu71fUwssXHmNqb3f3n79ST9rqb2n9erVM0GVnmAlNGHCBHOypCfTngYW+pzOgomUaIDXt2/fWwYGuuzrr79OtPy5556zZcmSJdHrsHr/22+/3VajRo1k7axateotAwsNDnUbPUakxtX97+p2etJcrVq1ZCdGlSpVStRmV9vnDvu+/fzzzxMt1+8GXf7ZZ5+5/RlI6XPkaftdvZ87nxPdtxUqVHBchEh4cqvfX5cvXzZ/6/Ho7rvvdqzXCxB9+vSx5cuXz3zHKA0w9Hk/+eQTl9r37bffJlpev359c3KvwURCenypVauW1/73U3uvXNlnzti/X1y56YXA1Bw4cMDsa91WA9tHH33UBBB6IdHdwELdcccd5oINbDaGQsHn/Prrr+Znhw4dEi3Xbtx77rlHli1blmi5LtMuVTstJatDRvbt22epHfXr1zdDopzRylYJ2UvXavdvQtoOlbQts2fPNhUltN3aXvuwF01oP3HihEft1f2i+0jbnVDHjh0d6xNq1apVor+rVKnitK0padu2rXiDK+3QYRs6dGj48OGyZcsWryXcJn0N2tWv7+2qVatM5TBP9qszVve1ldfvzmct6f7Q4Sk6hliXa5d/Qk2bNjXDnFwZPufu50iHmL322mvm/0eHISYcRmUfSuXJPtf39PDhw165vw7x3LlzpxnjnZQWqrgVPbboUIwxY8bI9OnTnf7fu7r/Xd1O27xjx45k7dN9m/R9cKV9nkr6XM2bNzfvs/3Y78lnwFvtd/d+t/qcHD9+3Awn0qHACYuG2IcL6hCu9evXm7+bNWtm8g11WK0OF9L3VPeNDiHWoVL2Skb2bV3h7LtKHzvp8qTfme7877v7Xln93/QGHTKt+133t+ZU6BCt999/3wx76969u3l97tBjMqWr/4fAAunyD6wOHTrk0vb2XAU9mUtKlyUdixsZGZlsOx3jqeN4rdDxtSlJ+pw6bja15QnbouObNWiqVauWOajp2Ew9KGlJO2U/oXWX7jdn+0wP9DqO9Vb7TU+q9QvE1f2W2v5JKrUTYVfaoeObdQzwF198Ycaz63hfHZerJ0lWFC5c2OkyfQ/0C9+T/eqM1X3t6et397OW9D21n1RpzpLmXOiJkd40QLEHR/b/V0/ofnAWvGu+1cSJE01eiVZt0y95bXe1atVc+v/QMex6DEjI/rcr+9yV+9tft5bOTsrZsqR0P+rJYtWqVU2JS/2MablLfa/tuTuu7n9Xt7O3OaXPvbvt84S2T8f0O9tnCf+X3PkMOPscedp+d+7nzuckpe8zZX/dGixonoNWMNRcL33Nmpehy5cvX27+1sBC86RcKXbirH36naT7K+l7oMsT/m+487/vzntl5X9TA7H/P9LGcdMgRYO2pMtdTejW3LbBgwfLp59+avIhNQ9Ej7MfffSRuEqf79ixYyYgBYEF0oFebdEDk1aFcoX9gOfsSpEuS/oFklZXCbJkyZLiupSe05W2fPnllyb5VpPoNCnP/jxJk7zdpfvN2T6LjY01J8ne3m/O9o+eaCu9Gp7Q0aNHU3wcV9qhX0Zjx441j6OVNzS57vfff5d7773XUgCZ0mdMX5v9y87d/eqM1X3t6et397OW9D21v7ZXXnlFbt68aU4Y9KYnP/Yv8GeeecarnyEt5ai9LPq47du3N8m4ejKjXJ28zer+duX+2i57Yn9SzpY5o1dHtVKevod69VdPkkaOHOnYp67uf1e3s7c5pc+9u+3zhLZPE2ed7TN7+9z9DKR0rPa0/a7ez53PSWr73P7+6Umu/q6BjQYQmuCtx1Qti6rJzatXrzYBhqu9FVa+p1z9TLn7XvnyVX09T9GCDkp7rV2lPTv6nac9wyCwQDrQq7VaUUfrPGtlDGe0C3bGjBnmd3vlKD1YJT0I60E+pcpSmUnSruWrV6+aikoJafUfpVeZXaH7RYc6aCWRhLTOtn4JpMd+0+peauvWrYmWz58/32vPoZWV+vTpY77o9YqZDjPw1E8//ZTob62UtHDhQnPCbj9ZSa/96ur77e7rd+WzlhK9iq29Hfq/6ElPmr4mPRHRExNX6YmH7tek7baf6PnScU0rKiWtfKOcLUuNvlYdaqcBoE4Yaq8M5Or+d3U7bbMOhUn6/6j7O+n/givt81TS59ITaf1c2v+XvP0Z8LT93njd2iuhQ4S07UmrLmlFMb2AoVXi7K/bPuxJAwt7AKG9/lrpSi8o6Ot3NbCwwtXPVGb5f3VWAt/Z67JfBEs4vDo1+p0xdOhQU2Ht2Wef9Xo7MyOGQiFdvPfee2ZMp45H1iuveiXDPqZS19WoUUMOHjxottWhHtq1qsM1tESnHpz0RFXHtGsXrpbKzMx0zKqOO9XXrVc5dDiLDlfRXJGEtKtbv3T0C8aVWcn79+9vrkpr6VwNwPSx9QRHD3b65ajdyGlNn1+77vW90wmE9Cqbll/VSYes0P0zbdo0s9/0xFt/fv311+aqmr1b3p1yswlPfHVssF4t1c+flr3UAFYnTkvv/Zra++3q6/f0s5YaLauswxj1aqS+pzocRIc76ImDnuCkNhRK26YnHXoi6+qYZX1P9DOk9eW13K3uC93fWtJRjw2+RMfh6xCz5557zgSfOhxi0KBBpnzxrWiJbH0v9P3Wz5+eWOvvuo/1JNbd/e/qdjpcRWcWHjhwoGmvnkjpRF8asHrSPnfLzer7u2jRIlmwYIH5TOrJul540ve2c+fOXvsMuNp+b90vNRqYaE+jlsPV44weY/TKuPbi67HGflFB6Xul79u2bdtMT4Wd/q77TYcjpdeVcVc+U+n5/2ovZ57wps+lFy2TLtdhoKnRsto1a9Y0F4j0e0p7nzVfTs89tIdYj/sp0Qsl+v/+3//+15Qo/+eff8zv9gtrgY7AAulCr2bowUhPjrQrV6+E6AFJT8z06pUehBJG+5999plJMNUgRMfealK0XkHRA5e9RnlmpV/A+kWjtb/1tel8BHoFOumXlu6zTz75xMwJobXGE85r4Ix2meuJr85srie7OoRHu6f1QKlfSO6ccFuhCY/6haLvmZ6s6Be1nsxYoffXE7gHH3zQvE7dV3olUIcDJR2v6+57oSfn+nnUq88aAOm+qlevXrrv19Teb09fv6uftdTol68+t+4nHcusV/I0MNH3+eWXX3YM9XBGLwboSaPetAco4TwWqdFgVD8/eiFC8z70uPHNN9/43ASXesKlcxHomHgNJvSETyfZsu/fpFdxkybkayCrQZ+O59e8GT0Gai5NwvHdru5/V7fTNusJmo7h1/lYtM16HG7RooVH7bMHwe6ML9e5Y3SYnr63GvxqD6Huw4T7y+pnwNX2e+t+qdGhVNoLoUGFDrPSz4oeO/T1aICXkL03QnMe9LOUdLl9eFR6cPUzlVn+XxPSHmi92Km9QNojpK+xR48e5iLnunXrzOcgKf1e0GOYnrto/oh+HjQI1fmEXCnYECiCtDRWRjcCANKTBqj6JaHd/J7M2gqk5sUXXzQVZvSkW3tZ/ZkGCcOGDTNBuStJ6wD8Gz0WAAB4iQ750qEZOkTC34MKpcNH9Io+QQUAlT5jIwAA8DM6NluHsmi5Sk2K1pwxzQHTYhQ6Pj0Q6Bh1ALAjsAAAwAM61l0nMNPa91qdS6v+6Lh0rSzmD9XrAMBd5FgAAAAAsIwcCwAAAACWEVgAAAAAsIwcCx+g43J1oiKtW+3L090DAAAgsNhsNjOhpc5XExycep8EgYUP0KCiRIkSGd0MAAAAwCmtfFe8eHFJDYGFD9CeCvsbZmUWYQAAAMCbLly4YC6A289XU0Ng4QPsw580qCCwAAAAgK9xZbg+ydsAAAAALCOwAAAAAGAZgQUAAAAAywgsAAAAAFhGYAEAAADAMgILAAAAAJYRWAAAAACwjHksAlhcvE3W7T8rJy/GSqGc4VK7TD4JCb51jWIAAAAgKQKLALVwa7SM/Gm7RMfEOpZF5g6XqDaVpEWVyAxtGwAAADIfhkIFaFDR76u/EwUV6nhMrFmu6wEAAAB3EFgE4PAn7amwOVlnX6brdTsAAADAVQQWAUZzKpL2VCSk4YSu1+0AAAAAVxFYpIHr16/L+vXr5eDBg+JrNFHbm9sBAAAAisDCyzSgqFq1qvTv319q1Kghzz33nE990rT6kze3AwAAABSBhZedO3dOlixZIuvWrZNt27bJ5MmT5ebNmz7zadOSslr9KaWisrpc1+t2AAAAQKYrN7tz505ZtGiROTEvWbKkdOzYUXLlyuX154mJiZGZM2fKoUOH5MUXX5T8+fMn2+bff/+VefPmmSFNzZo1kzp16jjWnThxQrZs2ZLsPmFhYXLvvffKAw884Fh26tQp03sRGuozu9nMU6ElZbX6kwYRCVO07cGGrmc+CwAAAGS6HovPP//cnID/9ddfEh8fL59++qmUL19e9uzZ49Xneeedd6RixYry888/y9ixY00Qk9Ts2bPlrrvukq1bt0p0dLQ0btxY3n33Xcf6HTt2yNtvv53sNnHixESPo23v16+ffPPNN+JrdJ6KyV1rSJHciYc76d+6nHksAAAA4K4gm82W4XVF9WS/SZMm8uGHH5q/deiQBhadO3eW0aNHO+110B6O2rVrJ1unw5C0l8GZ1atXm6BBexzq1asnu3fvNs9jd+PGDSlRooT06NFDRo0a5Qh6+vTpI/v375dixYq59Hp0GJTmVmjPSOnSpW+5/YULFyR37tzmdaVFL43SIElvCWlJ2R2nr8u52HjJGx4sFQtkTdZTERkZaW4AAAAIPBfcOE/1iTE6+fLlMyf1dtprocGFLndm/vz50rdvX1m4cKHcc889juUDBgyQWbNmyfbt2yVPnjzJ7le/fv1U2/HHH3+YoU7dunVzLOvUqZNJxNbn1ADjVpYtWyZdu3aVcePGmV4LvTVs2FCyZs0qGWnq1KkycuRIt+8XFRUlI0aMSJM2AQAAwH/4RGChQ5/0pL19+/ZSqlQpWbNmjbRp08YECs506dJFjh49Ki1btjR5Gdr7MGjQIPnhhx9kxYoVToMKV+zatUuCgoKkXLlyjmURERFStGhRs84VBw4ckMqVK5ueDruaNWs6DSwmTZpkbnFxcZLWdP+2bds20bKrV69KgwYNzO+///67ea1J0VsBAACATBNYHDlyxMz5ULx4cdPFEhISYhKotcslPNx52dOXXnrJ9HK0aNFCWrVqZXoKli9fLnfccYfH7bh8+bJky5bNPH9C2v2j61yhw6j05grtCdGbvYspLTkb0pTwNVWrVk2yZ8+epm0AAACA/8rw5G2tvKTDjZ5++mmTk/DGG2+Yq+d6sj106NBU7zt8+HDTO6AJ0ppgXalSJUttyZEjhznZTloe9vz582YdAAAAAB8NLDSn4cyZM1K3bl3HsuDgYJOYrZWZUqO9FpqArfkWgwcPNlWlrCaRq4TDnjTQ0GFX9nUAAAAAfDCw0EpLOvxJhzHZaY+B9lqkdjKvvRWam7F06VIzCZ3mY2g1qI0bN3rcFg1udDjWtGnTHMu++OILk3fRunVrjx8XAAAA8HcZnmOhvROawNyrVy9TBrZs2bImyND8Ch0W5Yye7GswoXkVWj5Wvfnmm6aalE5Qp70YzhK49XE12fvYsWPmb63cpNvpZHy1atUyE9l98sknJol83759ZviTVpkaP368FC5cOI33BAAAAJB5+cQ8FvYEbq3opMOitDKUJmWnlLh95coVc+JfpUqVZOv+/PPPRDNlJ53HYuXKlcmWP/jgg3LnnXc6/j58+LAsWLDA5H/o/BpWczd8YR4LZ3SYlz135NKlSyRvAwAAwOPzVJ8JLAIZgQUAAAAy+3lqhudYAAAAAMj8CCwAAAAAWEZgAQAAAMAyAgsAAAAAlhFYAAAAALCMwAIAAACAZQQWAAAAACwjsAAAAABgGYEFAAAAAMsILAAAAABYRmABAAAAwDICCwAAAACWEVgAAAAAsIzAAgAAAIBlBBYAAAAALCOwAAAAAGAZgQUAAAAAywgsAAAAAFhGYAEAAAAg4wKLq1evSuPGja23AAAAAEDgBhZhYWGydu1auXHjhndbBAAAACBwAovg4GBp1qyZfP31195tEQAAAIBMJ9TTO16/fl2yZcsm3bt3lxkzZsjtt98uWbJkSdSjMXbsWG+1EwAAAIA/Bhbx8fFy8eJFefDBB83fBw8eTLQ+IiLCeusAAAAA+HdgER4eLvPnz/duawAAAAAEVmCR0JEjR2Tnzp0SEhIiFStWlMKFC3vjYQEAAAAEwjwW58+fl06dOkmJEiWkadOm0qhRIylWrJj07t1bYmNjvddKAAAAAP4bWPTv31927NghS5culZiYGDl79qzMmTNHli1bJq+++qr3WgkAAADApwXZbDabJ3fUu2lVqG3btknZsmUTrVu9erV07txZDhw44K12+rULFy5I7ty5TXCWK1eudHvey5cvS44cOczvly5dkuzZs6fbcwMAAMC/zlM97rG4efOmmRwvMjIy2bqiRYuaE1UAAAAAgcHjwELnrKhataqMGjXKlJ6102Djrbfektq1a3urjQAAAAD8uSrU+++/L61btzazb1evXl3i4uJk/fr1ZvK8X3/91XutBAAAAOC/ydsNGzaUPXv2SI8ePUy+hY6/evbZZ80y7c0AAAAA4Lm4eJus2XtG5m46an7q337XY6G9Eq+99pqMHTtWhg8f7t1WAQAAAAFu4dZoGfnTdomO+b9pHCJzh0tUm0rSokryPOdM22MRHBxshkJ5WFQKAAAAQCpBRb+v/k4UVKjjMbFmua73m8AiNDRUqlSpIn/88Yd3WwQAAAAEsLh4m+mpcHb53r5M1/vasKhQK+Vmdbbtdu3aSd++feX22283laLs9PeOHTt6q50AAABAQFi3/2yynoqENJzQ9bpdvXL5JdMHFteuXZNPPvnE/D5lypRk63XiNQILAAAAwDXR0dHmtu7QVZe2X7flXwmLiTDzyjmbWy7TDIXSWZpPnz6d4o1ZtwEAAADXTZ06VWrWrClDB/VzaXvdTrfX+2XqHourV69K3bp1ZfPmzd5tEQAAABCA+vTpI23btjW5E31/Pilnrv7fJNRJ5Y8Ilu9nfS4hwUE+0VthKbAIDw8381XokKiwsDDvtgoAAAAIMJEJhjSNCv9fVSiVMEU76P//HNWxmtTysZKzHg+FCgoKMonbkydP9m6LAAAAgADXokqkTO5aQwrlTHwBv0jucLPcF+exsJS8HRMTI88995x88cUXyapCaY+GPbkbAAAAgHs0eKhfKqcUqlxfQnLklfnfz5SGFYuZ4U++yOPAQhUoUEC6devm/IFDLT00AAAAEPBCgoPk2uEtZj/ULp3XZ4MK5fHZv+ZVaE8FAAAAAHicY2F36dIl+emnnxLNZbF37172LAAAABBALAUWW7dulUqVKsnTTz8tL7zwgmO55l0sWLDAG+0DAAAA4O+BxYABA+Spp56S/fv3J1qugcW7774rgSg+Pl4++ugjad68uTz55JOybdu2jG4SAAAA4LuBhZ5Ar1+/Xl555RVTejahihUryj///COB6IMPPpAdO3bIkCFDpFSpUibAAAAAAPydpdJNN27cMAFG0sDi4MGDkitXLpcf5/Lly2KzJZz643+0fG1aTL4XFxdnZg7Pnj17srbbaXv0tYWEhLj12H379jWldtV9991nAg19PncfBwAAAAiIHovg4GC5//77Zfz48YlOzk+dOmWu1rtzpb5cuXJSpEiRRLecOXPK0KFDxZt0yNawYcPMjIb6+M6SzHVujscff1wiIiJMgPDAAw+YQMlu6dKlUrdu3WS3Vq1amfX2oEK9+uqrpkeHoAIAAAD+zlKPhV6Nb9SokXz77bdmwrwmTZrIunXrzIn7G2+84fLjHD9+PNHfixcvNoHJY489ZqV5TttbqFAhmTZtmpk13BnNGdm3b5/s2rXL9Gg88cQT0rp1a9m0aZMJEKpXry4TJkxIdr+sWbM6fteejmeffVby58/v9eAIAAAA8EVBNmdjkNxw9uxZmT59umzcuNH8XatWLXNyrj0CntKAQpOeteqUMz/++KN8/fXXJqBJONu35nX06tVLFi1aJHny5Enx8deuXSv16tWT3bt3S/ny5R3LDxw4IGXKlJH58+c7eiA0wNBZxRcuXOhSL0xsbKx07dpVGjZsKIMGDXLp9V64cEFy585tekvcGUJmlQ5By5Ejh6NssAZSAAAA8B2XM/h8zZ3zVMvTY+fLl89UgfKWM2fOyJw5c+Sdd95JcZt77rlHhg8fLp06dZLvvvvOzPKtQYj2mHTv3j3VoCI1GnAoDQrsbrvtNtMDo+tcCSzGjBljApsjR46Y4Edp6V3dT0lNmjTJ3DQHAwAAAMjMLAcW3jZjxgyTs6FDkFKiORi//vqrSY7u3LmzCTKaNWtm7pNaQHIrJ0+eNMniSXtbChYsaNa5omfPntKyZctEy1Lqvenfv7+52SNBAAAAILPyucDis88+k44dOzq9wp9Q0aJFZfny5aZ3oWbNmvLMM8/Ie++9Z/n5nY0Mc1b5KiUlSpQwNwAAACCQWJogz9s08XvLli0mT8IVOs7sypUrpoLT6dOnLQ8p0mDl+vXrcv78+UTLtbdCh0MBAAAAyASBxaeffioVKlQwQ5xuRROvGzdubHo3NL9izZo1Jmlcexc8Vb9+fdMzsWzZskQJ4RpYNGjQwOPHBQAAAPydzwQW2vOgVZ40R+FWw450/gktc9umTRv58MMPzQzXOixq1apV0qNHjxSDC53QT3s5dHI8+3Pq3zdv3nT0WDz55JPy0ksvmVnFdQZtnfBOK0glTOgGAAAA4GFgcezYMWnatKlUq1bNVG2y06TpDRs2iFXz5s0zAUW3bt1c6q3QoGLKlCmOIKR06dImuNCqUhosOKOT+Wnit95XS3VpD4X+PXPmTMc2kydPNus7dOhgJgDUyfvmzp3rco4FAAAAEIhcnseiX79+Jv/g+eefl9dff10eeeQRU+5VZ53WCeP0JzzDPBYAAAAImHkstJfg5ZdflsqVK5u5IzSwsL9IAAAAAIHN5aFQmmOgOQxKJ6T76quvzJwR+/btS8v2AQAAAPCnwEITms+dOyexsbHmb+2G+eGHH0wS9a3mnAAAAADg31zOsUDaIccCAAAAmT3HwmfKzQIAAADIvNIksNB5Ih599NG0eGgAAAAAgRJYxMXFyYIFC9LioQEAAAD4IIZCAQAAAEj/wOLatWvy1ltvmR6J6Oho6y0AAAAAkOm5PEGeXXx8vEyZMkWOHj1q/i5SpIjUqFHDcatevboUKFAgLdoKAAAAwF8Ci4iICDly5IicPHlS/vrrL8dt+vTppidD5cmTJy3aCgAAAMBfAgu7QoUKScuWLc3N7vTp045AY8eOHd5qIwAAAAB/DSyc0SFQzZs3NzcAAAAAgYOqUAAAAAAsI7AAAAAAYBmBBQAAAADLCCwAAAAAZHxgsXDhQunSpYs0bdrUsWzChAly5coVqw8NAAAAIBACiy+++EIee+wxyZEjh6xdu9ax/Ny5c/LBBx94o30AAAAA/D2wePPNN2XevHny3nvvJVrevn17+fLLL622DQAAAIC/BxY3b96Uw4cPS8OGDSUoKCjRusKFC8vx48e90T4AAAAA/hxYhIaGmiFQBw8eTBZYrFixQkqVKuWN9gEAAADw96FQ3bp1kx49esjOnTvN36dOnTJ5FwMGDDDLAQAAAASGUCt3fvvtt6V3795So0YNsdlsUqhQIQkJCZGBAwdK//79vddKAAAAAP4bWISFhcn06dNl9OjRsnnzZrOsevXqEhkZ6a32AQAAAPDnwOL69evy3XffmQpQxYoVMzcAAAAAgcnjHIu4uDiTS6EVoHSCvF9++cVUigIAAAAQeDwOLCIiIuTEiRMmWfvy5cvSrl0702sxePBgWb9+vXdbCQAAAMB/q0KFh4fLI488InPmzDHzVuiEeZs2bZI6derIXXfd5b1WAgAAAPDf5O2E8ubNKx07dpT4+HjTk7F3715vPTQAAAAAfw8srl69KvPmzZOZM2fKwoULpWDBgtKpUyfp2rWrd1oIAAAAwH8Dixs3bkjPnj1l9uzZ5u8OHTrIggULpHHjxhIcbGmEFQAAAIBACizOnTsn06ZNk7Zt25pkbgAAAACByePAIlu2bGYIFAAAAIC0ERdvk7ASVSUkR15Zd+CcNKyYTUKCgyTTBxY6T8Unn3wiWbJkkW7dupnfU6Lb9OjRwxttBAAAAALOwq3REjV3mxTpPMb83X3GZonMvVOi2lSSFlUixdcE2Ww2m6sbX7lyRe68807Jnj27rFmzxvyeEt1m8+bN3mqnX7tw4YLkzp1bYmJiJFeuXOn2vDr/SI4cOczvly5dMu8ZAAAA0k90dLS5JbX2yFV5Z/X5FO/3Uv08Urd48lSEyMhIc8uI89RQd4c/7dmzx/F3wt8BAAAAuGfq1KkycuTIxAuDgqVY308lJGcBCQpKPuzJZouX0Qt3y9EpPURs8YnWRUVFyYgRIyRT5Vhcv35dRo0alXxH3GIdAAAAgP/p06ePKYSU0NaT1+T1FWclJUFBwRKaq6BMX/C7VCkUlmidN3sr0nQoVEI6dKZIkSLmp7N1+qIuXrzojTb6PYZCAQAAwG7upqMy+NtNcivvd6omD1UrJr5ynpomE05oboVOlAcAAADAPYVyhnt1O58dCqUJv8WKFXP8nidPnkTr4+LiTI/Fa6+95r1WAgAAAAGidpl8Epk7XI7HxIqzoUWadVEkd7jZLlMHFuHh4abMbGxsrPTq1StZydmsWbNK2bJlpUqVKt5sJwAAABAQQoKDTEnZfl/9bYKIhMGFPZVb1/vafBZuBxYhISHy8MMPm56JUqVKyb333ps2LQMAAAACVIsqkTK5aw0zj8WJi9ccy7WnwlfnsfC4KpQGGPagQpM5Dh8+bCbQS7i+atWq3mklAAAAEGBaVImU+qVySqHK9c3M2/O/nykNKxbzuZ4Ky4GFOnTokDz55JPy22+/JVunk605qxgFAAAAwDUaRFw7vMX8Xrt0Xp8NKixXherfv79J5P7nn39MIHHw4EH59ttvzbKJEyd6r5UAAAAAfJqlHosVK1aYYCIsLMzkXJQsWdLctFLU66+/Lt27d/deSwEAAAD4X4+FlpqNj4+XfPnySbZs2czv9qFP1atXlz179niznQAAAAD8MbDQCbuDgv43xkt/aqL2tGnT5MaNGzJ9+nQpXry4N9sJAAAAwB+HQoWGhkqzZs0cf48aNUo6dOggQ4YMMUOjNNcCAAAAQGDwOLDQifJmz57t+Lt58+amStSOHTukQoUKUrhwYW+1EQAAAIA/J28nlT9/fmnQoIE3HxIAAACAvwUW165dk8GDB7vcozFhwgRP2wUviI6ONreUXL161fH7pk2bJCIiItXHi4yMNDcAAADAUmChCdunT592adtbnaQi7U2dOlVGjhzp0rau9DRFRUXJiBEjvNAyAAAA+Jsgm0YLyFAXLlyQ3LlzS0xMjOTKlctrj+tKj4U9oPj999/psQAAAPAxly9flhw5cpjfdWoHnZTaV89TLedY3Lx5UzZu3ChHjhyR9u3bO3ZAer9ouD90Sd8nu2rVqvGeAQAAIP3nsVD79++XGjVqSP369eWJJ55wLG/durWsWrXKykMDAAAACJTAon///mYozfHjxxMtHzp0qIwePVoCUVxcnLz33nty3333yaOPPmqSogEAAAB/Z2nmbe2VePfdd00FqITuuusuWb9+vQSiDz74wOQ1vPnmm2Y/tGzZ0uwrAAAAwJ95nGMRHx8vsbGxZgZuvUqf0IkTJyRbtmwePe7169clODjYPG5a0efQRJR8+fKZ53Lmxo0bJn/E3epW2ouTNWtW83udOnVk3LhxZl+FhIR4pe0AAACAX/VY6Imynjh//vnnEhQU5Fh+5coVGT58uDRq1Mitx/vrr7+kYcOGkjNnTilSpIgMGDDAPJY37dq1S5599lmT0FywYEHZt29fsm3Onj1rktA1+Vwz37VNe/fudaxftGiRSXROemvatKlZbw8q1EsvvWRKtBJUAED6iIu3yZq9Z2TupqPmp/4NAEgflroFdAI8PaH+8ccfTS9Aly5dZPny5Wboz9q1a11+nO3bt5uchGeeeUYWLlxoTs4//fRT2bZtm9SqVcvpffQ5EgY0t1qu9DFLlSolM2bMkFatWjnd5sknnzRDmQ4fPmx6Xbp27WqS0bds2WJ6UTSY+uKLL5LdL0uWLI7ftQdHX0vZsmVNIAMASHsLt0bLyJ+2S3RMrGNZZO5wiWpTSVpUYXJPAPD5eSwOHjwoH330kSk5qzQQGDhwoOl1cFWHDh1Mudp169a5tP1///tf+fLLL2XWrFmJegi016NHjx6yYsUKyZMnT4r316CnXr16snv3bilfvrxjufZglCtXTn755Rdp0aKFWbZnzx6pUKGCLFiwwORL3IqWcH388cdNMNK7d+8MncfC1+siA4A3g4p+X/0tSb/Q7JeZJnetQXABIFO6nInmsfB4KJT2UGjlJ+0BGDt2rCxevNjcRo0a5VZQoXkM2kvxyCOPJJtbISWNGzc2AU3Hjh1NO5QGNs2aNZO2bdumGlSk5s8//0w2C7UGHkWLFnWsuxXdF7/++qsJtuzDpM6cOeN020mTJkmlSpVS7JUBANyaDnfSngpnV8nsy3Q9w6IAIG15HFjocCOtfGS14tGpU6fMDNAaUNxxxx0m90GjokGDBpnkcGcKFCggy5YtM7kPWtJVK1DpkKy+ffvKG2+8YaktYWFhjqjQTtuk61zRr18/M4u1Dpey3/T1pJTorcPAArWCFgB4w7r9ZxMNf0pKv6V0vW4HAPDBHAvNKdCr+Rs2bLB0xd2eDzFx4kRZsmSJmXBP8xk0UNCTfC1n60yhQoVMz4AmV9etW1eef/55y3NnaFu0gpOzXpWUqke5O9s1AMC7Tl6M9ep2AIB0Diw0QVmHIrVr106ee+45uf322xMlMGuis71SUmq090HzJDTxW4MKVbVqVenWrZvMmzcvxcBCaS/CuXPnTCUpnQVcAwArZWp1yJOWmdXHzJs3r2P5yZMn/TJY0GEBYSWqSkiOvLLuwDlpWDGbhAQ7T3wHAF+jhTb0FnPymkvbxxw/JH//fYILQADga0OhdJjSW2+9ZeasGDZsmCnRqgnL9tvDDz/s0uNoIHDPPfckKy2rf6c2h4QOIdLA5YknnjDVozZv3myCk6RzarhD26E9E0uXLnUs09wNDWDuvfde8bdEx2YfrJUincdIwbYvSfcZm6XB2F/NcgDIDKZOnSo1a9aUbg82kJsXTonNlrzHWelyXa/b6fZ6PwCA93l8eV8z0rWHwBteffVVk3TdpEkTc3KvidKam/D222873X7nzp1m206dOsl7771nlmmZ2/vvv98EGlpO1tncEfZcDs1qV9ozcfr0adPjocOuNOlcq0q98MIL5nfNtdDKTjrcyp8Ci5SqpxyPiTXLqZ4CIDPo06eP+e5Qa49clXdWn3e6XVBQsLzSooLU7fm/fDZ/7IEGAL8oN+st8+fPlzFjxphqTyVLlpSePXvK008/7XRb7VH4+eefZfz48YmW69wTQ4YMMfNVaLCQlAYhzvIwdD4Ona9CXbt2zUxqZ5+b44EHHjCVnnSW7rSSnuVmdfiT9kyklOioA6GK5A6X34c2ZlgUgEx30SRq7jY5cfH/hkYxjwWAzO5yJio36zOBRSBLz8BCZ6J9fNqtJy/8plddqVcuf5q2BQC87cLFS1Kocn2TOzb/+5nSsGIxLpIAyNQuZ6LAwtLM28h8qJ4CwJ9pAYprh7eY32uXzktQAQCZIXkbmVOhnOFe3Q4AAABQBBYBpnaZfGbMcUpFZXW5rtftAAAAAFdZHgqlCc779u2T8+cTV+PQqkxWJs5D2g0TiGpTyVR/0iAiYYKNPdjQ9cxnAQAAgHQLLBYvXmzKu+oEcklpYokmmMD3tKgSaUrKJq2eotWgNKjQ9QAAAEC6BRZ9+/aVp556SgYNGmSyxRMKCmIGZ1+mwUP9UjmpngIAAICMDSx0husjR47IqFGjzOzZyHyongIAAIAMT97WHAqdyO7EiRNeawwAAACAAKwK9fzzz5sci7///lvOnTtnErjtN51EAwAAAEBg8HgMkyZm9+/f3/xes2bNZOtJ3gYAAAACh8eBRbZs2WT9+vWpDpUCAAAAEBg8DiyCg4Pl7rvv9m5rAAAAAGRKlss5bdu2TSZMmCD//vuv6aWoUqWKDBkyRMqUKeOdFgIAAADw7+Tt2bNny1133WWCCp1lW39fu3atVKxYUVatWuW9VgIAAADw3x6LoUOHyvjx42XgwIGJlg8fPtzcVq5cabV9AAAAAPy5x+L69euyd+9e6dOnT7J1/fr1M0OkAAAAAAQGjwOLrFmzmpKyOgwqKQ0q8ufPb7VtAAAAAAJhKFS3bt3koYcekqioKDOXRVxcnKxevVpGjBghgwcP9l4rAQAAAPhvYDFu3Dgzn4UOfYqNjTXLcubMKcOGDTM3AAAAAIHBUmARFhYmY8eOlVGjRsnBgwfN3BalSpUyPwEAAAAEjlCvPEhoqJQrV84bDwUAAADA3wOLq1evSsuWLSUiIkJmzZplfk+JbvPLL794o40AAAAA/Cmw0Jm1GzRoYIZA2X9PiW4DAIA3RUdHm1tKLl+5ImElqkpIjrzy9dL1Uq1YTgkJDkpx+8jISHMDAFgXZLPZbF54HFhw4cIFyZ07t8TExEiuXLnSbV9evnxZcuTIYX6/dOmSKR8MAL5Mqw6OHDnS6bqI2+pJvia9JTRXQceymxdOydllH8vVXWuc3kerGupjAoCvupzB52vunKd6nGNx5coVqV69uuzcudOtdQAAeEonZW3btm2y5WuPXJV3Vp9PtlyDjELth8tL9fNI3eIRydbTWwEA3uNxYBEfHy9Hjx51uu7atWty6tQpK+0CAMCloUtx8Tbpv+jXFPeWDoSasS1W+rSun+qwKADwRXHxNscQz3UHzknDitl89ljmdmChk+BpUrbOW6G/z58/P9n63377TcqWLevNdgIA4NS6/WclOuZ/cyk5o+N9db1uV69cfvYigExj4dZoiZq7TYp0HmP+7j5js0Tm3ilRbSpJiyqRmT+w0IDi4YcfdvRM2H+3y5o1qwkqJkyY4L1WAgCQgpMXY726HQD4SlDR76u/zcWRhI7HxJrlk7vW8Lngwu3AQhNGNLggjwIA4AsK5Qz36nYA4AvDn0b+tD1ZUKF0mQ6E0vXNKhXxqWFRHk+RnS1bNpKzAQAZrnaZfBKZO9x80Tqjy3W9bgcA/jbE069m3j5w4IAsWrRIDh8+LDdv3kw0j0VKJQEBAPAWvVqn4411aIAGEQmv8NmDDV3vS1f1ACC1uXrWHboqrli35V8Ji4nwmTl5PO6xUJq4XblyZfn444/l7bfflpUrV8rkyZNl7Nix8ueff3qvlQAApELHGet440I5E0/OWiR3uE+OQwYAZ6ZOnSo1a9aUoYP6iSt0O91e75fpJ8jToGLYsGHSvn17KVKkiJm0QyfR6Ny5s9x5550yevRo77bWTzFBHgB46Xh68ZIUqlzflGWc//1MaVixGD0VADJdj0VcvE36/nxSzlyNT3Hb/BHBMqVVIXOMS8seC3fOUz0OLHTYk84CqMGE/p4zZ065ceOGWffvv/9K69atZc+ePZ69ggBDYAEA/jFDLQB4uyqUpDDEM716Y905T/V4KJRWhgoNDTW38PBwk8yteRZK/9ZGAAAAAPB8iKcO6cwsQzwtJ2/bNW/eXHr37i1dunSR6dOnS+3atb310AAAAEDAaVEl0pSU1epPOhePls3WCne+WozC4x4L7ZVImCjy/vvvm0pQmnOhvRiTJk3yVhsBAACAgBQSHCT1yuWXh6oVMz99Naiw1GOhwYP2TthpwsicOXO81S4AAAAAmYilcrMAAAAA4HZgoRU2goKCXLrZq3IAAAAA8H9uDYWKiIiQ5cuXO/7+7bff5IMPPpCBAweayTni4uJkzZo18tFHH8k777yTFu0FAAAAkNkDi5CQELn//vsdfw8aNEjmzp0rDRo0cCxr166d1KpVy8zG3a+fa7MGAgAAAAjQHAudFG/nzp1Sp06dZOvq1asnW7Zssdo2AAAAAP4eWGhVKJ2F79tvv022bubMmVKoUCGrbQMAwC1x8TYJK1FVslVsKOsOnDN/AwAywQR5Y8aMkaeeekq++eYbqVGjhsmxWLt2rfz+++8ye/Zs77USAIBbWLg1WqLmbpMinceYv7vP2CyRuXdKVJtKPjlDLQD4G0vlZnv06CF//vmnFCxYUJYuXSorV66U2267zQyDat26tfdaCQDALYKKfl/9LScuXku0/HhMrFmu6wEAPtxjoe6++26ZPn26d1oDAICbdLjTyJ+2i7NBT7pM56jV9c0qFfHpGWsBIKACC5vNJgcPHpTg4GApUaKE+T0luk3JkiW90UYAAFK0bv9ZiY6JTXG9Bhe6XrerVy4/exIAfCGwuHz5spQpU0ayZ88ux48fN7+nRLfRCfUAAEhLJy/GenU7AEA6BBYaLOzevdv0Rth/T4luAwBAWiuUM9yr2wEA0iGwCAoKkvLlyzv+Tvg7AADpKTo62txC422SPyJYzlyNT3FbXR967oD8/fdBiYyMNDcAQAYGFlpOdvny5a49cGhoolm6AQDwpqlTp8rIkSPN7xG31ZOC7V4xGRVBQf/XY26zabARJDu+flNqj1hjlkVFRcmIESN4MwDAy4JsmpHtIs2ZyJkzp0vbkmPhugsXLpjJBmNiYiRXrlySXjRnJkeOHI73Vt8zAMhsPRZ2a49clU83XkjUc6E9FT2q55K6xSMcy+ixAIC0OU91q8dCT0LdiEMAAEgzSQOEGjVE+rS2mepPmqitORW1y+SjxCwAZJZ5LAAA8BU6TwUlZQEgkwYWWnZ22bJlcvjwYbl586ZjedasWeWll16y+vAAAAAA/D2wWLp0qXTo0EGKFi1qSs9WrlzZ/IyNjZWGDRsSWAAAAAABwtJkE88//7yMGzdONmzYIBEREfLPP/+YnosmTZpIo0aNvNdKAAAAAP4ZWOiwp127dkn37t0lJCRErl27ZpYXKFBA3n//ffn666+92U4AAAAA/hhY6HAnnasiS5YsprdCb8eOHTPrtCTtuXPnvNlOAAAAAP46FCohHf40YMAAmTNnjvlZQ+v+AQAAAAgIHgcWYWFh8t577zn+1uFPOoHGU089ZXorJk2a5K02AgAAAPCnmbeRNph5GwAAAJn9PNXjHourV69Kt27dZMmSJRIfH+/pwwAAAADwAx4HFloJ6tSpU/Lggw9K8eLFZciQIbJx40bvtg4AAACAfwcWOrP2ggULTCWoV155RVavXm0StnWSvDFjxsihQ4e821IAAAAAgZFjsXfvXjN/xeeff256My5evOith/Zr5FgAAAAgYHMsktIJ8nTm7c2bN5tejPz583vroQEAAAD4OEuBhSZtr1ixQnr16iVFihSRJ554wpShnT17tuzZs8d7rQQAAADg00KtzLxdoUIFOX78uDRt2lQmTpwo7du3l+zZs3u3hQAAAAD8t8ciKChIXnzxRTl69Kj88ssv0rVrV4IKEbl+/bq88cYbUrNmTVMxa+3atV59wwAAAAC/6rHQIU+DBg3ybmv8gM44rvnw06ZNk1WrVkmbNm3k5MmTJhADAAAA/JVPzLx95syZZBWktJxt0aJF0+T5Ll26JKdPnzbzb4SGOo+tNPP9xo0bUqBAAbceOy4uzszxYZ9EUJ9DK2QFB6fcOURVKAAAAPiiDKkKZcXw4cPN/Bf333+/49a9e3evP49WrerZs6c52S9TpowcOHAg2TYnTpyQZs2aScGCBaVkyZJmbo7t27c71v/8889Svnz5ZLd69eqZ9fagQuM17dEZPXp0qkEFAAAAENBDobytZcuW8sMPP3jUM+DKcvXjjz9KnTp15PHHHzcJ585orsjly5dNL0N4eLh069ZN2rZta4IL7UW57777ZOHChcnul7DnQ3s6nn76aalbt6706dPH5dcEAAAAZFY+dSldcxF0+NCtzJw50/QqJN32jz/+kEqVKsn58+ed3m/kyJGmNG5Klat2794tS5cuNcnX2uWjeSRvv/22mfhv8eLFZpscOXI47bEoXbq0Wa/dRK1bt5bmzZtL//79PdgLAAAAQAD2WOzcuVPWr1+f7GRer+737t3b5ceZNWuW/Prrryb/oVq1aiYJulatWk63bdWqlYwfP94kRs+fP9/0LKxZs8b0euiwqjx58nj0WvR1qPr16zuWacBQrFgxs04Dhlt55513TNK2BiMjRowwy7QylLNcDX2NetNeFgAAACBgA4sPP/xQBg8eLIUKFTJX+BPSXgFXAwsdnqRX96tWrWoCC/1dr/hv27ZNIiMj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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(8, 4))\n", + "positions = np.arange(1, len(confirmation_summary) + 1)\n", + "for position, summary in zip(positions, confirmation_summary):\n", + " scores = [\n", + " run[\"validation_mean\"]\n", + " for run in confirmation_runs[config_key(summary[\"config\"])]\n", + " ]\n", + " ax.scatter(np.full(len(scores), position), scores, color=\"tab:blue\", zorder=3)\n", + " ax.errorbar(\n", + " position, summary[\"mean\"], yerr=summary[\"standard_deviation\"],\n", + " color=\"black\", capsize=5, marker=\"_\", markersize=14,\n", + " )\n", + "ax.set(\n", + " xticks=positions,\n", + " xticklabels=[f\"C{index}\" for index in positions],\n", + " yscale=\"log\",\n", + " ylabel=r\"mean validation relative $L^2$ error\",\n", + " title=\"Confirmation runs: points are training seeds; bars show mean ± SD\",\n", + ")\n", + "fig.tight_layout()" + ] + }, + { + "cell_type": "markdown", + "id": "freeze", + "metadata": {}, + "source": [ + "## 10. Freeze the choice, then run the final audit\n", + "\n", + "The declared selection rule is the lowest mean confirmation validation error. The standard deviation indicates sensitivity to training randomness; with only three seeds, it is descriptive rather than a precise uncertainty estimate. Small differences should not be promoted into strong architectural conclusions.\n", + "\n", + "After the next cell evaluates the audit suite, **do not** use its result to revise the architecture, learning rate, seeds, epoch budget, or metric. Doing so would turn the audit suite into another validation suite. A revised experiment needs a fresh audit suite." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "select-configuration", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:02:11.025164Z", + "iopub.status.busy": "2026-08-17T09:02:11.024955Z", + "iopub.status.idle": "2026-08-17T09:02:11.029199Z", + "shell.execute_reply": "2026-08-17T09:02:11.028172Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Frozen selection:\n", + " C2: width=64, layers=4, lr=2.80e-03\n", + " confirmation validation = 5.619e-02 ± 3.31e-03 across seeds\n" + ] + } + ], + "source": [ + "selected_summary = min(confirmation_summary, key=lambda summary: summary[\"mean\"])\n", + "selected_config = selected_summary[\"config\"]\n", + "print(\"Frozen selection:\")\n", + "print(f\" C{selected_summary['candidate']}: {config_label(selected_config)}\")\n", + "print(\n", + " f\" confirmation validation = {selected_summary['mean']:.3e} \"\n", + " f\"± {selected_summary['standard_deviation']:.2e} across seeds\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "audit", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-17T09:02:11.030936Z", + "iopub.status.busy": "2026-08-17T09:02:11.030799Z", + "iopub.status.idle": "2026-08-17T09:02:11.051573Z", + "shell.execute_reply": "2026-08-17T09:02:11.050638Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seed validation mean audit mean audit maximum\n", + " 10007 5.563e-02 6.081e-02 8.194e-02\n", + " 10009 5.975e-02 4.795e-02 1.135e-01\n", + " 10037 5.320e-02 4.953e-02 1.105e-01\n", + "Validation across seeds: 5.619e-02 ± 3.31e-03\n", + "Final audit across seeds: 5.276e-02 ± 7.02e-03\n" + ] + } + ], + "source": [ + "audit_cases = make_parameter_cases(\n", + " experiment.audit_case_seed,\n", + " experiment.audit_case_count,\n", + " problem,\n", + ")\n", + "selected_runs = confirmation_runs[config_key(selected_config)]\n", + "audit_records = []\n", + "for run in selected_runs:\n", + " audit_score = score_cases(\n", + " run[\"model\"], audit_cases, problem, experiment, device\n", + " )\n", + " audit_records.append({\n", + " \"training_seed\": run[\"training_seed\"],\n", + " \"validation_mean\": run[\"validation_mean\"],\n", + " \"audit_mean\": audit_score[\"mean\"],\n", + " \"audit_maximum\": audit_score[\"maximum\"],\n", + " })\n", + "\n", + "print(\"seed validation mean audit mean audit maximum\")\n", + "for record in audit_records:\n", + " print(\n", + " f\"{record['training_seed']:8d} \"\n", + " f\"{record['validation_mean']:.3e} \"\n", + " f\"{record['audit_mean']:.3e} \"\n", + " f\"{record['audit_maximum']:.3e}\"\n", + " )\n", + "\n", + "validation_scores = [record[\"validation_mean\"] for record in audit_records]\n", + "audit_scores = [record[\"audit_mean\"] for record in audit_records]\n", + "print(\n", + " \"Validation across seeds: \"\n", + " f\"{statistics.fmean(validation_scores):.3e} ± \"\n", + " f\"{statistics.stdev(validation_scores):.2e}\"\n", + ")\n", + "print(\n", + " \"Final audit across seeds: \"\n", + " f\"{statistics.fmean(audit_scores):.3e} ± \"\n", + " f\"{statistics.stdev(audit_scores):.2e}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "checks", + "metadata": {}, + "source": [ + "## 11. Checks and interpretation exercise\n", + "\n", + "**Timebox: 10 minutes.** Use the executed evidence rather than the trial ranking alone.\n", + "\n", + "1. Did the configuration with the best exploratory score remain best across fresh seeds? Explain why either outcome is plausible.\n", + "2. Are the confirmation differences large relative to their seed-to-seed variability? What claim is justified, and what stronger claim is not?\n", + "3. Did TPE find a better candidate than random search under this one equal trial budget? Why does that not establish that TPE is the better algorithm in general?\n", + "4. Which configuration would you choose if training time or parameter count were a hard constraint? State the constraint before choosing.\n", + "5. Why would replacing validation solution error with training residual change the scientific meaning of the objective?\n", + "6. If the audit result is disappointing, what may be reported now, and what must wait for a new experiment with a fresh audit suite?\n", + "\n", + "### Optional transfer task\n", + "\n", + "Redesign the budget as a fixed wall-clock limit rather than fixed optimizer steps. Predict which architectures this favors, then explain how you would keep the comparison reproducible on machines with different performance. Do not implement the change until the decision rule and timing protocol are written down." + ] + }, + { + "cell_type": "markdown", + "id": "reference-discussion", + "metadata": {}, + "source": [ + "### Reference discussion for the recorded run\n", + "\n", + "Exact values may change with PyTorch versions and hardware, but the interpretation should follow the same rules.\n", + "\n", + "1. The best exploratory score was C1, the TPE proposal with width 64 and two hidden layers ($9.329\\times10^{-2}$). After longer training with fresh seeds, C2, the random-search proposal with four hidden layers, had the lowest mean validation error ($5.619\\times10^{-2}$). The longer budget and training randomness can both change the ranking; the exploratory score was a screening result, not a final estimate.\n", + "2. C2's seed standard deviation was $3.31\\times10^{-3}$, while C1's was $1.87\\times10^{-2}$. C2 was better under the declared mean-error rule and less variable in these three runs. Three seeds are still too few to claim that four layers are generally optimal.\n", + "3. Under this one eight-trial search, TPE found $9.329\\times10^{-2}$ and random search found $9.910\\times10^{-2}$. The difference is small and the search algorithms themselves were not repeated, so this is not evidence of general TPE superiority.\n", + "4. Under the declared error-only rule, C2 is selected. With a limit of 5,000 parameters, C2 is ineligible and C1, with 4,609 parameters, becomes the best confirmed eligible candidate. This conclusion is valid only because the constraint is stated before choosing.\n", + "5. The last-batch physics loss is a noisy, local training diagnostic. The validation error compares complete predicted trajectories with an independent reference. The table shows correlation in this run, but the quantities are not interchangeable.\n", + "6. The audit mean was $5.276\\times10^{-2}$ with a seed standard deviation of $7.02\\times10^{-3}$. That is the final reported estimate for this experiment. If it had been disappointing, the honest response would be to report it, design a revised experiment, and reserve a new audit suite—not tune against this one.\n", + "\n", + "For the transfer task, a wall-clock budget will usually favor smaller models, but timing is machine- and load-dependent. A defensible protocol needs a specified hardware and software environment, warm-up policy, repeated timings, and a rule for handling noise or interruptions." + ] + }, + { + "cell_type": "markdown", + "id": "next-steps", + "metadata": {}, + "source": [ + "## 12. Takeaways and limitations\n", + "\n", + "- Hyperparameter optimization is an experimental design problem before it is a framework problem. The objective, evidence split, stochastic repetitions, and budget determine what the result means.\n", + "- A small plain-Python random search exposes the mechanism and provides a baseline. Optuna then changes candidate generation without hiding the rest of the experiment.\n", + "- The best exploratory trial is subject to winner's curse: searching many noisy outcomes preferentially selects an optimistic one. Fresh-seed confirmation reduces this risk.\n", + "- Confirmation seeds address training variability. They do not repair an unrepresentative validation suite or establish that the chosen search algorithm is universally superior.\n", + "- The final audit estimates performance on another fixed sample from the in-range parameter domain. It says nothing about extrapolation beyond that domain.\n", + "- Equal epochs and batches are not equal compute. If accuracy, runtime, memory, and model size all matter, declare a constraint or a multi-objective decision rule rather than selecting one after seeing the plot.\n", + "- This heat equation has an analytical solution and does not need a PINN. That makes it valuable for controlled teaching, but it is not evidence that PINNs outperform conventional solvers.\n", + "\n", + "## References\n", + "\n", + "- [Optuna: efficient optimization algorithms](https://optuna.readthedocs.io/en/stable/tutorial/10_key_features/003_efficient_optimization_algorithms.html)\n", + "- J. Bergstra and Y. Bengio, [Random Search for Hyper-Parameter Optimization](https://www.jmlr.org/papers/v13/bergstra12a.html), *Journal of Machine Learning Research* 13 (2012).\n", + "- M. Raissi, P. Perdikaris, and G. E. Karniadakis, [Physics-informed neural networks](https://doi.org/10.1016/j.jcp.2018.10.045), *Journal of Computational Physics* 378 (2019)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.14.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/source-code/parameter-optimization/optuna/simple.py b/source-code/parameter-optimization/simple.py similarity index 100% rename from source-code/parameter-optimization/optuna/simple.py rename to source-code/parameter-optimization/simple.py diff --git a/source-code/pinns/README.md b/source-code/pinns/README.md index 2ce7f4f..c2e694b 100644 --- a/source-code/pinns/README.md +++ b/source-code/pinns/README.md @@ -11,5 +11,15 @@ equations in the loss function. equation using a PINN. 1. `pendulum.ipynb`: Jupyter notebook solving the equation of a pendulum with damping using a PINN. - equation using a PINN. -1. `environment.yml`: conda environment specification file. +1. `parameterized_heat_equation.ipynb`: Jupyter notebook training one PINN + across a family of heat equations with varying initial conditions and + diffusivities. It uses hard initial and boundary constraints and validates + interpolation and extrapolation against the analytical solution. + +All notebooks in this directory run in the repository's standard +[CPU](../../environment.yml) or [GPU](../../environment_gpu.yml) environment. + +The [PINN hyperparameter-optimization case study](../parameter-optimization/parameterized_heat_equation_optimization.ipynb) +is kept with the parameter-optimization material because its primary subject is +experimental methodology; it uses the parameterized heat equation as its +realistic example. diff --git a/source-code/pinns/environment.yml b/source-code/pinns/environment.yml deleted file mode 100644 index 7c34b76..0000000 --- a/source-code/pinns/environment.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: pytorch -channels: - - conda-forge -dependencies: - - jupyterlab - - matplotlib - - pytorch - - scipy - - torchopt - - torchvision - -prefix: "/home/gjb/mambaforge/envs/pytorch" diff --git a/source-code/pinns/logistic_de.ipynb b/source-code/pinns/logistic_de.ipynb index ed080d7..19c9350 100644 --- a/source-code/pinns/logistic_de.ipynb +++ b/source-code/pinns/logistic_de.ipynb @@ -13,14 +13,26 @@ "execution_count": 1, "id": "420984ea-3335-42a0-858e-0a1d4435e157", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from collections import OrderedDict\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import torch\n", "from torch.func import functional_call, grad, vmap\n", - "import torchopt" + "\n", + "torch.manual_seed(42)" ] }, { @@ -271,7 +283,7 @@ "id": "051f42f9-3337-4f9d-94a4-b4901c21f24b", "metadata": {}, "source": [ - "We will use an Adam optimizer to minimize the loss function using the learning rate as a parameter." + "We use PyTorch's Adam optimizer to update the model parameters. The derivatives with respect to time still come from `torch.func`; differentiating with respect to the model parameters and applying an optimizer step use the standard `backward()` workflow." ] }, { @@ -291,7 +303,7 @@ "metadata": {}, "outputs": [], "source": [ - "optimizer = torchopt.FuncOptimizer(torchopt.adam(lr=learning_rate))" + "optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)" ] }, { @@ -299,7 +311,7 @@ "id": "425282a0-9c4e-4b6b-b921-da1616199af3", "metadata": {}, "source": [ - "Now we get the neural network's current parameters as a tuple." + "The functional forward and derivative functions expect the model parameters as a tuple. These entries refer to the same parameter objects that Adam updates in place." ] }, { @@ -335,149 +347,31 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 1 with loss 3.12261e-01\n", - "Epoch 2 with loss 6.25678e-02\n", - "Epoch 3 with loss 1.20098e-01\n", - "Epoch 4 with loss 6.99897e-02\n", - "Epoch 5 with loss 8.25822e-02\n", - "Epoch 6 with loss 6.09384e-02\n", - "Epoch 7 with loss 6.43098e-02\n", - "Epoch 8 with loss 6.84182e-02\n", - "Epoch 9 with loss 6.65103e-02\n", - "Epoch 10 with loss 6.48356e-02\n", - "Epoch 11 with loss 5.96315e-02\n", - "Epoch 12 with loss 5.24541e-02\n", - "Epoch 13 with loss 4.38570e-02\n", - "Epoch 14 with loss 5.89740e-02\n", - "Epoch 15 with loss 4.38067e-02\n", - "Epoch 16 with loss 3.57324e-02\n", - "Epoch 17 with loss 3.05979e-02\n", - "Epoch 18 with loss 4.51232e-02\n", - "Epoch 19 with loss 2.38443e-02\n", - "Epoch 20 with loss 9.11335e-03\n", - "Epoch 21 with loss 3.09037e-02\n", - "Epoch 22 with loss 6.16947e-03\n", - "Epoch 23 with loss 2.87395e-02\n", - "Epoch 24 with loss 1.45336e-02\n", - "Epoch 25 with loss 1.81223e-02\n", - "Epoch 26 with loss 1.17420e-02\n", - "Epoch 27 with loss 1.08394e-02\n", - "Epoch 28 with loss 8.74930e-03\n", - "Epoch 29 with loss 4.74045e-03\n", - "Epoch 30 with loss 8.05342e-03\n", - "Epoch 31 with loss 2.07800e-03\n", - "Epoch 32 with loss 8.86609e-03\n", - "Epoch 33 with loss 1.63103e-03\n", - "Epoch 34 with loss 7.16136e-03\n", - "Epoch 35 with loss 1.25232e-03\n", - "Epoch 36 with loss 6.01959e-03\n", - "Epoch 37 with loss 1.04602e-03\n", - "Epoch 38 with loss 4.38662e-03\n", - "Epoch 39 with loss 1.02280e-03\n", - "Epoch 40 with loss 3.45627e-03\n", - "Epoch 41 with loss 1.13875e-03\n", - "Epoch 42 with loss 2.35877e-03\n", - "Epoch 43 with loss 2.57926e-03\n", - "Epoch 44 with loss 1.18175e-03\n", - "Epoch 45 with loss 2.07102e-03\n", - "Epoch 46 with loss 8.33326e-04\n", - "Epoch 47 with loss 1.92634e-03\n", - "Epoch 48 with loss 9.84188e-04\n", - "Epoch 49 with loss 1.48030e-03\n", - "Epoch 50 with loss 1.00213e-03\n", - "Epoch 51 with loss 9.89608e-04\n", - "Epoch 52 with loss 1.04931e-03\n", - "Epoch 53 with loss 5.58622e-04\n", - "Epoch 54 with loss 9.80342e-04\n", - "Epoch 55 with loss 1.75986e-04\n", - "Epoch 56 with loss 1.18718e-03\n", - "Epoch 57 with loss 1.23530e-04\n", - "Epoch 58 with loss 8.41206e-04\n", - "Epoch 59 with loss 1.32893e-04\n", - "Epoch 60 with loss 5.74356e-04\n", - "Epoch 61 with loss 2.63709e-04\n", - "Epoch 62 with loss 4.40693e-04\n", - "Epoch 63 with loss 3.53943e-04\n", - "Epoch 64 with loss 1.76223e-04\n", - "Epoch 65 with loss 4.62567e-04\n", - "Epoch 66 with loss 3.58829e-05\n", - "Epoch 67 with loss 4.24251e-04\n", - "Epoch 68 with loss 9.55534e-05\n", - "Epoch 69 with loss 2.63343e-04\n", - "Epoch 70 with loss 1.97777e-04\n", - "Epoch 71 with loss 9.55289e-05\n", - "Epoch 72 with loss 2.60386e-04\n", - "Epoch 73 with loss 9.69301e-05\n", - "Epoch 74 with loss 1.89340e-04\n", - "Epoch 75 with loss 7.50615e-05\n", - "Epoch 76 with loss 1.62381e-04\n", - "Epoch 77 with loss 8.87464e-05\n", - "Epoch 78 with loss 8.52953e-05\n", - "Epoch 79 with loss 1.25937e-04\n", - "Epoch 80 with loss 3.56436e-05\n", - "Epoch 81 with loss 1.93949e-04\n", - "Epoch 82 with loss 4.53294e-05\n", - "Epoch 83 with loss 7.96346e-05\n", - "Epoch 84 with loss 9.84911e-05\n", - "Epoch 85 with loss 2.34568e-05\n", - "Epoch 86 with loss 1.06834e-04\n", - "Epoch 87 with loss 3.02475e-05\n", - "Epoch 88 with loss 6.28007e-05\n", - "Epoch 89 with loss 8.52414e-05\n", - "Epoch 90 with loss 2.30894e-05\n", - "Epoch 91 with loss 7.66452e-05\n", - "Epoch 92 with loss 2.85219e-05\n", - "Epoch 93 with loss 5.83988e-05\n", - "Epoch 94 with loss 5.22415e-05\n", - "Epoch 95 with loss 2.81195e-05\n", - "Epoch 96 with loss 4.33593e-05\n", - "Epoch 97 with loss 3.01600e-05\n", - "Epoch 98 with loss 2.76552e-05\n", - "Epoch 99 with loss 3.77898e-05\n", - "Epoch 100 with loss 3.11008e-05\n", - "Epoch 101 with loss 3.12167e-05\n", - "Epoch 102 with loss 3.11700e-05\n", - "Epoch 103 with loss 3.91574e-05\n", - "Epoch 104 with loss 1.40297e-05\n", - "Epoch 105 with loss 3.03982e-05\n", - "Epoch 106 with loss 1.59833e-05\n", - "Epoch 107 with loss 1.59673e-05\n", - "Epoch 108 with loss 1.36748e-05\n", - "Epoch 109 with loss 2.06822e-05\n", - "Epoch 110 with loss 1.58647e-05\n", - "Epoch 111 with loss 1.79472e-05\n", - "Epoch 112 with loss 1.66825e-05\n", - "Epoch 113 with loss 1.43707e-05\n", - "Epoch 114 with loss 1.70082e-05\n", - "Epoch 115 with loss 2.17944e-05\n", - "Epoch 116 with loss 1.47123e-05\n", - "Epoch 117 with loss 1.64711e-05\n", - "Epoch 118 with loss 1.75252e-05\n", - "Epoch 119 with loss 2.00743e-05\n", - "Epoch 120 with loss 1.15596e-05\n", - "Epoch 121 with loss 1.56640e-05\n", - "Epoch 122 with loss 1.08105e-05\n", - "Epoch 123 with loss 1.18596e-05\n", - "Epoch 124 with loss 1.16240e-05\n", - "Epoch 125 with loss 1.06298e-05\n", - "Epoch 126 with loss 1.55553e-05\n", - "Epoch 127 with loss 1.34743e-05\n", - "Epoch 128 with loss 1.37127e-05\n", - "Epoch 129 with loss 1.24063e-05\n", - "Epoch 130 with loss 1.00807e-05\n" + "Epoch 1 with loss 6.89677e-01\n", + "Epoch 26 with loss 3.64968e-02\n", + "Epoch 51 with loss 5.85542e-03\n", + "Epoch 76 with loss 3.83922e-04\n", + "Epoch 101 with loss 6.83883e-05\n", + "Epoch 126 with loss 3.58403e-05\n", + "Epoch 151 with loss 1.32103e-05\n", + "Epoch 160 with loss 8.12446e-06\n" ] } ], "source": [ "losses = []\n", "for epoch in range(nr_epochs):\n", - " t = torch.FloatTensor(batch_size).uniform_(*input_domain)\n", + " t = torch.empty(batch_size).uniform_(*input_domain)\n", + " optimizer.zero_grad(set_to_none=True)\n", " loss = loss_function(params, t)\n", - " losses.append(float(loss.detach()))\n", - " if losses[-1] < loss_threshold:\n", + " loss_value = loss.item()\n", + " losses.append(loss_value)\n", + " if epoch % 25 == 0 or loss_value < loss_threshold:\n", + " print(f'Epoch {epoch + 1} with loss {loss_value:.5e}')\n", + " if loss_value < loss_threshold:\n", " break\n", - " params = optimizer.step(loss, params)\n", - " print(f'Epoch {epoch + 1} with loss {float(loss.detach()):.5e}')" + " loss.backward()\n", + " optimizer.step()" ] }, { @@ -496,7 +390,7 @@ "outputs": [ { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -550,7 +444,7 @@ }, { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -590,7 +484,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.14.2" + "version": "3.14.6" } }, "nbformat": 4, diff --git a/source-code/pinns/parameterized_heat_equation.ipynb b/source-code/pinns/parameterized_heat_equation.ipynb new file mode 100644 index 0000000..a88a19a --- /dev/null +++ b/source-code/pinns/parameterized_heat_equation.ipynb @@ -0,0 +1,1000 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "9b0c8471", + "metadata": {}, + "source": [ + "# A parameterized heat equation with a physics-informed neural network\n", + "\n", + "The earlier PINN examples in this repository approximate one solution for one\n", + "set of parameters. Here, one neural network approximates an entire family of\n", + "solutions. Its inputs specify position, time, the initial condition, and the\n", + "diffusivity.\n", + "\n", + "## Learning objectives\n", + "\n", + "After working through this notebook, you should be able to:\n", + "\n", + "- distinguish a PINN for one solution from a finite-dimensional parameterized\n", + " solution map;\n", + "- construct a trial solution that satisfies initial and boundary conditions\n", + " exactly;\n", + "- use automatic differentiation to form a partial-differential-equation\n", + " residual;\n", + "- validate a PINN on parameter combinations that were not used as labelled\n", + " training data;\n", + "- explain why interpolation, extrapolation, and a small residual are different\n", + " claims about model reliability.\n", + "\n", + "The default configuration normally runs in well under two minutes on a recent\n", + "CPU. The notebook needs PyTorch, NumPy, and Matplotlib from the [standard CPU environment](../../environment.yml); the [GPU environment](../../environment_gpu.yml) is optional.\n", + "Training uses no exact or numerical solution values; the analytical solution is\n", + "reserved for validation." + ] + }, + { + "cell_type": "markdown", + "id": "4096cc5c", + "metadata": {}, + "source": [ + "## 1. Setup\n", + "\n", + "The random seed makes a CPU execution reproducible for a fixed software\n", + "stack. Results can still differ between PyTorch versions and hardware\n", + "backends. CPU is the default because GPU launch and transfer overhead can\n", + "outweigh acceleration for this small network and collocation batch. Create\n", + "`TrainingConfig(use_cuda=True)` to benchmark your hardware rather than\n", + "assuming that an accelerator will be faster.\n", + "\n", + "Problem and training settings are collected in immutable configuration\n", + "objects. Helper functions receive the configuration they need explicitly;\n", + "they do not depend on module-level constants." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "e7522c59", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Using device: cpu\n" + ] + } + ], + "source": [ + "import math\n", + "import time\n", + "from dataclasses import dataclass\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import torch\n", + "from torch import nn\n", + "\n", + "\n", + "@dataclass(frozen=True)\n", + "class ProblemConfig:\n", + " x_min: float = 0.0\n", + " x_max: float = 1.0\n", + " t_min: float = 0.0\n", + " t_max: float = 1.0\n", + " coefficient_min: float = -1.0\n", + " coefficient_max: float = 1.0\n", + " kappa_min: float = 0.05\n", + " kappa_max: float = 0.20\n", + "\n", + " def input_bounds(self):\n", + " lower = torch.tensor(\n", + " [\n", + " self.x_min,\n", + " self.t_min,\n", + " self.coefficient_min,\n", + " self.coefficient_min,\n", + " self.kappa_min,\n", + " ]\n", + " )\n", + " upper = torch.tensor(\n", + " [\n", + " self.x_max,\n", + " self.t_max,\n", + " self.coefficient_max,\n", + " self.coefficient_max,\n", + " self.kappa_max,\n", + " ]\n", + " )\n", + " return lower, upper\n", + "\n", + "\n", + "@dataclass(frozen=True)\n", + "class TrainingConfig:\n", + " seed: int = 1729\n", + " use_cuda: bool = False\n", + " epochs: int = 5_000\n", + " collocation_batch_size: int = 512\n", + " learning_rate: float = 2.0e-3\n", + " report_every: int = 500\n", + "\n", + "\n", + "def seed_everything(seed):\n", + " torch.manual_seed(seed)\n", + " if torch.cuda.is_available():\n", + " torch.cuda.manual_seed_all(seed)\n", + "\n", + "\n", + "problem = ProblemConfig()\n", + "training = TrainingConfig()\n", + "\n", + "seed_everything(training.seed)\n", + "using_cuda = training.use_cuda and torch.cuda.is_available()\n", + "device = torch.device(\"cuda\" if using_cuda else \"cpu\")\n", + "print(f\"Using device: {device}\")" + ] + }, + { + "cell_type": "markdown", + "id": "f654a72b", + "metadata": {}, + "source": [ + "## 2. Define the family of problems\n", + "\n", + "We solve the dimensionless heat equation\n", + "\n", + "$$\n", + "\\frac{\\partial u}{\\partial t}\n", + "=\n", + "\\kappa\\frac{\\partial^2 u}{\\partial x^2},\n", + "\\qquad 0\\leq x\\leq 1,\\quad 0\\leq t\\leq 1,\n", + "$$\n", + "\n", + "with homogeneous Dirichlet boundary conditions\n", + "\n", + "$$\n", + "u(0,t)=u(1,t)=0\n", + "$$\n", + "\n", + "and the parameterized initial condition\n", + "\n", + "$$\n", + "u(x,0)=a_1\\sin(\\pi x)+a_2\\sin(2\\pi x).\n", + "$$\n", + "\n", + "The coefficients $a_1$ and $a_2$ select an initial temperature profile, while\n", + "$\\kappa$ controls how quickly it diffuses. We train over\n", + "$a_1,a_2\\in[-1,1]$ and $\\kappa\\in[0.05,0.20]$.\n", + "\n", + "Restricting the initial condition to two basis functions makes this a\n", + "**finite-dimensional parameterized solution map**, not a neural operator for\n", + "arbitrary input functions." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e4fe2d38", + "metadata": {}, + "outputs": [], + "source": [ + "def initial_profile(x, a1, a2, *, x_min, x_max):\n", + " scaled_x = (x - x_min) / (x_max - x_min)\n", + " return (\n", + " a1 * torch.sin(math.pi * scaled_x)\n", + " + a2 * torch.sin(2.0 * math.pi * scaled_x)\n", + " )\n", + "\n", + "\n", + "def exact_solution(inputs, problem):\n", + " # Used only to evaluate the trained PINN, never during training.\n", + " x, t, a1, a2, kappa = inputs.unbind(dim=1)\n", + " length = problem.x_max - problem.x_min\n", + " elapsed_time = t - problem.t_min\n", + " first_rate = (math.pi / length) ** 2\n", + " second_rate = (2.0 * math.pi / length) ** 2\n", + " profile_1 = initial_profile(\n", + " x,\n", + " a1,\n", + " torch.zeros_like(a2),\n", + " x_min=problem.x_min,\n", + " x_max=problem.x_max,\n", + " )\n", + " profile_2 = initial_profile(\n", + " x,\n", + " torch.zeros_like(a1),\n", + " a2,\n", + " x_min=problem.x_min,\n", + " x_max=problem.x_max,\n", + " )\n", + " return (\n", + " torch.exp(-kappa * first_rate * elapsed_time) * profile_1\n", + " + torch.exp(-kappa * second_rate * elapsed_time) * profile_2\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "2e45fd09", + "metadata": {}, + "source": [ + "The second spatial mode has four times the decay rate of the first. Before\n", + "running the next cell, predict how increasing $\\kappa$ changes each curve and\n", + "which mode will disappear first." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "0514253a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAGGCAYAAADmRxfNAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQAAtjpJREFUeJzs3QV4U2cXB/B/3UuVCoViLV7c3V2G24AhQzeGfRs2tjFsYzBgG7DBhvtwd6e4FStWKtTdNd9z3ktLC4VVksbO73nyNEnb5PYmbe+57xEdmUwmA2OMMcYYY4wVgm5hvpkxxhhjjDHGOLBgjDHGGGOMyQWvWDDGGGOMMcYKjQMLxhhjjDHGWKFxYMEYY4wxxhgrNA4sGGOMMcYYY4XGgQVjjDHGGGOs0DiwYIwxxhhjjBUaBxaMMcYYY4yxQuPAgjGmURwdHTFy5MgifU6ZTIZvv/0Wrq6u0NPTQ506daCudu3aBR0dHdy4cUOhz3Py5EnxPGfPni2S7y/M8xV2W5Xp8ePHYtvXrVunlH0nD76+vujWrRtsbGzEdvz6669F+vy5/fzK3ieMqSoOLBjTAhUrVhT/BHO76OvrK3vz1N727dsxd+5crFmzBqmpqQo/KC+sgwcPitf+4sWL0CSa+nNp+74bN24cfHx88OjRIxHEf/XVV8reJMbYB/ARBWNaokqVKvDy8lL2Zmikc+fOoXjx4mjbtq2yN0VttGnTRhwkFtX3F/b5NIm67bvz589j1KhRcHBwUMrzK/vnZ0yd8IoFY4wVUlhYGExMTHg/MiZnycnJiI2N5d8vxtQEBxaMsSw7duwQ6RA//fRTjr2yYcMGcf+KFSuy7qtRo0aOdKoSJUpg2LBhCAwMzPG9xsbGInWBcpFr164NU1NT1K1bF7du3RKfP336tLhNB+aVKlXCiRMn3ntFMh/jzJkzqFWrlrjt5uaGlStX5vnVoxxzeh56fgsLC7Rr1+69lCWqL2jQoAGsrKxga2uLVq1a4dixYx98TErPoJ+fvu/Vq1dZ+4NSorJvN51xpcel2wsXLhSfe/nyJQYOHAh7e3sYGRmhQoUK+PHHH5GWlpZje+jxrl+/Lj7n7OyMYsWKYejQoUhMTBRnUX/44Qe4uLiIn6t79+4iyPmY3377DV27dhXXmzZt+t42Z7d48WKULFlSvDbNmzfPdcUrMjISkyZNQunSpWFoaCi2ccKECYiJifnoduSWo569vuO/nvvd7/+vnyu356PHzJ4WSM9VrVo1LFmypFBnqGmfTJkyBeXLlxevOX2cOXMm4uLisr4mP69/XvZH5s9D72t6L9DZ/RkzZiA9Pf0/931B9p2ifobs6LFo/5F58+ZlbVdSUlKeXzt5/A7lpZ7iwYMH4mvoZ3yXt7c3dHV1MX/+/I/+vIxpBBljTONVqFBBVqVKlTx97RdffCHT09OTnT17Vty+d++ezMTERNavX78Pfk9CQoLs8uXLsho1asjq1asnS0tLy/qckZGRrGPHjrIBAwbIXrx4IQsODpZ16dJFVrx4cdmFCxdkffr0kT179kwWEhIi69Gjh8zCwkIWGRmZ4/HpMTp06CA+7+3tLQsNDZXNnz9fpqOjI1uyZEmOr3VwcJCNGDEix31Tp04Vj7Fs2TLx/AEBAbJx48bJjI2NZbdu3RJfc/78efF4CxculIWFhcmio6PFfbTt2X+e3PTq1Uvm6ur63v2ZPztt9+PHj2WvXr2SHThwQObn5yezt7eX1axZU3bz5k1ZVFSUbOPGjTJTU1OxPzLt3LmTjpDEvv/9999lERERsitXrsjs7Oxko0ePls2ePVu2fPlycf/Vq1fFPu3fv7/sv9A20OPS/n9X5nMOGjRI7FvaF7Tt1apVk7m5ueXYF7TdFStWFJfTp0/LYmNjZdevX5dVrVpV1qBBA1lqauoHt+HEiRPiec6cOVOg587t+z/2c+X29e+i51uzZo14XyxdujRf35uJXgt3d3dZ2bJlZYcPHxb76Pnz57IFCxbI1q9fL74mv69/XvYHvbesra1lTZo0kXl5ecnCw8NlK1askPXu3Vs8xj///CPXfaeInyE3iYmJ4vtnzpz50a/70Gsnj9+h3H7+3O5r3ry5rFy5crKMjIwc3//VV1+Jv6n0d4cxTceBBWNaEljQP8HcLq1bt87xtSkpKeKg0NHRURwA0D9/OnCkg8b/QsEIPeaNGzdyHFzTP+v4+Pis+x4+fCi+jg7G4+Lisu5/8uSJuH/16tU5Hpcew8rKShYTE5PjfjposrS0zPEY7wYWdJBFAcOcOXNyfC/98/fw8JB17txZ3P7xxx9lurq6Hz0YLkhgQdv37nZTUKOvry8OOLOjg8/sB3eZB0VjxozJ8XUzZswQjz127Ngc99NBEh3AvPt8BQksPv/88xz379u3T9x/6tSprPumT58unu/Ro0c5vvbu3bvia7du3VqgwCIvz62IwCLTyJEjxXu+IN9LQSy9j+7fv//Br8nv65+X/UHvBXpPBAYG5vhaeu8oIrBQxM9QmMDiQ6+dPH6H8hpYbN++Xdx39OjRHCddKODL/DvDmKbjVCjGtKh4+83JhBwXWubPzsDAQKREUToDpTu9fv1apBOYm5vn+Lp79+6hV69eor0rpUJRGkCLFi3E5549e5bjayntgdIMMrm7u4vUAEprMjMzy7qf0pvosV68ePHe9rds2VKkMGXXo0cPkXLzsS5M1O2Gfs4+ffrkuJ+2l1KdqPCaVK9eHRkZGRgwYIBIXUpJSYE85Lbdp06dEvu2bNmyOe7v3bt31uez69ix43tdvij3nIpKs6NUMkp9obSswurcuXOO21WrVhUfs782Bw4cEOkntD3ZeXh4wM7OLmvfKuK55eXvv/8WaWqWlpY5UoDefQ9nRylN73ZXo3QicvjwYfHzZ25zbvL7+udlf9D31KtXT/w+vvs7ogiK+BkU+doVxe/QJ598AicnJ/zxxx9Z923dulWkxo0YMSLfj8eYOuLAgjH2HsqDplxtymWm3GsKSrLz8/NDkyZNxAEW1SBQcSUdvGce4FPL1ezon212NOuBcqLfvZ8ODCjQiIqKem+bcusIk3nfx+oKgoKCsgIHClrouSmooQv1w6efgYKILl264M8//xQtLSkQojxs2gdHjx4t1DuEak/eFR4e/t4BIMm8792f5939lBmofOj+3PZffr372HTw9u5j0769e/eu2K/Z9y29jvQz0M+pqOeWBwoG6ICPDggpR57et5ntTLPXCeRHSEhIrq+5PF//3PYHPebHfkfkTRE/gyJfu6L4HaKTMtS96tChQ+JvJKE6MOoYR39fGNMGHFgwxt6zbds2bNmyBfXr1xfX9+7dm+Pze/bsEcEE/dOkA/bMjkhUzJkbOtDMz/25CQ4O/uB9VGj9IXTmnDx//lwccNDZSFqZoEvmqg0VHRM6KKCiUHrcjRs3iuLOTp064cKFCygoOth4Fw36+tjPk7nN8tx/+ZWXx6btbNy4sdiv2fdt5n6llS9FPbc8UFOChg0b4uuvvxbBdOZMlw+9jzPR6t27K39UsE6okDkgIOCj3y+v1z87+h342GPKmyJ+BkW+dkX1OzR69GjxmKtXrxYnWugyZMiQXP8OMKaJOLBgjOVAZ+zpAJu6o1y+fBnt27cX3Z5yS1mgTjDv/rNXFOrIkr2rDtm3b584w0jdnj4k80whDbHLKzrDSCkdFFzQQWNhAovctG7dGrdv334v3eLff//N+rwiZaafUSpIYdBqFnXb+a8D8aJSkJ/r3fcwHRgfP368wNtA7zdKE/xYxyNFvP6U1kevxbsH+/Q7khf53XfKfg8r4rWTB+o6RX87KSUrc0I4p0ExbcKBBWMsS3x8vDigpvSJ9evXi7SWzZs3i7QFup9SowgFG3SWf+rUqSL1g+ow6Mzhu//o5Ynyx6lFJOVPUxoGtcSlg5hvv/02R53Gu2hFZdq0aeLrfv75Z/j6+oqVCEqfoNaQmWeaZ8+ejTlz5oiDwoSEBPFzUa40nX2k1Ch5mj59umhpSzUqd+7cEXUitEJE07t79uwp0swUifLL6QwvpXllvqYFQe1My5UrJ/Lnjxw5InLJ6bWh6c3Dhw8XNRhFKb8/V7du3UQ9zaZNm8R7nw6U6X3+bt59fnzzzTdin9DBJW0HvbYUeFGb4czAWxGvP/3+UWvWvn37ipMD9FrQiuJ/tR8u6L5T9ntYEa+dvIwfP14EOfS3s1GjRu/VIDGmyTiwYExLZPZZz+2SWez4+eefi4MgOmCnGoPMFAtKaaEzsF9++aW4j/rVU3rUkydPxPwCSkmgr6eDd0Whf85jx44VBw+Uw071EMuXLxfBzX+hIIQCJSrkpqJRStPo37+/OAimAyQyceJEESxR8ELpLPR1dMBENSSU7iNPlLrh6ekp5hvQgRBtDwU1FABR6pmiUV457Tt6nSmt50NzLP4LHVheuXJFFAjTLAvKr6fi11mzZolgjALQopTfn4sOxulC7wF6zen9RbMOKleuXKgUIXptaeVizJgx4nGpVodW2+iAW1GvP/0e0oE2vYdpXgz9jtKcFXpcRew7Zb+HFfHayQs1bMjcDl6tYNpGh1pDKXsjGGPsY+hMLB2kZaYWMMaYKqNuVXQyhwaGvttRjzFNxisWjDHGGGNyQitFV69eFa2rOahg2oYDC8YYY4wxOaD6LUoJpS5QlBbGmLbhwIIxxhhjrJCocJ8aSVCtC9V00cBPxrQN11gwxhhjjDHGCo1XLBhjjDHGGGOFxoEFY4wxxhhjrND0C/8Qmi8jI0MMAKMJv9TbmzHGGGOMMW0gk8kQGxsrJsvT4NyP4cAiDyiooGFAjDHGGGOMaSM/Pz+4uLh89Gs4sMgDWqnI3KGWlpbyeXUYY4wxxhhTcTExMeIEe+bx8MdwYJEHmelPFFRwYMEYY4wxxrSNTh7KAbh4mzHGGGOMMVZoHFgwxhhjjDHGCo0DC8YYY4wxxlihcWDBGGOMMcYYKzQOLBhjjDHGGGOFxoEFY4wxxhhjrNA4sGCMMcYYY4wVGgcWjDHGGGOMsULjwIIxxhhjjDFWaBxYMMYYY4wxxgpNv/APwRhjjDGWu7SMNAQnBCMkIQThieGISIpAeFI4IpMiEZ8aj4TUBOljWgJSM1KRIctAuiwdGRkZ0NHRgYGuAQz0DMRHIz0jWBhaiIuloaX4aGdih+ImxWFvao/ipsXF/fR9jLGix4EFY4wxxgodPATEBeBF1Au8iH6Bl9Ev4Rfrh8D4QBFQUKBQVEz1TVHKshRKWpQUl9KWpeFm7YZyVuVgom9SZNvBmDbiwIIxxhhj+QoiKHB4EP4AD8Ie4GH4QzyOeIyUjJQPfg+tNjiYOsDWxBY2xjZZFzMDs6wLBQS0MqGnowddHV3xUQaZWMVISU8RH5PTkxGbEouYlBjxMTo5WqyChCSGIDQhFFHJUWLlg7aHLtnpQAeulq4iyKhmVw0e9h6obFuZgw3G5IgDC8YYY4x9EKUq3Qq5hWuB13An9I44YE9MS3zv64z1jFG6WGmUKVZGXFwtXOFs7iwulK5EwYKiUeDxOu61WC3xjfGFb6yvWEV5GvVUpGD5xPiIy4lXJ8TXU/Dibu2OWg61UNexLuo41EExo2IK307GNJWOTCaTKXsjVF1MTAyKFSuG6OhoWFpaKntzGGOMMYWhoOFOyB1cD7qOa0HXxKpEmiwtx9fQ6gKd7a9iWwVV7KqI65R2VBTBQ0GFJYbBO9JbBEZeYV64G3JXrHS8u6pRybYSGjg1QDOXZqhuXx36unwOlmm3mHwcB3NgIecdyhhjjKkbSiM6538OZ/3OwjPQU5z5z66EeQnUc6yHOo51UNWuqqhbUOUgIq+C4oPEKsyNoBsiiKIUr+yoELxxicZo7tJcBBpULM6YtonhwEJ5O5QxxhhTdZSsQOlBFEjQ5X7Y/Ryfp3oICiQoPaieUz0RWGgDKjSnAONSwCVcCLggajiy14k0dm6MdqXboUXJFhxkMK0Rw4GF8nYoY4wxpqqo7uDQy0M4/OKwqDXIzsPOQxww06W8VXmtb9manpEuAq7z/udxyveU6HaVPcigVYxu5bqhiUsTcZsxTcWBhRJ3KGOMMaZqtQVHXx7F4ZeHc6xM0EyIhk4NRSBBaT40B4J92LPIZzj26hiO+xzPEWRQd6tOZTrhE7dPRCE4Y5qGAwsl7lDGGGNM2ag16zm/c9jlvQtXAq+IoXOE6iIomOhUthNalWwFc0NzZW+qWnoS8QT7n+/HwRcHRbepTDXsa6Bvhb4iXYoCN8Y0AQcWStyhjDHGmLJQm9XdT3djz9M9Yrp1JprZQGfV25duL1q/MvkFcJcDLmPf830443smq3uWtZE1erj1wMCKA+Fo5si7m6k1DiyUuEMZY4yxoh5Yd8bvjFiduPz6ctb9tsa2Ij3nk/KfiEnUTPGdtSio2/V0l+g2RfR19MXq0NAqQzlNiqktDiyUuEMZY4yxokDTp3d778aWx1sQGB+YdX8j50bo7d5b1E5wUbFyAj0q+N74cCNuBN/Iup/a1n5W5TPRbUtHR0cJW8ZYwXBgIWccWDDGGFOldKctj7aIs+MJaQlZBcQ93XqKCw2qY6qBBvH94/UPTvqezKpzqWRTCZ97fI7WpVpzgMHUgkYHFt7e3vjzzz/x+PFjLFiwANWqVfvP77l37x5Wr16N4OBg8fUTJ06ElZVVnp+TAwvGGGPKdjf0LtZ5rcNpv9NZB6nUFvbTyp+ic9nOXCyswvxi/LDh4QbsfbYXSelJWQHGhJoT0LREUw4wmErLz3GwWo3NpECia9eu0NPTw6FDhxAe/rYw7UOuXbuG+vXrIyMjQ3zvsWPH0KRJEyQmJhbJNjPGGGMFRef+rgddx8hjIzH48OCsM9+UVrO6zWrs7rZbrFJwByLVVtKyJGY2mInjvY+L1QpTfVM8iniE8afGi9eVamPU7DwvY+q/YvH69Ws4OTkhICAAJUuWxJkzZ9CiRYuPfk/r1q1hbm6Offv2idtRUVFwcXHBwoULMWHChDw9L69YMMYYK0r0r/nS60v4896fuB1yO6sQuGu5rhhSeQjKW5fnF0SNRSZF4p8H/2Dro61ZKxi1HWrji5pfiI+MqRKNToUi/v7+eQoskpKSRFCxdu1aDB06NOv+7t27Iz09HQcPHszT83FgwbRaRrp00TMAuOCQFSH695Qho2LYDOjq6EBPRwe6ujoa/zNThycKKB6EPxD3GeoailWJ4VWHw8ncSdmbyOQ8vHDt/bXY8WQHUjJSxH1tSrXB5NqTxSoHY6ogP8fB+tBgvr6+IoCgFYrsMoOSD0lOThaX7DuUMY2RmgRE+QKRPtIl6hUQFwIkhAMJYUBCBJAcC6SnAGnJgCz97ffSwCc9Q8DAGDCxBkxt31xsAEsXwLr024t5cQ5EtEBSajqiE1PfXhKyXU9MRUxSKhJT0pGQko7E1HTx9YlvrovbKelITstAWoYM6dkvMunjuyi2pQBDTzfnRV9XFyaGujAx0BMXY/poqPf2tqEeLIz0YWligGIfuNDn6LGUFVDQILvlt5ZnBRQm+ibo495HtCotblpcKdvFFItminxd72vxGq++t1oU5FO62zn/cxhcaTBGeYyChaEFvwxMbWh0YJGSIkX/pqamOe6n25mf+1Atx/fff6/w7WNM4ShgCLgFBN8HgujiBUS8oMOYgj1eerJ0SYkF4kM//rX0z9ChCuBYDXCs+uajh7TywVRaRoYMYfHJCIxKQkhsMsLikhEa+/Yibr+5jwKGokRr7GkymQhE5I2CFmtTQ9ibG8HeQrrYmRtmXbc3N4aDpRGcrUxgZqQv16JsCiiuBV3LCihosNqQKkNEtyem+WiI3pyGc8Tr/vP1n0WQSalSNHhvfI3xYsVKX1ejD9mYhtDod2lm56eIiIgc91PR98e6Qk2fPh2TJ0/OsWJBqxyMqTxagfC5BPheBl5dASKef/igX6wsuL5ZXXAAzOzerkAYWUgrE/q0QmEE6OoC6anSCgatZKQmAomRb1Y4woH4cCDa780qyCsgxl8KPvw8pUsmA1PApQ5QqhFQqoF0MTApst3DJLQSEBCZCP/IBPhHJeJ1VKK4/To682MSUtKkrkN5QSf5310JyLxtaWwAcyNpBcHUUD9rVUGsKLy5z1Bf982qQ85VCEp/ovtE+tOblChaycjIkK5nfZTJkJoue281hK7TfRT80CUuOS3nakq26/R5Cloi4lPE5Ulw7Ed/ZitTAzgXM0EJaxOUsJIuFHDQbVcbU1ibGf7nfnsa+RQrbq8QqU+EZk70q9API6qN4OnYWsrN2g2r267GhYALIsDwifHBXM+52Pp4K2bUn4G6jnWVvYmMaW9gUaJECdja2uLu3bvo3Llz1v137txBzZo1P/h9RkZG4sKYyktLkYKIpyeAp8eBMO93vkAHsK8IOHkADm9WDegjBRGKrJeg7aKgRqySvLkE3pGCkZfnpQvRNwHKNAPc2gJu7aRAh8lt1SEwJgk+YfF4GRYvPvqES9d9IxLEgfjH0NujuIURHCyN3zmD//Y63W9jbghzQ321r32gQIoCDFqN+dAKTUhMMoJikhCblIaohFRxeRiYe6osBVWl7cxQxtZU+vjmQtcT0yOw/PZyHHh+ADLIoKuji27lumFs9bFwNncu8p+dqRYantfMpRkaOjcUtRd/3PkDz6KeYfix4ehRvoeov7A2tlb2ZjKmHcXbK1asEDMufv/9d3F70qRJoiPU9evXRZBx4sQJtGvXDufOnUOzZs3y9HxcvM1UCq0aPD8NeO0GnhyRVgYy6ei9WRFoCLg2AkrWk2ohVAGdXg57Ary6DPhekVZWYl/n/JriVYCqnwBVegK25ZS1pWqF/oQHRCXCOzgWT4Li8JQ+BsfiWUicqF34EFolcMl2tj37GXe67ljMGAZ6atWRvMhQ3cjrzJWeqCRplUdcl1aBgmPe1ujloJMCQ9tzMLK9AOhK6bgVLRpjSMXP0bxsNbG6w9i7opOjsezWMuz03iluWxlZYWqdqSIY5QnerChobFeoU6dOYenSpaLbE11v0KCBCBYGDhwoLmTkyJHw9PSEl5eXuB0XF4du3bqJIXnu7u64ffs2ZsyYgdmzZ+f5eTmwYCpxUP7qInB3O/D4AJAU/fZzZsWls/101r9cS8C4GNQC/ekJeSittNCKi69nzkJxpxpAtd6ARz+pEJyJVJ6Hr2PgFRCNJ0FSAEGBRPwH6hwojaiUjWnWmXLpDDp9NIVTMROlFSprOkrBotUhsVpEq0ShsbgbdRqBensAPel3Nz3BFUnBnZGRVCrr+5yKGcPdwQIVHC1QyckCVZ2Loay9Ob9OTLgTcgffX/lerF4QSoua1WAWyhYry3uIKZTGBha0UkFpTO+igIEuhAIImlXx7moE3U+Tt6tUqQJn5/wtNXNgwZQmNgi4swW4tQGIfPn2fnNHoMonQNWeQIk6Ug2EuqM0qceHAK9/gRfn3gYZVLBYoSNQa5gUOOnqQRtQd6UHr6Ph9Toa9wNi8CAgWhyk5vYX20BPB+XszbMOSt2KS9dpRUKfVx2UiobbUa48DUMjzmYl0LvMaFjJ6uBpSJwIEGm1KTBammXwLqpDqexsiarOlqhSopgINtwczHk1SUulZqRi48ONWHlnpZh/QQXdo6qNEhcDbozBFERjAwtl4cCCFSn6laRUIc8/gMeH3x5gU8F1tV5AtT5SqpMmH2DHhwEP9wJ3tgIBN97eTy1t644Aag+TWtxqCMrvpyDitm8UbvlG4q5/FPwiEnP9WjqrXcW5GCo7URBhCXcHc7ESwWlLqiU4Phi/3PgFR3yOiNvmBuZi4vLASgNznZJN9R20+uQdTMFGDB68jhH1G7l13aI0tkqOFqhZyho1S1mhVilrEURyWoz2CIgLwPyr83HeX6pXq2hTET82/hEVbCooe9OYBuLAQok7lLECo65LD/YCnr8Dr6VJu4JLPaD2UKByD8DIXPt2cPADacXm7jYgKeptd6kaA4H6YwE79ZtAHBSdJAKIW68icdsvCvcDonPtwkRpTFVLWIpAomqJYqjibCmKp5nqSk1PxaZHm7Dq7iokpCWIwuzebr0xvub4fLeOpe5dVGwvVq4CaOUqGg8CYhCbnPbe19L7olYpKxFs0EcPFysxx4NpLjovfOzVMczznIeo5CixekENAGiQIremZfLEgYWccWDBFIpat9KB86VlQEyAdB+d0azeTzpwdqjML4DYT0nAg93AlT+kuRyCDlCxM9BsGuBcQ2X/+fuEJ+Dqi3BcfRmBay8jRJHvu6xNDcSZ55pvDg4p5aWYKRfzqhPPQE9xFvlltJS2WN2+OmbWn4lKtpXk2u3LLzIBd/2jswLTh6+j3+vyRfU1FIjWL2uL+mVsUKe0jehUxTRzevfcK3Nx2u+0uF3FtgrmNZmHclbcAIPJBwcWcsaBBVOIlATg5j9SQBEX/LYQu94ooM5wqSUsyz1VzOeCFGB4H3077M+9A9Dsf4BLbaUHEs9D4+D5IkIEEhRQ0JC57KhmuqKjJWq5WqFmSWvUcrVGaVtTTmVR47Snn2/8jGM+x8RtWpmYVHuS6NpDKxaKRrM6aEWDVsEy0+ne7UxF7YMrO1mifhlb1C9rg3qlbfI0a4OpB/q7c+jlIRHYxqbEipkoE2pOwNDKQ6GnyWmzrEhwYKHEHcpYntrF3vgbuPDL2+nVxUoCTSYBNQdLQ+lY3oR6AxcWA/d3ArI3qUTl2wKtv5VmdxQRWoG4+DQUF56GwfNFOMLipFaimQz1dFGjlJU4c0wHdrQqIc/JzUw5MmQZYs7Ar7d+RXxqvAgi+lfoL9KeLA0tlXqQSUMOr70Mx9U3AS6lVL2roqMFGpe3QxM3O/HepGGFTL2FJITgu8vfiQF7mZ2j5jeZLyZ7M1ZQHFjIGQcWTG4tY6nj0em5QNQr6T4rV6DZVMCjP6DPZw8LLPy5FKhRHYYodtcBPPoCLWcqZOhebFIqrjwPx8VnYbj4NAwv3jloMzbQFWlNmWeHa5S0EpOmmeZ4FvlMtP68Eyp1KvSw88DshrNFEa0qCo5JylpBo4805+Td4Le2q7UIMpq62YlUPHUfeqitKLDc+2wvFlxbgMS0RBQzKoYfGv2AVqVaKXvTmJriwEKJO5SxXL04CxyfJU2gzmwX2+IbaYWCWwTKN8A4M08K4IieIVB3pFSDUYguUpTXToWzZ5/QqkSoyGunwtpMNA+iuksxNHWzFwdm1V2sROcepnmS05Px172/sNZrLdIy0mCqb4qJtSaiX4V+apVyQtPEaXWNAmNaaXu37sfK1ECsZjR3s0eLCvYobmmstG1lBfMq5hX+d/5/eBj+UNym9ygN1jPW59eS5Q8HFnLGgQUrsMhXwPGZwKMD0m0jS6DxRKDBWMDQjHesogTcAk7OAV5KrRhhYiOlR9Uakuc2vbQqQQddpx+H4MyTUHEglh0NnWvyJo2kYTlbnpqsBW4E3RCrFD4xPuJ2i5ItRHG2uqeZ0BluSpWiFTiRzvc8/L3OU9VKFEPLisXRqmJxeJTg1Qx16lK2/PZyrHuwTtwub1UePzf7GeWt1a+bHlMeDiyUuEMZy+r0dPFX4NKvQFoSoKMnnTlv/jVgZss7qaiKvJ+fAo7NBEIfS/c5VQc6/gyUqp/rt7wIjROBBF2u+0Tk6LRjbqQvAonmFezFx5I2pvw6aomYlBgsubEE/z6VVsLsTOwwvd50tHVtq5EF96npGbjrFyWCjLNPQkQHquzszA3RooIUZFDalIUxd5tSdZcCLmHmxZkITwoXc1S+rve1aIOsie9fJn8cWChxhzKGpyeAQ5OBKF9pZ5RuCnRcBDhU4Z2jrPkg1/4Czi4AkmOk+2oMBtrNRYaxtRhGd+xBMI4/CHqvVqKsnVnWWdq6pW04vUkLnfU7K1YpqKUn6e3eW3R8UmZxdlELjU0WAQYF3BRsxGVbzaC2trRi176KI9pVduCUKRVG7+FZl2aJIINQ17JZDWbBRN9E2ZvGVBwHFkrcoUyLxYUCR78BvHa9nRLd/kdpsB2fFVKN1+fU98DtjdJNfSsskn2GjfF1pGJvmrunpyMKrjODCUp3Ytq7SrHo2iLsf75f3C5tWRpzGs5BHUd6v2gvGuR4wydCWtl7EoIXoW+DcfozR00L2ldxEIGGqy3//qhiJ7N/vP4R6VF03d3aHUtbLEUpy1LK3jSmwjiwUOIOZVqacnNns5RyQ5OhqW99g3FAi+naOSlbBVGffzrTetQrCOGPzmFG+iq460rDCM/LauBk2a9Rt0YNUaTKaR3sYsBFzLk8R7Tu1IEOhlUZJlrIUgoJez99kFb8jj0Iwh2/qPfa2VKA0aGqo7jOaTeq41rgNUw7Pw0RSREwNzAXA/W4axT7EA4s5IwDC/bhN8drYN8EKZefOFYDui4HStTinaYCZ1YvPgvFwbuBOP4wOEf6RnFTHcy1O4m2YRugm5EKGJoD7ecBtYby6pIWi0uJw+Ibi7NqKVwtXfFj4x9Ro7hqTnVXNUHRSTj+MEgEGTQgMnvntHL2Zuji4Yyu1Z1QvriFUreTvR3sOPXc1KyWySOqjhBD9fR1eZ4Jy4kDCznjwILlukpxbwdwZBqQFA3QmcyWM4CG47l9rBKlpWfg8vNwHLz3WpxFjU5MzfqcUzHjrLOndVytoa+nC4Q9BfZ/Afhekb6ofBug2wrA0ll5PwRTCs9AT3x76VsExgeK24MrDcaXtb7k/PMCioxPwanHIWKV8PzTUBHoZ6LViy4eTiLQKM3phkqVmpEqGhNserRJ3K7nWA+Lmy+GtbG1cjeMqRQOLJS4Q5kWiA8DDn71toWscy3gk1WAfQVlb5lWohkT13wicODuaynVKf7t1Gt7CyN0rkYHME4i9zvXgV8Z6YDnSuDUD0B6MmBcDOi0GKjWh1cvtEBCagKW3FyC7U+2i9slzEtgbuO5YmIxkw9q3XziYTAO3gsUc2Cyd1urWsJSBBjdqjvD2YqLiJXlqM9RzLk0BwlpCeJ3YFnLZahgw//TmIQDCznjwILlGHS3+3MgLhig5eLm3wBNJgF6vHRc1Ghy8J7b/th7+3WO4V42ZoboWNVRHKzUK2MjhtflSegTYM9o4PVt6TYFFp2XAMZ8MkFT3Qu9h+kXpsM31jdrgNjk2pNhasCthBUlOiFVpEoduPdarC5mpktR4XeDMrboWasEOlZzEu2dWdF6HvUcX5z+An6xfmKlbkHTBWhdqjW/DAwcWMgZBxYM6WlSu9ILv1AeFGBXAei1BnDy4J1ThCLiU8TKxO5b/jl661sY6YsUp67VndGonK2U5lTQ15le43OLAFk6YF0a6LUWcNHuTkCahiZmr7m/BqvurkK6LF0MuPuh0Q9o6NxQ2ZumVcLjknHEK0j8Tl99GZF1v7GBrkhb/KRmCTEzpsC/zyzfopOjMeXcFFwNvCpuT6gxAZ97fM6F91ouJh+ZOzoyGrnJ5LZDmQaK9gd2jQD8PKXbNL25wyLAkM9qFlVHJ2ptScHE2SehSHtzhpNWIlq42+OTWiXQppIDjA3yNlE7T/yuSa95tK+0MkX1M42/yvPUbqa6/GP9xSpFZsFqx9IdMbPBTBQzKqbsTdNq/pEJ2HfnNf695Z+jhS2lM3av7ix+zys7WfIBbhHVXSy+vhhbHm8Rt9uXbi/SA3nehfaK4cBCeTuUaZjHh4C946Q2soYWQNdfgWq9lb1VGo/Od9zyjcKum/6iEDs26W1Hp2oliol0CVqdsDNXYPvPxCiplubBnreF3T3/AkxtFPecTKHvKZpJseDaAsSnxosWmzPqz0CXsl34YFXFXqd7/tHiRML+u68RmfC2AUMFBwvxu9+zlosIOJhi7fLehXlX54kVvko2lbC81XKxuse0TwwHFsrboUxDpKUAJ2YDV1dJt51rAr3/BmzKKnvLND7ViQ4otl/3w9OQuBwdnXrULIGeNUvAzaEIW1XSgi4N1Dv8PyAtEShWCui3QXo/MLVK7/jhyg84/uq4uF2reC3MbzpfFKky1UWdpM55h4paqpMPQ5CSnpE17bt1peLoX7cUmrnb572OiuXbzeCbmHx2sph3YW9ij99b/45KtpV4T2qZGA4slLdDmQaIDQZ2DHmb+tRwAtB6DqBvqOwt09iuTlTEue26L44/CM46eKA8607VnNC7lgsalLXNvaNTUQm6D2z/FIh8KbUW7vQzUHuo8raH5Rnlis+4OEMMu9PX0ce4GuMwvOpw6HFam9oVfR+6H4idN/1w2zcqx0mHPnVKom8dF7hYc3qqIryOe43xp8bjWdQzkQ5F7WibuTRTyHMx1cSBhRJ3KFNz/jeA7YOB2EDAyBLo+SdQoaOyt0pjh2ntuumH7Tf84BeRmCPVqV/dkuhWwxmWxgZQGZQatWcM4H1Eul1zsNSW1oBbZKpqnvgfd/7A2vtrIYNMDLtb2HQhqtpVVfamsUJ6EhQrVjV33/ZH1JtUKeoq1dTNHv3rlhQ1V4b6XPAtT7EpsWLlgua96OroYnq96ehfsb9cn4OpLg4slLhDmRq7tQE4NAVIT5G6PvXfAtiVV/ZWadwAuzNPQrH9uq8oyM4czGthrI8eNUqIgKJqCRUuos3IAC4uAc7MA2QZgFN1oO8GqXsUU6kzrF+f/zqrQLuXWy/8r+7/uI2sBjZ2OP4wWPw9ufQsPOt+WzNDUYvRv14plLM3V+o2alqwPvfKXOx5JtWdDasyDJNqTxKBBtNsMZwKpbwdytS0nuLo18CNv6XbFbtIA++MijCXX8OFxiaLf/5brvridXRS1v31StuIYIJSnkwM1ajj0vMzwL8jgIRwwMQG6LcJKN1Y2VvFAJzyPYXZl2aLM6xUoP1do+9EVxum2XzDE7D9hi923vBHSGxy1v2Ny9vi0wauYhWD29bKp7j+r/t/YcXtFeJ2W9e2mN9kPoz1jeXw6ExVcWChxB3K1EyOegodoNVMoMkUQJfPwMjjH9DNV5HY6PkKh+8HZk3bpQF2vWu7iIBCrc8mUhtiSpujgXq6BlLHMEqPYkqRnJ6MX278gq2Pt4rbVW2r4qfmP6GkRUl+RbRsVZTaUm97Z1WUajEG1islVjG4o1ThHXpxSATwtIrhYe+B31v9DitjKzk8MlNFHFgocYcyNRL8ENjSF4j2A6iHfa+/AHc+s1lYCSlpoh/9xiuv8DAwJuv+GiWtMKShq1idkOvMCWVKSQD2jXvbkrbRl0Cb73jeRRHzifbBtPPT8DjicVaKxpc1v4SBngrV6DClzMagVVKqxwiPTxH3GejpoGNVJ3za0BV1XK251XAh3Ai6gYlnJiImJQZlipXB6jar4WTuJK+Xj6kQDiyUuEOZmnh+GtgxFEiOAWzKAQN3cD1FIb0IjcMmT1/RtSVz7oSRvi6613DGpw1Ko5qLCtdOFLbu4txCaVo3qdBJmndhpMarMWrkwPMDmOs5F4lpibA2ssa8JvPQ1KWpsjeLqZDktHSxarrhyqscHaUqOlpgSMPS6FHTGaaG+krdRnX1POo5Rp8YjeCEYDiYOmBVm1Uob821iZpGYYFFSkoK9uzZgyNHjuDOnTuIjIwUT1S1alV06NABffr0gYmJ5nVI4cBCw9xcBxycDMjSAdfGUn48Dz0rcKvYc09D8ffFl7jwNCzr/lI2piKvuU8dF1iZakmb3ns7gX3jgfRkwKEaMGArYMVpOIqSkJoghnfR0DtS17Gu6PpU3LS4wp6TqT+vgGhsuOIjVlWT06TW1hZG+qJl7WeNS6OkDbesza+g+CARXLyIfgFLQ0sx66JG8RoKePWYxgQW6enpWLVqFX744QexbNikSRNUrFhRPElsbCyePn2KCxcuICEhAf/73/8wefJkGBpqzsEEBxYadGb51PfApV+l2x79gG4rAH2e4JpfiSnpotUjBRTPQ+Oz2j22rFBcpBg0d7NX7twJZfG7BmwbCMSHAmbFgUE7eJieAjyJeIKp56bCJ8ZHdKQZU30MPq/2Oc+mYHkWlZAiCr03XX2FV+EJ4j76k9W+iiNGNCmD2pwmlS9RSVEYf3o87oXeg7GeMX5p8QvPutAgcg8sli1bhgMHDoigoU2bNtDNpbCVHoaCi6VLl4qgY8GCBdAUHFhogNREYM9o4OE+6XaL6UDzr6WjYZZnwTFJ4mwf5S1Hvukfb26kLwqxhzYsjVK2fLYPUb7Alv5AyAPAwAzotxEo35rfZXKy++luzPOch5SMFLE6QasUtFrBWIFXXb1D8felnKuu1V2KYXiTMqImzECPm3nkdRVxyrkpuBhwEXo6evi+0ffoXr47vzE1gNwDC1qVsLDIe+vN/H69quPAQs0lREhF2v7Xpe493X8HqvdT9lapXfrA2osvcfDe66zuTi7WJviscRkx8dZClQbZqYKkGKlj1MtzgK4+0P0Pfs8VEtVQzL86H3uf7RW3m5ZoKuoprI2t5fGKMSYG79Eq7J47AUh5kyZF3aSoDoM6ShUz5b9z/4W6RM25NAcHXhwQt6fVmYYhVYbwu0vNcfG2EncoUzHRAcDGT4CwJwC1wqOhdzxvIE/SM2Q49ShYBBRXX0Zk3U+dVChVoF0VR+hpY7pTfuaj7B0LeO2SbredCzT6glfJCuBVzCsx9dc70lukPn1R8wsMrzqcB3MxhQiLS8Ymz1fiEhYndZMyMdATbbKpDqOsOrfJLgIZsgwsubEE6x+uF7fH1RiHMR5juAOXGlNoYHHlyhXs3LkTjx49EisTZmZmcHd3R48ePdC6tWYu93NgoabCnkpBBbWTtXAGPt0DFK+o7K1Si2m2u28F4K8LL/AyTKqf0NfVESkBFFBUL8m9yvNV13NiNnDlN+l2g/FAux95Tko+nHh1QvTLj0+Nh42xDX5q9hPqO9XP35uasQL+Ldx/97VYxXgcFCvuo+zZtpUcMKZFOdQqxatlH0KHln/e+xO/3fktqwX05NqTObhQUwoLLKZMmYIlS5aIQILqKKysrMSTPH/+HF5eXhg0aBA2bdoETcOBhRoKuAVs7i1NRrZ1k4IK7tDzUTFJqeIM3T+XfMSkbGJprI+B9V0xtJErnIppXse3InN5BXB8lnS9ai+gx0puGpCHlIqlN5di48ON4nat4rXwc/OfuesTK3J0mHT5ebhYvaWhe5nqlbHB2Obl0KKCPR8wfwD9/v50/Sdxva97X8xsMJNXGtWQQgKLq1evon379qLdbMuWLd/7/K1bt9C5c2esXr0a3bp1gybhwELNPD8j5benxEkdeQbtAszslL1VKiskJglrL73EFk9fxCZL8yecixljRNOy6F+3JMyMuL+7XNzbAewdB2SkAmVbSGl5hmbyeWwNbF857dw03Am9I25/VuUzfFnrS+hTvQpjSvQ0OBarz7/AvjsBWfVmNA9jTPNy6OLhBH0u9M614cJ3l7+DDDJ0KdsFcxvP5d9lNaOQwOK3337D9evXsX69lDOXm6+//lq0mZ07dy40CQcWaoQmIP87Sjp4K9Mc6L8ZMNKcRgLyHmj35/kXIu0pJV0qVHQrbi7+QXar4cydUBQ1mHHbYCA1HijZQGpHa6yhgwML6PLry/jm/DeITI6EhYEF5jaZi9alNDPNlqmvwOhErL3wEluv+SI+JV3cV8LKBKOalkG/uqVgYqin7E1UKUdeHsGMCzOQJksTv8+U0miopzljCTRdjCICi82bN4vg4tKlS7m2myW0UtGiRQsxx0KTcGChJm5tAPZ/SQvXQOUeQM8/Od0kF3f8orDq7HMcexiEzN9+KsimgKJVxeLaOX+iKPldBzb3ApKiAacawODdgJkttB0VfK6+txor76wUZzYr2lTEkuZLUNKShwwy1RWdkIqNnj4ihTQ8Xir0tjY1wNBGpUULbmszPnjOdNbvLKacnSJaRTcu0Ri/tvgVxvrGSnz1mFIDC3owqqugKdsjR45EhQoVRI0FPRnVWGzYsAGnT5/GgwcP4OLiAk3CgYUauPYXcHiqdL3OcKDTYkCXzxhl5/kiHCtOP8WlZ+FZ97WpVFwEFHVK2xT1K6bdAu9JjQUSwgD7SsCQfYCFA7RVZFIkpl+YjkuvL4nbvdx64Zt63/BBB1OrQu+dN/3x1/kX8I1IyOokNbhBKYxqVhbFLfgAmngGeuLL01+K9tENnRpiWatlMNHn+j2tLd729vbGhAkTcOrUKWRQt5NsGjdujOXLl6NWrVrQNBxYqLgrvwPHZkjXG06Quu7w4Lu3gyufhuG3089wzSciq8NT9xolMLp5Wbg7cJqY0oQ+ATZ0B2IDAZuywJD9WtlggCb10lAtqqugib2zGszioVpMbaWlZ+CIVxBWnXuOB69jxH1G+roYUK+U+JvLTTCAG0E3MO7UOBFc1HesjxWtV3Bwoe1zLCIjI/H48WPExcXB1NRUdImyt7eHpuLAQoVd+AU49YN0vekUoNVsDireBBTUvWT56We46xcldo+hni761nURKxQu1jwhWyVEvAQ2dJOmdRcrKa1c2JaDtrxHd3rvxIJrC5CWkQZXS1csabEE7tbuyt40xuTy/j7rHYoVp57ilq/0N9hATwe9a5fEuBblUNJGu/8G3wq+hbEnxyIhLQF1Hevit1a/wdRAu/eJKuMBeUrcoayIUDx8dgFwbpF0u8UMoPn/tD6oyMiQ4diDIKw4/QwPA6WzZcYGuhhYz1WcLXOw5OV4lRziSCsX4U8Bcwdg6AHAvgI0WXJ6spiiTd1iSJtSbUSnGHNDHjzGNLNV7fJTT7MGjdJg0U9qlsD4luVRxk57O8PdCbmDMSfHiBk11E56ZZuVHFyoKA4slLhDWREFFSfnAJeWSbfbfAc0mQRtn5J98N5rkfL0NCRO3GdmqIfBDV0xsklZ2FsYKXsT2cfEhQIbewDBXoBZcWDYIcBeM8/cB8YFYtLZSXgQ/kD0s/+y5pdiirYOpy8yDXftZYSoc6P0VEJ9Mrp4OGNCq/Jam5Z6N/QuxpwYg7jUONQsXlMEF2YG2htsqSoOLJS4Q1kRBBVUT+H5h3S7w0KgwVitDij23w3AilPP8OLNlGwLY3181qg0PmtchjuSqJP4cCktioILsXJxUOOCi2uB1zD13FTRSraYUTHRcrKRcyNlbxZjReq2byR+P/MMJx+9HbbXqZojJrZ2RwVH7Qsw7ofex+gToxGbGovq9tWxqs0qXr1UMRxYKHGHMgUHFTS9+Mpv0u3OS4C6I7Q25eng/UAsO+mN56FSQGFlaoCRTcrg04alUczEQNmbyOQRXNDKhZ2bRqSDbHi4AUtuLhFtZSvZVMLSlktRwryEsjeNMaV58DparDJTsTfRebOCMbG1G8oX1660wAdhDzDqxCjEpsRyWpQKUkpgsX37dmzatEkMyWvSpAk0CQcWKoDepqe+By4ulW53WSq1ldXCgOLogyD8etIb3sFxWQHF583KYkjD0jDnKdmaEVys7wqEPADMHYFhB9U6uEhITcC3l7/FMZ9j4na3ct0wu8FsbiXL2BtPgmKx7JQ3Dt8PykqRos59X7Z206oaDEqPHHVslFi5qOdYD7+1/o27RakIpQQW+/btw+rVq+Hp6Yk5c+Zg4sSJ0BQcWKiA0/OA8z9J12lGRb1R0Cb0a3r8YTCWnvDG46BYcZ+lsT5GNS2LYY1Lw8KYVyg0O7iglYvyUDevYl7hqzNf4VnUM+jr6OPrel+jX4V+XE/BWC4evo4RJ43ob332Iu8vW7mhlK2p1rSf/vzE56Kgm9Ikl7daDiM9rhHU6lSo9PR0hIaGwtHREZqCAwslO/cTcGaedL39AqDhOGhb29glJ7yzeqJbGOljeJMy4sIpTxosPgxY300KLiycpOBCjVrR0pRdGnpHRZn2Jvb4pcUvojiTMfZx9/2jRYBx6nFIVoDRp7aL6CKlDW1qqRUtdYuiORfNXJqJCd0GenzyTGMDi4MHD6J69eooWVJ7BjlxYKFEF5ZIKVCk7Vyg8ZfQBvRref5pGJYcf4K7/tFZXZ6oIHtk0zKwMjVU9iayIgsuaOXiIWBZAvjsCGDtqtL7nmooVt5diVV3V4nbFEz80vwX2Jtq7qwjxhThjl+UWKU+5x2aNQejT52S+KJVeY0ftEeNHmiIHrWmblWyFRa3WAwDXQ4uNDKwWLNmDb7//nscOXIEVatWzfG5hIQEPHnyBDVratZZKQ4slOTyCqlYm7T+VhqApwVuvorAoqNPRGtCYmKgh6GNSos6ChszDii0shXtuk5AmDdgXQYYfhSwUM0V4ejkaLFKcSHggrg9oOIATKszjc82MlYIN19FihWMzDa1hvq6GNrQFeNalNfozn+XAy5jwukJSM1IRfvS7bGw6ULo6+ore7O0UoyiU6FmzZqF33//XdRVNGvWDKmpqfjrr78wd+5cDB48GD///DM0CQcWSnB9DXBoytvhdy2+hqZ7HBSDxceeZLUgpH8eQxq4YkyLcrAz5xxTrRbzGvi7AxD1CrCvCAw7DJjZQpV4R3qLegq/WD+RE/1tw29FoTZjTD7oZNPi429POlFa7KhmZTGiSRmYaWjjjvP+5zHxzESkZaShS9ku+LHxj9DT1VP2ZmmdmKKosaBC7SlTpmDSpEnYsmULIiMjMXnyZFG0bWGhWX2YObAoYne3A3tGU0KQtEpBqxUazDc8AUtPemPvnQDR/Cozn5Y6gjhbafZyN8uHSB/g745A7GvA0UOa0G1ipRK78MjLI5hzeY7IiaYWsktbLEUl20rK3izGNA4dslFq1E9Hn+BhoFR3Z2tmKIbsDaxfCkb6mnfQfcr3FKaenYo0WRo+Kf8Jvmv0nRiuyTQssDh8+DDGjh0LX19ftG7dGv/++694Uk3EgUURenwY2D4YkKUD9UYDHRdJzb01UEhskuhhvvWaL1LTpV/DztWcMLmdO8rZa1cPc5ZHYU+BfzoC8aFAyfrA4N2AkfLeK3QWcenNpWJGBaEuLouaLoKVsWoEPIxpcuvxQ/cDRWOPl2+Go5awMsGktu6ikxSdoNIk1K76f+f/J2q4qLPczPozubucpgQWd+/exZgxY3Dz5k18/vnnqFu3LsaPH48ff/wRX331FTQRBxZF5MU5YHMfID0ZqD4A6P4HoKt5ZyWiE1Ox+txz/HPJB4mp6eK+Zu72mNauAqq5aGZwzuQoyAtY1xlIigLKNAMG7gQMjIt8F4cnhmPa+Wm4HnRd3B5ZbSQm1JjAaQqMFaHU9AzsvOEv5mAExySL+9yKm2NKuwpoX8VBow6+D744iBkXZkAGmfh7M7GW5ow10OrAYunSpbh16xZ++OEHlClTRtx35coVdO3aFUOHDsXixYs16o1MOLAoAv43pNaaqfFAxS5An/WAnmbljCampGPdZR+sOvdcBBekZikr/K99RTQsp1r58kzF+d+UJnSnxAHuHYB+m4AibMd4P/Q+Jp2dhOCEYJjqm2Jek3lo49qmyJ6fMZZTUmo61l/2wcpzzxGVIP1/qV7SCl+3r4BG5e00Znft9N6JH678IK5Prj0Zn1X9TNmbpBViFBlYpKWlQV///QM+6gbVoUMHsZpB07cV5eTJk1ixYgWCg4NRrVo1fPvttx9tfTtv3jzs3Lkzx33ly5fHrl278vycHFgoWPAD4J9O0hnYsi2AgTsAfc0pVk5Lz8COG/6iq0dIrHRGyd3BHFPbVUDbypp1RokVIZ+LwKZeQFoS4NEf6LGySFb4/vX+F/OuzhOdWkpblsaylstQ1qqswp+XMfbfYpJS8df5F1h78SUSUqQV8Sbl7fBNx4qoWkIzVsTX3l+LX2/9Kq7PaTgHvd17K3uTNF6MsgbkBQYG4tSpU6IzlCKcOHECnTp1EpO9GzZsiGXLluHOnTu4f//+B+s7KNB5/vx5jk5VJiYmqFChQp6flwMLBQp/LuWMxwUDLvWAIXsBQzNoAvrVOvUoBAuPPsazkDhxn4u1CSa3dUf3GpqXA8uUwPsYsHWAVJPUcALQ7keF1SSlpKdg/tX5+Pfpv+I29ZanlQpzQ64HYkzVhMYm4/czz7D56qusGr4eNZwxtX0FuFir/5C9X2/+irVea6EDHfzU7Cd0KNNB2Zuk0WLkHVj4+fnByckp15WKd9HDUUG3q6v8hzhRMFGuXDls2rRJ3E5KShLbNX36dPzvf//7YGARFhaWrxWKd3FgoSCxwcDatlILTYdqwDDqcmMNTXDXLwrzDz/C1TdtAa1NDUSXJ03t2sGU6O62N13UALT5DmgySe5PERQfhMlnJ+N+2H3xj/zLWl9ieNXh3JmFMRXnF5EgCrz33A7IamP+WaPSYgZGMVP1HThHx5o/ev6IHd47oK+jj+WtlqOpS1Nlb5bGys9xcJ7WzY8fPy6G4dGsitjY2Fy/Jj4+HuvXrxfD8TZv3gx5i4uLw9WrV8WKRSZjY2PRkYpWST7G09MTjRo1QseOHTF//nwkJibKfftYPiXHApt7S0EFDf36dLdGBBXUOvaLrbfR/fdLIqgw0tfF2BblcO5/LcXUbA4qmNxV7w+0ny9dP/kdcEvq0CQvVJzd72A/EVRYGlpiZZuVonCS2z0ypvpK2phiab8aOPhFEzQqZ4uUtAysPv8CzRefwZoLL5CcJqVLqRtKIZ5RfwY6lu4o2tDSiY+bwTeVvVksP6lQR48excyZM+Hl5YUaNWrA3d1dRC8UaDx9+lR0iaLVBJrK3adPH7nvXKrhqFixIk6fPo2WLVtm3f/ll1+KuouHDx/m+n3Tpk0T0VXz5s0REBAgto9uX758+YMrMMnJyeKSPVKjOo68RGosD9JSgC19gBdnATN7YMRxwEa9c7SjElKw4vQzbLjiI5adKRulZ00XTGnnzrMoWNGgoOLiUoD6u/fdCFTqUqiHo38N1EaW2smmy9JR0aaimE/hYuEit01mjBUd+p0++yQUC448gnewlJ5b0sZENBDp4uGklvV+VOs18fREXAi4AHMDc/zd/m+eoaNuNRa0anDkyBFR10BD8egJqlSpgvbt24sp3IpCAQ0Va1+6dEmsPmQPHPbu3SuCm9zQVHADg7fLfS9fvoSbm5tYXRk0aFCu3/Pdd9+JAORdHFjIQUYGsOdz4D61yDQDPjsEONeEunfioFzWmKQ0cV9TN6lQroqzZhTKMTVBf8r3TwBuU4coI2kVsHSTAj1UQmoCvrv8HY74HBG3u5btitkNZ8NEnwc2MqYJDUV23fQXKVKZDUWquxTDjE6VUL+s+nUopMGcY06Mwa2QW7AxtsG6DutQppjUtZSpefG2IlFhuLOzM/bv3y9a22YaPny4WK2gdKe8oq5QvXv3xsKFC3P9PK9YKNCxmcCV3wBdfan7U/nWUNfhRPvvvsbPx54gIEpKravoaCH+MNNMCsaUIj0N2DkUeHwQMLIEhh0CnDzy9RCvYl7hqzNf4VnUM5G7PLXuVAysOFAtz2Yyxj4sISUNay68FHOV4t90kGpTyQHfdKyA8sUt1GrXxabEYsSxEXgU8QiOZo7Y0GEDnMydlL1ZGkPuNRbZUcoTHdxTgXZRoiJtCiyuXbuW434KKGrXrp3nx6EVjJCQEFhYfPiXxsjISOy47BcmB5dXSEEFoeF3ahpUXHkejm6/X8RX2++IoMLR0hg/9/bAoS+bclDBlItmv/RaC7g2AZJjpIGTUX55/vZzfucw4OAAEVTYmdhhbfu1GFRpEAcVjGkgU0N90VTk7LSWGFS/lOhUePJRMNr/egEz9txHWNzblHBVZ2FogVVtV4mVCmo2MebkGEQnRyt7s7SSbkFSkgYOHCi6PtnY2Ih6B5q4vW7dOty+fRspKSmK2VIAo0aNwpo1a+Dj4yNub9myBY8fP8aIESOyvoYG99FqBKFtoZSmhISErNuTJk0SKxKKqANhH3FvJ3B8lnS97Vygej+1210+YfH4fMMNDPjLE14BMTA30se09hVwZmoL9KlTktvHMtVAU7j7bwbsKwFxQVJwkRj10W/JkGXg9zu/Y8LpCYhNjUXN4jWxo8sO1HKoVWSbzRhTDnsLI8z7pBqOfdVMzFZKz5Bhy1VftPj5rBjoqi4F3pQG9WfbP1HctDheRL/A+FPjRZoUK1oFSoXKyMiAt7e3CCToQl2j7t69Kz43ZcoUMX1bEWi1gYKI7du3w8HBAVFRUWISePbAYuTIkWIVgwIg+tGoC9Svv/4KKysrMVSPirBpwF6rVq3y/LzcbraQnp8GNvcFMlKBBuOB9vMU1mtfUQOHfjv9DP9ceikKs+mszsB6pfBVGzfYmmvOID+mYaL9gTVtgNhAoHRTYPC/uQ6epLN60y9MF8WPZEDFAZhWZxoMinCSN2NMdVx9EY4fDz3C/QDpjH8pG1NM71gRHao6qsXq5bPIZxhydIhIj2ru0hy/tvwV+pR+zdSrxoJmS2zYsEGsKJQqVQqKRHMpQkNDUbp0aTHs7t2ZG7RCkX0AHgVCVLRtbW0tVlnyiwOLQnh9B1jXGUiJA6r2AnquKZLpwPIqcNt23U8UuEXESytxVD8xu3MluDmoV/4p01JB94G/OwIpsUC1PsAnf+b4/XsS8UTUU/jH+cNIz0hMse1a7m0NG2NMO1Ed4e7bAfjp6OOsAu96ZWzwbZfKajHB+3bIbYw6PgrJ6cn4pPwn+L7R92oRFKkqpRVvU4oUFVO3adMGmoQDiwKK9AHWtAXiQ4AyzYFBO3M9Y6qKLjwNxdyDD7Na8pWzN8OsLpXRskJxZW8aYwVYMewDZKRJw/NoiB6Agy8O4vvL3yMpPQklzEuIVrKVbCvx3mWMZYlPThPF3TT7IjktQyQb9K7lItKAi1saq/SeOuN7Bl+d/Uqkeo6qNkoM9mQqGFjQmX9KSaLOSrrvnHmmegZaHcitVas648CiABIjgbXtgDBvwJGmah8GjFW/CP55aBzmH3qEU49DxG0rUwNMauMuJmYb6KnHSgtj77m9Gdg3TlxN7fQzliASmx5tErcbOzfGwqYLYWVsxTuOMZYralRCqxf77rwWt00N9TC+ZXmMaFIGxgZ6KrvX/vX+F99dkU6mfFPvG9GMgin2ODjfSWc0M2Ly5MkwNzeHh4eHGJZHH01NTfHPP/+IGgum5WgA3vZPpaDCsgQwcKfKBxU04G7ZqafYeOUV0jJk0NfVwacNXTGxtRusTA2VvXmMFU7NQaLmIuzCQky5vRi3jKWVQzqLN77GeOjpqu6BAWNM+UpYmWBZ/5oY2qg0fjjwEHf8okS7dSryprlNqjpgr5d7L4QlhuG3O79h0bVFsDWxRYfSHZS9WRqtQKlQ1GqWirXv3LkjLvfu3RM1D02bNsXWrVtF0KFJeMUiH+jttHcccHcLYGgBDD8KOFaFqkpNz8Bmz1f49dRTRCWkivtaVyyOGZ0roZy9Zr2PmXa7E3IHU46OQIgsBWYZGZhf4yu0qjlK2ZvFGFMzdNhIc5wWHXmM19FJ4r7artaY3aUyapRUvZVP0cjn6nxse7JNFHGvbLMSDZwaKHuz1IpGDshTJg4s8uHcT8AZ6vqkBwyiAXiqW29z6VkYvtv/AE9DpDqKCg4WmNWlEpq68YA7pjnoT/yOJzuw8PpCpGWkoRwMsdTfB2UMrYERJwAbnlDLGMu/xJR0/HXhBVaefY7EVKklbe/aLvi6Q0XRwlaVpGekY9r5aTjx6gTMDMzwT/t/uKYsHziwkDMOLPLo3g5g95szoF2WAnWGQxX5RSRg3qFHOPogSNy2NjXA5HYVMKBuSehzHQXTIElpSZjrORf7n+8Xt9u6tsXcOv+D2aY+QNA9wLa8FFyY5r9bHmOMkaDoJPx07DF23woQty2M9DGxjZtIm1Kl2kTqEDX25FhcD7oOW2NbbO68WTSuYP+NAws548AiD3wuARt7AOkpQKMvgXZzoYpnV2jYjzTwJ0PMo/i0gasozi5myj37mWYJiAvApDOT8CjiEXR1dDGp1iQMrTJUyoOODZJmXET7vZlxsRvQ51oixljB3fKNFFkA9/yjs7opzulaRbRpVxU022LY0WHwjvQWU7o3dtyIYkaq3z5X2TiwUOIO1UphT6WDlKQooFI3oM96lZpVQakgR7yCxCoFdbYgDcvaYk63yqjoyK8n0zyXAi7h6wtfi+F31kbW+Ln5z6jvVD/nFwU/ANa2l2Zc1BwMdPtNrQZXMsZUc/7Frpv+WHT0McLfzH+iad6zO1dGKVtTqILg+GAMOjwIwQnBqO1QW0zrNtTjEysfw4GFnHFg8RHxYcCa1tLMihJ1gGEHAYOcQwuV6UlQrDiDcuVFeFZni5mdK6GjmkwQZSy/ecSr763GqrurIIMMVW2rYkmLJXAyd8r9G7yPA1v7AbIMoO0PQOOJvMMZY4UWnZiK5aeeYt1lH6RnyGCor4vRzcpibItyMDVU/hRsWrEYemQo4lLj0LF0RyxstlCs7DIlBxYRERHibLCtrS00GQcWH5CaBGzoBvhdBaxcgZGnAHPVWPKMTkjF0pPe2Oj5SvxRM9LXxZjm5cTFxJBbazLNE5EUgekXpuPy68vidh/3Pvi63tdiovZHea4Cjn5N/w6AfpuASl2KZoMZYxrvaXAsvjvwAJeeSSf3nIoZY0anSirRntYz0BNjT4xFmiwNw6sOx6Tak5S6PZpyHFyg8OzChQuoWLGiCCgWLFgg7qP2szR5m2kJikdp4BYFFcbFpKnaKhBUUBCx9ZovWv5yNutMSYcqjjg5uTkmtXXnoIJpbCvZvgf6iqDCWM8Y85vMx7cNv/3voILUHw3UHUm/1FLzhdd3imKTGWNawM3BAptG1MeqwbXhYm2CwOgkfLH1Nvr/6YlHgTFK3TZqOft9Y2mg899ef2P74+1K3R5Nke8VC5pXUalSJXzzzTcICpK66ixevFh8bN68OebPn4/GjRsrZmuVhFcscnF2EXB2PqCrD3y6ByjTDMp281UE5ux/AK8A6Y+VW3FzUTjWxM1O2ZvGmELQn+/Njzbjlxu/iLNupS1Li9QnN2u3/D1QehqwpS/w/BRg4QSMOg1YOvOrxhiTm6TUdPx5/gX+OPsMSakZ0NUBBjdwxeS27kodREupo7/f+V2kQi1vuRzNSzZX2rZo5YrF6dOn0aRJE0ydOhVOTjnzdhs1aoRTp07lf4uZenmwRwoqMtvKKjmoCIlJwqTtd9Br5RURVFgY6+PbLpVxeGJTDiqYxopLicPUc1Ox6PoiEVS0L90e27psy39QQfT0gT7/APYVgdhAYEs/IFma78IYY/JgbKCHL1u74dSUFujs4YQMGbDhyiu0WHwWm96kLSvDaI/R6OnWExmyDDHrwivMSynboSnyHVjQikVmQPFuflxycjLS06UhKUxDBdwC9oyVrjcYD9QaorRNSUvPwNqLL9Hql3PYcztANLTpX7ckzkxtgeFNyqhU/2zG5F14OODQABx/dRz6Ovr4pt43+LnZz2LwU4FRSuPA7YCpnTTjYvfnQAb/PWeMyRc1Ufl9YC1sGVVfDKaNSkjFrL1e+OSPS7jrF1Xku5uOZWc1mIXGzo2RmJaI8afGwz/Wv8i3Q1Pk+8jLw8NDrFqkpaXlCCzCw8OxY8cO1K1bV97byFRFzGtg20AgLRFwa6fUWRXXfSLQZcVFzD34EHHJaahe0gp7xzXGwl4esDNXrYmfjMnTgecHMOjQIPjE+MDB1AH/dPgHgyoNkk8hpHVpoP8WgGoznhwCTs6RxyYzxth7GpWzw6Evm+C7rpVFpgHNv+jxxyVM330fkW9a1RYVA10D/NLiF1S0qSgaYdAgPWrXzfKvQF2h2rdvL/Kt7O3tkZKSgtq1a2Pt2rUoU6YMLl26BF0VmmEgD1xjASAlAVjXCXh9W0qXoGm9xkU/AyI0NhkLjzzGv7ekswlWpgb4ukNF9KtTErqUsMmYhqKpsQuvLcQu713idiPnRljYdCGsja3l/2T3dgK7qaAbQLcVSl2ZZIxpPvrfvuDIo6zp3dZv/rf3LeL/7SEJIWLGRVB8EGoVr4U/2/2ZtyYYGi5G0e1mk5KSRDeo7du3IyAgQHSH6tGjB+bOnQsLCwtoGq0PLOgtsuszqbbCxEYq7LQpU6SvAeVebr76Cj8fe4LYpLSstKf/ta8IazMebMM0Gy3LTz47WUzR1oEOxlYfi889PoeergJbJ59ZAJxbCOgaAEMPAK4NFfdcjDEG4NrLCMze64UnwbFif9QoaYUfe1RF1RJFNx37WeQzDDkyBLGpsehQugMWNVuk9TMuYhQZWDx79kzUUlSpUgXaQusDi7MLgbMLpAOMIfuA0kXb9euWb6T4Q/PgtdTtqWoJS8ztXhU1SyngTC1jKua072nMujQLsSmxsDKyEqsUjUsUwe9gRgawaxjwcJ9Ud/H5WcCqpOKflzGm1VLTM7D+sg9+PflUpDrTicTB9V0xtV0FFDM1KJJtuBZ4DaNPjkZaRho+q/oZJteeDG0Wo8jAYtmyZfD19cUvv/wCbaHVgYXXbmm1QgkpERHxKfjp6GNsu+4nblsa62Nah4oYWK8U9DjtiWm4lPQU0UZ2y+Mt4raHvQd+af4LHM0ci3Aj4oG17YHg+4BjNWD4McCwEAXijDGWR8ExSZh36BH2330tbtuaGeKbjhXRq5ZLkaRHHXxxUAwdJd81/A693HtBW8Uost1s+fLl8eDBg8JsH1MXATeBvW86QDWcUGRBRUaGDFuu+qLVL2ezgoretV1wemoLfNrAlYMKpvFexbzC4MODs4KKoZWHYl37dUUbVBAKIgZsedMp6r709yD/2bOMMZZvDpbGWD6gpugeVb64OcLjUzBt1z30XX2lSIbrdSnbBeOqjxPXf/T8UUzqZv8t3ysWsbGxaNWqFVq3bo1BgwaJAu7szMzMNK7OQitXLGICgT9bAHFBUgeoAdsAReZzv3HPP0qkPd31l7oxVHS0EPmVdUrbKPy5GVMFh18cxvdXvkdCWoJIfZrXZB6auSh5AOWrK8D6rkBGKtByJtD8f8rdHsaYVklJy8A/l15i2amnSEhJFycYhzR0xaS27rA0Vlx6FB0iz7g4Q6xeWBhYYFOnTShrVRbaJkaRqVA0ZXvatGkf/PyUKVOyJnFrCq0LLFKTpA5QtGJRRB2gohJSRGH2lmu+4oSohZE+JrdzFysU+jyPgmkB6p++6Noi/Pv0X3G7tkNtUU9R5KsUH3JrA7D/C+l6v01Apa7K3iLGmJYJjE7Ejwcf4dD9QHHb3sIIMztVQvcazvJpuf2BtNRRx0fhVsgtuJi7YHPnzbAx1q6TnTGKDCxoXkVgoPSC5sbOzg6Ojiryj1BOtCqwoLfD3nHA3S2AsRXw+RnApqxC05523fTHwqOPRU0F+aRmCUzvWBHFLY0V9ryMqRLqQkITX59FPRNdn0ZXHy2mwerr6kOlHPkauLoKoEF8I44DjlWVvUWMMS103jsU3+1/gBdh8eJ2/TI2mNujKtwdFJMxE5kUiYGHBsI/zh817GtgTfs1WtWGNkbR7Wa1jVYFFp4rgaPfADq6wODdQLmWCnuqx0ExmLXHCzdeRYrb7g7m+KF7VTQoa6uw52RMldCf3z3P9mDB1QVISk+CnYmdWKWo71QfKik9DdjcC3hxFihWSjrxYGan7K1ijGmh5LR0rLnwEitOP0VSagb0dXUwomkZTGztBlND+Z+UeRH9QtS+UYe+jmU6YlHTRQpbJdGqwOLRo0e4efPmBz9fuXJl1KpVC5pEawKL52eATb0AWTrQfgHQUCpakreElDSRJ7n2wkukZchgaqiHSW3cMaxxaRhw2hPTEnEpcfjB8wcceXkka+Ad1VNQcKHSEiKAv1oBkS8B18bAp3sBfZ4lwxhTDv/IBPxw4CGOPwwWt0tYmeCH7lXQupKD3J/rauBVjDkxBmmyNDFPaFwNxRwnaVVgsXLlSnz//fc57ouPj0dcXBxMTU3x9ddf49tvv4Um0YrAIuIl8FdLIDESqD4Q6PEHRPNoOTv1KBjf7nuAgKhEcbtDFUd827UynK1M5P5cjKkqrzAvfH3+a/jG+kJPRw8Tak7A8KrD1WcIU8hjYE0bICUWqDMc6LJU2VvEGNNyJx8GY87+nMcXc7pVhlMx+R5f7H66G3MuzxHXFzRdILpHaboYZaRCnT17FmPGjMHly5dhY6NZRS0aH1gkxwFr2wIhD4EStYFhhwEDY7kXXFE+5LEHij+jwJiqSs9Ix99ef+OPO3+IM15UmP1zs59Ro3gNqJ0nR4Gt/SmhC+j8C1B3pLK3iDGm5URGxMmnWHPxJdIzZDCjjIi27hjWqLRcG8EsvblU/C030DXAmnZrUMtBszJ1VKbGYuLEifDw8MCIESOgSTQ6sKDpujuHAI8OAOYO0nRdS2e5PXxaegbWXfbB0hPeiE9JV3gOJGOqKjAuENMvTsfNYCmVtH3p9pjdYDaKGRWD2rq4FDj5HUBF5p/uAcoouS0uY4y9qeGcuccLN9/UcFZ2ssT8ntVQo6SVXPZPhiwDU85OwUnfk6It+JZOW1DSsqTG7nuFDsj7GEqF8vOTBpoxNXFhsRRU6BlKLSTlGFTc9o1E198u4cdDj0RQUdvVGge/bILpHStxUMG0ytGXR9Frfy8RVJjqm+LHxj+KlQq1DipI46+Aan2AjDRgx1Ag0kfZW8QYY6joaImdoxtiQc9qKGZigIeBMfjkj0tiTlZ0Ymqh9xClrc5vOh9VbKsgKjkK406NQ3SyNH9L2+V7xSI4OPi94CE9PR33798X8y02bNiArl01q7+5xq5YPD4EbBsoXe/2G1DrU7k8LP3S/nzsMTZflWZS0C81tY/tW6ckdHW1o4MCYyQ+NR7zr87H/uf7xW0POw/R9UmjzmylJgL/dARe3wYcqkltaA1Nlb1VjDEmhMUlY/6hR9h9OyBr9sXsLpXR1cOp0F2dQhNCMfDwQATFB6GeYz2sarMKBnqKG9inVQPyrK2tMWHCBPzwww/QNBoZWIQ8elN8GQfUGw10+qnQD0lvpf13X2PuwUfiF5n0rFUCMzpVgp259vR7ZozcDb2Lb85/I/qe09mtUdVGifkUlJOrcaIDgD+bA/GhQNXeQK81Cmn+wBhjBXX5eZhocZ85+6Kpmx3mdq+K0nZmhdqp3pHeGHJkiDiR9En5T/B9o+81rg2tQgOL5ORkJCZKFfeZ9PX1YW5uDk2lcYFF9naRpZtKudGFjLBfhsXj231euPA0TNwua2+GH3tURaNyKt46kzE5S81IxZp7a7D63mqky9LhbOYsOodoenEffC4BG7pJaVHtfgQavZnSzRhjKjT7YvW5F/jtzDOkpGXAUF8XE1qWx+jmZWGkr1fgx73gfwETTk8QtRdf1foKI6ppb61xvgOLa9euifayLVu2zNfn1JlGBRZiwFVv4MUZwKoUMOosYGZbqF/SVWdf4Pezb39Jv2hZHp8X8peUMXX0POo5ZlycgYfhD8VtGqI0q8EsWBqq+d+NvLr6J3BkWpEM2GSMsYLyCYvHbDmfDN36eKtIfSVLWixBW9e2GvMCKbR4+/z58zh06NAHP3f48OH8PiQrSifnSEGFgSnQf0uhgorLz8LQ8dcLWHrSWwQVtKx4/Ktm+KK1GwcVTOvayK5/sB59D/QVQQUFEjSV9admP2lPUEHqjQJqDAJkGcCu4UDkK2VvEWOMvYfSnzYMr4flA2qKVO0XofEY+NdVTN5+JyuVO78GVByAQZUGieszL87MOsGkbeTaFerp06ews+PUF5V1fxdw5TfpOg3Ac6xWoIehX7pJ2+9g4JqrIleRCqFWDKgpfkkLm6vImLrxi/XD8GPDsfjGYqRkpKBJiSbY030POpXtBK1DecWdlwDONYHECGD7ICAlQdlbxRhj76E6iG7VnXFqSnN82sBV/PmiAu/Wv5zD1mu+yMjI/zSGqXWmonGJxkhMS8QXp78Qxd3aJs+pUH/99RfmzZsnlkOoCxQVa2dHKVD0uRs3bqBatYIdsKoqjUiFCvKSirXTEoEmk4E20tTI/KC3yo4bfph/+LHo/ES/hIPru2Jq+wqi8xNj2oR+H3Z67xQBBf0ToTay0+pOQy+3XhpXuJdv0f7A6uZAQpjUjrbnX1zMzRhTadQin2ZfUGtaUsfVWsy+cHewyNfjxKbEYvDhwXgR/QJVbavinw7/wFhfvkOHNaLGgtrJXr16FcePHxcP3KdPnxyfpydq2LAhSpbUoDaKmhJYiGLtllKP+XKtgUE7Ad381T88D43DjN33cfVlhEKGzTCmToLjgzHnyhxcCrgkbtd2qC1mU7hYuCh701SHz0VgQ3epmLv9fKDheGVvEWOM5Wmo75IT3khISYeBng7GNC+H8S3Lw9gg78dNfjF+GHB4gJht0bF0RyxqtkitTzgptHj72bNnojNUlSpVoC3UOrDISAe29AWenQSsXKXJ2qY2+S/Opg4K6RkwMdDDpLZuGN64DPT15JpJx5jKoz+X+57vw0/XfxJnpQx1DTGx1kQMrjxYtJRl77i6GjjyP0BHT+o+V7Y57yLGmMoLiErEt3u9cOpxiLhdxs4M8z7JX3H39aDr+Pz450iTpWF8jfEYU30M1JVCA4vsEhISEBkZKf7ZZrKwsBBPrknUOrA4/SNw/mdA3wQYeSJfdRXXfSIwffd9PAuJE7ebu9uLrgklbXj4FdM+AXEB+P7y97gSeEXcpomr85vMR1mrssreNNVF/xv2jgXubgVMbKQTG9auyt4qxhj7T3Rse8QrCN/tf4CQWKmgu09tFzGby9rMME978F/vf/Hdle/E9V+a/4J2pdup5Z5XeGBBXaEmT54Mb2/v9z43ZcoUMURPk6htYPHooFQ8SSjH2aNvnr6N6icWHX2MLVd9xW1bM0N827WyKHJS56U8xgqC+pJTG8Flt5aJWgojPSOMqzEOQyoPgb6uPu/UvEzm/rsDEHhHOrExnCdzM8bUR0xSKn46+hibPKVjIhszQ8zuUgk9apTI0zHRomuLsOnRJhjrGWNdx3XipJS6UWhg4e/vL9Kg5s+fjxcvXogViyFDhuDvv//GmTNncPnyZY2rs1DLwCLUWxqClxIL1B8LdFz4n99Cb4XD94Pw3YEHCH0TnferUxLTO1WElWneonPGNMmLqBeYc3kO7oTeEbdrFa8lpqqWLlZa2ZumXqL8gD9bvCnm7gv0/JOLuRljauXmKymLwztYyuKgFvuUxeFq+/FumGkZaaJD1MWAiyhuWhxbO28VH9WJwudYtGrVCuPHj4ezszOsrKzQokULbNiwQQQc586dK8y2M3lIinnT5jEWcG0CtJubp3zCketvYPyWWyKoKGtnhm2fN8Ci3h4cVDCtnJ79570/0ftAbxFUUMenWfVnie4eHFQUgFVJoM86qdbi/g7Ac6X8XzTGGFOg2q42OPhFU0xt5y6GAdNwvXZLz2Pl2edITc/44Pfp6+qLmUZli5VFSEIIJp6eiKS0JI19rfIdWAQGBqJsWSmnmKKX8PDwrM81atQIjx49ku8WsvzJzGkO8wYsnIE+/wB6H24Fm54hw9qLL9F2yTlRpEQdEL5s7YbDE5uiQdmCD89jTF09CH+AAQcHYMXtFSLAoLkUe7vvRb+K/bhAuzDKNAXaz5OuH58FvDwvnxeMMcaKCAUUE1q54dhXzdConC2S0zJE6njXFRdFu9oPsTC0wG+tfoOVkRW8wr0w+9LsHPXJWh1Y0I7IzCmrXLkyTp06JYKLpKQknDhxAg4ODorYTpZXF5cAjw8CeoZAv42A+YeX27wCovHJH5cw9+BD0VaNejYf/rIpJrd1z1dbNcY0AXV5mn91PgYeGognkU/EPwAqzv6j9R9wMndS9uZphvpjAI/+gCwd2DkMiJJylhljTJ1Ql6jNI+vjlz7VYW1qgMdBsei58jLm7PNCbFJqrt9T0rIklrRYAn0dfRz1OYpV91ZBE+U7sHB0dMyqoaAViurVq8PJyQm2trai/mLw4MGK2E6WF9RS9tSbtKdOPwMudXL9soSUNCw4/Ajdf7+Ee/7RsDDWF23UdoxuCLd8DoJhTN2J2qIXh9FtbzdRpE3F2h3LdBSrFF3LdeWGBfJEJ6W6/go4VQcSwoFtg6TibsYYUzN0kr1XbRecmtICPWuVEAkj66+8Qtsl53HsQVCu31PXsS5mN5wtrv9x5w8c8zkGTVOodrOEpnBTwTYVdjRr1ky0m9U0alG8HfFSKo5MigJqDQW6Lc/1y84+CcGsvV7wj5T+mXeu5oQ5XSujuKV6T4VkrCB8on0w7+o8eAZ6itulLUtjRv0ZaOjckHeowou5aTJ3OFB9ANBjJRdzM8bU2sWnYZi59z5ehSeI2+0qO+D77lXgVMzkva+lWUgbH25Um05RCu0K9c8//yA0NBT/+9//oC1UPrBISQDWtgOC7wMlagOfHQH0jXJ8CRVkU8rT/ruvxW3nYsaY26MqWlfi1DWmfahwbs39Nfjb629RR0GD7kZ5jMLwqsNhSGmETPGoxmJDDyktquNPQP3RvNcZY2otKTUdK04/xepzL5CWIYO5kT6mta+AwQ1coaf7tjVteka66BR1IeACipsUx9Yuqt0pSqFdoTIyMvD06dPCbB+TJ4oLD3wpBRVm9kDfjTmCCoobd1z3Q5sl50RQQe9rmpp9YnJzDiqYVqKWf5/s+wSr760WQUXjEo1F2hNNReWgogiVaQa0/UG6fmwG8OpyUT47Y4zJnbGBHqa1r4hDXzZFrVJWiEtOw5z9D9Br5WU8CozJ+jo9XT3RKapcsXIISQzBl6e/FHOSNEG+Vyz8/PxEu9mzZ8+iRIkS0AYqvWJBbRuPfiO1cRy6HyjdJOtTL0LjMGPPfXi+iBC3KztZYmGvavBwsVLiBjOmHL4xvlh8YzHO+J0Rt+ns0Df1vkGbUm24jkJZ6N/PvyMAr3+lEyOjzwOWzkrbHMYYk5eMDBk2X/PFT0ceIzY5Dfq6OhjZtCwmtnaDiaHUIMcv1k80DIlKjkL70u3xc7OfVfL/kUJToY4ePYqvvvpKBBg0v8Le3j7H5zt27Ih+/fpBk6hsYOFzEVjfTUol6LAQaDBW3J2SloFV557jtzPPxHVjA13R6YlWKvT18r1IxZhai0+NFzMpKJ+VVij0dPQwqNIgMT3bzODjg41YEUiJf5PK6QWUqAN8dvi9VE7GGFNXwTFJ+G7/Axzxkgq6S9mYioY5Td2k4+cbQTcw6sQoMUhvXPVxGFtDOpbTqlSoOnXq4JNPPoG1tTXS0tJyXOjzrAhEB0jtGimoqNZHauNIb1CfCHRefgFLTniLoKKZuz1OTGqOz5uV46CCaRXq7rT32V502dMlq5aikXMj/NvtX0yrO42DClVhaCa1xjYuBgTcAI5oT/0eY0zzOVgaY+Xg2vhrSB04FTOGb0QCPl17DZO230F4XDLqONbB7AZvOkXd/UO0otXqrlDaQOVWLNKSgX86AgE3AYdqwIjjiE43EENatlyV+sLbmhni266V0a26s0ouqzGmSLdDbmPRtUVi2B0pZVEK/6v7PzRzaca/D6rq6Ulgc2/KjwK6LgNqD1P2FjHGmFzFJafhl+NPsO6yj8gEtTI1wMxOldC7totI1d3wcAOM9IywrsM6VLWrqh2pUJmePXuGa9euwdXVFY0bN0ZsbCxSU1NhY2MDTaNygcX+L4Fb6wFjK8g+P4sjAcaiOIg6P5F+dUpieqeKsDLl7jZMu7yMfollt5bhlO8pcZtSncZ4jBGpTwYfmUDPVMT5xcDpudKAT+pu94FZPIwxps7u+kVh+u77ePimoJumeM/tURm/3P1GdIqyN7HH1s5b4WDmoPmpUOSnn34SU7fHjh2LPXv2iPuoBS3NsaB0KKZAN9dJQQV0ENZhJUbuD8O4zbdEUFHWzgxbRzXAot4eHFQwrRKWGIYfPX8U3Z4oqNDV0UUvt144+MlBDKs6jIMKddF0ClCxC5CeAmz/FIgLUfYWMcaY3FUvaYV9ExpjeseKog728vNwdFp2Ce66Y0SnqNDEUHx5Rj07ReU7sHj06BEWLlyImzdv4ttvv826v2zZsiLY2L17NxRpy5YtqF+/PkqXLo2uXbvCy8tLId+jkvxvAIenias3yo1Hs926OPU4BAZ6OviyVXkcntgUDcvZKnsrGSsyCakJWHl3JTrv7oztT7YjXZaOFi4tsLvbbnzX6DvYmdjxq6FOKG2ThuXZuQOxr4EdQ4H0VGVvFWOMyZ2Bni5GNy+HY181Q1M3OySnZeDX436I8x0Cc4NieBj+ELMvzRZjAzQ6sLhy5Qp69OiBatWqvfc5Cizu3r0LRdm1axeGDRuGUaNG4dChQ7CzsxOdqUJCQuT6PSqJztzRGbz0FFwxbIjeDxoiISUddVytcfjLppjcroLon8yYNkhJT8HmR5vReU9n/HHnDySkJaCqbVX83f5vrGi9AuWsyil7E1lBGVsC/bcAhhaA72Xg+Czel4wxjeVqa4YNw+thSd/qsDY1wLPXRgh51g860MMxn2Ni5pJGBxbZOz+9WxRMLWgtLCygKD/++COGDh2KkSNHokqVKvjrr7+gq6uLlStXyvV7VE56KtK3DxFn8J7JnDEqZgQsjA1Eu7IdoxvCzUFx+5wxVUKdnXZ67xQBxcJrC0UKlIu5C35u/jO2dN6Cuo51lb2JTB7s3ICeb/6ZXl0F3N3G+5UxprF0dHTQs5YLTk1pgZ41SyA9oSwSA7uLz/1+53eceHUCGhtY0Nn+AwcOwMfHJ0dgcfLkSWzatAnt2rWDogpHaDWkbdu2Wffp6+ujdevWOH/+vNy+R9Wkpqdi89ZPkejviViZCUanTELzauVwanJzDKrvCt1sI+IZ01TU33vfs33ouqcrfrjyA4Lig8SAO2rRt7/HfnQo3YG7PWmaip2BZm9azx6YCLy+o+wtYowxhbIxM8SSfjWwcUQ9OOo2R0pEY3H//85Mw5VHx9Vi7+vn9xvc3d0xadIkeHh4wMHBQZz9P3PmDG7duoXJkyejVq1aCtnQgIAA8ZGeMzu6fefOHbl9D0lOThaX7AGKsqzZORt/pD/AYlcXWCc5o0VFPYytVxL2psZK2ybGijKgOPLyiBhw5xPjI+6zNbbFKI9R6O3eW7TlYxqsxXQg8A7w9LiUCvr5WcCM68gYY5qtqZs9jn/VHEtOFMf+V6+QYOaPmZcnYYXeGlRxbwiNCizIrFmz0KpVK+zYsUMcvNva2mLevHno0KEDFCWzeIVWHLKj2+np6XL7HrJgwQJ8//33791PU8aLeiZEhiwd6Rnp1NkdwEOcxUl8h1FiO6jzDV10wKsWTDMH3FExdlbhmg7E1Gy6eMITIzBC2ZvIigp1iZJ5AV8XB3S5bTBjTIukp4BaWNCRXm29lkrZhPwUkBcosCCNGjUSl6JCB/UkLCwsx/3U5rZ48eJy+x4yffp0sfqSfcWiZMmS4vuUMcciKjQQEfrxOON/Dqd9T+Ne2L0cny9TrAxalWyFVqVaiYEqFGwwpq5dnnZ578L6B+sRkig1WLA2ssanlT/FgIoDYG5oruxNZMoQ/BBY0xpITQAaTwTa/sCvA2NMs6WnAhu6A68uIdzODbqDjsLa2k6pcywUFljQILy1a9eKLkv+/v5wcnJCmzZtxFwLExMTKAIFCdQu9uLFi+jeXSpoIRcuXBBdquT1PcTIyEhcVIWVvROsqKWvdXmMqDYCIQkhOOt3VgQZV4OuiqFga6PXYq3XWjFUpWXJliLIqOdYj/v3M7UQmRSJHU92iE5PkcmR4j6qofisymfo5d4LJvqK+bvC1IRDZaD778Cuz4BLywCnGkDVnsreKsYYU5wT34qggjrk2fbbAigpqMivfE/epq5QVMD98OFD9OrVCy4uLggODhaD8qiVq6enJ8zMzBSysb/88ovo8kSF4jVq1MCyZcvwzTff4N69e6hYsaL4milTpogZG2fPns3z96jd5O1sYlNicTHgoggyaFpjfGp81ufMDczR1KWpCDKaODfhs71M5byIfoFNDzfhwPMDSEpPEvdRlycKoLuV6wZDmsDMWCZqPXt5BWBgBow8KQUcjDGmae7tBHaPlK732wxU6qLUzcnPcXC+Vyz2798PX19fPHnyJCvVKHMad8OGDbFhwwaxcqEIlJ5EQQxN+KaWt/T8NKcie4BAP3T21Ke8fI86szC0QMcyHcWFevtfC7omgowzfmdEK04qfKWLga4B6jvVF0EGrWjw4DCmLHQug1baNj7ciPP+b7uzVbKphKFVhqJ96fbQ1y1wlibTZK2/AwLvAS/PAdsHAaPOACa0nssYYxoi6D6w/wvpetOpSg8qFL5isWrVKtEB6s8//3zvc7NnzxaF0XPmzIEi0apJbGwsrKys3iumpqiKUrWooDyv36POKxYfK3y9H3ZfBBl0yeyoQ6jY28PeQwQYzV2ai2FiRV2UzrSzfuLwy8PY9ngbnkQ+yXovtijZAkMqD0Fth9r8PmT/LT4c+LMFEO0LuLUDBmwHdLmujDGmARIipL9vUa+Acq2BQTsBXeUPP87PcXC+A4vLly9jwoQJuHbtWo5uS/Qw7du3x5gxY9Czp2blvqpjYJFbyolYyfA9817xt7OZs0iZaubSTNRlGOtzK1smP08jn4r6iYMvDiIuNU7cRzUTPcr3wOBKg1HKshTvbpY/NNPi7/ZAWhLQ/Gug5Qzeg4wx9ZaRDmzuAzw/BVi5Su21TW2gChQaWNB0bSp8NjU1xfDhw+Hs7Cy6JW3evBne3t5Zk60JdVIqV64c1J0mBBbZUfE3BRjn/M+J1Knk9LczO2guAAUXFGTQxdncWanbytQTvadoUigFFLdDbmfd72rpij7ufURQUcwobx0mGMvVna3A3jHS9f5bgYqdeEcxxtTXqbnAhcUANSsZeQJwrAZVodDAYvHixZg2bVqevpYKqenr1Z2mBRbZJaYl4lrgNZHrfj7gvJhonF15q/JZQUZ1++qc+84+iP6UUPrd/uf7RV1PTIo0WJLmTlBtT98KfUXQyu2QmdwcngZc+1N0TcHnZwA7N965jDH18+igVDdGev4FePSFKlFoYEFf/rHhctnRykXm6oU60+TA4t3X9mnUUxFkXPC/gDuhd0StRiZLQ0s0dG6Ihk4NxUdezWCEglFKc9r3bF+OWh5HM0f0cuuFnm49RetYxhTS5319N8D3MmBXARh1CjCy4B3NGFMfod7AX62AlFig/lig40KoGoUGFtpIWwKLd0UnR+NSwCWxkkEtbel2dpTW0sCpgQgy6Ew0dahi2iEqKQqnfE/hqM9RXA28Ctmb2fDGesZo49pGtIql94SeChSdMQ0XGwz82RyIDQQqdQX6bgS4GQVjTB0kx0pBRZg34NoYGLIP0DOA1gUWAQEB+Pvvv/Hy5UukpKTk+Fznzp0xYMAAaBJtDSyyS89IF0Xfl19fxpXXV+AV5oV02duVK0pvoanfmasZ1HWKWtwyzQsmjr86LoKJ7K9/HYc6IphoV7odzGjGAGNFye868E9HICMVaP0t0HQK73/GmGqTyYAdnwKPDgAWzsDoc4C5aq7uKzSwCAwMRLVq1UTRNn00MMh58NixY0f069cPmoQDi9wH810Pui6CDM9AzxwpMMRU3xS1HGqJFqJ00FnFtgpPAVdDgXGBIjXutN/p94KJijYVxcyJDqU7wMXCRanbyRhu/AMc/Eo0McagXYBbG94pjDHVdWEJcOp7gAbBfnYEcKkDVaXQwIJWKjZt2oTTp09DW3BgkbcDUAowMgONyOTIHJ+nFBkq/haBhmMdVLOrxm1tVXhlioIJ6hpGrWKzywwm2rm24zaxTPXQUKlbGwBjK6lVo00ZZW8RY4y979kpYHNvgOpYu/wK1PkMqkyhk7dJ+fLlC7ptTEM5mTvhE7dPxIUKvr0jvXEz+CZuBN0QHynQoGnLdMFdiO5SVW2ripQpcbHzEMW+PKiv6AXEBYjOYBQQUqpbVHJUjhQ3CgipKxgHE0zldVoMBD8AAm4C2wcDI44DhpyaxxhTIZE+wK7hUlBRa4jKBxX5VaBUqKZNm+Ls2bNwcdGO9AdesSgceovRgD4RaATfwM2gmwhJDHnv6+xN7MVKRmawQelTpgamhXx2ltscE5pfQsEEfaTAIjsqwm/i3ATNSjYTH63o7C9j6iI6QCrmjg8FqvYGeq3hYm7GmGpISQD+bgcE3Qeca0kpUAaqP5RY4cXb8+bNw4IFC1C/fn1YWOTsBETD84YNGwZNwoGFfNFbzj/WH7dCbom5B/dC74mUmzRZWo6vo7PlZSzLwN3GXaTgVLCugAo2FWBnYifnLdJcqempeBzxWKQ33Q29K/b1u4GEvo6+KLyv51RPFN/XKF6D55Uw9eZzCdjQDchIA9rPBxqOV/YWMca0nUwG7BkN3NsOmNpJxdrF1OMEvUIDC5quTUXbtWrVgoeHx3vF223atBHBhSbhwKJoBvU9Cn+UFWjQx8D4wFy/1tbYVgQaFHBQsFG2WFnR+lbbVzeS0pLwPOo5nkQ+Ealo1LmL9mlKRs7ObTrQQSXbSqIdLF2oyJ47OTGN47kKOPo1oKMHDNkLlGmm7C1ijGmzq6uBI/978zdpH1CmKdSFQgOLP/74A3v37sXx48ehLTiwUI7QhFBxtp0OlJ9EPBHXX8W8ypqZ8C4nMyeUKVYGpS1Li4+lLEqhhEUJcb8hdV3QEPGp8fCN8cWr2Fd4Ff1KDDWk/eMb65tjoGEmKyOrrDqWavbVxOoEDTtkTHvODtoCn58DrEoqe6sYY9ro1WVgfVe1XUVVaPG2jY0NSpUqVZjtYyxP7E3txaWpy9uoPiE1Ac+inmUFG3Rm3ifaRxSH0woHXagA+d0z9PQ4LuYuYlo4XaieQ1zoOUzsRXqVgQoMpaE4nwYRBicEi1qIzI+v416LwIECivCk8A9+v42xDdyt3cWFVnWo8LqkRUkuimfah4bkUbeVkIdSPjP1i//sqFrkMzPGNEjMa2DHUCmoqNoLaDAOmizfKxavX79Go0aNcOrUKZQrVw7agFcsVF9kUqSYpfEy+qUINOijf5y/qCegNKu8sDayRjGjYrA0skQxQ+kjndmn+8wNzGGkZyQuxvrG0kc9Y7ESQrUgmbJ3tUrLSENyejKS05Klj28utD0xKTEigKBL5nX6GJYYJr7mv1AAQSsypSxLobxVeZESRqlhlCbGnbUYy/7H4ZVUzJ0YCdQYDHT/jYu5GWNFIy0ZWNcZ8L8OFK8CjDyhlp3qFLpiceXKFWRkZKBKlSqoXbv2e8XbvXv3xsiRI/O/1YwVgrWxtbjULF4zx/0UN0ckRYgz/hRkULARFB8k0qzoID40MVRcKAigVY93528oCwUOxU2LZ10cTR1FHUlJy5IioKDOTYyxPLB2BXr/A2zqCdzZBJSoCdTl/1GMMQWTyYDD06SgwrgY0H+TWgYV+ZXvwMLOzg59+/b94OcdHR0Lu02MyQ2dvbc1sRUXqi/IDQUfNLuBAg2xipASjZjkmBwrCVTXQCsJVCAtPqYnZa1EiMd4U/eRuQBIt2lWR+aqRtZHfWNxPbdVEfpIKVkUSGhSTQhjSleuJdB6DnByDnDkG8ChGlCqvrK3ijGmyW6sBW6tFwnZ6LUWsCkLbVCgdrPahlOhGGNMzdG/up3DgId7AXMHqZjb0knZW8UY0/Ri7TbfAU0mQVuOg98mh+eTp6cnlixZgqNHj4rbISEhePnyZUEfjjHGGFMcqn/q/jtgXwmICwZ2DgXScrZiZoyxQov2B3YMkYKKKj2Bxl9p1U4tUGAxdepUtG7dWgQWJ0+eFPelpaWhQ4cOSEpKkvc2MsYYY4VnZA703wwYFQP8rgJHv+G9yhiTn9REYNsgID5USrnUwmYR+Q4s7ty5g40bN+LRo0eYNOnt0o6zszPq1q2LnTt3ynsbGWOMMfmwLQf0+kvKe6Yc6NubeM8yxuSTbnlgIhB4BzCxkU5iaEGxdqEDi+vXr6N79+5ilsW7bS3d3Nzw+PFjeW4fY4wxJl/u7YEW06XrBycDAbd4DzPGCsfzD2kgJ03W7rte6kinhfIdWOjq6iI+Pj7Xz3l7e8Pa2loe28UYY4wpTrNpQIVOAHV22/4pEBfKe5sxVjDPzwDHZ0nXabJ2mWZauyfzHVi0bdsWhw4dwt27d3OsWGzevBk7duxAp06d5L2NjDHGmHzp6gKfrAJsywMx/sCuz4D0NN7LjLH8iXgp/f2QZQA1BgH1R2v1Hsz3HAtKgfrpp59Qv359WFlZQV9fH1u3bhUTuRctWoTKlSsrZksZY4wxeaKhVf02A2taAz4XgBPfAh3m8z5mjOVNcpxUrJ0YCZSoDXReonXF2nKbY0FpT7t370ZAQABsbW1F3UXNmjmnHmsKnmPBGGMa7OF+YMen0vWefwEeHx4Cyxhjb2fjDAUe7nszG+csYOkMbT8OzndgQd2gEhMTUatWrXx9Tp1xYMEYYxru5PfAxSWAnhHw2RHApbayt4gxpsrOLwZOzwV0DYBhh4BS9aGpFDogj+ortmzZ8sHPUVoUY4wxplZazQLcO0jF3NsGAjGvlb1FjDFV5X0MOP2jdL3zYo0OKvKrwJO3cxMUFCTqLhhjjDG1oqsnpUGJydxBUnBBw64YYyy70CfAvyMpFwqoMwKoPYz3T0GKt7dt24bffvtN1FSkpqbC09Mzx+epBe39+/dx4cIF3sGMMcbUj7ElMGAr8Fcr4PVtYN94oNdarS/GZIy9kRABbOkHJMcApRoBHRbyriloYEHdoNq0aYPLly8jLi5OXM+Ocq6aNWuGOnXq5PUhGWOMMdViUwbouwHY2APw+hcoXhloNlXZW8UYU7b0VGDHECDyJWBVCui3EdA3VPZWqZx8F2/fuXNHrE40btwY2oKLtxljTMtcXwscmixd778FqNhZ2VvEGFOmg5OBG2sBQ3NgxHHAoYrWvB4xiizerlGjhlYFFYwxxrRQ3RFA3VHS9X9HAUFeyt4ixpiyXPtLCiqgI9ViaVFQodTibcYYY0xjdFgAlGkGpMYDWwcA8WHK3iLGWFF7cRY48rV0vc0coGInfg0+ggMLxhhjLDd6BkCf9YB1GSDaF9j+KZCWwvuKMW0R/hzYMRSQpQMe/YDGXyl7i1QeBxaMMcbYh5jaAAO3A0aWgO9l4PAUaeIuY0yzJUZJHaCSooASdYCuy7lDXB5wYMEYY4x9jH0Fqe0s5Vff2gBcXc37izFNlp4G7BoOhD8FLEtIDRwMjJW9VZrTbpZazB4/fjxPD9ioUSO0a9eusNvFGGOMqQ73dkDbH4ATs4Fj0wF7d6BcK2VvFWNMEU58Czw/BeibSEGFhQPvZ3kGFr6+vjh58mSeHtDe3p4DC8YYY5qn0RdAyEPg7lZg5zBg5CnAzk3ZW8UYk6eb6wHP36Xrn6wEnGvw/lXkHAttxHMsGGOMCalJwPqugP81qaibggszW945jGlKB6hNvYCMNKDFdKDFN8reIs2fY8EYY4xpLcqzptQImrxLE3i3DQTSkpW9VYyxwgp9AmwfIgUVVXsDzd+0mGXyT4V6F03e/uOPP8QU7oiICGRf9OjduzdGjhxZkIdljDHGVJ+5PTBwJ7C2HeDnCewbLw3N0tFR9pYxxgoiLhTY3AdIjgZKNgC6/86/zwWU7xWLtLQ0MXl7x44dovYiLCwMdnZ2uHr1Kh48eABHR8eCbgtjjDGmHopXBPquB3T1gfs7gbMLlb1FjLGCpjfSymPUK8C6NNB/M3eAKsrAgrpDZWRkwNPTE927d0fz5s2xadMmPH78GLq6uqJ4mzHGGNN45VoCnZdI188tBO7tUPYWMcbyIyMD2DtWqpkyLiatRJrZ8T4sysDi+fPnaNasGfT09GBkZCTSooiDgwMGDRqEEydOFGZ7GGOMMfVReyjQeKJ0nVKiXl1W9hYxxvLq7HzgwW5p5bHfJqmNNCvawCI5ORnGxtKQkBIlSsDLyyvrc1FRUWI1gzHGGNMarb8DKnUF0lOAbYOA8OfK3iLG2H+5sxU4/7N0vesyoEwz3mdyUKiuUDQIj+oq+vbti9GjR2Pt2rU8w4Ixxph20dUFPvkTcK4FJEYAW/oCCRHK3irG2If4XAT2fyFdbzIZqDmY95WyAouhQ4di8uTJ4rq5uTnOnj0LExMThISEYNu2bWjQoIG8to0xxhhTD4amwIBtQLGSQPgzYMcQIC1F2VvFGHtX2DNpZTEjFajcA2g1m/eRHPGAvDzgAXmMMcbyJPgBsLY9kBILVB8A9FjJbSsZUxXxYcDatkDEC6BEHWDYQcDARNlbpVHHwfp5fUCaV0EPSkXbdP1D6Gusra3zv9WMMcaYunOoAvRZJ6VD3d0KWJYAWvMZUcaULiUB2NJPCipowOWArRxUKCsV6s8//0SZMmUwb968rOsfutDXMMYYY1rLrQ3Q9Vfp+oXFwPW1yt4ixrRbehqwazgQcAMwsQYG/QuYF1f2VmlvKhR1e6JBeLQSQSsWdP1D6GtsbW2hSTgVijHGWL7R0LyzCwAdXamVZcXOvBMZK2p0mHvwK+DmOkDfGBiyHyhVn18HZaZCWVlZiQuhadsUi7i5ub33dfQ5SpPStMCCMcYYy7fmXwMxAcCtDcCuEcDQ/UDJerwjGStK5xdLQQUF+L3WclChal2hduzYgdWrV+f7c4wxxphW0dEBOi8F3NoDaYlSfnfYU2VvFWPa4/Ym4MyP0vWOPwGVuih7izReoeZYvCuzwFuRli5dCldXVzGkr27durh48eJHv37MmDHQ0dHJcalatapCt5ExxhgT9PSBPv+8nXGxqScQG8w7hzFFe3oC2P/l21kV9UbxPi8CeUqFIgcOHMD69evh7e0tpm/7+Pjk+Hx8fDzOnTsnvk5RaADfzJkzxcpIw4YN8dNPP6FDhw54+PAhSpUq9cHv69WrF3bt2qWw7WKMMcY+yNAMGLgD+Lud1JFmSx9g2CHAyIJ3GmOKEHAL2DEUkKVLbZ9bf8v7WdVWLGgInp2dHczMzLKuZ79Uq1YNO3fuROvWrRW2sT///DNGjhyJLl26iDqOhQsXitqPlStXKuw5GWOMsUIztwcG/wuY2gGBd6UBeumpvGMZkzcRvPcFUuOBsi2Brst5lowqrli0adNGXC5duoTY2FixUlCUKM3qyZMnmD9/ftZ9lNbUokULXL58+aPfe/ToUZiamoo0raZNm4qVjtKlSxfBVjPGGGNv2JQFBu0A1nUBnp8G9n/BA/QYk/cAvE29gPhQwNED6LcR0DfkfazKNRaNGzcu8qCCBAUFiY/29vY57i9evHjW53JTvnx5bN26VXzN6dOnRassCi7o44dQqhe11sp+YYwxxgqtRG2gz3pAR08aoHdyDu9UxuQhORbY3EdasShWChi0k9MNVTWwWLdunSh4/uWXX7Kuf+hCX5NXw4YNe6+w+t3Ls2fPPvoY1PqWvu5Dpk6diq5du4q+u5UqVcL27dvFHA76+CELFiwQqxuZl5IlS+b5Z2KMMcY+yr0d0G25dP3SMuDim2F6jLGCSU0Ctg0EXt8CTG2ltEMLR96bqpoK5eHhIWobateuLWos6PqH0NfkFQUpdMkLR0fpDRIaGprjfrrt4OCQ5+ekmgwXFxc8ffrhln/Tp0/H5MmTs27TigUHF4wxxuSm5mAgIQI4MVtatTCxAmoP4x3MWEGmav87Anh5HjA0BwbtAuzdeT+qcmBRq1Ytccl+u6jZ2NigQoUKOHPmDHr27Jm1WnH27Fl8+umneX4cmiLu7+8PZ2fnD36NkZGRuDDGGGMK0/hLqQXtxaXAwUmAsRVQpQfvcMbyM1X7wETg8UFAzwgYsBUoUfTHqKwAxdvvysjIEHULKSkpOe6n1CFra2soAqU1TZw4UdR4ULvZRYsWiUCBZlVkotUUT09PeHl5iVqJ/v37ixWIKlWqiMngX331FSwsLDBo0CC5blt6ejpSU7nDB1N/enp60NfX/2iKIWNMTlrPARIjpcnA/44EjC2Bcq149zKWl6Di+CzgziZpqnbvv4EyzXi/qWNgMWfOHNH6NTEx8b3PTZkyBYsXL4YiUNBAaUljx45FcHCwaHFLHZ9oYF5uaNWBvocCktu3b4uAhwq3r169Koq+5SUuLk6sgtAKCmOagLqoOTk5wdCQu2kwpvjp3EuAxCjg4V5g22Bg6H7ApQ7veMY+5uIS4Mpv0vVuv/FUbRWhI8vn0fD58+fRuXNnrFq1SqREGRgY5Pg8HbzTjAlNQsEMrcRQJykqAn93pYLqNehAjDpW8Vleps7ozwGtQlLtEr233dzcoKub7+ZxjLH8SksGtvQDXpyRUqKGHwWKV+L9yFhubvwtpQ+SdvOARhN4PynpOLjQKxYPHjxAv3795J5KpK4o/YkOxiiooMGBjKk7eh/TCYNXr16JIMPY2FjZm8SY5tM3AvptAjb2APyvAxu6A58dAWzLKXvLGFMtd7cDB9802Gk6hYMKFZPvU5E0WO5jMyC0Fa9UME3CqxSMKYGROTBwB1C8ChAXDKzvCkT68EvBWKYHe4C9VFcrA+qOBFrN5n2j7oFF69atxZnMzZs3i+JoxhhjjMmJqQ0wZC9g5w7EBADruwHRAbx7GXt8WGpwIMuQ2jV3/FmqUWLqHVj88ccfohB68ODBImWC0iSyX6gDE2N5QWk2NBWdivGPHDmiETvt4cOHorkBzUH5999/uaCfMZZ/5sWBIfsB6zJA1Ctp5SI2iPck017PTgI7hwIZaUC1PkDX5bS0ruytYvKosejWrRvKly//wc+XK8f5oOy/Xb58GX379kXjxo1x8uRJlChRAh07dlTrXXfixAl06dJF1B9Rp7IJEybg0KFD+Pvvv5W9aYwxdWPpJHWH+qcTEPFcqrkYdggws1P2ljFWtGjw3bZBQHoKUKkb0GMVoKvHr4KmBBZly5YVF6b+Zs6cifDwcFEfQp286MCeDvSLAk0yv3Xrlmj7S3U78vD48WP8+uuv4jrNYShTpgyGDh0KO7ui+UdMgcRnn30mOqZlpg1Se+PPP/8cDRo0KJJtYIxpEKtSb4OL0MdSYffQA4CJYmZFMaZyfD2BLf2BtCTAvQPQay2gV+ARbKwI5OnViYiIQEhIiDj4pOFZdP1D6GuoQxJTfXRWnQ7wadiht7c3WrVqJdJ36Kx7Xi1btgyPHj366Nf89ttv4kA/O3peeaMAqUaNGuJ6UlIS9u3bh99//110Mstrxy4KtCjg+pj69euLACK7J0+eiH34119/Zd3XpEkTETTt37+fAwvGWMHYlJXSotZ1AoLuAxt7Ap/uAUyseI8yzeZ/E9jcB0iNB8q2BPqsB/R5tpJGBBaUyjFt2jQx/M7R0VFc/xBFDshTB9R6NjE1XSnPbWKgl6/uVHQm/d0+xXQwnp/AglLfaBChKnTMqlChgrhkGjdunJgvcu/ePREM5AUNhMsMTj4kt4GMNMuE0CpJdhRYPHv2LI8/AWOM5cLe/U1w0Rl4fQvY+AkHF0yz+V0HNvUEkmMA1yZA/y2AAbc+15jAYsyYMejfvz8sLCzEigVd/xD6Gm1GQUXlb48p5bkf/tAepoZ5XyK8ceMGTp06hYCAAFFIfenSJXTo0EF8jtKU6Ew76d27N6pWrZrrY+QnCFE0+hl2794tCqgzB7zRhYILEh8fjx07diA2NhZdu3Z9LwjIfP/S+z2/MqfQv/v+p0EyCQkJBf6ZGGNMcKgspUVRlygKLqjmglYuqIsUY5rE9yqwqReQEgu4NgYGbgcMpf/jTPXl6SjU3NxcXLLfZuq9qkJdvc6dOycKqKlmhjp6bdmyBVWqVMnxtXv37kXFihU/GFgUNBVK3qi+om3btqKxAKV0VatWTaRA0fO6u7uL1ZhmzZqJafE0o2H27Nnw9PREpUqV5JIKlTmJMioqClZWb1MUIiMj4eLiIteflTGmpRyrSTUWG7oBgXekj7SSwcEF0xSvrgCbewMpcUDppm+CCjNlbxXLB66AUUA6Eq0cKOu58+LYsWPYuXMn/Pz84ODgIO7z8vISZ/Iz04DoAJwuPj4+apEKNWvWLNStW1esWGSaOHGiCBxo+2hC+p49e7JWKWgGS26BRUFToTIDMlotySxGp9oVqr1o31457wfGmAZyrAoMPSi1oKWaC1rBGLIPMLNV9pYxVjg+l97WVJRpBgzglQp1xIGFnNFBdH7SkZQhODhYFDNnnlmngGL06NEizY3O9OeHIlOhKDVr48aNYlXkv4IX+pk8PDyybl+4cEF0Z+rXr997q260ikCB1MKFC+WWCkWrEtRRa+XKlaK7Fr0Ptm/fLlZAKJWMMcbkmhZFrWcpuAim4KKrFFyYc+MUpsYtZbf0A1ITpEJtqqng9Ce1pNpHwEwh6MCX6g6oBWrlypVx9+5dcSbfzc0tz92TCotqICgdidDBN9Vz+Pv7ixUEWmnIrAHZtm0bVqxY8Z+PR6lJFBBQgEH1DtQVihoNVK9ePcfX0ecHDBggukXR7Ax5+vPPP0WL2Xr16olA4/jx41i0aFGOgnLGGJOL4hXfBhchD4D1XaQ0KRqux5g6eXH2TUvZRKBca6D/ZsCgaI5FmPxxYKGFaHYEnbGnA19K/aGDbErhiY6OLrJtoBWIzJSj7KlH2esRqLCcgg8DA4P/fLzhw4ejZs2aIkii9Cxq9frPP/+gZcuWWV9D7WBprgWtKvxXulNBUJBGz0GD8mgViIIKqu9gjDGFdYsSwUUXac7F3x2klQsr+bfzZkwhHh8Gdg4D0pMBt3ZA343c/UnN6ciokpd9FBX+FitWTBx4ZxbpZqIz4y9fvhRn/KkAWlNQbcW6detE8TYVRFO9xYwZM4p0GzZt2iSKyyn4KSyavUIH/u3atcs62G/Tpo0IQNj7NPV9zZhGCn8zmTvaD7B0AYbsBezclL1VjH3c3e3A3rGALB2o0Anosw7Q/3jaM1O94+B36RbZVjG11KNHjw92hFI06lwlj6CCUCcomozNKwiMMY1jWw4YfhSwdQNi/KWVi8C7yt4qxj7s2l/Ans+loMKjv7RSwUGFRuAVizzQxhULpt34fc2YGooPk4aKUVBhZCm16nRtpOytYuwtSpK5sBg4/aN0u97nQIdFdPaP95IK4xULxhhjTNuY2UkF3KUaSROLN/YEnp5Q9lYx9jaoOD7rbVDR7H9Ax584qNAwHCIyxhhjmsK4GDD4X6kQlrrsbO0PeP2r7K1i2i4jHdj/BXDlN+l2+/lAq5nUo1/ZW8bkjAMLxhhjTJNQ//9+m4GqvYCMNGDXCODKH8reKqatUhKA7YOB2xsBHV2g229Aw/HK3iqmIBxYMMYYY5pG3xDo+RdQdyTloADHpgNHpwMZGcreMqZN4kKldshPDgN6RkCf9UCtT5W9VUyBOLBgjDHGNJGuHtBpMdDme+m25x/AzqFAaqKyt4xpg7BnwNo2QMBNwMQaGLofqNxN2VvFFIwDC8YYY0xTUQ57k6+AXmsBPUPg0X5p5kVChLK3jGky36vA2rZApA9g5QqMOAGUaqDsrWJFgAMLxhhjTNNV6w18ukcq7vZ7c9AX8VLZW8U00aMDwIZuQGIE4FwLGHmSBzZqEQ4smFK9ePECR44cgZeXl8a8EtevXxcTy5OTk5W9KYwx9lbpJsDwY9J07nBKU2kL+F3nPcTk106WmgRs/xRISwLcOwLDDgLmxXkPaxEOLJjSfPnll6hWrRoWLlyIZs2aoWvXrmp9ML59+3ZUr14dvXv3xieffILIyEhlbxJjjOVUvJJ0BtmxGhAfCqzrDNzZynuJFU5aMrB/gtQkgJoF1BkB9NsEGJrxntUy+sreAKY8p06dQmxsLHR0dGBra4tatWrB1NS0SJ57586dWL16NTw9PVGzZk0EBASI51+8eDFmzpxZoMcMDw/HhQsXxHV9fX0xDb1KlSooysmU69evR1hYGNq2bVtkz8sYY/li6QR8dgTYPRp4cgjYOwYI9gLa/iAVfDOWH7HBwI5PpRQ7aifb7kegwTieUaGlOLDQYmvWrEFiYiIyMjLg7e2NqKgonD17FhUrVszzY1y+fBkhISEf/Zpu3bpBVzfn4tjGjRvRpk0bEVSQEiVKYMCAAdiwYUOBA4uHDx9i3bp14npSUpIIWugAf8eOHSJ4youEhAQcP378o19TsmRJ1K5d+737R40aJT6ePHmyQNvPGGNFxshCOqN8dj5w/mdpcFnoY6nI28SKXwiWN6/vANsGAjEBUv1O73+A8q1572kxDiy02NatOZe/O3fujJUrV2LZsmV5foxjx47h7t27H/0aetx3Awv6nkGDBuW4r0aNGli+fLkIdkxMTJBfTZs2FZdM/v7+cHV1FfUblHKVF3FxcVnByYe0aNEi18CCMcbUCv1dbjULKF4Z2DsOeHYSWNMaGLCNi23Zf6OJ7nvHSxPebd3evG/K857TchxYKKJ4KTUBSmFgmq+lx5SUFDx69EikIdF1qm+gg3oSGhqK58+fi+tubm4iVSo333//pj96PkVHR8Pa2jrHffQcMplMpBQVJLDI3O6nT5+Kj+np6eLxMn8mEhgYKNK/6GfKbRWjePHiovCaMca0RtWegG05YOtAqaj7r9ZA77WAG6d0slxkpANn5gMXFku33doBvdZIKxZM63FgIW8UVMx3Vs4ba8brPBdKUS3A9OnTYWVlhVKlSsHY2BhXrlxBx44dxefp+vz580VwsWLFCvTv31+uqVCGhoYi7ejd1QJiZGSUp5/h3e8dP348du/eDQ8PDxGkREREiMDC3d1dBE2jR4/GiRMnoKenBzs7O5GyZGNjI7dUKMYYU1tO1YHPz0gdffw8gc19gGZTgRbTue6CvRUXAvw7Enh5TrrdeCLQeg6/R1gWDiy0EKUhDR8+XKQxUZ0DoTP8Tk5OIh0pMxigy7BhwxSSClW2bFn4+fnluI9uU6BDl/yiuox79+5lPQb56aefxGoM3aaC6tatW4s0J6opoQBq//797/18nArFGNNa1BaUpiMf/Qa48bdUe+HrKdVdWDgoe+uYsvlcAnYNB+KCpAyJrssAj77K3iqmYjiwkDf6ZaOVA2U9dx7cuHFDHGxnBhXkhx9+EKlD1C41PwqaCkUH9tQVioqsabWEVhb+/fffrBUT8urVK9y+fVu0oaVVho+5du0a2rVrlxVUUIcoqteoU6eOuE0rFJ9++qm4TilQtDKRW90Fp0IxxrSavhHQZSng2hjY/yXgcwFY1URKjSrTTNlbx5QhIwO4tBQ4/SMgywDsKwJ91gPF897ohWkPDizkjfL2Vbxvc7169USNw6RJk0SLVzpzTwXO1JmJDsCLaoYFpWPRasbgwYPFyseTJ09Et6hMdN/YsWPFKsJ/1Vw0atRIdJSi2gmqqaDHTk1NzVqByUSrFRMmTECPHj3kns5EXamouxatnJCjR4+KQKdu3bpi3zLGmFpN6nb0AHYOBUIeAhu6Ay1mAE2nSEXfTDskRAC7PweenZBue/QHuixR+eMcpjwcWGghOlN/+PBhbN68GefPn8fIkSNFncSzZ8+KbBuocJtWGWhVgQ7AXVxccPPmTZQrVy7ra65evYrPPvssT4Xc8+bNg729vaiboMegAuwZM2bkWJWh1ZGhQ4eKrk4UsMgbbT+tupDu3btnFYFTsMaBBWNM7di7AyNPAYenAXc2AWd+BHwvA5+s5mnK2oDS4HaNAGL8AX1joNPPQM1PeT4F+ygdGeWgsI+iLkXFihUTZ/ktLS1zfI4OVl++fCmGsVFKjyb9zHQGfu7cuWjYsCHat28vzrwXJSrG/vbbb+HgUPjc3vj4eHTo0EGs0NC8DEJF687OSiq0V3Ga+r5mjBXQ7c3AoSlSa1FTO6D7b0CFt6mrTIOkpwLnFgEXfpFSn2zKAX03AI5Vlb1lTAWPg9/FgUUhd6imHoDdunUL48aNy7pNE7lPnz4NdUX1Gv369XsvcMmsu2DQivc1Y6wQQh5JHYFoSjep/RnQfh6nxWiSsGfA7pHA69vS7eoDgI4/AcYfP5hkmi2GA4ui26F8AMY0Eb+vGWO5SksGTs8FLq+QbtPZbEqNKlm0K9pMAQXaN/8Gjs+W2uYbW0lF/DTjhGm9mHwEFlyBxRhjjLG8d41q9yMwZD9g4QxEPAf+bgccmwmkKGk4LCuciBfAhm5SqhsFFWWaA2Mvc1DBCoQDC8YYY4zlT9nmwLjLUpcgysO/8huwqrE064CpzwRtz5XASnrdLkgt6zssAj7dCxTjToasYDiwYIwxxlj+mVgDPVcDA3e8Wb14AazrBBycDCRG8R5VZcEPgH86SsMQaZWidFNplaLBGG4nzAqFAwvGGGOMFZx7e2C8J1BrqHT7xlrgtzrA3e0AN55ULclxwPFZwKqmgN9VwNBCqqWg1DabMsreOqYBOLBgjDHGWOEYFwO6LQeGHgDs3IH4UGDP58D6rkDoE967ykYB3sP9wO/1pMJ7WTpQqasUENYZzqsUTG44sGCMMcaYfJRpBoy5BLSaLQ1Vo9z9lY2AI99IU5xZ0Qu6L01O3/EpEBMAWLkCA3cC/TYBxVz4FWFyxYEFY4wxxuRH3xBoNhUYfxVw7whkpAFXVwLLa0rFwjSAjSlebDCw/wsp7enlOUDPEGg6FRjnCbi341eAKYS+Yh6WsbzLyMiAru5/x7jp6elITc39H5I2DnGTyWTQ0dEpsu9jjLF8sS4NDNwGPD8NHJsFhDyQioWvrwFazgQq9+AUHEVIipECuMvLgZQ46b4qnwBtvpNeE8YUiFcsmNLs378fFSpUgIGBAVxcXPD7779/9OtXrFgBKyurHBdzc3MxFTw8PBzaMqSGpoWbmZmJYKpTp07w8/P7z++7f/8+OnToIL7HwcEBM2fOREpKSpFsM2NMy5VrBYy5AHT5FTCzB8KfAbs+A1Y3A54c4QJveaE5IpeWAcuqA2fnS0FFidrA8ONAn3UcVLAiwYGFFqMDS5qwnJycXOTPffv2bfTq1Qvjxo1DbGwsli9fjkmTJmHXrl0f/J6vvvpKbG/2S/369dG6dWvY2toWeFvo51fWfsiv4cOH486dO/Dy8hIBBa3idOnSRXz8kCdPnqBJkyZwd3dHYGAgXr16JYKyu3fvFum2M8a0mK4eUOcz4ItbQIvpUjei4PvA1v7AmjbA0xMcYBRUSry0QkEBxYlvgcQIwNYN6P03MOIkUKq+XF9Kxj5GR0Z5EazAo8zpgPTly5coU6aM2qXj0CpBWFiYSEUyMjJCx44d8ffff4tVgLyi1KSPHdSS3PYLHSDfu3cPN27cyLqvf//+4mD50qW8DVh6/PgxKlWqhO3bt6Nv374oiMjISDg7O4v0IPo56GcfNGgQli1bBj09vTw/DgUlH/tVotQj2seFQQFB6dKlceDAARFMZAYNFStWxPHjx9G2bdtcv69nz55iv16/fj3Pz6XO72vGmBqgQm46u351NZCWKN3nUBVo/JWUtqPHmdp52ofX/gKurpKCCWJVSgrcqvXlfciK5Dj4XbxiocX8/f3FASStXFCqzMOHD/HLL7/k6zG6d+/+XnrSu5fcVgKuXLmC5s2b57ivZcuWItBIS0vL03OvXbsWdnZ26NGjBwrK2toaiYmJYj9QkHTu3Dns3LkT27Zty9fjeHh4fHQfVKlSBYXl6ekpPmbfb5RK5ujoKPZnbuhnOnr0KPr16yduUxDJGGNKZ2oDtP0emHgXaDgBMDADgr2A3SOBFbWkgINqBdj7wp9LXbaWVpFSniiooNoJmkcx4SZQYyAHFUxp+JSAnNFZ68TMsy9FzETfpEBFuXQgTwenlFbk4+OTr+89fPgwCiI4OBj29vY57itevLgIcmgV4d3P5XbAvGHDBgwdOhSGhoYF2obcHpPShWgVJL/7gVYOCoL2/X8FUrTSQa8r7TO6bmFh8d5+o8/lhu6nwIlWY2rVqiVWiajG4rPPPsOcOXNEfQtjjCmNhQPQfh7QdApwfa3UPSrqFXDkf8CpHwCPfkDdkYBDZe1+kTLSpXSx638Bz06+vd+xmrTKQ4XwvMrDVAAHFnJGQUX9LcrJZ7w68CpMDUzzfCA8d+5cnDp1CqGhodDX1xcH9XSwSTZu3IgvvvhCXKf0KEqnkWcqVG5nzzNv5yU4OnjwIEJCQjBy5EgUxtWrVzFv3jxxxj8qKkqkP9EKy6hRo/7f3r1Ax3zlcQD/JSIJEvFImgdBEbJKUW3iWe+lVLtKtUdVWz0eWy3rrafdlraWVi3dUo9laeux61WPODisaDmWiGebIN5C4hVKkEjI3fO90/90JibPmWQyyfdzzv9M/jP//8x/5k7+c3//e+/vmseCjB8/Xo4dOyatWrXSA8xRkXdUV6jJkyfL9OnTcz3GHTt2SOvWrfXftl4Dn1tOn5mx/eeff667ULVs2VK3fKArFcp80qRJub42EVGxtWC0HyfSarjI4WUiMQtErieYZvHGUqu1SPPXRBq9KOJlfXGlVLt5TuToSpFD34v8euH3++t3FWk5TKReZ/zAOPMIiaywK1QZhKvYqCQHBwfrijUCClSqkWkIXXoAXWdw1R5Zh3LLHlTYrlB4bQQGlrCOyje6J+WnG1S7du30+ILCwiDoDh066K5FGAyN92m0PBifw5dffikTJ07UgQeCjo8++sihXaEQ3GUfkJ59MYIKfGZGWWX/3NDiZAuCIBz3wIEDpU2bNvpv3KKlZ+3atYX+7IiIioRnRZGIwSLDY0QGbjDNDu1WTuTCHpH1w0Wmh4msGWy6av8wf91mXU7aryIHvxNZ3MM0IDt6iimo8K5i6jY24pDIgNUi9bswqKASxyVbLFC5unHjhlSrVi3f3WDQ3eTOnTu6klfU3ZHQcuAMeO382Lx5s76SbXmlHC0U+HyaNWum1/G5GktRdIVClqLo6Gir+9B6gu5YxqBplBlaQ7Jf6U9KStLjBpYsWfLI8+J9IZDBcec1NwYyUKHCP2bMGPN933zzjX49dIeCZcuWmR/r1KmTxMXFObQrVEEgwEDLBD633r176/sQECGwQLBgQDCCLk74HPFeIiIiHuluhZYmdoMiohILV+Hrtjctty6JHFlhWpCq9ueVpqVCVdMEfOE9TSltEZS4qtTLIsc3iRyPEjm7SyTLmLPpt8/hyVdNrTWu/B6pbFAu5Ny5c2rChAkqMDAQ/TtUdHR0nvtkZWWp8ePHq4oVKypvb28VGhqq1q9fX6DXvXXrln493GaXlpam4uPj9a2r2LJli3J3d9e3V69eVQsXLtSfqZ+f3yPbvvHGG2rFihUOP4a4uDjl5eWlJk+erJKSktSiRYtUuXLlVFRUlHkbo6yzmzJliqpSpYrNz/zkyZO6rDZu3JjnMcyePVs/T2xsrD6GadOmqcqVK6unnnrqkW0TEhJUy5YtVXJysnKm119/XdWvX18dPHhQH1ObNm1UZGSk/p4DPhO8/7lz55r3wWfh6+urP9uUlBR96+Pjo2bOnJnj67ji95qISjmc5xJjlYoao9S0Okp9XPn35bMgpZb1U2rPHKUux5m2Lcky05U686NS2z9RakFHpT72s34/syOU+mmGUr9edPaREqnc6sHZuVSLxcqVK3W6K1wlb9GiRb72mTlzpixYsEBn+2nevLlOI9q3b1+dBQkZdcqibt266av06B6DK/v4PNA15sCBA8V2DI0aNdLliG5GyESF1LdogejZs6d5G1xRtzU+Y/ny5fLmm2/afOz06dP6O4KWj7xgfAa6gv3xj3/U3a/wnL169dIT7llCpirMsYG0tjl1OSou8+bN02M+jC5qOPZZs2aZx1gYYzkwfsKA8RTz58+X999/Xy5cuCC1atWSqVOnyvDhw534ToiICgjnuZotTEv3aSKJe0WORZmu9N+6IJKwxbRApcdE6rQVqfm0aZK4oCede7X/zjWRpIMilw6IJMaIXNj7e5pdQ81nTK0v4c+L+Ic560iJyt48FkiTGhoaqruEoI98bpCHHxVny24/devW1SlK//73v5fpeSzyA5VtzNiMOSZcwbhx4/RYhNGjRzvk+TZt2qQr4RiPYGvQdmlV2r/XRFSKoBpz+WeRM9EiZ34UOb/n0Uo7xmk81kjksXAR/4amintAQxG/UBEvH8cdB+aWuHlW5NoJkesnRK4liFyNsx54bfAJFHkc3b06mLpyVQ52zHEQOXEeC5dqsSgoZDvCAGT057eEQb8xMTFOOy5XsHv3bn2l+969e3peh7Fjx+qArqTLK8NSQQ0bNkyP50EaWkAgu27dOoe+BhER2dmSEfykaWkzUuTBfVOrQOI+UwvBxViRu1dNM31jyc7Lz1Sp9w0WqeQv4uljyjyFpTzGLlpkXVIPTTNd378jcv+2yP1UkTtXRVKTRG4nizx8NFmJGQIatJ7UeMrUmhIQzsHXVOo4NbBA5IMc+7nBfAYFmQE5e2ABmEQt+3PmNKEYYPCvZSYjRGplDdKSWs7lUJj5MUoDDNa2TIvLAc9ERCWch5fI4+1Mi9GScPuSSPKR31oSEky3GAiug4NbItewHHfM6/sEiQQ0EPHH0tDUMhLSTMTbzzHPT1SCOTWwQOpO9FvPDXLu16lTp1DPb1SGs2fEwXpuwQq6vmB+gbIMffSLOoOWK8iryY+IiEo41AX8apoWjGGwhNm9U5NFbqPFIUkk7aZIBlojUk1LZvYuVW6/tWj81qrh6SviEyDiG/J7qwcCG6IyyqmBBQZSYykqISEh+jb7rMRYNx6zBYNcLfvoo8UCYzqIiIioFPGubFrQqkBEdit1E+QhCEhJSdF/Y6BJ06ZNZdu2bVatFZgv4dlnn83xOZBVB1eqLRciIiIiIiolgQXGY1y+fNk8dgKDarGOid0MaGnATMqGDz/8UL799ls9U3N8fLwMGTJE95n/85//7JT3QERERERUGrlUYLFhwwY9M/Rzzz0ngYGB8s477+h15PY3oJXCcrA2Us0uXrxY5/HHfpileOfOnQ5PHeqCWXuJcsTvMxEREZWJeSxKUv7ezMxMOXXqlB6zgW2ISgN0J0QQjjS7hc3KRkRERK6P81gUc/YkzNSM7llIReru7lKNQERWcJ0Bc5cgqEBWMAYVRERElF+leoK84oCUtpjpGbMUnz9/3tmHQ+QQCCqCgoL4aRIREVG+MbBwAE9PTwkLC5OMjAxHPB2RU6HljS0VREREVFAMLBwEXaC8vb0d9XRERERERC6FAwKIiIiIiMhuDCyIiIiIiMhu7AqVD0ZGXqTbIiIiIiIqK27/Vv/NzwwVDCzyITU1Vd+GhobaWzZERERERC5ZH85rzjZOkJcPWVlZkpSUJL6+vjq9rDMiRQQ1iYmJj0zQR6Ufy5/4HSjbWP5lG8ufbju5HoiWCgQVmAw6r/na2GKRD/gQa9asKc6GLxMDi7KL5U/8DpRtLP+yjeVPlZ1YD8yrpcLAwdtERERERGQ3BhZERERERGQ3BhYuwMvLSz7++GN9S2UPy5/4HSjbWP5lG8ufvFyoHsjB20REREREZDe2WBARERERkd0YWBARERERkd0YWBARERERkd0YWJQQCQkJcvDgQbl//36R7kMl082bNyU2NlYuXbqU730wUc7Ro0fl7t27RXpsVDyTD8XFxcmRI0fk4cOHBdr37Nmzsnv3brl161aRHR8VvatXr8r+/fvl2rVrBdrvxIkTcuzYMf0dIteVmZkphw8fLlBZ3rlzR58z4uPjWQ8oBZKTkwt8Lkc9AHUHTKBXYihyquTkZBUREaGqVKmi6tatq6pVq6aioqIcvg+VXNOmTVPe3t7qD3/4g77t37+/ysjIyHH7devWqSeeeELVrFlTNWnSRFWqVElNnjy5WI+ZHOfYsWOqQYMGKjAwUJcpln379uVrX5wLgoKCUAtR27ZtY7G4oKysLPXee+8pLy8v1ahRI307ZsyYPPfbvXu3CgsLUyEhIap58+aqRYsW6uTJk8VyzORYP/74o/4/rl27tvL391eNGzdWZ86cyXUfnPMrVqyofwPq1aunqlevrpYvX86icUH79+9Xffr0UQEBAfpcHh0dnec+aWlp6qWXXlIVKlRQ4eHh+vYf//iHKgkYWDjZ888/ryIjI9W9e/f0+qeffqp8fHzUlStXHLoPlUzbt29X7u7u+hbOnj2rf1imTJmS4z6zZs1S8fHx5vUdO3YoDw8PtWbNmmI5ZnJspfLJJ59Uf/rTn9TDhw/1fW+//bYKDQ1V6enpue6L7bt06aImTJjAwMKFLVy4UJ+/jx49aq5kILhYtmxZjvucOnVKX1D44IMP9HcIfv75Z11BJdeSmpqqK5SjR4/W65mZmfr/ulWrVjnuExMTo//nN27caL5v0qRJytPTU925c6dYjpscZ/HixWrlypU6mMxvYDFx4kR9ESopKUmv//DDD3rfvXv3Or1oGFg40eXLl5Wbm5tavXq1+T4EC/jB+Prrrx22D5VcaJ1o27at1X1/+ctf9BWogsAVrlGjRjn46KioGRWE2NhY833nzp17pNJgC4LP7t27q8TERAYWLqx169ZqwIABVvch0OzcuXOO+wwePFi3VhjBKLkutDKUK1dOXb9+3XwfLjThHIDWTFs2bdqkH7fcBy2WuO/SpUvFctzkeIm/ncvzE1ighRvBZPZ6wNChQ51eNBxj4UToG4ngrkWLFub7KlSoIE888YQcOnTIYftQyYUysyxLiIiIkNOnT0tqamq+niMlJUX3s69fv34RHSUVZfm7u7tL8+bNzffVrl1bHnvssVz/n//3v//J7NmzZcmSJSycUnoOyK38//vf/0qPHj10v/wDBw7I+fPnOcbCRaGc69SpI9WrV7cqf+MxW7p27SpdunSRt956SzZv3ixr166VcePGyahRoyQkJKTYjp2cIykpSa5cuVLg80Zx8XD2AZRlN27c0LeWJxRj3XjMEftQyYUys1WWxmO+vr657o8gc/DgwRIQECCvv/56kR4rOR7KuEqVKjq4yO//86+//ir9+/eX+fPnS2BgoFy8eJFF46LS09MlLS3N5jkACR3w/+3m5mazYoHB3uHh4fr7gwGcqJz++9//5gWGUvAbgPN++fLlczwH4LH33ntP3nnnHR1Q4DuEfQYMGFBMR03OdKOE1wPZYuFEODkYPy6WcJLw9PR02D5UcqE8bZUl5Kc8hw8fLj/99JNs3LgxzyCEXKP88/p/Hj9+vG7VqFq1qs4ggkxC8Msvv+jMUuQ6cjufe3h42AwqjP2ioqJky5Yt+grlhQsX9P8/rmCT658DHjx4oJeczgE7d+6Ul156SRYtWqT/79HCjaCiffv2OrMQlW7lS3g9kIGFE6FyANlTjGK9Vq1aDtuHSi6Up62y9PLy0t1hcoMrVitXrtTdIho3blzER0pFVf737t3TrRAGVChwNTqn/+fKlSvrbSZOnKiXqVOn6vtRyVi8eDELyoWUK1dOatSoYfMcYJzrbUHrRMeOHaVhw4Z6vWLFijJw4EDZu3ev7h5FrgPljBYoyxSzxnpO54BNmzZJvXr1pFu3bub70HqB9LPR0dHFctzkPKGhobqVu6TWAxlYOFGzZs3E399fNmzYYL4POaxPnjyp+1AaMFcBcpUXZB9yDSizrVu3SkZGhvm+9evXS6dOnXSlA65fv66vTFtWGEaMGCHLly+X7du3S9OmTZ1y7GS/Dh066KtPlv/P27Zt08EG+lAbYmJidD96+PLLL/X3wVjQvxpmzpypHyPXOwegxdGoWGZlZel1y/M5urvt2bPHvI4KZfZKBbZBtyjjaia5BpQzzvEYN2X5G4BgsU2bNubvBP7X0a8e0PUV+1jOYWV0icRjVPqcOnXKPH4C343WrVtb/W5gPivUB0pEPdDZo8fLuvnz5+vUgkghumrVKj0/QadOnay2QWrZV155pUD7kGtISUnRKeN69eqlNmzYoEaOHKnLFtmCDCtWrNCZIjBnAbz//vs6iwiygO3atcu8HD9+3InvhAoL5Vm1alW1aNEitXTpUlWjRg01aNCgRzKAIK2sLcwK5doSEhJU5cqV1ZtvvqnPAcgUh+8DsoMZpk6dqs8LltkBg4OD1bBhw9TWrVvVV199pXx9fdX06dOd9C7IHi+//LKekwrn+nnz5un0w3/729+sUtLiN+Cf//ynXr948aKev6pHjx46exxSlTZt2lSnrs4rTTWVPFeuXNG/4WvXrtXljPkosH7+/HnzNkhDjrqeYefOnap8+fI67ez69et1imJkk8R3xdk4eNvJhgwZolsgvv/+e92M2a9fPxkzZozVNrgiHRwcXKB9yDVUq1ZNX6maNm2azJo1S2f02LVrlzzzzDPmbXAFCleujL6T6EPbsmVLPVATiwFXuCdNmuSU90GFN2XKFKlbt65ueUAXp7Fjx8q7775rtU1kZKTu/mILus3h+4Gr1eR6wsLC9DlgxowZutUJXVzQpcmyKxS6PhhXrwGD9vft2ydffPGFfP755xIUFCRLly6VF154wUnvguyBsvvqq690V0b8P3/zzTdWyTjQeo3yRzkDus9hlm7sg23x29C3b1/dPRb7k2s5cOCA/h0AlPN//vMfvQwaNEgvxnnCsmcDxtOg29ucOXN0i3aTJk10ndDHx0eczQ3RhbMPgoiIiIiIXBvHWBARERERkd0YWBARERERkd0YWBARERERkd0YWBARERERkd0YWBARERERkd0YWBARERERkd0YWBARERERkd0YWBARkVPt2LFDOnbsmOs2Dx8+lKefflpPJkVERCUTAwsiInKqGzduyKFDh8zr//rXv+Stt96y2gZzuSKoSE1NdcIREhFRfnjkaysiIqIi0rlzZ9m5c6d5PSkpSY4dO2a1jYeHh+zfv18aNmzIciAiKqHYYkFERLnq0qWLrF69WiZMmKCDgN69e8uePXustrl165Z88MEH8uyzz0rXrl1l1qxZ8uDBA/PjycnJMmrUKN3lqU+fPrJq1SrzY2itwGOwdu1amTt3rvzyyy+66xOWqKgo3RVq2LBhkpCQYN7vypUrMnr0aGnbtq10795dFi5cqFs2DCNGjJCZM2fK119/Lb169ZLnnntOlixZkut7vXjxokRERMju3bvN9x0+fFgiIyNl165d/KYQEeWCLRZERJQrVKwHDBggI0eO1MHDxo0bdYCBrkmNGjXSlXlU2jMzM2XSpEly+/ZtGTt2rBw/flzmzZunn+OFF16QGjVqyF//+le5e/euLF++XCpWrCg9e/a06grVrl07efHFF3Ul3tj38ccff6QrVEZGhg5iQkND5cMPP9StHHhNBAY4BkAQsmDBAt2tCgHIiRMnZOjQoVKtWjV9PLbUrFlTvx6eE60o58+flx49euigBsdGRES5UERERLmoXr266t27t9V9Xbt2Va+99pr++4cfflCenp4qKSnJ/PjWrVuVu7u7On36tMrIyEAzgoqJibF6jvT0dH27atUq5efnZ77/008/VZGRkVbbZmZm6ueIjo7W63PnzlVVq1ZVqamp5m2+/fZbVaFCBXXjxg293q1bN9WmTRur5+nTp496++23cy3vhIQE5eHhoY8rPDxcDR06lN8PIqJ8YFcoIiLKE1ooLKG7k5GhCbdNmjSR4OBgq+5T7u7uurWjfPny0r59exkyZIgemH327Fm9jZeXV6E/ebxm69atxcfHx3wfukOlpaVZjc9AVypLaDVBF6rchIWFyaBBg6Rfv356TMecOXMKfZxERGUJAwsiIsoTui1ZqlSpkrlbEm6xbvXj4u4uFSpUMG+zefNm3Q1pw4YN0rx5cz2O4dSpU4X+5G29phFkWGaOwqBvS25ublbjMGxBcBIXF6e3e+WVV6RcuXKFPk4iorKEgQUREeUJ4yUsoVWgXr16+u/69evr8QwYYG1ITEzUFXxjGwQZGKewbt06PZAb68ZYiEd+mNzd86z84zXj4+Ot7kMwAMZrFkZWVpb0799fvxcM/sYxWg5CJyKinDGwICKiPKELk5GRCRX47777TncXAlzVv3fvnsyYMUOvo1KODFKNGzeWVq1aybVr1+SLL77QLQGArlFoBfD29rb5WkFBQXowNir5OXnjjTf0YGwcB6Snp+sB18g6haCjsN599139/jBA/aOPPtJB0OLFiwv9fEREZQkDCyIiyhPGLyArUoMGDXRXpr59++pMURAQECBLly7VgUWtWrUkMDBQDh48qDM/IYDw8/OTlJQUCQkJ0VmkEDggyPjkk09svhayQmH8Re3atc3pZm2Ng0B6WWSqQhYnPCdeY9GiRYUuzc8++0zWrFkjW7ZsEX9/f6levbputcBxInAhIqLcuWEEdx7bEBFRGYZK9uzZs+Xll1+WM2fO6LEMlgO1DegyhFYNT09Pm60GSEeLcRVVq1bVgYDh5s2bOq1rs2bNrJ7r3Llzen6MOnXq6Ep+bGysHkzt6+tr3u7+/fty8uRJfUzYzhLuR5crpJC17KKFfbIfH34KEQzhfSEAMqAlBl2uwsPDrQaKExHRoxhYEBFRvgKLV199lZ8UERHliF2hiIiIiIjIbmyxICKiXB05ckSPnUAXJiIiopwwsCAiIiIiIruxKxQREREREdmNgQUREREREdmNgQUREREREdmNgQUREREREdmNgQUREREREdmNgQUREREREdmNgQUREREREdmNgQUREREREdmNgQUREREREYm9/g86PJt4eA4AXQAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "x_plot = torch.linspace(problem.x_min, problem.x_max, 301)\n", + "initial_conditions = [\n", + " (1.0, 0.0, r\"$a_1=1,\\ a_2=0$\"),\n", + " (0.0, 1.0, r\"$a_1=0,\\ a_2=1$\"),\n", + " (0.7, -0.6, r\"$a_1=0.7,\\ a_2=-0.6$\"),\n", + "]\n", + "\n", + "fig, ax = plt.subplots(figsize=(8, 4))\n", + "for a1, a2, label in initial_conditions:\n", + " profile = initial_profile(\n", + " x_plot,\n", + " a1,\n", + " a2,\n", + " x_min=problem.x_min,\n", + " x_max=problem.x_max,\n", + " )\n", + " ax.plot(x_plot, profile, label=label)\n", + "ax.set(xlabel=r\"position $x$\", ylabel=r\"initial temperature $u(x,0)$\")\n", + "ax.axhline(0.0, color=\"black\", linewidth=0.7)\n", + "ax.legend()\n", + "ax.set_title(\"Examples from the initial-condition family\")\n", + "fig.tight_layout()" + ] + }, + { + "cell_type": "markdown", + "id": "d96c0bcb", + "metadata": {}, + "source": [ + "## 3. Enforce the conditions by construction\n", + "\n", + "Let $N_\\Phi(x,t,a_1,a_2,\\kappa)$ be an ordinary multilayer perceptron with\n", + "trainable weights and biases $\\Phi$. Rather than using its output directly, we\n", + "define\n", + "\n", + "$$\n", + "\\hat u_\\Phi(x,t;a_1,a_2,\\kappa)\n", + "=u(x,0)+t\\,x(1-x)N_\\Phi(x,t,a_1,a_2,\\kappa).\n", + "$$\n", + "\n", + "At $t=0$, the correction vanishes and the initial condition is exact. At\n", + "$x=0$ and $x=1$, both the sine modes and the factor $x(1-x)$ vanish, so the\n", + "boundary conditions are exact as well. This is a **hard-constrained trial\n", + "solution**. The network only has to learn an interior correction.\n", + "\n", + "The five network inputs are scaled to $[-1,1]$. The scaling bounds are\n", + "registered as model buffers, so they move with the model and are stored in its\n", + "state. Scaling changes what the network sees, but automatic differentiation\n", + "still starts from the physical $x$ and $t$ values." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "762974c4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ParametricHeatPINN(\n", + " (network): Sequential(\n", + " (0): Linear(in_features=5, out_features=32, bias=True)\n", + " (1): Tanh()\n", + " (2): Linear(in_features=32, out_features=32, bias=True)\n", + " (3): Tanh()\n", + " (4): Linear(in_features=32, out_features=32, bias=True)\n", + " (5): Tanh()\n", + " (6): Linear(in_features=32, out_features=1, bias=True)\n", + " )\n", + ")\n" + ] + } + ], + "source": [ + "class ParametricHeatPINN(nn.Module):\n", + " def __init__(self, problem, width=32, hidden_layers=3):\n", + " super().__init__()\n", + " layers = [nn.Linear(5, width), nn.Tanh()]\n", + " for _ in range(hidden_layers - 1):\n", + " layers.extend([nn.Linear(width, width), nn.Tanh()])\n", + " layers.append(nn.Linear(width, 1))\n", + " self.network = nn.Sequential(*layers)\n", + "\n", + " input_lower, input_upper = problem.input_bounds()\n", + " self.register_buffer(\"input_lower\", input_lower)\n", + " self.register_buffer(\"input_upper\", input_upper)\n", + "\n", + " def forward(self, inputs):\n", + " x, t, a1, a2, _ = inputs.unbind(dim=1)\n", + " scaled_inputs = 2.0 * (\n", + " (inputs - self.input_lower) / (self.input_upper - self.input_lower)\n", + " ) - 1.0\n", + "\n", + " x_min = self.input_lower[0]\n", + " x_max = self.input_upper[0]\n", + " t_initial = self.input_lower[1]\n", + " starting_profile = initial_profile(\n", + " x,\n", + " a1,\n", + " a2,\n", + " x_min=x_min,\n", + " x_max=x_max,\n", + " )\n", + " correction = self.network(scaled_inputs).squeeze(dim=1)\n", + " constraint_factor = (t - t_initial) * (x - x_min) * (x_max - x)\n", + " return starting_profile + constraint_factor * correction\n", + "\n", + "\n", + "model = ParametricHeatPINN(problem).to(device)\n", + "print(model)" + ] + }, + { + "cell_type": "markdown", + "id": "2496da43", + "metadata": {}, + "source": [ + "The hard constraints should hold even though the network has random weights.\n", + "Predict the result before running this numerical check. Values near\n", + "$10^{-7}$ are zero to single-precision round-off." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "42520509", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Maximum initial-condition error: 0.000e+00\n", + "Maximum boundary-condition error: 2.357e-07\n" + ] + } + ], + "source": [ + "def random_parameters(n, problem, device):\n", + " coefficient_width = problem.coefficient_max - problem.coefficient_min\n", + " a1 = problem.coefficient_min + coefficient_width * torch.rand(\n", + " n, device=device\n", + " )\n", + " a2 = problem.coefficient_min + coefficient_width * torch.rand(\n", + " n, device=device\n", + " )\n", + " kappa = problem.kappa_min + (\n", + " problem.kappa_max - problem.kappa_min\n", + " ) * torch.rand(n, device=device)\n", + " return a1, a2, kappa\n", + "\n", + "\n", + "with torch.inference_mode():\n", + " n_check = 200\n", + " x = problem.x_min + (problem.x_max - problem.x_min) * torch.rand(\n", + " n_check, device=device\n", + " )\n", + " a1, a2, kappa = random_parameters(n_check, problem, device)\n", + " initial_inputs = torch.column_stack(\n", + " [x, torch.full_like(x, problem.t_min), a1, a2, kappa]\n", + " )\n", + " initial_error = (\n", + " model(initial_inputs) - exact_solution(initial_inputs, problem)\n", + " ).abs().max()\n", + "\n", + " boundary_x = torch.cat(\n", + " [\n", + " torch.full((n_check // 2,), problem.x_min, device=device),\n", + " torch.full((n_check // 2,), problem.x_max, device=device),\n", + " ]\n", + " )\n", + " t = problem.t_min + (problem.t_max - problem.t_min) * torch.rand(\n", + " n_check, device=device\n", + " )\n", + " a1, a2, kappa = random_parameters(n_check, problem, device)\n", + " boundary_inputs = torch.column_stack([boundary_x, t, a1, a2, kappa])\n", + " boundary_error = model(boundary_inputs).abs().max()\n", + "\n", + "print(f\"Maximum initial-condition error: {initial_error.item():.3e}\")\n", + "print(f\"Maximum boundary-condition error: {boundary_error.item():.3e}\")" + ] + }, + { + "cell_type": "markdown", + "id": "c66ca8e2", + "metadata": {}, + "source": [ + "## 4. Build the physics loss\n", + "\n", + "For each collocation point we compute\n", + "\n", + "$$\n", + "r_\\Phi=\n", + "\\frac{\\partial \\hat u_\\Phi}{\\partial t}\n", + "-\\kappa\\frac{\\partial^2 \\hat u_\\Phi}{\\partial x^2}.\n", + "$$\n", + "\n", + "The loss is the mean of $r_\\Phi^2$. There is no labelled target value and no\n", + "separate initial- or boundary-condition loss.\n", + "\n", + "`torch.autograd.grad` differentiates the network output with respect to its\n", + "inputs. The model contains no operations that mix examples within a batch, so\n", + "the gradient obtained from the summed outputs contains the derivative for each\n", + "corresponding row." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "10748283", + "metadata": {}, + "outputs": [], + "source": [ + "def sample_collocation_points(n, problem, device):\n", + " x = problem.x_min + (problem.x_max - problem.x_min) * torch.rand(\n", + " n, device=device\n", + " )\n", + " t = problem.t_min + (problem.t_max - problem.t_min) * torch.rand(\n", + " n, device=device\n", + " )\n", + " a1, a2, kappa = random_parameters(n, problem, device)\n", + " return torch.column_stack([x, t, a1, a2, kappa]).requires_grad_(True)\n", + "\n", + "\n", + "def physics_residual(model, inputs, *, create_parameter_graph=True):\n", + " u = model(inputs)\n", + " first_derivatives = torch.autograd.grad(\n", + " u,\n", + " inputs,\n", + " grad_outputs=torch.ones_like(u),\n", + " create_graph=True,\n", + " )[0]\n", + " du_dx = first_derivatives[:, 0]\n", + " du_dt = first_derivatives[:, 1]\n", + " d2u_dx2 = torch.autograd.grad(\n", + " du_dx,\n", + " inputs,\n", + " grad_outputs=torch.ones_like(du_dx),\n", + " create_graph=create_parameter_graph,\n", + " )[0][:, 0]\n", + " return du_dt - inputs[:, 4] * d2u_dx2" + ] + }, + { + "cell_type": "markdown", + "id": "26d4d3f0", + "metadata": {}, + "source": [ + "## 5. Train across time, space, and parameters\n", + "\n", + "Every epoch samples new values of $(x,t,a_1,a_2,\\kappa)$. Consequently, the\n", + "loss need not decrease monotonically: adjacent epochs use different\n", + "collocation points. The analytical solution is not called by the training\n", + "loop." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "74014f8e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "epoch 500: physics loss = 6.439e-02\n", + "epoch 1000: physics loss = 2.266e-02\n", + "epoch 1500: physics loss = 1.334e-02\n", + "epoch 2000: physics loss = 1.156e-02\n", + "epoch 2500: physics loss = 4.647e-03\n", + "epoch 3000: physics loss = 7.178e-03\n", + "epoch 3500: physics loss = 5.673e-03\n", + "epoch 4000: physics loss = 1.821e-03\n", + "epoch 4500: physics loss = 2.387e-03\n", + "epoch 5000: physics loss = 2.130e-03\n", + "Training time: 33.1 s\n" + ] + } + ], + "source": [ + "def train_pinn(model, problem, training, device):\n", + " optimizer = torch.optim.Adam(\n", + " model.parameters(),\n", + " lr=training.learning_rate,\n", + " )\n", + " loss_history = []\n", + "\n", + " if device.type == \"cuda\":\n", + " torch.cuda.synchronize()\n", + " start_time = time.perf_counter()\n", + "\n", + " model.train()\n", + " for epoch in range(training.epochs):\n", + " inputs = sample_collocation_points(\n", + " training.collocation_batch_size,\n", + " problem,\n", + " device,\n", + " )\n", + " optimizer.zero_grad(set_to_none=True)\n", + " residual = physics_residual(model, inputs)\n", + " loss = residual.square().mean()\n", + " loss.backward()\n", + " optimizer.step()\n", + " loss_history.append(loss.item())\n", + "\n", + " if (epoch + 1) % training.report_every == 0:\n", + " print(f\"epoch {epoch + 1:5d}: physics loss = {loss.item():.3e}\")\n", + "\n", + " if device.type == \"cuda\":\n", + " torch.cuda.synchronize()\n", + " elapsed_seconds = time.perf_counter() - start_time\n", + " return np.asarray(loss_history), elapsed_seconds\n", + "\n", + "\n", + "loss_history, elapsed_seconds = train_pinn(\n", + " model,\n", + " problem,\n", + " training,\n", + " device,\n", + ")\n", + "print(f\"Training time: {elapsed_seconds:.1f} s\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "5f7dd60a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(7, 4))\n", + "ax.semilogy(np.arange(1, len(loss_history) + 1), loss_history)\n", + "ax.set(xlabel=\"epoch\", ylabel=\"mean squared physics residual\")\n", + "ax.set_title(\"Training history\")\n", + "fig.tight_layout()" + ] + }, + { + "cell_type": "markdown", + "id": "1dc127fd", + "metadata": {}, + "source": [ + "## 6. Validate on unseen parameter combinations\n", + "\n", + "A small training residual is not sufficient evidence that the predicted\n", + "solution is accurate throughout the domain. Because this problem has an\n", + "analytical solution, we can test complete trajectories for parameter\n", + "combinations that were not supplied as labelled data.\n", + "\n", + "The three cases below are within the training ranges. They are *held out* in\n", + "the sense that the continuously sampled training process was never given their\n", + "analytical solution values—not in the sense that random collocation could\n", + "never draw nearby parameter values." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "e7f58e24", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " a1 a2 kappa relative L2 maximum error\n", + " 0.75 -0.50 0.080 2.111e-02 2.159e-02\n", + " -0.40 0.90 0.170 2.930e-02 1.724e-02\n", + " 0.20 -0.80 0.125 1.585e-02 1.112e-02\n" + ] + } + ], + "source": [ + "def make_evaluation_inputs(\n", + " a1,\n", + " a2,\n", + " kappa,\n", + " problem,\n", + " device,\n", + " *,\n", + " n_x=101,\n", + " n_t=51,\n", + "):\n", + " x = torch.linspace(problem.x_min, problem.x_max, n_x, device=device)\n", + " t = torch.linspace(problem.t_min, problem.t_max, n_t, device=device)\n", + " tt, xx = torch.meshgrid(t, x, indexing=\"ij\")\n", + " inputs = torch.column_stack(\n", + " [\n", + " xx.ravel(),\n", + " tt.ravel(),\n", + " torch.full_like(xx.ravel(), a1),\n", + " torch.full_like(xx.ravel(), a2),\n", + " torch.full_like(xx.ravel(), kappa),\n", + " ]\n", + " )\n", + " return inputs, x, t\n", + "\n", + "\n", + "def solution_error(model, a1, a2, kappa, problem, device, **grid_options):\n", + " inputs, _, _ = make_evaluation_inputs(\n", + " a1,\n", + " a2,\n", + " kappa,\n", + " problem,\n", + " device,\n", + " **grid_options,\n", + " )\n", + " model.eval()\n", + " with torch.inference_mode():\n", + " prediction = model(inputs)\n", + " reference = exact_solution(inputs, problem)\n", + " difference = prediction - reference\n", + " relative_l2 = (\n", + " torch.linalg.vector_norm(difference)\n", + " / torch.linalg.vector_norm(reference)\n", + " )\n", + " return relative_l2.item(), difference.abs().max().item()\n", + "\n", + "\n", + "held_out_cases = [\n", + " (0.75, -0.50, 0.080),\n", + " (-0.40, 0.90, 0.170),\n", + " (0.20, -0.80, 0.125),\n", + "]\n", + "\n", + "print(\" a1 a2 kappa relative L2 maximum error\")\n", + "for case in held_out_cases:\n", + " relative_l2, maximum_error = solution_error(\n", + " model,\n", + " *case,\n", + " problem,\n", + " device,\n", + " )\n", + " print(\n", + " f\"{case[0]:6.2f} {case[1]:6.2f} {case[2]:7.3f}\"\n", + " f\" {relative_l2:10.3e} {maximum_error:10.3e}\"\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "c89e3637", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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U1N15TfpBi4tzqVLl1aPmzVrhtWrV+Pdd99Vj+WuhWQYb9GixUP3IfNoZzeXtrwRpgqK5c015f4sDcuPZWgOeB6y/ArTOZjXfbDuLBj4vcXyy288B1l+llp35uq31axZU7Xy7tixA09KQkICTp06pRYhLdTyf2mZTjd58mTUrl074/FHH32kpv764IMPsHPnTrz66qtqu5EjRz6x4yQiIiIiIiJKl+v+YvPnz1fB608//YRq1arB1dU1y/PBwcFo3rx5bnevuqQPHjxY/b9s2bL4+eef1fLMM8/giy++yEhqVqZMmSzB//r16zF27FisXLlStXBv2bIFJUuWzPVxEBERERERET3xIHvNmjX466+/cPPmTfz+++/ZZhfPS5Bdv379jFbsh3n99dfVklmjRo3UQkRERERERFQggmzpgt23b1/Vqjxw4MBss4s7Ozub6hiJiIiIiIiICm+QvXfvXlSqVAm//fab6Y+IiIiIiIiIqIDKVeIzf39/NWUWEREREREREeUxyK5Vq5aak3r37t252ZyIiIiIiIioUMpVd/GLFy+ibdu2Kvt33bp1s80uXqJECTRt2tRUx0lERERERERUOINsacGWOajFyZMns32NZBdnkE1ERERERESWJFdBdseOHR8aXKdzcXHJ7TERERERERERWU6QLdNzlStXzvRHQ0RERERERGRpQXa6+Ph4LF68GMeOHVNBt4zRjoqKUvNoV6hQwXRHSURERERERFRYs4uLgwcPokyZMhg4cCC+/fZb/Pvvv2k71GrRvn17JCQkmPI4iYiIiIiIiApnkK3X69GrVy+VWfzMmTOYM2dOxnOSZbxNmzb4888/TXmcRERERERERIUzyJbs4qmpqZg/fz5Kly6tWq8zq1SpEufQJiIiIiIiIouTqyD7xo0bqFy5MmxsbNRjjUaT5Xl7e3vcuXPHNEdIREREREREVJiDbG9vbzWFl8FgyPb5/fv3o1ixYnk9NiIiIiIiIqLCH2TLWOzo6Gj83//9n+o2nrkle8uWLZg1axY6d+5syuMkIiIiIiIiKpxTeNna2mLixIl47rnnMHfuXPj6+iIiIgLNmzdXQbZM5VWnTh3THy0RERERERFRYZzCq2/fvmrarqCgIBw+fBgXLlzAlStXMGbMGEyfPt20R0lERERERERUWFuy07Vq1UotQsZn359lnIiIiIiIiMiS5CoqXr9+PT799NOsO8oUYGf3PBEREREREVFhl6sgOzw8HKdOnXrk86dPn87LcREREREREREVOE+kf3doaCgcHByexK6JiIiIiIiICv6Y7L1792LatGnq/5Lk7PLly3jppZceeJ1M7SUJ0UaPHm3aIyUiIiIiIiIqLEF2SEgIli5dqv6fnJyMpKSkjMfpZL5sLy8vvPDCC9kG4ERERERERESFWY6D7O7du6tFzJ8/XwXY8pOIiIiIiIiI8jCFV69evTICbiIiIiIiIiLKQ5BtZWWlFiIiIiIiIiJ6wtnFiYiIiIiIiCwRg2wiIiIiIiIiE2GQTURERERERGQpQbbBYEBUVBSMRmOOt5HX3r59+4keFxEREREREVGBCrK/+eYbeHp6wt/fH76+vvjll18e+XoJrPv27QsHBwcEBQXB0dERL7/8MhITE5/aMRMREREREZHlMtsge8GCBfi///s//Pnnn0hISMAPP/ygAubNmzc/dJt3330Xe/fuxdmzZ1XAvW/fPjWf91dfffVUj52IiIiIiIgsk9kG2ZMmTVJzcbdp0wYajQb9+vVDgwYNMGXKlIduc/r0aTRr1gyBgYHqcfny5VGnTh21noiIiIiIiMgig2wZhy2t0I0aNcqyvkmTJtizZ89Dt3vllVfw999/Y9WqVbh8+bJqDd+5cyeGDBnyFI6aiIiIiIiILJ0VzFBcXJwaR+3l5ZVlvbe3N27evPnQ7Xr37o3du3ejQ4cOcHZ2Rnx8PD799FO0atXqodskJSWpJV1MTExGoC9LXsk+JBGbKfZliVh+LENzwPOQ5VfYzsG87od1p/nj9xbLL7/xHGT5WXLdaZZBtnQPF3q9Pst6eazT6R7Zkr19+3ZcvHhRJT47ceIEWrdurbb77LPPst1mzJgx2T4nGc3v//25fTNiY2PVG6zVmmXHAbPG8mMZmgOehyy/wnYOyr7ygnWn+eP3Fssvv/EcZPlZct1plkG2tEK7uLggLCwsy3p5LJnGH1aIv/32G77//nsVYIsKFSrgxRdfVFnJHxZkjxo1CiNGjMjSkl20aFG4u7urY8grOS65aSD7Y5DN8ssPPAdZhvmN56D5laGVVd6qf9ad5o+fO5ZffuM5yPKz5LrTLINs0bhxY6xduzZLAPzvv/+qcdmZu5VL5nEfHx9VcPb29qqLeGbyGpnK62FsbW3Vcj/Zn6mCYnlzTbk/S8PyYxmaA56HLL/CdA7mdR+sOwsGfm+x/PIbz0GWn6XWnWYb9cld8nXr1mHcuHE4efIk3nvvPZw7dw7vvPNOxmvGjx+PMmXKZDx+7rnn1Nzay5YtU13G582bh+nTp2PAgAH59FcQERERERGRJTHbluyGDRti+fLlGD16tJq2q3Tp0qplu1y5chmvcXJygq+vb8bjb7/9VnX1lrFi0rU8ICAAY8eOVWO1iYiIiIiIiCw2yBbt27dXy8OMHDlSLZm7r0mLtyxERERERERET5vZdhcnIiIiIiIiKmgYZBMRERERERGZCINsIiIiIiIiIhNhkE1ERERERERkIgyyiYiIiIiIiEyEQTYRERERERGRiTDIJiIiIiIiImKQTURERERERGRe2JJNREREREREZCIMsomIiIiIiIhMhEE2ERERERERkYkwyCYiIiIiIiIyEQbZRERERERERCbCIJuIiIiIiIjIRBhkExEREREREZkIg2wiIiIiIiIiE2GQTURERERERGQiDLKJiIiIiIiITIRBNhEREREREZGJMMgmIiIiIiIiMhEG2UREREREREQmwiCbiIiIiIiIyEQYZBMRERERERGZCINsIiIiIiIiIhNhkE1ERERERERkIgyyiYiIiIiIiEyEQTYRERERERGRiTDIJiIiIiIiIjIRBtlERERERERElhRkGwyGXG1nNBpNfixEREREREREBTLInjFjBooVKwZra2uUKlUKixYt+s9tLl++jGeffRZOTk5wd3fH0KFDERMT81SOl4iIiIiIiCyb2QbZK1aswGuvvYbx48cjNjYWI0aMQJ8+fbB79+6HbnPr1i00bNhQ/f/cuXMIDw9HvXr1sHnz5qd45ERERERERGSpzDbI/v7779GlSxfVKu3g4IBhw4ahVq1amDhx4kO3GT16tPo5Z84cFClSRLWADx48GJ07d36KR05ERERERESWyiyDbBlLLS3WTZs2zbK+efPm2Llz5yNbv7t16wZbW9tcj+MmIiIiIiIiyi0rmCHpHp6QkABvb+8s6318fBAWFvbQ7S5dugRnZ2e0aNECW7duhYeHB3r16oWvv/5arc9OUlKSWtKlj9+WIN0UgbrsQ24aMOhn+eUXnoMsw/zGc9D8yjCv+2Hdaf74uWP55Teegyw/S647zTLIftgfIo81Gs1DXy+F+N1332Hh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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "a1, a2, kappa = held_out_cases[0]\n", + "times_to_plot = np.linspace(problem.t_min, problem.t_max, 4)\n", + "x = torch.linspace(problem.x_min, problem.x_max, 301, device=device)\n", + "\n", + "fig, axes = plt.subplots(2, 2, figsize=(10, 7), sharex=True, sharey=True)\n", + "model.eval()\n", + "for ax, current_time in zip(axes.flat, times_to_plot):\n", + " inputs = torch.column_stack(\n", + " [\n", + " x,\n", + " torch.full_like(x, current_time),\n", + " torch.full_like(x, a1),\n", + " torch.full_like(x, a2),\n", + " torch.full_like(x, kappa),\n", + " ]\n", + " )\n", + " with torch.inference_mode():\n", + " predicted = model(inputs).cpu()\n", + " exact = exact_solution(inputs, problem).cpu()\n", + " ax.plot(x.cpu(), exact, label=\"analytical\", linewidth=2)\n", + " ax.plot(x.cpu(), predicted, \"--\", label=\"PINN\")\n", + " ax.set_title(f\"t = {current_time:.2f}\")\n", + " ax.grid(alpha=0.25)\n", + "\n", + "axes[0, 0].legend()\n", + "fig.supxlabel(r\"position $x$\")\n", + "fig.supylabel(r\"temperature $u(x,t)$\")\n", + "fig.suptitle(\n", + " rf\"Unseen in-range case: $a_1={a1}$, $a_2={a2}$, $\\kappa={kappa}$\"\n", + ")\n", + "fig.tight_layout()" + ] + }, + { + "cell_type": "markdown", + "id": "89699a2d", + "metadata": {}, + "source": [ + "### Check the residual independently\n", + "\n", + "The next estimate uses fresh collocation points. Compare its scale with the\n", + "trajectory errors above. They measure different things: a local differential\n", + "equation residual and accumulated solution error, respectively." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "5f37e573", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fresh-collocation residual RMSE: 4.469e-02\n", + "Fresh-collocation maximum absolute residual: 1.011e+00\n" + ] + } + ], + "source": [ + "model.eval()\n", + "validation_inputs = sample_collocation_points(5_000, problem, device)\n", + "validation_residual = physics_residual(\n", + " model,\n", + " validation_inputs,\n", + " create_parameter_graph=False,\n", + ").detach()\n", + "\n", + "print(\n", + " \"Fresh-collocation residual RMSE: \"\n", + " f\"{validation_residual.square().mean().sqrt().item():.3e}\"\n", + ")\n", + "print(\n", + " \"Fresh-collocation maximum absolute residual: \"\n", + " f\"{validation_residual.abs().max().item():.3e}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "4eb100eb", + "metadata": {}, + "source": [ + "## 7. Exercise: interpolation is not extrapolation\n", + "\n", + "**Timebox: 10 minutes.** Before running the cell, rank the following cases by\n", + "expected error and justify the ranking.\n", + "\n", + "1. A smooth, first-mode-dominated profile inside all training ranges.\n", + "2. A second-mode-dominated profile inside all training ranges.\n", + "3. A diffusivity outside the training interval.\n", + "4. An initial-condition coefficient outside the training interval.\n", + "\n", + "Then compare the numerical result with your prediction. Do not infer a general\n", + "law from one training run: explain which result is consistent with your\n", + "reasoning and which result would require repeated runs or a broader test grid." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "da15efee", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "case relative L2 maximum error\n", + "first mode, in range 3.500e-02 3.261e-02\n", + "second mode, in range 1.471e-02 1.096e-02\n", + "diffusivity extrapolation 1.187e-01 8.093e-02\n", + "coefficient extrapolation 2.633e-01 3.361e-01\n" + ] + } + ], + "source": [ + "reasoning_cases = {\n", + " \"first mode, in range\": (0.90, 0.10, 0.100),\n", + " \"second mode, in range\": (0.10, 0.90, 0.100),\n", + " \"diffusivity extrapolation\": (0.90, 0.10, 0.250),\n", + " \"coefficient extrapolation\": (0.10, 2.00, 0.100),\n", + "}\n", + "\n", + "print(\"case relative L2 maximum error\")\n", + "for label, case in reasoning_cases.items():\n", + " relative_l2, maximum_error = solution_error(model, *case, problem, device)\n", + " print(f\"{label:28s} {relative_l2:10.3e} {maximum_error:10.3e}\")" + ] + }, + { + "cell_type": "markdown", + "id": "decfc2f4", + "metadata": {}, + "source": [ + "### Map error across the parameter family\n", + "\n", + "A few attractive trajectories can hide uneven performance. The heat map below\n", + "holds $\\kappa$ fixed and evaluates a grid of unseen coefficient combinations.\n", + "Look for structure: does error depend only on the size of the coefficients, or\n", + "also on which spatial mode dominates? The center is marked `N/A` because the\n", + "relative error is undefined when both the prediction and exact solution are\n", + "identically zero." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "18cdfe68", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAqkAAAHqCAYAAAAnAteYAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQAAdO1JREFUeJzt3QecE1XXx/Gz9N57ly5SFGwIUkQBRQWxY3lQVOwVFfRRwYa9F1BE7GIXFFSsWAAFBRsCivQqvbed9/O/Psmb7GaXJMxmk+zv62dkM5mZnUnbk3PvPTfD8zzPAAAAgCRSKL9PAAAAAMiKIBUAAABJhyAVAAAASYcgFQAAAEmHIBUAAABJhyAVAAAASYcgFQAAAEmHIBUAAABJp0h+nwCAgmXWrFm2ZMkSa926tdWtWze/TwcAkKTIpAJIiGXLltmRRx5p//nPf+ypp56yFi1a2P3338+jDwCIKINpUQEkwrx582zVqlXWoUMHd/vrr7+2Ll262D///GMVK1bkSQAAhCGTCuSDqVOn2gMPPGB79uzx7Zhbt251x5w5c6YloyZNmgQDVGnVqpVlZmbaunXr8vW8AADJiT6pwF4sWrTI3njjjeDtQoUKWaVKlezQQw91Tdbx+PTTT+2WW26xyy+/3AoXLhzTvh988IEtX77cLrzwwrD1GzdutOuvv94ef/xxO/DAAy3Rnn/+efM8z84///yoth81apQdcMABtt9++1lBN3LkSNc/97jjjrNUMGfOHJs8ebL7kqX3Qdu2bWPOqn/88ce2fft2u+yyy6xkyZIRt5sxY4b9+uuv7vc0b97c2rdvbxkZGWHb/PLLL+5YkZxzzjlWvXr1mM4NQPIgkwrsxdy5c13wpz+EK1ascEHrK6+84gKs008/3Xbt2pXQx/Dll1+2u+66K9v60qVL23XXXWcHHXSQJZoeg0suucTeeeedqLbXY3nPPfe4a8kadBREd9xxh7366quWCm688UZr06aNff755/b9999b586d7dxzz42qVWDcuHHu9dmrVy974okn3Ptqy5Yt2bb75JNPXFDarVs394VOXUN69+7tAmIFyKGmTZvmjvP777+792fokuj3JgB/kUkFonTyySfbxRdfHLw9fPhwu+mmm9wf6UsvvTTfH8eyZcu65v788Ntvv9mOHTuiCpAV3Jx11lkuoM2PjC/ip0D6vvvuszfffNNOOeUUt07vCWU4W7ZsaTfccMNeX6OjR492rxPtlzXgDPjuu+9cd5ApU6YE+yur73K7du3spJNOcq+3rF9u9LsV2AJIHwSpQJzUlKgg9bPPPssWpP7000/2ww8/uEyOSi1pVPvejB071hYvXux+VheAqlWrugA4tEyTggT9YVfTfmhAes0117ggUaPmjz76aBf8qd/rN99847oFlC9fPttIex2rZ8+eLrgIzRprH2W31IdUxypSZO8fE9OnT3f/7q3ZVxmx0047zV577TXr1KmTxUJdHL744gsXrNSuXdt69OhhZcqUCd6/cuVKe+mll+zEE090XQgmTpxo8+fPt1NPPdU9Xh9++KGdd955Vrx4cffz0qVLXfY30NSswEdBkR5HBTsa1BXaFUPHUmB95plnuu4eEyZMcFl1HbNChQoRz/mhhx5y/W6lWLFiVqdOHZcdDDwf6h7x4IMP2ubNm2327NnB57RGjRp29tln5/hYqAlcXUVuvfVWO+qoo9w6ZQ61rlq1au6YOTWh74tHHnnEmjZtGgxQRdnNY445xh599FEbNGiQ6w6Tk65du0b1e9RCoecgNBCtUqWKnXHGGS5I1nuAgBRIfwSpQJwCAYwCjQANAlIQo0BPTZpqgldT7v7772/vvfdetmAx1Nq1a12gIQqU3n//fevfv78LdK688kq3fs2aNbZt2zbXtBrYNnAOWfuk6vx0W+egYCzUiBEj7O6773Z/9GXnzp120UUXucD12GOPdf34Hn74YStVqpQLxurVq5frY6G+g5JbJvWPP/5wj4ky0rqO119/3a1XkKXAKjd33nmnexyPOOIIa9asmb3wwgvui4EeU2XxRAG+rleBq65DgawC0YMPPtgWLFjg7qtfv77de++9LjDXOauZWkH4gAEDXOCs81PAefvtt7vHQM3TDRo0cMdXc7KOoQBSTdUK1rTuhBNOyDFIVeAcaAbftGmT63uqPrs6roJ0PW96HrWNntfAc1q0aNFcHw9lGr/66iv3RUbU7N63b193rbq+SAGqHm/Vp90bvUaz9ncWfXHRlxG9JrPq2LGj68KhLzl+BI96v0Syfv36bO+50L7aOgedvwbo6UsWgBSnElQAcjZp0iT9RfSefvrpsPWPP/64W//QQw8F1/Xq1curVKmS99dffwXXrVixwqtZs6bXv3//4Lo77rjD7btt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uh5aikqD79XanudB6lFHHWU33nijzZs3LyxI/fDDD+3VV1+1H374wQqyUsWrWkbGvhewTRZFC5W0dFOqcGVLN8ULp/6HXFZ/zK5i6abKHv/qByaLtTvT75rW7Uy/99OudJl7M8SOfLwmz/t38etYqe63336z0aNHu5/PPffcbPcfdthhriU+z4NUjeZXX1TNx1qtWjU3o8DEiRPdaH+tb9OmTcwnAQAAgNR02GGHuWlQcxJvgf+4RvcPGjTIunbtam+++aYtXbrUKleubE8++aR16dIlrpMAAABIFSrk718x/9TP3GdkZLg6+n6LK0iVdu3auQUAAACYNWuWa11XKdLrrrvOlaaaMWOGHXnkkXE9OHHlX3ft2mWPP/64de/e3Q2U6tatmw0fPjzXVC8AAEA68P43cMqPRcdKB6NHj7b27dvb66+/7lrapVSpUnb99dfbjz/+mJggVSO4ND3qbbfdZg0bNrSzzjrLBaqPPfaYOznNOgUAAJCuAgOn/FpS3c6dO13m9LPPPrORI0eG3TdgwAB74oknEhOkTpo0yY3snz17to0YMcJuvvlml1WdM2eOy7COHTs2rhMBAABA6pk3b57Vrl3bJSuzlidVQvPPP/9MTJ/UP/74w3r27GnVq1cPW68aWH379nXBKgAAQLpi4FS44sWL51jI/9dff7WqVataQjKpKjv1888/u6L+WanPQbwnAgAAkArUj9TPJdU1btzYypcvb4888kjYejX/33777W6m0oRkUnv16mXXXnutnXDCCTZw4ECX3l25cqWNGTPGvvnmG3v22WfjOhEAAACkpldffdWOO+4427x5s+3Zs8e1uK9atcr69+/vxi8lJEgtW7asffnll3b11Ve75n2diIq0duzY0a2vVatWXCcCAACQCjK9fxe/jpUO2rRpY3PnzrX333/fdf1U3VTVz1c/1YTWSW3atKlNmDDBDZRatmyZ1ahRw/VHAAAASHf0SY2sdOnS1q9fP/NLoXhHcS1atMgVa61fv74LUFesWOHmbgUAAAASHqSuXbvW+vTpY8WKFcsWPZ955pkueAUAAEhXDJxK0iBV0121bdvWNfFn7auqIv/vvvuun+cHAACAAijmPqkataW+qDnNOKBMKwAAQLpi4FSSZlKPOOIIGz9+vKuVGurvv/+2V155xTp06ODn+QEAACQVmvsjmzVrlt1zzz324IMPuttbt261r7/+2hIWpLZq1crOPfdcO/jgg11xVpWiOu200+yAAw6wTp06Wffu3S2v/fTTT/bRRx/Z4sWLfd0nnuMCSF4//PCDXXbZZW7Gk4AZM2bYk08+GbadClBr8GeAyuldccUVruUIALB3o0ePduWmXn/9dXvzzTfdulKlStn111/vJntK2Oj+p59+2hXvl2nTptm2bdvs0UcfDZ5UXtm0aZN17tzZ9X296667rFmzZjZ06NB93iee4wJIfgo8Fag+9NBDwXUqLv3LL78Eb+ub/qeffhrWz/7555+3BQsWuC+tAJBTc79fS6rbuXOnXXfddW6GqZEjR4bdN2DAAHviiScSVydVVAfLz1pY0fjvf/9rS5cudUViK1asaJ9//rl169bNFYvVEu8+8RwXQGo47LDDbMmSJfbtt99G7I6kmfJCi02rJUX1n++880577LHH7JRTTknwGQNIdtRJzV6aVDOQ6rP0+++/D7uvYcOG9tJLL1nCMqn5wfM8e/nll11ErkBSjjrqKGvXrl2OFx/NPvEcF0DqyMjIsCuvvNK19uj9ntUXX3zh3vMBqlCiaZ8PPfRQW7Nmjc2fPz/BZwwAqUX18tevXx/xPnW3qlq1anoHqcqEqHKApt0KdeCBB2YbxBXLPvEcV3bs2GEbN24MWwAkp65du7oP0Y8//jhs/e7du11fdPWxl8zMTDcwtHfv3i64PfHEEymrByAbz+cl1TVu3NjKly/v+veHUvP/7bff7sYwJbS5P9E2bNjg/g1kOwMqV66cY/QezT7xHFeGDx9uw4YNi+taACSeBnmqr/lFF10UNohKX1A1e55899137kvrfffd527rM0Bdga666iorUiRlPi4BJGB0v5r8/TpWOnj11VftuOOOcwNO9+zZY9WrV3djAPr3729nnXVWXMdMmU/dwAxXGuQQSg+GMiTx7hPPcWXIkCF27bXXBm8rk1q3bt0YrwpAoqgLj96j7733XjAoVf9zZVkDdN+pp54a1kdVHf4nT54c1iUAABBOX/jnzp1r77//vhvjU6JECTeuJ/TzNGFBqkbNqqSARsRqBio1f6uprGTJkpYX6tWrZ4ULF85WHkq399tvv7j3iee4ogA2tyAWQPJRRlRBqOo9iwZTqb9qoFVFweiECROsSpUqwX00iEr9VAlSAQRk/m/xg1/HyU+LFi1yLVO9evXydVB9XH1SR4wY4QI49TFQelc0uEDRsgLVvKCIXBmPt99+O7hu3bp1rr/DscceG1w3c+ZMlx2Jdp9ojwsg9Wjw08CBA4O3VV7uueeec7VTZ8+ebXXq1LHSpUu7+9Q8pfqpoQGqqF/qGWeckfBzB4BUoS/5Ck6VuNRnrgr4RxqomueZ1D///NMGDx5skyZNsqlTpwYLYO+///4ucB03bpz16dPH8oL6gR555JF24YUXuoBYtbgaNWpk559/fljTnM4rULw7mn2i2QZA6lGfKC2hDjnkEPevPrtuvPHG4PpKlSq5JSsFscykByCU52W4xQ9+HSc/aaKnlStXuoSfZh9VM7+6V6kv6tlnn+1ixIRkUtU8ppGvHTt2dKNfQ7Vu3dqmT59ueUUjcHV8dSnQKF2ViVGNQ2VDAw466CBX4zSWfaLZBkB60Tf+3Lr0AMDemvv9WtJBuXLl7LzzznOTo6hykrpSaUKUFi1axN0aFXMmVbNLBUa5Zg1SlZmoX7++5SVNv6oC2zlRM16s+0S7DQAAAHJXs2ZN16quQekKWDWDX0IyqWoWVx1BBaShQapmGFDxewYXAACAdMa0qJGtXr3a9e3X4FR1m3z99ddd+b+xY8daQjKpyjiq5pX6HyhSFjWvf/nll64P5+GHHx7XiQAAAKQC1Tb1q75pOtRJXbp0qatB/cknn7hxAGref+qpp9zESPsirhJUKnStEfGKjHViKnyvjrKMgAUAAChY1qxZ44JT9UFVfFiokD8TmsZdJ1XlmSjRBAAACmpzv1/HSnWtW7e20aNH+37cqIJUdXj9448/ojqgRsuqFiEAAEA6ornfXG3UKVOmWIUKFVyJKf2cE20TT3fQqIJUTRWo2qgBKnq9e/du97NSuoEC/pq56frrr3d1RwEAAJCe/vjjDzv++ONd8Pnggw+6n3OibVTaM0+CVI3M0iLbt293v0wnc8kll1itWrXcaK4XX3zRzUR1ww03xHwSAAAAqYLmfrPDDjssmLCU0J/9EnPPVhVp1Xz3d955p9WuXduVoapWrZoNGjTIdZZ95513fD9JAAAAJCdNSX/qqafGfJ/vA6fUP1V9CyLR+ngLtgIAAKQCMqnh1Mq+ePFii2Tz5s2utn5CgtS2bdu6Jv1+/fpZz549g+vVYVYju0aNGhXXiQAAAKQCBk79a+PGjW4yp9mzZ7uf1doeateuXfbyyy/HPQV1zEGqZhG47rrrXJ9UNfcH+qTOnz/f9VE96aST4joRAAAApI7ff//djjnmmODt0J+lRIkS1rJlS3vhhRfiOn5c1VbvuOMON6pLI/m7dOliV1xxhf38889uKiwAAIB05v2vTqofi44Vi3nz5tlpp51mzZs3t06dOtmbb765z/t4nmdvvPGG9erVy1q0aOGCTU11vzcaSK99p0+fbj169HA/hy7btm2zH374wR0zocX8GzdubJdffnm8uwMAAKQkFd7M9PFY0Vq7dq0LMjVQXTN9Tps2zXW/VAnQvn37xr3PmDFjXImoq666yurWrWvfffedDRw40NavX+8SkXvTrl07N9uU3+IKUjdt2mT33HOPjR8/3pYsWWI1a9a0o48+2m655RarUqWK7ycJAABQ0I0cOdJ27tzpms+LFi3qgsMZM2bY7bffnmOQGs0+5557rp133nnBfVScX0HnxIkTowpSs1I9fWVSA1QJSkFxnjf3qw5W586d7dVXX3UXd//997uIfNKkSa5mlkZxAQAApCvPy/B1idaXX35pRx11lAs2AzSIfdasWS7rGe8+WQNIVWpSxlXxXrQ0uv/000+36tWrW5EiRdzvCywdOnSweMQcpCqq1gguXdzQoUNtwIABdvPNN9tPP/1klSpVstdeey2uEwEAAEil5n6/FlFsFbrs2LEj2+9V63WNGjXC1gVuL126NOK5xrLPAQcc4AbEq0unAs4bb7wx6sckUAtV+ygTq9lKL774YitZsqT997//tYQ09//9998uIi9XrlzY+uLFi9uxxx7r7i/IyhapYYUy/v/bSqorklHc0k05r6qlm93qfZ9mGo68x9LNw782tXQze/0eSzfb9/jV2zB5FMmIPluXKnZlptdrT31BQ912220uGRhK09ArSxkqkCFVE3skseyjROSWLVvs66+/dpWcVDrq0ksv3eu5K9j9888/bfLkyfbjjz/a66+/br1793ZL+fLl7bPPPst12lTfglSVnVItVPVvKFasWNiDoJPT6DEAAIB0lRfF/NVcHpoALF48e5JI437WrFkTtu6ff/5x/1atGjkBE8s+mlFUlAlV4Kl+q9EGqQ0bNnRxYdmyZcO6HqhSgKpCJaS5X+UJVFLgyCOPtGeeecY+/PBDV8Rf2VWVpVJ6GAAAANFTgBq6FI8QpB566KFu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s956661WunRp1/xeokQJu+SSS1x2UTWy8oL6kKrklILM0OBTt0MHailgVrN+6Dbnn3++ffrpp25b1XXdm7Vr17qMqwLVnCjrqmA2dAEAAIA/4qqTet5557n+p999952bZUCZTJWEqly5suWlG2+80QYOHOjqorZv397uu+8+149UAXLAxRdfbFOnTnWDvNS39MILL7SJEyfapEmT3IwHgeyvaqKqT636lqr8lMpUqTaqgtPrrrvOBcVnn312nl4PAABIPRot49d0pgycyoNi/soc9uzZ0xLp3HPPdUGpmto1WKpVq1Yu+AzNeCr4VJYzkBFV/1LRYKlQKlulLgDadtCgQXbnnXfaTz/95ILTI4880l588cU8D7oBAEDqoQRVEgep8+fPd03+GtQU2rQuGuWv4C+vaLCVlpw8/fTTwZ8VZAYyp7lRZja3WasAAACQ5EGqRverfFPjxo2tbdu2YVOJikbkAwAApCs/65vS3O9jkPrJJ59YmzZt3Eh5AAAAICmCVE0bquL3AAAABRF9UpO0BJUGFU2ePNm2bNmSN2cEAACQxDyf/4NPmVQVrS9SpIirl3rcccdZ2bJlw+7v1KmTWw8AAAAkLEhdsWKFVatWzS1z5szJdn9ghigAAIB0RHN/kgapp556qlsAAAAKIkb3J3kx/z179ri57ZcsWWI1a9Z0JamylqMCAAAAEjJwSr7++ms321OzZs2sW7du1qJFC2vatKl9+OGHcZ0EAABAqjX3+7XApyB11apV1qtXL+vYsaP98ssvtn79evvjjz/stNNOs759+9rcuXNjPSQAAEDK8Dx/F/jU3D9x4kQ75JBD7JlnngmuK1++vN17772u6f+9996zG264wQqq4hnlrHBG+nR7KOmVtnRTyStv6aZQhqWd2z9saunmx7XpV7pvRcYqSzeF4mtkTGolvFKWbnZ74dOyI/3EHKRu2rTJ6tevH/G+evXq2caNG/04LwAAgKSU+b/Fr2Mhspi/LrZt29bef/9918QfatGiRfbKK69Yu3btYj0kAAAAsG+Z1COOOMJOOOEEN3Cqa9euVrt2bVu5cqV9/vnnbhBV7969Yz0kAABAyqBOamLE1fFmzJgxLpvaqFEj++eff6xOnTr20ksvudH9hQqlX18eAACAID8HTTFwyv86qZr6lOlPAQAAkBfiSnvecccd9v3334etmzdv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1C9YI9YHDRoUzGyLuik8+uijYdnUve0T7Tb5QZ816tOtgSB6nm688UbXfSbgpptucpm2xx9/PMfPMBk+fLgdeeSRwUE3eo9qMKP6WivrrwGC+T0Lk1qoRowYEezKo9er3ouh56V+tqosofMNfIapT7SycA0aNHD3Ba4zluPmB3U5UF9udc3RjFPKjIZmADWQ7aKLLrJnnnnGWrRo4dappUrdcNS//5RTTsl2TGUS9XhMnDjRZVWVjb/iiiv22kUkr6llR+eR1XHHHedew6LPmZdfftllikNb4jQQV5/B+pzRQMCsFUei2QbJiyAVAAAASYc+qQAAAEg6BKkAAABIOgSpAAAASDoEqQAAAEg6BKkAAABIOgSpAAAASDoEqQAAAEg6BKlAilJxa00OcMghh7gpW1U4X0XY042mgzzppJMs2alovor8q1h8YNpbTVWqwuodOnSws846y00KoKL7odPN5kYTezz00EN5fOYAkJzyd9obAHGZNWuWDRgwwF555RU365Nmd9KMZWXLlt2nR7Rr1652yy235Ou85VlpxrPQ+eeTlWZt+uyzz+yxxx6zcuXKuXUKWpctW+ZmpdPMXlu3brUZM2bYrl27ojrmvHnz3ExeftIMRfpSEzpTHAAkI4JUIAVpGsE6derYaaedFlz31FNPWenSpff5uJpiE7H78ccfXWY7dNpNrVMmtX379u72tm3b7IcffrAKFSpEdUxNS1u8eHFfnw4FzX/88YevxwSAvEBzP5Bi7rzzTrvtttts+fLlruk40LSsOenffffd4HZa//bbbweboAPNxqNHj7YTTjjBunXr5ubF3rhxo1uvJvXNmze7+d9DjxvJ008/bQMHDrQXXnjBTj31VOvUqZPLJO7evdvGjBnjgjXNM67fFWrHjh1uPnJlart06WK33367yy6G+uKLL+zEE090+998883Z7hdlAs855xzr2LGjm49ec7Tvzbfffhucu11zsy9ZsiR4n6576NCh1rlzZ/e43HfffbZz585sc4Are63fqS8H48ePD96n69fx9XjosdNzpH///PNPdyz9rPs0h7x+t+ZND1ixYoWbT1y/u2/fvmFzkz/55JP25ptvhp3HG2+8Yb1793bb61h///138D7tq+dt6tSpbv56PcZXX321rV+/PrivMqnKxOuctGge95zoOrWNupR0797dXYueYwBICA9ASlmwYIE3ZMgQr06dOt4PP/zgzZw5063v1q2bd+ONNwa3q1y5sle6dGlv6NCh3jfffOMtWrTIGzVqlFetWjXv1Vdf9b788kvvvvvu884++2y3/S+//OKVKVPGu/fee8OOG8nNN9/sFS1a1DvuuOO8Tz75xBszZoxXqlQp76CDDvJ69+7tTZo0yf2uYsWKeRMnTgzud/rpp3sNGzb03nrrLe+9997z9t9/f69nz57B+/V7tY+u77PPPvOuuOIKr3jx4l6jRo2C23z00UdepUqVvAcffND76quvvCeffNIrV66c9+GHH+Z4vm+88YY77uDBg91xR44cGfZ79di1atXKe//999229evX984666zg/d9//71XoUIF74477nCP2+jRo72qVau6f+XHH3/02rZt651//vnuGubPn+/+1XOka9HPy5cv93766Se13XurV692+y1btsyrXbu216NHD2/cuHHeu+++637+/fff3f29evXyrrrqquB5DBs2zD1+L774ort2Pd/ly5f3Fi9e7O5/7bXXvMKFC7vn4Z133nGPVZs2bbyTTjrJ3b9q1SrvwgsvdOt0TlrWrFmT4+Om69I2uv7XX3/dXc8999yT4/YA4CeCVCAFPf3002GBW05B6gUXXBC2zYABA1wgFWr79u3BnxXwvPnmm3v9/QpSFShu2bIluO7MM8/0atSoEXa8E044wbvsssvcz4EAbfr06cH7Z8+e7WVkZLjATxTgnnrqqWG/q2vXrmHX2rx5c++xxx4L2+bOO+/0jjjiiIjnmpmZ6dWqVcsFqJGuWwG1Aru//voreN+3337rzlWBu3Tp0sW76aabwvZXEK6AMaBz587ucQml89ZzFZA1SL388svd9ezevTvsfHfs2JEtSFWQqy8GChxDKdi+4YYbgkGqjj9v3rzg/ePHj3cB+p49e9zt2267zevQoYMXj+uvv97r06dPXPsCQKzokwqksUBfyAA1BV9wwQVWo0YNO+644+ywww6Lu8/j/vvvb6VKlQrerlWrlh1wwAFhx9O6lStXup81YKhy5crWrl274P3Nmze3Bg0auPvUfD19+nQ3cCuUmv2fe+654Gh59accOXKkGzT2vy/arh/tunXrIp6nmtzVD7NPnz5h6wPnqd/duHFjNwAt4IgjjnCD0NSnVNf5zTff2NKlS93AqMDvVDcJNbWrW0CxYsXiegwnT55sxx9/vBUuXDi4LiMjI+Lx1J1AA67Ux1UC57Fw4cKw7TVAS9cTULt2bXeOenz0+EdL++gx/uijj1zXCHXVWLRoUbDSgs5HXTxElSWOPfbYuB4DAMgJQSqQxkKDSDnjjDNc0PL666+7YFX9Ie+55x7XvzSSNWvWWI8ePYK3Tz75ZBsyZIj7uUiR7B8fkdYFRqerRFOkgV1lypRx9wX6hmY959B9dL9ce+211rp167DtQgO9UBqsFPg9keztvBScqR/mhRde6KofRHPN0dK55XReWakfq36XqgcUKhQ+nECBaU7no6BXYqkSoOvVte7Zs8cuvfRS22+//axkyZKur3CrVq3cNo0aNXJ9Yp999lkXKAOA3whSgQJGA4cCI9A1sOmiiy5ywasCHQU/ocGM1o0YMSJ4u1q1anH/XmX3lNFUjdBAUKUgTdlIBTyibGbWkeezZ88O/qwAW8GSspga0BMNBVgK3DRYSJneSOf1119/uWA0kF1VcK4MsM5LQbMywloX7e+MVtOmTd15RaNJkyYueNRztC/nkfU5jkSD16ZNm+auOfBcKcutwXoHHnigu61svLLAn376adznAgC5YXQ/UICo2H9oEKigTEFL0aJFg4GHRqAHKLgLjALXUq9evbh/t5rtFWSqokAgSNKIegWBGq0u559/vqvfqaBRVB/15ZdfDjtfZX3vvvtu1xQf8Ouvv7ouAJGo2V6VAIYNGxYcCb99+3Z7/PHH3c9qvtZ13nXXXe52Zmamq3Cg4DZQL/bKK690j11oFQGd48MPP2z7QllKTVbwzjvvBNepQkPg+kMdfvjhbpT95Zdf7jLgARqdn9sI/az0HKvrQm6Bqh4DLQpSRefzn//8x2Vls2awASCvEKQCBYiycWqyr1u3rpsA4KqrrnL9PQNN7ArG/vvf/1qbNm1yLUEVDwWYY8eOdQGVAiVlJ9XnUV0PApMQKABVYNiiRQuXZVTZI2XrQqmElTK/msVJmc6aNWu60lLq35oTBaQK8LSNrls1ZgOUKdQ56HFQEK1zUybxtddeC/b1vP76610Xg169eln9+vXd46c+mIEMcLzUL1jBr4JznZOuRY9J9erVs22rAHHcuHFWqVIl149XfWVVb1X1cXVN0VJQri8muo6cSlCpDJe+VKhpX79HZcZUzkqBe2CiAgDIaxkaPZXnvwWA77MwqTm6ZcuWwXWaclN9KxVoiZqRlfmsWLFitv01EEZN7QpUsg7SUU1NDZDRR4OC1UjUbK/+mqHBUeCYCoQDdBw1UYcOStJxda76V4Fo1v6VgWMp26n9NChKmcPQaw300VRmVF0Qou2GoGOpyVpN/FkHjKn/pc5LfVt1DYG+nKHUJUADsRQcBh7ngMCMXwq+QzO8CjirVq3qbuvxUb1VNZmH9h3VICXNLqVtq1SpElyv36XzVFAc6p9//nHXoaAxtE+rBkfpMQ993iL9Tj0nCxYscF0vdAwFvpEog6rHQc9DpOdcVIdVwb/6pwKAnwhSAQAx0xeEK664wn7//XcXKOsLkTK9kb50AEA8GDgFAIiZylllzZ5Gyj4DQLzIpAIAACDp0C4DAACApEOQCgAAgKRDkAoAAICkQ5AKAACApEOQCgAAgKRDkAoAAICkQ5AKAACApEOQCgAAgKRDkAoAAICkQ5AKAAAASzb/B5duqjb4WbZvAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "grid_size = 9\n", + "a1_values = np.linspace(\n", + " problem.coefficient_min,\n", + " problem.coefficient_max,\n", + " grid_size,\n", + ")\n", + "a2_values = np.linspace(\n", + " problem.coefficient_min,\n", + " problem.coefficient_max,\n", + " grid_size,\n", + ")\n", + "relative_errors = np.empty((len(a2_values), len(a1_values)))\n", + "\n", + "for row, a2 in enumerate(a2_values):\n", + " for column, a1 in enumerate(a1_values):\n", + " if a1 == 0.0 and a2 == 0.0:\n", + " relative_errors[row, column] = np.nan\n", + " continue\n", + " relative_errors[row, column], _ = solution_error(\n", + " model,\n", + " float(a1),\n", + " float(a2),\n", + " 0.125,\n", + " problem,\n", + " device,\n", + " n_x=51,\n", + " n_t=31,\n", + " )\n", + "\n", + "fig, ax = plt.subplots(figsize=(7, 5))\n", + "masked_errors = np.ma.masked_invalid(relative_errors)\n", + "colormap = plt.colormaps[\"magma\"].copy()\n", + "colormap.set_bad(color=\"lightgray\")\n", + "image = ax.imshow(\n", + " masked_errors,\n", + " origin=\"lower\",\n", + " extent=[\n", + " problem.coefficient_min,\n", + " problem.coefficient_max,\n", + " problem.coefficient_min,\n", + " problem.coefficient_max,\n", + " ],\n", + " aspect=\"auto\",\n", + " cmap=colormap,\n", + ")\n", + "ax.set(\n", + " xlabel=r\"first-mode coefficient $a_1$\",\n", + " ylabel=r\"second-mode coefficient $a_2$\",\n", + " title=r\"Relative $L^2$ error at $\\kappa=0.125$\",\n", + ")\n", + "ax.text(\n", + " 0.0,\n", + " 0.0,\n", + " \"N/A\",\n", + " ha=\"center\",\n", + " va=\"center\",\n", + " fontsize=8,\n", + ")\n", + "fig.colorbar(image, ax=ax, label=\"relative error\")\n", + "fig.tight_layout()" + ] + }, + { + "cell_type": "markdown", + "id": "69ebfa8e", + "metadata": {}, + "source": [ + "## 8. Takeaways and limitations\n", + "\n", + "- The network represents $\\hat u(x,t;a_1,a_2,\\kappa)$ rather than one fixed\n", + " trajectory. Training is amortized over a family of initial conditions and\n", + " diffusivities.\n", + "- The trial-solution construction satisfies the initial and boundary\n", + " conditions to floating-point precision without balancing several loss terms.\n", + "- The physics residual supplies the training signal, while the analytical\n", + " solution provides independent validation.\n", + "- Good interpolation does not establish reliable extrapolation. A residual,\n", + " several trajectories, and a parameter-space error map provide complementary\n", + " evidence.\n", + "- This controlled problem is deliberately easier than many realistic PINN\n", + " applications. A conventional analytical or numerical solver is faster and\n", + " more reliable here. The example demonstrates the idea of a reusable\n", + " parameterized surrogate; it does not establish that PINNs are generally\n", + " superior differential-equation solvers.\n", + "- The initial condition is restricted to two coefficients. Learning a mapping\n", + " from an arbitrary function to its solution would require an operator-learning\n", + " formulation rather than simply adding more scalar inputs indefinitely.\n", + "\n", + "## References\n", + "\n", + "- M. Raissi, P. Perdikaris, and G. E. Karniadakis,\n", + " [Physics-informed neural networks](https://doi.org/10.1016/j.jcp.2018.10.045),\n", + " *Journal of Computational Physics* 378 (2019), 686–707.\n", + "- A. S. Krishnapriyan *et al.*,\n", + " [Characterizing possible failure modes in physics-informed neural networks](https://proceedings.neurips.cc/paper/2021/hash/df438e5206f31600e6ae4af72f2725f1-Abstract.html),\n", + " NeurIPS 2021." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.14.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/source-code/pinns/pendulum.ipynb b/source-code/pinns/pendulum.ipynb index e97e55f..575208f 100644 --- a/source-code/pinns/pendulum.ipynb +++ b/source-code/pinns/pendulum.ipynb @@ -13,7 +13,9 @@ "import scipy\n", "import torch\n", "from torch.func import functional_call, grad, vjp, vmap\n", - "import torchopt" + "\n", + "torch.manual_seed(42)\n", + "data_rng = np.random.default_rng(42)" ] }, { @@ -141,7 +143,7 @@ "outputs": [ { "data": { - "image/png": "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", + "image/png": "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vL293XTVVVeZUlJSer1cQkKC6T//+Y9JC5566inTlClT+nWZpUuXmkJDQ00FBQXi8yNHjpg8PDxM7777rkntWltbTUOGDDH97ne/6/FnTpw4IR6jGRkZJrVJS0szffjhh6ampiZxv91zzz1n/MzatWvF8W/YsEF8Xl1dbUpOTjbdddddPV7vQC5jK6+88oopPz9ffPTz8zvj+3v37hXH2/k+veiii0yTJk3q9XrDwsJMH3zwgUlp/L9v3bp1ptraWvE3//rrr8/4mYcfftg0d+7cfl3vo48+aoqKijKVlJSIz/fs2WNydnY2ffHFFyZ7KiwsNL355pumuro60+WXX25atGjRWS/T2Nho8vf3Nz3yyCM9/szBgwfF36uoqMikpOPHj5u+++47y+cdHR2mm266yRQdHd3l5yZMmGC64oorxPfZc889Z/L09DSdPHmyx+seyGX6AwFOP9x3331nvNi/9tprJnd3d/GAtdZl1OSjjz4STzJ+gektwHnwwQdNX331lWnnzp2m5uZmk5oDnNGjR5u+//570+rVqy3/HHszcuRI0+9///suX1u4cKFp3rx5JrX75ptvxP23f//+swY4/GL47bffmo4ePWpSo54CnFtvvfWMF/tnn33W5OvrK4L07gzkMrbWU4DTnddff93k6upqeWHoKcB57LHHRECxe/duERgp6WwBzuTJk8Xj75dffjGVlZWd9fpiY2NNS5Ys6fK1888/X7xgKqWvAQ4H7Q4ODr2+qZADnM8//1wEGOnp6Sa1WL58uTi28vJy8Tn/z+DP169fb/kZDvj4jeB///vfbq9jIJfpL3Wtr6scL9GdnnvBy728h8jbOda6jJpwXgDnnJytWRMvO7/99tt05ZVXitu7e/duUivOo3n55Zfpz3/+M8XExNCzzz7ba24Ebwl0dx/yfat2fJ9MnjxZLGv3hgfO/utf/6J///vf4ucXLFhAlZWVpAU9Pcd4GT03N9dql1Hb85K3C842KPizzz4TS/68lcPbOGp+zPLW+KuvvkoPPfSQeF7yY7EnvOXKz2MtPy/PO+88kVPWG962fP7558X/K97y5+2q0/MdlXr8hYeHi20lJv/NO98fvPUfHx/f4/0xkMv0FwKcfu61yndo531iOcHMWpdRCw5a3nvvPfrHP/7R68+98sorIlj7/vvvRb4AP2B5X5nzd9SGE/T4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", "text/plain": [ "
" ] @@ -161,7 +163,7 @@ "metadata": {}, "outputs": [], "source": [ - "sample_indices = np.random.choice(len(θ_values), 100)\n", + "sample_indices = data_rng.choice(len(θ_values), 100)\n", "t_data = [t_values[i] for i in sample_indices]\n", "θ_data = [θ_values[i] for i in sample_indices]" ] @@ -176,7 +178,7 @@ "outputs": [ { "data": { - "image/png": "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IqJOwgCHOme7KnECv9NERNRpuEVFREREusMAh4iIiHSHAQ4RERHpDgMcIiIi0h0GOERERKQ7DHCIiIhIdxjgEBERke4wwCEiIiLdYYBDREREumPITsZWq1Vel5SUePpUiIiIyEn2523783hrDBnglJaWyusePXp4+lSIiIioA8/joaGhrR5jsjoTBumMxWLBmTNnEBwcDJPJ5PLoUgROWVlZCAkJgd7o/eszwtfIr0/7+Bhqm94fP3d+jSJkEcFNfHw8zObWs2wMuYIjvindu3d36/8hHlC9/uAa4eszwtfIr0/7+Bhqm94fP3d9jW2t3NgxyZiIiIh0hwEOERER6Q4DHBfz8/PDn//8Z3mtR3r/+ozwNfLr0z4+htqm98dPLV+jIZOMiYiISN+4gkNERES6wwCHiIiIdIcBDhEREekOAxwiIiLSHQY4HfDqq68iMTER/v7+GD58ODZt2tTq8Rs2bJDHieN79+6N119/HWq0YMECXHbZZbLDc3R0NG644QYcOXKk1c9Zv3697Abd+HL48GGo0dNPP93kXGNjY3Xx+Am9evVq9vG4//77Nfn4bdy4Edddd53sWirO68svv2zwcVEjIR5T8fGAgABMmjQJBw8ebPN+ly1bhpSUFFnhIa6XL18ONX6NNTU1ePTRRzFo0CAEBQXJY+644w7Zib017733XrOPa2VlJdT2GN51111NznP06NG6eQyF5h4LcfnHP/6h+sdwgRPPC2r9PWSA005Lly7F3Llz8cQTT2D37t2YMGECpk2bhszMzGaPT09Px7XXXiuPE8c//vjjmDNnjnxg1UY8kYsnwq1bt2Lt2rWora3F5MmTUV5e3ubnih/4nJwcx6Vv375QqwEDBjQ41/3797d4rJYeP+HHH39s8LWJx1G4+eabNfn4iZ+9IUOG4OWXX27243//+9/xwgsvyI+Lr10Eq9dcc41j3lxztmzZgltuuQWzZ8/G3r175fWsWbOwbds2qO1rrKiowK5du/DUU0/J6y+++AJHjx7FzJkz27xf0T22/mMqLiJIV9tjKEydOrXBea5cubLV+9TSYyg0fhzeeecdGazceOONqn8MNzjxvKDa30NRJk7OGzlypPW+++5rcFtycrL1sccea/b4P/3pT/Lj9f32t7+1jh49WvXf9ry8PNFCwLphw4YWj/n+++/lMefOnbNqwZ///GfrkCFDnD5ey4+f8OCDD1r79OljtVgsmn/8xHkuX77c8b74mmJjY63PPfec47bKykpraGio9fXXX2/xfmbNmmWdOnVqg9umTJlivfXWW61q+xqbs337dnlcRkZGi8e8++678vugNs19fXfeeaf1+uuvb9f9aP0xFF/vlVde2eoxan0M8xo9L6j595ArOO1QXV2NnTt3yui1PvF+ampqi1Fq4+OnTJmCHTt2yOVnNSsuLpbX4eHhbR47dOhQxMXF4aqrrsL3338PNTt27JhcShXbjLfeeitOnjzZ4rFafvzEz+sHH3yAX//6120OldXS41d/dS03N7fB4yOWuidOnNji72Nrj2lrn6O230vxeHbt2rXV48rKypCQkCDn7s2YMUOuQKqV2CoV2x/9+vXDPffcg7y8vFaP1/JjePbsWXzzzTe4++672zxWjY9hcaPnBTX/HjLAaYeCggLU1dUhJiamwe3iffEAN0fc3tzxYplP3J9aiRci8+bNw/jx4zFw4MAWjxNPim+++abcshHL50lJSfJJUuxJq9GoUaOwZMkSrF69Gm+99ZZ8fMaOHYvCwkJdPX6CyAM4f/68zHHQy+NXn/13rj2/j/bPa+/nqIXIv3jsscdw2223tTrAMDk5WeZwrFixAh9//LHc1hg3bpwM7tVGbPF/+OGH+N///od//etfcovjyiuvRFVVlS4fw8WLF8t8lp///OetHqfGx9DazPOCmn8PDTlN/GI1fjUsHvTWXiE3d3xzt6vJAw88gH379mHz5s2tHieeEMXFbsyYMcjKysI///lPXH755VDjH1M7kbgpzrdPnz7yj474xdXL4ye8/fbb8usVq1V6efxc8fvY0c/xNLFiKFYcLRaLLHRojUjSrZ+oK54Yhw0bhpdeegmLFi2Cmog8DDvxpDlixAi5aiFWOVoLArT4GAoi/+b2229vM5dGjY/hA608L6jx95ArOO0QGRkJLy+vJhGmWE5tHInaiWSr5o739vZGREQE1OgPf/iDfNUgtirE0mh7iV9KNb5SbI6oTBGBTkvnq8XHT8jIyMC6devwm9/8RrePn736rT2/j/bPa+/nqCG4EQmYYjtAJHq2tnrTHLPZLCthtPC4ilVFEeC0dq5afAwFUXErEvo78nvp6cfwDy08L6j595ABTjv4+vrKcmF7ZYqdeF9sczRHvCJufPyaNWvkqxQfHx+oiYieRYQutirEcrHIUekIsU8s/khpgVgGP3ToUIvnq6XHr753331X5jRMnz5dt4+f+PkUfyTrPz4i70hUfbT0+9jaY9ra56ghuBFPbCJo7UhgLX639+zZo4nHVWwXi1XE1s5Va49h/VVV8RwiKq608hha23heUPXvocvSlQ3ik08+sfr4+Fjffvtta1pamnXu3LnWoKAg66lTp+THRTXV7NmzHcefPHnSGhgYaH3ooYfk8eLzxOd//vnnVrX53e9+JzPf169fb83JyXFcKioqHMc0/vr+/e9/y4qBo0ePWg8cOCA/Ln6sli1bZlWjhx9+WH594nHZunWrdcaMGdbg4GBdPH52dXV11p49e1offfTRJh/T2uNXWlpq3b17t7yI83rhhRfk2/YKIlG5IX5mv/jiC+v+/futv/jFL6xxcXHWkpISx32Ir7d+leMPP/xg9fLykp976NAhee3t7S1/HtT2NdbU1Fhnzpxp7d69u3XPnj0Nfi+rqqpa/Bqffvpp66pVq6wnTpyQ9/WrX/1Kfo3btm1T1dcnPiZ+J1NTU63p6emyqm/MmDHWbt266eYxtCsuLpZ/S1577bVm70Otj+HvnHheUOvvIQOcDnjllVesCQkJVl9fX+uwYcMalFGLkseJEyc2OF78YAwdOlQe36tXrxZ/wD1N/GI2dxHlii19fc8//7wsQ/b397eGhYVZx48fb/3mm2+sanXLLbfIXzwRpMTHx1t//vOfWw8ePKiLx89u9erV8nE7cuRIk49p7fGzl7E3voivw16iKkr/RZmqn5+f9fLLL5d/YOsTX6/9eLvPPvvMmpSUJH8ORBsATwZ0rX2N4km/pd9L8XktfY3ihZcIcsXPbFRUlHXy5MkyiFDb1yeeJMW5iXMUj4U4Z3F7Zmambh5DuzfeeMMaEBBgPX/+fLP3odbHEE48L6j199Bk+wKIiIiIdIM5OERERKQ7DHCIiIhIdxjgEBERke4wwCEiIiLdYYBDREREusMAh4iIiHSHAQ4RERHpDgMcIiIi0h0GOERERKQ7DHCIiIhIdxjgEBERke4wwCEiIiLozf8HnNEBwjwLmrcAAAAASUVORK5CYII=", + "image/png": "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8UWMGTNGBgFiv7///nv5unSnJdfxhX/96194/fXX5UFPQUFBvedJBDbifSnen+ILXOyreN3973//kwGLO3/5y1+QlpaGLl26OC4T1/N3gPPLL79g9uzZyM7Olp9/Yr/rBjiffPIJ3n//fYwfP95xWWJiYqMBjng9XHDBBTJwGjRoENauXYurrrpKPpb+JAIR8Rr97rvvUFtbKwO4ugGO2EcRcDpbuXKl7KgvApyGiOdbvC/FZ41zMDFw4EC/fndkZ2fL158ITsXrTRwAiy7Fn332mXzvON/HSZMmyQZ8IgjavHkz3n77bVx++eVub7sl12kWUUVFnvn1119FxZl18eLF8veysjLrwIEDrVdddZVXrxMoO3bssH7//feO32tra62XXnqptU+fPo1er3v37tZ///vfVi144oknrCNHjmzWdebMmWNNTk62Hjt2TP6ekZFhjYiIsL7//vtWtauurra2b9/eescdd7jd5uDBg/I1unfvXqva7N692/rxxx9bKyoq5PN2++2319tm+fLlcv9Xrlwpfy8qKrL27NnTeuutt7q93ZZcx1deeeUV69GjR+XPuLi4en/fvHmz3F/n5/S8886zDh8+vNHbbdeunfWjjz6yBpr47Pv555+tJSUl8jH/3//+V2+b+++/3zpx4sRm3e5DDz1k7dSpkzUnJ0f+vmnTJmtwcLB1wYIFVn86fvy49a233rKWlpZaL7zwQuu0adOavE55ebk1Pj7e+sADD7jdZtu2bfLxysrKsgbSvn37rIsWLXL8brFYrNddd501NTXVZbuhQ4daL7roIvl34dlnn7VGRkZaT5w44fa2W3Kd5mCA0wyzZs2q92X/+uuvW8PDw+UL1lvXUZP//ve/8k0mvmAaC3Duvfde65dffmndsGGDtbKy0qrmAGfAgAHWb775xrps2TLHh2Nj+vXrZ73zzjtdLrvkkkusZ599tlXtvvrqK/n8bdmypckAR3wZLly40Lpz506rGrkLcG688cZ6X/bPPPOMNTY2VgbpDWnJdXzNXYDTkP/85z/W0NBQxxeDuwDn4YcflgHFb7/9JgOjQGoqwBkxYoR8/f3000/WvLy8Jm+vS5cu1tmzZ7tcdu6558ovzEDxNMARQbvJZGr0oMIe4Hz++ecywNizZ49VLb7++mu5b/n5+fJ38Zkhfl+xYoVjGxHwiQPBN954o8Hb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", "text/plain": [ "
" ] @@ -250,7 +252,7 @@ "id": "778b686d-2fb1-47b9-9cdd-727e43d690b1", "metadata": {}, "source": [ - "Now we get the neural network's current parameters as a tuple." + "The functional forward and derivative functions expect the model parameters as a tuple. These entries refer to the same parameter objects that the optimizer updates in place." ] }, { @@ -369,7 +371,7 @@ "id": "7e7309b3-ec55-4551-8342-9c9fd5603c4f", "metadata": {}, "source": [ - "The Adam optimizer is used with a learning rate of 0.01." + "PyTorch's Adam optimizer is used with a learning rate of 0.01. Derivatives with respect to time still come from `torch.func`; gradients with respect to the model parameters use the standard `backward()` workflow." ] }, { @@ -389,7 +391,7 @@ "metadata": {}, "outputs": [], "source": [ - "optimizer = torchopt.FuncOptimizer(torchopt.adam(lr=learning_rate))" + "optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)" ] }, { @@ -424,38 +426,41 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 1 with loss 1.4024e-01\n", - "Epoch 101 with loss 6.0150e-03\n", - "Epoch 201 with loss 5.7146e-03\n", - "Epoch 301 with loss 5.0245e-03\n", - "Epoch 401 with loss 4.4967e-03\n", - "Epoch 501 with loss 4.2435e-03\n", - "Epoch 601 with loss 4.0222e-03\n", - "Epoch 701 with loss 3.4903e-03\n", - "Epoch 801 with loss 3.3739e-03\n", - "Epoch 901 with loss 2.2528e-03\n", - "Epoch 1001 with loss 1.6255e-03\n", - "Epoch 1101 with loss 1.2264e-03\n", - "Epoch 1201 with loss 6.8257e-04\n", - "Epoch 1301 with loss 3.9798e-04\n", - "Epoch 1401 with loss 3.5392e-04\n", - "Epoch 1501 with loss 3.9757e-04\n", - "Epoch 1601 with loss 1.7708e-04\n", - "Epoch 1701 with loss 3.3246e-04\n", - "Epoch 1801 with loss 7.0709e-04\n", - "Epoch 1901 with loss 2.7778e-05\n" + "Epoch 1 with loss 5.1072e-02\n", + "Epoch 101 with loss 6.7929e-03\n", + "Epoch 201 with loss 6.3143e-03\n", + "Epoch 301 with loss 5.4911e-03\n", + "Epoch 401 with loss 5.1791e-03\n", + "Epoch 501 with loss 4.1048e-03\n", + "Epoch 601 with loss 3.7494e-03\n", + "Epoch 701 with loss 5.9103e-03\n", + "Epoch 801 with loss 4.5360e-03\n", + "Epoch 901 with loss 3.5692e-03\n", + "Epoch 1001 with loss 3.4571e-03\n", + "Epoch 1101 with loss 3.7942e-03\n", + "Epoch 1201 with loss 3.4977e-03\n", + "Epoch 1301 with loss 2.5390e-03\n", + "Epoch 1401 with loss 2.2144e-03\n", + "Epoch 1501 with loss 1.9502e-03\n", + "Epoch 1601 with loss 1.2583e-03\n", + "Epoch 1701 with loss 7.6283e-04\n", + "Epoch 1801 with loss 6.1161e-04\n", + "Epoch 1901 with loss 6.3824e-04\n" ] } ], "source": [ "for epoch in range(nr_epochs):\n", - " t = torch.FloatTensor(batch_size).uniform_(*t_domain)\n", + " t = torch.empty(batch_size).uniform_(*t_domain)\n", + " optimizer.zero_grad(set_to_none=True)\n", " loss = loss_function(params, t)\n", - " if loss < loss_threshold:\n", + " loss_value = loss.item()\n", + " if loss_value < loss_threshold:\n", " break\n", - " params = optimizer.step(loss, params)\n", + " loss.backward()\n", + " optimizer.step()\n", " if epoch % 100 == 0:\n", - " print(f'Epoch {epoch + 1} with loss {float(loss.detach()):.4e}')" + " print(f'Epoch {epoch + 1} with loss {loss_value:.4e}')" ] }, { @@ -466,7 +471,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjgAAAGdCAYAAAAfTAk2AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAi2BJREFUeJzt3Qd4XMW1B/D/3areey+2Vdx7BRswtgHTwfQSDAkQIEB4SQgvLwSSkJAESCCU0EPoGBOKcQPce5OLZEtW772X1Zb7vplZyZYsyZKl1b27e37ft99cra5Wo72S9uzMmTOSLMsyCCGEEEJciEbpDhBCCCGEjDQKcAghhBDicijAIYQQQojLoQCHEEIIIS6HAhxCCCGEuBwKcAghhBDicijAIYQQQojLoQCHEEIIIS5HBzdks9lQVlYGX19fSJKkdHcIIYQQMgisNnFzczOioqKg0Qw8RuOWAQ4LbmJjY5XuBiGEEELOQXFxMWJiYgY8xy0DHDZy0/UE+fn5Kd0dQgghhAxCU1MTH6Doeh0fiFsGOF3TUiy4oQCHEEIIcS6DSS+hJGNCCCGEuBwKcAghhBDicijAIYQQQojLccscHEIIIc7DarXCbDYr3Q0ySvR6PbRa7bAfhwIcQgghqtXS0oKSkhJe/4S4TwJxTEwMfHx8hvU4FOAQQghR7cgNC268vLwQGhpKhVndgCzLqK6u5td97NixwxrJoQCHEEKIKrFpKfaCx4IbT09PpbtDRgm73gUFBfz6DyfAoSRjQgghqkZb6rgXaYS2UKIAhxBCCCEuZ1QCnJdffhmJiYnw8PDA9OnTsXXr1n7P/fzzz3HxxRfzISpWZXju3LlYt27dGeetWrUK6enpMBqNvF29erWDfwpCCCGEOAuHBzgff/wxHn74YTzxxBM4ePAgzjvvPFxyySUoKirq8/wtW7bwAGfNmjXYv38/LrjgAlx++eX8a7vs3LkTN9xwA2677TZkZGTwdsWKFdi9e7ejfxxCCCGEOAPZwWbNmiXfe++9Pe5LTU2Vf/WrXw36MdLT0+Xf/e533R+vWLFCXrZsWY9zli5dKt94442DerzGxka23pC3hBBC1Km9vV3OzMzkrTO54447+GsMu+l0OjkxMVH++c9/Lre0tMj5+fn8/oMHD/Jzuz4ODQ2Vm5qaejzO5MmT5d/+9rfdHy9cuJCf++GHH/Y47/nnn5fj4+Nld7jujUN4/XboCE5nZycfhVmyZEmP+9nHO3bsGNRj2Gw2NDc3IygoqMcITu/HXLp0ab+PaTKZ+A6kp98cwmICVt0DbP4LUHbIMd+DEEKI6i1btgzl5eXIy8vD73//e56q8dhjj/V7Pnud++tf/3rWx2WpHv/7v/9LhQ8HwaEBTk1NDa9jEB4e3uN+9nFFRcWgHuNvf/sbWltb+RRUF/a1Q3nMZ555Bv7+/t03ttW6I9hqcoEjnwA//B7410Lg858AnW0O+V6EEOJu2JLxtk6LIrehFhpk+aERERH89ebmm2/GLbfcgi+++KLf8x988EE899xzqKqqGvBxb7rpJjQ2NuL1118fUn/ckU6JJV/sF2Uwy8A+/PBDPPnkk/jvf/+LsLCwc37Mxx9/HI8++mj3x2wExxFBTrXVE++Yb8QkTS6WaPdDe/gjoLkMuOUzQGcc8e9HCCHupN1sRfr/nbnoZDRkPrUUXoZzf8lkdXwG2m6CBS4bNmzAU089hZdeeqnf89jim1//+tf8vDvuuAPe3t7n3CdX59ARnJCQEF6kp/fICotQe4/A9JWcvHLlSnzyySdYvHhxj8+xqHgoj8kiafZLcfrNEWqlYKzyuh73mR/BLZ2/RovsAeRvAdb92iHfjxBCiPrt2bMHH3zwAS666KJ+z2Fv0P/0pz/hX//6F3Jzcwd8vPvvv59PVbERH6LQCI7BYODLwllUevXVV3ffzz6+8sorBxy5ueuuu3h72WWXnfF5tnScPcYjjzzSfd/69esxb948KCk9yg97nliM+tZO/HV9HB7Y24l3DM8Ce98AUi4FxvT/y00IIWRgnnotH0lR6nsPxddff833UrJYLHzkhr3mvfjii2hr6z9tgeWSLliwAL/5zW94QNQf9qadjeA88MADuO+++4bUL3fi8CkqNjXElnHPmDGDByYsOmVLxO+9997u6aPS0lL8+9//5h+zoOb222/H3//+d8yZM6d7pIYN77H8GeZnP/sZzj//fPz5z3/mvzRsCmvjxo3Ytm0b1CDQ24DfXzUBv9dr8c6uQ7hTtx7mrx+D/sE9gFavdPcIIcQpsVGO4UwTjSZW4uSVV17hO2NHRUXxlmFbEAyEjeKw18r/+Z//GfC8W2+9lSclswTmhISEEe27q3B4HRxWr+aFF17g0eaUKVN4nRtW4yY+Pp5/nmWZn14T57XXXuMR709/+lNERkZ231hQ04WN1Hz00Ud4++23MWnSJLzzzjt8Smv27NlQ0x/i45ekYkPkT1Aj+0HfkAcceFfpbhFCCBkFLDdmzJgx/LWuK7gZjFmzZuGaa67Br371qwHP02g0fAENC6LOFjS5q1EJhdl8Ibv1hQUnp9u0adOgHvO6667jNzXTaTX4v2tn48UXr8bv9O+i84e/wDDtDhrFIYQQ0q8//OEPGD9+PHS6gV+iWQoHe2PPBgbOltfqjmgvKgdLifCFZcrtqJb9YWirADL/6+hvSQghxImNGzeO56F2dHSc9VyWqjGY89yRxKr9wc2wZeIsn4fVEnDUiqrTVTZ14MO/PICHtZ+iLWQSvH66hc1hOfz7EkKIM2Mv3Pn5+d17GRL30DHAdR/K6zeN4IyCcD8P1Kbdig5ZD6+aw0DpgdH4toQQQojbogBnlNy4aCrW2mby47a9743WtyWEEELcEgU4o2R8lD+OhFwqnvRjq8S+VYQQQghxCApwRtG4OctRLgfBw9IE+cS3o/mtCSGEELdCAc4oumRyDL6SF/Djxn2fjua3JoQQQtwKBTijyM9Dj6aES/ixZ+H3gJmW9hFCCCGOQAHOKJs0axGfpjLa2iDnDa6oISGEEEKGhgKcUXZ+Sji+l8Vqqob9n4/2tyeEEELcAgU4o8xDr0V1zMX82Ji3DrBZR7sLhBBCyFmxrZQCAgLgrCjAUUDSjIvRKHvBy9JARf8IIcQFFRcXY+XKlXwncYPBwDfdZJtG19bW9jhv0aJFfHNmdjMajYiOjsbll1+Ozz8/c4S/67zeN7b5NDkTBTgKWJgajR22Cfy46dg6JbpACCHEQfLy8jBjxgxkZ2fjww8/xMmTJ/Hqq6/iu+++w9y5c1FXV9fj/HvuuQfl5eX8vFWrViE9PR033ngjfvzjH5/x2G+//TY/9/TbVVdd5bTXsrOz02GPTQGOAvy99MgPmMOPTSc2KtEFQgghDvLTn/6Uj9qsX78eCxcuRFxcHC655BJs3LgRpaWleOKJJ3qc7+XlhYiICMTGxmLOnDl8A022Q/jrr7/Ov+Z0bMqInXv6baB9up588kn+/dnoEBtNeuihh7o/V19fj9tvvx2BgYG8D6yPOTk5fT7OiRMn+GjR8ePHe9z/3HPPISEhAV3bWmZmZuLSSy+Fj48P3+H8tttuQ01NTY8RqwceeACPPvooQkJCcPHFImXDESjAUYgxZTFvg+ozgI5GpbpBCCHOg72IdrYqcxvkvtRsdGbdunW4//774enp2eNzLBi55ZZb8PHHH3cHBP254447eODR11TVYH322Wd4/vnnebDEApcvvvgCEydO7P78nXfeiX379uHLL7/Ezp07eZ9YcGI2m894rJSUFEyfPh3vv/9+j/s/+OAD3HzzzTz4YaNJLKCbMmUKf9y1a9eisrISK1as6PE17777LnQ6HbZv38775ig6hz0yGdDUSZOQuycSyZpyWHM3Qzv+CnrGCCFkIOY24I9RyjxHvy4DDN5nPY0FEixQSEtL6/Pz7H42clJdXY2wsLB+H0ej0WDcuHEoKCjocf9NN90ErVbb477Dhw8jKSnpjMcoKiriQdXixYuh1+v5SM6sWbO6+8kCGxZkzJs3j9/Hghc2isQCoeuvv/6Mx2PB2UsvvYSnn36af8ym4Pbv349///vf/ONXXnkF06ZNwx//+Mfur3nrrbf4Y7Jz2c/DjBkzBs8++ywcjUZwFDI5JgC7NVP4cd3htUp1gxBCyCjqGrlhIx6DObf3eWxE5tChQz1uLIDoy/XXX4/29nYe/LA8n9WrV8NisfDPZWVl8VGU2bNnd58fHBzMR2rY5/rC8oIKCwuxa9eu7oCIjdawnCGGBTs//PADn57quqWmpvLP5ebmdj8Oy08aDTSCoxCtRkJT5Hyg/FtoinYo1Q1CCHEeei8xkqLU9x4ENjrBghKWi9JX8i/LYWFTTyz/ZCBWq5WPssycKeqmdWEjMux7DEZsbCzPndmwYQPP5WHTZn/5y1+wefPmfqfI+gqqukRGRuKCCy7g01IsV4glUP/kJz/p/rzNZuMrwFgOUV9f28Xb++wjYSOBAhwFhY1fBJQDwe35QEs14BOqZHcIIUTd2AvvIKaJlMRGQVji7Msvv4xHHnmkRx5ORUUFH/Vgib1nG8FheSpsKuvaa68dVn88PT1xxRVX8BtLfmYjKkeOHOGjLmw0Z/fu3d1TVGwJO5tK6m96rWua6pe//CWfKmOjMmxUpwubnmKrwFjSMRsdUhpNUSloWmoSsmxiaLEzf7uSXSGEEDJCWJ6KyWTC0qVLsWXLFl4ThyXcssCH1bn5wx/+0OP8trY2HvyUlJTwgIMFEPfeey/uu+8+PmJyuoaGBn7u6bfW1tZ+C/W9+eabOHr0KF+6/t577/GAh9XkGTt2LK688ko+dbVt2zZkZGTg1ltv5f1j9/fnmmuuQVNTU3ff2PldWADFkqxZ8LNnzx7+PdlKsrvuuouPSI02CnAUFB/shSO68fy4NvMHJbtCCCFkhLDgga0iSk5Oxg033MBbVtOGBQRstVJQUFCP89lycDaFw867+uqr+fQWW2nFRoF6+9GPfsTPPf324osv9tmPgIAA/tjz58/HpEmTeB2er776io8yddXUYSujli9fzuvzsOmpNWvW8ITk/vj5+fFpKBYQsdGc07Fl6CxpmQUzLLibMGECL27o7+/Pk6ZHmySfba2aC2LRJ3vCGxsb+cVS0puv/Q0ry59ClXcKwv5nj6J9IYQQNeno6EB+fj4SExMHrPVC3Oe6Nw3h9ZtGcBTmn3I+b0Nas6keDiGEEDJCKMBR2MTUVOTZIqCBDEvBTqW7QwghhLgECnAUNjbMBxkakbFek7lF6e4QQgghLoECHKUvgEZCc8hUfmwp3qt0dwghhBCXQAGOCngkitLZwY3HWKUkpbtDCCGEOD0KcFQgPmU6WmUjPG2tQE220t0hhBBVccPFvm5NHqHrTQGOCkyMC8IRWWyU1pBDBf8IIYTp2lSys7OTnhA30mm/3r03FR0q5WspE3gZdCj2TMccUxaaTu5CwPyV9KwQQtweK/fv5eXFd95mxeeUKBZHRhfbz4pdb3bdh7vdAwU4KtEZMQ0oXAVj5UGlu0IIIarA9mtilXpZ0Te2izVxDxqNBnFxcYPacX0gFOCohN+YOUAhENqWC3S2qn5DOUIIGQ0Gg4FvfUDTVO51zTUjMFpHAY5KpKWkonxjECKlOlhKDkCXdJ7SXSKEEFVgL3a0VQMZKprQVImkEG8clcbw4+oTVNGYEEIIGQ4KcFRU8K/OT+wsbio6oHR3CCGEEKc2KgEO2/K9a1dQtjX71q1b+z23vLwcN998M1JSUviw5MMPP3zGOe+88w5PPup9YzuQOrXIKbzxrjumdE8IIYQQp+bwAOfjjz/mQcoTTzyBgwcP4rzzzsMll1yCoqKiPs83mUwIDQ3l50+ePLnfx2XbpLNg6PSbs8/RBiZP522wqRgwtSjdHUIIIcRpOTzAee6557By5UrcfffdSEtLwwsvvIDY2Fi88sorfZ6fkJCAv//977j99tvh7+/f7+OyEZuIiIgeN2c3LikJ5XKQ2Fm8/LDS3SGEEEKclkMDHLasb//+/ViyZEmP+9nHO3bsGNZjt7S0ID4+HjExMVi+fDkfHeoPGxVqamrqcVOjuCAvnEACP67JoY03CSGEEFUGODU1NbBarQgPD+9xP/u4oqLinB83NTWV5+F8+eWX+PDDD/nU1Pz585GTk9Pn+c888wwfDeq6sREktSYa1/im8eN2SjR2K22dFlQ3m2C10Z47hBAyEkalDk7vaoRsI63hVCicM2cOv3Vhwc20adPw4osv4h//+McZ5z/++ON49NFHuz9mIzhqDXJs4ROBFsCzhhKNXR37O1hzpAKvbcnF4ZJGfl+Alx5XTI7CAxeOQZivc+eUEUKIywY4ISEhfLOs3qM1VVVVZ4zqDAdbbTVz5sx+R3CMRiO/OQP/pBlALhDSngdYTIDOOfpNhqbDbMVjn2bgm8OlmKPJwk+0efz+wx1J+M9OE74+XI6Xbp6Keckh9NQSQojaAhxWbpktC9+wYQOuvvrq7vvZx1deeeWIvhM+dOgQJk6cCGeXPCYF9et9ECi1wFqRCW3MVKW7REaYxWrD/e8fQN2JHVhvfA1jpdIeny/QxOGRtpW46x0L3r5zFuYmB9M1IIQQta2iYlNDb7zxBt566y1kZWXhkUce4UvE77333u7pI7Zi6nQsWGE3lkjMdhVlx5mZmd2f/93vfod169YhLy+Pf46t0mJt12M6s8RQXxy3JxrXntytdHeIA/zuq0x4Z3+BzwxPiuDG6A9MuBYYfw0/TrAV4VPj01hm3YK7392LvGoqGUAIIarLwbnhhhtQW1uLp556iteqmTBhAtasWcNXQDHsvt41caZOPTVqwVZhffDBB/z8goICfl9DQwN+/OMf86kvljTMzt+yZQtmzZoFZ6fVSKjyTgHajqKl4BDClO4QGVEbMytRumc1Xtf/E1pJBtKvBC7/O+AZKE5orwe++hl0mf/Fc4ZXcV+nEQ9+6I3P758Ho05LV4MQQgZJktn8jpthScYsMGpsbOQFA9Vm1dt/xbWFT6PIZwriHtusdHfICGlsM+OO5z7Gv83/Az+pDZhyC3DFSyyJrOeJNhvw1UPAwffQCg8sN/0Bl19wHh5dkkLXghDi1pqG8PpNe1GpkHfsJN4Gt55kCUZKd4eMkBe/y8bjnS/y4MYWMwtY/sKZwQ3D7mOfi18Ab3Tg7/qX8K8tJ1FU20bXghBCBokCHBWKHDMZFlkDb7kFaCpTujtkBBTXtaF197uYrTkOq9YTmmvfAHSG/r9AqwOuexOyhz8mafJxg7wOf1hzKg+NEELIwCjAUaGxUcHIkyP5cWNhhtLdISPglfUZeEz7AT/WXPhrIFDkoA3INwLSRb/lh4/pPsG+Y9k4Wirq5RBCCBkYBTgq5GXQoUSfyI/r8/vfgoI4h/LGdgQfexvBUjM6/BIgzblv8F88/Ud8l3lfqR336b7E37/ru9YTIYSQnijAUalm/3G8NZdTRWNn98Hmo7hb8xU/9lj8v4BWP/gvZvk4F/2GH96q3YiMzOM4UdHsqK4SQojLoABHpaTwdN561x9XuitkmHtM2fa/C3+pDa1+ycCEa4b+IMkXAbFz4CGZ8WPd13hnRz5dE0IIOQsKcFTKP2EKb0NNhYDVrHR3yDn6JqMEN8pr+bHn+T8DNOdQy4bt23b+//DDG7SbsO5ADupbO+maEELIACjAUan4pDQ0y57QwwJrNeVdOKv8bZ8iVlONDp0/NJOuP/cHSr4Qcsg4notzhbwJn+wrHsluEkKIy6EAR6Xigr1xEmLH85o8SjR2RiermjG/bjU/tk69HTB4nfuDaTSQZv+EH96pXYdP9xbyPdgIIYT0jQIcldJoJFR6JvPjZloq7pTWbd+D+VqRJO49/8fDf8DJN0Fme1VpKhFetweHihuG/5iEEOKiKMBRsY6gVN5KVVTgzdnYbDK0Rz7hx3Whs4GAuOE/qMEb0sTr+OH12s34dH/J8B+TEEJcFAU4KmaMHM9b3+aTSneFDNG+gjostfzAj/3m3DFyz9/UW3izTLMXmzJy0GG20rUhhJA+UICjYiGJYk+qEEsFYG5XujtkCI7s2oBETSVMkid0E64cuecuahrk0DS+ZHyReRu+y6qi60IIIX2gAEfFEuPjUSf7QAMZpooTSneHDGF6yvvkl/y4Lu5iwOgzcs+dJEGyj+Jcpd2GNUfL6boQQkgfKMBRsWAfIwqkGH5cnU97UjmL/YV1OM+6ix+HzL5h5L/BeFEscIaUjSNZx9HeSdNUhBDSGwU4KiZJEmo9xZ5UrSWUaOwsMnb/gGiplk9P6cdeNPLfwD8acuxsaCQZF9h2YXM2TVMRQkhvFOConClwLG+lGpqichZeud/wti56EaD3dMj3kNKv4u2l2t1Yc6TCId+DEEKcGQU4KqePEEvFfZpzle4KGYT86hbMNW3nxwHTz2HfqcFKF4nLM6UTOJyVRaupCCGkFwpwVC4oXqykCjOX0p5UTuDA/p189VQn9PBMv8Rx34hNU8XM4tNU51t3YVdereO+FyGEOCEKcFQuPmEM35NKBys6aU8q1evMWsfbyqCZgNHXod9LSruct4s1B/D9ccrDIYSQ01GAo3Khfh4okKL5cXXeYaW7QwbQarIgvn4nP/ZIW+r452rcMt7M1mRhZxbtTUUIIaejAMcJVlLVeCTw4+bio0p3hwxg9/EiTJeO8+OQqZc5/rkKGQtbQAKMkgWJTXtxsqqFrg8hhNhRgOME2gPGiIPqbKW7QgZQnrGeBxt1hkhIwfZr5kiSBE2KGMW5UHMQ39E0FSGEdKMAxwnowsRKKu8m2pNKzXxLNvO2OWYRDz5GxdglvLlAewg/ZNFycUII6aLrPiKq5R8/ETgMhHUWAzYroNEq3SXSS3VTB6Z07OVvGYImXzp6z0/CAtj0Xgg3N6Cj+CBaTLPhY6Q/a3fR1mnBhsxKbM6uRlWTCR56LVIjfHHFlCiMC3dskjshakf/CZ1AbGIqTLIeRqkT5toC6EOTle4S6eXIkQO4UFMNM3TwTb1w9J4fnRGa5AuB419jIQ5iT34tLkwNp+vj4mRZxqf7SvDsuhOoaTH1+NzGrEq89MNJLEkPx++uHI9If8cUmyRE7WiKyglEBnojH1H8uDqfVlKpUUPm97wt85kwsptrDsYYsR3EfO1RbMuhejiuju099vDHh/CLVYd5cBMT6In7FyXjuRWT8dSV43lgo9VIWJ9ZiaXPb8HOXPqdIO6JRnCcZCVVlUcCUk2FaCo6iqhZVyvdJdKLf+Vu3lrjFoz+c5O0iDdTpRz8MaeYlTke/T6QUdFhtuKef+/DtpM1PIh5bEkKVi5IhEF36r3q7XMTkF3ZjP/5NAMZJY24/a3dePmW6bg4nUb2iHuhERwn0e6XxFsLFftTnfKGNkwwi5G18MmLR78DgYmw+sfBIFkRWLMPVc0do98H4nA2m4wHPzzIgxsvgxb/WTkb9y1K7hHcdGH5Nx//ZC4umxgJs1XGAx8cwJ78OrpKxK1QgOMkNCFi003Ppjylu0J6OXL4AMKlBr49g3fS3NF/fiQJ2qSF/HCe5hh2nKQpCVf09+9yeEKxUafBW3fOxNzk4AHPZwnHf79xChanhcNkseG+/+xHZRMFv8R9UIDjJLyjxVLxoA42BUHUpCnrB95W+E4E9B7KdMI+TbVAc5S/wyeuhe01xgIc5g9XT8ScpIGDmy46rQYv3TwVaZF+qG3txIMfHITVJju4t4SoAwU4TiI8QeRVBMoNkNvrle4OOU1g9R7eWuPmK/e8JIoRnHRNITJzTvJVNsR1kop/uUpMgd44MxbXTY0Ccn8Avn4UeGc58O4VwJpfAPlb2fKqPkdyXr5lGi8fsKegDm9vz1fgpyBk9FGA4yRiI8JRKQfw47qiLKW7Q+xqmzsw3nyEH4dOFKuZFOETClvYeH6Y1HIQ+TWtyvWFjKjnNpxAYW0bIvw88L8zrMCbi4H3rgL2vQkUbAXyNwN7XgPeXQ68tQyoPnHGYySGeOPXl6bx47+tz0ZRbRtdJeLyKMBxEiyRsEwbw4/rio4p3R1idzwzAxFSPc+/8UlWIP/mNJrkC3g7X3OUEkpdxMmqZry5TYy4vD6zFD7vLQNK9wMGH2DGXcDVrwFXvQJMvQ3QeQLFu4DXFgInvj3jsdjoz5ykILSbrfjjGnqTRFzfqAQ4L7/8MhITE+Hh4YHp06dj69at/Z5bXl6Om2++GSkpKdBoNHj44Yf7PG/VqlVIT0+H0Wjk7erVq+HqGr3iedtRQXtSqUXjcVH/psR7vHL5N72mqeZqMinAcRF/XnsCLGXm8bhMTNz+EGDpAMYsBh7cDyx/Hph8IzDlZuDKl8R9LBfL0g58dDNwdFWPx9JoJDx15QRoJGDtsQrsK6BVVcS1OTzA+fjjj3mQ8sQTT+DgwYM477zzcMkll6CoqKjP800mE0JDQ/n5kydP7vOcnTt34oYbbsBtt92GjIwM3q5YsQK7d4taJK7KHCAqGGvqaE8qtfAq38fbjqjZSncFiJsNGRISNJXIzaffEWe3t6COr5qap83Cj2v+zOoXA9PuAG76GPCNOPML/KOBWz4DptwCyDZg9b1A/pYzlo/fMDOWH//+myzK1SIuzeEBznPPPYeVK1fi7rvvRlpaGl544QXExsbilVde6fP8hIQE/P3vf8ftt98Of3//Ps9hj3HxxRfj8ccfR2pqKm8vuugifr8r04eP461vS4HSXSEAOi02xLWL6cLAcQomGHfx8IctfAI/jGnKQGlDu9I9IsPw7NrjCEITXvV8GZLNDKRfJUZttAPUZ9XqgSteBNKuAKydwKc/AprKe5zyyOJxvI7OoeIGXu2YEFfl0ACns7MT+/fvx5IlYsfjLuzjHTt2nPPjshGc3o+5dOnSfh+TjQo1NTX1uDmjgFiRJBhqLmVVv5TujtvLystHkiRePCLGn6eK50MbP4+3MzXHsZcKuzn16A27/c3wGvwstUBoqsi1GcxGu+yca14HwicCbTXA5/f0+H8R5ueBO+cl8ON//kAr7ojrcmiAU1NTA6vVivDwniXC2ccVFRXn/Ljsa4fymM888wwfDeq6sREkZxSVkAKzrIUnTDDVUz0cpVUcE7lk5fo4SF5BUIV4keg8W3OcLwkmzumVTbm4UrMdF2gOAlojcN1bgMFr8A/A8sGufxvQe4uVVgfe6fFptr2Dh16DwyWNVDeJuCzNaO2ldDpWo6P3fY58TDaF1djY2H0rLnbO4CDU3wclCOPHVQWZSnfH7dmKRP2bhuAp6nku4sQITopUjGN5fee5EXXLKm/CnuMFeEL/gbhj4S+AcFECYEhY9fOLfiOONz4JtFR1fyrYx4ibZsXx45e+p3wt4pocGuCEhIRAq9WeMbJSVVV1xgjMUERERAzpMdlKKz8/vx43p9100yhGn5pKKMBREguoQxsy+LFHorLLw3vwDYc1MAkaSUZQ7UHUtpiU7hEZote35uFB3WqESQ1AUDIw78Fzfw5n/RiInAx0NAIb/q/Hp358fhL0Wgm78+twuKSBrhNxOQ4NcAwGA18WvmHDhh73s4/nzRPvNM/F3Llzz3jM9evXD+sxnUWrj5g7t1SJsu1EGRUNLUi3iWsQOeF8VV0GbYL4O5jF8nBomsqp1LV2Yu/hY7hTu17csexPgM547g/I8nEue14cZ3wEVJ6qoRXp78k342Te3VE4vI4T4o5TVI8++ijeeOMNvPXWW8jKysIjjzzCl4jfe++93dNHbMXU6Q4dOsRvLS0tqK6u5seZmadGLH72s5/xgObPf/4zjh8/ztuNGzf2WzPHlchBYtNNQwNtuqmk/GN74SWZ0AJveESKbTTUNk01U3MC+wtpWw9n8um+YqzEFzBKZshxc4GxFw//QWOmixVYbJn5d0/1+NQd9mTjrw6X0WgfcTkOD3BYvRq2fPupp57ClClTsGXLFqxZswbx8fHdhf1618SZOnUqv7EVWB988AE/vvTSS7s/z0ZqPvroI7z99tuYNGkS3nnnHV5vZ/ZsFdQicTDPSLFUPLCd3nEpqTVXrNgr9RnPKqhBVeyJxpOkXBwrpGXAzsJmk7F+5wHcpBXFI6VFj/Od4kfEhb8BJC2QvRYoOlUvbEpsACbF+POSBx/tdc7cREL6Myr/me+//34UFBTw5dosaDn//FND+iw42bRp0xn5Db1v7OtPd9111/HRG7YUnY0MXXPNNXAHIfEi2TDUVgnZ3KF0d9yWV+V+3poipkN1AhNh8Y6AQbJCKjvAX7yI+m3Jqcbylk9hlCywxs4DEkdw6jNkjKh4zGx7vkde3x1zxSjO+7sKaadx4lJU9taTnE1sbCKaZU9oIaOxlLZsUAILuKPbxF4+vgrvP9UnSYI2XoxmTpSzkVnunHWf3M3Xe47jeu1mfqxd+NjIjd50mc+m8CUg+1ug8tSU/2WTIuHnoUNZYwd25taO7PckREEU4DgZT6MOpZooflxdSCuplFBcXoEEiAJ/0ePVmdguxczk7TRNDg4WUR6O2jV1mBGU/Sl8pA50BIwFki8c+W/CRnHSrxDH2//efbeHXosrpoj/KZ/up2kq4joowHFCdZ6ifkVbOe0IrISSzJ28rdSEw+AXClWyBzhTNSdxgBKNVW/t4RLcKokdwI0Lfjryozc9RnEAHPkUaCrrvvv66aL8xNqjFTzYIsQVUIDjhEx+SeKghgp0KaG9QGywWe13DsXXRkvkZNg0eoRKjSgvpKlMtSvYuRpxmmp06PwhTbrBcd8oehoQPx+QrcD+d7vvZonGY8N8YLLY8HVGz72rCHFWFOA4IW3oGN56tFClWiV41RzmrS1CRRWMe9N7QrZvvBnZfARVzZSQrlbFdW2YWvM1P7ZMvnloWzKci5krRbv/HcBq7k42vn5GDD+maSriKijAcUI+9qXiwaYSpbvidqw2GTHtJ/hx4Fh1lyXQxs46bZqKKtWq1YY9GWLPKfa3PedHjv+GqZcD3mFASwVw/Jvuu6+aGg2tRsLBogbkVbc4vh+EOBgFOE4oNF4UlguR62DroH9Eo6mguBixktjTJypN3QEOTk80LqZEY7WyHvoYOsmGmoDJQGiK47+hzgBMsxdX3ftG991hvh5YMCaEH399mKapiPOjAMcJRUZEoF724cfVxWI0gYyOskxR4K9MGw2tV6C6n/aYGbxJlwpwtODURotEPXKrmnFB2zp+7DX7jtH7xtPvBCSN2Gm8Nrf77uWTxNYNXx8+lYBMiLOiAMcJ6bQaVGjFP6L64uNKd8etdBaJAn+1/ipOMO4SmACLZzAv+GctOwSzlQr+qc3BHRswRlMGk2SE19TrR+8bB8QCyReJ44wPu+9eMj4CBq0G2ZUtyK5sHr3+kFFhsdpQ0djB8746zFaXf9Z1SneAnJsGj1igLQftlbRCZjT51B3hrRyl4gTj0wv+sTyc7G8x3paNExXNmBDtr3SvyGmMx1fxtjzyYiR4+I3uczP5RuDkBiDjY2DRr/mWI/6eepw/LgQbs6rwdUYZHl0yClNmxOGFSX84UYUPdhdh28kadJjFGx2NBEyNC+S5V9dPj+H1kFwNjeA4qU5/UV4ddflKd8Wt9gqK6xABZWCyyvNv7KTYU/VwDpc0Kt0dcpqi6mbMbt/Gj4Pm2LdRGE2plwFGP6CxCCgSU6/M8klR3Xk47MWROK/8mlZc9+pO3PXOPh60suCGJZIbdBrYZPDNeH/zxVEs+ssm/HDc9aaxKcBxUtoQUQvHs5k23RwtJcUFiJRqYZUlRKaKFUqq113wLweHS2gllZpk7FiDMKkBLZIP/NJHYNfwodJ7AuOvOmOaanF6OIw6DfJqWmmbDye27lgFLv37Vh7EeOq1+PH5SVjz0HnI/v0lOPH0Mmz/1YX4v+XpiPL3QEVTB370zl78cU0WfyPnKijAcVLeEWKpeBAtFR81FSf28LZUFwOd5yhPJ5yrqKmQISFaqkVxUc8Na4mydFlf8LYiarFY2aSEyTeJ9th/gc42fuhj1OGClLDuysbE+Xy8twj3/Wc/2s1WzE0Kxnc/X4hfXxSD9KpvoF3zc0gf3Yzob1firrY3sekqM+6ZJypZ/2tLHh786CDP1XEFFOA4qdD4NN6GyTWwmcQ/JuJYHSWiVkmdb6rzPNVGX1iC7IUhaw67RWKhM6hqbMFM+/RU8Gx7kKGE2DlAQDzQ2QycWNN995Lx4bzdkFmpXN/IOY/cPP75ET4FddOsWLx3axqi9v0Z+GsK8MW9wL43xbU+8Q2w40UYPr4BT2Rfh//OPg5PrYxvDpfjsU8zXGIkhwIcJxUREc13FWeqS2ip+GjwqBGbm1rDRIVgZ6GLmcbbCcijKQeVyNyxBiFSE5okPwSOX6xcRzQaYOJ14vjY6u67L0wN47kaxyuaUVRLb6CcxYGiejz04UEe3Nw4MxZ/nNkB3avzgG3PA+ZWIHgsMO9BYPkLwKV/FeUCvEOBlkpMzngKOyP+gkRNFb44VIYXNjr/AhYKcJyUTqdFmVYkA9YV0VLx0RDelsNb34SpcCZS9HTeTtLk4XAx5eGogdY+PVUQdhGgVXgxa7o9D+fkRsAkCocGeBkwKyGIH6/PpGkqZ9DQ1okH3j/A9xNbnBaGP4zNhvT2pUBTCS8ZgRs/BB7YCyz5PTDjR8Cse4DL/w48kimCHaM/AmoPYa33k5gincQ/vj+JtUedu+AjBTjOvlSc7SpeKV54iePU1NUiVhZ/7NHOkmDcJWrqqQCHEo0V12m2IK1RTE95T7lG6e4AEROBoCTA0gFkr+2+++J0mqZyFmy12y8+O4yyxg4kBHvhpfEnoF19D2AzA2lXAD/ZCqRe2vcu9Sz/iwU7920DoqbBaG7AJ55/xBxNJn7+SQavmeOsKMBxYia/eHFQm6d0V1xeyfF90EgyqqUgeAeJIotOI3wCbJKW7yxeVky/K0o7fmAzQqRGtMATiTOWKt0d8aLXNYqTKUaWTg9w9hbUob61U6nekUH4dH8J1mdWQq+V8M55zfD45iFAtgHT7gCufxcYTI2lgDjgjq94AUiDrQNvGZ9DvDmXBzlsDz5nRAGOE9OGJPPWs4WWijtac4FIMK7yHAunY/CCNUQUbPOrP4IWk0XpHrm1pkNf8vak3xxo9EaoQtdy8ZwN3dNUsUFeSI3w5fkc37lgjRRXUdti4su7mafn65Hww08B2SpWyLEpKJZnNVhGH+DGD4D4BfCS2/Cu4VnkF+TirW3OWW+NAhwn5mVfKh7YQbuKO5qm6ihvO4LFRqfORm9PNJ4o5eNoKRX8U1Jk5SbeyuNUMHrTJWISEJgopqlyxN5YXVs3MBsoD0e1/rjmOBrazJgYbsQN+b8BTE1A3DwR3PQ1JXU2eg/gpg+A0DSESg140fASXtiQiZJ655uqogDHiYXG2ZeK26ph6+xQujsuLahJrFQzxjrBFg19iRIBzmQpF0eoorFiSvNPINlWwItFJs9TQf5NF/ZC2DWKc+zUNNUS+zTVlmxW4p9KDKgNK+K36kAJv3xvRn8NqTpLrIpa8S6gG8booIc/cMN7kA0+mKPJwn3yJ3j6a7GK1JlQgOPEIqJi0SoboWW5ISXOv6RPrdo7TEi0iiHayBRRGdjp2BONJ2rykVFcr3Rv3Fbxrs95m20cD78gETyoxumrqcziDdP4KD9E+nvwgnG78mqV7R85I7H4GfvU1K9SKhGW+bb4xJUvAz6iUOOwhIyFdMU/+OF92i9Rkbmd72nlTCjAcfKl4uW0VNzhCnIOw0Myow0eCIpx0s0Hw8fDptEjUGpBdQmtulOKT+F63jbG2nfyVpPIyYBfNGBuA/K38LskScLCcaH8eNOJaoU7SE7Hkor3FdbDV2/FysaXxJ0zVgLjlozcEzXhWmDiCv4m+ln9v/CXrw87VcIxBThOrt6+VLy1gkZwHPYc5+7nbakhCZLSNUvOlc4IW6jIHwpuPMZrZpDR1dnagJT2DH4cMv1q9T39bJ5j3DJxfFpV40UpIsDZnE0BjlqwIOPZtaL+2SsJ26CrzwV8woHFvx35b3bJn2HzCkWKpgRL6t/H6oOlcBYU4LjKUvE6Wv7rKLbyI7xt9HeiLRoGqGg8SZOPI5RoPOoK9q6FXrKiGBFISlVpLlfKpaJl9XDsO4nPHxMCnUbiO1MX1rYq2z/CrTlSjtzqVqR6NmB++bvizqV/FLkzI80rCJpLn+WH92q/wofrtsFkcY58LApwnJwmWOwq7tFcpHRXXJZvQ9apgmjOrKvgn5SLo6VNSvfG7bQd38Db/IA50GjOYXXLaEg8DzD4AM3lQPkhfpevhx7T4wP5MY3iKI/tEfXS9yf58d/CvoXEVr7FzxfTSY4y/mpY4xfwqfoftb+F93c5x+sNBTgus1S8WOmuuKxoUy5v/RPFCIjTirbvSaXJR2YpJRqPtrDqHbzVjFFh/k0XtvIm+UJxfOLb7rsX2XcXpzwc5W3MqsSJymZMMlbw3cG5xb87tyXhgyVJ0F7yJ9igwXLtbuz4/ku0d6p/FIcCHBdZKh5uq4LNTHkVI62mogghaODLemNSxJ5OTis0FVatEX5SOxpLaYPW0dRckYMoaxnMshZJM+15LmrVNU11Wh5OV6LxjlxaLq70yql//mAfvQn6AhKrVpy6HIgdhdWdEROB6Xfwwwcs7+CjPeovMEsBjpMLj45Hu2yATrKhilbHjLiKnAO8LdVEwtPbF05Nq+9ONPZrzEIrVTQeNSV7xDvtTG0KosJHYAmvI41dAkgaoOII0CBGhtMifRHuZ0SH2YY9+XVK99Bt7cytRUZJI6brCzC2fou4Thf936h9f80FT8Ci9cAUTR4yN32CTosNakYBjpPT6XQo14q9kWqL7LkiZMS0Fh3mbbWX2BbD2emjJ/N2vFSArHLKwxk1ud/zpjpsHlTPOxiInd1jmoqWi6vDW9sLePtUkCg3gInXA6GjWLrCJxSY/RN+eGfnB/h8v7pzcSjAcQH1xhjetldQfZORpmGVQdkS30AnrX/TV0l+e4BzrIwCnFFhtSCucS8/9EpX0fYMA+laLn5SJEafnoezOdu5ir25iqLaNnx3vBLJUinSGzeLOxc8Mur90C14GJ1ab4zXFCLz+/dhsap3FIcCHBfQ4SuWisv1zrkhmpr5t4j5bkO0k6+g6hIplienawpxtKRB6d64hZrsHfBGG+plH4yfdj6cwpjFos3f2l3VmC0X12okvjy5uM759iVydu/uLOAr938btBESZJErFSZyMEeVVxCkOffxw1vaP8CGY+VQKwpwXIAUlMBbY5P6k76cic1qRYxZPKchSSqtWzJU4emwSVqESE2oKKWAeDRUHRTJuseMU+Hv4wGnED4e8I0ELO1AkVj95e+px7S4AH68NadG4Q66lxaTBZ/sZRWUarGgXUx3YsGjivVHv+BBmLTevPhfxvcfQ60owHEBnuFjeOvfUaZ0V1xKReEJeEkmmGQ9opOccxfxM+g9YQ0Uvy+etcdUnyToCryLxbYHjdHnwWmwJcddy9lPftd994IxYjXV9pMU4Iym1QdK0Gyy4Ge+P0BjMwPxC0Zn5VR/PANgmfojfnhh3Uc4rNLR4FEJcF5++WUkJibCw8MD06dPx9atWwc8f/Pmzfw8dn5SUhJeffXVHp9/5513eNJb71tHh3vuqB0UM5a34dZyyDb11yZwFlW5B3lbrIuDTm+Aq9DFiETjVDkf2ZXNSnfHtZmaEd0u8rgCJ4zgHkGjOU3FNt+0WzA2mLfbc2t4wTkyOkvDP9hTDCM6cTXsozdz71f8qfc+/wFYoMMszQl8v+FruGWA8/HHH+Phhx/GE088gYMHD+K8887DJZdcgqKivrOv8/Pzcemll/Lz2Pm//vWv8dBDD2HVqlU9zvPz80N5eXmPGwuI3FF47DhYZA2vMtlQSQX/RkpHiVhBVe/jGiuoukgR9pVUmgJkUqKxQ9Ud3wodbCiSQzFh/AQ4laRFYhly9fHu5eKTYwLgY9Shoc2MTFqFNypY1XG24vEq/S54mBsA/9hTSeBK8otE0zhRPTkt/x1UNnW4X4Dz3HPPYeXKlbj77ruRlpaGF154AbGxsXjllVf6PJ+N1sTFxfHz2Pns6+666y789a9/7XEeG7GJiIjocXNXLLCrlMTQcVUxFXAbKfo68Vxagp17D6ozRNpXUmkKcLSsUeneuLTao2L044THZPh56OFUPAOBGPs0SK6YptJpNZiTJEZxttE01aj4cC8bDJDxU2/76M3MlYBGCzUIuvjnvL1Y2oevvxdTsW4T4HR2dmL//v1YsqTn0Cz7eMcOkbjW286dO884f+nSpdi3bx/MZnP3fS0tLYiPj0dMTAyWL1/OR3v6YzKZ0NTU1OPmauoMohZOazktFR8pwa1iiwavGBEQuAz7UvEYqQaFJc6zM7Az8igV/+dao5yg/s1gp6nG2KepKMBxuLZOC748VIYpUi7iOrIBrRGYejtUIzQFlZEXQiPJ8M14Q3WbcDo0wKmpqYHVakV4eHiP+9nHFRUVfX4Nu7+v8y0WC388JjU1lefhfPnll/jwww/5CMb8+fORk9P3i/szzzwDf3//7hsbQXI1rd7iZzLX0MqYkdBp6kC0Vbz4h48Vm1S6DM8AmH3j+KGm8gislEvhGB1NiGoTo4CB6RfAKXUlGudtBqziDeaCsSG8ZRWNO8zqekFzNd8cLucrqO73sid6sw01WSFGFQm56CHeXmrbjO8OiTeFbpVkzKaTeidN9b7vbOeffv+cOXNw6623YvLkyTxX55NPPsG4cePw4osv9vl4jz/+OBobG7tvxcWul6diC0jkra5RVLokw1N6MgN6yYom2Qvh0WLHdleis1c0TrbmoaC2VenuuKTG7K3QwoZCWxgmpTtZ/k2XyKmAVzBgagJKRLHC5FAfvm2DyWLD/kLatNWRPt5bDD+04ELbTnHHrLuhNtrkRaj1TICP1IGKLW/DbQKckJAQaLXaM0Zrqqqqzhil6cJyafo6n21JEBzcd+Sq0Wgwc+bMfkdwjEYjT0o+/eZqDKHiRdi33fWCNyXU5mfwttSQAEnjetUUpMhTicZU0dgxao6Kd91ZHpMR6O2kq/DY737X7uL2aSr2RpMV/WMoD8dxcqtbsK+wHlfpdkIndwLhE4CoaVAdSYJuzj388PyGL3BSRSszHfqf22Aw8OXeGzacKvfNsI/nzet7Tnru3LlnnL9+/XrMmDEDen3fSXpshOfQoUOIjBR5KO7IL0osFQ8xq7eqpDMxlx3lbZOfeF5dTuRpWzaUUqKxI3iU2PNvIufCqXXn4ZxeD0cEOJSH4zhfHBRT5D/y2i7umHKLqE+kQv6zb0eH5IkxmjLs3Pg51MLhb00fffRRvPHGG3jrrbeQlZWFRx55hC8Rv/fee7unj26//VTSFLu/sLCQfx07n33dm2++iccee6z7nN/97ndYt24d8vLyeGDDVmmxtusx3VF4vCjZHYQmtDXTsPFweTZk81a2777tcuyJxslSGXJKaG+hEdfRiAh7/k1Amn0ExFmx5eJMeQbQJnYS7xrBOVLaiIa2TiV755LYm/bVB0uRIhUhsTMb0OiBSSugWh5+qBlzDT+MznlPNblZDg9wbrjhBr7k+6mnnsKUKVOwZcsWrFmzhq+AYlj9mtNr4rCCgOzzmzZt4uc//fTT+Mc//oFrrxXr7ZmGhgb8+Mc/5svI2Yqr0tJS/rizZs2Cu/IPDEY9fPlxZSEtFR+usPY83vrGudgKqi6+ETB7hEArybCUH+nOcyMjoyVH5N/k28IxabyTB8m+EUAoK5UgAwWiSGu4nwfGhvnwvZF25tYq3UOXw3KbSurbcbPBXhQ3ZRngLYJKtYpc/CBvF8r78P3uA1AD3Wh8k/vvv5/f+sJWQ/W2cOFCHDjQ/xP0/PPP8xvpqUoXiUBLMxpKs4EJc+jpOUetTfWIkiv5cdQ4Fc55jwRJgiZqMpD3HeI6T6K8sQNRAZ5K98pl1Bz9Hj4AMo2TcJmvEU6PjeKwgn95m4D0K7tXU+VUtfA8nEsmum96gCOw0Rs9LLhWtx1ggyFTb4PaacPTUOo/HdGN+9G48x1ggYJbSdi5XvakG2v2jOFtZ5W6luo5m/KTIsG4GoEIDHHdApJaFuCwncWlAhylPJwRZSwWeRPNEU6ef9N7mootF++Vh0OJxiOL7Q/39eFyXKg5CB9rA+ATASTbl+urnM+8u3h7XstaZFcon9tHAY4LMfuJaT800FLx4WgsFAFOmUEsvXdZ3RWNC5FVrp6VD06vowlhbSKHyy/VHhg4u/j5gKQF6nKBBpFSMCsxCFqNhMLaNpQ1tCvdQ5ex6UQVGtvNuMloTy6efAOgHZXJlmHzn3Yt2jTevIjo3u9WQ2kU4LgQbbBYKu7V0vc+X2Rw5MpjvG3xd9EVVL0SjVOlYpwoE8mjZPg6C3d3178Zn+oi23x4+AHR03uM4vh66DEh2p8fUx7OyPniUCn80IoFsFfnn3QDnIbeE7VJV/HD0JMf89EoJVGA40K8I8bwNqiTyu8Ph1eDvZ5SmFiZ5rICE2HR+8AomdFenql0b1xGTaYIAI5q0xAX5AWX0TVNlX9qmmpesqhNtoMSjUdEU4cZG7OqsFS7FzrZDISmAeHjR+bBR0nkBT/h7SLbbmzNOK5oXyjAcSEhcSm8DbdVw2KmpZvnKtQkpvh8YifCpWk0kFnxMLaUufEELwlPhk8uFFVn60OmDVix3XnzcDaxdcz8cK59481debW0Em8ErDtawUc9bvTYI+6YeGr1sDNVSS/3ToVBsqJq27uK9oUCHBcSGpkAk6yHTrKhspgSjc9FR3M9QmUxXROV7KJLxE+jjzpV0fh4uettQjvqrGaENIoikYak+XApbGdxvRfQWg1UiRG/GQmB0GsllDa0o7iO8nCGa92xCoSgEVOth0/tPeWEdDPu4O2chm/Q0ancGycKcFyIhm2LoRVbYNSVUC2cc1GeK/6xVCEQISGhcHn2RON0iSUaU4AzXHL5YRjlDjTI3khOc7ESAzoDED+vRx6Ol0GHKbEB/HhnntgMmZwbNoK6JacGl2p3QQObyHkKcs598ELn3oJOr0jEz7wEHpLYpFUJFOC4mAZjNG/bKk4q3RWn1FAk3n1XGOJca3qhPxFiGi5dU4jMMgpwhqv++BbeHpBTMCFGvPC7lNOnqey6pqkoD2f4q6fY9NQK4y5xx8Tr4bQ8/GF4LBOaS//CE4+VQgGOi+nwjeOtrU5U4iVDY6kUSXEtPsnu8dSFpsIm6RAgtaK6lKY1h6vt5DbelvpNhlGnhctJXCjagm18Oo6ZY080ZiupqCL2uVt7tAIxUjUm2E4AkgYYfzWcmkb58EL5HpCRFZjAG0MzLRU/F0b7Cio5ZBzcgs4Ic5D4WY3VR2G10ZYN50yW4V9jr8AeOxsuiSWlewUD5lagZB+/a1pcIAw6DaqaTciraVW6h06J7d30w/EqLNeIBHUkLBBbZJBhoQDHxXiGiaXi/h20VPxcBLeLFVTe0U6+f9AQ6GNEovEYWz4Ka+kF6pzV5cHXUgeTrENEmj1XxdWwd+Vdozj2aSoPvRbT4wL5MU1TnRu2K3trpxVXGPaKO8aLjSvJ8FCA42ICYsRS8QhLOWSbskWWnI3Z1IYIawU/DnODFVRdNPaCfywPhyoan7u2XFF59oichCmJLvzuO/F80do33mTm2qepdlE9nHOenopCDdJlNk0sAanLR+RSuTsKcFxMeJyovusjtaO2WrxYk8EpzzvGd9dukr0QEWnf9sIddG/ZUIDMcuX3j3FWDSfEC362cTxCXWGDzbMFOCV7AXN7zwAnrxY2muYcErPVhg1ZlVimtY/esJVqPm6wgnMUUIDjYoyePqiC+GdTXZyldHecSl3BEd6W6eOg0brRn4a92B/bP6awpEzp3jgtY5koztYWofwuyg7Fli77RgHWTqB4N79rckwAPPVa1LZ2IruK9jUbij35dWhoM+NyvT3ASbvCEVfNLbnRf3H3UWuI4m1TGS0VHwpTuQgIG31cfJPN3jwDYPIRO9HbKkSQR4aotaY7f8t/3ALXfvpY+YTE88Rxvhi1YknGrOgfQ/tSDX16KhQNmAx77bI0mp4aKRTguKBWb/FiZamhpeJDoa8XK6is9lVF7kRjr2gc2ZaNhjba5mOorIWidkmOLRqTxjpncbYhSTiv3zwcCnAGj03nserFbO8pDWRR3M9f/P8mw0cBjguy+osRCF2jeEdJBiegLZ+3nlHus4Kq95YNvOAfVTQ+5wJ/GVIqxob5wOV1jeCU7gdMLfxwXnIIb3fn11G5gUE6WNzAl9dfphNL7ml6amRRgOOCDGHiHaRPW4nSXXEaVosF0RaxtD400cU32RyoojHfsoFyKIZKLhIjOLVBU6HRSO5Rb8s/DrBZgGLxs0+I8oOPUYfGdjNt+zFIbPQmAM2YJR0Td6Rd7rBL5o4owHFBfpFiJVWImRJGB6uyKBtGycw3K42MF0vt3Yp9JdUYqRQnSmhPoSGxmBDQKPK3tPFz4DZ65eHotBrMSgzixzRNdXas6jPLv7lYux9atvcUS/YPdpMK6qOEAhwXFB6fKlrUoaWF3o0PRlW+2GSzVBsNrU4Ht+MXjU5DAPSSFe2lYj8uMkgVR6GXO1En+yB+rBuN/vWRhzOvKw8nr1apXjkNNlJaVNeGS7uWh9PqqRFHAY4L8gkMRwvEBmflhbSr+GC0l2Xytt7bzVZQdZEk2MLEcnGf+ixem4MMTkeBmKI5aBuLKfaKvm41glN2COgQG7XOsW+8yZY+W+h3aEBrj1XAB21YoLG/oUin5eEjjQIcVyRJqNJF8sPG0myle+MUtLViBZU5UEzvuSNj7BTepiAfudUicZScXfNJsX9QrjHNtQv89cZW+wQmArIVKBLPQXqkH/w99WgxWXCklIpGDmTd0QqcpzkCPcyitlCoGHknI4cCHBfV5CmWGnZU01LxwfBrESuoDJFpcFdSjy0bxDtycnaGCrHBZkf4NPd7urrzcMQqMpZgPSfJnodD01T9yqtuwYnKZlystW/OmnKpqC9ERhQFOC7K7BvHW6lOvHCT/rE9uyLNYvf14HgxTeOW7Cup0qQiZJXRu+9BaaniG9vaZAn+Y2bB7ST0sS+VfZqKEo0Hnp7SwIbFepH7h3HLHHqZ3BUFOC5KY8/G92oVL9ykf5XlxfCXWmGVJUQmuVGSaG8hY2HVGODL9jErptytwZDZfkyswJ8cjfTEWLidBHvV5vLDQHs9P5xrr4ezr6AenRbK5epvemqqlAM/WyNg9Afi3Gj13SiiAMdF+USO4W2AiZaKn01lXgZvy7URMHiI5Gy3pNXDFCTyALRVR/kyVjKwllyRYHxIHosJUf7u93T5RQLB7H+NDBTu4HeNC/dBsLcB7WYrMkoalO6h6pQ2tCOjpBEXaQ+KO8Yu5n97ZORRgOOigmPEdgNRtkp0mi1Kd0fVWkvECqpajwS4O0OMqGgc25mL6maT0t1RPVOB2GyywncCPA1auKWEnvVwJEnCHNq2oV/rj1XwdrmHeGOFcZc4/hq5KQpwXFRwdDLMspYXr6sopS0bBlQjVpqZAqjIls6+ZcN4qYC2bDgbmxV+tfYcihgX30F8MInGfeTh7MilopG9seJ+MVIV4iyFgKQFxlw0etfKzVCA46IkrR7V2jB+XFt8XOnuqJpPcy5vdWG0TBM9VlJRkcgBVWXBYGtHs+yJqLEiMHTrEZzKo0BrbY+NNw8UNaDDbFWyd6pS02LC3oI6LNbYV0+x3BsvseqMjDwKcFxYvTGKt22VJ5XuiqpFdIpEbL84N15B1SU8HTIkREj1KC4uVLo3qmYt3sPbDFsSpsSJF3S35BN2qoZL4TbeJIV4I9zPyJOM9xeK5GMCbMyshE0GrvQ6Ip4OWj3lUBTguLAOH7FU3FZLS8X7U19XgzDU8ePIZDd+F97F6It233h+aGMrY0i/mnJEcbtMTQqSQ91gB/Eh5uHMt6+m2n6Spql6Vy+eZLEHOCmUf+NIFOC4MlZllCWONtFS8f5U5IpEv2oEwtufhooZjX3jzYCm4zS9MABN6T7eNoVMdo8dxIeYhzNvjD3AyaV9qRi2yzoL9lj1Yq1sAYKSeWkG4jgU4Lgwj3CRNOvXXqJ0V1SrqfgYb6uMYtSCAMYYsWVDmlSI7ErKw+lTewP8W0WVcI/E2fRrE2+vh1N9nBc/ZOaPEdN2R0oa+Iu7u/vheBXMVhlXe9tHRmn0xuEowHFhgdFiqXi4tRw2NvFLzmCtEgXtWv1oBVUXyT6Cw1ZS0ZYN/Sjdz5sCWzhSkpLoL8s7GAif0GMUJ9Lfk+fisH89u2nbBr56ilUvXiDb69+MW0q/Nw5GAY4LC4tL4W2Q1Izqmmqlu6NKno1iBRVCxHNFWNa1CHCSpHKcLBHvxklPpkKRYHxQHoPJsW5Y4G8QeTjMPPsozg43n6Zq77RiU3YVpkgn4WVpsFcvnqt0t1zeqAQ4L7/8MhITE+Hh4YHp06dj69ZTfwB92bx5Mz+PnZ+UlIRXX331jHNWrVqF9PR0GI1G3q5evdqBP4Fz0nn5ow7in29lIS0V70toh6gR5B2dPqrXRtV8w9FhDIZGktFaYk+GJD205YoE43xjOsJ8PejZ6ScPhxKNhc3Z1egw205NT1H1YtcIcD7++GM8/PDDeOKJJ3Dw4EGcd955uOSSS1BU1Hfia35+Pi699FJ+Hjv/17/+NR566CEe0HTZuXMnbrjhBtx2223IyMjg7YoVK7B7t6gqSk6pNUTztqVcFLMjp3S0tyLSJqqKRtAKqh4soWK6waOWtmw4gyzDs0pMM5gjp9OfVJf4eWyCE6g9CTSV87vmJAXzTbJzqlpQ1dThts/VOnv14qW6Q+IOql7sGgHOc889h5UrV+Luu+9GWloaXnjhBcTGxuKVV17p83w2WhMXF8fPY+ezr7vrrrvw17/+tfsc9rmLL74Yjz/+OFJTU3l70UUX8ftJT63eYgNAc7V9KoZ0K8s9Cq0kowleCAqPoWfmNJ5xU3mbbMlHSX07PTenq82Fh6UJHbIeIcnT6Lnp/qUJBOz5W8jfwptAbwPSI/3cepqK1QLamFXJqxeHdeRR9WJXCXA6Ozuxf/9+LFmypMf97OMdO8TGbL2x0Zne5y9duhT79u2D2Wwe8Jz+HtNkMqGpqanHzV3YAsT+SrpGKtrWW33RUd6W6+IgaSgd7XTaqNMrGrvP38tgyCUi/+aInIiJ8aFKd0ddEs8XbYEIcJj59uXi7rptw868WjR3WHClp326l6oXjxqH/levqamB1WpFeHh4j/vZxxUVYsiuN3Z/X+dbLBb+eAOd099jPvPMM/D39+++sREkd2EIFauDfNqKle6K6nRWiLykRh9aBdNfonGqVISsMqpEe7q2PJF/kyGPxcRoSjDuIXFRjxEcZp5924btJ2vdcod6tnqKucrLnn9D1YtHzai8bWVVLU/Hfsl733e283vfP5THZFNYjY2N3bfiYvd5sfeLFquDQi1lbvnPZSCG+hzeWoOp2NYZgpJg1nrCU+pEbaHYbZ0I1sK9vK30m+i+O4j3h41OaHRAQxFQLxL4ZyUGQa+VUNrQjqK6NrgTq03GhkxRvTi5zZ5/Q/VvXCPACQkJgVarPWNkpaqq6owRmC4RERF9nq/T6RAcHDzgOf09Jltp5efn1+PmLsLixR4xEXItGppalO6OqgS2iS0sPCNpBdUZNFp0BKWJQ7aJIhE6W+HTKGonaeNm0bPSm9EHiJ7RYxTHy6DD1NjA7lEcd7KvoA41LZ1Y6pEJjc3M3zggeIzS3XIbDg1wDAYDX+69YcOGHvezj+fNYxn3Z5o7d+4Z569fvx4zZsyAXq8f8Jz+HtOdefiHoxUefMlvOS0V72azWBBlKeXHwYkTlbtAKmaIEXtzRbTnUCXaLmUHebG2cjkIScmikCbpJw/n9Gkqez2c7W6Wh8P2nmJu8M88tXpqgNkL4mRTVI8++ijeeOMNvPXWW8jKysIjjzzCl4jfe++93dNHt99+e/f57P7CwkL+dex89nVvvvkmHnvsse5zfvazn/GA5s9//jOOHz/O240bN/Ll6KQXSUK1Tuwq3lQmpmQIUFGcAw/JDJOsR2QcvVANtGVDOlU07mYtshf4s43BlNgA+lM6W4BjnxbvSjTemVvrNlXVWUrAOnv14int9hImKcuU7pZbcXiAw+rVsOXbTz31FKZMmYItW7ZgzZo1iI8Xe/+Ul5f3qInDCgKyz2/atImf//TTT+Mf//gHrr322u5z2EjNRx99hLfffhuTJk3CO++8w+vtzJ5Ne8L0pdlLLIHuqKKl4l1q8kXCX4k2Gjr7yCDpJWJi90qqzNJGenp4gvEu/jxkasbRDuL9iZkJ6DyAlkqgWkznTY4JgJdBi7rWThyvcI/9zY6UNqKssQOz9XkwdNZT9WIF6Ebjm9x///381hcWnPS2cOFCHDhwYMDHvO666/iNnJ3ZPxFo2gJNg8g5IUB7WRZ/Guq9xI7rpA9h6bBBixCpCSXF7HfHzVebyTJ05WIPqtbQqdC6+w7i/dF7iGTjvE1iFCcsFQadhicbbzpRzZeLp0f5uc3qqTtDsgC2EJGqF486Kv7hBnQh4oXJu6Xv6tHuSFMrKjt3BlLCX7/0nmj1E7871rKM0bo06tVYDE9TDcyyFr5J9kRacpZpqs3ddy2wT1Ntyalxi+mprgBnrnWfuJOWh486CnDcgE+EWAYd3CmSagng15LHnwZ9hFhlRvqmiRTTVP6NWbwiq1srEcvDM+V4TIiPULo36pa4ULQF2wCblR+eP04URWQ7i3eYxX2uKruyBXk1rUjU1sCvKcdevXix0t1yOxTguIEQ+1LxSLkKre0mpbujPFlGpFmMZgXE0QqqgXjZt2xIQQFOVrl3mQFz1w7ilGB8dpFTAIMv0NEAVIgKvmPDfBDh5wGTxYbd+XVwZd8eFXtx3R0ucpCoerEyKMBxA35hCTBDC6NkQWmxGLlwZ/VVJfBDK6yyhOjk8Up3R9Uk+95C46VCZLr5lg0d+WIlTIFHGsL8aAfxAWl1QML8HsvFWSHWhfZRnC3Z1XBl3x4R01OLNWJTVpqeUgYFOO5Ao0WVVgypN5SI7QncWWWeWEFVrgmHl5eP0t1Rt3AxwpWgqcTJYvGu1C1ZTPCqFQUPbV2F7MiQ6+EsTBEBzmYXDnByq1tworIZ/poOhNWJaU0KcJRBAY6baPQQS8XbK0/C3TWXHONttVFsREoG4B2MNg9RIby92F5q3h1VHIVWNqNO9kFMElW+HlKAU7gDsIqNkucnh4AtPmPTnWzrBlfUlVy8MqoAUlf14hDaDkYJFOC4CZNvHG/lOloq3lWbo81fbERKBmYJE6M4HrXH3Hc/M3uC8UHbWEyJC1K6N84hbDzgFQyYW4FSUfbD30uPqXGBLj1NteaIGOm83Gh/Q0DVixVDAY6b0ASL5b6etFQcXk2i4KEmTGxESgbmbU80TrLku+y77rNpzxcF/jLkMZgQ7fo1XEaERgMknHfGcvHzx9qnqU64XoBTVNuGY2VN0Ek2xNftEHdS9WLFUIDjJrwiRL2XgA5aKh5mKuTPhW8MJRgPhjZKJBqnawqQWeaeicayfQSnOmAy3zySDD8PZ/vJGpitNpdcPXVLdBU07TVUvVhhFOC4iaBYsVQ8ylYOk9kCd9XRXI9QWSxRjRwjNpMkZ2FfSTVOKsHxUtde3tunlip4tZbAJkswxlOC8TnVwyneDZjF6N/EaH8EeunRbLLgUHEDXMm39vyb631FQjpVL1YWBThuIih6LP8H7Su1o6zcfUdxynPFCqoqBCIoSFRWJWcREI9OrQ8vM1BfKGqauJUSUYk2R45GeoJI1ieDFJwM+EYB1k4R5LARQY2EBS44TcWmb1nAxjYLT23aLu5MuVTpbrk1CnDchKT3RK0mmB/XFbnvUvGGIvHOqsIQx+tykEGQJHQEi5VD2mr7O1M3YisW01OHWIG/ONpBfEjY31hf01Rd9XByql1u9dRl0Sboak/YqxdfpHS33BoFOG6k3hjN25aKHLgrS6UI7pp93HzjyCEyxk7hbWRbDhrbxZJfd9FuL/CXqaUdxM9Jkn2aKveH7rvOHytGTw+XNKKmxTWqq6+159/cGpQp7oifB3iKFWNEGRTguJF2H7FU3FbrvkvFPRpEHSA5ZJzSXXEqxhgR4KRLhTjuThWNbVYYKkU12o7wabSD+LlIWiTasoNAm8jhYpWg0yP9XGaaqryxHfsK2ZbhwNT2neJO2lxTcRTguBGZFZwCYGgSq4jcUVC7CO68oqhY25BETDxtJVUj3Eb1ceitbWiRPRCSKJKtyRD5RQFh7O9NBvI2dd+9OC2MtxuzKp3+Kf06o5xtcYeFcQYYS0VJAaRconS33B4FOG7EI1wUtvNvL4Y7sna2I8Iq5snDkujFakhCU2GVdPCX2lBemA23YV8enmFLxuQ4kcNGzkHyhaLN/b77rsXp4d0F/0wW595d/MuMMt6ujMgFbBaAjRCzBGuiKApw3EhAtJiWCbeWw2pzv4q0VQVZ0EoymmQvREbTNg1DojOg1V+Um7eWi5VobrWDuEwJxsOSfMGpPBx7NewJUf4I8zWitdOKXXnOW34gv6YVR0ob+fTlbLP4faHpKXWgAMeNhMaJWjihUiMqqmvgbmoLxBLnEl0stFr61R8qrb0eTkDjcXRaXKtA29kCnGLPdIT50g7i5yxuHqA1Ak0lQI0YAdRoJFyUJkZxvnPiaaqv7KM35yUHwpj/nbiTloerAv2XdyNar0A0wpcfVxeJ/ZjcSUe5WN3Q6J2odFecklecSDRORQHfMdnldTTCs1EkpUsxVOBvWAxeYlVRr2mqi9PteTiZlU65zxnrc9f01B0x5UBHA+AZBMTOUrprhAIc91NjEEvFm8rcKI/CTlcnlsebA2ln33MhRYrKz2maQvfYsqH0ACTIKLKFIjmRygo4Ig9nXnIIPPValDV2INMJV+dllTfzndENOg3mWUW+FsYuATRapbtGKMBxP23esby11IgNJ92Jf6tYQWWITFO6K84pYgJvYqQa5BYVu83+UwdltoM4FfgbsQCnYBtgEbVvPPRaLLDXxPkuqwrO5qvDYvTmgpRQGE+uE3fS5pqqQVNUbsYaIJJrdY1utlTcZkWkRbwoB8WLF2oyRB7+aPESWxW0Fx1y+afPVCAK/GXIY3lCLBmm8PGATzhgbgOKdp2aprLn4WzIrHS66amu/JubkkxAXS6g0QPJVL1YLSjAcTOGULF00afN9d+Bn66+7CQ8YIZJ1iM2kUZwzpUcLurheNYeg82VV+LJMjSlYg+q+qBJ8DTQlMOIbNvQPU1lT8YFcGFaGDQS+Eqkkvo2OAtW2K+kvh3eBi3md01PJSwAPEQBQ6I8CnDcjF+UWCoeai5zyqS+c1WVL1ZQFWmi4elhULo7Tssrbipvk+V85NW0wmXV5cHQ2QCTrINvvPiZiWPycEJ8jJiVGMSPvz0i6lQ5g8/2lfD20omR0OesEXfS6ilVoQDHzYTGp/A2CtWoaXSDlTB2bSXHeFvrSfVvhkMbJZaKj5cKcbS00eV3ED8mJ2BivFjpQ0ZAkr0eTsURoOVUzs1lEyN5+/URsZ+T2rV3WvGNva83pRmAYnv9m9TLlO0Y6YECHDdjDIhGBwy84F1lkfuspJJqxLL4Dv8xSnfFuUWIAGeMVIrMYudLCh0sq/0F66BtLKZSgvHI8Qnt/h3CyVPTVEsnRPBpqoziBqeYplp3rAItJgtigzwxpW2H2IYiejrgL1apEnWgAMfdSBKqdFH8sNGNlor7NOfxVhsuih2Sc+QXBZM+ADrJhsYiMe3nikwFIsDJ0qUgKcRH6e64FraMmsmxrzpiW6f4ejjVNNVn+8X01LXTYqA58bW4M3W5sp0iZ6AAxw0121fCdFS6yVJxWUZEp1g15h87XuneODdJgiVMrEIzVrtoorG5HR61oiikOWI6r7hLRlDXLttsBMdqdrppqrKGdmzPFZXgrxvvC+RvEZ9Iu0LZjpEzUIDjhqz+Ig9FaiiAO2ivK4UP2mCVJUQn0xLx4fK0VzROtuaioNYFE43LM6CRLaiSAxCbIJLyyQiKngZ4hQCmJqBoZ49pKskJpqlWHyzl22nNTgxCTNUWsblmaCoQQtPfakMBjhvSdS0Vb3GPAKcyL4O3JVIEgvzFVhXk3GnsFY3TNYV8aa/LsRf4O2RLxpS4QKV743pYld+uaarsntNULGhg1qh0FIeNWH66T5TYuHZ6DHD8K/GJtMuV7RjpEwU4bsg/WuShhHSydyIuOMXQS1OxWEFVaUyAxN4ikuGJELVw0qQiHC2pd7ln01wgRhX228ZRBWNHGXdmgMNcNknkB/73kCigpzY7cmtRUNsGX6MOl6X6AzkbxSco/0aVKMBxQyEJIg8lBpWobnLBKYZebFXHedvqS/sJjYjgsbBojPCROlBdJJ5blyHLkO1Vdou9J/AaLcRB9XA0OqA2B6g9lQu4nNWU0Uo4VtaE4xXq25vq/d0il+/qadHwLt4CWNoB/zjAPqpJ1IUCHDdkDIyFCQYYJCvKC8QGlK7Mq1H8A5VCRQ0gMkxaHczBYhRQV3nEtRKN6/Nh6KhFp6yFZwLtIO4wHv6ndhc/bRQn0NuAC1NF3aFV9pVKalHZ1IH19u0kbp4dB2R1TU8tF1WaiepQgOOONBpU6e1LxUtc7B14H0I6RK6Rd0y60l1xGYa4abwdYz2Jwjr1JoQOWZHYf+qonIjJiRFK98Y9VlNlr+1xN1t6zaw+WAaL1Qa1+GRvMaw2GTPiA5Ea4gFkfys+QdNT7hng1NfX47bbboO/vz+/seOGhoYBv4blhDz55JOIioqCp6cnFi1ahGPHRA5FF3Yfy6U4/XbjjTc68kdxOc1ecbw1Vbl2LRxrax2CZPE7F5FEw8gjRRsjRjemaHJdKtHYViwCnH22FEyjBOPRCXAKtwMdp6ajFqWEIcjbgJoWE7bmiOXYSmOBzYd7ivjxrXPigbwfgI5GsXlo3Bylu0eUCHBuvvlmHDp0CGvXruU3dsyCnIE8++yzeO655/DSSy9h7969iIiIwMUXX4zm5uYe591zzz0oLy/vvr322muO/FFcjjVQ5KPo6kUBPFdVZV9BVSYHIyo8VOnuuA5WtRXARCkPx0rq4Co681lVWuCIJhWpEbTizqGCk4GgZLHM+rS9qQw6Da6YLEaYPzugjmmqH45XoayxA4FeeiybEAEcXSU+kX6VWBVG3CvAycrK4kHNG2+8gblz5/Lb66+/jq+//honToiy+X2N3rzwwgt44okncM0112DChAl499130dbWhg8++KDHuV5eXjz46bqxESIyePowUd/Dt028K3FV9YVHeVuuj4OWCraNnJBxMGu94C2ZUFcgnmOn194AY50Y0bREz4ROSzP4DpdyiWiPf9Pj7uvYEmwAG45VorbFBKW9vSOft9fPiIUHzMBx++aaE65VtmNkQA77C965cycPOmbPnt1935w5c/h9O3aId0m95efno6KiAkuWLDmVEGs0YuHChWd8zfvvv4+QkBCMHz8ejz322BkjPKczmUxoamrqcXN3ATEiSTTcXOJaSaK9dFZk8baZVlCNLI0WnWFiys+j+qBrlBso2QcJMgps4RibSCvuRkVX/RiWh2M5FchMiPbHpBh/dFpt+MS+a7dS2Kay20/W8jdId8xLAE5uADqbAb8YIGamon0jCgU4LFAJCztzF152H/tcf1/DhIeH97iffXz619xyyy348MMPsWnTJvzmN7/BqlWr+IhPf5555pnuPCB2i42NhbsLiU/v3lW8vM51cih6M9aLVWJyCK2gGmkeCeKfe6olh9cGcXrFYnn4fnkspsVTgb9RETML8IkQVY3zNvf4FM91AfCfXYU8B0Ypb2wV0/jLJ0UiOsATOPq5+MR4Nj1Fo3xqNuSrwxKAeyf49r7t27ePn9tXUTX2Tu9sxdZ6f77317D8m8WLF/MpLJZc/Nlnn2Hjxo04cOBAn4/3+OOPo7GxsftWXCwqUboznV8E2uAhdhUvdN2VVEHtYgWVVxTtQTXStLEi0XiyJpeX13d2nQX2AMeWgqmUYDw6WIDAllkzWf/t8SmWh+PvqUdpQzs2nahSbN+prw6Lqsr3nJcEdLaeWvVF01OuF+A88MADPL9moBsLPFheTGWlqBlwuurq6jNGaLqwr2F6j/BUVVX1+zXMtGnToNfrkZPTd00XNs3l5+fX4+b22K7iBjGS1VjqmgGOraMF4TbxjzEseZLS3XHZRONUVtG48My/daditUBTup8f1gRO5i+sZJR0bVLJ8lqslu67PfRarJghcnHe2yUK7I22t7fn89GjuUnBfNqMBzfmNiAwAYiaqkifiAMDHJb3kpqaOuDNw8ODJxWz0ZI9e/Z0f+3u3bv5ffPm2Qs89ZKYmMiDnA0bNnTf19nZic2bN/f7NQxbRm42mxEZKXajJYPT6i2GgC1VJ13yKasqOMLbOtkXsdHiHyUZQX7R6DCGQCfZ0FwgggOnVXkEOmsbmmQvhCRSOYFRFT8f8Axiu+IChdv6nKbanF2NvOqWUe0WS25+f7dYhPHj8+05Wd3TU9dQcT8n4LAJxLS0NCxbtoxPJ+3atYvf2PHy5cuRknIqH4IFRKtXr+bHbBrq4Ycfxh//+Ed+39GjR3HnnXfyFVNsyTmTm5uLp556ik+DFRQUYM2aNbj++usxdepUzJ8/31E/jkuyBYk/Wn2Day4V71rdU6KLoxUxjiBJsEWJURy/2sMwWaxwWsXijdgB21hMjQ9WujfuRasDUi8Tx5lf9vhUfLA3FqeF8d27/7VldP9Pse/X1mnlyc6LUkKB9nogZ734JE1POQWHZkixlU4TJ07kq6LYbdKkSXjvvfd6nMOWjLNRnS6/+MUveJBz//33Y8aMGSgtLcX69evh6ytqUhgMBnz33XdYunQpD5Qeeugh/tgsB0erpXoEQ+ERLpaK+7e75lJxU3kmb5t8aEWMo3gmzuLtBJxEZpnzrk60FnZtsDkW0ynBePSlXyna41+zLbt7fOq+Rcm8XXWgBBWNHaPSnepmE97dKfL3Hlk8TuSAstEbaycQPhGImDAq/SDDo4MDBQUF4T//+c+A5/ReXsp+kVgiM7v1ha2AYlNWZPgCYtN4G2kp5SXRXa3uh65O5GRZg0QgR0aeZM/DmSzl4ofiBqdNzrUW7gZ7e5RtHI/EEG+lu+N+EhcCRn+gpRIo2gEkLOj+1PT4IMxKCMKegjq+oul/lzt+y5VXN+eiw2zDlNgAMXrDZHwk2slUNd9ZuNYrGhmS4DjxjyJCqkNpVa3LPXuBbaI4l2e0COSIA9gTLRM0lTiRr0wi6LA1FMPQWgaLrIEuduZZV3kSB9AZgHR7TZzDn5zx6fsuEKM4LCeGja44Elu1xZamM49cbB+9qTkJlOwBJC0w8XqHfn8ycijAcWMa7yA0SWLqr7JQTOe4CtliQoSljB+HJtIKKofxDECbn5gCtBQ7aaJxoSgielROwIREsUUAUcCkG0R77AvA3HMqatG4UEyODUC72YoXv+97texI+dO3x2Gy2DArMQjnjw0Rdx62j96MuQjw7X9FL1EXCnDcXI19qXhLad/bZzir6sIsvrqnRfZEdNwYpbvj0nT2ejjRLcdUUVZ/qOQCsXJnty2N8m+UFL+Ar8yDqfFUMq8dG0X51TJRff2D3UUorG11SBf2F9bhq4wylj+P/1ueLkZvWE5Q9/TUTQ75vsQxKMBxc22+YhmmlQ3BupDq/MO8LdHGwKCn5HNHMsSLROPpmmxklDhfwT9zvghwDkjpfMUMUbDoX9fqpMMfn/HpucnBWDguFBabjGfXjvwbMpaH+Nsvj/HjG2bEiro3DFu63lgscoRSLh3x70schwIcd8d282XFEBtFvoqraC8TU24N3olKd8X1xYr95qZoTiKj0MlyuZorYGjIg02W0Bk1ixeXIyqYpmIjOGxZdi+/uiQVbM/cb46Uj3h1439tzcPR0iZe5PHnS07b2mX/O6KdcA2g9xjR70kciwIcN+cZKf6QAzpca6m4rlbsCm0OHKt0V1xf+Hi+s7if1I7qvAw4Y/7NcTkOE5LFaCZREFt+HTZeLMfO7Ll1A5MW6Ye75os3Lb/571G0d45M7aWTVc14YaPI7WFTU6G+RvGJlupTtXlm/GhEvhcZPRTguLkg+1LxKGsZOsxOXKitl8DWXN4aaA8qx9NoYYqYxg+9Kvc51+709gBnty0VsxOpwJ8qTFoh2oN9lxhhK5ui/D1QXNeOP68d/jYz7P/eQx8eQqfFxpeEXzMt+tQnD70P2MxiW5JIqnDtbCjAcXMBMWIEJ0RqQnFZ37u8OxvZ0okoi9hQNZjK7o8Kz2RRRTzdehz5DkoAdYTOvK283SenYVp8gNLdIV2JvBodULIXqBQ5MafzNurwh6sn8uN3dhRg7dHh/d/6v/8eRWZ5E4K8DfjTNZNOlQlgycX73xbH02n0xhlRgOPmJA8/1GlEcbaqgjP/mTijuuLj0MOKVtmImMTT5tKJw2jj5/B2hnQC+wvPzJ1QpbY6GGrFCEBzxGx4GRxa95QMFluG3ZXMu88eYPRyQWoY7jlPTFX9z2cZyK85t6D63R0F+GRfCc/refGmqYjwPy3HJn8TUF8AGP1E/g1xOhTgENR7iNyD1rIsl3g2qvMO8bZIGwcPA+0KPSqiZ8AGDeI01TiRI/KfnGV6KscWjbQxlIyuKl35Lmw1VWffwcsvlqViWlwAmjssuP2t3ahqGto2Dv89VIonvxJv6h5bmoL5Y+w1b7rsef1U4rOBqls7IwpwCDr8xUoq1DjJC9NZdJSKTTbrvOw/F3E8Dz+0BogtMSyFu50w/yZI6d6Q0yUuAgITAFPTqR28e9FrNXjtthmID/bi+TgrXts5qPo4bHugf+8swMMfH+KbeN4xNx73Lez1v4KVzTjxrTie/RO6Nk6KAhwCbbiYxvFudo1dxXW1okZGZzBNT40mQ8Jc3sa2HHZ4Of2RYLbn3+yRWYE/CnBUVxNn+p3ieN9bLCrp8zS22um9u2YjOsATBbVtuPKf2/HN4fIz9jjsUtfayQOb//vvMf6Qt86Jw28vH3/m9hy7XmahEDBuGRBCKzGdFQU4BH6x4/mzEG4qcq4VMP0IaBErqIy0gmpUGZPm8XaGJptXhFW19gboqsRIX0PoDF77hKjMlFsBrREoOwAU9z8qGBfshdX3z+NFGhvazPjpBwdw7Ss78Mm+Yr78m+0ttSuvFr//OhPnP/sD/nuoDFqNhF8uS8XTV06AhiXgnK6tDjj0gTie+1MH/5DEkSirjiA0YQJ/FuJQjoqGFkQFif2pnJFs7kCEtZQfByVOUbo77iVWVDQeLxVgTW45lk2IhGoVbIMEG3JtkUhOpt3mVcknVOzcfeBdYPs/gDiRyN6XMD8PfHbvPLz0fQ5e3ZKHA0UN/NaX9Eg/PH3VhP635dj7JmBpByImAQnnjdRPQxRAIzgE+sA4tMMIg2RFaf7w60ooqaEkEzrY0CR7IT6ecnBGVUA8OjxCoZesaM5TeR5O3ibebLdNwPzkXsmlRD3mPiDaE2uAmoE32TToNHh0SQq2/eIC/OyisXxzTl+jDjqNxKewLp8chddvn4GvH1zQf3DT0QTs+qc4nvcQ2wRrpH8iMopoBIfw+e5qQyziOk+isfgYMH2m0z4rVScPgf3rKtDGY5KRfr1HlSRBjpsHZP8X4bV70Wq6h9csUSPzyR/AJqV2yhPxbBLl36hW6Dhg3CVA9rfAzpeAy/9+1i9hozmsGCC7Ddmef4ktIoLH0NJwF0AjOIRr8U3irbXyhEusoKr3ptEbJXiOW8Tb2VIWDvYzRaC4pjLo60/CKktoiZwNXw/Kv1G1+Q+JluXFNIgCng7BRm92vCiOF/6SV+gmzo0CHMLJ9pUCxsaTLrGCyhpCK6gUYc9ZmKbJwf68cqhS3mbeHJETMWUc1b9Rvbi5QPwCsT/Vlmcd9312vwp0NAAh407tak6cGgU4hPOOSudtUHuhUz8jQfY9qDxjRCl3MsqCx6DdGAKjZEZTjqgzozYyq1ALYAfLv+ld3I2oD8uDueg34vjg+0Ct+BsfUU3lwLYXxDGN3rgMCnAIF5IoAoI4Wwma2jud8lmxmVoRbhX70kQk0woqRUgSzLFiX6rAqj18A0NVkWVYcn7gh3ulSZgaR/tPOQW2gmrsEkC2At8/PfKPzx7T3MorcmM8bcvgKijAIZxPZApskBAgtaKo2DlHcSrzDkMjyaiV/RAbK7afIKPPJ+UC3s7AMRwqVlkeTk0O9G2VMMl6aOLnwKijPAuncSEbxZGAY6u7V8GNiNL9Ytdw5pI/iyKDxCXQlSSC3gPV2gh+WJsvEnWdTa19D6oSfTx0WvrVVoom6XzeTpVOYle2qEmkGvYXxr22cZg9Lkrp3pChiJwEzLxbHK/5H8AyAiPN7DH+++CpPadiZtA1cSH0KkC6NXgn8Lajwjk33ewsFxvnNfmOUbor7i0oCW3GMJ6HU3d8G9TElvtDd/7NPKp/43wu/F/AO1Tsm7fdnjMzHFv/BlQdA7yCgSV/GIkeEhWhAId0MweKlVTaOudcSWWsE5uFyqFpSnfFvbF6OPEiDye4Zg9aTRaogsUE2b6C6qBhGq9oS5yMZwCw9BlxvOlPQPGec3+swp3A1r+K40v/IionE5dCAQ7pZogQS6v9Wpxz082QdtFvn1haQaU0L3sezhzpKPYUqGRfqqKd0FpaUSUHIGzszDP3ICLOYeJ1wITrRMLxqpVAa+3QH6O5Evj0DsBmASZeT4nFLooCHNItKE7sSRVlKYbZqrLVL2dhaqlHuFzNjyPHTlW6O25PSr6gOw9n//ECdTwfORt4s8k6GYvSwpXuDRnOsvHlz/GtQdBQBHx0E2BuH/zXdzQCH1wPtFQCbLSXVUemLRlcEgU4pFtQvAhwYqQaFFWcw7siBZVn7xMtghERLpKliYIC4tDskwidZENHtsh7UZrlxDrebpKnYOG4MKW7Q4bDwx+4+RPRsp3GP74N6Gw9+9exncLfXwGUZwBeIcCN7wMGb7oWLooCHHLql8EnBI2SX/eSa2fSmC9WUJUakiHRuzFV0I5bzNukxl2oa1W4tlJ9AXR1ObDIGjRGzkeQt0HZ/pDhC0sFbvwA0HkCJzcA7ywfuAhg+WHgzSVA8S7A6AfcugoIpi1dXBkFOKSHak+xJ1VL8RGnembkStHflgDaokEtvNKW8vZ87WFsyxHTh0pPT+2Xx2F2mvgdJy4gYQFwx5eARwBQdgB4dQGw/jdAdTYv6gibTYzWfP0o8PoFQG0O4BcD3LUWiKJioK5OnVv9EsWY2EqqtkNAtXMtFfdtEHtQaSIpwVg14ufDIhkQgxr85/A+XDElWrGuWLPXg5X0+8E6BctTaXrKpcTOAu7dCnxxP1CwFdjxD3HTGkUiMksk7pJ+JXDpXwEf+h1wBzSCQ3rQRY7nrV+zEy0Vt1kR1ZnPD/0TKMFYNQxeaImYxQ91+d/DapOV6UdnG5C/hR9meM6k5eGuKCAOuOMrkZeTfKEIbqwmEdzovYHU5cAdXwMr/k3BjRuhERzSQ3DiFGAfEGMu4PsIGXTqj4FbKrLhAxPaZQMSxk5SujvkNL7jlwLl2zDDchAZJQ2YFhc4+s9P7nfQWjtQbAtFzLgZtDzcVbHcu3FLxc1iEqukJA3gEwFo6aXOHan/1YuMquDEyd0rqQrLxMaValeZs5+3eZo4+Pt4KN0dchrtuIt5O0eTia3HlNnjTM76irfrbDOwZEIkXR93oDOKUR3/GApu3BgFOKQHySsIdZogflyRK1YmqV1rUQZva7xoiwbVCU1Fi1cMPCQzmo6tH/3vbzXDevxbfrhZMwfnjQ0Z/T4QQlwvwKmvr8dtt90Gf39/fmPHDQ0D7y78+eefY+nSpQgJCeHLfQ8dOvNF1mQy4cEHH+TneHt744orrkBJSYkDfxL3Uusllk62lTjHpps6tpcM22oiVOQPERWRJGjTLuOHaY1bUdnUMbrfv2AbdJ1NqJb9EJAyHx562j2cEHfh0ADn5ptv5gHK2rVr+Y0dsyBnIK2trZg/fz7+9Kc/9XvOww8/jNWrV+Ojjz7Ctm3b0NLSguXLl8NqtTrgp3A/piCx1FpbfRzOILg1h7decWJ6jaiL58QreXuR5gA2ZZYpMj21wTodyybGjOr3JoQoy2GZV1lZWTyo2bVrF2bPns3ve/311zF37lycOHECKSl91yvpCoAKCvou797Y2Ig333wT7733HhYvFoXE/vOf/yA2NhYbN27koz9keDyiJgBFQECL+ldSWVrrEW6r4sdRY6cr3R3Sl9jZaNcFINDSgIKDG4E5Px6d58lmgyXzK+jZ8nBpFl5Ioc0UCXEnDhvB2blzJ5+W6gpumDlz5vD7duzYcc6Pu3//fpjNZixZsqT7vqioKEyYMKHfx2VTWk1NTT1upH/BSaIAVpy1EO2d6h4Vq7AnGJfJIYiLVq7OChmAVgfzGPHGI6LsOzS2m0fn6SrcDn1bFRplL+jHLIK3kVbSEOJOHBbgVFRUICzszGJK7D72ueE8rsFgQGBgz+Wm4eHh/T7uM888050HxG5stIf0L8C+J1WY1ICC4mJVP1V1eQd4W2ZMouW/KuY35SreXqTZh43HRmd1nnz4E96usc7G4olxo/I9CSFOHOA8+eSTPPl3oNu+fWLjw772BJJl2SF7BQ30uI8//jif2uq6Fav8RVtpktEXVVqx23KVyldS2crtWzQEpindFTKQ5AvQqfHk5QdO7Pve8c+VxQTrsS/44bfSAiwZTxuwEuJuhjxm+8ADD+DGG28c8JyEhAQcPnwYlZWVZ3yuurqaj7acq4iICHR2dvIVWqeP4lRVVWHevHl9fo3RaOQ3Mnj13mMQ1lSJjlIWQIh332rk2yi2aNBF0RYNqqb3RMeYS2DI/hyxpd+gqeNm+Hmw7BgHyVnPV0+Vy0EISr8APjQ9RYjbGfIIDluanZqaOuDNw8ODJxOz0ZI9e/Z0f+3u3bv5ff0FIoMxffp06PV6bNggNs9jysvLcfTo0WE9LunJHJzKW32tCCDUSLaaEW3foiEkaZrS3SFn4TfzFt5eotmJ9YcdO4pqO/wpb7+0zsVV02hKmhB35LAcnLS0NCxbtgz33HMPX0nFbuyYLec+fQUVC4jYku8udXV1fDl5ZmYm/5ituGIfd+XXsByalStX4uc//zm+++47HDx4ELfeeismTpzYvaqKDJ9XjKgpE9Saq9qns7bwKDzQiRbZAwkptEWD6iUtQps+ECFSE3J2feO479NWB/mEKO63xbgIC8ZQcT9C3JFD6+C8//77PPBgK57YbdKkSXx59+lYAMNGdbp8+eWXmDp1Ki67TBQHY9Nh7ONXX321+5znn38eV111FVasWMFr5nh5eeGrr76CVktFvEZKaLLYtDLRVoDG1k6oUdUJMTqYp0uCh8GB0x1kZGh1sKVfzQ9TqteiuK7NMc/s4Y+htXUiyxaH1CnzodNSwXZC3JEks+xcN8OWibORIBZY+fn5Kd0ddbJ0wvz7SOhhwf6rt2L6ZPWNkGS8/hNMLv0ImwKvw6Kfval0d8hgFO8F3lzMN0Z9Z+63uG/ZjJF93mQZ5hdnQl+Xg/81/wh3PPQ0xob70rUhxA1fv+mtDembzoByQwI/rM/dq8pnyadWbCVhi1Bf8EX6ETMDjX7j4Cl1wrT/A9hsI/z+qmgnD27aZCNKY5dTcEOIG6MAh/SrOUAkGlvLDqvvWbJZEdUhKi37J89UujdksCQJnnPv4YeXmdZic7aoQj1SbHvf6k4uvnZeOl0XQtwYBTikX9ooMTLi26i+Palay47DEx38nXrCOFF5mTgHw9QbeU2csZpS7Phe7BU1IprKAHvtm2+Ml2BJOtW+IcSdUYBD+hU0RuRHxHeeRKfFpqpnqixrF29PahIR7OeldHfIUHj4oTPtGn44tfxjnKxqHpHnT971CjSyGbttqZg+90IYdPTvjRB3Rv8BSL9Ck8XmldFSDfKK1FX9ub1I7EFV60cVjJ2Rz8IHebtMsxdffbd5+A/Y0QjrHpFo/i6uwJ3zRP4YIcR9UYBD+iV5BqBSK4b5K7LF9htq4VkjtmiwRU5WuivkXISloT5mMTSSjLis11HZ1DGs51He/Rp0llZk26IRO/sqBHgZ6LoQ4uYowCEDqvMVicamkoPqeaZsNkS15/DDoORZSveGnKOApb/k7RXSVnywduu5P4+ttbBu+zs/fEW+BivPT6ZrQgihAIcMzBYudhb3rBWVpdWgqewEvNHOa6kkpdEWDc5Kip2Fhoj50EtWjD36t3Mu/Gfb+hx05hYcs8UjeNaNCPP1GPG+EkKcD43gkAH5JogAIqI9h+/YrgalmTt5m6dNhL+Pp9LdIcMQcOWfYIOE5Zqd+GDVZ0N/gOpsPj3F/FN7Cx686NQ2MIQQ90YBDhlQxDhRYyZJLkFJdb0qni1ToSg8SAnGLiByEppSV/DDS4v/hk1ZpYP/WpsNpi8ehFY243vrFMxevAL+XrRlByFEoACHDMgQFItGyQ86yYbC42LlktJ8aw7x1hY1wmX+iSICLnsa7VpfTNQUIPuz36FukHuf2Xb+E8bSXbwW0ifhD+PWubRyihByCgU4ZGCShGrvsfywKV8FK6ksnYgxiQTjgHHzlO4NGQm+4dAsf44f3mX5FG+9+wasZ9vCoXAn5I2/5Yd/kW/BYysuhlYj0fUghHSjAIecVWe4qBRsrMxQ/Nmqzz8AI8yok30wJpX2oHIVxqkrUD/uOj5S+OPKp/DS+5/1n/NVcQSm91ZAK1v5lgxTr3kMY8J8RrvLhBCVowCHnJXfmNm8jW7NHPnNEYeoKlMsJ87Rp8LHg/ItXEngipdRFzIDflI7Vp58AK+98hwa206brpJldB7+HKZ/LYHR0oT9trEomPcMrpgSrWS3CSEqpVO6A0T9IlLnA+uAMShGfnkVkqPDFeuLpUgkGDcGUYE/l6MzIujuz1H9xvUIrdmNe6uewuFnP0Rd5EIEehsQWrEFUS1iB3m2HcOBeS/jwaW0DxkhpG8U4JCz0gXGoE4TjCBbLYqP7UJy9JWKPWvBDWJnc2MCFfhzSR7+CL33a1R+8zSCDr6MScgBykXOFWOS9XhfewUSVzyF+9JjFO0qIUTdKMAhg1LlNx5BDVvQwZdoKxPgmJuqEGEt58exExco0gcyCnQGhF/5NCyL7kfW9++ipfgITJ1m1PikQD/hKtw8ewo89Fq6FISQAVGAQwbFFjUdaNgC7xrlEo1Lj24DWwich2gkRFPehavT+Uci7epfKd0NQoiToiRjMijB4+bwNqHjODotNkWetcacHbwt9R4PDS0JJoQQMgAKcMighKWIACdWqsLJ/AJFnjWPSlFo0BJJ+08RQggZGAU4ZFAkzwCU6mL5cflxMZIyqqxmxLUd44f+qQtH//sTQghxKhTgkEFrDBSF9SyFe0b9Was9uQeeMKFe9sG4CbRFAyGEkIFRgEMGzZAgNt4MrBN7QY2m6iM/8Pa4YTx8PAyj/v0JIYQ4FwpwyKBFTbqQt+nWE6iobxnVZ04q3snbhlAavSGEEHJ2FOCQQfOKnogWyRs+UgdyDo9iHo7NhqgmMWrkM/b80fu+hBBCnBYFOGQIvy0alPmKLRJas8WeUKOhqfgIfOUWtMlGpEydP2rflxBCiPOiAIcMiTVWLBf3qxZ7Qo2G0kMbeZulS0VYgO+ofV9CCCHOiwIcMiRh4y/g7TjTMbR0mEfl2bMWiPyb+hDKvyGEEDI4FOCQIQkeNxsm6BEiNSHziCi851A2G2IaxLJ0z3FU/4YQQsjgUIBDhkZnRIlXOj+sObbJ4c9ec+FBBMiNaJWNGDtdjB4RQgghZ0MBDhkyS4zIw/Eo2+XwZ6/0wFreHtZNRFiAn8O/HyGEENdAAQ4ZsrBJF/N2gukgGlpNDn0GNflilKgxklZPEUIIGTwKcMiQBaaejw4YECY14MhBkQDsCLK5HfEtov5N4MSlDvs+hBBCXA8FOGTodEYU+4kdvZszNzjsGSw/uhlGdKJSDsTEKbMc9n0IIYS4HocGOPX19bjtttvg7+/Pb+y4oaFhwK/5/PPPsXTpUoSEhECSJBw6dOa+R4sWLeKfO/124403OvAnIb3ZEkXCb0jldoc9OTWHvuVttvd0eBn1dBEIIYSoI8C5+eabeYCydu1afmPHLMgZSGtrK+bPn48//elPA553zz33oLy8vPv22muvjXDvyUCiZ1zK24mWYyiuqnPIkxVc+j1vOxMX08UghBAyJDo4SFZWFg9qdu3ahdmzZ/P7Xn/9dcydOxcnTpxASkpKn1/XFQAVFBQM+PheXl6IiIhwQM/JYPjETESdJghBtjoc27UesVeM7AiaqTIb0ZYimGUt4mZdQReFEEKIOkZwdu7cyaeluoIbZs6cOfy+HTuGv1Hj+++/z6exxo8fj8ceewzNzc3DfkwyBJKEmnCxssmWvX7En7qCHat4e0gzHmPioujSEEIIUccITkVFBcLCws64n93HPjcct9xyCxITE/kIztGjR/H4448jIyMDGzb0nfBqMpn4rUtTU9Owvj8R/CdfAZR/hfHN29DU3gk/T8OIPTXaHFH/pibmQp5jRQghhDh0BOfJJ588I8G3923fvn383L5emGRZHvYLFsu/Wbx4MSZMmMCTiz/77DNs3LgRBw4c6PP8Z555pjvRmd1iY2OH9f2JED71UnRCj3ipEgf3DX9Urou5pRYJbYf5ceTMa+jpJoQQ4vgRnAceeOCsK5YSEhJw+PBhVFZWnvG56upqhIeHYyRNmzYNer0eOTk5/Lg3NsLz6KOP9hjBoSBnBBh9UBgwC2MbtqPl8FfAeYtG4lGRt/0zpMCGk4jDxAmTRuQxCSGEuJchBzgs74XdzoYlEzc2NmLPnj2YNUvUMNm9eze/b968eRhJx44dg9lsRmRkZJ+fNxqN/EZGni59ObBjO+Krf4DJYoVRpx32Y0pHP+NtfvgSjNHQ9BQhhBAVJRmnpaVh2bJlfDqJraRiN3a8fPnyHiuoUlNTsXr16u6P6+rq+HLyzMxM/jFbccU+7srbyc3NxVNPPcWnwdhKqzVr1uD666/H1KlT+fJyMrri51wLGyRMQC529zNFOBTmpkokNYspTr9ZVNuIEEKICuvgsJVOEydOxJIlS/ht0qRJeO+993qcwwIYNqrT5csvv+TBymWXXcY/ZtNh7ONXX32Vf2wwGPDdd9/xYoAsUHrooYf4Y7McHK12+KMHZGg0fuEo8JvBjxt3fzDspy9v03+ggw1HMQbTpkyny0EIIeScSDLL+nUzLAeHJRuzwMrPj3aoHq6SH95EzOZHkS9HIuRXh+E7jNVUuX+ah+SOY1gf8xCW3P30sPtGCCHEPV+/aS8qMmzRc6/nm28mSuXYsfXc96ZqKjrMgxuLrEHCwoErXhNCCCEDoQCHDJvk4YeS8Iv4sWX/f3gpgHNRtP5l3u42zMa4sePoyhBCCDlnFOCQERG+8G7eLur4Dkfziof89VZTK+JL/suPzVPuoKtCCCFkWCjAISPCN+0iVBgS4C2ZkLNu6BufZq99Fb5oQwnCMHvxdXRVCCGEDAsFOGRkSBKss37MD6dXfoKCqlMr485GtnQiKEOskstMuAOeRj1dFUIIIcNCAQ4ZMdHn34kmjT/ipSrs/a/IpxmMzPVvItxWhWrZH1OveICuCCGEkGGjAIeMHIM3Gqf/lB/OLXkDx0uqz/ollo4WhO79Kz8+Gn8bQoMC6IoQQggZNgpwyIiKXfIQGrTBiJFqcOCjp8+6ourQR79DmFyDMoRgyjW/oKtBCCFkRFCAQ0aW3hO2xb/jh9c2f4DP1n7X76lFR7djcv6b/Lhw2i8RGOBPV4MQQsiIoACHjLigObeiNHgejJIZ03Y+gO1Hc884p6aiCNpVP4JesmKP5wLMWS6WmRNCCCEjgQIcMvIkCVF3voN6XSiSNeUI+PQa/HfzHlhtYrrqyJFDaHrtMkTLlSiVwjHmrjcgaehXkRBCyMihvahoLyqHMZVkwPTWFfCzNaBVNmK7Zjr0GmCeZS8f3alBIEy3fY3o5AmO6wQhhBCXQXtREVUwxkyG9083odJ/Ei8AuETegQusO3hwc9J7KnT3bqLghhBCiEPoHPOwhAja4ESEP7wFnXnbUJO1FWYbEJi2CGPGzOVTWYQQQogjUIBDHE+SYEg+D1HJ59GzTQghZFRQZichhBBCXA4FOIQQQghxORTgEEIIIcTlUIBDCCGEEJdDAQ4hhBBCXA4FOIQQQghxORTgEEIIIcTlUIBDCCGEEJdDAQ4hhBBCXA4FOIQQQghxORTgEEIIIcTlUIBDCCGEEJdDAQ4hhBBCXI5b7iYuyzJvm5qalO4KIYQQQgap63W763V8IG4Z4DQ3N/M2NjZW6a4QQggh5Bxex/39/Qc8R5IHEwa5GJvNhrKyMvj6+kKSpBGPLlngVFxcDD8/P7gaV//53OFnpJ/P+dE1dG6ufv0c+TOykIUFN1FRUdBoBs6yccsRHPakxMTEOPR7sAvqqr+47vDzucPPSD+f86Nr6Nxc/fo56mc828hNF0oyJoQQQojLoQCHEEIIIS6HApwRZjQa8dvf/pa3rsjVfz53+Bnp53N+dA2dm6tfP7X8jG6ZZEwIIYQQ10YjOIQQQghxORTgEEIIIcTlUIBDCCGEEJdDAQ4hhBBCXA4FOOfg5ZdfRmJiIjw8PDB9+nRs3bp1wPM3b97Mz2PnJyUl4dVXX4UaPfPMM5g5cyav8BwWFoarrroKJ06cGPBrNm3axKtB974dP34cavTkk0+e0deIiAiXuH5MQkJCn9fjpz/9qVNevy1btuDyyy/nVUtZv7744osen2drJNg1ZZ/39PTEokWLcOzYsbM+7qpVq5Cens5XeLB29erVUOPPaDab8ctf/hITJ06Et7c3P+f222/nldgH8s477/R5XTs6OqC2a3jnnXee0c85c+a4zDVk+roW7PaXv/xF9dfwmUG8Lqj175ACnCH6+OOP8fDDD+OJJ57AwYMHcd555+GSSy5BUVFRn+fn5+fj0ksv5eex83/961/joYce4hdWbdgLOXsh3LVrFzZs2ACLxYIlS5agtbX1rF/LfuHLy8u7b2PHjoVajR8/vkdfjxw50u+5znT9mL179/b42dh1ZK6//nqnvH7sd2/y5Ml46aWX+vz8s88+i+eee45/nv3sLFi9+OKLu/eb68vOnTtxww034LbbbkNGRgZvV6xYgd27d0NtP2NbWxsOHDiA3/zmN7z9/PPPkZ2djSuuuOKsj8uqx55+TdmNBelqu4bMsmXLevRzzZo1Az6mM11Dpvd1eOutt3iwcu2116r+Gm4exOuCav8O2TJxMnizZs2S77333h73paamyr/61a/6PP8Xv/gF//zpfvKTn8hz5sxR/dNeVVXFSgjImzdv7vecH374gZ9TX18vO4Pf/va38uTJkwd9vjNfP+ZnP/uZnJycLNtsNqe/fqyfq1ev7v6Y/UwRERHyn/70p+77Ojo6ZH9/f/nVV1/t93FWrFghL1u2rMd9S5culW+88UZZbT9jX/bs2cPPKyws7Pect99+mz8PatPXz3fHHXfIV1555ZAex9mvIft5L7zwwgHPUes1rOr1uqDmv0MawRmCzs5O7N+/n0evp2Mf79ixo98otff5S5cuxb59+/jws5o1NjbyNigo6KznTp06FZGRkbjooovwww8/QM1ycnL4UCqbZrzxxhuRl5fX77nOfP3Y7+t//vMf3HXXXWfdVNaZrt/po2sVFRU9rg8b6l64cGG/f48DXdOBvkZtf5fsegYEBAx4XktLC+Lj4/m+e8uXL+cjkGrFpkrZ9Me4ceNwzz33oKqqasDznfkaVlZW4ptvvsHKlSvPeq4ar2Fjr9cFNf8dUoAzBDU1NbBarQgPD+9xP/uYXeC+sPv7Op8N87HHUyv2RuTRRx/FggULMGHChH7PYy+K//rXv/iUDRs+T0lJ4S+SbE5ajWbPno1///vfWLduHV5//XV+febNm4fa2lqXun4MywNoaGjgOQ6ucv1O1/U3N5S/x66vG+rXqAXLv/jVr36Fm2++ecANDFNTU3kOx5dffokPP/yQT2vMnz+fB/dqw6b433//fXz//ff429/+xqc4LrzwQphMJpe8hu+++y7PZ7nmmmsGPE+N11Du43VBzX+Hbrmb+HD1fjfMLvpA75D7Or+v+9XkgQcewOHDh7Ft27YBz2MviOzWZe7cuSguLsZf//pXnH/++VDjP9MuLHGT9Tc5OZn/02F/uK5y/Zg333yT/7xstMpVrt9I/D2e69cojY0YshFHm83GFzoMhCXpnp6oy14Yp02bhhdffBH/+Mc/oCYsD6MLe9GcMWMGH7VgoxwDBQHOeA0Zln9zyy23nDWXRo3X8IEBXhfU+HdIIzhDEBISAq1We0aEyYZTe0eiXViyVV/n63Q6BAcHQ40efPBB/q6BTVWwodGhYn+Uanyn2Be2MoUFOv311xmvH1NYWIiNGzfi7rvvdtnr17X6bSh/j11fN9SvUUNwwxIw2XQAS/QcaPSmLxqNhq+EcYbrykYVWYAzUF+d8RoybMUtS+g/l79Lpa/hg/28Lqj575ACnCEwGAx8uXDXypQu7GM2zdEX9o649/nr16/n71L0ej3UhEXPLEJnUxVsuJjlqJwLNk/M/kk5AzYMnpWV1W9/nen6ne7tt9/mOQ2XXXaZy14/9vvJ/kmefn1Y3hFb9dHf3+NA13Sgr1FDcMNe2FjQei6BNfvbPnTokFNcVzZdzEYRB+qrs13D00dV2WsIW3HlLNdQPsvrgqr/DkcsXdlNfPTRR7Jer5fffPNNOTMzU3744Ydlb29vuaCggH+eraa67bbbus/Py8uTvby85EceeYSfz76Off1nn30mq819993HM983bdokl5eXd9/a2tq6z+n98z3//PN8xUB2drZ89OhR/nn2a7Vq1SpZjX7+85/zn49dl127dsnLly+XfX19XeL6dbFarXJcXJz8y1/+8ozPOdv1a25ulg8ePMhvrF/PPfccP+5aQcRWbrDf2c8//1w+cuSIfNNNN8mRkZFyU1NT92Own/f0VY7bt2+XtVot/9qsrCze6nQ6/vugtp/RbDbLV1xxhRwTEyMfOnSox9+lyWTq92d88skn5bVr18q5ubn8sX70ox/xn3H37t2q+vnY59jf5I4dO+T8/Hy+qm/u3LlydHS0y1zDLo2Njfx/ySuvvNLnY6j1Gt43iNcFtf4dUoBzDv75z3/K8fHxssFgkKdNm9ZjGTVb8rhw4cIe57NfjKlTp/LzExIS+v0FVxr7w+zrxpYr9vfz/fnPf+bLkD08POTAwEB5wYIF8jfffCOr1Q033MD/8FiQEhUVJV9zzTXysWPHXOL6dVm3bh2/bidOnDjjc852/bqWsfe+sZ+ja4kqW/rPlqkajUb5/PPP5/9gT8d+3q7zu3z66adySkoK/z1gZQCUDOgG+hnZi35/f5fs6/r7GdkbLxbkst/Z0NBQecmSJTyIUNvPx14kWd9YH9m1YH1m9xcVFbnMNezy2muvyZ6ennJDQ0Ofj6HWa4hBvC6o9e9Qsv8AhBBCCCEug3JwCCGEEOJyKMAhhBBCiMuhAIcQQgghLocCHEIIIYS4HApwCCGEEOJyKMAhhBBCiMuhAIcQQgghLocCHEIIIYS4HApwCCGEEOJyKMAhhBBCiMuhAIcQQgghLocCHEIIIYTA1fw/s+nZwq5qk/oAAAAASUVORK5CYII=", + "image/png": "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", "text/plain": [ "
" ] @@ -508,7 +513,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.14.2" + "version": "3.14.6" } }, "nbformat": 4, diff --git a/source-code/pytorch-lightning/README.md b/source-code/pytorch-lightning/README.md index 06b0265..0b38e7a 100644 --- a/source-code/pytorch-lightning/README.md +++ b/source-code/pytorch-lightning/README.md @@ -12,3 +12,9 @@ logic, rather than the boilerplate code for training and validation. 1. `mnist.ipynb`: A Jupyter notebook that demonstrates how to use PyTorch Lightning to train a simple neural network on the MNIST dataset. It includes code for data loading, model definition, training, and evaluation. +2. [`ddp/`](ddp/): A batch-friendly ResNet-50 benchmark for comparing one and + multiple GPUs with PyTorch Lightning's DDP strategy. +3. [`activation-checkpointing/`](activation-checkpointing/): A Lightning DDP + counterpart of the native activation-checkpointing exercise. +4. [`fsdp/`](fsdp/): A batch-friendly synthetic-transformer benchmark for + comparing Lightning DDP with FSDP2 memory sharding. diff --git a/source-code/pytorch-lightning/activation-checkpointing/README.md b/source-code/pytorch-lightning/activation-checkpointing/README.md new file mode 100644 index 0000000..9d08503 --- /dev/null +++ b/source-code/pytorch-lightning/activation-checkpointing/README.md @@ -0,0 +1,130 @@ +# PyTorch Lightning activation-checkpointing exercise + +[`activation_checkpointing.py`](activation_checkpointing.py) is the Lightning +counterpart of the +[native PyTorch exercise](../../pytorch/activation-checkpointing/). It uses the +same synthetic transformer, presets, checkpoint boundaries, optimizer, batch +semantics, warm-up, timed steps, and output metrics. + +This comparison exposes an important abstraction boundary: Lightning owns the +distributed training machinery, but activation checkpointing remains a model +decision. The model still calls PyTorch's `torch.utils.checkpoint`; this is not +the same feature as Lightning's `ModelCheckpoint`, which saves training state +to storage. + +## Requirements and duration + +As a follow-on to the native exercise, allow 25–35 minutes. Used independently, +allow 40–50 minutes. The requirements are CUDA-enabled PyTorch, Lightning 2.x, +and at least one CUDA GPU. Lightning is an optional dependency and is not part +of the repository's core GPU environment: + +```bash +python -m pip install lightning +``` + +Install it before the session in a project-specific environment or course +container rather than modifying a shared cluster Python installation. + +## Core code map + +Function and class names are more durable than line numbers if the file changes. + +| Area | Function or class and line | What to inspect | +|---|---|---| +| Options and validation | [`parse_arguments()` — line 91](activation_checkpointing.py#L91) | Defines the checkpoint interval, preset, batch, timing, devices, nodes, precision, and protected output. | +| Precision setup | [`resolve_trainer_precision()` — line 177](activation_checkpointing.py#L177) | Maps FP32/BF16 choices to Lightning Trainer precision modes. | +| Transformer block | [`TransformerBlock` — line 195](activation_checkpointing.py#L195) | Defines the model unit selected for recomputation. | +| Checkpoint selection | [`SyntheticTransformer.forward()` — line 248](activation_checkpointing.py#L248) | Uses the same non-reentrant PyTorch checkpoint call as the native implementation. | +| Lightning module | [`ActivationCheckpointBenchmark` — line 267](activation_checkpointing.py#L267) | Owns the synthetic workload plus benchmark-specific measurement hooks. | +| Batch interpretation | [`setup()` — line 313](activation_checkpointing.py#L313) | Resolves local/global batch semantics after Lightning establishes the world size. | +| Synthetic input | [`on_train_start()` — line 333](activation_checkpointing.py#L333) | Creates a distinct GPU-resident token batch on each worker. | +| Training cycle | [`training_step()` — line 354](activation_checkpointing.py#L354) | Returns the forward loss; Lightning performs backward, recomputation, synchronization, and optimizer update. | +| Measurement | [`on_train_batch_start()` — line 375](activation_checkpointing.py#L375) and [`on_train_batch_end()` — line 393](activation_checkpointing.py#L393) | Exclude warm-up, synchronize workers, time steps, and record peak CUDA memory. | +| Result construction | [`on_train_end()` — line 423](activation_checkpointing.py#L423) | Reduces correctness/performance metrics and writes the rank-zero JSON result. | +| Trainer setup | [`main()` — line 513](activation_checkpointing.py#L513) | Configures devices, nodes, DDP, precision, and a barebones training loop. | + +## Run the matched comparison + +Outside Slurm, Lightning can launch the workers itself: + +```bash +python activation_checkpointing.py \ + --devices 1 \ + --preset small \ + --checkpoint-every 0 \ + --batch-size-per-device 4 \ + --output result-small-none.json + +python activation_checkpointing.py \ + --devices 1 \ + --preset small \ + --checkpoint-every 1 \ + --batch-size-per-device 4 \ + --output result-small-every-block.json +``` + +Under Slurm, Lightning expects one task per GPU. The task count, allocated GPU +count, and `--devices` value must agree: + +```bash +#!/usr/bin/env bash +#SBATCH --nodes=1 +#SBATCH --ntasks-per-node=2 +#SBATCH --gpus-per-node=2 +#SBATCH --time=00:10:00 + +set -euo pipefail + +srun python activation_checkpointing.py \ + --devices 2 \ + --checkpoint-every 0 \ + --output result-none.json + +srun python activation_checkpointing.py \ + --devices 2 \ + --checkpoint-every 1 \ + --output result-checkpoint.json +``` + +Cluster launch conventions vary. Validate this pattern with the local Slurm and +Lightning configuration before the course. + +## Follow-on tasks + +1. Predict which parts of the native script Lightning should remove and which + parts must remain because they define the scientific model or measurement. +2. Run the matched Lightning comparison and verify the configuration fields + before comparing `peak_allocated_gib` and `milliseconds_per_step`. +3. Compare `SyntheticTransformer.forward()` in both implementations. Explain + why the checkpoint boundaries remain explicit even though backward and the + optimizer step disappeared from Lightning's `training_step()`. +4. Compare native and Lightning results cautiously. Small timing differences + can be framework-loop overhead rather than checkpoint recomputation. +5. Decide whether the abstraction saves meaningful research-code complexity in + this example. Support the answer with concrete responsibilities rather than + line count alone. + +The checkpointing conclusion should agree across implementations: selected +forward activations are exchanged for backward recomputation. Exact memory and +timing numbers need not be identical. + +## Important limitations + +- `barebones=True` removes loggers, progress bars, storage checkpoints, and + other Trainer services that would distort a short benchmark. It is not a + normal production Trainer configuration. +- `--precision auto` is resolved before Lightning launches distributed workers + and assumes homogeneous GPUs. Use an explicit precision on heterogeneous + nodes. +- The model contains no dropout, so the checkpoint call disables RNG-state + preservation. Preserve random state when checkpointed production blocks use + stochastic operations. +- Lightning's `ModelCheckpoint` and activation checkpointing solve unrelated + problems: recoverability versus activation memory. +- The workload is synthetic, reuses one GPU-resident batch, and reports + PyTorch-allocator memory. It is not an end-to-end training benchmark. + +For the full task sequence, model presets, interpretation guidance, and +checkpoint-interval experiment, follow the +[native exercise README](../../pytorch/activation-checkpointing/README.md). diff --git a/source-code/pytorch-lightning/activation-checkpointing/activation_checkpointing.py b/source-code/pytorch-lightning/activation-checkpointing/activation_checkpointing.py new file mode 100644 index 0000000..8204a28 --- /dev/null +++ b/source-code/pytorch-lightning/activation-checkpointing/activation_checkpointing.py @@ -0,0 +1,552 @@ +#!/usr/bin/env python3 +"""Measure activation-checkpoint memory and time with Lightning DDP. + +This is the PyTorch Lightning counterpart of the native PyTorch activation- +checkpointing exercise. Compare otherwise identical runs with +``--checkpoint-every 0`` and ``--checkpoint-every 1``:: + + python activation_checkpointing.py --devices 1 \ + --checkpoint-every 0 --output result-no-checkpoint.json + python activation_checkpointing.py --devices 1 \ + --checkpoint-every 1 --output result-checkpoint.json + +Lightning owns the distributed training loop, but activation checkpoint +boundaries remain part of the model and use ``torch.utils.checkpoint``. +""" + +from __future__ import annotations + +import argparse +import json +import math +import os +import platform +import socket +import time +from dataclasses import asdict, dataclass +from datetime import timedelta +from pathlib import Path +from typing import Any + +import lightning as L +import torch +from lightning.pytorch.strategies import DDPStrategy +from torch import Tensor, nn +from torch.distributed import ReduceOp +from torch.utils.checkpoint import checkpoint +from torch.utils.data import DataLoader + +GIBIBYTE = 2**30 + + +@dataclass(frozen=True) +class ModelConfig: + """Configuration for one synthetic transformer preset.""" + + layers: int + hidden_size: int + attention_heads: int + feedforward_size: int + sequence_length: int + vocabulary_size: int = 4096 + classes: int = 16 + + +PRESETS = { + "small": ModelConfig( + layers=8, + hidden_size=512, + attention_heads=8, + feedforward_size=2048, + sequence_length=512, + ), + "medium": ModelConfig( + layers=12, + hidden_size=768, + attention_heads=12, + feedforward_size=3072, + sequence_length=768, + ), +} + + +def positive_integer(value: str) -> int: + """Parse a positive command-line integer.""" + + number = int(value) + if number <= 0: + raise argparse.ArgumentTypeError("must be a positive integer") + return number + + +def non_negative_integer(value: str) -> int: + """Parse a non-negative command-line integer.""" + + number = int(value) + if number < 0: + raise argparse.ArgumentTypeError("must be a non-negative integer") + return number + + +def parse_arguments() -> argparse.Namespace: + """Parse arguments and reject invalid runs before Trainer startup.""" + + parser = argparse.ArgumentParser( + description="Benchmark activation checkpointing with Lightning DDP.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + parser.add_argument("--preset", choices=tuple(PRESETS), default="small") + parser.add_argument( + "--checkpoint-every", + type=non_negative_integer, + default=0, + metavar="N", + help="checkpoint every Nth transformer block; 0 disables checkpointing", + ) + batches = parser.add_mutually_exclusive_group() + batches.add_argument( + "--batch-size-per-device", + type=positive_integer, + default=4, + help="samples per GPU; keeping this fixed is weak scaling", + ) + batches.add_argument( + "--global-batch-size", + type=positive_integer, + help="total samples across GPUs; must be divisible by the world size", + ) + parser.add_argument( + "--warmup-steps", type=positive_integer, default=3, help="untimed steps" + ) + parser.add_argument( + "--steps", type=positive_integer, default=10, help="timed optimizer steps" + ) + parser.add_argument( + "--precision", + choices=("auto", "fp32", "bf16"), + default="auto", + help="auto uses BF16 when supported, otherwise FP32", + ) + parser.add_argument("--seed", type=int, default=1234) + parser.add_argument( + "--devices", + type=positive_integer, + default=1, + help="GPUs per node; under Slurm this must match --ntasks-per-node", + ) + parser.add_argument( + "--num-nodes", type=positive_integer, default=1, help="Slurm node count" + ) + parser.add_argument( + "--output", type=Path, help="optional JSON result path written by rank zero" + ) + parser.add_argument( + "--overwrite-output", + action="store_true", + help="allow replacement of an existing output file", + ) + arguments = parser.parse_args() + + if arguments.seed < 0: + parser.error("--seed must be non-negative") + if arguments.output is None and arguments.overwrite_output: + parser.error("--overwrite-output requires --output") + if arguments.output is not None: + if arguments.output.is_dir(): + parser.error(f"output path is a directory: {arguments.output}") + if arguments.output.exists() and not arguments.overwrite_output: + parser.error( + f"output already exists: {arguments.output}; " + "use --overwrite-output to replace it" + ) + if not arguments.output.parent.exists(): + parser.error(f"output directory does not exist: {arguments.output.parent}") + + expected_world_size = arguments.devices * arguments.num_nodes + if ( + arguments.global_batch_size is not None + and arguments.global_batch_size % expected_world_size != 0 + ): + parser.error( + f"--global-batch-size={arguments.global_batch_size} is not divisible " + f"by devices x nodes={expected_world_size}" + ) + return arguments + + +def resolve_trainer_precision(requested: str) -> tuple[str, str]: + """Map the shared CLI vocabulary to Lightning's precision vocabulary.""" + + if not torch.cuda.is_available(): + raise RuntimeError("CUDA is unavailable; this benchmark requires a GPU") + if requested == "fp32": + return "32-true", "fp32" + if requested == "bf16": + if not torch.cuda.is_bf16_supported(): + raise ValueError( + "BF16 was requested, but the selected GPU does not support it" + ) + return "bf16-mixed", "bf16" + if torch.cuda.is_bf16_supported(): + return "bf16-mixed", "bf16" + return "32-true", "fp32" + + +class TransformerBlock(nn.Module): + """Pre-normalized self-attention and feed-forward transformer block.""" + + def __init__(self, config: ModelConfig) -> None: + super().__init__() + self.attention_norm = nn.LayerNorm(config.hidden_size) + self.attention = nn.MultiheadAttention( + embed_dim=config.hidden_size, + num_heads=config.attention_heads, + dropout=0.0, + bias=False, + batch_first=True, + ) + self.feedforward_norm = nn.LayerNorm(config.hidden_size) + self.feedforward = nn.Sequential( + nn.Linear(config.hidden_size, config.feedforward_size, bias=False), + nn.GELU(approximate="tanh"), + nn.Linear(config.feedforward_size, config.hidden_size, bias=False), + ) + + def forward(self, hidden_states: Tensor) -> Tensor: + """Apply one residual attention and feed-forward block.""" + + normalized = self.attention_norm(hidden_states) + attention_output, _ = self.attention( + normalized, normalized, normalized, need_weights=False + ) + hidden_states = hidden_states + attention_output + return hidden_states + self.feedforward(self.feedforward_norm(hidden_states)) + + +class SyntheticTransformer(nn.Module): + """Transformer whose selected blocks discard forward activations.""" + + def __init__(self, config: ModelConfig, checkpoint_every: int) -> None: + super().__init__() + self.checkpoint_every = checkpoint_every + self.token_embedding = nn.Embedding(config.vocabulary_size, config.hidden_size) + self.position_embedding = nn.Parameter( + torch.empty(config.sequence_length, config.hidden_size) + ) + nn.init.normal_(self.position_embedding, mean=0.0, std=0.02) + self.blocks = nn.ModuleList( + TransformerBlock(config) for _ in range(config.layers) + ) + self.output_norm = nn.LayerNorm(config.hidden_size) + self.classifier = nn.Linear(config.hidden_size, config.classes, bias=False) + + def should_checkpoint(self, block_index: int) -> bool: + """Return whether a block belongs to the selected checkpoint interval.""" + + return self.checkpoint_every > 0 and block_index % self.checkpoint_every == 0 + + def forward(self, token_ids: Tensor) -> Tensor: + """Return logits while checkpointing the selected transformer blocks.""" + + hidden_states = self.token_embedding(token_ids) + hidden_states = hidden_states + self.position_embedding.unsqueeze(0) + for block_index, block in enumerate(self.blocks): + if self.should_checkpoint(block_index): + hidden_states = checkpoint( + block, + hidden_states, + use_reentrant=False, + preserve_rng_state=False, + ) + else: + hidden_states = block(hidden_states) + hidden_states = self.output_norm(hidden_states[:, 0]) + return self.classifier(hidden_states) + + +class ActivationCheckpointBenchmark(L.LightningModule): + """Synthetic transformer plus Lightning timing and reporting hooks.""" + + def __init__( + self, + *, + config: ModelConfig, + preset: str, + checkpoint_every: int, + batch_size_per_device: int, + global_batch_size: int | None, + warmup_steps: int, + measured_steps: int, + precision_requested: str, + precision_resolved: str, + seed: int, + output: Path | None, + ) -> None: + super().__init__() + self.model = SyntheticTransformer(config, checkpoint_every) + self.config = config + self.preset = preset + self.checkpoint_every = checkpoint_every + self.batch_size_per_device_requested = batch_size_per_device + self.global_batch_size_requested = global_batch_size + self.warmup_steps = warmup_steps + self.measured_steps = measured_steps + self.precision_requested = precision_requested + self.precision_resolved = precision_resolved + self.seed = seed + self.output = output + + self._token_ids: Tensor | None = None + self._targets: Tensor | None = None + self._last_loss: Tensor | None = None + self._start_time: float | None = None + self._maxima: Tensor | None = None + self._batch_mode = "" + self._batch_size_per_device = 0 + self._global_batch_size = 0 + + def forward(self, token_ids: Tensor) -> Tensor: + """Apply the synthetic transformer.""" + + return self.model(token_ids) + + def setup(self, stage: str) -> None: + """Resolve batch semantics after Lightning establishes world size.""" + + if stage != "fit": + return + world_size = self.trainer.world_size + if self.global_batch_size_requested is None: + self._batch_size_per_device = self.batch_size_per_device_requested + self._global_batch_size = self._batch_size_per_device * world_size + self._batch_mode = "fixed_per_device" + else: + if self.global_batch_size_requested % world_size != 0: + raise ValueError( + f"--global-batch-size={self.global_batch_size_requested} is " + f"not divisible by the actual world size {world_size}" + ) + self._batch_size_per_device = self.global_batch_size_requested // world_size + self._global_batch_size = self.global_batch_size_requested + self._batch_mode = "fixed_global" + + def on_train_start(self) -> None: + """Create one rank-specific synthetic batch on the selected GPU.""" + + generator = torch.Generator(device=self.device).manual_seed( + self.seed + self.global_rank + ) + self._token_ids = torch.randint( + 0, + self.config.vocabulary_size, + (self._batch_size_per_device, self.config.sequence_length), + generator=generator, + device=self.device, + ) + self._targets = torch.randint( + 0, + self.config.classes, + (self._batch_size_per_device,), + generator=generator, + device=self.device, + ) + + def training_step(self, _batch: int, _batch_idx: int) -> Tensor: + """Compute loss; Lightning runs backward and the optimizer update.""" + + if self._token_ids is None or self._targets is None: + raise RuntimeError("synthetic inputs were not initialized") + logits = self(self._token_ids) + loss = nn.functional.cross_entropy(logits.float(), self._targets) + self._last_loss = loss.detach() + return loss + + def configure_optimizers(self) -> torch.optim.Optimizer: + """Use the same stateless optimizer as the native benchmark.""" + + return torch.optim.SGD(self.parameters(), lr=1e-3) + + def train_dataloader(self) -> DataLoader: + """Supply one lightweight token for every optimizer step.""" + + total_steps = self.warmup_steps + self.measured_steps + return DataLoader(range(total_steps), batch_size=None, num_workers=0) + + def on_train_batch_start(self, _batch: int, batch_idx: int) -> None: + """Start synchronized measurement after the warm-up batches.""" + + if batch_idx != self.warmup_steps: + return + for optimizer in self.trainer.optimizers: + optimizer.zero_grad(set_to_none=True) + self.trainer.strategy.barrier() + torch.cuda.synchronize(self.device) + steady_state_allocated = float(torch.cuda.memory_allocated(self.device)) + torch.cuda.reset_peak_memory_stats(self.device) + self._start_time = time.perf_counter() + self._maxima = torch.tensor( + [0.0, steady_state_allocated, 0.0, 0.0], + dtype=torch.float64, + device=self.device, + ) + + def on_train_batch_end(self, _outputs: Tensor, _batch: int, batch_idx: int) -> None: + """Stop timing after the final measured optimizer step.""" + + total_steps = self.warmup_steps + self.measured_steps + if batch_idx + 1 != total_steps: + return + if self._start_time is None or self._maxima is None: + raise RuntimeError("benchmark timer was not started") + + torch.cuda.synchronize(self.device) + self._maxima[0] = time.perf_counter() - self._start_time + self._maxima[2] = float(torch.cuda.max_memory_allocated(self.device)) + self._maxima[3] = float(torch.cuda.max_memory_reserved(self.device)) + self._maxima = self.trainer.strategy.reduce( + self._maxima, reduce_op=ReduceOp.MAX + ) + + def _parameter_checksum_difference(self) -> float: + """Return the largest checksum difference between model replicas.""" + + checksum = torch.zeros(2, dtype=torch.float64, device=self.device) + with torch.no_grad(): + for parameter in self.parameters(): + values = parameter.detach().to(torch.float64) + checksum[0] += values.sum() + checksum[1] += values.square().sum() + minimum = self.trainer.strategy.reduce(checksum.clone(), reduce_op=ReduceOp.MIN) + maximum = self.trainer.strategy.reduce(checksum, reduce_op=ReduceOp.MAX) + return (maximum - minimum).abs().max().item() + + def on_train_end(self) -> None: + """Reduce correctness metrics and write one rank-zero result.""" + + if self._last_loss is None or self._maxima is None: + raise RuntimeError("the benchmark did not complete all requested steps") + + mean_loss = self.trainer.strategy.reduce( + self._last_loss.to(torch.float64), reduce_op="mean" + ).item() + if not math.isfinite(mean_loss): + raise RuntimeError( + "the final loss is not finite; retry with --precision fp32 or " + "the small preset" + ) + checksum_difference = self._parameter_checksum_difference() + elapsed, steady_state_allocated, peak_allocated, peak_reserved = ( + self._maxima.tolist() + ) + parameter_count = sum(parameter.numel() for parameter in self.parameters()) + checkpointed_blocks = sum( + self.model.should_checkpoint(index) for index in range(self.config.layers) + ) + samples = self.measured_steps * self._global_batch_size + tokens = samples * self.config.sequence_length + + result = { + "model": "synthetic encoder-style transformer", + "data": "synthetic GPU-resident integer token sequences", + "preset": self.preset, + "model_config": asdict(self.config), + "parameter_count": parameter_count, + "model_parameters_fp32_gib": 4 * parameter_count / GIBIBYTE, + "checkpoint_every_blocks": self.checkpoint_every, + "checkpointed_blocks": checkpointed_blocks, + "activation_checkpointing": checkpointed_blocks > 0, + "checkpoint_implementation": "torch.utils.checkpoint, non-reentrant", + "batch_mode": self._batch_mode, + "batch_size_per_device": self._batch_size_per_device, + "global_batch_size": self._global_batch_size, + "world_size": self.trainer.world_size, + "warmup_steps": self.warmup_steps, + "measured_steps": self.measured_steps, + "precision_requested": self.precision_requested, + "precision_resolved": self.precision_resolved, + "seed": self.seed, + "elapsed_seconds": elapsed, + "milliseconds_per_step": 1000.0 * elapsed / self.measured_steps, + "samples_per_second": samples / elapsed, + "tokens_per_second": tokens / elapsed, + "final_loss_mean": mean_loss, + "steady_state_allocated_gib": steady_state_allocated / GIBIBYTE, + "peak_allocated_gib": peak_allocated / GIBIBYTE, + "peak_reserved_gib": peak_reserved / GIBIBYTE, + "parameter_checksum_max_difference": checksum_difference, + "parameters_synchronized": checksum_difference == 0.0, + "gpu_name_rank_zero": torch.cuda.get_device_name(self.device), + "hostname_rank_zero": socket.gethostname(), + "pytorch_version": torch.__version__, + "lightning_version": L.__version__, + "cuda_version": torch.version.cuda, + "python_version": platform.python_version(), + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "lightning_barebones": True, + } + if self.trainer.is_global_zero: + print_summary(result) + if self.output is not None: + text = json.dumps(result, indent=2, sort_keys=True) + self.output.write_text(f"{text}\n", encoding="utf-8") + print(f" JSON result: {self.output}") + + +def print_summary(result: dict[str, Any]) -> None: + """Print a compact summary suitable for a Slurm log.""" + + print("Lightning activation-checkpointing benchmark") + print(f" checkpoint interval: {result['checkpoint_every_blocks']}") + print(f" checkpointed blocks: {result['checkpointed_blocks']}") + print(f" preset: {result['preset']}") + print(f" GPUs: {result['world_size']}") + print(f" precision: {result['precision_resolved']}") + print(f" batch/device: {result['batch_size_per_device']}") + print(f" time/step: {result['milliseconds_per_step']:.3f} ms") + print(f" throughput: {result['tokens_per_second']:.1f} tokens/s") + print(f" steady allocation: {result['steady_state_allocated_gib']:.2f} GiB") + print(f" peak allocated/GPU: {result['peak_allocated_gib']:.2f} GiB") + print(f" peak reserved/GPU: {result['peak_reserved_gib']:.2f} GiB") + print(f" parameters synchronized: {result['parameters_synchronized']}") + + +def main() -> None: + """Create the Lightning module and run the barebones DDP Trainer.""" + + arguments = parse_arguments() + trainer_precision, resolved_precision = resolve_trainer_precision( + arguments.precision + ) + L.seed_everything(arguments.seed, workers=True) + benchmark = ActivationCheckpointBenchmark( + config=PRESETS[arguments.preset], + preset=arguments.preset, + checkpoint_every=arguments.checkpoint_every, + batch_size_per_device=arguments.batch_size_per_device, + global_batch_size=arguments.global_batch_size, + warmup_steps=arguments.warmup_steps, + measured_steps=arguments.steps, + precision_requested=arguments.precision, + precision_resolved=resolved_precision, + seed=arguments.seed, + output=arguments.output, + ) + trainer = L.Trainer( + accelerator="gpu", + devices=arguments.devices, + num_nodes=arguments.num_nodes, + strategy=DDPStrategy( + timeout=timedelta(minutes=5), gradient_as_bucket_view=True + ), + precision=trainer_precision, + max_steps=arguments.warmup_steps + arguments.steps, + max_epochs=1, + use_distributed_sampler=False, + barebones=True, + benchmark=True, + ) + trainer.fit(benchmark) + + +if __name__ == "__main__": + main() diff --git a/source-code/pytorch-lightning/ddp/README.md b/source-code/pytorch-lightning/ddp/README.md new file mode 100644 index 0000000..e7fddce --- /dev/null +++ b/source-code/pytorch-lightning/ddp/README.md @@ -0,0 +1,126 @@ +# PyTorch Lightning DDP benchmark + +[`ddp_resnet50.py`](ddp_resnet50.py) is the PyTorch Lightning counterpart of +the [native PyTorch DDP benchmark](../../pytorch/ddp/ddp_resnet50.py). It uses +the same randomly initialized ResNet-50, synthetic ImageNet-shaped inputs, +optimizer, batch modes, warm-up period, timed steps, and result metrics. + +No model weights or dataset are downloaded. The ResNet-50 implementation is +part of `torchvision`, and `weights=None` requests a random initialization. + +The example is intended to compare one and multiple GPUs and, alongside the +native version, to show which DDP responsibilities Lightning takes over. It +measures model computation, Lightning's training-loop overhead, and gradient +communication. It does not measure data-loading performance or model accuracy. + +## Requirements + +The script requires CUDA-enabled PyTorch, `torchvision`, and Lightning 2.x +using the current `lightning` package and import name. Lightning is an optional +dependency and is not added to the repository's core GPU environment: + +```bash +python -m pip install lightning +``` + +On a cluster, prefer installing it in a project-specific environment rather +than altering a shared system Python installation. + +## Core code map + +The line numbers below refer to the current version of +[`ddp_resnet50.py`](ddp_resnet50.py). Function and method names are the more +durable reference if the file changes later. + +| Area | Function or method and line | What to inspect | +|---|---|---| +| Input and option validation | [`parse_arguments()` — line 57](ddp_resnet50.py#L57) | Defines the batch, timing, precision, device, node, and output options and rejects inconsistent runs. | +| Precision setup | [`resolve_trainer_precision()` — line 138](ddp_resnet50.py#L138) | Maps the shared FP32/BF16/FP16 options to Lightning's precision modes. | +| Model creation | [`ResNet50Benchmark.__init__()` — line 161](ddp_resnet50.py#L161) | Creates `torchvision.models.resnet50(weights=None)` at line 174 and stores the benchmark configuration. | +| Distributed batch interpretation | [`ResNet50Benchmark.setup()` — line 198](ddp_resnet50.py#L198) | Uses Lightning's actual world size to distinguish a fixed per-device batch from a fixed global batch. | +| Synthetic input | [`ResNet50Benchmark.on_train_start()` — line 218](ddp_resnet50.py#L218) | Creates a distinct GPU-resident image batch and labels for each rank. | +| One training cycle | [`ResNet50Benchmark.training_step()` — line 240](ddp_resnet50.py#L240) | Runs the forward pass and loss calculation. Lightning performs backward propagation, DDP gradient synchronization, and the optimizer update. | +| Optimizer setup | [`ResNet50Benchmark.configure_optimizers()` — line 249](ddp_resnet50.py#L249) | Creates the same SGD optimizer as the native example. | +| Training-loop input | [`ResNet50Benchmark.train_dataloader()` — line 254](ddp_resnet50.py#L254) | Supplies one lightweight token per optimizer step; the real synthetic images already reside on each GPU. | +| Warm-up and measured cycles | [`on_train_batch_start()` — line 260](ddp_resnet50.py#L260) and [`on_train_batch_end()` — line 270](ddp_resnet50.py#L270) | Synchronize the ranks, exclude warm-up steps, time the measured steps, and collect peak CUDA memory. | +| DDP and Trainer setup | [`main()` — line 379](ddp_resnet50.py#L379) | Creates the module and configures Lightning's GPU accelerator, `DDPStrategy`, precision plugin, and barebones Trainer. | + +Start with `main()` to see the high-level Lightning setup, then compare +`training_step()` with the native benchmark's `training_step()`. + +## What Lightning changes + +| Responsibility | Native PyTorch example | Lightning example | +|---|---|---| +| Process and NCCL setup | Explicit process-group initialization and teardown | `Trainer` and `DDPStrategy` | +| Device placement and DDP wrapper | Explicit local-rank device selection and `DistributedDataParallel(...)` | Lightning accelerator and strategy | +| Mixed precision | Explicit autocast and gradient scaler | Trainer `precision` setting | +| Backward pass and optimizer update | Written in the training step | Automatic after `training_step()` returns the loss | +| Benchmark timing and reporting | Custom code | Still custom code, because these are benchmark requirements rather than ordinary training features | + +This is intentionally an exact comparison rather than the shortest possible +Lightning program. Consequently, validation, timing, JSON reporting, and +correctness checks still account for much of the file. The simplification is +most visible in `main()` and `training_step()`. + +## Run as a Slurm batch job + +Lightning detects the Slurm environment from its variables. The Slurm task +count per node, allocated GPU count, and `--devices` value must agree. For a +single-node, four-GPU job, the relevant batch-script lines are typically: + +```bash +#SBATCH --nodes=1 +#SBATCH --ntasks-per-node=4 +#SBATCH --gpus-per-node=4 + +srun python ddp_resnet50.py \ + --devices 4 \ + --batch-size-per-device 32 \ + --output result-4gpu.json +``` + +Some clusters spell the GPU request as `#SBATCH --gres=gpu:4`; use the syntax +documented by the local site. For the one-GPU baseline, change all three `4` +values to `1` and use a different output name. + +For weak scaling, keep `--batch-size-per-device` fixed while changing the GPU +count. For strong scaling, keep the global batch fixed: + +```bash +srun python ddp_resnet50.py \ + --devices 4 \ + --global-batch-size 128 \ + --output result-global128-4gpu.json +``` + +Outside Slurm, Lightning can launch the DDP worker processes itself: + +```bash +python ddp_resnet50.py \ + --devices 4 \ + --batch-size-per-device 32 \ + --output result-4gpu.json +``` + +## Interpreting the result + +The JSON result records throughput, time per optimizer step, peak PyTorch CUDA +memory, the resolved precision, software versions, hardware information, and a +check that model parameters remained synchronized. + +There are several deliberate limitations: + +- `barebones=True` removes logging, checkpointing, progress bars, and other + Trainer services so that they do not distort a short benchmark. It is not a + recommended default for a real training application. +- The synthetic batch lives on the GPU and is reused. This isolates model and + communication performance but says nothing about storage or data-pipeline + scaling. +- The timed region includes Lightning's per-step loop overhead. That is useful + for this comparison, but means a small difference from the native result is + not necessarily a DDP communication difference. +- `--precision auto` assumes homogeneous GPUs across all nodes. Select an + explicit precision on a heterogeneous allocation. +- PyTorch's CUDA memory counters do not include every allocation made directly + by CUDA libraries such as NCCL. diff --git a/source-code/pytorch-lightning/ddp/ddp_resnet50.py b/source-code/pytorch-lightning/ddp/ddp_resnet50.py new file mode 100644 index 0000000..2c1aaf5 --- /dev/null +++ b/source-code/pytorch-lightning/ddp/ddp_resnet50.py @@ -0,0 +1,415 @@ +#!/usr/bin/env python3 +"""Benchmark ResNet-50 training with PyTorch Lightning DDP. + +This is the Lightning counterpart of +``source-code/pytorch/ddp/ddp_resnet50.py``. It uses the same model, synthetic +ImageNet-shaped inputs, optimizer, batch modes, warm-up period, measurements, +and JSON result fields. Lightning owns process and device setup, DDP wrapping, +mixed precision, gradient synchronization, and optimizer execution. + +Inside a single-node Slurm allocation with four tasks and four GPUs:: + + srun python ddp_resnet50.py --devices 4 \ + --batch-size-per-device 32 --output result-4gpu.json + +Outside Slurm, Lightning can launch the processes itself:: + + python ddp_resnet50.py --devices 4 \ + --batch-size-per-device 32 --output result-4gpu.json + +The benchmark uses Lightning's barebones Trainer mode. The memory figures +cover PyTorch's CUDA allocator; NCCL may allocate additional device memory. +""" + +from __future__ import annotations + +import argparse +import json +import math +import os +import platform +import socket +import time +from datetime import timedelta +from pathlib import Path + +import lightning as L +import torch +import torchvision +from lightning.pytorch.strategies import DDPStrategy +from torch import Tensor, nn +from torch.distributed import ReduceOp +from torch.utils.data import DataLoader +from torchvision.models import resnet50 + +GIBIBYTE = 2**30 + + +def positive_integer(value: str) -> int: + """Parse a positive command-line integer.""" + + number = int(value) + if number <= 0: + raise argparse.ArgumentTypeError("must be a positive integer") + return number + + +def parse_arguments() -> argparse.Namespace: + """Parse arguments and reject invalid runs before Trainer startup.""" + + parser = argparse.ArgumentParser( + description="Benchmark synthetic ResNet-50 training with Lightning DDP.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + batches = parser.add_mutually_exclusive_group() + batches.add_argument( + "--batch-size-per-device", + type=positive_integer, + default=32, + help="samples per GPU; keeping this fixed is a weak-scaling experiment", + ) + batches.add_argument( + "--global-batch-size", + type=positive_integer, + help="total samples across GPUs; must be divisible by the world size", + ) + parser.add_argument( + "--warmup-steps", + type=positive_integer, + default=10, + help="untimed steps used to initialize kernels and DDP buckets", + ) + parser.add_argument( + "--steps", type=positive_integer, default=50, help="timed optimizer steps" + ) + parser.add_argument( + "--precision", + choices=("auto", "fp32", "bf16", "fp16"), + default="auto", + help="auto uses BF16 when supported, otherwise FP16", + ) + parser.add_argument("--seed", type=int, default=1234) + parser.add_argument( + "--devices", + type=positive_integer, + default=1, + help="GPUs per node; under Slurm this must match --ntasks-per-node", + ) + parser.add_argument( + "--num-nodes", type=positive_integer, default=1, help="Slurm node count" + ) + parser.add_argument( + "--output", type=Path, help="optional JSON result path written by rank zero" + ) + parser.add_argument( + "--overwrite-output", + action="store_true", + help="allow replacement of an existing output file", + ) + arguments = parser.parse_args() + + if arguments.seed < 0: + parser.error("--seed must be non-negative") + if arguments.output is None and arguments.overwrite_output: + parser.error("--overwrite-output requires --output") + if arguments.output is not None: + if arguments.output.is_dir(): + parser.error(f"output path is a directory: {arguments.output}") + if arguments.output.exists() and not arguments.overwrite_output: + parser.error( + f"output already exists: {arguments.output}; " + "use --overwrite-output to replace it" + ) + if not arguments.output.parent.exists(): + parser.error(f"output directory does not exist: {arguments.output.parent}") + + expected_world_size = arguments.devices * arguments.num_nodes + if ( + arguments.global_batch_size is not None + and arguments.global_batch_size % expected_world_size != 0 + ): + parser.error( + f"--global-batch-size={arguments.global_batch_size} is not divisible " + f"by devices x nodes={expected_world_size}" + ) + return arguments + + +def resolve_trainer_precision(requested: str) -> tuple[str, str]: + """Map the shared CLI vocabulary to Lightning's Trainer vocabulary.""" + + if not torch.cuda.is_available(): + raise RuntimeError("CUDA is unavailable; this benchmark requires GPUs") + if requested == "fp32": + return "32-true", "fp32" + if requested == "bf16": + if not torch.cuda.is_bf16_supported(): + raise ValueError( + "BF16 was requested, but the selected GPU does not support it" + ) + return "bf16-mixed", "bf16" + if requested == "fp16": + return "16-mixed", "fp16" + if torch.cuda.is_bf16_supported(): + return "bf16-mixed", "bf16" + return "16-mixed", "fp16" + + +class ResNet50Benchmark(L.LightningModule): + """ResNet-50 workload plus benchmark-specific timing and reporting hooks.""" + + def __init__( + self, + *, + batch_size_per_device: int, + global_batch_size: int | None, + warmup_steps: int, + measured_steps: int, + precision_requested: str, + precision_resolved: str, + seed: int, + output: Path | None, + ) -> None: + super().__init__() + self.model = resnet50(weights=None) + self.batch_size_per_device_requested = batch_size_per_device + self.global_batch_size_requested = global_batch_size + self.warmup_steps = warmup_steps + self.measured_steps = measured_steps + self.precision_requested = precision_requested + self.precision_resolved = precision_resolved + self.seed = seed + self.output = output + + self._images: Tensor | None = None + self._targets: Tensor | None = None + self._last_loss: Tensor | None = None + self._start_time: float | None = None + self._maxima: Tensor | None = None + self._batch_mode = "" + self._batch_size_per_device = 0 + self._global_batch_size = 0 + + def forward(self, images: Tensor) -> Tensor: + """Apply ResNet-50 to a batch of images.""" + + return self.model(images) + + def setup(self, stage: str) -> None: + """Resolve batch semantics after Lightning establishes the world size.""" + + if stage != "fit": + return + world_size = self.trainer.world_size + if self.global_batch_size_requested is None: + self._batch_size_per_device = self.batch_size_per_device_requested + self._global_batch_size = self._batch_size_per_device * world_size + self._batch_mode = "fixed_per_device" + else: + if self.global_batch_size_requested % world_size != 0: + raise ValueError( + f"--global-batch-size={self.global_batch_size_requested} is not " + f"divisible by the actual world size {world_size}" + ) + self._batch_size_per_device = self.global_batch_size_requested // world_size + self._global_batch_size = self.global_batch_size_requested + self._batch_mode = "fixed_global" + + def on_train_start(self) -> None: + """Create one rank-specific synthetic batch on Lightning's chosen device.""" + + generator = torch.Generator(device=self.device).manual_seed( + self.seed + self.global_rank + ) + self._images = torch.randn( + self._batch_size_per_device, + 3, + 224, + 224, + generator=generator, + device=self.device, + ) + self._targets = torch.randint( + 0, + 1000, + (self._batch_size_per_device,), + generator=generator, + device=self.device, + ) + + def training_step(self, _batch: int, _batch_idx: int) -> Tensor: + """Compute the loss; Lightning runs backward and the optimizer update.""" + + if self._images is None or self._targets is None: + raise RuntimeError("synthetic inputs were not initialized") + loss = nn.functional.cross_entropy(self(self._images), self._targets) + self._last_loss = loss.detach() + return loss + + def configure_optimizers(self) -> torch.optim.Optimizer: + """Use the same optimizer as the native DDP benchmark.""" + + return torch.optim.SGD(self.parameters(), lr=0.1, momentum=0.9) + + def train_dataloader(self) -> DataLoader: + """Supply one lightweight token for every optimizer step.""" + + total_steps = self.warmup_steps + self.measured_steps + return DataLoader(range(total_steps), batch_size=None, num_workers=0) + + def on_train_batch_start(self, _batch: int, batch_idx: int) -> None: + """Start synchronized timing after the warm-up batches.""" + + if batch_idx != self.warmup_steps: + return + self.trainer.strategy.barrier() + torch.cuda.synchronize(self.device) + torch.cuda.reset_peak_memory_stats(self.device) + self._start_time = time.perf_counter() + + def on_train_batch_end(self, _outputs: Tensor, _batch: int, batch_idx: int) -> None: + """Stop timing after the final measured optimizer step.""" + + total_steps = self.warmup_steps + self.measured_steps + if batch_idx + 1 != total_steps: + return + if self._start_time is None: + raise RuntimeError("benchmark timer was not started") + + torch.cuda.synchronize(self.device) + elapsed = time.perf_counter() - self._start_time + local = torch.tensor( + [ + elapsed, + float(torch.cuda.max_memory_allocated(self.device)), + float(torch.cuda.max_memory_reserved(self.device)), + ], + dtype=torch.float64, + device=self.device, + ) + self._maxima = self.trainer.strategy.reduce(local, reduce_op=ReduceOp.MAX) + + def _parameter_checksum_difference(self) -> float: + """Return the largest checksum difference between model replicas.""" + + checksum = torch.zeros(2, dtype=torch.float64, device=self.device) + with torch.no_grad(): + for parameter in self.parameters(): + values = parameter.detach().to(torch.float64) + checksum[0] += values.sum() + checksum[1] += values.square().sum() + minimum = self.trainer.strategy.reduce(checksum.clone(), reduce_op=ReduceOp.MIN) + maximum = self.trainer.strategy.reduce(checksum, reduce_op=ReduceOp.MAX) + difference = maximum - minimum + return difference.abs().max().item() + + def on_train_end(self) -> None: + """Reduce correctness metrics and write one result on global rank zero.""" + + if self._last_loss is None or self._maxima is None: + raise RuntimeError("the benchmark did not complete all requested steps") + + mean_loss = self.trainer.strategy.reduce( + self._last_loss.to(torch.float64), reduce_op="mean" + ).item() + if not math.isfinite(mean_loss): + raise RuntimeError( + "the final loss is not finite; retry with --precision fp32 or a " + "smaller batch" + ) + checksum_difference = self._parameter_checksum_difference() + elapsed, peak_allocated, peak_reserved = self._maxima.tolist() + + result = { + "model": "torchvision.models.resnet50", + "data": "synthetic GPU-resident 3x224x224 images with random labels", + "batch_mode": self._batch_mode, + "batch_size_per_device": self._batch_size_per_device, + "global_batch_size": self._global_batch_size, + "world_size": self.trainer.world_size, + "warmup_steps": self.warmup_steps, + "measured_steps": self.measured_steps, + "precision_requested": self.precision_requested, + "precision_resolved": self.precision_resolved, + "seed": self.seed, + "elapsed_seconds": elapsed, + "milliseconds_per_step": 1000.0 * elapsed / self.measured_steps, + "images_per_second": ( + self.measured_steps * self._global_batch_size / elapsed + ), + "final_loss_mean": mean_loss, + "peak_allocated_gib": peak_allocated / GIBIBYTE, + "peak_reserved_gib": peak_reserved / GIBIBYTE, + "parameter_checksum_max_difference": checksum_difference, + "parameters_synchronized": checksum_difference == 0.0, + "gpu_name_rank_zero": torch.cuda.get_device_name(self.device), + "hostname_rank_zero": socket.gethostname(), + "pytorch_version": torch.__version__, + "torchvision_version": torchvision.__version__, + "lightning_version": L.__version__, + "cuda_version": torch.version.cuda, + "cudnn_version": torch.backends.cudnn.version(), + "python_version": platform.python_version(), + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "lightning_barebones": True, + } + if self.trainer.is_global_zero: + print_summary(result) + if self.output is not None: + text = json.dumps(result, indent=2, sort_keys=True) + self.output.write_text(f"{text}\n", encoding="utf-8") + print(f" JSON result: {self.output}") + + +def print_summary(result: dict[str, object]) -> None: + """Print a compact summary suitable for a Slurm log.""" + + print("Lightning DDP ResNet-50 synthetic training benchmark") + print(f" GPUs: {result['world_size']}") + print(f" precision: {result['precision_resolved']}") + print(f" batch/device: {result['batch_size_per_device']}") + print(f" global batch: {result['global_batch_size']}") + print(f" time/step: {result['milliseconds_per_step']:.3f} ms") + print(f" throughput: {result['images_per_second']:.1f} images/s") + print(f" peak allocated/GPU: {result['peak_allocated_gib']:.2f} GiB") + print(f" peak reserved/GPU: {result['peak_reserved_gib']:.2f} GiB") + print(f" parameters synchronized: {result['parameters_synchronized']}") + + +def main() -> None: + """Create the Lightning module and run the barebones DDP Trainer.""" + + arguments = parse_arguments() + trainer_precision, resolved_precision = resolve_trainer_precision( + arguments.precision + ) + L.seed_everything(arguments.seed, workers=True) + model = ResNet50Benchmark( + batch_size_per_device=arguments.batch_size_per_device, + global_batch_size=arguments.global_batch_size, + warmup_steps=arguments.warmup_steps, + measured_steps=arguments.steps, + precision_requested=arguments.precision, + precision_resolved=resolved_precision, + seed=arguments.seed, + output=arguments.output, + ) + trainer = L.Trainer( + accelerator="gpu", + devices=arguments.devices, + num_nodes=arguments.num_nodes, + strategy=DDPStrategy( + timeout=timedelta(minutes=5), gradient_as_bucket_view=True + ), + precision=trainer_precision, + max_steps=arguments.warmup_steps + arguments.steps, + max_epochs=1, + use_distributed_sampler=False, + barebones=True, + benchmark=True, + ) + trainer.fit(model) + + +if __name__ == "__main__": + main() diff --git a/source-code/pytorch-lightning/fsdp/README.md b/source-code/pytorch-lightning/fsdp/README.md new file mode 100644 index 0000000..2454464 --- /dev/null +++ b/source-code/pytorch-lightning/fsdp/README.md @@ -0,0 +1,242 @@ +# PyTorch Lightning FSDP2 benchmark + +[`fsdp2_transformer.py`](fsdp2_transformer.py) is the PyTorch Lightning +counterpart of the +[native PyTorch DDP/FSDP2 benchmark](../../pytorch/fsdp/fsdp2_transformer.py). +It uses the same synthetic transformer, presets, optimizer, batch modes, +warm-up period, timed steps, and result metrics. + +No model, weights, tokenizer, or dataset are downloaded. The model is assembled +from standard PyTorch modules, and every rank creates a distinct synthetic token +batch directly on its GPU. + +This is primarily a memory-scaling exercise. FSDP2 exchanges parameters during +the forward and backward passes so that parameters, gradients, and optimizer +state do not need to remain fully replicated. That usually reduces per-GPU +model-state memory, but it can make training slower than DDP when the complete +model already fits comfortably. + +## Requirements + +The script targets the Lightning 2.6 `ModelParallelStrategy` API and requires +PyTorch 2.4 or newer. The repository's +[`environment_gpu.yml`](../../../environment_gpu.yml) selects PyTorch 2.13 but +does not install Lightning, because Lightning is an optional dependency: + +```bash +python -m pip install lightning +``` + +Install it in a project-specific environment on a cluster rather than changing +a shared system Python installation. The example needs a CUDA-enabled PyTorch +build and at least two GPUs to demonstrate sharding; a one-GPU run is useful +only as a smoke test. + +The use of +[`ModelParallelStrategy`](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.strategies.ModelParallelStrategy.html) +is deliberate. Lightning's older `FSDPStrategy` wraps PyTorch's FSDP1 class. +`ModelParallelStrategy` exposes the FSDP2 and device-mesh workflow, and this +script sets `tensor_parallel_size=1` so that every worker participates only in +the data-parallel/FSDP dimension. Lightning currently labels this strategy +experimental, so version upgrades may require small API changes. PyTorch's +[FSDP2 tutorial](https://docs.pytorch.org/tutorials/intermediate/FSDP_tutorial.html) +explains the underlying per-parameter sharding model. + +## Model presets + +Start with `small`. Validate `medium` on the actual lab hardware before the +session. `large` can exhaust smaller GPUs and is best kept as an optional +capacity experiment. + +| Preset | Blocks | Hidden size | Parameters | FP32 parameters only | Approximate DDP model state with AdamW | +|---|---:|---:|---:|---:|---:| +| `small` | 12 | 768 | 88,327,680 | 0.33 GiB | 1.32 GiB | +| `medium` | 24 | 1,024 | 306,563,072 | 1.14 GiB | 4.57 GiB | +| `large` | 32 | 1,280 | 634,903,040 | 2.37 GiB | 9.46 GiB | + +The final column estimates FP32 parameters, gradients, and the two AdamW +moment tensors after the first optimizer step. It excludes activations, +communication buckets, all-gather buffers, CUDA context memory, allocator +fragmentation, and NCCL allocations. Actual peak memory will therefore be +higher. + +## Command-line options + +| Option | Default | Meaning | +|---|---|---| +| `--strategy {ddp,fsdp2}` | required | Select replicated Lightning DDP or Lightning-managed FSDP2. | +| `--preset {small,medium,large}` | `small` | Select model dimensions from the table above. | +| `--fsdp-wrap {block,root}` | `block` | Choose per-block or root-only FSDP2 grouping; ignored for DDP. | +| `--batch-size-per-device N` | `1` | Set the local batch; keeping it fixed gives weak scaling. | +| `--global-batch-size N` | unset | Set a fixed total batch for strong scaling; mutually exclusive with the local batch option. | +| `--warmup-steps N` | `5` | Run untimed steps that initialize optimizer state and communication paths. | +| `--steps N` | `15` | Set the number of timed optimizer steps. | +| `--precision {auto,fp32,bf16}` | `auto` | Use BF16 when the selected GPU supports it; otherwise use FP32. | +| `--seed N` | `1234` | Control model initialization and rank-specific synthetic inputs. | +| `--devices N` | `1` | Set GPUs per node; under Slurm this must match the tasks per node. | +| `--num-nodes N` | `1` | Set the Lightning/Slurm node count. | +| `--output PATH` | unset | Write the rank-zero result as JSON; existing files are protected. | +| `--overwrite-output` | off | Permit replacement of an existing result file. | + +The script validates numbers, batch divisibility, and output behavior before +starting the Trainer. Each result includes the resolved configuration, seed, +framework versions, throughput, peak PyTorch CUDA memory, and parameter +checksums. + +## Core code map + +The line numbers below refer to the current version of +[`fsdp2_transformer.py`](fsdp2_transformer.py). Function and method names are +the more durable reference if the file changes later. + +| Area | Function or method and line | What to inspect | +|---|---|---| +| Options and validation | [`parse_arguments()` — line 97](fsdp2_transformer.py#L97) | Defines strategy, preset, wrapping, batch, precision, device, timing, and output options. | +| Precision setup | [`resolve_precision()` — line 183](fsdp2_transformer.py#L183) | Resolves FP32 or BF16 before Lightning launches workers. | +| Transformer block | [`TransformerBlock` — line 199](fsdp2_transformer.py#L199) | Defines the unit used as an FSDP2 communication and sharding boundary. | +| Complete model | [`SyntheticTransformer` — line 230](fsdp2_transformer.py#L230) | Defines embeddings, transformer blocks, normalization, and classifier. | +| Model creation and FSDP2 setup | [`TransformerBenchmark.configure_model()` — line 304](fsdp2_transformer.py#L304) | Creates the large layers in Lightning's strategy-aware hook, then applies `fully_shard()` to blocks and root. | +| Distributed batch interpretation | [`TransformerBenchmark.setup()` — line 348](fsdp2_transformer.py#L348) | Uses Lightning's actual world size to resolve local and global batches. | +| Synthetic input | [`TransformerBenchmark.on_train_start()` — line 368](fsdp2_transformer.py#L368) | Measures the local parameter shard and creates rank-specific GPU-resident tokens. | +| One training cycle | [`TransformerBenchmark.training_step()` — line 392](fsdp2_transformer.py#L392) | Runs forward propagation and loss calculation; Lightning performs backward, synchronization, and update. | +| Optimizer setup | [`TransformerBenchmark.configure_optimizers()` — line 402](fsdp2_transformer.py#L402) | Creates AdamW after `configure_model()` has sharded the model. | +| Training-loop input | [`TransformerBenchmark.train_dataloader()` — line 409](fsdp2_transformer.py#L409) | Supplies one lightweight token per optimizer step; the actual token tensor is already on the GPU. | +| Warm-up and measured cycles | [`on_train_batch_start()` — line 415](fsdp2_transformer.py#L415) and [`on_train_batch_end()` — line 425](fsdp2_transformer.py#L425) | Synchronize workers, exclude warm-up, time the measured steps, and collect peak CUDA memory. | +| Result construction | [`TransformerBenchmark.on_train_end()` — line 473](fsdp2_transformer.py#L473) | Reduces correctness and performance metrics and writes rank-zero output. | +| DDP or FSDP2 strategy | [`make_strategy()` — line 579](fsdp2_transformer.py#L579) | Selects `DDPStrategy` or a pure-FSDP2 `ModelParallelStrategy` device mesh. | +| Trainer setup | [`main()` — line 594](fsdp2_transformer.py#L594) | Configures Lightning's GPU devices, nodes, precision, strategy, and barebones training loop. | + +Start with `main()`, then inspect `configure_model()` and `training_step()`. +The key FSDP2 detail is that large layers are created in the strategy-aware +hook, sharding is applied before optimizer construction, and the model code +itself remains ordinary PyTorch. + +## What Lightning changes + +| Responsibility | Native PyTorch example | Lightning example | +|---|---|---| +| Process group, ranks, and teardown | Explicit NCCL setup and cleanup | `Trainer` and the selected strategy | +| Device placement | Explicit local-rank CUDA binding | Lightning accelerator | +| DDP wrapping | Explicit `DistributedDataParallel(...)` | `DDPStrategy` | +| FSDP2 device mesh | Implicit world process group | `ModelParallelStrategy` creates and exposes the mesh | +| FSDP2 wrapping policy | Explicit `fully_shard()` calls | Still explicit in `configure_model()` because layer boundaries are a model decision | +| Mixed precision | DDP autocast or FSDP2 policy | Trainer precision for DDP; `MixedPrecisionPolicy` for FSDP2 communication and parameters | +| Backward and optimizer step | Explicit calls in `training_step()` | Automatic after the Lightning step returns loss | +| Timing and reporting | Custom benchmark code | Still custom, because these are benchmark requirements | + +This is intentionally an exact comparison rather than the shortest possible +Lightning program. Input checks, timing, JSON reporting, and correctness checks +therefore still account for much of the file. The simplification is clearest in +`main()` and `training_step()`. + +## Run the comparison + +Use the same GPU count, preset, precision, and batch settings for both runs. On +a four-GPU node outside Slurm: + +```bash +python fsdp2_transformer.py \ + --strategy ddp \ + --devices 4 \ + --preset medium \ + --batch-size-per-device 1 \ + --output result-medium-ddp.json + +python fsdp2_transformer.py \ + --strategy fsdp2 \ + --devices 4 \ + --fsdp-wrap block \ + --preset medium \ + --batch-size-per-device 1 \ + --output result-medium-fsdp2-block.json +``` + +If `medium` is too slow or exceeds memory, substitute `small` in both commands. +Changing only one workload invalidates the comparison. For strong scaling, +replace the local batch option in both commands with a global batch divisible +by the worker count, for example `--global-batch-size 4`. + +## Run as a single-node Slurm batch job + +Lightning detects the Slurm environment. Unlike the native example, which +runs one Slurm launcher task and lets `torchrun` create workers, this version +uses one Slurm task per GPU. The Slurm task count, GPU allocation, and +`--devices` value must agree: + +```bash +#!/usr/bin/env bash +#SBATCH --nodes=1 +#SBATCH --ntasks-per-node=4 +#SBATCH --gpus-per-node=4 + +set -euo pipefail + +srun python fsdp2_transformer.py \ + --strategy ddp \ + --devices 4 \ + --preset medium \ + --output result-medium-ddp.json + +srun python fsdp2_transformer.py \ + --strategy fsdp2 \ + --devices 4 \ + --fsdp-wrap block \ + --preset medium \ + --output result-medium-fsdp2-block.json +``` + +Some clusters spell the GPU request as `#SBATCH --gres=gpu:4`; follow the local +site documentation. For multi-node runs, set both the Slurm node count and +`--num-nodes`, and keep `--devices` equal to the number of tasks and GPUs on +each node. + +## Hands-on tasks + +Before running, predict which strategy will use less peak memory and which will +have higher throughput. Then: + +1. Run DDP and block-wrapped FSDP2 with otherwise identical options. +2. Compare `local_parameter_fraction`, `peak_allocated_gib`, + `milliseconds_per_step`, and `tokens_per_second` in the JSON results. +3. Explain why DDP stores nearly all parameters on every rank while FSDP2 + approaches a local fraction of `1 / world_size`. +4. Repeat FSDP2 with `--fsdp-wrap root`; predict its peak memory and throughput + before looking at the result. +5. Compare the Lightning script with the native implementation and identify + which distributed responsibilities disappeared and which model-specific + decisions remained. +6. If hardware and time permit, find the largest preset each strategy can run. + Treat an out-of-memory outcome as capacity evidence, not throughput data. + +## Interpret the output carefully + +- `local_parameter_fraction` measures parameter elements stored by a rank. It + excludes gradients, optimizer state, activations, and communication buffers. +- FSDP2 peak memory does not fall exactly by `1 / world_size`: the active layer + is gathered for computation, activations remain local, and CUDA libraries + need temporary memory. +- Block wrapping permits layer-wise gathering and potential communication/ + computation overlap. Root-only wrapping gathers the whole model as one unit + and is included as a deliberately poor boundary choice. +- `parameters_synchronized` is meaningful for replicated DDP parameters. It is + `null` for FSDP2 because ranks hold complementary shards; global checksums are + reported instead. +- `--precision auto` is resolved before Lightning starts distributed workers + and therefore assumes homogeneous GPUs. Use an explicit precision on a + heterogeneous allocation. +- `barebones=True` disables logging, checkpoints, progress bars, and other + Trainer services that would distort a short benchmark. It is not a sensible + default for a production training application. +- Peak memory uses PyTorch's CUDA allocator counters and does not capture every + allocation made directly by NCCL or other CUDA libraries. +- Synthetic, reused input isolates model and communication costs. The results + are not end-to-end training performance and say nothing about model accuracy. +- The seed makes model initialization and inputs repeatable, but GPU kernels + are not forced into deterministic implementations. + +Activation checkpointing and distributed checkpoint files are intentionally +left out. They are useful follow-ups, but adding either would introduce a second +memory mechanism and obscure the first DDP/FSDP2 comparison. +The separate +[`activation-checkpointing`](../activation-checkpointing/) exercise isolates +that memory/recomputation trade-off before participants combine techniques. diff --git a/source-code/pytorch-lightning/fsdp/fsdp2_transformer.py b/source-code/pytorch-lightning/fsdp/fsdp2_transformer.py new file mode 100644 index 0000000..f2480a0 --- /dev/null +++ b/source-code/pytorch-lightning/fsdp/fsdp2_transformer.py @@ -0,0 +1,636 @@ +#!/usr/bin/env python3 +"""Compare Lightning DDP and FSDP2 on a synthetic transformer. + +This is the Lightning counterpart of +``source-code/pytorch/fsdp/fsdp2_transformer.py``. It uses the same model, +synthetic token batches, optimizer, presets, warm-up period, measurements, and +JSON result fields. Lightning owns process setup, device placement, backward +propagation, and optimizer execution. + +Inside a single-node Slurm allocation with four tasks and four GPUs:: + + srun python fsdp2_transformer.py --strategy fsdp2 --devices 4 \ + --preset medium --output result-fsdp2.json + +Outside Slurm, Lightning can launch the worker processes itself:: + + python fsdp2_transformer.py --strategy fsdp2 --devices 4 \ + --preset medium --output result-fsdp2.json + +No model, tokenizer, weights, or dataset are downloaded. FSDP2 is useful for +reducing model-state memory, but can be slower than DDP when the complete model +already fits comfortably on every GPU. +""" + +from __future__ import annotations + +import argparse +import json +import math +import os +import platform +import socket +import time +from dataclasses import asdict, dataclass +from datetime import timedelta +from pathlib import Path + +import lightning as L +import torch +from lightning.pytorch.strategies import DDPStrategy, ModelParallelStrategy +from torch import Tensor, nn +from torch.distributed import ReduceOp +from torch.distributed.fsdp import MixedPrecisionPolicy, fully_shard +from torch.distributed.tensor import DTensor +from torch.utils.data import DataLoader + +GIBIBYTE = 2**30 + + +@dataclass(frozen=True) +class ModelConfig: + """Configuration for one synthetic transformer preset.""" + + layers: int + hidden_size: int + attention_heads: int + feedforward_size: int + sequence_length: int + vocabulary_size: int = 4096 + classes: int = 16 + + +PRESETS = { + "small": ModelConfig( + layers=12, + hidden_size=768, + attention_heads=12, + feedforward_size=3072, + sequence_length=256, + ), + "medium": ModelConfig( + layers=24, + hidden_size=1024, + attention_heads=16, + feedforward_size=4096, + sequence_length=256, + ), + "large": ModelConfig( + layers=32, + hidden_size=1280, + attention_heads=20, + feedforward_size=5120, + sequence_length=256, + ), +} + + +def positive_integer(value: str) -> int: + """Parse a positive command-line integer.""" + + number = int(value) + if number <= 0: + raise argparse.ArgumentTypeError("must be a positive integer") + return number + + +def parse_arguments() -> argparse.Namespace: + """Parse arguments and reject invalid runs before Trainer startup.""" + + parser = argparse.ArgumentParser( + description="Compare Lightning DDP and FSDP2 with a synthetic transformer.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + parser.add_argument("--strategy", choices=("ddp", "fsdp2"), required=True) + parser.add_argument("--preset", choices=tuple(PRESETS), default="small") + parser.add_argument( + "--fsdp-wrap", + choices=("block", "root"), + default="block", + help="FSDP2 communication-group boundary; ignored for DDP", + ) + batches = parser.add_mutually_exclusive_group() + batches.add_argument( + "--batch-size-per-device", + type=positive_integer, + default=1, + help="samples per GPU; keeping this fixed is weak scaling", + ) + batches.add_argument( + "--global-batch-size", + type=positive_integer, + help="total samples across GPUs; must be divisible by devices x nodes", + ) + parser.add_argument( + "--warmup-steps", type=positive_integer, default=5, help="untimed steps" + ) + parser.add_argument( + "--steps", type=positive_integer, default=15, help="timed optimizer steps" + ) + parser.add_argument( + "--precision", + choices=("auto", "fp32", "bf16"), + default="auto", + help="auto uses BF16 when supported by the selected GPU, otherwise FP32", + ) + parser.add_argument("--seed", type=int, default=1234) + parser.add_argument( + "--devices", + type=positive_integer, + default=1, + help="GPUs per node; under Slurm this must match --ntasks-per-node", + ) + parser.add_argument( + "--num-nodes", type=positive_integer, default=1, help="Slurm node count" + ) + parser.add_argument( + "--output", type=Path, help="optional JSON result path written by rank zero" + ) + parser.add_argument( + "--overwrite-output", + action="store_true", + help="allow replacement of an existing output file", + ) + arguments = parser.parse_args() + + if arguments.seed < 0: + parser.error("--seed must be non-negative") + if arguments.output is None and arguments.overwrite_output: + parser.error("--overwrite-output requires --output") + if arguments.output is not None: + if arguments.output.is_dir(): + parser.error(f"output path is a directory: {arguments.output}") + if arguments.output.exists() and not arguments.overwrite_output: + parser.error( + f"output already exists: {arguments.output}; " + "use --overwrite-output to replace it" + ) + if not arguments.output.parent.exists(): + parser.error(f"output directory does not exist: {arguments.output.parent}") + + expected_world_size = arguments.devices * arguments.num_nodes + if ( + arguments.global_batch_size is not None + and arguments.global_batch_size % expected_world_size != 0 + ): + parser.error( + f"--global-batch-size={arguments.global_batch_size} is not divisible " + f"by devices x nodes={expected_world_size}" + ) + return arguments + + +def resolve_precision(requested: str) -> str: + """Resolve the shared CLI precision before Lightning launches workers.""" + + if not torch.cuda.is_available(): + raise RuntimeError("CUDA is unavailable; this benchmark requires GPUs") + if requested == "fp32": + return "fp32" + if requested == "bf16": + if not torch.cuda.is_bf16_supported(): + raise ValueError( + "BF16 was requested, but the selected GPU does not support it" + ) + return "bf16" + return "bf16" if torch.cuda.is_bf16_supported() else "fp32" + + +class TransformerBlock(nn.Module): + """Pre-normalized self-attention and feed-forward transformer block.""" + + def __init__(self, config: ModelConfig) -> None: + super().__init__() + self.attention_norm = nn.LayerNorm(config.hidden_size) + self.attention = nn.MultiheadAttention( + embed_dim=config.hidden_size, + num_heads=config.attention_heads, + dropout=0.0, + bias=False, + batch_first=True, + ) + self.feedforward_norm = nn.LayerNorm(config.hidden_size) + self.feedforward = nn.Sequential( + nn.Linear(config.hidden_size, config.feedforward_size, bias=False), + nn.GELU(approximate="tanh"), + nn.Linear(config.feedforward_size, config.hidden_size, bias=False), + ) + + def forward(self, hidden_states: Tensor) -> Tensor: + """Apply one residual attention and feed-forward block.""" + + normalized = self.attention_norm(hidden_states) + attention_output, _ = self.attention( + normalized, normalized, normalized, need_weights=False + ) + hidden_states = hidden_states + attention_output + return hidden_states + self.feedforward(self.feedforward_norm(hidden_states)) + + +class SyntheticTransformer(nn.Module): + """Encoder-style transformer for a synthetic sequence classification task.""" + + def __init__(self, config: ModelConfig) -> None: + super().__init__() + self.token_embedding = nn.Embedding(config.vocabulary_size, config.hidden_size) + self.position_embedding = nn.Parameter( + torch.empty(config.sequence_length, config.hidden_size) + ) + nn.init.normal_(self.position_embedding, mean=0.0, std=0.02) + self.blocks = nn.ModuleList( + TransformerBlock(config) for _ in range(config.layers) + ) + self.output_norm = nn.LayerNorm(config.hidden_size) + self.classifier = nn.Linear(config.hidden_size, config.classes, bias=False) + + def forward(self, token_ids: Tensor) -> Tensor: + """Return sequence-classification logits for integer token IDs.""" + + hidden_states = self.token_embedding(token_ids) + hidden_states = hidden_states + self.position_embedding.unsqueeze(0) + for block in self.blocks: + hidden_states = block(hidden_states) + hidden_states = self.output_norm(hidden_states[:, 0]) + return self.classifier(hidden_states) + + +class TransformerBenchmark(L.LightningModule): + """Synthetic transformer workload with timing and reporting hooks.""" + + def __init__( + self, + *, + config: ModelConfig, + preset: str, + strategy_name: str, + fsdp_wrap: str, + batch_size_per_device: int, + global_batch_size: int | None, + warmup_steps: int, + measured_steps: int, + precision_requested: str, + precision_resolved: str, + seed: int, + output: Path | None, + ) -> None: + super().__init__() + self.config = config + self.preset = preset + self.strategy_name = strategy_name + self.fsdp_wrap = fsdp_wrap + self.batch_size_per_device_requested = batch_size_per_device + self.global_batch_size_requested = global_batch_size + self.warmup_steps = warmup_steps + self.measured_steps = measured_steps + self.precision_requested = precision_requested + self.precision_resolved = precision_resolved + self.seed = seed + self.output = output + + # Large layers belong in configure_model(), which Lightning invokes in + # a strategy-aware context. Keeping this hook idempotent is required. + self.model: SyntheticTransformer | None = None + self._global_parameter_count = 0 + self._local_parameter_count = 0 + self._token_ids: Tensor | None = None + self._targets: Tensor | None = None + self._last_loss: Tensor | None = None + self._start_time: float | None = None + self._maxima: Tensor | None = None + self._batch_mode = "" + self._batch_size_per_device = 0 + self._global_batch_size = 0 + + def configure_model(self) -> None: + """Create the model and apply FSDP2 through Lightning's device mesh.""" + + if self.model is not None: + return + torch.manual_seed(self.seed) + self.model = SyntheticTransformer(self.config) + self._global_parameter_count = sum( + parameter.numel() for parameter in self.model.parameters() + ) + if self.strategy_name != "fsdp2": + return + if self.device_mesh is None: + raise RuntimeError("Lightning did not create the FSDP2 device mesh") + + data_parallel_mesh = self.device_mesh["data_parallel"] + mixed_precision_policy = ( + MixedPrecisionPolicy( + param_dtype=torch.bfloat16, + reduce_dtype=torch.float32, + ) + if self.precision_resolved == "bf16" + else MixedPrecisionPolicy() + ) + if self.fsdp_wrap == "block": + for block in self.model.blocks: + fully_shard( + block, + mesh=data_parallel_mesh, + mp_policy=mixed_precision_policy, + ) + fully_shard( + self.model, + mesh=data_parallel_mesh, + mp_policy=mixed_precision_policy, + ) + + def forward(self, token_ids: Tensor) -> Tensor: + """Apply the configured model to integer token IDs.""" + + if self.model is None: + raise RuntimeError("model was not created by configure_model()") + return self.model(token_ids) + + def setup(self, stage: str) -> None: + """Resolve batch semantics after Lightning establishes the world size.""" + + if stage != "fit": + return + world_size = self.trainer.world_size + if self.global_batch_size_requested is None: + self._batch_size_per_device = self.batch_size_per_device_requested + self._global_batch_size = self._batch_size_per_device * world_size + self._batch_mode = "fixed_per_device" + else: + if self.global_batch_size_requested % world_size != 0: + raise ValueError( + f"--global-batch-size={self.global_batch_size_requested} is not " + f"divisible by the actual world size {world_size}" + ) + self._batch_size_per_device = self.global_batch_size_requested // world_size + self._global_batch_size = self.global_batch_size_requested + self._batch_mode = "fixed_global" + + def on_train_start(self) -> None: + """Measure local shards and create one rank-specific synthetic batch.""" + + if self.model is None: + raise RuntimeError("model was not created by configure_model()") + self._local_parameter_count = local_parameter_elements(self.model) + generator = torch.Generator(device=self.device).manual_seed( + self.seed + self.global_rank + ) + self._token_ids = torch.randint( + 0, + self.config.vocabulary_size, + (self._batch_size_per_device, self.config.sequence_length), + generator=generator, + device=self.device, + ) + self._targets = torch.randint( + 0, + self.config.classes, + (self._batch_size_per_device,), + generator=generator, + device=self.device, + ) + + def training_step(self, _batch: int, _batch_idx: int) -> Tensor: + """Compute loss; Lightning runs backward and the optimizer update.""" + + if self._token_ids is None or self._targets is None: + raise RuntimeError("synthetic inputs were not initialized") + logits = self(self._token_ids) + loss = nn.functional.cross_entropy(logits.float(), self._targets) + self._last_loss = loss.detach() + return loss + + def configure_optimizers(self) -> torch.optim.Optimizer: + """Create AdamW after configure_model() has applied any sharding.""" + + if self.model is None: + raise RuntimeError("model was not created before optimizer setup") + return torch.optim.AdamW(self.model.parameters(), lr=1e-3) + + def train_dataloader(self) -> DataLoader: + """Supply one lightweight token for every optimizer step.""" + + total_steps = self.warmup_steps + self.measured_steps + return DataLoader(range(total_steps), batch_size=None, num_workers=0) + + def on_train_batch_start(self, _batch: int, batch_idx: int) -> None: + """Start synchronized timing after the warm-up batches.""" + + if batch_idx != self.warmup_steps: + return + self.trainer.strategy.barrier() + torch.cuda.synchronize(self.device) + torch.cuda.reset_peak_memory_stats(self.device) + self._start_time = time.perf_counter() + + def on_train_batch_end(self, _outputs: Tensor, _batch: int, batch_idx: int) -> None: + """Stop timing after the final measured optimizer step.""" + + total_steps = self.warmup_steps + self.measured_steps + if batch_idx + 1 != total_steps: + return + if self._start_time is None: + raise RuntimeError("benchmark timer was not started") + + torch.cuda.synchronize(self.device) + elapsed = time.perf_counter() - self._start_time + local = torch.tensor( + [ + elapsed, + float(torch.cuda.max_memory_allocated(self.device)), + float(torch.cuda.max_memory_reserved(self.device)), + ], + dtype=torch.float64, + device=self.device, + ) + self._maxima = self.trainer.strategy.reduce(local, reduce_op=ReduceOp.MAX) + + def _parameter_checksums(self) -> tuple[float, float, float | None]: + """Return global checksums and DDP replica disagreement when applicable.""" + + if self.model is None: + raise RuntimeError("model was not created by configure_model()") + checksum = torch.zeros(2, dtype=torch.float64, device=self.device) + with torch.no_grad(): + for parameter in self.model.parameters(): + values = ( + parameter.to_local() + if isinstance(parameter, DTensor) + else parameter + ) + values = values.detach().to(torch.float64) + checksum[0] += values.sum() + checksum[1] += values.square().sum() + + if self.strategy_name == "fsdp2": + checksum = self.trainer.strategy.reduce(checksum, reduce_op=ReduceOp.SUM) + return checksum[0].item(), checksum[1].item(), None + + minimum = self.trainer.strategy.reduce(checksum.clone(), reduce_op=ReduceOp.MIN) + maximum = self.trainer.strategy.reduce(checksum, reduce_op=ReduceOp.MAX) + difference = (maximum - minimum).abs().max().item() + return checksum[0].item(), checksum[1].item(), difference + + def on_train_end(self) -> None: + """Reduce correctness metrics and write one result on global rank zero.""" + + if self._last_loss is None or self._maxima is None: + raise RuntimeError("the benchmark did not complete all requested steps") + + mean_loss = self.trainer.strategy.reduce( + self._last_loss.to(torch.float64), reduce_op="mean" + ).item() + if not math.isfinite(mean_loss): + raise RuntimeError( + "the final loss is not finite; retry with --precision fp32 or the " + "small preset" + ) + checksum_sum, checksum_squared_sum, checksum_difference = ( + self._parameter_checksums() + ) + if not math.isfinite(checksum_sum) or not math.isfinite(checksum_squared_sum): + raise RuntimeError("model parameters contain non-finite values") + + elapsed, peak_allocated, peak_reserved = self._maxima.tolist() + samples = self.measured_steps * self._global_batch_size + tokens = samples * self.config.sequence_length + result = { + "model": "synthetic encoder-style transformer", + "data": "synthetic GPU-resident integer token sequences", + "strategy": self.strategy_name, + "fsdp_wrap": (self.fsdp_wrap if self.strategy_name == "fsdp2" else None), + "preset": self.preset, + "model_config": asdict(self.config), + "global_parameter_count": self._global_parameter_count, + "local_parameter_elements": self._local_parameter_count, + "local_parameter_fraction": ( + self._local_parameter_count / self._global_parameter_count + ), + "model_parameters_fp32_gib": (4 * self._global_parameter_count / GIBIBYTE), + "batch_mode": self._batch_mode, + "batch_size_per_device": self._batch_size_per_device, + "global_batch_size": self._global_batch_size, + "world_size": self.trainer.world_size, + "warmup_steps": self.warmup_steps, + "measured_steps": self.measured_steps, + "precision_requested": self.precision_requested, + "precision_resolved": self.precision_resolved, + "seed": self.seed, + "elapsed_seconds": elapsed, + "milliseconds_per_step": 1000.0 * elapsed / self.measured_steps, + "samples_per_second": samples / elapsed, + "tokens_per_second": tokens / elapsed, + "final_loss_mean": mean_loss, + "peak_allocated_gib": peak_allocated / GIBIBYTE, + "peak_reserved_gib": peak_reserved / GIBIBYTE, + "parameter_checksum_sum": checksum_sum, + "parameter_checksum_squared_sum": checksum_squared_sum, + "parameter_checksum_max_difference": checksum_difference, + "parameters_synchronized": ( + checksum_difference == 0.0 if checksum_difference is not None else None + ), + "gpu_name_rank_zero": torch.cuda.get_device_name(self.device), + "hostname_rank_zero": socket.gethostname(), + "pytorch_version": torch.__version__, + "lightning_version": L.__version__, + "cuda_version": torch.version.cuda, + "python_version": platform.python_version(), + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "lightning_barebones": True, + } + if self.trainer.is_global_zero: + print_summary(result) + if self.output is not None: + text = json.dumps(result, indent=2, sort_keys=True) + self.output.write_text(f"{text}\n", encoding="utf-8") + print(f" JSON result: {self.output}") + + +def local_parameter_elements(model: nn.Module) -> int: + """Count parameter elements physically held by this rank when sharded.""" + + total = 0 + for parameter in model.parameters(): + if isinstance(parameter, DTensor): + total += parameter.to_local().numel() + else: + total += parameter.numel() + return total + + +def print_summary(result: dict[str, object]) -> None: + """Print a compact summary suitable for a Slurm log.""" + + print("Lightning DDP/FSDP2 synthetic transformer benchmark") + print(f" strategy: {result['strategy']}") + print(f" FSDP wrap: {result['fsdp_wrap']}") + print(f" preset: {result['preset']}") + print(f" GPUs: {result['world_size']}") + print(f" parameters: {result['global_parameter_count']:,}") + print(f" local param fraction: {result['local_parameter_fraction']:.3f}") + print(f" precision: {result['precision_resolved']}") + print(f" time/step: {result['milliseconds_per_step']:.3f} ms") + print(f" throughput: {result['tokens_per_second']:.1f} tokens/s") + print(f" peak allocated/GPU: {result['peak_allocated_gib']:.2f} GiB") + print(f" peak reserved/GPU: {result['peak_reserved_gib']:.2f} GiB") + if result["parameters_synchronized"] is not None: + print(f" parameters synchronized: {result['parameters_synchronized']}") + + +def make_strategy( + strategy_name: str, devices: int, num_nodes: int +) -> DDPStrategy | ModelParallelStrategy: + """Create the Lightning strategy for replicated or FSDP2 training.""" + + timeout = timedelta(minutes=5) + if strategy_name == "ddp": + return DDPStrategy(timeout=timeout, gradient_as_bucket_view=True) + return ModelParallelStrategy( + data_parallel_size=devices * num_nodes, + tensor_parallel_size=1, + timeout=timeout, + ) + + +def main() -> None: + """Create the module and run the selected barebones Lightning Trainer.""" + + arguments = parse_arguments() + resolved_precision = resolve_precision(arguments.precision) + trainer_precision = ( + "bf16-mixed" + if arguments.strategy == "ddp" and resolved_precision == "bf16" + else "32-true" + ) + L.seed_everything(arguments.seed, workers=True) + model = TransformerBenchmark( + config=PRESETS[arguments.preset], + preset=arguments.preset, + strategy_name=arguments.strategy, + fsdp_wrap=arguments.fsdp_wrap, + batch_size_per_device=arguments.batch_size_per_device, + global_batch_size=arguments.global_batch_size, + warmup_steps=arguments.warmup_steps, + measured_steps=arguments.steps, + precision_requested=arguments.precision, + precision_resolved=resolved_precision, + seed=arguments.seed, + output=arguments.output, + ) + trainer = L.Trainer( + accelerator="gpu", + devices=arguments.devices, + num_nodes=arguments.num_nodes, + strategy=make_strategy( + arguments.strategy, arguments.devices, arguments.num_nodes + ), + precision=trainer_precision, + max_steps=arguments.warmup_steps + arguments.steps, + max_epochs=1, + use_distributed_sampler=False, + barebones=True, + ) + trainer.fit(model) + + +if __name__ == "__main__": + main() diff --git a/source-code/pytorch/README.md b/source-code/pytorch/README.md index 447a724..82ba8a5 100644 --- a/source-code/pytorch/README.md +++ b/source-code/pytorch/README.md @@ -15,6 +15,10 @@ natural language processing, computer vision, and reinforcement learning. 1. `mnist_mlp.ipynb`: Jupyter notebook that trains and compares multilayer perceptrons with and without dropout on the MNIST dataset. It also covers checkpointing, confusion matrices, and sensitivity to initialization. +1. `mnist_cross_validation.ipynb`: Jupyter notebook that introduces stratified + cross-validation with a compact MNIST multilayer perceptron. It covers + paired model comparison, fold-to-fold variation, leakage prevention, and + one final test-set evaluation. 1. `mnist_cnn.ipynb`: Jupyter notebook that demonstrates how to train a simple neural network on the MNIST dataset using PyTorch. It includes code for loading the dataset, defining the model architecture, training the model, @@ -23,9 +27,13 @@ natural language processing, computer vision, and reinforcement learning. tensors. It covers the basics of tensor operations, including creation, indexing, slicing, and mathematical operations. This notebook serves as a foundation for understanding how to work with data in PyTorch. -1. `environment.yml`: Conda environment file that specifies the dependencies - required to run the PyTorch notebooks. It includes PyTorch and other - necessary libraries. -1. `pytorch_linux64_conda_specs.txt`: Text file containing the specifications - for creating a Conda environment with PyTorch for Linux 64-bit systems. - It lists the required packages and their versions. +1. `ddp`: directory containing code to illustrate the use of Distributed Data + Parallel (DDP) in PyTorch. +1. [`activation-checkpointing/`](activation-checkpointing/): hands-on material + measuring the activation-memory versus recomputation trade-off in a native + PyTorch DDP workload. +1. [`memory-diagnostics/`](memory-diagnostics/): hands-on exercise using + phase-by-phase CUDA measurements to distinguish activation, optimizer-state, + and retained-graph memory pressure. +1. [`fsdp/`](fsdp/): batch-friendly material comparing DDP with PyTorch FSDP2 + using a synthetic transformer. diff --git a/source-code/pytorch/activation-checkpointing/README.md b/source-code/pytorch/activation-checkpointing/README.md new file mode 100644 index 0000000..515377e --- /dev/null +++ b/source-code/pytorch/activation-checkpointing/README.md @@ -0,0 +1,184 @@ +# PyTorch activation-checkpointing exercise + +[`activation_checkpointing.py`](activation_checkpointing.py) measures the +memory/time trade-off created by activation checkpointing in a native PyTorch +DDP training loop. It uses a synthetic transformer and GPU-resident token +batches, so no model, weights, tokenizer, or dataset are downloaded. + +Activation checkpointing retains the inputs to selected transformer blocks but +discards their internal forward activations. Backward recomputes those blocks. +This can reduce peak activation memory, but it adds computation. It does not +shard parameters, gradients, or optimizer state. + +## Learning objectives, prerequisites, and duration + +After this 40–50 minute exercise, participants should be able to: + +1. predict how activation checkpointing changes peak memory and step time; +2. measure the trade-off while keeping model, batch, precision, and GPU count + fixed; +3. distinguish persistent allocation from the peak created during a training + cycle; +4. choose checkpoint boundaries based on measured memory pressure rather than + enabling checkpointing indiscriminately. + +Required prerequisites are basic PyTorch training knowledge, the preceding DDP +material, a CUDA-enabled PyTorch environment, and at least one CUDA GPU. More +GPUs can be used, but checkpointing acts independently inside each DDP replica. +The repository's [`environment_gpu.yml`](../../../environment_gpu.yml) supplies +the intended PyTorch environment. + +## Workload and safe starting point + +Start with the `small` preset and validate it on the actual course hardware. +The `medium` preset makes activation pressure more visible but may require +reducing the local batch on smaller GPUs. + +| Preset | Blocks | Hidden size | Sequence | Parameters | FP32 parameters only | +|---|---:|---:|---:|---:|---:| +| `small` | 8 | 512 | 512 | 27,550,720 | 0.10 GiB | +| `medium` | 12 | 768 | 768 | 88,720,896 | 0.33 GiB | + +The parameter-memory column excludes gradients, DDP buckets, activations, +temporary attention workspaces, allocator fragmentation, and CUDA/NCCL state. +The script deliberately uses stateless SGD so optimizer state does not obscure +the activation-memory comparison. + +`--checkpoint-every 0` disables checkpointing. A value of `1` checkpoints every +transformer block; `2` checkpoints blocks 0, 2, 4, and so forth. Larger +intervals save fewer activations and perform less recomputation. + +## Core code map + +Function and class names are more durable than line numbers if the file changes. + +| Area | Function or class and line | What to inspect | +|---|---|---| +| Options and validation | [`parse_arguments()` — line 90](activation_checkpointing.py#L90) | Defines checkpoint interval, model preset, batch semantics, precision, timing, and protected JSON output. | +| Distributed setup | [`initialize_distributed()` — line 160](activation_checkpointing.py#L160) | Reads `torchrun` variables, binds one GPU per process, and initializes NCCL. | +| Precision setup | [`resolve_precision()` — line 212](activation_checkpointing.py#L212) | Selects BF16 only when every participating GPU supports it. | +| Transformer block | [`TransformerBlock` — line 232](activation_checkpointing.py#L232) | Defines the unit used as a checkpoint/recomputation boundary. | +| Checkpoint selection | [`SyntheticTransformer.forward()` — line 285](activation_checkpointing.py#L285) | Applies non-reentrant `torch.utils.checkpoint.checkpoint()` to the selected blocks. | +| Synthetic input | [`make_batch()` — line 304](activation_checkpointing.py#L304) | Creates a distinct GPU-resident token batch for each rank. | +| Training cycle | [`training_step()` — line 331](activation_checkpointing.py#L331) | Runs forward, backward/recomputation, DDP gradient synchronization, and the optimizer update. | +| Benchmark cycle | [`run()` — line 365](activation_checkpointing.py#L365) | Builds the model, warms up, resets peak statistics, times steps, reduces metrics, and constructs the result. | + +Start with `run()`, then inspect `SyntheticTransformer.forward()`. The rest of +the model is intentionally unchanged between checkpointed and uncheckpointed +runs. + +## Core comparison + +Before running, predict which metric should change most: + +- `steady_state_allocated_gib`; +- `peak_allocated_gib`; +- `milliseconds_per_step`. + +Use the same GPU count, preset, batch, precision, warm-up, and measured steps in +both runs: + +```bash +torchrun --standalone --nproc-per-node=1 activation_checkpointing.py \ + --preset small \ + --checkpoint-every 0 \ + --batch-size-per-device 4 \ + --output result-small-none.json + +torchrun --standalone --nproc-per-node=1 activation_checkpointing.py \ + --preset small \ + --checkpoint-every 1 \ + --batch-size-per-device 4 \ + --output result-small-every-block.json +``` + +Compare the two JSON files and calculate: + +```text +memory saving = 1 - checkpointed peak / uncheckpointed peak +time overhead = checkpointed time per step / uncheckpointed time per step - 1 +``` + +There is no universal expected percentage. A successful result keeps the +scientific workload fixed, shows `parameters_synchronized: true`, and supports +an explanation of the observed memory/time trade-off. Normally the checkpointed +run has a lower peak and a longer step time. If the difference is lost in the +persistent-memory baseline, increase the batch or try `medium`—but change the +same option in both comparison runs. + +## Hands-on tasks + +1. Predict the ordering of steady allocation, peak allocation, and step time + for checkpoint intervals 0, 1, and 2. +2. Run the uncheckpointed and every-block commands above. +3. Verify that model configuration, batch, precision, and parameter count are + identical before comparing the peak and time. +4. Run `--checkpoint-every 2`. Decide whether its compromise is preferable on + the allocated GPU, and justify the decision with both memory and time. +5. Increase `--batch-size-per-device` equally in paired runs. Find one batch + that fails without checkpointing but succeeds with it, if hardware and time + permit. Treat the failure as capacity evidence, not as a performance result. +6. Explain why activation checkpointing is a plausible response when memory + grows with microbatch or sequence length, but not when parameters alone do + not fit. + +The exercise is complete when the participant can recommend one interval—or +recommend no checkpointing—and state the measured reason. Merely producing JSON +files is not sufficient. + +## Slurm batch example + +This single-node example asks Slurm for one launcher task and two GPUs; +`torchrun` creates one process per GPU. Use local scheduler directives where +they differ. + +```bash +#!/usr/bin/env bash +#SBATCH --nodes=1 +#SBATCH --ntasks-per-node=1 +#SBATCH --gpus-per-node=2 +#SBATCH --time=00:10:00 + +set -euo pipefail + +srun torchrun --standalone --nproc-per-node=2 activation_checkpointing.py \ + --checkpoint-every 0 \ + --batch-size-per-device 4 \ + --output result-none.json + +srun torchrun --standalone --nproc-per-node=2 activation_checkpointing.py \ + --checkpoint-every 1 \ + --batch-size-per-device 4 \ + --output result-checkpoint.json +``` + +For a pure checkpointing comparison, one GPU is enough and avoids DDP +communication noise. Two or more GPUs connect the result to the DDP material +and verify that checkpointing does not replace data parallelism. + +## Interpretation and limitations + +- `steady_state_allocated_gib` is sampled after warm-up and after gradients are + cleared. `peak_allocated_gib` captures the maximum live PyTorch allocation + during measured forward/backward/optimizer cycles. +- Compare allocated memory first. Reserved memory includes cached blocks and may + remain high after tensors have been released. +- The code uses the recommended non-reentrant checkpoint implementation. + Checkpoint boundaries are whole transformer blocks, not arbitrary individual + operations. +- The model has no stochastic dropout, so `preserve_rng_state=False` avoids + unnecessary random-state work. Real checkpointed regions containing dropout + normally need RNG-state preservation to reproduce the uncheckpointed + computation. +- Recomputing every block is not automatically optimal. Partial checkpointing + can be faster when only a modest amount of memory must be recovered. +- Fused attention kernels already avoid materializing some intermediates. + Consequently, the saving depends on GPU, PyTorch version, precision, shapes, + and selected backend. +- CUDA allocator metrics omit some allocations made directly by libraries such + as NCCL. Synthetic reused inputs also exclude data-pipeline costs and say + nothing about model accuracy. + +See the current PyTorch +[`torch.utils.checkpoint` documentation](https://docs.pytorch.org/docs/stable/checkpoint.html) +for API details and determinism limitations. diff --git a/source-code/pytorch/activation-checkpointing/activation_checkpointing.py b/source-code/pytorch/activation-checkpointing/activation_checkpointing.py new file mode 100644 index 0000000..b37479c --- /dev/null +++ b/source-code/pytorch/activation-checkpointing/activation_checkpointing.py @@ -0,0 +1,512 @@ +#!/usr/bin/env python3 +"""Measure the memory/time trade-off of activation checkpointing with DDP. + +The model and batches are synthetic and are created locally. Compare otherwise +identical runs with ``--checkpoint-every 0`` and ``--checkpoint-every 1``:: + + torchrun --standalone --nproc-per-node=1 activation_checkpointing.py \ + --checkpoint-every 0 --output result-no-checkpoint.json + torchrun --standalone --nproc-per-node=1 activation_checkpointing.py \ + --checkpoint-every 1 --output result-checkpoint.json + +Activation checkpointing discards selected intermediate activations during the +forward pass and recomputes them during backward. It does not shard parameters, +gradients, or optimizer state. +""" + +from __future__ import annotations + +import argparse +import json +import math +import os +import platform +import socket +import sys +import time +from dataclasses import asdict, dataclass +from datetime import timedelta +from pathlib import Path +from typing import Any + +import torch +import torch.distributed as dist +from torch import Tensor, nn +from torch.nn.parallel import DistributedDataParallel as DDP +from torch.utils.checkpoint import checkpoint + +GIBIBYTE = 2**30 + + +@dataclass(frozen=True) +class ModelConfig: + """Configuration for one synthetic transformer preset.""" + + layers: int + hidden_size: int + attention_heads: int + feedforward_size: int + sequence_length: int + vocabulary_size: int = 4096 + classes: int = 16 + + +PRESETS = { + "small": ModelConfig( + layers=8, + hidden_size=512, + attention_heads=8, + feedforward_size=2048, + sequence_length=512, + ), + "medium": ModelConfig( + layers=12, + hidden_size=768, + attention_heads=12, + feedforward_size=3072, + sequence_length=768, + ), +} + + +def positive_integer(value: str) -> int: + """Parse a positive command-line integer.""" + + number = int(value) + if number <= 0: + raise argparse.ArgumentTypeError("must be a positive integer") + return number + + +def non_negative_integer(value: str) -> int: + """Parse a non-negative command-line integer.""" + + number = int(value) + if number < 0: + raise argparse.ArgumentTypeError("must be a non-negative integer") + return number + + +def parse_arguments() -> argparse.Namespace: + """Parse arguments and reject invalid output behavior before GPU setup.""" + + parser = argparse.ArgumentParser( + description="Benchmark activation checkpointing with PyTorch DDP.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + parser.add_argument("--preset", choices=tuple(PRESETS), default="small") + parser.add_argument( + "--checkpoint-every", + type=non_negative_integer, + default=0, + metavar="N", + help="checkpoint every Nth transformer block; 0 disables checkpointing", + ) + batches = parser.add_mutually_exclusive_group() + batches.add_argument( + "--batch-size-per-device", + type=positive_integer, + default=4, + help="samples per GPU; keeping this fixed is weak scaling", + ) + batches.add_argument( + "--global-batch-size", + type=positive_integer, + help="total samples across GPUs; must be divisible by WORLD_SIZE", + ) + parser.add_argument( + "--warmup-steps", type=positive_integer, default=3, help="untimed steps" + ) + parser.add_argument( + "--steps", type=positive_integer, default=10, help="timed optimizer steps" + ) + parser.add_argument( + "--precision", + choices=("auto", "fp32", "bf16"), + default="auto", + help="auto uses BF16 when every GPU supports it, otherwise FP32", + ) + parser.add_argument("--seed", type=int, default=1234) + parser.add_argument( + "--output", type=Path, help="optional JSON result path written by rank zero" + ) + parser.add_argument( + "--overwrite-output", + action="store_true", + help="allow replacement of an existing output file", + ) + parser.add_argument( + "--local-rank", "--local_rank", type=int, help=argparse.SUPPRESS + ) + arguments = parser.parse_args() + + if arguments.seed < 0: + parser.error("--seed must be non-negative") + if arguments.output is None and arguments.overwrite_output: + parser.error("--overwrite-output requires --output") + if arguments.output is not None: + if arguments.output.is_dir(): + parser.error(f"output path is a directory: {arguments.output}") + if arguments.output.exists() and not arguments.overwrite_output: + parser.error( + f"output already exists: {arguments.output}; " + "use --overwrite-output to replace it" + ) + if not arguments.output.parent.exists(): + parser.error(f"output directory does not exist: {arguments.output.parent}") + return arguments + + +def initialize_distributed() -> tuple[int, int, int, torch.device]: + """Initialize NCCL and bind this process to its torchrun GPU.""" + + required = ("LOCAL_RANK", "RANK", "WORLD_SIZE", "MASTER_ADDR", "MASTER_PORT") + missing = [name for name in required if name not in os.environ] + if missing: + raise RuntimeError( + f"missing torchrun variables {', '.join(missing)}; launch with, for " + "example, 'torchrun --standalone --nproc-per-node=1 " + "activation_checkpointing.py'" + ) + if not torch.cuda.is_available(): + raise RuntimeError("CUDA is unavailable; this benchmark requires a GPU") + + local_rank = int(os.environ["LOCAL_RANK"]) + rank = int(os.environ["RANK"]) + world_size = int(os.environ["WORLD_SIZE"]) + visible_devices = torch.cuda.device_count() + if not 0 <= local_rank < visible_devices: + raise RuntimeError( + f"LOCAL_RANK={local_rank}, but this process sees " + f"{visible_devices} CUDA device(s)" + ) + + torch.cuda.set_device(local_rank) + device = torch.device("cuda", local_rank) + dist.init_process_group( + backend="nccl", init_method="env://", timeout=timedelta(minutes=5) + ) + return local_rank, rank, world_size, device + + +def resolve_batch_sizes( + arguments: argparse.Namespace, world_size: int +) -> tuple[int, int, str]: + """Resolve per-device and global batch sizes after distributed setup.""" + + if arguments.global_batch_size is None: + per_device = arguments.batch_size_per_device + return per_device, per_device * world_size, "fixed_per_device" + if arguments.global_batch_size % world_size != 0: + raise ValueError( + f"--global-batch-size={arguments.global_batch_size} is not divisible " + f"by WORLD_SIZE={world_size}" + ) + return ( + arguments.global_batch_size // world_size, + arguments.global_batch_size, + "fixed_global", + ) + + +def resolve_precision(requested: str, device: torch.device) -> tuple[str, bool]: + """Choose FP32 or BF16 consistently across all participating GPUs.""" + + bf16_supported = torch.tensor( + int(torch.cuda.is_bf16_supported()), dtype=torch.int32, device=device + ) + dist.all_reduce(bf16_supported, op=dist.ReduceOp.MIN) + all_support_bf16 = bool(bf16_supported.item()) + + if requested == "fp32": + return "fp32", False + if requested == "bf16": + if not all_support_bf16: + raise ValueError( + "BF16 was requested, but at least one GPU does not support it" + ) + return "bf16", True + return ("bf16", True) if all_support_bf16 else ("fp32", False) + + +class TransformerBlock(nn.Module): + """Pre-normalized self-attention and feed-forward transformer block.""" + + def __init__(self, config: ModelConfig) -> None: + super().__init__() + self.attention_norm = nn.LayerNorm(config.hidden_size) + self.attention = nn.MultiheadAttention( + embed_dim=config.hidden_size, + num_heads=config.attention_heads, + dropout=0.0, + bias=False, + batch_first=True, + ) + self.feedforward_norm = nn.LayerNorm(config.hidden_size) + self.feedforward = nn.Sequential( + nn.Linear(config.hidden_size, config.feedforward_size, bias=False), + nn.GELU(approximate="tanh"), + nn.Linear(config.feedforward_size, config.hidden_size, bias=False), + ) + + def forward(self, hidden_states: Tensor) -> Tensor: + """Apply one residual attention and feed-forward block.""" + + normalized = self.attention_norm(hidden_states) + attention_output, _ = self.attention( + normalized, normalized, normalized, need_weights=False + ) + hidden_states = hidden_states + attention_output + return hidden_states + self.feedforward(self.feedforward_norm(hidden_states)) + + +class SyntheticTransformer(nn.Module): + """Transformer whose selected blocks discard forward activations.""" + + def __init__(self, config: ModelConfig, checkpoint_every: int) -> None: + super().__init__() + self.checkpoint_every = checkpoint_every + self.token_embedding = nn.Embedding(config.vocabulary_size, config.hidden_size) + self.position_embedding = nn.Parameter( + torch.empty(config.sequence_length, config.hidden_size) + ) + nn.init.normal_(self.position_embedding, mean=0.0, std=0.02) + self.blocks = nn.ModuleList( + TransformerBlock(config) for _ in range(config.layers) + ) + self.output_norm = nn.LayerNorm(config.hidden_size) + self.classifier = nn.Linear(config.hidden_size, config.classes, bias=False) + + def should_checkpoint(self, block_index: int) -> bool: + """Return whether a block belongs to the selected checkpoint interval.""" + + return self.checkpoint_every > 0 and block_index % self.checkpoint_every == 0 + + def forward(self, token_ids: Tensor) -> Tensor: + """Return logits while checkpointing the selected transformer blocks.""" + + hidden_states = self.token_embedding(token_ids) + hidden_states = hidden_states + self.position_embedding.unsqueeze(0) + for block_index, block in enumerate(self.blocks): + if self.should_checkpoint(block_index): + hidden_states = checkpoint( + block, + hidden_states, + use_reentrant=False, + preserve_rng_state=False, + ) + else: + hidden_states = block(hidden_states) + hidden_states = self.output_norm(hidden_states[:, 0]) + return self.classifier(hidden_states) + + +def make_batch( + config: ModelConfig, + batch_size: int, + rank: int, + seed: int, + device: torch.device, +) -> tuple[Tensor, Tensor]: + """Create one rank-specific, GPU-resident synthetic batch.""" + + generator = torch.Generator(device=device).manual_seed(seed + rank) + token_ids = torch.randint( + 0, + config.vocabulary_size, + (batch_size, config.sequence_length), + generator=generator, + device=device, + ) + targets = torch.randint( + 0, + config.classes, + (batch_size,), + generator=generator, + device=device, + ) + return token_ids, targets + + +def training_step( + model: DDP, + token_ids: Tensor, + targets: Tensor, + optimizer: torch.optim.Optimizer, + use_bf16: bool, +) -> Tensor: + """Run forward, backward, DDP synchronization, and the optimizer update.""" + + optimizer.zero_grad(set_to_none=True) + with torch.autocast(device_type="cuda", dtype=torch.bfloat16, enabled=use_bf16): + logits = model(token_ids) + loss = nn.functional.cross_entropy(logits.float(), targets) + loss.backward() + optimizer.step() + return loss.detach() + + +def parameter_checksum_difference(model: nn.Module, device: torch.device) -> float: + """Return the largest checksum difference between DDP replicas.""" + + checksum = torch.zeros(2, dtype=torch.float64, device=device) + with torch.no_grad(): + for parameter in model.parameters(): + values = parameter.detach().to(torch.float64) + checksum[0] += values.sum() + checksum[1] += values.square().sum() + minimum = checksum.clone() + maximum = checksum.clone() + dist.all_reduce(minimum, op=dist.ReduceOp.MIN) + dist.all_reduce(maximum, op=dist.ReduceOp.MAX) + return (maximum - minimum).abs().max().item() + + +def run(arguments: argparse.Namespace) -> dict[str, Any]: + """Run one activation-checkpoint configuration and return its metrics.""" + + local_rank, rank, world_size, device = initialize_distributed() + per_device_batch, global_batch, batch_mode = resolve_batch_sizes( + arguments, world_size + ) + precision, use_bf16 = resolve_precision(arguments.precision, device) + config = PRESETS[arguments.preset] + + torch.manual_seed(arguments.seed) + model = SyntheticTransformer(config, arguments.checkpoint_every).to(device) + parameter_count = sum(parameter.numel() for parameter in model.parameters()) + checkpointed_blocks = sum( + model.should_checkpoint(index) for index in range(config.layers) + ) + distributed_model = DDP( + model, + device_ids=[local_rank], + output_device=local_rank, + gradient_as_bucket_view=True, + ) + optimizer = torch.optim.SGD(distributed_model.parameters(), lr=1e-3) + token_ids, targets = make_batch( + config, per_device_batch, rank, arguments.seed, device + ) + + loss = torch.zeros((), device=device) + for _ in range(arguments.warmup_steps): + loss = training_step(distributed_model, token_ids, targets, optimizer, use_bf16) + + optimizer.zero_grad(set_to_none=True) + dist.barrier() + torch.cuda.synchronize(device) + steady_state_allocated = float(torch.cuda.memory_allocated(device)) + torch.cuda.reset_peak_memory_stats(device) + start_time = time.perf_counter() + for _ in range(arguments.steps): + loss = training_step(distributed_model, token_ids, targets, optimizer, use_bf16) + torch.cuda.synchronize(device) + elapsed = time.perf_counter() - start_time + + maxima = torch.tensor( + [ + elapsed, + steady_state_allocated, + float(torch.cuda.max_memory_allocated(device)), + float(torch.cuda.max_memory_reserved(device)), + ], + dtype=torch.float64, + device=device, + ) + dist.all_reduce(maxima, op=dist.ReduceOp.MAX) + elapsed, steady_state_allocated, peak_allocated, peak_reserved = maxima.tolist() + + loss = loss.to(torch.float64) + dist.all_reduce(loss, op=dist.ReduceOp.SUM) + mean_loss = loss.item() / world_size + if not math.isfinite(mean_loss): + raise RuntimeError( + "the final loss is not finite; retry with --precision fp32 or the " + "small preset" + ) + checksum_difference = parameter_checksum_difference(distributed_model, device) + + samples = arguments.steps * global_batch + tokens = samples * config.sequence_length + return { + "model": "synthetic encoder-style transformer", + "data": "synthetic GPU-resident integer token sequences", + "preset": arguments.preset, + "model_config": asdict(config), + "parameter_count": parameter_count, + "model_parameters_fp32_gib": 4 * parameter_count / GIBIBYTE, + "checkpoint_every_blocks": arguments.checkpoint_every, + "checkpointed_blocks": checkpointed_blocks, + "activation_checkpointing": checkpointed_blocks > 0, + "checkpoint_implementation": "torch.utils.checkpoint, non-reentrant", + "batch_mode": batch_mode, + "batch_size_per_device": per_device_batch, + "global_batch_size": global_batch, + "world_size": world_size, + "warmup_steps": arguments.warmup_steps, + "measured_steps": arguments.steps, + "precision_requested": arguments.precision, + "precision_resolved": precision, + "seed": arguments.seed, + "elapsed_seconds": elapsed, + "milliseconds_per_step": 1000.0 * elapsed / arguments.steps, + "samples_per_second": samples / elapsed, + "tokens_per_second": tokens / elapsed, + "final_loss_mean": mean_loss, + "steady_state_allocated_gib": steady_state_allocated / GIBIBYTE, + "peak_allocated_gib": peak_allocated / GIBIBYTE, + "peak_reserved_gib": peak_reserved / GIBIBYTE, + "parameter_checksum_max_difference": checksum_difference, + "parameters_synchronized": checksum_difference == 0.0, + "gpu_name_rank_zero": torch.cuda.get_device_name(device), + "hostname_rank_zero": socket.gethostname(), + "pytorch_version": torch.__version__, + "cuda_version": torch.version.cuda, + "python_version": platform.python_version(), + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + } + + +def print_summary(result: dict[str, Any]) -> None: + """Print a compact summary suitable for a Slurm log.""" + + print("PyTorch activation-checkpointing benchmark") + print(f" checkpoint interval: {result['checkpoint_every_blocks']}") + print(f" checkpointed blocks: {result['checkpointed_blocks']}") + print(f" preset: {result['preset']}") + print(f" GPUs: {result['world_size']}") + print(f" precision: {result['precision_resolved']}") + print(f" batch/device: {result['batch_size_per_device']}") + print(f" time/step: {result['milliseconds_per_step']:.3f} ms") + print(f" throughput: {result['tokens_per_second']:.1f} tokens/s") + print(f" steady allocation: {result['steady_state_allocated_gib']:.2f} GiB") + print(f" peak allocated/GPU: {result['peak_allocated_gib']:.2f} GiB") + print(f" peak reserved/GPU: {result['peak_reserved_gib']:.2f} GiB") + print(f" parameters synchronized: {result['parameters_synchronized']}") + + +def main() -> int: + """Parse options, run the benchmark, and write rank-zero output.""" + + arguments = parse_arguments() + try: + result = run(arguments) + if dist.get_rank() == 0: + print_summary(result) + if arguments.output is not None: + text = json.dumps(result, indent=2, sort_keys=True) + arguments.output.write_text(f"{text}\n", encoding="utf-8") + print(f" JSON result: {arguments.output}") + return 0 + except (OSError, RuntimeError, ValueError) as error: + rank = os.environ.get("RANK", "unknown") + print(f"rank {rank}: error: {error}", file=sys.stderr) + return 2 + finally: + if dist.is_initialized(): + dist.destroy_process_group() + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/source-code/pytorch/ddp/README.md b/source-code/pytorch/ddp/README.md new file mode 100644 index 0000000..f6cb1ae --- /dev/null +++ b/source-code/pytorch/ddp/README.md @@ -0,0 +1,62 @@ +# PyTorch DistributedDataParallel benchmark + +[`ddp_resnet50.py`](ddp_resnet50.py) measures the training throughput of a +randomly initialized ResNet-50 using native PyTorch +`DistributedDataParallel` (DDP). It creates synthetic ImageNet-shaped inputs +directly on each GPU, so no model weights or dataset are downloaded. + +The example is intended to compare one and multiple GPUs. It measures model +computation and gradient communication, not data-loading performance or model +accuracy. + +## Core code map + +The line numbers below refer to the current version of +[`ddp_resnet50.py`](ddp_resnet50.py). Function names are the more durable +reference if the file changes later. + +| Area | Function and line | What to inspect | +|---|---|---| +| Distributed setup | [`initialize_distributed()` — line 125](ddp_resnet50.py#L125) | Reads the environment created by `torchrun`, selects one GPU per process, and initializes the NCCL process group. | +| Batch interpretation | [`resolve_batch_sizes()` — line 156](ddp_resnet50.py#L156) | Distinguishes a fixed per-device batch from a fixed global batch. | +| Precision setup | [`resolve_precision()` — line 176](ddp_resnet50.py#L176) | Selects FP32, BF16, or FP16 consistently across all ranks. | +| Synthetic input | [`make_batch()` — line 202](ddp_resnet50.py#L202) | Creates a distinct GPU-resident image batch and labels for each rank. | +| One training cycle | [`training_step()` — line 213](ddp_resnet50.py#L213) | Runs zeroing, forward propagation, loss calculation, backward propagation, DDP gradient synchronization, and the optimizer update. | +| Model creation and DDP wrapper | [`run()` — line 258](ddp_resnet50.py#L258) | Creates ResNet-50 at line 271, wraps it in DDP at line 272, and creates the optimizer and gradient scaler at lines 278–279. | +| Warm-up and measured cycles | [`run()` — line 258](ddp_resnet50.py#L258) | Executes warm-up steps at lines 283–284 and the timed training loop at lines 286–305. | + +The `run()` function is the best starting point for reading the program because +it shows how the setup, input, model, and training-cycle functions fit together. + +## Run inside a Slurm allocation + +Use `torchrun` for both the one-GPU baseline and multi-GPU measurements so that +all runs follow the same DDP code path. For example, on a node assigned four +GPUs: + +```bash +torchrun --standalone --nproc-per-node=4 ddp_resnet50.py \ + --batch-size-per-device 32 \ + --output result-4gpu.json +``` + +For weak scaling, keep `--batch-size-per-device` fixed while changing the GPU +count. For strong scaling, keep the global batch fixed: + +```bash +torchrun --standalone --nproc-per-node=4 ddp_resnet50.py \ + --global-batch-size 128 \ + --output result-global128-4gpu.json +``` + +The JSON output records throughput, time per optimizer step, peak PyTorch CUDA +memory, the resolved precision, software versions, hardware information, and a +check that model parameters remained synchronized. PyTorch's memory counters do +not include every allocation made directly by CUDA libraries such as NCCL. + +## Related hands-on exercise + +The [`data-sharding`](data-sharding/) exercise supplies an intentionally buggy +DDP input pipeline and a complete reference solution. Participants inspect +per-rank sample identifiers, diagnose duplicated data ownership, and repair the +loader with `DistributedSampler` and per-epoch reshuffling. diff --git a/source-code/pytorch/ddp/data-sharding/README.md b/source-code/pytorch/ddp/data-sharding/README.md new file mode 100644 index 0000000..51c36bf --- /dev/null +++ b/source-code/pytorch/ddp/data-sharding/README.md @@ -0,0 +1,182 @@ +# Exercise: diagnose DDP data sharding + +This 30–40 minute exercise demonstrates a correctness problem that can be easy +to miss: native PyTorch `DistributedDataParallel` (DDP) synchronizes gradients, +but it does **not** automatically divide a dataset between ranks. + +The exercise uses a tiny deterministic dataset whose samples have visible +integer identifiers. It therefore completes quickly, needs no downloads, and +lets you inspect data ownership directly instead of inferring it from training +speed or model accuracy. + +## Learning objective and success criterion + +After the exercise, you should be able to diagnose duplicated sample ownership +from per-rank evidence and repair it with a `DistributedSampler`. + +A correct epoch has all three properties below: + +- `processed_assignments` equals `dataset_size`; +- `unique_samples` equals `dataset_size`; +- `duplicate_assignments` is zero. + +The resulting `exactly_once_global` field must therefore be `true`. + +## Prerequisites + +- basic familiarity with a PyTorch `Dataset` and `DataLoader`; +- the DDP setup introduced by the parent + [`ddp_resnet50.py`](../ddp_resnet50.py) example; +- an environment containing PyTorch with distributed support; +- at least two `torchrun` processes. GPUs are useful but not required for this + correctness exercise. + +## Files + +| File | Purpose | +|---|---| +| [`buggy_data_sharding.py`](buggy_data_sharding.py) | Starting point with an intentionally incorrect input pipeline. It reports the defect but exits successfully because the failure is the expected exercise result. | +| [`solution_data_sharding.py`](solution_data_sharding.py) | Complete reference implementation using `DistributedSampler` and `set_epoch()`. It exits unsuccessfully if the exactly-once check fails. | + +The scripts are intentionally similar. A file comparison makes the small but +important input-pipeline changes visible; it is not necessary to rewrite DDP +boilerplate during the lab. + +## Part 1: predict, run, and diagnose + +Before running the buggy program, predict the answers to these questions: + +1. With a dataset of 32 samples and two ranks, how many sample assignments + should one correct global epoch contain? +2. Does wrapping the model in DDP also alter the `DataLoader`? +3. If every rank constructs the same ordinary shuffled `DataLoader`, which + sample identifiers do you expect the ranks to share? + +Run the starter program on CPU from this directory: + +```bash +torchrun --standalone --nproc-per-node=2 buggy_data_sharding.py \ + --device cpu \ + --output buggy-report.json +``` + +On a GPU node, omit `--device cpu` or use `--device cuda`. With the defaults and +two ranks, the important output is: + +```text +assignments: 64; unique samples: 32; duplicate assignments: 32 +exactly once globally: False +``` + +Inspect the rank-specific sample-ID lists and the +`pairwise_rank_overlap` field in `buggy-report.json`. Explain why the model can +still train and remain synchronized even though this is not useful data +parallelism. + +## Part 2: repair the input pipeline + +Work in a personal copy of the buggy script. Change only the data-loading and +epoch setup needed to meet the success criterion. Do not use the reference +solution until you have a proposed diagnosis. + +### Hints + +1. DDP owns the model and gradient communication; look at + `make_dataloader()` for the separate data-ownership decision. +2. A `DistributedSampler` needs the number of replicas and this process's + global rank. When a sampler supplies indices, `DataLoader(shuffle=True)` is + neither needed nor allowed. +3. For deterministic shuffling that changes between epochs, call + `sampler.set_epoch(epoch)` before iterating over the loader. + +Run your repaired version with the same arguments. A correct two-rank run +should report 32 assignments, 32 unique samples, zero duplicate assignments, +and `exactly once globally: True` in every epoch. + +## Part 3: compare with the reference + +Run the complete solution: + +```bash +torchrun --standalone --nproc-per-node=2 solution_data_sharding.py \ + --device cpu \ + --output solution-report.json +``` + +Then compare the implementations: + +```bash +diff -u buggy_data_sharding.py solution_data_sharding.py +``` + +The essential repair is small: + +- `DistributedSampler` assigns a disjoint subset of indices to every rank; +- the loader receives `sampler=sampler` instead of `shuffle=True`; +- `sampler.set_epoch(epoch)` changes the sampler's deterministic shuffle seed + for each epoch. + +`set_epoch()` does not provide the sharding itself—the sampler does. Conversely, +the sampler can shard without `set_epoch()`, but its shuffled ordering then +repeats each epoch. As an extension, comment out `set_epoch()` in a copy of the +solution and compare the rank-specific order across epochs. + +## Run as a Slurm batch job + +For a single node with four assigned GPUs, one Slurm task can start four local +DDP processes: + +```bash +#!/usr/bin/env bash +#SBATCH --nodes=1 +#SBATCH --ntasks-per-node=1 +#SBATCH --gpus-per-node=4 +#SBATCH --time=00:05:00 + +srun torchrun --standalone --nproc-per-node=4 \ + solution_data_sharding.py \ + --dataset-size 32 \ + --output "solution-${SLURM_JOB_ID}.json" +``` + +Adapt the resource directives to the cluster; some sites require a GPU +partition, account, or module setup. The scripts use NCCL when CUDA is selected +and Gloo for the CPU fallback. + +## Core code map + +Function names are more durable than line numbers if the files change later. + +| Area | Buggy starter | Reference solution | What to inspect | +|---|---|---|---| +| Indexed input | [`IndexedClassificationDataset` — line 47](buggy_data_sharding.py#L47) | [`IndexedClassificationDataset` — line 45](solution_data_sharding.py#L45) | Creates deterministic samples and returns a visible sample ID with each item. | +| Distributed setup | [`initialize_distributed()` — line 131](buggy_data_sharding.py#L131) | [`initialize_distributed()` — line 129](solution_data_sharding.py#L129) | Reads `torchrun` variables, chooses NCCL/CUDA or Gloo/CPU, and initializes the process group. | +| Model creation | [`make_model()` — line 194](buggy_data_sharding.py#L194) | [`make_model()` — line 192](solution_data_sharding.py#L192) | Builds the same tiny classifier on every rank. | +| Input handling | [`make_dataloader()` — line 204](buggy_data_sharding.py#L204) | [`make_dataloader()` — line 202](solution_data_sharding.py#L202) | Contains the deliberate defect and its sampler-based repair. | +| Training cycle | [`train_one_epoch()` — line 221](buggy_data_sharding.py#L221) | [`train_one_epoch()` — line 230](solution_data_sharding.py#L230) | Runs forward, backward, DDP gradient synchronization, and the optimizer step while recording sample IDs. | +| Evidence | [`analyze_assignments()` — line 273](buggy_data_sharding.py#L273) | [`analyze_assignments()` — line 282](solution_data_sharding.py#L282) | Computes coverage, duplication, missing IDs, and pairwise rank overlap. | +| Orchestration | [`run()` — line 338](buggy_data_sharding.py#L338) | [`run()` — line 347](solution_data_sharding.py#L347) | Connects distributed setup, input, model construction, training, and reporting. | + +## Assumptions and limitations + +- The dataset size must be divisible by the world size. In general, + `DistributedSampler(drop_last=False)` pads its index list when divisibility is + impossible, so a few repeated samples can be expected rather than erroneous. + This exercise rejects that case to keep the exactly-once test unambiguous. +- Identical sample order is deliberately encouraged in the buggy script by + using the same loader seed on every rank. Independent seeds would change the + order but would **not** fix the ownership bug: every rank would still process + the complete dataset. +- A changed permutation is random behavior, not a mathematical guarantee for + tiny shards. The solution verifies exactly-once ownership and reports whether + each observed ordering changed; the call to `set_epoch()` is the relevant + implementation check. +- `gather_object()` is suitable for the small diagnostic lists used here, but + object collectives are inefficient for large datasets. Production code + should avoid gathering every sample ID during normal training and use compact + counters or purpose-built validation instead. + +## Further reading + +- [PyTorch `DistributedDataParallel` documentation](https://docs.pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html) +- [PyTorch `DistributedSampler` documentation](https://docs.pytorch.org/docs/stable/data.html#torch.utils.data.distributed.DistributedSampler) diff --git a/source-code/pytorch/ddp/data-sharding/buggy_data_sharding.py b/source-code/pytorch/ddp/data-sharding/buggy_data_sharding.py new file mode 100644 index 0000000..3859ac9 --- /dev/null +++ b/source-code/pytorch/ddp/data-sharding/buggy_data_sharding.py @@ -0,0 +1,435 @@ +#!/usr/bin/env python3 +"""Diagnose an intentionally incorrect DDP input pipeline. + +Run this program with at least two processes. It trains a tiny classifier and +records the sample identifiers processed by every rank. The input pipeline is +plausible for single-process training but intentionally incorrect for DDP. + +Example:: + + torchrun --standalone --nproc-per-node=2 buggy_data_sharding.py \ + --device cpu --output buggy-report.json + +The program exits successfully when it exposes the intended data-sharding +failure. That makes it convenient to use in a scheduled hands-on exercise. +""" + +from __future__ import annotations + +import argparse +import json +import os +import sys +from collections import Counter +from dataclasses import dataclass +from datetime import timedelta +from pathlib import Path +from typing import Any + +import torch +import torch.distributed as dist +from torch import Tensor, nn +from torch.nn.parallel import DistributedDataParallel as DDP +from torch.utils.data import DataLoader, Dataset + + +@dataclass(frozen=True) +class DistributedRuntime: + """Information about this process in the distributed job.""" + + local_rank: int + rank: int + world_size: int + device: torch.device + backend: str + + +class IndexedClassificationDataset(Dataset[tuple[Tensor, Tensor, int]]): + """Small deterministic dataset that exposes each sample's identifier.""" + + def __init__( + self, + size: int, + feature_count: int, + class_count: int, + seed: int, + ) -> None: + generator = torch.Generator().manual_seed(seed) + self.features = torch.randn(size, feature_count, generator=generator) + projection = torch.randn(feature_count, class_count, generator=generator) + self.targets = (self.features @ projection).argmax(dim=1) + + def __len__(self) -> int: + return self.features.shape[0] + + def __getitem__(self, index: int) -> tuple[Tensor, Tensor, int]: + return self.features[index], self.targets[index], index + + +def positive_integer(value: str) -> int: + """Parse a positive command-line integer.""" + + number = int(value) + if number <= 0: + raise argparse.ArgumentTypeError("must be a positive integer") + return number + + +def parse_arguments() -> argparse.Namespace: + """Parse and validate options that do not depend on the worker count.""" + + parser = argparse.ArgumentParser( + description="Expose a data-sharding bug in a native PyTorch DDP job.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + parser.add_argument("--dataset-size", type=positive_integer, default=32) + parser.add_argument("--batch-size", type=positive_integer, default=4) + parser.add_argument("--epochs", type=positive_integer, default=2) + parser.add_argument("--seed", type=int, default=1234) + parser.add_argument( + "--device", + choices=("auto", "cpu", "cuda"), + default="auto", + help="auto uses CUDA when available and CPU otherwise", + ) + parser.add_argument( + "--output", + type=Path, + help="optional JSON report path written by rank zero", + ) + parser.add_argument( + "--overwrite-output", + action="store_true", + help="allow replacement of an existing JSON report", + ) + parser.add_argument( + "--local-rank", "--local_rank", type=int, help=argparse.SUPPRESS + ) + arguments = parser.parse_args() + + if arguments.dataset_size > 256: + parser.error("--dataset-size must not exceed 256 in this lab exercise") + if arguments.epochs < 2: + parser.error("--epochs must be at least 2 to inspect epoch reshuffling") + if arguments.seed < 0: + parser.error("--seed must be non-negative") + if arguments.output is None and arguments.overwrite_output: + parser.error("--overwrite-output requires --output") + if arguments.output is not None: + if arguments.output.is_dir(): + parser.error(f"output path is a directory: {arguments.output}") + if arguments.output.exists() and not arguments.overwrite_output: + parser.error( + f"output already exists: {arguments.output}; use " + "--overwrite-output to replace it" + ) + if not arguments.output.parent.exists(): + parser.error(f"output directory does not exist: {arguments.output.parent}") + return arguments + + +def initialize_distributed(requested_device: str) -> DistributedRuntime: + """Initialize a torchrun process group and select this rank's device.""" + + required = ("LOCAL_RANK", "RANK", "WORLD_SIZE", "MASTER_ADDR", "MASTER_PORT") + missing = [name for name in required if name not in os.environ] + if missing: + raise RuntimeError( + f"missing torchrun variables {', '.join(missing)}; launch with " + "'torchrun --standalone --nproc-per-node=2 " + "buggy_data_sharding.py'" + ) + + local_rank = int(os.environ["LOCAL_RANK"]) + rank = int(os.environ["RANK"]) + world_size = int(os.environ["WORLD_SIZE"]) + if world_size < 2: + raise RuntimeError("this exercise requires at least two processes") + + use_cuda = requested_device == "cuda" or ( + requested_device == "auto" and torch.cuda.is_available() + ) + if requested_device == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("--device=cuda was requested, but CUDA is unavailable") + + if use_cuda: + visible_devices = torch.cuda.device_count() + if not 0 <= local_rank < visible_devices: + raise RuntimeError( + f"LOCAL_RANK={local_rank}, but this process sees " + f"{visible_devices} CUDA device(s)" + ) + torch.cuda.set_device(local_rank) + device = torch.device("cuda", local_rank) + backend = "nccl" + else: + device = torch.device("cpu") + backend = "gloo" + + dist.init_process_group( + backend=backend, init_method="env://", timeout=timedelta(minutes=5) + ) + return DistributedRuntime(local_rank, rank, world_size, device, backend) + + +def validate_distributed_arguments( + arguments: argparse.Namespace, runtime: DistributedRuntime +) -> None: + """Reject configurations that make the sharding evidence ambiguous.""" + + if arguments.dataset_size % runtime.world_size != 0: + raise ValueError( + f"--dataset-size={arguments.dataset_size} must be divisible by " + f"WORLD_SIZE={runtime.world_size}; otherwise DistributedSampler " + "pads its index list and the reference run can contain duplicates" + ) + intended_samples_per_rank = arguments.dataset_size // runtime.world_size + if arguments.batch_size > intended_samples_per_rank: + raise ValueError( + f"--batch-size={arguments.batch_size} exceeds the intended " + f"per-rank shard size {intended_samples_per_rank}" + ) + + +def make_model(feature_count: int, class_count: int) -> nn.Module: + """Create the deliberately small classifier used by the exercise.""" + + return nn.Sequential( + nn.Linear(feature_count, 32), + nn.ReLU(), + nn.Linear(32, class_count), + ) + + +def make_dataloader( + dataset: IndexedClassificationDataset, + batch_size: int, + seed: int, +) -> DataLoader[tuple[Tensor, Tensor, Tensor]]: + """Create the intentionally incorrect input pipeline for each rank.""" + + generator = torch.Generator().manual_seed(seed) + return DataLoader( + dataset, + batch_size=batch_size, + shuffle=True, + generator=generator, + num_workers=0, + ) + + +def train_one_epoch( + model: DDP, + dataloader: DataLoader[tuple[Tensor, Tensor, Tensor]], + optimizer: torch.optim.Optimizer, + device: torch.device, +) -> tuple[float, list[int]]: + """Train for one epoch and return global loss plus local sample IDs.""" + + model.train() + local_loss_sum = 0.0 + local_example_count = 0 + local_sample_ids: list[int] = [] + non_blocking = device.type == "cuda" + + for features, targets, sample_ids in dataloader: + features = features.to(device, non_blocking=non_blocking) + targets = targets.to(device, non_blocking=non_blocking) + optimizer.zero_grad(set_to_none=True) + loss = nn.functional.cross_entropy(model(features), targets) + loss.backward() + optimizer.step() + + batch_size = targets.shape[0] + local_loss_sum += loss.detach().item() * batch_size + local_example_count += batch_size + local_sample_ids.extend(int(index) for index in sample_ids.tolist()) + + totals = torch.tensor( + [local_loss_sum, local_example_count], + dtype=torch.float64, + device=device, + ) + dist.all_reduce(totals, op=dist.ReduceOp.SUM) + return (totals[0] / totals[1]).item(), local_sample_ids + + +def gather_sample_ids( + local_sample_ids: list[int], runtime: DistributedRuntime +) -> list[list[int]] | None: + """Gather each rank's ordered sample identifiers on rank zero.""" + + gathered: list[Any] | None = ( + [None] * runtime.world_size if runtime.rank == 0 else None + ) + dist.gather_object(local_sample_ids, gathered, dst=0) + if gathered is None: + return None + if not all(isinstance(item, list) for item in gathered): + raise RuntimeError("rank zero did not receive every sample-ID list") + return [[int(index) for index in item] for item in gathered] + + +def analyze_assignments( + sample_ids_by_rank: list[list[int]], dataset_size: int, epoch: int +) -> dict[str, Any]: + """Measure coverage, duplication, and overlap in one epoch.""" + + flattened = [ + sample_id + for rank_sample_ids in sample_ids_by_rank + for sample_id in rank_sample_ids + ] + counts = Counter(flattened) + expected = set(range(dataset_size)) + observed = set(flattened) + overlaps = [] + for left_rank, left_ids in enumerate(sample_ids_by_rank): + for right_rank in range(left_rank + 1, len(sample_ids_by_rank)): + shared = sorted(set(left_ids) & set(sample_ids_by_rank[right_rank])) + overlaps.append( + { + "ranks": [left_rank, right_rank], + "shared_count": len(shared), + "shared_sample_ids": shared, + } + ) + + return { + "epoch": epoch, + "rank_sample_ids": sample_ids_by_rank, + "processed_assignments": len(flattened), + "unique_samples": len(observed), + "duplicate_assignments": sum(count - 1 for count in counts.values()), + "duplicated_sample_ids": sorted( + sample_id for sample_id, count in counts.items() if count > 1 + ), + "missing_sample_ids": sorted(expected - observed), + "pairwise_rank_overlap": overlaps, + "rank_orders_identical": all( + rank_ids == sample_ids_by_rank[0] for rank_ids in sample_ids_by_rank[1:] + ), + "exactly_once_global": len(flattened) == dataset_size and observed == expected, + } + + +def print_epoch_report(report: dict[str, Any]) -> None: + """Print concise, human-readable evidence for one epoch.""" + + print(f"\nepoch {report['epoch']}") + for rank, sample_ids in enumerate(report["rank_sample_ids"]): + print(f" rank {rank}: {sample_ids}") + print( + " assignments: " + f"{report['processed_assignments']}; unique samples: " + f"{report['unique_samples']}; duplicate assignments: " + f"{report['duplicate_assignments']}" + ) + print(f" missing sample IDs: {report['missing_sample_ids']}") + print(f" exactly once globally: {report['exactly_once_global']}") + + +def write_report(path: Path, report: dict[str, Any]) -> None: + """Write a machine-readable report from rank zero.""" + + path.write_text(json.dumps(report, indent=2) + "\n", encoding="utf-8") + + +def run(arguments: argparse.Namespace) -> None: + """Set up DDP, build the input pipeline, and run the diagnosis.""" + + runtime = initialize_distributed(arguments.device) + validate_distributed_arguments(arguments, runtime) + + feature_count = 16 + class_count = 4 + torch.manual_seed(arguments.seed) + dataset = IndexedClassificationDataset( + arguments.dataset_size, feature_count, class_count, arguments.seed + ) + dataloader = make_dataloader(dataset, arguments.batch_size, arguments.seed) + + model = make_model(feature_count, class_count).to(runtime.device) + if runtime.device.type == "cuda": + distributed_model = DDP( + model, + device_ids=[runtime.local_rank], + output_device=runtime.local_rank, + ) + else: + distributed_model = DDP(model) + optimizer = torch.optim.SGD(distributed_model.parameters(), lr=0.05) + + epoch_reports: list[dict[str, Any]] = [] + losses: list[float] = [] + for epoch in range(arguments.epochs): + mean_loss, local_sample_ids = train_one_epoch( + distributed_model, dataloader, optimizer, runtime.device + ) + sample_ids_by_rank = gather_sample_ids(local_sample_ids, runtime) + if runtime.rank == 0: + if sample_ids_by_rank is None: + raise RuntimeError("rank zero did not receive sample identifiers") + epoch_report = analyze_assignments( + sample_ids_by_rank, arguments.dataset_size, epoch + ) + epoch_reports.append(epoch_report) + losses.append(mean_loss) + print_epoch_report(epoch_report) + + if runtime.rank != 0: + return + + rank_order_changed = [ + any( + epoch_reports[epoch]["rank_sample_ids"][rank] + != epoch_reports[0]["rank_sample_ids"][rank] + for epoch in range(1, len(epoch_reports)) + ) + for rank in range(runtime.world_size) + ] + all_epochs_exactly_once = all( + report["exactly_once_global"] for report in epoch_reports + ) + report = { + "implementation": "buggy_plain_dataloader", + "world_size": runtime.world_size, + "device": runtime.device.type, + "backend": runtime.backend, + "dataset_size": arguments.dataset_size, + "batch_size_per_rank": arguments.batch_size, + "epochs": arguments.epochs, + "seed": arguments.seed, + "mean_loss_by_epoch": losses, + "rank_order_changed_between_epochs": rank_order_changed, + "all_ranks_changed_order_between_epochs": all(rank_order_changed), + "all_epochs_exactly_once": all_epochs_exactly_once, + "epoch_reports": epoch_reports, + "pytorch_version": torch.__version__, + } + if arguments.output is not None: + write_report(arguments.output, report) + print(f"\nwrote {arguments.output}") + + if all_epochs_exactly_once: + print("\nSHARDING CHECK: unexpectedly passed") + else: + print("\nSHARDING CHECK: failed as intended; diagnose the evidence above") + + +def main() -> None: + """Run the exercise and always release the process group.""" + + try: + run(parse_arguments()) + except (OSError, RuntimeError, ValueError) as error: + rank = os.environ.get("RANK", "unknown") + print(f"rank {rank}: error: {error}", file=sys.stderr) + raise SystemExit(1) from error + finally: + if dist.is_initialized(): + dist.destroy_process_group() + + +if __name__ == "__main__": + main() diff --git a/source-code/pytorch/ddp/data-sharding/solution_data_sharding.py b/source-code/pytorch/ddp/data-sharding/solution_data_sharding.py new file mode 100644 index 0000000..803d9e3 --- /dev/null +++ b/source-code/pytorch/ddp/data-sharding/solution_data_sharding.py @@ -0,0 +1,454 @@ +#!/usr/bin/env python3 +"""Reference solution for correct DDP data sharding. + +Run this program with at least two processes. It trains a tiny classifier and +records the sample identifiers processed by every rank. A +``DistributedSampler`` gives each rank a disjoint shard, while ``set_epoch`` +changes the deterministic shuffled order between epochs. + +Example:: + + torchrun --standalone --nproc-per-node=2 solution_data_sharding.py \ + --device cpu --output solution-report.json +""" + +from __future__ import annotations + +import argparse +import json +import os +import sys +from collections import Counter +from dataclasses import dataclass +from datetime import timedelta +from pathlib import Path +from typing import Any + +import torch +import torch.distributed as dist +from torch import Tensor, nn +from torch.nn.parallel import DistributedDataParallel as DDP +from torch.utils.data import DataLoader, Dataset, DistributedSampler + + +@dataclass(frozen=True) +class DistributedRuntime: + """Information about this process in the distributed job.""" + + local_rank: int + rank: int + world_size: int + device: torch.device + backend: str + + +class IndexedClassificationDataset(Dataset[tuple[Tensor, Tensor, int]]): + """Small deterministic dataset that exposes each sample's identifier.""" + + def __init__( + self, + size: int, + feature_count: int, + class_count: int, + seed: int, + ) -> None: + generator = torch.Generator().manual_seed(seed) + self.features = torch.randn(size, feature_count, generator=generator) + projection = torch.randn(feature_count, class_count, generator=generator) + self.targets = (self.features @ projection).argmax(dim=1) + + def __len__(self) -> int: + return self.features.shape[0] + + def __getitem__(self, index: int) -> tuple[Tensor, Tensor, int]: + return self.features[index], self.targets[index], index + + +def positive_integer(value: str) -> int: + """Parse a positive command-line integer.""" + + number = int(value) + if number <= 0: + raise argparse.ArgumentTypeError("must be a positive integer") + return number + + +def parse_arguments() -> argparse.Namespace: + """Parse and validate options that do not depend on the worker count.""" + + parser = argparse.ArgumentParser( + description="Demonstrate correct data sharding in native PyTorch DDP.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + parser.add_argument("--dataset-size", type=positive_integer, default=32) + parser.add_argument("--batch-size", type=positive_integer, default=4) + parser.add_argument("--epochs", type=positive_integer, default=2) + parser.add_argument("--seed", type=int, default=1234) + parser.add_argument( + "--device", + choices=("auto", "cpu", "cuda"), + default="auto", + help="auto uses CUDA when available and CPU otherwise", + ) + parser.add_argument( + "--output", + type=Path, + help="optional JSON report path written by rank zero", + ) + parser.add_argument( + "--overwrite-output", + action="store_true", + help="allow replacement of an existing JSON report", + ) + parser.add_argument( + "--local-rank", "--local_rank", type=int, help=argparse.SUPPRESS + ) + arguments = parser.parse_args() + + if arguments.dataset_size > 256: + parser.error("--dataset-size must not exceed 256 in this lab exercise") + if arguments.epochs < 2: + parser.error("--epochs must be at least 2 to inspect epoch reshuffling") + if arguments.seed < 0: + parser.error("--seed must be non-negative") + if arguments.output is None and arguments.overwrite_output: + parser.error("--overwrite-output requires --output") + if arguments.output is not None: + if arguments.output.is_dir(): + parser.error(f"output path is a directory: {arguments.output}") + if arguments.output.exists() and not arguments.overwrite_output: + parser.error( + f"output already exists: {arguments.output}; use " + "--overwrite-output to replace it" + ) + if not arguments.output.parent.exists(): + parser.error(f"output directory does not exist: {arguments.output.parent}") + return arguments + + +def initialize_distributed(requested_device: str) -> DistributedRuntime: + """Initialize a torchrun process group and select this rank's device.""" + + required = ("LOCAL_RANK", "RANK", "WORLD_SIZE", "MASTER_ADDR", "MASTER_PORT") + missing = [name for name in required if name not in os.environ] + if missing: + raise RuntimeError( + f"missing torchrun variables {', '.join(missing)}; launch with " + "'torchrun --standalone --nproc-per-node=2 " + "solution_data_sharding.py'" + ) + + local_rank = int(os.environ["LOCAL_RANK"]) + rank = int(os.environ["RANK"]) + world_size = int(os.environ["WORLD_SIZE"]) + if world_size < 2: + raise RuntimeError("this exercise requires at least two processes") + + use_cuda = requested_device == "cuda" or ( + requested_device == "auto" and torch.cuda.is_available() + ) + if requested_device == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("--device=cuda was requested, but CUDA is unavailable") + + if use_cuda: + visible_devices = torch.cuda.device_count() + if not 0 <= local_rank < visible_devices: + raise RuntimeError( + f"LOCAL_RANK={local_rank}, but this process sees " + f"{visible_devices} CUDA device(s)" + ) + torch.cuda.set_device(local_rank) + device = torch.device("cuda", local_rank) + backend = "nccl" + else: + device = torch.device("cpu") + backend = "gloo" + + dist.init_process_group( + backend=backend, init_method="env://", timeout=timedelta(minutes=5) + ) + return DistributedRuntime(local_rank, rank, world_size, device, backend) + + +def validate_distributed_arguments( + arguments: argparse.Namespace, runtime: DistributedRuntime +) -> None: + """Reject configurations that make the sharding evidence ambiguous.""" + + if arguments.dataset_size % runtime.world_size != 0: + raise ValueError( + f"--dataset-size={arguments.dataset_size} must be divisible by " + f"WORLD_SIZE={runtime.world_size}; otherwise DistributedSampler " + "pads its index list and the reference run can contain duplicates" + ) + intended_samples_per_rank = arguments.dataset_size // runtime.world_size + if arguments.batch_size > intended_samples_per_rank: + raise ValueError( + f"--batch-size={arguments.batch_size} exceeds the intended " + f"per-rank shard size {intended_samples_per_rank}" + ) + + +def make_model(feature_count: int, class_count: int) -> nn.Module: + """Create the deliberately small classifier used by the exercise.""" + + return nn.Sequential( + nn.Linear(feature_count, 32), + nn.ReLU(), + nn.Linear(32, class_count), + ) + + +def make_dataloader( + dataset: IndexedClassificationDataset, + batch_size: int, + seed: int, + runtime: DistributedRuntime, +) -> tuple[ + DataLoader[tuple[Tensor, Tensor, Tensor]], + DistributedSampler[tuple[Tensor, Tensor, int]], +]: + """Create one deterministic, shuffled dataset shard per DDP rank.""" + + sampler = DistributedSampler( + dataset, + num_replicas=runtime.world_size, + rank=runtime.rank, + shuffle=True, + seed=seed, + drop_last=False, + ) + dataloader = DataLoader( + dataset, + batch_size=batch_size, + sampler=sampler, + num_workers=0, + ) + return dataloader, sampler + + +def train_one_epoch( + model: DDP, + dataloader: DataLoader[tuple[Tensor, Tensor, Tensor]], + optimizer: torch.optim.Optimizer, + device: torch.device, +) -> tuple[float, list[int]]: + """Train for one epoch and return global loss plus local sample IDs.""" + + model.train() + local_loss_sum = 0.0 + local_example_count = 0 + local_sample_ids: list[int] = [] + non_blocking = device.type == "cuda" + + for features, targets, sample_ids in dataloader: + features = features.to(device, non_blocking=non_blocking) + targets = targets.to(device, non_blocking=non_blocking) + optimizer.zero_grad(set_to_none=True) + loss = nn.functional.cross_entropy(model(features), targets) + loss.backward() + optimizer.step() + + batch_size = targets.shape[0] + local_loss_sum += loss.detach().item() * batch_size + local_example_count += batch_size + local_sample_ids.extend(int(index) for index in sample_ids.tolist()) + + totals = torch.tensor( + [local_loss_sum, local_example_count], + dtype=torch.float64, + device=device, + ) + dist.all_reduce(totals, op=dist.ReduceOp.SUM) + return (totals[0] / totals[1]).item(), local_sample_ids + + +def gather_sample_ids( + local_sample_ids: list[int], runtime: DistributedRuntime +) -> list[list[int]] | None: + """Gather each rank's ordered sample identifiers on rank zero.""" + + gathered: list[Any] | None = ( + [None] * runtime.world_size if runtime.rank == 0 else None + ) + dist.gather_object(local_sample_ids, gathered, dst=0) + if gathered is None: + return None + if not all(isinstance(item, list) for item in gathered): + raise RuntimeError("rank zero did not receive every sample-ID list") + return [[int(index) for index in item] for item in gathered] + + +def analyze_assignments( + sample_ids_by_rank: list[list[int]], dataset_size: int, epoch: int +) -> dict[str, Any]: + """Measure coverage, duplication, and overlap in one epoch.""" + + flattened = [ + sample_id + for rank_sample_ids in sample_ids_by_rank + for sample_id in rank_sample_ids + ] + counts = Counter(flattened) + expected = set(range(dataset_size)) + observed = set(flattened) + overlaps = [] + for left_rank, left_ids in enumerate(sample_ids_by_rank): + for right_rank in range(left_rank + 1, len(sample_ids_by_rank)): + shared = sorted(set(left_ids) & set(sample_ids_by_rank[right_rank])) + overlaps.append( + { + "ranks": [left_rank, right_rank], + "shared_count": len(shared), + "shared_sample_ids": shared, + } + ) + + return { + "epoch": epoch, + "rank_sample_ids": sample_ids_by_rank, + "processed_assignments": len(flattened), + "unique_samples": len(observed), + "duplicate_assignments": sum(count - 1 for count in counts.values()), + "duplicated_sample_ids": sorted( + sample_id for sample_id, count in counts.items() if count > 1 + ), + "missing_sample_ids": sorted(expected - observed), + "pairwise_rank_overlap": overlaps, + "rank_orders_identical": all( + rank_ids == sample_ids_by_rank[0] for rank_ids in sample_ids_by_rank[1:] + ), + "exactly_once_global": len(flattened) == dataset_size and observed == expected, + } + + +def print_epoch_report(report: dict[str, Any]) -> None: + """Print concise, human-readable evidence for one epoch.""" + + print(f"\nepoch {report['epoch']}") + for rank, sample_ids in enumerate(report["rank_sample_ids"]): + print(f" rank {rank}: {sample_ids}") + print( + " assignments: " + f"{report['processed_assignments']}; unique samples: " + f"{report['unique_samples']}; duplicate assignments: " + f"{report['duplicate_assignments']}" + ) + print(f" missing sample IDs: {report['missing_sample_ids']}") + print(f" exactly once globally: {report['exactly_once_global']}") + + +def write_report(path: Path, report: dict[str, Any]) -> None: + """Write a machine-readable report from rank zero.""" + + path.write_text(json.dumps(report, indent=2) + "\n", encoding="utf-8") + + +def run(arguments: argparse.Namespace) -> None: + """Set up DDP, build the input pipeline, and verify the solution.""" + + runtime = initialize_distributed(arguments.device) + validate_distributed_arguments(arguments, runtime) + + feature_count = 16 + class_count = 4 + torch.manual_seed(arguments.seed) + dataset = IndexedClassificationDataset( + arguments.dataset_size, feature_count, class_count, arguments.seed + ) + dataloader, sampler = make_dataloader( + dataset, arguments.batch_size, arguments.seed, runtime + ) + + model = make_model(feature_count, class_count).to(runtime.device) + if runtime.device.type == "cuda": + distributed_model = DDP( + model, + device_ids=[runtime.local_rank], + output_device=runtime.local_rank, + ) + else: + distributed_model = DDP(model) + optimizer = torch.optim.SGD(distributed_model.parameters(), lr=0.05) + + epoch_reports: list[dict[str, Any]] = [] + losses: list[float] = [] + for epoch in range(arguments.epochs): + sampler.set_epoch(epoch) + mean_loss, local_sample_ids = train_one_epoch( + distributed_model, dataloader, optimizer, runtime.device + ) + sample_ids_by_rank = gather_sample_ids(local_sample_ids, runtime) + if runtime.rank == 0: + if sample_ids_by_rank is None: + raise RuntimeError("rank zero did not receive sample identifiers") + epoch_report = analyze_assignments( + sample_ids_by_rank, arguments.dataset_size, epoch + ) + epoch_reports.append(epoch_report) + losses.append(mean_loss) + print_epoch_report(epoch_report) + + if runtime.rank != 0: + return + + rank_order_changed = [ + any( + epoch_reports[epoch]["rank_sample_ids"][rank] + != epoch_reports[0]["rank_sample_ids"][rank] + for epoch in range(1, len(epoch_reports)) + ) + for rank in range(runtime.world_size) + ] + all_epochs_exactly_once = all( + report["exactly_once_global"] for report in epoch_reports + ) + report = { + "implementation": "distributed_sampler_reference", + "world_size": runtime.world_size, + "device": runtime.device.type, + "backend": runtime.backend, + "dataset_size": arguments.dataset_size, + "batch_size_per_rank": arguments.batch_size, + "epochs": arguments.epochs, + "seed": arguments.seed, + "mean_loss_by_epoch": losses, + "rank_order_changed_between_epochs": rank_order_changed, + "all_ranks_changed_order_between_epochs": all(rank_order_changed), + "all_epochs_exactly_once": all_epochs_exactly_once, + "epoch_reports": epoch_reports, + "pytorch_version": torch.__version__, + } + if arguments.output is not None: + write_report(arguments.output, report) + print(f"\nwrote {arguments.output}") + + if not all_epochs_exactly_once: + raise RuntimeError("SHARDING CHECK failed in the reference solution") + print("\nSHARDING CHECK: passed; every sample was assigned exactly once") + if all(rank_order_changed): + print("RESHUFFLING OBSERVATION: every rank's order changed") + else: + print( + "RESHUFFLING OBSERVATION: at least one rank received the same " + "order; different random permutations can coincide, especially " + "for very small datasets" + ) + + +def main() -> None: + """Run the solution and always release the process group.""" + + try: + run(parse_arguments()) + except (OSError, RuntimeError, ValueError) as error: + rank = os.environ.get("RANK", "unknown") + print(f"rank {rank}: error: {error}", file=sys.stderr) + raise SystemExit(1) from error + finally: + if dist.is_initialized(): + dist.destroy_process_group() + + +if __name__ == "__main__": + main() diff --git a/source-code/pytorch/ddp/ddp_resnet50.py b/source-code/pytorch/ddp/ddp_resnet50.py new file mode 100644 index 0000000..6f41294 --- /dev/null +++ b/source-code/pytorch/ddp/ddp_resnet50.py @@ -0,0 +1,387 @@ +#!/usr/bin/env python3 +"""Benchmark ResNet-50 training with native PyTorch DDP. + +Synthetic ImageNet-shaped data is created directly on each GPU, so this +measures model computation and DDP communication rather than data loading or +model accuracy. Use ``torchrun`` even for one GPU so every measurement follows +the same code path. + +Fixed batch per GPU (weak scaling):: + + torchrun --standalone --nproc-per-node=1 ddp_resnet50.py \ + --batch-size-per-device 32 --output result-1gpu.json + torchrun --standalone --nproc-per-node=4 ddp_resnet50.py \ + --batch-size-per-device 32 --output result-4gpu.json + +Fixed global batch (strong scaling):: + + torchrun --standalone --nproc-per-node=4 ddp_resnet50.py \ + --global-batch-size 128 --output result-4gpu.json + +Within a single-node Slurm allocation, set ``--nproc-per-node`` to the number +of GPUs assigned to the job. Multi-node rendezvous settings belong in the +Slurm submission script. The memory figures reported here cover PyTorch's +CUDA allocator; NCCL may allocate additional device memory outside it. +""" + +from __future__ import annotations + +import argparse +import json +import math +import os +import platform +import socket +import sys +import time +from datetime import timedelta +from pathlib import Path + +import torch +import torch.distributed as dist +import torchvision +from torch import Tensor, nn +from torch.nn.parallel import DistributedDataParallel as DDP +from torchvision.models import resnet50 + +GIBIBYTE = 2**30 + + +def positive_integer(value: str) -> int: + """Parse a positive command-line integer.""" + + number = int(value) + if number <= 0: + raise argparse.ArgumentTypeError("must be a positive integer") + return number + + +def parse_arguments() -> argparse.Namespace: + """Parse arguments and reject unsafe output behavior before GPU startup.""" + + parser = argparse.ArgumentParser( + description="Benchmark synthetic ResNet-50 training with PyTorch DDP.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + batches = parser.add_mutually_exclusive_group() + batches.add_argument( + "--batch-size-per-device", + type=positive_integer, + default=32, + help="samples per GPU; keeping this fixed is a weak-scaling experiment", + ) + batches.add_argument( + "--global-batch-size", + type=positive_integer, + help="total samples across GPUs; must be divisible by WORLD_SIZE", + ) + parser.add_argument( + "--warmup-steps", + type=positive_integer, + default=10, + help="untimed steps used to initialize kernels and DDP buckets", + ) + parser.add_argument( + "--steps", type=positive_integer, default=50, help="timed optimizer steps" + ) + parser.add_argument( + "--precision", + choices=("auto", "fp32", "bf16", "fp16"), + default="auto", + help="auto uses BF16 when every GPU supports it, otherwise FP16", + ) + parser.add_argument("--seed", type=int, default=1234) + parser.add_argument( + "--output", type=Path, help="optional JSON result path written by rank zero" + ) + parser.add_argument( + "--overwrite-output", + action="store_true", + help="allow replacement of an existing output file", + ) + # Some torchrun versions pass this option; device selection uses LOCAL_RANK. + parser.add_argument( + "--local-rank", "--local_rank", type=int, help=argparse.SUPPRESS + ) + arguments = parser.parse_args() + + if arguments.seed < 0: + parser.error("--seed must be non-negative") + if arguments.output is None and arguments.overwrite_output: + parser.error("--overwrite-output requires --output") + if arguments.output is not None: + if arguments.output.is_dir(): + parser.error(f"output path is a directory: {arguments.output}") + if arguments.output.exists() and not arguments.overwrite_output: + parser.error( + f"output already exists: {arguments.output}; " + "use --overwrite-output to replace it" + ) + if not arguments.output.parent.exists(): + parser.error(f"output directory does not exist: {arguments.output.parent}") + return arguments + + +def initialize_distributed() -> tuple[int, int, int, torch.device]: + """Initialize NCCL and bind this process to one visible GPU.""" + + required = ("LOCAL_RANK", "RANK", "WORLD_SIZE", "MASTER_ADDR", "MASTER_PORT") + missing = [name for name in required if name not in os.environ] + if missing: + raise RuntimeError( + f"missing torchrun variables {', '.join(missing)}; launch with, for " + "example, 'torchrun --standalone --nproc-per-node=1 ddp_resnet50.py'" + ) + if not torch.cuda.is_available(): + raise RuntimeError("CUDA is unavailable; this benchmark requires GPUs") + + local_rank = int(os.environ["LOCAL_RANK"]) + rank = int(os.environ["RANK"]) + world_size = int(os.environ["WORLD_SIZE"]) + visible_devices = torch.cuda.device_count() + if not 0 <= local_rank < visible_devices: + raise RuntimeError( + f"LOCAL_RANK={local_rank}, but this process sees " + f"{visible_devices} CUDA device(s)" + ) + + torch.cuda.set_device(local_rank) + device = torch.device("cuda", local_rank) + dist.init_process_group( + backend="nccl", init_method="env://", timeout=timedelta(minutes=5) + ) + return local_rank, rank, world_size, device + + +def resolve_batch_sizes( + arguments: argparse.Namespace, world_size: int +) -> tuple[int, int, str]: + """Resolve the local and global batches once WORLD_SIZE is known.""" + + if arguments.global_batch_size is None: + per_device = arguments.batch_size_per_device + return per_device, per_device * world_size, "fixed_per_device" + if arguments.global_batch_size % world_size != 0: + raise ValueError( + f"--global-batch-size={arguments.global_batch_size} is not divisible " + f"by WORLD_SIZE={world_size}" + ) + return ( + arguments.global_batch_size // world_size, + arguments.global_batch_size, + "fixed_global", + ) + + +def resolve_precision( + requested: str, device: torch.device +) -> tuple[str, torch.dtype | None, bool]: + """Choose one precision supported by every participating GPU.""" + + bf16_supported = torch.tensor( + int(torch.cuda.is_bf16_supported()), dtype=torch.int32, device=device + ) + dist.all_reduce(bf16_supported, op=dist.ReduceOp.MIN) + all_support_bf16 = bool(bf16_supported.item()) + + if requested == "fp32": + return "fp32", None, False + if requested == "bf16": + if not all_support_bf16: + raise ValueError( + "BF16 was requested, but at least one GPU does not support it" + ) + return "bf16", torch.bfloat16, False + if requested == "fp16": + return "fp16", torch.float16, True + if all_support_bf16: + return "bf16", torch.bfloat16, False + return "fp16", torch.float16, True + + +def make_batch( + batch_size: int, rank: int, seed: int, device: torch.device +) -> tuple[Tensor, Tensor]: + """Create one rank-specific synthetic batch outside the timed region.""" + + generator = torch.Generator(device=device).manual_seed(seed + rank) + images = torch.randn(batch_size, 3, 224, 224, generator=generator, device=device) + targets = torch.randint(0, 1000, (batch_size,), generator=generator, device=device) + return images, targets + + +def training_step( + model: DDP, + images: Tensor, + targets: Tensor, + optimizer: torch.optim.Optimizer, + scaler: torch.amp.GradScaler, + autocast_dtype: torch.dtype | None, +) -> Tensor: + """Run forward, backward, gradient synchronization, and optimizer update.""" + + optimizer.zero_grad(set_to_none=True) + with torch.autocast( + device_type="cuda", + dtype=autocast_dtype, + enabled=autocast_dtype is not None, + ): + loss = nn.functional.cross_entropy(model(images), targets) + + if scaler.is_enabled(): + scaler.scale(loss).backward() + scaler.step(optimizer) + scaler.update() + else: + loss.backward() + optimizer.step() + return loss.detach() + + +def parameter_checksum_difference(model: DDP, device: torch.device) -> float: + """Return the largest checksum difference between model replicas.""" + + checksum = torch.zeros(2, dtype=torch.float64, device=device) + with torch.no_grad(): + for parameter in model.module.parameters(): + values = parameter.detach().to(torch.float64) + checksum[0] += values.sum() + checksum[1] += values.square().sum() + + minimum = checksum.clone() + maximum = checksum.clone() + dist.all_reduce(minimum, op=dist.ReduceOp.MIN) + dist.all_reduce(maximum, op=dist.ReduceOp.MAX) + return (maximum - minimum).abs().max().item() + + +def run(arguments: argparse.Namespace) -> dict[str, object]: + """Run the benchmark and return its result record.""" + + local_rank, rank, world_size, device = initialize_distributed() + per_device_batch, global_batch, batch_mode = resolve_batch_sizes( + arguments, world_size + ) + precision, autocast_dtype, scale_gradients = resolve_precision( + arguments.precision, device + ) + + torch.manual_seed(arguments.seed) + torch.backends.cudnn.benchmark = True + model = resnet50(weights=None).to(device).train() + model = DDP( + model, + device_ids=[local_rank], + output_device=local_rank, + gradient_as_bucket_view=True, + ) + optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9) + scaler = torch.amp.GradScaler("cuda", enabled=scale_gradients) + images, targets = make_batch(per_device_batch, rank, arguments.seed, device) + + loss = torch.zeros((), device=device) + for _ in range(arguments.warmup_steps): + loss = training_step(model, images, targets, optimizer, scaler, autocast_dtype) + + dist.barrier() + torch.cuda.synchronize(device) + torch.cuda.reset_peak_memory_stats(device) + start = time.perf_counter() + for _ in range(arguments.steps): + loss = training_step(model, images, targets, optimizer, scaler, autocast_dtype) + torch.cuda.synchronize(device) + elapsed = time.perf_counter() - start + + # Runtime is limited by the slowest rank; memory reports the largest rank peak. + maxima = torch.tensor( + [ + elapsed, + float(torch.cuda.max_memory_allocated(device)), + float(torch.cuda.max_memory_reserved(device)), + ], + dtype=torch.float64, + device=device, + ) + dist.all_reduce(maxima, op=dist.ReduceOp.MAX) + elapsed, peak_allocated, peak_reserved = maxima.tolist() + + loss = loss.to(torch.float64) + dist.all_reduce(loss, op=dist.ReduceOp.SUM) + mean_loss = loss.item() / world_size + if not math.isfinite(mean_loss): + raise RuntimeError( + "the final loss is not finite; retry with --precision fp32 or a " + "smaller batch" + ) + checksum_difference = parameter_checksum_difference(model, device) + + return { + "model": "torchvision.models.resnet50", + "data": "synthetic GPU-resident 3x224x224 images with random labels", + "batch_mode": batch_mode, + "batch_size_per_device": per_device_batch, + "global_batch_size": global_batch, + "world_size": world_size, + "warmup_steps": arguments.warmup_steps, + "measured_steps": arguments.steps, + "precision_requested": arguments.precision, + "precision_resolved": precision, + "seed": arguments.seed, + "elapsed_seconds": elapsed, + "milliseconds_per_step": 1000.0 * elapsed / arguments.steps, + "images_per_second": arguments.steps * global_batch / elapsed, + "final_loss_mean": mean_loss, + "peak_allocated_gib": peak_allocated / GIBIBYTE, + "peak_reserved_gib": peak_reserved / GIBIBYTE, + "parameter_checksum_max_difference": checksum_difference, + "parameters_synchronized": checksum_difference == 0.0, + "gpu_name_rank_zero": torch.cuda.get_device_name(device), + "hostname_rank_zero": socket.gethostname(), + "pytorch_version": torch.__version__, + "torchvision_version": torchvision.__version__, + "cuda_version": torch.version.cuda, + "cudnn_version": torch.backends.cudnn.version(), + "python_version": platform.python_version(), + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + } + + +def print_summary(result: dict[str, object]) -> None: + """Print a compact summary suitable for a Slurm log.""" + + print("DDP ResNet-50 synthetic training benchmark") + print(f" GPUs: {result['world_size']}") + print(f" precision: {result['precision_resolved']}") + print(f" batch/device: {result['batch_size_per_device']}") + print(f" global batch: {result['global_batch_size']}") + print(f" time/step: {result['milliseconds_per_step']:.3f} ms") + print(f" throughput: {result['images_per_second']:.1f} images/s") + print(f" peak allocated/GPU: {result['peak_allocated_gib']:.2f} GiB") + print(f" peak reserved/GPU: {result['peak_reserved_gib']:.2f} GiB") + print(f" parameters synchronized: {result['parameters_synchronized']}") + + +def main() -> int: + """Parse options, run the benchmark, and write rank-zero output.""" + + arguments = parse_arguments() + try: + result = run(arguments) + if dist.get_rank() == 0: + print_summary(result) + if arguments.output is not None: + text = json.dumps(result, indent=2, sort_keys=True) + arguments.output.write_text(f"{text}\n", encoding="utf-8") + print(f" JSON result: {arguments.output}") + return 0 + except (RuntimeError, ValueError) as error: + rank = os.environ.get("RANK", "unknown") + print(f"rank {rank}: error: {error}", file=sys.stderr) + return 2 + finally: + if dist.is_initialized(): + dist.destroy_process_group() + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/source-code/pytorch/environment.yml b/source-code/pytorch/environment.yml deleted file mode 100644 index 8cca41d..0000000 --- a/source-code/pytorch/environment.yml +++ /dev/null @@ -1,9 +0,0 @@ -name: pytorch -channels: - - conda-forge -dependencies: - - jupyterlab - - pytorch - - torchvision - -prefix: "/home/gjb/mambaforge/envs/pytorch" diff --git a/source-code/pytorch/fsdp/README.md b/source-code/pytorch/fsdp/README.md new file mode 100644 index 0000000..38c8883 --- /dev/null +++ b/source-code/pytorch/fsdp/README.md @@ -0,0 +1,226 @@ +# PyTorch FSDP2 benchmark + +[`fsdp2_transformer.py`](fsdp2_transformer.py) compares native PyTorch +`DistributedDataParallel` (DDP) with Fully Sharded Data Parallel version 2 +(FSDP2). It uses the same synthetic transformer workload for both strategies +and reports per-GPU memory, throughput, timing, and parameter-storage metrics. + +No model, weights, tokenizer, or dataset are downloaded. The model is an +encoder-style transformer assembled from standard PyTorch modules, and each +rank creates a distinct synthetic token batch directly on its GPU. + +This is primarily a memory-scaling exercise. FSDP2 may be slower than DDP when +the complete model already fits comfortably on every GPU. That is not a failed +experiment: it demonstrates the cost of exchanging parameters in return for +lower persistent model-state memory. + +## Learning objectives and prerequisites + +After this 45–60 minute hands-on, participants should be able to: + +1. distinguish DDP replication from FSDP parameter, gradient, and optimizer + sharding; +2. compare memory and throughput without changing the model or effective + batch; +3. explain why FSDP peak memory does not decrease by exactly `1 / world_size`; +4. choose a transformer-block sharding boundary instead of blindly sharding + only the root model. + +Required prerequisites are the preceding DDP exercise, basic PyTorch training +knowledge, a single node with at least two CUDA GPUs, and a CUDA-enabled build +of PyTorch 2.13 as specified by this repository's +[`environment_gpu.yml`](../../../environment_gpu.yml). +BF16 support is helpful but not required: `--precision auto` falls back to FP32 +when any participating GPU lacks BF16 support. + +The example uses the public `torch.distributed.fsdp.fully_shard` API. PyTorch's +[FSDP2 tutorial](https://docs.pytorch.org/tutorials/intermediate/FSDP_tutorial.html) +marks FSDP1 as deprecated and explains the current per-parameter design. + +## Model presets + +Start with `small`. The instructor should validate `medium` on the actual lab +hardware before the session. `large` is deliberately capable of exhausting +smaller GPUs and should be treated as an optional capacity experiment. + +| Preset | Blocks | Hidden size | Parameters | FP32 parameters only | Approximate DDP model state with AdamW | +|---|---:|---:|---:|---:|---:| +| `small` | 12 | 768 | 88,327,680 | 0.33 GiB | 1.32 GiB | +| `medium` | 24 | 1,024 | 306,563,072 | 1.14 GiB | 4.57 GiB | +| `large` | 32 | 1,280 | 634,903,040 | 2.37 GiB | 9.46 GiB | + +The final column estimates FP32 parameters, gradients, and the two AdamW +moment tensors after the first optimizer step. It excludes activations, DDP +buckets, temporary all-gather buffers, CUDA context memory, allocator +fragmentation, and NCCL allocations, so actual peak memory will be higher. + +## Command-line options + +| Option | Default | Meaning | +|---|---|---| +| `--strategy {ddp,fsdp2}` | required | Select replicated DDP or fully sharded training. | +| `--preset {small,medium,large}` | `small` | Select the model dimensions from the table above. | +| `--fsdp-wrap {block,root}` | `block` | Choose per-transformer-block or root-only FSDP grouping; ignored for DDP. | +| `--batch-size-per-device N` | `1` | Set the local batch; keeping it fixed gives a weak-scaling comparison. | +| `--global-batch-size N` | unset | Set a fixed total batch for strong scaling; mutually exclusive with the local batch option. | +| `--warmup-steps N` | `5` | Run untimed steps that initialize optimizer state and communication paths. | +| `--steps N` | `15` | Set the number of timed optimizer steps. | +| `--precision {auto,fp32,bf16}` | `auto` | Use BF16 only when all ranks support it; `auto` otherwise selects FP32. | +| `--seed N` | `1234` | Control model initialization and rank-specific synthetic inputs. | +| `--output PATH` | unset | Write the rank-zero result as JSON; existing files are protected. | +| `--overwrite-output` | off | Permit replacement of an existing `--output` file. | + +## Core code map + +The line numbers below refer to the current version of +[`fsdp2_transformer.py`](fsdp2_transformer.py). Function and class names are +the more durable reference if the file changes later. + +| Area | Function or class and line | What to inspect | +|---|---|---| +| Options and validation | [`parse_arguments()` — line 92](fsdp2_transformer.py#L92) | Defines the strategy, preset, wrapping, batch, precision, timing, and output options. | +| Distributed setup | [`initialize_distributed()` — line 162](fsdp2_transformer.py#L162) | Reads `torchrun` variables, binds one GPU per process, and initializes NCCL. | +| Batch interpretation | [`resolve_batch_sizes()` — line 194](fsdp2_transformer.py#L194) | Distinguishes fixed per-device and fixed global batches. | +| Precision setup | [`resolve_precision()` — line 214](fsdp2_transformer.py#L214) | Selects BF16 only when every participating GPU supports it. | +| Transformer block | [`TransformerBlock` — line 234](fsdp2_transformer.py#L234) | Defines the unit used as an FSDP communication and sharding boundary. | +| Complete model | [`SyntheticTransformer` — line 265](fsdp2_transformer.py#L265) | Creates embeddings, transformer blocks, normalization, and a classification head. | +| Synthetic input | [`make_batch()` — line 292](fsdp2_transformer.py#L292) | Creates distinct GPU-resident tokens and labels for each rank. | +| DDP or FSDP2 setup | [`configure_distributed_model()` — line 319](fsdp2_transformer.py#L319) | Wraps the full model in DDP or applies `fully_shard()` to each block and then the root. | +| Local shard measurement | [`local_parameter_elements()` — line 353](fsdp2_transformer.py#L353) | Counts parameter elements physically stored on one rank. | +| One training cycle | [`training_step()` — line 365](fsdp2_transformer.py#L365) | Runs zeroing, forward propagation, loss, backward propagation, communication, and AdamW update. | +| Benchmark cycle | [`run()` — line 412](fsdp2_transformer.py#L412) | Creates the model and optimizer, performs warm-up, times training, reduces metrics, and constructs the result. | +| Program entry point | [`main()` — line 543](fsdp2_transformer.py#L543) | Handles rank-zero reporting, optional JSON output, errors, and process-group cleanup. | + +Start with `run()`, then compare the two branches of +`configure_distributed_model()`. The most important FSDP2 detail is that the +optimizer is created only after `fully_shard()` has transformed the model +parameters. + +## Run the core comparison + +Use the same process count, preset, precision, and batch for both runs. On a +four-GPU node: + +```bash +torchrun --standalone --nproc-per-node=4 fsdp2_transformer.py \ + --strategy ddp \ + --preset medium \ + --batch-size-per-device 1 \ + --output result-medium-ddp.json + +torchrun --standalone --nproc-per-node=4 fsdp2_transformer.py \ + --strategy fsdp2 \ + --fsdp-wrap block \ + --preset medium \ + --batch-size-per-device 1 \ + --output result-medium-fsdp2-block.json +``` + +If `medium` is too slow or exceeds memory, substitute `small` in both commands. +Do not shrink only one run: changing the workload invalidates the comparison. + +For strong scaling, hold the global batch constant. It must be divisible by the +number of processes: + +```bash +torchrun --standalone --nproc-per-node=4 fsdp2_transformer.py \ + --strategy fsdp2 \ + --preset small \ + --global-batch-size 4 \ + --output result-small-global4-fsdp2.json +``` + +## Run as a single-node Slurm batch job + +This layout asks Slurm for one launcher task and four GPUs; `torchrun` creates +one worker process per GPU. Scheduler options differ between clusters, so use +the local GPU-resource spelling when it is not `--gpus-per-node`. + +```bash +#!/usr/bin/env bash +#SBATCH --nodes=1 +#SBATCH --ntasks-per-node=1 +#SBATCH --gpus-per-node=4 + +set -euo pipefail + +srun torchrun --standalone --nproc-per-node=4 fsdp2_transformer.py \ + --strategy ddp \ + --preset medium \ + --output result-medium-ddp.json + +srun torchrun --standalone --nproc-per-node=4 fsdp2_transformer.py \ + --strategy fsdp2 \ + --fsdp-wrap block \ + --preset medium \ + --output result-medium-fsdp2-block.json +``` + +Some sites use `#SBATCH --gres=gpu:4`. This example covers one node only; +multi-node `torchrun` requires rendezvous settings supplied by the batch job. + +## Hands-on tasks + +Before running anything, predict which strategy will have the lowest peak +memory and which will have the best throughput. Then: + +1. Run the DDP and block-wrapped FSDP2 commands above. +2. Compare `local_parameter_fraction`, `peak_allocated_gib`, + `milliseconds_per_step`, and `tokens_per_second` in the JSON files. +3. Explain why DDP reports a local parameter fraction of approximately `1.0`, + while FSDP2 approaches `1 / world_size`. +4. Repeat FSDP2 with `--fsdp-wrap root` and predict the result first: + + ```bash + torchrun --standalone --nproc-per-node=4 fsdp2_transformer.py \ + --strategy fsdp2 \ + --fsdp-wrap root \ + --preset medium \ + --output result-medium-fsdp2-root.json + ``` + +5. Explain why root-only and per-block FSDP store similar persistent shards but + can have different peak memory and throughput. +6. If time and hardware permit, find the largest preset that runs with each + strategy. Treat an out-of-memory result as capacity evidence, not as a + throughput measurement. + +A successful solution does more than produce three JSON files. It gives a +defensible explanation of the observed trade-off and identifies which strategy +is appropriate when the model fits and when it does not. + +## Interpret the output carefully + +- `local_parameter_fraction` counts parameter elements stored by the rank. It + does not include gradients, optimizer state, activations, or communication + buffers. +- With one process, FSDP2 has nothing to shard and the local fraction remains + approximately `1.0`; use at least two GPUs to demonstrate its purpose. +- FSDP2 peak memory does not fall exactly by `1 / world_size`: the current + layer must be gathered for computation, activations remain local, and CUDA + libraries need temporary memory. +- Block wrapping gives each transformer block its own communication group, + permitting parameter all-gathers to overlap with computation. Root-only + wrapping gathers the entire model as one group and is intentionally included + as a poor boundary choice. +- `parameters_synchronized` is meaningful for replicated DDP parameters. It is + `null` for FSDP2 because ranks own complementary shards rather than replicas; + the script instead reports checksums reduced across all shards. +- BF16 is implemented with DDP autocast and an FSDP2 mixed-precision policy. + The two mechanisms are idiomatic for their respective strategies but do not + make every intermediate tensor identical. +- Peak memory uses PyTorch's CUDA allocator counters. Allocations made directly + by libraries such as NCCL are not fully represented. +- Peak statistics are reset after warm-up, so they describe steady-state + training and deliberately exclude model-construction and initial sharding + peaks. +- Synthetic, reused input removes I/O noise and model accuracy from the + exercise. The result must not be presented as end-to-end training + performance. + +Activation checkpointing and distributed checkpoint files are deliberately +left out. Both are valuable follow-up topics, but either would add another +memory mechanism and make the core DDP/FSDP comparison harder to interpret. +The separate +[`activation-checkpointing`](../activation-checkpointing/) exercise isolates +the activation-memory versus recomputation trade-off. diff --git a/source-code/pytorch/fsdp/fsdp2_transformer.py b/source-code/pytorch/fsdp/fsdp2_transformer.py new file mode 100644 index 0000000..157983f --- /dev/null +++ b/source-code/pytorch/fsdp/fsdp2_transformer.py @@ -0,0 +1,566 @@ +#!/usr/bin/env python3 +"""Compare native PyTorch DDP and FSDP2 on a synthetic transformer. + +The model and token batches are created locally, so the benchmark downloads +nothing and measures model computation plus distributed communication rather +than storage or data-pipeline performance. The default ``small`` preset is +intended as a quick smoke test; ``medium`` makes model-state memory sharding +more visible on typical multi-GPU training nodes. + +Run both strategies with the same number of processes and settings:: + + torchrun --standalone --nproc-per-node=4 fsdp2_transformer.py \ + --strategy ddp --preset medium --output result-ddp.json + torchrun --standalone --nproc-per-node=4 fsdp2_transformer.py \ + --strategy fsdp2 --preset medium --output result-fsdp2.json + +FSDP2 is most useful for reducing model-state memory. It may be slower than +DDP when the unsharded model already fits comfortably on every GPU. +""" + +from __future__ import annotations + +import argparse +import json +import math +import os +import platform +import socket +import sys +import time +from dataclasses import asdict, dataclass +from datetime import timedelta +from pathlib import Path + +import torch +import torch.distributed as dist +from torch import Tensor, nn +from torch.distributed.fsdp import MixedPrecisionPolicy, fully_shard +from torch.distributed.tensor import DTensor +from torch.nn.parallel import DistributedDataParallel as DDP + +GIBIBYTE = 2**30 + + +@dataclass(frozen=True) +class ModelConfig: + """Configuration for one synthetic transformer preset.""" + + layers: int + hidden_size: int + attention_heads: int + feedforward_size: int + sequence_length: int + vocabulary_size: int = 4096 + classes: int = 16 + + +PRESETS = { + "small": ModelConfig( + layers=12, + hidden_size=768, + attention_heads=12, + feedforward_size=3072, + sequence_length=256, + ), + "medium": ModelConfig( + layers=24, + hidden_size=1024, + attention_heads=16, + feedforward_size=4096, + sequence_length=256, + ), + "large": ModelConfig( + layers=32, + hidden_size=1280, + attention_heads=20, + feedforward_size=5120, + sequence_length=256, + ), +} + + +def positive_integer(value: str) -> int: + """Parse a positive command-line integer.""" + + number = int(value) + if number <= 0: + raise argparse.ArgumentTypeError("must be a positive integer") + return number + + +def parse_arguments() -> argparse.Namespace: + """Parse arguments and reject invalid output behavior before GPU setup.""" + + parser = argparse.ArgumentParser( + description="Compare DDP and FSDP2 with a synthetic transformer.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + parser.add_argument("--strategy", choices=("ddp", "fsdp2"), required=True) + parser.add_argument("--preset", choices=tuple(PRESETS), default="small") + parser.add_argument( + "--fsdp-wrap", + choices=("block", "root"), + default="block", + help="FSDP2 communication-group boundary; ignored for DDP", + ) + batches = parser.add_mutually_exclusive_group() + batches.add_argument( + "--batch-size-per-device", + type=positive_integer, + default=1, + help="samples per GPU; keeping this fixed is weak scaling", + ) + batches.add_argument( + "--global-batch-size", + type=positive_integer, + help="total samples across GPUs; must be divisible by WORLD_SIZE", + ) + parser.add_argument( + "--warmup-steps", type=positive_integer, default=5, help="untimed steps" + ) + parser.add_argument( + "--steps", type=positive_integer, default=15, help="timed optimizer steps" + ) + parser.add_argument( + "--precision", + choices=("auto", "fp32", "bf16"), + default="auto", + help="auto uses BF16 when every GPU supports it, otherwise FP32", + ) + parser.add_argument("--seed", type=int, default=1234) + parser.add_argument( + "--output", type=Path, help="optional JSON result path written by rank zero" + ) + parser.add_argument( + "--overwrite-output", + action="store_true", + help="allow replacement of an existing output file", + ) + parser.add_argument( + "--local-rank", "--local_rank", type=int, help=argparse.SUPPRESS + ) + arguments = parser.parse_args() + + if arguments.seed < 0: + parser.error("--seed must be non-negative") + if arguments.output is None and arguments.overwrite_output: + parser.error("--overwrite-output requires --output") + if arguments.output is not None: + if arguments.output.is_dir(): + parser.error(f"output path is a directory: {arguments.output}") + if arguments.output.exists() and not arguments.overwrite_output: + parser.error( + f"output already exists: {arguments.output}; " + "use --overwrite-output to replace it" + ) + if not arguments.output.parent.exists(): + parser.error(f"output directory does not exist: {arguments.output.parent}") + return arguments + + +def initialize_distributed() -> tuple[int, int, int, torch.device]: + """Initialize NCCL and bind this process to its torchrun GPU.""" + + required = ("LOCAL_RANK", "RANK", "WORLD_SIZE", "MASTER_ADDR", "MASTER_PORT") + missing = [name for name in required if name not in os.environ] + if missing: + raise RuntimeError( + f"missing torchrun variables {', '.join(missing)}; launch with, for " + "example, 'torchrun --standalone --nproc-per-node=2 " + "fsdp2_transformer.py --strategy fsdp2'" + ) + if not torch.cuda.is_available(): + raise RuntimeError("CUDA is unavailable; this benchmark requires GPUs") + + local_rank = int(os.environ["LOCAL_RANK"]) + rank = int(os.environ["RANK"]) + world_size = int(os.environ["WORLD_SIZE"]) + visible_devices = torch.cuda.device_count() + if not 0 <= local_rank < visible_devices: + raise RuntimeError( + f"LOCAL_RANK={local_rank}, but this process sees " + f"{visible_devices} CUDA device(s)" + ) + + torch.cuda.set_device(local_rank) + device = torch.device("cuda", local_rank) + dist.init_process_group( + backend="nccl", init_method="env://", timeout=timedelta(minutes=5) + ) + return local_rank, rank, world_size, device + + +def resolve_batch_sizes( + arguments: argparse.Namespace, world_size: int +) -> tuple[int, int, str]: + """Resolve per-device and global batch sizes after distributed setup.""" + + if arguments.global_batch_size is None: + per_device = arguments.batch_size_per_device + return per_device, per_device * world_size, "fixed_per_device" + if arguments.global_batch_size % world_size != 0: + raise ValueError( + f"--global-batch-size={arguments.global_batch_size} is not divisible " + f"by WORLD_SIZE={world_size}" + ) + return ( + arguments.global_batch_size // world_size, + arguments.global_batch_size, + "fixed_global", + ) + + +def resolve_precision(requested: str, device: torch.device) -> tuple[str, bool]: + """Choose FP32 or BF16 consistently across all participating GPUs.""" + + bf16_supported = torch.tensor( + int(torch.cuda.is_bf16_supported()), dtype=torch.int32, device=device + ) + dist.all_reduce(bf16_supported, op=dist.ReduceOp.MIN) + all_support_bf16 = bool(bf16_supported.item()) + + if requested == "fp32": + return "fp32", False + if requested == "bf16": + if not all_support_bf16: + raise ValueError( + "BF16 was requested, but at least one GPU does not support it" + ) + return "bf16", True + return ("bf16", True) if all_support_bf16 else ("fp32", False) + + +class TransformerBlock(nn.Module): + """Pre-normalized self-attention and feed-forward transformer block.""" + + def __init__(self, config: ModelConfig) -> None: + super().__init__() + self.attention_norm = nn.LayerNorm(config.hidden_size) + self.attention = nn.MultiheadAttention( + embed_dim=config.hidden_size, + num_heads=config.attention_heads, + dropout=0.0, + bias=False, + batch_first=True, + ) + self.feedforward_norm = nn.LayerNorm(config.hidden_size) + self.feedforward = nn.Sequential( + nn.Linear(config.hidden_size, config.feedforward_size, bias=False), + nn.GELU(approximate="tanh"), + nn.Linear(config.feedforward_size, config.hidden_size, bias=False), + ) + + def forward(self, hidden_states: Tensor) -> Tensor: + """Apply one residual attention and feed-forward block.""" + + normalized = self.attention_norm(hidden_states) + attention_output, _ = self.attention( + normalized, normalized, normalized, need_weights=False + ) + hidden_states = hidden_states + attention_output + return hidden_states + self.feedforward(self.feedforward_norm(hidden_states)) + + +class SyntheticTransformer(nn.Module): + """Encoder-style transformer for a synthetic sequence classification task.""" + + def __init__(self, config: ModelConfig) -> None: + super().__init__() + self.token_embedding = nn.Embedding(config.vocabulary_size, config.hidden_size) + self.position_embedding = nn.Parameter( + torch.empty(config.sequence_length, config.hidden_size) + ) + nn.init.normal_(self.position_embedding, mean=0.0, std=0.02) + self.blocks = nn.ModuleList( + TransformerBlock(config) for _ in range(config.layers) + ) + self.output_norm = nn.LayerNorm(config.hidden_size) + self.classifier = nn.Linear(config.hidden_size, config.classes, bias=False) + + def forward(self, token_ids: Tensor) -> Tensor: + """Return sequence-classification logits for integer token IDs.""" + + hidden_states = self.token_embedding(token_ids) + hidden_states = hidden_states + self.position_embedding.unsqueeze(0) + for block in self.blocks: + hidden_states = block(hidden_states) + hidden_states = self.output_norm(hidden_states[:, 0]) + return self.classifier(hidden_states) + + +def make_batch( + config: ModelConfig, + batch_size: int, + rank: int, + seed: int, + device: torch.device, +) -> tuple[Tensor, Tensor]: + """Create one rank-specific, GPU-resident synthetic batch.""" + + generator = torch.Generator(device=device).manual_seed(seed + rank) + token_ids = torch.randint( + 0, + config.vocabulary_size, + (batch_size, config.sequence_length), + generator=generator, + device=device, + ) + targets = torch.randint( + 0, + config.classes, + (batch_size,), + generator=generator, + device=device, + ) + return token_ids, targets + + +def configure_distributed_model( + model: SyntheticTransformer, + strategy: str, + fsdp_wrap: str, + use_bf16: bool, + local_rank: int, + device: torch.device, +) -> nn.Module: + """Wrap the model with DDP or apply FSDP2 in place.""" + + if strategy == "ddp": + model.to(device) + return DDP( + model, + device_ids=[local_rank], + output_device=local_rank, + gradient_as_bucket_view=True, + ) + + mixed_precision_policy = ( + MixedPrecisionPolicy( + param_dtype=torch.bfloat16, + reduce_dtype=torch.float32, + ) + if use_bf16 + else MixedPrecisionPolicy() + ) + if fsdp_wrap == "block": + for block in model.blocks: + fully_shard(block, mp_policy=mixed_precision_policy) + fully_shard(model, mp_policy=mixed_precision_policy) + return model + + +def local_parameter_elements(model: nn.Module) -> int: + """Count parameter elements physically held by this rank when sharded.""" + + total = 0 + for parameter in model.parameters(): + if isinstance(parameter, DTensor): + total += parameter.to_local().numel() + else: + total += parameter.numel() + return total + + +def training_step( + model: nn.Module, + token_ids: Tensor, + targets: Tensor, + optimizer: torch.optim.Optimizer, + use_ddp_autocast: bool, +) -> Tensor: + """Run one forward, backward, communication, and optimizer cycle.""" + + optimizer.zero_grad(set_to_none=True) + with torch.autocast( + device_type="cuda", dtype=torch.bfloat16, enabled=use_ddp_autocast + ): + logits = model(token_ids) + loss = nn.functional.cross_entropy(logits.float(), targets) + loss.backward() + optimizer.step() + return loss.detach() + + +def parameter_checksums( + model: nn.Module, strategy: str, device: torch.device +) -> tuple[float, float, float | None]: + """Return global parameter checksums and DDP replica disagreement.""" + + checksum = torch.zeros(2, dtype=torch.float64, device=device) + with torch.no_grad(): + for parameter in model.parameters(): + values = ( + parameter.to_local() if isinstance(parameter, DTensor) else parameter + ) + values = values.detach().to(torch.float64) + checksum[0] += values.sum() + checksum[1] += values.square().sum() + + if strategy == "fsdp2": + dist.all_reduce(checksum, op=dist.ReduceOp.SUM) + return checksum[0].item(), checksum[1].item(), None + + minimum = checksum.clone() + maximum = checksum.clone() + dist.all_reduce(minimum, op=dist.ReduceOp.MIN) + dist.all_reduce(maximum, op=dist.ReduceOp.MAX) + difference = (maximum - minimum).abs().max().item() + return checksum[0].item(), checksum[1].item(), difference + + +def run(arguments: argparse.Namespace) -> dict[str, object]: + """Run the selected strategy and return one benchmark result record.""" + + local_rank, rank, world_size, device = initialize_distributed() + per_device_batch, global_batch, batch_mode = resolve_batch_sizes( + arguments, world_size + ) + precision, use_bf16 = resolve_precision(arguments.precision, device) + config = PRESETS[arguments.preset] + + torch.manual_seed(arguments.seed) + model = SyntheticTransformer(config) + global_parameter_count = sum(parameter.numel() for parameter in model.parameters()) + model = configure_distributed_model( + model=model, + strategy=arguments.strategy, + fsdp_wrap=arguments.fsdp_wrap, + use_bf16=use_bf16, + local_rank=local_rank, + device=device, + ) + model.train() + local_parameter_count = local_parameter_elements(model) + optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3) + token_ids, targets = make_batch( + config, per_device_batch, rank, arguments.seed, device + ) + + use_ddp_autocast = arguments.strategy == "ddp" and use_bf16 + loss = torch.zeros((), device=device) + for _ in range(arguments.warmup_steps): + loss = training_step(model, token_ids, targets, optimizer, use_ddp_autocast) + + dist.barrier() + torch.cuda.synchronize(device) + torch.cuda.reset_peak_memory_stats(device) + start_time = time.perf_counter() + for _ in range(arguments.steps): + loss = training_step(model, token_ids, targets, optimizer, use_ddp_autocast) + torch.cuda.synchronize(device) + elapsed = time.perf_counter() - start_time + + maxima = torch.tensor( + [ + elapsed, + float(torch.cuda.max_memory_allocated(device)), + float(torch.cuda.max_memory_reserved(device)), + ], + dtype=torch.float64, + device=device, + ) + dist.all_reduce(maxima, op=dist.ReduceOp.MAX) + elapsed, peak_allocated, peak_reserved = maxima.tolist() + + loss = loss.to(torch.float64) + dist.all_reduce(loss, op=dist.ReduceOp.SUM) + mean_loss = loss.item() / world_size + if not math.isfinite(mean_loss): + raise RuntimeError( + "the final loss is not finite; retry with --precision fp32 or the " + "small preset" + ) + checksum_sum, checksum_squared_sum, checksum_difference = parameter_checksums( + model, arguments.strategy, device + ) + if not math.isfinite(checksum_sum) or not math.isfinite(checksum_squared_sum): + raise RuntimeError("model parameters contain non-finite values") + + samples = arguments.steps * global_batch + tokens = samples * config.sequence_length + return { + "model": "synthetic encoder-style transformer", + "data": "synthetic GPU-resident integer token sequences", + "strategy": arguments.strategy, + "fsdp_wrap": (arguments.fsdp_wrap if arguments.strategy == "fsdp2" else None), + "preset": arguments.preset, + "model_config": asdict(config), + "global_parameter_count": global_parameter_count, + "local_parameter_elements": local_parameter_count, + "local_parameter_fraction": (local_parameter_count / global_parameter_count), + "model_parameters_fp32_gib": 4 * global_parameter_count / GIBIBYTE, + "batch_mode": batch_mode, + "batch_size_per_device": per_device_batch, + "global_batch_size": global_batch, + "world_size": world_size, + "warmup_steps": arguments.warmup_steps, + "measured_steps": arguments.steps, + "precision_requested": arguments.precision, + "precision_resolved": precision, + "seed": arguments.seed, + "elapsed_seconds": elapsed, + "milliseconds_per_step": 1000.0 * elapsed / arguments.steps, + "samples_per_second": samples / elapsed, + "tokens_per_second": tokens / elapsed, + "final_loss_mean": mean_loss, + "peak_allocated_gib": peak_allocated / GIBIBYTE, + "peak_reserved_gib": peak_reserved / GIBIBYTE, + "parameter_checksum_sum": checksum_sum, + "parameter_checksum_squared_sum": checksum_squared_sum, + "parameter_checksum_max_difference": checksum_difference, + "parameters_synchronized": ( + checksum_difference == 0.0 if checksum_difference is not None else None + ), + "gpu_name_rank_zero": torch.cuda.get_device_name(device), + "hostname_rank_zero": socket.gethostname(), + "pytorch_version": torch.__version__, + "cuda_version": torch.version.cuda, + "python_version": platform.python_version(), + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + } + + +def print_summary(result: dict[str, object]) -> None: + """Print a compact summary suitable for a Slurm log.""" + + print("DDP/FSDP2 synthetic transformer benchmark") + print(f" strategy: {result['strategy']}") + print(f" FSDP wrap: {result['fsdp_wrap']}") + print(f" preset: {result['preset']}") + print(f" GPUs: {result['world_size']}") + print(f" parameters: {result['global_parameter_count']:,}") + print(f" local param fraction: {result['local_parameter_fraction']:.3f}") + print(f" precision: {result['precision_resolved']}") + print(f" time/step: {result['milliseconds_per_step']:.3f} ms") + print(f" throughput: {result['tokens_per_second']:.1f} tokens/s") + print(f" peak allocated/GPU: {result['peak_allocated_gib']:.2f} GiB") + print(f" peak reserved/GPU: {result['peak_reserved_gib']:.2f} GiB") + if result["parameters_synchronized"] is not None: + print(f" parameters synchronized: {result['parameters_synchronized']}") + + +def main() -> int: + """Parse options, run the benchmark, and write rank-zero output.""" + + arguments = parse_arguments() + try: + result = run(arguments) + if dist.get_rank() == 0: + print_summary(result) + if arguments.output is not None: + text = json.dumps(result, indent=2, sort_keys=True) + arguments.output.write_text(f"{text}\n", encoding="utf-8") + print(f" JSON result: {arguments.output}") + return 0 + except (RuntimeError, ValueError) as error: + rank = os.environ.get("RANK", "unknown") + print(f"rank {rank}: error: {error}", file=sys.stderr) + return 2 + finally: + if dist.is_initialized(): + dist.destroy_process_group() + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/source-code/pytorch/memory-diagnostics/README.md b/source-code/pytorch/memory-diagnostics/README.md new file mode 100644 index 0000000..dec6ae7 --- /dev/null +++ b/source-code/pytorch/memory-diagnostics/README.md @@ -0,0 +1,259 @@ +# Exercise: diagnose CUDA memory empirically + +This 50–60 minute exercise uses phase-by-phase measurements to distinguish +activation pressure, persistent optimizer state, and an accidentally retained +training graph. The cases are labelled `alpha`, `beta`, and `gamma` so the +diagnosis must come from evidence rather than the option name. + +[`memory_diagnostics.py`](memory_diagnostics.py) creates a synthetic transformer +and GPU-resident inputs locally. It downloads no model, weights, tokenizer, or +dataset. One GPU is sufficient. An optional DDP extension compares ranks on a +multi-GPU node. + +## Learning objectives and success criteria + +After the exercise, participants should be able to: + +1. distinguish live tensor allocation from memory reserved by PyTorch's caching + allocator; +2. identify whether a memory increase occurs during forward propagation, on the + first optimizer step, or cumulatively between training steps; +3. test a diagnosis by changing one workload dimension at a time; +4. choose a targeted intervention and reject an unrelated one. + +The exercise is complete when the participant correctly diagnoses all three +cases, cites a measured phase transition or scaling trend for each diagnosis, +and proposes a matching response. Producing the JSON files alone is not the +success criterion. + +Required prerequisites are familiarity with a PyTorch training cycle and a +CUDA-enabled PyTorch environment with at least one GPU. The repository's +[`environment_gpu.yml`](../../../environment_gpu.yml) provides the intended +software environment. DDP knowledge and a second GPU are optional. + +## Files + +| File | Purpose | +|---|---| +| [`memory_diagnostics.py`](memory_diagnostics.py) | Runs an anonymous workload, records memory at model, input, forward, backward, update, and gradient-clearing boundaries, and writes JSON. | +| [`compare_memory_reports.py`](compare_memory_reports.py) | Produces a compact comparison table from one or more JSON reports without naming the diagnosis. | +| [`SOLUTION.md`](SOLUTION.md) | Complete reference procedure, expected diagnoses, reasoning, and limitations. Consult it after forming a hypothesis. | + +## What is measured + +Every phase reports four related but non-interchangeable quantities: + +| Metric | Interpretation | +|---|---| +| `allocated_mib` | Live tensor storage known to PyTorch's CUDA allocator. Use this first when reasoning about tensor lifetimes. | +| `reserved_mib` | Blocks retained by the caching allocator. Released tensors can reduce allocated memory without immediately reducing this value. | +| `peak_allocated_mib` | Largest live PyTorch allocation since the peak was reset at the start of the current step. | +| `device_used_mib` | Device-wide consumption derived from free memory. It includes CUDA libraries and other processes, so an exclusive Slurm allocation is preferable. | + +The report also derives three diagnosis aids: + +- `first_step_persistent_change_mib`: allocation remaining after the first step + and gradient clearing, relative to the pre-training baseline; +- `between_step_growth_mib`: change in the post-cleanup baseline from the first + to the final step; +- `largest_forward_increase_mib`: the largest forward allocation above the + preceding post-cleanup baseline. + +These indicators are evidence, not universal thresholds. Absolute numbers vary +with GPU, precision, PyTorch version, kernel selection, and model shape. + +## Part 1: predict and collect a baseline + +Before running, sketch the expected live-allocation curve for one training +step. Mark model construction, forward propagation, backward propagation, the +first optimizer update, and gradient clearing. + +Run all three cases with the same configuration: + +```bash +python memory_diagnostics.py --case alpha --output alpha.json +python memory_diagnostics.py --case beta --output beta.json +python memory_diagnostics.py --case gamma --output gamma.json + +python compare_memory_reports.py --show-phases alpha.json beta.json gamma.json +``` + +For each case, answer these questions before looking at the implementation: + +1. Is its main change transient within a step, persistent after the first step, + or cumulative across steps? +2. Which phase provides the strongest evidence? +3. Is the gap between allocated and reserved memory itself evidence of a leak? + +Do not interpret a large `reserved_mib` value alone as live memory pressure. + +## Part 2: test each hypothesis + +A diagnosis needs a perturbation, not just a plausible story. Change one +variable at a time. + +### Batch-size sweep + +Predict which indicator will respond most strongly, then run: + +```bash +python memory_diagnostics.py --case alpha --batch-size-per-device 1 \ + --output alpha-batch1.json +python memory_diagnostics.py --case alpha --batch-size-per-device 4 \ + --output alpha-batch4.json + +python compare_memory_reports.py alpha-batch1.json alpha-batch4.json +``` + +### Model-size sweep + +Predict whether transient and persistent allocations will change in the same +proportion: + +```bash +python memory_diagnostics.py --case beta --preset small \ + --output beta-small.json +python memory_diagnostics.py --case beta --preset medium \ + --batch-size-per-device 1 --output beta-medium.json + +python compare_memory_reports.py beta-small.json beta-medium.json +``` + +### Step-count sweep + +Run the suspected cumulative case for longer. Compare the *post-cleanup +baseline*, not only its largest peak: + +```bash +python memory_diagnostics.py --case gamma --steps 10 \ + --output gamma-steps10.json +``` + +If `medium` exceeds the assigned GPU or takes too long, omit that run. An OOM is +capacity evidence, not a required outcome and not a valid performance result. + +## Part 3: recommend an intervention + +For every case, choose one primary response and explain why at least one other +response is poorly targeted. Candidate responses include: + +- reduce the local microbatch; +- use activation checkpointing; +- shard model state with FSDP; +- change optimizer or optimizer-state precision; +- stop retaining training graphs and store detached CPU summaries instead. + +The question is not “which technique saves memory?” but “which technique acts +on the measured source of pressure?” + +## Optional detailed snapshot + +Counters should answer the first question. Once one run is suspicious, collect +a detailed allocator history: + +```bash +python memory_diagnostics.py --case gamma --steps 6 \ + --snapshot gamma-snapshot.pickle \ + --output gamma-with-snapshot.json +``` + +The generated file is rank-qualified, for example +`gamma-snapshot-rank0.pickle`. Copy it from the compute node and open it in the +[PyTorch memory visualizer](https://pytorch.org/memory_viz). Recording histories +adds overhead and can create large files, which is why it is optional and +bounded by `--snapshot-max-entries`. + +PyTorch allocator snapshots cannot see allocations made directly by NCCL and +some other CUDA libraries. Compare snapshot evidence with `device_used_mib` +rather than assuming the snapshot accounts for the entire device. + +## Optional DDP rank-imbalance extension + +Use two GPUs first with equal local batches, then deliberately give rank zero a +larger batch: + +```bash +torchrun --standalone --nproc-per-node=2 memory_diagnostics.py \ + --case alpha --output alpha-ddp-balanced.json + +torchrun --standalone --nproc-per-node=2 memory_diagnostics.py \ + --case alpha --rank-zero-extra-samples 2 \ + --output alpha-ddp-imbalanced.json +``` + +Inspect every entry in `rank_reports`. Rank-zero-only logging would hide a +problem on another rank in a real workload. The artificial imbalance also +changes the effective weighting of samples in ordinary DDP gradient averaging; +it is a diagnostic demonstration, not a recommended training configuration. + +### Slurm example + +```bash +#!/usr/bin/env bash +#SBATCH --nodes=1 +#SBATCH --ntasks-per-node=1 +#SBATCH --gpus-per-node=2 +#SBATCH --time=00:10:00 + +set -euo pipefail + +srun torchrun --standalone --nproc-per-node=2 memory_diagnostics.py \ + --case alpha \ + --output "alpha-ddp-${SLURM_JOB_ID}.json" +``` + +Adapt the GPU directive, partition, account, and environment activation to the +local cluster. One Slurm task launches `torchrun`; `torchrun` creates one worker +per assigned GPU. + +## Hints + +1. Many optimizers create state lazily during their first `step()`, not when the + optimizer object is constructed. +2. A healthy steady-state training loop normally reuses memory rather than + increasing live allocation on every iteration. +3. `empty_cache()` does not release live tensors. Do not add it to conceal an + unexplained growth trend. +4. `detach()` breaks an autograd connection but does not move or discard the + underlying GPU tensor. For logging, retain a scalar or transfer the required + result to CPU. + +## Core code map + +Function and class names are more durable than line numbers if the file changes. + +| Area | Function or class and line | What to inspect | +|---|---|---| +| Options and validation | [`parse_arguments()` — line 103](memory_diagnostics.py#L103) | Defines the case, workload, precision, output, snapshot, and imbalance options. | +| CUDA/DDP setup | [`initialize_runtime()` — line 184](memory_diagnostics.py#L184) | Selects one GPU and initializes NCCL only when launched by `torchrun`. | +| Model blocks | [`TransformerBlock` — line 236](memory_diagnostics.py#L236) | Defines the attention and feed-forward unit. | +| Complete model | [`SyntheticTransformer` — line 267](memory_diagnostics.py#L267) | Creates the transformer used by every case. | +| Model/DDP creation | [`make_model()` — line 294](memory_diagnostics.py#L294) | Constructs an identical local model and optionally wraps it in DDP. | +| Input handling | [`make_batch()` — line 322](memory_diagnostics.py#L322) | Creates rank-specific synthetic token batches directly on the GPU. | +| Memory sampling | [`sample_memory()` — line 347](memory_diagnostics.py#L347) | Records allocated, reserved, peak, and device-wide memory at a phase boundary. | +| Training cycle | [`training_step()` — line 362](memory_diagnostics.py#L362) | Measures forward, backward, optimizer, and cleanup phases. | +| Evidence derivation | [`derive_indicators()` — line 425](memory_diagnostics.py#L425) | Converts raw samples into three hypothesis-testing indicators. | +| Orchestration | [`run()` — line 467](memory_diagnostics.py#L467) | Builds the workload, collects evidence, optionally dumps snapshots, and gathers ranks. | + +## Limitations + +- Synchronizing at every phase makes the measurement boundaries clear but + distorts step timing; this is a memory experiment, not a throughput benchmark. +- Synthetic reused input excludes data-loader and host-to-device transfer + memory. Diagnose those separately in a real application. +- Model-size changes affect both parameters and activations. The small-batch + medium run reduces, but does not eliminate, that confounder. +- DDP may create persistent gradient-bucket storage during its first backward + pass. Diagnose the three core cases on one GPU first; in the extension, + compare otherwise identical DDP runs rather than applying single-GPU + thresholds blindly. +- The anonymous cases isolate one dominant cause each. Real workloads can have + several simultaneous sources of pressure. +- Allocator internals used for optional snapshots have underscored names and + are more version-sensitive than the ordinary counter API. + +## Further reading + +- [PyTorch CUDA memory management API](https://docs.pytorch.org/docs/stable/cuda.html#memory-management) +- [PyTorch: Understanding CUDA Memory Usage](https://docs.pytorch.org/docs/stable/torch_cuda_memory.html) +- [PyTorch `max_memory_allocated`](https://docs.pytorch.org/docs/stable/generated/torch.cuda.memory.max_memory_allocated.html) diff --git a/source-code/pytorch/memory-diagnostics/SOLUTION.md b/source-code/pytorch/memory-diagnostics/SOLUTION.md new file mode 100644 index 0000000..d4b6c9b --- /dev/null +++ b/source-code/pytorch/memory-diagnostics/SOLUTION.md @@ -0,0 +1,93 @@ +# Reference solution: empirical CUDA memory diagnosis + +Run the commands in the exercise before reading this file. Exact MiB values are +hardware- and version-dependent; the phase and scaling patterns are the answer. + +## Reference procedure + +The following is a complete runnable collection and comparison sequence: + +```bash +python memory_diagnostics.py --case alpha --output alpha.json +python memory_diagnostics.py --case beta --output beta.json +python memory_diagnostics.py --case gamma --output gamma.json + +python compare_memory_reports.py alpha.json beta.json gamma.json + +python memory_diagnostics.py --case alpha --batch-size-per-device 1 \ + --output alpha-batch1.json +python memory_diagnostics.py --case alpha --batch-size-per-device 4 \ + --output alpha-batch4.json + +python memory_diagnostics.py --case beta --preset medium \ + --batch-size-per-device 1 --output beta-medium.json +python memory_diagnostics.py --case gamma --steps 10 \ + --output gamma-steps10.json +``` + +Skip the `medium` run if it is unsuitable for the allocated GPU. The three +default runs plus the alpha batch sweep are sufficient to meet the core +learning objective. + +## Diagnosis + +| Case | Dominant cause | Decisive evidence | Targeted response | +|---|---|---|---| +| `alpha` | Forward activations | Allocation rises during forward and its increment increases with local batch size, while the post-cleanup baseline remains stable across steps. | Reduce the microbatch, use activation checkpointing, or use a more memory-efficient kernel. | +| `beta` | AdamW optimizer state | The optimizer object initially adds almost no tensor storage, but a persistent allocation appears after the first `optimizer.step()` and remains after gradients are cleared. It grows with parameter count. | Shard model state, use a lower-memory optimizer, or reduce optimizer-state precision where scientifically acceptable. | +| `gamma` | Accidentally retained autograd graphs | `allocated_mib` after gradient clearing grows from one step to the next. More steps produce more growth even though model and batch dimensions are unchanged. | Stop retaining graphs and do not store graph-connected losses; retain only detached CPU values needed for logging. | + +## Why the alternatives are not interchangeable + +Activation checkpointing primarily removes selected forward intermediates and +recomputes them during backward. It is well targeted to `alpha`, but does not +remove AdamW's persistent moment tensors in `beta` and does not repair the +lifetime bug in `gamma`. + +FSDP can shard parameters, gradients, and optimizer state, making it plausible +for `beta` when those states dominate. It may also reduce some model-related +baseline in the other cases, but it leaves ordinary unsharded activations local +and merely distributes a retained-graph bug across processes. + +Calling `torch.cuda.empty_cache()` is not a repair. It can release unused cached +blocks to other applications, but it cannot free the live tensors represented +by `allocated_mib`. A large `reserved_mib - allocated_mib` gap is therefore not, +by itself, proof of a leak. + +## Source confirmation + +After making the empirical diagnosis, inspect `CASES` and `training_step()` in +[`memory_diagnostics.py`](memory_diagnostics.py): + +- `alpha` uses stateless SGD and the normal graph lifetime; +- `beta` uses AdamW, whose moment buffers are initialized lazily at its first + update; +- `gamma` requests `retain_graph=True` and keeps each graph-connected loss in a + list. + +The intentionally bad `gamma` behavior should be repaired in production as: + +```python +loss.backward() +logged_losses.append(loss.detach().cpu().item()) +``` + +Often it is better to maintain an online scalar sum rather than store every +value. Merely using `loss.detach()` while retaining the tensor on the GPU would +still keep that tensor's storage alive, although it would break the autograd +connection. + +## Interpreting DDP evidence + +With equal local workloads, ranks should have similar phase patterns, although +small differences can result from allocator and communication details. DDP can +also establish persistent gradient-bucket storage during the first backward, +so its first-step baseline need not equal the single-GPU result. With +`--rank-zero-extra-samples`, rank zero should show a larger forward increment. +The maximum across ranks is the relevant capacity constraint: the complete job +fails if any one rank exhausts its GPU. + +PyTorch allocator counters omit some memory allocated directly by NCCL and +other CUDA libraries. A larger `device_used_mib` than `reserved_mib` is +therefore expected, but device-wide usage can also include unrelated processes +unless the GPU allocation is exclusive. diff --git a/source-code/pytorch/memory-diagnostics/compare_memory_reports.py b/source-code/pytorch/memory-diagnostics/compare_memory_reports.py new file mode 100644 index 0000000..57d6dd4 --- /dev/null +++ b/source-code/pytorch/memory-diagnostics/compare_memory_reports.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python3 +"""Compare JSON reports produced by memory_diagnostics.py.""" + +from __future__ import annotations + +import argparse +import json +import sys +from pathlib import Path +from typing import Any + + +def parse_arguments() -> argparse.Namespace: + """Parse report paths.""" + + parser = argparse.ArgumentParser( + description="Tabulate CUDA-memory diagnosis indicators.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + parser.add_argument("reports", nargs="+", type=Path) + parser.add_argument( + "--show-phases", + action="store_true", + help="also show rank-maximum allocated memory at first-step boundaries", + ) + return parser.parse_args() + + +def load_report(path: Path) -> dict[str, Any]: + """Load and minimally validate one exercise report.""" + + with path.open(encoding="utf-8") as handle: + report = json.load(handle) + required = {"case", "preset", "batch_size_per_device", "rank_reports"} + missing = required.difference(report) + if missing: + raise ValueError(f"{path}: missing fields: {', '.join(sorted(missing))}") + if not report["rank_reports"]: + raise ValueError(f"{path}: contains no rank reports") + return report + + +def maximum_indicator(report: dict[str, Any], name: str) -> float: + """Return the largest indicator across ranks.""" + + return max(rank["indicators"][name] for rank in report["rank_reports"]) + + +def maximum_phase_allocation( + report: dict[str, Any], step: int, phase: str +) -> float: + """Return the largest allocated-memory sample for a phase across ranks.""" + + values = [] + for rank in report["rank_reports"]: + values.extend( + sample["allocated_mib"] + for sample in rank["samples"] + if sample["step"] == step and sample["phase"] == phase + ) + if not values: + raise ValueError(f"missing phase sample: step={step}, phase={phase}") + return max(values) + + +def main() -> int: + """Print side-by-side evidence without automatically naming a diagnosis.""" + + arguments = parse_arguments() + try: + loaded = [(path, load_report(path)) for path in arguments.reports] + except (OSError, ValueError, json.JSONDecodeError) as error: + print(f"error: {error}", file=sys.stderr) + return 2 + + headings = ( + "report", + "case", + "preset", + "batch", + "first persistent MiB", + "step growth MiB", + "forward increase MiB", + "peak MiB", + ) + rows = [] + for path, report in loaded: + rows.append( + ( + path.name, + str(report["case"]), + str(report["preset"]), + str(report["batch_size_per_device"]), + f"{maximum_indicator(report, 'first_step_persistent_change_mib'):.1f}", + f"{maximum_indicator(report, 'between_step_growth_mib'):.1f}", + f"{maximum_indicator(report, 'largest_forward_increase_mib'):.1f}", + f"{maximum_indicator(report, 'maximum_peak_allocated_mib'):.1f}", + ) + ) + + widths = [ + max(len(headings[column]), *(len(row[column]) for row in rows)) + for column in range(len(headings)) + ] + print(" ".join(value.ljust(width) for value, width in zip(headings, widths))) + print(" ".join("-" * width for width in widths)) + for row in rows: + print(" ".join(value.ljust(width) for value, width in zip(row, widths))) + + if arguments.show_phases: + phase_columns = ( + (-1, "after_input", "input"), + (0, "after_forward", "forward"), + (0, "after_backward", "backward"), + (0, "after_optimizer_step", "optimizer"), + (0, "after_clear_gradients", "cleared"), + ) + phase_headings = ("report", *(label for _, _, label in phase_columns)) + phase_rows = [] + try: + for path, report in loaded: + phase_rows.append( + ( + path.name, + *( + f"{maximum_phase_allocation(report, step, phase):.1f}" + for step, phase, _ in phase_columns + ), + ) + ) + except ValueError as error: + print(f"error: {error}", file=sys.stderr) + return 2 + phase_widths = [ + max( + len(phase_headings[column]), + *(len(row[column]) for row in phase_rows), + ) + for column in range(len(phase_headings)) + ] + print("\nFirst-step allocated memory (MiB; maximum across ranks)") + print( + " ".join( + value.ljust(width) for value, width in zip(phase_headings, phase_widths) + ) + ) + print(" ".join("-" * width for width in phase_widths)) + for row in phase_rows: + print( + " ".join( + value.ljust(width) for value, width in zip(row, phase_widths) + ) + ) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/source-code/pytorch/memory-diagnostics/memory_diagnostics.py b/source-code/pytorch/memory-diagnostics/memory_diagnostics.py new file mode 100644 index 0000000..5a5f62c --- /dev/null +++ b/source-code/pytorch/memory-diagnostics/memory_diagnostics.py @@ -0,0 +1,634 @@ +#!/usr/bin/env python3 +"""Collect phase-by-phase CUDA memory evidence for three mystery workloads. + +The script runs on one GPU with plain ``python`` and optionally on several GPUs +with ``torchrun``. It uses a locally constructed transformer and synthetic +GPU-resident inputs, so it downloads neither a model nor a dataset. + +Start with one GPU and compare the anonymous cases empirically:: + + python memory_diagnostics.py --case alpha --output alpha.json + python memory_diagnostics.py --case beta --output beta.json + python memory_diagnostics.py --case gamma --output gamma.json +""" + +from __future__ import annotations + +import argparse +import json +import math +import os +import platform +import socket +import sys +from dataclasses import asdict, dataclass +from datetime import timedelta +from pathlib import Path +from typing import Any + +import torch +import torch.distributed as dist +from torch import Tensor, nn +from torch.nn.parallel import DistributedDataParallel as DDP + +MEBIBYTE = 2**20 + + +@dataclass(frozen=True) +class ModelConfig: + """Dimensions for one synthetic transformer preset.""" + + layers: int + hidden_size: int + attention_heads: int + feedforward_size: int + sequence_length: int + vocabulary_size: int = 4096 + classes: int = 16 + + +@dataclass(frozen=True) +class CaseConfig: + """Hidden implementation choices behind one mystery case.""" + + optimizer: str + retain_training_graphs: bool + + +PRESETS = { + "small": ModelConfig( + layers=4, + hidden_size=384, + attention_heads=6, + feedforward_size=1536, + sequence_length=256, + ), + "medium": ModelConfig( + layers=8, + hidden_size=512, + attention_heads=8, + feedforward_size=2048, + sequence_length=512, + ), +} + +# The labels deliberately do not reveal the expected diagnosis. Participants +# should inspect this mapping only after using the measurements to form a +# hypothesis. +CASES = { + "alpha": CaseConfig(optimizer="sgd", retain_training_graphs=False), + "beta": CaseConfig(optimizer="adamw", retain_training_graphs=False), + "gamma": CaseConfig(optimizer="sgd", retain_training_graphs=True), +} + + +def positive_integer(value: str) -> int: + """Parse a positive command-line integer.""" + + number = int(value) + if number <= 0: + raise argparse.ArgumentTypeError("must be a positive integer") + return number + + +def non_negative_integer(value: str) -> int: + """Parse a non-negative command-line integer.""" + + number = int(value) + if number < 0: + raise argparse.ArgumentTypeError("must be a non-negative integer") + return number + + +def parse_arguments() -> argparse.Namespace: + """Parse options and protect output files before allocating GPU memory.""" + + parser = argparse.ArgumentParser( + description="Diagnose CUDA memory pressure from phase measurements.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + parser.add_argument("--case", choices=tuple(CASES), required=True) + parser.add_argument("--preset", choices=tuple(PRESETS), default="small") + parser.add_argument( + "--batch-size-per-device", + type=positive_integer, + default=2, + help="synthetic samples held on each GPU", + ) + parser.add_argument( + "--steps", type=positive_integer, default=6, help="measured training steps" + ) + parser.add_argument( + "--rank-zero-extra-samples", + type=non_negative_integer, + default=0, + help="optional DDP extension that makes rank zero's local batch larger", + ) + parser.add_argument( + "--precision", + choices=("fp32", "bf16"), + default="fp32", + help="BF16 requires support on every participating GPU", + ) + parser.add_argument("--seed", type=int, default=1234) + parser.add_argument( + "--output", type=Path, required=True, help="rank-zero JSON report path" + ) + parser.add_argument( + "--overwrite-output", + action="store_true", + help="allow replacement of an existing JSON report", + ) + parser.add_argument( + "--snapshot", + type=Path, + help="optional base path for a detailed allocator snapshot per rank", + ) + parser.add_argument( + "--snapshot-max-entries", + type=positive_integer, + default=100_000, + help="maximum recorded allocator-history entries per rank", + ) + parser.add_argument( + "--overwrite-snapshot", + action="store_true", + help="allow replacement of rank-qualified snapshot files", + ) + parser.add_argument( + "--local-rank", "--local_rank", type=int, help=argparse.SUPPRESS + ) + arguments = parser.parse_args() + + if arguments.seed < 0: + parser.error("--seed must be non-negative") + validate_new_file(parser, arguments.output, arguments.overwrite_output) + if arguments.snapshot is not None: + validate_new_file(parser, arguments.snapshot, arguments.overwrite_snapshot) + return arguments + + +def validate_new_file( + parser: argparse.ArgumentParser, path: Path, overwrite: bool +) -> None: + """Reject missing parents, directories, and accidental replacement.""" + + if path.is_dir(): + parser.error(f"output path is a directory: {path}") + if path.exists() and not overwrite: + parser.error(f"output already exists: {path}; enable overwrite explicitly") + if not path.parent.exists(): + parser.error(f"output directory does not exist: {path.parent}") + + +def initialize_runtime() -> tuple[int, int, int, torch.device]: + """Select one CUDA device and initialize NCCL when launched by torchrun.""" + + if not torch.cuda.is_available(): + raise RuntimeError("CUDA is unavailable; this exercise requires a GPU") + + distributed_variables = ("LOCAL_RANK", "RANK", "WORLD_SIZE") + supplied = [name in os.environ for name in distributed_variables] + if any(supplied) and not all(supplied): + raise RuntimeError( + "incomplete torchrun environment: LOCAL_RANK, RANK, and WORLD_SIZE " + "must either all be set or all be absent" + ) + + if all(supplied): + local_rank = int(os.environ["LOCAL_RANK"]) + rank = int(os.environ["RANK"]) + world_size = int(os.environ["WORLD_SIZE"]) + else: + local_rank = rank = 0 + world_size = 1 + + visible_devices = torch.cuda.device_count() + if not 0 <= local_rank < visible_devices: + raise RuntimeError( + f"LOCAL_RANK={local_rank}, but this process sees {visible_devices} GPU(s)" + ) + torch.cuda.set_device(local_rank) + device = torch.device("cuda", local_rank) + + if world_size > 1: + dist.init_process_group( + backend="nccl", init_method="env://", timeout=timedelta(minutes=5) + ) + return local_rank, rank, world_size, device + + +def resolve_precision(requested: str, device: torch.device) -> bool: + """Return whether BF16 autocast can be used consistently across ranks.""" + + if requested == "fp32": + return False + supported = torch.tensor( + int(torch.cuda.is_bf16_supported()), dtype=torch.int32, device=device + ) + if dist.is_initialized(): + dist.all_reduce(supported, op=dist.ReduceOp.MIN) + if not bool(supported.item()): + raise ValueError("BF16 was requested but at least one GPU lacks support") + return True + + +class TransformerBlock(nn.Module): + """A pre-normalized attention and feed-forward block.""" + + def __init__(self, config: ModelConfig) -> None: + super().__init__() + self.attention_norm = nn.LayerNorm(config.hidden_size) + self.attention = nn.MultiheadAttention( + config.hidden_size, + config.attention_heads, + dropout=0.0, + bias=False, + batch_first=True, + ) + self.feedforward_norm = nn.LayerNorm(config.hidden_size) + self.feedforward = nn.Sequential( + nn.Linear(config.hidden_size, config.feedforward_size, bias=False), + nn.GELU(approximate="tanh"), + nn.Linear(config.feedforward_size, config.hidden_size, bias=False), + ) + + def forward(self, hidden_states: Tensor) -> Tensor: + """Apply attention and feed-forward residual paths.""" + + normalized = self.attention_norm(hidden_states) + attention_output, _ = self.attention( + normalized, normalized, normalized, need_weights=False + ) + hidden_states = hidden_states + attention_output + return hidden_states + self.feedforward(self.feedforward_norm(hidden_states)) + + +class SyntheticTransformer(nn.Module): + """A compact encoder-style transformer for memory experiments.""" + + def __init__(self, config: ModelConfig) -> None: + super().__init__() + self.token_embedding = nn.Embedding(config.vocabulary_size, config.hidden_size) + self.position_embedding = nn.Parameter( + torch.empty(config.sequence_length, config.hidden_size) + ) + nn.init.normal_(self.position_embedding, mean=0.0, std=0.02) + self.blocks = nn.ModuleList( + TransformerBlock(config) for _ in range(config.layers) + ) + self.output_norm = nn.LayerNorm(config.hidden_size) + self.classifier = nn.Linear(config.hidden_size, config.classes, bias=False) + + def forward(self, token_ids: Tensor) -> Tensor: + """Return classification logits for token sequences.""" + + hidden_states = self.token_embedding(token_ids) + hidden_states = hidden_states + self.position_embedding.unsqueeze(0) + for block in self.blocks: + hidden_states = block(hidden_states) + hidden_states = self.output_norm(hidden_states[:, 0]) + return self.classifier(hidden_states) + + +def make_model( + config: ModelConfig, local_rank: int, world_size: int, device: torch.device +) -> nn.Module: + """Create the transformer and optionally wrap one replica in DDP.""" + + model = SyntheticTransformer(config).to(device) + if world_size == 1: + return model + return DDP( + model, + device_ids=[local_rank], + output_device=local_rank, + gradient_as_bucket_view=True, + ) + + +def make_optimizer( + model: nn.Module, case: CaseConfig +) -> torch.optim.Optimizer: + """Create the optimizer selected by the anonymous workload.""" + + if case.optimizer == "sgd": + return torch.optim.SGD(model.parameters(), lr=1e-3) + if case.optimizer == "adamw": + return torch.optim.AdamW(model.parameters(), lr=1e-4) + raise AssertionError(f"unknown optimizer: {case.optimizer}") + + +def make_batch( + config: ModelConfig, + batch_size: int, + rank: int, + seed: int, + device: torch.device, +) -> tuple[Tensor, Tensor]: + """Create one reproducible rank-specific batch directly on the GPU.""" + + generator = torch.Generator(device=device).manual_seed(seed + rank) + token_ids = torch.randint( + config.vocabulary_size, + (batch_size, config.sequence_length), + generator=generator, + device=device, + ) + targets = torch.randint( + config.classes, + (batch_size,), + generator=generator, + device=device, + ) + return token_ids, targets + + +def sample_memory(device: torch.device, step: int, phase: str) -> dict[str, Any]: + """Synchronize and record process-local and device-wide CUDA memory.""" + + torch.cuda.synchronize(device) + free_bytes, total_bytes = torch.cuda.mem_get_info(device) + return { + "step": step, + "phase": phase, + "allocated_mib": torch.cuda.memory_allocated(device) / MEBIBYTE, + "reserved_mib": torch.cuda.memory_reserved(device) / MEBIBYTE, + "peak_allocated_mib": torch.cuda.max_memory_allocated(device) / MEBIBYTE, + "device_used_mib": (total_bytes - free_bytes) / MEBIBYTE, + } + + +def training_step( + model: nn.Module, + token_ids: Tensor, + targets: Tensor, + optimizer: torch.optim.Optimizer, + case: CaseConfig, + use_bf16: bool, + step: int, + device: torch.device, + retained_losses: list[Tensor], +) -> tuple[Tensor, list[dict[str, Any]]]: + """Run one cycle and measure forward, backward, update, and cleanup phases.""" + + torch.cuda.reset_peak_memory_stats(device) + with torch.autocast(device_type="cuda", dtype=torch.bfloat16, enabled=use_bf16): + logits = model(token_ids) + loss = nn.functional.cross_entropy(logits.float(), targets) + samples = [sample_memory(device, step, "after_forward")] + + # One anonymous case deliberately preserves old training graphs. The + # measurements, rather than this line, should be the participant's first + # evidence that live allocations accumulate between steps. + loss.backward(retain_graph=case.retain_training_graphs) + samples.append(sample_memory(device, step, "after_backward")) + optimizer.step() + samples.append(sample_memory(device, step, "after_optimizer_step")) + + if case.retain_training_graphs: + retained_losses.append(loss) + optimizer.zero_grad(set_to_none=True) + samples.append(sample_memory(device, step, "after_clear_gradients")) + return loss.detach(), samples + + +def snapshot_path(base: Path, rank: int) -> Path: + """Make allocator snapshot names collision-free across ranks.""" + + suffix = base.suffix or ".pickle" + stem = base.stem if base.suffix else base.name + return base.with_name(f"{stem}-rank{rank}{suffix}") + + +def enable_memory_history(max_entries: int) -> None: + """Enable PyTorch's optional allocator-history recorder.""" + + memory_module = torch.cuda.memory + recorder = getattr(memory_module, "_record_memory_history", None) + if recorder is None: + raise RuntimeError( + "this PyTorch build does not provide CUDA allocator history recording" + ) + recorder(max_entries=max_entries) + + +def dump_memory_snapshot(path: Path) -> None: + """Write a snapshot consumable by the PyTorch memory visualizer.""" + + dumper = getattr(torch.cuda.memory, "_dump_snapshot", None) + if dumper is None: + raise RuntimeError("this PyTorch build cannot dump CUDA memory snapshots") + dumper(str(path)) + + +def derive_indicators(samples: list[dict[str, Any]]) -> dict[str, float]: + """Derive diagnosis aids without assigning a semantic label to the case.""" + + initial = next(sample for sample in samples if sample["phase"] == "after_input") + cleared = [ + sample for sample in samples if sample["phase"] == "after_clear_gradients" + ] + forwards = [sample for sample in samples if sample["phase"] == "after_forward"] + first_persistent_change = cleared[0]["allocated_mib"] - initial["allocated_mib"] + between_step_growth = cleared[-1]["allocated_mib"] - cleared[0]["allocated_mib"] + + baselines = [initial, *cleared[:-1]] + forward_increases = [ + forward["allocated_mib"] - baseline["allocated_mib"] + for forward, baseline in zip(forwards, baselines, strict=True) + ] + return { + "first_step_persistent_change_mib": first_persistent_change, + "between_step_growth_mib": between_step_growth, + "largest_forward_increase_mib": max(forward_increases), + "maximum_peak_allocated_mib": max( + sample["peak_allocated_mib"] for sample in samples + ), + } + + +def gather_rank_reports( + local_report: dict[str, Any], rank: int, world_size: int +) -> list[dict[str, Any]] | None: + """Collect compact per-rank evidence on rank zero.""" + + if world_size == 1: + return [local_report] + gathered: list[dict[str, Any] | None] | None + gathered = [None] * world_size if rank == 0 else None + dist.gather_object(local_report, gathered, dst=0) + if rank != 0: + return None + assert gathered is not None and all(report is not None for report in gathered) + return [report for report in gathered if report is not None] + + +def run(arguments: argparse.Namespace) -> dict[str, Any] | None: + """Construct the workload, collect phase evidence, and gather all ranks.""" + + local_rank, rank, world_size, device = initialize_runtime() + use_bf16 = resolve_precision(arguments.precision, device) + config = PRESETS[arguments.preset] + case = CASES[arguments.case] + rank_snapshot = ( + snapshot_path(arguments.snapshot, rank) + if arguments.snapshot is not None + else None + ) + if rank_snapshot is not None and rank_snapshot.exists(): + if not arguments.overwrite_snapshot: + raise FileExistsError( + f"snapshot already exists: {rank_snapshot}; enable overwrite explicitly" + ) + + if rank_snapshot is not None: + enable_memory_history(arguments.snapshot_max_entries) + + torch.manual_seed(arguments.seed) + model = make_model(config, local_rank, world_size, device) + parameter_count = sum(parameter.numel() for parameter in model.parameters()) + torch.cuda.reset_peak_memory_stats(device) + samples = [sample_memory(device, -1, "after_model")] + + optimizer = make_optimizer(model, case) + samples.append(sample_memory(device, -1, "after_optimizer_creation")) + token_ids, targets = make_batch( + config, + arguments.batch_size_per_device + + (arguments.rank_zero_extra_samples if rank == 0 else 0), + rank, + arguments.seed, + device, + ) + samples.append(sample_memory(device, -1, "after_input")) + + retained_losses: list[Tensor] = [] + loss = torch.zeros((), device=device) + for step in range(arguments.steps): + loss, step_samples = training_step( + model, + token_ids, + targets, + optimizer, + case, + use_bf16, + step, + device, + retained_losses, + ) + samples.extend(step_samples) + + if not math.isfinite(loss.item()): + raise RuntimeError("the final loss is not finite; retry with FP32") + if rank_snapshot is not None: + dump_memory_snapshot(rank_snapshot) + + free_bytes, total_bytes = torch.cuda.mem_get_info(device) + local_report = { + "rank": rank, + "local_rank": local_rank, + "local_batch_size": token_ids.shape[0], + "gpu_name": torch.cuda.get_device_name(device), + "device_total_mib": total_bytes / MEBIBYTE, + "device_free_at_end_mib": free_bytes / MEBIBYTE, + "snapshot": str(rank_snapshot) if rank_snapshot is not None else None, + "samples": samples, + "indicators": derive_indicators(samples), + } + rank_reports = gather_rank_reports(local_report, rank, world_size) + if rank != 0: + return None + assert rank_reports is not None + return { + "exercise": "empirical CUDA memory diagnosis", + "case": arguments.case, + "preset": arguments.preset, + "model_config": asdict(config), + "parameter_count": parameter_count, + "parameters_fp32_mib": 4 * parameter_count / MEBIBYTE, + "batch_size_per_device": arguments.batch_size_per_device, + "rank_zero_extra_samples": arguments.rank_zero_extra_samples, + "steps": arguments.steps, + "precision": arguments.precision, + "world_size": world_size, + "seed": arguments.seed, + "final_loss_rank_zero": loss.item(), + "rank_reports": rank_reports, + "pytorch_version": torch.__version__, + "cuda_version": torch.version.cuda, + "python_version": platform.python_version(), + "hostname_rank_zero": socket.gethostname(), + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "measurement_notes": { + "allocated": "live tensor memory tracked by the PyTorch CUDA allocator", + "reserved": "memory held by the PyTorch caching allocator", + "device_used": "device-wide use, including other processes and libraries", + "peak": "maximum allocated since the per-step peak reset", + }, + } + + +def print_summary(result: dict[str, Any]) -> None: + """Print evidence from every rank in a compact Slurm-log format.""" + + print("PyTorch CUDA memory-diagnostics exercise") + print(f" mystery case: {result['case']}") + print(f" preset: {result['preset']}") + print(f" GPUs: {result['world_size']}") + print(f" batch/device: {result['batch_size_per_device']}") + print(f" precision: {result['precision']}") + print(f" FP32 parameter memory: {result['parameters_fp32_mib']:.1f} MiB") + for rank_report in result["rank_reports"]: + indicators = rank_report["indicators"] + print(f" rank {rank_report['rank']} indicators:") + print( + " first-step persistent change: " + f"{indicators['first_step_persistent_change_mib']:.1f} MiB" + ) + print( + " between-step growth: " + f"{indicators['between_step_growth_mib']:.1f} MiB" + ) + print( + " largest forward increase: " + f"{indicators['largest_forward_increase_mib']:.1f} MiB" + ) + print( + " maximum peak allocated: " + f"{indicators['maximum_peak_allocated_mib']:.1f} MiB" + ) + + +def main() -> int: + """Run the selected case and write the rank-zero JSON report.""" + + arguments = parse_arguments() + try: + result = run(arguments) + if result is not None: + print_summary(result) + text = json.dumps(result, indent=2, sort_keys=True) + arguments.output.write_text(f"{text}\n", encoding="utf-8") + print(f" JSON result: {arguments.output}") + return 0 + except torch.cuda.OutOfMemoryError as error: + rank = os.environ.get("RANK", "0") + print( + f"rank {rank}: CUDA out of memory. This is capacity evidence, but the " + "exercise does not require an OOM. Retry with --preset small or a " + f"smaller batch. Original error: {error}", + file=sys.stderr, + ) + return 3 + except (FileExistsError, OSError, RuntimeError, ValueError) as error: + rank = os.environ.get("RANK", "0") + print(f"rank {rank}: error: {error}", file=sys.stderr) + return 2 + finally: + if dist.is_initialized(): + dist.destroy_process_group() + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/source-code/pytorch/mnist_cross_validation.ipynb b/source-code/pytorch/mnist_cross_validation.ipynb new file mode 100644 index 0000000..50b2733 --- /dev/null +++ b/source-code/pytorch/mnist_cross_validation.ipynb @@ -0,0 +1,1221 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3e6ee324", + "metadata": {}, + "source": [ + "# MNIST: cross-validation with a multilayer perceptron\n", + "\n", + "A single validation split gives one estimate of how well a model generalizes. That estimate can depend on which examples happened to enter the validation set. In this notebook, we use **stratified $k$-fold cross-validation** to measure that variation and to compare two multilayer perceptrons (MLPs) without consulting the test set.\n", + "\n", + "This is a **tutorial notebook** intended to follow `mnist_mlp.ipynb`. The default workflow takes approximately 10–20 minutes on a typical CPU, including interpretation; the full experiment is substantially more expensive.\n", + "\n", + "## Learning objectives\n", + "\n", + "After completing the notebook, you should be able to:\n", + "\n", + "- explain what changes between folds and what remains fixed;\n", + "- implement stratified $k$-fold cross-validation without leaking information between folds;\n", + "- compare candidate models using paired folds and summarize fold-to-fold variation;\n", + "- keep the test set outside model selection and use it only after the choice is frozen;\n", + "- recognize when ordinary random cross-validation is inappropriate or unnecessarily expensive.\n", + "\n", + "## Prerequisites and expected output\n", + "\n", + "**Required:** the train/validation/test distinction, PyTorch datasets and data loaders, and the MLP training loop introduced in `mnist_mlp.ipynb`.\n", + "\n", + "**Helpful, but not required:** familiarity with means, standard deviations, and class stratification.\n", + "\n", + "The notebook produces per-fold loss and accuracy, a paired comparison of a classic and dropout MLP, and one final test-set result. It downloads MNIST into `data/` if necessary. No package installation is performed inside the notebook." + ] + }, + { + "cell_type": "markdown", + "id": "fb139ff5", + "metadata": {}, + "source": [ + "## Experimental design\n", + "\n", + "The official MNIST training split is our source of **development data**. We divide the working development set into $k$ folds. Each fold becomes the validation fold once, while the other $k-1$ folds are used for training.\n", + "\n", + "The official test split is not one of the folds. It remains untouched until we have selected a model configuration and fitted that configuration one final time.\n", + "\n", + "The quick configuration uses a stratified subset of the official training split so that repeated training remains practical during a course. This makes the notebook a demonstration of the method, not an attempt to obtain the best possible MNIST model. Set `FULL_EXPERIMENT = True` to cross-validate on all 60,000 development examples." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "849d27db", + "metadata": {}, + "outputs": [], + "source": [ + "from collections.abc import Callable, Sequence\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "import torch\n", + "from IPython.display import display\n", + "from sklearn.model_selection import StratifiedKFold, StratifiedShuffleSplit\n", + "from torch import nn\n", + "from torch.utils.data import DataLoader, Dataset, Subset\n", + "from torchvision import datasets\n", + "from torchvision.transforms import v2" + ] + }, + { + "cell_type": "markdown", + "id": "165e55fe", + "metadata": {}, + "source": [ + "## Configuration\n", + "\n", + "Five folds make the mechanics and the fold-to-fold variation visible. The quick path deliberately uses a small model, a subset, and only three epochs. Cross-validation multiplies training cost: comparing two candidates with five folds requires ten independent fits before the final refit." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "8264ed4a", + "metadata": {}, + "outputs": [], + "source": [ + "FULL_EXPERIMENT = False\n", + "\n", + "N_SPLITS = 5\n", + "DEVELOPMENT_EXAMPLES = None if FULL_EXPERIMENT else 12_000\n", + "EPOCHS = 10 if FULL_EXPERIMENT else 3\n", + "BATCH_SIZE = 256\n", + "LEARNING_RATE = 0.05\n", + "MOMENTUM = 0.9\n", + "\n", + "SPLIT_SEED = 1_734\n", + "MODEL_SEED = 2_741\n", + "LOADER_SEED = 3_907\n", + "FINAL_MODEL_SEED = 4_997" + ] + }, + { + "cell_type": "markdown", + "id": "ec0ed3d2", + "metadata": {}, + "source": [ + "## Reproducibility and device selection\n", + "\n", + "Fixed seeds make the data splits and CPU runs reproducible under the same software and hardware configuration. Exact results can still differ across PyTorch versions and devices. We pass transfer settings explicitly so that data-loader memory pinning and device transfers remain distinct concerns." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "0877e241", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Using device: cuda\n" + ] + } + ], + "source": [ + "torch.manual_seed(MODEL_SEED)\n", + "\n", + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "using_cuda = device.type == \"cuda\"\n", + "print(f\"Using device: {device}\")" + ] + }, + { + "cell_type": "markdown", + "id": "ed6f5092", + "metadata": {}, + "source": [ + "## Prepare the data\n", + "\n", + "The transformation converts each image to a `float32` tensor in channels-first format and scales pixel values to $[0, 1]$. The labels remain integer class indices, as required by `nn.CrossEntropyLoss`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "c9a986e6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Official development examples: 60,000\n", + "Official test examples: 10,000\n" + ] + } + ], + "source": [ + "transform = v2.Compose(\n", + " [\n", + " v2.ToImage(),\n", + " v2.ToDtype(torch.float32, scale=True),\n", + " ]\n", + ")\n", + "\n", + "official_development_data = datasets.MNIST(\n", + " root=\"data\",\n", + " train=True,\n", + " download=True,\n", + " transform=transform,\n", + ")\n", + "official_test_data = datasets.MNIST(\n", + " root=\"data\",\n", + " train=False,\n", + " download=True,\n", + " transform=transform,\n", + ")\n", + "\n", + "all_development_targets = official_development_data.targets.numpy()\n", + "print(f\"Official development examples: {len(official_development_data):,}\")\n", + "print(f\"Official test examples: {len(official_test_data):,}\")" + ] + }, + { + "cell_type": "markdown", + "id": "f0ea88b4", + "metadata": {}, + "source": [ + "### Select the working development set\n", + "\n", + "In quick mode, `StratifiedShuffleSplit` selects a smaller working set while approximately preserving the digit proportions. The remaining official training examples are simply unused in this demonstration; they are **not** silently treated as test data." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "f6883622", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Working development examples: 60,000\n", + "Class counts: [5923, 6742, 5958, 6131, 5842, 5421, 5918, 6265, 5851, 5949]\n" + ] + } + ], + "source": [ + "if DEVELOPMENT_EXAMPLES is None:\n", + " development_positions = np.arange(len(official_development_data))\n", + "else:\n", + " subset_splitter = StratifiedShuffleSplit(\n", + " n_splits=1,\n", + " train_size=DEVELOPMENT_EXAMPLES,\n", + " random_state=SPLIT_SEED,\n", + " )\n", + " development_positions, _ = next(\n", + " subset_splitter.split(\n", + " np.zeros(len(official_development_data)),\n", + " all_development_targets,\n", + " )\n", + " )\n", + "\n", + "development_data = Subset(\n", + " official_development_data,\n", + " development_positions.tolist(),\n", + ")\n", + "development_targets = all_development_targets[development_positions]\n", + "\n", + "print(f\"Working development examples: {len(development_data):,}\")\n", + "print(\n", + " \"Class counts:\",\n", + " np.bincount(development_targets, minlength=10).tolist(),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "0db8aca7", + "metadata": {}, + "source": [ + "## Construct the folds\n", + "\n", + "`StratifiedKFold` keeps the class proportions approximately equal across folds. Shuffling before splitting avoids folds that depend on the original storage order, while `random_state` makes the fold assignment reproducible.\n", + "\n", + "Each example must occur in exactly one validation fold. With 12,000 examples and five folds, predict the number of training and validation examples in each fit before running the next cell." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "68d98304", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
foldtraining examplesvalidation examples
014800012000
124800012000
234800012000
344800012000
454800012000
\n", + "
" + ], + "text/plain": [ + " fold training examples validation examples\n", + "0 1 48000 12000\n", + "1 2 48000 12000\n", + "2 3 48000 12000\n", + "3 4 48000 12000\n", + "4 5 48000 12000" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "splitter = StratifiedKFold(\n", + " n_splits=N_SPLITS,\n", + " shuffle=True,\n", + " random_state=SPLIT_SEED,\n", + ")\n", + "folds = list(\n", + " splitter.split(\n", + " np.zeros(len(development_data)),\n", + " development_targets,\n", + " )\n", + ")\n", + "\n", + "validation_positions = np.concatenate(\n", + " [validation for _, validation in folds]\n", + ")\n", + "assert len(validation_positions) == len(development_data)\n", + "assert np.array_equal(\n", + " np.sort(validation_positions),\n", + " np.arange(len(development_data)),\n", + ")\n", + "\n", + "fold_sizes = pd.DataFrame(\n", + " [\n", + " {\n", + " \"fold\": fold_number,\n", + " \"training examples\": len(training),\n", + " \"validation examples\": len(validation),\n", + " }\n", + " for fold_number, (training, validation) in enumerate(folds, start=1)\n", + " ]\n", + ")\n", + "display(fold_sizes)" + ] + }, + { + "cell_type": "markdown", + "id": "b9bb7e28", + "metadata": {}, + "source": [ + "## Define the candidate MLPs\n", + "\n", + "Both candidates have the same linear layers. The second adds dropout after each hidden activation. Keeping the architecture simple lets us focus on the experimental design rather than on image-specific CNN details.\n", + "\n", + "A model factory is crucial: calling it creates a **new model with new parameters** for every fold. Reusing a trained model would leak information from earlier validation folds into later fits." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "9059910d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Trainable parameters per model: 109,386\n" + ] + } + ], + "source": [ + "class MnistMLP(nn.Module):\n", + " def __init__(self, dropout_probability: float = 0.0) -> None:\n", + " super().__init__()\n", + " self.layers = nn.Sequential(\n", + " nn.Flatten(),\n", + " nn.Linear(28 * 28, 128),\n", + " nn.ReLU(),\n", + " nn.Dropout(dropout_probability),\n", + " nn.Linear(128, 64),\n", + " nn.ReLU(),\n", + " nn.Dropout(dropout_probability),\n", + " nn.Linear(64, 10),\n", + " )\n", + "\n", + " def forward(self, images: torch.Tensor) -> torch.Tensor:\n", + " return self.layers(images)\n", + "\n", + "\n", + "def make_classic_mlp() -> nn.Module:\n", + " return MnistMLP(dropout_probability=0.0)\n", + "\n", + "\n", + "def make_dropout_mlp() -> nn.Module:\n", + " return MnistMLP(dropout_probability=0.25)\n", + "\n", + "\n", + "model_factories: dict[str, Callable[[], nn.Module]] = {\n", + " \"classic\": make_classic_mlp,\n", + " \"dropout\": make_dropout_mlp,\n", + "}\n", + "\n", + "parameter_count = sum(\n", + " parameter.numel() for parameter in make_classic_mlp().parameters()\n", + ")\n", + "print(f\"Trainable parameters per model: {parameter_count:,}\")" + ] + }, + { + "cell_type": "markdown", + "id": "e1e38927", + "metadata": {}, + "source": [ + "## Training and evaluation helpers\n", + "\n", + "The helpers aggregate loss and accuracy by example rather than averaging batch averages. Every relevant execution setting is passed explicitly. Validation loaders are not shuffled because ordering does not affect their metrics." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "64c8d7dc", + "metadata": {}, + "outputs": [], + "source": [ + "def make_loader(\n", + " dataset: Dataset,\n", + " positions: Sequence[int] | np.ndarray,\n", + " *,\n", + " shuffle: bool,\n", + " seed: int,\n", + " batch_size: int,\n", + " pin_memory: bool,\n", + ") -> DataLoader:\n", + " generator = torch.Generator().manual_seed(seed)\n", + " return DataLoader(\n", + " Subset(dataset, list(positions)),\n", + " batch_size=batch_size,\n", + " shuffle=shuffle,\n", + " generator=generator,\n", + " pin_memory=pin_memory,\n", + " num_workers=0,\n", + " )\n", + "\n", + "\n", + "def train_one_epoch(\n", + " model: nn.Module,\n", + " data_loader: DataLoader,\n", + " loss_function: nn.Module,\n", + " optimizer: torch.optim.Optimizer,\n", + " *,\n", + " device: torch.device,\n", + " non_blocking: bool,\n", + ") -> dict[str, float]:\n", + " model.train()\n", + " total_loss = 0.0\n", + " total_correct = 0\n", + " total_examples = 0\n", + "\n", + " for images, targets in data_loader:\n", + " images = images.to(device, non_blocking=non_blocking)\n", + " targets = targets.to(device, non_blocking=non_blocking)\n", + "\n", + " optimizer.zero_grad(set_to_none=True)\n", + " logits = model(images)\n", + " loss = loss_function(logits, targets)\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " batch_size = targets.size(0)\n", + " total_loss += loss.item() * batch_size\n", + " total_correct += (logits.argmax(dim=1) == targets).sum().item()\n", + " total_examples += batch_size\n", + "\n", + " return {\n", + " \"loss\": total_loss / total_examples,\n", + " \"accuracy\": total_correct / total_examples,\n", + " }\n", + "\n", + "\n", + "@torch.inference_mode()\n", + "def evaluate(\n", + " model: nn.Module,\n", + " data_loader: DataLoader,\n", + " loss_function: nn.Module,\n", + " *,\n", + " device: torch.device,\n", + " non_blocking: bool,\n", + ") -> dict[str, float]:\n", + " model.eval()\n", + " total_loss = 0.0\n", + " total_correct = 0\n", + " total_examples = 0\n", + "\n", + " for images, targets in data_loader:\n", + " images = images.to(device, non_blocking=non_blocking)\n", + " targets = targets.to(device, non_blocking=non_blocking)\n", + " logits = model(images)\n", + " loss = loss_function(logits, targets)\n", + "\n", + " batch_size = targets.size(0)\n", + " total_loss += loss.item() * batch_size\n", + " total_correct += (logits.argmax(dim=1) == targets).sum().item()\n", + " total_examples += batch_size\n", + "\n", + " return {\n", + " \"loss\": total_loss / total_examples,\n", + " \"accuracy\": total_correct / total_examples,\n", + " }" + ] + }, + { + "cell_type": "markdown", + "id": "d417463d", + "metadata": {}, + "source": [ + "## Cross-validation function\n", + "\n", + "For every fold, the function:\n", + "\n", + "1. resets the model seed;\n", + "2. creates fresh training and validation loaders;\n", + "3. creates a fresh model and optimizer;\n", + "4. trains for a fixed number of epochs;\n", + "5. evaluates once on that fold's validation examples.\n", + "\n", + "We use the same folds, initialization seeds, and training-loader seeds for both candidates. This paired design removes avoidable sources of variation from the comparison. Dropout still makes the two optimization paths differ.\n", + "\n", + "Data-dependent preprocessing belongs inside the fold as well: means, scaling parameters, feature selection, or dimensionality reduction must be learned from the training portion only. The MNIST transformation above merely applies a fixed conversion and scaling rule, so it has no fitted state to leak." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "8d83541a", + "metadata": {}, + "outputs": [], + "source": [ + "def cross_validate(\n", + " model_name: str,\n", + " model_factory: Callable[[], nn.Module],\n", + " dataset: Dataset,\n", + " folds: Sequence[tuple[np.ndarray, np.ndarray]],\n", + " *,\n", + " epochs: int,\n", + " batch_size: int,\n", + " learning_rate: float,\n", + " momentum: float,\n", + " model_seed: int,\n", + " loader_seed: int,\n", + " device: torch.device,\n", + " pin_memory: bool,\n", + " non_blocking: bool,\n", + ") -> pd.DataFrame:\n", + " loss_function = nn.CrossEntropyLoss()\n", + " fold_results = []\n", + "\n", + " for fold_number, (training_positions, validation_positions) in enumerate(\n", + " folds,\n", + " start=1,\n", + " ):\n", + " torch.manual_seed(model_seed + fold_number)\n", + "\n", + " training_loader = make_loader(\n", + " dataset,\n", + " training_positions,\n", + " shuffle=True,\n", + " seed=loader_seed + fold_number,\n", + " batch_size=batch_size,\n", + " pin_memory=pin_memory,\n", + " )\n", + " validation_loader = make_loader(\n", + " dataset,\n", + " validation_positions,\n", + " shuffle=False,\n", + " seed=loader_seed + fold_number,\n", + " batch_size=batch_size,\n", + " pin_memory=pin_memory,\n", + " )\n", + "\n", + " model = model_factory().to(device)\n", + " optimizer = torch.optim.SGD(\n", + " model.parameters(),\n", + " lr=learning_rate,\n", + " momentum=momentum,\n", + " )\n", + "\n", + " for _ in range(epochs):\n", + " training_metrics = train_one_epoch(\n", + " model,\n", + " training_loader,\n", + " loss_function,\n", + " optimizer,\n", + " device=device,\n", + " non_blocking=non_blocking,\n", + " )\n", + "\n", + " validation_metrics = evaluate(\n", + " model,\n", + " validation_loader,\n", + " loss_function,\n", + " device=device,\n", + " non_blocking=non_blocking,\n", + " )\n", + "\n", + " fold_results.append(\n", + " {\n", + " \"model\": model_name,\n", + " \"fold\": fold_number,\n", + " \"training_loss\": training_metrics[\"loss\"],\n", + " \"training_accuracy\": training_metrics[\"accuracy\"],\n", + " \"validation_loss\": validation_metrics[\"loss\"],\n", + " \"validation_accuracy\": validation_metrics[\"accuracy\"],\n", + " }\n", + " )\n", + " print(\n", + " f\"{model_name:>7s}, fold {fold_number}: \"\n", + " f\"val_loss={validation_metrics['loss']:.4f}, \"\n", + " f\"val_accuracy={validation_metrics['accuracy']:.4f}\"\n", + " )\n", + "\n", + " return pd.DataFrame(fold_results)" + ] + }, + { + "cell_type": "markdown", + "id": "aed0570d", + "metadata": {}, + "source": [ + "## Run the paired comparison\n", + "\n", + "Before running the cell, make two predictions:\n", + "\n", + "- Will the candidate with the highest training accuracy necessarily have the best mean validation loss?\n", + "- Will one candidate win on every fold?\n", + "\n", + "The selection rule is declared in advance: **select the candidate with the lowest mean validation loss**. The test set plays no role in this decision." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "ccb48b1e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cross-validating classic MLP\n", + "classic, fold 1: val_loss=0.0814, val_accuracy=0.9758\n", + "classic, fold 2: val_loss=0.0906, val_accuracy=0.9748\n", + "classic, fold 3: val_loss=0.0847, val_accuracy=0.9764\n", + "classic, fold 4: val_loss=0.0873, val_accuracy=0.9746\n", + "classic, fold 5: val_loss=0.0962, val_accuracy=0.9742\n", + "\n", + "Cross-validating dropout MLP\n", + "dropout, fold 1: val_loss=0.0832, val_accuracy=0.9743\n", + "dropout, fold 2: val_loss=0.0892, val_accuracy=0.9752\n", + "dropout, fold 3: val_loss=0.0867, val_accuracy=0.9742\n", + "dropout, fold 4: val_loss=0.0929, val_accuracy=0.9714\n", + "dropout, fold 5: val_loss=0.0965, val_accuracy=0.9737\n", + "\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
modelfoldtraining_losstraining_accuracyvalidation_lossvalidation_accuracy
0classic10.03510.98940.08140.9758
1classic20.03280.99000.09060.9748
2classic30.03370.99000.08470.9764
3classic40.03270.99010.08730.9746
4classic50.03340.98930.09620.9742
5dropout10.09920.96920.08320.9743
6dropout20.09630.97090.08920.9752
7dropout30.09650.97000.08670.9742
8dropout40.09240.97190.09290.9714
9dropout50.09650.96980.09650.9737
\n", + "
" + ], + "text/plain": [ + " model fold training_loss training_accuracy validation_loss \\\n", + "0 classic 1 0.0351 0.9894 0.0814 \n", + "1 classic 2 0.0328 0.9900 0.0906 \n", + "2 classic 3 0.0337 0.9900 0.0847 \n", + "3 classic 4 0.0327 0.9901 0.0873 \n", + "4 classic 5 0.0334 0.9893 0.0962 \n", + "5 dropout 1 0.0992 0.9692 0.0832 \n", + "6 dropout 2 0.0963 0.9709 0.0892 \n", + "7 dropout 3 0.0965 0.9700 0.0867 \n", + "8 dropout 4 0.0924 0.9719 0.0929 \n", + "9 dropout 5 0.0965 0.9698 0.0965 \n", + "\n", + " validation_accuracy \n", + "0 0.9758 \n", + "1 0.9748 \n", + "2 0.9764 \n", + "3 0.9746 \n", + "4 0.9742 \n", + "5 0.9743 \n", + "6 0.9752 \n", + "7 0.9742 \n", + "8 0.9714 \n", + "9 0.9737 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "candidate_results = []\n", + "\n", + "for model_name, model_factory in model_factories.items():\n", + " print(f\"Cross-validating {model_name} MLP\")\n", + " candidate_results.append(\n", + " cross_validate(\n", + " model_name,\n", + " model_factory,\n", + " development_data,\n", + " folds,\n", + " epochs=EPOCHS,\n", + " batch_size=BATCH_SIZE,\n", + " learning_rate=LEARNING_RATE,\n", + " momentum=MOMENTUM,\n", + " model_seed=MODEL_SEED,\n", + " loader_seed=LOADER_SEED,\n", + " device=device,\n", + " pin_memory=using_cuda,\n", + " non_blocking=using_cuda,\n", + " )\n", + " )\n", + " print()\n", + "\n", + "cross_validation_results = pd.concat(candidate_results, ignore_index=True)\n", + "display(cross_validation_results.round(4))" + ] + }, + { + "cell_type": "markdown", + "id": "4429ff03", + "metadata": {}, + "source": [ + "## Summarize fold-to-fold variation\n", + "\n", + "The mean summarizes performance across folds. The sample standard deviation describes how much the score changed when the validation examples changed. It is not, by itself, a confidence interval for future performance.\n", + "\n", + "Because both candidates used identical folds, compare them within each fold as well as through their means." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "a6049cc1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
mean_lossstd_lossmean_accuracystd_accuracy
model
classic0.08810.00570.97520.0009
dropout0.08970.00520.97380.0014
\n", + "
" + ], + "text/plain": [ + " mean_loss std_loss mean_accuracy std_accuracy\n", + "model \n", + "classic 0.0881 0.0057 0.9752 0.0009\n", + "dropout 0.0897 0.0052 0.9738 0.0014" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "summary = (\n", + " cross_validation_results.groupby(\"model\")\n", + " .agg(\n", + " mean_loss=(\"validation_loss\", \"mean\"),\n", + " std_loss=(\"validation_loss\", \"std\"),\n", + " mean_accuracy=(\"validation_accuracy\", \"mean\"),\n", + " std_accuracy=(\"validation_accuracy\", \"std\"),\n", + " )\n", + " .sort_values(\"mean_loss\")\n", + ")\n", + "display(summary.round(4))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "8c7cc8f2", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "figure, axes = plt.subplots(1, 2, figsize=(11, 4))\n", + "\n", + "for model_name, results in cross_validation_results.groupby(\"model\"):\n", + " axes[0].plot(\n", + " results[\"fold\"],\n", + " results[\"validation_loss\"],\n", + " marker=\"o\",\n", + " label=model_name,\n", + " )\n", + " axes[1].plot(\n", + " results[\"fold\"],\n", + " results[\"validation_accuracy\"],\n", + " marker=\"o\",\n", + " label=model_name,\n", + " )\n", + "\n", + "axes[0].set(\n", + " xlabel=\"Validation fold\",\n", + " ylabel=\"Validation loss\",\n", + " xticks=range(1, N_SPLITS + 1),\n", + ")\n", + "axes[1].set(\n", + " xlabel=\"Validation fold\",\n", + " ylabel=\"Validation accuracy\",\n", + " xticks=range(1, N_SPLITS + 1),\n", + ")\n", + "for axis in axes:\n", + " axis.grid(alpha=0.25)\n", + " axis.legend()\n", + "figure.suptitle(\"Paired cross-validation results\")\n", + "figure.tight_layout(rect=(0, 0, 1, 0.93))" + ] + }, + { + "cell_type": "markdown", + "id": "414eff36", + "metadata": {}, + "source": [ + "### Interpreting the comparison\n", + "\n", + "A small difference in mean performance should not be treated as decisive when it is comparable to the fold-to-fold variation. Inspect whether the models differ consistently on the same folds, and consider runtime, model complexity, and the scientific cost of different errors.\n", + "\n", + "Cross-validation reduces dependence on one arbitrary split; it does not eliminate optimization randomness. Repeating the entire cross-validation experiment with new initialization seeds would measure an additional source of variation, at a substantial computational cost." + ] + }, + { + "cell_type": "markdown", + "id": "301d3dfe", + "metadata": {}, + "source": [ + "## Freeze the choice, then use the test set once\n", + "\n", + "We now select the candidate with the lowest mean validation loss, create a fresh instance, and fit it on the entire **working development set**. In quick mode that is the stratified subset selected earlier; the unused official training examples remain unused. In full mode it is all 60,000 official training examples.\n", + "\n", + "We keep the epoch count fixed. If we used the scored validation fold for early stopping, it would influence both training and evaluation and make the fold score optimistic. A sound early-stopping workflow needs a further inner split inside each training fold—or a nested cross-validation design.\n", + "\n", + "After the next cell evaluates the official test set, do not use that result to change the architecture, dropout probability, learning rate, or epoch count. Doing so would turn the test set into another validation set." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "aa39e9fa", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Selected candidate: classic\n", + "Epoch 1/10: loss=0.5976, accuracy=0.8230\n", + "Epoch 2/10: loss=0.1875, accuracy=0.9436\n", + "Epoch 3/10: loss=0.1243, accuracy=0.9637\n", + "Epoch 4/10: loss=0.0966, accuracy=0.9712\n", + "Epoch 5/10: loss=0.0770, accuracy=0.9774\n", + "Epoch 6/10: loss=0.0619, accuracy=0.9812\n", + "Epoch 7/10: loss=0.0527, accuracy=0.9839\n", + "Epoch 8/10: loss=0.0431, accuracy=0.9873\n", + "Epoch 9/10: loss=0.0377, accuracy=0.9885\n", + "Epoch 10/10: loss=0.0311, accuracy=0.9909\n" + ] + } + ], + "source": [ + "selected_name = summary[\"mean_loss\"].idxmin()\n", + "selected_factory = model_factories[selected_name]\n", + "print(f\"Selected candidate: {selected_name}\")\n", + "\n", + "torch.manual_seed(FINAL_MODEL_SEED)\n", + "selected_model = selected_factory().to(device)\n", + "final_optimizer = torch.optim.SGD(\n", + " selected_model.parameters(),\n", + " lr=LEARNING_RATE,\n", + " momentum=MOMENTUM,\n", + ")\n", + "loss_function = nn.CrossEntropyLoss()\n", + "\n", + "final_training_loader = make_loader(\n", + " development_data,\n", + " np.arange(len(development_data)),\n", + " shuffle=True,\n", + " seed=LOADER_SEED,\n", + " batch_size=BATCH_SIZE,\n", + " pin_memory=using_cuda,\n", + ")\n", + "\n", + "for epoch in range(1, EPOCHS + 1):\n", + " final_training_metrics = train_one_epoch(\n", + " selected_model,\n", + " final_training_loader,\n", + " loss_function,\n", + " final_optimizer,\n", + " device=device,\n", + " non_blocking=using_cuda,\n", + " )\n", + " print(\n", + " f\"Epoch {epoch:2d}/{EPOCHS}: \"\n", + " f\"loss={final_training_metrics['loss']:.4f}, \"\n", + " f\"accuracy={final_training_metrics['accuracy']:.4f}\"\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "f252f805", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Final test loss: 0.0694\n", + "Final test accuracy: 0.9788\n" + ] + } + ], + "source": [ + "test_loader = DataLoader(\n", + " official_test_data,\n", + " batch_size=BATCH_SIZE,\n", + " shuffle=False,\n", + " pin_memory=using_cuda,\n", + " num_workers=0,\n", + ")\n", + "test_metrics = evaluate(\n", + " selected_model,\n", + " test_loader,\n", + " loss_function,\n", + " device=device,\n", + " non_blocking=using_cuda,\n", + ")\n", + "print(f\"Final test loss: {test_metrics['loss']:.4f}\")\n", + "print(f\"Final test accuracy: {test_metrics['accuracy']:.4f}\")" + ] + }, + { + "cell_type": "markdown", + "id": "4e991349", + "metadata": {}, + "source": [ + "## When ordinary $k$-fold cross-validation is not the right tool\n", + "\n", + "Cross-validation is useful when a single split would waste scarce data or give an unstable comparison. It is not automatically the best default for deep learning:\n", + "\n", + "- repeated fitting may be prohibitively expensive for large models and datasets;\n", + "- a sufficiently large, representative validation set may already give a stable estimate;\n", + "- ordinary random folds are invalid when related observations can cross folds—for example, images from the same patient, measurements from the same instrument run, or nearby time points;\n", + "- temporal forecasting requires splits that respect time order;\n", + "- extensive hyperparameter search can overfit the cross-validation results, requiring nested cross-validation or a separate audit set for an unbiased performance estimate.\n", + "\n", + "The splitter must reflect how genuinely new data will arrive. Stratification balances labels, but it does not repair group, spatial, or temporal dependence." + ] + }, + { + "cell_type": "markdown", + "id": "1e63881b", + "metadata": {}, + "source": [ + "## Interpretation and transfer questions\n", + "\n", + "Timebox: 10 minutes. Use the tables and plot rather than rerunning the test evaluation.\n", + "\n", + "1. Did the candidate with the best training accuracy also achieve the lowest mean validation loss? Explain why these can disagree.\n", + "2. Was the difference between candidates large relative to fold-to-fold variation? What claim is justified by these five folds?\n", + "3. What information would leak if the same model instance were trained continuously across folds?\n", + "4. Suppose every patient contributed five images. Which part of this notebook would need to change, and why is stratification alone insufficient?\n", + "5. If early stopping were essential, sketch a split hierarchy that keeps each outer validation fold independent.\n", + "\n", + "Expected evidence of completion: an explanation of the selection decision, one limitation of the estimate, and an appropriate splitter for grouped data.\n", + "\n", + "
\n", + "Suggested answers\n", + "\n", + "1. Not necessarily. Higher training accuracy can indicate greater capacity or overfitting; validation loss evaluates predictive distributions on unseen fold data.\n", + "2. Compare the paired fold results and the mean difference with the observed variation. Five folds support a cautious comparison on this working MNIST sample, not a universal claim about either architecture.\n", + "3. Later folds would start from parameters that had already learned from examples—including examples later used for validation—so their scores would no longer represent independent held-out evaluation.\n", + "4. Replace `StratifiedKFold` with a group-aware splitter such as `StratifiedGroupKFold`, using patient ID as the group. Otherwise images from one patient can appear in both training and validation data.\n", + "5. For each outer fold, reserve the outer validation data strictly for scoring. Split only the outer training data again into an inner training and early-stopping set. Nested cross-validation extends this idea when model selection itself needs an unbiased outer estimate.\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "a5239f30", + "metadata": {}, + "source": [ + "## Takeaways\n", + "\n", + "- Cross-validation estimates sensitivity to the development-data split by rotating the held-out fold.\n", + "- Every fold needs fresh model and optimizer state.\n", + "- Candidate models should use the same folds for a paired comparison.\n", + "- Mean and standard deviation summarize the observed folds but do not remove every source of uncertainty.\n", + "- The test set remains outside model selection and is evaluated only after the decision is frozen.\n", + "- The split strategy must match the dependence structure and deployment setting of the real problem." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.14.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/source-code/pytorch/pytorch_linux64_conda_specs.txt b/source-code/pytorch/pytorch_linux64_conda_specs.txt deleted file mode 100644 index edf6586..0000000 --- a/source-code/pytorch/pytorch_linux64_conda_specs.txt +++ /dev/null @@ -1,234 +0,0 @@ -List of packages in environment: "/home/gjb/mambaforge/envs/pytorch" - -https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda -https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda -https://conda.anaconda.org/conda-forge/noarch/anyio-4.12.1-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda -https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py314h5bd0f2a_2.conda -https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/async-lru-2.1.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda -https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda -https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda -https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda -https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-h5f6438b_0.conda -https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda -https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda -https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda -https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.2-py314hd8ed1ab_101.conda -https://conda.anaconda.org/conda-forge/linux-64/cuda-crt-tools-12.9.86-ha770c72_2.conda -https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-12.9.79-h5888daf_0.conda -https://conda.anaconda.org/conda-forge/noarch/cuda-cudart_linux-64-12.9.79-h3f2d84a_0.conda -https://conda.anaconda.org/conda-forge/linux-64/cuda-cuobjdump-12.9.82-hffce074_1.conda -https://conda.anaconda.org/conda-forge/linux-64/cuda-cupti-12.9.79-h676940d_1.conda -https://conda.anaconda.org/conda-forge/linux-64/cuda-nvcc-tools-12.9.86-he02047a_2.conda -https://conda.anaconda.org/conda-forge/linux-64/cuda-nvdisasm-12.9.88-hffce074_1.conda -https://conda.anaconda.org/conda-forge/linux-64/cuda-nvrtc-12.9.86-hecca717_1.conda -https://conda.anaconda.org/conda-forge/linux-64/cuda-nvtx-12.9.79-hecca717_1.conda -https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-tools-12.9.86-h4bc722e_2.conda -https://conda.anaconda.org/conda-forge/noarch/cuda-version-12.9-h4f385c5_3.conda -https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda -https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py314h42812f9_0.conda -https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda -https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.1.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda -https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda -https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py314h28848ee_2.conda -https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda -https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda -https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda -https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda -https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.1.0-pyha191276_0.conda -https://conda.anaconda.org/conda-forge/noarch/ipython-9.10.0-pyh53cf698_0.conda -https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda -https://conda.anaconda.org/conda-forge/noarch/json5-0.13.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda -https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda -https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyh29332c3_0.conda -https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.3-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda -https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda -https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda -https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda -https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libabseil-20250512.1-cxx17_hba17884_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h316e467_3.conda -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda -https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda -https://conda.anaconda.org/conda-forge/linux-64/libcublas-12.9.1.4-h676940d_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.2.21-hf7e9902_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libcudss-0.7.1.4-h58dd1b1_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libcufft-11.4.1.4-hecca717_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libcufile-1.14.1.1-hbc026e6_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libcurand-10.3.10.19-h676940d_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libcusolver-11.7.5.82-h676940d_2.conda -https://conda.anaconda.org/conda-forge/linux-64/libcusparse-12.5.10.65-hecca717_2.conda -https://conda.anaconda.org/conda-forge/linux-64/libde265-1.0.15-h00ab1b0_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda -https://conda.anaconda.org/conda-forge/linux-64/libheif-1.19.7-gpl_hc18d805_100.conda -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda -https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda -https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-ha7672b3_6.conda -https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libnl-3.11.0-hb9d3cd8_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libnvjitlink-12.9.86-hecca717_2.conda -https://conda.anaconda.org/conda-forge/linux-64/libnvjpeg-12.4.0.76-hecca717_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.31.1-h49aed37_4.conda -https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-258.3-h6569c3e_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_mkl_he24fa84_301.conda -https://conda.anaconda.org/conda-forge/linux-64/libudev1-258.3-h6569c3e_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.8-h4922eb0_0.conda -https://conda.anaconda.org/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda -https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda -https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda -https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda -https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/linux-64/nccl-2.29.2.1-h4d09622_1.conda -https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda -https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py314h2b28147_0.conda -https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda -https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py314h9891dd4_0.conda -https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/parso-0.8.5-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py314h8ec4b1a_0.conda -https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.24.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda -https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py314h0f05182_0.conda -https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda -https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda -https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda -https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda -https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda -https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-h32b2ec7_101_cp314.conda -https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda -https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.2-h4df99d1_101.conda -https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_mkl_py314_h5d64bf0_301.conda -https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/pyyaml-6.0.3-pyh7db6752_0.conda -https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hfb55c3c_0.conda -https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.7.1-h8fae777_3.conda -https://conda.anaconda.org/conda-forge/linux-64/rdma-core-61.0-h192683f_0.conda -https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda -https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda -https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda -https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda -https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_0.conda -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.2-pyh332efcf_0.conda -https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda -https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda -https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda -https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/linux-64/svt-av1-4.0.0-hecca717_0.conda -https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda -https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda -https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda -https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.5.1-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda -https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/linux-64/torchvision-0.25.0-cuda129_py314_h89435d6_3.conda -https://conda.anaconda.org/conda-forge/linux-64/torchvision-extra-decoders-0.0.2-py314h862e9cd_6.conda -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.4-py314h7b0bd38_0.conda -https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/linux-64/triton-3.6.0-cuda129py314h2b49ec1_0.conda -https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda -https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda -https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda -https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.5.3-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda -https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/x265-3.5-h924138e_3.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda -https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda -https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h387f397_9.conda -https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda diff --git a/source-code/pytorch/tensors.ipynb b/source-code/pytorch/tensors.ipynb index 1c5dd41..e1fed56 100644 --- a/source-code/pytorch/tensors.ipynb +++ b/source-code/pytorch/tensors.ipynb @@ -2,90 +2,183 @@ "cells": [ { "cell_type": "markdown", - "id": "1e75b550-75fc-402b-85ee-ced51f26ce10", + "id": "262e82f2", "metadata": {}, "source": [ - "## Requirements" + "# PyTorch tensors: a course reference\n", + "\n", + "A tensor is a multidimensional array whose **shape**, **dtype**, **device**, and\n", + "relationship to an automatic-differentiation graph determine how it behaves.\n", + "This notebook explains the tensor concepts and operations used by the PyTorch\n", + "MNIST and physics-informed neural-network (PINN) examples in this repository.\n", + "\n", + "It is a reference rather than an exhaustive API catalogue. The examples are\n", + "small, require no downloaded data, and are intended to make the mechanisms\n", + "behind the course notebooks visible.\n", + "\n", + "## Learning objectives\n", + "\n", + "After working through this notebook, you should be able to:\n", + "\n", + "- interpret tensor dimensions in terms of batches, channels, features, and\n", + " physical coordinates;\n", + "- predict the result shape of indexing, broadcasting, reduction, reshaping,\n", + " stacking, and concatenation operations;\n", + "- distinguish views, copies, detached tensors, and NumPy arrays that share\n", + " storage;\n", + "- preserve dtype and device when creating or converting tensors;\n", + "- explain how `requires_grad`, `backward`, `torch.autograd.grad`, and gradient\n", + " modes are used in the training and PINN notebooks.\n", + "\n", + "**Required prerequisite:** basic Python and NumPy array operations.\n", + "\n", + "**Helpful, but not required:** elementary derivatives and the chain rule." ] }, { - "cell_type": "code", - "execution_count": 1, - "id": "bd7c2823-a421-43b7-bffc-8ff8cd32fd09", + "cell_type": "markdown", + "id": "bc344031", "metadata": {}, - "outputs": [], "source": [ - "import sys\n", - "\n", - "import numpy as np\n", - "import torch" + "## 1. Setup" ] }, { - "cell_type": "markdown", - "id": "8168e5a5-3ca5-46e3-9574-9466d814ec0b", + "cell_type": "code", + "execution_count": 1, + "id": "85c66f85", "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PyTorch version: 2.13.0\n" + ] + } + ], "source": [ - "## Tensor basics" + "import numpy as np\n", + "import torch\n", + "\n", + "torch.manual_seed(1729)\n", + "\n", + "print(f\"PyTorch version: {torch.__version__}\")" ] }, { "cell_type": "markdown", - "id": "8fbc155c-6438-4dc4-94ce-74aad5fb05cc", + "id": "8006cf22", "metadata": {}, "source": [ - "PyTorch tensors can be created in multiple ways. The most basic is initialization from a Python (nested) list." + "## 2. The tensor contract\n", + "\n", + "When reading tensor code, first establish five facts:\n", + "\n", + "1. What does each dimension mean?\n", + "2. What is the element dtype?\n", + "3. On which device is the data stored?\n", + "4. Is PyTorch recording operations for automatic differentiation?\n", + "5. Does this tensor share storage with another object?\n", + "\n", + "The first four can be inspected directly. Storage sharing is discussed in the\n", + "sections on views, copies, and NumPy conversion." ] }, { "cell_type": "code", "execution_count": 2, - "id": "6c2626b8-109f-4bb5-aaae-93b29ac5713e", + "id": "813a0169", "metadata": {}, "outputs": [], "source": [ - "t1 = torch.tensor([1.0, 3.0, 7.0], dtype=torch.float64)" + "def describe(tensor):\n", + " return {\n", + " \"shape\": tuple(tensor.shape),\n", + " \"ndim\": tensor.ndim,\n", + " \"dtype\": tensor.dtype,\n", + " \"device\": tensor.device,\n", + " \"requires_grad\": tensor.requires_grad,\n", + " \"is_leaf\": tensor.is_leaf,\n", + " \"grad_fn\": (\n", + " type(tensor.grad_fn).__name__\n", + " if tensor.grad_fn is not None\n", + " else None\n", + " ),\n", + " }" ] }, { "cell_type": "code", "execution_count": 3, - "id": "99441a76-43ff-4514-8755-34dd3dbac447", - "metadata": {}, - "outputs": [], - "source": [ - "t2 = torch.tensor([\n", - " [3.1, 2.4, 5.7],\n", - " [1.9, 12.3, 2.6],\n", - "])" - ] - }, - { - "cell_type": "markdown", - "id": "38534f31-29af-43e0-86ee-7788c279fe55", + "id": "889a9948", "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "({'shape': (32, 1, 28, 28),\n", + " 'ndim': 4,\n", + " 'dtype': torch.float32,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': False,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None},\n", + " {'shape': (32, 10),\n", + " 'ndim': 2,\n", + " 'dtype': torch.float32,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': False,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None},\n", + " {'shape': (512, 5),\n", + " 'ndim': 2,\n", + " 'dtype': torch.float32,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': False,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None})" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "### Tensor attributes" + "images = torch.rand(32, 1, 28, 28)\n", + "logits = torch.randn(32, 10)\n", + "pinn_inputs = torch.rand(512, 5)\n", + "\n", + "describe(images), describe(logits), describe(pinn_inputs)" ] }, { "cell_type": "markdown", - "id": "e6cc55f7-c92c-4470-8404-6be67c48fb81", + "id": "08d3f8a6", "metadata": {}, "source": [ - "Similar to numpy arrays, PyTorch tensors have many attributes." + "The examples use these dimension conventions:\n", + "\n", + "- `images`: `[batch, channel, height, width]`;\n", + "- `logits`: `[batch, class]`;\n", + "- `pinn_inputs`: `[sample, coordinate_or_parameter]`.\n", + "\n", + "`shape` reports all dimension sizes, `ndim` reports the number of dimensions,\n", + "`size(dim)` reports one dimension size, and `numel()` reports the total number\n", + "of elements." ] }, { "cell_type": "code", "execution_count": 4, - "id": "93e34a9d-283b-4f54-9d12-31ea07329005", + "id": "78063e35", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(torch.Size([3]), torch.Size([2, 3]))" + "(torch.Size([32, 1, 28, 28]), 4, 32, 25088)" ] }, "execution_count": 4, @@ -94,19 +187,40 @@ } ], "source": [ - "t1.shape, t2.shape" + "images.shape, images.ndim, images.size(0), images.numel()" + ] + }, + { + "cell_type": "markdown", + "id": "f4dfc3e1", + "metadata": {}, + "source": [ + "## 3. Creating tensors, dtypes, and devices\n", + "\n", + "`torch.tensor` copies values from Python or array-like input. Factory functions\n", + "such as `zeros`, `rand`, `arange`, and `linspace` construct tensors directly.\n", + "Specify `dtype` and `device` when they matter rather than relying on implicit\n", + "defaults." ] }, { "cell_type": "code", "execution_count": 5, - "id": "7a6a4590-6d37-4b0c-9b7e-a36747caeb37", + "id": "fcbbb265", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(torch.float64, torch.float32)" + "({'shape': (2, 2),\n", + " 'ndim': 2,\n", + " 'dtype': torch.float64,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': False,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None},\n", + " tensor([0, 2, 4, 6, 8]),\n", + " tensor([0.0000, 0.2000, 0.4000, 0.6000, 0.8000, 1.0000]))" ] }, "execution_count": 5, @@ -115,35 +229,42 @@ } ], "source": [ - "t1.dtype, t2.dtype" - ] - }, - { - "cell_type": "markdown", - "id": "0fcbda5f-9277-4f58-9d10-232cc45790c1", - "metadata": {}, - "source": [ - "Contrary to what you might expect, the default `dtype` of a PyTorch tensor is `torch.float32`, not double precision as you are used to in numpy." + "from_python = torch.tensor(\n", + " [[1.0, 2.0], [3.0, 4.0]],\n", + " dtype=torch.float64,\n", + ")\n", + "zeros = torch.zeros(2, 3)\n", + "random_normal = torch.randn(2, 3)\n", + "indices = torch.arange(0, 10, 2)\n", + "coordinates = torch.linspace(0.0, 1.0, 6)\n", + "\n", + "describe(from_python), indices, coordinates" ] }, { "cell_type": "markdown", - "id": "4260b1a0-10cb-4af8-a929-9b3fe13486b1", + "id": "1de84f09", "metadata": {}, "source": [ - "Attributes that are specific to PyTorch tensors are the device it is on, and whether gradients are required." + "### Dtype inference is source-dependent\n", + "\n", + "Python floating-point values normally use PyTorch's current default floating\n", + "dtype, usually `torch.float32`. Python integers normally produce an integer\n", + "tensor. `torch.from_numpy` preserves the NumPy dtype, which is often\n", + "`float64`. Class labels in the MNIST notebooks are integers, while model inputs\n", + "and parameters are floating point." ] }, { "cell_type": "code", "execution_count": 6, - "id": "c83e0762-e742-4cb6-8488-279f61a85f1b", + "id": "15a748d1", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(device(type='cpu'), False)" + "(torch.float32, torch.int64, torch.float64)" ] }, "execution_count": 6, @@ -152,45 +273,34 @@ } ], "source": [ - "t1.device, t1.requires_grad" - ] - }, - { - "cell_type": "markdown", - "id": "b9d7b79d-31df-4994-a3e2-530c99d9b96d", - "metadata": {}, - "source": [ - "By default, the device is the CPU, i.e., the host device, and no gradients are required." - ] - }, - { - "cell_type": "markdown", - "id": "e850483b-b041-49d6-bbd1-c967395dbb8e", - "metadata": {}, - "source": [ - "### Initialization" + "python_floats = torch.tensor([1.0, 2.0])\n", + "python_integers = torch.tensor([1, 2])\n", + "numpy_values = np.array([1.0, 2.0])\n", + "from_numpy = torch.from_numpy(numpy_values)\n", + "\n", + "python_floats.dtype, python_integers.dtype, from_numpy.dtype" ] }, { "cell_type": "markdown", - "id": "9af6d5d8-02d6-48e9-8dc6-03bffb6a1016", + "id": "5204bf49", "metadata": {}, "source": [ - "Similar to numpy, PyTorch has a number of built-in functions to initialize tensors. Below are a few examples." + "`torch.empty` allocates storage without initializing its values. It is useful\n", + "when every element will be overwritten immediately, but it must not be treated\n", + "as a tensor of zeros." ] }, { "cell_type": "code", "execution_count": 7, - "id": "93c543a7-0e8e-442b-a4b7-fbe1b93fdf49", + "id": "b79e761b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([[0., 0., 0., 0.],\n", - " [0., 0., 0., 0.],\n", - " [0., 0., 0., 0.]])" + "tensor([-0.4450, -0.1404, 0.7986, -0.5439, -0.5952])" ] }, "execution_count": 7, @@ -199,20 +309,60 @@ } ], "source": [ - "torch.zeros(3, 4)" + "samples = torch.empty(5)\n", + "samples.uniform_(-1.0, 1.0)" + ] + }, + { + "cell_type": "markdown", + "id": "b1734ef2", + "metadata": {}, + "source": [ + "### Constructing relative to another tensor\n", + "\n", + "The `_like` factories and `new_tensor` are useful in device-independent code.\n", + "They inherit dtype and device from a reference tensor. `new_tensor` always\n", + "copies its input; when its input is already a tensor, explicit\n", + "`detach().clone()` is usually clearer." ] }, { "cell_type": "code", "execution_count": 8, - "id": "c2415d4d-de0d-4837-89d6-8cbc9c33e4f8", + "id": "20290217", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([[1., 1., 1.],\n", - " [1., 1., 1.]])" + "({'shape': (4,),\n", + " 'ndim': 1,\n", + " 'dtype': torch.float64,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': False,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None},\n", + " {'shape': (4,),\n", + " 'ndim': 1,\n", + " 'dtype': torch.float64,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': False,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None},\n", + " {'shape': (4,),\n", + " 'ndim': 1,\n", + " 'dtype': torch.float64,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': False,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None},\n", + " {'shape': (1,),\n", + " 'ndim': 1,\n", + " 'dtype': torch.float64,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': False,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None})" ] }, "execution_count": 8, @@ -221,25 +371,57 @@ } ], "source": [ - "torch.ones(2, 3)" + "reference = torch.linspace(0.0, 1.0, 4, dtype=torch.float64)\n", + "zeros_like_reference = torch.zeros_like(reference)\n", + "boundary_values = torch.full_like(reference, 2.5)\n", + "initial_time = reference.new_tensor([0.0])\n", + "\n", + "(\n", + " describe(reference),\n", + " describe(zeros_like_reference),\n", + " describe(boundary_values),\n", + " describe(initial_time),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "b3fc60a0", + "metadata": {}, + "source": [ + "The older `torch.Tensor(...)` and `torch.FloatTensor(...)` constructors occur\n", + "in some PINN examples. Prefer `torch.tensor(...)` for existing data and factory\n", + "functions with explicit `dtype` and `device` for new data:\n", + "\n", + "```python\n", + "samples = torch.empty(batch_size, device=device).uniform_(*domain)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "e31ea76a", + "metadata": {}, + "source": [ + "## 4. Arithmetic, matrix multiplication, and broadcasting\n", + "\n", + "Arithmetic operators are element-wise. Matrix multiplication uses `@` or\n", + "`torch.matmul`; it is not the same as element-wise multiplication." ] }, { "cell_type": "code", "execution_count": 9, - "id": "de7888c5-4520-4566-bedd-01cf7c851e3c", + "id": "4c84dcb1", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([[[ 0.5219, 0.1576],\n", - " [ 0.8565, -0.6006],\n", - " [-0.2756, 0.1271]],\n", - "\n", - " [[ 0.9766, -1.7953],\n", - " [ 0.5326, -0.4391],\n", - " [ 0.9004, 0.1726]]])" + "(tensor([[ 0.5000, 3.0000],\n", + " [ 6.0000, -4.0000]]),\n", + " tensor([[ 4.5000, -0.5000],\n", + " [ 9.5000, 0.5000]]))" ] }, "execution_count": 9, @@ -248,19 +430,41 @@ } ], "source": [ - "torch.randn(2, 3, 2)" + "left = torch.tensor([[1.0, 2.0], [3.0, 4.0]])\n", + "right = torch.tensor([[0.5, 1.5], [2.0, -1.0]])\n", + "\n", + "elementwise_product = left * right\n", + "matrix_product = left @ right\n", + "\n", + "elementwise_product, matrix_product" + ] + }, + { + "cell_type": "markdown", + "id": "3666bbab", + "metadata": {}, + "source": [ + "### Broadcasting\n", + "\n", + "Broadcasting compares dimensions from right to left. Two dimensions are\n", + "compatible when they are equal, one of them is `1`, or one dimension is absent.\n", + "Broadcasting logically expands compatible dimensions without copying all\n", + "values.\n", + "\n", + "The PINN input normalization is a useful example: a `[sample, feature]` tensor\n", + "is combined with one lower and upper bound per feature." ] }, { "cell_type": "code", "execution_count": 10, - "id": "bd95428d-701f-486a-bc6e-daa6b0d36ce1", + "id": "8a4adda2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([-2.4468e-17, 4.2203e-41, -1.9479e-14, 3.4682e-41, 0.0000e+00])" + "(torch.Size([8, 5]), torch.Size([5]), torch.Size([8, 5]))" ] }, "execution_count": 10, @@ -269,49 +473,73 @@ } ], "source": [ - "torch.empty(5)" + "inputs = torch.rand(8, 5)\n", + "lower = torch.tensor([0.0, 0.0, -1.0, -1.0, 0.05])\n", + "upper = torch.tensor([1.0, 1.0, 1.0, 1.0, 0.20])\n", + "\n", + "scaled_inputs = 2.0 * (inputs - lower) / (upper - lower) - 1.0\n", + "\n", + "inputs.shape, lower.shape, scaled_inputs.shape" ] }, { "cell_type": "markdown", - "id": "b77d587e-4a39-4c63-8712-75cc5d087168", + "id": "ec3971c7", "metadata": {}, "source": [ - "## Tensor operations" + "**Reasoning check:** before running the next cell, predict the result shape.\n", + "This operation is legal, but is it likely to express an intended scientific\n", + "calculation?" ] }, { - "cell_type": "markdown", - "id": "dfb5c291-0931-4f37-9694-7a98d1b5f208", + "cell_type": "code", + "execution_count": 11, + "id": "ee5125c5", "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "torch.Size([4, 4])" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "As you would expect, arithmetic operations are defined on Pytorch tensors. Similar to numpy, broadcasting is supported." + "column = torch.ones(4, 1)\n", + "row = torch.arange(4.0)\n", + "(column + row).shape" ] }, { - "cell_type": "code", - "execution_count": 11, - "id": "84280275-f824-4adb-b250-a17d7708c1ae", + "cell_type": "markdown", + "id": "b1c462f4", "metadata": {}, - "outputs": [], "source": [ - "t1 = torch.tensor([\n", - " [1.0, 2.0],\n", - " [3.0, 4.0],\n", - "])" + "The result is `[4, 4]`, not `[4, 1]` or `[4]`. Broadcasting errors are often\n", + "semantic rather than runtime errors: an operation can succeed while computing\n", + "the wrong quantity.\n", + "\n", + "Methods ending in an underscore, such as `add_` and `uniform_`, modify a tensor\n", + "in place. In-place operations can be efficient, but they also affect every view\n", + "sharing the same storage and can invalidate values saved for autograd. Prefer\n", + "ordinary out-of-place arithmetic unless mutation is deliberate." ] }, { "cell_type": "code", "execution_count": 12, - "id": "3f2b0be1-f430-4371-95cd-d26227aae3da", + "id": "a16e7bfa", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([[3., 4.],\n", - " [5., 6.]])" + "(tensor([1., 2., 3.]), tensor([0., 1., 2.]))" ] }, "execution_count": 12, @@ -320,20 +548,31 @@ } ], "source": [ - "2.0 + t1" + "original = torch.tensor([1.0, 2.0, 3.0])\n", + "modified = original.clone()\n", + "modified.subtract_(1.0)\n", + "\n", + "original, modified" + ] + }, + { + "cell_type": "markdown", + "id": "6e813995", + "metadata": {}, + "source": [ + "## 5. Indexing and masking" ] }, { "cell_type": "code", "execution_count": 13, - "id": "2ed6a1b4-6d15-4d3b-889b-0ff565551ef0", + "id": "9e92d6b5", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([[0.5000, 1.0000],\n", - " [1.5000, 2.0000]])" + "(torch.Size([]), torch.Size([4]), torch.Size([3]), torch.Size([3, 1]))" ] }, "execution_count": 13, @@ -342,20 +581,42 @@ } ], "source": [ - "0.5*t1" + "matrix = torch.arange(12).reshape(3, 4)\n", + "\n", + "scalar = matrix[1, 2]\n", + "row = matrix[1]\n", + "column = matrix[:, 1]\n", + "dimension_preserving_column = matrix[:, 1:2]\n", + "\n", + "(\n", + " scalar.shape,\n", + " row.shape,\n", + " column.shape,\n", + " dimension_preserving_column.shape,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "7bbc4812", + "metadata": {}, + "source": [ + "Comparisons produce Boolean tensors. A Boolean mask can select or replace\n", + "elements without writing a Python loop." ] }, { "cell_type": "code", "execution_count": 14, - "id": "79f3dfd7-66a8-4907-8829-ee4f6f1f99c9", + "id": "c57a5884", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([[ 1., 4.],\n", - " [ 9., 16.]])" + "(tensor([ True, True, False, False, False]),\n", + " tensor([-2.0000, -0.5000]),\n", + " tensor([0.0000, 0.0000, 0.0000, 1.5000, 3.0000]))" ] }, "execution_count": 14, @@ -364,43 +625,79 @@ } ], "source": [ - "t1**2" + "values = torch.tensor([-2.0, -0.5, 0.0, 1.5, 3.0])\n", + "negative_mask = values < 0.0\n", + "positive_values = values.clone()\n", + "positive_values[negative_mask] = 0.0\n", + "\n", + "negative_mask, values[negative_mask], positive_values" ] }, { "cell_type": "markdown", - "id": "581943fd-d9e0-4033-bc2a-de7bcc7b1639", + "id": "4e939d1c", "metadata": {}, "source": [ - "When operating on tensors, shapes should match." + "Basic indexing usually returns a view that shares storage. Advanced indexing,\n", + "including indexing with a tensor of positions, returns a copy. This difference\n", + "matters when values are modified later." ] }, { "cell_type": "code", "execution_count": 15, - "id": "92b5430b-cd20-4774-93e1-ad203f6341fe", + "id": "a44ec546", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(tensor([ 0., 1., -1., 3., 4., 5.]),\n", + " tensor([ 1., -1., 3.]),\n", + " tensor([1., 2., 3.]))" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "source = torch.arange(6.0)\n", + "basic_view = source[1:4]\n", + "advanced_copy = source[torch.tensor([1, 2, 3])]\n", + "\n", + "source[2] = -1.0\n", + "\n", + "source, basic_view, advanced_copy" + ] + }, + { + "cell_type": "markdown", + "id": "9b4b19d2", "metadata": {}, - "outputs": [], "source": [ - "t2 = torch.tensor([\n", - " [0.1, 0.2],\n", - " [0.3, 0.4],\n", - "])" + "## 6. Reshaping, views, and contiguity\n", + "\n", + "A view has different shape or indexing metadata but shares the underlying\n", + "storage. `view` can only reinterpret compatible strides. `reshape` returns a\n", + "view when possible and otherwise makes a copy; code should not rely on which\n", + "choice it makes." ] }, { "cell_type": "code", "execution_count": 16, - "id": "aeabdbd7-e068-49aa-9da9-dd1065d7e84f", + "id": "e498c4f5", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(tensor([[1.1000, 2.2000],\n", - " [3.3000, 4.4000]]),\n", - " tensor([[0.1000, 0.4000],\n", - " [0.9000, 1.6000]]))" + "(tensor([ 0., 1., 2., 3., 4., -1., 6., 7., 8., 9., 10., 11.]),\n", + " tensor([[ 0., 1., 2., 3.],\n", + " [ 4., -1., 6., 7.],\n", + " [ 8., 9., 10., 11.]]))" ] }, "execution_count": 16, @@ -409,80 +706,139 @@ } ], "source": [ - "t1 + t2, t1*t2" + "flat = torch.arange(12.0)\n", + "grid = flat.view(3, 4)\n", + "grid[1, 1] = -1.0\n", + "\n", + "flat, grid" ] }, { - "cell_type": "markdown", - "id": "2cea87b1-5011-4322-ad15-e1513f1e2e5b", + "cell_type": "code", + "execution_count": 17, + "id": "3bf4af7e", "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(False,\n", + " \"view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead.\",\n", + " tensor([ 0., 4., 8., 1., -1., 9., 2., 6., 10., 3., 7., 11.]))" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "Note that the operations are element-wise." + "transposed = grid.transpose(0, 1)\n", + "\n", + "try:\n", + " flattened_with_view = transposed.view(-1)\n", + "except RuntimeError as error:\n", + " flattened_with_view = str(error).splitlines()[0]\n", + "\n", + "flattened_with_reshape = transposed.reshape(-1)\n", + "\n", + "(\n", + " transposed.is_contiguous(),\n", + " flattened_with_view,\n", + " flattened_with_reshape,\n", + ")" ] }, { - "cell_type": "code", - "execution_count": 17, - "id": "a5b2d4ff-53b9-4f91-947b-5c3cf39a391a", + "cell_type": "markdown", + "id": "828e1848", "metadata": {}, - "outputs": [], "source": [ - "t3 = torch.tensor([\n", - " [-1.0, 0.0, 1.0],\n", - " [1.0, 0.0, -1.0],\n", - "])" + "`unsqueeze` inserts a dimension of size one. `squeeze(dim)` removes a specific\n", + "size-one dimension. Supplying `dim` is safer than an unrestricted `squeeze()`:\n", + "it documents which dimension is expected to disappear and avoids accidentally\n", + "removing a batch dimension of size one." ] }, { "cell_type": "code", "execution_count": 18, - "id": "f1343ad1-3255-4efe-8086-5b6d8f4528eb", + "id": "aefab895", "metadata": {}, "outputs": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "The size of tensor a (2) must match the size of tensor b (3) at non-singleton dimension 1\n" - ] + "data": { + "text/plain": [ + "(torch.Size([28, 28]),\n", + " torch.Size([1, 28, 28]),\n", + " torch.Size([1, 1, 28, 28]),\n", + " torch.Size([28, 28]))" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "try:\n", - " t1 + t3\n", - "except Exception as e:\n", - " print(e, file=sys.stderr)" + "image = torch.rand(28, 28)\n", + "image_with_channel = image.unsqueeze(0)\n", + "batch = image_with_channel.unsqueeze(0)\n", + "image_again = batch.squeeze(0).squeeze(0)\n", + "\n", + "image.shape, image_with_channel.shape, batch.shape, image_again.shape" ] }, { "cell_type": "markdown", - "id": "9cab7992-057b-40f7-b64d-267b0d39d11f", + "id": "5f3d11db", "metadata": {}, "source": [ - "However, broadcasting works when shapes match." + "### Combining and splitting tensors\n", + "\n", + "`cat` joins tensors along an existing dimension. `stack` introduces a new\n", + "dimension. `column_stack` constructs columns, while `unbind` removes one\n", + "dimension and returns its slices as separate tensors." ] }, { "cell_type": "code", "execution_count": 19, - "id": "0de91063-42d3-4bcf-9de3-f17cf1265278", + "id": "90a43efc", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(torch.Size([4]), torch.Size([2, 2]), torch.Size([2, 2]))" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "t4 = torch.tensor([10.0, 20.0])" + "first = torch.tensor([1.0, 2.0])\n", + "second = torch.tensor([3.0, 4.0])\n", + "\n", + "concatenated = torch.cat([first, second])\n", + "stacked = torch.stack([first, second])\n", + "columns = torch.column_stack([first, second])\n", + "\n", + "concatenated.shape, stacked.shape, columns.shape" ] }, { "cell_type": "code", "execution_count": 20, - "id": "7942c836-6d94-465b-ab93-8312110678cc", + "id": "9a878fb4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([[11., 22.],\n", - " [13., 24.]])" + "(torch.Size([6]), torch.Size([6]), torch.Size([6]))" ] }, "execution_count": 20, @@ -491,27 +847,41 @@ } ], "source": [ - "t4 + t1" + "coordinates = torch.rand(6, 5)\n", + "x, t, coefficient_1, coefficient_2, diffusivity = coordinates.unbind(dim=1)\n", + "\n", + "x.shape, t.shape, diffusivity.shape" ] }, { "cell_type": "markdown", - "id": "994b495c-c16a-470e-9458-4f6eb3de8c48", + "id": "1c3fe6f1", "metadata": {}, "source": [ - "Operations can be done in place, explicitely using the `add_`, `subtract_`, `multiply_` and `divide_` methods." + "### Constructing coordinate grids\n", + "\n", + "The heat-equation PINN evaluates combinations of time and position.\n", + "`meshgrid(..., indexing=\"ij\")` constructs coordinate matrices, `ravel()`\n", + "flattens them, and `column_stack` turns the coordinates into one row per\n", + "evaluation point." ] }, { "cell_type": "code", "execution_count": 21, - "id": "70b77683-2e08-4f89-b396-0697997b411b", + "id": "ffa056cf", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([ 9., 19.])" + "(torch.Size([3, 4]),\n", + " torch.Size([3, 4]),\n", + " torch.Size([12, 2]),\n", + " tensor([[0.0000, 0.0000],\n", + " [0.3333, 0.0000],\n", + " [0.6667, 0.0000],\n", + " [1.0000, 0.0000]]))" ] }, "execution_count": 21, @@ -520,33 +890,40 @@ } ], "source": [ - "t4.subtract_(1.0)" + "x_grid = torch.linspace(0.0, 1.0, 4)\n", + "t_grid = torch.linspace(0.0, 0.5, 3)\n", + "tt, xx = torch.meshgrid(t_grid, x_grid, indexing=\"ij\")\n", + "grid_points = torch.column_stack([xx.ravel(), tt.ravel()])\n", + "\n", + "xx.shape, tt.shape, grid_points.shape, grid_points[:4]" ] }, { "cell_type": "markdown", - "id": "751e1331-80d4-48d2-a258-f72d090e5691", + "id": "94910656", "metadata": {}, "source": [ - "Matrix multiplication can be done using the `@` operator." + "## 7. Reductions and scalar tensors\n", + "\n", + "Reductions combine values along one or more dimensions. The `dim` argument\n", + "specifies which dimension disappears; `keepdim=True` retains it with size one,\n", + "which can make subsequent broadcasting clearer." ] }, { "cell_type": "code", "execution_count": 22, - "id": "e6bac20e-83cb-493a-9383-e3c06293b18d", + "id": "77545b30", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(tensor([[0.6039, 0.4147, 0.7988],\n", - " [0.8561, 0.6574, 0.9251]]),\n", - " tensor([[0.3971, 0.6389, 0.5313, 0.8186],\n", - " [0.6357, 0.2963, 0.6215, 0.9515],\n", - " [0.5241, 0.2777, 0.3573, 0.5848]]),\n", - " tensor([[0.9221, 0.7305, 0.8640, 1.3561],\n", - " [1.2427, 0.9986, 1.1940, 1.8673]]))" + "(tensor(0.),\n", + " tensor([2., 1., 0.]),\n", + " tensor([1, 0, 1]),\n", + " torch.Size([2]),\n", + " torch.Size([2, 1]))" ] }, "execution_count": 22, @@ -555,49 +932,88 @@ } ], "source": [ - "t5 = torch.rand(2, 3)\n", - "t6 = torch.rand(3, 4)\n", - "t5, t6, t5@t6" + "measurements = torch.tensor(\n", + " [[3.0, 1.0, 4.0], [2.0, 5.0, 0.0]]\n", + ")\n", + "\n", + "global_minimum = measurements.min()\n", + "column_minima = measurements.min(dim=0)\n", + "row_means = measurements.mean(dim=1)\n", + "row_means_kept = measurements.mean(dim=1, keepdim=True)\n", + "\n", + "(\n", + " global_minimum,\n", + " column_minima.values,\n", + " column_minima.indices,\n", + " row_means.shape,\n", + " row_means_kept.shape,\n", + ")" ] }, { "cell_type": "markdown", - "id": "ca52fbef-d2bd-4e3e-a4ee-b7e65ddf0bbe", + "id": "4405e298", "metadata": {}, "source": [ - "## Indexing" + "The MNIST training notebooks turn class scores into predictions and Boolean\n", + "comparisons into a count of correct examples." ] }, { - "cell_type": "markdown", - "id": "33b82597-9477-4913-a250-bd296184a8cc", + "cell_type": "code", + "execution_count": 23, + "id": "43ee8196", "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(tensor([2, 0, 1]), tensor([True, True, True]), tensor(3), tensor(1.))" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "Indexing tensors is very similar to numpy arrays. FAncy indexing works as well." + "targets = torch.tensor([2, 0, 1])\n", + "example_logits = torch.tensor(\n", + " [\n", + " [0.1, 0.2, 1.7],\n", + " [1.2, 0.4, 0.3],\n", + " [0.1, 1.3, 0.2],\n", + " ]\n", + ")\n", + "\n", + "predictions = example_logits.argmax(dim=1)\n", + "correct = predictions == targets\n", + "number_correct = correct.sum()\n", + "accuracy = correct.float().mean()\n", + "\n", + "predictions, correct, number_correct, accuracy" ] }, { - "cell_type": "code", - "execution_count": 23, - "id": "18d1114b-3331-489d-af30-a252f99d6dba", + "cell_type": "markdown", + "id": "973ed359", "metadata": {}, - "outputs": [], "source": [ - "t = torch.randn(3, 4)" + "`torch.bincount` counts occurrences of non-negative integer values.\n", + "`minlength` retains classes that are absent from the observed data, which is\n", + "why the MNIST notebooks specify the known number of classes." ] }, { "cell_type": "code", "execution_count": 24, - "id": "3fa01c31-f4a9-4042-b672-b0ede31c74ce", + "id": "f1def6eb", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([[-0.0427, 0.3275, 0.5494, -0.3665],\n", - " [ 0.1741, -2.3084, -0.5032, -0.2944],\n", - " [ 0.4861, -0.5477, -0.9698, -1.9089]])" + "tensor([1, 2, 0, 3, 0])" ] }, "execution_count": 24, @@ -606,19 +1022,30 @@ } ], "source": [ - "t" + "labels = torch.tensor([0, 1, 1, 3, 3, 3])\n", + "class_counts = torch.bincount(labels, minlength=5)\n", + "class_counts" + ] + }, + { + "cell_type": "markdown", + "id": "3418382e", + "metadata": {}, + "source": [ + "Scientific losses and error measures often compose element-wise operations and\n", + "reductions. `torch.linalg.vector_norm` makes the intended norm explicit." ] }, { "cell_type": "code", "execution_count": 25, - "id": "136e944a-308b-4bd0-8a8b-df0e6d66eb47", + "id": "e4f41bb3", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor(-0.5032)" + "(tensor(0.0375), tensor(0.1936), tensor(0.3873), tensor(0.3000))" ] }, "execution_count": 25, @@ -627,19 +1054,43 @@ } ], "source": [ - "t[1, 2]" + "residual = torch.tensor([-0.2, 0.1, 0.3, -0.1])\n", + "\n", + "mean_squared_residual = residual.square().mean()\n", + "root_mean_squared_residual = mean_squared_residual.sqrt()\n", + "l2_norm = torch.linalg.vector_norm(residual)\n", + "maximum_absolute_residual = residual.abs().max()\n", + "\n", + "(\n", + " mean_squared_residual,\n", + " root_mean_squared_residual,\n", + " l2_norm,\n", + " maximum_absolute_residual,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "8aceec5e", + "metadata": {}, + "source": [ + "A reduction still returns a tensor, even when it has no dimensions. `item()`\n", + "converts a one-element tensor to a Python number. It is not differentiable and,\n", + "on an accelerator, obtaining the value can force the host to wait for queued\n", + "device work. Use it for reporting or control flow, not repeatedly inside\n", + "performance-critical tensor calculations." ] }, { "cell_type": "code", "execution_count": 26, - "id": "c33c58dc-f5f7-4240-bc2d-d19a1c7d791d", + "id": "01ddf0ed", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([ 0.3275, -2.3084, -0.5477])" + "(torch.Size([]), torch.Tensor, float)" ] }, "execution_count": 26, @@ -648,884 +1099,689 @@ } ], "source": [ - "t[:, 1]" + "scalar_tensor = residual.square().mean()\n", + "python_number = scalar_tensor.item()\n", + "\n", + "scalar_tensor.shape, type(scalar_tensor), type(python_number)" ] }, { - "cell_type": "code", - "execution_count": 27, - "id": "a0c9e3ce-1393-4aa2-905c-bc784bad9735", + "cell_type": "markdown", + "id": "9a2fa061", "metadata": {}, - "outputs": [], - "source": [ - "t[t < 0.0] = 0.0" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "a205dc35-86a9-4262-a13b-f17397ab9fa6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "tensor([[0.0000, 0.3275, 0.5494, 0.0000],\n", - " [0.1741, 0.0000, 0.0000, 0.0000],\n", - " [0.4861, 0.0000, 0.0000, 0.0000]])" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t" - ] - }, - { - "cell_type": "markdown", - "id": "ac3f6010-d82d-4e22-ab9a-c46e80ceb13f", - "metadata": {}, - "source": [ - "## Reshaping" - ] - }, - { - "cell_type": "markdown", - "id": "cf3dd4a7-22c5-4b20-adba-ed526a96da25", - "metadata": {}, - "source": [ - "A common operation on a tensor is reshaping it, i.e., modifying its rank. In PyTorch, this is done by creating a view on the tensor." - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "f864de93-78ba-4515-aedc-c42d271504ac", - "metadata": {}, - "outputs": [], - "source": [ - "t = torch.arange(1, 25)" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "e312a3f1-2447-410b-b488-8d561eadd56a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "torch.Size([24])" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "t.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "d9c23fd5-3a9d-40d7-a71c-daefe3bbdbb0", - "metadata": {}, - "outputs": [], - "source": [ - "v = t.view(4, 6)" + "## 8. Copies, detaching, and NumPy interoperability\n", + "\n", + "`clone()` copies tensor data while preserving its relationship to the autograd\n", + "graph. `detach()` returns a tensor that shares storage but is disconnected from\n", + "the graph. Use `detach().clone()` when both an independent copy and graph\n", + "disconnection are required.\n", + "\n", + "`describe()` reports metadata and autograd status; it cannot reveal whether two\n", + "tensors share storage. The mutation below makes that difference observable." ] }, { "cell_type": "code", - "execution_count": 32, - "id": "0a88a0ca-82f4-47f7-aa1b-b7990222cb41", + "execution_count": 27, + "id": "9a860392", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "torch.Size([4, 6])" + "({'result': {'shape': (2,),\n", + " 'ndim': 1,\n", + " 'dtype': torch.float32,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': True,\n", + " 'is_leaf': False,\n", + " 'grad_fn': 'PowBackward0'},\n", + " 'cloned result': {'shape': (2,),\n", + " 'ndim': 1,\n", + " 'dtype': torch.float32,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': True,\n", + " 'is_leaf': False,\n", + " 'grad_fn': 'CloneBackward0'},\n", + " 'detached': {'shape': (2,),\n", + " 'ndim': 1,\n", + " 'dtype': torch.float32,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': False,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None},\n", + " 'detached clone': {'shape': (2,),\n", + " 'ndim': 1,\n", + " 'dtype': torch.float32,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': False,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None}},\n", + " tensor([-1., 2.], requires_grad=True),\n", + " tensor([-1., 2.]),\n", + " tensor([1., 2.]))" ] }, - "execution_count": 32, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "v.shape" + "tracked = torch.tensor([1.0, 2.0], requires_grad=True)\n", + "result = tracked.square()\n", + "cloned_result = result.clone()\n", + "detached = tracked.detach()\n", + "independent = tracked.detach().clone()\n", + "\n", + "descriptions = {\n", + " \"result\": describe(result),\n", + " \"cloned result\": describe(cloned_result),\n", + " \"detached\": describe(detached),\n", + " \"detached clone\": describe(independent),\n", + "}\n", + "\n", + "with torch.no_grad():\n", + " tracked[0] = -1.0\n", + "\n", + "(\n", + " descriptions,\n", + " tracked,\n", + " detached, # changed because it shares storage with tracked\n", + " independent, # unchanged because clone() copied the data\n", + ")" ] }, { "cell_type": "markdown", - "id": "d57f317b-b028-422f-a9b6-4c6e3609d08a", - "metadata": {}, - "source": [ - "A view is exactly that, so in the example above, both `t` and `v` refer to the same data." - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "320d6138-f495-4657-9bb4-d03e2c316d0e", + "id": "7f68f072", "metadata": {}, - "outputs": [], "source": [ - "v[1, 1] = -1" + "`torch.from_numpy` and a supported CPU tensor's `.numpy()` method normally\n", + "share storage. `torch.tensor(array)` copies instead. Mutating shared data from\n", + "either side changes the other object." ] }, { "cell_type": "code", - "execution_count": 34, - "id": "73b23b8b-d6ba-4b08-9370-b83d7201a836", + "execution_count": 28, + "id": "763e5a36", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([ 1, 2, 3, 4, 5, 6, 7, -1, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,\n", - " 19, 20, 21, 22, 23, 24])" + "(array([-1., 1., 2., 3.], dtype=float32),\n", + " tensor([-1., 1., 2., 3.]),\n", + " tensor([0., 1., 2., 3.]))" ] }, - "execution_count": 34, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "t" + "array = np.arange(4, dtype=np.float32)\n", + "shared_tensor = torch.from_numpy(array)\n", + "copied_tensor = torch.tensor(array)\n", + "\n", + "array[0] = -1.0\n", + "\n", + "array, shared_tensor, copied_tensor" ] }, { "cell_type": "markdown", - "id": "d74b7181-9bdf-42f0-9fda-48767c17a605", + "id": "0eeb949a", "metadata": {}, "source": [ - "Flattening a tensor is simple." - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "5c738443-a751-4794-ab8f-8e72bd249a41", - "metadata": {}, - "outputs": [], - "source": [ - "v1 = v.view(-1)" + "The robust conversion used for plotting or NumPy analysis is:\n", + "\n", + "```python\n", + "array = tensor.detach().cpu().numpy()\n", + "```\n", + "\n", + "- `detach()` removes the autograd relationship;\n", + "- `cpu()` transfers accelerator data to host memory;\n", + "- `numpy()` exposes the CPU values as an array.\n", + "\n", + "The resulting array may still share storage with the detached CPU tensor. Add\n", + "`.copy()` on the NumPy side when independent storage is required." ] }, { "cell_type": "code", - "execution_count": 36, - "id": "59466140-70e2-40da-bcbc-b70e918cba90", + "execution_count": 29, + "id": "6b85fa1c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "torch.Size([24])" + "array([1., 4.], dtype=float32)" ] }, - "execution_count": 36, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "v1.shape" + "plot_values = result.detach().cpu().numpy()\n", + "plot_values" ] }, { "cell_type": "markdown", - "id": "acd254b0-cb43-44a2-89e6-e4c3b3deb6fb", - "metadata": {}, - "source": [ - "You can add another dimension to a view using `unsqueeze`." - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "eba4a1c9-bc6c-42c3-bfda-e9024532cb9a", - "metadata": {}, - "outputs": [], - "source": [ - "v2 = v1.unsqueeze(0)" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "4e63d209-be6f-4198-8d80-e894a3aa3a16", + "id": "5bfc40e6", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "torch.Size([1, 24])" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "v2.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "id": "df748047-f18e-4b06-8927-84ba326e83a0", - "metadata": {}, - "outputs": [], - "source": [ - "v3 = v1.unsqueeze(1)" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "5632b736-878b-4b3b-9b87-bf7281b09390", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "torch.Size([24, 1])" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "v3.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "f16ff285-5dd5-4366-bdb4-0abd2e166dc0", - "metadata": {}, - "outputs": [], - "source": [ - "v4 = v2.unsqueeze(2)" + "## 9. Moving tensors between devices\n", + "\n", + "Operations generally require participating tensors to be on the same device.\n", + "`to` can change device, dtype, or both. It returns the original tensor when no\n", + "conversion is needed and otherwise returns a converted tensor; assigning the\n", + "result is therefore essential." ] }, { "cell_type": "code", - "execution_count": 42, - "id": "a57b46fc-c398-4ed3-ba9c-bb47c862d656", + "execution_count": 30, + "id": "98c547d9", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "torch.Size([1, 24, 1])" + "({'shape': (5,),\n", + " 'ndim': 1,\n", + " 'dtype': torch.float32,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': False,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None},\n", + " {'shape': (5,),\n", + " 'ndim': 1,\n", + " 'dtype': torch.float32,\n", + " 'device': device(type='cuda', index=0),\n", + " 'requires_grad': False,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None},\n", + " {'shape': (5,),\n", + " 'ndim': 1,\n", + " 'dtype': torch.float32,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': False,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None})" ] }, - "execution_count": 42, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "v4.shape" + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "using_cuda = device.type == \"cuda\"\n", + "\n", + "host_values = torch.linspace(0.0, 1.0, 5)\n", + "device_values = host_values.to(\n", + " device,\n", + " dtype=torch.float32,\n", + " non_blocking=using_cuda,\n", + ")\n", + "returned_values = device_values.cpu()\n", + "\n", + "describe(host_values), describe(device_values), describe(returned_values)" ] }, { "cell_type": "markdown", - "id": "f053d5cf-e425-4d96-aefd-6d2fffcfe90a", - "metadata": {}, - "source": [ - "The reverse operation, `squeeze`, removes a dimension if it is 1." - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "e690db43-08b7-41fa-a8fa-030910eccd1e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "torch.Size([24, 1])" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "v4.squeeze(0).shape" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "d5aae858-8dd4-4476-b2c3-094933d3bd3d", + "id": "49009eac", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "torch.Size([1, 24])" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "v4.squeeze(2).shape" + "The MNIST loaders use `pin_memory=True` only when CUDA is used, and tensor\n", + "transfers separately use `non_blocking=True`. Pinned host memory can enable\n", + "efficient asynchronous host-to-device copies, but it consumes a limited host\n", + "resource and does not guarantee a speedup. It is a data-loading optimization,\n", + "not a requirement for correctness.\n", + "\n", + "Create tensors directly on their target device when possible:" ] }, { "cell_type": "code", - "execution_count": 45, - "id": "b674b707-e88c-412d-8d33-ac253e373e41", + "execution_count": 31, + "id": "7b413537", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "torch.Size([1, 24, 1])" + "{'shape': (4, 5),\n", + " 'ndim': 2,\n", + " 'dtype': torch.float32,\n", + " 'device': device(type='cuda', index=0),\n", + " 'requires_grad': False,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None}" ] }, - "execution_count": 45, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "v4.squeeze(1).shape" + "device_samples = torch.rand(4, 5, device=device)\n", + "describe(device_samples)" ] }, { "cell_type": "markdown", - "id": "bc6154dd-92e9-480e-906a-5ac96083816d", + "id": "28608324", "metadata": {}, "source": [ - "## \n", - "Conversions" - ] - }, - { - "cell_type": "markdown", - "id": "95f17769-45ad-4989-ace5-74e627dc31b3", - "metadata": {}, - "source": [ - "The result of a computation involving tensors is a tensor, even when the result is a single number." - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "id": "74262e76-efb6-460a-8943-99af9664491a", - "metadata": {}, - "outputs": [], - "source": [ - "t = torch.rand(3, 3).sum()" + "## 10. Automatic differentiation\n", + "\n", + "PyTorch records operations involving tensors that require gradients. The\n", + "recorded graph is created dynamically during each forward calculation. It\n", + "enables reverse-mode automatic differentiation but consumes time and memory.\n", + "\n", + "A **leaf tensor** is not the result of a recorded differentiable operation.\n", + "Model parameters and explicitly marked input coordinates are typical leaves.\n", + "Only leaf tensors have `.grad` populated by `backward()` unless\n", + "`retain_grad()` is requested for an intermediate tensor." ] }, { "cell_type": "code", - "execution_count": 47, - "id": "a4ef3443-adf0-4bdb-a193-fb544dc22411", + "execution_count": 32, + "id": "e6d634d4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor(4.2559)" + "({'shape': (3,),\n", + " 'ndim': 1,\n", + " 'dtype': torch.float32,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': True,\n", + " 'is_leaf': True,\n", + " 'grad_fn': None},\n", + " {'shape': (3,),\n", + " 'ndim': 1,\n", + " 'dtype': torch.float32,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': True,\n", + " 'is_leaf': False,\n", + " 'grad_fn': 'AddBackward0'},\n", + " {'shape': (),\n", + " 'ndim': 0,\n", + " 'dtype': torch.float32,\n", + " 'device': device(type='cpu'),\n", + " 'requires_grad': True,\n", + " 'is_leaf': False,\n", + " 'grad_fn': 'SumBackward0'})" ] }, - "execution_count": 47, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "t" + "x = torch.tensor([2.0, 3.0, 4.0], requires_grad=True)\n", + "u = 3.0 * x**2 - 2.0 * x + 1.0\n", + "loss = u.sum()\n", + "\n", + "describe(x), describe(u), describe(loss)" ] }, { "cell_type": "markdown", - "id": "0c1ad887-6b9c-43a4-8ad9-8174a49f4bbc", + "id": "c2928598", "metadata": {}, "source": [ - "To get a number, use the `item()` method." + "`backward()` traverses the graph from a scalar result and accumulates\n", + "derivatives in the `.grad` attributes of leaf tensors." ] }, { "cell_type": "code", - "execution_count": 48, - "id": "4baeb817-c9fe-4b1b-afc5-cfd71b7fa307", + "execution_count": 33, + "id": "69b1fb1b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "4.255926609039307" + "(tensor([10., 16., 22.]), tensor([20., 32., 44.]))" ] }, - "execution_count": 48, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "t.item()" - ] - }, - { - "cell_type": "markdown", - "id": "622f8d8d-956b-462e-8bc3-92047272ada9", - "metadata": {}, - "source": [ - "Note that this is a Python `float value." + "loss.backward()\n", + "first_gradient = x.grad.clone()\n", + "\n", + "loss = (3.0 * x**2 - 2.0 * x + 1.0).sum()\n", + "loss.backward()\n", + "accumulated_gradient = x.grad.clone()\n", + "\n", + "first_gradient, accumulated_gradient" ] }, { "cell_type": "markdown", - "id": "8b104311-c837-4d13-ac28-f10f717a934e", + "id": "8c6b4f97", "metadata": {}, "source": [ - "You can also easily convert a numpy array to and from a PyTorch tensor." + "The second result is twice the first because gradients accumulate. Neural\n", + "network training loops call `optimizer.zero_grad(...)` before the next backward\n", + "pass. For an isolated leaf tensor, assigning `x.grad = None` clears it." ] }, { "cell_type": "code", - "execution_count": 49, - "id": "c8a995da-1556-455f-90f6-186cbb200910", - "metadata": {}, - "outputs": [], - "source": [ - "data = np.random.uniform(size=(3, 4))" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "cb22b856-2853-4c0f-902e-3a69345b5882", - "metadata": {}, - "outputs": [], - "source": [ - "t = torch.from_numpy(data)" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "529d5545-e1cf-4526-9d48-8c07ab9faa80", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "torch.float64" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t.dtype" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "66220b56-cbc7-469e-b203-c126cbc962c4", + "execution_count": 34, + "id": "06748721", "metadata": {}, "outputs": [], "source": [ - "t = t.to(torch.float32)" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "id": "aa0eb010-1896-4efc-8091-8349efdf50bd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "torch.float32" - ] - }, - "execution_count": 53, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t.dtype" + "x.grad = None\n", + "x.grad" ] }, { "cell_type": "markdown", - "id": "c121e3d9-824f-4426-afef-2eb03618773d", - "metadata": {}, - "source": [ - "t1 = torch.rand(3, 4)" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "d2e719ed-9384-44ed-93d7-b994460aae4e", + "id": "34065361", "metadata": {}, - "outputs": [], "source": [ - "data1 = t1.numpy()" + "### `backward()` versus `torch.autograd.grad`\n", + "\n", + "`backward()` is convenient for accumulating a loss gradient in all model\n", + "parameters. `torch.autograd.grad` returns derivatives with respect to selected\n", + "inputs. PINNs use the latter to differentiate the network output with respect\n", + "to space and time." ] }, { "cell_type": "code", - "execution_count": 55, - "id": "6afd3de7-ba81-4fa7-b1df-50b02c1bd6c0", + "execution_count": 35, + "id": "e093e5fc", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "((3, 4), dtype('float64'))" + "(tensor([-1.0000, -0.5000, 0.0000, 0.5000, 1.0000], requires_grad=True),\n", + " tensor([3.0000, 0.7500, 0.0000, 0.7500, 3.0000], grad_fn=),\n", + " tensor([-6., -3., 0., 3., 6.]))" ] }, - "execution_count": 55, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "data.shape, data.dtype" - ] - }, - { - "cell_type": "markdown", - "id": "f6a3454c-cdbd-441e-8189-8a3ac598905d", - "metadata": {}, - "source": [ - "## Devices" + "coordinate = torch.linspace(-1.0, 1.0, 5).requires_grad_()\n", + "field = coordinate**3\n", + "\n", + "first_derivative = torch.autograd.grad(\n", + " field,\n", + " coordinate,\n", + " grad_outputs=torch.ones_like(field),\n", + " create_graph=True,\n", + ")[0]\n", + "second_derivative = torch.autograd.grad(\n", + " first_derivative,\n", + " coordinate,\n", + " grad_outputs=torch.ones_like(first_derivative),\n", + ")[0]\n", + "\n", + "coordinate, first_derivative, second_derivative" ] }, { "cell_type": "markdown", - "id": "9cc5571c-e3e9-4758-8908-b167d75e1a4b", + "id": "153d9054", "metadata": {}, "source": [ - "You can check whether a CUDA device is available." - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "id": "01f10941-e56d-4a16-9517-557f8c39eb4f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 56, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "torch.cuda.is_available()" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "id": "c9750b55-31f1-45db-baa3-9c89f026c8a7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1" - ] - }, - "execution_count": 57, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "torch.cuda.device_count()" + "`grad_outputs` defines a vector-Jacobian product. With\n", + "`torch.ones_like(field)`, it differentiates the sum of the output components.\n", + "The result above can be read as one derivative per sample because each output\n", + "depends only on the corresponding input. That interpretation is not generally\n", + "valid for operations that couple different samples.\n", + "\n", + "`create_graph=True` records the derivative calculation itself. It is required\n", + "when another derivative will be taken, and when a PINN loss must be\n", + "differentiated through a physical derivative back to model parameters." ] }, { "cell_type": "markdown", - "id": "9adfd788-b95b-4763-b7eb-6219a66dfa95", - "metadata": {}, - "source": [ - "You can move a tensor from the host to a device." - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "id": "79d8bf7d-7077-4f21-92ee-485e97d3001a", + "id": "ce6d49cd", "metadata": {}, - "outputs": [], "source": [ - "t_host = torch.rand(3, 4)" + "### Gradient modes and model evaluation\n", + "\n", + "`torch.no_grad()` and `torch.inference_mode()` prevent operations from being\n", + "recorded by autograd. Inference mode removes additional tracking overhead but\n", + "places more restrictions on using its results later in differentiated code.\n", + "\n", + "`model.eval()` is separate: it changes the behaviour of modules such as\n", + "dropout and batch normalization but does not disable gradient recording. The\n", + "MNIST evaluation functions correctly use both `model.eval()` and\n", + "`@torch.inference_mode()`." ] }, { "cell_type": "code", - "execution_count": 59, - "id": "f73fa2dd-6aa2-4dd2-8572-0799b0dcefe8", + "execution_count": 36, + "id": "26e8ee95", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "device(type='cpu')" + "(True, False, False)" ] }, - "execution_count": 59, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "t_host.device" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "id": "d6db348c-6f3b-4f84-99dd-25fe8658874b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "device is cuda:0\n", - "tensor([[-1.0000, 0.2456, 0.5680, 0.5148],\n", - " [ 0.3087, 0.3336, 0.0437, 0.4458],\n", - " [ 0.3451, 0.2805, 0.1695, 0.5190]], device='cuda:0')\n" - ] - } - ], - "source": [ - "if torch.cuda.is_available():\n", - " t_dev = t_host.to('cuda')\n", - " print(f'device is {t_dev.device}')\n", - " t_dev[0, 0] = -1.0\n", - " print(t_dev)" + "tracked_input = torch.tensor([2.0], requires_grad=True)\n", + "\n", + "ordinary_output = tracked_input.square()\n", + "with torch.no_grad():\n", + " no_grad_output = tracked_input.square()\n", + "with torch.inference_mode():\n", + " inference_output = tracked_input.square()\n", + "\n", + "(\n", + " ordinary_output.requires_grad,\n", + " no_grad_output.requires_grad,\n", + " inference_output.requires_grad,\n", + ")" ] }, { "cell_type": "markdown", - "id": "0fd9d6e3-cfaf-415f-9027-65f2d36a6410", + "id": "78d89810", "metadata": {}, "source": [ - "The tensor on the host has not changed." + "## 11. Appendix: functional differentiation used by the PINNs\n", + "\n", + "`torch.func` provides function transformations rather than tensor methods:\n", + "\n", + "- `grad(f)` returns a function that evaluates the gradient of scalar-valued\n", + " `f`;\n", + "- transformations can be nested for higher derivatives;\n", + "- `vmap(f)` maps `f` over a tensor dimension without writing a Python loop;\n", + "- `functional_call` evaluates a module with an explicit parameter mapping.\n", + "\n", + "This style is used by the logistic and pendulum PINNs. It is useful for batched\n", + "derivatives, but is a more advanced and more version-sensitive API than the\n", + "core tensor and autograd mechanisms above." ] }, { "cell_type": "code", - "execution_count": 61, - "id": "43af0245-9776-429a-8c79-000cb1358674", + "execution_count": 37, + "id": "ac8353f8", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([[0.2740, 0.2456, 0.5680, 0.5148],\n", - " [0.3087, 0.3336, 0.0437, 0.4458],\n", - " [0.3451, 0.2805, 0.1695, 0.5190]])" + "(tensor([0.5403, 0.8776, 1.0000, 0.8776, 0.5403]),\n", + " tensor([ 0.8415, 0.4794, -0.0000, -0.4794, -0.8415]))" ] }, - "execution_count": 61, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "t_host" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "id": "177c59a4-ad1e-4897-98ed-124364c1c100", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "tensor([[-1.0000, 0.2456, 0.5680, 0.5148],\n", - " [ 0.3087, 0.3336, 0.0437, 0.4458],\n", - " [ 0.3451, 0.2805, 0.1695, 0.5190]])\n" - ] - } - ], - "source": [ - "if torch.cuda.is_available():\n", - " t1_host = t_dev.to('cpu')\n", - " print(t1_host)" - ] - }, - { - "cell_type": "markdown", - "id": "e70700ff-4cbf-4482-bd12-bef79c930d7d", - "metadata": {}, - "source": [ - "## Gradients" + "from torch.func import grad, vmap\n", + "\n", + "\n", + "def scalar_function(value):\n", + " return torch.sin(value)\n", + "\n", + "\n", + "first_derivative_function = grad(scalar_function)\n", + "second_derivative_function = grad(first_derivative_function)\n", + "points = torch.linspace(-1.0, 1.0, 5)\n", + "\n", + "(\n", + " vmap(first_derivative_function)(points),\n", + " vmap(second_derivative_function)(points),\n", + ")" ] }, { "cell_type": "markdown", - "id": "b9776363-08f9-4f57-a167-b5faaaa428d2", - "metadata": {}, - "source": [ - "As tensors are used to represent layers of neural networks, and training of such networks is done uisng backpropagation, computing gradients is a major part of the training process. PyTorch tensors can keep track of information to significantly speed up this computation, but at the cost of memory consumption." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "654a608c-42fc-4027-8b47-05133739176c", + "id": "740b5414", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "torch.is_grad_enabled()" + "The PINN notebooks use `functional_call` to evaluate a module with\n", + "an explicit parameter mapping. This makes the parameters ordinary function\n", + "arguments that can participate in function transformations." ] }, { "cell_type": "code", - "execution_count": 28, - "id": "3e2f9994-ae2b-4022-bd0f-8478b5ca1b09", - "metadata": {}, - "outputs": [], - "source": [ - "t = torch.tensor([2.0, 3.0, 4.0], requires_grad=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "ea8d7182-8115-46dd-9aff-f85e31417f55", - "metadata": {}, - "outputs": [], - "source": [ - "u = 3.0*t**2 - 2.0*t + 1.0" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "29b607dd-652e-4f0d-827a-876b8c836a84", - "metadata": {}, - "outputs": [], - "source": [ - "v = u.sum()" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "id": "3921e590-5edf-425e-9a92-46a0be18d890", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "t.requires_grad: True\n", - "u.requires_grad: True\n", - "u.requires_grad: True\n" - ] - } - ], - "source": [ - "print(\"t.requires_grad:\", t.requires_grad)\n", - "print(\"u.requires_grad:\", u.requires_grad)\n", - "print(\"u.requires_grad:\", v.requires_grad)" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "be1cce3f-70fb-4587-bc96-88051613b648", - "metadata": {}, - "outputs": [], - "source": [ - "v.backward()" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "6bf05bb4-2542-43d8-8f5d-71404ecbcad2", + "execution_count": 38, + "id": "5c3ee951", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([10., 16., 22.])" + "tensor([ 0.0353, 0.0208, 0.0016, -0.0171, -0.0318], grad_fn=)" ] }, - "execution_count": 36, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "t.grad" + "from torch import nn\n", + "from torch.func import functional_call\n", + "\n", + "model = nn.Sequential(\n", + " nn.Linear(1, 4),\n", + " nn.Tanh(),\n", + " nn.Linear(4, 1),\n", + ")\n", + "parameters = dict(model.named_parameters())\n", + "\n", + "\n", + "def model_at(value, model_parameters):\n", + " output = functional_call(\n", + " model,\n", + " model_parameters,\n", + " (value.reshape(1, 1),),\n", + " )\n", + " return output.squeeze()\n", + "\n", + "\n", + "model_derivative = grad(model_at)\n", + "model_points = torch.linspace(-1.0, 1.0, 5)\n", + "vmap(model_derivative, in_dims=(0, None))(model_points, parameters)" ] }, { "cell_type": "markdown", - "id": "63f99698-82d1-46e1-bd86-0a77da7dcee9", + "id": "cbbbc481", "metadata": {}, "source": [ - "The derivative of `u` is `6.0*t - 2.0`." + "## 12. Reasoning checks\n", + "\n", + "Try to answer these before opening the solutions.\n", + "\n", + "1. An MNIST batch has shape `[64, 1, 28, 28]`. What are the shapes of\n", + " `batch[0]`, `batch[0:1]`, and `batch.squeeze(1)`?\n", + "2. Why can `tensor.reshape(...)` be safer than `tensor.view(...)`, and why must\n", + " code still avoid relying on whether `reshape` returns a view or a copy?\n", + "3. What is the difference between `torch.cat([a, b])` and\n", + " `torch.stack([a, b])` for one-dimensional `a` and `b`?\n", + "4. Why is `prediction.detach().cpu().numpy()` preferable to\n", + " `prediction.numpy()` in device-independent model code?\n", + "5. Why does a PINN need `create_graph=True` while calculating some physical\n", + " derivatives?\n", + "\n", + "
\n", + "Solutions\n", + "\n", + "1. `[1, 28, 28]`, `[1, 1, 28, 28]`, and `[64, 28, 28]`. Integer indexing\n", + " removes a dimension, slicing preserves it, and `squeeze(1)` removes the\n", + " known size-one channel dimension.\n", + "2. `view` requires compatible strides, while `reshape` can copy when needed.\n", + " Because `reshape` may either alias or copy, mutation-sensitive code should\n", + " use an explicit view or `clone()` according to its intended ownership.\n", + "3. `cat` extends the existing dimension; `stack` introduces a new dimension.\n", + "4. It works for tensors that track gradients and for accelerator tensors. The\n", + " direct `.numpy()` conversion is restricted to supported CPU tensors that do\n", + " not require gradients.\n", + "5. The derivative must itself remain in the autograd graph so that a higher\n", + " derivative can be computed or the physics loss can propagate back to model\n", + " parameters.\n", + "\n", + "
" ] }, { "cell_type": "markdown", - "id": "04c5d9a1-6b35-48b7-891d-0dbbbe9a3f88", + "id": "dc4eca3a", "metadata": {}, "source": [ - "When you do not need to calculate gradients, e.g., during inference, the `torch.no_grad()` context manager can be used." + "## 13. Further reference\n", + "\n", + "- [Tensor attributes](https://docs.pytorch.org/docs/stable/tensor_attributes.html)\n", + "- [Broadcasting semantics](https://docs.pytorch.org/docs/stable/notes/broadcasting.html)\n", + "- [Tensor views](https://docs.pytorch.org/docs/stable/tensor_view.html)\n", + "- [Autograd mechanics](https://docs.pytorch.org/docs/stable/notes/autograd.html)\n", + "- [`torch.func`](https://docs.pytorch.org/docs/stable/func.html)\n", + "\n", + "The official documentation is the authority for version-specific signatures.\n", + "This notebook focuses on the durable concepts needed to understand the course\n", + "examples." ] } ], @@ -1545,7 +1801,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.14.2" + "version": "3.14.6" } }, "nbformat": 4, diff --git a/training.toml b/training.toml index d5b9210..72bf2a8 100644 --- a/training.toml +++ b/training.toml @@ -1,6 +1,7 @@ schema_version = 2 id = "machine-learning-with-python" title = "Machine learning with Python" +content_language = "en" summary = """ Machine learning plays an increasingly important role in many scientific domains. A Python programmer can use high-quality machine learning frameworks for classic machine learning as well as for state-of-the-art algorithms. This training concentrates on methodological and practical aspects of machine learning and how to apply those using Python. """ @@ -128,6 +129,10 @@ path = "environment.yml" name = "Geert Jan Bex" email = "geertjan.bex@uhasselt.be" +[[maintainers]] +name = "Geert Jan Bex" +email = "geertjan.bex@uhasselt.be" + [[sessions]] id = "session-1" title = "Session one"