Hoe een CNN te implementeren met Deeplearning4j

1. Overzicht

In deze tutorial zullen we bouw en train een convolutioneel neuraal netwerk model met behulp van de Deeplearning4j-bibliotheek in Java.

Raadpleeg onze gids over Deeplearning4j voor meer informatie over het opzetten van de bibliotheek.

2. Afbeeldingsclassificatie

2.1. Probleemstelling

Stel dat we een reeks afbeeldingen hebben. Elke afbeelding vertegenwoordigt een object van een bepaalde klasse. Bovendien behoort het object op de afbeelding tot de enige bekende klasse. Zo, de probleemstelling is om het model te bouwen dat in staat zal zijn om de klasse van het object op de gegeven afbeelding te herkennen.

Laten we bijvoorbeeld zeggen dat we een reeks afbeeldingen hebben met tien handgebaren. We bouwen een model en trainen het om ze te classificeren. Na de training kunnen we andere afbeeldingen doorgeven en de handgebaren daarop classificeren. Het gegeven gebaar behoort natuurlijk tot de bekende klassen te behoren.

2.2. Afbeelding representatie

In het computergeheugen kan de afbeelding worden weergegeven als een matrix van getallen. Elk nummer is een pixelwaarde, variërend van 0 tot 255.

Een afbeelding in grijstinten is een 2D-matrix. Evenzo is de RGB-afbeelding een 3D-matrix met afmetingen voor breedte, hoogte en diepte.

Zoals we kunnen zien, de afbeelding is een reeks getallen. Daarom kunnen we meerlaagse netwerkmodellen bouwen om ze te trainen om afbeeldingen te classificeren.

3. Convolutionele neurale netwerken

Een Convolutioneel Neuraal Netwerk (CNN) is een meerlaags netwerkmodel met een specifieke structuur. De structuur van een CNN kan worden onderverdeeld in twee blokken: convolutionele lagen en volledig verbonden (of dichte) lagen. Laten we ze allemaal eens bekijken.

3.1. Convolutionele laag

Elk convolutionele laag is een reeks vierkante matrices, kernels genaamd. Bovenal hebben we ze nodig om convolutie uit te voeren op het invoerbeeld. Het aantal en de grootte kan variëren, afhankelijk van de gegeven dataset. We gebruiken meestal 3 × 3 of 5 × 5 kernels, en zelden 7 × 7. De exacte maat en hoeveelheid worden met vallen en opstaan ​​geselecteerd.

Bovendien selecteren we willekeurig de variabelen van kernelmatrices aan het begin van de trein. Het zijn de gewichten van het netwerk.

Om convolutie uit te voeren, kunnen we de kernel gebruiken als het schuifvenster. We vermenigvuldigen de gewichten van de kernel met de corresponderende beeldpixels en berekenen de som. Vervolgens kunnen we de kernel verplaatsen om het volgende deel van de afbeelding te bedekken met stride (naar rechts) en padding (naar beneden). Als resultaat zullen we waarden hebben die in verdere berekeningen zullen worden gebruikt.

Kortom, met deze laag krijgen we een geconvolueerd beeld. Sommige variabelen zijn mogelijk kleiner dan nul. Dit betekent meestal dat deze variabelen minder belangrijk zijn dan de andere. Daarom is het toepassen van de ReLU-functie een goede insteek om minder berekeningen verder uit te voeren.

3.2. Subsampling-laag

De subsampling (of pooling) laag is een laag van het netwerk, meestal gebruikt na de convolutionele laag. Na de convolutie krijgen we veel berekende variabelen. Het is echter onze taak om de meest waardevolle onder hen te kiezen.

De aanpak is om een ​​schuifvenster-algoritme toe te passen op het geconvolueerde beeld. Bij elke stap kiezen we de maximale waarde in het vierkante venster met een vooraf gedefinieerde grootte, meestal tussen 2 × 2 en 5 × 5 pixels. Als gevolg hiervan hebben we minder berekende parameters. Daarom zal dit de berekeningen verminderen.

3.3. Dichte laag

Een dichte (of volledig verbonden) laag is er een die uit meerdere neuronen bestaat. We hebben deze laag nodig om classificatie uit te voeren. Bovendien kunnen er twee of meer van dergelijke opeenvolgende lagen zijn. Belangrijk is dat de laatste laag een grootte moet hebben die gelijk is aan het aantal klassen voor classificatie.

De output van het netwerk is de waarschijnlijkheid dat de afbeelding bij elk van de klassen hoort. Om de kansen te voorspellen, gebruiken we de Softmax-activeringsfunctie.

3.4. Optimalisatietechnieken

Om te kunnen trainen, moeten we de gewichten optimaliseren. Onthoud dat we deze variabelen aanvankelijk willekeurig kiezen. Het neurale netwerk is een grote functie. En het heeft veel onbekende parameters, onze gewichten.

Als we een afbeelding doorgeven aan het netwerk, geeft dat ons het antwoord. Dan kunnen we bouw een verliesfunctie op, die van dit antwoord zal afhangen. In termen van begeleid leren hebben we ook een concreet antwoord: de echte klas. Onze missie is om deze verliesfunctie te minimaliseren. Als het ons lukt, is ons model goed opgeleid.

