[PYTHON] Generieren Sie mit GAN physisch stabile Formen und drucken Sie mit einem 3D-Drucker

0. Das Schöne an diesem Artikel

1. Übersicht

--DCGAN (Radford et al., 2016) [^ DCGAN] wird verwendet, und der Verlustfunktion werden Festigkeitsinformationen hinzugefügt, um hochfeste Zahlen zu erzeugen. --Stärke kann unter Beibehaltung des Datenkonzepts manipuliert werden

(Der Artikel ist lang, aber ich denke, Sie können ihn sofort lesen, da er ungefähr 3/4 des Bildes oder einen Bonus ausmacht.)

2. Hintergrund

Ich habe kürzlich einen 3D-Drucker bekommen, und als ich mich fragte, ob ich mit der Kombination ** 3D-Drucker x Deep Learning ** etwas anfangen könnte, habe ich beschlossen, es auszuprobieren.

Es scheint, dass sich die grundlegende Theorie der Materialmechanik in den letzten 100 Jahren nicht geändert hat, deshalb wollte ich mich der Deep-Learning-Seite nähern, die einen hohen Freiheitsgrad aufweist.

Sie können gerne lesen, welche Anzahl von "0-9" voraussichtlich stabil ist. Es gibt eine Art von außergewöhnlich stabiler Nummer.

(* Ich mache es, während ich das Buch über Materialmechanik lese (Japan Society of Mechanical Engineers, 2007) [^ JSME], also kann ich etwas Passendes sagen. Ich konnte keine ähnliche Studie im oben genannten Bereich finden, aber bitte lassen Sie es mich wissen.)

[^ JSME]: JSME Text Series Material Mechanics, Japanische Gesellschaft für Maschinenbauingenieure, 2007.

3. Theorie

Wenn Sie nicht interessiert sind, können Sie es überhaupt überspringen.

3.1 Sekundäres Querschnittsmoment

Erstens hat die grobe Wortstärke mehrere Indikatoren. Ich weiß nicht, wie Materiallager die Wortstärke verwenden, aber wir, die breite Öffentlichkeit, verwenden die Wortstärke auf viele Arten.

Morsehärte, Vickershärte, Streckgrenze (Zugfestigkeit) usw. Unter diesen ist die dominierende Kraft das ** sekundäre Querschnittsmoment **, das nur durch die Form des Querschnitts bestimmt wird, ohne vom Material abhängig zu sein. Dies ist ein Faktor dafür, wie schwer es ist, das Mitglied zu biegen.

Wenn Kraft angewendet wird, biegen sich die meisten Dinge im Verhältnis zur Kraft auf einer unsichtbaren Ebene. Und wenn Sie sich zu stark biegen, brechen die meisten Dinge und Sie können nicht zurückkehren. Umgekehrt ist es weniger wahrscheinlich, dass ein Element mit einem stärkeren Querschnitt bricht.

Zum Beispiel können Zeitungen nichts unterstützen, wenn sie flauschig sind, aber wenn sie nur gerollt werden, sind sie ziemlich steif. (Obwohl es einen Faktor gibt, der die Dicke des Papiers erhöht)

Die Japan Society of Mechanical Engineers, in [^ JSME] Kapitel 5, S. 63, "wenn eine schlanke Stange eine seitliche Last erhält, die eine Biegung in einer Ebene einschließlich der Achse der Stange aus der seitlichen Richtung verursacht, wird eine solche Stange als Balken bezeichnet." Es ist definiert als "."

↑ MNIST [1] 形状をした断面と断面二次モーメントと向きの関係、3Dプリントのイメージ

Wenn Sie in diesem Bild beide Seiten des länglichen Stabes in der Form "2" fixieren, wird er zu einem "Balken". Zu diesem Zeitpunkt beträgt für die Pfeilrichtung ** das sekundäre Querschnittsmoment für die vertikale Kraft $ I_x $ und das sekundäre Querschnittsmoment für die laterale Kraft $ I_y $ **.

Es ist etwas verwirrend, weil die Ausrichtung von $ x $ und $ y $ auf die Achse der Bildverarbeitung übertragen wird. Wikipedia senior [^ wikipedia] sagte das auch, und dies ist wahrscheinlich der Standard.

Als nächstes erklären wir, wie das sekundäre Querschnittsmoment berechnet wird.

Das sekundäre Querschnittsmoment $ I_x $ in Bezug auf die Kraft von der vertikalen Achse ist

I_x = \int_A y^2 dA \tag{1}

Es kann mit berechnet werden. Wobei $ A $ die Querschnittsfläche und $ y $ der vertikale Abstand von der neutralen Achse (dem Schwerpunkt des Querschnitts) ist.

In ähnlicher Weise ist das sekundäre Querschnittsmoment $ I_y $ in Bezug auf die Kraft von der horizontalen Achse

I_y = \int_A x^2 dA \tag{2}

Es kann mit berechnet werden. Wobei $ x $ den seitlichen Abstand von der neutralen Achse darstellt.

Es gibt auch einen Index, der als Querschnitts-Sekundärpolmoment bezeichnet wird und die Stärke des Querschnitts gegen "Verdrehen" angibt.

I_r = I_x + I_y \tag{3}

Kann berechnet werden als. Da es sehr viel ist, werde ich diese Stärke in das Experiment einbringen. "Verdrehen" ist leicht zu verstehen, wenn Sie sich die Rotationskraft vorstellen, die beim Drücken eines Lappens ausgeübt wird.

Die Einheit aller dieser drei Indikatoren ist m ^ 4. Dies liegt daran, dass das Quadrat der Distanzdifferenz [m ^ 2] durch die Fläche [m ^ 2] integriert wird.

Insbesondere im Fall eines einfachen rechteckigen Querschnitts ist das Querschnittssekundärmoment

Sie können intuitiv erkennen, dass es proportional zu ist.

Was passiert also in diesem Fall?

