Un réseau de neurones a été formé pour reconnaître les visages dans une vidéo à partir d'une photo. Comment nous avons appris à un réseau de neurones à reconnaître les robes et les chaussures Réseaux de neurones associatifs pour la reconnaissance faciale

Dans ce journal, j'écris sur tout ce que je rencontre pour la première fois. Cette fois, j'ai succombé à l'hystérie générale, et nous parlerons de réseaux de neurones convolutifs. Cette fois encore, j'essaierai de décrire en détail le processus de mes pensées, et pas seulement d'énumérer les résultats et les moyens d'y parvenir. Il y aura donc « beaucoup de bukaf ».
Pendant très longtemps, j'ai résisté à ces réseaux de neurones « sales et artificiels », préférant le SVM « pur et naturel ». Les gars sérieux résolvent des problèmes en utilisant des réseaux de neurones convolutifs depuis longtemps. J'ai besoin d'un problème simple, de préférence que j'ai déjà résolu dans un paradigme différent, afin de tester une technologie qui est nouvelle pour moi. C'est décidé : reconnaître les visages. Pour réchauffer la vidéo du produit final :
https://www.youtube.com/watch?v=mwDbGpAZdxU

Outils

Comme vous le savez, les réseaux de neurones s'entraînent beaucoup plus efficacement sur les GPU que sur les CPU. Je n'ai pas d'ordinateur de bureau avec une carte vidéo. Heureusement, il y a plusieurs années, lorsque j'ai acheté un ordinateur portable, j'ai acheté un ordinateur portable de jeu dans l'espoir de devoir maîtriser le calcul GPU, et je l'ai acheté avec une carte vidéo nvidia geforce gt 650m 2 Go. Donc, ce que j'avais quand j'ai commencé à travailler : une série d'articles sur l'apprentissage automatique, c'est amusant et tout simplement génial pour un débutant, une certaine expérience en vision par ordinateur, du matériel du site face-rec.org. Vous devez décider des outils. Bien sûr, ce sera le langage C++, la bibliothèque de vision par ordinateur opencv, mais avec le framework de reconnaissance faciale, tout s'est avéré plus compliqué. Il s'avère qu'OpenFace, qu'Adam utilise, est écrit en Python et utilise torch, qui à son tour est écrit en Lua. J'ai essentiellement besoin d'une solution monolithique en C++. Un dlib léger a été rapidement trouvé, qui disposait à l'époque d'un détecteur de visage de haute qualité, d'outils pour travailler avec des réseaux convolutifs, y compris à l'aide de GPU, mais n'avait pas de fonctionnalité de reconnaissance faciale. Juste ce dont vous avez besoin !
Commençons par le déplier. Vous devez télécharger les sources et construire en utilisant cmake. Après quelques tourments, j'ai compris que pour utiliser la carte vidéo, vous devez installer CUDA Toolkit et cuDNN à partir du site Web de Nvidia. Le chemin d'installation ne doit pas contenir d'espaces. Pour démarrer mon projet avec dlib, j'ai examiné les paramètres dans les cas de test. En plus de la liste des bibliothèques, vous devez y spécifier la définition du préprocesseur DLIB_USE_CUDA et définir les paramètres d'optimisation. J'ai également installé l'utilitaire GPUZ utile pour surveiller l'utilisation de la carte vidéo pendant l'entraînement.

J'ai exécuté plusieurs configurations de test de réseaux de neurones pour l'ensemble de données bien connu MNIST :


  • Le perceptron à deux couches a été entraîné pendant une demi-heure sur un cœur de processeur. Précision sur l'ensemble d'entraînement et sur l'ensemble de test : (0,9908, 0,9792).

  • Le réseau LeNet (Lekun) s'est entraîné pendant près de 6 heures sur un cœur de processeur et 15 minutes sur une carte vidéo ! Précision atteinte (0,99975, 0,9915).

  • Réseau ResNet - 1 heure et 15 minutes sur une carte vidéo, précision (0,9938).

  • Réseau de création - environ 4 heures sur une carte vidéo, précision (0,999217, 0,9904).

Jetons maintenant un coup d'œil à l'ensemble de formation. J'ai parcouru la liste des bases de données ouvertes, téléchargé tout ce qui pouvait être téléchargé, obtenu un accès où je pouvais accéder rapidement, téléchargé, partiellement converti, partiellement travaillé de mes mains, au final, pour commencer, j'ai obtenu une base de données de 65 000 images de 6 700 personnes différentes avec la possibilité de doubler les temps de base de données, si vous surmontez la paresse.

