[PYTHON] À en juger par l'image du chien Shiba en apprenant en profondeur si c'est mon enfant (1)

introduction

――Ceci est le résultat de mon propre dossier d'étude sur l'apprentissage automatique et l'apprentissage profond. ――Cette fois, Google Colaboratory classera deux types de données d'image. Jugez "mon enfant (chien de compagnie)" et "autre que mon enfant (chien de compagnie)" à partir de l'image du chien Shiba. ―― Décrivez autant que possible les parties qui ont trébuché en raison de diverses erreurs, et décrivez-les afin que tout le monde puisse les reproduire facilement. ――C'est la première fois que vous publiez un article sur qiita, donc si vous avez des avis ou des corrections, veuillez nous en informer.

Qui est la cible de cet article

――Ceux qui étudient l'apprentissage en profondeur et veulent faire diverses analyses, mais manquent de connaissances et d'informations et ont trébuché de diverses manières dans et autour de Google Colaboratory, et l'analyse ne se déroule pas comme prévu (articles pour les utilisateurs avancés de Bali Bali) Ne pas!)

À propos de moi

――J'ai commencé à étudier l'apprentissage automatique en 2018, et depuis 2019, je suis membre de la société qui étudie principalement les samedis et dimanches quand il n'y a pas de travail, en me concentrant sur l'apprentissage profond. «Je n'ai aucune expérience en tant qu'ingénieur et j'ai travaillé en tant que membre de la société. Je n'ai aucune chance d'utiliser l'apprentissage automatique dans la pratique, mais plus j'étudie, plus je deviens accro au charme profond de ce domaine, et en septembre 2019 ** JDLA Deep Learning for Engeneer 2019 # J'ai 2 **. ――Je souhaite acquérir de l'expérience dans diverses analyses d'apprentissage en profondeur et je participe actuellement à l'analyse de cas en utilisant des données réelles. ―― À la fin du mois de mars 2020, je prendrai ma retraite d'une fonction publique avec 18 ans de service et à partir d'avril je changerai de poste en ingénieur de données.

Littérature référencée

-: Closed_book: ** "Deep learning with Python and Keras" **: boy_tone1: Francois Chollet Traduit par Quipe Co., Ltd. Traduit par Yusuke Negago, publié par My Navi Publishing Co., Ltd.

Préparation préalable

-Vous devez avoir un ** compte Google **. --Si vous ne l'avez pas, veuillez vous référer à ** Cet article ** et obtenir votre propre compte à l'avance.

Aperçu de la procédure

** Étape 1 Collectez des photos à analyser, redimensionnez et importez sur Google Drive au format zip ** ** Étape 2 Créez un dossier de travail sur Google Drive et décompressez les données. ** ** ** Étape 3 Copiez le nombre spécifié de photos de chiens Shiba (50 chacune) dans les dossiers train, test et validation. ** ** ** Étape 4 Construction du modèle ** ** Étape 5 Apprentissage ** ** Résultat de l'étape 6 ** ** Étape 7 Augmentation des données ** ** Étape 8 Autres résultats de réglage (changement de la taille d'entrée de l'image, etc.) **

À propos de mon enfant

mirin025_m.jpg

Tout d'abord, permettez-moi de vous présenter mon enfant avant de procéder à la procédure d'analyse. Depuis janvier 2020, je suis une Shiba de 16 ans. Le nom est ** Mirin **. Le nom est ma femme, mais comme c'est un chien japonais, il a été nommé dans un style japonais. ** Déjà, ce mirin est mignon et mignon! ** ** Il y a beaucoup de jolies images de ce mirin dans le fichier zip des données d'analyse (mydog) qui sortira plus tard. Nous espérons que vous y jetterez un œil également et que vous apprécierez ensemble les différentes expressions de notre Mirin (← ** Parent idiot **).

Procédure spécifique

Étape 1 Collectez des photos à analyser, redimensionnez et téléchargez sur Google Drive au format zip

(1) Collection de photos de chiens Shiba

--Recueillir des photos libres de droits de chiens Shiba en ligne. Je l'ai apporté d'un site ici. Lors de la recherche sur des sites étrangers, les photos apparaissent avec le mot «Shiba Inu» comme terme de recherche.  pixabay
 unsplash
 Gahag
Matériel photo Adachi Matériel gratuit dot com ――Ce site, qui vous permet de rechercher sur plusieurs sites de matériel gratuits, était également pratique.  O-DAN

