Classification des images Fashion MNIST

Le jeu de données Fashion MNIST est identique au jeu de données MNIST (chiffres manuscrits) en termes de taille de jeu de données d'entraînement, de taille de jeu de données de test, de nombre d'étiquettes de classe et de dimensions des images.

Pour récapituler, le jeu de données est composé:

  • 60000 images d'entraînement

  • 10000 images de test

  • 10 classes

  • Images en niveaux de gris 28 × 28

Les 10 classes (labels) de ce jeu de donneés sont :

  1. T-shirt/top
  2. Trouser
  3. Pullover
  4. Dress
  5. Coat
  6. Sandal
  7. Shirt
  8. Sneaker
  9. Bag
  10. Ankle boot

Nous allons maintenant construire un CNN pour prédire le label d'une image. Commençons par importer les packages suivants:

In [ ]:
## pour tracer des figures
import matplotlib.pyplot as plt
## pour déclarer le CNN
import keras
from keras import datasets
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Activation, Conv2D, MaxPooling2D
from keras import backend as K
import tensorflow as tf

Lecture du jeu de données

In [ ]:
(X_train, y_train), (X_test, y_test) = datasets.fashion_mnist.load_data()
print('X_train shape:', X_train.shape)
print('X_test shape:', X_test.shape)

Tracer 2 images

In [ ]:
#on peut changer les indices des images pour afficher d'autres images
plt.subplot(221)
plt.imshow(X_train[0], cmap=plt.get_cmap('gray'))
plt.subplot(222)
plt.imshow(X_train[1], cmap=plt.get_cmap('gray'));

Paramètres de réglage et dimensions du jeu de données

In [ ]:
## paramètres de réglage
batch_size = 100
epochs = 12
## dimensions
num_classes = 10
img_rows, img_cols = 28, 28

Mettre les données aux bonnes dimensions et aux bons formats

In [ ]:
## le format des données 
if K.image_data_format() == 'channels_first': 
    X_train = X_train.reshape(X_train.shape[0], 1, img_rows, img_cols)
    X_test = X_test.reshape(X_test.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    X_train = X_train.reshape(X_train.shape[0], img_rows, img_cols, 1)
    X_test = X_test.reshape(X_test.shape[0], img_rows, img_cols, 1)
    
input_shape = (img_rows, img_cols, 1)

X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255

## encodage binaires de la variables réponses 
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

## un peu d'affichage
print(K.image_data_format())
print('X_train shape:', X_train.shape)
print('X_test shape:', X_test.shape)
print(X_train.shape[0], "images pour l'apprentissage")
print(X_test.shape[0], "images de test")

Création ou déclaration du réseau de neurones

L'architecture du réseau de neurones convolutifs sera composée

  1. La première couche cachée Conv2D est une couche convolutive qui a 32 feature maps, chacune avec une taille de 3x3 et nous utilisons une fonction d'activation linéaire rectifiée relu.

  2. Nous ajoutons ensuite une autre couche convolutive avec 64 feature maps.

  3. Nous ajoutons une troisième couche convolutive avec 128 feature maps.

  4. Nous ajoutons ensuite une couche de pooling MaxPooling2D1 qui est configurée avec un pool size de 2x2.

  5. Nous appliquons ensuite une couche de régularisation en utilisant une couche dite Dropout qui consiste à exclure de manière aléatoire 25% des neurones de la couche - ceci est utilisé pour réduire le surajustement.

  6. Nous convertissons ensuite la matrice à 2 dimensions en un vecteur en utilisant une procédure Flatten - cela permet à notre sortie d'être traitée par des couches entièrement connectées

  7. Ensuite, nous ajoutons une couche entièrement connectée qui a 128 neurones et une fonction d'activation ReLU.

  8. Nous ajouterons ensuite une autre couche de régularisation pour réduire le surajustement, cette fois nous excluons aléatoirement 50% des neurones

  9. Nous terminons le réseau de neurones avec une couche de sortie qui a 10 neurones - le même que le nombre de classes dans notre problème de classification et une fonction d'activation softmax. Cela produira une prédiction de la probabilité qu'une image appartienne à chaque classe.

In [ ]:
model = Sequential()

# ajout des couches au réseau de neurones 
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation=Activation(tf.nn.softmax)))

model.summary()

Compiler le modèle

In [ ]:
model.compile(loss=keras.losses.categorical_crossentropy, 
              optimizer=keras.optimizers.Adadelta(), 
              metrics=['accuracy'])

Apprentissage du modèle

In [ ]:
model.fit(X_train, y_train, 
          batch_size=batch_size, 
          epochs=epochs, 
          verbose=1, 
          validation_data=(X_test, y_test))
In [ ]:
score = model.evaluate(X_test, y_test, verbose=0)
print('Erreur de test:', score[1])