[PYTHON] Premier classificateur d'images

Bonjour. Dans mon travail, je suis loin de l'ingénierie et je n'ai pas grand-chose à écrire sur ce que j'ai fait. Maintenant que j'ai un peu de temps, je voudrais résumer un peu ce que j'ai appris. Calendrier de l'Avent Je n'ai pas peur! Vous pouvez écrire un article que vous venez de faire un tutoriel! C'est un ...

Lecteur supposé

J'ai beaucoup entendu parler de l'apprentissage automatique, mais je n'ai pas beaucoup parlé de la mise en œuvre, alors j'y reviendrai. Les lecteurs visés sont donc ceux qui n'ont jamais touché à l'apprentissage automatique mais qui sont intéressés et aimeraient jeter un coup d'œil à la mise en œuvre de l'apprentissage automatique. Les personnes expérimentées ont les yeux chaleureux, et il serait utile que vous puissiez signaler les erreurs: smile_cat:

thème

Si vous n'avez pas de thème facile à suivre, vous ne saurez pas quel objectif vous devriez viser et vous vous perdrez. Alors cette fois, quand je donne une image, je classe ce qu'il y a dans l'image, Faisons un classificateur d'images.

Tout va bien, mais décidons d'abord quel type de classificateur utiliser. J'ai été accro au curry ces derniers temps, alors je vais essayer de faire un classificateur d'images d'épices.

IMG_2034.jpg

Notre blog Merci pour votre coopération.

Connaissances préalables

Étant donné que le classificateur d'images est un thème accrocheur, il existe de nombreux articles de didacticiel, mais plutôt que de commencer à lire sans aucune connaissance préalable, il est recommandé de saisir le tout avec les articles suivants.

