Heimnetzwerk | Implementierung von GoogleNet in Keras

Inhalt

Einführung

Deep Learning gewinnt schnell an Bedeutung, da immer mehr Forschungsarbeiten aus der ganzen Welt erscheinen.. Zweifellos, diese Dokumente enthalten viele Informationen, aber sie können oft schwer zu analysieren sein. Und um sie zu verstehen, Möglicherweise müssen Sie dieses Dokument mehrmals überprüfen (Und vielleicht noch andere abhängige Dokumente!).

Dies ist wirklich eine gewaltige Aufgabe für Nicht-Akademiker wie uns..

Nachbearbeitung-dieser-300x225-6282215

Persönlich, Ich finde die Aufgabe, einen Forschungsartikel zu rezensieren, interpretieren Sie die Crux dahinter und implementieren Sie den Code als eine wichtige Fähigkeit, die jeder Deep-Learning-Enthusiast und -Praktiker besitzen sollte. Die praktische Umsetzung von Forschungsideen bringt den Denkprozess des Autors zum Vorschein und hilft auch, diese Ideen in reale Industrieanwendungen zu überführen..

Dann, In diesem Artikel (und die folgende Artikelserie) mein grund zu schreiben ist zweierlei:

  1. Lassen Sie die Leser mit der neuesten Forschung Schritt halten, indem Sie Deep-Learning-Artikel in verständliche Konzepte aufteilen.
  2. Lerne, Forschungsideen für mich selbst zu programmieren und ermutige die Leute, dies gleichzeitig zu tun.

In diesem Artikel wird davon ausgegangen, dass Sie die Grundlagen von Deep Learning gut verstehen.. Falls du es nicht brauchst, oder brauche einfach eine Auffrischung, Überprüfen Sie zuerst die folgenden Punkte und kommen Sie dann bald wieder hierher:

Inhaltsverzeichnis

  • Dokumentzusammenfassung “Tauchen Sie ein in Windungen”
    • Ziel der Arbeit
    • Vorgeschlagene architektonische Details
    • Trainingsmethodik
  • GoogLeNet-Implementierung in Keras

Dokumentzusammenfassung “Tauchen Sie ein in Windungen”

Dieser Artikel konzentriert sich auf Papier “Mit Windungen tiefer graben” woher die unverwechselbare Idee des Homenet kam. Das Heimnetzwerk galt einst als Architektur (das Model) Deep Learning der nächsten Generation zur Lösung von Bilderkennungs- und Erkennungsproblemen.

Herausragende bahnbrechende Leistung bei der ImageNet Visual Recognition Challenge (In 2014), Dies ist eine renommierte Plattform für das Benchmarking von Bilderkennungs- und -erkennungsalgorithmen. zusammen mit, Es wurde viel geforscht, um neue Deep-Learning-Architekturen mit innovativen und wirkungsvollen Ideen zu schaffen.

Wir werden die wichtigsten Ideen und Vorschläge des oben genannten Dokuments überprüfen und versuchen, die darin enthaltenen Techniken zu verstehen. In den Worten des Autors:

“In diesem Artikel, Wir werden uns auf eine effiziente Deep Neural Network Architektur für Computer Vision konzentrieren, dessen Codename Inception ist, was seinen Namen ableitet (…) das berühmte Internet-Meme” wir müssen tiefer gehen “.

a88-1164825

Das klingt faszinierend, Nein? Gut, Dann lies weiter!

Ziel der Arbeit

Es gibt eine einfache, aber leistungsstarke Möglichkeit, bessere Deep-Learning-Modelle zu erstellen. Du kannst einfach ein größeres Modell machen, entweder in Bezug auf die Tiefe, nämlich, Anzahl der Schichten, oder die Anzahl der Neuronen in jeder Schicht. Aber wie kannst du dir das vorstellen, das kann oft zu komplikationen führen:

  • Je größer das Modell, anfälliger für Überanpassung. Dies macht sich besonders bemerkbar, wenn die Trainingsdaten klein sind..
  • Wenn Sie die Anzahl der Parameter erhöhen, müssen Sie Ihre vorhandenen Rechenressourcen erhöhen

