In den letzten Jahren haben Physically Informed Neural Networks (PINNs) zunehmend Aufmerksamkeit in der wissenschaftlichen Gemeinschaft erhalten. Dies liegt daran, dass sie physikalisches Vorwissen in maschinelle Lernmodelle integrieren, um die Vorhersagegenauigkeit und die generalisierbare Leistungsfähigkeit zu verbessern. In diesem Artikel geben wir eine Einführung in PINNs, erklären ihre Funktionsweise und stellen ein einfaches Beispiel in Python vor, das zeigt, wie man PINNs für die Lösung eines Differentialgleichungsproblems nutzen kann.
Was sind Physically Informed Neural Networks?
Physically Informed Neural Networks (PINNs) sind eine Erweiterung traditioneller neuronaler Netzwerke, die physikalische Gesetze in das Trainingsverfahren integrieren. Während klassische neuronale Netzwerke auf große Mengen an Daten angewiesen sind, kombinieren PINNs maschinelles Lernen mit physikalischen Gesetzen, wie z. B. partiellen Differentialgleichungen (PDEs). Dadurch können sie auch mit begrenzten Daten robuste Vorhersagen treffen, da die physikalischen Gesetzmäßigkeiten als regulierendes Element dienen.
Ein großer Vorteil von PINNs besteht darin, dass sie nicht nur zur Modellierung von datengetriebenen Phänomenen, sondern auch zur Lösung von Differentialgleichungen (PDEs und ODEs) verwendet werden können. Sie sind besonders nützlich für die Modellierung physikalischer Systeme, in denen analytische Lösungen schwierig zu finden sind oder numerische Methoden zu rechenintensiv sind.
Grundlagen von PINNs
Im Gegensatz zu herkömmlichen neuronalen Netzen wird bei PINNs der Verlust (Loss) nicht nur durch den Fehler zwischen den vorhergesagten und tatsächlichen Daten berechnet. Stattdessen wird eine zusätzliche Komponente in den Verlust integriert, die sicherstellt, dass die physikalischen Gesetze eingehalten werden. Diese physikalischen Gesetze werden in der Regel durch Differentialgleichungen beschrieben. Dadurch können PINNs Systeme modellieren, bei denen herkömmliche neuronale Netzwerke scheitern könnten.
Das Training eines PINNs erfordert also eine Modifikation der Verlustfunktion, sodass sie sowohl die Daten als auch die physikalischen Bedingungen (z.B. PDEs) berücksichtigt.
Die Standard-Form einer Verlustfunktion für ein PINN sieht folgendermaßen aus:
\( L_{data}(\Theta) \) : Der Verlust, der auf der Diskrepanz zwischen den beobachteten Daten und den Modellvorhersagen basiert (wie bei traditionellen neuronalen Netzen).\( L_{phy}(\Theta) \) : Der physikalisch informierte Verlust, der sicherstellt, dass das Modell die zugrunde liegenden physikalischen Gesetze respektiert.
Beispiel: Lösung der 1D Poisson-Gleichung
Als Beispiel lösen wir die Poisson-Gleichung, eine einfache partielle Differentialgleichung, mit einem PINN. Die Poisson-Gleichung in einer Dimension lautet:
Wir nehmen an, dass f(x)=sin(πx) und die Randbedingungen sind u(0)=u(1)=0.
Implementierung des PINN in Python
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# Definition der Randbedingungen und Quellterm
def f(x):
return np.sin(np.pi * x)
# PINN Klasse
class PINN(tf.keras.Model):
def __init__(self):
super(PINN, self).__init__()
self.hidden_layer_1 = tf.keras.layers.Dense(20, activation='tanh')
self.hidden_layer_2 = tf.keras.layers.Dense(20, activation='tanh')
self.hidden_layer_3 = tf.keras.layers.Dense(20, activation='tanh')
self.output_layer = tf.keras.layers.Dense(1, activation=None)
def call(self, x):
z = self.hidden_layer_1(x)
z = self.hidden_layer_2(z)
z = self.hidden_layer_3(z)
output = self.output_layer(z)
return output
# Loss Funktion für das PINN
def loss_pinn(model, x):
with tf.GradientTape(persistent=True) as tape1:
tape1.watch(x)
u = model(x)
du_dx = tape1.gradient(u, x)
with tf.GradientTape() as tape2:
tape2.watch(x)
du_dx = tape2.gradient(u, x)
d2u_dx2 = tape2.gradient(du_dx, x)
return tf.reduce_mean((d2u_dx2 + f(x))**2)
# Loss für die Randbedingungen
def loss_bc(model, x_bc):
u_bc = model(x_bc)
return tf.reduce_mean(u_bc**2)
# Gesamtverlust (PDE und Randbedingungen)
def total_loss(model, x, x_bc):
loss_pde = loss_pinn(model, x)
loss_boundary = loss_bc(model, x_bc)
return loss_pde + loss_boundary
# Training des Modells
def train(model, x_interior, x_boundary, epochs=1000, lr=0.001):
optimizer = tf.keras.optimizers.Adam(learning_rate=lr)
for epoch in range(epochs):
with tf.GradientTape() as tape:
loss = total_loss(model, x_interior, x_boundary)
grads = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(grads, model.trainable_variables))
if epoch % 100 == 0:
print(f'Epoch {epoch}: Loss = {loss.numpy()}')
# Domänen- und Randbedingungen vorbereiten
x_interior = np.linspace(0, 1, 100).reshape(-1, 1)
x_boundary = np.array([[0.0], [1.0]])
# Tensor-Konvertierung
x_interior_tf = tf.convert_to_tensor(x_interior, dtype=tf.float32)
x_boundary_tf = tf.convert_to_tensor(x_boundary, dtype=tf.float32)
# Modell initialisieren und trainieren
pinn_model = PINN()
train(pinn_model, x_interior_tf, x_boundary_tf, epochs=1000)
# Vorhersagen machen
x_test = np.linspace(0, 1, 100).reshape(-1, 1)
x_test_tf = tf.convert_to_tensor(x_test, dtype=tf.float32)
u_pred = pinn_model(x_test_tf)
# Visualisierung der Lösung
plt.plot(x_test, u_pred, label='PINN Lösung')
plt.xlabel('x')
plt.ylabel('u(x)')
plt.title('Lösung der Poisson-Gleichung mit einem PINN')
plt.legend()
plt.show()
Fazit
Physically Informed Neural Networks (PINNs) sind eine leistungsstarke Methode, um physikalische Systeme zu modellieren, indem sie physikalische Gesetze in neuronale Netze integrieren. PINNs bieten eine robuste Möglichkeit, komplexe Differentialgleichungen zu lösen, und können dabei helfen, die Genauigkeit und Effizienz numerischer Simulationen zu verbessern.
Durch das Hinzufügen physikalischer Gesetze zu den neuronalen Netzen können PINNs nicht nur auf datengetriebene Probleme angewendet werden, sondern auch auf physikalisch basierte Modelle. Ihr Einsatzbereich reicht von Ingenieurwissenschaften bis hin zur Naturwissenschaft und Medizin.