―― J'ai collecté des photos de Mirin à partir des dossiers de mon smartphone et de mon appareil photo numérique. À ce moment-là, afin d'éviter que le montant de la caractéristique ne soit dispersé, j'ai choisi la période de la photographie en excluant la période chiot et en me concentrant sur la période de 12 à 16 ans (actuelle).

(2) Rognage et redimensionnement de l'image

――Comme chaque image comporte différentes photographies, elle ne convient pas pour une utilisation en tant que données telles quelles. Par conséquent, je l'ai coupé pour que le rapport de l'élément chien dans une image soit aussi élevé que possible. À l'aide de logiciels de retouche photo (Photoshop Elements, gimp, etc.), avec un rapport hauteur / largeur de 1: 1, découpez de plus en plus sans vous soucier de la taille de l'image, et enregistrez-la sous forme de fichier image (fichier jpg). --Le fichier découpé utilise un logiciel tel que ** Reduction **, et cette fois c'est une image de 320 x 320 pixels. Redimensionner en masse au format. J'ai utilisé ** FlexRena84 ** pour renommer par lots des fichiers image.

Je publierai quelques photos. ** Photo de Mirin (mon chien) ** mydog52.jpgmydog1.jpgmydog54.jpgmydog14.jpg

** Photos d'autres chiens Shiba (autres chiens) ** otherdogs0.jpgotherdogs1.jpgotherdogs2.jpgotherdogs21.jpg

(3) Télécharger sur Google Drive

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

À partir de là, lancez Google Colaboratory et opérez sur Colab.

(1) Tout d'abord, montez Google Drive.

Pour les nouveaux utilisateurs, veuillez vous référer à ** ici **.

#Monture Google Drive
from google.colab import drive
drive.mount('/content/drive')

(2) Remplacez le répertoire actuel par le dossier de travail et décompressez le fichier zip.

# cd '/content/drive/'My Drive/'Colab Notebooks'Remplacez le répertoire actuel par le dossier de travail dans
%cd '/content/drive/'My Drive/Colab Notebooks/Self_Study/02_mydog_or_otherdogs/original_data

# mydog1.Décompressez le zip
!unzip "mydog1.zip"

# otherdogs1.Décompressez le zip
!unzip "otherdogs1".zip"

#Vérifiez le nombre de fichiers décompressés
!ls ./original_data/mydog1 | wc -l
!ls ./original_data/otherdogs1 | wc -l

** Note) Les données doivent être compressées et téléchargées sur Google Drive avant la décompression. </ font> ** J'ai essayé de télécharger directement sur Google Drive sans compression, mais cela prend beaucoup de temps. L'opération étant effectuée sur le colaboratoire, la commande de décompression utilise la commande Linux commençant par "!". unzip.png Un message comme celui-ci apparaîtra et le fichier sera décompressé.

Étape 3 Copiez le nombre spécifié de photos de chiens Shiba (60 chacune) dans les dossiers train, test et validation.

(1) Définissez le chemin du fichier pour copier le fichier image et créez un nouveau dossier à utiliser.

#Chargement des bibliothèques requises
import os, shutil

#Définissez le chemin de fichier requis
# cd '/content/drive/'My Drive/'Colab Notebooks'Remplacez le répertoire actuel par le dossier de travail dans
%cd '/content/drive/'My Drive/Colab Notebooks/Self_Study/02_mydog_or_otherdogs

# original_Définition du chemin d'accès au fichier du dossier de données
original_dataset_dir = 'original_data'
# original_data(Nom de la définition'original_dataset_dir')Définissez les deux chemins de dossier suivants dans.
original_mydog_dir = 'original_data/mydog'
original_otherdogs_dir = 'original_data/otherdogs'

# use_Définition du chemin de fichier des données
base_dir = 'use_data'

# use_dossier de données(Nom de la définition'base_dir')Définissez les trois chemins de dossier suivants dans. Créez un dossier.
train_dir = os.path.join(base_dir, 'train')
os.mkdir(train_dir)
validation_dir = os.path.join(base_dir, 'validation')
os.mkdir(validation_dir)
test_dir = os.path.join(base_dir, 'test')
os.mkdir(test_dir)

#Dans le dossier du train'mydog'Avec dossiers'otherdogs'Définissez le chemin du dossier. Créez un dossier.
train_mydog_dir = os.path.join(train_dir, 'mydog')
os.mkdir(train_mydog_dir)
train_otherdogs_dir = os.path.join(train_dir, 'otherdogs')
os.mkdir(train_otherdogs_dir)

