Skip to content

Instantly share code, notes, and snippets.

@yusugomori
Created April 26, 2012 17:48
Show Gist options
  • Save yusugomori/2501338 to your computer and use it in GitHub Desktop.
Save yusugomori/2501338 to your computer and use it in GitHub Desktop.
bpnn.rb
#!/usr/bin/env ruby -Ku
# -*- coding: utf-8 -*-
srand(0)
class BPNN
def initialize(ni, nh, no)
@ni = ni + 1
@nh = nh
@no = no
@ai = [1.0] * @ni
@ah = [1.0] * @nh
@ao = [1.0] * @no
@wi = self.makeMatrix(@ni, @nh)
@wo = self.makeMatrix(@nh, @no)
for i in 0...@ni
for j in 0...@nh
@wi[i][j] = self.random(-0.2, 0.2)
end
end
for j in 0...@nh
for k in 0...@no
@wo[j][k] = self.random(-2.0, 2.0)
end
end
@ci = self.makeMatrix(@ni, @nh)
@co = self.makeMatrix(@nh, @no)
end
def update(inputs)
unless inputs.length == @ni - 1
raise ArgumentError, "wrong number of inputs"
end
for i in 0...@ni-1
@ai[i] = inputs[i]
end
for j in 0...@nh
sum = 0.0
for i in 0...@ni
sum = sum + @ai[i] * @wi[i][j]
end
@ah[j] = self.sigmoid(sum)
end
for k in 0...@no
sum = 0.0
for j in 0...@nh
sum = sum + @ah[j] * @wo[j][k]
end
@ao[k] = self.sigmoid(sum)
end
return @ao
end
def backPropagate(targets, n, m)
unless targets.length == @no
raise ArgumentError, "wrong number of target values"
end
output_deltas = [0.0] * @no
for k in 0...@no
error = targets[k] - @ao[k]
output_deltas[k] = self.dsigmoid(@ao[k]) * error
end
hidden_deltas = [0.0] * @nh
for j in 0...@nh
error = 0.0
for k in 0...@no
error = error + output_deltas[k] * @wo[j][k]
end
hidden_deltas[j] = self.dsigmoid(@ah[j]) * error
end
for j in 0...@nh
for k in 0...@no
change = output_deltas[k] * @ah[j]
@wo[j][k] = @wo[j][k] + n * change + m * @co[j][k]
@co[j][k] = change
end
end
for i in 0...@ni
for j in 0...@nh
change = hidden_deltas[j] * @ai[i]
@wi[i][j] = @wi[i][j] + n * change + m * @ci[i][j]
@ci[i][j] = change
end
end
error = 0.0
for k in 0...targets.length
error = error + 0.5 * (targets[k] - @ao[k])**2
end
return error
end
def test(patterns)
for p in patterns
puts "#{p[0]} -> #{self.update(p[0])}"
end
end
def train(patterns, iter=100, n=0.5, m=0.1)
for i in 0...iter
error = 0.0
for p in patterns
inputs = p[0]
targets = p[1]
self.update(inputs)
error += self.backPropagate(targets, n, m)
end
end
end
def random(a, b)
return (b-a) * rand() + a
end
def makeMatrix(i, j, fill=0.0)
m = []
for k in 0...i
m.push([fill]*j)
end
return m
end
def sigmoid(x)
return Math.tanh(x)
end
def dsigmoid(y)
return 1.0 - y**2
end
end
def benchmark
# XOR
patterns = [
[[-1,-1], [-1]],
[[-1,1], [1]],
[[1,-1], [1]],
[[1,1], [-1]]
]
bp = BPNN.new(2, 3, 1)
bp.train(patterns, 10000)
bp.test(patterns)
end
start = Time.now
benchmark()
end_ = Time.now
puts
puts end_ - start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment