LoginSignup
1
0

More than 3 years have passed since last update.

「ゼロから作るDeep Learning」自習メモ(その2)2章 パーセプトロン、半加算器、全加算器

Last updated at Posted at 2020-08-11

「ゼロから作るDeep Learning」(斎藤 康毅 著 オライリー・ジャパン刊)を読んでいる時に、参照したサイト等をメモしていきます。 その1← →その3

この本では、「ゼロから」作るために、pythonの基礎やパーセプトロンとか、土台からきちんと説明されています。
ただ、そのせいで、最初のうちは自分が何を作ろうとしているのか、わからなくなったりします。
結局、あ、そういうこと? と腑に落ちたのは、P86の図と説明を読んでからでした。

kankyou6.jpg

私みたいな古い人間は、「過去のデータを分析して」となると、回帰分析とかの手法をプログラムで組んで係数を計算させて、それを使って答えを出して、なんて感じで、アルゴリズムは人間が与えて、コンピュータは計算するだけでした。
しかし、ニューラルネットワークやディープラーニングは「データ駆動」であり、

ニューラルネットワークの利点は、すべての問題を同じ流れで解くことができる点にあります。たとえば、解くべき問題が「5」を認識する問題なのか、「犬」を認識する問題なのか、それとも、「人の顔」を認識する問題なのかといった詳細とは関係なしに、ニューラルネットワークは与えられたデータをただひたすら学習し、与えられた問題のパターンを発見しようと試みます。

どうしてそのようなことが可能になるのかというのが、この本には説明されているわけで、
それが、パーセプトロンであり、それを発展させたニューラルネットワークであり、その動作を行列で記述すると簡単に表現でき、しかもpythonのライブラリNumPyを使うと、プログラムもそのまま簡潔に記述できる、ということなわけです。

2.パーセプトロン、半加算器、全加算器

パーセプトロンについての説明は、特に難しいわけではありません。
しかし、パーセプトロンの重みとバイアスを変えると、ANDやORの論理回路を作れるということには驚きました。

素直にその先に行けないのが、年寄りの悪いところ。
昔の情報処理概論では、論理回路が真っ先にあって、そこから半加算器、全加算器の説明があるのがお決まりでした。

なので、この本では省略されている半加算器、全加算器をpythonで実装してみます。

P32の図
p32.jpg

なぜか、XORゲートの記号が載せてありません。
p32xor.jpg
 XOR

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

で、これらを組み合わせて、半加算器
p32han.jpg

# 半加算器 half adder
def HA(a, b):
    s = XOR(a, b)
    c = AND(a, b)
    return c, s

全加算器
p32zen.jpg

# 全加算器 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

その1← →その3

読めない用語集

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0