Visualisieren Sie zum besseren Verständnis zunächst das sekundäre Querschnittsmoment des Bildes mit allen Pixelwerten = 1,0 (Maximalwert).

Bild \Delta I_x \Delta I_y


I_x=1.000 (MAX)
I_y=1.000 (MAX)

Dabei ist $ \ Delta I_x $ die Auswirkung auf das sekundäre Querschnittsmoment $ I_x $ pro Pixeleinheit und $ \ Delta I_y $ die Auswirkung auf das sekundäre Querschnittsmoment $ I_y $ pro Pixel. Wenn Sie diese zusammenfassen, erhalten Sie $ I_x $ und $ I_y $.

Auch dieses Mal werden wir es von der metrischen Einheit trennen und dieses Quadrat als maximales sekundäres Querschnittsmoment von $ 1,0 $ festlegen.

Lassen Sie uns eine ähnliche Abbildung mit einigen Daten von MNIST anzeigen.

(Für Werte <0,0 <Pixelwert <1,0 ist die Annäherung, dass der Pixelwert und die Fläche proportional sind. Mit anderen Worten, wenn der Pixelwert "0,5" ist, hat die Hälfte der Pixel keinen Querschnitt, und wenn er "0,1" ist, fehlen 90%. * Dies ist zum Zeitpunkt des endgültigen Drucks eine andere Annäherung. )

Bild \Delta I_x \Delta I_y


I_x=0.112
I_y=0.093

I_x=0.060 I_y=0.036

"0" ist sowohl für $ I_x $ als auch für $ I_y $ hoch, aber Sie können sehen, dass die Stärke in vertikaler Richtung besonders stark ist. Im Gegenteil, "1" ist sowohl für $ I_x $ als auch für $ I_y $ niedrig, und es gibt insbesondere fast keine seitliche Stärke.

Bei der Berechnung des sekundären Querschnittsmoments hat die Festigkeit einen stärkeren Einfluss, wenn der Abstand von der neutralen Achse zunimmt, und der Einfluss nimmt ab, wenn der Abstand von der neutralen Achse zunimmt. In Anbetracht dessen wird die Tatsache, dass die meisten Strukturen auf der Welt hohl sind (der Inhalt ist matschig), weitgehend vom sekundären Querschnittsmoment beeinflusst.

Aus dem Obigen entsprechen typische Querschnitte mit hoher Festigkeit unter Unterdrückung des Materials und des Gewichts hohlen kreisförmigen / quadratischen und H-Typ / I-Typ (nur die Festigkeit einer Achse ist stark). Dieses Mal gibt es keine besonderen Einschränkungen wie das Gewicht des Materials. Die härteste Form ist also das ** "Quadrat" **, in das die Pixelwerte des Bildes gefüllt sind.

Wie behalten Sie die Form der Zahlen bei, während Sie ihre Stärke beibehalten?

3.2 Generative Adversarial Nets (Goodfellow et al., 2014)[2]

Die grundlegenden generativen kontradiktorischen Netze (= GAN) verwenden zwei Modelle neuronaler Netze, eines ist ein Generator, der eine Verteilung in der Nähe der Daten ausgibt, das andere ist ein Generator oder es wird für die Dateneingabe generiert. Es besteht aus einem Diskriminator, der bestimmt, ob es sich um eine Sache handelt oder nicht.

Je genauer das Urteil des Diskriminators ist, desto mehr ändert die Fehler-Backpropagation-Methode die Parameter des Generators, sodass der Generator eine datenähnlichere Verteilung erzeugen kann. Andererseits ist die Ungenauigkeit des Urteils des Diskriminators eine Strafe des Diskriminators selbst, und die Parameter werden geändert, um die Genauigkeit des Urteils zu verbessern.

Diese stammen aus der Formulierung [^ GAN] von Gleichung (4) von Goodfellow et al.

\min _{G} \max _{D} V(D, G)=\mathbb{E}_{\boldsymbol{x} \sim p_{\text {data }}(\boldsymbol{x})}[\log D(\boldsymbol{x})]+\mathbb{E}_{\boldsymbol{z} \sim p_{\boldsymbol{z}}(\boldsymbol{z})}[\log (1-D(G(\boldsymbol{z})))] \tag{4}

Um es auf den Punkt zu bringen: Wenn Sie dies auf die Bilddaten von Zahlen anwenden, lernt die Generatorseite, ein zahlenähnliches Bild zu generieren. Wenn das Lernen erfolgreich ist, werden sogar Zahlen generiert, die nicht im Datensatz vorhanden sind. ist.

Darüber hinaus wurden verschiedene Methoden für die GAN-Theorie und Lernmethoden entwickelt, die diesmal jedoch auf dem klassischen DCGAN [^ DCGAN] basieren. DCGAN ist kurz gesagt ein Artikel, der die grundlegende Methode von GAN auf ein Faltungsnetzwerk anwendet.

3.3 Danmen-GAN

Nachdem wir die grundlegende Technologie erklärt haben, schreiben wir die Logik zum Erstellen stabiler Zahlen.

Im normalen GAN-Training beträgt der Verlust am Generator Gleichung (5). Dies bedeutet, dass der Diskriminator das Ergebnis der Generatorerzeugung empfängt, wenn Rauschen eingegeben wird, und der Verlust mit der Rate zunimmt, mit der der Diskriminator richtig antwortet.

