[PYTHON] Défiez la classification des images par TensorFlow2 + Keras 6-Essayez le prétraitement et la classification des images préparées par vous-même-

introduction

Il s'agit d'un mémo d'étude (6ème) sur la classification d'images (environnement Google Colaboratory) utilisant TensorFlow2 + Keras. Le sujet est la classification des images numériques manuscrites (MNIST), qui est un élément standard.

Dernière fois a fait une prédiction (classification) en utilisant l'image numérique manuscrite préparée à l'avance par le MNIST. Cette fois, j'aimerais utiliser ** une image que je me suis préparée ** pour classer les modèles comme entraînés. En outre, je voudrais expliquer le programme Python (en utilisant la bibliothèque Pillow) lié au ** prétraitement tel que le redimensionnement et le rognage ** requis à ce moment-là.

予測.png

前後.png

Création d'images numériques manuscrites

J'ai créé un caractère manuscrit de "** 8 **" avec une taille de ** 100 ** $ \ fois $ ** 100 ** pixel en peignant et l'ai enregistré en tant que fichier PNG de couleur (RVB). Je l'ai nommé test-8.png.

test-8.png

プロパティ.png

Téléchargez des fichiers image sur Google Colab.

Vous pouvez importer en activant l'onglet Fichier dans Google Colab. Menu latéral et glisser-déposer depuis votre bureau comme suit: Le fichier téléchargé sera supprimé ** après une certaine période de temps **.

ファイルアップロード.png

Vous pouvez également télécharger à l'aide de la boîte de dialogue de sélection de fichier en écrivant une cellule de code et en l'exécutant comme suit.

ファイルアップロード2.png

Le chemin absolu du fichier téléchargé (test-8.png) sera / content / test-8.png. De plus, puisque le répertoire courant est / content, vous pouvez y accéder avec juste test-8.png.

Vous pouvez également monter Google Drive et le rechercher. Pour plus d'informations, consultez Google Colaboratory (de la première utilisation au chargement des fichiers) @ Qiita.

Lire le fichier image et vérifier le contenu

Chargez le fichier image téléchargé et affichez-le pour en vérifier le contenu. Les images sont gérées à l'aide de Pillow (PIL Fork). Seulement 3 lignes.

python


import PIL.Image as Image
img = Image.open('test-8.png')
display(img)

Convertir en un format pouvant être entré dans le modèle entraîné

Le ** prétraitement ** suivant est requis pour remplir le modèle formé.

  1. Créez une image en échelle de gris.
  2. Redimensionnez à 28 $ \ fois 28 $ pixel.
  3. Créez un tableau à deux dimensions de type numpy.ndarray.
  4. Faites du blanc "0.0" et du noir "1.0".

Vous pouvez effectuer le prétraitement ci-dessus avec le code suivant. Il convient de noter qu'une image normale à 256 niveaux de gris ** blanc est "255" et le noir est "0" **, il doit donc être inversé.

python


import numpy as np
import PIL.Image as Image
import matplotlib.pyplot as plt

img = Image.open('test-8.png')

img = img.convert('L')             # 1.Convertir en échelle de gris
img = img.resize((28,28))          # 2.Redimensionné à 28x28
x_sample = np.array(img)           # 3. numpy.Convertir en type ndarray
x_sample = 1.0 - x_sample / 255.0  # 4.Inversion / normalisation
y_sample = 8  #Corriger les données de réponse

#Sortie de confirmation
print(f'x_sample.type = {type(x_sample)}')
print(f'x_sample.shape = {x_sample.shape}')
plt.figure()
plt.imshow(x_sample,vmin=0.,vmax=1.,cmap='Greys')
plt.show()

Le résultat de l'exécution est le suivant. test-8_.png

Pour cet x_sample, faites une prédiction avec un modèle entraîné et créez un rapport de résultat de prédiction avec le programme montré dans 4th. Ce sera comme suit.

test-8_p.png

J'ai pu faire un bon pronostic (classement).

Repost: programme de création de rapport de résultats de prédiction

Fondamentalement, c'est le même que le programme montré dans 4th, mais x_sample est la seule donnée d'entrée, y_sample est la bonne réponse, Je réécris l'hypothèse que le modèle entraîné est stocké dans model.

