――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.
――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!)
――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.
-: 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.
-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.
** É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.) **
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 **).
--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).
――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) **
** Photos d'autres chiens Shiba (autres chiens) **
À partir de là, lancez Google Colaboratory et opérez sur Colab.
Pour les nouveaux utilisateurs, veuillez vous référer à ** ici **.
#Monture Google Drive
from google.colab import drive
drive.mount('/content/drive')
# 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 "!". Un message comme celui-ci apparaîtra et le fichier sera décompressé.
#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)
#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.
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.
from keras import optimizers
model.compile(loss='binary_crossentropy',
optimizer=optimizers.RMSprop(lr=1e-4),
metrics=['acc'])
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')
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)
model.save('mydog_or_otherdogs_01a.h5')
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
Tout d'abord, la précision
D'autre part, à propos de la perte
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.
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.
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.
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.
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