Die Jedi-Technik zur Reduzierung von Convolutional Networks — Pruning

Die Jedi-Technik zur Reduzierung von Convolutional Networks — Pruning

Du stehst erneut vor der Aufgabe der Objekterkennung. PrioritĂ€t hat die Geschwindigkeit bei akzeptabler Genauigkeit. Du nimmst die Architektur YOLOv3 und feinstimmst sie. Genauigkeit (mAp75) ĂŒber 0,95. Doch die Geschwindigkeit ist immer noch niedrig. Verdammt.

Heute lassen wir die Quantisierung beiseite. Im Anschluss betrachten wir Model Pruning — das Entfernen ĂŒberflĂŒssiger Teile des Netzwerks zur Beschleunigung der Inferenz bei Erhaltung der Genauigkeit. Anschaulich — wo, wie viel und wie kann ausgeschnitten werden. Wir werden besprechen, wie man dies manuell macht und wo man es automatisieren kann. Am Ende — ein Repository fĂŒr Keras.

EinfĂŒhrung

Bei meinem vorherigen Arbeitgeber, dem Permer Macroscop, habe ich mir eine Angewohnheit angeeignet — stets die Laufzeit der Algorithmen zu ĂŒberwachen. Und die Laufzeit der Netzwerke immer ĂŒber einen Angemessenheitsfilter zu ĂŒberprĂŒfen. In der Regel bestehen state-of-the-art Modelle in der Produktion diesen Filter nicht, was mich zum Pruning gefĂŒhrt hat.

Pruning — ein altes Thema, das in den Stanford-Vorlesungen behandelt wurde. Im Jahr 2017. Die grundlegende Idee ist, die GrĂ¶ĂŸe des trainierten Netzwerks zu verringern, ohne dass die Genauigkeit leidet, indem verschiedene Knoten entfernt werden. Klingt cool, aber ich höre selten von seiner Anwendung. Wahrscheinlich mangelt es an Implementierungen, es gibt keine deutschsprachigen Artikel oder einfach alle halten pruning fĂŒr ein Geheimnis und schweigen.
Aber lass uns das auseinandernehmen.

Ein Blick in die Biologie

Ich liebe es, wenn Ideen aus der Biologie im Deep Learning Anwendung finden. Auf sie, ebenso wie auf die Evolution, kann man vertrauen (wusstest du, dass ReLU sehr Àhnlich ist wie die Aktivierungsfunktion von Neuronen im Gehirn??)

Der Prozess des Model Pruning ist ebenfalls eng mit der Biologie verbunden. Die Reaktion des Netzwerks lÀsst sich mit der PlastizitÀt des Gehirns vergleichen. Einige interessante Beispiele findet man im Buch von Norman Doidge.:

  1. Das Gehirn einer Frau, die von Geburt an nur eine GehirnhĂ€lfte hatte, hat sich selbst umprogrammiert, um die Funktionen der fehlenden HĂ€lfte auszufĂŒhren.
  2. Ein Mann hatte sich einen Teil seines Gehirns entfernt, der fĂŒr das Sehen verantwortlich war. Im Laufe der Zeit ĂŒbernahmen andere Teile des Gehirns diese Funktionen. (Wir versuchen nicht, das zu wiederholen.)

So kann auch aus deinem Modell ein Teil schwacher Schichten entfernt werden. Im Zweifelsfall helfen die verbleibenden Schichten, die entfernten zu ersetzen.

Liebst du Transfer Learning oder lernst du von Grund auf?

Option Nummer eins. Sie nutzen Transfer Learning mit Yolov3, Retina, Mask-RCNN oder U-Net. Doch hĂ€ufig mĂŒssen wir nicht 80 Objektklassen wie im COCO-Datensatz erkennen. In meiner Erfahrung beschrĂ€nkt sich das alles auf 1-2 Klassen. Man könnte annehmen, dass die Architektur fĂŒr 80 Klassen hier ĂŒbertrieben ist. Daher liegt der Gedanke nahe, die Architektur zu verkleinern. Und das möchte ich gerne tun, ohne die bestehenden vortrainierten Gewichte zu verlieren.

