やりたいこと
ニューラルネットワークのプログラムを書きたくなったので、
一番簡単な最急降下法でプログラムを書いてみる。
今日は、とりあえず枠組みだけ。
プログラム
入力データ
適当なinput layerのデータ。
1,2,3,4,5,15,7,11,9,10,1 14,21,6,8,2,9,4,5,10,7,2 19,5,13,9,2,8,18,11,7,3,3 11,9,7,13,19,3,8,2,12,10,4 9,2,3,15,11,17,12,8,9,10,5
nn.rb
require 'csv' NUM_ITERATION = 10 NUM_INPUT_DATA = 5 NUM_INPUT_LAYER = 10 NUM_HIDDEN_LAYER = 15 NUM_OUTPUT_LAYER = 5 # Input Data data = CSV.open("data.csv", "r") line_num = 0 input_data = [] expected_result = [] data.each do |row| input_data << [] field_cnt = 0 NUM_INPUT_LAYER.times do |j| input_data[line_num] << row[field_cnt].to_i field_cnt += 1 end expected_result << row[field_cnt].to_i line_num += 1 end # Input Layer Initialize input_layer = [] NUM_INPUT_LAYER.times do |i| input_layer << 0.0 end # Hidden Layer Initialize hidden_layer = [] NUM_HIDDEN_LAYER.times do |i| hidden_layer << 0.0 end # Output Layer Initialize output_layer = [] NUM_OUTPUT_LAYER.times do |i| output_layer << 0.0 end # Initialize Parameter weight_input_hidden = [] NUM_INPUT_LAYER.times do |i| weight_input_hidden << [] NUM_HIDDEN_LAYER.times do |h| weight_input_hidden[i] << rand end end weight_hidden_output = [] NUM_HIDDEN_LAYER.times do |i| weight_hidden_output << [] NUM_OUTPUT_LAYER.times do |h| weight_hidden_output[i] << rand end end threshold_hidden = [] NUM_HIDDEN_LAYER.times do |i| threshold_hidden << rand end # Sigmoid Function def sigmoid(val) return 1.0/(1.0 + Math.exp(-val)) end # Main Loop NUM_ITERATION.times do |itr| error = 0.0 NUM_INPUT_DATA.times do |d| # Set data to input layer NUM_INPUT_LAYER.times do |i| input_layer[i] = input_data[d][i] end # Calculate hidden layer's output NUM_HIDDEN_LAYER.times do |h| sum = 0.0 NUM_INPUT_LAYER.times do |i| sum += weight_input_hidden[i][h] * input_layer[i] end sum += threshold_hidden[h] hidden_layer[h] = sigmoid(sum) end # Calculate output layer's output NUM_OUTPUT_LAYER.times do |o| sum = 0.0 NUM_HIDDEN_LAYER.times do |h| sum += weight_hidden_output[h][o] * hidden_layer[h] end output_layer[o] = sigmoid(sum) end # Calculated total error NUM_OUTPUT_LAYER.times do |o| error += (expected_result[o] - output_layer[o])*(expected_result[o] - output_layer[o]) end end # puts "Iteration #{itr+1} total error : #{error}" end