Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Embedded Probabilistic Programming

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Embedded Probabilistic Programming

Avatar for Ryosuke TAKASHIMA

Ryosuke TAKASHIMA

June 30, 2010
Tweet

More Decks by Ryosuke TAKASHIMA

Other Decks in Programming

Transcript

  1. ふつうにプログラミング OCamlでふつうに書くとこんな感じ。 モンテカルロ法で解くと47%くらい。 let flip p = dist [(p, true);

    (1.-.p, false)] let grassModel = let rain = flip 0.3 and sprinkler = flip 0.5 in let grass_is_wet = flip 0.9 && rain || flip 0.8 && sprinkler || flip 0.1 in if grass_is_wet then rain else fail()
  2. 確率分布DSL こんなDSLを用意する。(Haskell) type Prob = Float data PM a dist

    :: [(Prob, a)] -> PM a con :: PM Bool -> PM Bool -> PM Bool dis :: PM Bool -> PM Bool -> PM Bool if_ :: PM Bool -> PM a -> PM a -> PM a let_ :: PM a -> (PM a -> PM b) -> PM b
  3. DSLで記述した確率モデル 芝生の例はDSLでこんな風に書ける。 grassModel = let_ (flip_ 0.3) (¥ rain ->

    let_ (flip_ 0.5) (¥ sprinkler -> let_ (dis (con (flip_ 0.9) rain) (dis (con (flip_ 0.8) sprinkler) (flip_ 0.1))) (¥ grassIsWet -> if_ grassIsWet rain (dist []))))
  4. 確率を木構造で表現 T T T X T T X T X

    F F X F F X F X F X F X F X 0.1 0.9 0.2 0.8 0.1 0.9 0.1 0.9 0.1 0.9 0.8 0.2 0.9 0.1 0.5 0.5 0.1 0.9 0.2 0.8 0.1 0.9 0.2 0.8 0.9 0.1 0.1 0.9 0.1 0.9 0.8 0.2 0.9 0.1 0.9 0.1 0.9 0.8 0.2 0.1 0.5 0.5 0.3 0.7 1.0
  5. 木探索でDSLを実装(1) data VC a = V a | C (PV

    a) type PV a = [(Prob, VC a)] type PM a = PV a pvUnit :: a -> PV a pvUnit x = [(1.0, V x)] pvBind :: PV a -> (a -> PV b) -> PV b pvBind m f = map g m where g (p, V x) = (p, C (f x)) g (p, C t) = (p, C (pvBind (t f)))
  6. 木探索でDSLを実装(2) dist ch = map (¥(p,v) -> (p, V v))

    ch con e1 e2 = pvBind e1 (¥v1 -> if v1 then e2 else pvUnit False) dis e1 e2 = pvBind e1 (¥v1 -> if v1 then pvUnit True else e2) if_ et e1 e2 = pvBind et (¥t -> if t then e1 else e2)
  7. CPSでDSLを実装 data VC a = V a | C (PV

    a) type PV a = [(Prob, VC a)] type PM a = (a -> PV Bool) -> PV Bool dist ch k = map (¥(p,v) -> (p, C (k v))) ch con e1 e2 k = e1 (¥v1 -> if v1 then e2 k else k False) dis e1 e2 k = e1 (¥v1 -> if v1 then k True else e2 k) if_ et e1 e2 k = et (¥t -> if t then e1 k else e2 k)
  8. 限定継続の扱いの違い OCaml let rec times lst = match lst with

    [] -> 1 | 0 :: rest -> shift (fun cont -> 0) | first :: rest -> first * times rest Haskell times lst = case lst of [] -> return 1 0 : rest -> shift (¥ cont -> 0) first : rest -> (first *) `liftM` times rest ← 戻り値は数値 ← 戻り値は継続
  9. shift / reset で実装(OCaml) let dist ch = shift (fun

    k -> List.map (fun (p,v) -> (p, C (fun () -> k v))) ch) let neg e = not e let con e1 e2 = e1 && e2 let dis e1 e2 = e1 || e2 let if_ et e1 e2 = if et then e1 () else e2 () let reify0 m = reset (fun () -> pv_unit (m ()))
  10. shift / reset で実装(Haskell) dist ch = shift (¥k ->

    map (¥ (p,v) -> (p, C (k v))) ch) neg = liftM not con = liftM2 (&&) dis = liftM2 (||) if_ et e1 e2 = et >>= (¥t -> if t then e1 else e2) reify0 m = reset (pvUnit `liftM` m) いろいろ余計なものが付いてる
  11. モナドの力 do記法を使うと、擬似的に生のデータを扱える grassModel = do rain <- flip_ 0.3 sprinkler

    <- flip_ 0.5 wetByRain <- flip_ 0.9 wetBySprinkler <- flip_ 0.8 wetByOther <- flip_ 0.1 let grassIsWet = wetByRain && rain || wetBySprinkler && sprinkler || wetByOther if grassIsWet then return rain else dist []
  12. メモして高速化 F T F T F T F T F

    T F T F T F T T F T F T F T F T F T F T F T F T 1回目 2回目 3回目 4回目 5回目 N回までの計算結果を再利用できる