Grootschalige beeldclassificatie met Keras - vgg16 fine-tune -

Dit artikel is meer dan een jaar geleden gepubliceerd. De informatie kan verouderd zijn.
1. Inleiding
Ik ben onlangs begonnen met het leren van machine learning en deelnemen aan Kaggle , de competitie voor Kaggle .
Deze keer zal ik samenvatten hoe vgg16 fine-tunen te implementeren met python keras library 1.
2 Over gegevens
De gegevensset is als volgt.
Ik had alleen datasets als MNIST die vaak in ML-tutorials werden gezien, dus ik vond het een hele grote dataset.
- Klassen : ongeveer 15.000
- Grootte van leergegevens : ongeveer 1,2 miljoen afbeeldingsbestanden. Meer dan 300 GB
- De grootte van elk afbeeldingsbestand : varieert tussen de bestanden. bijv. 1600 \ * 1200
- Testgegevens : ongeveer 120.000 bestanden
3 Implementatie
3.1 Gegevens leren
Eerst zal ik je de volledige code laten zien.
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 Leren met grootschalige gegevens
In de meeste tutorials zien we dat gegevens als volgt worden geladen.
1(X_train, y_train), (X_test, y_test) = mnist.load_data()Het is echter niet mogelijk om hele gegevens in het geheugen te laden wanneer u grootschalige gegevens zoals deze keer behandelt.
In plaats daarvan kunt u de functie flow_from_directory gebruiken om gegevens 2 te laden.
Deze functie verwerkt beeldgegevens en breidt de gegevens in realtime uit.
Eerst moet u ImageDataGenerator .
1train_datagen = ImageDataGenerator(rescale=1. / 255)2validation_datagen = ImageDataGenerator(rescale=1. / 255)Deze klasse voert batch-generatie van beeldgegevens uit tijdens het voorbewerken. Deze keer eenvoudig opnieuw schalen. 1/255 wordt gebruikt om het RGB-waardebereik van 0-255 tot 0-1 te normaliseren.
Lees vervolgens gegevens
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")Aangezien het een categorische classificatie is, stelt u class_mode als categorical .
Op dit moment moet u voorzichtig zijn met de mappenstructuur. Zoals hieronder wordt getoond, moet u een submap maken voor elke klasse die u wilt classificeren.
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 Gebruik vgg16-model
Leer het gebruik van het VGG16-model dat kan worden gebruikt met 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])Gebruik eerst het standaard vgg16-model. Op dit moment is de grootte van de invoergegevensset opgegeven.
1input_tensor = Input(shape=(img_width, img_height, 3))2 3vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)Bevestig vervolgens uw eigen model.
Merk op dat include_top in het bovenstaande argument moet worden ingesteld op False voor het afstemmen van het doel.
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))Om eerlijk te zijn, begrijp ik de relu functie hier niet volledig.
Dus ik denk niet dat de inhoud van dit model erg nuttig is.
Vervolgens wordt het gewicht vastgesteld. Als dit niet wordt gespecificeerd, worden de gewichten opnieuw geleerd vanaf het begin, maar deze keer worden deze vastgesteld.
1for layer in model.layers[:15]:2 layer.trainable = FalseStel het model samen. Geef op dit moment de optimizer op. Dit geeft aan welk algoritme moet worden gebruikt bij het bijwerken van parameters.
1optimizer = optimizers.rmsprop(lr=5e-7, decay=5e-5)2model.compile(loss='categorical_crossentropy',3 optimizer=optimizer,4 metrics=['accuracy'])Eindelijk leren. Als ModelCheckpoint is ingesteld in callbacks, kunnen tussentijdse resultaten worden opgeslagen. Het is niet verplicht.
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 Voorspellen
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)Het is niet zo veel anders dan het leren van code. Evenzo worden gegevens gelezen met flow_from_directory , maar het punt om op te merken is dat submappen vereist zijn, zelfs voor testgegevens (= klassen onbekend). In de volgende configuratie werkt het bijvoorbeeld alleen als u de gegevens in submappen organiseert.
1data/2 test/3 sub/4 aaa.jpg5 bbb.jpg6 ...Aangezien de klasse onbekend is, stelt u class_mode in op None .
4 Samenvatting
- Begrepen hoe vgg16 te gebruiken met Keras.
- Laad grootschalige gegevens met
flow_from_directory. - Merk op dat je ook submappen nodig hebt voor voorspelling.



