Class: TLearn::FNN

Inherits:
Object
  • Object
show all
Defined in:
lib/t_learn/feedforward_neural_network.rb

Overview

Defined Under Namespace

Classes: Node

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(learning_rate = 0.1, threshold = 0.0, momentum_rate = 0.01) ⇒ FNN

Returns a new instance of FNN.



10
11
12
13
14
15
16
17
18
19
20
# File 'lib/t_learn/feedforward_neural_network.rb', line 10

def initialize(learning_rate=0.1, threshold=0.0, momentum_rate=0.01)
  @layer_size = 0    #layer iterator
  @layer_list = Array.new
  @link_list = Hash.new
  @node_id = 0
  @learning_rate = learning_rate
  @momentum_weight_list = Hash.new
  @momentum_rate = momentum_rate
  @err_list = Array.new
  @threshold = threshold
end

Instance Attribute Details

#err_listObject

Returns the value of attribute err_list.



9
10
11
# File 'lib/t_learn/feedforward_neural_network.rb', line 9

def err_list
  @err_list
end

#layer_listObject

Returns the value of attribute layer_list.



9
10
11
# File 'lib/t_learn/feedforward_neural_network.rb', line 9

def layer_list
  @layer_list
end

#layer_sizeObject

Returns the value of attribute layer_size.



9
10
11
# File 'lib/t_learn/feedforward_neural_network.rb', line 9

def layer_size
  @layer_size
end

#learning_rateObject

Returns the value of attribute learning_rate.



9
10
11
# File 'lib/t_learn/feedforward_neural_network.rb', line 9

def learning_rate
  @learning_rate
end

Returns the value of attribute link_list.



9
10
11
# File 'lib/t_learn/feedforward_neural_network.rb', line 9

def link_list
  @link_list
end

#node_idObject

Returns the value of attribute node_id.



9
10
11
# File 'lib/t_learn/feedforward_neural_network.rb', line 9

def node_id
  @node_id
end

#thresholdObject

Returns the value of attribute threshold.



9
10
11
# File 'lib/t_learn/feedforward_neural_network.rb', line 9

def threshold
  @threshold
end

Instance Method Details

#add_layer(node_num) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/t_learn/feedforward_neural_network.rb', line 22

def add_layer(node_num)
  node_list = Array.new()
  node_num.times do |num|
    node = Node.new(0.0,"sig", @threshold)
    node.set_id(@node_id)
    node_list.push(node)
    @node_id += 1
  end

  @layer_list.push(node_list)
  # connect link
  if @layer_size != 0  # if not first layer
    # connect link to @layer_size - 1 layer
    connect_nodes
  end
  @layer_size += 1
end

#back_propagation(y) ⇒ Object

Parameters:

  • y

    Array teacher_data



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/t_learn/feedforward_neural_network.rb', line 110

def back_propagation(y)

  raise "output size different from node num of output layer"  if get_output_layer.size != y.size
  # raise "o"  if get_output_layer.size != y.size
  delta = {}
  ( @layer_size - 1).downto(0) do |layer_num|
    if ( @layer_size - 1) == layer_num   # if output layer
      @layer_list[layer_num].each_with_index do |output_node, i|
        delta["#{output_node.id}"] = -1.0 * calc_err(y[i], output_node.w) * output_node.w * (1.0 -output_node.w)
      end
    else 
      @layer_list[layer_num].each do |from_node|
        # リンクの更新
        @layer_list[layer_num + 1].each do |to_node|
          # モメンタムによる更新
          momentum_weight = @momentum_rate * @momentum_weight_list["#{from_node.id}_#{to_node.id}"]
          update_weight = -1.0 * @learning_rate * delta["#{to_node.id}"] * from_node.w
          @link_list["#{from_node.id}_#{to_node.id}"] = @link_list["#{from_node.id}_#{to_node.id}"] + update_weight + momentum_weight
          @momentum_weight_list["#{from_node.id}_#{to_node.id}"] = update_weight # for momentum
        end
        # その層のdeltaの更新
        delta["#{from_node.id}"] = calc_delta(delta,layer_num, from_node) * from_node.w * (1.0 - from_node.w)
      end
    end
  end
end

#calc_ave_err(y) ⇒ Object



95
96
97
98
99
100
101
102
# File 'lib/t_learn/feedforward_neural_network.rb', line 95

def calc_ave_err(y)
  sum_err = 0.0
  @layer_list[@layer_size - 1].each_with_index do |node, i|
    sum_err += calc_err(node.w,y[i]).abs
  end
  ave_err = (sum_err)/y.size
  return ave_err 
end

#calc_delta(delta, layer_i, from_node) ⇒ Object



141
142
143
144
145
146
147
# File 'lib/t_learn/feedforward_neural_network.rb', line 141

def calc_delta(delta,layer_i, from_node)
  sum = 0.0
  @layer_list[layer_i+1].each do |to_node|
    sum += delta["#{to_node.id}"] * @link_list["#{from_node.id}_#{to_node.id}"]
  end
  return sum
end

#calc_err(teacher_data, w) ⇒ Object



137
138
139
# File 'lib/t_learn/feedforward_neural_network.rb', line 137

def calc_err(teacher_data, w)
  return (teacher_data -w)
end

#connect_nodesObject

connect_nodes



43
44
45
46
47
48
49
50
# File 'lib/t_learn/feedforward_neural_network.rb', line 43

def connect_nodes
  @layer_list[@layer_size - 1].each do |from_node|
    @layer_list[@layer_size].each do |to_node|
      @link_list["#{from_node.id}_#{to_node.id}"] = rand(-1.0...1.0)
      @momentum_weight_list["#{from_node.id}_#{to_node.id}"] = 0.0
    end
  end
end

#evaluate(x_test, y_test) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/t_learn/feedforward_neural_network.rb', line 149

def evaluate(x_test, y_test)
  # compare teacher_datas and output of nn
  sum_err = 0.0
  x_test.zip(y_test).each do |x, y|
    propagation(x)
    output = []
    err = 0.0
    @layer_list[@layer_size -1].zip(y).each do |o, y_f|
      output.push(o.w)
      err += (y_f - o.w).abs
    end
    sum_err += (err/y_test[0].size)
    # puts "x #{x}, y #{y} , output #{output}"
  end 
  return (sum_err/y_test.size) * 100.0
  # return 0.0
end

#fit(x_train, y_train, epoch) ⇒ Object

Parameters:

  • x_train

    Array

  • y_train

    Array



58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/t_learn/feedforward_neural_network.rb', line 58

def fit(x_train, y_train, epoch)
  # input teacher_datas
  epoch.times do 
    epoch_err = 0.0 
    x_train.zip(y_train).each do |x, y|
      x, y = x_train.zip(y_train).sample
      # puts "x #{x}, y #{y}"
      propagation(x)
      epoch_err += calc_ave_err(y)
      back_propagation(y)
    end
    @err_list.push(epoch_err)
  end
end

#get_output_layerObject



167
168
169
170
171
172
173
# File 'lib/t_learn/feedforward_neural_network.rb', line 167

def get_output_layer
  output = []
  @layer_list[@layer_size-1].each do |node|
    output.push(node.w)
  end
  return output
end

#propagation(x) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/t_learn/feedforward_neural_network.rb', line 73

def propagation(x)
  raise "input size is different from  node num of input layer "  if @layer_list[0].size != x.size
  # input data 
  @layer_list[0].each_with_index do |node, i|
    node.input (x[i])
  end
  @layer_size.times do |layer_num|
    if layer_num != (@layer_size-1)
      # puts "layernum #{layer_num}"
      @layer_list[layer_num + 1].each do |to_node|
        sum_all_from_node = 0.0
        @layer_list[layer_num].each do |from_node|
          sum_all_from_node += @link_list["#{from_node.id}_#{to_node.id}"] * from_node.w
        end
        to_node.update_w(sum_all_from_node + 1.0)
      end
    end
  end

  return get_output_layer 
end