Skip to content

Instantly share code, notes, and snippets.

Created March 24, 2013 16:55
Show Gist options
  • Save anonymous/5232625 to your computer and use it in GitHub Desktop.
Save anonymous/5232625 to your computer and use it in GitHub Desktop.
A neural network in Titan and Clojure implementing the xor function
(ns martha.core
(:require [clojurewerkz.titanium.graph :as g]
[clojurewerkz.titanium.vertices :as v]
[clojurewerkz.titanium.edges :as e]
[clojurewerkz.titanium.types :as t]
[ogre.core :as q]))
(def conf {:storage {:backend "embeddedcassandra"
:hostname "127.0.0.1"
:keyspace "martha"
:cassandra-config-dir
(str "file://"
(System/getProperty "user.dir")
"/resources/cassandra.yaml")}})
(def graph (g/open conf))
(defn get-all-edges []
(seq (.getEdges graph)))
(defn get-all-vertices []
(seq (.getVertices graph)))
(defn clear-graph []
(g/transact!
(doseq [edge (get-all-edges)] (.remove edge))
(doseq [vs (get-all-vertices)] (v/delete! vs))))
(defn new-network []
(clear-graph)
(g/transact!
(let [input1 (v/create! {:type "input" :threshold 0.5 :energy 0 :input 0})
input2 (v/create! {:type "input" :threshold 0.5 :energy 0 :input 1})
hidden1 (v/create! {:type "hidden" :threshold 1.5 :energy 0})
hidden2 (v/create! {:type "hidden" :threshold 0.5 :energy 0})
output (v/create! {:type "output" :threshold 0.5 :energy 0})]
(e/connect! input1 :link hidden1 {:weight 1})
(e/connect! input1 :link hidden2 {:weight 1})
(e/connect! input2 :link hidden1 {:weight 1})
(e/connect! input2 :link hidden2 {:weight 1})
(e/connect! hidden1 :link output {:weight -1})
(e/connect! hidden2 :link output {:weight 1}))))
(defn activated? [u]
(<= (v/get u :threshold)
(v/get u :energy)))
(defn propogate [firing]
(q/query firing
;;Edges that are firing
q/--E>
(q/as "active")
;;Vertices that are being hit
q/in-vertex
(q/as "vertex")
;;Accumulate energy
(q/select (q/prop :weight) identity)
(q/side-effect (fn [[weight u]] (v/update! u :energy + weight)))
;;Pull out the touched vertices
(q/transform second)
(q/dedup)
;;Breadth first
q/gather
q/scatter
q/to-list!))
(defn xor-nn [& args]
(new-network)
(g/transact!
(doseq [u (get-all-vertices)] (v/assoc! u :energy 0))
;;Load input
(let [update-input #(v/assoc! % :energy (nth args (v/get % :input)))
active-inputs (q/query (v/find-by-kv :type "input")
(q/side-effect update-input)
(q/filter activated?)
(q/to-list!))]
;;Loop through network, propogating energy and filtering thresholds
(loop [firing active-inputs]
(let [receivers (propogate firing)
;;Filter out only the active vertices
activated (doall (filter activated? receivers))]
(when (not (empty? activated))
(recur activated))))
(q/query (v/find-by-kv :type "output")
(q/transform #(if (activated? %) 1 0))
q/into-vec!))))
;; martha.core> (xor-nn 0 0)
;; [0]
;; nil
;; martha.core> (xor-nn 0 1)
;; [1]
;; nil
;; martha.core> (xor-nn 1 0)
;; [1]
;; nil
;; martha.core> (xor-nn 1 1)
;; [0]
;; nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment