Je t'avoue que je ne connais pas assez le C++ pour te guider plus avant dans ce langage. Par contre, les algorithmes sous-jacents peuvent être discutés quel que soit le langage.
Il me semble que, si ta fonction index retournait, non pas la valeur la plus faible (en termes de distance), mais toutes les distances, on progresserait. En effet, ce n'est pas du tout la même chose d'avoir (Arnaud, Bérénice, Chimène) = (80.3, 81.2, 79.8) et (Arnaud, Bérénice, Chimène) = (104.5, 257.4, 79.8) : dans le premier cas, tu as en réalité pas mal d'incertitude, alors que dans le second, il y en a peu.
Tu peux mesurer de façon simple la précision d'une estimation : il s'agit du rapport entre la meilleure estimation et son concurrent le plus proche (en partant du principe qu'une distance de 0 correspond à une correspondance exacte). Pour te donner un exemple en R : precision = distance[1] / distance[2] - 1
Où distance est le vecteur des distances aux ensembles d'apprentissages des différents individus, trié de la plus faible à la plus élevée (en R, l'indexation des vecteurs commence à 1).
Donc là, tu as déjà plus d'info.
Ensuite, l'intérêt de récompenser le robot quand il te reconnaît, c'est d'augmenter la taille de l'ensemble d'apprentissage. Bien sûr, le robot n'est pas "content" de recevoir une récompense : par contre, il a une image de plus dans son ensemble d'apprentissage, qui améliorera la précision de ses reconnaissances futures. De même si tu le corriges. Par contre, il peut être amusant d'implémenter ça sous une forme plus ludique que oui/non : bravo, "Non, c'était Bérénice" peuvent être implémentés comme mots-clefs. Le top serait qu'il ait aussi une certaine reconnaissance vocale pour pouvoir interagir avec lui : ainsi, tu n'aurais qu'à dire "bravo !" et il comprendrait.
Intéressons-nous maintenant à cette grandeur, la distance (je vais continuer de l'appeler distance, c'est plus simple). La question est de la combiner avec d'autres grandeurs qui apportent de l'information. Une solution est de tout passer en probabilité. Pour ce faire, on peut employer une régression logistique. Il te faut : un ensemble d'images d'apprentissage de la distance, un second ensemble d'images (différent !) d'apprentissage de la régression logistique, et une phase de test avec un troisième ensemble d'images de test, encore différent. À chaque image doit associé un booléen : TRUE si tu es sur l'image, FALSE si tu en es absent.
Dans un premier temps, tu entraînes ton FaceRecognizer avec l'ensemble 1. Puis tu lui fais reconnaître ton second ensemble d'images. Tu enregistres alors les distances proposées et le booléen associé à chaque image. Tu devrais alors obtenir deux vecteurs : un vecteur de booléens et le vecteur des distances associées.
On va maintenant estimer bêta0 et bêta1 au maximum de vraisemblance dans le cadre d'une régression logistique. Une régression logistique est une technique statistique destinée à attribuer à un jeu de données prenant ses valeurs dans R (l'ensemble des réels, pas le langage) une probabilité (prenant ses valeurs dans [0,1]).
Le principe de la régression logistique est le suivant :
On construit un prédicteur linéaire Y = beta0 + beta1*X1 + beta2*X2 + ... où les Xi sont les variables prédictrices.
On calcule P la probabilité d'avoir boolean = TRUE : P = 1/(exp(Y) +1)
On calcule la vraisemblance globale. La vraisemblance d'un individu (ici, l'individu est une image de l'ensemble 2) est donnée par vraisemblance = X - P + 1, où P est la proba calculée à l'étape précédente et X vaut 1 si boolean = TRUE, 0 sinon (la vraie formule de la vraisemblance est plus complexe, mais dans ce cas particulier, cette formule est exacte). La vraisemblance globale est égale au produit des vraisemblances individuelles. Comme il est difficile de travailler avec des valeurs très faibles, il est courant de passer par la log-vraisemblance : c'est tout simplement le logarithme de la vraisemblance. La log-vraisemblance globale est alors la somme des log-vraisemblances individuelles.
On ajuste alors successivement beta0 et beta1 pour maximiser la log-vraisemblance globale (ou la vraisemblance. C'est équivalent puisque la fonction log est strictement croissante)
À la fin, on obtient beta0 et beta1. On peut alors répéter l'algo pour calculer, avec ces valeurs de beta0 et beta1, une proba pour toute valeur de distance.
Tu peux accélérer l'algorithme en centrant tes données. Pour ce faire, tu définis : distance_centree[i] = distance[i] - mean(distance)
Ce qui revient à retirer à chaque valeur de distance la moyenne des distances dans l'ensemble d'apprentissage. On peut alors démontrer que beta0 = exp(P/(1-P)) où P est la probabilité moyenne d'observer TRUE : P est tout simplement ta proportion d'images où tu apparais. Du coup, on n'a plus qu'à estimer beta1.
Cet algorithme peut être encore amélioré en observant la distribution de tes distances. Pour ce faire, passe-lui un jeu de photos et trace l'histogramme de tes distances. Plus l'histogramme a une gueule de loi gaussienne, meilleurs seront les résultats. À toi de trouver la fonction (monotone) qui donne la meilleure gueule à cet histogramme.
Ensuite, il s'agit de tester cet algorithme. Passe-lui le jeu de photos numéro 3 et contrôle qu'il te sort une proba plus élevée (en moyenne) pour les photos où tu te trouves que pour celles dont tu es absent.
Une fois que tu es satisfait, passons à l'intégration du temps et de l'espace. À toi de voir comment découper le temps. Tu peux faire des tranches horaires rigides (je pars toujours au boulot à 8h45) ou souples (entre 8h30 et 9h, la probabilité que je sois parti croît linéairement de 0 à 0,9, elle est de 0,9 à 9h et elle reste à 0,9 jusqu'à 18h). Bien sûr, c'est un exemple simple, mais tu vois l'idée.
Là encore, il va s'agir d'assigner à chaque couple (temps, lieu) une proba de te trouver. Tu peux initialiser cette proba (par exemple, elle est de 0,9 pour le salon à 19h30 au lancement du robot) mais tu dois pondérer cette initialisation. Par exemple, tu peux dire qu'à l'initialisation, le robot croit t'avoir déjà trouvé 9 fois dans le salon dans cette tranche horaire et 1 fois hors du salon. Ainsi, au fur et à mesure que ton robot vieillira, le poids des a priori s'effacera devant la dure réalité.
On a alors : une proba de t'avoir trouvé sachant l'image et une proba de t'avoir trouvé sachant (temps, lieu). Comment on les combine ? Le plus simple est de les multiplier. Si la proba finale est supérieure à 0,5, le robot se plantera moins d'une fois sur 2 en croyant t'avoir trouvé. Si elle est inférieure à 0,5, il se plantera moins d'une fois sur 2 en croyant ne pas t'avoir trouvé.
Avec le temps, et l'augmentation de l'ensemble d'apprentissage, ton robot s'améliorera... S'il a la puissance de calcul pour, et si l'algo de reconnaissance d'image fait bien son boulot. Peut-être que tu te retrouveras obligé de déporter le calcul vers ton PC, et le robot se contenterait d'obéir aux ordres de ton PC. Ça dépend de la quantité de calculs requis.
Ça, ce sont les sources. Le mouton que tu veux est dedans.
[^] # Re: confiance
Posté par Liorel . En réponse au journal Mon ami se fait des amis. Évalué à 6.
Je t'avoue que je ne connais pas assez le C++ pour te guider plus avant dans ce langage. Par contre, les algorithmes sous-jacents peuvent être discutés quel que soit le langage.
Il me semble que, si ta fonction index retournait, non pas la valeur la plus faible (en termes de distance), mais toutes les distances, on progresserait. En effet, ce n'est pas du tout la même chose d'avoir (Arnaud, Bérénice, Chimène) = (80.3, 81.2, 79.8) et (Arnaud, Bérénice, Chimène) = (104.5, 257.4, 79.8) : dans le premier cas, tu as en réalité pas mal d'incertitude, alors que dans le second, il y en a peu.
Tu peux mesurer de façon simple la précision d'une estimation : il s'agit du rapport entre la meilleure estimation et son concurrent le plus proche (en partant du principe qu'une distance de 0 correspond à une correspondance exacte). Pour te donner un exemple en R :
precision = distance[1] / distance[2] - 1Où
distanceest le vecteur des distances aux ensembles d'apprentissages des différents individus, trié de la plus faible à la plus élevée (en R, l'indexation des vecteurs commence à 1).Donc là, tu as déjà plus d'info.
Ensuite, l'intérêt de récompenser le robot quand il te reconnaît, c'est d'augmenter la taille de l'ensemble d'apprentissage. Bien sûr, le robot n'est pas "content" de recevoir une récompense : par contre, il a une image de plus dans son ensemble d'apprentissage, qui améliorera la précision de ses reconnaissances futures. De même si tu le corriges. Par contre, il peut être amusant d'implémenter ça sous une forme plus ludique que oui/non : bravo, "Non, c'était Bérénice" peuvent être implémentés comme mots-clefs. Le top serait qu'il ait aussi une certaine reconnaissance vocale pour pouvoir interagir avec lui : ainsi, tu n'aurais qu'à dire "bravo !" et il comprendrait.
Intéressons-nous maintenant à cette grandeur, la distance (je vais continuer de l'appeler distance, c'est plus simple). La question est de la combiner avec d'autres grandeurs qui apportent de l'information. Une solution est de tout passer en probabilité. Pour ce faire, on peut employer une régression logistique. Il te faut : un ensemble d'images d'apprentissage de la distance, un second ensemble d'images (différent !) d'apprentissage de la régression logistique, et une phase de test avec un troisième ensemble d'images de test, encore différent. À chaque image doit associé un booléen : TRUE si tu es sur l'image, FALSE si tu en es absent.
Dans un premier temps, tu entraînes ton FaceRecognizer avec l'ensemble 1. Puis tu lui fais reconnaître ton second ensemble d'images. Tu enregistres alors les distances proposées et le booléen associé à chaque image. Tu devrais alors obtenir deux vecteurs : un vecteur de booléens et le vecteur des distances associées.
On va maintenant estimer bêta0 et bêta1 au maximum de vraisemblance dans le cadre d'une régression logistique. Une régression logistique est une technique statistique destinée à attribuer à un jeu de données prenant ses valeurs dans R (l'ensemble des réels, pas le langage) une probabilité (prenant ses valeurs dans [0,1]).
Le principe de la régression logistique est le suivant :
Y = beta0 + beta1*X1 + beta2*X2 + ...où les Xi sont les variables prédictrices.boolean = TRUE:P = 1/(exp(Y) +1)vraisemblance = X - P + 1, où P est la proba calculée à l'étape précédente et X vaut 1 siboolean = TRUE, 0 sinon (la vraie formule de la vraisemblance est plus complexe, mais dans ce cas particulier, cette formule est exacte). La vraisemblance globale est égale au produit des vraisemblances individuelles. Comme il est difficile de travailler avec des valeurs très faibles, il est courant de passer par la log-vraisemblance : c'est tout simplement le logarithme de la vraisemblance. La log-vraisemblance globale est alors la somme des log-vraisemblances individuelles.À la fin, on obtient beta0 et beta1. On peut alors répéter l'algo pour calculer, avec ces valeurs de beta0 et beta1, une proba pour toute valeur de distance.
Tu peux accélérer l'algorithme en centrant tes données. Pour ce faire, tu définis :
distance_centree[i] = distance[i] - mean(distance)Ce qui revient à retirer à chaque valeur de distance la moyenne des distances dans l'ensemble d'apprentissage. On peut alors démontrer que
beta0 = exp(P/(1-P))où P est la probabilité moyenne d'observer TRUE : P est tout simplement ta proportion d'images où tu apparais. Du coup, on n'a plus qu'à estimer beta1.Cet algorithme peut être encore amélioré en observant la distribution de tes distances. Pour ce faire, passe-lui un jeu de photos et trace l'histogramme de tes distances. Plus l'histogramme a une gueule de loi gaussienne, meilleurs seront les résultats. À toi de trouver la fonction (monotone) qui donne la meilleure gueule à cet histogramme.
Ensuite, il s'agit de tester cet algorithme. Passe-lui le jeu de photos numéro 3 et contrôle qu'il te sort une proba plus élevée (en moyenne) pour les photos où tu te trouves que pour celles dont tu es absent.
Une fois que tu es satisfait, passons à l'intégration du temps et de l'espace. À toi de voir comment découper le temps. Tu peux faire des tranches horaires rigides (je pars toujours au boulot à 8h45) ou souples (entre 8h30 et 9h, la probabilité que je sois parti croît linéairement de 0 à 0,9, elle est de 0,9 à 9h et elle reste à 0,9 jusqu'à 18h). Bien sûr, c'est un exemple simple, mais tu vois l'idée.
Là encore, il va s'agir d'assigner à chaque couple (temps, lieu) une proba de te trouver. Tu peux initialiser cette proba (par exemple, elle est de 0,9 pour le salon à 19h30 au lancement du robot) mais tu dois pondérer cette initialisation. Par exemple, tu peux dire qu'à l'initialisation, le robot croit t'avoir déjà trouvé 9 fois dans le salon dans cette tranche horaire et 1 fois hors du salon. Ainsi, au fur et à mesure que ton robot vieillira, le poids des a priori s'effacera devant la dure réalité.
On a alors : une proba de t'avoir trouvé sachant l'image et une proba de t'avoir trouvé sachant (temps, lieu). Comment on les combine ? Le plus simple est de les multiplier. Si la proba finale est supérieure à 0,5, le robot se plantera moins d'une fois sur 2 en croyant t'avoir trouvé. Si elle est inférieure à 0,5, il se plantera moins d'une fois sur 2 en croyant ne pas t'avoir trouvé.
Avec le temps, et l'augmentation de l'ensemble d'apprentissage, ton robot s'améliorera... S'il a la puissance de calcul pour, et si l'algo de reconnaissance d'image fait bien son boulot. Peut-être que tu te retrouveras obligé de déporter le calcul vers ton PC, et le robot se contenterait d'obéir aux ordres de ton PC. Ça dépend de la quantité de calculs requis.
Ça, ce sont les sources. Le mouton que tu veux est dedans.