163
tutorials/tutorial7/tutorial.ipynb
vendored
163
tutorials/tutorial7/tutorial.ipynb
vendored
@@ -5,47 +5,34 @@
|
||||
"id": "dbbb73cb-a632-4056-bbca-b483b2ad5f9c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Tutorial: Resolution of an inverse problem\n",
|
||||
"# Tutorial: Inverse Problem Solving with Physics-Informed Neural Network\n",
|
||||
"\n",
|
||||
"[](https://colab.research.google.com/github/mathLab/PINA/blob/master/tutorials/tutorial7/tutorial.ipynb)\n",
|
||||
"\n",
|
||||
"## Introduction to the Inverse Problem\n",
|
||||
"\n",
|
||||
"This tutorial demonstrates how to solve an inverse Poisson problem using Physics-Informed Neural Networks (PINNs).\n",
|
||||
"\n",
|
||||
"The problem is defined as a Poisson equation with homogeneous boundary conditions:\n",
|
||||
"\n",
|
||||
"[](https://colab.research.google.com/github/mathLab/PINA/blob/master/tutorials/tutorial7/tutorial.ipynb)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "84508f26-1ba6-4b59-926b-3e340d632a15",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Introduction to the inverse problem"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cae54664-4572-49df-8b2d-9e7dd1e45ec0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This tutorial shows how to solve an inverse Poisson problem with Physics-Informed Neural Networks. The problem definition is that of a Poisson problem with homogeneous boundary conditions and it reads:\n",
|
||||
"\\begin{equation}\n",
|
||||
"\\begin{cases}\n",
|
||||
"\\Delta u = e^{-2(x-\\mu_1)^2-2(y-\\mu_2)^2} \\text{ in } \\Omega\\, ,\\\\\n",
|
||||
"u = 0 \\text{ on }\\partial \\Omega,\\\\\n",
|
||||
"u(\\mu_1, \\mu_2) = \\text{ data}\n",
|
||||
"\\Delta u = e^{-2(x - \\mu_1)^2 - 2(y - \\mu_2)^2} \\quad \\text{in } \\Omega, \\\\\n",
|
||||
"u = 0 \\quad \\text{on } \\partial \\Omega, \\\\\n",
|
||||
"u(\\mu_1, \\mu_2) = \\text{data}\n",
|
||||
"\\end{cases}\n",
|
||||
"\\end{equation}\n",
|
||||
"where $\\Omega$ is a square domain $[-2, 2] \\times [-2, 2]$, and $\\partial \\Omega=\\Gamma_1 \\cup \\Gamma_2 \\cup \\Gamma_3 \\cup \\Gamma_4$ is the union of the boundaries of the domain.\n",
|
||||
"\n",
|
||||
"This kind of problem, namely the \"inverse problem\", has two main goals:\n",
|
||||
"- find the solution $u$ that satisfies the Poisson equation;\n",
|
||||
"- find the unknown parameters ($\\mu_1$, $\\mu_2$) that better fit some given data (third equation in the system above).\n",
|
||||
"Here, $\\Omega$ is the square domain $[-2, 2] \\times [-2, 2]$, and $\\partial \\Omega = \\Gamma_1 \\cup \\Gamma_2 \\cup \\Gamma_3 \\cup \\Gamma_4$ represents the union of its boundaries.\n",
|
||||
"\n",
|
||||
"In order to achieve both goals we will need to define an `InverseProblem` in PINA."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c1f8cb1b-c1bc-4495-96e2-ce8e9102fe56",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let's start with useful imports."
|
||||
"This type of setup defines an *inverse problem*, which has two primary objectives:\n",
|
||||
"\n",
|
||||
"- **Find the solution** $u$ that satisfies the Poisson equation,\n",
|
||||
"- **Identify the unknown parameters** $(\\mu_1, \\mu_2)$ that best fit the given data (as described by the third equation in the system).\n",
|
||||
"\n",
|
||||
"To tackle both objectives, we will define an `InverseProblem` using **PINA**.\n",
|
||||
"\n",
|
||||
"Let's begin with the necessary imports:\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -67,7 +54,7 @@
|
||||
"883"
|
||||
]
|
||||
},
|
||||
"execution_count": 20,
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -81,7 +68,7 @@
|
||||
"except:\n",
|
||||
" IN_COLAB = False\n",
|
||||
"if IN_COLAB:\n",
|
||||
" !pip install \"pina-mathlab\"\n",
|
||||
" !pip install \"pina-mathlab[tutorial]\"\n",
|
||||
" # get the data\n",
|
||||
" !mkdir \"data\"\n",
|
||||
" !wget \"https://github.com/mathLab/PINA/raw/refs/heads/master/tutorials/tutorial7/data/pinn_solution_0.5_0.5\" -O \"data/pinn_solution_0.5_0.5\"\n",
|
||||
@@ -91,6 +78,9 @@
|
||||
"import torch\n",
|
||||
"import warnings\n",
|
||||
"\n",
|
||||
"from lightning.pytorch import seed_everything\n",
|
||||
"from lightning.pytorch.callbacks import Callback\n",
|
||||
"\n",
|
||||
"from pina import Condition, Trainer\n",
|
||||
"from pina.problem import SpatialProblem, InverseProblem\n",
|
||||
"from pina.operator import laplacian\n",
|
||||
@@ -99,8 +89,6 @@
|
||||
"from pina.solver import PINN\n",
|
||||
"from pina.domain import CartesianDomain\n",
|
||||
"from pina.optim import TorchOptimizer\n",
|
||||
"from lightning.pytorch import seed_everything\n",
|
||||
"from lightning.pytorch.callbacks import Callback\n",
|
||||
"\n",
|
||||
"warnings.filterwarnings(\"ignore\")\n",
|
||||
"seed_everything(883)"
|
||||
@@ -111,12 +99,20 @@
|
||||
"id": "5138afdf-bff6-46bf-b423-a22673190687",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Then, we import the pre-saved data, for ($\\mu_1$, $\\mu_2$)=($0.5$, $0.5$). These two values are the optimal parameters that we want to find through the neural network training. In particular, we import the `input` points (the spatial coordinates), and the `target` points (the corresponding $u$ values evaluated at the `input`)."
|
||||
"Next, we import the pre-saved data corresponding to the true parameter values $(\\mu_1, \\mu_2) = (0.5, 0.5)$. \n",
|
||||
"These values represent the *optimal parameters* that we aim to recover through neural network training.\n",
|
||||
"\n",
|
||||
"In particular, we load:\n",
|
||||
"\n",
|
||||
"- `input` points — the spatial coordinates where observations are available,\n",
|
||||
"- `target` points — the corresponding $u$ values (i.e., the solution evaluated at the `input` points).\n",
|
||||
"\n",
|
||||
"This data will be used to guide the inverse problem and supervise the network’s prediction of the unknown parameters."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"execution_count": 11,
|
||||
"id": "2c55d972-09a9-41de-9400-ba051c28cdcb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -132,12 +128,17 @@
|
||||
"id": "6541ffbe-7940-421a-9048-a796ec56f1d6",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Moreover, let's plot also the data points and the reference solution: this is the expected output of the neural network."
|
||||
"Next, let's visualize the data:\n",
|
||||
"\n",
|
||||
"- We'll plot the data points, i.e., the spatial coordinates where measurements are available.\n",
|
||||
"- We'll also display the reference solution corresponding to $(\\mu_1, \\mu_2) = (0.5, 0.5)$.\n",
|
||||
"\n",
|
||||
"This serves as the ground truth or expected output that our neural network should learn to approximate through training."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"execution_count": 12,
|
||||
"id": "55cef553-7495-401d-9d17-1acff8ec5953",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -167,20 +168,17 @@
|
||||
"id": "de7c4c83",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Inverse problem definition in PINA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c46410fa-2718-4fc9-977a-583fe2390028",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Then, we initialize the Poisson problem, that is inherited from the `SpatialProblem` and from the `InverseProblem` classes. We here have to define all the variables, and the domain where our unknown parameters ($\\mu_1$, $\\mu_2$) belong. Notice that the Laplace equation takes as inputs also the unknown variables, that will be treated as parameters that the neural network optimizes during the training process."
|
||||
"## Inverse Problem Definition in PINA\n",
|
||||
"\n",
|
||||
"Next, we initialize the Poisson problem, which inherits from the `SpatialProblem` and `InverseProblem` classes. \n",
|
||||
"In this step, we need to define all the variables and specify the domain in which our unknown parameters $(\\mu_1, \\mu_2)$ reside.\n",
|
||||
"\n",
|
||||
"Note that the Laplace equation also takes these unknown parameters as inputs. These parameters will be treated as variables that the neural network will optimize during the training process, enabling it to learn the optimal values for $(\\mu_1, \\mu_2)$."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"execution_count": 13,
|
||||
"id": "8ec0d95d-72c2-40a4-a310-21c3d6fe17d2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -204,11 +202,6 @@
|
||||
"\n",
|
||||
"\n",
|
||||
"class Poisson(SpatialProblem, InverseProblem):\n",
|
||||
" r\"\"\"\n",
|
||||
" Implementation of the inverse 2-dimensional Poisson problem in the square\n",
|
||||
" domain :math:`[0, 1] \\times [0, 1]`,\n",
|
||||
" with unknown parameter domain :math:`[-1, 1] \\times [-1, 1]`.\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" output_variables = [\"u\"]\n",
|
||||
" x_min, x_max = -2, 2\n",
|
||||
@@ -242,12 +235,12 @@
|
||||
"id": "6b264569-57b3-458d-bb69-8e94fe89017d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Then, we define the neural network model we want to use. Here we used a model which imposes hard constrains on the boundary conditions, as also done in the Wave tutorial!"
|
||||
"Next, we define the neural network model that will be used for solving the inverse problem. In this case, we use a simple FeedForeard model, but you could build one that imposes *hard constraints* on the boundary conditions, similar to the approach used in the [Wave tutorial](https://mathlab.github.io/PINA/tutorial3/tutorial.html) to have better performances!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"execution_count": 14,
|
||||
"id": "c4170514-eb73-488e-8942-0129070e4e13",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -270,7 +263,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"execution_count": 15,
|
||||
"id": "e3e0ae40-d8c6-4c08-81e8-85adc60a94e6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -288,19 +281,21 @@
|
||||
"id": "b272796a-888c-4795-9d88-3e13121e8f38",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Here, we define a simple callback for the trainer. We use this callback to save the parameters predicted by the neural network during the training. The parameters are saved every 100 epochs as `torch` tensors in a specified directory (`tmp_dir` in our case).\n",
|
||||
"The goal is to read the saved parameters after training and plot their trend across the epochs."
|
||||
"Here, we define a simple callback for the trainer. This callback is used to save the parameters predicted by the neural network during training. \n",
|
||||
"The parameters are saved every 100 epochs as `torch` tensors in a specified directory (in our case, `tutorial_logs`).\n",
|
||||
"\n",
|
||||
"The goal of this setup is to read the saved parameters after training and visualize their trend across the epochs. This allows us to monitor how the predicted parameters evolve throughout the training process.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 26,
|
||||
"execution_count": 16,
|
||||
"id": "e1409953-eb1b-443b-923d-c7ec3af0dfb0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# temporary directory for saving logs of training\n",
|
||||
"tmp_dir = \"tmp_poisson_inverse\"\n",
|
||||
"tmp_dir = \"tutorial_logs\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class SaveParameters(Callback):\n",
|
||||
@@ -321,12 +316,12 @@
|
||||
"id": "fc6e0030-f6ae-40cf-a3b3-d21d6538e7f2",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Then, we define the `PINN` object and train the solver using the `Trainer`."
|
||||
"Then, we define the `PINN` object and train the solver using the `Trainer`"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"execution_count": 17,
|
||||
"id": "05a0f311-3cca-429b-be2c-1fa899b14e62",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -340,11 +335,18 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Epoch 1499: 100%|██████████| 1/1 [00:00<00:00, 68.34it/s, v_num=2, g1_loss=0.000142, g2_loss=3.78e-5, g3_loss=0.000105, g4_loss=3.2e-5, D_loss=0.000561, data_loss=2.71e-5, train_loss=0.000906] "
|
||||
]
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "ca3282f5c0654d9d8d4335107e7254e1",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Training: | | 0/? [00:00<?, ?it/s]"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
@@ -352,13 +354,6 @@
|
||||
"text": [
|
||||
"`Trainer.fit` stopped: `max_epochs=1500` reached.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Epoch 1499: 100%|██████████| 1/1 [00:00<00:00, 54.70it/s, v_num=2, g1_loss=0.000142, g2_loss=3.78e-5, g3_loss=0.000105, g4_loss=3.2e-5, D_loss=0.000561, data_loss=2.71e-5, train_loss=0.000906]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
@@ -433,15 +428,17 @@
|
||||
"id": "f1fa4406",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## What's next?\n",
|
||||
"## What's Next?\n",
|
||||
"\n",
|
||||
"We have shown the basic usage PINNs in inverse problem modelling, further extensions include:\n",
|
||||
"We have covered the basic usage of PINNs for inverse problem modeling. Here are some possible directions for further exploration:\n",
|
||||
"\n",
|
||||
"1. Train using different Physics Informed strategies\n",
|
||||
"1. **Experiment with different Physics-Informed strategies**: Explore variations in PINN training techniques to improve performance or tackle different types of problems.\n",
|
||||
"\n",
|
||||
"2. Try on more complex problems\n",
|
||||
"2. **Apply to more complex problems**: Scale the approach to higher-dimensional or time-dependent inverse problems.\n",
|
||||
"\n",
|
||||
"3. Many more..."
|
||||
"3. **...and many more!**: The possibilities are endless, from integrating additional physical constraints to testing on real-world datasets.\n",
|
||||
"\n",
|
||||
"For more resources and tutorials, check out the [PINA Documentation](https://mathlab.github.io/PINA/)."
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user