Option Nummer zwei. Vielleicht haben Sie viele Daten und Rechenressourcen oder benötigen einfach eine hochgradig angepasste Architektur. Das ist irrelevant. Aber Sie trainieren das Netzwerk von Grund auf. Der ĂŒbliche Ablauf besteht darin, sich die Datenstruktur anzusehen, eine ÜBERFLÜSSIGE leistungsstarke Architektur auszuwĂ€hlen und Dropouts gegen Überanpassung anzuwenden. Ich habe Dropouts von 0.6 gesehen, Karl.

In beiden FĂ€llen lĂ€sst sich das Netzwerk verkleinern. Wir haben einen Grund dafĂŒr formuliert. Jetzt wollen wir herausfinden, was es mit dem Pruning auf sich hat.

Algorithmus insgesamt

Wir haben entschieden, dass wir Faltungen entfernen können. Das sieht ziemlich einfach aus:

Die Jedi-Technik zur Reduzierung von Convolutional Networks — Pruning

Das Entfernen von Faltungen belastet das Netzwerk und fĂŒhrt in der Regel zu einem gewissen Anstieg der Fehlerquote. Einerseits zeigt dieser Anstieg, wie gut wir die Faltungen entfernen (ein großer Anstieg deutet darauf hin, dass wir etwas falsch machen). Ein kleiner Anstieg ist jedoch durchaus akzeptabel und kann oft durch anschließendes leichtes Nachtraining mit einer kleinen Lernrate behoben werden. FĂŒgen wir einen Nachtrainingsschritt hinzu:

Die Jedi-Technik zur Reduzierung von Convolutional Networks — Pruning

Jetzt mĂŒssen wir verstehen, wann wir unseren Lern-Pruning-Zyklus stoppen möchten. Es kann exotische Szenarien geben, in denen wir das Netzwerk auf eine bestimmte GrĂ¶ĂŸe und Geschwindigkeit reduzieren mĂŒssen (z. B. fĂŒr mobile GerĂ€te). Das hĂ€ufigste Szenario ist jedoch das Fortsetzen des Zyklus, bis der Fehler ĂŒber den akzeptablen Wert steigt. FĂŒgen wir eine Bedingung hinzu:

Die Jedi-Technik zur Reduzierung von Convolutional Networks — Pruning

Somit wird der Algorithmus klar. Es bleibt zu klÀren, wie die zu entfernenden Faltungen identifiziert werden.

Suche nach entfernbaren Faltungen

Wir mĂŒssen einige Faltungen entfernen. Einfach unĂŒberlegt und willkĂŒrlich Faltungen zu entfernen, ist keine gute Idee, auch wenn es funktionieren könnte. Aber wenn wir klug sind, können wir versuchen, "schwache" Faltungen zur Entfernung auszuwĂ€hlen. Es gibt mehrere AnsĂ€tze:

  1. Die kleinste L1-Metrik oder Low-Magnitude-Pruning. Die Idee besagt, dass Faltungen mit geringen Gewichtswerten nur einen kleinen Einfluss auf die endgĂŒltige Entscheidungsfindung haben.
  2. Die kleinste L1-Metrik unter BerĂŒcksichtigung des Mittelwerts und der Standardabweichung. ErgĂ€nzt durch eine Bewertung der Verteilungsart.
  3. Maskierung von Faltungen und Ausschluss der am wenigsten relevanten fĂŒr die endgĂŒltige Genauigkeit.. Eine genauere Bestimmung von unbedeutenden Faltungen, aber sehr zeit- und ressourcenintensiv.
  4. Andere

Jede der Varianten hat ihre Daseinsberechtigung und spezifische Implementierungsmerkmale. Hier betrachten wir die Variante mit der kleinsten L1-Metrik.

