Skip to content

Instantly share code, notes, and snippets.

@suxue
Created March 11, 2014 04:54
Show Gist options
  • Save suxue/9479701 to your computer and use it in GitHub Desktop.
Save suxue/9479701 to your computer and use it in GitHub Desktop.
simple ann example
assert = require("assert")
_ = require("underscore")
sigmoid = (v) ->
return 1 / (1 + Math.E ** (-v))
pass = () -> undefined
class Ann
constructor: (inputs, hiddens, outputs) ->
@inputs = inputs
@hiddens = hiddens
@outputs = outputs
# ibitialize input-to-hidden weights
@i2h_weights = []
for i in [0 ... @inputs]
@i2h_weights[i] = []
for j in [0 ... @hiddens]
@i2h_weights[i][j] = Math.random()
@h2o_weights = []
for i in [0 ... @hiddens]
@h2o_weights[i] = []
for j in [0 ... @outputs]
@h2o_weights[i][j] = Math.random()
calculate: (input_vector, hidden_vector, output_vector) ->
hidden_vector = [] if not _.isArray(hidden_vector)
output_vector = [] if not _.isArray(output_vector)
for i in [0 ... @hiddens]
hidden_vector[i] = 0
for j in [0 ... @inputs]
hidden_vector[i] += input_vector[j] * @i2h_weights[j][i]
hidden_vector[i] = sigmoid hidden_vector[i]
for i in [0 ... @outputs]
output_vector[i] = 0
for j in [0 ... @hiddens]
output_vector[i] += hidden_vector[j] * @h2o_weights[j][i]
output_vector[i] = sigmoid output_vector[i]
[hidden_vector, output_vector]
train: (input_vector, target_vector) ->
assert input_vector.length == @inputs
assert target_vector.length == @outputs
hidden_error = []
output_error = []
hidden_vector = []
output_vector = []
# forward train
forward_pass = () =>
@calculate input_vector, hidden_vector, output_vector
# backward propagation
backward_pass = () =>
# calculate output layer errors
out = null
for i in [0 ... @outputs]
out = output_vector[i]
output_error[i] = out * (1 - out) * (target_vector[i] - out)
# update weights for H2O
for i in [0 ... @hiddens]
for j in [0 ... @outputs]
@h2o_weights[i][j] += output_error[j] * hidden_vector[i]
# calculate hidden layer errors
for i in [0 ... @hiddens]
out = hidden_vector[i]
offset = 0
for j in [0 ... @outputs]
offset += output_error[j] * @h2o_weights[i][j]
hidden_error[i] = out * (1 - out) * offset
# update weights for I2H
for i in [0 ... @inputs]
for j in [0 ... @hiddens]
@i2h_weights[i][j] += input_vector[i] * hidden_error[j]
do pass
do forward_pass
do backward_pass
err_num = 0
err_sum = 0
hidden_error.forEach (v) -> err_num += 1; err_sum += v
output_error.forEach (v) -> err_num += 1; err_sum += v
err = Math.abs (err_sum / err_num)
module.exports = Ann
inputs = 2
input_vectors = [
[1, 0]
[0, 1]
]
target_vectors = [
[1, 0]
[0, 1]
]
Ann = require "Ann"
ann = new Ann 2, 2, 2
err = Infinity
threshold = 0.0000005
while err >= threshold
for i in [0 ... input_vectors.length]
input_vector = input_vectors[i]
target_vector = target_vectors[i]
err = ann.train(input_vector, target_vector)
console.log "err = #{err}"
break if err < threshold
test = (a, b) ->
input = [a, b]
result = ann.calculate input
console.log "[#{input}] => []#{result[1]}]"
test 0, 1
test 1, 0
test 0.78, 0.22
for i in [0...10]
v = Math.random()
test v, 1-v
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment