[PYTHON] Juger si c'est mon enfant à partir de l'image du chien Shiba par apprentissage en profondeur (2) Augmentation des données / transfert d'apprentissage / réglage fin

introduction

――Ceci est le résultat de mon propre dossier d'étude sur l'apprentissage automatique et l'apprentissage profond.

Public cible de cet article / Documents de référence

Le meme que la derniere fois. Pour plus de détails ** ici **.

À propos de moi

--Acquis ** JDLA Deep Learning pour Engeneer 2019 # 2 ** en septembre 2019. ――Jusqu'à la fin mars 2020, vous occuperez le bureau d'une société d'intérêt public. À partir d'avril 2020, il a changé de carrière en ingénieur de données.

Aperçu de l'analyse précédente (1)

――Nous avons collecté un total de 120 fichiers image (jpg), 60 photos de chiens de compagnie (chiens Shiba) et 60 photos de chiens Shiba (autres que des chiens de compagnie), et les avons classés en 2 catégories par apprentissage profond. ―― À la suite de l'apprentissage du modèle et de sa vérification avec des données de test, la précision n'était que d'environ 75 à 76%.

Aperçu de la procédure de cette époque (2)

** Étape 1 Augmentez la quantité de données d'analyse (doublez le nombre de photos) et téléchargez-les sur Google Drive ** ** Étape 2 Créez un dossier de travail sur Google Drive, décompressez et copiez les données ** ** Étape 3 Construction du modèle / apprentissage / résultats ** ** Étape 4 Transfert de l'apprentissage avec le modèle ImageNet (VGG16) ** ** Étape 5 Réglage fin avec le modèle ImageNet (VGG16) **

Étape 1 Augmentez la quantité de données d'analyse (doublez le nombre de photos) et téléchargez-les sur Google Drive

(1) Augmentation des données photo

Dans l'analyse précédente, je pense qu'il y a plusieurs raisons pour lesquelles l'exactitude de la classification est restée dans la fourchette de 70%, mais je pense que la plus importante est que les données de formation étaient aussi petites que 60 données. Il est assez difficile d'augmenter les données, mais pour ce classement, nous avons augmenté le nombre de photos à 120 pour les chiens de compagnie et 120 pour les shiba autres que les chiens de compagnie, pour un total de 240 photos. Reclassez en fonction de ce fichier de données.

--Fichier jpg Pet Dog (120 feuilles) Exemple de photo nouvellement ajouté ⇒ Résumer dans mydog2.zip mydog28.jpgmydog20.jpgmydog36.jpgmydog104.jpg

-Fichier jpg de chiens Shiba autres que votre chien (120 feuilles) Exemple de photo nouvellement ajouté → Résumer dans otherdogs2.zip pixabay041.jpgpixabay051.jpgpixabay015.jpgwp011.jpg

(2) Conservez un dossier pour stocker les données dans Google Drive

--Lorsque vous avez effectué l'analyse précédente, vous avez créé les dossiers suivants pour stocker les données. (La figure est un exemple de ma structure de dossiers) drive3b.png

(3) Télécharger le fichier de données

--Téléchargez les deux fichiers zip "mydog2.zip" et "otherdogs2.zip" dans Google Drive (dossier "original_data").

Étape 2 Créez un dossier de travail sur Google Drive, décompressez et copiez les données

** Note) À propos du décalage temporel concernant la coopération entre Colaboratory et Google Drive ** Cela ressemble plus à la rédaction d'un mémo qu'à une mise en garde, mais pour la coopération entre Colaboratory et Google Drive Je pense qu'il y a un décalage dans le temps. Afin d'effectuer le traitement en toute sécurité, il semble préférable de procéder étape par étape tout en confirmant que chaque traitement est terminé, au lieu d'effectuer chaque traitement tel que la création d'un dossier de travail et la copie en une seule fois. Je pense. Dans mon essai, après avoir émis une commande de Colaboratory vers Google Drive, il faut un certain temps pour qu'elle se reflète réellement. Par conséquent, bien que cela puisse dépendre de la synchronisation, si le processus suivant est exécuté avant la réflexion, une erreur peut se produire. Si cela ne fonctionne pas d'un seul coup, il est judicieux de diviser le processus en plusieurs étapes. </ font>

Étape 3 Construction du modèle / apprentissage / résultats

