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

⏱️3 Min
Teilen:

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.

python
1from keras.preprocessing.image import ImageDataGenerator
2from keras import optimizers
3from keras.applications.vgg16 import VGG16
4from keras.layers import Dense, Dropout, Flatten, Input, BatchNormalization
5from keras.models import Model, Sequential
6from keras.callbacks import ModelCheckpoint
7import numpy as np
8
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, 150
16nb_train_samples = 915649
17nb_validation_samples = 302091
18epochs = 50
19batch_size = 64
20nb_category = 14951
21
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_tensor
35input_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_model
47model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))
48
49# Fix layers
50for layer in model.layers[:15]:
51 layer.trainable = False
52
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 model
69model.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.

python
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.

python
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

python
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.

javascript
1data/
2 train/
3 classA/
4 aaa.jpg
5 bbb.jpg
6 ...
7 classB/
8 ccc.jpg
9 ddd.jpg
10 ...
11
12 validation/
13 classA/
14 eee.jpg
15 fff.jpg
16 ...
17 classB/
18 ggg.jpg
19 hhh.jpg
20 ...

3.1.2 Verwenden Sie das Modell vgg16

Erfahren Sie, wie Sie das VGG16-Modell verwenden, das mit Keras .

python
1# define input_tensor
2input_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_model
14model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))
15
16# Fix layers
17for layer in model.layers[:15]:
18 layer.trainable = False
19
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.

python
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.

python
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_model
9model = 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.

python
1for layer in model.layers[:15]:
2 layer.trainable = False

Kompilieren Sie das Modell. Geben Sie zu diesem Zeitpunkt das Optimierungsprogramm an. Dies gibt an, welcher Algorithmus beim Aktualisieren von Parametern verwendet werden soll.

python
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.

python
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

python
1from keras.preprocessing.image import ImageDataGenerator
2from keras import optimizers
3from keras.applications.vgg16 import VGG16
4from keras.layers import Dense, Dropout, Flatten, Input, BatchNormalization
5from keras.models import Model, Sequential, load_model
6import pandas as pd
7import numpy as np
8import os
9from pandas import DataFrame
10
11test_data_dir = "/test/"
12
13test_datagen = ImageDataGenerator(rescale=1. / 255)
14
15img_width, img_height = 200, 150
16nb_test_samples = 115474
17batch_size = 1
18nb_category = 14951
19
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.

javascript
1data/
2 test/
3 sub/
4 aaa.jpg
5 bbb.jpg
6 ...

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.

5 Referenz

Footnotes

  1. Keras Documentation

  2. Building powerful image classification models using very little data

Teilen:

Verwandte Artikel

Android Anwendung CI/CD mit Flutter
Guides

Android Anwendung CI/CD mit Flutter

Erfahren Sie, wie Sie CI/CD-Pipelines für Android-Apps mit Flutter erstellen. Basierend auf GitHub Actions, ohne fastlane.

mark241
So lokalisieren Sie die App in Flutter
Guides

So lokalisieren Sie die App in Flutter

Erfahren Sie, wie Sie Ihre Flutter-App mit arb-Dateien lokalisieren. Dieser Artikel basiert auf Flutter 2.0.1.

mark241