Billede anerkendelse med Machine Learning på Python, Convolutional Neurale Netværk

kilde: the irish times, Pól — Muirí

Efter forbehandling af data, er det tid til at opbygge vores model til at udføre Billedet anerkendelse opgave. En af teknikken er at bruge konvolution neurale netværk.

denne artikel følger den artikel, jeg skrev om billedbehandling. Når dataene er tilgængelige for billedgenkendelsesopgaven, er det tid til at oprette en algoritme, der udfører opgaven. Blandt mange teknikker, der bruges til at genkende billeder som flerlags perceptron model, Convolution neurale netværk (CNN) fremstår som en meget effektiv. I denne artikel vil vi se, hvordan man bygger en CNN, og hvordan man anvender den på et datasæt med billeder.

når vi begynder at opbygge en billedgenkendelsesmodel for første gang, er det normalt en god ide at træne og evaluere den på et relativt simpelt datasæt.

en af de enkleste opgaver, vi kan udføre, er håndskrevet ciffergenkendelse. Givet et billede af et håndskrevet ciffer (dvs., 0, 1, …, 9), Vi ønsker, at vores model skal kunne klassificere sin numeriske værdi korrekt. Selvom denne opgave virker relativt enkel, bruges den faktisk ret ofte i det virkelige liv, såsom automatisk udtrækning af kreditkortnumre fra et billede. Det datasæt, vi vil bruge til digitgenkendelse, er MNIST-datasættet, som er det datasæt, der bruges til maskinlæringsbaseret digitgenkendelse.MNIST-databasen (Modified National Institute of Standards and Technology) indeholder 60.000 træningseksempler og 10.000 testeksempler. Databasen indeholder gråtoner håndskrevne cifre, der blev ændret til at passe i en 20h20 billedfelt, som derefter blev centreret i et 28h28 billede (polstret med mellemrum). MNIST-databasen er tilgængelig via Python.

i denne artikel vil jeg vise dig, hvordan du koder dit indviklede neurale netværk ved hjælp af keras, Tensorstrøms API på højt niveau. Jeg bruger tensorstrøm 2.0 i denne artikel.

1 – initialisering

da hvert gråtonebillede har dimensioner 28h28, er der 784 billedpunkter pr. Derfor svarer hvert inputbillede til en tensor på 784 normaliserede flydende punktværdier mellem 0,0 og 1,0. Etiketten til et billede er en en-hot tensor med 10 klasser (hver klasse repræsenterer et ciffer). Med hensyn til vores kode har vi img_v = 28, img_cols = 28 og num_classes = 10. Således input har form (number_eksempler, img_rækker, img_cols) dermed 60000h28h28.
et andet vigtigt element at oprette er det tilfældige frø, da vi vil beholde startpunktet, når en computer genererer en tilfældig talsekvens.

Vi importerer også MNIST-datasættet.

import tensorflow as tf # tensorflow 2.0
from keras.datasets import mnist
import numpy as npseed=0
np.random.seed(seed) # fix random seed
tf.random.set_seed(seed)# input image dimensions
num_classes = 10 # 10 digits
img_rows, img_cols = 28, 28 # number of pixels
# the data, shuffled and split between train and test sets
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()

2 – omformning og omskalering

som nævnt i det foregående afsnit har indgange form (taleksempler, img_rækker, img_cols). Men for at kunne bruge dataene med vores convolutional neurale netværk, er vi nødt til at få det til NHV-format.format har en form med fire dimensioner:

  1. antal billeddataprøver (batchstørrelse)
  2. højde på hvert billede
  3. bredde på hvert billede
  4. kanaler pr.billede

højden og bredden af hvert billede fra datasættet er img_rækker og img_cols, mens antallet af kanaler er 1 (da billederne er gråtoner).

hvert punkt indeholder også en gråtoneværdi kvantificeret med et heltal mellem 0 og 255. Så databasen er normaliseret til at have flydende punktværdier mellem 0,0 og 1,0. I dette tilfælde svarer 0,0 til en gråtonepunktsværdi på 255 (ren hvid), mens 1.0 svarer til en gråtonepunktværdi på 0 (ren sort).