\mathcal{L}_{G} = \mathbb{E} [\log (1 - D(G(z))] \tag{5}

Da das Lernen jedoch nur so abläuft, dass Zahlen zufällig erzeugt werden, wird die Funktion $ S (\ cdot) $, die das sekundäre Moment des Querschnitts aus der Querschnittsform des Eingabebildes berechnet, und das erzeugte Querschnittsbild aufgenommen Erstellen Sie einen neuen Verlust $ \ mathcal {L} _ {S} $, sodass der Generator umso mehr bestraft wird, je niedriger das sekundäre Moment im Querschnitt ist.

\mathcal{L}_{S} = \mathbb{E} \left[\|1 - S(G(z))\|_{2}\right] \tag{6}

Wenn wir die Achsen von vertikalem x, horizontalem y und r in $ S (\ cdot) $ einführen und sie mit den Parametern α, β und γ gewichten, wird Gleichung (6) zu Gleichung (7). Werden.

\mathcal{L}_{S} = \alpha \cdot\mathbb{E} \left[|1 - S_x(G(z))|_2\right] + \beta \cdot\mathbb{E} \left[|1 - S_y(G(z))|_2\right] + \gamma \cdot\mathbb{E} \left[|1 - S_r(G(z))|_2\right]

Fügen Sie schließlich Gleichung (7) zum Verlust auf der Generatorseite von GAN hinzu, um Gleichung (8) zu erstellen, und es ist abgeschlossen.

\mathcal{L}_{All} = \mathcal{L}_{G} + \mathcal{L}_{S} \tag{8}

Unter Verwendung von Gleichung (8) als Zielfunktion des Generators besteht die Logik darin, dass das quadratische Moment des Querschnitts erhöht werden kann, während die Form der Zahlen im Querschnitt beibehalten wird.

4. Datenanalyse

Der Datensatz ist MNIST [^ MNIST]. Dieses Mal benötigen wir nur die Quelle der generierten Daten, daher verwenden wir nur die Trainingsdaten.

Zuerst möchte ich wissen, wie stark das Innere des Datensatzes ist, also werde ich es berechnen.

4.1 Globale Stärke

Durchschnittliches sekundäres Querschnittsmoment für jede Achse des gesamten Datensatzes $ \ mathbb {E} \ left [I_x \ right] $, $ \ mathbb {E} \ left [I_y \ right] $, $ \ mathbb {E} \ left Ich habe nach [I_r \ right] $ gefragt. Wir haben auch die Standardabweichungen der sekundären Querschnittsmomente $ \ sigma_ {Ix} $, $ \ sigma_ {Iy} $, $ \ sigma_ {Ir} $ für jede Statistik berechnet.

E[I_x] (\sigma_{Ix}) E[I_y] (\sigma_{Iy}) E[I_r] (\sigma_{Ir})
0.088(0.032) 0.063(0.034) 0.076(0.031)

Wenn ich mir diese Tabelle anschaue, habe ich das Gefühl, dass es je nach Daten einige Unterschiede im sekundären Querschnittsmoment gibt. Es ist auch ersichtlich, dass die Festigkeit in vertikaler Richtung größer ist als die in horizontaler Richtung insgesamt.

4.2 Stärke für jede Zahl

Als nächstes haben wir unter Berücksichtigung der Tatsache, dass die Form für jede Zahl vorgespannt ist, die statistischen Werte des sekundären Querschnittsmoments für jede Zahl zusammengefasst. Dies wird durch eine Reihe von Box-Whiskern und -Tabellen dargestellt. Für abnormale Werte wird keine Verarbeitung durchgeführt.

Number(n) E[I_{xn}] (\sigma_{Ixn}) E[I_{yn}] (\sigma_{Iyn}) $E[I_{rn}] $ (\sigma_{Irn})
0 0.121(0.029) 0.110(0.034) 0.116(0.030)
1 0.052(0.015) 0.020(0.014) 0.036(0.013)
2 0.107(0.031) 0.078(0.027) 0.093(0.027)
3 0.106(0.028) 0.066(0.026) 0.086(0.026)
4 0.064(0.018) 0.063(0.026) 0.064(0.021)
5 0.093(0.031) 0.065(0.024) 0.079(0.026)
6 0.083(0.022) 0.065(0.028) 0.074(0.024)
7 0.079(0.021) 0.053(0.022) 0.066(0.020)
8 0.105(0.027) 0.067(0.027) 0.086(0.026)
9 0.074(0.019) 0.054(0.024) 0.064(0.021)

Aus diesen können wir folgendes sehen.

4.3 Am stärksten und am schwächsten

Ich habe mit argmax / argmin nach der stärksten und der schwächsten Zahl gesucht.

Das stärkste ist natürlich "0", aber

allmax.png

Ist der Stift nicht zu breit ... Übrigens, $ I_x = 0,259 $, $ I_y = 0,244 $, $ I_r = 0,251 $, die in allen Feldern die Spitze sind. Die Person, die das geschrieben hat, ist stolz.

Als nächstes werde ich das schwächste von $ I_x $ vorstellen.

minIxa.png

Es ist "2", aber es ist zerquetscht. In Bezug auf die Berechnung denke ich, dass es auch die am meisten zerquetschte Zahl ist. Sieht schwach aus. ($ I_x = 0,013 $)

Und der schwächste von $ I_y $

minIy.png

Es ist zu dünn. Wenn Sie Kraft von der Seite ausüben, wird es brechen. ($ I_y = 0,0015 $ ← Ich habe die Ziffer gesenkt, weil sie zu klein ist.)

Schließlich der schwächste von $ I_r $

minIx.png

Auf den ersten Blick ähnelt es der vorherigen "1", ist aber leicht geneigt. ($ I_r = 0,010 $) Datensätze für maschinelles Lernen können eindeutig sein.

5. Experimentieren

Lass uns ein Experiment machen.

Ich habe mit TensorFlow 2.0 ein theoretisches Modell erstellt und GAN gelernt, indem ich die Verlustfunktion von Gleichung (8) auf den Generator angewendet habe. Das Modell wird als Bonus zum Anhang hinzugefügt. Ich habe den ganzen Code auf GitHub gestellt.

Version etc.

5.1 Verschiedene Parameter und Generierungsergebnisse

5.1.1 Danmen-GAN

Der minimale FID ist der minimale FID-Wert, der während des Trainings erreicht wird. (Je kleiner der FID, desto besser.) Zusätzlich ist das Vergleichsziel von FID das erzeugte Bild und die Trainingsdaten.

GAN-I_x-to-1.0 alpha (2).png

Die Grafik zeigt die Änderungen in $ I_x $, $ FID $ und $ \ frac {I_x} {FID} $, wenn α geändert wird (β = γ = 0). Aus diesem Diagramm wird deutlich, dass wir anstelle des sekundären Querschnittsmoments den FID opfern.

Änderung des Ausgabebildes (β = γ = 0). Je tiefer Sie gehen, desto stärker ist die vertikale Stärke.

\alpha Ausgabe(Letzte Epoche) Mindest-FID maximalI_x maximalI_y maximalI_r
\alpha=0 (Normales GAN) _vanillaGAN_24000_image.png 36.0 0.109 0.090 0.083
0.1 _I_x01_24000_image.png 36.9 0.106 0.082 0.095
1.0 _I_x1_24000_image.png 32.8 0.103 0.077 0.090
5.0 _I_x5_24000_image.png 59.5 0.126 0.097 0.111
10.0 _I_x10_24000_image.png 69.4 0.145 0.116 0.130
25.0 _I_x25_24000_image.png 96.0 0.193 0.160 0.176
50.0 _I_x50_24000_image.png 135.8 0.249 0.212 0.230
75.0 _I_x+75_24000_image.png 180.4 0.317 0.278 0.297
100.0 _I_x100_24000_image.png 208.7 0.374 0.354 0.364

Immerhin ist "0" stark. Ich denke, das liegt an der Verzerrung im Datensatz.

Auch ohne Verlust wird ein Querschnitt mit einem sekundären Querschnittsmoment erzeugt, das 20% über dem Durchschnitt von $ I_x $ liegt, so dass die Stärke des normalen GAN selbst in erster Linie verzerrt zu sein scheint. Dies kann auf das grundlegende Verhalten von GAN zurückzuführen sein, z. B. auf die Anfälligkeit für Rauschen.

Wenn Sie auf die Ebene $ \ alpha = 50.0 $ aufsteigen, ** scheint es, dass die Stärke der Ausreißerklasse der Originaldaten im Durchschnitt generiert werden kann. Ich bin daher der Meinung, dass dies auf die Datenerweiterung anwendbar ist, die eine kleine Anzahl von Daten mit GAN * generiert *. Zum Beispiel gibt es im Fall von medizinischen Diagnosebildern Bilder mit Kernspinresonanzverfahren T1 / T2, aber bei T1 scheint der Tumor ein wenig weiß auszusehen [^ T1], also durch Anwenden eines Verlusts, der den Pixelwert des Bildes erhöht. Es ist möglich, ein erzeugtes Bild mit einem extrem großen Tumor zu erstellen. Da sich danach die Eigenschaften des Gehirns usw. an der Außenseite (äußere Rille und Großhirnrinde) und an der Innenseite (Kaiba und Großhirnkanal) des Querschnitts ändern, sollte sich die Tendenz der Krankheit wahrscheinlich ändern. Auf diese Weise dachte ich, dass es möglich sein könnte, ein Bild mit einer Form nahe der Krankheit zu erzeugen, indem die GAN-Daten entsprechend der Zielkrankheit erweitert werden. (Ich weiß nichts über medizinische Versorgung, also könnte ich etwas Passendes sagen ...)

Beispiel für $ I_y $, $ I_r $

Parameter Ausgabe(Letzte Epoche) Mindest-FID maximalI_x maximalI_y maximalI_r
\beta=25.0, \alpha=\gamma=0 _I_y+25_24000_image.png 122.2 0.180 0.178 0.179
\beta=75.0, \alpha=\gamma=0 _I_y+75_24000_image.png 160.8 0.267 0.284 0.275
\gamma=25.0, \alpha=\beta=0 _I_r+25_24000_image.png 113.2 0.181 0.165 0.173
\gamma=75.0, \alpha=\beta=0 _I_r+75_24000_image.png 170.5 0.285 0.284 0.285

Diese haben auch eine starke "0". Andere Nummern wurden ordnungsgemäß veröffentlicht, sodass es unwahrscheinlich ist, dass es sich um einen Moduszusammenbruch handelt.

5.1.2 Zahlen schwächen

Durch Anwendung der Danmen-GAN-Theorie kann das gewünschte sekundäre Querschnittsmoment auf "0,0" eingestellt und die Festigkeit verringert werden. Dies kann durch Gleichung (9) ausgedrückt werden.

\mathcal{L}_{S} = \mathbb{E} \left[\| S(G(z))\|_{2}\right] \tag{9}

GAN-I_x-to-0.0 alpha (2).png

Dieses Diagramm zeigt die Änderungen in $ I_x $ und FID sowie in $ \ frac {1} {I_x \ times FID} $, wenn $ \ alpha $ geändert wird (β = γ = 0). Die Reduzierung des sekundären Querschnittsmoments geht ebenfalls zu Lasten von FID. Dies liegt daran, dass die Abweichung von der Verteilung der Originaldaten der Zunahme entspricht.

Änderungen im Ausgabebild ($ \ beta = \ gamma = 0 $)

\alpha Ausgabe(Letzte Epoche) Mindest-FID MinimumI_x MinimumI_y MinimumI_r
0.1 _I_x-01_24000_image.png 38.6 0.093 0.058 0.076
1.0 _I_x-1_24000_image.png 40.5 0.091 0.058 0.073
5.0 _I_x-5_24000_image.png 35.3 0.084 0.050 0.067
10.0 _I_x-10_24000_image.png 36.4 0.086 0.053 0.070
25.0 _I_x-25_24000_image.png 30.0 0.069 0.042 0.056
50.0 _I_x-50_24000_image.png 41.5 0.062 0.033 0.048
100.0 _I_x-100_24000_image.png 48.6 0.055 0.026 0.040
500.0 _I_x-500_24000_image.png 112.4 0.043 0.013 0.028

Schließlich besteht die Tendenz, dass viele "1", die ursprünglich eine geringe Stärke haben, auftreten. Außerdem fühle ich mich schlank.

Die Skalierung des Parameters hat sich seit dem Verstärken des Sekundärmoments des Querschnitts geändert, und es scheint, dass dies weniger beeinflusst wird, selbst wenn es stark angewendet wird (wahrscheinlich aufgrund des Pixelverhältnisses).

Beispiel für $ I_y $, $ I_r $

Parameter Ausgabe(Letzte Epoche) Mindest-FID MinimumI_x MinimumI_y MinimumI_r
\beta=25.0, \alpha=\gamma=0 _I_y+25_24000_image.png 32.0 0.079 0.047 0.063
\beta=500.0, \alpha=\gamma=0 _I_y-500_24000_image.png 136.3 0.049 0.015 0.032
\gamma=25.0, \alpha=\beta=0 _I_r+25_24000_image.png 30.2 0.074 0.047 0.061
\gamma=500.0, \alpha=\beta=0 _I_r-500_24000_image.png 139.7 0.046 0.013 0.030

Dies ist eine Möglichkeit, aber ich denke, wenn Sie einen Verlust auf den Wert setzen, der die Intensität verringert, wird ** das Rauschen unterdrückt und der FID verbessert **. Insbesondere hat die Berechnung des sekundären Moments des Querschnitts die Eigenschaft, einen starken Verlust auf den Rand des Bildschirms auszuüben, und CNN führt verdächtige Dinge wie das Auffüllen bei der Verarbeitung des Randes des Bildschirms aus, so dass die Möglichkeit besteht, dass die Kompatibilität im Netz liegt. Es gibt. Insbesondere kann das Sekundärpolmoment $ I_r $ im Querschnitt wirksam sein, da es die gesamte Kante des Bildschirms beeinflusst.

Dies kann nur ein Zufall sein, also werde ich persönlich tiefer graben.

5.2 Moment des zweiten Abschnitts gegen FID

Wir haben bestätigt, wie stark der Anstieg des FID in Bezug auf die Dehnung des sekundären Moments des Querschnitts unterdrückt wurde. $ \ frac {I_x} {FID} $ erhält die größte im Training. Es scheint, dass der FID als Reaktion auf eine leichte Zunahme des Sekundärmoments des Querschnitts explodiert. Statt an Stärke zu gewinnen, weicht er von der Verteilung der Originaldaten ab.

\alpha \frac{I_x}{FID}
\alpha=0.0 0.00250
\alpha=0.1 0.00250
\alpha=1.0 0.00277
\alpha=5.0 0.00207
\alpha=10.0 0.00220
\alpha=25.0 0.00180
\alpha=50.0 0.00150
\alpha=75.0 0.00130
\alpha=100.0 0.00120
ones 0.00257

Einer ist der Querschnitt, wenn alles 1.0 ist. Die FID betrug zu diesem Zeitpunkt 394,5. In diesem Fall ist die Leistung von $ \ frac {I_x} {FID} $ besser, wenn die gesamte Ausgabe 1.0 ist oder wenn die Ausgabe einfach ist. Im Gegenteil, wenn Sie eine Ebene erstellen, um die FID zu berechnen und $ \ frac {I_x} {FID} $ als Verlust zu entwerfen, erscheint es interessant, dass wieder unterschiedliche Ergebnisse erzielt werden. (Ich konnte eine FID-Ebene erstellen [^ fidlayer], aber ich habe sie gestoppt, weil der Teil, der die Quadratwurzel der Matrix findet, zu einem Engpass bei der Berechnung wurde. Im Prinzip ist dies möglich.)

Am Ende ist es uns gelungen, mehr als den stärksten Abschnitt des Datensatzes zu generieren, aber wir haben die Generierung eines Abschnitts, der schwächer als der schwächste ist, noch nicht bestätigt (obwohl wir möglicherweise einen stärkeren Verlust erzielen können).

6. Drucken mit einem 3D-Drucker

Da es eine große Sache ist, drucken wir es mit einem 3D-Drucker und überprüfen die Stärke.

Ich habe ein Modell namens Ender-3 verwendet, das auf Online-Shopping-Sites zwischen 20.000 und 30.000 liegt.

6.1 Führen Sie TensorFlow 2.0 mit Blender aus und generieren Sie automatisch Zahlenpolygone

Auf der Mixerseite wird die automatische Generierung wie folgt durchgeführt. Das Bild unten ist die erste "0" in den MNIST-Daten.

1.png

Der dem Pixel entsprechende Teil wird automatisch mit "add_cube" generiert. (Da die Methode ziemlich rau ist, scheint es, dass der 3D-Shop wütend wird)

Das Bild unten ist eine "8" -ähnliche Zahl, die von Danmen-GAN mit einer Strafe von $ \ alpha = 75 $ generiert wurde. Mit einem Modul namens "bpy" können Sie die API von Blender in Python bearbeiten, sodass Python on Blender das trainierte Modell von TensorFlow lädt und es im laufenden Betrieb generiert. Sehr angenehm.

2.png

Pixelwerte unter "0,25" sind "0", Pixelwerte zwischen "0,25 und 0,75" werden zufällig auf 3/4 der Fläche perforiert (leicht perforiert, um die Festigkeit zu verringern) und Pixelwerte über "0,75" Ist eine Heuristik mit 1.0, um vorerst mehrdeutige Pixel zu verarbeiten.

Teile, die nicht mit der Festigkeit zusammenhängen, werden manuell entfernt. (Zur Verbesserung der Druckeffizienz)

3.png

Das Folgende ist der Querschnitt nach der Vorbereitung.

Ich habe so etwas wie ein Fragment unter der Nummer mit dem Bild eines Sockels zum Befestigen der Mitglieder gemacht. Dies geschieht durch Invertieren der Pixel der Zahl (1.0 --img), Aufrunden mit np.ceil (), Anwenden der Verkleinerung von Scikit-Bildern (skimage.morphology.binary_erosion), Anpassen und Es ist eine Menge mit der for-Anweisung.

Unten sehen Sie den Bildschirm einer Software namens Cura, die Gcode (3D-Druckerdüsensteuerungsbefehl) für 3D-Drucker generiert.

Ursprünglich habe ich es mit einer Gesamtlänge von 60 mm gemacht, aber da die Druckzeit 3-4 Stunden betrug, habe ich es um 40% reduziert und gedruckt. (Da Cura grundlegende Modelloperationen wie die Skalierung ausführen kann, muss sich Blender nicht um die Skalierung kümmern.)

6.2 Ergebnis drucken

Die linke Seite ist "0" und die rechte Seite ist "8". (Mir ist hier aufgefallen, dass die Basis von "8" links und rechts getrennt ist.)

IMG_4978.JPG

IMG_1209.JPG

IMG_6556.JPG

(Ich bemerkte, dass "8" stabil wurde, als ich es umdrehte.)

Es ist so.

6.3 Ausdauer

Machen wir auch einen Ausdauertest. Ich habe im halbgebackenen Stresstest keine leichte Bewegung gemacht, also habe ich mich endlich darauf konzentriert, weil es keinen anderen Weg gab.

"0" im Datensatz

ezgif-2-632e2eb25ad3-compressor.gif

Generierte Nummer

ezgif-2-aaaf95b89279-compressor.gif

Beide haben gebrochen ... (Ich bedauere, dass ich den stärkeren gefunden hätte, wenn ich beide gleichzeitig belastet hätte. Derzeit basiert das Ergebnis der GAN-Generierung auf einem zufälligen Startwert, sodass es leicht zu reproduzieren ist. )

Als ich den Querschnitt überprüfte, waren beide entlang der laminierten Oberfläche des Filaments des 3D-Druckers gebrochen.

7. Schlussfolgerung

Fazit

Neue Hypothese im Experiment erhalten

8. Fazit

Dieses Mal habe ich es mit MNIST versucht, um das Verständnis und die Komplexität des Lernens von GAN zu erleichtern, aber ich denke, dass es theoretisch auf andere Daten angewendet werden kann.

Da diese voreingenommen sind, denke ich auch, dass es notwendig ist, sie mit bedingtem GAN usw. zu konditionieren, um die gewünschte Anzahl zu erhalten, während die Stärke manipuliert wird. Als Anwendung sollte es logisch möglich sein, dem Konditionierungsteil des bedingten GAN Festigkeitsinformationen zu geben und einen Querschnitt entsprechend dieser Festigkeit zu erzeugen.

Wenn ich diese schließlich mit FEM (= Finite-Elemente-Methode) anwende, das Gleichgewicht der Strukturkräfte berechne und Verluste hinzufüge, denke ich, dass sie auch auf dreidimensionale Strukturen angewendet werden können. (Bitte lassen Sie mich wissen, wenn Sie es bereits haben)

Ich denke, es passt gut zu "StackGAN font alchemy [^ nardtree]", das nardtree gemacht hat.

9. Danke

Shichiya-san (@ sitiya78): Der 3D-Drucker ist eine persönliche Amazon-Wunschliste. Vielen Dank für diesen Abschnitt. Ich kann Ihnen nicht genug danken.

10. Experimenteller Code

Hier: Ich werde alles unter https://github.com/p-geon/DanmenGAN einfügen.

--Statistische Berechnung: https://github.com/p-geon/DanmenGAN/tree/master/calcstats

Appendix

Bonus

A. Über die Schichtstruktur von TensorFlow

Beschreibt die Schichtstruktur von TensorFlow 2.0. Ich werde ungefähr drei Dinge erklären: Generator / Diskriminator / Generator & Diskriminator. Für Enthusiasten.

A-1. Generator

(Klicken Sie auf das Bild, um die Details anzuzeigen.)

Generator ist ungefähr ein Diagramm, das Bilder generiert ( Generator </ font>), ein normalisiertes Diagramm ( Normalisieren </ font>) und ein Diagramm, das die Dichte berechnet ( Normalisieren </ font>). Dichte </ font>), Diagramm zum Ermitteln des sekundären Querschnittsmoments $ I_x $ ( Ix </ font>), Ermitteln des sekundären Querschnittsmoments $ I_y $ Es kann in ein Diagramm ( Iy </ font>) und ein Diagramm $ I_r $ ( Ir </ font>) unterteilt werden, um das Sekundärpolmoment des Querschnitts zu ermitteln.