Manueller Prozess fĂŒr YOLOv3

Die ursprĂŒngliche Architektur enthĂ€lt Restblöcke. Aber egal wie effektiv sie fĂŒr tiefe Netzwerke sind, sie stören uns ein wenig. Das Problem ist, dass wir in diesen Schichten keine Faltungen mit unterschiedlichen Indizes löschen können:

Die Jedi-Technik zur Reduzierung von Convolutional Networks — Pruning

Deshalb heben wir die Schichten hervor, aus denen wir Faltungen ohne Bedenken entfernen können:

Die Jedi-Technik zur Reduzierung von Convolutional Networks — Pruning

Jetzt bauen wir einen Arbeitszyklus auf:

  1. Aktivierungen exportieren
  2. SchÀtzen, wie viel ausgeschnitten werden soll
  3. Ausschneiden
  4. Trainieren ĂŒber 10 Epochen mit LR=1e-4
  5. Testen

Es ist hilfreich, Faltungen zu exportieren, um zu bewerten, welchen Teil wir zu einem bestimmten Zeitpunkt entfernen können. Beispiele fĂŒr den Export:

Die Jedi-Technik zur Reduzierung von Convolutional Networks — Pruning

Wir sehen, dass praktisch ĂŒberall 5 % der Faltung eine sehr niedrige L1-Norm aufweisen, sodass wir sie entfernen können. Bei jedem Schritt wiederholte sich diese Auslagerung und es wurde bewertet, aus welchen Schichten und wie viel ausgeschnitten werden kann.

Der gesamte Prozess wurde in 4 Schritte gegliedert (hier und ĂŒberall beziehen sich die Zahlen auf die RTX 2060 Super):

SchrittmAp75Anzahl der Parameter, MillionenNetzwerkgrĂ¶ĂŸe, MBVon der ursprĂŒnglichen, %Durchlaufzeit, msBedienung des Zuschneidens
00.965660241100180—
10.962255218911755 % von allem
20.962550197831685 % von allem
30.9633391556415515 % fĂŒr Schichten mit 400+ Faltungen
40.9555311245114610 % fĂŒr Schichten mit 100+ Faltungen

Zu Schritt 2 kam ein positiver Effekt hinzu — der Batch-Size 4 konnte in den Speicher geladen werden, was den Prozess des Nachtrainierens erheblich beschleunigte.
Im Schritt 4 wurde der Prozess gestoppt, da selbst umfangreiches Nachtrainieren den mAp75 nicht auf die alten Werte hob.
Letztendlich gelang es, die Inferenz um 15%, die GrĂ¶ĂŸe um 35% zu reduzieren und dabei die Genauigkeit nicht zu verlieren.

Automatisierung fĂŒr einfachere Architekturen

FĂŒr einfachere Netzwerkarchitekturen (ohne bedingte Additionen, Konkatenierungen und Residualblöcke) kann man sich gut auf die Verarbeitung aller Faltungen konzentrieren und den Prozess des Ausschneidens von Faltungen automatisieren.

Diese Option habe ich implementiert. hier.
Es ist ganz einfach: Sie benötigen lediglich die Verlustfunktion, den Optimierer und die Batch-Generatoren:

import pruning
from keras.optimizers import Adam
from keras.utils import Sequence

train_batch_generator = BatchGenerator...
score_batch_generator = BatchGenerator...

opt = Adam(lr=1e-4)
pruner = pruning.Pruner("config.json", "categorical_crossentropy", opt)

pruner.prune(train_batch, valid_batch)

Bei Bedarf können die Konfigurationsparameter geÀndert werden:

{
    "input_model_path": "model.h5",
    "output_model_path": "model_pruned.h5",
    "finetuning_epochs": 10, # Anzahl der Epochen fĂŒr das Training zwischen den Pruning-Schritten
    "stop_loss": 0.1, # Verlust zum Stoppen des Prozesses
    "pruning_percent_step": 0.05, # Anteil der Convolutionen, die bei jedem Pruning-Schritt gelöscht werden
    "pruning_standart_deviation_part": 0.2 # Verschiebung zur Begrenzung des Pruning-Anteils
}