(1) Résultats d'apprentissage sans augmentation des données

――Les résultats de la formation sont présentés dans le graphique ci-dessous. Il y a des signes de surapprentissage à la fois en précision et en perte, et il n'y a pas d'amélioration notable. traial03b.png

(2) Application pour tester les données (pas d'augmentation des données)

Les résultats de vérification appliqués aux données de test sont les suivants. L'augmentation du nombre d'échantillons de données a conduit à une précision améliorée et la précision a atteint environ 80%. test loss: 1.7524430536416669 test acc: 0.8166666567325592

(3) Résultats d'apprentissage avec augmentation des données

Ensuite, je me suis entraîné avec l'augmentation des données. Les résultats de la formation sont présentés dans le graphique ci-dessous. traial04-2.png

(4) Application pour tester les données (avec augmentation des données)

Ensuite, les résultats de vérification des données de test lorsque le paramètre Image Generator est défini pour remplir les données d'image sont les suivants (les conditions de remplissage sont les mêmes que les paramètres de l'essai précédent, seul l'affichage des résultats). Celui-ci a une plus grande précision. test loss: 1.382319548305386 test acc: 0.8666666634877522

Étape 4 Transfert de l'apprentissage avec le modèle ImageNet (VGG16)

Cette fois, nous effectuerons l'apprentissage par transfert. Importez le modèle entraîné (VGG16) d'ImageNet, qui est un modèle typique, à partir de la bibliothèque keras et utilisez-le. À partir du modèle VGG16, seule la base de convolution entraînée est utilisée pour extraire une carte de caractéristiques locales polyvalente. En connectant le classificateur "(pour Shiba chien) mon enfant-autre enfant" à la sortie, la précision de la classification sera améliorée.

(1) À propos de VGG16

--VGG16 est un réseau neuronal multicouche composé de 13 couches convolutives et de 3 couches entièrement connectées, pour un total de 16 couches. Le modèle publié est formé à l'aide d'un grand ensemble d'images appelé ImageNet. --Il est implémenté dans le module keras.applications.vgg16 en tant que bibliothèque Keras.

(2) Chargez le modèle

――Ce qui suit sera basé sur l'hypothèse qu'un dossier de stockage de données et un dossier de travail ont été créés dans Google Drive et que les données d'image à analyser ont été stockées. (Implémenté dans le même environnement d'analyse qu'avant) --Chargez le modèle VGG16 dans la variable conv_base.

#Chargement de VGG16
from keras.applications import VGG16

conv_base = VGG16(weights='imagenet', #Spécifiez le type de poids(Ici, spécifiez le poids appris par Imagenet)
                  include_top=False, #S'il faut inclure le classificateur entièrement couplé du côté sortie du NW(Puisque nous utiliserons ici notre propre classificateur entièrement connecté, nous ne l'inclurons pas.)
                  input_shape=(320, 320, 3)) #Le standard ImageNet est la forme du tenseur d'image fourni au NW.(224, 224 3) (Cette fois 320pxl*Spécifier une image RVB 320pxl)
conv_base.summary()

La structure de modèle suivante s'affiche pour la partie correspondante du VGG16 chargé.

Model: "vgg16"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_2 (InputLayer)         (None, 320, 320, 3)       0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 320, 320, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 320, 320, 64)      36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 160, 160, 64)      0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 160, 160, 128)     73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 160, 160, 128)     147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 80, 80, 128)       0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 80, 80, 256)       295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 80, 80, 256)       590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 80, 80, 256)       590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 40, 40, 256)       0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 40, 40, 512)       1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 40, 40, 512)       2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 40, 40, 512)       2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 20, 20, 512)       0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 20, 20, 512)       2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 20, 20, 512)       2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 20, 20, 512)       2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 10, 10, 512)       0         
=================================================================
Total params: 14,714,688
Trainable params: 14,714,688
Non-trainable params: 0
_________________________________________________________________

(3) Construction du modèle

Créez un modèle en joignant la couche entièrement connectée pour cette classification binaire à conv_base.

from keras import models
from keras import layers

model = models.Sequential()
model.add(conv_base)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

model.summary()