Generator: Bilderzeugungsdiagramm ~ Normalisierungsdiagramm

Unten finden Sie den Code vom Bildgenerator zur Normalisierung des Generators.

Die Grundlagen sind die gleichen wie bei normalem GAN. Außerdem gibt es im Internet viele Informationen über GAN, daher werde ich sie hier weglassen.

"smoa" ist eine Klasse zur Berechnung des sekundären Querschnittsmoments, und innerhalb dieser Klasse werden die Dichteberechnung und das sekundäre Querschnittsmoment berechnet.

def build_generator(params, smoa):
    # Noise
    z = z_in = tf.keras.layers.Input(shape=(params.NOISE_DIM, ), name="noise")

    # (NOISE_DIM, ) -> (1024, )
    x = tf.keras.layers.Dense(1024)(z)
    x = tf.keras.layers.LeakyReLU(alpha=0.2)(x)
    x = tf.keras.layers.BatchNormalization(momentum=0.8)(x)

    # (1024, ) -> (7*7*64, ) -> (7, 7, 64)
    x = tf.keras.layers.Dense(7*7*64)(z)
    x = tf.keras.layers.LeakyReLU(alpha=0.2)(x)
    x = tf.keras.layers.BatchNormalization(momentum=0.8)(x)
    x = tf.keras.layers.Reshape(target_shape=(7, 7, 64))(x)

    # (7, 7, 64) -> (14, 14, 32)
    x = tf.keras.layers.Conv2DTranspose(32, kernel_size=(5, 5)
        , padding='same', strides=(2, 2), use_bias=False, activation=None)(x)
    x = tf.keras.layers.BatchNormalization(momentum=0.8)(x)
    x = tf.keras.layers.LeakyReLU(alpha=0.2)(x)

    # (14, 14, 128) -> (28, 28, 1)
    x = tf.keras.layers.Conv2DTranspose(1, kernel_size=(5, 5)
        , padding='same', strides=(2, 2), use_bias=False, activation=None)(x)
    img = tf.math.tanh(x)
    y = tf.keras.layers.Lambda(lambda x: x, name="generated_image")(img) #Da img später verwendet wird, ändern Sie den Variablennamen in y

    """
Berechnung des Querschnittssekundärmoments(Es wird ein Diagramm wie ResNet)
    """
    # range: [-1.0, 1.0] -> [0.0, 1.0]
    img = (img + 1.0)/2.0
    I_x, I_y, I_r = smoa.calc_second_moment_of_area(img)

    return tf.keras.Model(inputs=z_in, outputs=[y, I_x, I_y, I_r])

