概要
書籍『ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装』2章のコードを参考に Python と Ruby でパーセプトロンによる論理回路
(ANDゲート, NANDゲート, ORゲート, XORゲート)を実装する。
計算処理では外部ライブラリを利用する。Python では NumPy を、Ruby では Numo::NArray を使用する。
環境構築が必要な場合はこちらを参照。
→ Python vs Ruby 『ゼロから作るDeep Learning』 1章 sin関数とcos関数のグラフ http://qiita.com/niwasawa/items/6d9aba43f3cdba5ca725
ANDゲート
重みとバイアスは、人力で適切な値を導いたもの。
Python
and_gate.py
import numpy as np
def AND(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5]) # 重み
b = -0.7 # バイアス
tmp = np.sum(w*x) + b
if tmp <= 0:
return 0
else:
return 1
if __name__ == '__main__':
for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]:
y = AND(xs[0], xs[1])
print(str(xs) + " -> " + str(y))
Ruby
and_gate.rb
require 'numo/narray'
def AND(x1, x2)
x = Numo::DFloat[x1, x2]
w = Numo::DFloat[0.5, 0.5] # 重み
b = -0.7 # バイアス
tmp = (w*x).sum + b
if tmp <= 0
0
else
1
end
end
if __FILE__ == $0
for xs in [[0, 0], [1, 0], [0, 1], [1, 1]]
y = AND(xs[0], xs[1])
puts "#{xs} -> #{y}"
end
end
実行結果
Python と Ruby の実行結果を比較する。入力が同じ値の場合は、出力も同じ値になっていることがわかる。
$ python and_gate.py
(0, 0) -> 0
(1, 0) -> 0
(0, 1) -> 0
(1, 1) -> 1
$ ruby and_gate.rb
[0, 0] -> 0
[1, 0] -> 0
[0, 1] -> 0
[1, 1] -> 1
NANDゲート
NANDゲートの実装は、重みとバイアスだけがANDゲートと異なる。
Python
nand_gate.py
import numpy as np
def NAND(x1, x2):
x = np.array([x1, x2])
w = np.array([-0.5, -0.5])
b = 0.7
tmp = np.sum(w*x) + b
if tmp <= 0:
return 0
else:
return 1
if __name__ == '__main__':
for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]:
y = NAND(xs[0], xs[1])
print(str(xs) + " -> " + str(y))
Ruby
nand_gate.rb
require 'numo/narray'
def NAND(x1, x2)
x = Numo::DFloat[x1, x2]
w = Numo::DFloat[-0.5, -0.5]
b = 0.7
tmp = (w*x).sum + b
if tmp <= 0
0
else
1
end
end
if __FILE__ == $0
for xs in [[0, 0], [1, 0], [0, 1], [1, 1]]
y = NAND(xs[0], xs[1])
puts "#{xs} -> #{y}"
end
end
実行結果
$ python nand_gate.py
(0, 0) -> 1
(1, 0) -> 1
(0, 1) -> 1
(1, 1) -> 0
$ ruby nand_gate.rb
[0, 0] -> 1
[1, 0] -> 1
[0, 1] -> 1
[1, 1] -> 0
ORゲート
ORゲートの実装も、重みとバイアスの値のみ異なる。
Python
or_gate.py
import numpy as np
def OR(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.2
tmp = np.sum(w*x) + b
if tmp <= 0:
return 0
else:
return 1
if __name__ == '__main__':
for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]:
y = OR(xs[0], xs[1])
print(str(xs) + " -> " + str(y))
Ruby
or_gate.rb
require 'numo/narray'
def OR(x1, x2)
x = Numo::DFloat[x1, x2]
w = Numo::DFloat[0.5, 0.5]
b = -0.2
tmp = (w*x).sum + b
if tmp <= 0
0
else
1
end
end
if __FILE__ == $0
for xs in [[0, 0], [1, 0], [0, 1], [1, 1]]
y = OR(xs[0], xs[1])
puts "#{xs} -> #{y}"
end
end
実行結果
$ python or_gate.py
(0, 0) -> 0
(1, 0) -> 1
(0, 1) -> 1
(1, 1) -> 1
$ ruby or_gate.rb
[0, 0] -> 0
[1, 0] -> 1
[0, 1] -> 1
[1, 1] -> 1
XORゲート
XORゲートの実装では、NAND・OR・ANDのゲートを重ねた多層パーセプトロンを使う。
Python
xor_gate.py
from and_gate import AND
from or_gate import OR
from nand_gate import NAND
def XOR(x1, x2):
s1 = NAND(x1, x2)
s2 = OR(x1, x2)
y = AND(s1, s2)
return y
if __name__ == '__main__':
for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]:
y = XOR(xs[0], xs[1])
print(str(xs) + " -> " + str(y))
Ruby
xor_gate.rb
require './and_gate'
require './or_gate'
require './nand_gate'
def XOR(x1, x2)
s1 = NAND(x1, x2)
s2 = OR(x1, x2)
y = AND(s1, s2)
return y
end
if __FILE__ == $0
for xs in [[0, 0], [1, 0], [0, 1], [1, 1]]
y = XOR(xs[0], xs[1])
puts "#{xs} -> #{y}"
end
end
実行結果
$ python xor_gate.py
(0, 0) -> 0
(1, 0) -> 1
(0, 1) -> 1
(1, 1) -> 0
$ ruby xor_gate.rb
[0, 0] -> 0
[1, 0] -> 1
[0, 1] -> 1
[1, 1] -> 0
参考資料
- Python vs Ruby 『ゼロから作るDeep Learning』 まとめ - Qiita http://qiita.com/niwasawa/items/b8191f13d6dafbc2fede