はじめに
書籍「機械学習と深層学習」を購入して勉強していたら、C言語で書いてあるプログラムが簡単そうだったので、Rubyで書き換えてみることにしました。
ちなみに、書籍で紹介されているソースコードは以下のURLからダウンロード可能です。
nn.c
第4章 ニューラルネット
4.1 ニューラルネットワークの基礎
上記のnn.cをRubyで書き換えてみました。
なお、完全に同一ではありませんので悪しからず。
nn.rb
# ライブラリの読込
include Math
# 定数の定義
$inputno = 3
$hiddenno = 2
$maxinputno = 100
# 学習データの読み込み
def getdata()
e = [
[0.0,0.0],
[0.0,1.0],
[1.0,0.0],
[1.0,1.0]
]
return e
end
# 順方向の計算
def forward(wh, wo, hi, e)
u = 0.0
o = 0.0
(0..$hiddenno-1).each do |i|
u = 0.0
j = 0
e.each do |e_val|
u += e_val * wh[i][j]
j += 1
end
u -= wh[i][j]
hi[i] = f(u)
end
o = 0.0
(0..$hiddenno).each do |i|
o += hi[i] * wo[i]
end
o -= wo[wo.length-1]
return f(o)
end
# 中間層の重みの初期化
def initwh(n_of_hidden, n_of_row)
w = Array.new(n_of_hidden).map{
Array.new(n_of_row + 1)
}
w[0][0] = -2.0
w[0][1] = 3.0
w[0][2] = -1.0
w[1][0] = -2.0
w[1][1] = 1.0
w[1][2] = 0.5
return w
end
# 出力層の重みの初期化
def initwo(n_of_hidden)
w = Array.new(n_of_hidden + 1)
w[0] = -60.0
w[1] = 94.0
w[2] = -1.0
return w
end
# 中間層の出力の初期化
def inithi(n_of_hidden)
hi = Array.new(n_of_hidden + 1).map{ 0.0 }
return hi
end
# 伝達関数
def f(u)
x = 0.0
if u >= 0.0
x = 1.0
else
x = 0.0
end
return x
#return 1.0 / (1.0 + exp(-u))
end
# メインプログラム
e = getdata()
wh = initwh($hiddenno, e[0].length)
wo = initwo($hiddenno)
hi = inithi($hiddenno)
n_of_e = e.length
puts "データの個数:#{n_of_e}"
o = 0.0
e.each do |vals|
o = forward(wh, wo, hi, vals)
puts "入力: #{vals}, 出力: #{o}"
end
実行
$ ruby nn.rb
データの個数:4
入力: [0.0, 0.0], 出力: 0.0
入力: [0.0, 1.0], 出力: 1.0
入力: [1.0, 0.0], 出力: 1.0
入力: [1.0, 1.0], 出力: 0.0
できた!