[PYTHON] J'ai créé une application pour découvrir à qui ressemblent les membres des Pirates du Chapeau de Paille

J'ai créé une application pour découvrir à qui ressemblent les membres des Pirates du Chapeau de Paille

Cette fois, j'ai fait une application qui utilise la reconnaissance d'image de l'apprentissage automatique. Comme le titre l'indique, vous pouvez découvrir à quel point votre visage ressemble à celui qui est membre des Pirates du Chapeau de Paille dans One Piece.

Cliquez ici pour git hub ↓↓↓ https://github.com/Sho-cmyk/shiny-winner

Tout d'abord, regardez le formulaire rempli. 図1.png Lorsque vous appuyez sur le bouton de prise de vue, Il montre à quel point votre visage ressemble à n'importe quel membre des Pirates du Chapeau de Paille. Les deux premiers caractères similaires sont affichés. ャ.JPG J'ai trouvé que c'était 38% similaire à Jinbei et 20% similaire à Luffy.

Si l'application vous intéresse, essayez-la à partir de cette URL. ↓↓↓ https://one-piece-camera.herokuapp.com/

Étapes pour créer une application

Ensuite, je présenterai la procédure de création d'une application. La procédure est grossièrement divisée comme suit.

  1. Structure du fichier (flacon)

  2. Collectez des images pour apprendre

  3. Prétraitement d'image

    1. Apprentissage
  4. Estimation

  5. Organisez l'écran de sortie avec html / css / js

  6. Structure des fichiers dans Flask

