Es ist sehr neu, aber ich zeige Ihnen, wie Sie die Implementierungsbibliothek für neuronale ODE verwenden. Neural ODE ist übrigens das beste Papier von NeuroIPS 2018.
Die offiziellen Autoren der Neuronalen ODE haben eine Bibliothek offizieller Repositories mit dem Namen [torchdiffeq] veröffentlicht (https://github.com/rtqichen/torchdiffeq).
Obwohl Neural ODE viele Artikel enthält, die die Theorie und Interpretation erklären, dachte ich, dass es nur wenige japanische Artikel gibt, die die tatsächliche Verwendung dieser Bibliothek beschreiben, und fasste die grundlegende Verwendung in diesem Artikel zusammen. Torchdiffeq ist übrigens eine Bibliothek für PyTorch.
Wenn Sie diesen Artikel lesen, können Sie:
--Torchdiffeq kann das Anfangswertproblem der gewöhnlichen Differentialgleichung erster Ordnung lösen --Torchdiffeq kann das Anfangswertproblem der gewöhnlichen Differentialgleichung zweiter Ordnung lösen
Ich werde die erforderlichen Kenntnisse für die Verwendung von torchdiffeq überprüfen.
Von den Differentialgleichungen wird diejenige mit im wesentlichen nur einer unbekannten Variablen als normale Differentialgleichung bezeichnet. Beispielsweise haben Differentialgleichungen wie $ \ frac {dz} {dt} = f (z (t), t) $ und $ m \ ddot {x} = -kx $ mehrere Variablen, aber $ Da z $ und $ x $ Funktionen von $ t $ sind, gibt es im Wesentlichen nur eine unbekannte Variable, $ t $, und es kann gesagt werden, dass es sich um eine normale Differentialgleichung handelt.
Es gibt viele andere leicht verständliche Artikel über neuronale ODE. Bitte lesen Sie sie.
Um den Umriss kurz zu erläutern, kann man von neuronaler ODE als "neuronales Netzwerk mit kontinuierlichen Schichten" sprechen.
Es gibt eine Theorie, dass es schwierig ist, das Konzept zu verstehen, weil es ein Wort "normale Differentialgleichung" gibt, das im neuronalen Netzbereich nicht zu hören ist, aber ich denke, dass der wichtige Punkt darin besteht, dass "Schichten kontinuierlich sind". .. Dies ermöglicht es beispielsweise, "die Ausgabe der 0,5-ten Schicht herauszunehmen", was mit dem herkömmlichen Modell nicht möglich war.
Referenzlink unten:
Nun wollen wir sehen, wie man torchdiffeq benutzt.
Führen Sie zum Installieren den folgenden Befehl aus.
pip install torchdiffeq
Bevor wir mit der Implementierung der neuronalen ODE beginnen, nehmen wir als Beispiel eine einfache gewöhnliche Differentialgleichung erster Ordnung, um zu sehen, wie Torchdiffeq einfach verwendet werden kann.
Betrachten Sie die folgende Gleichung Differentialgleichung.
Diese Lösung verwendet $ C $ als Integrationskonstante
Da $ z (0) = 0 $ ist, können wir sehen, dass die Lösung dieser Differentialgleichung wie folgt ist.
Die einfachste Implementierung zur Lösung dieses Problems mit torchdiffeq finden Sie unten.
first_order.py
from torchdiffeq import odeint
def func(t, z):
return t
z0 = torch.Tensor([0])
t = torch.linspace(0,2,100)
out = odeint(func, z0, t)
Unten sind die Punkte aufgelistet.
func
entspricht $ f $ der obigen Differentialgleichung $ \ frac {dz} {dt} = f (t, z) $. Die Argumente sind in der Reihenfolge "(t, z)". Die Abmessungen der Ausgabe müssen mit "z" übereinstimmen. Sie müssen weder z noch t
verwenden.――Es ist zu beachten, dass das Element von t eine Spalte sein muss, die im engeren Sinne zunimmt (abnimmt). Ein Fehler tritt auch dann auf, wenn derselbe Wert enthalten ist, z. B. "t = Tensor ([0, 0, 1])".
Zeichnen Sie die obigen Ergebnisse.
from matplotlib.pyplot as plt
plt.plot(t, out)
plt.axes().set_aspect('equal', 'datalim') #Seitenverhältnis 1:Auf 1 setzen
plt.grid()
plt.xlim(0,2)
plt.show()
Sie können sehen, dass es mit der Lösung $ z = \ frac {t ^ 2} {2} $ der durch Handberechnung erhaltenen Differentialgleichung übereinstimmt.
Wenn Sie torchdiffeq verwenden, können Sie auch die Differentialgleichung zweiter Ordnung lösen. Als Beispiel lösen wir die (?) Einfache Schwingungsdifferentialgleichung, die der Wissenschaft mit torchdiffeq vertraut ist. Die Differentialgleichung der einfachen Schwingung lautet wie folgt.
Hier ist $ \ boldsymbol {y} = \ left [
\begin{array}{c}
x \
\dot{x} \
\end{array}
Wenn Sie \ right] $ setzen, führt diese Differentialgleichung zweiter Ordnung zu der folgenden Differentialgleichung erster Ordnung.
Die Implementierung ist wie folgt. $ k = 1, m = 1 $.
oscillation.py
class Oscillation:
def __init__(self, km):
self.mat = torch.Tensor([[0, 1],
[-km, 0]])
def solve(self, t, x0, dx0):
y0 = torch.cat([x0, dx0])
out = odeint(self.func, y0, t)
return out
def func(self, t, y):
# print(t)
out = y @ self.mat # @Ist das Matrixprodukt
return out
if __name__=="__main__":
x0 = torch.Tensor([1])
dx0 = torch.Tensor([0])
import numpy as np
t = torch.linspace(0, 4 * np.pi, 1000)
solver = Oscillation(1)
out = solver.solve(t, x0, dx0)
Wenn Sie es zeichnen, können Sie sehen, dass die Lösung der einfachen Vibration richtig erhalten wird.
Nachdem Sie nun mit der Verwendung von torchdiffeq vertraut sind, wollen wir sehen, wie ODE Block tatsächlich implementiert wird. Der ODE-Block ist ein Modul, das die Dynamik von $ \ frac {dz} {dt} = f (t, z) $ bildet. Die eigentliche neuronale ODE wird unter Verwendung des ODE-Blocks zusammen mit der normalen Full-Connect-Schicht und der Faltungsschicht konstruiert.
Die folgende Implementierung betont die Einfachheit und ist nur ein Beispiel.
from torchdiffeq import odeint_adjoint as odeint
class ODEfunc(nn.Module):
def __init__(self, dim):
super(ODEfunc, self).__init__()
self.seq = nn.Sequential(nn.Linear(dim, 124),
nn.ReLU(),
nn.Linear(124, 124),
nn.ReLU(),
nn.Linear(124, dim),
nn.Tanh())
def forward(self, t, x):
out = self.seq(x)
return out
class ODEBlock(nn.Module):
def __init__(self, odefunc):
super(ODEBlock, self).__init__()
self.odefunc = odefunc
self.integration_time = torch.tensor([0, 1]).float()
def forward(self, x):
self.integration_time = self.integration_time.type_as(x)
out = odeint(self.odefunc, x, self.integration_time)
return out[1] # out[0]Weil der Anfangswert in enthalten ist.
Um es kurz zu erklären,
--ODE Block behandelt die empfangene Eingabe "x" als Anfangswert der Differentialgleichung.
--ODEfunc
ist $ f $, das die Dynamik des Systems beschreibt.
Auf diese Weise können Sie den ODE-Block wie unten gezeigt als ein Modul des neuronalen Netzes verwenden.
class ODEnet(nn.Module):
def __init__(self, in_dim, mid_dim, out_dim):
super(ODEnet, self).__init__()
odefunc = ODEfunc(dim=mid_dim)
self.fc1 = nn.Linear(in_dim, mid_dim)
self.relu1 = nn.ReLU(inplace=True)
self.norm1 = nn.BatchNorm1d(mid_dim)
self.ode_block = ODEBlock(odefunc) #Verwenden Sie den ODE-Block
self.norm2 = nn.BatchNorm1d(mid_dim)
self.fc2 = nn.Linear(mid_dim, out_dim)
def forward(self, x):
batch_size = x.shape[0]
x = x.view(batch_size, -1)
out = self.fc1(x)
out = self.relu1(out)
out = self.norm1(out)
out = self.ode_block(out)
out = self.norm2(out)
out = self.fc2(out)
return out
Dieses Modell war langsam zu berechnen. Die Verwendung von torchdiffeq scheint es jedoch nicht zu verlangsamen, und soweit ich es versucht habe, ist das neuronale ODE-Modell im offiziellen Repository so schnell wie ein normales neuronales Netzwerk. (Dieses sollte ein kleineres Modell sein ...)
Wir haben eine rudimentäre Verwendung von torchdiffeq eingeführt, die für die Implementierung von neuronaler ODE nützlich ist. Wenn Sie das Programm sehen möchten, das das Modell tatsächlich trainiert, lesen Sie bitte das folgende Offizielle Torchdiffeq-Repository oder [Mein Implementierungs-Repository](https: // github). com / TakadaTakumi / neuralODE_sample).
torchdiffeq - GitHub Mein Implementierungs-Repository
Recommended Posts