Generator: Dichteberechnungsdiagramm ~ Abschnitt Sekundärmomentberechnungsdiagramm

Das Folgende ist eine Graphkonstruktionsmethode, die das sekundäre Querschnittsmoment nur durch Tensorberechnung erhält.

Berechnen Sie zuerst die Konstanten im Berechnungsdiagramm und bereiten Sie zuerst den Tensor vor, indem Sie "tf.constant ()" als Klassenvariable verwenden.

Verwenden Sie "self.arange_x", "self.arange_y", "self.distance_matrix_x", "self.distance_matrix_y", "self.norm_I_x", "self.norm_I_y".

Als Beschreibung der Variablen

--self.arange_x / self.arange_y: Einfach geordnete Vektoren --self.distance_matrix_x / self.distance_matrix_y: Tensol, das den Abstand von der Achse darstellt --self.norm_I_x / self.norm_y: Maximales sekundäres Querschnittsmoment für die Normalisierung (skalar)

Es wird sein.

class SecondMomentOfArea:
    def __init__(self, img_shape=(28, 28)):
        distance_vector_x = np.asarray([0.5+d for d in range(img_shape[1])])
        distance_matrix_x = np.tile(distance_vector_x, (img_shape[0], 1))
        distance_matrix_y = distance_matrix_x.T
        """
Matrix zur Normalisierung
        """
        matrix_for_norm_I_x = np.tile(np.abs(arange_y - img_shape[0]/2.0), (img_shape[1], 1)).T
        norm_I_x = np.sum(matrix_for_norm_I_x)

        matrix_for_norm_I_y = np.tile(np.abs(arange_x - img_shape[1]/2.0), (img_shape[0], 1)).T
        norm_I_y = np.sum(matrix_for_norm_I_y)

        """
        to TFconstant
        """
        self.arange_x = tf.constant(arange_x, dtype=tf.float32) # (28, )
        self.arange_y = tf.constant(arange_y, dtype=tf.float32) # (28,)
        self.distance_matrix_x = tf.constant(distance_matrix_x[np.newaxis, :, :, np.newaxis], dtype=tf.float32) # (1, 28, 28, 1)
        self.distance_matrix_y = tf.constant(distance_matrix_y[np.newaxis, :, :, np.newaxis], dtype=tf.float32) #(1, 28, 28, 1)
        self.norm_I_x = tf.constant(norm_I_x, dtype=tf.float32) #()
        self.norm_I_y = tf.constant(norm_I_y, dtype=tf.float32) #()

