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 |
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) |
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.