recunoașterea imaginii cu învățare automată pe Python, rețea neuronală convoluțională

sursa: the Irish Times, P Unktifl Untif Muir Untif

după pre-procesarea datelor, este timpul pentru a construi modelul nostru pentru a efectua sarcina de recunoaștere a imaginii. Una dintre tehnici este utilizarea rețelei neuronale de convoluție.

Acest articol urmează articolul pe care l-am scris despre procesarea imaginilor. După ce datele disponibile pentru sarcina de recunoaștere a imaginii, este timpul pentru a crea un algoritm care va efectua sarcina. Printre numeroasele tehnici utilizate pentru recunoașterea imaginilor ca model de perceptron multistrat, rețeaua neuronală de convoluție (CNN) apare ca una foarte eficientă. În acest articol, vom vedea cum să construim un CNN și cum să îl aplicăm pe un set de date de imagini.

când începem să construim un model de recunoaștere a imaginilor pentru prima dată, este de obicei o idee bună să îl instruim și să îl evaluăm pe un set de date relativ simplu.

una dintre cele mai simple sarcini pe care le putem efectua este recunoașterea cifrelor scrise de mână. Având în vedere o imagine a unei cifre scrise de mână (adică., 0, 1, …, 9), vrem ca modelul nostru să poată clasifica corect valoarea sa numerică. Deși această sarcină pare relativ simplă, este de fapt folosită destul de des în viața reală, cum ar fi extragerea automată a numerelor cărților de credit dintr-o imagine. Setul de date pe care îl vom folosi pentru recunoașterea cifrelor este setul de date MNIST, care este setul de date utilizat pentru recunoașterea cifrelor bazate pe învățarea automată.baza de date Mnist (Institutul Național de standarde și Tehnologie modificat) conține 60.000 de exemple de instruire și 10.000 de exemple de testare. Baza de date conține cifre scrise de mână în tonuri de gri care au fost redimensionate pentru a se potrivi într-o cutie de 20×20 pixeli, care a fost apoi centrată într-o imagine de 28×28 (căptușită cu spațiu alb). Baza de date MNIST este accesibilă prin Python.

în acest articol, vă voi arăta cum să vă codificați rețeaua neuronală convoluțională folosind keras, API-ul de nivel înalt al TensorFlow. Folosesc tensorflow 2.0 în acest articol.

1 – inițializare

deoarece fiecare imagine în tonuri de gri are dimensiunile 28×28, există 784 pixeli pe imagine. Prin urmare, fiecare imagine de intrare corespunde unui tensor de 784 valori normalizate în virgulă mobilă între 0,0 și 1,0. Eticheta pentru o imagine este un tensor one-hot cu 10 clase (fiecare clasă reprezintă o cifră). În ceea ce privește codul nostru, avem img_rows = 28, img_cols = 28 și num_classes = 10. Astfel, intrarea are forma (number_examples, img_rows, img_cols), prin urmare, 60000x28x28.
un alt element important de configurat este sămânța aleatorie, deoarece dorim să păstrăm punctul de pornire atunci când un computer generează o secvență de numere aleatorii.

de asemenea, importăm setul de date MNIST.

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 – Remodelarea și redimensionarea

după cum sa menționat în secțiunea anterioară, intrările au formă (number_examples, img_rows, img_cols). Cu toate acestea, pentru a utiliza datele cu rețeaua noastră neuronală convoluțională, trebuie să le introducem în format NHWC.

formatul NHWC are o formă cu patru dimensiuni:

  1. Numărul de eșantioane de date de imagine (dimensiunea lotului)
  2. înălțimea fiecărei imagini
  3. lățimea fiecărei imagini
  4. canale pe imagine

înălțimea și lățimea fiecărei imagini din setul de date sunt img_rows și img_cols, în timp ce numărul de canale este 1 (deoarece imaginile sunt în tonuri de gri).

De asemenea, fiecare pixel conține o valoare în tonuri de gri cuantificată de un număr întreg între 0 și 255. Deci, baza de date este normalizată pentru a avea valori în virgulă mobilă între 0,0 și 1,0. În acest caz, 0,0 corespunde unei valori a pixelilor în tonuri de gri de 255 (alb pur), în timp ce 1.0 corespunde unei valori a pixelilor în tonuri de gri de 0 (negru pur).

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 – vectori de etichetă de turnare Y

