* Tutorial doc update * update doc tutorial * doc not compiling --------- Co-authored-by: Dario Coscia <dcoscia@euclide.maths.sissa.it> Co-authored-by: Dario Coscia <dariocoscia@Dario-Coscia.local>
541 lines
92 KiB
Plaintext
Vendored
541 lines
92 KiB
Plaintext
Vendored
{
|
|
"cells": [
|
|
{
|
|
"attachments": {},
|
|
"cell_type": "markdown",
|
|
"id": "6f71ca5c",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Tutorial: Physics Informed Neural Networks on PINA"
|
|
]
|
|
},
|
|
{
|
|
"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",
|
|
"<p align=\"center\">\n",
|
|
" <img src=\"../../readme/API_color.png\" alt=\"PINA API\" width=\"400\"/>\n",
|
|
"</p>\n",
|
|
"\n",
|
|
"Specifically, the tutorial aims to introduce the following topics:\n",
|
|
"\n",
|
|
"* Explaining how to build **PINA** Problem,\n",
|
|
"* Showing how to generate data for `PINN` straining\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 busing 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 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 about 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": [
|
|
"from pina.problem import SpatialProblem, TimeDependentProblem\n",
|
|
"from pina 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)\n",
|
|
"* `TimeDependentProblem` $\\rightarrow$ a time-dependent differential equation\n",
|
|
"* `ParametricProblem` $\\rightarrow$ a parametrized differential equation\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.operators` module. Again, we'll consider Equation (1) and represent it in **PINA**:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"id": "f2608e2e",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from pina.problem import SpatialProblem\n",
|
|
"from pina.operators import grad\n",
|
|
"from pina import Condition\n",
|
|
"from pina.geometry import CartesianDomain\n",
|
|
"from pina.equation import Equation, FixedValue\n",
|
|
"\n",
|
|
"import torch\n",
|
|
"\n",
|
|
"\n",
|
|
"class SimpleODE(SpatialProblem):\n",
|
|
"\n",
|
|
" output_variables = ['u']\n",
|
|
" spatial_domain = CartesianDomain({'x': [0, 1]})\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",
|
|
" 'x0': Condition(location=CartesianDomain({'x': 0.}), equation=FixedValue(1)), # We fix initial condition to value 1\n",
|
|
" 'D': Condition(location=CartesianDomain({'x': [0, 1]}), equation=Equation(ode_equation)), # We wrap the python equation using Equation\n",
|
|
" }\n",
|
|
"\n",
|
|
" # sampled points (see below)\n",
|
|
" input_pts = None\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 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 reusults, or points in the domains. In case we do 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', variables=['x'], locations='all')\n",
|
|
"\n",
|
|
"# sampling 20 points in (0, 1) through latin hypercube samping in D, and 1 point in x0\n",
|
|
"problem.discretise_domain(n=20, mode='latin', variables=['x'], locations=['D'])\n",
|
|
"problem.discretise_domain(n=1, mode='random', variables=['x'], locations=['x0'])\n",
|
|
"\n",
|
|
"# sampling 20 points in (0, 1) randomly\n",
|
|
"problem.discretise_domain(n=20, mode='random', variables=['x'])"
|
|
]
|
|
},
|
|
{
|
|
"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', locations=['x0'])\n",
|
|
"problem.discretise_domain(20, 'lh', locations=['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.8569]],\n",
|
|
" [[0.9478]],\n",
|
|
" [[0.3030]],\n",
|
|
" [[0.8182]],\n",
|
|
" [[0.4116]],\n",
|
|
" [[0.6687]],\n",
|
|
" [[0.5394]],\n",
|
|
" [[0.9927]],\n",
|
|
" [[0.6082]],\n",
|
|
" [[0.4605]],\n",
|
|
" [[0.2859]],\n",
|
|
" [[0.7321]],\n",
|
|
" [[0.5624]],\n",
|
|
" [[0.1303]],\n",
|
|
" [[0.2402]],\n",
|
|
" [[0.0182]],\n",
|
|
" [[0.0714]],\n",
|
|
" [[0.3697]],\n",
|
|
" [[0.7770]],\n",
|
|
" [[0.1784]]])}\n",
|
|
"Input points labels: ['x']\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"print('Input points:', problem.input_pts)\n",
|
|
"print('Input points labels:', problem.input_pts['D'].labels)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "669e8534",
|
|
"metadata": {},
|
|
"source": [
|
|
"To visualize the sampled points we can use the `.plot_samples` method of the `Plotter` class"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"id": "33cc80bc",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAGwCAYAAABVdURTAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAk3ElEQVR4nO3dCbRV1X0/8N9jdAQiyKQQ1KhoQF2KICb9G5WWVGt0qSvEGKMGtbZineqAEkmTRlLjgMaBZVJLTLUSrLGRUFKEGG0gDmhSHJuqBBSZagQjyHj/dx97X4A8Rt+977Hf57PW4XLP3Wfa9753vm+fvc+tK5UFAEAmWjX1DgAANCbhBgDIinADAGRFuAEAsiLcAABZEW4AgKwINwBAVto09Q40hXXr1sX8+fNj9913j7q6uqbeHQBgK6Rb87333nvRs2fPaNVq0+0zLTLcpGDTq1evpt4NAGA7zJs3L/bee+9Nvt4iw01qsalUTocOHZp4bwCArbFs2bKicaJyHt+UFhluKpeiUrARbgBgx7KlLiU6FAMAWRFuAICsCDcAQFZaZJ8bAGiu1q5dG6tXr27q3WgSbdu2jdatW3/k9Qg3ANBM7uGyYMGCePfdd5t6V5pUp06donv37h/pPnTCDQA0A5Vg07Vr19hll11a3E1mS+Vwt3z58li0aFHxvEePHtu9LuEGAJrBpahKsOncuXNT706T2XnnnYvHFHBSXWzvJSodigGgiVX62KQWm5Zul/+rg4/S70i4AYBmoqVdiqpWHQg3AEBWhBsAICvCDQCQFeEGAKiaxx9/PA4//PBo3759fOITn4jx48dXbVsVwg0AZOTtpStixmtLisem9sYbb8SJJ54Yxx57bPzqV7+KSy+9NM4777z46U9/WtXtCjcAkIkJz8yNT31renzxu08Vj+l5NS1evLi4m/ANN9xQP2/GjBnRrl27mDZtWowbNy722WefuPnmm+Oggw6KESNGxOmnnx633nprVfdLuAGADKSWmpEPz451pQ+fp8drH36hqi04e+65Z9x7773xta99LZ599tl477334qyzzipCzPHHHx8zZ86MIUOGbLDM0KFDi/nV5A7FAJCBN5a8Xx9sKtaWSjFnyfLo0fHDO/9WwwknnBDnn39+nHnmmTFgwIDYddddY8yYMfVfKdGtW7cNyqfny5YtixUrVtTfkbixabkBgAzs02XXaLXR/e9a19VFny7Vv+vxTTfdFGvWrImJEyfG/fffX3QebkrCDQBkILXOjDm1fxFokvR4w6n9qtpqU/Haa6/F/PnzY926dTFnzpz6+ak/zsKFCzcom5536NChaq02ictSAJCJYUf2jv93wJ7FpajUYlOLYLNq1ar40pe+FMOGDYsDDzywGA01e/bs4osvBw8eHJMnT96g/NSpU4v51aTlBgAy0qMcaAbv17kmwSa57rrrYunSpXH77bfH1VdfHQcccEB85StfKV678MIL4/XXX4+rrroqXnnllbjrrrvihz/8YVx22WVV3SfhBgDY7hv0jR07Nn7wgx8Ul5patWpV/P/JJ5+Mu+++uxgG/pOf/KRorTn00EOLIeHf+973ihFT1eSyFACwXT7zmc/E6tWrN5jXp0+foiVn/TLPP//8dq1/e2m5AQCyItwAAFkRbgCArAg3AEBWhBsAICvCDQCQFeEGAMiKcAMAZEW4AQCyItwAANvtnHPOibq6umJq27ZtdOvWLf70T/807r333uJbwpuCcAMAfCSf/exn4+233445c+bEv//7v8exxx4bl1xySfzFX/xFrFmz5iOte3v4bikAyMnStyLeeS1ij/0iOu5Vk022b98+unfvXvx/r732isMPPzyOOuqoOP7442P8+PFx3nnn1WQ/KrTcAEAunrsvYmy/iO+f9OFjet5EjjvuuOKbwB9++OGab1u4AYBcWmwevSSi9H/9XNLjo5d+OL+J9O3bt7hUVWvCDQDkIF2KqgSbitLa8vzXK89qrlQqFR2Na024AYAcpD42dRud1utal+fv2zT7U/byyy/HPvvsU/PtCjcAkIPUefik2z4MNEl6PGlszToVb2z69Okxe/bsOO2002q+baOlACAXh385Yr/jP7wUlVpsahRsVq5cGQsWLIi1a9fGwoULY8qUKTFmzJhiKPiXv1zepxoTbgAgJx3LgSZNNZTCTI8ePaJNmzbxsY99rBgldfvtt8fZZ58drVrV/iKRcAMAbLd0H5s0NSf63AAAWalJuLnzzjujT58+sdNOO8WgQYPi6aef3mz5iRMnFmPjU/n+/fvH5MmTN1n2wgsvLIaZjR1b7jQFALR4VQ83EyZMiMsvvzxGjx4dzz33XHEdbujQobFo0aIGy8+YMSPOOOOMGD58eDz//PNxyimnFNMLL7zwR2V/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ICvCDQCQFeEGAMiKcAMAZEW4AQCyItwAAFkRbgCArAg3AEBWhBsAICvCDQCQFeEGAMiKcAMAZEW4AQCyItwAAFkRbgCArAg3AEBWhBsAICvCDQCQFeEGAMiKcAMAZEW4AQCyItwAAFkRbgCArAg3AEBWWjX1DgAANCbhBgDIinADAGRFuAEAsiLcAABZEW4AgKwINwBAVoQbACArwg0AkBXhBgDIinADAGRFuAEAsiLcAABZEW4AgKwINwBAVoQbACArwg0AkJU2Tb0DTaFUKhWPy5Yta+I9AQC2VuW8XTmPb0qLDDfvvfde8dirV68m3hMAYHvO4x07dtzk63WlLcWfDK1bty7mz58fu+++e9TV1TV6qkyhad68edGhQ4dGXTfquSn4TKvrHPlc75h1nSJLCjY9e/aMVq023bOmRbbcpArZe++9q7qN9AYKN9WnnmtHXavrHPlc73h1vbkWmwodigGArAg3AEBWhJtG1r59+xg9enTxSPWo59pR1+o6Rz7Xedd1i+xQDADkS8sNAJAV4QYAyIpwAwBkRbgBALIi3GyjO++8M/r06RM77bRTDBo0KJ5++unNlp84cWL07du3KN+/f/+YPHnydr9ZLc221PV3v/vd+JM/+ZP42Mc+VkxDhgzZ4nvD9tX1+h588MHiLt+nnHKK6qxSXb/77rtx0UUXRY8ePYrRJgcccIDfI1Wq67Fjx8aBBx4YO++8c3FH3csuuyw++OCDrd1ci/TEE0/ESSedVNwxOP0ueOSRR7a4zOOPPx6HH3548Xn+xCc+EePHj2/8HUujpdg65V/kpXbt2pXuvffe0osvvlg6//zzS506dSotXLiwwfK/+MUvSq1bty7deOONpZdeeqk0atSoUtu2bUuzZ89W5Y1c11/84hdL5V9kpeeff7708ssvl84555xSx44dS2+++aa6buS6rnjjjTdKe+21V6kcKksnn3yyeq5CXa9cubI0YMCA0gknnFD6z//8z6LOyyeG0q9+9Sv13ch1ff/995fKJ9viMdXzT3/601I5UJbKAUddb0b5D/bSddddV3r44YfTyOvSj370o82ULpVef/310i677FK6/PLLi/Pid77zneI8OWXKlM0ut62Em20wcODAUvkvqPrna9euLZXTamnMmDENlv/85z9fOvHEEzeYV/7rofSXf/mX2/FWtSzbWtcbW7NmTWn33Xcvff/736/WLrbouk71e/TRR5e+973vlc4++2zhpkp1fffdd5f23Xff0qpVq7Z2E2xnXaeyxx133Abz0gn4U5/6lDrdSlsTbq666qrSJz/5yQ3mDRs2rDR06NCt3MrWcVlqK5V/ucSsWbOKyx3rf0dVej5z5swGl0nz1y+flN/ATZZn++t6Y8uXL4/Vq1fHHnvsoVqrUNdf//rXo2vXrjF8+HD1W8W6/vGPfxyDBw8uLkt169Yt+vXrFzfccEOUT9TqvZHruhzWi2Uql67KLQzF5b9yq5m6bkS1Oi+2yC/O3B5LliwpfqGkXzDrS89feeWVBpdZsGBBg+XTfBq3rjd29dVXF9eAN/4h4qPXdfnySPzjP/5jlC+NqM4q13U6wU6fPj3OPPPM4kT7P//zP/HXf/3XRXBPd3yl8eq6fGm7WO7Tn/508c3T5dbJuPDCC+Paa69VzY1oU+fF9M3hK1asKPo7NQYtN2TnW9/6VtHRtdw8WnQkpPG89957cdZZZxUduLt06aJqq2zdunVFC9k999wTRxxxRJSb76PcvyHGjRun7htZ6uSaWsXuuuuueO6556LchyR+8pOfxDe+8Q11vQPScrOV0i/ycqenKHdG22B+et69e/cGl0nzt6U821/XFTfddFMRbh577LE45JBDVGkj1/Vrr70Wc+bMKUZHrH8CTtq0aROvvvpq7Lfffuq9Eeo6SSOk2rZtWyxXcdBBBxV//aZLL+UOs+q6ker6q1/9ahHczzvvvOJ5Gt36/vvvxwUXXFAEynRZi49uU+fFDh06NFqrTeLd2krpl0j6y2natGkb/FJPz9M18Yak+euXT6ZOnbrJ8mx/XSc33nhj8VfWlClTYsCAAaqzCnWdbmswe/bs4pJUZfrc5z4Xxx57bPH/NHyWxqnrpNyZtbgUVQmQyX//938XoUewabzPdaWf3sYBphIqP+wrS2Oo2XmxUbsnt4ChhWmo4Pjx44shbOVEXwwtLP8VVbxeTv2la665ZoOh4OW/Zkvl1oRieHL5Grmh4FWq63JrTTHs86GHHiq9/fbb9VP5Mkpjvf3Z2ta63pjRUtWr67lz5xaj/kaMGFEqt4qVJk2aVCpfpir9/d///Xa91y3JttZ1+v2c6vpf/uVfiuHK//Ef/1Eqt0IWo17ZtPQ7Nt2CI00pUtxyyy3F/3/7298Wr6c6TnW98VDwK6+8sjgvplt4GAreDKQx+b179y5OpGmo4S9/+cv614455pjiF/36fvjDH5YOOOCAonwa/la+hlvrXW4Rdf3xj3+8+MHaeEq/sGjcut6YcFO9z3UyY8aM4hYS6USdhoV/85vfLIbi07h1Xe6kXfra175WBJpyX71SuRWyVO68Xfrd736nqjfjZz/7WYO/eyt1mx5TXW+8zGGHHVa8L+kz/U//9E+b2cL2qUv/NG5bEABA09HnBgDIinADAGRFuAEAsiLcAABZEW4AgKwINwBAVoQbACArwg0AkBXhBgDIinADAGRFuAEAsiLcADu8xYsXR/fu3eOGG26onzdjxoxo165dTJs2rQn3DGgKvjgTyMLkyZPjlFNOKULNgQceGIcddlicfPLJccsttzT1rgE1JtwA2bjoooviscceiwEDBsTs2bPjmWeeifbt2zf1bgE1JtwA2VixYkX069cv5s2bF7NmzYr+/fs39S4BTUCfGyAbr732WsyfPz/WrVsXc+bMaerdAZqIlhsgC6tWrYqBAwcWfW1Sn5uxY8cWl6a6du3a1LsG1JhwA2ThyiuvjIceeih+/etfx2677RbHHHNMdOzYMSZNmtTUuwbUmMtSwA7v8ccfL1pqfvCDH0SHDh2iVatWxf+ffPLJuPvuu5t694Aa03IDAGRFyw0AkBXhBgDIinADAGRFuAEAsiLcAABZEW4AgKwINwBAVoQbACArwg0AkBXhBgDIinADAGTl/wOG2uJmlooI8QAAAABJRU5ErkJggg==",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"from pina import Plotter\n",
|
|
"\n",
|
|
"pl = Plotter()\n",
|
|
"pl.plot_samples(problem=problem)"
|
|
]
|
|
},
|
|
{
|
|
"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.solvers`. 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 `lightining` logger, by default `CSVLogger`. If you want to track the metric by yourself without a logger, use `pina.callbacks.MetricTracker`."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"id": "3bb4dc9b",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"/u/d/dcoscia/.local/lib/python3.9/site-packages/torch/cuda/__init__.py:546: UserWarning: Can't initialize NVML\n",
|
|
" warnings.warn(\"Can't initialize NVML\")\n",
|
|
"/u/d/dcoscia/.local/lib/python3.9/site-packages/torch/cuda/__init__.py:651: UserWarning: CUDA initialization: CUDA unknown error - this may be due to an incorrectly set up environment, e.g. changing env variable CUDA_VISIBLE_DEVICES after program start. Setting the available devices to be zero. (Triggered internally at ../c10/cuda/CUDAFunctions.cpp:109.)\n",
|
|
" return torch._C._cuda_getDeviceCount() if nvml_count < 0 else nvml_count\n",
|
|
"GPU available: False, used: False\n",
|
|
"TPU available: False, using: 0 TPU cores\n",
|
|
"IPU available: False, using: 0 IPUs\n",
|
|
"HPU available: False, using: 0 HPUs\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Epoch 1499: : 1it [00:00, 143.58it/s, v_num=5, mean_loss=1.09e-5, x0_loss=1.33e-7, D_loss=2.17e-5] "
|
|
]
|
|
},
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"`Trainer.fit` stopped: `max_epochs=1500` reached.\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Epoch 1499: : 1it [00:00, 65.39it/s, v_num=5, mean_loss=1.09e-5, x0_loss=1.33e-7, D_loss=2.17e-5] \n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from pina import PINN, Trainer\n",
|
|
"from pina.model import FeedForward\n",
|
|
"from pina.callbacks import MetricTracker\n",
|
|
"\n",
|
|
"\n",
|
|
"# 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",
|
|
")\n",
|
|
"\n",
|
|
"# create the PINN object\n",
|
|
"pinn = PINN(problem, model)\n",
|
|
"\n",
|
|
"# create the trainer\n",
|
|
"trainer = Trainer(solver=pinn, max_epochs=1500, callbacks=[MetricTracker()], accelerator='cpu', enable_model_summary=False) # we train on CPU and avoid model summary at beginning of training (optional)\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 `Lightinig` loggers. The final loss can be accessed by `trainer.logged_metrics`"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"id": "f5fbf362",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{'mean_loss': tensor(1.0938e-05),\n",
|
|
" 'x0_loss': tensor(1.3328e-07),\n",
|
|
" 'D_loss': tensor(2.1743e-05)}"
|
|
]
|
|
},
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# inspecting final loss\n",
|
|
"trainer.logged_metrics"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "0963d7d2",
|
|
"metadata": {},
|
|
"source": [
|
|
"By using the `Plotter` class from **PINA** we can also do some quatitative plots of the solution. "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"id": "19078eb5",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAArwAAAKnCAYAAABkq54bAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABsJElEQVR4nO3dB3gU1fv28XvTEyCh996rIAiIIL0XwQqKNAFBsXfsHX9WLEhTujQVUJEOAiKIAqKitNB7Jw1Sd96c8Z+8gICUJLO7+X6ua2VmM1mePRPJnZNnzrisVAIAAAB8lJ/TBQAAAACZicALAAAAn0bgBQAAgE8j8AIAAMCnEXgBAADg0wi8AAAA8GkEXgAAAPg0Ai8AAAB8WoDTBXgit9ut/fv3K1euXHK5XE6XAwAAgHOYe6fFxMSoaNGi8vO7+Bwugfc8TNgtUaLERQcOAAAAztuzZ4+KFy9+0WMIvOdhZnbTBjA8PDzjzwwAAACuSnR0tD1BmZbbLobAex5pbQwm7BJ4AQAAPNeltJ9y0RoAAAB8GoEXAAAAPo3ACwAAAJ9GD+9VLIWRnJyslJSUjDwfQJby9/dXQEAAy+8BAHwagfcKJCYm6sCBAzp16lRGnw8gy4WFhalIkSIKCgpi9AEAPonAewU3pdixY4c9M2YWOjYhgZtTwFt/S2F+eDty5Ij9NV2hQoX/XLgbAABvROC9TCYgmNBr1n0zM2OANwsNDVVgYKB27dplf22HhIQ4XRIAABmO6ZwrHThmwuAj+FoGAPg6Ai8AAAB8GoEXHmHcuHHKnTu302V41HtZunSp3R9+8uTJDKgKAIDsy9HAO2TIENWtW9e+B3LBggXVpUsXbd68+aKf07RpUzsEnPvo0KFD+jG9e/f+18fbtm2b2W8HXqB06dIaOnSo02Wc9+v6kUceOeu5G264wV4NJCIi4l/HAwAAL7lobdmyZRo0aJAdes2ats8++6xat26tv//+Wzly5Djv58yYMcO+uCbNsWPHVLNmTd1+++1nHWcC7tixY9P3g4ODM+dN4KLMuWK5qytjxq1w4cJ8hQEA4M0zvPPmzbNnY6tVq2aHVvOr4N27d2vt2rUX/Jy8efPaISDtsXDhQnu1hHMDrwm4Zx6XJ0+ezH47Hs3MID700EN66qmn0sfw5ZdfPusY86vzfv36qUCBAgoPD1fz5s31+++/p3/cnCszC38mMytpXvvMv+eBBx6wn8+fP7/atGljP//++++rRo0a9g8yZoWL+++/X7GxsZdc/86dO+2ZevMDT7Nmzexzbr5mVq1addZxK1as0I033mivPmD+HvOe4+Li0mszqxE8+uij6TP/F1quy4xNyZIl7a8js/yceZ00J06cUM+ePe2vKVNHu3bttHXr1gvW/l/jZj5ufvj78MMP0+sy7/d8LQ1ff/21/f+LqcvMVr/33ntnva557s0339Q999xj/+bEvIdRo0ZdwggDAOC7PKqHNyoqyv7TBLJL9fnnn6tbt27/mhE2YcG0SVSqVEn33XefPRN8IQkJCYqOjj7rcTlMQDqVmJzlD/P3Xo7x48fb47R69Wq9/fbbevXVV+0fGNKYHxoOHz6suXPn2j901K5dWy1atNDx48cv++8xs5M//fSTRowYkb4SwEcffaS//vrL/viSJUvs8H25nnvuOT3xxBNav369KlasqDvvvNP+7YCxbds2e2b/1ltv1R9//KFp06bZAdgEcMOE5eLFi9vv27QKmMf5mFD5wQcfaOTIkXaQnTVrlh3W05iAumbNGn377bd24DbnoX379kpKSrrs92OYoNugQQP1798/vS4T1s9lzskdd9xhf73/+eefdih/4YUX7B8Uz2RC8HXXXafffvvN/sHCfP3/V6sQAAC+zGPW4TVr25pZr4YNG6p69eqX9Dm//PKLNmzYYIfeM5nQc8stt6hMmTJ2CDKtEmYWzoQTc8OI8/USv/LKK1dc++mkFFV9cf4Vf/6V+vvVNgoLuvRTeM011+ill16yt81NBj755BMtXrxYrVq1soOhGU8TeNPaP95991077H311Ve69957L/nvMa9tAvWZzuxPNbOQr7/+ugYOHKhPP/30kl/XMGE3rV/bnDMz2xkZGanKlSvb57F79+7pf5epw4TsJk2aaPjw4fYPUub8m5nPi7UKmN8ymI+3bNnSXqPWzJLWq1fP/pgJwCbomjBvemyNL774wg6oZqzO/U3DpTA9uuYHBDNbfLG6zCy5+QHEhFzDBH7T/vPOO+/YITyNCd8m6BpPP/20Hd5/+OEH+4c/AACyI4+Z4TW9vCa8Tp069ZI/xwRdM/OWFkbSmBmwm266yf6Y+VXy7Nmz9euvv9qzvuczePBge3Y57bFnz56rei+eygTeM5nbyZqAa5jWBdNikC9f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",
|
|
"text/plain": [
|
|
"<Figure size 800x800 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# plotting the solution\n",
|
|
"pl.plot(trainer=trainer)"
|
|
]
|
|
},
|
|
{
|
|
"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": "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",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"pl.plot_loss(trainer=trainer, metric='mean_loss', log_scale=True)"
|
|
]
|
|
},
|
|
{
|
|
"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",
|
|
"Nice you have completed the introductory tutorial of **PINA**! There are multiple 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 trainining and benchmark the speed\n",
|
|
"\n",
|
|
"4. Many more..."
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"interpreter": {
|
|
"hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49"
|
|
},
|
|
"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.9.7"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|