Как получить единое решение из нейронной сети, основанной на физике (PINN) для УЧП с начальными и граничными условиями?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как получить единое решение из нейронной сети, основанной на физике (PINN) для УЧП с начальными и граничными условиями?

Сообщение Anonymous »

Я работаю с нейронной сетью, основанной на физике (PINN), для решения системы уравнений в частных производных (PDE). Модель предназначена для прогнозирования как реальной, так и мнимой частей решения, но после обучения я получаю несколько значений вместо одного решения. Я не знаю, как извлечь из модели единственное решение с учетом начальных и граничных условий.
Моя настройка
  • < li>Модель: сеть выводит два компонента — действительную и мнимую части решения.
  • Функция потерь: Функция потерь равна на основе остатков PDE, и я включаю как начальные, так и граничные условия в модель.
  • Цикл обучения. После обучения мне нужно получить одно решение для каждого входного параметра с учетом начальных и граничных условий.
    Проблема Я сталкиваюсь с тем, что вместо того, чтобы получить одно решение, я получаю несколько значений в каждой точке. Это происходит даже тогда, когда я применяю граничные и начальные условия. Я не уверен в подходе к получению единственного решения (т. е. уникальной пары действительных и мнимых частей) из сети после обучения.
Вывод что я получаю
Реальную часть решения:

[-0.06334841 -0.062509 -0.06163921 -0.06073928 -0.05980941 -0.05884991
-0.05786142 -0.05684437 -0.0557996 -0.05472792 -0.05363033 -0.052508
-0.05136216 -0.05019434 -0.04900604 -0.04779914 -0.04657538 -0.04533695
-0.04408599 -0.04282483 -0.04155596 -0.04028207 -0.03900566 -0.03772958
-0.03645669 -0.03518973 -0.03393145 -0.03268468 -0.0314519 -0.03023547
-0.02903758 -0.0278598 -0.02670354 -0.02556948 -0.02445777 -0.0233678
-0.02229816 -0.02124669 -0.02021031 -0.01918506 -0.01816619 -0.01714829
-0.01612531 -0.01509104 -0.01403899 -0.01296301 -0.0118577 -0.01071849
-0.00954226 -0.00832763 -0.00707515 -0.00578765 -0.00447029 -0,00313038
-0,00177728 -0,00042213 0,00092289 0,00224471 0,00353035 0,00476716
0,0059436 0,00704944 0,00807618 0.00901716 0.00986777 0.01062508
0.01128795 0.01185676 0.01233314 0.01271974 0.01302004 0.01323804
0.01337828 0.01344543 0.01344434 0.01338004 0.01325734 0.01308119
0.0128563 0.01258733 0.01227872 0.01193491 0.01156 0.011158
0.01073269 0.01028769 0.00982638 0.00935204 0.00886751 0.00837567
0.00787903 0.00737998 0.00688063 0.0063829 0.00588859 0.00539917
0.00491606 0.00444037 0.00397322 0.00351539]

Мнимая часть решения:

[ 0.00741371 0.00815623 0.00891515 0.00969044 0.01048192 0.01128931
0.01211199 0.01294932 0.01380036 0.01466383 0.01553827 0.01642179
0.01731227 0.01820713 0.01910323 0.01999709 0.02088475 0.02176158
0.02262247 0.02346156 0.0242725 0.02504807 0.0257806 0.02646159
0.02708185 0.02763153 0.02810027 0.02847715 0.02875073 0.0289094
...
0.00787903-0.12341416j 0.00737998-0.12441608j 0.00688063-0.12536152j
0.0063829 -0.12625429j 0.00588859-0.12709787j 0.00539917-0.12789568j
0.00491606-0.1286508j 0.00444037-0.1293662j 0.00397322-0.13004452j
0.00351539-0.13068835j]

Мой код

Код: Выделить всё

import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

def sech(x):
return 2 / (torch.exp(x) + torch.exp(-x))

class PINN(nn.Module):
def __init__(self, layers):
super(PINN, self).__init__()
self.layers = nn.ModuleList()
for i in range(len(layers) - 1):
self.layers.append(nn.Linear(layers[i], layers[i + 1]))
self.activation = torch.tanh

def forward(self, x):
for i, layer in enumerate(self.layers):
x = layer(x)
if i <  len(self.layers) - 1:
x = self.activation(x)
return x

# Initial condition
def initial_condition(x, A=1.0, k=1.0, x0=0.0, omega=0.0):
q_real = A * sech(k * (x - x0)) * torch.cos(omega * x)
q_imag = A * sech(k * (x - x0)) * torch.sin(omega * x)
return q_real, q_imag

# Boundary condition
def boundary_condition(t, A=0.0):
u_bc = torch.full_like(t, A)  # Real part at boundary
v_bc = torch.full_like(t, A)  # Imaginary part at boundary
return u_bc, v_bc

# Model definition
layers = [2, 50, 50, 50, 2]  # 2 outputs for real and imaginary parts
model = PINN(layers).to(device)

# Loss function for PINN (based on the PDE residual)
def pde_loss(x, t):
# Ensure x has requires_grad=True
x.requires_grad = True
t.requires_grad = True  # Ensure t has requires_grad=True as well

