Class: RubyNN::NeuralNetwork
- Inherits:
-
Object
- Object
- RubyNN::NeuralNetwork
- Defined in:
- lib/neural_network.rb
Instance Attribute Summary collapse
-
#alpha ⇒ Object
readonly
Returns the value of attribute alpha.
-
#error ⇒ Object
readonly
Returns the value of attribute error.
-
#layer_parameters ⇒ Object
readonly
Returns the value of attribute layer_parameters.
Instance Method Summary collapse
- #back_propagate(predictions, target_output) ⇒ Object
- #back_propagation_multiplyer(v1, v2) ⇒ Object
- #calculate_deltas(input, deltas) ⇒ Object
- #calculate_outcomes(abstraction) ⇒ Object
- #calculate_prediction(input) ⇒ Object
- #find_deltas(predictions, outcomes) ⇒ Object
- #find_weights(i, weights) ⇒ Object
- #get_weights ⇒ Object
-
#initialize(layer_parameters, alpha = 0.001) ⇒ NeuralNetwork
constructor
A new instance of NeuralNetwork.
- #initialize_weights ⇒ Object
- #leaky_relu(input) ⇒ Object
- #multiply_vector(input, weight_matrix) ⇒ Object
- #offsets ⇒ Object
- #relu_derivative(output) ⇒ Object
- #save_weights(filename) ⇒ Object
- #set_weights(weight_matrix) ⇒ Object
- #softmax(vector) ⇒ Object
- #train(input, target_output) ⇒ Object
- #update_weights(weighted_deltas, i) ⇒ Object
- #weight_counts ⇒ Object
- #weighted_sum(input, weights) ⇒ Object
Constructor Details
#initialize(layer_parameters, alpha = 0.001) ⇒ NeuralNetwork
Returns a new instance of NeuralNetwork.
6 7 8 9 10 11 |
# File 'lib/neural_network.rb', line 6 def initialize(layer_parameters, alpha = 0.001) @alpha = alpha @weight_matrix = [] @layer_parameters = layer_parameters @error = 0 end |
Instance Attribute Details
#alpha ⇒ Object (readonly)
Returns the value of attribute alpha.
4 5 6 |
# File 'lib/neural_network.rb', line 4 def alpha @alpha end |
#error ⇒ Object (readonly)
Returns the value of attribute error.
4 5 6 |
# File 'lib/neural_network.rb', line 4 def error @error end |
#layer_parameters ⇒ Object (readonly)
Returns the value of attribute layer_parameters.
4 5 6 |
# File 'lib/neural_network.rb', line 4 def layer_parameters @layer_parameters end |
Instance Method Details
#back_propagate(predictions, target_output) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/neural_network.rb', line 94 def back_propagate(predictions, target_output) reversed_weight_matrix = @weight_matrix.reverse last_weighted = [] predictions.reverse.each_with_index do |prediction, i| delta_set = find_deltas(prediction, target_output) if i == 0 if i != 0 delta_set = back_propagation_multiplyer(last_weighted, relu_derivative(prediction)) end weighted = multiply_vector(delta_set, reversed_weight_matrix[i].transpose) last_weighted = weighted update_weights(delta_set, i) end end |
#back_propagation_multiplyer(v1, v2) ⇒ Object
181 182 183 |
# File 'lib/neural_network.rb', line 181 def back_propagation_multiplyer(v1, v2) v1.zip(v2).map { |set| set[0] * set[1] } end |
#calculate_deltas(input, deltas) ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/neural_network.rb', line 137 def calculate_deltas(input, deltas) weighted_deltas = [] deltas.each { weighted_deltas.push([]) } deltas.size.times do |index| input.size.times do |count| weighted_deltas[index][count] = input[count] * deltas[index] end end weighted_deltas end |
#calculate_outcomes(abstraction) ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/neural_network.rb', line 158 def calculate_outcomes(abstraction) first = 0.0 second = 0.0 third = 0.0 abstraction.setups.each do |setup| white_wins = setup.outcomes[:white_wins].to_f black_wins = setup.outcomes[:black_wins].to_f draws = setup.outcomes[:draws].to_f if setup.position_signature[-1] == 'w' first += white_wins second += black_wins else second += black_wins first += white_wins end third = draws end [first, second, third] end |
#calculate_prediction(input) ⇒ Object
56 57 58 59 60 61 62 63 64 65 |
# File 'lib/neural_network.rb', line 56 def calculate_prediction(input) predictions = [] layer_parameters[0..-2].each_with_index do |layer, i| input_value = i == 0 ? input : predictions[i - 1] prediction_vector = multiply_vector(input_value, @weight_matrix[i]) prediction_vector = leaky_relu(prediction_vector) if layer_parameters[0..-2][i + 1] predictions << prediction_vector end predictions end |
#find_deltas(predictions, outcomes) ⇒ Object
115 116 117 118 119 120 121 122 123 124 |
# File 'lib/neural_network.rb', line 115 def find_deltas(predictions, outcomes) deltas = [] predictions.size.times do |index| delta = predictions[index] - outcomes[index] deltas[index] = delta @error = delta ** 2 end deltas end |
#find_weights(i, weights) ⇒ Object
84 85 86 87 |
# File 'lib/neural_network.rb', line 84 def find_weights(i, weights) weight_amount, offset, slice_value = weight_counts[i], offsets[i], layer_parameters[i] weights[(offset)...(offset + weight_amount)].each_slice(slice_value).to_a end |
#get_weights ⇒ Object
196 197 198 |
# File 'lib/neural_network.rb', line 196 def get_weights @weight_matrix end |
#initialize_weights ⇒ Object
13 14 15 16 17 18 19 20 |
# File 'lib/neural_network.rb', line 13 def initialize_weights weights = [] weight_counts.reduce(0, :+).times { weights << rand } layer_parameters[0..-2].each_with_index do |layer, i| @weight_matrix[i] = find_weights(i, weights) end @weight_matrix end |
#leaky_relu(input) ⇒ Object
150 151 152 |
# File 'lib/neural_network.rb', line 150 def leaky_relu(input) input.map { |value| value > 0 ? value : 0.0001 } end |
#multiply_vector(input, weight_matrix) ⇒ Object
76 77 78 79 80 81 82 |
# File 'lib/neural_network.rb', line 76 def multiply_vector(input, weight_matrix) predictions = [] weight_matrix.size.times do |index| predictions[index] = weighted_sum(input, weight_matrix[index]) end predictions end |
#offsets ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/neural_network.rb', line 22 def offsets if @offsets @offsets else @offsets = [0] weight_count_size = weight_counts.size weight_counts.each_with_index do |weight_count, i| if weight_count_size > i + 1 @offsets << @offsets.last + weight_count end end @offsets end end |
#relu_derivative(output) ⇒ Object
154 155 156 |
# File 'lib/neural_network.rb', line 154 def relu_derivative(output) output.map { |value| value > 0 ? 1 : 0.0001 } end |
#save_weights(filename) ⇒ Object
108 109 110 111 112 113 |
# File 'lib/neural_network.rb', line 108 def save_weights(filename) File.open(filename, "w") do |f| f.write(@weight_matrix.to_json) end puts 'saved weights to ' + filename end |
#set_weights(weight_matrix) ⇒ Object
38 39 40 |
# File 'lib/neural_network.rb', line 38 def set_weights(weight_matrix) @weight_matrix = weight_matrix end |
#softmax(vector) ⇒ Object
185 186 187 188 189 190 191 192 193 194 |
# File 'lib/neural_network.rb', line 185 def softmax(vector) sum = vector.sum.to_f vector.map do |value| if value == 0 0 else value / sum end end end |
#train(input, target_output) ⇒ Object
89 90 91 92 |
# File 'lib/neural_network.rb', line 89 def train(input, target_output) predictions = calculate_prediction(input) back_propagate(predictions, target_output) end |
#update_weights(weighted_deltas, i) ⇒ Object
126 127 128 129 130 131 132 133 134 135 |
# File 'lib/neural_network.rb', line 126 def update_weights(weighted_deltas, i) reversed_weight_matrix = @weight_matrix.reverse @weight_matrix.reverse[i].size.times do |index| @weight_matrix.reverse[i][index].size.times do |count| weight = @weight_matrix.reverse[i][index][count] adjusted_value = (weight - (@alpha * weighted_deltas[index])) @weight_matrix.reverse[i][index][count] = adjusted_value if adjusted_value > 0 end end end |
#weight_counts ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/neural_network.rb', line 42 def weight_counts if @weight_counts @weight_counts else @weight_counts = [] layer_parameters.each_with_index do |count, i| if layer_parameters[i + 1] @weight_counts << (layer_parameters[i] * layer_parameters[i + 1]) end end @weight_counts end end |
#weighted_sum(input, weights) ⇒ Object
67 68 69 70 71 72 73 74 |
# File 'lib/neural_network.rb', line 67 def weighted_sum(input, weights) total_weight = 0 raise raise NeuralNetworkError, 'arrays are not equal length' if input.size != weights.size input.size.times do |index| total_weight += input[index] * weights[index] end total_weight end |