Énoncé du problème et première solution
Passons maintenant à la tâche principale. Je souhaite construire un classificateur assez fiable pour un petit groupe de visages (jusqu'à 100 personnes), basé sur 3 à 5 photographies de chacun. Le classificateur doit normalement « digérer » des images très variables. En effet, selon l'angle de vue, les conditions d'éclairage, la présence d'une coiffe, de lunettes et l'expression du visage, des images très différentes seront obtenues. Il est clair qu'avec un si petit échantillon de formation (3 à 5 photos d'une personne), il est logique d'utiliser uniquement un classificateur linéaire. Et nous avons besoin d'un descripteur de très haute qualité, que nous appliquerons au préalable, dont le but est de mettre en évidence les différences entre les photographies de différentes personnes et les similitudes entre les différentes photographies d'une même personne.

On sait qu'une couche du réseau neuronal effectue une division linéaire. Si la dernière couche de notre réseau neuronal classe linéairement, alorsle reste du réseau neuronal peut être considéré comme une « transformation compression-rectification » des vecteurs d’images du visage enun espace où ces personnes sont linéairement séparables. Profitons-en.


La première idée qui m'est venue à l'esprit a été d'entraîner un réseau de neurones pour rechercher les différences. Pour ce faire, fournissez en entrée une paire d'images et une indication si ces images appartiennent à la même personne ou à des personnes différentes.

Le cas échéant la grille est formée avec succès, vous pouvez alors obtenir un descripteur en soumettant quelques images, une - un descripteurÀ que nous calculons, et la seconde est n'importe quelle image, la seule chose importante est qu'elle soit toujours la même. J'ai trouvé une image moyenne d'un visage en ligne.Comme vecteur descripteur, vous pouvez prendre l'avant-dernière couche du réseau neuronal, la dernière sera composée de seulement deux neurones.


La première configuration est très simple, similaire à Lenet, elle comprend une paire de couches convolutives et trois entièrement connectées :
const statique size_t MINI_BATCH_SIZE = 128 ; //128 ; const non signé long descriptor_size = 128 ; cv const statique :: Taille DATASET_IMAGE_SIZE = ( 128 , 128 ) ; //Grille comme LeNet //LeCun, Yann, et al. "Apprentissage basé sur les gradients appliqué à la reconnaissance de documents." //Actes de l'IEEE 86.11 (1998) : 2278-2324. en utilisant net_type = dlib::loss_multiclass_log< dlib:: fc < 2 , dlib:: fc < 128 , //!!!RELU MANQUÉ ICI dlib :: relu > >>> >>> >> >> > > > ;
La formation ressemble à ceci :

Std :: cout<< "net initialization..." << std:: endl ; net_type net; //Le code ci-dessous utilise une descente de gradient stochastique en mini-lots avec un taux d'apprentissage initial de 0,01 pour y parvenir. std :: cout<< "trainer initialization..." << std:: endl ; dlib:: dnn_trainer < net_type>entraîneur(filet); //dnn_trainer entraîneur(net, adam(0,0005, 0,9, 0,999), (0, 0, 0, 0)); entraîneur.set_learning_rate(0,01); //1e-3 trainer.set_min_learning_rate (MIN_LEARNING_RATE) ; entraîneur.set_mini_batch_size (MINI_BATCH_SIZE) ; entraîneur.be_verbose(); trainer.set_synchronization_file ("lenet_faces_sync" , std::chrono::seconds (180) ) ; // Former std :: vecteur< dlib:: matrix < unsigned char >> mini_batch_samples ; std :: vecteur< unsigned long >mini_batch_labels ; dlib:: rand rnd(temps (0 ) ) ; std :: cout<< "traning..." << std:: endl ; while (trainer.get_learning_rate () >= MIN_LEARNING_RATE) ( dataset.GetInputSamplePairBatch (mini_batch_samples, mini_batch_labels, MINI_BATCH_SIZE) ; win1.set_image (mini_batch_samples[ 0 ]) ; win2.set_image (mini_batch_samples[ 1 ]) ; trainer.train_one_step (mini_batch_samples, mini_batch_ labels) ; ) // Lorsque vous appelez train_one_step(), le formateur effectuera son traitement de manière // fil séparé. Cependant, cela signifie également que nous devons attendre les mini-lots qui sont // toujours en cours d'exécution. L'appel de get_net() effectue la synchronisation nécessaire. entraîneur.get_net(); norme<< std:: endl ; net.clean () ; //Effacer le réseau des informations auxiliaires dlib::serialize("lenet_faces.dat")<< net; //Et sauvegardez-le. Pour télécharger deserialize("lenet_faces.dat") >> net;

Une fois la formation terminée, le maillage est utilisé comme descripteur. À l'aide d'un échantillon de test séparé, un classificateur linéaire est entraîné et testé dans l'espace de vecteurs obtenu à partir des réponses de la deuxième couche entièrement connectée du réseau neuronal à une paire d'images. L’échantillon de test contient environ 1 500 images représentant 15 personnes différentes. Le classificateur est formé sur 5 images par personne. Tests - pour tout le monde.
//Formation du classificateur std :: cout<< "Traning classifier..." << std:: endl ; TSVMClassifier classifier({ cv:: ml :: SVM :: POLY ,2 ,2 } ) ; static const long NL = 5 ; long i = 0 ; std:: vector < long >isum(dataset.ClassNumber()); cv:: Mat descr(1 , descriptor_size, CV_32FC1) , train_data(dataset.ClassNumber () * NL, descriptor_size, CV_32FC1) , train_classes(dataset.ClassNumber () * NL, 1 , CV_32SC1) , test_data(dataset.Size () , descriptor_size, CV_32FC1) , test_classes(dataset.Size () , 1 , CV_32SC1) , Predicted_classes(dataset.Size () , 1 , CV_32FC1) , moyenne = cv::imread (""../AveragedMan.jpg" , CV_LOAD_IMAGE_GRAYSCALE) ; dlib :: matrice< unsigned char >moyenne_dlib(DATASET_IMAGE_SIZE.height , DATASET_IMAGE_SIZE.width ) , sample_dlib; //Préparation du visage moyen TFaceDetector FaceDetector( "shape_predictor_68_face_landmarks.dat") ; std :: vecteur< dlib:: rectangle >face_rects = FaceDetector.Detect (moyenne) ; dlib :: tableau< dlib:: matrix < unsigned char >>des visages ; FaceDetector.ExtractFaces(averaged, face_rects, faces) ; if (faces.size () == 1 ) resize_image(faces[ 0 ] , Averaged_dlib) ; dlib::image_window gagner; //On s'entraîne sur 5 objets de chaque classe, et on teste sur tous pour (unsigned long idx = 0 ; idx< dataset.Size () ; idx++ ) { try { sample_dlib = dataset.GetSample (idx) ; win.set_image (sample_dlib) ; std:: cout << dataset.GetLabelIdx (idx) << " " << dataset.GetLabelByIdx (dataset.GetLabelIdx (idx) ) << std:: endl ; } catch (exception & e) { TException * E = dynamic_cast < TException * >(&e) ; si (E) std :: cout<< E- >quoi()<< std:: endl ; else std:: cout << e.what () << std:: endl ; continue ; } ; net(dataset.MakeInputSamplePair (& averaged_dlib, & sample_dlib) ) ; for (unsigned long iv = 0 ; iv < dlib:: layer < 2 >(net).get_output().size(); iv++ ) descr.at< float >(iv) = dlib :: couche< 2 >(net).get_output().host()[iv]; descr.copyTo(test_data.row(idx)); test_classes.at< long >(idx) = (long) dataset.GetLabelIdx (idx) ; si (isum[ test_classes.at< long >(idx)]< NL) { //train_data.push_back(descr); //train_classes.push_back(test_classes.at (idx)); descr.copyTo(train_data.row(i)); train_classes.at< long >(i) = test_classes.at< long >(idx); isum[ test_classes.at< long >(idx) ] ++ ; je++ ; ) ) std :: cout<< train_data.cols << " " << train_data.rows << " " << train_classes.cols << " " << train_classes.rows << std:: endl ; classifier.Train (train_data, train_classes) ; classifier.Save ("classifier.txt" ) ; //Test du classificateur linéaire std :: cout<< "Test du classificateur linéaire..."<< std:: endl ; classifier.Predict (test_data, predicted_classes) ; unsigned long num_right = 0 , num_wrong = 0 ; for (unsigned long idx = 0 ; idx < dataset.Size () ; idx++ ) if (test_classes.at < long >(idx) == (long) predit_classes.at< float >(idx) ) num_right++ ; sinon num_wrong++ ; std :: cout<< "training num_right: " << num_right << std:: endl ; std:: cout << "training num_wrong: " << num_wrong << std:: endl ; std:: cout << "training accuracy: " << num_right/ (double ) (num_right+ num_wrong) << std:: endl ; std:: cin >>c;

Le processus d'apprentissage lui-même ressemble à ceci :


On peut voir que la charge sur la carte vidéo, ainsi que sur le processeur, est minime. Est-il possible d’accélérer davantage les calculs en utilisant les ressources existantes ? Environ 10 paires par seconde ont été traitées.Le goulot d'étranglement n'était même pas la lecture à partir du disque, comme je m'y attendais, mais la détection des visages.Il existait une option permettant d'exécuter le détecteur sur toutes les images à l'avance et de sauvegarder le résultat sur le disque, puis de travailler avec.Mais je n’ai pas aimé cette option car je devrais stocker deux bases de données volumineuses sur le disque, car je peux changer de détecteur à l’avenir et je suis obligé de stocker des images « brutes » non traitées. Il existe également une option de mise en cache. L'échantillon entier est divisé en blocs qui tiennent dans la RAM. Nous sélectionnons au hasard un bloc et nous entraînons sur ses sous-ensembles aléatoires d'images jusqu'à ce que chaque image soit utilisée n une fois. Ensuite, nous passons au bloc suivant. De cette façon, vous pouvez réduire le nombre de lectures sur disque d’un facteur n.

J'ai parallélisé la détection des visages en utilisant un pool de threads de la même bibliothèque dlib, et j'ai obtenu un gain de temps de 5 à 6 fois.
struct TR ( TDataset * Dataset; bool Positif; dlib::matrix< unsigned char >Paire d'échantillons ; Étiquette longue non signée ; ) ; ... si (UseMultiThreading) ( std::vecteur< TR>trv; std :: vecteur< dlib:: future < TR>> fv(batch_size) ; pour (long non signé i = 0 ; je< batch_size; i++ ) { trv.push_back (TR() = { this , positive} ) ; fv[ i] = trv[ i] ; //Vous pouvez bien sûr vous passer de lambdas ThreadPool- > add_task_by_value( (TR & val) ( val.Dataset -> GetInputSamplePair(val.Positive, val.SamplePair, val.Label) ; ) , fv[ i] ) ; positif = ! positif; ) ; //Chaque thread a besoin de sa propre instance du détecteur, car elle peut être de différentes tailles, etc. ThreadPool-> wait_for_all_tasks() ; pour (long non signé i = 0 ; je< batch_size; i++ ) { batch_sample_pairs.push_back (fv[ i] .get () .SamplePair ) ; batch_labels.push_back (fv[ i] .get () .Label ) ; //batch_sample_pairs.push_back(tfv[i].SamplePair); //batch_labels.push_back(tfv[i].Label);) ; ) else ( pour (unsigned long i = 0 ; i< batch_size; i++ ) { GetInputSamplePair(positive, sample_pair, label) ; batch_sample_pairs.push_back (sample_pair) ; batch_labels.push_back (label) ; positive = ! positive; // Exemples alternatifs positifs et négatifs } ; }

Maintenant, le processus d'apprentissage ressemble à ceci :

À en juger par la charge sur le processeur, le GPU et le disque dur, le seul moyen d'accélérer considérablement les choses est désormais de remplacer le matériel.

P.S. Je déteste Livejournal pour limiter la taille des articles. C'est en partie pourquoi je lance mon site delirium.su, sur lequel je prévois, entre autres, de maintenir une version complète du blog.

Rechercher des vêtements à l’aide d’une photo de votre téléphone est réservé aux filles, dites-vous. Ce n'est pas pour les informaticiens sérieux, dites-vous. Et en général, où est la technologie hautement scientifique, et où est le mmm... le monde de la mode et du glamour vanille ?

Lorsqu'en 11 nous sommes devenus résidents du cluster informatique de Skolkovo et avons signé un peu plus tard un contrat avec Odnoklassniki pour développer un programme informatique complexe de détection de visages, nous avons également pensé de la même manière. Par exemple, nous travaillerons dans des domaines scientifiques sympas toute notre vie, pas de bonbons pour vous.

Mais quelque temps plus tard, en étudiant les statistiques mondiales sur la recherche visuelle, le commerce en ligne et mobile, les tendances générales du marché mondial de la vente au détail, nous avons réalisé que l'intérêt des entreprises pour la reconnaissance mobile des vêtements, chaussures et accessoires (au sein de l'équipe, nous appelons cela le mot général mode) ) connaît une croissance rapide.

Illustrons.

Quelques chiffres

Les industries de l'habillement, de la mode et du luxe constituent un marché très prometteur. Les spécialistes du marketing et les financiers de McKinsey affirment dans leur étude que l’industrie mondiale de l’habillement connaîtra une croissance à deux chiffres entre 2014 et 2020. En outre, la croissance sera due aux marchés émergents (la Russie, bien entendu, s'applique également ici) et en grande partie aux acheteurs asiatiques (le taux d'urbanisation de la Chine est aujourd'hui 10 fois plus rapide que celui de la Grande-Bretagne au XIXe siècle).