#Dans le dossier de validation'mydog'Avec dossiers'otherdogs'Définissez le chemin du dossier. Créez un dossier.
validation_mydog_dir = os.path.join(validation_dir, 'mydog')
os.mkdir(validation_mydog_dir)
validation_otherdogs_dir = os.path.join(validation_dir, 'otherdogs')
os.mkdir(validation_otherdogs_dir)

#Dans le dossier de test'mydog'Avec dossiers'otherdogs'Définissez le chemin du dossier. Créez un dossier.
test_mydog_dir = os.path.join(test_dir, 'mydog')
os.mkdir(test_mydog_dir)
test_otherdogs_dir = os.path.join(test_dir, 'otherdogs')
os.mkdir(test_otherdogs_dir)

(2) Effectuez une copie des fichiers et vérifiez le nombre de fichiers copiés.


#train pour le train_mydog_Copiez 30 fichiers mydog dans le répertoire
fnames = ['mydog{}.jpg'.format(i) for i in range(30)]
for fname in fnames:
    src = os.path.join(original_mydog_dir, fname)
    dst = os.path.join(train_mydog_dir, fname)
    shutil.copyfile(src, dst)

#validation pour validation_mydog_Copiez 20 fichiers mydog dans le répertoire
fnames = ['mydog{}.jpg'.format(i) for i in range(30,50)]
for fname in fnames:
    src = os.path.join(original_mydog_dir, fname)
    dst = os.path.join(validation_mydog_dir, fname)
    shutil.copyfile(src, dst)

#test pour test_mydog_Copiez 10 fichiers mydog dans le répertoire
fnames = ['mydog{}.jpg'.format(i) for i in range(50,60)]
for fname in fnames:
    src = os.path.join(original_mydog_dir, fname)
    dst = os.path.join(test_mydog_dir, fname)
    shutil.copyfile(src, dst)

#train pour le train_otherdogs_Copiez 30 autres fichiers de chiens dans le répertoire
fnames = ['otherdogs{}.jpg'.format(i) for i in range(30)]
for fname in fnames:
    src = os.path.join(original_otherdogs_dir, fname)
    dst = os.path.join(train_otherdogs_dir, fname)
    shutil.copyfile(src, dst)

#validation pour validation_otherdogs_Copiez 20 autres fichiers de chiens dans le répertoire
fnames = ['otherdogs{}.jpg'.format(i) for i in range(30, 50)]
for fname in fnames:
    src = os.path.join(original_otherdogs_dir, fname)
    dst = os.path.join(validation_otherdogs_dir, fname)
    shutil.copyfile(src, dst)

#test pour test_otherdogs_Copiez 10 autres fichiers de chiens dans le répertoire
fnames = ['otherdogs{}.jpg'.format(i) for i in range(50, 60)]
for fname in fnames:
    src = os.path.join(original_otherdogs_dir, fname)
    dst = os.path.join(test_otherdogs_dir, fname)
    shutil.copyfile(src, dst)

#Vérifiez le nombre de fichiers stockés dans chaque dossier
print('total training mydog images:', len(os.listdir(train_mydog_dir)))
print('total training otherdogs images:', len(os.listdir(train_otherdogs_dir)))
print('total validation mydog images:', len(os.listdir(validation_mydog_dir)))
print('total validation otherdogs images:', len(os.listdir(validation_otherdogs_dir)))
print('total test mydog images:', len(os.listdir(test_mydog_dir)))
print('total test otherdogs images:', len(os.listdir(test_otherdogs_dir)))

Le nombre de fichiers s'affiche comme suit. files.png

Étape 4 Construction du modèle

(1) Importez des keras et construisez un modèle comme suit.

La taille de l'image d'entrée est de 320 * 320 dans le fichier d'origine, mais cette fois la taille de l'entrée est lue comme 150 * 150.


from keras import layers
from keras import models

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu',
                        input_shape=(150, 150, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

model.summary()

La configuration du modèle est affichée comme ceci. model_sum.png

(2) Définissez la fonction de perte (crossentropie binaire), l'optimiseur (RMS Prop) et l'indice de surveillance (précision) et compilez le modèle.


from keras import optimizers

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

(3) Convertissez le fichier image en un tenseur à l'aide de la bibliothèque keras ImageDataGenerator.

Aucune augmentation de données n'a été mise en œuvre cette fois.


from keras.preprocessing.image import ImageDataGenerator

# rescaled by 1./255
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
        # target directory
        train_dir,
        # resized to 150x150
        target_size=(150, 150),
        batch_size=20,
        class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
        validation_dir,
        target_size=(150, 150),
        batch_size=20,
        class_mode='binary')

Étape 5 Apprentissage

(1) Entraînez le modèle à l'aide du générateur de lots.

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

