[PYTHON] J'ai examiné les traits du visage de Yuki Kashiwagi pour comprendre TensorFlow [Partie 2]

J'ai examiné les traits du visage de Yuki Kashiwagi pour comprendre TensorFlow et CNN (réseau de neurones convolutifs). Cette fois, je vais expliquer et résumer l'ensemble du processus en me concentrant sur la partie jugement de TensorFlow dans l'ensemble du processus. Dans le jugement, le modèle entraîné est utilisé pour juger si l'image individuelle est Yuki Kashiwagi. Le principe de cet article est Partie 1 et Partie 2. 90.summary01_flow.JPG

Processus de détermination

Comme je l'ai écrit dans Partie 1, le jugement d'image se poursuit avec la détection de visage en utilisant le recadrage OpenCV + et le jugement d'image en utilisant TensorFlow comme indiqué dans la figure ci-dessous. Faire. Les paramètres appris enregistrés dans le processus de "3. Apprentissage" sont utilisés lors du jugement de l'image. 50.Judge01.JPG

Exécution du jugement

Prêt à courir

La structure du dossier ressemble à ceci et place le modèle d'apprentissage utilisé pour la détection de visage utilisé dans OpenCV dans le dossier "models". La source d'acquisition est Github. Pour les bases d'OpenCV, veuillez vous référer à l'article "[Explication pour les débutants] mécanisme et pratique de détection de visage openCV (detectMultiScale)". Ensuite, placez le fichier image à juger dans le dossier "images". Plusieurs fichiers peuvent être placés, mais seul le fichier image qui a réussi la détection de visage en premier est évalué et les fichiers image restants ne sont pas évalués. Les images autres que le dossier "images" peuvent également être chargées en spécifiant des paramètres lors de l'exécution.

models
│  haarcascade_frontalface_default.xml
│  haarcascade_frontalface_alt.xml
│  haarcascade_frontalface_alt2.xml
│  haarcascade_frontalface_alt_tree.xml
│  haarcascade_profileface.xml
images
│ Fichier image à juger

Exécution de l'apprentissage

python judge_image.py

Exécutez la commande ci-dessus, et si la détection de visage réussit, l'image du visage détecté sera affichée dans une fenêtre contextuelle. 91.Judge01.JPG Tout va bien, alors appuyez sur la touche pour exécuter le jugement. 91.Judge02.JPG

Les éléments suivants sont fournis en tant que paramètres d'exécution. Implémenté à l'aide de la bibliothèque argparse, qui est un peu expliquée dans l'article "Spécifier les paramètres avec la détection de visage openCV pour améliorer rapidement la précision de détection" Faire.

Paramètres Contenu valeur initiale Remarques
cascade Fichier modèle pour la détection de visage alt Utilisé pour la détection de visage dans OpenCV
scale Paramètre ScaleFactor pour la détection de visage 1.3 C'est moins faux positif
neighbors Paramètre MinNeighbors pour la détection de visage 2 C'est moins faux positif. 3 peut être bien.
min Paramètre MinSize pour la détection de visage 50 Peut être un peu plus grand
input_dir Dossier avec image de jugement ./images/ Vous pouvez spécifier le dossier / fichier de données de test en modifiant cette valeur.
log_dir Répertoire de stockage des journaux /tmp/tensorflow/kashiwagi/logs Répertoire pour enregistrer les paramètres appris et les journaux TensorBoard
image_size Taille de l'image 81 resizeするときの初期Taille de l'image
pool_size Taille de la mise en commun 3 マックスTaille de la mise en commun

Programme Python

Partie de jugement (juge_image.py)

[Pièce modèle (model_deep.py)](http://qiita.com/FukuharaYohei/items/1192ca038b0052ef300f#%E3%83%A2%E3%83%87%E3%83%AB%E9%83%A8%E5 % 88% 86 model_deeppy) est appelé pour juger l'image.

import cv2, argparse, os
import numpy as np
import tensorflow as tf
import model_deep  #Partie estimée de TensorFlow

#Emplacement du modèle d'identification d'image formé
CKPT_PATH = '/tmp/tensorflow/kashiwagi/logs/'

#Paramètres de base du modèle
FLAGS = None

#Étiquette d'identification et le nom correspondant à chaque numéro d'étiquette
HUMAN_NAMES = { 0: u'Kashiwagi', 1: u'others',}

#Type de modèle entraîné par détection de visage
CASCADE = ['default','alt','alt2','tree','profile']

#Acquisition des caractéristiques du classificateur
def get_cascade():
    #Répertoire du trieur(Obtenu à partir de)
    # https://github.com/opencv/opencv/blob/master/data/haarcascades/

    #Fichier de modèle formé
    if   FLAGS.cascade == CASCADE[0]:#'default':
        cascade_path = './models/haarcascade_frontalface_default.xml'
    elif FLAGS.cascade == CASCADE[1]:#'alt':
        cascade_path = './models/haarcascade_frontalface_alt.xml'
    elif FLAGS.cascade == CASCADE[2]:#'alt2':
        cascade_path = './models/haarcascade_frontalface_alt2.xml'
    elif FLAGS.cascade == CASCADE[3]:#'tree':
        cascade_path = './models/haarcascade_frontalface_alt_tree.xml'
    elif FLAGS.cascade == CASCADE[4]:#'profile':
        cascade_path = './models/haarcascade_profileface.xml'

    #Acquérir la quantité de caractéristiques du classificateur en cascade
    return(cv2.CascadeClassifier(cascade_path))

#Jugement de visage
def run_judge(image):
    
    #Sort et renvoie la probabilité de chaque étiquette pour l'image d'entrée
    logits = model_deep.inference(image, 1.0, FLAGS.image_size, FLAGS.pool_size)
    
    #Calcul Softmax
    loss   = tf.nn.softmax(logits)

    #Exportez le contenu jusqu'à présent vers TensorBoard
    summary = tf.summary.merge_all()

    #Préparation d'appels de modèles formés
    saver = tf.train.Saver()
    
    #Créer une session(Les calculs TensorFlow doivent être effectués dans une session absolue)
    with tf.Session() as sess:
    
        #Préparation à l'écriture sur TensorBoard
        summary_writer = tf.summary.FileWriter(FLAGS.log_dir, sess.graph)

        #Initialisation variable(Exécuter avant de charger le modèle entraîné)
        sess.run(tf.global_variables_initializer())
        
        #Obtention d'un modèle entraîné
        ckpt = tf.train.get_checkpoint_state(CKPT_PATH)

        #Lire s'il existe un modèle entraîné
        if ckpt:
            saver.restore(sess, ckpt.model_checkpoint_path)

        #Exécutez la session et obtenez le résumé et l'erreur TensorBoard
        summary_str, loss_value = sess.run([summary, loss])

        #Ajouter un résumé à TensorBoard et fermer
        summary_writer.add_summary(summary_str)
        summary_writer.close()

        #résultat du jugement
        result = loss_value[0]
        
        humans = []
        #Créer un hachage pour le nom et la probabilité
        for index, rate in enumerate(result):
            humans.append({
                'name': HUMAN_NAMES[index],
                'rate': rate * 100
            })
        #Trier par ordre décroissant avec probabilité et afficher la réponse la plus probable
        rank = sorted(humans, key=lambda x: x['rate'], reverse=True)        
        print('Probalibity %d %% :This image is %s' % (rank[0]['rate'], rank[0]['name']))

#Détection et jugement des visages à l'aide d'OpenCV
def read_and_edit_images(file_name, faceCascade):

    #Lecture de fichier image
    img = cv2.imread(FLAGS.input_dir + file_name)

    #Comme il y a des fichiers qui échouent rarement lorsqu'il y a un grand nombre d'images, enregistrez la sortie et ignorez(Cause inconnue)
    if img is None:
        print(file_name + ':Cannot read image file')
        return 0

    #Détection facial
    face = faceCascade.detectMultiScale(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY), 
                                        scaleFactor=FLAGS.scale, minNeighbors=FLAGS.neighbors, minSize=(FLAGS.min, FLAGS.min))

    #S'il ne peut pas être détecté, enregistrez la sortie et quittez
    if len(face) <= 0:
        print(file_name + ':No Face')
    else:
        
        #Découpez la partie du visage et redimensionnez l'image en utilisant uniquement le premier visage détecté
        cut_image = cv2.resize(img[face[0,1]:face[0,1] + face[0,3], face[0,0]:face[0,0] + face[0,2]], (FLAGS.image_size, FLAGS.image_size))
        
        #Afficher l'image du visage coupé dans la fenêtre contextuelle(Appuyez sur la touche pour fermer la fenêtre contextuelle et passer au processus suivant)
        cv2.imshow('image', cut_image)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

        image = []

        #Convertir au format TensorFlow(Flotteur 0-Gamme de 1)
        image.append(cut_image.astype(np.float32)/255.0)
        
        #Revenir sous forme de tableau
        return np.asarray(image)

        