Si nous ne parlons que du marché des vêtements pour femmes, sa croissance dans les 12 prochaines années sera supérieure à 50 % dans le monde (selon l'étude McKinsey - Unleashing Fashion Growth City by City).

Les vêtements sont triés. Nous avons réalisé que le marché est en croissance, ce qui signifie qu'il existe des opportunités de développement technologique. Bien.

Ensuite, nous avons commencé à étudier les tendances des achats en ligne. Nous avons regardé en Amérique. En 2015, 205 millions d'Américains (sur une population de 325 millions, soit plus de 60 %) ont au moins une fois recherché un produit sur Internet, comparé les prix ou acheté quelque chose en ligne. On s'attend à ce que d'ici 2019, ce chiffre atteigne 224 millions.

Une tendance similaire est observée à l’échelle mondiale : une étude réalisée pour la Conférence des Nations Unies sur le commerce et le développement indique que d’ici 2018, environ 1,623 milliard de personnes dans le monde achèteront des biens et des services en ligne (contre 1,039 milliard en 2013).

Dans le même temps, il est intéressant de noter que le segment du commerce mobile (c’est-à-dire les achats effectués à partir d’appareils mobiles) est également en croissance. Rien qu'aux États-Unis, selon les prévisions d'eMarketer, les revenus du commerce de détail mobile atteindront 130,12 milliards de dollars d'ici 2018 (contre 56,67 milliards de dollars en 2014), soit plus du double.

La tendance mondiale à la « mobilisation » des achats en ligne est également évidente. Goldman Sachs a publié un rapport selon lequel sur 5 ans le segment du m-commerce en termes de nombre d'utilisateurs va croître 5 fois : de 379 millions d'utilisateurs en 2013 à plus d'1 milliard d'acheteurs en 2018 (à noter que le rapport ne prend pas en compte les achats en ligne dans le segment "Voyage").

Il faut dire que les vêtements, selon les recherches de Nielsen, sont la catégorie la plus fréquemment achetée en ligne. Seuls les livres, les fournitures de bureau et la musique lui font concurrence.

En substance, c'est ce qui se passe : à présent que le marché de l'accès à Internet a atteint son point de saturation, la croissance du nombre d'utilisateurs a considérablement ralenti (prévue à 5-10 % dans les années suivantes). La croissance du marché des smartphones se dirige également vers zéro.

Regardez par exemple la présentation du discours de Mark Zuckerberg lors de la conférence Facebook F8.

Cela signifie qu’Internet et le marché des smartphones sont devenus ce qu’on appelle une marchandise, un bien de consommation, faisant partie de la vie quotidienne. Mais les achats via des appareils mobiles sont de nouveaux modèles de comportement qui ouvrent la voie au développement de nouvelles technologies.

Tous ces faits nous ont servi de base pour réfléchir à la manière dont nous pouvons appliquer notre technologie de réseau neuronal et faire quelque chose d'intéressant et nécessaire dans ce domaine. Ainsi, en 2014, nous avons commencé à développer un système mobile de reconnaissance des vêtements.

Comment et pourquoi apprendre au système à reconnaître les robes ?

L'idée même de la reconnaissance mobile est simple : l'utilisateur voit un article de mode qu'il aime (sur une personne dans la rue, dans une vitrine ou sur la couverture d'un magazine), le prend en photo sur un appareil mobile, télécharge la photo sur l'application mobile installée, qui reconnaît le produit dans l'image et sélectionne des produits similaires dans l'assortiment du magasin. Bien entendu, les marchandises peuvent être achetées immédiatement. Tous.

