En tant qu'exemple d'application d'une tâche utilisant le Deep Learning, j'ai essayé de "créer une application d'assistance erronée".
Dans un monde pratique maintenant, il existe un site du portail Misscon de l'université.
Il y a beaucoup de participants et c'est amusant. Cependant, en même temps, je voulais aussi voir tout le monde ensemble. Je voulais aussi assembler des visages similaires. (Peut-être que c'est une mauvaise idée, mais au moins j'aime Miscon comme ça)
Donc cette fois, nous fixerons les objectifs suivants
Par conséquent, j'ai considéré le flux de travail suivant.
Je vais faire tout cela en Python.
Chacun peut être réalisé à l'aide de la bibliothèque Python.
J'omettrai la partie 1 parce que j'écris habituellement juste le code de scraping.
La plupart des articles utilisent des bibliothèques d'apprentissage automatique.
Passons à la distribution Anaconda, qui est forte dans les bibliothèques d'apprentissage automatique. Article de référence
Nous allons également procéder dans un environnement utilisant MacOSX 10.10 / Python 2.7.
Toutes les images qui peuvent être obtenues montrent non seulement le visage mais aussi tout le corps et le paysage en arrière-plan. Par exemple, Il ressemble à ceci
Cette fois, le but est d'apporter un visage similaire l'un à l'autre, de sorte que tout le corps et l'arrière-plan sont des informations inutiles.
Par conséquent, je ne découperai automatiquement que la partie du visage.
Cette opération peut être réalisée avec la combinaison d'OpenCV + cv2.
Vous pouvez installer opencv avec conda
, un outil de gestion de paquets d'anaconda.
$ conda install -c https://conda.binstar.org/menpo opencv
Vérifions l'installation
>>> import cv2
>>> cv2.__version__
'2.4.9.1'
>>> exit()
Tout d'abord, chargez l'image
import cv2
image = cv2.imread(path_to_imagefile)
Ensuite, effectuez les réglages pour déterminer la zone où se trouve le visage. Un modèle d'apprentissage automatique est nécessaire pour déterminer la zone du visage. openCV dispose déjà d'un modèle de détermination de la surface du visage formé avec des fonctionnalités appelées __ fonctionnalités de cascade __.
Le modèle de jugement de la zone du visage est enregistré sous forme de fichier xml, spécifiez donc le chemin.
Si vous ne le trouvez pas, essayez de rechercher haarcascade_frontalface_alt.xml
avec la commande find
.
Spécifiez le chemin comme constante.
CASCADE_PATH = "/Users/kensuke-mi/.pyenv/versions/anaconda-2.1.0/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml"
Avant d'identifier la zone du visage, mettez-la en niveaux de gris. (L'échelle de gris n'est pas nécessaire pour identifier la zone du visage. Il s'agit d'un prétraitement pour l'apprentissage avec Deep NN.)
image_gray = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY)
De plus, uniformisez les valeurs numériques de la matrice d'image. Pour plus de détails, voir Manual.
image_gray = cv2.equalizeHist(image_gray)
Enfin, appelez le juge de la zone du visage pour trouver la zone.
cascade = cv2.CascadeClassifier(CASCADE_PATH)
facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=3, minSize=(50, 50))
Les coordonnées de la zone de l'image du visage sont renvoyées dans facerect
.
J'ai essayé de transformer une série de flux en fonction.
def detectFace(image):
image_gray = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY)
image_gray = cv2.equalizeHist(image_gray)
cascade = cv2.CascadeClassifier(CASCADE_PATH)
facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=3, minSize=(50, 50))
return facerect
Puisque la zone est déjà connue, la partie de face peut être extraite simplement en découpant la zone de l'objet «imaga». C'est aussi une fonction.
def extract_face(facerect_list, image, path_to_save):
"""Découpez la partie du visage. Cependant, notez qu'il n'y a qu'un seul visage sur une photo.
:param facerect_list:
:param image:
:param path_to_save:
:return:
"""
assert os.path.exists(os.path.dirname(path_to_save))
for rect in facerect_list:
x = rect[0]
y = rect[1]
w = rect[2]
h = rect[3]
# img[y: y + h, x: x + w]
cv2.imwrite(path_to_save, image[y:y+h, x:x+w])
return image[y:y+h, x:x+w]
Uniformise la taille de l'image.
Il s'agit d'apprendre efficacement avec DeepNN. Même si les tailles sont différentes, il est possible d'apprendre, mais la quantité de calcul sera importante, nous allons donc organiser les tailles ici.
Définissez l'objet ʻimage comme ʻim
, spécifiez la taille après le redimensionnement et exécutez le redimensionnement.
RESIZED_TUPLE = (100, 100)
resized_im = cv2.resize(im,size_tuple)
Veuillez vous référer à github pour le flux.
RBM, qui est un type de Deep NN (Neural Network), est utilisé. Cet article est excellent pour le principe de fonctionnement de RBM, il est donc bon de s'y référer.
Pour utiliser RBM, utilisez la bibliothèque Pylearn2
.
En ce qui concerne le Deep Learning, le «chainer» de PFI est célèbre, mais le «chainer» ne prend pas en charge la méthode d'apprentissage pour l'utilisation de la RBM (à partir du 25 octobre 2015).
Si vous souhaitez utiliser le réseau Auto Encoder au lieu de RBM, nous vous recommandons chainer
.
En gros, tout ce que vous avez à faire est de cloner le référentiel Git et de l'installer.
git clone git://github.com/lisa-lab/pylearn2.git
cd pylearn2
python setup.py build
sudo python setup.py install
Après cela, je vois souvent des explications telles que "passer le chemin utilisé par pylearn2", mais en fait Pylearn2 fonctionne même si vous ne passez pas le chemin.
Cependant, pour que le code du didacticiel fonctionne, vous devez toujours suivre le chemin.
Du clone git à l'exécution du code du didacticiel est transformé en un script shell, veuillez donc vous y référer. (Je suis désolé si ça ne marche pas)
Le flux général de pylearn2 est comme ça
1.Faites les données d'entraînement dans un format qui peut être utilisé avec pylearn2 2. Écrivez la méthode d'entraînement dans le fichier yaml 3. Exécutez le script de formation
Les données d'apprentissage sont préparées par ndarray de numpy et converties en objet pour pylearn2.
Ici, on suppose que les données sont déjà préparées dans numpy.ndarray
.
Tout d'abord, préparez une classe pour réécrire le format de pylearn2.
Ici, nous allons préparer une classe appelée «FacePicDataSet», qui signifie «données d'image de visage». Cette classe hérite de pylearn2.datasets.DenseDesignMatrix
.
from pylearn2.datasets import DenseDesignMatrix
class FacePicDataSet(DenseDesignMatrix):
def __init__(self, data):
self.data = data
super(FacePicDataSet, self).__init__(X=data))
Ensuite, créez un objet FacePicDataSet
train = FacePicDataSet(data=data_matrix)
Ensuite, enregistrez le fichier au format nupmy et le fichier pickle de l'ensemble de données.
from pylearn2.utils import serial
train.use_design_loc(path_to_npy_file)
# save in pickle
serial.save(train_pkl_path, train)
En gros, c'est comme apporter un modèle de tutoriel et jouer avec.
L'endroit où appeler à partir du script d'entraînement et insérer la variable est décrit avec le type `% (nom de la variable) '.
Le point est
raw: & raw_train! Pkl:
nvis:
(10000 dimensions pour 100 * 100 images)save_path:
Veuillez vous reporter à Mon fichier yaml pour le texte complet car il sera plus long.
Tout d'abord, importez le package d'utilisation. Assurez-vous d'importer la classe du fichier pickle de l'ensemble de données __
import os
from pylearn2.testing import skip
from pylearn2.testing import no_debug_mode
from pylearn2.config import yaml_parse
from make_dataset_pylearn2 import FacePicDataSet
Tout d'abord, écrivez une fonction pour l'entraînement
@no_debug_mode
def train_yaml(yaml_file):
train = yaml_parse.load(yaml_file)
train.main_loop()
De plus, lisez le fichier yaml et remplissez les variables.
yaml_file_path = path_to_yaml_file
save_path = path_to_save_file
yaml = open(yaml_file_path, 'r').read()
hyper_params = {'detector_layer_dim': 500,
'monitoring_batches': 10,
'train_stop': 50000,
'max_epochs': 300,
'save_path': save_path,
'input_pickle_path': input_pickle_path}
yaml = yaml % (hyper_params)
Enfin, exécutez la formation
train_yaml(yaml)
DeepNN a une couche cachée, et cette couche cachée correspond aux entités extraites.
Comme c'est un gros problème, j'ai également créé un script pour extraire la couche cachée.
Tout ce que vous avez à faire est de créer une image en utilisant les nombres dans nupmy.ndarray
.
Veuillez consulter ici pour une explication détaillée.
Une fois exécutées, les images correspondant au nombre de nœuds de couche masqués seront affichées de cette manière.
Les données d'origine sont mappées à l'aide des fonctionnalités apprises.
Par exemple, cette fois, les données d'origine ont 711 photos, et chaque image est de 150 * 150 = 22 500 dimensions. Par conséquent, la matrice des données originales est composée de «711 * 22500».
D'autre part, la matrice de conversion de quantité d'entités est «(le nombre de dimensions d'origine) * (le nombre de nœuds de couche cachés)». Cette fois, nous avons préparé 500 nœuds de couche cachés, c'est donc une matrice de «22500 * 500».
Par conséquent, après conversion, la matrice sera (711 * 22500) * (22500 * 500) = 711 * 500
.
Lisez les données matricielles de «711 * 22500».
Il semble que je devrais lire le fichier pickle de données d'entraînement, mais cela n'a pas fonctionné. J'obtiens une erreur due à la classe FacePicDataSet
.
Donc, cette fois, je vais lire le fichier numpy.
import numpy
datasource_ndarray = numpy.load(path_to_datasource_npy)
Ainsi, les données originales ont été lues.
Chargez ensuite le fichier d'objet pickle entraîné.
import pickle
file_obj = open(path_to_trained_model_pickle, 'rb')
model_object = pickle.load(file_obj)
De plus, récupérez la matrice de poids du calque caché
feature_vector = model_object.get_weights()
Enfin, la cartographie spatiale
Puisque feature_vector
a été transféré, il sera transféré avec T
med.
new_space_matrix = numpy.dot(a=data_matrix, b=feature_vectors.T)
Cela vous donnera la matrice transformée new_space_matrix
.
Cette opération est communément appelée «intégration».
Compressez les données d'intégration.
Cette fois, je veux créer une carte de dispersion bidimensionnelle, donc elle est toujours grande même dans un espace de 500 dimensions.
TSNE / PCA est souvent utilisé pour la compression dimensionnelle. (Je pense empiriquement)
Ces deux méthodes peuvent être facilement réalisées en utilisant scicit-learn. tSNE, [pca](http://scikit-learn.org/stable/modules/generated/sklearn .décomposition.PCA.html)
Je vais omettre l'explication détaillée, veuillez donc voir l'exemple de scikit-learn et Mon code. S'il te plait donne moi.
Créez un diagramme de dispersion interactif.
Je veux des fonctionnalités parce que c'est un gros problème. Parce qu'il prend en charge le mal
Je veux la fonction de.
Vous pouvez tout faire. Avec Bokeh!
Si vous l'utilisez avec anaconda, c'est très simple.
La commande sur la Page officielle de Bokeh se termine immédiatement.
Cependant, sachez qu'il remplacera le notebook standard ipython.
C'est une bonne idée de pouvoir basculer l'environnement python global avec pyenv.
L'avantage de Bokeh est que vous pouvez le créer avec un notebook ipython.
Je l'ai créé en utilisant un notebook ipython.
D'une manière ou d'une autre, l'explication est confuse, mais supposons que vous ayez un objet dict comme celui-ci maintenant. Les clés et les valeurs sont stockées pour le nombre de participants.
{
string: {
"major": string,
"grade": int,
"age": int,
"member_name_rubi": string,
"height": float,
"member_index": int,
"profile_url": string,
"blog_url": string,
"member_name": string,
"university": string,
"position_vector": [
float,
float
],
"photo_url": string
}
Pour créer un graphique avec Bokeh, procédez à peu près comme ceci
show (graph object)
Pour créer un objet de table Bokeh, préparez plusieurs données de liste et utilisez la méthode ColumnDataSource
.
Transformez l'objet dict pour qu'il ressemble à ceci
{
'X': [Données ici],
'Y': [Données ici],
'desc': [Données ici],
'imgs': [Données ici],
Combiné avec clé et valeur
}
X et Y peuvent être n'importe quel nom de clé tel que desc. De toute évidence, toutes les listes de valeurs doivent avoir la même longueur. Enregistrez-le sous le nom d'objet items_for_graph.
Commencez par créer un objet table pour Bokeh.
from bokeh.plotting import figure, output_file, show, ColumnDataSource
source = ColumnDataSource(
data=dict(
x=items_for_graph['X'],
y=items_for_graph['Y'],
desc=items_for_graph['labels'],
imgs = items_for_graph['images'],
univ = items_for_graph['universities'],
major = items_for_graph['major'],
height = items_for_graph['height'],
age = items_for_graph['age'],
blog = items_for_graph['blog_links'],
profile= items_for_graph['profile_links'],
)
)
Ensuite, spécifiez la fonction que vous souhaitez utiliser dans le graphique et spécifiez la taille du graphique. Dans Outils, spécifiez la fonction que vous souhaitez utiliser dans le graphique. Consultez le manuel Bokeh (http://bokeh.pydata.org/en/0.10.0/docs/user_guide/tools.html) pour plus d'informations.
from bokeh.io import output_file, show, vform, vplot
from bokeh.models import HoverTool, OpenURL, TapTool
# Import bokeh, sub modules for making scallter graph with tooltip
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn
from bokeh.models import ColumnDataSource, OpenURL, TapTool
from bokeh.plotting import figure, output_file, show
GRAPH_HEIGHT = 1000
GRAPH_WIDTH = 800
TOOLS = [WheelZoomTool(), PanTool(), ResetTool(), TapTool()]
Créez ensuite un objet graphique. Cette fois, la méthode du cercle est spécifiée pour créer un diagramme de dispersion. Si vous modifiez cela, vous pouvez tracer une ligne pour afficher la série chronologique. Regardons également le Manuel de Bokeh.
s1 = figure(plot_width=GRAPH_WIDTH, plot_height=GRAPH_HEIGHT, tools=TOOLS, title=graph_title_name)
s1.circle('x', 'y', size=10, source=source)
Enfin, créez un graphique html avec show (s1)
.
Dans Bokeh, vous pouvez en fait écrire vous-même des balises html pour créer des puces d'outils.
Par conséquent, vous pouvez écrire une balise html qui affiche une image et l'utiliser comme puce d'outil.
Pour plus d'informations ici
Vous pouvez facilement intégrer une URL en utilisant la méthode ʻOpenURL`.
Cliquez pour ouvrir l'URL dans le tableau.
Pour plus d'informations, cliquez ici [http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#openurl)
Il n'est pas possible d'afficher toutes les informations du graphique. Par conséquent, je mettrai des informations détaillées dans le tableau.
Et le haut est un diagramme de dispersion et le bas est un graphique. Vous pouvez l'afficher comme ceci.
Voir cette partie pour plus de détails.
C'est pourquoi le graphique que j'ai créé est ici. Ce graphique est le résultat de le rendre bidimensionnel avec des plongements RBM + PCA.
Voir aussi tSNE.
En comparaison, je pense que PCA a plus de visages similaires tracés de plus près.
Je pense que PCA est mieux à même de compresser les dimensions des Embeddings en deux dimensions.
C'est pourquoi, cette fois, j'ai utilisé Deep Learning pour créer quelque chose pour prendre en charge Miscon. Nous espérons que vous le considérerez comme un exemple d'utilisation du Deep Learning.
De plus, tout le code est publié sur github. Veuillez utiliser tous les moyens. Aussi, nous recherchons des personnes qui développeront ensemble des choses intéressantes. Si vous avez des idées intéressantes, n'hésitez pas à nous contacter.
Recommended Posts