flask_app
├ one-piece_cnn_aug.h5 ---Économisez du poids
├ static ---Emplacement du fichier statique
│ ├ image
│ └ webcam.js
│ └ stylesheet.css
├ templates ---modèle
│ └ index.html
│ └ photoclick.html
│ └ photoclick_copy.html
├ main.py ---Script d'exécution d'application (entrée d'application)
├ requirements.txt 
└ runtime.txt
└ Profile
└ README.md
  1. Collectez des images pour apprendre J'utilise la recherche d'images de Yahoo pour récupérer des images de chaque membre des Pirates du Chapeau de Paille. J'ai gratté 200 feuilles chacun. Pour la méthode de grattage détaillée, reportez-vous à ce qui suit. Citation: https://www.youtube.com/watch?v=BrCaYYJtC4w

  2. Prétraitement d'image Je ne laisserai que les images qui pourront être utilisées ensuite. J'effacerai les photos que le personnage cible n'a pas déplacé de lui-même. 図2.png

L'image est maintenant divisée en données d'entraînement et données de test. Les données d'entraînement sont gonflées à l'aide d'ImageDataGenerator.

generatedata.py


from PIL import Image
import os,glob
import numpy as np
from sklearn.model_selection import train_test_split
from keras.preprocessing.image import ImageDataGenerator

classes=["Usop","Sanji","Jinbei","Zoro","hachoir","Nami","Bibi","Frankie","Ruisseau","Luffy","Robin"]
num_classes=len(classes)
image_size=50
num_testdata=30

#Chargement des images
X_train=[]
X_test=[]
Y_train=[]
Y_test=[]

for index,classlabel in enumerate(classes):
    photos_dir="./"+classlabel
    files=glob.glob(photos_dir+"/*.jpg ")
    for i,file in enumerate(files):
        if i >=200:break
        image= Image.open(file)
        image=image.convert("RGB")
        image=image.resize((image_size,image_size))
        data=np.asarray(image)
        X_train.append(data) #Ajouter à la fin de la liste
        Y_train.append(index) #Ajouter une étiquette
#Standardisation
datagen=ImageDataGenerator(samplewise_center=True,samplewise_std_normalization=True)


g=datagen.flow(X_train,Y_train,shuffle=False)
X_batch,y_batch=g.next()

#0 tout en maintenant le rapport des valeurs RVB-Près de 255 pour une visualisation facile
X_batch *=127.0/max(abs(X_batch.min()),X_batch.max())
X_batch +=127.0
X_batch =X_batch.astype('unit8')

#Mettez-le dans un tableau et divisez-le en données de test et d'entraînement
X_train=np.array(X_train)
X_test=np.array(X_test)
y_train=np.array(Y_train)
y_test=np.array(Y_test)

#X_train,X_test,y_train,y_test=train_test_split(X,Y)
xy=(X_train,X_test,y_train,y_test)
np.save("./one-piece_aug.npy",xy)#Enregistrer le code

    1. Apprentissage Le modèle de formation utilise CNN. Le code est ci-dessous.

one-piece_cnn_aug.py


from keras.models import Sequential
from keras.layers import Conv2D,MaxPooling2D
from keras.layers import Activation,Dropout,Flatten,Dense
from keras.utils import np_utils
import keras
import numpy as np
from tensorflow.keras.optimizers import RMSprop

classes=["Usop","Sanji","Jinbei","Zoro","hachoir","Nami","Bibi","Frankie","Ruisseau","Luffy","Robin"]
num_classes=len(classes)
image_size=50
#Définir la fonction principale qui effectue la formation
def main():
    X_train,X_test,y_train,y_test=np.load("./one-piece.npy",allow_pickle=True) #Lire les données d'un fichier texte
    X_train=X_train.astype("float")/256 #Normaliser et faire converger les valeurs RVB de 0 à 1 pour faciliter l'apprentissage des réseaux de neurones
    X_test=X_test.astype("float")/256 #Aussi
    y_train=np_utils.to_categorical(y_train,num_classes) #one-hot-vector:La valeur de réponse correcte est 1 et les autres sont 0. Le premier argument est l'étiquette que vous souhaitez convertir en vecteur et le deuxième argument est l'étiquette que vous souhaitez convertir en vecteur.
    y_test=np_utils.to_categorical(y_test,num_classes) #Aussi

    model=model_train(X_train,y_train) #Apprenez
    model_eval(model,X_test,y_test) #Faire une évaluation

#Définir un modèle pour CNN
def model_train(X,y):
    model=Sequential() #Créez un modèle séquentiel qui connecte chaque couche du réseau neuronal dans l'ordre
    #Extraire la quantité de fonction
    model.add(Conv2D(32,(3,3),padding='same',input_shape=X.shape[1:])) #32 couches de couche pliante 3x3
    model.add(Activation('relu')) #Fonction d'activation relu,Négatif → 0, positif → tel quel
    model.add(Conv2D(32,(3,3))) #2ème couche de pli
    model.add(Activation('relu')) #Fonction d'activation relu
    model.add(MaxPooling2D(pool_size=(2,2))) #La couche de regroupement fait ressortir les fonctionnalités et les retire
    model.add(Dropout(0.25)) #Jeter 25% des données pour réduire le biais des données

    model.add(Conv2D(64,(3,3),padding='same')) #Vient ensuite 64 couches de noyau
    model.add(Activation('relu')) #fonction d'activation relu
    model.add(Conv2D(64,(3,3))) #Aussi une couche de pliage
    model.add(Activation('relu')) #fonction d'activation relu
    model.add(MaxPooling2D(pool_size=(2,2))) #Mise en commun maximale

    #Rejoignez pleinement. Classer en fonction des caractéristiques
    model.add(Flatten()) #Commencez par organiser les données dans une ligne
    model.add(Dense(512)) #Rejoignez pleinement
    model.add(Activation('relu')) #fonction d'activation relu
    model.add(Dropout(0.5)) #Jeter la moitié
    model.add(Dense(11)) #11 nœuds de couche de sortie
    model.add(Activation('softmax')) #Utilisez la fonction softmax qui totalise jusqu'à 1

    opt=RMSprop(lr=0.0001,decay=1e-6) #Définition de la méthode d'optimisation. Mettre à jour l'algorithme pendant l'entraînement.

    model.compile(loss='categorical_crossentropy',
                    optimizer=opt,metrics=['accuracy']) #Fonction d'évaluation. perte:Erreur entre la bonne réponse et la valeur estimée dans la fonction de perte. opter:Méthode d'optimisation. métrique:Valeur d'évaluation

    model.fit(X,y,batch_size=32,epochs=100) #Optimisation des paramètres. lot_size:Le nombre de données utilisées à la fois. epoch: nombre d'apprentissages.
#Enregistrer le modèle
    model.save('./one-piece_cnn.h5')

    return model

#Rendre le modèle utilisable
def model_eval(model,X,y):
    scores=model.evaluate(X,y,verbose=1) #verbose:Afficher la progression,Mettez le résultat d'apprentissage en score
    print('Test Loss:',scores[0]) #perte
    print('Test Accuracy:',scores[1]) #Précision

#Autoriser ce programme à être appelé par d'autres fichiers
if __name__=="__main__":
    main()

Les résultats d'apprentissage sont les suivants.

Epoch 100/100
7888/7888 [==============================] - 64s 8ms/step - loss: 0.0200 - acc: 0.9962
330/330 [==============================] - 1s 4ms/step
  1. Estimation

main.py


import PIL
import io
import base64
import re
from io import StringIO
from PIL import Image
import os
from flask import Flask, request, redirect, url_for, render_template, flash,jsonify
from werkzeug.utils import secure_filename
from keras.models import Sequential, load_model
from keras.preprocessing import image
import tensorflow as tf
import numpy as np
from datetime import datetime

classes=["Usop","Sanji","Jinbei","Zoro","hachoir","Nami","Bibi","Frankie","Ruisseau","Luffy","Robin"]
classes_img=["static/img/usoppu.jpg ","static/img/sanji.jpg ","static/img/jinbe.jpg ","static/img/zoro.jpg ","static/img/chopper.jpg ","static/img/nami.jpg ","static/img/bibi.jpg ","static/img/franky.jpg ","static/img/bruck.jpg ","static/img/rufi.jpg ","static/img/robin.jpg "]
num_classes=len(classes)
image_size=50

UPLOAD_FOLDER = "./static/image/"
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])

