Detaillierte Erläuterung des Prinzips des Diffusionsmodells

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]x_0x_0x_1x_1x_2x_nx_n
    x_1x_1
  • 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, x_2durch 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 x_2. Mit diesem Wissen können wir eine Formel verwenden, um die Beziehung zwischen der Zeit und zwei Bildern wie folgt x_1auszudrücken :x_tx_t-1

X_t=\sqrt{a_t} X_{t-1}+\sqrt{1-a_t} Z_1 --Formel 1

Darin X_tstellt es Tdas Bild zu diesem Zeitpunkt dar, X_{t-1}stellt t-1das Zeitbild dar und Z_1stellt 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 X_tsowohl und X_{t-1}als auch Z_1eine 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 \sqrt{a_t}.\sqrt{1-a_t}

 Ich denke, Sie haben die Formel 1 verstanden, aber Sie haben möglicherweise immer noch Zweifel am Verständnis von \sqrt{a_t}sum \sqrt{1-a_t}, z. B. warum sollte ein solches Gewicht festgelegt werden? Ist die Einstellung dieses Gewichts von uns voreingestellt? Tatsächlich beihängt es auch mit einer anderen Größe zusammen \beta_t. Die Beziehung ist wie folgt:

​——Formel a_t=1-\beta_t 2

Darunter \beta_tbefindet sich ein vorgegebener Wert, der mit der Zeit zunimmt und dessen Bereich im Papier [0,0001,0,02] beträgt. Da \beta_tes immer größer wird, beiwird es immer kleiner beiund 1− beiwird immer größer. Betrachten wir nun Formel 1: Z_1Das Gewicht des Gewichts  \sqrt{1-a_t}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 x_tdem Moment und x_{t-1}den beiden Bildern des Augenblicks erhalten, aber x_{t-1}das Bild des Augenblicks ist unbekannt. [ Hinweis: Es ist nur x_0das Bühnenbild bekannt, also das Originalbild] Wir müssen das Zeitbild von der Zeit x_{t-2}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:x_{t-1}x_{t-3}x_{t-2}x_0x_1x_{t-2}x_{t-1}

 X_{t-1}=\sqrt{a_{t-1}} X_{t-2}+\sqrt{1-a_{t-1}} Z_2   ——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\begin{aligned} X_t & =\sqrt{a_t}\left(\sqrt{a_{t-1}} X_{t-2}+\sqrt{1-a_{t-1}} Z_2\right)+ \sqrt{1-a_t} Z_1 \\ & =\sqrt{a_t a_{t-1}} X_{t-2}+\sqrt{a_t\left(1-a_{t-1}\right)} Z_2+ \sqrt{1-a_t} Z_1 \\ & =\sqrt{a_t a_{t-1}} X_{t-2}+\sqrt{1-a_t a_{t-1}} \hat{Z}_2 \ end{aligned} 4

Kann jeder diese Formel 4 verstehen? Ich denke, jeder sollte an der letzten Gleichung zweifeln, nämlich: Wie \sqrt{a_t\left(1-a_{t-1}\right)} Z_2+\sqrt{1-a_t} Z_1ist sie gleich \sqrt{1-a_t a_{t-1}} \hat{Z}_2? 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) \hat{Z}_2gilt . 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:N\sqrt{a_t\left(1-a_{t-1}\right)} Z_2+\sqrt{1-a_t} Z_1N\left(0,1-a_t a_{t-1}\right)x_tx_{t-2}x_{t-3}x_{t-2}

X_{t-2}=\sqrt{a_{t-2}} X_{t-3}+\sqrt{1-a_{t-2}} Z_3 ——Offiziell 5

In ähnlicher Weise ersetzen wir Formel 5 durch Formel 4, um die Beziehung zwischen x_tZeitbildern und x_{t-3}Zeitbildern zu erhalten. Die Formel lautet wie folgt: 

X_t=\sqrt{a_t a_{t-1} a_{t-2}} X_{t-3}+\sqrt{1-a_t a_{t-1} a_{t-2}} \hat{Z} _3——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 \hat{Z}_3auch der (0,1)-Gaußschen Verteilung folgt N. Dann kann Formel 6 die Beziehung zwischen x_tdem Zeitbild und x_{t-3}dem Zeitbild ermitteln. Wenn wir auf diese Weise weiterrechnen, erhalten wir  die Beziehung zwischen x_t dem Zeitbild und x_0dem 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 x_t und x_0dem Zeitbild direkt gemäß dieser Regel schreiben. Die Formel lautet wie folgt:

X_t=\sqrt{\bar{a}_t} X_0+\sqrt{1-\bar{a}_t} \hat{Z}_t ——Offiziell 7

Darunter \bar{a}_tstellt es die Multiplikationsoperation dar, das heißt \bar{a}_t=a_t \cdot a_{t-1} \cdot a_{t-2} \cdots a_1 , \hat{Z}_tdie Stichprobe folgt Nder Gaußschen Verteilung von (0,1). [Hier ist \hat{Z}_t nur eine Darstellung. Solange es Zder Standard-Gaußschen Verteilung folgt, können Sie jede Darstellung verwenden.] Diese Formel 7 ist die Kernformel des gesamten Vorwärtsprozesses: „Das x_tBild, das die Zeit darstellt, kann sein.“ Besteht aus x_0dem 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 x_tin einem Moment um Gaußsches Rauschen. Wir hoffen, x_tdas Gaußsche Rauschen der Zeit in x_0ein 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 x_tdem Zeitbild und x_{t-1}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 x_tein Zeitbild erhalten x_{t-1}.

Hier müssen wir die Schlussfolgerungen im Vorwärtsprozess verwenden. Wir können das Zeitbild aus dem Zeitbild im Vorwärtsprozess x_{t-1}erhalten und es dann mit der Bayes'schen Formel lösen. Der Ausdruck der Bayes'schen Formel lautet wie folgt: x_t

Dann verwenden wir die Bayes'sche Formel, um x_{t-1}das Momentbild zu finden. Die Formel lautet wie folgt:

q\left(X_{t-1} \mid X_t\right)=q\left(X_t \mid X_{t-1}\right) \frac{q\left(X_{t-1}\right)} {q\left(X_t\right)}——Offiziell 8

Wir können es der Formel 8 entnehmen q\left(X_t \mid X_{t-1}\right), die wir gerade im Vorwärtsprozess gefunden haben. Aber q\left(X_{t-1}\right)und q\left(X_{t}\right)ist unbekannt. Aus Formel 7 ist auch ersichtlich, dass X_0das Bild zu jedem Zeitpunkt erhalten werden kann, X_tund natürlich X_{t-1}kann das Bild gleichzeitig erhalten werden. Fügen Sie also eins zu Formel 8 X_0als bekannte Bedingung hinzu und ändern Sie Formel 8 in Formel 9. folgendermaßen:

q\left(X_{t-1} \mid X_t, X_0\right)=q\left(X_t \mid X_{t-1}, X_0\right) \frac{q\left(X_{t-1} \mid X_0\right)}{q\left(X_t \mid X_0\right)}——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 q\left(X_{t-1} \mid X_t, X_0\right). 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: f(x)=\frac{1}{\sqrt{2 \pi \sigma}} e^{-\frac{(xu)^2}{2 \sigma^2}}. 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 q\left(X_{t-1} \mid X_t, X_0\right)

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, M \cdot e^{-\frac{1}{2}\left[\left(\frac{\alpha_t}{\beta_t}+\frac{1}{1-\bar{a}_{t-1 }}\right) X_{t-1}^2-\left(\frac{2 \sqrt{a_t}}{\beta_t} \bar{a}_{t-1}} X_0\right) X_{t-1}+C\left(X_t, X_0\right)\right]}ist tatsächlich q\left(X_{t-1} \mid X_t\right)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 q\left(X_{t-1} \mid X_t\right)gehorcht der Gaußschen Verteilung. Dann lautet sein Ausdruck  f(x)=\frac{1}{\sqrt{2 \pi \sigma}} e^{-\frac{(xu)^2}{2 \sigma^2}}=\frac{1}{\ sqrt{2 \pi \sigma}} e^{-\frac{1}{2}\left[\frac{x^2}{\sigma^2}-\frac{2 ux}{\sigma^2} +\frac{u^2}{\sigma^2}\right]}. Wir können die uSumme berechnen, indem wir die beiden Ausdrücke vergleichen \sigma^2, wie gezeigt in der Abbildung unten:

Da wir nun den Mittelwert uund die Varianz haben, \sigma^2 können wir sie finden q\left(X_{t-1} \mid X_t\right), also x_{t-1}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, uund \sigma^2die mittlere Bedeutung X_0, X_0was 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 X_0. 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 q\left(X_{t-1}\right)Summe darzustellen q\left(X_{t}\right). Jetzt scheint es jedoch, dass an dieser Stelle eine neue Unbekannte eingeführt wird X_0. Was sollen wir tun? Zu diesem Zeitpunkt erwägen wir die Verwendung von Formel 7, um die Schätzung umzukehren , d. h. den Ausdruck,  X_0der durch Umkehren von Formel 7 erhalten wird , wie folgt:X_0

X_0=\frac{1}{\sqrt{a_t}}\left(X_t-\sqrt{1-\bar{a}_t} \hat{Z}_t\right)——Offiziell 10

Der erhaltene geschätzte Wert X_0setzt zu diesem Zeitpunkt die Formel 10 in die obige Abbildung ein uund erhält nach der Berechnung den endgültigen geschätzten Wert  \tilde{u}. Der Ausdruck lautet wie folgt:

​——Formel \tilde{u}=\frac{1}{\sqrt{a_t}}\left(x_t-\frac{\beta_t}{\sqrt{1-\bar{a}_t}} \hat{Z}_t\ Rechts) 11

Ok, jetzt sortieren wir den Mittelwert und die Varianz Tdes Bildes zum Zeitpunkt −1  , wie in der folgenden Abbildung gezeigt:u\sigma^2

Mit Formel 12 können wir das Bild des Augenblicks abschätzen und dann Schritt für Schritt die Bilder von , , , X_{t-1}finden .X_{t-2}X_{t-3}X_{1}X_{0}


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.pyund das andere ist ddpm_condition.py. ddpm.pySie können es als das einfachste Diffusionsmodell und ddpm_condition.pydie beste Optimierung verstehen ddpm.py. In diesem Abschnitt wird es ddpm.pyjedem . Der Code ist sehr einfach zu verwenden. Geben Sie zunächst ddpm.pyden Datensatzpfad in der Datei an, bei dem es sich um den festgelegten dataset_pathWert handelt, und dann können wir den Code ausführen. Beachten Sie, dass Sie bei Verwendung einer CPU möglicherweise auch devicedie Parameter im Code ändern müssen.


Hier kurz ddpmauf die Bedeutung des vollständigen englischen Namens Denoising Diffusion Probabilistic Modelund 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 X_0.

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:

X_t=\sqrt{\bar{a}_t} X_0+\sqrt{1-\bar{a}_t} \hat{Z}_t

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_hattatsä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)

modelDie 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\sigma_t\sqrt{\beta}\sqrt{\frac{\beta_t\left(1-\bar{a}_{t-1}\right)}{1-\bar{a}_t}}\bar{a}_{t-1}\bar{a}_{t}\frac{\left(1-\bar{a}_{t-1}\right)}{1-\bar{a}_t}

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:

f(x)=\frac{1}{\sqrt{2 \pi \sigma}} e^{-\frac{(xu)^2}{2 \sigma^2}}

Wo uist der Mittelwert und \sigma^2die Varianz? Wenn die XZufallsvariable einer Gaußschen Verteilung mit einem normalen Mittelwert uund einer Varianz von folgt \sigma^2, wird sie im Allgemeinen als aufgezeichnet X \sim N\left(u, \sigma^2\right). 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 X \sim N\left(u, \sigma^2\right), dann a X \sim N\left(au,(a \sigma)^2\right).
  • Wenn X \sim N\left(u_1, \sigma^2{ }_1\right), Y \sim N\left(u_2, \sigma^2{ }_2\right), dann X+Y \sim N\left(u_1+u_2, \sigma^2{ }_1+\sigma^2{ }_2\right).

 

Referenzinhalt: Detaillierte Erläuterung des Prinzips des Diffusionsmodells und Quellcode-Analyse – Zhihu (zhihu.com)

Ich denke du magst

Origin blog.csdn.net/weixin_42620109/article/details/129156101
Empfohlen
Rangfolge