X_train = X_train.reshape(X_train.shape, img_rows, img_cols, 1) 
X_test = X_test.reshape(X_test.shape, img_rows, img_cols, 1)input_shape = (img_rows, img_cols, 1)# cast floats to single precision
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')# rescale data in interval
X_train /= 255
X_test /= 255

3 – Casting label vektorer Y

Vi er nødt til at omdanne vores klasser til vektorer. Vi gør dette ved at trykke på følgende linje:

Y_train = keras.utils.to_categorical(Y_train, num_classes)
Y_test = keras.utils.to_categorical(Y_test, num_classes)

for at få en bedre forklaring på dette trin, skal du se denne artikel.

nu hvor vi har behandlet vores data, kan vi begynde at opbygge model.

Convolution neurale netværksmodel

som nævnt i slutningen af artiklen skrev jeg om billedbehandling, spiller filtre en stor rolle i billedgenkendelse. Vi bruger filtre til at transformere input og udtrække funktioner, der gør det muligt for vores model at genkende bestemte billeder. Et meget højt niveau eksempel på dette ville være et kurvedetekteringsfilter, som gør det muligt for vores model at skelne mellem cifre med kurver og cifre uden kurver.

1-filtre

som alle neurale netværksvægte er filterets vægte træningsbare variabler. Vi træner vores neurale netværk (via kernematricen vægte) til at producere filtre, der er i stand til at udtrække de mest nyttige skjulte funktioner.

