パーセプトロンの練習
最近、機械学習に興味を持ち始めていて、SVMを実装してみようと思ったら、挫折したのでやはり段階を踏むべきであろうということでパーセプトロンから試してみた。
komamitsu/ocaml-perceptron · GitHub
- perceptron.ml
let ($) f g = f g let print x = Hashtbl.iter (fun k v -> Printf.printf "%s => %d " k v) x; print_newline () let inner_prod w x = Hashtbl.fold (fun wk wv a -> a + wv * (Hashtbl.find x wk)) w 0 let classify w x = if inner_prod w x >= 0 then 1 else -1 let learn w x y = if classify w x != y then Hashtbl.iter (fun xk xv -> let wv = Hashtbl.find w xk in Hashtbl.replace w xk $ wv + xv * y) x let learn_all n w set_of_x_y = for i = 1 to n do List.iter (fun (x, y) -> learn w x y) set_of_x_y done; w
これがパーセプトロンで学習したり分類したりするもので、何というか手順をそのままコードに落としただけ。
- sample.ml
(* * ocamlc -c perceptron.ml && ocaml perceptron.cmo sample.ml *) let ($) f g = f g let vec_of_assoc assoc = List.fold_left (fun w (k, v) -> Hashtbl.replace w k v; w) (Hashtbl.create 4) assoc let train_src = List.rev $ List.fold_left (fun train_src (assoc, y) -> let x = vec_of_assoc assoc in (x, y)::train_src) [] [ ([("R", 255); ("G", 0); ("B", 0); ("bias", 1)], 1); ([("R", 0); ("G", 255); ("B", 255); ("bias", 1)], -1); ([("R", 0); ("G", 255); ("B", 0); ("bias", 1)], -1); ([("R", 255); ("G", 0); ("B", 255); ("bias", 1)], 1); ([("R", 0); ("G", 0); ("B", 255); ("bias", 1)], -1); ([("R", 255); ("G", 255); ("B", 0); ("bias", 1)], 1); ] let print_result x = let s = if x = 1 then "warm" else "cool" in print_endline s let _ = let init = vec_of_assoc [("R", 0); ("G", 0); ("B", 0); ("bias", 1)] in let w = Perceptron.learn_all 10 init train_src in Perceptron.print w; let x = vec_of_assoc [("R", 200); ("G", 100); ("B", 100); ("bias", 1)] in print_result $ Perceptron.classify w x; let x = vec_of_assoc [("R", 100); ("G", 200); ("B", 200); ("bias", 1)] in print_result $ Perceptron.classify w x
で、こちらがそれを利用するサンプルで、機械学習超入門III 〜機械学習の基礎、パーセプトロンを30分で作って学ぶ〜 - EchizenBlog-Zweiの暖色・寒色の例を使わせて頂きました。
実行するとこんな感じに。
komamitsu@carrot:~/lab/ocaml/perceptron$ ocamlc -c perceptron.ml && ocaml perceptron.cmo sample.ml bias => 0 B => -255 R => 255 G => -255 warm cool
それはそうと、OCamlでHashtblを簡単に構築できるリテラル(PerlとかRubyみたいやつ)が欲しいなぁと思いました。camlp4を使った何かがあるのかなぁ。