app = Flask(__name__)

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

model = load_model('./one-piece_cnn_aug.h5')#Charger le modèle entraîné

graph = tf.get_default_graph()


app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def upload_file():

    global graph
    with graph.as_default():
        if request.method == 'POST':

                myfile= request.form['snapShot'].split(',')
                imgdata = base64.b64decode(myfile[1])
                image = Image.open(io.BytesIO(imgdata))

                #sauvegarder
                basename = datetime.now().strftime("%Y%m%d-%H%M%S")
                image.save(os.path.join(UPLOAD_FOLDER, basename+".png "))
                filepath = os.path.join(UPLOAD_FOLDER, basename+".png ")


                image=image.convert('RGB')
                image=image.resize((image_size,image_size))
                data=np.asarray(image)
                X=[]
                X.append(data)
                X=np.array(X).astype('float32')
                X /=256

                result=model.predict([X])[0]
                result_proba = model.predict_proba(X, verbose=1)[0]
                    
                percentage=(result_proba*100).astype(float)
                array_sort =sorted(list(zip(percentage,classes,classes_img)),reverse=True)
                percentage,array_class,array_img = zip(*array_sort)
                
                
                pred_answer1="étiquette:"+str(array_class[0])+ ",probabilité:"+str(percentage[0])+"%"
                pred_answer2="étiquette:"+str(array_class[1])+ ",probabilité:"+str(percentage[1])+"%"
                pred_answer3="étiquette:"+str(array_class[2])+ ",probabilité:"+str(percentage[2])+"%"
                
                img_src1=array_img[0]
                img_src2=array_img[1]
                img_src3=array_img[2]


                basename = datetime.now().strftime("%Y%m%d-%H%M%S")
                filepath3 = UPLOAD_FOLDER + basename+".png "


                return render_template("index.html",answer1=pred_answer1,img_data1=img_src1,answer2=pred_answer2,img_data2=img_src2,answer3=pred_answer3,img_data3=img_src3)

        return render_template("index.html",answer="")

        

if __name__ == '__main__':
   app.run(debug = True)


Cinq. Organiser l'écran de sortie Tout ce que vous avez à faire est d'organiser l'écran de sortie avec html / css / js.

Recommended Posts

J'ai créé une application pour découvrir à qui ressemblent les membres des Pirates du Chapeau de Paille
J'ai créé une commande appdo pour exécuter des commandes dans le contexte de l'application
Avec LINEBot, j'ai fait une application qui m'informe de "l'heure du bus"
J'ai utilisé Python pour découvrir les choix de rôle des 51 "Yachts" dans le monde.
J'ai essayé de trouver l'entropie de l'image avec python
J'ai essayé de découvrir les grandes lignes de Big Gorilla
J'ai fait une fonction pour vérifier le modèle de DCGAN
(Python) J'ai créé une application de Trello qui notifie périodiquement le relâchement des tâches sur le point d'expirer.
J'ai fait un package npm pour obtenir l'ID de la carte IC avec Raspberry Pi et PaSoRi
Comment connaître le nombre de processeurs sans utiliser la commande sar
J'ai essayé de trouver l'itinéraire optimal du pays des rêves par recuit (quantique)
Je veux analyser les sentiments des gens qui veulent se rencontrer et trembler
Je souhaite laisser une commande arbitraire dans l'historique des commandes de Shell
J'ai fait un programme pour vérifier la taille d'un fichier avec Python
J'ai créé une fonction pour voir le mouvement d'un tableau à deux dimensions (Python)
La fin de la programmation catastrophique # 02 "Il est difficile d'obtenir 5 et 6 de dés ... J'en ai envie, alors considérez les nombres aléatoires"
J'ai créé une application d'analyse de fréquence en ligne
J'ai fait un outil pour estimer le temps d'exécution de cron (+ débuts de PyPI)
J'ai utilisé gawk pour connaître la valeur maximale qui entre dans NF.
Un débutant en programmation a essayé de vérifier le temps d'exécution du tri, etc.
Je t'ai fait exprimer la fin de l'adresse IP avec L Chika
J'ai créé un outil pour sauvegarder automatiquement les métadonnées de l'organisation Salesforce
Je souhaite stocker les résultats de% time, %% time, etc. dans un objet (variable)
J'ai créé un programme pour rechercher des mots sur la fenêtre (développement précédent)
J'ai fait un script pour enregistrer la fenêtre active en utilisant win32gui de Python