Bildklassifizierung in großem Maßstab mit Keras - Feinabstimmung mit vgg16 -

Dieser Artikel wurde vor über einem Jahr veröffentlicht. Die Informationen könnten veraltet sein.
1. Einleitung
Ich habe kürzlich angefangen, maschinelles Lernen zu lernen und an Kaggle , dem Wettbewerb für Kaggle , teilgenommen.
Dieses Mal werde ich zusammenfassen, wie die Feinabstimmung von vgg16 mit der Python- keras Bibliothek 1 implementiert wird.
2 Informationen zu Daten
Der Datensatz ist wie folgt.
Ich hatte nur Daten wie MNIST die oft in ML-Tutorials zu sehen waren. Ich hatte das Gefühl, dass es sich um einen sehr großen Datensatz handelt.
- Klassen: ca. 15.000
- Größe der Lerndaten: ca. 1,2 Millionen Bilddateien. Mehr als 300 GB
- Größe jeder Bilddatei: variiert zwischen den Dateien. z.B. 1.600 \ * 1.200
- Testdaten: ca. 120.000 Dateien
3 Implementierung
3.1 Daten lernen
Zuerst zeige ich Ihnen den gesamten Code.
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 Lernen Sie mit großen Datenmengen
In den meisten Tutorials sehen wir, dass Daten wie folgt geladen werden.
1(X_train, y_train), (X_test, y_test) = mnist.load_data()Es ist jedoch nicht möglich, ganze Daten in den Speicher zu laden, wenn Sie große Datenmengen wie dieses Mal bearbeiten.
Stattdessen können Sie die Funktion flow_from_directory verwenden, um Daten zu laden 2.
Diese Funktion verarbeitet Bilddaten, während die Daten in Echtzeit erweitert werden.
Zuerst müssen Sie ImageDataGenerator erstellen.
1train_datagen = ImageDataGenerator(rescale=1. / 255)2validation_datagen = ImageDataGenerator(rescale=1. / 255)Diese Klasse führt eine Stapelgenerierung von Bilddaten durch, während eine Vorverarbeitung durchgeführt wird. Diesmal einfach neu skalieren. 1/255 wird verwendet, um den RGB-Wertebereich von 0-255 bis 0-1 zu normalisieren.
Lesen Sie als Nächstes die Daten
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")Da es sich um eine kategoriale Klassifizierung handelt, setzen Sie class_mode auf categorical .
Zu diesem Zeitpunkt müssen Sie mit der Ordnerstruktur vorsichtig sein. Wie unten gezeigt, müssen Sie für jede Klasse, die Sie klassifizieren möchten, einen Unterordner erstellen.
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 Verwenden Sie das Modell vgg16
Erfahren Sie, wie Sie das VGG16-Modell verwenden, das mit 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])Verwenden Sie zunächst das Standardmodell vgg16. Zu diesem Zeitpunkt wird die Größe des Eingabedatensatzes angegeben.
1input_tensor = Input(shape=(img_width, img_height, 3))2 3vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)Als nächstes befestigen Sie Ihr eigenes Modell.
Beachten Sie, dass include_top im obigen Argument für die Feinabstimmung auf False gesetzt werden muss.
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))Um ehrlich zu sein, verstehe relu die hier angegebene relu Funktion nicht vollständig.
Daher finde ich den Inhalt dieses Modells nicht sehr hilfreich.
Als nächstes wird das Gewicht festgelegt. Wenn dies nicht angegeben ist, werden die Gewichte von Anfang an neu gelernt, diesmal jedoch behoben.
1for layer in model.layers[:15]:2 layer.trainable = FalseKompilieren Sie das Modell. Geben Sie zu diesem Zeitpunkt das Optimierungsprogramm an. Dies gibt an, welcher Algorithmus beim Aktualisieren von Parametern verwendet werden soll.
1optimizer = optimizers.rmsprop(lr=5e-7, decay=5e-5)2model.compile(loss='categorical_crossentropy',3 optimizer=optimizer,4 metrics=['accuracy'])Endlich lernen. Wenn ModelCheckpoint in Rückrufen festgelegt ist, können Zwischenergebnisse gespeichert werden. Es ist nicht zwingend erforderlich.
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 Vorhersagen
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)Es unterscheidet sich nicht so sehr vom Lernen von Code. Ebenso werden Daten mit flow_from_directory gelesen, wobei jedoch zu beachten ist, dass Unterordner auch für Testdaten erforderlich sind (= Klassen unbekannt). In der folgenden Konfiguration funktioniert dies beispielsweise nur, wenn Sie die Daten in Unterordnern organisieren.
1data/2 test/3 sub/4 aaa.jpg5 bbb.jpg6 ...Da die Klasse unbekannt ist, setzen Sie class_mode auf None .
4 Zusammenfassung
- Verstanden, wie man vgg16 mit Keras benutzt.
- Laden Sie umfangreiche Daten mit
flow_from_directory. - Beachten Sie, dass Sie für die Vorhersage auch Unterordner benötigen.