Wenn Sie die Distanzmatrix normalisieren und "[0,:,:, 0]" beschneiden, sieht die Abbildung wie folgt aus.

distance_matrix_x distance_matrix_y

Ich werde die Fortsetzung der vorherigen Klasse schreiben.

Um das Sekundärmoment des Querschnitts zu berechnen, muss zunächst der Schwerpunkt (neutrale Achse) des Querschnitts berechnet werden. Berechnen Sie dann die Dichte (Summe aller Pixel / Anzahl der Pixel im Bild), um die neutrale Achse zu berechnen.

Multiplizieren Sie zunächst die "distance_matrix" und den Pixelwert des Bildes mit jedem Element, um den Moment zu erhalten. Als nächstes wird das Moment unter Verwendung der Dichte korrigiert, und wenn die Momente gerade sind, befindet sich die neutrale Achse in der Mitte des Bildes.

Erstellen Sie nach der Berechnung der neutralen Achse einen Tensor, der den Abstand zur neutralen Achse in der Reihenfolge Subtraktion → Absolutwert → Transformation → Binden → Addieren der Achse darstellt.

Berechnen Sie danach den Tensor und das Bild, die den Abstand darstellen, indem Sie jedes Element multiplizieren, die Summe berechnen und normalisieren. Die Berechnung des quadratischen Querschnittsmoments ist abgeschlossen.