Eine Lösung dafür, wie das Dokument vorschlägt, ist der Wechsel zu lose verbundenen Netzwerkarchitekturen, die vollständig verbundene Netzwerkarchitekturen ersetzen werden, insbesondere innerhalb von Faltungsschichten. Diese Idee kann in den folgenden Bildern konzeptualisiert werden:

screenshot-from-2018-10-16-10-52-13-206x300-3658357

Dicht vernetzte Architektur

screenshot-from-2018-10-16-10-52-30-300x165-1701673

Schwach vernetzte Architektur

Dieser Artikel schlägt eine neue Idee zum Erstellen tiefer Architekturen vor. Dieser Ansatz ermöglicht es Ihnen, beizubehalten “Rechenbudget”, bei gleichzeitiger Erhöhung der Tiefe und Breite des Netzes. Klingt zu schön um wahr zu sein! So sieht die konzeptionierte Idee aus:

googlenet-1196311

Schauen wir uns die vorgeschlagene Architektur etwas genauer an.

Vorgeschlagene architektonische Details

Das Dokument schlägt eine neue Art von Architektur vor: GoogLeNet oder Inception v1. Es ist im Grunde ein konvolutionelles neuronales Netzwerk (CNN) Was stimmt damit nicht 27 Schichten tief.. Unten ist die Zusammenfassung des Modells:

screenshot-from-2018-10-16-11-24-42-74x300-3793794

Beachten Sie im obigen Bild, dass es eine Ebene gibt, die als Startebene bezeichnet wird. Dies ist eigentlich die Hauptidee hinter dem Fokus des Dokuments. Die erste Schicht ist das zentrale Konzept einer schlecht vernetzten Architektur.

screenshot-from-2018-10-16-10-52-30-300x1651-300x165-3297392

Idee eines Startermoduls

Lassen Sie mich etwas genauer erklären, worum es bei einer Startup-Schicht geht. Auszug aus dem Artikel:

“(Ebene starten) es ist eine Kombination all dieser Schichten (nämlich, Faltdeckel 1 × 1, Faltdeckel 3 × 3, Faltdeckel 5 × 5) mit ihren Ausgangsfilterbänken zu einem einzigen Ausgangsvektor verkettet, der die Eingabe des folgenden Szenarios bildet.”

Zusammen mit den oben genannten Schichten, Es gibt zwei Haupt-Plugins in der ursprünglichen Startebene:

  • Faltdeckel 1 × 1 bevor Sie eine weitere Schicht auftragen, die hauptsächlich zur Dimensionsreduktion verwendet wird
  • Eine parallele maximale Gruppierungsschicht, die eine weitere Option für die Startschicht bietet
screenshot-from-2018-10-17-11-14-10-3445962

Ebene starten

Die Bedeutung der Struktur der Anfangsschicht verstehen, der Autor greift auf das hebbische Prinzip des menschlichen Lernens zurück. Das sagt das “Neuronen, die zusammen feuern, sie verbinden sich”. Der Autor schlägt vor, dass Beim Erstellen einer Beitragsebene in einem Deep-Learning-Modell, Es sollte auf die Erkenntnisse aus der vorherigen Schicht geachtet werden.

Vermuten, zum Beispiel, dass eine Schicht unseres Deep-Learning-Modells gelernt hat, sich auf einzelne Teile eines Gesichts zu konzentrieren. Die nächste Schicht des Netzwerks würde sich wahrscheinlich auf das allgemeine Gesicht des Bildes konzentrieren, um die verschiedenen dort vorhandenen Objekte zu identifizieren. Jetzt, um dies zu tun, der Layer muss die entsprechenden Filtergrößen haben, um verschiedene Objekte zu erkennen.

cat_vs_dog_explain4-300x231-5284051