når inputdataene har flere kanaler, vil et filter have en separat kernematrice pr. MNIST-datasættet har kun en kanal, men for andre typer billeddata (f.eks.

2-Convolution

Vi har nu nået omdrejningspunktet for convolutional neurale netværk: convolution. Konvolutionen repræsenterer, hvordan vi anvender vores filtervægte på inputdataene. Den vigtigste operation, der anvendes af en konvolution, er matricen prik produkt, dvs.en summation over det elementvise produkt af to matricer.

Antallet af matrix dot-produkter i en foldning afhænger af dimensionerne af input data og kerne matrix, samt skridtlængde størrelse. Skridtstørrelsen er den lodrette / vandrette forskydning af kernematricen, når den bevæger sig langs inputdataene.

3-polstring

Nogle gange, når vi udfører prikproduktoperationen som set før, bruger vi ikke en række eller en kolonne. For at undgå dette fænomen kan vi bruge polstring.

Hvis vi således vil bruge alle inputdataene i vores foldning, kan vi padde inputdatamatricen med 0 ‘er. dette betyder, at vi tilføjer rækker/kolonner, der udelukkende er lavet af 0’ er, til kanterne af inputdatamatricen. Da 0 ganget med et hvilket som helst tal resulterer i 0, påvirker polstringen ikke matricen prikprodukter. Dette er vigtigt, fordi vi ikke ønsker at tilføje forvrængninger til vores konvolution.

4-Convolution layer

et convolution layer i en CNN anvender flere filtre til input tensor. Mens hvert filter har en separat kernematrice for hver af indgangskanalerne, er det samlede resultat af et filters konvolution summen af omviklingerne på tværs af alle indgangskanalerne.

tilføjelse af flere filtre til et konvolutionslag giver laget mulighed for bedre at udtrække skjulte funktioner. Dette kommer dog på bekostning af yderligere træningstid og beregningskompleksitet, da filtre tilføjer ekstra vægte til modellen. Antallet af kanaler til outputdataene er lig med antallet af filtre, som konvolutionslaget bruger.

Pooling

mens konvolutionslaget udtrækker vigtige skjulte funktioner, kan antallet af funktioner stadig være ret stort. Vi kan bruge pooling til at reducere størrelsen på dataene i højde-og breddedimensionerne. Dette gør det muligt for modellen at udføre færre beregninger og i sidste ende træne hurtigere. Det forhindrer også overmontering ved kun at udtrække de mest fremtrædende funktioner og ignorere potentielle forvrængninger eller usædvanlige funktioner, der kun findes i nogle få eksempler.

hvordan fungerer pooling?

i lighed med en konvolution bruger vi filtermatricer i pooling. Pooling-filteret har dog ingen vægte, og det udfører heller ikke matrice dot-produkter. I stedet anvender den en reduktionsoperation til underafsnit af inputdataene.

den type pooling, der normalt bruges i CNNs, kaldes maksimal pooling. Filtrene til maks. pooling bruger maks. funktionen til at opnå det maksimale antal i hver submatriks af inputdataene.

flere lag

1 – Tilføjelse af ekstra lag

som alle neurale netværk kan CNN ‘ er drage fordel af yderligere lag. De ekstra lag giver en CNN mulighed for i det væsentlige at stable flere filtre sammen til brug på billeddataene. Men i lighed med at opbygge et neuralt netværk skal vi være forsigtige med, hvor mange ekstra lag vi tilføjer. Hvis vi tilføjer for mange lag til en model, risikerer vi at have det overfit til træningsdataene og derfor generalisere meget dårligt. Desuden tilføjer hvert ekstra lag beregningskompleksitet og øger træningstiden for vores model.

2-Forøg filtre

Vi øger normalt antallet af filtre i et konvolutionslag, jo dybere det er i vores model. I dette tilfælde har vores andet konvolutionslag 64 filtre sammenlignet med de 32 filtre i det første konvolutionslag. Jo dybere konvolutionslaget er, desto mere detaljerede bliver de ekstraherede funktioner. For eksempel kan det første foldningslag have filtre, der udtrækker funktioner såsom linjer, kanter og kurver. Når vi kommer til det andet niveau, kunne filtrene i konvolutionslaget nu udtrække flere kendetegn, såsom den skarpe vinkel på en 77 eller de krydsende kurver på en 88.

fuldt forbundet lag

1-fuldt forbundet lag

Vi anvender et fuldt forbundet lag af størrelse 1024 (dvs.antallet af neuroner i laget) til outputdataene for det andet poolinglag. Antallet af enheder er noget vilkårligt. Nok til at være stærk, men ikke så meget som at være for ressourceintensiv. Formålet med det fuldt tilsluttede lag er at samle datafunktionerne, før vi konverterer dem til klasser. Dette gør det muligt for modellen at gøre bedre forudsigelser, end hvis vi lige havde konverteret pooling output direkte til klasser.

2-udfladning

de data, vi har brugt i vores model, er af NHV-formatet. For at kunne bruge et fuldt forbundet lag har vi imidlertid brug for, at dataene skal være en matrice, hvor antallet af rækker repræsenterer batchstørrelsen, og kolonnerne repræsenterer datafunktionerne. Denne gang er vi nødt til at omforme i den modsatte retning og konvertere fra NHV til en 2D-matrice.

Dropout

1 – Co-tilpasning

Co-tilpasning refererer til, når flere neuroner i et lag ekstraherer de samme eller meget lignende skjulte funktioner fra inputdataene. Dette kan ske, når forbindelsesvægtene for to forskellige neuroner er næsten identiske.

når et fuldt forbundet lag har et stort antal neuroner, er det mere sandsynligt, at co-tilpasning forekommer. Dette kan være et problem af to grunde. For det første er det spild af beregning, når vi har overflødige neuroner, der beregner det samme output. For det andet, hvis mange neuroner udvinder de samme funktioner, tilføjer det mere betydning for disse funktioner til vores model. Dette fører til overmontering, hvis de duplikerede ekstraherede funktioner kun er specifikke for træningssættet.

2-Dropout

måden vi minimerer Co-tilpasning til fuldt forbundne lag med mange neuroner er ved at anvende dropout under træning. I dropout lukker vi tilfældigt en brøkdel af et lags neuroner ved hvert træningstrin ved at nulstille neuronværdierne.

Soft-maks lag

da der er 10 mulige cifre, kan et MNIST-billede være, bruger vi et 10 neuron fuldt forbundet lag til at opnå klasserne for hver cifret klasse. Softmaks-funktionen anvendes til klasserne for at konvertere dem til PR.

opbygning af modellen

nu er vi klar til at bygge vores model. Her er koden:

from keras.models import Sequential
from keras.layers import Dense, Conv2D, Flatten
from keras.layers import MaxPooling2D, Dropoutmodel = Sequential()#add model layers
model.add(Conv2D(32, kernel_size=(5, 5),
activation='relu',
input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))# add second convolutional layer with 20 filters
model.add(Conv2D(64, (5, 5), activation='relu'))
# add 2D pooling layer
model.add(MaxPooling2D(pool_size=(2, 2)))
# flatten data
model.add(Flatten())
# add a dense all-to-all relu layer
model.add(Dense(1024, activation='relu'))
# apply dropout with rate 0.5
model.add(Dropout(0.5))
# soft-max layer
model.add(Dense(num_classes, activation='softmax'))

den modeltype, vi vil bruge, er sekventiel. Sekventiel er den nemmeste måde at opbygge en model i Keras. Det giver dig mulighed for at opbygge en model lag for lag.

Vi bruger Tilføj () – metoden til at vedhæfte lag til vores model. Med henblik på vores indledende eksempel er det tilstrækkeligt at fokusere på tætte lag for enkelhed. Hvert tæt () lag accepterer som sit første krævede argument et heltal, der specificerer antallet af neuroner. Typen af aktiveringsfunktion for laget defineres ved hjælp af det valgfrie aktiveringsargument, hvis indgang er navnet på aktiveringsfunktionen i strengformat. Eksempler omfatter relu, tanh, elu, sigmoid, softmaks.

i dette neurale netværk har vi 2 foldningslag efterfulgt hver gang af et samlingslag. Derefter fladder vi dataene for at tilføje et tæt lag, hvorpå vi anvender dropout med en hastighed på 0,5. Endelig tilføjer vi et tæt lag for at allokere hvert billede med den rigtige klasse.

kompilering af modellen

Dernæst skal vi kompilere vores model. Kompilering af modellen tager tre parametre: optimering, tab og målinger.

optimeringen styrer indlæringshastigheden. Vi vil bruge ‘adam’ som vores optimerer. Adam er generelt en god optimeringsanordning til brug i mange tilfælde. Adam optimisator justerer læringshastigheden under hele træningen.

læringshastigheden bestemmer, hvor hurtigt de optimale vægte for modellen beregnes. En mindre læringshastighed kan føre til mere nøjagtige vægte (op til et bestemt punkt), men nedskæringen er computertiden.

Vi bruger ‘categorical_crossentropy’ til vores tabsfunktion. Dette er det mest almindelige valg til klassificering. En lavere score indikerer, at modellen klarer sig bedre.

for at gøre tingene endnu lettere at fortolke bruger vi metrikken ‘nøjagtighed’ til at se nøjagtighedsscore på valideringssættet, når vi træner modellen.

#compile model using accuracy to measure model performance
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=)