matplotlib_Processus de préparation de la sortie japonaise


!pip install japanize-matplotlib
import japanize_matplotlib

python


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patheffects as pe 
import matplotlib.transforms as ts 

s_sample = model.predict(np.array([x_sample]))[0] #Prédiction (classification)

fig, ax = plt.subplots(nrows=2,figsize=(3,4.2), dpi=120, 
                       gridspec_kw={'height_ratios': [3, 1]})

plt.subplots_adjust(hspace=0.05)

#Afficher l'image des nombres manuscrits sur la face supérieure
ax[0].imshow(x_sample,interpolation='nearest',vmin=0.,vmax=1.,cmap='Greys')
ax[0].tick_params(axis='both', which='both', left=False, 
                  labelleft=False, bottom=False, labelbottom=False)

#La valeur de réponse correcte et la valeur prédite sont affichées en haut à gauche
t = ax[0].text(0.5, 0.5, f'Bonne réponse:{y_sample}',
               verticalalignment='top', fontsize=9, color='tab:red')
t.set_path_effects([pe.Stroke(linewidth=2, foreground='white'), pe.Normal()])
t = ax[0].text(0.5, 2.5, f'Prédiction:{s_sample.argmax()}', 
               verticalalignment='top', fontsize=9, color='tab:red')
t.set_path_effects([pe.Stroke(linewidth=2, foreground='white'), pe.Normal()])

#Afficher la sortie de prédiction NN en bas
b = ax[1].bar(np.arange(0,10),s_sample,width=0.95)
b[s_sample.argmax()].set_facecolor('tab:red') #Rendre l'élément maximum rouge

#Réglage de l'axe X
ax[1].tick_params(axis='x',bottom=False)
ax[1].set_xticks(np.arange(0,10))
t = ax[1].set_xticklabels(np.arange(0,10),fontsize=11)
t[s_sample.argmax()].set_color('tab:red') #Rendre l'élément maximum rouge

offset = ts.ScaledTranslation(0, 0.03, plt.gcf().dpi_scale_trans)
for label in ax[1].xaxis.get_majorticklabels() :
    label.set_transform(label.get_transform() + offset)

#Réglage de l'axe Y
ax[1].tick_params(axis='y',direction='in')
ax[1].set_ylim(0,1)
ax[1].set_yticks(np.linspace(0,1,5))
ax[1].set_axisbelow(True)
ax[1].grid(axis='y')

Prétraitement: Lorsqu'il n'y a pas de numéro au centre de l'image, cela correspond à la présence de saleté

Si vous préparez vous-même une image de nombres manuscrits, il y a des cas où ** le numéro ne se trouve pas au centre de l'image ** comme indiqué ci-dessous. test-2b.png

Si vous appliquez la prédiction (classification) à une image telle qu'elle est, vous obtiendrez ** des résultats terribles ** comme suit. test-2_p.png

Pour cette raison, avant de faire une prédiction, il est nécessaire de déplacer la partie caractère vers le centre et d'effectuer un prétraitement de telle sorte que la partie caractère net représente environ 90% de la taille de la figure. il y a. De plus, il est nécessaire d'éliminer les ** saletés ** et ** poussières ** autres que les caractères.

Ici, je voudrais faire le prétraitement (automatisé) suivant. フロー.png

Prétraitement


import numpy as np
from PIL import Image, ImageChops,ImageFilter, ImageOps, ImageDraw
import matplotlib.pyplot as plt

#Ajouter des marges (blanches) de la largeur spécifiée en haut, en bas, à gauche et à droite de la figure
def add_margin(img, margin):
    w, h = img.size
    w2 = w + 2 * margin
    h2 = h + 2 * margin
    result = Image.new('L', (w2, h2), 255)
    result.paste(img, (margin, margin))
    return result