Hier kommt die erste Schicht in den Vordergrund. Ermöglicht den inneren Schichten die Auswahl der Filtergröße, die relevant ist, um die erforderlichen Informationen zu kennen. Dann, auch wenn die größe des gesichts auf dem bild unterschiedlich ist (wie auf den Bildern unten zu sehen), der Umhang funktioniert entsprechend, um das Gesicht zu erkennen. Für das erste Bild, du bräuchtest wahrscheinlich eine höhere Filtergröße, während ich für das zweite Bild ein niedrigeres nehmen würde.

screenshot-from-2018-10-17-11-42-40-300x103-5993337

Allgemeine Architektur, mit allen Spezifikationen, es sieht aus wie das:

screenshot-from-2018-10-16-11-56-41-300x163-9994576

Trainingsmethodik

Beachten Sie, dass diese Architektur größtenteils darauf zurückzuführen ist, dass die Autoren an einer Herausforderung zur Bilderkennung und -erkennung teilgenommen haben.. Deswegen, Es gibt viele “Schnickschnack” die sie im Dokument erklärt haben. Diese beinhalten:

  • Die Hardware, mit der sie die Modelle trainiert haben.
  • Die Datenerweiterungstechnik zum Erstellen des Trainingsdatensatzes.
  • Die Hyperparameter des neuronalen Netzes, wie die Optimierungstechnik und das Lernratenprogramm.
  • Zusatzausbildung zum Trainieren des Modells erforderlich.
  • Montagetechniken, mit denen sie die Abschlusspräsentation erstellt haben.

Dazwischen, Die von den Autoren durchgeführte Hilfsausbildung ist von Natur aus sehr interessant und neu. Deshalb konzentrieren wir uns vorerst darauf.. Die Details der restlichen Techniken können dem Artikel selbst entnommen werden, oder in der Implementierung, die wir unten sehen werden.

Um zu verhindern, dass der mittlere Teil des Netzwerks "verschwindet", die Autoren führten zwei Hilfsklassifikatoren ein (die lila Quadrate im Bild). Grundsätzlich, legte Softmax auf die Ausgänge von zwei der Startermodule und berechnete einen Hilfsverlust auf den gleichen Labels. Die Gesamtverlustfunktion ist eine gewichtete Summe aus Hilfsverlust und tatsächlichem Verlust. Der auf dem Papier verwendete Gewichtswert war 0,3 für jeden Hilfsverlust.

GoogLeNet-Implementierung in Keras

Jetzt haben Sie die GoogLeNet-Architektur und die Intuition dahinter verstanden, Es ist an der Zeit, Python zu starten und unsere Erkenntnisse mit Keras umzusetzen!! Dazu verwenden wir den CIFAR-10-Datensatz.

cifar-9579521

CIFAR-10 ist ein beliebter Datensatz zur Bildklassifizierung. Es besteht aus 60.000 Bilder von 10 Lektionen (jede Klasse wird im obigen Bild als Zeile dargestellt). Der Datensatz ist unterteilt in 50.000 Trainingsbilder und 10.000 Testbilder.

Denken Sie daran, dass Sie die erforderlichen Bibliotheken installiert haben müssen, um den Code zu implementieren, den wir in diesem Abschnitt sehen werden. Dazu gehören Keras und TensorFlow (als Backend für Keras). Sie können das überprüfen offizielle Installationsanleitung falls Sie Keras noch nicht auf Ihrem Computer installiert haben.

Jetzt haben wir uns um die Voraussetzungen gekümmert, wir können endlich damit beginnen, die Theorie zu codieren, die wir in den vorherigen Abschnitten behandelt haben. Als erstes müssen wir alle notwendigen Bibliotheken und Module importieren, die wir im gesamten Code verwenden werden.