# Forward pass: Get the model predictions (real and imaginary parts)
q_pred = model(torch.cat([x, t], dim=-1))  # Forward pass

u_pred = q_pred[:, 0]  # Real part (first column)
v_pred = q_pred[:, 1]  # Imaginary part (second column)

# Calculate second derivatives (u_xx and v_xx)
u_xx = torch.autograd.grad(u_pred, x, grad_outputs=torch.ones_like(u_pred), create_graph=True)[0]
v_xx = torch.autograd.grad(v_pred, x, grad_outputs=torch.ones_like(v_pred), create_graph=True)[0]

# Calculate time derivatives (u_t and v_t)
u_t = torch.autograd.grad(u_pred, t, grad_outputs=torch.ones_like(u_pred), create_graph=True)[0]
v_t = torch.autograd.grad(v_pred, t, grad_outputs=torch.ones_like(v_pred), create_graph=True)[0]

u_abs_sq = u_pred**2 + v_pred**2
v_abs_sq = u_pred**2 + v_pred**2

# Define the PDE residuals
f_r = u_t - 0.5 * u_xx - u_abs_sq * u_pred - v_abs_sq * u_pred
f_i = v_t + 0.5 * v_xx + u_abs_sq * v_pred + v_abs_sq * v_pred

# Compute the loss as the sum of squared residuals
loss = torch.mean(f_r**2 + f_i**2)
return loss

# Test metric (Mean Squared Error)
def test_metric(q_pred, q_true):
return torch.mean((q_pred - q_true)**2)

# Optimizer
optimizer = optim.Adam(model.parameters(), lr=0.0001)

# Training loop
n_iterations = 1000
train_losses = []
test_losses = []
test_metrics = []

for iterations in range(n_iterations):
# Define x and t for the initial and boundary conditions
x = torch.linspace(-5, 5, 100).reshape(-1, 1).to(device)
t = torch.linspace(0, 10, 100).reshape(-1, 1).to(device)

# Apply initial and boundary conditions
u_init, v_init = initial_condition(x)
u_bc, v_bc = boundary_condition(t)

optimizer.zero_grad()

# Compute the PDE loss (Train loss)
loss = pde_loss(x, t)

# Backpropagation
loss.backward()
optimizer.step()

train_losses.append(loss.item())

# Every 100 iterations, print the training loss
if iterations % 100 == 0:
print(f"iterations {iterations}, Train Loss: {loss.item()}")

# Evaluate on test data (at multiple x values, for example)
if iterations % 100 == 0:
x_test = torch.linspace(-5, 5, 100).reshape(-1, 1).to(device)  # Test points over the domain
t_test = torch.zeros_like(x_test).to(device)  # Test at t = 0

q_pred = model(torch.cat([x_test, t_test], dim=-1))  # Model output
q_real_pred, q_imag_pred = q_pred[:, 0], q_pred[:, 1]
q_pred_full = q_real_pred + 1j * q_imag_pred  # Complex solution

# Create the true solution (use exact solution for the test points)
q_real_true, q_imag_true = initial_condition(x_test.cpu())  # Compute on CPU, since we are using CPU tensors here
q_true_full = torch.stack([q_real_true, q_imag_true], dim=1).to(device)  # Stack and move to device

# Calculate test loss
test_loss = pde_loss(x_test, t_test).item()
test_losses.append(test_loss)

# Calculate test metric (Mean Squared Error)
test_metric_val = test_metric(q_pred_full, q_true_full).item()
test_metrics.append(test_metric_val)

# Print test metric (MSE)
print(f"iterations {iterations}, Test MSE:  {test_metric_val:.6f}")

Мой вопрос
Как я могу гарантировать, что модель дает единственное уникальное решение как для действительной, так и для мнимой частей после рассмотрения начальной и граничной частей? условиях?
Есть ли какие-либо конкретные корректировки в процедуре обучения или архитектуре модели, которые помогли бы достичь согласованного решения только с одной реальной и одной мнимой частью, а не с несколькими значениями в каждой точке?< /p>
Любая помощь или идеи о том, как обеспечить Мы будем очень признательны за единое решение для обеих частей!

Подробнее здесь: https://stackoverflow.com/questions/793 ... pinn-for-a
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как получить единственное решение из нейронной сети, основанной на физике (PINN) для УЧП с начальными и граничными услов
    Anonymous » » в форуме Python
    0 Ответы
    32 Просмотры
    Последнее сообщение Anonymous
  • Оптимизация нейронной сети, основанной на физике
    Anonymous » » в форуме Python
    0 Ответы
    17 Просмотры
    Последнее сообщение Anonymous
  • Оптимизация нейронной сети, основанной на физике
    Anonymous » » в форуме Python
    0 Ответы
    19 Просмотры
    Последнее сообщение Anonymous
  • Оптимизация нейронной сети, основанной на физике
    Anonymous » » в форуме Python
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous
  • Решение нелинейной системы ОДУ с граничными условиями на Python
    Anonymous » » в форуме Python
    0 Ответы
    31 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»