Houdend aan mijn reeks artikelen over het bouwen van klassieke convolutionele neurale netwerken die de computervisuele wereld in de laatste 1-2 decennia revolutioneerden, zullen we nu VGG, een zeer diep convolutioneel neurale netwerk, vanaf de grond af opbouwen met PyTorch. U kunt de vorige artikelen in de reeks op mijn profiel zien, voornamelijk LeNet5 en AlexNet.
Net als eerder zullen we kijken naar de architectuur en intuïtie achter VGG en hoe de resultaten destijds waren. We zullen vervolgens onze dataset, CIFAR100, verkennen en hem in ons programma laden met behulp van code die geheugengefficiëntie is. Daarna zullen we VGG16 (het getal verwijst naar het aantal lagen, er zijn eigenlijk twee versies: VGG16 en VGG19) vanaf de grond af implementeren met PyTorch en trainen we het op ons dataset, waarna we de prestaties evalueren op ons testset om te zien hoe het presteert op ongeziene data
VGG
Bij het bouwen op het werk van AlexNet focusert VGG op een ander cruciale aspect van Convolutionele Neurale Netwerken (CNN’s), diepte. Het werd ontwikkeld door Simonyan en Zisserman. Het bestaat gewoonlijk uit 16 convolutionele lagen, maar kan ook uitgebreid worden tot 19 lagen (dus de twee versies, VGG-16 en VGG-19). Alle convolutionele lagen bestaan uit 3×3 filters. U kunt meer over het netwerk lezen in het officiële paper hier
VGG16-architectuur. Bron
Data Laden
Dataset
Voordat we beginnen met het bouwen van het model, is het laden, analyseren en voorbereiden van de dataset een van de belangrijkste stappen in elk project op het gebied van Machine Learning. In dit artikel zullen we werken met de CIFAR-100 dataset. Deze dataset is net als de CIFAR-10, maar bevat 100 klassen met elk 600 afbeeldingen. Er zijn 500 trainingsbeelden en 100 testbeelden per klasse. De 100 klassen in de CIFAR-100 zijn onderverdeeld in 20 superklassen. Elke afbeelding wordt geassocieerd met een “fijne” label (de klasse waartoe het behoort) en een “coarse” label (de superklasse waartoe het behoort). We zullen in dit artikel gebruik maken van het “fijne” label. Hier is de lijst met klassen in de CIFAR-100:
Lijst met klassen voor de CIFAR-100 dataset
Libraries importeren
We zullen vooral werken met torch
(gebruikt voor het bouwen van het model en het trainen), torchvision
(voor data- Laden/verwerking, bevat datasets en methodes voor de verwerking van deze datasets in computer vision) en numpy
(voor wiskundige manipulatie). We zullen ook een variabele device
definiëren zodat het programma de GPU gebruikt indien beschikbaar
Gegevens worden geladen
torchvision
is een bibliotheek die gemakkelijke toegang biedt tot veel computervisuele datasetten en methodes om deze datasetten gemakkelijk en intuitief te voorbereiden
- We definiëren een functie
data_loader
die afhankelijk van de argumenten train/validatiegegevens of testgegevens teruggeeft - We beginnen met het definiëren van de variabele
normalize
met de gemiddelden en standaardafwijkingen van elke kanaal (rood, groen en blauw) in het dataset. Dit kan handmatig worden berekend, maar is ook online beschikbaar. Dit wordt gebruikt in de variabeletransform
waar we de gegevens opnieuw schalen, omzetten in tensor en vervolgens normaliseren - Als het argument
test
waar is, laden we simpelweg de testpartij van het dataset en geven we dit terug met hulp van data loaders (explandeerd hieronder) - In het geval dat
test
niet waar is (standaardgedrag ook), laden we de trainpartij van het dataset en splitsen we deze random in train- en validatieset (0.9:0.1) - Ten slotte maakten we gebruik van data loaders. Dit kan de prestatie niet beïnvloeden bij een klein dataset zoals CIFAR100, maar kan de prestatie behoorlijk belemmeren bij grote datasets en wordt algemeen gezien als een goed gedrag. Data loaders staan ons toe om de gegevens in batchformat door te itereren, en de gegevens worden geladen terwijl geiterated wordt en niet allemaal direct in het begin van uw RAM geladen.
VGG16 vanaf het begin
Om het model vanaf het begin te bouwen, moeten we eerst begrijpen hoe modeldefinities werken in torch
en de verschillende typen lagen die we hier zullen gebruiken:
- Elke aangepaste model moet erfelijk zijn aan de
nn.Module
klasse, aangezien deze enkele basisfunctionaliteit biedt die het model helpt te trainen. - Tweede, er zijn twee hoofdactiviteiten die we moeten uitvoeren. Eerst, definieer de verschillende lagen van ons model binnen de
__init__
functie en de sequentie waarin deze lagen op de invoer worden uitgevoerd binnen deforward
functie.
Laat ons nu de verschillende typen lagen definiëren die we hier gebruiken:
nn.Conv2d
: Dit zijn de convolutie lagen die het aantal invoer- en uitgangskanalen aanvaarden als argumenten, samen met de filter kleine voor het filter. Het accepteert ook eventuele strides of padding als u die wilt toepassen.nn.BatchNorm2d
: Dit past batch normalisatie toe op de uitvoer van de convolutie laag.nn.ReLU
: Dit is de activatie die wordt toegepast op de verschillende uitvoer in het netwerk.nn.MaxPool2d
: Dit toepast max pooling op de uitvoer met de kernelgrootte gegevennn.Dropout
: Dit wordt gebruikt om dropout toe te passen op de uitvoer met een gegeven kansnn.Linear
: Dit is eigenlijk een volledig verbonden laagnn.Sequential
: Dit is technisch gezien geen soort laag, maar helpt bij het combineren van verschillende bewerkingen die deel uitmaken van hetzelfde stap
Met deze kennis kunnen we nu onze VGG16-model bouwen met de architectuur uit het artikel:
VGG16 vanaf Scratch
Hyperparameters
Een van de belangrijke delen van elk machine- of diepgeleerdenproject is het optimaliseren van de hyperparameters. Hier zal niet geexperimenteerd worden met verschillende waarden voor die, maar we zullen ze vooraf moeten definiëren. Dit omvat het definiëren van het aantal epochs, batchgrootte, learning rate, verliesfunctie samen met de optimizer
Hyperparameters instellen
Trainen
We zijn nu klaar om ons model te trainen. We zullen eerst kijken hoe we ons model trainen in torch
en vervolgens naar de code kijken:
- Voor elke epoch ga we door de afbeeldingen en labels binnen ons
train_loader
en verplaats die afbeeldingen en labels naar de GPU als beschikbaar. Dit gebeurt automatisch - We gebruiken ons model om voorspellingen te maken op de labels (
model(images)
) en bereken vervolgens de verliesfunctie tussen de voorspellingen en de ware labels met behulp van onze verliesfunctie (criterion(outputs, labels)
) - Vervolgens gebruiken we dat verlies om terug te propageren (
loss.backward
) en de gewichten bij te werken (optimizer.step()
). Vergeet echter niet om de gradiënten op nul te zetten voor elke update. Dat doen we met behulp vanoptimizer.zero_grad()
- Ook aan het eind van elke epoch gebruiken we ons validatieset om de accurateit van het model te berekenen. In dit geval hoeft geen gradiënten gebruikt te worden, dus gebruiken we
with torch.no_grad()
voor sneller evalueren
Nu combineren we al dit samen in het volgende code:
Trainen
We kunnen de uitvoer van bovenstaande code zien als volgt, die aangeeft dat het model daadwerkelijk leert omdat het verlies afneemt met elke epoch:
Training Verliezen
Testen
Voor testen gebruiken we exact hetzelfde code als voor validatie, maar met de test_loader
:
Testen
Met het bovenstaande code en door het trainen van het model voor 20 epochs, zijn we in staat geweest om een nauwkeurigheid van 75% op de testset te behalen.
Conclusie
Laten we nu samenvatten wat we in dit artikel hebben gedaan:
- We zijn begonnen met het begrijpen van de architectuur en de verschillende soorten lagen in het VGG-16 model
- Volgend zijn we de CIFAR100 dataset geladen en voorbereidt door middel van
torchvision
- Dan hebben we
PyTorch
gebruikt om ons VGG-16 model van de grond af op te bouwen, inclusief het begrijpen van de verschillende typen lagen beschikbaar intorch
- Ten slotte hebben we ons model getraind en getest op de CIFAR100 dataset, en het model leek goed te presteren op de testdataset met 75% nauwkeurigheid
Toekomstige Werk
Met dit artikel krijg je een goede introductie en praktische leer maar je zult veel meer leren als je dit uitbreidt en zie wat je anders kunt doen:
- U kunt proberen met verschillende datasets. Een dergelijk dataset is CIFAR10 of een subset van de ImageNet dataset.
- U kunt experimenteren met verschillende hyperparameters en kijk welke combinatie er het beste is voor het model
- U kunt tenslotte proberen om lagen toe te voegen of weg te halen uit het dataset om hun impact te zien op de capaciteit van het model. Nog beter, probeer de VGG-19 versie van dit model aan te bouwen.
Source:
https://www.digitalocean.com/community/tutorials/vgg-from-scratch-pytorch