importieren schwer
von harte.Schichten.Kern importieren Schicht
importieren keras.backend wie K
importieren Tensorfluss wie tf
von harte.datensätze importieren cifar10
von hart.models importieren Modell
von harte.schichten importieren Conv2D, MaxPool2D,  
    Aussteigen, Dicht, Eingang, verketten,      
    GlobalAveragePooling2D, DurchschnittPooling2D,
    Ebnen

importieren cv2 
importieren numpy wie z.B 
von harte.datensätze importieren cifar10 
von schwer importieren Backend wie K 
von hard.utils importieren np_utils

importieren Mathematik 
von harte.optimierer importieren SGD 
von laute.rückrufe importieren LearningRateScheduler

Dann laden wir den Datensatz und führen einige Vorverarbeitungsschritte durch. Dies ist eine kritische Aufgabe, bevor das Deep-Learning-Modell trainiert wird.

Anzahl_Klassen = 10

def load_cifar10_data(img_rows, img_cols):

    # cifar10 Trainings- und Validierungssets laden
    (X_Zug, Y_Zug), (X_gültig, Y_gültig) = cifar10.lade Daten()

    # Trainingsbilder skalieren
    X_Zug = z.B.Array([cv2.Größe ändern(img, (img_rows,img_cols)) zum img In X_Zug[:,:,:,:]])
    X_gültig = z.B.Array([cv2.Größe ändern(img, (img_rows,img_cols)) zum img In X_gültig[:,:,:,:]])

    # Transformieren Sie Ziele in ein mit Keras kompatibles Format
    Y_Zug = np_utils.to_kategorial(Y_Zug, Anzahl_Klassen)
    Y_gültig = np_utils.to_kategorial(Y_gültig, Anzahl_Klassen)
    
    X_Zug = X_Zug.astyp('float32')
    X_gültig = X_gültig.astyp('float32')

    # Daten vorverarbeiten
    X_Zug = X_Zug / 255.0
    X_gültig = X_gültig / 255.0

    Rückkehr X_Zug, Y_Zug, X_gültig, Y_gültig
X_Zug, y_train, X_test, y_test = load_cifar10_data(224, 224)

Jetzt, wir werden unsere Deep-Learning-Architektur definieren. Dazu definieren wir schnell eine Funktion, das, wenn Sie die notwendigen Informationen erhalten, gibt die gesamte Startebene zurück.

def inception_module(x,
                     filter_1x1,
                     filter_3x3_reduzieren,
                     filter_3x3,
                     filter_5x5_reduzieren,
                     filter_5x5,
                     filter_pool_proj,
                     Name=Keiner):
    
    conv_1x1 = Conv2D(filter_1x1, (1, 1), Polsterung='gleich', Aktivierung='relu', kernel_initializer=Kernel_init, bias_initializer=bias_init)(x)
    
    conv_3x3 = Conv2D(filter_3x3_reduzieren, (1, 1), Polsterung='gleich', Aktivierung='relu', kernel_initializer=Kernel_init, bias_initializer=bias_init)(x)
    conv_3x3 = Conv2D(filter_3x3, (3, 3), Polsterung='gleich', Aktivierung='relu', kernel_initializer=Kernel_init, bias_initializer=bias_init)(conv_3x3)

    conv_5x5 = Conv2D(filter_5x5_reduzieren, (1, 1), Polsterung='gleich', Aktivierung='relu', kernel_initializer=Kernel_init, bias_initializer=bias_init)(x)
    conv_5x5 = Conv2D(filter_5x5, (5, 5), Polsterung='gleich', Aktivierung='relu', kernel_initializer=Kernel_init, bias_initializer=bias_init)(conv_5x5)

    pool_proj = MaxPool2D((3, 3), Schritte=(1, 1), Polsterung='gleich')(x)
    pool_proj = Conv2D(filter_pool_proj, (1, 1), Polsterung='gleich', Aktivierung='relu', kernel_initializer=Kernel_init, bias_initializer=bias_init)(pool_proj)

    Ausgang = verketten([conv_1x1, conv_3x3, conv_5x5, pool_proj], Achse=3, Name=Name)
    
    Rückkehr Ausgang

