Il s'agit d'un mémo d'étude (4e) sur la classification des images (environnement Google Colaboratory) à l'aide de TensorFlow2 + Keras. Le sujet est la classification des images numériques manuscrites (MNIST), qui est un élément standard.
Dernière fois a créé une image des données MNIST acquises (données de caractères manuscrites) à l'aide de matplotlib. Cette fois, nous allons essayer "** Prédiction **" en utilisant le modèle entraîné. Il génère également des images de rapport pour les prévisions telles que:
L'exemple de code pour "déplacement pour le moment" montré dans Partie 1 était comme suit.
python
import tensorflow as tf
# (1)Téléchargez le jeu de données d'images numériques manuscrites (MNIST) et stockez-le dans une variable
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# (2)Normalisation des données (prétraitement)
x_train, x_test = x_train / 255.0, x_test / 255.0
# (3)Construire un modèle NN
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])
# (4)Compilation du modèle (y compris les paramètres liés à la méthode d'apprentissage)
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
# (5)Formation de modèle (en utilisant les données d'entrée et les données de réponse correctes pour la formation)
model.fit(x_train, y_train, epochs=5)
# (6)Évaluation du modèle (à l'aide des données d'entrée de test et des données de réponse correctes)
model.evaluate(x_test, y_test, verbose=2)
Dans ce processus ** (6) ** model.evaluate (...)
, "** La prédiction (classification) utilisant le modèle entraîné **" est effectuée sur les données d'entrée x_test
pour les tests. Ensuite, les données de réponse correctes «y_test» ont été utilisées pour correspondre aux résultats de la prédiction, et le résultat de l'évaluation des performances du modèle tel que «perte: 0,0766 - précision: 0,9762» a été produit.
Cependant, avec ce model.evaluate (...)
, il n'est pas possible de confirmer spécifiquement "quel type de données d'entrée a été prévu (classé)?". Pour vérifier cela, utilisez les éléments suivants prédire_classes (...)
ou prédire (...)
.
Utilisez predict_classes (...)
pour obtenir les ** résultats de prédiction ** de toutes les données de texte manuscrites en utilisant le modèle entraîné.
A titre d'exemple, je voudrais obtenir la prédiction et le résultat pour les 5 premières feuilles de données d'entrée de test x_test [: 5]
. Il compare également les données de réponse correctes «y_test» avec la réponse.
python
# x_Prédiction de test (classification)
s = model.predict_classes( x_test[:5] )
print(s) #Résultat d'exécution-> [7 2 1 0 4]
# y_Faire correspondre les réponses en comparant avec le test
a = y_test[:5]
print(a) #Résultat d'exécution-> [7 2 1 0 4]
print(a==s) #Résultat d'exécution-> [True True True True True]
Si vous donnez un tableau de données d'entrée de type numpy.ndarray à l'argument de predict_classes (...)
, le résultat de la prédiction sera donné de type numpy.ndarray.
Pour prédire (classer) uniquement des données uniques (une image), procédez comme suit.
python
import numpy as np
target = x_test[0] #Préparer une seule donnée d'entrée
s = model.predict_classes( np.array([target]) )
#s = model.predict_classes( target.reshape([1,28,28]) ) #OK aussi ici
print(s[0]) #Résultat d'exécution-> 7
La valeur de retour de predict_classes (...)
nous a donné un résultat de prédiction (classification), mais vous voudrez peut-être en savoir plus **. En d'autres termes, dans l'exemple ci-dessus, les informations au stade précédant la conclusion de "7", par exemple, ne pouvaient pas être considérées comme ** "1"? ** ou ** "1". La possibilité était assez élevée, mais êtes-vous parvenu à la conclusion "7" par une petite marge? L'information est **.
Utilisez prédire (...)
pour obtenir ces informations. La valeur de retour est une information telle que le "degré de certitude" de quelle catégorie de 0 à 9 peut être classée (valeur dans la couche de sortie du modèle NN). La valeur varie de 0,0 à 1,0, et plus elle est proche de 1,0, plus la certitude de pouvoir être classée dans la catégorie est forte.
Je pense que c'est plus facile à comprendre si vous le regardez concrètement. Comme confirmé dans l'exemple précédent, "x_test [0]" a été prédit (classé) comme "7", qui est jugé à partir de la valeur de sortie de la couche de sortie comme suit.
import numpy as np
target = x_test[0]
s = model.predict( np.array([target]) )
print(s[0]) #Résultat d'exécution-> [2.8493771e-08 2.6985079e-08 8.6063519e-06 3.0076344e-04 1.7041087e-10
# 1.2664158e-07 1.4036484e-13 9.9965346e-01 4.4914569e-07 3.6610269e-05]
#Formaté pour afficher jusqu'à la deuxième fraction
s = [ f'{s:.2f}' for s in s[0]]
print(s) #Résultat d'exécution-> ['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '1.00', '0.00', '0.00']
Ceci est la sortie finale de print (s)
, mais à partir du 0, le 7 est "1,00". En d'autres termes, nous pouvons voir que le modèle NN a une forte confiance dans la classification prédictive de «7».
Cependant, dans cet exemple, ce n'est pas très intéressant, je vais donc essayer d'utiliser un caractère manuscrit légèrement subtil. x_test [1003]
est les données suivantes lors de la création d'image (cela peut être confirmé par y_test [1003]
, mais "5" est la bonne réponse).
Pour ce x_test [1003]
, si vous obtenez la valeur de retour depredire (...)
et que vous la vérifiez, ce sera comme suit.
python
import numpy as np
target = x_test[1003]
s = model.predict( np.array([target]) )
s = [ f'{s:.2f}' for s in s[0]] #Façonner
print(s)
#Résultat d'exécution-> ['0.00', '0.00', '0.00', '0.27', '0.00', '0.73', '0.00', '0.00', '0.01', '0.00']
Il s'avère que le modèle NN conclut avec la possibilité qu'il s'agisse d'un «3» plutôt que d'un «5» avec une forte conviction.
Notez que ʻargmax () dans
predict (...) correspond à
predict_classes (...) comme suit: ʻArgmax ()
renvoie le numéro d'index de l'élément avec la valeur la plus élevée dans le tableau.
python
import numpy as np
target = x_test[1003]
s = model.predict( np.array([target]) )
p = model.predict_classes( np.array([target]) )
print( s.argmax() == p[0] ) #Résultat d'exécution-> True
Nous utiliserons matplotlib pour créer le rapport suivant qui combine les données d'entrée (c'est-à-dire l'image numérique manuscrite) et le graphique de sortie prévu du modèle entraîné.
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
idn = 1601 #Index des données de test cible (0 à 9999)
s_test = model.predict(x_test) #Prédire à l'aide d'un modèle entraîné
fig, ax = plt.subplots(nrows=2,figsize=(3,4.2), dpi=120,
gridspec_kw={'height_ratios': [3, 1]})
plt.subplots_adjust(hspace=0.05) #Espacement entre les graphiques du haut et du bas
#Afficher l'image des nombres manuscrits sur la face supérieure
ax[0].imshow(x_test[idn],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évue sont affichées en haut à gauche
t = ax[0].text(0.5, 0.5, f'Bonne réponse:{y_test[idn]}',
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_test[idn].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_test[idn],width=0.95)
b[s_test[idn].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_test[idn].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')
――La prochaine fois, comme indiqué ci-dessous, quel type de nombres manuscrits ne permet pas de prédire (classer), et quel type d'erreur de classification existe («7» et «1» sont faux) Est-ce facile?) J'aimerais voir. matplotlib fonctionne bien.
■ Cas où la valeur de réponse correcte «6» n'a pas pu être prédite (classée) correctement