|
| 1 | +# Physics-Informed Neural Network (PINN) vs. Traditional Neural Network (ANN) |
| 2 | + |
| 3 | +## 📌 Introduction |
| 4 | + |
| 5 | +In this experiment, we compare **Physics-Informed Neural Networks (PINNs)** and **Artificial Neural Networks (ANNs)** for solving the **1D Heat Equation**: |
| 6 | + |
| 7 | +\[ |
| 8 | +\frac{\partial u}{\partial t} = \alpha \frac{\partial^2 u}{\partial x^2} |
| 9 | +\] |
| 10 | + |
| 11 | +where \( u(x, t) \) represents the heat distribution, and \( \alpha \) is the diffusion coefficient. |
| 12 | + |
| 13 | +### 🔹 What is PINN? |
| 14 | +PINNs use **both data and physics constraints** (e.g., differential equations) to improve learning. |
| 15 | + |
| 16 | +### 🔹 What is ANN? |
| 17 | +A traditional ANN learns purely from **data without any physics knowledge**. |
| 18 | + |
| 19 | +### 📌 Goal |
| 20 | +- Train both **PINN and ANN** on noisy data. |
| 21 | +- Compare their ability to **recover the underlying solution**. |
| 22 | + |
| 23 | +--- |
| 24 | +## 📌 Implementation |
| 25 | + |
| 26 | +### 🔹 **Step 1: Define PINN and ANN Models** |
| 27 | + |
| 28 | +```python |
| 29 | +import torch |
| 30 | +import torch.nn as nn |
| 31 | +import torch.optim as optim |
| 32 | +import numpy as np |
| 33 | +import matplotlib.pyplot as plt |
| 34 | + |
| 35 | +# Define the PINN network |
| 36 | +class PINN(nn.Module): |
| 37 | + def __init__(self): |
| 38 | + super(PINN, self).__init__() |
| 39 | + self.net = nn.Sequential( |
| 40 | + nn.Linear(2, 32), nn.Tanh(), |
| 41 | + nn.Linear(32, 32), nn.Tanh(), |
| 42 | + nn.Linear(32, 32), nn.Tanh(), |
| 43 | + nn.Linear(32, 1) |
| 44 | + ) |
| 45 | + |
| 46 | + def forward(self, x, t): |
| 47 | + input_tensor = torch.cat((x, t), dim=1) |
| 48 | + return self.net(input_tensor) |
| 49 | + |
| 50 | +# Define the traditional ANN network |
| 51 | +class ANN(nn.Module): |
| 52 | + def __init__(self): |
| 53 | + super(ANN, self).__init__() |
| 54 | + self.net = nn.Sequential( |
| 55 | + nn.Linear(2, 32), nn.ReLU(), |
| 56 | + nn.Linear(32, 32), nn.ReLU(), |
| 57 | + nn.Linear(32, 32), nn.ReLU(), |
| 58 | + nn.Linear(32, 1) |
| 59 | + ) |
| 60 | + |
| 61 | + def forward(self, x, t): |
| 62 | + input_tensor = torch.cat((x, t), dim=1) |
| 63 | + return self.net(input_tensor) |
| 64 | +``` |
| 65 | + |
| 66 | +--- |
| 67 | +### 🔹 **Step 2: Define the Physics Loss for PINN** |
| 68 | +```python |
| 69 | +def physics_loss(model, x, t, alpha=0.01): |
| 70 | + x.requires_grad = True |
| 71 | + t.requires_grad = True |
| 72 | + |
| 73 | + u = model(x, t) |
| 74 | + u_t = torch.autograd.grad(u, t, grad_outputs=torch.ones_like(u), create_graph=True)[0] |
| 75 | + u_x = torch.autograd.grad(u, x, grad_outputs=torch.ones_like(u), create_graph=True)[0] |
| 76 | + u_xx = torch.autograd.grad(u_x, x, grad_outputs=torch.ones_like(u_x), create_graph=True)[0] |
| 77 | + |
| 78 | + residual = u_t - alpha * u_xx # Heat equation residual |
| 79 | + return torch.mean(residual**2) |
| 80 | +``` |
| 81 | + |
| 82 | +--- |
| 83 | +### 🔹 **Step 3: Generate Noisy Training Data** |
| 84 | +```python |
| 85 | +N = 1000 # Number of training points |
| 86 | +x_train = torch.rand((N, 1)) * 2 - 1 # x in [-1, 1] |
| 87 | +t_train = torch.rand((N, 1)) * 2 - 1 # t in [-1, 1] |
| 88 | + |
| 89 | +noise_level = 0.1 |
| 90 | +u_exact = torch.sin(torch.pi * x_train) # True function |
| 91 | +u_noisy = u_exact + noise_level * torch.randn_like(u_exact) # Noisy data |
| 92 | +``` |
| 93 | + |
| 94 | +--- |
| 95 | +### 🔹 **Step 4: Train Both Models** |
| 96 | +```python |
| 97 | +pinn_model = PINN() |
| 98 | +ann_model = ANN() |
| 99 | +optimizer_pinn = optim.Adam(pinn_model.parameters(), lr=0.01) |
| 100 | +optimizer_ann = optim.Adam(ann_model.parameters(), lr=0.01) |
| 101 | + |
| 102 | +epochs = 5000 |
| 103 | +for epoch in range(epochs): |
| 104 | + optimizer_pinn.zero_grad() |
| 105 | + u_pred = pinn_model(x_train, torch.zeros_like(t_train)) |
| 106 | + loss_data = torch.mean((u_pred - u_noisy) ** 2) |
| 107 | + loss_physics = physics_loss(pinn_model, x_train, t_train) |
| 108 | + loss = loss_data + loss_physics |
| 109 | + loss.backward() |
| 110 | + optimizer_pinn.step() |
| 111 | + |
| 112 | + optimizer_ann.zero_grad() |
| 113 | + u_ann_pred = ann_model(x_train, torch.zeros_like(t_train)) |
| 114 | + loss_ann = torch.mean((u_ann_pred - u_noisy) ** 2) |
| 115 | + loss_ann.backward() |
| 116 | + optimizer_ann.step() |
| 117 | + |
| 118 | + if epoch % 500 == 0: |
| 119 | + print(f"Epoch {epoch}, PINN Loss: {loss.item():.6f}, ANN Loss: {loss_ann.item():.6f}") |
| 120 | +``` |
| 121 | + |
| 122 | +--- |
| 123 | +### 🔹 **Step 5: Visualizing Results** |
| 124 | +```python |
| 125 | +x_test = torch.linspace(-1, 1, 100).view(-1, 1) |
| 126 | +t_test = torch.zeros_like(x_test) |
| 127 | + |
| 128 | +u_true = torch.sin(torch.pi * x_test).detach().numpy() |
| 129 | +u_noisy_sample = u_noisy[:100].detach().numpy() |
| 130 | +u_pinn_pred = pinn_model(x_test, t_test).detach().numpy() |
| 131 | +u_ann_pred = ann_model(x_test, t_test).detach().numpy() |
| 132 | + |
| 133 | +plt.figure(figsize=(10, 5)) |
| 134 | +plt.plot(x_test, u_true, label="True Solution", linestyle="dashed", color="blue") |
| 135 | +plt.scatter(x_train[:100], u_noisy_sample, label="Noisy Data", color="gray", alpha=0.5) |
| 136 | +plt.plot(x_test, u_pinn_pred, label="PINN Prediction", color="red") |
| 137 | +plt.plot(x_test, u_ann_pred, label="ANN Prediction", color="green") |
| 138 | +plt.xlabel("x") |
| 139 | +plt.ylabel("u(x, 0)") |
| 140 | +plt.title("Comparison of PINN, ANN, and Noisy Data") |
| 141 | +plt.legend() |
| 142 | +plt.grid() |
| 143 | +plt.show() |
| 144 | +``` |
| 145 | + |
| 146 | +--- |
| 147 | +## 📌 Results and Observations |
| 148 | +✅ **PINN learns a smooth solution**, despite noisy data. |
| 149 | +✅ **ANN overfits noise**, failing to recover the true function. |
| 150 | +✅ **PINN generalizes better**, as it incorporates physical laws. |
| 151 | + |
| 152 | +| Model | Uses Physics? | Handles Noisy Data? | Generalization | |
| 153 | +|--------|--------------|----------------|--------------| |
| 154 | +| **PINN** | ✅ Yes | ✅ Robust | ✅ Excellent | |
| 155 | +| **ANN** | ❌ No | ❌ Overfits | ❌ Poor | |
| 156 | + |
| 157 | +--- |
| 158 | +## 📌 Future Work |
| 159 | +✅ Extend PINN to **2D Heat Equation** |
| 160 | +✅ Apply PINNs to **Navier-Stokes (fluid dynamics)** |
| 161 | +✅ Experiment with **real-world physics problems** |
| 162 | + |
| 163 | + |
0 commit comments