Dann erstellen wir die GoogLeNet-Architektur, wie im Dokument erwähnt.

Kernel_init = schwer.Initialisierer.glorot_uniform()
bias_init = schwer.Initialisierer.Konstante(Wert=0.2)
screenshot-from-2018-10-16-11-56-41-300x163-9994576
input_layer = Eingang(Form=(224, 224, 3))

x = Conv2D(64, (7, 7), Polsterung='gleich', Schritte=(2, 2), Aktivierung='relu', Name='conv_1_7x7/2', kernel_initializer=Kernel_init, bias_initializer=bias_init)(input_layer)
x = MaxPool2D((3, 3), Polsterung='gleich', Schritte=(2, 2), Name='max_pool_1_3x3/2')(x)
x = Conv2D(64, (1, 1), Polsterung='gleich', Schritte=(1, 1), Aktivierung='relu', Name='conv_2a_3x3/1')(x)
x = Conv2D(192, (3, 3), Polsterung='gleich', Schritte=(1, 1), Aktivierung='relu', Name='conv_2b_3x3/1')(x)
x = MaxPool2D((3, 3), Polsterung='gleich', Schritte=(2, 2), Name='max_pool_2_3x3/2')(x)

x = inception_module(x,
                     filter_1x1=64,
                     filter_3x3_reduzieren=96,
                     filter_3x3=128,
                     filter_5x5_reduzieren=16,
                     filter_5x5=32,
                     filter_pool_proj=32,
                     Name='Anfang_3a')

x = inception_module(x,
                     filter_1x1=128,
                     filter_3x3_reduzieren=128,
                     filter_3x3=192,
                     filter_5x5_reduzieren=32,
                     filter_5x5=96,
                     filter_pool_proj=64,
                     Name='Anfang_3b')

x = MaxPool2D((3, 3), Polsterung='gleich', Schritte=(2, 2), Name='max_pool_3_3x3/2')(x)

x = inception_module(x,
                     filter_1x1=192,
                     filter_3x3_reduzieren=96,
                     filter_3x3=208,
                     filter_5x5_reduzieren=16,
                     filter_5x5=48,
                     filter_pool_proj=64,
                     Name='Anfang_4a')


x1 = DurchschnittPooling2D((5, 5), Schritte=3)(x)
x1 = Conv2D(128, (1, 1), Polsterung='gleich', Aktivierung='relu')(x1)
x1 = Ebnen()(x1)
x1 = Dicht(1024, Aktivierung='relu')(x1)
x1 = Aussteigen(0.7)(x1)
x1 = Dicht(10, Aktivierung='softmax', Name='auxilliary_output_1')(x1)

x = inception_module(x,
                     filter_1x1=160,
                     filter_3x3_reduzieren=112,
                     filter_3x3=224,
                     filter_5x5_reduzieren=24,
                     filter_5x5=64,
                     filter_pool_proj=64,
                     Name='Anfang_4b')

x = inception_module(x,
                     filter_1x1=128,
                     filter_3x3_reduzieren=128,
                     filter_3x3=256,
                     filter_5x5_reduzieren=24,
                     filter_5x5=64,
                     filter_pool_proj=64,
                     Name='Anfang_4c')

x = inception_module(x,
                     filter_1x1=112,
                     filter_3x3_reduzieren=144,
                     filter_3x3=288,
                     filter_5x5_reduzieren=32,
                     filter_5x5=64,
                     filter_pool_proj=64,
                     Name='inception_4d')


x2 = DurchschnittPooling2D((5, 5), Schritte=3)(x)
x2 = Conv2D(128, (1, 1), Polsterung='gleich', Aktivierung='relu')(x2)
x2 = Ebnen()(x2)
x2 = Dicht(1024, Aktivierung='relu')(x2)
x2 = Aussteigen(0.7)(x2)
x2 = Dicht(10, Aktivierung='softmax', Name='auxilliary_output_2')(x2)

