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

⏱️3 min
Condividi:

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.

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 Impara con dati su larga scala

Nella maggior parte dei tutorial, possiamo vedere i dati caricati come segue.

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

python
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

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

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.

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 Utilizzare il modello vgg16

Scopri come utilizzare il modello VGG16 che può essere utilizzato con 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])

Innanzitutto, utilizzare il modello predefinito vgg16. A questo punto, viene specificata la dimensione del set di dati di input.

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

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

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.

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

Compila il modello. Al momento, specifica l'ottimizzatore. Questo specifica quale algoritmo usare quando si aggiornano i parametri.

python
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

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 Predire

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)

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.

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

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

Condividi:

Articoli correlati

Applicazione Android CI/CD con Flutter
Software

Applicazione Android CI/CD con Flutter

Scopri come costruire pipeline CI/CD per app Android con Flutter. Basato su GitHub Actions, senza usare fastlane.

mark241
Come localizzare l'app in Flutter
Software

Come localizzare l'app in Flutter

Scopri come localizzare la tua app Flutter usando i file arb. Questo articolo è basato su Flutter 2.0.1.

mark241