Introduction aux réseaux de neurones à partir de zéro qui ne nécessite pas de connaissances mathématiques [Comprendre les «bases des réseaux de neurones» - Introduction à l'apprentissage profond | Partie 1](https://www.imagazine.co.jp/%E3%83%8B%E3%83%A5%E3%83 % BC% E3% 83% A9% E3% 83% AB% E3% 83% 8D% E3% 83% 83% E3% 83% 88% E3% 83% AF% E3% 83% BC% E3% 82% AF % E3% 82% 92% E7% 90% 86% E8% A7% A3% E3% 81% 99% E3% 82% 8B% E3% 80% 80% EF% BD% 9E% E3% 83% 87% E3 % 82% A3% E3% 83% BC% E3% 83% 97 /)

Veuillez également vous référer au lien de référence pour les mots qui ressemblent à des termes techniques.

Faites un tutoriel

tensorflow (Tensorflow * 1) Nous allons faire un tutoriel sur l'apprentissage par transfert (* 2). Transfert d'apprentissage avec TensorFlow Hub.

Je l'ai écrit selon l'élément de la version de 2019/12, mais s'il y a un changement, j'espère que vous pourrez le lire de manière agréable. Le code de chaque section a été réimprimé, mais les résultats ne sont pas inclus sauf pour certains, veuillez donc le lire en l'exécutant vous-même.

(* 1) tensorflow est l'une des bibliothèques d'apprentissage automatique, créée par google. wiki (* 2) Il s'agit d'une méthode pour détourner un modèle appris dans une tâche différente du transfert d'apprentissage vers une autre tâche. Dans ce cas, la précision ne s'améliorera que si une assez grande quantité de données est préparée. Il semble que cela puisse être résolu avec un nombre assez restreint de feuilles. Si vous maîtrisez un langage de programmation, la deuxième maîtrise sera plus rapide. Référence

Setup En principe, ce tutoriel utilise Google Colaboratory (ci-après dénommé Colab * 3), nous allons donc cliquer sur "Exécuter dans Google Colab" en haut pour l'activer. Lorsque l'écran Colab s'ouvre, exécutons-le dans l'ordre du haut. Placez le curseur autour de [] dans le coin supérieur gauche du code et vous devriez voir le bouton d'exécution.

from __future__ import absolute_import, division, print_function, unicode_literals

import matplotlib.pylab as plt

import tensorflow as tf

Vous importez diverses bibliothèques ici. La description de «future ..» sert à maintenir la compatibilité de python2-3. ʻImport matplotlib.pylab as plt` est une bibliothèque pour les tracés pour une utilisation ultérieure.

!pip install -q -U tf-hub-nightly
import tensorflow_hub as hub

from tensorflow.keras import layers

La description de ! Pip install -q -U tf-hub-nightly est l'installation de la bibliothèque python. tensorflow_hub est une bibliothèque permettant d'utiliser une plateforme (tensorflow hub) qui peut facilement utiliser des modèles pré-entraînés. tensorflow.keras est une bibliothèque d'apprentissage automatique qui semble avoir été créée par un ingénieur Google mais qui peut être utilisée par n'importe qui d'autre que tensorflow.

C'est incroyable de voir à quel point il est facile de s'exécuter sur une machine virtuelle simplement en l'écrivant sous forme de texte.

(* 3) Colaboratory est un environnement de notebook Jupyter qui s'exécute entièrement dans le cloud. Aucun paramètre n'est requis et vous pouvez l'utiliser gratuitement. Avec Colaboratory, vous pouvez écrire et exécuter du code, stocker et partager des analyses, accéder à de puissantes ressources informatiques, etc., le tout gratuitement depuis votre navigateur. De Welcome to Colaboratory

image.png Au fait, si vous obtenez une telle erreur, vous devez suivre le support et appuyer sur le bouton [RESTART RUNTIME] puis sur le gros bouton de lecture.

curry_ko.png

An ImageNet classifier C'est un élément pour essayer la classification d'image en utilisant le modèle entraîné.

Download the classifier

classifier_url ="https://tfhub.dev/google/tf2-preview/mobilenet_v2/classification/2" #@param {type:"string"}

L'URL du classificateur entraîné. Comme je l'ai écrit dans le tutoriel, peu importe que ce soit celui placé ici.

IMAGE_SHAPE = (224, 224)

classifier = tf.keras.Sequential([
    hub.KerasLayer(classifier_url, input_shape=IMAGE_SHAPE+(3,))
])

Poke le modèle entraîné comme une couche du réseau neuronal. Il semble qu'il soit nécessaire de dire le format de l'image donnée, alors donnez-le par (largeur, hauteur, canal). Le canal (nombre de couleurs) 3 sera ajouté plus tard. Cela a-t-il une signification profonde?

Run it on a single image Lorsque vous êtes prêt, faisons une distinction avec une image appropriée.

import numpy as np
import PIL.Image as Image

grace_hopper = tf.keras.utils.get_file('image.jpg','https://storage.googleapis.com/download.tensorflow.org/example_images/grace_hopper.jpg')
grace_hopper = Image.open(grace_hopper).resize(IMAGE_SHAPE)
grace_hopper

[grace_hopper](https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B9%E3%83%BB%E3% 83% 9B% E3% 83% 83% E3% 83% 91% E3% 83% BC) est en cours d'acquisition.

grace_hopper = np.array(grace_hopper)/255.0
grace_hopper.shape

Il semble que vous effectuez une conversion de type.

result = classifier.predict(grace_hopper[np.newaxis, ...])
result.shape

Si vous ajoutez une dimension aux données d'image et exécutez la prédiction, vous obtiendrez un tableau de vecteurs de 1001 éléments (pour être exact, ndarray).

predicted_class = np.argmax(result[0], axis=-1)
predicted_class

Cet élément 1001 représente la probabilité de chaque classe (dans ce cas, l'élément inféré), supprimons donc celui avec la probabilité maximale. La valeur 653 est renvoyée. Cela représente ce que ce classificateur a déduit.

Decodethe predictions

labels_path = tf.keras.utils.get_file('ImageNetLabels.txt','https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt')
imagenet_labels = np.array(open(labels_path).read().splitlines())

Téléchargez les étiquettes et mettez-les dans un tableau pour découvrir ce que montrent les résultats précédents. Comme vous pouvez le voir immédiatement en accédant directement à l'URL, cela correspond à l'élément 1001 mentionné précédemment.

plt.imshow(grace_hopper)
plt.axis('off')
predicted_class_name = imagenet_labels[predicted_class]
_ = plt.title("Prediction: " + predicted_class_name.title())

output_uzziRK3Z2VQo_0.png

Utilisez la bibliothèque d'affichage d'images pour afficher ce qu'était la 653e image. Le résultat est un uniforme militaire. Toutes nos félicitations.

nut_hakkaku.png

Simple transfer learning De là, c'est la production. L'actuel était "Vous pouvez utiliser un classificateur entraîné comme celui-ci", Vient ensuite "Je vais créer un classificateur avec les images que j'ai collectées".

Dataset Dans ce tutoriel, nous utiliserons une image de fleur. Enfin, permutons cet ensemble de données de manière appropriée pour en faire un classificateur différent.

data_root = tf.keras.utils.get_file(
  'flower_photos','https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz',
   untar=True)

Téléchargement de l'ensemble de données

image_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1/255)
image_data = image_generator.flow_from_directory(str(data_root), target_size=IMAGE_SHAPE)

Plongez dans ImageDataGenarator pour bien gérer les images. En passant, vous pouvez voir la classification des images en téléchargeant le groupe d'images à partir de l'URL ci-dessus, C'est comme collecter des images spécifiques pour chaque répertoire.

for image_batch, label_batch in image_data:
  print("Image batch shape: ", image_batch.shape)
  print("Label batch shape: ", label_batch.shape)
  break

Itérez image_data pour créer un tableau de image_batch et label_batch.

Run the classifier on a batch of images Afin de le comparer à l'état après apprentissage, classons-le dans l'état non appris.

result_batch = classifier.predict(image_batch)
result_batch.shape

Faisons la même prédiction qu'avant.

predicted_class_names = imagenet_labels[np.argmax(result_batch, axis=-1)]
predicted_class_names

Il y a 32 résultats de classification. Vérifiez-le par rapport à l'image.

plt.figure(figsize=(10,9))
plt.subplots_adjust(hspace=0.5)
for n in range(30):
  plt.subplot(6,5,n+1)
  plt.imshow(image_batch[n])
  plt.title(predicted_class_names[n])
  plt.axis('off')
_ = plt.suptitle("ImageNet predictions")

output_IXTB22SpxDLP_0.png

En regardant les résultats, c'est assez différent. C'est peut-être parce qu'ils sont sélectionnés parmi 1001 objets, mais ils ne sont pas du tout corrects.

Download the headless model Alors faisons notre propre classificateur.


feature_extractor_url = "https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/2" #@param {type:"string"}

Comme d'habitude, nous téléchargerons le modèle entraîné depuis le hub tensorflow. L'extracteur ressemble à un extracteur.


feature_extractor_layer = hub.KerasLayer(feature_extractor_url,
                                         input_shape=(224,224,3))

Créez un calque pour plonger dans le modèle.


feature_batch = feature_extractor_layer(image_batch)
print(feature_batch.shape)

Ce type renverra 1280 vecteurs pour chaque image. Vous essayez de classer les images à partir de divers éléments.


feature_extractor_layer.trainable = False

Cette fois, la partie extracteur ne sera pas réglée, alors spécifiez-la pour qu'elle ne soit pas apprise.

Attach a classification head


model = tf.keras.Sequential([
  feature_extractor_layer,
  layers.Dense(image_data.num_classes, activation='softmax')
])

model.summary()

Je pousse l'instance d'extraction que je viens de créer dans le classificateur. Vous affichez également un résumé du modèle que vous avez créé.


predictions = model(image_batch)
predictions.shape

Je vérifie la forme du tenseur.

Train the model


model.compile(
  optimizer=tf.keras.optimizers.Adam(),
  loss='categorical_crossentropy',
  metrics=['acc'])

Compilez le modèle. optimiseur: Il semble qu'il existe différents types. Référence perte (fonction de perte): une fonction utilisée pour la formation pour ajuster la perte pour qu'elle soit aussi petite que possible. Cela semble être différent. Référence métriques (fonction d'évaluation): valeur utilisée pour évaluer les performances d'un modèle, mais non utilisée pour l'entraînement comme une fonction de perte. Cela semble également être différent. Référence

class CollectBatchStats(tf.keras.callbacks.Callback):
  def __init__(self):
    self.batch_losses = []
    self.batch_acc = []

  def on_train_batch_end(self, batch, logs=None):
    self.batch_losses.append(logs['loss'])
    self.batch_acc.append(logs['acc'])
    self.model.reset_metrics()

Il s'agit d'une définition de fonction permettant d'observer quelles sont les valeurs de la fonction de perte et de la fonction d'évaluation.

steps_per_epoch = np.ceil(image_data.samples/image_data.batch_size)

batch_stats_callback = CollectBatchStats()

history = model.fit_generator(image_data, epochs=2,
                              steps_per_epoch=steps_per_epoch,
                              callbacks = [batch_stats_callback])

Commencez à apprendre avec fit_generator. Vous spécifiez le nombre d'apprentissage et ainsi de suite. Référence L'apprentissage prendra du temps.

plt.figure()
plt.ylabel("Loss")
plt.xlabel("Training Steps")
plt.ylim([0,2])
plt.plot(batch_stats_callback.batch_losses)

output_A5RfS1QIIP-P_1.png

C'est la transition de la fonction de perte. C'est bien qu'il diminue progressivement.

plt.figure()
plt.ylabel("Accuracy")
plt.xlabel("Training Steps")
plt.ylim([0,1])
plt.plot(batch_stats_callback.batch_acc)

output_3uvX11avTiDg_1.png

C'est la transition de la fonction d'évaluation. C'est en place donc ça fait du bien.

Check the predictions Classifions enfin.

class_names = sorted(image_data.class_indices.items(), key=lambda pair:pair[1])
class_names = np.array([key.title() for key, value in class_names])
class_names

Prenons une classe qui existe réellement. Il n'y a que 5 types.

predicted_batch = model.predict(image_batch)
predicted_id = np.argmax(predicted_batch, axis=-1)
predicted_label_batch = class_names[predicted_id]

Prédisez comme vous l'avez fait précédemment, récupérez la valeur maximale et étiquetez-la.

label_id = np.argmax(label_batch, axis=-1)

Réservez l'étiquette correcte

plt.figure(figsize=(10,9))
plt.subplots_adjust(hspace=0.5)
for n in range(30):
  plt.subplot(6,5,n+1)
  plt.imshow(image_batch[n])
  color = "green" if predicted_id[n] == label_id[n] else "red"
  plt.title(predicted_label_batch[n].title(), color=color)
  plt.axis('off')
_ = plt.suptitle("Model predictions (green: correct, red: incorrect)")

output_wC_AYRJU9NQe_0.png

Si la réponse est correcte, elle sera affichée en vert, et si elle échoue, elle sera sortie en rouge. Je pense que vous avez généralement raison. Yosage.

Après cela, le tutoriel continue pendant un moment, et l'exportation du modèle appris est écrite, mais comme c'est la fin de l'utilisation, je l'omettrai à partir de maintenant.

cooking_cumin_seed.png

Construisez votre propre classificateur

Maintenant, créons votre propre classificateur en utilisant le code qui est sorti dans le didacticiel. Cette fois, je vais fixer un objectif jusqu'à ce qu'il bouge sur Colab.

Collection d'images

La collecte d'images est essentielle pour la classification des images.

Télécharger l'image

google-images-download est utile. (Faites attention à la licence de l'image téléchargée)

Il peut être installé via pip, donc si vous utilisez mac, vous pouvez l'utiliser comme suit.

pip install google_images_download
googleimagesdownload --keywords "L'image que vous voulez trouver"

Tri des images

Si vous essayez d'utiliser l'image téléchargée telle quelle, il y a beaucoup de déchets et vous ne pouvez pas l'utiliser. Alors, supprimons les images étranges tout en regardant les images une par une. Ce travail a été le plus dur.

image.png En fin de compte, créons un état où des images propres spécifiques sont rassemblées pour chaque répertoire comme celui-ci.

Package et télécharger

Pour le moment, nous allons télécharger le fichier compressé tar quelque part afin qu'il puisse être téléchargé depuis Colab. Je l'ai téléchargé sur Google Drive. Dans le cas de GoogleDrive, téléchargez tar.gz, obtenez un lien partageable et remplacez la partie ID par le lien ci-dessous. https://drive.google.com/uc?export=download&id=XXXXXXXXXXXXXXXXXXXXX

Reflété dans le code Colab

J'ai préparé un fichier Colab qui extrait uniquement la partie qui fait le trieur ici, veuillez donc remplacer la partie xxxx. Open In Colab

Cela a-t-il fonctionné?

Cela ressemble à ça dans ma main. image (85).png

spice_clove.png

en conclusion

J'ai pu expérimenter le côté supérieur de l'apprentissage automatique, mais j'ai le sentiment que l'image du classificateur veut que les photos prises par moi-même soient classées. Je veux créer quelque chose qui semble un peu plus décontracté en créant un environnement à portée de main. Je vais m'accrocher.

Recommended Posts

Premier classificateur d'images
Premier traitement d'image Python
Premier flacon
Suppression du bruit de l'image
Premier examen de python-
Premier gdb
Reconnaissance d'image
Explorateur d'images