Classificazione delle immagini su larga scala con Keras - vgg16 fine-tune -

Questo articolo è stato pubblicato più di un anno fa. Le informazioni potrebbero essere obsolete.
1. Introduzione
Di recente ho iniziato a studiare l'apprendimento automatico e a partecipare a Kaggle , il concorso per la classificazione delle immagini.
Questa volta voglio riassumere come implementare vgg16 perfezionare con python keras libreria [^2].
2 Informazioni sui dati
Il set di dati è il seguente.
Avevo sperimentato solo set di dati come MNIST che erano spesso visti nei tutorial ML, quindi ho pensato che fosse un set di dati molto grande.
- Classi : circa 15.000
- Dimensione dei dati di apprendimento : circa 1,2 milioni di file di immagini. Più di 300 GB
- Le dimensioni di ciascun file di immagine : variano tra i file. per esempio. 1.600 \ 1.200 *
- Dati di prova : circa 120.000 file
3 Implementazione
3.1 Impara i dati
Per prima cosa ti mostrerò l'intero codice.
1from keras.preprocessing.image import ImageDataGenerator2from keras import optimizers3from keras.applications.vgg16 import VGG164from keras.layers import Dense, Dropout, Flatten, Input, BatchNormalization5from keras.models import Model, Sequential6from keras.callbacks import ModelCheckpoint7import numpy as np8 9train_data_dir = "/train/"10validation_data_dir = "/validation/"11 12train_datagen = ImageDataGenerator(rescale=1. / 255)13validation_datagen = ImageDataGenerator(rescale=1. / 255)14 15img_width, img_height = 200, 15016nb_train_samples = 91564917nb_validation_samples = 30209118epochs = 5019batch_size = 6420nb_category = 1495121 22train_generator = train_datagen.flow_from_directory(23 train_data_dir,24 target_size=(img_width, img_height),25 batch_size=batch_size,26 class_mode="categorical")27 28validation_generator = validation_datagen.flow_from_directory(29 validation_data_dir,30 target_size=(img_width, img_height),31 batch_size=batch_size,32 class_mode="categorical")33 34# define input_tensor35input_tensor = Input(shape=(img_width, img_height, 3))36 37vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)38 39top_model = Sequential()40top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))41top_model.add(Dense(256, activation='relu', kernel_initializer='he_normal'))42top_model.add(BatchNormalization())43top_model.add(Dropout(0.5))44top_model.add(Dense(nb_category, activation='softmax'))45 46# Connect vgg16 and top_model47model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))48 49# Fix layers50for layer in model.layers[:15]:51 layer.trainable = False52 53optimizer = optimizers.rmsprop(lr=5e-7, decay=5e-5)54model.compile(loss='categorical_crossentropy',55 optimizer=optimizer,56 metrics=['accuracy'])57 58checkpoint_cb = ModelCheckpoint("snapshot/{epoch:03d}-{val_acc:.5f}.hdf5", save_best_only=True)59 60model.fit_generator(61 train_generator,62 steps_per_epoch=nb_train_samples // batch_size,63 epochs=epochs,64 validation_data=validation_generator,65 validation_steps=nb_validation_samples // batch_size,66 callbacks=[checkpoint_cb])67 68# Save the model69model.save("model.h5")70 71model.summary()3.1.1 Impara con dati su larga scala
Nella maggior parte dei tutorial, possiamo vedere i dati caricati come segue.
1(X_train, y_train), (X_test, y_test) = mnist.load_data()Tuttavia, non è possibile caricare interi dati in memoria quando si trattano dati su larga scala come in questo momento.
Invece, puoi usare la funzione flow_from_directory per caricare i dati [^1].
Questa funzione elabora i dati di immagine mentre li espande in tempo reale.
Per prima cosa devi creare ImageDataGenerator .
1train_datagen = ImageDataGenerator(rescale=1. / 255)2validation_datagen = ImageDataGenerator(rescale=1. / 255)Questa classe esegue la generazione batch di dati di immagine durante l'esecuzione della preelaborazione. Questa volta, basta ridimensionare. 1/255 viene utilizzato per normalizzare l'intervallo di valori RGB da 0-255 a 0-1.
Quindi, leggi i dati
1train_generator = train_datagen.flow_from_directory(2 train_data_dir,3 target_size=(img_width, img_height),4 batch_size=batch_size,5 class_mode="categorical")6 7validation_generator = validation_datagen.flow_from_directory(8 validation_data_dir,9 target_size=(img_width, img_height),10 batch_size=batch_size,11 class_mode="categorical")Poiché si tratta di una classificazione categoriale, impostare class_mode come categorical .
In questo momento, devi stare attento alla struttura delle cartelle. Come mostrato di seguito, è necessario creare una sottocartella per ogni classe che si desidera classificare.
1data/2 train/3 classA/4 aaa.jpg5 bbb.jpg6 ...7 classB/8 ccc.jpg9 ddd.jpg10 ...11 12 validation/13 classA/14 eee.jpg15 fff.jpg16 ...17 classB/18 ggg.jpg19 hhh.jpg20 ...3.1.2 Utilizzare il modello vgg16
Scopri come utilizzare il modello VGG16 che può essere utilizzato con Keras .
1# define input_tensor2input_tensor = Input(shape=(img_width, img_height, 3))3 4vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)5 6top_model = Sequential()7top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))8top_model.add(Dense(256, activation='relu', kernel_initializer='he_normal'))9top_model.add(BatchNormalization())10top_model.add(Dropout(0.5))11top_model.add(Dense(nb_category, activation='softmax'))12 13# Connect vgg16 with top_model14model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))15 16# Fix layers17for layer in model.layers[:15]:18 layer.trainable = False19 20optimizer = optimizers.rmsprop(lr=5e-7, decay=5e-5)21model.compile(loss='categorical_crossentropy',22 optimizer=optimizer,23 metrics=['accuracy'])24 25checkpoint_cb = ModelCheckpoint("snapshot/{epoch:03d}-{val_acc:.5f}.hdf5", save_best_only=True)26 27model.fit_generator(28 train_generator,29 steps_per_epoch=nb_train_samples // batch_size,30 epochs=epochs,31 validation_data=validation_generator,32 validation_steps=nb_validation_samples // batch_size,33 callbacks=[checkpoint_cb])Innanzitutto, utilizzare il modello predefinito vgg16. A questo punto, viene specificata la dimensione del set di dati di input.
1input_tensor = Input(shape=(img_width, img_height, 3))2 3vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)Quindi, collega il tuo modello.
Si noti che include_top nell'argomento precedente deve essere impostato su False per la regolazione fine.
1top_model = Sequential()2top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))3top_model.add(Dense(256, activation='relu', kernel_initializer='he_normal'))4top_model.add(BatchNormalization())5top_model.add(Dropout(0.5))6top_model.add(Dense(nb_category, activation='softmax'))7 8# Connect vgg16 with top_model9model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))Ad essere sincero, non capisco appieno la funzione relu qui specificata.
Quindi non penso che i contenuti di questo modello siano molto utili.
Successivamente, il peso è fisso. Se questo non viene specificato, i pesi verranno nuovamente appresi dall'inizio, ma questa volta verrà risolto.
1for layer in model.layers[:15]:2 layer.trainable = FalseCompila il modello. Al momento, specifica l'ottimizzatore. Questo specifica quale algoritmo usare quando si aggiornano i parametri.
1optimizer = optimizers.rmsprop(lr=5e-7, decay=5e-5)2model.compile(loss='categorical_crossentropy',3 optimizer=optimizer,4 metrics=['accuracy'])Finalmente l'apprendimento. Se ModelCheckpoint è impostato nei callback, è possibile salvare i risultati intermedi. Non è obbligatorio
1checkpoint_cb = ModelCheckpoint("snapshot/{epoch:03d}-{val_acc:.5f}.hdf5", save_best_only=True)2 3model.fit_generator(4 train_generator,5 steps_per_epoch=nb_train_samples // batch_size,6 epochs=epochs,7 validation_data=validation_generator,8 validation_steps=nb_validation_samples // batch_size,9 callbacks=[checkpoint_cb])3.2 Predire
1from keras.preprocessing.image import ImageDataGenerator2from keras import optimizers3from keras.applications.vgg16 import VGG164from keras.layers import Dense, Dropout, Flatten, Input, BatchNormalization5from keras.models import Model, Sequential, load_model6import pandas as pd7import numpy as np8import os9from pandas import DataFrame10 11test_data_dir = "/test/"12 13test_datagen = ImageDataGenerator(rescale=1. / 255)14 15img_width, img_height = 200, 15016nb_test_samples = 11547417batch_size = 118nb_category = 1495119 20test_generator = test_datagen.flow_from_directory(21 test_data_dir,22 target_size=(img_width, img_height),23 batch_size=batch_size,24 class_mode=None,25 shuffle=False)26 27model = load_model("model.h5")28 29pred = model.predict_generator(30 test_generator,31 steps=nb_test_samples,32 verbose=1)Non è molto diverso dal codice di apprendimento. Allo stesso modo, i dati vengono letti con flow_from_directory , ma il punto da notare è che le sottocartelle sono necessarie anche per i dati di test (= classi sconosciute). Ad esempio, nella seguente configurazione, non funzionerà se non si organizzano i dati in sottocartelle.
1data/2 test/3 sub/4 aaa.jpg5 bbb.jpg6 ...Poiché la classe è sconosciuta, impostare class_mode None .
4 Riepilogo
- Ho capito come usare vgg16 con Keras.
- Carica dati su larga scala con
flow_from_directory. - Nota che hai bisogno anche di sottocartelle per la previsione.
5 Riferimento
[^1]: Building powerful image classification models using very little data [^2]: Keras Documentation