Om de functie te minimaliseren, moeten we de gewichten van het netwerk bijwerken. Om dat te doen, kunnen we de afgeleide van de verliesfunctie berekenen met betrekking tot elk van deze onbekende parameters. Vervolgens kunnen we elk gewicht bijwerken.

We kunnen de gewichtswaarde verhogen of verlagen om het lokale minimum van onze verliesfunctie te vinden, omdat we de helling kennen. Bovendien, dit proces is iteratief en wordt Gradient Descent genoemd. Backpropagation gebruikt gradiëntafdaling om de gewichtsupdate van het einde naar het begin van het netwerk te verspreiden.

In deze tutorial gebruiken we het optimalisatie-algoritme Stochastic Gradient Decent (SGD). Het belangrijkste idee is dat we bij elke stap willekeurig de batch met treinafbeeldingen kiezen. Dan passen we backpropagation toe.

3.5. Evaluatiestatistieken

Ten slotte moeten we na het trainen van het netwerk informatie krijgen over hoe goed ons model presteert.

De meest gebruikte statistiek is nauwkeurigheid. Dit is de verhouding tussen correct geclassificeerde afbeeldingen en alle afbeeldingen. Ondertussen, recall, precisie en F1-score zijn zeer belangrijke statistieken voor beeldclassificatie ook.

4. Voorbereiding van de dataset

In deze sectie bereiden we de afbeeldingen voor. Laten we in deze tutorial de ingesloten CIFAR10-dataset gebruiken. We maken iterators om toegang te krijgen tot de afbeeldingen:

openbare klasse CifarDatasetService implementeert IDataSetService {privé CifarDataSetIterator trainIterator; privé CifarDataSetIterator testIterator; openbare CifarDatasetService () {trainIterator = nieuwe CifarDataSetIterator (trainBatch, trainImagesNum, true); testIterator = nieuwe CifarDataSetIterator (testBatch, testImagesNum, false); } // andere methoden en velden declaratie}

We kunnen zelf een aantal parameters kiezen. TrainBatch en testBatch zijn het aantal afbeeldingen per trein respectievelijk evaluatiestap. TrainImagesNum en testImagesNum zijn de aantallen afbeeldingen voor training en testen. Een tijdperk duurt trainImagesNum / trainBatch stappen. Dus als je 2048 treinafbeeldingen hebt met een batchgrootte = 32, krijg je 2048/32 = 64 stappen per epoche.

5. Convolutioneel neuraal netwerk in Deeplearning4j

5.1. Het model bouwen

Laten we vervolgens ons CNN-model helemaal opnieuw bouwen. Om het te doen, we zullen convolutionele, subsampling (pooling) en volledig verbonden (dichte) lagen gebruiken.

MultiLayerConfiguration-configuratie = nieuwe NeuralNetConfiguration.Builder () .seed (1611) .optimizationAlgo (OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT) .learningRate (properties.getLearningRate ()). Regularization (true) .updater (properties.getlayerOptimizer) (.). (0, conv5x5 ()) .layer (1, pooling2x2Stride2 ()) .layer (2, conv3x3Stride1Padding2 ()) .layer (3, pooling2x2Stride1 ()) .layer (4, conv3x3Stride1Padding1 ()). (5, pooling2x2Stride1 ()). )) .layer (6, dense ()) .pretrain (false) .backprop (true) .setInputType (dataSetService.inputType ()) .build (); netwerk = nieuw MultiLayerNetwork (configuratie);

Hier specificeren we de leersnelheid, het update-algoritme, het invoertype van ons model en de gelaagde architectuur. We kunnen met deze configuraties experimenteren. We kunnen dus veel modellen trainen met verschillende architecturen en trainingsparameters. Verder kunnen we de resultaten vergelijken en het beste model kiezen.

5.2. Het model trainen

Daarna gaan we het gebouwde model trainen. Dit kan gedaan worden in een paar regels code:

openbare ongeldige trein () {netwerk.init (); IntStream.range (1, epochsNum + 1) .forEach (epoch -> {network.fit (dataSetService.trainIterator ());}); }

Het aantal tijdperken is de parameter die we zelf kunnen specificeren. We hebben een kleine dataset. Als resultaat zullen enkele honderden tijdperken voldoende zijn.

5.3. Evaluatie van het model

Ten slotte kunnen we het nu getrainde model evalueren. De Deeplearning4j-bibliotheek biedt de mogelijkheid om dit gemakkelijk te doen:

openbare evaluatie evalueren () {retourneer netwerk.evalueren (dataSetService.testIterator ()); }

Evaluatie is een object dat berekende metrieken bevat na het trainen van het model. Die zijn nauwkeurigheid, precisie, terugroepen en F1-score. Bovendien heeft het een gebruiksvriendelijke afdrukbare interface:

========================== Scores ===================== # van klassen: 11 Nauwkeurigheid: 0,8406 Precisie: 0,7303 Recall: 0,6820 F1-score: 0,6466 ========================== ===========================

6. Conclusie

In deze zelfstudie hebben we geleerd over de architectuur van CNN-modellen, optimalisatietechnieken en evaluatiestatistieken. Verder hebben we het model geïmplementeerd met behulp van de Deeplearning4j-bibliotheek in Java.

Zoals gewoonlijk is code voor dit voorbeeld beschikbaar op GitHub.