Fortsetzung meiner Reihe über die Erstellung klassischer Konvolutionalen Neuronalen Netze, die den Bereich der Bildverarbeitung in den letzten 1-2 Jahrzehnten revolutioniert haben, werden wir nun das sehr tiefe Konvolutionale Neuronale Netz VGG aus dem Nichts mit PyTorch aufbauen. Du kannst die vorherigen Artikel in der Reihe auf meinem Profil sehen, hauptsächlich LeNet5 und AlexNet.
Wie zuvor werden wir die Architektur und die Intuition hinter VGG untersuchen und wie die Ergebnisse zu der Zeit waren. Danach werden wir unser Datensatz CIFAR100 untersuchen und mit memory-effizientem Code in unser Programm laden. Anschließend werden wir VGG16 (die Zahl bezieht sich auf die Anzahl der Schichten, es gibt grundsätzlich zwei Versionen: VGG16 und VGG19) von Grund auf mit PyTorch implementieren und es mit unserem Datensatz trainieren, sowie es auf unserem Testdatensatz evaluieren, um zu sehen, wie es auf unbekannten Daten performt
VGG
Aufbauend auf die Arbeit von AlexNet konzentriert sich VGG auf einen weiteren wichtigen Aspekt von Convolutional Neural Networks (CNNs), nämlich Tiefe. Es wurde von Simonyan und Zisserman entwickelt. Es besteht normalerweise aus 16 Konvolutionsschichten, kann aber auch auf 19 Schichten erweitert werden (daher die beiden Versionen, VGG-16 und VGG-19). Alle Konvolutionsschichten bestehen aus 3×3-Filtern. Mehr über die Netzwerkarchitektur kannst du in der offiziellen Arbeit hier
VGG16-Architektur lesen. Quelle
Daten Laden
Datensatz
vor dem Modellbau ist es eine der wichtigsten Dinge in jedem Machine Learning Projekt, Daten zu laden, zu analysieren und zu vorverarbeiten. In diesem Artikel verwenden wir das CIFAR-100 Datenset. Dieses Datenset ähnelt dem CIFAR-10, unterscheidet sich jedoch durch 100 Klassen, die jeweils 600 Bilder enthalten. Es gibt 500 Trainingsbilder und 100 Testbilder pro Klasse. Die 100 Klassen des CIFAR-100 sind in 20 Superklassen gruppiert. Jeder Bildschirm ist mit einer „fine“ Label (der Klasse, der er angehört) und einem „coarse“ Label (der Superklasse, der er angehört) versehen. Wir verwenden hier das „fine“ Label. Hier ist die Liste der Klassen im CIFAR-100:
Klassenliste für das CIFAR-100 Datenset
Bibliotheken importieren
Wir arbeiten hauptsächlich mit torch
(für das Erstellen und die Trainings des Modells), torchvision
(für die Datenladung/Verarbeitung, enthält Datensets und Methoden zur Verarbeitung dieser Datensets in der Computervision) und numpy
(für mathematische Manipulation). Wir definieren auch eine Variable device
, sodass das Programm die GPU verwenden kann, wenn verfügbar
Daten laden
torchvision
ist eine Bibliothek, die einfache Zugriff auf viele Computerbildverarbeitungsdatenbanken bietet und Methoden zur Vorverarbeitung dieser Datenbanken in einer einfach und intuitiv handhabbaren Weise bereitstellt
- Wir definieren eine Funktion
data_loader
, die entweder Trainings-/Validierungsdaten oder Testdaten abhängig von den Argumenten liefert - Wir beginnen mit der Definition der Variable
normalize
, die die Mittelwerte und Standardabweichungen jedes Kanals (rot, grün und blau) im Datensatz enthält. Diese können manuell berechnet werden, sind aber auch online verfügbar. Dies wird in der Variabletransform
verwendet, wo wir die Daten skalieren, sie in Tensoren umwandeln und anschließend normalisieren - Wenn das Argument
test
wahr ist, laden wir einfach den Testteil des Datensatzes und liefern ihn mit Hilfe von Datenladern (unten erklärt) aus - Wenn
test
nicht wahr ist (Standardverhalten), laden wir den Trainingsteil des Datensatzes und teilen ihn zufällig in einen Trainings- und Validierungsteil (0,9:0,1) auf - Schließlich verwenden wir Datenladen. Dies kann die Leistung bei kleinen Datensätzen wie CIFAR100 nicht beeinträchtigen, aber es kann die Leistung bei großen Datensätzen erheblich beeinträchtigen und ist generell eine gute Praxis. Datenladen ermöglichen es uns, die Daten in Batches durchzugehen, und die Daten werden während der Iteration geladen und nicht alle gleichzeitig in den Arbeitsspeicher geladen.
VGG16 von Grund auf
Um das Modell von Grund auf zu erstellen, müssen wir zunächst verstehen, wie Modelldefinitionen in torch
funktionieren und die verschiedenen Arten von Schichten, die wir hier verwenden werden:
- Jeder benutzerdefinierte Modell muss von der Klasse
nn.Module
erben, da sie einige grundlegende Funktionen bereitstellt, die dem Modell helfen, zu trainieren. - Zweitens gibt es zwei Hauptaufgaben, die wir erfüllen müssen. Erstens Definieren wir die verschiedenen Schichten unseres Modells innerhalb der Funktion
__init__
und die Reihenfolge, in der diese Schichten auf das Eingabedaten aufgerufen werden, innerhalb der Funktionforward
Lassen Sie uns nun die verschiedenen Arten von Schichten definieren, die wir hier verwenden:
nn.Conv2d
: Diese sind die Konvolutionsschichten, die die Anzahl der Eingangs- und Ausgangskanäle als Argumente akzeptieren, zusammen mit der Kernelgröße für das Filter. Es können auch Strides oder Padding angewendet werden, wenn Sie das verlangennn.BatchNorm2d
: Dies führt Batch-Normalisierung auf dem Ausgang der Konvolutionsschicht annn.ReLU
: Dies ist die Aktivierung, die auf verschiedenen Netzwerkausgaben angewendet wird.nn.MaxPool2d
: Dies führt max pooling auf der Ausgabe mit der angegebenen Kernelgröße ausnn.Dropout
: Dies wird verwendet, um dropout mit einer gegebenen Wahrscheinlichkeit auf der Ausgabe anzuwendennn.Linear
: Dies ist grundsätzlich eine vollständig verknpfte Schichtnn.Sequential
: Technisch gesehen ist dies kein Typ von Schicht, aber es hilft dabei, unterschiedliche Operationen, die zum gleichen Schritt gehören, zu kombinieren
Mit diesen Kenntnissen können wir nun unseren VGG16-Modell auf der Architektur aus dem Paper aufbauen:
VGG16 von Scratch
Hyperparameter
Ein wichtiger Teil jedes maschinellen oder deep learning Projekts besteht darin, die Hyperparameter zu optimieren. Hier werden wir nicht verschiedene Werte für diese experimentieren, sondern wir werden sie vorher definieren müssen. Dies包括但不限于 die Definition der Anzahl der Epochen, der Batchgröße, der Lernrate, der Verlustfunktion sowie des Optimizers
Hyperparameter einstellen
Training
Wir sind nun bereit, unser Modell zu trainieren. Wir werden zunächst anschauen, wie wir unser Modell in torch
trainieren und dann auf den Code eingehen:
- Für jede Epoche gehen wir durch die Bilder und Label innerhalb unseres
train_loader
und verschieben diese Bilder und Label an den GPU, wenn verfügbar. Dies geschieht automatisch - Wir verwenden unser Modell, um auf den Label zu predigen (
model(images)
) und berechnen dann den Verlust zwischen den Vorhersagen und den wahren Labeln mit unserer Verlustfunktion (criterion(outputs, labels)
) - Dann verwenden wir diesen Verlust, um backpropagation durchzuführen (
loss.backward
) und die Gewichte zu aktualisieren (optimizer.step()
). Denken Sie jedoch daran, die Gradienten vor jedem Update auf Null zu setzen. Dies wird mitoptimizer.zero_grad()
erledigt - Außerdem berechnen wir am Ende jeder Epoche auch die Genauigkeit des Modells auf unserem Validierungsdatensatz. In diesem Fall brauchen wir keine Gradienten, also verwenden wir
with torch.no_grad()
für eine schnellere Evaluierung
Nun kombinieren wir all das in folgendem Code:
Training
Wir können die Ausgabe des obigen Codes wie folgt sehen, die zeigt, dass das Modell tatsächlich lernt, da der Verlust mit jeder Epoche abnimmt:
Training Verluste
Testing
Für die Tests verwenden wir exakt den gleichen Code wie beim Validieren, allerdings mit dem test_loader
:
Testing
Durch die Verwendung des oben stehenden Codes und die Trainings des Modells für 20 Epochen konnten wir eine Genauigkeit von 75% auf dem Testset erreichen.
Schlussfolgerung
Lassen Sie uns nun abschließend zusammenfassen, was wir in diesem Artikel taten:
- Wir haben zunächst die Architektur und verschiedene Arten von Schichten im VGG-16-Modell verstanden
- Danach haben wir das CIFAR100-Datensatz mit
torchvision
geladen und vorverarbeitet - Dann haben wir mit
PyTorch
unser VGG-16-Modell von Grund auf aufgebaut und verschiedene Arten von Schichten intorch
verstanden - Schließlich haben wir unser Modell auf dem CIFAR100-Datensatz trainiert und getestet, und das Modell hat auf dem Testdatensatz mit 75% Genauigkeit gut abgeschnitten
Weitere Arbeit
Mit diesem Artikel erhalten Sie eine gute Einführung und praktische Lernform, aber Sie werden noch mehr lernen, wenn Sie dies erweitern und sehen, was Sie sonst tun können:
- Sie können verschiedene Datensets verwenden. Ein solches Datenset ist CIFAR10 oder ein Subset der ImageNet-Datenbank.
- Sie können mit verschiedenen Hyperparameter-Kombinationen experimentieren und die beste finden, die für das Modell geeignet ist.
- Schließlich können Sie versuchen, Schichten hinzuzufügen oder zu entfernen, um deren Auswirkung auf die Fähigkeiten des Modells zu testen. Noch besser wäre es, die VGG-19-Version dieses Modells zu entwickeln.
Source:
https://www.digitalocean.com/community/tutorials/vgg-from-scratch-pytorch