Commit 269a2bc2 authored by zlu's avatar zlu 🤸🏿
Browse files

added support for linear training set

parent 9a8429ae
class ML
@@weights = [0, 0, 0]
@@weights_for_binary = [0, 0, 0]
@@weights_for_linear = [0.0]
def dot_product(a, b)
[a, b].transpose.map{ |e| e = e[0]*e[1] }.inject{ |s, n| s += n }
def weights_for_binary
@@weights_for_binary
end
def validation_set
def weights_for_linear
@@weights_for_linear
end
def binary_training_set
[[[1, 0, 0], 1], [[1, 0, 1], 1], [[1, 1, 0], 1], [[1, 1, 1], 0]]
end
def weights
@@weights
def linear_training_set
[[[1.0], 2.0], [[1.5], 3.0], [[2.0], 4.0]]
end
def threshold
0.5
end
def learning_rate
0.005
def dot_product(input, weights)
[input, weights].transpose.map{ |e| e = e[0] * e[1] }.inject{ |s, n| s += n }
end
def train
w_dist = 20
(4..10).each do |size|
set = gen_training_set(size)
weights = perceive_all(set)
dist = w_distance(weights)
w_dist = dist if w_dist > dist
puts "final distance: " + w_dist.to_s
end
puts "final distance: " + w_dist.to_s
w_dist
def binary_train_all
train_all(binary_training_set, weights_for_binary, lambda{ |a,b| dot_product(a, b) > threshold ? 1 : 0 })
end
def perceive_all(t_set)
puts "in per all " + t_set.size.to_s
counter = 0
while counter < t_set.size
counter = 0
t_set.each do |set|
counter += perceive(set[0], set[1])
end
puts "set:counter => " + t_set.size.to_s + ":" + counter.to_s
end
puts "final weights: " + weights.join(":")
weights
def linear_train_all
train_all(linear_training_set, weights_for_linear, lambda{ |a,b| dot_product(a, b) })
end
def perceive(input, output)
result = dot_product(input, weights) > threshold ? 1 : 0
diff = result - output
return 1 if diff == 0
def sigmoid_train_all
input.each_with_index do |inp, index|
weights[index] += (-1 * diff * learning_rate) if inp != 0
end
end
0
def stop_condition(training_set, counter, repetition, weights)
counter == training_set.size || ( repetition > 1500 && rms(weights) < 0.01)
end
def rms(w)
Math.sqrt(w.inject(0){ |s, n| s += n * n } / w.size)
end
def w_distance(w)
total_distance = 0.0
w.each_with_index do |elem, index|
if (index < w.length-1)
(index+1..w.length-1).each do |n_elem|
total_distance += (elem - w[n_elem]).abs
end
def train_all(training_set, weights, activation_function)
counter = 0
repetition = 0
learning_rate = 0.9
while !stop_condition(training_set, counter, repetition, weights)
counter = 0
repetition += 1
training_set.each do |set|
counter += train(set[0], set[1], learning_rate, weights, activation_function)
end
learning_rate *= 0.99
p learning_rate
puts "intermediary weights: " + weights.join(":")
end
total_distance
puts "final weights: " + weights.join(":")
end
def gen_training_set(size)
set = [[]]
(0..size-1).each do |i|
temp = []
(0..2).each do |j|
temp[j] = rand(2)
end
set[i] = [temp, temp.include?(0)? 1 : 0]
def train(input, expected_output, learning_rate, weights, activation_function)
actual_output = activation_function.call(input, weights)
train_step = (expected_output - actual_output) * learning_rate
return 1 if train_step == 0
input.each_with_index do |inp, index|
weights[index] += inp * train_step
end
p set
set
0
end
end
\ No newline at end of file
......@@ -7,28 +7,34 @@ describe "ML#do_product" do
end
it "should produce 4321" do
ML.new.dot_product([1,2,3,4],[1,10,100,1000]).should == 4321
ML.new.dot_product([1, 2, 3, 4], [1, 10, 100, 1000]).should == 4321
end
it "should produce 1 with input set 1" do
ml = ML.new
ml.perceive([1, 0, 0], 1).should == 1
ml.perceive([1, 1, 0, 0], 1, 0.1).should == 1
end
it "should produce 1 with input set 2" do
ML.new.perceive([1,0,0], 1).should == 1
ML.new.perceive([1, 1, 0, 0], 1, 0.1).should == 1
end
it "should produce 1 with input set 3" do
ML.new.perceive([1,1,0], 1).should == 1
ML.new.perceive([1, 1, 1, 0], 1, 0.1).should == 1
end
it "should produce 0 with input set 4" do
ML.new.perceive([1,1,1], 0).should == 1
ML.new.perceive([1, 1, 1, 1], 0, 0.1).should == 1
end
it "should produce correct results for all input sets" do
ML.new.perceive_all(ML.new.validation_set)
ML.new.binary_train_all#(ML.new.validation_set)
end
describe "linear perceive" do
it "should produce correct results for all input sets" do
ML.new.linear_train_all#(ML.new.validation_set)
end
end
it "should return 1 for the distance amongst weights of verification set" do
......@@ -42,6 +48,12 @@ describe "ML#do_product" do
end
it "should perceive with training sets and return the smallest w_distance" do
ML.new.train.should_not be_nil
# ML.new.train.should_not be_nil
end
it "should give correct rms" do
set = [1.0,2.0,3.0]
ML.new.rms(set).to_s.should include("2.16024689946929")
# ML.new.rms(set).should == 2.16024689946929
end
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment