[PYTHON] [Classification des images] Analyse faciale du chien

1.Tout d'abord

J'ai essayé de m'intéresser à l'analyse faciale des animaux.

2. Références

"Créez un modèle d'apprentissage automatique qui distingue les" chiens qui rient "et les" chiens en colère "à Keras." https://qiita.com/ariera/items/545d48c961170a784075

3. Contenu

3-1. Prétraitement des données

#Définir une fonction pour lire une image et la convertir en matrice
from keras.preprocessing.image import load_img, img_to_array
def img_to_traindata(file, img_rows, img_cols, rgb):
    if rgb == 0:
        img = load_img(file, color_mode = "grayscale", target_size=(img_rows,img_cols)) #Lire avec des niveaux de gris
    else:
        img = load_img(file, color_mode = "rgb", target_size=(img_rows,img_cols)) #Lire en RVB
    x = img_to_array(img)
    x = x.astype('float32')
    x /= 255
    return x

#Données d'entraînement, génération de données de test
import glob, os

img_rows = 224 #La taille de l'image est la taille par défaut de VGG16
img_cols = 224
nb_classes = 2 #2 classes de colère et de rire
img_dirs = ["./dog_angry", "./dog_smile"] #Répertoire contenant des images de chiens en colère et de chiens rieurs

X_train = []
Y_train = []
X_test = []
Y_test = []
for n, img_dir in enumerate(img_dirs):
    img_files = glob.glob(img_dir+"/*.jpg ")   #Lire tous les fichiers image dans le répertoire
    for i, img_file in enumerate(img_files):  #annuaire(Type de caractère)Pour tous les fichiers dans
        x = img_to_traindata(img_file, img_rows, img_cols, 1) #Lisez chaque fichier image en RVB et convertissez-le en matrice
        if i < 8: #Apprentissage des données de la 1ère à la 8ème feuille
            X_train.append(x) #Données d'entraînement(contribution)Ajoutez une matrice qui convertit les images en
            Y_train.append(n) #Données d'entraînement(production)Classer(Fâché=0, lol=1)Ajouter
        else:       #Données de test pour la 9e feuille et les suivantes
            X_test.append(x) #données de test(contribution)Ajoutez une matrice qui convertit les images en
            Y_test.append(n) #données de test(production)Classer(Fâché=0, lol=1)Ajouter

import numpy as np
#Formation et test des données de liste à numpy.Convertir en ndarray
X_train = np.array(X_train, dtype='float') 
Y_train = np.array(Y_train, dtype='int')
X_test = np.array(X_test, dtype='float')
Y_test = np.array(Y_test, dtype='int')

#Données catégoriques(vecteur)Conversion en
from keras.utils import np_utils
Y_train = np_utils.to_categorical(Y_train, nb_classes)
Y_test = np_utils.to_categorical(Y_test, nb_classes)

#Enregistrez les données d'entraînement et les données de test créées dans un fichier
np.save('models/X_train_2class_120.npy', X_train)
np.save('models/X_test_2class_120.npy', X_test)
np.save('models/Y_train_2class_120.npy', Y_train)
np.save('models/Y_test_2class_120.npy', Y_test)

#Afficher le type de données créées
print(X_train.shape)
print(Y_train.shape)
print(X_test.shape)


from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D

#【Réglages des paramètres】
batch_size = 20
epochs = 30

input_shape = (img_rows, img_cols, 3)
nb_filters = 32
# size of pooling area for max pooling
pool_size = (2, 2)
# convolution kernel size
kernel_size = (3, 3)

#[Définition du modèle]
model = Sequential()
model.add(Conv2D(nb_filters, kernel_size, #Couche pliante
                        padding='valid',
                        activation='relu',
                        input_shape=input_shape))
model.add(Conv2D(nb_filters, kernel_size, activation='relu')) #Couche pliante
model.add(MaxPooling2D(pool_size=pool_size)) #Couche de regroupement
model.add(Conv2D(nb_filters, kernel_size, activation='relu')) #Couche pliante
model.add(MaxPooling2D(pool_size=pool_size)) #Couche de regroupement
model.add(Dropout(0.25)) #Abandonner(Déconnectez au hasard entre l'entrée et la sortie pour éviter le surapprentissage)

model.add(Flatten()) #Convertir un tableau multidimensionnel en tableau unidimensionnel
model.add(Dense(128, activation='relu'))  #Couche entièrement connectée
model.add(Dropout(0.2))  #Abandonner
model.add(Dense(nb_classes, activation='sigmoid'))  #Puisqu'il s'agit de 2 classes, la couche entièrement connectée est sigmoïde

#Compiler le modèle
model.compile(loss='binary_crossentropy', #Binaire car c'est 2 classes_crossentropy
              optimizer='adam', #Utiliser les valeurs par défaut pour les paramètres de la fonction d'optimisation
              metrics=['accuracy'])

#Définissez un rappel pour générer des résultats d'apprentissage pour chaque époque(Enregistrez uniquement lorsque la précision est meilleure que la dernière fois)】
from keras.callbacks import ModelCheckpoint
import os
model_checkpoint = ModelCheckpoint(
    filepath=os.path.join('models','model_2class120_{epoch:02d}.h5'),
    monitor='val_accuracy',
    mode='max',
    save_best_only=True,
    verbose=1)
print("filepath",os.path.join('models','model_.h5'))

#[Apprentissage]
result = model.fit(X_train, Y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(X_test, Y_test),
                   callbacks=[model_checkpoint],validation_split=0.1)

3-2. Apprentissage

from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D

#【Réglages des paramètres】
batch_size = 20
epochs = 30

input_shape = (img_rows, img_cols, 3)
nb_filters = 32
# size of pooling area for max pooling
pool_size = (2, 2)
# convolution kernel size
kernel_size = (3, 3)

#[Définition du modèle]
model = Sequential()
model.add(Conv2D(nb_filters, kernel_size, #Couche pliante
                        padding='valid',
                        activation='relu',
                        input_shape=input_shape))
model.add(Conv2D(nb_filters, kernel_size, activation='relu')) #Couche pliante
model.add(MaxPooling2D(pool_size=pool_size)) #Couche de regroupement
model.add(Conv2D(nb_filters, kernel_size, activation='relu')) #Couche pliante
model.add(MaxPooling2D(pool_size=pool_size)) #Couche de regroupement
model.add(Dropout(0.25)) #Abandonner(Déconnectez au hasard entre l'entrée et la sortie pour éviter le surapprentissage)

model.add(Flatten()) #Convertir un tableau multidimensionnel en tableau unidimensionnel
model.add(Dense(128, activation='relu'))  #Couche entièrement connectée
model.add(Dropout(0.2))  #Abandonner
model.add(Dense(nb_classes, activation='sigmoid'))  #Puisqu'il s'agit de 2 classes, la couche entièrement connectée est sigmoïde

#Compiler le modèle
model.compile(loss='binary_crossentropy', #Binaire car c'est 2 classes_crossentropy
              optimizer='adam', #Utiliser les valeurs par défaut pour les paramètres de la fonction d'optimisation
              metrics=['accuracy'])

#Définissez un rappel pour générer des résultats d'apprentissage pour chaque époque(Enregistrez uniquement lorsque la précision est meilleure que la dernière fois)】
from keras.callbacks import ModelCheckpoint
import os
model_checkpoint = ModelCheckpoint(
    filepath=os.path.join('models','model_2class120_{epoch:02d}_{val_acc:.3f}.h5'),
    monitor='val_acc',
    mode='max',
    save_best_only=True,
    verbose=1)

#[Apprentissage]
result = model.fit(X_train, Y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(X_test, Y_test),
                   callbacks=[model_checkpoint])

3-3. Classification

from keras.models import load_model
from keras.preprocessing.image import load_img, img_to_array
import matplotlib.pyplot as plt

model = load_model('models/model_2class120_04.h5')
model.summary()