træning af modellen

nu træner vi vores model. For at træne bruger vi funktionen ‘fit()’ på vores model med følgende parametre: træningsdata (Y_train), måldata (Y_train), valideringsdata og antallet af epoker.

til vores valideringsdata bruger vi det testsæt, der er leveret til os i vores datasæt, som vi har opdelt i Y_test og Y_test.

antallet af epoker er antallet af gange modellen vil cykle gennem dataene. Jo flere epoker vi kører, jo mere vil modellen blive bedre, op til et bestemt punkt. Efter dette punkt vil modellen stoppe med at forbedre sig i hver epoke. For vores model indstiller vi antallet af epoker til 3.

#train the model
model.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=3)

Evaluer modellen

nu har vi trænet vores model, vi kan evaluere dens ydeevne:

# evaluate the model
score = model.evaluate(X_test, Y_test, verbose=1)
# print performance
print()
print('Test loss:', score)
print('Test accuracy:', score)

således har vi en nøjagtighed på 99,3% og en tabt på 0,025 på testsættet, hvilket er meget godt. Vi kan stadig forbedre modellen ved at øge antallet af epoch og ved at indføre en batchstørrelse.

lav forudsigelser

Hvis du vil se de faktiske forudsigelser, som vores model har lavet for testdataene, kan vi bruge funktionen predict_classes. Vi kan også til dette ved hjælp af forudsige funktion vil give et array med 10 numre. Disse tal er sandsynlighederne for, at inputbilledet repræsenterer hvert ciffer (0-9). Array-indekset med det højeste tal repræsenterer modelforudsigelsen. Summen af hvert array er lig med 1 (da hvert tal er en sandsynlighed).