x = inception_module(x,
                     filter_1x1=256,
                     filter_3x3_reduzieren=160,
                     filter_3x3=320,
                     filter_5x5_reduzieren=32,
                     filter_5x5=128,
                     filter_pool_proj=128,
                     Name='inception_4e')

x = MaxPool2D((3, 3), Polsterung='gleich', Schritte=(2, 2), Name='max_pool_4_3x3/2')(x)

x = inception_module(x,
                     filter_1x1=256,
                     filter_3x3_reduzieren=160,
                     filter_3x3=320,
                     filter_5x5_reduzieren=32,
                     filter_5x5=128,
                     filter_pool_proj=128,
                     Name='Anfang_5a')

x = inception_module(x,
                     filter_1x1=384,
                     filter_3x3_reduzieren=192,
                     filter_3x3=384,
                     filter_5x5_reduzieren=48,
                     filter_5x5=128,
                     filter_pool_proj=128,
                     Name='Anfang_5b')

x = GlobalAveragePooling2D(Name='avg_pool_5_3x3/1')(x)

x = Aussteigen(0.4)(x)

x = Dicht(10, Aktivierung='softmax', Name='Ausgang')(x)
Modell = Modell(input_layer, [x, x1, x2], Name='inception_v1')

Fassen wir unser Modell zusammen, um zu überprüfen, ob unsere bisherige Arbeit gut gelaufen ist.

__________________________________________________________________________________________________
Schicht (Typ)                    Parameter der Ausgabeform #     Verbunden
================================================ ===============================================
Eingang_1 (Eingabeebene)            (Keiner, 224, 224, 3)  0                                            
__________________________________________________________________________________________________
conv_1_7x7/2 (Conv2D)           (Keiner, 112, 112, 64) 9472        Eingang_1[0][0]                    
__________________________________________________________________________________________________
max_pool_1_3x3/2 (MaxPooling2D) (Keiner, 56, 56, 64)   0           conv_1_7x7/2[0][0]               
__________________________________________________________________________________________________
norm1 (LRN2D)                   (Keiner, 56, 56, 64)   0           max_pool_1_3x3/2[0][0]           
__________________________________________________________________________________________________
...
...
...
dropout_3 (Aussteigen)             (Keiner, 1024)         0           avg_pool_5_3x3/1[0][0]           
__________________________________________________________________________________________________
dropout_1 (Aussteigen)             (Keiner, 1024)         0           dicht_1[0][0]                    
__________________________________________________________________________________________________
dropout_2 (Aussteigen)             (Keiner, 1024)         0           dicht_2[0][0]                    
__________________________________________________________________________________________________
Ausgang (Dicht)                  (Keiner, 10)           10250       dropout_3[0][0]                  
__________________________________________________________________________________________________
auxilliary_output_1 (Dicht)     (Keiner, 10)           10250       dropout_1[0][0]                  
__________________________________________________________________________________________________
auxilliary_output_2 (Dicht)     (Keiner, 10)           10250       dropout_2[0][0]                  
================================================ ===============================================
Gesamtparameter: 10,334,030
Trainierbare Parameter: 10,334,030
Nicht trainierbare Parameter: 0
__________________________________________________________________________________________________

Das Modell sieht gut aus, Wie können Sie aus der obigen Ausgabe messen?. Wir können noch den letzten Schliff hinzufügen, bevor wir unser Modell trainieren. Wir werden Folgendes definieren:

  • Verlustfunktion für jede Ausgabeschicht
  • Dieser Ausgabeschicht zugewiesene Gewichtung
  • Optimierungsfunktion, die modifiziert wird, um nach jedem eine Gewichtsabnahme einzuschließen 8 Epochen.
  • Bewertungsmetrik
Epochen = 25
initial_lrate = 0.01

def Verfall(Epoche, Schritte=100):
    initial_lrate = 0.01
    Tropfen = 0.96
    epochs_drop = 8
    lrate = initial_lrate * Mathematik.pow(Tropfen, Mathematik.Boden((1+Epoche)/epochs_drop))
    Rückkehr lrate

