ズッキーニのプログラミング実験場

プログラミング + アカデミック + 何か面白いこと。 記載されているものは基本的に私が所属する団体とは関係がありません。

   Jul 15

[Ruby]最急降下法によるニューラルネットの学習 part1

by zuqqhi2 at 2013年7月15日
Pocket

やりたいこと

ニューラルネットワークのプログラムを書きたくなったので、
一番簡単な最急降下法でプログラムを書いてみる。
今日は、とりあえず枠組みだけ。

プログラム

入力データ

適当な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

Related Posts

Pocket

You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.