for at vise dette viser vi forudsigelserne for de første 4 billeder i testsættet.

Bemærk: Hvis vi har nye data, kan vi indtaste vores nye data i predict-funktionen for at se de forudsigelser, vores model laver på de nye data. Da vi ikke har nye usete data, viser vi forudsigelser ved hjælp af testsættet for nu.

#predict first 4 images in the test set
model.predict_classes(X_test)

#predict first 4 images in the test set
model.predict(X_test)

We can see that our model predicted 7, 2, 1 and 0 for the first four images.

Let’s compare this with the actual results.

#actual results for first 4 images in test set
y_test

div>

de faktiske resultater viser, at de første fire billeder også er 7, 2,1 og 0. Vores model forudsagde korrekt!

hele modellen

import tensorflow as tf # tensorflow 2.0
from keras.datasets import mnist
import numpy as np
seed=0
np.random.seed(seed) # fix random seed
tf.random.set_seed(seed)
# input image dimensions
num_classes = 10 # 10 digitsimg_rows, img_cols = 28, 28 # number of pixels# the data, shuffled and split between train and test sets
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()X_train = X_train.reshape(X_train.shape, img_rows, img_cols, 1)
X_test = X_test.reshape(X_test.shape, img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)# cast floats to single precision
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')# rescale data in interval
X_train /= 255
X_test /= 255Y_train = keras.utils.to_categorical(Y_train, num_classes)
Y_test = keras.utils.to_categorical(Y_test, num_classes)from keras.models import Sequential
from keras.layers import Dense, Conv2D, Flatten
from keras.layers import MaxPooling2D, Dropout
model = Sequential()#add model layers
model.add(Conv2D(32, kernel_size=(5, 5),
activation='relu',
input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
# add second convolutional layer with 20 filters
model.add(Conv2D(64, (5, 5), activation='relu'))
# add 2D pooling layer
model.add(MaxPooling2D(pool_size=(2, 2)))
# flatten data
model.add(Flatten())
# add a dense all-to-all relu layer
model.add(Dense(1024, activation='relu'))
# apply dropout with rate 0.5
model.add(Dropout(0.5))
# soft-max layer
model.add(Dense(num_classes, activation='softmax'))#compile model using accuracy to measure model performance
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=)#train the model
model.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=3)# evaluate the model
score = model.evaluate(X_test, Y_test, verbose=1)# print performance
print()
print('Test loss:', score)
print('Test accuracy:', score)#predict first 4 images in the test set
model.predict(X_test)model.predict_classes(X_test)#actual results for first 4 images in test set
Y_test

fortsættes…

i denne artikel taklede jeg den anden del af billedgenkendelse, som bygger et Konvolutionsneuralt netværk.

Jeg håber, du fandt, hvad du kom her for i denne artikel, og bliv hos mig til de næste episoder af denne billedgenkendelsesrejse!

PS: Jeg er i øjeblikket en Master of Engineering studerende på Berkeley, og hvis du vil diskutere emnet, er du velkommen til at nå mig. Her er min e-mail.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.