sgd = SGD(lr=initial_lrate, Schwung=0.9, nesterov=Falsch)

lr_sc = LearningRateScheduler(Verfall, ausführlich=1)

Modell.kompilieren(Verlust=['kategoriale_Kreuzentropie', 'kategoriale_Kreuzentropie', 'kategoriale_Kreuzentropie'], verlust_gewichte=[1, 0.3, 0.3], Optimierer=sgd, Metriken=['Richtigkeit'])

Unser Modell ist nun fertig! Probieren Sie es aus, um zu sehen, wie es funktioniert.

Geschichte = Modell.fit(X_Zug, [y_train, y_train, y_train], Validierungsdaten=(X_test, [y_test, y_test, y_test]), Epochen=Epochen, batch_size=256, Rückrufe=[lr_sc])

Unten ist das Ergebnis, das ich beim Training des Modells erhalten habe:

Trainieren auf 50000 Proben, validieren an 10000 Proben
Epoche 1/25

Epoche 00001: LearningRateScheduler reduziert die Lernrate auf 0.01.
50000/50000 [==============================] - 188s 4ms/Schritt - Verlust: 3.7140 - Ausgabe_Verlust: 2.3280 - auxilliary_output_1_loss: 2.3101 - auxilliary_output_2_loss: 2.3099 - output_acc: 0.1030 - auxilliary_output_1_acc: 0.1029 - auxilliary_output_2_acc: 0.0992 - Wertverlust: 3.6898 - val_output_loss: 2.3085 - val_auxilliary_output_1_loss: 2.3018 - val_auxilliary_output_2_loss: 2.3025 - val_output_acc: 0.1000 - val_auxilliary_output_1_acc: 0.1017 - val_auxilliary_output_2_acc: 0.0984
Epoche 2/25

Epoche 00002: LearningRateScheduler reduziert die Lernrate auf 0.01.
50000/50000 [==============================] - 181s 4ms/Schritt - Verlust: 3.6635 - Ausgabe_Verlust: 2.2894 - auxilliary_output_1_loss: 2.2817 - auxilliary_output_2_loss: 2.2987 - output_acc: 0.1161 - auxilliary_output_1_acc: 0.1321 - auxilliary_output_2_acc: 0.1151 - Wertverlust: 3.6559 - val_output_loss: 2.3095 - val_auxilliary_output_1_loss: 2.2315 - val_auxilliary_output_2_loss: 2.2565 - val_output_acc: 0.1466 - val_auxilliary_output_1_acc: 0.1478 - val_auxilliary_output_2_acc: 0.1417
Epoche 3/25

Epoche 00003: LearningRateScheduler reduziert die Lernrate auf 0.01.
50000/50000 [==============================] - 180s 4ms/Schritt - Verlust: 3.2981 - Ausgabe_Verlust: 2.0660 - auxilliary_output_1_loss: 2.0414 - auxilliary_output_2_loss: 2.0653 - output_acc: 0.2212 - auxilliary_output_1_acc: 0.2363 - auxilliary_output_2_acc: 0.2256 - Wertverlust: 3.1812 - val_output_loss: 2.0064 - val_auxilliary_output_1_loss: 1.9372 - val_auxilliary_output_2_loss: 1.9787 - val_output_acc: 0.2578 - val_auxilliary_output_1_acc: 0.2909 - val_auxilliary_output_2_acc: 0.2767
Epoche 4/25

Epoche 00004: LearningRateScheduler reduziert die Lernrate auf 0.01.
50000/50000 [==============================] - 181s 4ms/Schritt - Verlust: 3.0797 - Ausgabe_Verlust: 1.9258 - auxilliary_output_1_loss: 1.9214 - auxilliary_output_2_loss: 1.9248 - output_acc: 0.2803 - auxilliary_output_1_acc: 0.2914 - auxilliary_output_2_acc: 0.2872 - Wertverlust: 3.0099 - val_output_loss: 1.8852 - val_auxilliary_output_1_loss: 1.8900 - val_auxilliary_output_2_loss: 1.8589 - val_output_acc: 0.3080 - val_auxilliary_output_1_acc: 0.3122 - val_auxilliary_output_2_acc: 0.3296
Epoche 5/25

