[PYTHON] [Pour les débutants en IA] Je vais expliquer mnist_transfer_cnn.py ligne par ligne (apprendre MNIST avec Keras)

introduction

Cet article est le troisième article prévu pour les trois fois. Cet article n'est qu'une explication ligne par ligne de mnist_transfer_cnn.py. Il y a des chevauchements avec le précédent, mais veuillez noter qu'une partie du contenu peut être dupliquée pour faciliter la lecture de l'article seul. Il est destiné aux personnes intéressées par l'IA mais qui n'y ont pas encore touché. Je pense que si vous lisez ceci, vous devriez être en mesure de comprendre le flux d'apprentissage de base de l'apprentissage profond. (À l'origine, il a été créé en interne avec l'intention de l'utiliser pour la formation)

  1. [Pour les débutants en IA] Expliquez mnist_mlp.py ligne par ligne (apprenez MNIST avec Keras)
  2. [Pour les débutants en IA] Expliquez mnist_cnn.py ligne par ligne (apprenez MNIST avec Keras)
  3. [Pour les débutants en IA] Expliquez mnist_transfer_cnn.py ligne par ligne (apprenez MNIST avec Keras)

À propos de la méthode de vérification du fonctionnement

Puisque MNIST est une image, il est préférable d'avoir un GPU pour exécuter ce code (c'est un peu pénible pour un CPU). La méthode recommandée consiste à utiliser Google Colaboratory. colab.gif Il n'y a que deux choses à faire. · Ouvrez un nouveau notebook Python 3 · Activer le GPU à partir du runtime Vous pouvez maintenant utiliser le GPU. Collez simplement le code dans la cellule et exécutez-le (le raccourci est CTRL + ENTRÉE) et cela fonctionnera.

À propos de mnist

Un ensemble de données d'images de texte manuscrit, souvent utilisé dans les didacticiels d'apprentissage automatique. Contenu: caractères manuscrits de 0 à 9 Taille de l'image: 28px * 28px Couleur: noir et blanc Taille des données: 70000 feuilles (60000 données d'entraînement, 10000 images et étiquettes de données de test sont disponibles)

Qu'est-ce que le réglage fin?

Utilisez les paramètres d'un bon modèle existant comme valeurs initiales pour gérer une autre tâche. En faisant cela, vous pouvez vous attendre à réduire le coût de calcul et à améliorer la précision.

En parlant de cette fois

  1. Créez un modèle pour classer 0 à 4 images (créez les poids sous-jacents)
  2. Fixez le poids du calque qui extrait les caractéristiques de l'image du modèle créé afin qu'il ne puisse pas être modifié.
  3. Former 5 à 9 images (couche entièrement connectée = mettre à jour uniquement le poids de la pièce à classer)
  4. Enfin, un modèle qui reçoit 5 types de caractères manuscrits de 5 à 9 en entrée et les classe en 5 types de 5 à 9 est terminé.

*** Puisque nous nous sommes entraînés à classer les images de 5 à 9, nous ne pouvons pas classer les images de 0 à 4 avec le modèle finalement terminé cette fois. *** ***

Description du code

Préparation

'''Trains a simple convnet on the MNIST dataset.
Gets to 99.25% test accuracy after 12 epochs
(there is still a lot of margin for parameter tuning).
16 seconds per epoch on a GRID K520 GPU.
'''
'''Transfer learning toy example.
1 - Train a simple convnet on the MNIST dataset the first 5 digits [0..4].
2 - Freeze convolutional layers and fine-tune dense layers
   for the classification of digits [5..9].
Get to 99.8% test accuracy after 5 epochs
for the first five digits classifier
and 99.2% for the last five digits after transfer + fine-tuning.
'''

#Aucun code spécial nécessaire (requis si Python version 3 mais le code est écrit en Python 2)
from __future__ import print_function

#Importer les bibliothèques requises
import datetime
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K

#Obtenez l'heure actuelle
now = datetime.datetime.now

#constant
batch_size = 128   #Taille du lot. Taille des données à apprendre en une seule fois
num_classes = 5    #Nombre d'étiquettes à classer. Cette fois, nous classerons les images manuscrites en 5 types de 5 à 9.
epochs = 5         #Nombre d'époques. Combien de fois pour apprendre toutes les données
img_rows, img_cols = 28, 28  #Nombre de dimensions de l'image d'entrée
filters = 32       #Nombre de filtres pliables
pool_size = 2      #Taille maximale de la mise en commun
kernel_size = 3    #Filtre pliant(noyau)Taille
#Forme des données
if K.image_data_format() == 'channels_first':
    input_shape = (1, img_rows, img_cols)
else:
    input_shape = (img_rows, img_cols, 1)

En ce qui concerne le formulaire de données, les détails sont [Pour les débutants en IA] mnist_cnn.py sera expliqué ligne par ligne (apprendre MNIST avec Keras) Vérifier. Il est décrit dans la partie prétraitement des données.

Il détermine que le format d'image est différent selon que le backend Keras est Theano (channels_first) ou tensorflow (channels_last). Cette fois, c'est tensorflow, donc ce sera (28, 28, 1).

Prétraitement des données

#Lire les données mnist et former les données(60000 caisses)Et tester les données(10000 caisses)Diviser en
(x_train, y_train), (x_test, y_test) = mnist.load_data()

#Créer des ensembles de données séparés par l'étiquette 5 ou plus ou moins
#Image d'entraînement avec une valeur d'étiquette inférieure à 5
x_train_lt5 = x_train[y_train < 5]
#Étiquette de formation avec une valeur d'étiquette inférieure à 5
y_train_lt5 = y_train[y_train < 5]
#Image de test avec une valeur d'étiquette inférieure à 5
x_test_lt5 = x_test[y_test < 5]
#Étiquette de test avec une valeur d'étiquette inférieure à 5
y_test_lt5 = y_test[y_test < 5]

#Image d'entraînement avec une valeur d'étiquette égale ou supérieure à 5
x_train_gte5 = x_train[y_train >= 5]
#Un ensemble de données d'étiquettes d'entraînement avec une valeur d'étiquette égale ou supérieure à 5 moins 5.(5-9 ⇒ 0-4)
y_train_gte5 = y_train[y_train >= 5] - 5
#Image de test avec une valeur d'étiquette égale ou supérieure à 5
x_test_gte5 = x_test[y_test >= 5]
#Un ensemble de données d'étiquettes de test avec une valeur d'étiquette égale ou supérieure à 5 moins 5.(5-9 ⇒ 0-4)
y_test_gte5 = y_test[y_test >= 5] - 5

Tout d'abord, afin de créer un modèle qui classe les images de 0 à 4, nous le divisons en données de 0 à 4 et données de 5 à 9.

Ensuite, pour les données de 5 à 9, changez l'étiquette de 5 à 9 à 0 à 4.

Définition du modèle

#Définition du modèle(.add()Modèles qui n'utilisent pas de méthodes)

#Apprenez les fonctionnalités avec la convolution
feature_layers = [
    #Couche pliante (filtre: 32 feuilles, taille du filtre:(3, 3), Recevoir la taille d'entrée:(28, 28, 1))
    Conv2D(filters, kernel_size,
           # padding='valid'Ne complétez pas avec 0. 0 Lors du rembourrage'same'Spécifier
           padding='valid',
           input_shape=input_shape),
    #Fonction d'activation: Relu
    Activation('relu'),
    #Couche pliante (filtre: 32 feuilles, taille du filtre:(3, 3))
    Conv2D(filters, kernel_size),
    #Fonction d'activation: Relu
    Activation('relu'),
    #Couche de regroupement
    MaxPooling2D(pool_size=pool_size),
    # 0.25 chances de décrochage
    Dropout(0.25),
    #Convertir les données en une dimension
    Flatten(),
]

#Apprenez la classification dans des couches entièrement connectées
classification_layers = [
    #Couche entièrement connectée (128 unités)
    Dense(128),
    #Fonction d'activation: relu
    Activation('relu'),
    # 0.5 chances d'abandonner
    Dropout(0.5),
    #Couche entièrement connectée (5 unités)
    Dense(num_classes),
    #Fonction d'activation: softmax(En raison de problèmes de classification)
    Activation('softmax')
]

#Fonctionnalité dans la classe séquentielle_couches et classification_Instancier ce qui a passé les couches
model = Sequential(feature_layers + classification_layers)

Cette fois, contrairement aux parties 1 et 2, le modèle est défini sans utiliser la méthode .add (). Dans Keras, vous pouvez également définir un modèle en passant une liste ordonnée de couches à Sequential () et en l'instanciant.

La raison d'écrire de cette façon est que *** Le réglage fin ne change pas (ou ne change) le poids que d'une couche spécifique pendant l'apprentissage ***. C'est pourquoi j'ose l'écrire comme ça.

*** En définissant le calque pour extraire les caractéristiques de l'image et le calque pour la classification séparément, il devient facile de mettre à jour un seul des poids ***.

Fonction à apprendre

#Créer une fonction pour former
def train_model(model, train, test, num_classes):
    
    #Prétraitement des données
    #Remodeler et faire correspondre le format des données
    x_train = train[0].reshape((train[0].shape[0],) + input_shape)  # (30596, 28, 28) -> reshape(30596, 28, 28, 1)
    x_test = test[0].reshape((test[0].shape[0],) + input_shape)     # (5139, 28, 28)  -> reshape(5139, 28, 28, 1)
    #Les données d'image prennent une valeur de 0 à 255, donc standardisez les données en les divisant par 255.
    x_train = x_train.astype('float32')
    x_test = x_test.astype('float32')
    # .astype('float32')Convertissez le type de données avec.(Sinon, vous devriez obtenir une erreur lorsque vous vous brisez)
    x_train /= 255
    x_test /= 255
    print('x_train shape:', x_train.shape)
    print(x_train.shape[0], 'train samples')
    print(x_test.shape[0], 'test samples')

    #Étiqueter les données un-hot-Vectorisation
    '''one-hot-L'image du vecteur ressemble à ceci
    label  0 1 2 3 4 
    0:    [1,0,0,0,0]
    3:    [0,0,0,1,0]'''
    y_train = keras.utils.to_categorical(train[1], num_classes)
    y_test = keras.utils.to_categorical(test[1], num_classes)

    #Mettre en place le processus d'apprentissage
    model.compile(loss='categorical_crossentropy',  #Réglez la fonction de perte. Cette fois, c'est une classification, si catégorique_crossentropy
                  optimizer='adadelta',  #L'algorithme d'optimisation est adadelta
                  metrics=['accuracy'])  #Spécifier la fonction d'évaluation

    #Obtenir l'heure de début de l'apprentissage
    t = now()
    #Apprendre
    model.fit(x_train, y_train,       #Données d'entraînement, étiquette
              batch_size=batch_size,  #Taille du lot (128)
              epochs=epochs,          #Nombre d'époques (5)
              verbose=1,              #Afficher la progression de l'apprentissage sous forme de graphique à barres en temps réel(Cacher à 0)
              validation_data=(x_test, y_test))  #données de test(Pour tester chaque époque et calculer l'erreur)
    #Sortie du temps pris pour l'apprentissage
    print('Training time: %s' % (now() - t))
    
    #Évaluation
    #Passer les données de test(verbose=0 ne donne pas de message de progression)
    score = model.evaluate(x_test, y_test, verbose=0)
    #Erreur de généralisation de la sortie
    print('Test score:', score[0])
    #Performances de généralisation de sortie
    print('Test accuracy:', score[1])

Cette fois, nous nous entraînerons deux fois pour créer un modèle qui classe 5 à 9 images.

Apprentissage

#Apprenez à utiliser la fonction créée ci-dessus
#Apprenez en attribuant de 0 à 4 étiquettes aux images de moins de 5(Classer)
train_model(model,
            (x_train_lt5, y_train_lt5),
            (x_test_lt5, y_test_lt5), num_classes)

# trainable=Faux pour empêcher la couche d'apprendre
#Caractéristique qui est la partie à plier_Définir de ne pas mettre à jour les paramètres des couches et de classer_Mettre à jour uniquement les paramètres des couches
#Pour que les modifications prennent effet, compilez dans le modèle après les modifications de propriété()Besoin d'appeler
for l in feature_layers:
    l.trainable = False

#Apprenez à utiliser la fonction créée ci-dessus
#Apprenez en attribuant 0 à 4 étiquettes à 5 images ou plus(Classer)
train_model(model,
            (x_train_gte5, y_train_gte5),
            (x_test_gte5, y_test_gte5), num_classes)

C'est enfin apprendre.

  1. Créez un modèle pour classer 0 à 4 images (créez les poids sous-jacents)
  2. Fixez le poids de feature_layers afin qu'il ne puisse pas être modifié
  3. Former 5 à 9 images (couche entièrement connectée = mettre à jour uniquement le poids de la pièce à classer)
  4. Enfin, un modèle qui reçoit 5 types de caractères manuscrits de 5 à 9 en entrée et les classe en 5 types de 5 à 9 est terminé!

en conclusion

Ceci est la fin des trois articles de commentaire source. L'explication est terminée, mais en prime, je publierai un article sur la façon de sauvegarder et de charger le modèle et comment l'utiliser la prochaine fois. Si vous le créez et ne le sauvegardez pas, il disparaîtra même si vous l'avez fait.

Recommended Posts

[Pour les débutants en IA] Je vais expliquer mnist_transfer_cnn.py ligne par ligne (apprendre MNIST avec Keras)
[Pour les débutants en IA] Expliquez mnist_mlp.py ligne par ligne (apprenez MNIST avec Keras)
[Pour les débutants en IA] Expliquez mnist_cnn.py ligne par ligne (apprenez MNIST avec Keras)
[Pour les débutants] J'ai fait un capteur humain avec Raspberry Pi et notifié LINE!
J'ai essayé de déplacer GAN (mnist) avec keras
J'ai essayé le tutoriel MNIST de tensorflow pour les débutants.
Classer les numéros mnist par keras sans apprentissage par l'enseignant [Auto Encoder Edition]
J'ai essayé de classer MNIST par GNN (avec PyTorch géométrique)
Pour les débutants, comment gérer les erreurs courantes dans les keras
Détection d'anomalies par encodeur automatique à l'aide de keras [Exemple d'implémentation pour les débutants]