Die Berechnung des sekundären Querschnittspolmoments $ I_r $ wird normalisiert, indem $ I_x $ und $ I_y $ wie definiert addiert werden, so dass das Maximum 1,0 beträgt.

tf.keras.layers.Lambda (lambda x: x) (・) tut nichts, sondern wurde geschrieben, um die Sichtbarkeit der Ebenen zu verbessern.

    def calc_second_moment_of_area(self, img): # (None, 28, 28, 1)
        """
Berechnung der neutralen Achse
        """
        density = (tf.reduce_sum(img, axis=[1, 2], keepdims=True)/(img.shape[1]*img.shape[2]))
        # (1, 28, 28, 1) x (None, 28, 28, 1) -> (None, 28, 28, 1)
        x_moment = tf.math.divide_no_nan(tf.math.multiply(self.distance_matrix_x, img), density)
        y_moment = tf.math.divide_no_nan(tf.math.multiply(self.distance_matrix_y, img), density)

        # (None, 28, 28, 1) -> (None, )
        neutral_axis_x = tf.math.reduce_mean(x_moment, axis=[1, 2])
        neutral_axis_y = tf.math.reduce_mean(y_moment, axis=[1, 2])

        """
Sekundäres Schnittmoment(Vertikal)
        I_x = ∫_A y^2 dA
        """
        # sub: (None, 28, ) - (None, ) -> abs: (None, 28)
        dy = tf.math.abs(self.arange_y - neutral_axis_y)
        # (None, 28) -> (None, 1, 28)
        dy = tf.reshape(dy, shape=[-1, img.shape[1], 1])
        # (None, 1, 28) -> (None, 28, 28)
        matrix_x = tf.tile(dy, multiples=[1, 1, img.shape[2]])
        # (None, 28, 28) -> (None, 28, 28, 1)
        matrix_x = tf.expand_dims(matrix_x, 3)
        # (None, 28, 28, 1)x(None, 28, 28, 1) -> (None, 28, 28, 1) -> (None,)
        I_x = tf.math.reduce_sum(tf.math.multiply(matrix_x, img), axis=[1, 2])/self.norm_I_x

        """
Sekundäres Schnittmoment(Seite)
        I_y = ∫_A x^2 dA
        """
        # sub: (None, 28, ) - (None, ) -> abs: (None, 28)
        dx = tf.math.abs(self.arange_x - neutral_axis_x)
        # (None, 28) -> (None, 28, 1)
        dx = tf.reshape(dx, shape=[-1, 1, img.shape[2]])
        # (None, 1, 28) -> (None, 28, 28)
        matrix_y = tf.tile(dx, multiples=[1, img.shape[1], 1])
        # (None, 28, 28) -> (None, 28, 28, 1)
        matrix_y = tf.expand_dims(matrix_y, 3)
        # (None, 28, 28, 1)x(None, 28, 28, 1) -> (None, 28, 28, 1) -> (None,)
        I_y = tf.math.reduce_sum(tf.math.multiply(matrix_y, img), axis=[1, 2])/self.norm_I_y
        """
Abschnitt Sekundärpolmoment(2 zur Normalisierung.Teilen Sie durch 0)
        """
        I_r = (I_x + I_y)/2.0
        """
        Lambda
        """
        I_x = tf.keras.layers.Lambda(lambda x: x, name="I_x")(I_x)
        I_y = tf.keras.layers.Lambda(lambda x: x, name="I_y")(I_y)
        I_r = tf.keras.layers.Lambda(lambda x: x, name="I_z")(I_r)

        return I_x, I_y, I_r

