Transfer de cunoștințe
Bazat pe exemplul 5.3 din Chollet F, învățarea profundă cu Python, Ed Manning, 2018
mariano rivera
versiunea 1.0
martie 2019
import osos.environ="PCI_BUS_ID";os.environ="1";
iv id = „04bf1b6bb1”
Using TensorFlow backend.'2.2.4'
VGG16: o presetare a rețelei de convoluție
O strategie de abordare a rețelelor neuronale profunde este de a utiliza rețele anterior pre-astined cu baze de date mari și să le adaptezi la problema interesului nostru.
În acest scop, este necesar ca rețeaua de pre-intenție să fie instruită pentru a rezolva o problemă de natură mai generală, din care problema noastră poate fi considerată un caz particular. De exemplu, pentru cazul clasificării câinilor și pisicilor, putem folosi o rețea instruită pentru a clasifica mai multe clase ca așa-numitul VGG16 (Simonyan și Zisserrman, 2015). Motivele pe care le folosim VGG16 sunt următoarele
-
are o arhitectură ușor de înțeles și, dacă este cazul, de implementat.
-
realizarea unui rezultat excelent în competiția de imagini (ILSVRC-2014), între 96% și 97%.
-
conține relativ puține straturi convoluționale: 13 straturi convoluționare și 3 dense, Prin urmare, în numele său include 16.
-
rețeaua (model și pesos instruit) Această diponare în Kera
( Simonyan și Zisserrman, 2015) K. Simonyan și A. Zisserman, rețele de convoluție foarte profundă pentru recunoașterea imaginii la scară largă, ICLR 2015.
Rețelele diplebile în Keras care au fost instruiți în Imagenetul BD sunt
rețeaua VGG19 este o variantă cu mai multe straturi de calcul decât VGG16, deci mai greu decât cerințele de memorie și de calcul.
Co. Mo pe care o vedem, deoarece VGG16 a fost instruit pentru a rezolva problema de clasare de 1000 de clada în Imagenet, ea trebuie să codifice informațiile pentru a extrage caracteristici de clasifice foarte diferite, reprezentate în mai mult de 1,4 milioane de fotografii Imagenet. Printre acele clase există soiuri foarte diferite de animale, în medii foarte diferite. Prin urmare, VGG16 este un candidat foarte bun pentru a fi specializat la problema clasificării binare a câinilor și a pisicilor.
Observăm că există o performanță mai modernă, mai bună, dar VGG16 va servi foarte bine pentru scopul nostru. Așa cum am văzut în exemplele anterioare, rețelele convoluționale pentru clasificare urmează o structură cu două blocuri:
-
Pasul straturilor convertite pentru extragerea caracteristicilor
-
Decizia dens bazată pe straturi.
VGG16 Această arhitectură continuă cu credincioșie. Vizualizați SIGINETE Figura
Folosind VGG16 Anterior instruit cu Imagenetul BD ne permite să presupunem că etapa de extracție a caracteristicilor, În mod eficient, relațiile epaceeiale care fac obiectele distincte și apariția imaginilor ne face să presuprimăm că aceste relații spațiale sunt suficient de generice pentru a putea codifica caracteristicile distinctive ale câinilor și pisicilor.
Vom merge pas Pasul, am încărcat mai întâi rețeaua VGG16 în pachetul keras.applications
Încărcați un model prestabilit și, deoarece vă putem accesa componentele. Ca o ilustrare, definim versiunea noastră a funcției summary
al modelelor Keras. Cu aceasta, arătăm cum accesul la numele straturilor, numărul lor de parametri etc.
def resumen(model=None): ''' ''' header = '{:4} {:16} {:24} {:24} {:10}'.format('#', 'Layer Name','Layer Input Shape','Layer Output Shape','Parameters' ) print('='*(len(header))) print(header) print('='*(len(header))) count=0 count_trainable=0 for i, layer in enumerate(model.layers): count_trainable += layer.count_params() if layer.trainable else 0 input_shape = '{}'.format(layer.input_shape) output_shape = '{}'.format(layer.output_shape) str = '{:<4d} {:16} {:24} {:24} {:10}'.format(i,layer.name, input_shape, output_shape, layer.count_params()) print(str) count += layer.count_params() print('_'*(len(header))) print('Total Parameters : ', count) print('Total Trainable Parameters : ', count_trainable) print('Total No-Trainable Parameters : ', count-count_trainable) vgg16=None
apoi încărcați modelul VGG16 cu următorii parametri:
-
greutăți indică faptul că greutățile vor fi utilizate pentru a inițializa modelul
-
includere_top Indică dacă rețeaua completă este încărcată (extragerea caracteristicilor și Etapa de decizie) sau doar etapa de extracție a subiecților
-
intrare_shape Forma imaginilor care urmează să fie procesate (opțional, deoarece rețeaua pe care o puteți procesa orice dimensiune a imaginii)
iv I id = „eb184cf5f8”
==================================================================================# Layer Name Layer Input Shape Layer Output Shape Parameters==================================================================================0 input_5 (None, 224, 224, 3) (None, 224, 224, 3) 01 block1_conv1 (None, 224, 224, 3) (None, 224, 224, 64) 17922 block1_conv2 (None, 224, 224, 64) (None, 224, 224, 64) 369283 block1_pool (None, 224, 224, 64) (None, 112, 112, 64) 04 block2_conv1 (None, 112, 112, 64) (None, 112, 112, 128) 738565 block2_conv2 (None, 112, 112, 128) (None, 112, 112, 128) 1475846 block2_pool (None, 112, 112, 128) (None, 56, 56, 128) 07 block3_conv1 (None, 56, 56, 128) (None, 56, 56, 256) 2951688 block3_conv2 (None, 56, 56, 256) (None, 56, 56, 256) 5900809 block3_conv3 (None, 56, 56, 256) (None, 56, 56, 256) 59008010 block3_pool (None, 56, 56, 256) (None, 28, 28, 256) 011 block4_conv1 (None, 28, 28, 256) (None, 28, 28, 512) 118016012 block4_conv2 (None, 28, 28, 512) (None, 28, 28, 512) 235980813 block4_conv3 (None, 28, 28, 512) (None, 28, 28, 512) 235980814 block4_pool (None, 28, 28, 512) (None, 14, 14, 512) 015 block5_conv1 (None, 14, 14, 512) (None, 14, 14, 512) 235980816 block5_conv2 (None, 14, 14, 512) (None, 14, 14, 512) 235980817 block5_conv3 (None, 14, 14, 512) (None, 14, 14, 512) 235980818 block5_pool (None, 14, 14, 512) (None, 7, 7, 512) 019 flatten (None, 7, 7, 512) (None, 25088) 020 fc1 (None, 25088) (None, 4096) 10276454421 fc2 (None, 4096) (None, 4096) 1678131222 predictions (None, 4096) (None, 1000) 4097000__________________________________________________________________________________Total Parameters : 138357544Total Trainable Parameters : 138357544Total No-Trainable Parameters : 0
sunt aproximativ 139 de milioane de parametri. Acesta a consumat într-adevăr timp pentru a descărca modelul complet (se face numai pentru prima dată că funcția VGG16 este invocată. Observăm că, din fericire, mulți dintre parametrii (cum ar fi 90%) corespund pasului de decizie. Extracția trădării Etapa (ilustrată în figura următoare) are mai puțini parametri.
(Imagine luată din rețea, utilizată în mai multe bloguri, ca în ilustrația VGG16
Pentru a evita încărcarea straturilor pe care nu le vom folosi, putem invoca metoda cu parametrul include_top=False
și pentru dimensiunea specifică pe care am folosit-o (150 × 150150 \ ori 150150 × 150 pixeli)
if vgg16 != None: del vgg16 from keras.applications import VGG16conv_base = VGG16(weights='imagenet', include_top=False, input_shape=(150, 150, 3)) resumen(conv_base)
==================================================================================# Layer Name Layer Input Shape Layer Output Shape Parameters==================================================================================0 input_6 (None, 150, 150, 3) (None, 150, 150, 3) 01 block1_conv1 (None, 150, 150, 3) (None, 150, 150, 64) 17922 block1_conv2 (None, 150, 150, 64) (None, 150, 150, 64) 369283 block1_pool (None, 150, 150, 64) (None, 75, 75, 64) 04 block2_conv1 (None, 75, 75, 64) (None, 75, 75, 128) 738565 block2_conv2 (None, 75, 75, 128) (None, 75, 75, 128) 1475846 block2_pool (None, 75, 75, 128) (None, 37, 37, 128) 07 block3_conv1 (None, 37, 37, 128) (None, 37, 37, 256) 2951688 block3_conv2 (None, 37, 37, 256) (None, 37, 37, 256) 5900809 block3_conv3 (None, 37, 37, 256) (None, 37, 37, 256) 59008010 block3_pool (None, 37, 37, 256) (None, 18, 18, 256) 011 block4_conv1 (None, 18, 18, 256) (None, 18, 18, 512) 118016012 block4_conv2 (None, 18, 18, 512) (None, 18, 18, 512) 235980813 block4_conv3 (None, 18, 18, 512) (None, 18, 18, 512) 235980814 block4_pool (None, 18, 18, 512) (None, 9, 9, 512) 015 block5_conv1 (None, 9, 9, 512) (None, 9, 9, 512) 235980816 block5_conv2 (None, 9, 9, 512) (None, 9, 9, 512) 235980817 block5_conv3 (None, 9, 9, 512) (None, 9, 9, 512) 235980818 block5_pool (None, 9, 9, 512) (None, 4, 4, 512) 0__________________________________________________________________________________Total Parameters : 14714688Total Trainable Parameters : 14714688Total No-Trainable Parameters : 0
sunt „doar” doar sub 15 milioane de parametri, o reducere substanțială în raport cu VGG16 complet Rețea.
Să vedem Rezumatul rețelei Keras
#conv_base.summary()
Ieșirea finală a modelului de bază încărcată (conv_base
) au forma iv id = „b3a639f657” .
rețea pre-introdusă ca caracteristici extractor offline
prima strategie pe care o vom folosi Pentru a reutiliza cunoștințele stocate (achiziționate) de o rețea de clasificare și o particularizează, va fi în considerare extragerea trăsăturilor independente ale clasificării ion. Este o abordare de tip sumbră (spre deosebire de profundă). Adică, vom trece imaginile la rețeaua de consolidare a bazei (conv_base
) și stocați caracteristicile din memorie sau disc (ceea ce este computațional eficient) și apoi alimentați cu astfel de caracteristici un clasificator. Acest lucru este ilustrat în figura următoare.
Pentru a genera codarea (dantelă sau încorporarea) de imagini și pisici de câine Va folosi un generator
Este important dacă folosim preprocesul VGG16 datele (imaginile) pentru a le normaliza cu aceeași procedură utilizată pentru a instrui rețeaua originală. În acest caz, nu le este de a le salva la interval, dar pentru a scădea media fiecărui canal de culoare
import osimport numpy as npfrom tqdm import tqdmfrom keras.applications.imagenet_utils import preprocess_input#from tqdm import tqdm_notebook as tqdmfrom keras.preprocessing.image import ImageDataGeneratorbase_dir = '/home/mariano/Data/dogs_vs_cats_small'#base_dir = '/home/mariano/Documents/deep/kaggle/dogs_vs_cats_small'train_dir = os.path.join(base_dir, 'train')validation_dir = os.path.join(base_dir, 'validation')test_dir = os.path.join(base_dir, 'test')datagen = ImageDataGenerator(#rescale=1./255) preprocessing_function=preprocess_input)batch_size = 20def extract_features(directory, sample_count): ''' Codificador de imagenes mediante conv_base en rasgos para posteriormente usarlos como datos para una red clasificadora densa parámetros directory directorio con con los subdirectorios que definen clases sample_count número de muestras a generar resultados conjunto de características y etiquetas ''' # memoria para tensores con datos y etiquetas features = np.zeros(shape=(sample_count, 4, 4, 512)) labels = np.zeros(shape=(sample_count)) # instanciación del generador a partir del directorio donde estan las clases generator = datagen.flow_from_directory(directory, target_size = (150, 150), batch_size = batch_size, class_mode = 'binary') rango = list(range(int(sample_count/batch_size))) i = 0 with tqdm(total=len(rango)) as pbar: for inputs_batch, labels_batch in tqdm(generator): # características predichas (codificadas) por la subred base # para las imágenes generadas (aumentadas) en lote features_batch = conv_base.predict(inputs_batch) # datos y etiquetas features = features_batch labels = labels_batch i += 1 if i * batch_size >= sample_count: # La ejecucion del generador debe terminarse explícitamente después # usar todas la imágenes break pbar.update(1) return features, labels
set de trăsături de date pentru instruire, Validare și testare
train_features, train_labels = extract_features(train_dir, 2000)validation_features, validation_labels = extract_features(validation_dir, 1000)test_features, test_labels = extract_features(test_dir, 1000)
0%| | 0/100 0%| | 0/100 3%|▎ | 3/100 ... 99%|█████████▉| 99/100 2%|▏ | 1/50 ... 98%|█████████▊| 49/50 2%|▏ | 1/50 ... 98%|█████████▊| 49/50 )import timetstart = time.time()history = model.fit(train_features, train_labels, epochs = 30, batch_size = 20, validation_data = (validation_features, validation_labels), verbose = 2)print('seconds=', time.time()-tstart)
iv id = „0B4841DE4C”
Formarea este foarte rapidă Având în vedere că rețeaua de clasificare constă doar din două straturi Dense
.
Curbele valorii și preciziei funcției țintă (accuracy
) Sunt arătate mai jos.
import matplotlib.pyplot as pltacc = history.historyval_acc = history.historyloss = history.historyval_loss = history.historyepochs = range(len(acc))plt.plot(epochs, acc, 'bo', label='Entrenamiento acc')plt.plot(epochs, val_acc, 'b', label='Validación acc')plt.title('Accuracy - exactitud de entrenamiento y validación')plt.legend()plt.figure()plt.plot(epochs, loss, 'bo', label='Entrenamiento loss')plt.plot(epochs, val_loss, 'b', label='Validación loss')plt.title('Loss - función objetivo en entrenamiento y prueba')plt.legend()plt.show()
id = „8AAA8BC3FF”> PNG
Valorizarea atinge o precizie de 90%, mult mai bună decât modelul instruit cu augmentarea datelor și BD Paquea care a atins 86%.
curba de precizie ilustrează că foarte curând începe să aveți o suprapunere (suprasolicitare). Se datorează faptului că nu folosim augmentarea Ei bine, în memorie sau disc, ar fi impracticabilă stocarea datelor sporite pentru clasificarea ulterioară. Acest lucru este explicat mai jos.
Transferul de cunoștințe de rețea Performizează la noi probleme
modelul Conv_Base ca strat de extracție de îndepărtare
dacă presupunem că etapa convoluționară de la VGG16 extrage caracteristici generale, va fi acea parte pe care o putem reutiliza. Caracteristicile extrase trebuie să fie transmise unui nou clasificator binar pe care trebuie să-l implementăm și să pregătim ex-profesie. Acest proces este Musra în următoarea figură
ca figura ilustrează,
-
Realizăm doar stadiul convoluțional al rețelei.
-
Definim o nouă etapă de clasificare în funcție de problema noastră.
-
Deoarece avem, relativ, câteva date de instruire, setați sub semnul de extracție a caracteristicilor (înghețați greutățile lor) pentru a le împiedica să fie modificate în instruire.
-
ne pregătim Greutățile „viabile”, cele ale stadiului de clasare care fac datele noastre prin întreaga rețea.
Vom folosi generatoare de date pentru a face o formare cu generatoare (fit_generator
), ca în exemplul secțiunii anterioare.
în Keras Totul sunt straturi (straturi), deci vom folosi modelul conv_base
ca prim strat al rețelei, un strat care calculează caracteristici.
apoi adăugați la noul model secvențial clasificat Dense Doras.
Această tehnică, deși simplă pentru a implementa rușinea că fiecare imagine crescută este trecută prin rețeaua conv_base
și apoi prin sortare. Acest lucru provoacă acum calculele mai scumpe și nu este posibil să le îndeplinească în CPU, avem nevoie de un GPU.
model.reset_states()
iv id = „C303C153AE”
acesta este ceea ce arată modelul nostru:
#model.summary()resumen(model)
==================================================================================# Layer Name Layer Input Shape Layer Output Shape Parameters==================================================================================0 vgg16 (None, 150, 150, 3) (None, 4, 4, 512) 147146881 flatten_1 (None, 4, 4, 512) (None, 8192) 02 dense_3 (None, 8192) (None, 256) 20974083 dense_4 (None, 256) (None, 1) 257__________________________________________________________________________________Total Parameters : 16812353Total Trainable Parameters : 16812353Total No-Trainable Parameters : 0
rețeaua de consolvare VGG16 15 milioane de parametri, care sunt foarte mari. Clasificatorul de pe oprire adaugă încă 2 milioane de opriri.
înainte de antrenament „Vom îngheța” extracția de rețea a caracteristicilor, deoarece avem câteva date și dorim să profităm de „cunoștințe” stocate în subterana de bază VGG16, care a fost instruită cu multe clase și ar trebui să fie Un foarte mult extractor general de caracteristici.
Acest lucru realizat prin marcarea greutăților „stratului” conv_base
ca non-instruire:
print('Número de pesos (matrices) entrenables antes de congelar conv_base : ', len(model.trainable_weights))
Número de pesos (matrices) entrenables antes de congelar conv_base : 30
conv_base.trainable = False
iv id = „
==================================================================================# Layer Name Layer Input Shape Layer Output Shape Parameters==================================================================================0 vgg16 (None, 150, 150, 3) (None, 4, 4, 512) 147146881 flatten_1 (None, 4, 4, 512) (None, 8192) 02 dense_3 (None, 8192) (None, 256) 20974083 dense_4 (None, 256) (None, 1) 257__________________________________________________________________________________Total Parameters : 16812353Total Trainable Parameters : 2097665Total No-Trainable Parameters : 14714688
Numărul matricelor depășește straturile, deoarece fiecare strat poate avea o matrice de greutate www și un vector de părtinire BBB.
Pentru a face ca datele de îngheț, trebuie să compilați modelul și apoi să definim parametrii generatorului.
from keras.preprocessing.image import ImageDataGeneratorfrom keras import modelsfrom keras import layersfrom keras import optimizerstrain_datagen = ImageDataGenerator(#rescale = 1./255, preprocessing_function=preprocess_input, rotation_range = 40, width_shift_range = 0.2, height_shift_range= 0.2, shear_range = 0.2, zoom_range = 0.2, horizontal_flip = True, fill_mode = 'constant', #'nearest') cval = 0)# La validación no se aumenta!test_datagen = ImageDataGenerator(#rescale=1./255) preprocessing_function=preprocess_input)train_generator = train_datagen.flow_from_directory( train_dir, # directorio con datos de entrenamiento target_size= (150, 150), # tamaño de la imágenes batch_size = 20, shuffle = True, class_mode = 'binary') # para clasificación binariavalidation_generator = test_datagen.flow_from_directory( validation_dir, target_size=(150, 150), batch_size=20, class_mode='binary')model.compile(loss='binary_crossentropy', optimizer=keras.optimizers.Nadam(lr=2e-5), #optimizers.RMSprop(lr=2e-5), metrics=)#model.reset_states()import timetstart = time.time()history = model.fit_generator(train_generator, steps_per_epoch = 100, epochs = 30, validation_data = validation_generator, validation_steps= 50, verbose = 2)print('seconds=', time.time()-tstart)
Found 2000 images belonging to 2 classes.Found 1000 images belonging to 2 classes.Epoch 1/30 - 10s - loss: 1.9860 - acc: 0.7660 - val_loss: 0.7680 - val_acc: 0.9040Epoch 2/30 - 9s - loss: 0.9115 - acc: 0.8815 - val_loss: 0.5760 - val_acc: 0.9210...Epoch 30/30 - 9s - loss: 0.1956 - acc: 0.9640 - val_loss: 0.3213 - val_acc: 0.9660seconds= 281.5276675224304
iv id = „428D2F1ABE”
grafic grafic comportamentul valorilor înregistrate în timpul națiune
import matplotlib.pyplot as pltacc = history.historyval_acc = history.historyloss = history.historyval_loss = history.historyepochs = range(len(acc))plt.plot(epochs, acc, 'bo', label='Entrenamiento acc')plt.plot(epochs, val_acc, 'b', label='Validación acc')plt.title('Accuracy - exactitud de entrenamiento y validación')plt.legend()plt.figure()plt.plot(epochs, loss, 'bo', label='Entrenamiento loss')plt.plot(epochs, val_loss, 'b', label='Validación loss')plt.title('Loss - función objetivo en entrenamiento y prueba')plt.legend()plt.show()
Potrivit autorului Cartei (Chollet), se atinge o precizie de aproape 96,5%.
Reglare fină
O altă strategie pe scară largă în reutilizarea rafinării este ajustarea fină (reglaj fină), care, odată ce un strat de clasificare cu pretranetranda, a fost instruit, dezghețați Ultimele straturi ale bazei convoluționare pentru a permite greutăților lor să se adapteze mai bine la stratul de clasificare. Realizarea unei integrări mai bune între bază (instruită pentru o problemă diferită) și clasificarea.
Etapele de antrenament fine sunt:
- adăugați la o bază generală convoluționară o scenă Clasificarea finală.
- înghețați baza convoluțională.
- Formarea etapei de sortare.
- Dezghețare ultimele straturi ale bazei convolutionale.
- Stadiul de sortare a trenurilor și ultimele straturi ale convoluției împreună.
pardo a modelului anterior anterior (pașii 1,2 și 3) Vedem că straturile de dezghețare sunt cele corespunzătoare blocului5.
Ca o reamintire Rezumatul convoluției este
resumen(conv_base)
==================================================================================# Layer Name Layer Input Shape Layer Output Shape Parameters==================================================================================0 input_6 (None, 150, 150, 3) (None, 150, 150, 3) 01 block1_conv1 (None, 150, 150, 3) (None, 150, 150, 64) 17922 block1_conv2 (None, 150, 150, 64) (None, 150, 150, 64) 369283 block1_pool (None, 150, 150, 64) (None, 75, 75, 64) 04 block2_conv1 (None, 75, 75, 64) (None, 75, 75, 128) 738565 block2_conv2 (None, 75, 75, 128) (None, 75, 75, 128) 1475846 block2_pool (None, 75, 75, 128) (None, 37, 37, 128) 07 block3_conv1 (None, 37, 37, 128) (None, 37, 37, 256) 2951688 block3_conv2 (None, 37, 37, 256) (None, 37, 37, 256) 5900809 block3_conv3 (None, 37, 37, 256) (None, 37, 37, 256) 59008010 block3_pool (None, 37, 37, 256) (None, 18, 18, 256) 011 block4_conv1 (None, 18, 18, 256) (None, 18, 18, 512) 118016012 block4_conv2 (None, 18, 18, 512) (None, 18, 18, 512) 235980813 block4_conv3 (None, 18, 18, 512) (None, 18, 18, 512) 235980814 block4_pool (None, 18, 18, 512) (None, 9, 9, 512) 015 block5_conv1 (None, 9, 9, 512) (None, 9, 9, 512) 235980816 block5_conv2 (None, 9, 9, 512) (None, 9, 9, 512) 235980817 block5_conv3 (None, 9, 9, 512) (None, 9, 9, 512) 235980818 block5_pool (None, 9, 9, 512) (None, 4, 4, 512) 0__________________________________________________________________________________Total Parameters : 14714688Total Trainable Parameters : 14714688Total No-Trainable Parameters : 0
Vom face Ajustarea fină a ultimelor trei straturi convoalimentare: block5_conv1
, block5_conv2
și iv id = „90a4f4c6e3” .
Este important să rețineți că cele mai vechi niveluri coduri mai generale, deci nu este convenabil Renectați-le dacă scopul este de a reutiliza cunoștințele. Vom termina supraestimarea modelului la mici BD Nustras.
div id = „4d447758bf”>
input_6block1_conv1block1_conv2block1_poolblock2_conv1block2_conv2block2_poolblock3_conv1block3_conv2block3_conv3block3_poolblock4_conv1block4_conv2block4_conv3block4_poolblock5_conv1block5_conv2block5_conv3block5_pool
iv id = „8dca67662b”
==================================================================================# Layer Name Layer Input Shape Layer Output Shape Parameters==================================================================================0 input_6 (None, 150, 150, 3) (None, 150, 150, 3) 01 block1_conv1 (None, 150, 150, 3) (None, 150, 150, 64) 17922 block1_conv2 (None, 150, 150, 64) (None, 150, 150, 64) 369283 block1_pool (None, 150, 150, 64) (None, 75, 75, 64) 04 block2_conv1 (None, 75, 75, 64) (None, 75, 75, 128) 738565 block2_conv2 (None, 75, 75, 128) (None, 75, 75, 128) 1475846 block2_pool (None, 75, 75, 128) (None, 37, 37, 128) 07 block3_conv1 (None, 37, 37, 128) (None, 37, 37, 256) 2951688 block3_conv2 (None, 37, 37, 256) (None, 37, 37, 256) 5900809 block3_conv3 (None, 37, 37, 256) (None, 37, 37, 256) 59008010 block3_pool (None, 37, 37, 256) (None, 18, 18, 256) 011 block4_conv1 (None, 18, 18, 256) (None, 18, 18, 512) 118016012 block4_conv2 (None, 18, 18, 512) (None, 18, 18, 512) 235980813 block4_conv3 (None, 18, 18, 512) (None, 18, 18, 512) 235980814 block4_pool (None, 18, 18, 512) (None, 9, 9, 512) 015 block5_conv1 (None, 9, 9, 512) (None, 9, 9, 512) 235980816 block5_conv2 (None, 9, 9, 512) (None, 9, 9, 512) 235980817 block5_conv3 (None, 9, 9, 512) (None, 9, 9, 512) 235980818 block5_pool (None, 9, 9, 512) (None, 4, 4, 512) 0__________________________________________________________________________________Total Parameters : 14714688Total Trainable Parameters : 7079424Total No-Trainable Parameters : 7635264
Notă că conv_base
au instruire și paramper nealcabili.
pentru instruire fină Mergem la compilarea modelului cu o dimensiune mică a pasului pentru a evita schimbări mari în greutăți, deoarece presupunem că este aproape de optimă, iar ajustarea nu trebuie să fie foarte mare.
DIV ID = „BFE7F7D723”>
Epoch 1/100100/100 - 10s 104ms/step - loss: 0.1938 - acc: 0.9645 - val_loss: 0.2769 - val_acc: 0.9580Epoch 2/100100/100 - 9s 94ms/step - loss: 0.2239 - acc: 0.9635 - val_loss: 0.2606 - val_acc: 0.9650... Epoch 100/100100/100 - 10s 97ms/step - loss: 0.0269 - acc: 0.9960 - val_loss: 0.3666 - val_acc: 0.9620
iv id = „35b2c26c9f”
METRICS GRAFILE înregistrate în timpul antrenamentului
import matplotlib.pyplot as pltacc = history.historyval_acc = history.historyloss = history.historyval_loss = history.historyepochs = range(len(acc))plt.plot(epochs, acc, 'bo', label='Entrenamiento acc')plt.plot(epochs, val_acc, 'b', label='Validación acc')plt.title('Accuracy - exactitud de entrenamiento y validación')plt.legend()plt.figure()plt.plot(epochs, loss, 'bo', label='Entrenamiento loss')plt.plot(epochs, val_loss, 'b', label='Validación loss')plt.title('Loss - función objetivo en entrenamiento y prueba')plt.legend()plt.show()
Deoarece curbele sunt foarte zgomotoase, Este posibil să le filtrați pentru a aprecia mai bine tendința prin intermediul unui filtru de trecere scăzut, se poate încerca
s ~ i = σk = 0nwksi-k \ tilde s_i = \ sum_ {k = 0} ^ n w_k s_ {ik} s ~ i = k = 0σnwksi-k
unde www sunt o pesos co n σkwk = 1 \ sum_k w_k = 1σkwk = 1; Dar vom avea nevoie de un filtru destul de larg (NNN mare) pentru a elimina zgomotul corect, în schimb, încercăm versiunea recursivă (ca în cartea pe care se bazează aceste note)
i
s ~ i = αs ~ i -1+ (1-a) dacă \ tilde s_i = \ alpha \ tilde s_ {i-1} + (1- α) s_is ~ i = α ~ i-1 + (1-α) Dacă
că utilizați datele recent actualizate cu o procedură similară. Aceste filtre recursive pot fi exprimate ca non-recursive (înlocuind datele actualizate prin formula sa). Avantajul formei recursive este compactul expresiei de actualizare
def smooth_curve(points, factor=0.8): smoothed_points = for point in points: if smoothed_points: previous = smoothed_points smoothed_points.append(previous * factor + point * (1 - factor)) else: smoothed_points.append(point) return smoothed_pointsimport matplotlib.pyplot as pltacc = history.historyval_acc = history.historyloss = history.historyval_loss = history.historyepochs = range(len(acc))alpha = 0.9plt.plot(epochs, smooth_curve(acc, alpha), 'bo', label='Entrenamiento acc')plt.plot(epochs, smooth_curve(val_acc, alpha), 'b', label='Validación acc')plt.title('Accuracy - exactitud de entrenamiento y validación')plt.legend()plt.figure()plt.plot(epochs, smooth_curve(loss, alpha), 'bo', label='Entrenamiento loss')plt.plot(epochs, smooth_curve(val_loss,alpha), 'b', label='Validación loss')plt.title('Loss - función objetivo en entrenamiento y prueba')plt.legend()plt.show()
În aceste curbe puteți aprecia mai bine tendința, putem observa că a fost o îmbunătățire de aproximativ 1%.
În (Chollet, 2018) observația se face ca acuratețea să se îmbunătățească chiar și atunci când pierderea nu. Acest lucru se datorează faptului că pierderea este evaluată printr-un proces de sumă de eroare în vectorul de ieșire, ceva de genul:
σi∈epoch∥yi-y ^ i∥m \ sum_ {i \ în epoch} \ | Y_I – \ HAT Y_I \ | _MIAPOCHΣ∥YI-Y ^ I∥m
În cazul în care presupunem că YYY se află într-o codificare unică și m indică unele metrice.Pe de altă parte, precizia este calculată prin intermediul unor erori de clasament:
σi∈epoch1-δ (Argmaxiyi-Argmaxiy ^ i) \ sum_ {i \ în Epoch } 1- Δ (τ \ \ max_i {\ hat y_i}) ∈epochς1-δ (Argimiaxi-Argimaxy ^ I)
Evaluați acum, în cele din urmă și pieri, setul de testare:
test_generator = test_datagen.flow_from_directory( test_dir, target_size=(150, 150), batch_size=20, class_mode='binary')test_loss, test_acc = model.evaluate_generator(test_generator, steps=50)print('test acc:', test_acc)
Found 1000 images belonging to 2 classes.test acc: 0.9669999933242798
* Foarte aproape de 97%
În competiția originală Kaggle, ar fi printre Cele mai bune rezultate (de sus) și că folosim doar 2000 de date de instruire vs. 20.000 în concurența Kaggle.
Rezumat
-
Rețelele convoluționale sunt cel mai bun model de rețele neuronale care să se ocupe de prelucrarea imaginilor și problemele de viziune a computerului.
-
Augmentarea datelor vă permite să evitați suprasarcarea în baza de date mică și creșterea cu datele sintetice Dimensiunea probei de antrenament
-
Este posibil Pentru a utiliza modele de preînnurire în etapa de extracție a caracteristicilor pentru a face față bazelor de date mici.
-
Ajustarea fină permite îmbunătățirea interconectării etapei prestabilite cu stadiul constant, îmbunătățirea generală performanța la un cost computațional scăzut.