trebuie să ne transformăm clasele în vectori. Facem acest lucru atingând următoarea linie:

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

pentru a avea o explicație mai bună a acestui pas, ar trebui să vedeți acest articol.

acum că ne-am procesat datele, putem începe să construim modelul.

convoluție model de rețea neuronală

după cum sa menționat la sfârșitul articolului pe care l-am scris despre procesarea imaginilor, filtrele joacă un rol imens în recunoașterea imaginii. Folosim filtre pentru a transforma intrările și extrage caracteristici care permit modelului nostru să recunoască anumite imagini. Un exemplu foarte înalt în acest sens ar fi un filtru de detectare a curbelor, care permite modelului nostru să facă distincția între cifrele cu curbe și cifrele fără curbe.

1-filtre

ca toate greutățile rețelei neuronale, greutățile filtrului sunt variabile antrenabile. Ne antrenăm rețeaua neuronală (prin greutățile matricei kernel-ului) pentru a produce filtre care sunt capabile să extragă cele mai utile caracteristici ascunse.

când datele de intrare au mai multe canale, un filtru va avea o matrice de nucleu separată pe canal. Setul de date MNIST are un singur canal, dar pentru alte tipuri de date de imagine (de exemplu, RGB), am antrena modelul pentru a obține greutăți optime pentru matricea nucleului fiecărui canal.

2-convoluția

am ajuns acum la punctul focal al rețelelor neuronale convoluționale: convoluția. Convoluția reprezintă modul în care aplicăm greutățile filtrului la datele de intrare. Operația principală utilizată de o convoluție este produsul matricei punct, adică o însumare peste produsul elementar al două matrice.

numărul de produse punct matrice într-o convoluție depinde de dimensiunile datelor de intrare și matricea kernel, precum și dimensiunea pas. Dimensiunea pasului este decalajul vertical / orizontal al matricei kernel-ului pe măsură ce se deplasează de-a lungul datelor de intrare.

3-Padding

uneori, atunci când facem operațiunea de produs dot așa cum sa văzut înainte, nu folosim un rând sau o coloană. Pentru a evita acest fenomen, putem folosi căptușeala.

astfel, dacă dorim să folosim toate datele de intrare în convoluția noastră, putem tampona matricea de date de intrare cu 0. Aceasta înseamnă că adăugăm rânduri / coloane realizate în întregime din 0 la marginile matricei de date de intrare. Deoarece 0 înmulțit cu orice număr rezultă în 0, umplutura nu afectează produsele matrix dot. Acest lucru este important pentru că nu vrem să adăugăm distorsiuni convoluției noastre.

4-convoluție strat

un strat convoluție într-un CNN aplică mai multe filtre tensorului de intrare. În timp ce fiecare filtru are o matrice de nucleu separată pentru fiecare dintre canalele de intrare, rezultatul general al convoluției unui filtru este suma convoluțiilor pe toate canalele de intrare.

adăugarea mai multor filtre la un strat de convoluție permite stratului să extragă mai bine caracteristicile ascunse. Cu toate acestea, acest lucru vine cu costul timpului suplimentar de antrenament și al complexității computaționale, deoarece filtrele adaugă greutăți suplimentare modelului. Numărul de canale pentru datele de ieșire este egal cu numărul de filtre pe care le folosește stratul de convoluție.

punerea în comun

în timp ce stratul de convoluție extrage caracteristici ascunse importante, Numărul de caracteristici poate fi încă destul de mare. Putem folosi punerea în comun pentru a reduce dimensiunea datelor în dimensiunile înălțime și lățime. Acest lucru permite modelului să efectueze mai puține calcule și, în cele din urmă, să se antreneze mai repede. De asemenea, previne suprasolicitarea, prin extragerea numai a celor mai importante caracteristici și ignorarea distorsiunilor potențiale sau a caracteristicilor neobișnuite găsite în doar câteva exemple.

cum funcționează punerea în comun?

Similar cu o convoluție, folosim matrice de filtrare în comun. Cu toate acestea, filtrul de punere în comun nu are greutăți și nici nu efectuează produse matrix dot. În schimb, aplică o operație de reducere la subsecțiunile datelor de intrare.

tipul de punere în comun, care este de obicei utilizat în CNNs este menționată ca Max pooling. Filtrele max pooling utilizează operația max pentru a obține numărul maxim în fiecare submatrică a datelor de intrare.

mai multe straturi

1 – Adăugarea de straturi suplimentare

ca toate rețelele neuronale, CNN-urile pot beneficia de straturi suplimentare. Straturile suplimentare permit unui CNN să stivă în esență mai multe filtre împreună pentru a fi utilizate pe datele imaginii. Cu toate acestea, similar cu construirea oricărei rețele neuronale, trebuie să fim atenți la câte straturi suplimentare adăugăm. Dacă adăugăm prea multe straturi la un model, riscăm să-l suprapunem la datele de antrenament și, prin urmare, să generalizăm foarte slab. În plus, fiecare strat suplimentar adaugă complexitate computațională și crește timpul de antrenament pentru modelul nostru.

2 – creșteți filtrele

de obicei creștem numărul de filtre într-un strat de convoluție cu cât este mai adânc în modelul nostru. În acest caz, al doilea strat de convoluție are 64 de filtre, comparativ cu cele 32 de filtre ale primului strat de convoluție. Cu cât stratul de convoluție este mai profund, cu atât caracteristicile extrase devin mai detaliate. De exemplu, primul strat de convoluție poate avea filtre care extrag caracteristici precum linii, margini și curbe. Când ajungem la al doilea nivel, filtrele stratului de convoluție ar putea extrage acum caracteristici mai distinctive, cum ar fi unghiul ascuțit al unui 77 sau curbele intersectate ale unui 88.

strat complet conectat

1-strat complet conectat

aplicăm un strat complet conectat de dimensiunea 1024 (adică numărul de neuroni din strat) la datele de ieșire ale celui de-al doilea strat de grupare. Numărul de unități este oarecum arbitrar. Suficient pentru a fi puternic, dar nu atât de mult încât să fie prea intensiv în resurse. Scopul stratului complet conectat este de a agrega caracteristicile de date înainte de a le converti în clase. Acest lucru permite modelului să facă predicții mai bune decât dacă tocmai am fi convertit ieșirea de grupare direct în clase.

2-aplatizare

datele pe care le-am folosit în modelul nostru sunt de format NHWC. Cu toate acestea, pentru a utiliza un strat complet conectat, avem nevoie ca datele să fie o matrice, unde numărul de rânduri reprezintă dimensiunea lotului și coloanele reprezintă caracteristicile datelor. De data aceasta trebuie să remodelăm în direcția opusă și să convertim de la nhwc la o matrice 2-D.

abandon

1 – Co-adaptare

Co-adaptare se referă la momentul în care mai mulți neuroni dintr-un strat extrag aceleași caracteristici ascunse sau foarte similare din datele de intrare. Acest lucru se poate întâmpla atunci când greutățile de conectare pentru doi neuroni diferiți sunt aproape identice.

când un strat complet conectat are un număr mare de neuroni, este mai probabil să apară co-adaptarea. Aceasta poate fi o problemă din două motive. În primul rând, este o risipă de calcul atunci când avem neuroni redundanți care calculează aceeași ieșire. În al doilea rând, dacă mulți neuroni extrag aceleași caracteristici, adaugă mai multă semnificație acelor caracteristici pentru modelul nostru. Acest lucru duce la suprasolicitare dacă caracteristicile extrase duplicat sunt specifice numai setului de antrenament.

2-abandonul școlar

modul în care minimizăm co-adaptarea pentru straturi complet conectate cu mulți neuroni este prin aplicarea abandonului școlar în timpul antrenamentului. În abandon, închidem aleatoriu o parte din neuronii unui strat la fiecare pas de antrenament prin reducerea la zero a valorilor neuronilor.

Soft-max Layer

deoarece există 10 cifre posibile pe care le poate avea o imagine MNIST, folosim un strat de 10 neuroni complet conectat pentru a obține clasele pentru fiecare clasă de cifre. Funcția Softmax este aplicată claselor pentru a le converti în probabilități per clasă.

construirea modelului

acum suntem gata să construim modelul nostru. Iată codul:

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'))

tipul de model pe care îl vom folosi este secvențial. Secvențial este cel mai simplu mod de a construi un model în Keras. Vă permite să construiți un model strat cu strat.

