1 (ns neural-net.som ; Kohonen maps
5 (defn self-organizing-map:run
6 "Return a map of the dot product of each neurons weight against x" [this x]
7 (reduce (fn [a [k v]] (cons [k (reduce + (map * x (v :weights)))] a))
8 [] (get (this :map) :vertices)))
10 (defn self-organizing-map:learn
11 "Return a map of learning spread through the map." [this x y d]
12 (let [verts (map first (reverse (sort-by second y)))]
13 (loop [ns [(first verts)] rem (set (rest verts)) dist 0 out {}]
16 (let [m (filter (partial contains? rem) (mapcat (partial neighbors (this :map)) ns))]
17 (recur m (difference rem (set m)) (inc dist)
18 (reduce (fn [a n] (assoc a n ((this :update) this dist n x)))
21 (defn self-organizing-map:train [this delta]
23 :map (neural-net.core.Graph.
24 (reduce (fn [a [k d]] (assoc a
25 k {:weights (map + d ((get a k) :weights))}))
26 (get (this :map) :vertices) delta)
27 (get (this :map) :edges))))
29 (comment ; train a self organizing map
30 (let [som {:phi self-organizing-map:run
31 :learn self-organizing-map:learn
32 :train self-organizing-map:train
34 :update (fn [this dist n x]
35 (map (fn [x] (* (/ x (inc dist)) (this :eta)))
37 x (((get (this :map) :vertices) n) :weights))))
38 :map (neural-net.core.Graph.
42 :d {:weights [ 0 -1]}}
43 [[:a :b] [:b :c] [:c :d]])}]
44 (first (train som [0.8 0.2] nil nil)))
46 ;; {:d (0.2 0.3), :c (0.6 0.06666666666666667),
47 ;; :b (0.4 -0.4), :a (-0.19999999999999996 0.2)}