ZusÀtzlich wurde eine EinschrÀnkung basierend auf der Standardabweichung implementiert. Ziel ist es, den Anteil der entfernten Elemente zu begrenzen, indem Convolutions mit bereits "ausreichenden" L1-Messungen ausgeschlossen werden:

Die Jedi-Technik zur Reduzierung von Convolutional Networks — Pruning

So erlauben wir es, nur schwache Convolutionen aus Verteilungen zu entfernen, die der rechten Àhnlich sind, und beeinflussen nicht die Entfernung aus Verteilungen, die der linken Àhnlich sind:

Die Jedi-Technik zur Reduzierung von Convolutional Networks — Pruning

Wenn sich die Verteilung dem Normalverteilung annÀhert, kann der Koeffizient pruning_standart_deviation_part aus folgendem ausgewÀhlt werden:

Die Jedi-Technik zur Reduzierung von Convolutional Networks — Pruning
Ich empfehle einen Toleranzwert von 2 Sigma. Alternativ kann man sich auch nicht an dieser Besonderheit orientieren und einen Wert < 1,0 beibehalten.

Das Ergebnis ist ein Diagramm, das die NetzgrĂ¶ĂŸe, den Verlust und die Laufzeit ĂŒber den gesamten Test hinweg anzeigt, normiert auf 1.0. Zum Beispiel wurde hier die NetzgrĂ¶ĂŸe fast halbiert, ohne QualitĂ€tsverlust (eine kleine Faltungsnetzwerk mit 100k Gewichten):

Die Jedi-Technik zur Reduzierung von Convolutional Networks — Pruning

Die Laufgeschwindigkeit unterliegt normalen Schwankungen und hat sich praktisch nicht verÀndert. Das hat seine ErklÀrung:

  1. Die Anzahl der Faltungen wechselt von bequemen (32, 64, 128) zu weniger praktischen fĂŒr Grafikkarten — 27, 51 usw. Ich könnte mich irren, aber wahrscheinlich hat das einen Einfluss.
  2. Die Architektur ist nicht breit, aber sequenziell. Durch Verkleinerung der Breite berĂŒhren wir nicht die Tiefe. Dadurch reduzieren wir die Last, Ă€ndern jedoch nicht die Geschwindigkeit.

Daher zeigt sich die Verbesserung in der Reduzierung der CUDA-Last wÀhrend des Laufs um 20-30%, jedoch nicht in der Verringerung der Laufzeit.

Ergebnisse

Lassen Sie uns reflektieren. Wir haben zwei Varianten des Pruning betrachtet — fĂŒr YOLOv3 (wenn man manuell arbeiten muss) und fĂŒr Netzwerke mit einfacheren Architekturen. Es ist evident, dass man in beiden FĂ€llen die NetzgrĂ¶ĂŸe reduzieren und die Geschwindigkeit erhöhen kann, ohne an Genauigkeit zu verlieren. Ergebnisse:

  • Reduzierung der GrĂ¶ĂŸe
  • Beschleunigung des Laufs
  • Reduzierung der CUDA-Last
  • Infolgedessen legen wir Wert auf Nachhaltigkeit (Wir optimieren die zukĂŒnftige Nutzung von Rechenressourcen. Irgendwo freut sich jemand. Greta Thunberg)

Anhang

  • Nach dem Schritt pruning kann man auch die Quantisierung anwenden (zum Beispiel mit TensorRT)
  • TensorFlow bietet Möglichkeiten fĂŒr low_magnitude_pruning. Es funktioniert.
  • Repository Ich möchte mich weiterentwickeln und freue mich ĂŒber Hilfe.

Quelle: habr.com

Erwerben Sie zuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz, VPS VDS-Server đŸ”„ Kaufen Sie zuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster