ゼロから作るDeep LearningをMac/Raspberry Piでゼロから勉強 1章から3章

1章 Python入門

 1章は基本的にpythonの初歩的な内容なのでざっと読み飛ばしました。章の最後で、以下のような本やサイトが推奨されていました。

2章 パーセプトロン

 ここからは、実際に手を動かして本に書いてあることをベースに、所々自分でアレンジしてコードを書いていきます。コードは、GitHubのリポジトリにアップしています。

 これ以降は、章で理解する概要と、上記のリポジトリにアップしたコードの具体的な中身を説明していきます。

 2章では、パーセプトロン単体でANDゲート、ORゲート、NANDゲートを作れることと、多層(2層)のパーセプトロンでNORゲートもつくれることを理解できます。NANDゲートさえあれば、組み合わせで論理回路は何でもつくれちゃうというのは、大学の時に習った覚えがあります。つまりパーセプトロンを組み合わせれば汎用的になんでもできちゃうわけですね。

 パーセプトロンを図示すると以下のようなかたちになります。

perceptron

 丸がニューロン(もしくはノード)で、x1,x2が入力信号yが出力信号, w1,w2が重み係数。数式としては以下となります。yが閾値θを超えて1になるとニューロンが発火したこととなります。

$$
y = 0 (w_1 x_1 + w_2 x_2 <= \theta) \\
y = 1 (w_1 x_1 + w_2 x_2 > \theta) \\
$$

以下作成したコードの説明です。

2_3_1_perceptron.py

 ANDゲートです。ソースコードは以下。

def AND(x1, x2):
    w1, w2, theta = 0.5, 0.5, 0.7
    tmp = x1*w1 + x2*w2
    if tmp <= theta:
        return 0
    else:
        return 1

print("AND(0,0)")
print(AND(0,0))
print("AND(1,0)")
print(AND(1,0))
print("AND(0,1)")
print(AND(0,1))
print("AND(1,1)")
print(AND(1,1))

 実行結果は以下。ふむ、ANDゲートだ。

$ python 2_3_1_perceptron.py
AND(0,0)
0
AND(1,0)
0
AND(0,1)
0
AND(1,1)
1

2_3_2_perceptron.py

 2_3_1_perceptron.pyとやっていることは同じですが、AND、OR、NANAD、ORをnumpyを使って行列を使って計算できるように書き直しています。コードは以下。

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

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

def OR(x1, x2):
    x = np.array([x1,x2])
    w = np.array([0.5,0.5])
    b = - 0.3
    tmp = np.sum(w*x) + b
    if tmp <=0:
        return 0
    else:
        return 1


print("AND(0,0)")
print(AND(0,0))
print("AND(1,0)")
print(AND(1,0))
print("AND(0,1)")
print(AND(0,1))
print("AND(1,1)")
print(AND(1,1))

print("NAND(0,0)")
print(NAND(0,0))
print("NAND(1,0)")
print(NAND(1,0))
print("NAND(0,1)")
print(NAND(0,1))
print("NAND(1,1)")
print(NAND(1,1))

print("OR(0,0)")
print(OR(0,0))
print("OR(1,0)")
print(OR(1,0))
print("OR(0,1)")
print(OR(0,1))
print("OR(1,1)")
print(OR(1,1))

 実行結果は以下。ふむ、なるほど。

$ python 2_3_2_perceptron.py
AND(0,0)
0
AND(1,0)
0
AND(0,1)
0
AND(1,1)
1
NAND(0,0)
1
NAND(1,0)
1
NAND(0,1)
1
NAND(1,1)
0
OR(0,0)
0
OR(1,0)
1
OR(0,1)
1
OR(1,1)
1

2_5_2_perceptron.py

 1層では実現できないNORをNAND、OR、ANDを組み合わせて2層のパーセプトロンを実現。線形から非線形という感じだろうか。コードは以下。

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

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

def OR(x1, x2):
    x = np.array([x1,x2])
    w = np.array([0.5,0.5])
    b = - 0.3
    tmp = np.sum(w*x) + b
    if tmp <=0:
        return 0
    else:
        return 1

def XOR(x1, x2):
    s1 = NAND(x1, x2)
    s2 = OR(x1, x2)
    y = AND(s1, s2)
    return y


print("XOR(0,0)")
print(XOR(0,0))
print("XOR(1,0)")
print(XOR(1,0))
print("XOR(0,1)")
print(XOR(0,1))
print("XOR(1,1)")
print(XOR(1,1))

 実行結果は以下

$ python 2_5_2_perceptron.py XOR(0,0)
0
XOR(1,0)
1
XOR(0,1)
1
XOR(1,1)
0

3章 ニューラルネットワーク

 3章はニューラルネットワークに関して。

3.1 パーセプトロンからニューラルネットワークへ

 ニューラルネットワークのニューロンは以下のように図示できるそうです。

neuralnetwork
 数式は以下となります。

$$
a = b + w_1 x_1 + w_2 x_2
$$

$$
y = h(a)
$$

 このh(a)が活性化関数と呼ばれるのですが、この活性化関数がステップ関数(ある閾値を境に出力が切り替わる関数。以下のような数式)のニューロンをパーセプトロンと呼ぶ。と言っているように読めます。ちなみに初版の(3,3)の式のxはyの間違いじゃないかという気がする。

$$
h(a) = 0 (a >=0 ) \\ h(a) = 1 (a < 0)
$$

 でも、なんとなくパーセプトロンの定義違うような気も…よく読むと本にもパーセプトロンに関しては「本書では厳密な統一がなされずに使われています。」という注意書きもある。どういうこっちゃ!?一般的には「単純パーセプトロン」が活性化関数にステップ関数を使用した単層のネットワークで、「多層のパーセプトロン」は基本的にニューラルネットワークになるみたいです。そしてどうも多層になると、活性化関数はステップ関数以外の活性化関数が使われるようです。

 ふむ、わかったようなわからないような…

3.2 活性化関数

 ここから活性化関数の実装方法と具体的な中身をみていくことになります。

3_2_3_stepfunc.py

 単純パーセプトロンの活性化関数として使われるステップ関数のプログラム。ソースは以下

import numpy as np
import matplotlib.pylab as plt

def step_function(x):
    y = x > 0
    return y.astype(np.int)

x = np.arange(-5.0, 5.0 , 0.1)
y = step_function(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1)
plt.show()

 step_function(x)の中身は、numpyの配列を扱うためにこのような記述になっています。astype()はnumpy配列の型の変換を行えるメソッドです。step_function(x)は他にも、以下のような書き方もできるようです。

def step_function(x):
    return np.array(x > 0, dtype=np.int)

 以下実行結果です。

$ python 3_2_3_stepfunc.py  

 以下のようなグラフが表示されます。
step function

3_2_4_sigmoid.py

 同様に活性化関数のシグモイド関数。

import numpy as np
import matplotlib.pylab as plt

def sigmoid(x):
    return 1/(1 + np.exp(-x))

x = np.arange(-5.0, 5.0 , 0.1)
y = sigmoid(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1)
plt.show()

 以下実行結果です。

$ python 3_2_4_sigmoid.py  

 以下のようなグラフが表示されます。
sigmoid

 ステップ関数より滑らかな関数ということがわかります。

3_2_7_relu.py

 ReLUという関数です。最近人気らしくよく使われているそうです。

import numpy as np
import matplotlib.pylab as plt

def relu(x):
    return np.maximum(0, x)

x = np.arange(-5.0, 5.0 , 0.1)
y = relu(x)
plt.plot(x, y)
plt.ylim(-1, 5)
plt.show()

 以下実行結果です。

$ python 3_2_7_relu.py

 以下のようなグラフが表示されます。

3.3 多次元配列の計算

 Numpyを使った多次元配列の計算方法。行列の内積の計算方法まで解説しています。詳細は省略。

 続きは勉強中

スポンサーリンク
レクタングル(大)広告
レクタングル(大)広告

シェアする

  • このエントリーをはてなブックマークに追加

フォローする