「ゼロから作るDeep Learning」(斎藤 康毅 著 オライリー・ジャパン刊)を読んでいる時に、参照したサイト等をメモしていきます。 その1← →その3
この本では、「ゼロから」作るために、pythonの基礎やパーセプトロンとか、土台からきちんと説明されています。
ただ、そのせいで、最初のうちは自分が何を作ろうとしているのか、わからなくなったりします。
結局、あ、そういうこと? と腑に落ちたのは、P86の図と説明を読んでからでした。
私みたいな古い人間は、「過去のデータを分析して」となると、回帰分析とかの手法をプログラムで組んで係数を計算させて、それを使って答えを出して、なんて感じで、アルゴリズムは人間が与えて、コンピュータは計算するだけでした。
しかし、ニューラルネットワークやディープラーニングは「データ駆動」であり、
ニューラルネットワークの利点は、すべての問題を同じ流れで解くことができる点にあります。たとえば、解くべき問題が「5」を認識する問題なのか、「犬」を認識する問題なのか、それとも、「人の顔」を認識する問題なのかといった詳細とは関係なしに、ニューラルネットワークは与えられたデータをただひたすら学習し、与えられた問題のパターンを発見しようと試みます。
どうしてそのようなことが可能になるのかというのが、この本には説明されているわけで、
それが、パーセプトロンであり、それを発展させたニューラルネットワークであり、その動作を行列で記述すると簡単に表現でき、しかもpythonのライブラリNumPyを使うと、プログラムもそのまま簡潔に記述できる、ということなわけです。
##2.パーセプトロン、半加算器、全加算器
パーセプトロンについての説明は、特に難しいわけではありません。
しかし、パーセプトロンの重みとバイアスを変えると、ANDやORの論理回路を作れるということには驚きました。
が
素直にその先に行けないのが、年寄りの悪いところ。
昔の情報処理概論では、論理回路が真っ先にあって、そこから半加算器、全加算器の説明があるのがお決まりでした。
なので、この本では省略されている半加算器、全加算器をpythonで実装してみます。
import numpy as np
def perceptron(x1, x2, w1, w2, b):
tmp = w1*x1 + w2*x2 + b
if tmp <= 0:
return 0
else:
return 1
def AND(x1, x2):
return perceptron(x1, x2, 0.5, 0.5, -0.7)
def NAND(x1, x2):
return perceptron(x1, x2, -0.5, -0.5, 0.7)
def OR(x1, x2):
return perceptron(x1, x2, 0.5, 0.5, -0.2)
def XOR(x1, x2):
s1 = NAND(x1, x2)
s2 = OR(x1, x2)
y = AND(s1, s2)
return y
# 半加算器 half adder
def HA(a, b):
s = XOR(a, b)
c = AND(a, b)
return c, s
# 全加算器 full adder
def FA(a, b, c1):
c2, s2 = HA(a, b)
c3, s3 = HA(s2, c1)
c4 = OR(c2,c3)
return c4, s3
4ビット(0~15)の足し算をする計算機
def fourALU(a,b):
c0, s0 = HA(a[0],b[0])
c1, s1 = FA(a[1],b[1], c0)
c2, s2 = FA(a[2], b[2], c1)
c3, s3 = FA(a[3], b[3], c2)
y = np.array([s0, s1, s2, s3, c3])
return y
# 10進数を2進数にして配列に格納して戻す。
# ただし、下1桁目から格納するので、左右が逆になる
def i2arr(a):
if a < 0:
print(a," 加算範囲外")
aa = np.array([0, 0, 0, 0])
elif a > 15:
print(a," 加算範囲外")
aa = np.array([1, 1, 1, 1])
else:
a3 = a // 8
m = a % 8
a2 = m // 4
m = m % 4
a1 = m // 2
a0 = m % 2
aa = np.array([a0, a1, a2, a3])
return aa
a = 4
b = 9
aa = i2arr(a)
ba = i2arr(b)
y = fourALU(aa, ba)
print(aa)
print(ba)
print(y)
print(a,"+",b,"=",y[0]+y[1]*2+y[2]*4+y[3]*8+y[4]*16)
実行結果は
[0 0 1 0]
[1 0 0 1]
[1 0 1 1 0]
4 + 9 = 13