Gen, un langage probabiliste universel dans Julia
Il ambitionne de faciliter l'utilisation d'intelligence artificielle pour tous

Le , par dourouc05

50PARTAGES

18  0 
La programmation probabiliste est un paradigme de programmation assez peu répandu, notamment parce que ses utilisations sont liées à l’intelligence artificielle (et pas à grand-chose d’autre). L’objectif est d’effectuer des calculs sur des variables aléatoires (c’est-à-dire une quantité qui n’est pas connue exactement), puis d’effectuer de l’inférence pour expliquer des données. Par exemple, pour de la reconstruction de pose 3D (trouver l’orientation des bras, des torses, des jambes, etc. à partir d’une photo d’une personne), on dispose d’une image à expliquer. Une manière classique d’aborder le problème serait de trouver les bras, le torse, les jambes, puis leurs orientations. En programmation probabiliste, on préférera utiliser une série de variables aléatoires (orientation des bras, des jambes, etc.) : une fois les valeurs fixées, on peut calculer exactement la pose de la personne. Ensuite, on peut comparer l’image obtenue avec celle d’entrée : si elles sont très proches, on a trouvé les bonnes valeurs des variables aléatoires. Le processus d’inférence consiste, ici, à tirer un grand nombre de valeurs différentes pour les variables aléatoires, puis de prendre la meilleure correspondance avec l’image d’entrée, la “meilleure explication”.

Gen est un système prévu pour la programmation probabiliste “généraliste”, sans a priori sur les variables aléatoires que l’on peut utiliser. Ce système est embarqué comme une bibliothèque pour le langage Julia.

En pratique, pour effectuer de l’inférence, il faut deux choses : d’un côté, une fonction génératrice, qui tire au hasard (ou choisit de manière plus intelligente) des valeurs pour les variables aléatoires et détermine d’autres valeurs (une sorte de résultat final : par exemple, une pose) ; de l’autre, des données à expliquer.

Par exemple, on dispose d’une série de coordonnées de points et on cherche une droite qui passe par ces points (on en connaît les coordonnées : x_i et y_i). Au lieu d’utiliser une régression linéaire, on peut passer par de la programmation probabiliste. Une droite, en deux dimensions, est déterminée par deux paramètres (une pente et une intersection avec l’un des axes, par exemple). Pour comparer le modèle aléatoire aux données, il faut calculer les coordonnées de points : on connaît les x_i, on détermine les y_i selon les paramètres tirés aléatoirement ; après, on comparera ces y_i aux vraies valeurs. La fonction génératrice ressemble alors à une fonction Julia normale, mais annotée avec @gen (de même, chaque variable aléatoire est annotée avec @trace) :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
@gen function line_model(xs::Vector{Float64})
    slope = @trace(normal(0, 1), :slope)
    intercept = @trace(normal(0, 2), :intercept)
 
    for (i, x) in enumerate(xs)
        @trace(normal(slope * x + intercept, 0.1), (:y, i))
    end
 
    return length(xs)
end
Ensuite, on peut effectuer de l’inférence (ici, en tirant au hasard des valeurs cent fois — un procédé très cru, pas forcément rapide, mais facile à implémenter et comprendre !) :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
xs = [-5., -4., -3., -.2, -1., 0., 1., 2., 3., 4., 5.]
ys = [6.75003, 6.1568, 4.26414, 1.84894, 3.09686, 1.94026, 1.36411, -0.83959, -0.976, -1.93363, -2.91303]
 
observations = Gen.choicemap()
for (i, y) in enumerate(ys)
    observations[(:y, i)] = y
end
 
(trace, _) = Gen.importance_resampling(model, (xs,), observations, 100)
En répétant l’expérience un certain nombre de fois, on trouve une série de droites qui expliquent au mieux, pour chaque centaine de tentatives, les données :


Après cette inférence, Gen a appris la densité la plus probable des paramètres de la ligne : il peut ensuite générer de nouveaux points, grâce à ce qu’il a enregistré, en utilisant la fonction Gen.generate.


La différence entre Gen et d’autres systèmes de programmation probabiliste est sa nature universelle : le système peut être utilisé pour n’importe quelle tâche de programmation probabiliste (même si cet article se focalise sur l’inférence a posteriori). L’implémentation est prévue pour être facile à adapter à ses propres besoins (on peut écrire son propre moteur d’inférence, même s’il en existe déjà un certain nombre). Jusqu’à présent, les systèmes probabilistes disposaient soit de bonnes capacités d’inférence (mais une modélisation limitée), soit au contraire étaient aussi généralistes, mais sans algorithme d’inférence performant. Gen renverse la donne, en étant universel, mais aussi en incluant une grande variété de possibilités d’inférence.

Source : Gen: a general-purpose probabilistic programming system with programmable inference. L’exemple développé provient de la documentation de Gen.

Voir aussi : le code source de Gen.

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de gallima
Membre habitué https://www.developpez.com
Le 02/07/2019 à 7:55
Cela me fait un peu penser à Problog un langage probabiliste (inférence bayésienne) basé sur Prolog.
2  0 
Avatar de SQLpro
Rédacteur https://www.developpez.com
Le 04/07/2019 à 13:37
l'algorithme sous-jacent est vieux comme le monde, c'est la "méthode de Monte-Carlo" !
0  1 

 
Responsable bénévole de la rubrique HPC : Thibaut Cuvelier -

Partenaire : Hébergement Web