Lorsque l'apprentissage commence, l'affichage ressemblera à ceci et le calcul se poursuivra. (Cela prendra un moment) fit.png

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

model.save('mydog_or_otherdogs_01a.h5')

Résultat de l'étape 6

(1) Afficher le résultat d'apprentissage dans un graphique

import matplotlib.pyplot as plt

acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(len(acc))

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

plt.figure()

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

plt.show()

Graphique de résultat traial01.png

Tout d'abord, la précision

  • La précision de la formation a atteint 100% immédiatement depuis le début.
  • La précision de la validation est d'environ 70% à 85%, et la précision ne s'améliore plus. Vous pouvez voir les fonctionnalités telles que. Malheureusement, nous ne regardons que les caractéristiques qui ne sont valables que pour les données de train, et on ne peut pas dire que nous avons une caractéristique claire de notre chien qui est valable pour d'autres que les données de train.

D'autre part, à propos de la perte

  • La perte d'entraînement est proche de 0 depuis le début.
  • La perte de validation ne diminue pas à mesure que le nombre de fois augmente, mais augmente à la hausse.

De ce qui précède, nous surentraînons les données du train. Après tout, le nombre de données était à l'origine petit, il semble donc que le résultat soit inévitable.

(2) Application aux données de test

Appliquons ce modèle aux données de test avec le code suivant pour voir la précision de la classification. ** Note) ImageDataGenerator échouera sans conversion s'il n'y a pas deux sous-dossiers ou plus dans le dossier cible. ** (Dans ce cas, vous avez besoin de deux sous-dossiers, mydog et otherdogs) </ font>


test_datagen = ImageDataGenerator(rescale=1./255)
test_generator = test_datagen.flow_from_directory(
    test_dir,
    target_size=(150,150),
    batch_size=50,
    class_mode='binary')

test_loss, test_acc = model.evaluate_generator(test_generator, steps=50)
print('test loss:', test_loss)
print('test acc:', test_acc)

test loss: 2.7508722241719563 test acc: 0.7666666607062022

La précision de ce résultat de mise en œuvre est d'environ 76%. D'autres ajustements sont nécessaires.

Étape 7 Augmentation des données

Continuons à utiliser le modèle précédent, effectuons une augmentation des données sur les données du train et entraînons-le à nouveau. Le code de la partie complétée de ImageDataGenerator est ci-dessous.

#Données de train gonflées
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,)

#les données de validation ne sont pas complétées
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
        # Target directory
        train_dir,
        # resized to 150x150
        target_size=(150, 150),
        batch_size=32,
        class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
        validation_dir,
        target_size=(150, 150),
        batch_size=32,
        class_mode='binary')

Apprenez le modèle avec 100 époques.


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

Enregistrez le modèle entraîné.


model.save('mydog_or_otherdogs_01b.h5')

Le graphique résultant est présenté ci-dessous. traial02.png

Appliquons le modèle entraîné aux données de test et voyons la précision de la classification. test loss: 2.480180886810025 test acc: 0.7499999996026357 En général, il semble que le rembourrage améliore la précision, mais dans cet exemple, la précision a un peu baissé par rapport au précédent. Comme le nombre d'échantillons de données est à l'origine petit, je me demande si c'est le cas.

Étape 8 Autres réglages (changement de la taille d'entrée d'image, etc.)

Jusqu'à présent, la taille de l'image d'entrée a été définie sur 150 pixels x 150 pixels. Que faire si je change la taille de l'image d'entrée à la taille d'origine de 320 pixels x 320 pixels? En utilisant le modèle construit jusqu'à présent, entraînons le modèle de deux manières: ** ① sans Augmentation de données ** ** ② avec Augmentation de données **, et voyons les résultats de l'implémentation.

** * Ajouté 2020/1/4 Puisque la valeur numérique était incorrecte, la valeur numérique a été corrigée à la bonne et le commentaire a également été révisé. </ font> ** La précision de classification des données d'essai est la suivante. Résultat de ① test loss: 1.6523902654647826 ~~(1.7524430536416669)~~ test acc: 0.75 ~~(0.8166666567325592)~~

Résultat de ② test loss: 2.102495942115784 ~~(1.382319548305386)~~ test acc: 0.75 ~~(0.8666666634877522)~~

Par rapport à la taille d'entrée de 150 pixels, il n'y avait pas beaucoup de différence d'erreur et de précision à la taille d'entrée de 320 pixels. </ font>

La prochaine fois, j'aimerais analyser à nouveau lorsque j'augmente le nombre d'échantillons de données d'image.

Recommended Posts