Epoche 00005: LearningRateScheduler reduziert die Lernrate auf 0.01.
50000/50000 [==============================] - 181s 4ms/Schritt - Verlust: 2.8427 - Ausgabe_Verlust: 1.7733 - auxilliary_output_1_loss: 1.7933 - auxilliary_output_2_loss: 1.7711 - output_acc: 0.3454 - auxilliary_output_1_acc: 0.3485 - auxilliary_output_2_acc: 0.3509 - Wertverlust: 2.6623 - val_output_loss: 1.6788 - val_auxilliary_output_1_loss: 1.6531 - val_auxilliary_output_2_loss: 1.6250 - val_output_acc: 0.3922 - val_auxilliary_output_1_acc: 0.4094 - val_auxilliary_output_2_acc: 0.4103
Epoche 6/25
...
...
...
Epoche 00024: LearningRateScheduler reduziert die Lernrate auf 0.008847359999999999.
50000/50000 [==============================] - 181s 4ms/Schritt - Verlust: 0.7803 - Ausgabe_Verlust: 0.3791 - auxilliary_output_1_loss: 0.7608 - auxilliary_output_2_loss: 0.5767 - output_acc: 0.8665 - auxilliary_output_1_acc: 0.7332 - auxilliary_output_2_acc: 0.7962 - Wertverlust: 1.0228 - val_output_loss: 0.6043 - val_auxilliary_output_1_loss: 0.7442 - val_auxilliary_output_2_loss: 0.6508 - val_output_acc: 0.7970 - val_auxilliary_output_1_acc: 0.7408 - val_auxilliary_output_2_acc: 0.7724
Epoche 25/25

Epoche 00025: LearningRateScheduler reduziert die Lernrate auf 0.008847359999999999.
50000/50000 [==============================] - 181s 4ms/Schritt - Verlust: 0.7411 - Ausgabe_Verlust: 0.3543 - auxilliary_output_1_loss: 0.7349 - auxilliary_output_2_loss: 0.5545 - output_acc: 0.8755 - auxilliary_output_1_acc: 0.7408 - auxilliary_output_2_acc: 0.8060 - Wertverlust: 0.9524 - val_output_loss: 0.5383 - val_auxilliary_output_1_loss: 0.7346 - val_auxilliary_output_2_loss: 0.6458 - val_output_acc: 0.8191 - val_auxilliary_output_1_acc: 0.7435 - val_auxilliary_output_2_acc: 0.7791

Unser Modell lieferte eine beeindruckende Präzision der 80% + im Validierungsset, was zeigt, dass es sich wirklich lohnt, diese Modellarchitektur auszuprobieren.

Abschließende Anmerkungen

Dies war ein wirklich schöner Artikel zu schreiben und ich hoffe, Sie fanden ihn ebenso nützlich. Inception v1 stand im Mittelpunkt dieses Artikels, in dem ich das Wesentliche dieses Frameworks erklärte und demonstrierte, wie man es von Grund auf in Keras umsetzt.

In den nächsten Artikeln, Ich werde mich auf Fortschritte bei Inception-Architekturen konzentrieren. Diese Fortschritte wurden in späteren Artikeln detailliert beschrieben., nämlich, Einführung v2, Einführung v3, etc. Und wenn, sie sind so faszinierend wie der Name vermuten lässt, Also bleibt gespannt!

Wenn Sie Vorschläge haben / Kommentar zum Artikel, poste es im Kommentarbereich unten.

Abonniere unseren Newsletter

Wir senden Ihnen keine SPAM-Mail. Wir hassen es genauso wie du.