#La taille qui correspond au côté long du rectangle donné par l'argument
#Calculer un carré (mais un peu plus grand) carré
def to_square( rect ):
  x1, y1, x2, y2 = rect   # (x1,y1)Est le coin supérieur gauche, (x2,y2)Est la coordonnée inférieure droite
  s = max( x2-x1, y2-y1 ) #Obtenez la longueur du côté long
  s = int(s*1.3)          #Un peu plus grand
  nx1 = (x1+x2)/2 - s/2
  nx2 = (x1+x2)/2 + s/2
  ny1 = (y1+y2)/2 - s/2
  ny2 = (y1+y2)/2 + s/2
  return (nx1,ny1,nx2,ny2)

img = Image.open('test-2x.png')

img  = img.convert('L')
#display(img)

#Ajoutez des marges blanches en haut, en bas, à gauche et à droite de l'image
img  = add_margin(img,int(max(img.size)*0.2))
#display(img)

#Créer une image inversée
img2 = ImageOps.invert(img)

#Brouiller
img2 = img2.filter(ImageFilter.GaussianBlur(1.5))
#display(img2)

#Binarisation
img2 = img2.point(lambda p: p > 150 and 255)  
#display(img2)

#Obtenez la plus petite zone (rectangulaire) autre que le noir
rect = img2.getbbox() 
# tmp = img2.convert('RGB')
# ImageDraw.Draw(tmp).rectangle(rect, fill=None, outline='red')
# display(tmp)

#Convertir un rectangle en carré qui s'adapte au côté long
sqr = to_square(rect)
# tmp = img2.convert('RGB')
# ImageDraw.Draw(tmp).rectangle(sqr, fill=None, outline='red')
# display(tmp)

#Paré d'un carré
img = img.crop(sqr)
#display(img)

#Après ça, comme avant
img = img.convert('L')             # 1.Convertir en échelle de gris
img = img.resize((28,28))          # 2.Redimensionné à 28x28
x_sample = np.array(img)           # 3. numpy.Convertir en type ndarray
x_sample = 1.0 - x_sample / 255.0  # 4.Inversion / normalisation
y_sample = 2  #Corriger les données de réponse

#Sortie de confirmation
print(f'x_sample.type = {type(x_sample)}')
print(f'x_sample.shape = {x_sample.shape}')
plt.figure()
plt.imshow(x_sample,vmin=0.,vmax=1.,cmap='Greys')
plt.show()

Il s'agit d'une comparaison des résultats de la ** classification prédictive sans prétraitement et de la ** classification prédictive après prétraitement. Je me rends compte une fois de plus que le prétraitement est important avant d'essayer et de se tromper sur le modèle de prédiction.

前後.png

la prochaine fois

――Depuis que le fossé extérieur est comblé, je voudrais enfin étudier la ** construction du modèle ** du réseau neuronal.

Recommended Posts

Défiez la classification des images par TensorFlow2 + Keras 6-Essayez le prétraitement et la classification des images préparées par vous-même-
Défi la classification des images par TensorFlow2 + Keras 4 ~ Prédisons avec un modèle entraîné ~
Défiez la classification des images avec TensorFlow2 + Keras 9-Apprentissage, sauvegarde et chargement de modèles-
Défiez la classification des images par TensorFlow2 + Keras 5 ~ Observez les images dont la classification échoue ~
Challenge classification des images par TensorFlow2 + Keras 7-Compréhension des types de couches et des fonctions d'activation-
Challenge classification des images par TensorFlow2 + Keras 3 ~ Visualiser les données MNIST ~
Classification d'images avec un réseau de neurones auto-fabriqué par Keras et PyTorch
Challenge classification des images par TensorFlow2 + Keras 1-Move pour le moment-
Challenge classification des images par TensorFlow2 + Keras 2 ~ Regardons de plus près les données d'entrée ~
Classification d'image avec Keras - Du prétraitement au test de classification -
Comparez le TensorFlow brut avec tf.contrib.learn et Keras
Classification des textes du défi par Naive Bayes avec sklearn
Juge Yosakoi Naruko par classification d'image de Tensorflow.
Analyse d'images par apprentissage profond à partir de Kaggle et Keras
Identifiez le nom de l'image de la fleur avec des keras (flux tenseur)
J'ai essayé d'implémenter Grad-CAM avec keras et tensorflow
Découvrez Wasserstein GAN avec le modèle Keras et l'optimisation TensorFlow