Classification d'images à grande échelle avec Keras - vgg16 affiner -

⏱️3 min
Partager :

1. Introduction

J'ai récemment commencé à apprendre le machine learning et à participer à Kaggle , le concours de classification d'images. Cette fois, je vais résumer comment implémenter vgg16 avec la bibliothèque keras python 1.

2 À propos des données

L'ensemble de données est le suivant. Je n'avais expérimenté que des ensembles de données comme MNIST qui étaient souvent vus dans les tutoriels ML, donc je sentais que c'était un très gros ensemble de données.

  • Cours: environ 15 000
  • Taille des données d'apprentissage: environ 1,2 million de fichiers image. Plus de 300 Go
  • La taille de chaque fichier image: varie selon les fichiers. par exemple. 1.600 \ * 1.200
  • Données de test: environ 120 000 fichiers

3 Mise en œuvre

3.1 Apprendre les données

Je vais d'abord vous montrer tout le 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 Apprendre avec des données à grande échelle

Dans la plupart des didacticiels, nous pouvons voir que les données sont chargées comme suit.

python
1(X_train, y_train), (X_test, y_test) = mnist.load_data()

Cependant, il n'est pas possible de charger des données entières en mémoire lorsque vous traitez des données à grande échelle comme cette fois. Au lieu de cela, vous pouvez utiliser la fonction flow_from_directory pour charger les données 2. Cette fonction traite les données d'image tout en développant les données en temps réel.

Vous devez d'abord créer ImageDataGenerator .

python
1train_datagen = ImageDataGenerator(rescale=1. / 255)
2validation_datagen = ImageDataGenerator(rescale=1. / 255)

Cette classe effectue une génération par lots de données d'image lors du prétraitement. Cette fois, redimensionnez simplement. 1/255 est utilisé pour normaliser la plage de valeurs RVB de 0-255 à 0-1.

Ensuite, lisez les données

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

Puisqu'il s'agit d'une classification catégorielle, définissez class_mode comme categorical . À ce stade, vous devez faire attention à la structure des dossiers. Comme indiqué ci-dessous, vous devez créer un sous-dossier pour chaque classe que vous souhaitez classer.

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 Utiliser le modèle vgg16

Apprenez à utiliser le modèle VGG16 qui peut être utilisé avec 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])

Tout d'abord, utilisez le modèle par défaut vgg16. À ce stade, la taille de l'ensemble de données d'entrée est spécifiée.

python
1input_tensor = Input(shape=(img_width, img_height, 3))
2
3vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)

Ensuite, attachez votre propre modèle. Notez que include_top dans l'argument ci-dessus doit être défini sur False à des fins de réglage fin.

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

Pour être honnête, je ne comprends pas complètement la fonction relu spécifiée ici. Je ne pense donc pas que le contenu de ce modèle soit très utile.

Ensuite, le poids est fixe. Si cela n'est pas spécifié, les poids seront réappris depuis le début, mais cette fois, ils seront corrigés.

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

Compilez le modèle. À ce stade, spécifiez l'optimiseur. Ceci spécifie l'algorithme à utiliser lors de la mise à jour des paramètres.

python
1optimizer = optimizers.rmsprop(lr=5e-7, decay=5e-5)
2model.compile(loss='categorical_crossentropy',
3 optimizer=optimizer,
4 metrics=['accuracy'])

Enfin l'apprentissage. Si ModelCheckpoint est défini dans les rappels, les résultats intermédiaires peuvent être enregistrés. Ce n'est pas obligatoire.

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 Prédire

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)

Ce n'est pas tellement différent de l'apprentissage du code. De même, les données sont lues avec flow_from_directory , mais le point à noter est que des sous-dossiers sont nécessaires même pour les données de test (= classes inconnues). Par exemple, dans la configuration suivante, cela ne fonctionnera que si vous organisez les données dans des sous-dossiers.

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

Puisque la classe est inconnue, définissez class_mode sur None .

4 Résumé

  • Compris comment utiliser vgg16 avec Keras.
  • Chargez des données à grande échelle avec flow_from_directory .
  • Notez que vous avez également besoin de sous-dossiers pour la prédiction.

5 Référence

Footnotes

  1. Keras Documentation

  2. Building powerful image classification models using very little data

Partager :

Articles connexes

Application Android CI/CD avec Flutter
Guides

Application Android CI/CD avec Flutter

Découvrez comment construire un pipeline CI/CD pour les apps Android avec Flutter. Basé sur GitHub Actions, sans fastlane.

mark241