Autrement dit, les attentes des utilisateurs vis-à-vis du service peuvent se réduire à trois étapes : vu - photographié - acheté.

Pour développer et construire un tel système, nous avons dû traiter plus de 30 000 000 d'images, comprendre la différence entre un pull et un pull (il y a aussi des pulls et des cardigans, et ce sont toutes des choses différentes), des derby et des monks, un duffle et un fourre-tout. sacs, et ouvrir notre « kunstkamera », louer des mannequins, se sentir comme de jeunes créateurs de mode (enfin, pas vraiment jeunes, d'accord) - et bien plus encore. Mais tout d’abord.

Nous avons décidé de construire le système de reconnaissance mobile sur les réseaux de neurones est la quintessence de la technologie du deep learning. Les réseaux imitent le travail des neurones du cerveau humain en termes d'apprentissage et de correction des erreurs : le réseau apprend de manière indépendante (avec suffisamment de données d'entraînement) et agit sur la base de l'expérience antérieure, commettant de moins en moins d'erreurs à chaque nouvel apprentissage.

Un neurone est un élément informatique distinct d’un réseau ; chaque neurone est connecté aux neurones des couches précédente et suivante du réseau. Lorsqu'une image, une vidéo ou un fichier audio arrive en entrée, elle est traitée séquentiellement par toutes les couches du réseau. En fonction des résultats, le réseau peut changer sa configuration (les paramètres de chaque neurone).

Pour notre tâche, les réseaux de neurones sont utiles car, compte tenu de la quantité de données d'entraînement requise, ils peuvent apprendre à reconnaître presque n'importe quel type d'objet.

Étape 1 : Tout savoir sur la mode

Ainsi, d'un point de vue technologique, le système doit fonctionner dans la séquence suivante : analyse de la photo chargée par le système - mise en évidence des zones contenant potentiellement un produit - détermination de la catégorie du produit - séparation d'un objet de l'arrière-plan - création d'une empreinte numérique de l'image du produit - recherche de produits similaires dans une catégorie donnée.

Le premier point du plan R&D était la création d’une classification correcte, complète et précise de la mode.

Nous avons décidé de commencer par la classification des chaussures. Et pour les femmes, il nous semblait que c'était plus facile (on aurait dû se signer tout de suite, imbéciles naïfs). Nous comprenons : pour que le système reconnaisse correctement les catégories, nous avons besoin d'une classification détaillée des types de chaussures pour femmes. Ils ont utilisé Wikipédia, des dictionnaires explicatifs, des sites de magasins de chaussures en ligne et des images de Google comme ceci :

Parallèlement à la recherche d'images par catégorie et au balisage, nous avons créé un dossier interne « Kunstkamera », qui a commencé à s'alimenter d'exemples de chaussures insolites (voire carrément étranges), dont certaines que nous voulions immédiatement « ne pas voir ». Par exemple, nous avons les expositions suivantes :

Bien entendu, nous n’avons pas pris de telles images pour former le réseau. C'est pour moi – « juste pour rire » (c).

Et on s’est rendu compte qu’il existe des chaussures unisexes. Par exemple, les catégories de chaussures telles que les espadrilles, les mocassins ou les chaussures Timberland peuvent avoir une apparence très similaire, tant pour les hommes que pour les femmes.

Au total, nous avons classé 10 catégories comme unisexes.

Ainsi, au total, nous avons identifié un peu moins de 100 catégories de chaussures, après quoi nous avons résumé les défis auxquels nous avons dû faire face à cette étape.

D'abord- C'est une classification en soi. Quelles catégories faut-il mettre en avant ? Seront-ils trop petits ? Ou au contraire excessivement agrandi ?

Ici, nous avons été aidés par la structure des catalogues de nos clients finaux - les boutiques en ligne. Nous nous sommes basés sur leur catégorisation et l'avons amenée à une forme qui puisse satisfaire nos exigences (être universelle pour les magasins russes et américains, ni trop générale ni trop détaillée).

Deuxième– controverse sur la classification de certains produits dans une certaine catégorie. Par exemple, qu'est-ce que c'est ? Des bottines ou des baskets ?

Extérieurement, bien sûr, elles ressemblent à des bottines, mais sur les sites Web de certaines boutiques en ligne, ces chaussures sont classées comme des baskets. Comment savoir dans quelle catégorie le client souhaitera rechercher des bottes similaires ?

Troisième– détail du classificateur. Il fallait parfois devenir « ennuyeux » et, pour une recherche plus précise, sélectionner des catégories supplémentaires qui ne correspondent pas toujours aux catégories de magasins (à ne pas confondre avec les filtres de recherche !) afin d'obtenir de meilleurs résultats de reconnaissance.

C’est ainsi que nous avons obtenu des bottines compensées, des bottines à talons aiguilles, des bottines à talons larges, des bottines avec fourrure, etc.

Quatrième– difficulté à sélectionner les images dans certaines catégories. Il fut un temps où, par exemple, les images de chaussures bateau ne pouvaient être trouvées que sur des ressources étrangères - ces chaussures n'étaient pas encore largement représentées dans nos magasins.

ET dernière chose. Nous ne comprenions pas comment le neurone se comporterait pour déterminer le matériau de la chaussure. Autrement dit, le réseau de bottes hautes en cuir recherchera-t-il spécifiquement des bottes en cuir, ou les résultats de la recherche contiendront-ils toutes les bottes de forme similaire, mais de matériaux différents ?

Et du coup, nous ne savions pas s’il fallait séparer les catégories par matière : chaussures en cuir, chaussures en daim, chaussures en tissu, etc.

Pour les tests, nous avons créé 2 catégories : « Bottes en daim » et « Bottes en cuir » (elles se chevauchent bien sûr avec d'autres catégories - bottes hautes, bottes compensées et autres). Le réseau les reconnaît correctement. Mais en fin de compte, nous n'avons pas divisé tous les types de chaussures par matériau en catégories qui ne se chevauchent pas - cela aurait été inutile. Mais ces deux catégories « historiquement établies » ont été laissées. Ils ne gênent pas le bon travail.

En général, après avoir préparé un classificateur de chaussures, nous avons commencé à nous considérer comme un mélange d'Alexander Vasiliev, Vyacheslav Zaitsev et Valentin Yudashkin.

Notre correspondance interne

Puis, selon le même principe, nous avons commencé à distinguer les sacs pour femmes et pour hommes, puis les vêtements pour femmes et pour hommes.

Étape 2 : Entraînez les réseaux de neurones pour distinguer les moines des mocassins et un pull d'un pull.

Nous avons donc identifié les catégories de mode avec lesquelles notre système fonctionnera. Nous devons maintenant entraîner les réseaux de neurones à reconnaître les catégories dans une photo : c'est-à-dire déterminer où se trouve l'objet souhaité dans l'image et le classer correctement.

Pour entraîner un réseau de neurones à reconnaître une catégorie, la première chose à faire est de sélectionner et de télécharger sur le réseau (nous appelons ce processus « alimenter les réseaux ») un nombre considérable d'images : de mille à plusieurs centaines de milliers.

Autrement dit, pour apprendre au système à reconnaître la catégorie « Chaussures à talons hauts », vous devez télécharger sur Internet au moins deux mille images différentes de chaussures à talons hauts. Le principe est simple : plus de données d’entraînement signifie de meilleures performances du réseau (plus précisément, la reconnaissance).

Le téléchargement des images pour la formation se fait à moitié automatiquement par nos algorithmes internes, à moitié manuellement. Ensuite, l’ensemble des photographies est vérifié pour s’assurer qu’il n’y a pas de doublons ou d’images inappropriées prises au hasard. De plus, tous les fichiers reçoivent des noms uniformes et le même format (extension).

Et puis commence la partie la plus difficile : marquer manuellement les produits sur l’image. Nos collaborateurs dessinent un cadre autour du produit sur la photo et déterminent sa catégorie.

Par exemple:

Cela est nécessaire pour que le système comprenne : exactement ce qu'il y a dans le rectangle est un produit d'une certaine catégorie. Le travail de marquage prend le plus de temps : la tâche est laborieuse et n'avance pas très vite. Si vous mesurez les heures de travail consacrées au marquage des tasses de café, le résultat sera de plus d'une tonne de boisson revigorante.

Avec quoi te bats-tu ?

Lors de l'étape de marquage, le manque d'expérience et de prévoyance s'est retourné contre nous : après avoir identifié de nouvelles catégories de sacs et de vêtements, nous avons dû ré-étiqueter les photographies de chaussures précédemment marquées pour en faire de nouveaux produits. En raison du manque de marquage pour les nouvelles catégories, le système a trouvé des vêtements, mais a considéré qu'il s'était trompé et a ajouté les produits trouvés au « fond ».

Autrement dit, si nous identifiions d'abord toutes les catégories possibles de chaussures, de vêtements et d'accessoires (amenons le classificateur sous la forme qu'il est actuellement) et marquons ensuite les images sur Tous catégories à la fois, nous économiserions alors beaucoup de ressources.

Un autre goulot d'étranglement était que plusieurs employés étaient impliqués dans le marquage. Et il se trouve que chacun avait sa propre compréhension de quel vêtement appartenait à quelle catégorie (nous avons parlé de cas controversés ci-dessus). Par conséquent, un employé responsable a été nommé qui a accepté les photographies marquées de ses collègues et a revérifié tous les dossiers et images pour l'exactitude des marquages.

Voici à quoi ressemble notre classificateur de mode en prenant comme exemple les chaussures pour femmes (une des pages) :

Les réseaux de neurones sont désormais largement utilisés pour le traitement et la reconnaissance d'images, dans les systèmes de reconnaissance vocale, l'analyse vidéo et la sécurité intellectuelle. Les réseaux créent de la musique ( Jukedeck). Le moment n’est pas loin où apparaîtront les robots des réseaux neuronaux, qui remplaceront l’intelligence humaine dans un certain nombre d’activités (par exemple, dans un centre d’appels conseillant un client sur des questions fondamentales).

De manière générale, il faut dire que beaucoup de personnes sont impliquées dans les réseaux. Ce sont les requins du marché Internet : "Yandex"(par exemple, leur fonctionnalité récente pour Auto.ru - reconnaître la marque et le modèle d'une voiture à partir d'une image), Microsoft(service What-Dog.net, identifiant les races de chiens à partir de photos), Mail.ru Et Facebook(une division de Facebook AI Research) et, bien sûr, Google. Mais ce sont aussi de jeunes startups (uniquement celles qui disposent de suffisamment de fonds pour la puissance de calcul).

Les réseaux sont étudiés avec diligence dans les universités techniques du monde entier, en particulier dans MIPT Peut-être souhaitez-vous désormais également vous impliquer dans des réseaux. Cool!

Ensuite, nous exprimerons immédiatement deux points auxquels vous devez vous préparer.

Disons encore une fois qu’une partie importante de la technologie réside dans les données de formation. C'est le premier « mais ». Pour que le réseau puisse réussir à distinguer un type d'objet, il est nécessaire de collecter plusieurs milliers d'exemples de cet objet sur lesquels une formation serait réalisée. Souvent, le nombre d’objets se compte par centaines. Les bases de données de formation finales peuvent compter des centaines de milliers ou des millions d'objets.

Par conséquent, la préparation de la base est un processus très laborieux. Parfois, des startups viennent nous voir et nous disent : nous voulons faire de la reconnaissance comme Pinterest, avec des liens vers des produits d'Amazon. « Cool », disons-nous, « nous pouvons arranger ça. Mais il faut beaucoup d’images pour chaque produit pour que le réseau fonctionne. Pouvons-nous le récupérer ? Après cela, pour une raison quelconque, les clients disparaissent dans l'espace.

Même s'il faut noter que diverses technologies d'apprentissage accéléré font désormais leur apparition. Par exemple, un tableau accessible au public d'images déjà formées ImageNet; des réseaux de neurones pré-entraînés capables de reconnaître des images et ne nécessitant pas une longue préparation du réseau pour fonctionner.

Les progrès sont également visibles du côté matériel : il existe des cartes vidéo hautes performances qui permettent de former et d'utiliser les réseaux plusieurs centaines de fois plus rapidement.

Deuxièmement, le stockage et le traitement de grandes quantités de données nécessitent une puissance de calcul et des fonds d'infrastructure importants. Pour la formation et le fonctionnement du réseau, des cartes avec au moins 3 à 4 Go de mémoire sont nécessaires, et pour certaines architectures, les 11 Go sont requis. Les cartes ne sont pas bon marché : un petit projet nécessite une carte coûtant environ 100 000 roubles. De plus, beaucoup d’espace disque est requis pour les données elles-mêmes.

Ainsi, la technologie des réseaux neuronaux se développe largement et la demande est grande. Sur Internet, vous trouverez de nombreuses publications et recherches sur le sujet ; même le code des programmes pour les réseaux est disponible. Autrement dit, d’une part, la technologie semble être largement disponible, mais d’autre part, elle reste pour le moment complexe et mal comprise. Les grandes entreprises organisent régulièrement toutes sortes de concours pour les meilleurs algorithmes, et souvent la bataille ne porte que sur les dixièmes et centièmes de la précision des algorithmes.

Ainsi, avec notre article sur la reconnaissance mobile dans le domaine de la mode, nous sommes arrivés en finale KDD, la plus grande conférence au monde dans le domaine de la découverte de connaissances et de l'exploration de données. Le texte du rapport est disponible sur le lien.

Nous continuons à travailler sur le développement de la technologie.

En contact avec

Reconnaissance de visage Il s'agit d'un problème fondamental dans le domaine de la vision par ordinateur et d'une étape clé vers la création d'applications capables de reconnaître et de distinguer les personnes grâce à leur visage. Les méthodes de reconnaissance faciale ont été activement étudiées au cours des 20 dernières années, au cours desquelles des méthodes précises et efficaces ont été proposées, fonctionnant dans certaines conditions.

Les techniques modernes de reconnaissance faciale ont obtenu des résultats impressionnants lorsqu'on travaille avec des images de visages moyens et grands. l'efficacité du travail avec de petites images n'est pas satisfaisante. La principale difficulté lors de la reconnaissance des petits visages (par exemple, d'une taille de 10 x 10 pixels) est le manque de détails du visage permettant de le distinguer de l'arrière-plan. Un autre problème est que les méthodes actuelles de reconnaissance de visage sont basées sur des réseaux neuronaux convolutifs et utilisent des cartes de caractéristiques convolutives avec un faible taux d'échantillonnage et un grand pas pour représenter un visage (8, 16, 32), qui perdent des informations et sont trop imprécises pour décrire de petits visages. images de taille .

Pour surmonter ces difficultés et parvenir à une meilleure reconnaissance des visages, un réseau neuronal convolutif universel basé sur un réseau neuronal antagoniste génératif classique a été proposé. Il se compose de deux sous-réseaux : Générateur Et discriminateur.

Le générateur utilise un réseau neuronal SRN (réseau super-résolution) pour augmenter la résolution. Contrairement à l'amélioration de la résolution bilinéaire, SRN n'ajoute pas d'artefacts aux images générées et améliore leur qualité grâce à des facteurs d'échelle importants. Malgré cela, en utilisant SRN et d’autres réseaux neuronaux avancés, les chercheurs ont reçu des images très floues et sans détails fins. Ceci est une conséquence de la très faible résolution des images d’entrée.

Un réseau neuronal « amélioré » a été utilisé pour restaurer les détails manquants dans les images résultantes et créer des images précises à haute résolution pour les tâches de classification. RN (réseau de raffinement). Les images finales et réelles passent par un discriminateur qui détermine si les deux images sont réelles ou créées, et si elles montrent des visages ou non. Le retour amène le générateur à créer des images avec des traits du visage plus précis.

Architecture du réseau neuronal

Examinons d’abord la structure du générateur. Il se compose de deux parties — Réseau neuronal SRN et réseau neuronal d'amélioration. Le premier réseau neuronal augmente la résolution de l'image d'entrée. Parce que les images de petits visages manquent de détails et également en raison de l'influence de la perte quadratique moyenne, Les images générées par le premier réseau de neurones sont généralement floues. Par conséquent, un deuxième réseau neuronal est utilisé pour améliorer ces images. Finalement une branche de classification pour la reconnaissance faciale est ajoutée au discriminateur, qui permet au discriminateur de classer les visages et autres objets, et de faire la distinction entre les images générées et réelles.

Architecture du générateur et du discriminateur

Générateur

Le réseau neuronal amélioré du générateur présente une architecture de réseau neuronal convolutif. Après chaque couche convolutive, à l'exception de la dernière, une normalisation (normalisation par lots) et une activation de ReLU ont été effectuées.

Le réseau neuronal SRN du générateur augmente de 4 fois la résolution des fragments d'image sélectionnés. Les fragments résultants étaient flous si le visage était éloigné de la caméra ou en mouvement. Améliorer le réseau neuronal traite ces fragments et produit des images plus détaillées, dans lequel le discriminateur peut facilement reconnaître les visages.

Discriminateur

Le discriminateur utilise le réseau neuronal comme réseau neuronal principal VGG19, à partir de laquelle la couche de sous-échantillonnage a été supprimée pour éliminer diverses opérations de réduction de résolution. De plus, toutes les couches entièrement connectées (c'est-à-dire f c6, f c7, f c8) sont remplacées par deux couches parallèles entièrement connectées. fcGAN et fcclc. Une image de résolution accrue est fournie à l'entrée. La branche fcGAN donne la probabilité que l'image d'entrée soit réelle, et la branche fcclc donne la probabilité que l'image d'entrée contienne un visage.

Fonction de perte

Perte par pixel : L'entrée du générateur est constituée de petites images floues, pas de bruit aléatoire. Un moyen naturel de rendre l'image de sortie du générateur proche de l'image réelle consiste à utiliser l'erreur quadratique moyenne par pixel, qui est calculée comme suit :

où ILR et IHR désignent respectivement de petits fragments flous (basse résolution) et des images haute résolution (haute résolution), G1 — réseau neuronal SNR, G2 — amélioration du réseau neuronal, w- Paramètres du générateur.

Pertes contradictoires : Pour obtenir des résultats plus réalistes, des pertes contradictoires sont introduites, définies comme :

La perte contradictoire oblige le réseau neuronal à générer des détails haute fréquence plus précis afin de « tromper » le discriminateur.

Pertes de classement : Pour rendre plus faciles à reconnaître les images restituées par le générateur, des pertes de classification sont introduites. La formule de calcul des pertes de classement est la suivante :

Les pertes de classification sont utilisées pour deux raisons. Premièrement, ils permettent au discriminateur de déterminer si les images réelles et générées contiennent ou non des visages. Et deuxièmement, ils stimulent le générateur pour créer des images plus détaillées.

Fonction objectif : les pertes contradictoires et de classification sont incluses dans la perte efficace par pixel. Un réseau neuronal antagoniste génératif peut être formé à l'aide d'une fonction objective. Pour un meilleur comportement du gradient, les fonctions de perte du générateur G et du discriminateur D ont été modifiées comme suit :


La première équation comprend les pertes contradictoires, quadratiques moyennes et de classification, ce qui rend les images reconstruites similaires aux images réelles à haute résolution aux niveaux de détail à haute fréquence, de pixel et sémantique, respectivement. La fonction de perte du discriminateur D dans la deuxième équation ajoute une perte de classification pour déterminer si les visages sont présents dans les images haute résolution. En ajoutant une perte de classification, les images reconstruites par le générateur sont plus réalistes que les résultats optimisés à l'aide de pertes quadratiques contradictoires et moyennes.

Des scientifiques russes ont proposé une nouvelle méthode pour reconnaître les personnes dans les vidéos en utilisant un réseau neuronal profond. L'approche ne nécessite pas un grand nombre de photographies ; elle peut améliorer considérablement la précision de la reconnaissance par rapport aux analogues connus auparavant, même si une seule photographie frontale d'une personne est disponible. Les résultats des travaux ont été publiés dans les revues Expert Systems with Applications () et Optical Memory and Neural Networks ().

Récemment, ce sont les réseaux de neurones ultra-précis qui font le meilleur travail pour reconnaître les visages. Pour qu’un tel système fonctionne mieux, il doit montrer autant d’échantillons de photographies que possible. Au cours du processus d'apprentissage, le système identifie les caractéristiques clés et établit des liens entre elles, puis utilise les connaissances acquises pour reconnaître les images inconnues. Pour des données contrôlées, c’est-à-dire avec la même position dans le cadre, le même éclairage, etc., la précision des algorithmes permet depuis longtemps d’obtenir des résultats comparables à ceux des humains. Mais il reste difficile d’atteindre une grande précision dans la reconnaissance des données vidéo collectées dans des conditions incontrôlées, avec des éclairages, des angles et des tailles variables.

Afin de résoudre ce problème, des chercheurs de la Higher School of Economics ont utilisé la théorie des ensembles flous et la théorie des probabilités. Ils ont développé un algorithme qui peut améliorer la précision de l'identification des visages à partir d'une vidéo de 2 à 6 % par rapport aux expériences menées précédemment.

Comme base de test, les chercheurs ont utilisé plusieurs ensembles de données traditionnels pour évaluer les méthodes de reconnaissance vidéo des visages : IJB-A (IARPA Janus Benchmark A) et YTF (YouTube Faces). Ces ensembles comprennent des images accessibles au public de personnes célèbres (acteurs, politiciens, personnalités publiques) qui ont été collectées à partir de sources ouvertes dans des conditions incontrôlées à différents moments. L'algorithme était censé reconnaître les visages sur les vidéos YouTube, en utilisant comme échantillons plusieurs photographies des mêmes personnes provenant d'un autre ensemble de données - LFW (Labeled Faces in the Wild). LFW a utilisé une résolution plus élevée et les photographies ont été prises à différentes époques, allant des années 1970 aux années 2010.

La nouvelle approche utilise des informations sur la façon dont les photographies de référence sont liées les unes aux autres, c'est-à-dire à quel point elles sont proches ou éloignées les unes des autres dans un modèle mathématique. Dans ce cas, le lien entre des personnes similaires est moindre, entre des personnes différentes - plus. Connaître à quel point les personnes sont différentes les unes des autres permet au système de corriger les erreurs lors du processus de reconnaissance des images vidéo.

« L’algorithme évalue à quel point une image est plus proche d’une personne et à quel point une autre est plus proche d’une autre. Il compare ensuite à quel point les deux personnes se ressemblent. Ensuite, il ajoute une troisième personne et évalue de qui il est le plus proche - la première ou la seconde. Grâce à cette proximité, il corrige une fois de plus les erreurs de reconnaissance », explique le professeur Savchenko.