Das Diffusionsmodell (Diffusion Model) zielt auf das Generative Adversarial Network (GAN) ab. Solange GAN dies kann, kann es dies grundsätzlich tun. Bevor das GAN-Netzwerk zur Realisierung einiger Bilderzeugungsaufgaben verwendet wird, ist der Effekt nicht sehr ideal und das Training ist oft sehr instabil. Die nach dem Wechsel zum Diffusionsmodell erzeugten Bilder sind jedoch sehr realistisch und es ist offensichtlich, dass die Ergebnisse jeder Trainingsrunde besser sind als zuvor, das heißt, das Training ist stabiler.
In diesem Artikel werden gängige Sprachen und Formeln verwendet, um Ihnen das Diffusionsmodell vorzustellen. Außerdem werden die Formeln kombiniert, um den Code des Diffusionsmodells für Sie zu sortieren und zu untersuchen, wie es durch Code implementiert wird.
die ganze Idee
Die Gesamtidee des Diffusionsmodells ist in der folgenden Abbildung dargestellt:
Es ist hauptsächlich in Vorwärtsprozesse und Rückwärtsprozesse unterteilt. Der Vorwärtsprozess ähnelt der Codierung und der Rückwärtsprozess ähnelt der Decodierung.
- Vorwärtsprozess Zuerst fügen wir
einem Originalbild ein Gaußsches Rauschen hinzu, und das Bild wird zu . 【Hinweis: Hier muss Gaußsches Rauschen hinzugefügt werden, da Gaußsches Rauschen der Gaußschen Verteilung gehorcht und einige der folgenden Operationen einige Merkmale der Gaußschen Verteilung verwenden müssen】" Dann werden wir Gaußsches Rauschen auf der Grundlage von hinzufügen . Wiederholen Sie den obigen Schritt des Hinzufügens von Gaußschem Rauschen, bis das Bild wird . Da ausreichend Gaußsches Rauschen hinzugefügt wurde, folgt die aktuelle Näherung einer Gaußschen Verteilung (auch als Normalverteilung bezeichnet). Jetzt gibt es eine Frage, über die jeder nachdenken sollte: Ist die Menge an Gauß'chem Rauschen, die wir in jedem Schritt hinzufügen, immer konstant? Drip, fang an zu antworten. Die Antwort ist, dass die Menge des in jedem Schritt hinzugefügten Gaußschen Rauschens variiert und der letzte Schritt mehr Gaußsches Rauschen hinzufügt als der vorherige Schritt. Ich denke, es ist für Sie anhand des obigen Bildes sehr leicht zu verstehen. Am Anfang ist das Originalbild relativ sauber. Wir können eine kleine Menge Gaußsches Rauschen hinzufügen, um das Originalbild zu stören; dann wird es im Grunde kein Gaußsches Rauschen geben keinen Einfluss auf die Ergebnisse des vorherigen Schritts haben. [Hinweis: Das später beschriebene Bild jedes Augenblicks und das Bild jedes Schritts hier haben dieselbe Bedeutung, z. B. stellt das Bild des Augenblicks dieses Bild dar] - Der umgekehrte Prozess
: Zuerst erzeugen wir zufällig ein Rauschbild, das einer Gaußschen Verteilung folgt, und reduzieren dann das Rauschen Schritt für Schritt, bis das erwartete Bild erzeugt wird. Es ist gut für alle, den umgekehrten Prozess so zu verstehen, und die Einzelheiten werden später vorgestellt.
Implementierungsdetails
In diesem Teil werden die Details des Vorwärts- und Rückwärtsprozesses des Diffusionsmodells vorgestellt, hauptsächlich durch die Ableitung einiger Formeln, um die Beziehung zwischen Bildern vor und nach dem Hinzufügen von Rauschen auszudrücken.
Vorwärtsprozess
Im allgemeinen Denkteil wissen wir bereits, dass der Vorwärtsprozess tatsächlich ein Prozess des kontinuierlichen Hinzufügens von Rauschen ist. Daher überlegen wir, ob wir einige Formeln verwenden können, um die Beziehung zwischen dem Bild vor und nach dem Hinzufügen von Rauschen auszudrücken. Ich möchte, dass jeder darüber nachdenkt, welche Faktoren das Bild im nächsten Moment beeinflussen werden, und genauer gesagt, durch welche Größen wird es bestimmt? Ich denke, dieses Problem ist sehr einfach, das heißt, es wird durch die Summe des Rauschens bestimmt, das heißt, das Bild im nächsten Moment wird hauptsächlich durch zwei Größen bestimmt, eine ist das Bild im vorherigen Moment und die andere ist die Menge an hinzugefügtem Rauschen . Mit diesem Wissen können wir eine Formel verwenden, um die Beziehung zwischen der Zeit und zwei Bildern wie folgt auszudrücken :
--Formel 1
Darin stellt es das Bild zu diesem Zeitpunkt dar, stellt das Zeitbild dar und stellt das hinzugefügte Gaußsche Rauschen dar, das der N(0,1)-Verteilung folgt. [Hinweis: N(0,1) stellt eine Standard-Gaußsche Verteilung mit einer Varianz von 1 und einem Mittelwert von 0 dar.] Derzeit können Sie sehen, dass sowohl und als auch eine Beziehung haben, die mit dem übereinstimmt, was wir zuvor gesagt haben 后一时刻的图像由前一时刻图像和噪声决定
. Die Summe vor dieser Formel stellt das Gewicht dieser beiden Größen dar und die Summe ihrer Quadrate ist 1 .
Ich denke, Sie haben die Formel 1 verstanden, aber Sie haben möglicherweise immer noch Zweifel am Verständnis von sum , z. B. warum sollte ein solches Gewicht festgelegt werden? Ist die Einstellung dieses Gewichts von uns voreingestellt? Tatsächlich hängt es auch mit einer anderen Größe zusammen . Die Beziehung ist wie folgt:
——Formel 2
Darunter befindet sich ein vorgegebener Wert, der mit der Zeit zunimmt und dessen Bereich im Papier [0,0001,0,02] beträgt. Da es immer größer wird, wird es immer kleiner und 1− wird immer größer. Betrachten wir nun Formel 1: Das Gewicht des Gewichts nimmt mit der Zeit zu, was darauf hinweist, dass wir immer mehr Gaußsches Rauschen hinzufügen, was mit unserem Gesamtdenken übereinstimmt, das heißt, je mehr wir hinzufügen, desto mehr Rauschen.
Jetzt haben wir die Beziehung zwischen dem Moment und den beiden Bildern des Augenblicks erhalten, aber das Bild des Augenblicks ist unbekannt. [ Hinweis: Es ist nur das Bühnenbild bekannt, also das Originalbild] Wir müssen das Zeitbild von der Zeit ableiten und dann das Zeitbild von der Zeit ableiten , und so weiter, bis das Zeitbild von der Zeit abgeleitet wird Zeit. In diesem Fall könnten wir auch zuerst die Beziehung zwischen Zeitbildern und Zeitbildern wie folgt ausprobieren:
——Beamter 3
Diese Formel ist eine analoge Formel zu Formel 1. Zu diesem Zeitpunkt ersetzen wir Formel 3 durch Formel 1, um Folgendes zu erhalten:
——Formel 4
Kann jeder diese Formel 4 verstehen? Ich denke, jeder sollte an der letzten Gleichung zweifeln, nämlich: Wie ist sie gleich ? Tatsächlich erfordert dies einige Kenntnisse der Gaußschen Verteilung, siehe Anhang zu diesem Teil. Nachdem ich die relevanten Eigenschaften der Gaußschen Verteilung im Anhang gelesen habe, denke ich, dass Sie es hier verstehen sollten. Ich helfe Ihnen, es zu klären, wie in der folgenden Abbildung gezeigt:
Jetzt verstehe ich den Inhalt der Formel 4. Beachten Sie, dass hier auch die Gaußsche Verteilung (0,1) gilt . Schauen wir uns an, was Formel 4 erhalten hat: Sie hat die Beziehung zwischen dem Zeitbild und dem Zeitbild erhalten. Nach unserem bisherigen Verständnis listen wir die Beziehung zwischen Zeitbildern und Zeitbildern wie folgt auf:
——Offiziell 5
In ähnlicher Weise ersetzen wir Formel 5 durch Formel 4, um die Beziehung zwischen Zeitbildern und Zeitbildern zu erhalten. Die Formel lautet wie folgt:
——Offiziell 6
Ich habe Sie nicht Schritt für Schritt durch die Berechnung von Formel 5 geführt, sondern nur das Endergebnis geschrieben. Sie können es selbst berechnen. Es ist sehr einfach und verwendet nur die relevanten Eigenschaften der Gaußschen Verteilung. Beachten Sie, dass das Obige auch der (0,1)-Gaußschen Verteilung folgt . Dann kann Formel 6 die Beziehung zwischen dem Zeitbild und dem Zeitbild ermitteln. Wenn wir auf diese Weise weiterrechnen, erhalten wir die Beziehung zwischen dem Zeitbild und dem Zeitbild. Eine solche Ableitung scheint jedoch sehr lang zu sein. Wenn Sie rückwärts schließen, werden Sie feststellen, dass diese Ableitung regelmäßig ist. Wir können die Ergebnisse von Formel 4 und Formel 6 vergleichen, und Sie werden eine offensichtliche Regel finden. Hier werde ich die Beziehung zwischen dem Zeitbild und dem Zeitbild direkt gemäß dieser Regel schreiben. Die Formel lautet wie folgt:
——Offiziell 7
Darunter stellt es die Multiplikationsoperation dar, das heißt , die Stichprobe folgt der Gaußschen Verteilung von (0,1). [Hier ist \hat{Z}_t nur eine Darstellung. Solange es der Standard-Gaußschen Verteilung folgt, können Sie jede Darstellung verwenden.] Diese Formel 7 ist die Kernformel des gesamten Vorwärtsprozesses: „Das Bild, das die Zeit darstellt, kann sein.“ Besteht aus dem Bild zu diesem Zeitpunkt und einer Standard-Gaußschen Rauschdarstellung. Sie müssen diese Formel im Hinterkopf behalten, sie wird später und im Code verwendet.
umgekehrter Vorgang
Der umgekehrte Prozess ist der Prozess der Wiederherstellung des Gaußschen Rauschens im erwarteten Bild. Werfen wir zunächst einen Blick auf das, was wir wissen: Tatsächlich handelt es sich in einem Moment um Gaußsches Rauschen. Wir hoffen, das Gaußsche Rauschen der Zeit in ein Bild der Zeit umzuwandeln, was in einem Schritt nur schwer zu vervollständigen ist. Daher können wir darüber nachdenken, ob wir zunächst die Beziehung zwischen dem Zeitbild und der Zeit wie in der Zukunft betrachten können Prozess und leiten Sie dann Schritt für Schritt die Schlussfolgerung ab. Ok, da wir nun eine Idee haben, überlegen wir uns zunächst, wie wir aus einem bekannten Zeitbild ein Zeitbild erhalten .
Hier müssen wir die Schlussfolgerungen im Vorwärtsprozess verwenden. Wir können das Zeitbild aus dem Zeitbild im Vorwärtsprozess erhalten und es dann mit der Bayes'schen Formel lösen. Der Ausdruck der Bayes'schen Formel lautet wie folgt:
Dann verwenden wir die Bayes'sche Formel, um das Momentbild zu finden. Die Formel lautet wie folgt:
——Offiziell 8
Wir können es der Formel 8 entnehmen , die wir gerade im Vorwärtsprozess gefunden haben. Aber und ist unbekannt. Aus Formel 7 ist auch ersichtlich, dass das Bild zu jedem Zeitpunkt erhalten werden kann, und natürlich kann das Bild gleichzeitig erhalten werden. Fügen Sie also eins zu Formel 8 als bekannte Bedingung hinzu und ändern Sie Formel 8 in Formel 9. folgendermaßen:
——Offiziell 9
Nun kann festgestellt werden, dass die drei Elemente auf der rechten Seite der Formel 9 berechnet werden können. Wir listen ihre Formeln und entsprechenden Verteilungen auf, wie in der folgenden Abbildung dargestellt:
Wenn wir die Verteilung der drei Terme auf der rechten Seite der Gleichung in Formel 9 kennen, können wir die linke Seite der Gleichung berechnen . Diese Berechnung ist sehr einfach, es sind keine Fähigkeiten erforderlich, es handelt sich um reine Berechnung. Im Anhang -> Abschnitt über die Eigenschaften der Gaußschen Verteilung wissen wir, dass der Ausdruck der Gaußschen Verteilung wie folgt lautet: . Dann müssen wir nur noch nach den drei Gaußschen Verteilungsausdrücken auf der rechten Seite der Gleichung in Formel 9 fragen und dann Multiplikations- und Divisionsoperationen durchführen, um sie zu erhalten .
Die obige Abbildung zeigt die drei Gaußschen Verteilungsausdrücke auf der rechten Seite der Gleichung. Jeder sollte wissen, wie man dieses Ergebnis erhält, das heißt, man ersetzt einfach den jeweiligen Mittelwert und die Varianz in den Gaußschen Verteilungsausdrücken. Jetzt müssen wir nur noch die entsprechenden Multiplikations- und Divisionsoperationen für die oben genannten drei Formeln durchführen, wie in der folgenden Abbildung dargestellt:
Nun, die Formel, die wir in der obigen Abbildung erhalten haben, ist tatsächlich der Ausdruck von. Wenn man weiß, wozu dieser Ausdruck dient, dient er hauptsächlich dazu, den Mittelwert und die Varianz zu ermitteln. Zunächst sollten wir wissen, dass das Ergebnis der Multiplikation und Division der Gaußschen Verteilung immer noch eine Gaußsche Verteilung ist, das heißt, es gehorcht der Gaußschen Verteilung. Dann lautet sein Ausdruck . Wir können die Summe berechnen, indem wir die beiden Ausdrücke vergleichen , wie gezeigt in der Abbildung unten:
Da wir nun den Mittelwert und die Varianz haben, können wir sie finden , also das Bild des Augenblicks. Ich weiß nicht, wie viel Sie verstanden haben, nachdem Sie es hierher abgeleitet haben? Wenn Sie mit Ihren kleinen Händen rechnen, werden Sie feststellen, dass es immer noch sehr einfach ist. Aber ich weiß nicht, ob Sie ein Problem entdeckt haben. Das Endergebnis, das wir gerade erhalten haben, und die mittlere Bedeutung , was ist das, es ist das Endergebnis, das wir wollen, wie kann es jetzt als bekannte Größe betrachtet werden? Dieses Stück ist in der Tat etwas seltsam. Werfen wir einen Blick darauf, wo wir es eingeführt haben . Wenn Sie nach oben scrollen, werden Sie feststellen, dass wir bei Verwendung der Bayes'schen Formel die im Vorwärtsprozess abgeleitete Formel 7 verwenden, um die Summe darzustellen . Jetzt scheint es jedoch, dass an dieser Stelle eine neue Unbekannte eingeführt wird . Was sollen wir tun? Zu diesem Zeitpunkt erwägen wir die Verwendung von Formel 7, um die Schätzung umzukehren , d. h. den Ausdruck, der durch Umkehren von Formel 7 erhalten wird , wie folgt:
——Offiziell 10
Der erhaltene geschätzte Wert setzt zu diesem Zeitpunkt die Formel 10 in die obige Abbildung ein und erhält nach der Berechnung den endgültigen geschätzten Wert . Der Ausdruck lautet wie folgt:
——Formel 11
Ok, jetzt sortieren wir den Mittelwert und die Varianz des Bildes zum Zeitpunkt −1 , wie in der folgenden Abbildung gezeigt:
Mit Formel 12 können wir das Bild des Augenblicks abschätzen und dann Schritt für Schritt die Bilder von , , , finden .
Prinzipielle Zusammenfassung
Die ausführliche Erklärung des Prinzips dieses Abschnitts ist für alle hier. Wie viel verstehen Sie? Ich glaube, dass Sie nach dem Lesen dieses Teils bereits ein allgemeines Verständnis des Prinzips des Diffusionsmodells haben, aber es müssen einige Zweifel bestehen. Machen Sie sich keine Sorgen, der Codeteil wird Ihnen weiterhelfen.
Quellcodeanalyse des Diffusionsmodells
Code herunterladen und verwenden
Diese Code-Download-Adresse: Diffusionsmodellcode
Lassen Sie uns zunächst über die Verwendung des Codes sprechen. Der Code enthält zwei Elemente, eines ist ddpm.py
und das andere ist ddpm_condition.py
. ddpm.py
Sie können es als das einfachste Diffusionsmodell und ddpm_condition.py
die beste Optimierung verstehen ddpm.py
. In diesem Abschnitt wird es ddpm.py
jedem . Der Code ist sehr einfach zu verwenden. Geben Sie zunächst ddpm.py
den Datensatzpfad in der Datei an, bei dem es sich um den festgelegten dataset_path
Wert handelt, und dann können wir den Code ausführen. Beachten Sie, dass Sie bei Verwendung einer CPU möglicherweise auch device
die Parameter im Code ändern müssen.
Hier kurz ddpm
auf die Bedeutung des vollständigen englischen Namens Denoising Diffusion Probabilistic Model
und der chinesischen Übersetzung eingehen 去噪扩散概率模型
.
Code-Flussdiagramm
Hier schauen wir uns direkt das im Papier angegebene Flussdiagramm wie folgt an:
Diese Abbildung zeigt, dass der Prozess des gesamten Algorithmus in die Trainingsphase (Training) und die Abtastphase (Sampling) unterteilt ist.
- Training
Wie wir alle wissen, benötigen wir für das Training reale und vorhergesagte Werte. Was sind also die realen und vorhergesagten Werte für dieses Beispiel? Ist der wahre Wert das von uns eingegebene Bild und der vorhergesagte Wert das von uns ausgegebene Bild? Tatsächlich ist dies nicht der Fall. In diesem Beispiel handelt es sich sowohl beim tatsächlichen Wert als auch beim vorhergesagten Wert um Rauschen. Nehmen Sie auch das Bild unten als Demonstration für alle auf.
Das Rauschen, das wir im Vorwärtsprozess hinzufügen, ist tatsächlich bekannt und kann als tatsächlicher Wert verwendet werden. Der umgekehrte Prozess entspricht einem Entrauschungsprozess. Wir verwenden ein Modell, um das Rauschen vorherzusagen, sodass das in jedem Schritt des Vorwärtsprozesses hinzugefügte Rauschen so konsistent wie möglich mit dem im entsprechenden Schritt des umgekehrten Prozesses vorhergesagten Rauschen ist Eine Möglichkeit, Rauschen im umgekehrten Prozess vorherzusagen, besteht darin, es in das Modell einzuwerfen. Das Training ist eigentlich der fünfte Schritt im Training.
- Die Probenahme
kennt den Trainingsprozess und der Probenahmeprozess ist sehr einfach. Tatsächlich entspricht der Probenahmeprozess dem in unserem theoretischen Teil eingeführten umgekehrten Prozess und iteriert Schritt für Schritt von einem Gaußschen Rauschen vorwärts und erhält schließlich das Zeitbild .
Code-Analyse
Zunächst sollte es nach unserem theoretischen Teil zu einem positiven Prozess kommen, dessen wichtigster die Schlussformel 7 ist, die wie folgt lautet:
Schauen wir uns dann an, wie diese Formel 7 im Code verwendet wird. Der Code lautet wie folgt:
def noise_images(self, x, t):
sqrt_alpha_hat = torch.sqrt(self.alpha_hat[t])[:, None, None, None]
sqrt_one_minus_alpha_hat = torch.sqrt(1 - self.alpha_hat[t])[:, None, None, None]
Ɛ = torch.randn_like(x)
return sqrt_alpha_hat * x + sqrt_one_minus_alpha_hat * Ɛ, Ɛ
Ɛ ist eine zufällige Standard-Gauß-Verteilung, die tatsächlich der wahre Wert ist. Wie Sie sehen können, stellt der Rückgabewert der obigen Formel sqrt_alpha_hat * x + sqrt_one_minus_alpha_hat
tatsächlich Formel 7 dar. [Hinweis: Ich habe in diesem Code viele Details weggelassen. Ich zeige Ihnen nur den Schlüsselcode. Wenn Sie ihn vollständig verstehen möchten, müssen Sie daran denken, zu debuggen und zu debuggen.]
Dann sagen wir das Rauschen mithilfe eines Modells wie folgt voraus:
predicted_noise = model(x_t, t)
model
Die Struktur ist sehr einfach, es handelt sich um eine Unet-Struktur, in der mehrere Transformer-Mechanismen verschachtelt sind, sodass ich nicht jeden dazu auffordern werde, einen Blick darauf zu werfen. Da wir nun den vorhergesagten Wert und den tatsächlichen Wert Ɛ haben [nach der Rückkehr wird Ɛ durch Rauschen dargestellt], können wir ihren Verlust berechnen und kontinuierlich iterieren.
loss = mse(noise, predicted_noise)
optimizer.zero_grad()
loss.backward()
optimizer.step()
Das Obige ist eigentlich die allgemeine Struktur des Trainingsprozesses. Ich habe viel weggelassen. Schauen wir uns nun den Code des Stichprobenprozesses an.
def sample(self, model, n):
logging.info(f"Sampling {n} new images....")
model.eval()
with torch.no_grad():
x = torch.randn((n, 3, self.img_size, self.img_size)).to(self.device)
# for i in tqdm(reversed(range(1, self.noise_steps)), position=0):
for i in tqdm(reversed(range(1, 5)), position=0):
t = (torch.ones(n) * i).long().to(self.device)
predicted_noise = model(x, t)
alpha = self.alpha[t][:, None, None, None]
alpha_hat = self.alpha_hat[t][:, None, None, None]
beta = self.beta[t][:, None, None, None]
if i > 1:
noise = torch.randn_like(x)
else:
noise = torch.zeros_like(x)
x = 1 / torch.sqrt(alpha) * (x - ((1 - alpha) / (torch.sqrt(1 - alpha_hat))) * predicted_noise) + torch.sqrt(beta) * noise
model.train()
x = (x.clamp(-1, 1) + 1) / 2
x = (x * 255).type(torch.uint8)
return x
Der Schlüssel zum obigen Code ist diese Formel, die Schritt 4 in der Sampling-Phase des Code-Flussdiagramms entspricht. Es ist zu beachten, dass hier die Formel für die Varianz angegeben ist , aber in unserer theoretischen Berechnung wird hier tatsächlich eine Näherungsberechnung durchgeführt, das heißt, die Summe und die Summe sind beide sehr klein und liegen nahe bei 0, sodass sie wie folgt berechnet werden 1. Passen Sie hier gut auf. x = 1 / torch.sqrt(alpha) * (x - ((1 - alpha) / (torch.sqrt(1 - alpha_hat))) * predicted_noise) + torch.sqrt(beta) * noise
Code-Zusammenfassung
Es ist ersichtlich, dass der Platzbedarf in diesem Teil sehr gering ist und nur die wichtigsten Teile aufgelistet sind und viele Details von jedem verstanden werden müssen. Beispielsweise ist die Verwendung der Zeit T im Code tatsächlich schwer zu verstehen und wird im Code als Sinus-Cosinus-Positionscode behandelt. Wenn Sie mit der Positionskodierung nicht vertraut sind, können Sie sich diesen Artikel ansehen , der eine detaillierte Einführung in die Positionskodierung enthält.
Anhang
Eigenschaften der Gaußschen Verteilung
Die Gaußsche Verteilung wird auch als Normalverteilung bezeichnet und hat den folgenden Ausdruck:
Wo ist der Mittelwert und die Varianz? Wenn die Zufallsvariable einer Gaußschen Verteilung mit einem normalen Mittelwert und einer Varianz von folgt , wird sie im Allgemeinen als aufgezeichnet . Darüber hinaus muss jeder wissen: Wenn wir wissen, dass eine Zufallsvariable einer Gaußschen Verteilung folgt und wir ihren Mittelwert und ihre Varianz kennen, können wir den Ausdruck der Zufallsvariablen schreiben.
Auch die Gaußsche Verteilung hat einige sehr gute Eigenschaften. Hier sind einige Beispiele, die Ihnen das Verständnis erleichtern.
- Wenn , dann .
- Wenn , dann .
Referenzinhalt: Detaillierte Erläuterung des Prinzips des Diffusionsmodells und Quellcode-Analyse – Zhihu (zhihu.com)