La structure de modèle suivante s'affiche.

Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
vgg16 (Model)                (None, 10, 10, 512)       14714688  
_________________________________________________________________
flatten_1 (Flatten)          (None, 51200)             0         
_________________________________________________________________
dense_1 (Dense)              (None, 256)               13107456  
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 257       
=================================================================
Total params: 27,822,401
Trainable params: 27,822,401
Non-trainable params: 0
_________________________________________________________________

(4) Vérifiez le nombre de poids entraînables

# conv_Nombre de poids pouvant être formés avant de congeler la base
print('conv_Nombre de poids pouvant être formés avant de congeler la base:' ,len(model.trainable_weights))

Une fois exécuté, le résultat "30" est affiché.

(5) Définissez uniquement le poids de conv_base sur non entraînable et vérifiez le résultat du réglage.

# conv_Définir uniquement le poids de base pour qu'il ne puisse pas être entraîné
conv_base.trainable = False

#Vérification du nombre de poids entraînables
print('conv_base Nombre de poids pouvant être entraînés à l'état gelé:' ,len(model.trainable_weights))

Une fois exécuté, le nombre de poids entraînables sera changé en "4" et affiché. Entraînez le modèle dans cet état de configuration.

(5) Tensorisation d'image et apprentissage

Utilisez le code ci-dessous.

from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers

#Paramètres du générateur de données de train Gonflé: Oui
train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest')

#Paramètres du générateur pour les données de validation et les données de test Gonflé: Aucun\(Le générateur de données de validation et de données de test est courant)
test_datagen = ImageDataGenerator(rescale=1./255)

#Tensolisation des données du train
train_generator = train_datagen.flow_from_directory(
        # target directory
        train_dir,
        # size 320x320
        target_size=(320, 320),
        batch_size=20,
        #Binaire comme fonction de perte_Nécessite une étiquette binaire pour utiliser la copie croisée
        class_mode='binary')

#Tensolisation des données de validation
validation_generator = test_datagen.flow_from_directory(
        validation_dir,
        target_size=(320, 320),
        batch_size=32,
        class_mode='binary')

#Compiler le modèle
model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=2e-5),
              metrics=['acc'])

#Apprentissage
history = model.fit_generator(
      train_generator,
      steps_per_epoch=100,
      epochs=30,
      validation_data=validation_generator,
      validation_steps=50,
      verbose=2)

Enregistrez le modèle après l'exécution.

model.save('mydog_or_otherdogs_02a.h5')

(6) Résultat d'exécution

  • Le graphique des résultats de la formation est le suivant. traial04.png ――La forme du graphique a changé. La précision commence autour de 0,88 et s'améliore de 0,93 à environ 0,96. La perte commence autour de 0,3 et se situe entre 0,1 et 0,2. Il y a des signes d'amélioration par rapport à l'état de surapprentissage.

  • Ensuite, vérifiez le résultat de la classification de ce modèle avec les données de test. (Voir l'article précédent pour le code) test loss: 0.274524162985399 test acc: 0.9333333373069763

  • À la suite de l'apprentissage par transfert, les performances de classification se sont améliorées. La précision a dépassé 90% pour la première fois. Dans cet essai, seul le module formé de VGG16 a été utilisé pour la base de convolution, mais la capacité d'extraire la carte des caractéristiques locales très polyvalente obtenue par la formation avec ImageNet contribue grandement aux performances de classification. Vous pouvez voir que ce sera le cas.

Étape 5 Réglage fin avec le modèle ImageNet (VGG16)

(1) Aperçu du réglage fin

Le réglage fin dégivre plusieurs couches côté sortie de la base de convolution gelée utilisée pour l'extraction de caractéristiques et entraîne à la fois la partie nouvellement ajoutée du modèle (dans ce cas le classificateur entièrement couplé) et la couche décongelée. C'est un mécanisme à faire.

(2) Procédure de mise en œuvre du réglage fin

  1. Ajouter un réseau personnalisé à la fin du réseau de base formé
  1. Gelez le réseau de base
  2. Apprenez la pièce ajoutée
  3. Décompressez certaines couches du réseau de base
  4. Entraînez la couche décongelée et la pièce ajoutée en même temps
  • En ce qui concerne la description de (1) et (2), la partie pertinente est citée de "Deep Learning by Python and Keras" par Francois Chollet, traduit par Quipe Co., Ltd., traduit par Yusuke Negago et publié par My Navi Publishing Co., Ltd.

(3) Réglage des poids entraînables

  • Le code suivant définit les poids qui peuvent être formés lors de l'exécution d'un réglage fin.
  • Ne définissez que trois couches, block5_conv1, block5_conv2 et block5_conv3, pour être entraînables.
conv_base.trainable = True

set_trainable = False
for layer in conv_base.layers:
  if layer.name == 'block5_conv1':
    set_trainable = True
  if set_trainable:
    layer.trainable = True
  else:
    layer.trainable = False

(4) Exécution du réglage fin

Apprenons avec le code suivant.

#Sélectionnez RMSprop comme optimiseur et utilisez un taux d'apprentissage assez faible
#Si la valeur de mise à jour est élevée, cela endommagera les expressions des trois couches cibles de réglage fin.

model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-5),
              metrics=['acc'])

history = model.fit_generator(
      train_generator,
      steps_per_epoch=100,
      epochs=100,
      validation_data=validation_generator,
      validation_steps=50)

Enregistrez le modèle après l'entraînement.

model.save('mydog_or_otherdogs_02b.h5')

(5) Graphique des résultats

Le graphique résultant est présenté ci-dessous. traial05.png Le code suivant lisse le graphique.

#Lissage du tracé
def smooth_curve(points, factor=0.8):
    smoothed_points = []
    for point in points:
        if smoothed_points:
            previous = smoothed_points[-1]
            smoothed_points.append(previous * factor + point * (1 - factor))
        else:
            smoothed_points.append(point)
    return smoothed_points


plt.plot(epochs, smooth_curve(acc), 'bo', label='Smoothed training acc')
plt.plot(epochs, smooth_curve(val_acc), 'b', label='Smoothed validation acc')
plt.title('Training and validation accuracy')
plt.legend()

plt.figure()

plt.plot(epochs, smooth_curve(loss), 'bo', label='Smoothed training loss')
plt.plot(epochs, smooth_curve(val_loss), 'b', label='Smoothed validation loss')
plt.title('Training and validation loss')
plt.legend()

plt.show()

Le graphique est le suivant. En regardant l'état de validation, il ne semble pas que les performances s'améliorent à mesure que le nombre d'époques augmente, mais la plage de changement dans le graphique est affichée dans une plage plus étroite qu'auparavant, de sorte que la précision est améliorée. Vous pouvez vous attendre à y être. traial06.png

(6) Appliquer le modèle entraîné aux données de test pour vérifier l'exactitude de la classification.

Les résultats de vérification appliqués aux données de test sont les suivants.

test loss: 0.5482699687112941 test acc: 0.9499999916553498

Grâce à des ajustements précis, nous avons pu améliorer encore les performances de classification. Je voudrais mettre en œuvre diverses approches que je n'ai pas encore essayées pour améliorer encore la précision. Dans cette vérification, nous ferons une pause jusqu'à présent.

Recommended Posts

Juger si c'est mon enfant à partir de l'image du chien Shiba par apprentissage en profondeur (2) Augmentation des données / transfert d'apprentissage / réglage fin
À en juger par l'image du chien Shiba en apprenant en profondeur si c'est mon enfant (1)
Déterminer s'il s'agit de mon enfant à partir de l'image du chien Shiba par apprentissage profond (3) Visualisation par Grad-CAM
Découvrez le nom de la méthode qui l'a appelée à partir de la méthode qui est python
Autour de l'endroit où la valeur d'Errbot est stockée
À en juger par l'image du chien Shiba en apprenant en profondeur si c'est mon enfant (1)
Juger si c'est mon enfant à partir de l'image du chien Shiba par apprentissage en profondeur (2) Augmentation des données / transfert d'apprentissage / réglage fin
Déterminez s'il s'agit de mon enfant à partir de l'image du chien Shiba par apprentissage profond (4) Visualisation par Grad-CAM et Grad-CAM guidé
Essayez Fine Tuning (apprentissage par transfert), qui est le courant dominant avec des images avec keras, avec apprentissage des données
L'apprentissage en profondeur! L'histoire des données elles-mêmes qui sont lues lorsqu'elles ne suivent pas après la reconnaissance des nombres manuscrits
Traitement de la voix par apprentissage profond: identifions qui est l'acteur vocal à partir de la voix