Python vs Ruby 『ゼロから作るDeep Learning』 2章 パーセプトロンによる論理回路

## 概要

書籍『ゼロから作る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

```python
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

```ruby
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

```python
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

```ruby
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

```python
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

```ruby
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

```python
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

```ruby
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