Commit 269a2bc2 by zlu 🤸🏿

### 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!