Grootschalige beeldclassificatie met Keras - vgg16 fine-tune -

⏱️3 min
Delen:

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.

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 Leren met grootschalige gegevens

In de meeste tutorials zien we dat gegevens als volgt worden geladen.

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

python
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

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")

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.

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 Gebruik vgg16-model

Leer het gebruik van het VGG16-model dat kan worden gebruikt met 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])

Gebruik eerst het standaard vgg16-model. Op dit moment is de grootte van de invoergegevensset opgegeven.

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

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))

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.

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

Stel het model samen. Geef op dit moment de optimizer op. Dit geeft aan welk algoritme moet worden gebruikt bij het bijwerken van parameters.

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

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 Voorspellen

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)

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.

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

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.

5 Referentie

Footnotes

  1. Keras Documentation

  2. Building powerful image classification models using very little data

Delen:

Gerelateerde artikelen

Android applicatie CI/CD met Flutter
Guides

Android applicatie CI/CD met Flutter

Leer hoe u CI/CD-pipelines bouwt voor Android-apps met Flutter. Gebaseerd op GitHub Actions, zonder fastlane.

mark241
Hoe de app in Flutter te lokaliseren
Guides

Hoe de app in Flutter te lokaliseren

Leer hoe u uw Flutter-app lokaliseert met arb-bestanden. Dit artikel is gebaseerd op Flutter 2.0.1.

mark241
Beschrijf Azure-resources als ARM Template
Guides

Beschrijf Azure-resources als ARM Template

ARM Template is een json-bestand dat Azure-resources definieert. Leer hoe u efficiënt ARM Templates kunt maken.

mark241