{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "6f71ca5c", "metadata": {}, "source": [ "# Tutorial: Physics Informed Neural Networks on PINA\n", "\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" ] }, { "attachments": {}, "cell_type": "markdown", "id": "ef4949c9", "metadata": {}, "source": [ "In this tutorial, we will demonstrate a typical use case of **PINA** on a toy problem, following the standard API procedure. \n", "\n", "

\n", " \"PINA\n", "

\n", "\n", "Specifically, the tutorial aims to introduce the following topics:\n", "\n", "* Explaining how to build **PINA** Problems,\n", "* Showing how to generate data for `PINN` training\n", "\n", "These are the two main steps needed **before** starting the modelling optimization (choose model and solver, and train). We will show each step in detail, and at the end, we will solve a simple Ordinary Differential Equation (ODE) problem using the `PINN` solver." ] }, { "attachments": {}, "cell_type": "markdown", "id": "cf9c96e3", "metadata": {}, "source": [ "## Build a PINA problem" ] }, { "attachments": {}, "cell_type": "markdown", "id": "8a819659", "metadata": {}, "source": [ "Problem definition in the **PINA** framework is done by building a python `class`, which inherits from one or more problem classes (`SpatialProblem`, `TimeDependentProblem`, `ParametricProblem`, ...) depending on the nature of the problem. Below is an example:\n", "### Simple Ordinary Differential Equation\n", "Consider the following:\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$. In this case, our ODE depends only on the spatial variable $x\\in(0,1)$ , meaning that our `Problem` class is going to be inherited from the `SpatialProblem` class:\n", "\n", "```python\n", "from pina.problem import SpatialProblem\n", "from pina.domain import CartesianProblem\n", "\n", "class SimpleODE(SpatialProblem):\n", " \n", " output_variables = ['u']\n", " spatial_domain = CartesianProblem({'x': [0, 1]})\n", "\n", " # other stuff ...\n", "```\n", "\n", "Notice that we define `output_variables` as a list of symbols, indicating the output variables of our equation (in this case only $u$), this is done because in **PINA** the `torch.Tensor`s are labelled, allowing the user maximal flexibility for the manipulation of the tensor. The `spatial_domain` variable indicates where the sample points are going to be sampled in the domain, in this case $x\\in[0,1]$.\n", "\n", "What if our equation is also time-dependent? In this case, our `class` will inherit from both `SpatialProblem` and `TimeDependentProblem`:\n" ] }, { "cell_type": "code", "execution_count": 1, "id": "2373a925", "metadata": {}, "outputs": [], "source": [ "## routine needed to run the notebook on Google Colab\n", "try:\n", " import google.colab\n", " IN_COLAB = True\n", "except:\n", " IN_COLAB = False\n", "if IN_COLAB:\n", " !pip install \"pina-mathlab\"\n", "\n", "from pina.problem import SpatialProblem, TimeDependentProblem\n", "from pina.domain import CartesianDomain\n", "\n", "class TimeSpaceODE(SpatialProblem, TimeDependentProblem):\n", " \n", " output_variables = ['u']\n", " spatial_domain = CartesianDomain({'x': [0, 1]})\n", " temporal_domain = CartesianDomain({'t': [0, 1]})\n", "\n", " # other stuff ..." ] }, { "attachments": {}, "cell_type": "markdown", "id": "ad8566b8", "metadata": {}, "source": [ "where we have included the `temporal_domain` variable, indicating the time domain wanted for the solution.\n", "\n", "In summary, using **PINA**, we can initialize a problem with a class which inherits from different base classes: `SpatialProblem`, `TimeDependentProblem`, `ParametricProblem`, and so on depending on the type of problem we are considering. Here are some examples (more on the official documentation):\n", "* ``SpatialProblem`` $\\rightarrow$ a differential equation with spatial variable(s) ``spatial_domain``\n", "* ``TimeDependentProblem`` $\\rightarrow$ a time-dependent differential equation with temporal variable(s) ``temporal_domain``\n", "* ``ParametricProblem`` $\\rightarrow$ a parametrized differential equation with parametric variable(s) ``parameter_domain``\n", "* ``AbstractProblem`` $\\rightarrow$ any **PINA** problem inherits from here" ] }, { "attachments": {}, "cell_type": "markdown", "id": "592a4c43", "metadata": {}, "source": [ "### Write the problem class\n", "\n", "Once the `Problem` class is initialized, we need to represent the differential equation in **PINA**. In order to do this, we need to load the **PINA** operators from `pina.operator` module. Again, we'll consider Equation (1) and represent it in **PINA**:" ] }, { "cell_type": "code", "execution_count": null, "id": "f2608e2e", "metadata": {}, "outputs": [], "source": [ "from pina.problem import SpatialProblem\n", "from pina.operator import grad\n", "from pina import Condition\n", "from pina.domain import CartesianDomain\n", "from pina.equation import Equation, FixedValue\n", "\n", "import torch\n", "import matplotlib.pyplot as plt\n", "plt.style.use('tableau-colorblind10')\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.}),\n", " 'D': CartesianDomain({'x': [0, 1]})\n", " }\n", "\n", " # defining the ode equation\n", " def ode_equation(input_, output_):\n", "\n", " # computing the derivative\n", " u_x = grad(output_, input_, components=['u'], d=['x'])\n", "\n", " # extracting the u input variable\n", " u = output_.extract(['u'])\n", "\n", " # calculate the residual and return it\n", " return u_x - u\n", "\n", " # conditions to hold\n", " conditions = {\n", " 'bound_cond': Condition(domain='x0', equation=FixedValue(1.)),\n", " 'phys_cond': Condition(domain='D', equation=Equation(ode_equation))\n", " }\n", "\n", " # defining the true solution\n", " def truth_solution(self, pts):\n", " return torch.exp(pts.extract(['x']))\n", " \n", "problem = SimpleODE()" ] }, { "attachments": {}, "cell_type": "markdown", "id": "7cf64d01", "metadata": {}, "source": [ "After we define the `Problem` class, we need to write different class methods, where each method is a function returning a residual. These functions are the ones minimized during PINN optimization, given the initial conditions. For example, in the domain $[0,1]$, the ODE equation (`ode_equation`) must be satisfied. We represent this by returning the difference between subtracting the variable `u` from its gradient (the residual), which we hope to minimize to 0. This is done for all conditions. Notice that we do not pass directly a `python` function, but an `Equation` object, which is initialized with the `python` function. This is done so that all the computations and internal checks are done inside **PINA**.\n", "\n", "Once we have defined the function, we need to tell the neural network where these methods are to be applied. To do so, we use the `Condition` class. In the `Condition` class, we pass the location points and the equation we want minimized on those points (other possibilities are allowed, see the documentation for reference).\n", "\n", "Finally, it's possible to define a `truth_solution` function, which can be useful if we want to plot the results and see how the real solution compares to the expected (true) solution. Notice that the `truth_solution` function is a method of the `PINN` class, but it is not mandatory for problem definition.\n" ] }, { "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": 3, "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": 4, "id": "329962b6", "metadata": {}, "outputs": [], "source": [ "# sampling for training\n", "problem.discretise_domain(1, 'random', domains=['x0']) # TODO check\n", "problem.discretise_domain(20, 'lh', domains=['D'])" ] }, { "cell_type": "markdown", "id": "ca2ac5c2", "metadata": {}, "source": [ "The points are saved in a python `dict`, and can be accessed by calling the attribute `input_pts` of the problem " ] }, { "cell_type": "code", "execution_count": 5, "id": "d6ed9aaf", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Input points: {'x0': LabelTensor([[0.]]), 'D': LabelTensor([[0.4519],\n", " [0.4306],\n", " [0.8085],\n", " [0.6035],\n", " [0.8842],\n", " [0.7970],\n", " [0.3849],\n", " [0.1173],\n", " [0.7432],\n", " [0.0200],\n", " [0.5698],\n", " [0.9792],\n", " [0.5295],\n", " [0.3197],\n", " [0.0558],\n", " [0.2836],\n", " [0.1626],\n", " [0.2333],\n", " [0.6633],\n", " [0.9157]])}\n", "Input points labels: ['x']\n" ] } ], "source": [ "print('Input points:', problem.discretised_domains)\n", "print('Input points labels:', problem.discretised_domains['D'].labels)" ] }, { "cell_type": "markdown", "id": "669e8534", "metadata": {}, "source": [ "To visualize the sampled points we can use `matplotlib.pyplot`:" ] }, { "cell_type": "code", "execution_count": null, "id": "3802e22a", "metadata": {}, "outputs": [ { "data": { "image/png": "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tGih2NjYwLZu3brJ5/OpqqpK8fHxYZ1zNGvIej/88MMaOnSofvnLX0qSevTooYMHD2rEiBGaNGmSYmK4P9CYTvaamZiYGNJdG4k7N/UWHx+vjIwMlZSUBLbV1taqpKRE2dnZde6TnZ0dNF6Sli5detLxCNaQNZekJ554Qo8++qiKi4vVq1evSEzVhFDXu2vXrlq7dq3WrFkTeNx88836yU9+ojVr1ig9PT2S0486DXl+X3PNNfryyy8DESlJ//73v9WhQwfC5jQast6HDh06IWCOh6Xjf8vY6Br1NTPktyCfxebNm+e8Xq+bPXu227BhgxsxYoRLTk52Pp/POefc0KFD3fjx4wPjP/74YxcXF+eeeuopt3HjRldQUMBHwUMU6ppPnTrVxcfHu9dff9198803gceBAwea6hKiSqjr/UN8Wio0oa739u3bXatWrdyoUaPc5s2b3ZIlS1z79u3d73//+6a6hKgS6noXFBS4Vq1aub/+9a9uy5Yt7p///Kfr0qWLu/3225vqEqLKgQMH3OrVq93q1audJPfMM8+41atXu23btjnnnBs/frwbOnRoYPzxj4KPGzfObdy40c2cOZOPgkfK888/7zp27Oji4+NdZmam++STTwJf69u3rxs2bFjQ+L/97W/ukksucfHx8e7yyy93b731VoRnHP1CWfOLLrrISTrhUVBQEPmJR6lQn+P/i7gJXajrvXz5cpeVleW8Xq/r3Lmze+yxx9zRo0cjPOvoFcp6V1dXu9/+9reuS5cuLiEhwaWnp7v77rvPffvtt5GfeBR699136/z3+PgaDxs2zPXt2/eEfXr27Oni4+Nd586d3Z///OcGndvjHPfWAACAHbznBgAAmELcAAAAU4gbAABgCnEDAABMIW4AAIApxA0AADCFuAEAAKYQNwAAwBTiBgAAmELcAAAAU4gbAABgCnEDAABM+f/F1ffAV2cNNQAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "variables=problem.spatial_variables\n", "fig = plt.figure()\n", "proj = \"3d\" if len(variables) == 3 else None\n", "ax = fig.add_subplot(projection=proj)\n", "for location in problem.input_pts:\n", " coords = problem.input_pts[location].extract(variables).T.detach()\n", " ax.plot(coords.flatten(),torch.zeros(coords.flatten().shape),\".\",label=location)\n" ] }, { "attachments": {}, "cell_type": "markdown", "id": "22e502dd", "metadata": {}, "source": [ "## Perform a small training" ] }, { "attachments": {}, "cell_type": "markdown", "id": "075f43f5", "metadata": {}, "source": [ "Once we have defined the problem and generated the data we can start the modelling. Here we will choose a `FeedForward` neural network available in `pina.model`, and we will train using the `PINN` solver from `pina.solver`. We highlight that this training is fairly simple, for more advanced stuff consider the tutorials in the ***Physics Informed Neural Networks*** section of ***Tutorials***. For training we use the `Trainer` class from `pina.trainer`. Here we show a very short training and some method for plotting the results. Notice that by default all relevant metrics (e.g. MSE error during training) are going to be tracked using a `lightning` logger, by default `CSVLogger`. If you want to track the metric by yourself without a logger, use `pina.callback.MetricTracker`." ] }, { "cell_type": "code", "execution_count": 7, "id": "3bb4dc9b", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "GPU available: False, used: False\n", "TPU available: False, using: 0 TPU cores\n", "HPU available: False, using: 0 HPUs\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "d2c3b03173424844beead0135687f8a1", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Sanity Checking: | | 0/? [00:00" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAqgAAAKTCAYAAADVBfoyAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAdX5JREFUeJzt3Xd0FNXj/vFn0xNIIUBIgqFX6V06KBgQEZTeO9JBQIpKEQt2sWBHilIFASmCFAOioKKioIhUESGglDRIsuX+/uBLfp9IDZDMJnm/ztlzzO6dzbOMgSdzZ+7YjDFGAAAAgJvwsDoAAAAA8L8oqAAAAHArFFQAAAC4FQoqAAAA3AoFFQAAAG6FggoAAAC3QkEFAACAW/GyOsDt4HK5dPz4cQUGBspms1kdBwAAAP9hjFFCQoIiIyPl4XHtY6Q5oqAeP35cUVFRVscAAADAdfz111+64447rjkmRxTUwMBASRc/cFBQkMVpAAAA8F/x8fGKiopK623XkiMK6qVp/aCgIAoqAACAG7uR0zG5SAoAAABuhYIKAAAAt0JBBQAAgFvJEeeg3iin0ym73W51DCBH8fb2lqenp9UxAAA5SK4oqMYYxcbG6ty5c1ZHAXKkkJAQhYeHsw4xAOC2yBUF9VI5DQsLU0BAAP+IAreJMUbnz5/XqVOnJEkREREWJwIA5AQ5vqA6nc60cpo/f36r4wA5jr+/vyTp1KlTCgsLY7ofAHDLcvxFUpfOOQ0ICLA4CZBzXfr54hxvAMDtkOML6iVM6wOZh58vAMDtlGsKKgAAALIHCioAAADcSoYK6vTp01WrVi0FBgYqLCxMbdu21b59+665TZMmTWSz2S57tGrVKm1M7969L3u9RYsWN/eJkOWaNGmiUaNGWR0j002dOlVVq1bNsu83Z84chYSE3PL7xMTEyGazscwaACDbyFBB3bJli4YOHaodO3Zow4YNstvtuvfee5WUlHTVbT799FOdOHEi7bFnzx55enqqQ4cO6ca1aNEi3biFCxfe3CfKQS4V9+eeey7d8ytWrMhW5/zNmTPnir90nDt3TjabTTExMTf8Xr1791bbtm1vb8Ac5Eq/LNSrV08nTpxQcHCwNaEAAMigDC0ztW7dunRfz5kzR2FhYfrhhx/UqFGjK24TGhqa7utFixYpICDgsoLq6+ur8PDwjMTJFfz8/PT888/r4YcfVr58+bL0e9vtdnl7e9+W9/Ly8tLGjRv15ZdfqmnTprflPbOKMUZOp9PqGDfNx8eHny0AQLZyS+egxsXFSbq8hF7LrFmz1LlzZ+XJkyfd8zExMQoLC1PZsmU1ePBgnT59+qrvkZKSovj4+HSPjDDG6Hyqw5KHMSZDWZs1a6bw8HBNnz79muO2bdumhg0byt/fX1FRURoxYkS6I9s2m00rVqxIt01ISIjmzJkjSTpy5IhsNpsWL16sxo0by8/PT/Pnz9fp06fVpUsXFS5cWAEBAapUqdJNHd3OkyeP+vbtqwkTJlxz3F9//aWOHTsqJCREoaGhatOmjY4cOSLp4hT73LlztXLlyrRTQWJiYtS+fXsNGzYs7T1GjRolm82m33//XZKUmpqqPHnyaOPGjZIu/v8zYsQIhYWFyc/PTw0aNND333+ftv2lKfHPP/9cNWrUkK+vr7Zt23ZZ1oMHD6pEiRIaNmzYFferMUZTp05VkSJF5Ovrq8jISI0YMSLt9bNnz6pnz57Kly+fAgIC1LJlS+3fv/+qfzZXOno8atQoNWnSJO31LVu26LXXXkv78zly5MgVp/iXLVumChUqyNfXV8WKFdPLL7+c7n2LFSumZ599Vn379lVgYKCKFCmi995776rZAAC4nW56oX6Xy6VRo0apfv36qlix4g1t891332nPnj2aNWtWuudbtGihhx56SMWLF9fBgwf12GOPqWXLltq+ffsVF/2ePn26nnzyyZuNrgt2p+6cvP6mt78Vv02LVoDPjf+xe3p66tlnn1XXrl01YsQI3XHHHZeNOXjwoFq0aKGnn35aH374of755x8NGzZMw4YN0+zZszOUb8KECXr55ZdVrVo1+fn5KTk5WTVq1ND48eMVFBSkNWvWqEePHipZsqRq166dofeeOnWqSpUqpaVLl6p9+/aXvW632xUdHa26devqq6++kpeXl55++mm1aNFCv/zyi8aOHau9e/cqPj4+7XOFhoZq9+7devfdd9PeZ8uWLSpQoIBiYmJUrlw5ff/997Lb7apXr54kady4cVq2bJnmzp2rokWL6oUXXlB0dLQOHDiQ7petCRMm6KWXXlKJEiWUL1++dKci/PLLL4qOjla/fv309NNPX/HzLlu2TK+++qoWLVqkChUqKDY2Vj///HPa671799b+/fv12WefKSgoSOPHj9d9992n33777aaOXL/22mv6448/VLFiRU2bNk2SVLBgwbSCf8kPP/ygjh07aurUqerUqZO++eYbDRkyRPnz51fv3r3Txr388st66qmn9Nhjj2np0qUaPHiwGjdurLJly2Y4GwAAGXHTR1CHDh2qPXv2aNGiRTe8zaxZs1SpUqXLik3nzp31wAMPqFKlSmrbtq1Wr16t77///qrnJk6cOFFxcXFpj7/++utmP0a28OCDD6pq1aqaMmXKFV+fPn26unXrplGjRql06dKqV6+eXn/9dc2bN0/JyckZ+l6jRo1K+2UhIiJChQsX1tixY1W1alWVKFFCw4cPV4sWLbRkyZIMf47IyEiNHDlSjz/+uBwOx2WvL168WC6XSx988IEqVaqk8uXLa/bs2Tp69KhiYmKUN29e+fv7p50OEh4eLh8fHzVp0kS//fab/vnnH509e1a//fabRo4cmfb/T0xMjGrVqqWAgAAlJSXp7bff1osvvqiWLVvqzjvv1Pvvvy9/f//LfnGaNm2amjdvrpIlS6Yrrt98842aNGmisWPHXrWcStLRo0cVHh6uZs2aqUiRIqpdu7YGDBggSWnF9IMPPlDDhg1VpUoVzZ8/X3///fdlR7pvVHBwsHx8fBQQEJD253OlX/BeeeUV3XPPPZo0aZLKlCmj3r17a9iwYXrxxRfTjbvvvvs0ZMgQlSpVSuPHj1eBAgX05Zdf3lQ2AAAy4qaOoA4bNkyrV6/W1q1br3hE70qSkpK0aNGitCM711KiRAkVKFBABw4c0D333HPZ676+vvL19c1w7kv8vT3127Tom97+Vvh739xtIJ9//nndfffdGjt27GWv/fzzz/rll180f/78tOeMMXK5XDp8+LDKly9/w9+nZs2a6b52Op169tlntWTJEv39999KTU1VSkrKTd+Za/z48Xr33Xf14YcfqmPHjpd9jgMHDigwMDDd88nJyTp48OBV37NixYoKDQ3Vli1b5OPjo2rVqun+++/XzJkzJV08onppGvzgwYOy2+2qX79+2vbe3t6qXbu29u7dm+59//tnIV0snc2bN9czzzxz3ZULOnTooBkzZqhEiRJq0aKF7rvvPrVu3VpeXl7au3evvLy8VKdOnbTx+fPnV9myZS/Lcbvt3btXbdq0Sfdc/fr1NWPGDDmdzrRSW7ly5bTXbTabwsPDderUqUzNBgCAlMGCaozR8OHDtXz5csXExKh48eI3vO0nn3yilJQUde/e/bpjjx07ptOnTysiIiIj8W6YzWbL0DS7O2jUqJGio6M1ceLEdNOwkpSYmKiHH3443fmNlxQpUkTSxc/83/Mkr3Rbyv+eG/ziiy/qtdde04wZM1SpUiXlyZNHo0aNUmpq6k19jpCQEE2cOFFPPvmk7r///ss+R40aNdIV7UsKFix41fe02Wxq1KiRYmJi5OvrqyZNmqhy5cpKSUnRnj179M0331yx2F/Pf/8sLuWIjIzUwoUL1bdvXwUFBV11+6ioKO3bt08bN27Uhg0bNGTIEL344ovasmVLhrNIkoeHxw3tw9vlv6cZ2Gw2uVyuTPt+AABckqEp/qFDh+rjjz/WggULFBgYqNjYWMXGxurChQtpY3r27KmJEydetu2sWbPUtm1b5c+fP93ziYmJevTRR7Vjxw4dOXJEmzZtUps2bVSqVClFR1tzlNNdPffcc1q1apW2b9+e7vnq1avrt99+U6lSpS57+Pj4SLpYrE6cOJG2zf79+3X+/Pnrfs+vv/5abdq0Uffu3VWlShWVKFFCf/zxxy19juHDh8vDw0OvvfbaZZ9j//79CgsLu+xzXFoiycfH54pX1Ddu3FgxMTGKiYlRkyZN5OHhoUaNGunFF19USkpK2hHTkiVLysfHR19//XXatna7Xd9//73uvPPO62b39/fX6tWr5efnp+joaCUkJFx3fOvWrfX6668rJiZG27dv1+7du1W+fHk5HA59++23aWNPnz6tffv2XTXHf/ehJO3atSvd11f78/lf5cuXT/f5pYv7uUyZMlc8JQAAgKyWoYL69ttvKy4uTk2aNFFERETaY/HixWljjh49etk/ovv27dO2bdvUr1+/y97T09NTv/zyix544AGVKVNG/fr1U40aNfTVV1/d0jR+TlSpUiV169ZNr7/+errnx48fr2+++UbDhg3Trl27tH//fq1cuTLdle1333233nzzTf3000/auXOnBg0adEMX4pQuXVobNmzQN998o7179+rhhx/WyZMnb+lz+Pn56cknn7zsc3Tr1k0FChRQmzZt9NVXX+nw4cOKiYnRiBEjdOzYMUkXry7/5ZdftG/fPv37779pRxAvnYf666+/qkGDBmnPzZ8/XzVr1kw7GponTx4NHjxYjz76qNatW6fffvtNAwYM0Pnz56/4/+eV5MmTR2vWrJGXl5datmypxMTEK46bM2eOZs2apT179ujQoUP6+OOP5e/vr6JFi6p06dJq06aNBgwYoG3btunnn39W9+7dVbhw4cum3y+5++67tXPnTs2bN0/79+/XlClTtGfPnnRjihUrpm+//VZHjhzRv//+e8UjnmPGjNGmTZv01FNP6Y8//tDcuXP15ptv3tRRZgAAMkOGCqox5oqP/51yjomJSVu66JKyZcvKGKPmzZtf9p7+/v5av369Tp06pdTUVB05ckTvvfeeChUqdFMfKKebNm3aZaWjcuXK2rJli/744w81bNhQ1apV0+TJkxUZGZk25uWXX1ZUVJQaNmyorl27auzYsTd0HukTTzyh6tWrKzo6Wk2aNFF4ePhtWSi/V69eKlGiRLrnAgICtHXrVhUpUkQPPfSQypcvr379+ik5OTltKn3AgAEqW7asatasqYIFC6YdCaxUqZJCQkJUtWpV5c2bV9LFgup0OtPOP73kueeeU7t27dSjRw9Vr15dBw4c0Pr16zO0zmzevHn1+eefyxijVq1aXfFmFSEhIXr//fdVv359Va5cWRs3btSqVavSZhFmz56tGjVq6P7771fdunVljNHatWuv+otDdHS0Jk2apHHjxqlWrVpKSEhQz549040ZO3asPD09deedd6pgwYI6evToZe9TvXp1LVmyRIsWLVLFihU1efJkTZs27bJTRwAAsIrNZHRhTjcUHx+v4OBgxcXFXXZOYHJysg4fPqzixYvLz8/PooRAzsbPGQDgeq7V1/7rlhbqBwAAQDbldEjOzLvY9lZQUAEAAHKjb9+W3m8qHf/J6iSXoaACAADkNmcOyWx+RordffHhZiioAAAAuYkx0qpRsjkuaJdXZe0Je8DqRJehoAIAAOQmu+ZLh7co2XhrZFJv7Tkeb3Wiy1BQAQAAcouEkzLrH5MkveJor8jiFdSpVpTFoS6Xve73CQAAgJv3+TjZkuO021VM8z3u19p2lWSz2axOdRmOoAIAAOQGv6+Rflshh/HQePtAPXLvnSqaP4/Vqa6IgopMFRMTI5vNpnPnzt3S+xw5ckQ2m+2ye88DAIAbkBwns2aMJOk95/3yvqOq+tQvbnGoq6OguimbzXbNx9SpU62OmGl69+592e1Uo6KidOLECVWsWNGaUAAAZGcbpsiWcEKHXOF627TXi+0ry9PD/ab2L+EcVDd14sSJtP9evHixJk+erH379qU9d+l+85JkjJHT6ZSXV87dnZ6engoPD7c6BgAA2c+Rr6UfZkuSJtoH6OHmd6pMoUCLQ10bR1DdVHh4eNojODhYNpst7evff/9dgYGB+vzzz1WjRg35+vpq27ZtVzzyOGrUKDVp0iTta5fLpenTp6t48eLy9/dXlSpVtHTp0mtmeeutt1S6dGn5+fmpUKFCat++fdprKSkpGjFihMLCwuTn56cGDRro+++/v+p7TZ06VVWrVk333IwZM1SsWLG01+fOnauVK1emHS2OiYm54hT/li1bVLt2bfn6+ioiIkITJkyQw+FIe71JkyYaMWKExo0bp9DQUIWHh+foI88AAFzGniytGiFJWuBoqoTwOnq4cUmLQ11fzj3kdi3GSPbz1nxv7wDpNl0tN2HCBL300ksqUaKE8uXLd0PbTJ8+XR9//LHeeecdlS5dWlu3blX37t1VsGBBNW7c+LLxO3fu1IgRI/TRRx+pXr16OnPmjL766qu018eNG6dly5Zp7ty5Klq0qF544QVFR0frwIEDCg0NzfBnGjt2rPbu3av4+HjNnn3xt73Q0FAdP3483bi///5b9913n3r37q158+bp999/14ABA+Tn55euhM6dO1ejR4/Wt99+q+3bt6t3796qX7++mjdvnuFsAABkO1tfkE4f0EkTohdd3fRxh8ry9nT/45O5s6Daz0vPRlrzvR87Lvncnivmpk2blqGilZKSomeffVYbN25U3bp1JUklSpTQtm3b9O67716xoB49elR58uTR/fffr8DAQBUtWlTVqlWTJCUlJentt9/WnDlz1LJlS0nS+++/rw0bNmjWrFl69NFHM/yZ8ubNK39/f6WkpFxzSv+tt95SVFSU3nzzTdlsNpUrV07Hjx/X+PHjNXnyZHl4XPzhq1y5sqZMmSJJKl26tN58801t2rSJggoAyPlid8t8/Zpskibb+6hb48qqEBlsdaobkjsLag5Rs2bNDI0/cOCAzp8/f1k5S01NTSud/9W8eXMVLVpUJUqUUIsWLdSiRQs9+OCDCggI0MGDB2W321W/fv208d7e3qpdu7b27t2b8Q+UAXv37lXdunXTrd1Wv359JSYm6tixYypSpIikiwX1f0VEROjUqVOZmg0AAMs5HdJnw2VzObTWWVsHCzTV6/eUsjrVDcudBdU7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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').as_subclass(torch.Tensor).cpu().detach()\n", "true_output = pinn.problem.truth_solution(pts).cpu().detach()\n", "pts = pts.cpu()\n", "fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(8, 8))\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 plot easily the loss:" ] }, { "cell_type": "code", "execution_count": 10, "id": "bf6211e6", "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkIAAAGwCAYAAABFFQqPAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAASmlJREFUeJzt3XdUVGf+BvBnCszQEZA+FMGGBVSKWGLDGGM0plliDGrU1ZjERNfUX9pmd80mm6zrOjE96qZoNNFsEqNRomJBaaKiKCIICNJEupSZub8/0IlEUYSBO+X5nDPnyL2XO98XDfPkvW+RCIIggIiIiMgCScUugIiIiEgsDEJERERksRiEiIiIyGIxCBEREZHFYhAiIiIii8UgRERERBaLQYiIiIgsllzsAoydTqdDYWEhHBwcIJFIxC6HiIiI2kAQBFRXV8Pb2xtSaev9PgxCt1FYWAiVSiV2GURERNQO+fn58PX1bfU8g9BtODg4AGj+QTo6OopcDREREbVFVVUVVCqV/nO8NQxCt3HtcZijoyODEBERkYm53bAWDpYmIiIii2URQeinn35C79690bNnT3z66adil0NERERGwuwfjWk0Gixbtgx79uyBk5MThgwZggceeACurq5il0ZEREQiM/seocTERPTr1w8+Pj6wt7fHxIkT8euvv4pdFhERERkBow9C8fHxmDx5Mry9vSGRSLBt27YbrlGr1QgICIBSqURUVBQSExP15woLC+Hj46P/2sfHBwUFBV1ROhERERk5ow9CtbW1CA0NhVqtvun5TZs2YdmyZXj99deRmpqK0NBQTJgwASUlJe16v4aGBlRVVbV4ERERkXky+iA0ceJE/PWvf8UDDzxw0/Pvv/8+FixYgLlz5yIkJAQffvghbG1t8fnnnwMAvL29W/QAFRQUwNvbu9X3W7lyJZycnPQvLqZIRERkvow+CN1KY2MjUlJSEBMToz8mlUoRExODhIQEAEBkZCTS09NRUFCAmpoa/PLLL5gwYUKr93zppZdQWVmpf+Xn53d6O4iIiEgcJj1rrKysDFqtFh4eHi2Oe3h44PTp0wAAuVyO9957D2PGjIFOp8Pzzz9/yxljCoUCCoWiU+smIiIi42DSQaitpkyZgilTpohdBhERERkZk3405ubmBplMhuLi4hbHi4uL4enp2aF7q9VqhISEICIiokP3ISIi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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "list_ = [\n", " idx for idx, s in enumerate(trainer.callbacks)\n", " if isinstance(s, MetricTracker)\n", " ]\n", "trainer_metrics = trainer.callbacks[list_[0]].metrics\n", "\n", "loss = trainer_metrics['val_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": "58172899", "metadata": {}, "source": [ "As we can see the loss has not reached a minimum, suggesting that we could train for longer" ] }, { "cell_type": "markdown", "id": "33e672da", "metadata": {}, "source": [ "## What's next?\n", "\n", "Congratulations on completing the introductory tutorial of **PINA**! There are several directions you can go now:\n", "\n", "1. Train the network for longer or with different layer sizes and assert the finaly accuracy\n", "\n", "2. Train the network using other types of models (see `pina.model`)\n", "\n", "3. GPU training and speed benchmarking\n", "\n", "4. Many more..." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.7" } }, "nbformat": 4, "nbformat_minor": 5 }