folosim metoda add() pentru a atașa straturi la modelul nostru. În scopul exemplului nostru introductiv, este suficient să ne concentrăm pe straturi Dense pentru simplitate. Fiecare strat dens () acceptă ca prim argument necesar un număr întreg care specifică numărul de neuroni. Tipul funcției de activare pentru strat este definit folosind argumentul opțional de activare, a cărui intrare este numele funcției de activare în format șir. Exemplele includ relu, tanh, elu, sigmoid, softmax.

în această rețea neuronală, avem 2 straturi de convoluție urmate de fiecare dată de un strat de grupare. Apoi aplatizăm datele pentru a adăuga un strat dens pe care aplicăm abandonul cu o rată de 0,5. În cele din urmă, adăugăm un strat dens pentru a aloca fiecare imagine cu clasa corectă.

compilarea modelului

în continuare, trebuie să compilăm modelul nostru. Compilarea modelului are trei parametri: optimizator, pierdere și valori.

Optimizatorul controlează rata de învățare. Vom folosi ‘adam’ ca optimizator. Adam este, în general, un bun optimizator de utilizat pentru multe cazuri. Optimizatorul adam ajustează rata de învățare pe tot parcursul antrenamentului.

rata de învățare determină cât de repede se calculează greutățile optime pentru model. O rată de învățare mai mică poate duce la greutăți mai precise (până la un anumit punct), dar reducerea este timpul de calcul.

vom folosi ‘categorical_crossentropy’ pentru funcția noastră de pierdere. Aceasta este cea mai comună alegere pentru clasificare. Un scor mai mic indică faptul că modelul funcționează mai bine.

pentru a face lucrurile și mai ușor de interpretat, vom folosi metrica ‘precizie’ pentru a vedea scorul de precizie pe setul de validare atunci când antrenăm modelul.

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

formarea modelului

acum vom instrui modelul nostru. Pentru a ne antrena, vom folosi funcția ‘fit ()’ pe modelul nostru cu următorii parametri: date de antrenament (X_train), date țintă (Y_train), date de validare și numărul de epoci.

pentru datele noastre de validare, vom folosi setul de testare furnizat în setul nostru de date, pe care l-am împărțit în X_test și Y_test.

Numărul de epoci este de câte ori modelul va parcurge datele. Cu cât rulăm mai multe epoci, cu atât modelul se va îmbunătăți, până la un anumit punct. După acest punct, modelul va înceta să se îmbunătățească în fiecare epocă. Pentru modelul nostru, vom seta numărul de epoci la 3.

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

evaluați modelul

acum am pregătit modelul nostru putem evalua performanța acestuia:

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

astfel, avem o precizie de 99,3% și o pierdere de 0,025 pe setul de testare, care este foarte bun. Putem îmbunătăți în continuare modelul prin creșterea numărului de epoch și prin introducerea unei dimensiuni a lotului.

faceți predicții

Dacă doriți să vedeți predicțiile reale pe care modelul nostru le-a făcut pentru datele de testare, putem folosi funcția predict_classes. Putem, de asemenea, la acest lucru prin utilizarea funcției prezice va da o matrice cu 10 numere. Aceste numere sunt probabilitățile ca imaginea de intrare să reprezinte fiecare cifră (0-9). Indicele matricei cu cel mai mare număr reprezintă predicția modelului. Suma fiecărei matrice este egală cu 1 (deoarece fiecare număr este o probabilitate).

pentru a arăta acest lucru, vom arăta predicțiile pentru primele 4 imagini din setul de testare.

Notă: Dacă avem date noi, putem introduce noile noastre date în funcția de predicție pentru a vedea predicțiile pe care modelul nostru le face asupra noilor date. Deoarece nu avem date noi nevăzute, vom afișa predicții folosind setul de testare pentru moment.

#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

rezultatele reale arată că primele patru imagini sunt, de asemenea, 7, 2,1 și 0. Modelul nostru a prezis corect!

întreg model

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

pentru a continua…

în acest articol, am abordat a doua parte a recunoașterii imaginii, care este construirea unei rețele neuronale convoluție.

sper că ați găsit ceea ce ați venit aici în acest articol și rămâneți cu mine pentru următoarele episoade ale acestei călătorii de recunoaștere a imaginilor!

PS: în prezent Sunt student la Master Of Engineering la Berkeley și, dacă doriți să discutați subiectul, nu ezitați să mă contactați. Iată e-mailul meu.

Lasă un răspuns

Adresa ta de email nu va fi publicată.