Bei der Erzeugung auf der Mixerseite muss das Sekundärmoment des Querschnitts nicht berechnet werden, sodass Sie drei Tensoren von "(None,)" mit einer geeigneten Funktion ausgeben können. Ich habe es mit tf.reduce_sum (img) verarbeitet.

A-2. Discriminator

Der Diskriminator unterscheidet sich nicht von einem normalen GAN. Es ist ein klassischer DCGAN-Stil.

A-3. Generator & Discriminator

Wir werden auch ein Diagramm erstellen, das Generator und Diskriminator kombiniert, um GAN zu trainieren.

Die Eingabe ist nur Rauschen "z", und die Ausgabe sind die vorhergesagten Wahrscheinlichkeiten "p" und "I_x", "I_y", "I_r", die vom Diskriminator ausgegeben werden.

Die drei Arten von sekundären Querschnittsmomenten können berechnet und die Koeffizienten angepasst werden, wenn der Verlust angewendet wird, sodass Sie normales GAN lernen und die sekundären Querschnittsmomente verstärken können. .. Wenn Sie das sekundäre Querschnittsmoment schwächen möchten, können Sie den Zielwert von $ I $ von "1,0" auf "0,0" ändern.

Referenzmaterial

Hauptsächlich meine Notizen, die ich geschrieben habe, um dies zu machen

  • Bei Verwendung von tf.print () kann der Inhalt des Tensors nicht in f-Zeichenfolge angezeigt werden: https://qiita.com/HyperPigeon/items/007c5adca9a4e78bc6d1
  • Erste Hilfe, wenn Nan in tf.linalg.sqrtm () der FID-Berechnung (TensorFlow 2.0 Frechet Inception Distance) erscheint: https://qiita.com/HyperPigeon/items/f3f20f480269e2594724 --AttributeError: Das Objekt 'dict' hat bei Verwendung von tf.keras.utils.plot_model () in TensorFlow 2.0 und seiner Lösung kein Attribut 'name': https://qiita.com/HyperPigeon/items/fb22b555e76b52b3d688
  • Lösung, wenn die Sitzung des Labors (Jupyter Notebook) mit tensorflow_addons (tfa.image.rotate) abstürzt: https://qiita.com/HyperPigeon/items/94831b8a9af75527b67b
  • Notation der Abmessungen (Meter usw.) in Blender 2.8 und höher: https://qiita.com/HyperPigeon/items/c5d2ec3264e8fd14d167
  • Installieren Sie TensorFlow 2.0 (CPU) mit Blender 2.8.2, HelloWorld (Windows 10): https://qiita.com/HyperPigeon/items/e6c37dc143039b75d0e4

  1. LeCun, Yann and Cortes, Corinna. MNIST handwritten digit database, 2010. ↩︎

  2. Ian Goodfellow, Jean Pouget-Abadie, Mehdi Mirza, Bing Xu, David Warde-Farley, Sherjil Ozair,Aaron Courville, and Yoshua Bengio. Generative Adversarial Networks. In NIPS, 2014. ↩︎