def cut_and_judge_images():
    
    #Acquisition des caractéristiques du classificateur
    faceCascade = get_cascade()

    #Stocker les fichiers dans des dossiers dans des variables(Stocke également les répertoires)
    files =  os.listdir(FLAGS.input_dir)

    #Lorsqu'un visage est détecté à partir des données d'image collectées, coupez-le et enregistrez-le.
    for file_name in files:

        #Pour les fichiers(Si ce n'est pas un annuaire)
        if os.path.isfile(FLAGS.input_dir + file_name):
            
            #Lecture d'image et recadrage du visage
            image = read_and_edit_images(file_name, faceCascade)
            
            if image is not None:
                #Jugement d'image en passant à TensorFlow
                run_judge(image)
                
                #Si tu juge même une fois, ça se termine
                return 0.
            
            
#Passer si courir directement(Importé et ne passe pas au moment de l'exécution)
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--cascade',
        type=str,
        default='alt',
        choices=CASCADE,
        help='cascade file.'
  )
    parser.add_argument(
        '--scale',
        type=float,
        default=1.3,
        help='scaleFactor value of detectMultiScale.'
  )
    parser.add_argument(
        '--neighbors',
        type=int,
        default=2,
        help='minNeighbors value of detectMultiScale.'
  )
    parser.add_argument(
        '--min',
        type=int,
        default=50,
        help='minSize value of detectMultiScale.'
  )
    parser.add_argument(
        '--input_dir',
        type=str,
        default='./images/',
        help='The path of input directory.'
  )
    parser.add_argument(
        '--image_size',
        type=int,
        default=81,
        help='Input image size'
    )
    parser.add_argument(
        '--pool_size',
        type=int,
        default=3,
        help='Pooling size'
    )
    parser.add_argument(
        '--log_dir',
        type=str,
        default='/tmp/tensorflow/kashiwagi_judges',
        help='Directory to put the log data.'
    )

    #Acquisition et exécution des paramètres
    FLAGS, unparsed = parser.parse_known_args()
    
    #Si le répertoire de sauvegarde TensorBoard existe, supprimez-le et recréez-le.
    if tf.gfile.Exists(FLAGS.log_dir):
        tf.gfile.DeleteRecursively(FLAGS.log_dir)
    tf.gfile.MakeDirs(FLAGS.log_dir)

    #Détection de visage et jugement
    cut_and_judge_images()

Amélioration globale

Un jour, je veux surmonter les améliorations et vengeance suivantes: lifter_tone1: Quand sera-ce?

Manque de données d'entraînement

Je pense que la petite quantité de données d'entraînement a été un facteur majeur pour réduire la précision. Comme vous pouvez le voir dans l'article "Appel de l'API Bing Image Search v5 depuis Python pour collecter des images", j'utilise Bing, mais Google et d'autres C'était bon? Autre que moi [Phénomène selon lequel les images ne peuvent pas être acquises avec Bing](http://qiita.com/ysdyt/items/49e99416079546b65dfc#%E7%B5%90%E6%9E%9C%E3%81%A8%E6% 89% 80% E6% 84% 9F) se produisait. Il y avait également une augmentation du remplissage d'image.

Modèle d'apprentissage CNN

Cette fois, j'ai utilisé le même modèle d'apprentissage que Deep MNIST for Experts, mais Image Recognition Vous devriez vous référer à / tutorials / image_recognition).

finalement

Même les débutants en Python et en Deep Learning, sans parler de TensorFlow, pourraient faire cette qualité! TensorFlow est génial. Cela a pris du temps, mais c'était amusant. "J'ai créé un classificateur de visage Dir en gray en utilisant TensorFlow" et ["Créer une IA qui identifie le visage de Zuckerberg avec un apprentissage en profondeur" ]](Http://qiita.com/AkiyoshiOkano/items/72f3e4ba9caf514460ee) a été très utile.

Recommended Posts

J'ai examiné les traits du visage de Yuki Kashiwagi pour comprendre TensorFlow [Partie 2]
J'ai examiné les traits du visage de Yuki Kashiwagi pour comprendre TensorFlow [Partie 2]
J'ai examiné les traits du visage de Yuki Kashiwagi pour comprendre TensorFlow [Partie 1]
Je veux comprendre à peu près systemd
J'ai essayé d'implémenter Autoencoder avec TensorFlow
J'ai essayé de visualiser AutoEncoder avec TensorFlow
Je veux gérer la rime part1
Je veux gérer la rime part3
J'ai essayé de classer le texte en utilisant TensorFlow
Je veux gérer la rime part2
Je veux gérer la rime part5
Je veux gérer la rime part4
Implémentation de DQN avec TensorFlow (je voulais ...)
Je n'ai pas compris le redimensionnement de TensorFlow, alors je l'ai résumé visuellement.