{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "6f71ca5c", "metadata": {}, "source": [ "# Tutorial: Introductory Tutorial: Physics Informed Neural Networks with PINA \n", "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/mathLab/PINA/blob/master/tutorials/tutorial1/tutorial.ipynb)\n", "\n", "> ##### ⚠️ ***Before starting:***\n", "> We assume you are already familiar with the concepts covered in the [Getting started with PINA](https://mathlab.github.io/PINA/_tutorial.html#getting-started-with-pina) tutorials. If not, we strongly recommend reviewing them before exploring this advanced topic.\n" ] }, { "attachments": {}, "cell_type": "markdown", "id": "ef4949c9", "metadata": {}, "source": [ "In this tutorial, we will demonstrate a typical use case of **PINA** for Physics Informed Neural Network (PINN) training. We will cover the basics of training a PINN with PINA, if you want to go further into PINNs look at our dedicated [tutorials](https://mathlab.github.io/PINA/_tutorial.html#physics-informed-neural-networks) on the topic.\n", "\n", "Let's start by importing the useful modules:" ] }, { "cell_type": "code", "execution_count": 1, "id": "86478a84", "metadata": {}, "outputs": [], "source": [ "## routine needed to run the notebook on Google Colab\n", "try:\n", " import google.colab\n", "\n", " IN_COLAB = True\n", "except:\n", " IN_COLAB = False\n", "if IN_COLAB:\n", " !pip install \"pina-mathlab[tutorial]\"\n", "\n", "import warnings\n", "import torch\n", "import matplotlib.pyplot as plt\n", "\n", "from pina import Trainer, Condition\n", "from pina.problem import SpatialProblem\n", "from pina.operator import grad\n", "from pina.solver import PINN\n", "from pina.model import FeedForward\n", "from pina.optim import TorchOptimizer\n", "from pina.domain import CartesianDomain\n", "from pina.callback import MetricTracker\n", "from pina.equation import Equation, FixedValue\n", "\n", "warnings.filterwarnings(\"ignore\")" ] }, { "attachments": {}, "cell_type": "markdown", "id": "8a819659", "metadata": {}, "source": [ "## Build the problem\n", "\n", "We will use a simple Ordinary Differential Equation as pedagogical example:\n", "\n", "$$\n", "\\begin{equation}\n", "\\begin{cases}\n", "\\frac{d}{dx}u(x) &= u(x) \\quad x\\in(0,1)\\\\\n", "u(x=0) &= 1 \\\\\n", "\\end{cases}\n", "\\end{equation}\n", "$$\n", "\n", "with the analytical solution $u(x) = e^x$. \n", "\n", "The PINA problem is easly written as:" ] }, { "cell_type": "code", "execution_count": 2, "id": "f2608e2e", "metadata": {}, "outputs": [], "source": [ "def ode_equation(input_, output_):\n", " u_x = grad(output_, input_, components=[\"u\"], d=[\"x\"])\n", " u = output_.extract([\"u\"])\n", " return u_x - u\n", "\n", "\n", "class SimpleODE(SpatialProblem):\n", "\n", " output_variables = [\"u\"]\n", " spatial_domain = CartesianDomain({\"x\": [0, 1]})\n", "\n", " domains = {\n", " \"x0\": CartesianDomain({\"x\": 0.0}),\n", " \"D\": spatial_domain,\n", " }\n", "\n", " conditions = {\n", " \"bound_cond\": Condition(domain=\"x0\", equation=FixedValue(1.0)),\n", " \"phys_cond\": Condition(domain=\"D\", equation=Equation(ode_equation)),\n", " }\n", "\n", " def solution(self, pts):\n", " return torch.exp(pts.extract([\"x\"]))\n", "\n", "\n", "problem = SimpleODE()" ] }, { "attachments": {}, "cell_type": "markdown", "id": "7cf64d01", "metadata": {}, "source": [ "We are going to use latin hypercube points for sampling. We need to sample in all the conditions domains. In our case we sample in domain `D` and `x0`:" ] }, { "cell_type": "code", "execution_count": 3, "id": "622f705c", "metadata": {}, "outputs": [], "source": [ "# sampling for training\n", "problem.discretise_domain(1, \"lh\", domains=[\"x0\"])\n", "problem.discretise_domain(20, \"lh\", domains=[\"D\"])" ] }, { "attachments": {}, "cell_type": "markdown", "id": "78b30f95", "metadata": {}, "source": [ "## Generate data \n", "\n", "Data for training can come in form of direct numerical simulation results, or points in the domains. In case we perform unsupervised learning, we just need the collocation points for training, i.e. points where we want to evaluate the neural network. Sampling point in **PINA** is very easy, here we show three examples using the `.discretise_domain` method of the `AbstractProblem` class." ] }, { "cell_type": "code", "execution_count": 4, "id": "09ce5c3a", "metadata": {}, "outputs": [], "source": [ "# sampling 20 points in [0, 1] through discretization in all locations\n", "problem.discretise_domain(n=20, mode=\"grid\", domains=\"all\")\n", "\n", "# sampling 20 points in (0, 1) through latin hypercube sampling in D, and 1 point in x0\n", "problem.discretise_domain(n=20, mode=\"latin\", domains=[\"D\"])\n", "problem.discretise_domain(n=1, mode=\"random\", domains=[\"x0\"])\n", "\n", "# sampling 20 points in (0, 1) randomly\n", "problem.discretise_domain(n=20, mode=\"random\")" ] }, { "cell_type": "markdown", "id": "8fbb679f", "metadata": {}, "source": [ "We are going to use latin hypercube points for sampling. We need to sample in all the conditions domains. In our case we sample in `D` and `x0`." ] }, { "cell_type": "code", "execution_count": 5, "id": "329962b6", "metadata": {}, "outputs": [], "source": [ "# sampling for training\n", "problem.discretise_domain(1, \"random\", domains=[\"x0\"])\n", "problem.discretise_domain(20, \"lh\", domains=[\"D\"])" ] }, { "cell_type": "markdown", "id": "669e8534", "metadata": {}, "source": [ "To visualize the sampled points we can use `matplotlib.pyplot`:" ] }, { "cell_type": "code", "execution_count": 6, "id": "3802e22a", "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkIAAAGdCAYAAAD+JxxnAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAALmlJREFUeJzt3XlclWX+//E3iyyWgKICGrgUBe6FgejM0FfpS8tUfrPJzFxKs0UdCys1F5ya0pwWW1zGmkl7pGm2PcoYG0OryXADLA0kp1Q0f6CWQrmwXr8/fHhmTiFykMMBrtfz8TgPO9d93ff1ua6OnXf3uc99vIwxRgAAABby9nQBAAAAnkIQAgAA1iIIAQAAaxGEAACAtQhCAADAWgQhAABgLYIQAACwFkEIAABYy9fTBXhCVVWVDh48qFatWsnLy8vT5QAAgFowxuinn35Shw4d5O1dP+dyrAxCBw8eVGRkpKfLAAAAdbB//35ddNFF9XIsK4NQq1atJJ1eyKCgIA9XAwAAaqOkpESRkZGO9/H6YGUQOvNxWFBQEEEIAIAmpj4va+FiaQAAYC2CEAAAsBZBCAAAWMvKa4QAAI1HZWWlysvLPV0GGgEfHx/5+vo26K1tCEIAAI/5+eefdeDAARljPF0KGomWLVsqIiJCfn5+DTIeQQgA4BGVlZU6cOCAWrZsqXbt2nGDW8sZY1RWVqbDhw9rz549io6OrrebJtaEIAQA8Ijy8nIZY9SuXTsFBgZ6uhw0AoGBgWrRooX27dunsrIyBQQEuH1MLpYGAHgUZ4Lw3xriLJDTeA06GgAAQCNCEAIAANYiCAEA4IKrrrpKDzzwgKfLqFbnzp01f/58T5dxVnv37pWXl5e2b9/u6VIcCEIAAMBaBCEAAGAtghAAAC6qqKjQhAkTFBwcrLZt22rmzJmOm0IePXpUI0eOVOvWrdWyZUtde+212r17t2Pf2bNnq0+fPk7Hmz9/vjp37ux4Pnr0aA0ePFhPP/20IiIiFBoaqvHjxzvdgfvQoUO64YYbFBgYqC5dumj58uUuzeHYsWO65557FBYWpoCAAPXo0UNr1qxxbH/77bfVvXt3+fv7q3PnznrmmWec9u/cubOefPJJ3XXXXWrVqpWioqK0ZMkSpz5btmzR5ZdfroCAAPXt21c5OTku1dgQCEIAgCYvp+Co3sk+oJyCow0y3rJly+Tr66stW7bo+eef17PPPqtXXnlF0ukQs23bNr3//vvKzMyUMUbXXXedyz8jsmHDBn377bfasGGDli1bpqVLl2rp0qWO7aNHj9b+/fu1YcMGvfXWW1q4cKEOHTpUq2NXVVXp2muv1caNG/X6668rNzdXc+fOlY+PjyQpKytLt956q2677Tbt2LFDs2fP1syZM53Gl6RnnnnGEXDuv/9+3XfffcrPz5d0+q7hv//979WtWzdlZWVp9uzZeuihh1xagwZhLFRcXGwkmeLiYk+XAgDWOnnypMnNzTUnT548r+PMSc81naascTzmpOfWU4XVS0pKMrGxsaaqqsrRNmXKFBMbG2u++eYbI8ls3LjRse3IkSMmMDDQvPnmm8YYY9LS0kzv3r2djvncc8+ZTp06OZ6PGjXKdOrUyVRUVDja/vCHP5ihQ4caY4zJz883ksyWLVsc2/Py8owk89xzz51zDh999JHx9vY2+fn51W6//fbbzdVXX+3U9vDDD5tu3bo5nnfq1MnccccdjudVVVWmffv2ZtGiRcYYY/7617+a0NBQp3+/ixYtMpJMTk7OWWur6XXhjvdvzggBAJqsnIKjWvzpd05tiz/9zu1nhvr16+d0I8jExETt3r1bubm58vX1VUJCgmNbaGioLrvsMuXl5bk0Rvfu3R1naCQpIiLCccYnLy9Pvr6+iouLc2yPiYlRSEhIrY69fft2XXTRRbr00kur3Z6Xl6cBAwY4tQ0YMEC7d+9WZWWlo61Xr16Of/by8lJ4eLhTjb169XK6O3RiYmKt6mtIBCEAQJO158hxl9obA29v71/9yGx1H5u1aNHC6bmXl5eqqqrqpYb6+kkTd9bYUAhCAIAmq0vbC1xqry+bN292er5p0yZFR0erW7duqqiocNr+ww8/KD8/X926dZMktWvXToWFhU5hyNX76sTExKiiokJZWVmOtvz8fB07dqxW+/fq1UsHDhzQN998U+322NhYbdy40alt48aNuvTSS53OUtUkNjZWX331lU6dOuVo27RpU632bUgEIQBAk3V5VGvdm9TVqe2+pK66PKq1W8ctKChQamqq8vPz9cYbb+jFF1/UpEmTFB0drZtuukl33323Pv/8c3355Ze644471LFjR910002STt+Q8fDhw5o3b56+/fZbLViwQP/4xz9cGv+yyy7TNddco3vuuUebN29W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FkEIAABYiyAEAACsRRACAADWIggBAABrEYQAAIC1CEIAAMBaBCEAAGAtghAAALAWQQgAAFiLIAQAAKzl6+kCPMEYI0kqKSnxcCUAAKC2zrxvn3kfrw9WBqGffvpJkhQZGenhSgAAgKt++OEHBQcH18uxvEx9xqomoqqqSgcPHlSrVq3k5eVVr8cuKSlRZGSk9u/fr6CgoHo9Ns6Odfcc1t4zWHfPYe09p7i4WFFRUTp69KhCQkLq5ZhWnhHy9vbWRRdd5NYxgoKC+AviAay757D2nsG6ew5r7zne3vV3iTMXSwMAAGsRhAAAgLUIQvXM399faWlp8vf393QpVmHdPYe19wzW3XNYe89xx9pbebE0AACAxBkhAABgMYIQAACwFkEIAABYiyAEAACsRRBy0YIFC9S5c2cFBAQoISFBW7ZsqbH/6tWrFRMTo4CAAPXs2VPp6ekNVGnz48rav/zyy/rtb3+r1q1bq3Xr1kpOTj7nvyucnauv+zNWrlwpLy8vDR482L0FNlOurvuxY8c0fvx4RUREyN/fX5deein/zakjV9d+/vz5uuyyyxQYGKjIyEg9+OCDOnXqVANV2zx89tlnuuGGG9ShQwd5eXnpvffeO+c+n3zyia644gr5+/vrkksu0dKlS10f2KDWVq5cafz8/Mzf//538/XXX5u7777bhISEmKKiomr7b9y40fj4+Jh58+aZ3NxcM2PGDNOiRQuzY8eOBq686XN17W+//XazYMECk5OTY/Ly8szo0aNNcHCwOXDgQANX3vS5uvZn7Nmzx3Ts2NH89re/NTfddFPDFNuMuLrupaWlpm/fvua6664zn3/+udmzZ4/55JNPzPbt2xu48qbP1bVfvny58ff3N8uXLzd79uwxH330kYmIiDAPPvhgA1fetKWnp5vp06ebd955x0gy7777bo39v/vuO9OyZUuTmppqcnNzzYsvvmh8fHzM2rVrXRqXIOSC+Ph4M378eMfzyspK06FDBzNnzpxq+996663m+uuvd2pLSEgw99xzj1vrbI5cXftfqqioMK1atTLLli1zV4nNVl3WvqKiwvTv39+88sorZtSoUQShOnB13RctWmS6du1qysrKGqrEZsvVtR8/frwZOHCgU1tqaqoZMGCAW+tszmoThB555BHTvXt3p7ahQ4ealJQUl8bio7FaKisrU1ZWlpKTkx1t3t7eSk5OVmZmZrX7ZGZmOvWXpJSUlLP2R/Xqsva/dOLECZWXl6tNmzbuKrNZquvaP/bYY2rfvr3GjBnTEGU2O3VZ9/fff1+JiYkaP368wsLC1KNHDz355JOqrKxsqLKbhbqsff/+/ZWVleX4+Oy7775Tenq6rrvuugap2Vb19R5r5Y+u1sWRI0dUWVmpsLAwp/awsDDt2rWr2n0KCwur7V9YWOi2Opujuqz9L02ZMkUdOnT41V8a1Kwua//555/rb3/7m7Zv394AFTZPdVn37777TuvXr9fw4cOVnp6uf//737r//vtVXl6utLS0hii7WajL2t9+++06cuSIfvOb38gYo4qKCt1777169NFHG6Jka53tPbakpEQnT55UYGBgrY7DGSE0e3PnztXKlSv17rvvKiAgwNPlNGs//fSTRowYoZdffllt27b1dDlWqaqqUvv27bVkyRLFxcVp6NChmj59uhYvXuzp0pq9Tz75RE8++aQWLlyo7OxsvfPOO/rwww/1+OOPe7o01AJnhGqpbdu28vHxUVFRkVN7UVGRwsPDq90nPDzcpf6oXl3W/oynn35ac+fO1ccff6xevXq5s8xmydW1//bbb7V3717dcMMNjraqqipJkq+vr/Lz83XxxRe7t+hmoC6v+YiICLVo0UI+Pj6OttjYWBUWFqqsrEx+fn5urbm5qMvaz5w5UyNGjNDYsWMlST179tTx48c1btw4TZ8+Xd7enHNwh7O9xwYFBdX6bJDEGaFa8/PzU1xcnDIyMhxtVVVVysjIUGJiYrX7JCYmOvWXpHXr1p21P6pXl7WXpHnz5unxxx/X2rVr1bdv34Yotdlxde1jYmK0Y8cObd++3fG48cYb9T//8z/avn27IiMjG7L8Jqsur/kBAwbo3//+tyN4StI333yjiIgIQpAL6rL2J06c+FXYORNIDT/n6Tb19h7r2nXcdlu5cqXx9/c3S5cuNbm5uWbcuHEmJCTEFBYWGmOMGTFihJk6daqj/8aNG42vr695+umnTV5enklLS+Pr83Xk6trPnTvX+Pn5mbfeesv8v//3/xyPn376yVNTaLJcXftf4ltjdePquhcUFJhWrVqZCRMmmPz8fLNmzRrTvn178+c//9lTU2iyXF37tLQ006pVK/PGG2+Y7777zvzzn/80F198sbn11ls9NYUm6aeffjI5OTkmJyfHSDLPPvusycnJMfv27TPGGDN16lQzYsQIR/8zX59/+OGHTV5enlmwYAFfn28IL774oomKijJ+fn4mPj7ebNq0ybEtKSnJjBo1yqn/m2++aS699FLj5+dnunfvbj788MMGrrj5cGXtO3XqZCT96pGWltbwhTcDrr7u/xtBqO5cXfcvvvjCJCQkGH9/f9O1a1fzxBNPmIqKigauunlwZe3Ly8vN7NmzzcUXX2wCAgJMZGSkuf/++83Ro0cbvvAmbMOGDdX+d/vMWo8aNcokJSX9ap8+ffoYPz8/07VrV/Pqq6+6PK6XMZy3AwAAduIaIQAAYC2CEAAAsBZBCAAAWIsgBAAArEUQAgAA1iIIAQAAaxGEAACAtQhCAADAWgQhAABgLYIQAACwFkEIAABYiyAEAACs9f8B0tWoAmnqFCcAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "for location in problem.input_pts:\n", " coords = (\n", " problem.input_pts[location].extract(problem.spatial_variables).flatten()\n", " )\n", " plt.scatter(coords, torch.zeros_like(coords), s=10, label=location)\n", "_ = plt.legend()" ] }, { "attachments": {}, "cell_type": "markdown", "id": "22e502dd", "metadata": {}, "source": [ "## Easily solve a Physics Problem with three step pipeline" ] }, { "attachments": {}, "cell_type": "markdown", "id": "075f43f5", "metadata": {}, "source": [ "Once the problem is defined and the data is generated, we can move on to modeling. This process consists of three key steps:\n", "\n", "**Choosing a Model**\n", "- Select a neural network architecture. You can use the model we provide in the `pina.model` module (see [here](https://mathlab.github.io/PINA/_rst/_code.html#models) for a full list), or define a custom PyTorch module (more on this [here](https://pytorch.org/docs/stable/notes/modules.html)).\n", "\n", "**Choosing a PINN Solver & Defining the Trainer**\n", "* Use a Physics Informed solver from `pina.solver` module to solve the problem using the specified model. We have already implemented most State-Of-The-Arte solvers for you, [have a look](https://mathlab.github.io/PINA/_rst/_code.html#solvers) if interested. Today we will use the standard `PINN` solver.\n", "\n", "**Training**\n", "* Train the model with the [`Trainer`](https://mathlab.github.io/PINA/_rst/trainer.html) class. The Trainer class provides powerful features to enhance model accuracy, optimize training time and memory, and simplify logging and visualization, thanks to PyTorch Lightning's excellent work, see [our dedicated tutorial](https://mathlab.github.io/PINA/tutorial11/tutorial.html) for further details. By default, training metrics (e.g., MSE error) are logged using a lightning logger (CSVLogger). If you prefer manual tracking, use `pina.callback.MetricTracker`.\n", "\n", "Let's cover all steps one by one!\n", "\n", "First we build the model, in this case a FeedForward neural network, with two layers of size 10 and hyperbolic tangent activation:" ] }, { "cell_type": "code", "execution_count": 7, "id": "3bb4dc9b", "metadata": {}, "outputs": [], "source": [ "# build the model\n", "model = FeedForward(\n", " layers=[10, 10],\n", " func=torch.nn.Tanh,\n", " output_dimensions=len(problem.output_variables),\n", " input_dimensions=len(problem.input_variables),\n", ")" ] }, { "cell_type": "markdown", "id": "c3b92328", "metadata": {}, "source": [ "Then we build the solver. The Physics-Informed Neural Network (`PINN`) solver class needs to be initialised with a `model` and a specific `problem` to be solved. They also take extra arguments, as the optimizer, scheduler, loss type and weighting for the different conditions which are all set to their defualt values.\n", "\n", ">##### 💡***Bonus tip:***\n", "> All physics solvers in PINA can handle both forward and inverse problems without requiring any changes to the model or solver structure! See [our tutorial](https://mathlab.github.io/PINA/tutorial7/tutorial.html) of inverse problems for more infos." ] }, { "cell_type": "code", "execution_count": 8, "id": "f5127744", "metadata": {}, "outputs": [], "source": [ "# create the PINN object with RAdam Optimizer, notice that Optimizer need to\n", "# be wrapped with the pina.optim.TorchOptimizer class\n", "pinn = PINN(problem, model, TorchOptimizer(torch.optim.RAdam, lr=0.005))" ] }, { "cell_type": "markdown", "id": "c5d877cc", "metadata": {}, "source": [ "Finally, we train the model using the Trainer API. The trainer offers various options to customize your training, refer to the official documentation for details. Here, we highlight the `MetricTracker` from `pina.callback`, which helps track metrics during training. In order to train just call the `.train()` method.\n", "\n", "> ##### ⚠️ ***Important Note:***\n", "> In PINA you can log metrics in different ways. The simplest approach is to use the `MetricTraker` class from `pina.callbacks` as we will see today. However, expecially when we need to train multiple times to get an average of the loss across multiple runs, we suggest to use `lightning.pytorch.loggers` (see [here](https://lightning.ai/docs/pytorch/stable/extensions/logging.html) for reference).\n" ] }, { "cell_type": "code", "execution_count": null, "id": "582a843e", "metadata": {}, "outputs": [], "source": [ "# create the trainer\n", "trainer = Trainer(\n", " solver=pinn, # The PINN solver to be used for training\n", " max_epochs=1500, # Maximum number of training epochs\n", " logger=True, # Enables logging (default logger is CSVLogger)\n", " callbacks=[MetricTracker()], # Tracks training metrics using MetricTracker\n", " accelerator=\"cpu\", # Specifies the computing device (\"cpu\", \"gpu\", ...)\n", " train_size=1.0, # Fraction of the dataset used for training (100%)\n", " test_size=0.0, # Fraction of the dataset used for testing (0%)\n", " val_size=0.0, # Fraction of the dataset used for validation (0%)\n", " enable_model_summary=False, # Disables model summary printing\n", ")\n", "\n", "# train\n", "trainer.train()" ] }, { "cell_type": "markdown", "id": "f8b4f496", "metadata": {}, "source": [ "After the training we can inspect trainer logged metrics (by default **PINA** logs mean square error residual loss). The logged metrics can be accessed online using one of the `Lightning` loggers. The final loss can be accessed by `trainer.logged_metrics`" ] }, { "cell_type": "code", "execution_count": 10, "id": "f5fbf362", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'bound_cond_loss': tensor(4.2729e-08),\n", " 'phys_cond_loss': tensor(1.6728e-05),\n", " 'train_loss': tensor(1.6770e-05)}" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# inspecting final loss\n", "trainer.logged_metrics" ] }, { "cell_type": "markdown", "id": "0963d7d2", "metadata": {}, "source": [ "By using `matplotlib` we can also do some qualitative plots of the solution. " ] }, { "cell_type": "code", "execution_count": 11, "id": "ffbf0d5e", "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiwAAAGdCAYAAAAxCSikAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAWcRJREFUeJzt3Xl4DXfDxvHvyZ6QRUgkIfZdCII0dkpDW6Wramsp1ZaoqkeVbnQT1Y22SqtKtVW0tbS0FG2ofY01lhC72CWErGfePzzO+6S2JJJMlvtzXee6nDm/mXPPEOfOzJwZi2EYBiIiIiIFmJ3ZAURERERuR4VFRERECjwVFhERESnwVFhERESkwFNhERERkQJPhUVEREQKPBUWERERKfBUWERERKTAczA7QG6wWq0cP34cd3d3LBaL2XFEREQkCwzD4OLFiwQEBGBnd+t9KEWisBw/fpzAwECzY4iIiEgOHDlyhPLly99yTJEoLO7u7sDVFfbw8DA5jYiIiGRFYmIigYGBts/xWykSheXaYSAPDw8VFhERkUImK6dz6KRbERERKfBUWERERKTAU2ERERGRAi9b57BERkYyZ84cdu/ejaurK82aNeP999+nZs2aN52nTZs2LF++/Lrp9957LwsXLgSgd+/efPvtt5leDw8PZ9GiRdmJd0uGYZCenk5GRkauLVNEwN7eHgcHB11SQETyVLYKy/Lly4mIiKBJkyakp6fz6quvcs8997Br1y5KlChxw3nmzJlDamqq7fnZs2cJDg7m0UcfzTSuY8eOTJ061fbc2dk5O9FuKTU1lRMnTnD58uVcW6aI/D83Nzf8/f1xcnIyO4qIFFHZKiz/3uMxbdo0fH192bRpE61atbrhPN7e3pmez5w5Ezc3t+sKi7OzM35+ftmJkyVWq5W4uDjs7e0JCAjAyclJvwmK5BLDMEhNTeX06dPExcVRvXr12178SUQkJ+7oa80JCQnA9aXkVqZMmcLjjz9+3R6ZqKgofH19KVWqFO3atePdd9+ldOnSN1xGSkoKKSkptueJiYk3fb/U1FSsViuBgYG4ubllOaeIZI2rqyuOjo4cOnSI1NRUXFxczI4kIkVQjn8VslqtDB48mObNmxMUFJSledavX8+OHTt45plnMk3v2LEj06dPZ9myZbz//vssX76cTp063fR8k8jISDw9PW2PrFzlVr/1ieQd/XyJSF6zGIZh5GTG/v3788cff7By5crbXk73mueee441a9awbdu2W447cOAAVatWZenSpdx9993XvX6jPSyBgYEkJCRcd+G45ORk4uLiqFy5sn7zE8kj+jkTkZxITEzE09Pzhp/f/5ajX4sGDhzIggUL+Pvvv7NcVpKSkpg5cyZ9+/a97dgqVapQpkwZYmNjb/i6s7Oz7aq2urqtiIhI0ZetwmIYBgMHDmTu3Ln89ddfVK5cOcvz/vTTT6SkpPDUU0/dduzRo0c5e/Ys/v7+2YknJmnTpg2DBw82O0aeGzVqFA0aNMi395s2bRpeXl53vJyoqCgsFgsXLly442WJiJglW4UlIiKC77//nhkzZuDu7k58fDzx8fFcuXLFNqZnz56MGDHiunmnTJlC165drzuR9tKlS7z88susXbuWgwcPsmzZMrp06UK1atUIDw/P4WoVDb1798ZisTBmzJhM0+fNm1eovuk0bdo0LBYLHTt2zDT9woULWCwWoqKisrys3r1707Vr19wNWITcqDw2a9aMEydO4OnpaU4oEZFckK3CMnHiRBISEmjTpg3+/v62x6xZs2xjDh8+zIkTJzLNt2fPHlauXHnDw0H29vZs27aNBx54gBo1atC3b19CQkL4559/cvVaLIWVi4sL77//PufPn8/3905LS8u1ZTk4OLB06VL+/vvvXFtmfrl20cHCysnJCT8/v0JVckWkADEMjn73HKf//sLUGNk+JHSjR+/evW1joqKimDZtWqb5atasiWEYdOjQ4bplurq6snjxYk6dOkVqaioHDx7kq6++omzZsjlaoayux+XUdFMe2T3HuX379vj5+REZGXnLcStXrqRly5a4uroSGBjIoEGDSEpKsr1usViYN29epnm8vLxsf1cHDx7EYrEwa9YsWrdujYuLCz/88ANnz56le/fulCtXDjc3N+rVq8ePP/6YrXUAKFGiBH369GH48OG3HHfkyBEee+wxvLy88Pb2pkuXLhw8eBC4ekjm22+/Zf78+VgsFtvemUceeYSBAwfaljF48GAsFgu7d+8Grn61vUSJEixduhS4etL2oEGD8PX1xcXFhRYtWrBhwwbb/NcOofzxxx+EhITg7OzMypUrr8u6f/9+qlSpwsCBA2/492oYBqNGjaJChQo4OzsTEBDAoEGDbK+fP3+enj17UqpUKdzc3OjUqRP79u276ba50d6lwYMH06ZNG9vry5cvZ/z48bbtc/DgwRseEvrll1+oW7cuzs7OVKpUiY8++ijTcitVqsTo0aPp06cP7u7uVKhQga+++uqm2USk6Dq6YDTl98/Ee/mrHNmzxbQcd3QdlsLqSloGdd5cbMp773o7HDenrG92e3t7Ro8ezRNPPMGgQYNueJLz/v376dixI++++y7ffPMNp0+fZuDAgQwcODDT1YOzYvjw4Xz00Uc0bNgQFxcXkpOTCQkJ4ZVXXsHDw4OFCxfSo0cPqlatStOmTbO17FGjRlGtWjV+/vlnHnnkketeT0tLIzw8nLCwMP755x8cHBx499136dixI9u2bWPo0KHExMSQmJhoWy9vb2+2b9/Ol19+aVvO8uXLKVOmDFFRUdSqVYsNGzaQlpZGs2bNABg2bBi//PIL3377LRUrVmTs2LGEh4cTGxub6ZpCw4cP58MPP6RKlSqUKlUq06Grbdu2ER4eTt++fXn33XdvuL6//PILn3zyCTNnzqRu3brEx8ezdetW2+u9e/dm3759/Prrr3h4ePDKK69w7733smvXLhwdHbO1bQHGjx/P3r17CQoK4u233wbAx8fHVviu2bRpE4899hijRo2iW7durF69mgEDBlC6dOlMv3x89NFHvPPOO7z66qv8/PPP9O/fn9atW9/yVhwiUrScXDuT8pvGAjCz9EAer97AtCy6eEIh8OCDD9KgQQNGjhx5w9cjIyN58sknGTx4MNWrV6dZs2Z8+umnTJ8+neTk5Gy91+DBg3nooYeoXLky/v7+lCtXjqFDh9KgQQOqVKnCCy+8QMeOHZk9e3a21yMgIIAXX3yR11577YaHWGbNmoXVauXrr7+mXr161K5dm6lTp3L48GGioqIoWbIkrq6utqsi+/n54eTkRJs2bdi1axenT5/m/Pnz7Nq1ixdffNFWMKKiomjSpAlubm4kJSUxceJEPvjgAzp16kSdOnWYPHkyrq6uTJkyJVOet99+mw4dOlC1atVMRWb16tW0adOGoUOH3rSswNXDo35+frRv354KFSrQtGlT+vXrB2ArKl9//TUtW7YkODiYH374gWPHjl23JyyrPD09cXJyws3NzbZ97O3trxv38ccfc/fdd/PGG29Qo0YNevfuzcCBA/nggw8yjbv33nsZMGAA1apV45VXXqFMmTKF8pCeiORMwr7VlFp0de/1ry5dePC5UdjbmXdouVjuYXF1tGfX2+ac0OvqeP0HSFa8//77tGvXjqFDh1732tatW9m2bRs//PCDbZphGLbbEtSuXTvL79O4ceNMzzMyMhg9ejSzZ8/m2LFjpKamkpKSkuOrBr/yyit8+eWXfPPNNzz22GPXrUdsbCzu7u6ZpicnJ7N///6bLjMoKAhvb2+WL1+Ok5MTDRs25P7772fChAnA1T0u1w6b7N+/n7S0NJo3b26b39HRkaZNmxITE5Npuf/eFnC1hHTo0IH33nvvtt+MevTRRxk3bhxVqlShY8eO3HvvvXTu3BkHBwdiYmJwcHAgNDTUNr506dLUrFnzuhy5LSYmhi5dumSa1rx5c8aNG0dGRoat5NSvX9/2usViwc/Pj1OnTuVpNhEpGFJOH4AZj+NEGivtmhDWf1K2jg7khWJZWCwWi+kbPrtatWpFeHg4I0aMyLTbHq5+0+q5557LdH7ENRUqVACurvO/z7O40Um1/75lwgcffMD48eMZN24c9erVo0SJEgwePDjTDS2zw8vLixEjRvDWW29x//33X7ceISEhmYrXNT4+PjddpsVioVWrVkRFReHs7EybNm2oX78+KSkp7Nixg9WrV9+w6N3OjW7o6ePjQ0BAAD/++CN9+vS55TWAAgMD2bNnD0uXLmXJkiUMGDCADz744IZ3L88KOzu7LP0d5pZ/H5ayWCxYrdY8ez8RKRisl89z7qsu+BsJxFAZ/77f4+Np/q1tdEioEBkzZgy//fYba9asyTS9UaNG7Nq1i2rVql33uHb3XB8fn0zf3tq3b1+W7l69atUqunTpwlNPPUVwcDBVqlRh7969d7QeL7zwAnZ2dowfP/669di3bx++vr7Xrce1r+Q6OTnd8JYNrVu3JioqiqioKNq0aYOdnR2tWrXigw8+ICUlxbZHpWrVqjg5ObFq1SrbvGlpaWzYsIE6dercNrurqysLFizAxcWF8PBwLl68eNvxnTt35tNPPyUqKoo1a9awfft2ateuTXp6OuvWrbONPXv2LHv27Llpjn//HQJER0dnen6z7fO/ateunWn94erfc40aNW54CElEipGMNA5NegT/tMPEG95cfuQHqpbL/RsT54QKSyFSr149nnzyST799NNM01955RVWr17NwIEDiY6OZt++fcyfPz/TN2fatWvH559/zpYt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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "pts = pinn.problem.spatial_domain.sample(256, \"grid\", variables=\"x\")\n", "predicted_output = pinn.forward(pts).extract(\"u\").tensor.detach()\n", "true_output = pinn.problem.solution(pts).detach()\n", "fig, ax = plt.subplots(nrows=1, ncols=1)\n", "ax.plot(pts.extract([\"x\"]), predicted_output, label=\"Neural Network solution\")\n", "ax.plot(pts.extract([\"x\"]), true_output, label=\"True solution\")\n", "_ = plt.legend()" ] }, { "cell_type": "markdown", "id": "bf47b98a", "metadata": {}, "source": [ "The solution is overlapped with the actual one, and they are barely indistinguishable. We can also visualize the loss during training using the `MetricTracker`:" ] }, { "cell_type": "code", "execution_count": 12, "id": "03398692", "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# plot loss\n", "trainer_metrics = trainer.callbacks[0].metrics\n", "loss = trainer_metrics[\"train_loss\"]\n", "epochs = range(len(loss))\n", "plt.plot(epochs, loss.cpu())\n", "# plotting\n", "plt.xlabel(\"epoch\")\n", "plt.ylabel(\"loss\")\n", "plt.yscale(\"log\")" ] }, { "cell_type": "markdown", "id": "33e672da", "metadata": {}, "source": [ "## What's Next?\n", "\n", "Congratulations on completing the introductory tutorial on Physics-Informed Training! Now that you have a solid foundation, here are several exciting directions you can explore:\n", "\n", "1. **Experiment with Training Duration & Network Architecture**: Try different training durations and tweak the network architecture to optimize performance.\n", "\n", "2. **Explore Other Models in `pina.model`**: Check out other models available in `pina.model` or design your own custom PyTorch module to suit your needs.\n", "\n", "3. **Run Training on a GPU**: Speed up your training by running on a GPU and compare the performance improvements.\n", "\n", "4. **Test Various Solvers**: Explore and evaluate different solvers to assess their performance on various types of problems.\n", "\n", "5. **... and many more!**: The possibilities are vast! Continue experimenting with advanced configurations, solvers, and other features in PINA.\n", "\n", "For more resources and tutorials, check out the [PINA Documentation](https://mathlab.github.io/PINA/)." ] } ], "metadata": { "kernelspec": { "display_name": "deep", "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.12.11" } }, "nbformat": 4, "nbformat_minor": 5 }