def img_to_traindata(file, img_rows, img_cols, rgb):
    if rgb == 0:
        img = load_img(file, color_mode = "grayscale", target_size=(img_rows,img_cols)) #Lire avec des niveaux de gris
    else:
        img = load_img(file, color_mode = "rgb", target_size=(img_rows,img_cols)) #Lire en RVB
    x = img_to_array(img)
    x = x.astype('float32')
    x /= 255
    return x

import numpy as np
img_rows = 224 #La taille de l'image est la taille par défaut de VGG16
img_cols = 224

##Chargement d'image
filename = "dog_smile/n02085936_37.jpg "
x = img_to_traindata(filename, img_rows, img_cols, 1) # img_to_La fonction traindata est définie lors de la génération des données d'entraînement
x = np.expand_dims(x, axis=0)

##Déterminez quelle classe
preds = model.predict(x)
pred_class = np.argmax(preds[0])
print("Résultat de l'identification:", pred_class)
print("probabilité:", preds[0])

from keras import backend as K
import cv2

#Sortez la sortie finale du modèle
model_output = model.output[:, pred_class]

#Retirez la dernière couche de convolution
last_conv_output = model.get_layer('conv2d_3').output #'block5_conv3').output

#Gradient de la sortie finale de la couche de convolution par rapport à la sortie finale du modèle
grads = K.gradients(model_output, last_conv_output)[0]
# model.Lorsque vous entrez l'entrée, le dernier_conv_Définir une fonction qui génère des résultats et des notes
gradient_function = K.function([model.input], [last_conv_output, grads]) 

#Trouvez le dégradé de l'image chargée
output, grads_val = gradient_function([x])
output, grads_val = output[0], grads_val[0]

#Poids moyens et multiplier par la sortie de couche pour créer une carte thermique
weights = np.mean(grads_val, axis=(0, 1))
heatmap = np.dot(output, weights)

heatmap = cv2.resize(heatmap, (img_rows, img_cols), cv2.INTER_LINEAR)
heatmap = np.maximum(heatmap, 0) 
heatmap = heatmap / heatmap.max()

heatmap = cv2.applyColorMap(np.uint8(255 * heatmap), cv2.COLORMAP_JET)  #Colorez la carte de chaleur
heatmap = cv2.cvtColor(heatmap, cv2.COLOR_BGR2RGB)  #Convertir la couleur en RVB

img = plt.imread(filename, cv2.IMREAD_UNCHANGED)
print(img.shape)  # (330, 440, 4)

fig, ax = plt.subplots()
ax.imshow(img)

plt.show()

4. Résultat de la classification

2020-04-26 21:12:46.904489: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x7fded852e7f0 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-04-26 21:12:46.904528: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 222, 222, 32)      896       
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 220, 220, 32)      9248      
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 110, 110, 32)      0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 108, 108, 32)      9248      
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 54, 54, 32)        0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 54, 54, 32)        0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 93312)             0         
_________________________________________________________________
dense_1 (Dense)              (None, 128)               11944064  
_________________________________________________________________
dropout_2 (Dropout)          (None, 128)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 2)                 258       
=================================================================
Total params: 11,963,714
Trainable params: 11,963,714
Non-trainable params: 0
_________________________________________________________________
Résultat d'identification: 1
probabilité:[0.27252397 0.6845933 ]
(375, 500, 3)

5. Problèmes futurs

Il est nécessaire de réduire les problèmes pour améliorer la précision.

Recommended Posts

[Classification des images] Analyse faciale du chien
[PyTorch] Classification des images du CIFAR-10
Analyse d'image de microtomographie à rayons X par Python
[PyTorch] Classification des images du CIFAR-10
Apprendre avec l'enseignant 1 Principes de base de l'apprentissage avec l'enseignant (classification)
Pratiquer des méthodes typiques de statistiques (1)
Classification multi-étiquette d'images multi-classes avec pytorch
Algorithme d'apprentissage automatique (implémentation de la classification multi-classes)
[Classification des images] Analyse faciale du chien
Juge Yosakoi Naruko par classification d'image de Tensorflow.
Image de fermeture
[OpenCV / Python] J'ai essayé l'analyse d'image de cellules avec OpenCV
Histoire de l'analyse d'image du fichier PDF et de l'extraction de données
Bases de l'analyse de régression