パーセプトロン



[ゼロから作るDeep Learning ――Pythonで学ぶディープラーニングの理論と実装](https://github.com/oreilly-japan/deep-learning-from-scratch) 3章のコード

## 内積（ドット積）

```python
#　行列Aの1次元目の列数(3)と行列Bの0次元目の行数(3)が同じ
a = np.array([[1,2,3],[4,5,6]])
b = np.array([[1,2],[3,4],[5,6]])
print(a.shape) # (2, 3) 1次元目の列数と
print(b.shape) # (3, 2) 0次元目の行数の一致が必須
c = np.dot(a,b)
print(c)
print(c.shape) # (2, 2) Aの行数、Bの列数
>> 
	[[22 28]
	 [49 64]]
```

```python:出力
e = np.dot(b,a)
print(e)
>>
	[[ 9 12 15]
	 [19 26 33]
	 [29 40 51]]
```

## 指数関数（exp）

```python
a = np.array([1,2,3,4,5])
b = np.exp(a)
>>>
	array([   2.71828183,    7.3890561 ,   20.08553692,   54.59815003,
        148.4131591 ])
```

ネイピア数
e=2.71828183


## シグモイド関数

ステップ関数を滑らかにしたもの

$$
h(x)=\frac{1}{1+\exp(-x)}\
$$

```python:実装
def sigmoid(x):
    return 1 / (1 + np.exp(-x))
```

```python:出力
x = np.arange(-10,10,1)
y = sigmoid(x)
>>>
	array([  4.53978687e-05,   1.23394576e-04,   3.35350130e-04,
         9.11051194e-04,   2.47262316e-03,   6.69285092e-03,
         1.79862100e-02,   4.74258732e-02,   1.19202922e-01,
         2.68941421e-01,   5.00000000e-01,   7.31058579e-01,
         8.80797078e-01,   9.52574127e-01,   9.82013790e-01,
         9.93307149e-01,   9.97527377e-01,   9.99088949e-01,
         9.99664650e-01,   9.99876605e-01])
```

## ソフトマックス関数

$$
y_k=\frac{\exp(a_k)}{\sum_{i=1}^{n}\exp(a_i)}
$$

```python:実装
def softmax(a):
    c = np.max(a) # オーバーフロー対策
    exp_a = np.exp(a - c)
    sum_a = np.sum(exp_a)
    return exp_a / sum_a
```

```python:出力
a = np.array([1,2,3,4,5])
softmax(a)
>>>
	array([ 0.01165623,  0.03168492,  0.08612854,  0.23412166,  0.63640865])
```

## サンプルコード

使われやすい関数
・回帰問題：恒等関数
・分類問題：ソフトマックス関数

`load_mnist`は以下にまとめられている汎化関数のひとつ
https://github.com/oreilly-japan/deep-learning-from-scratch/blob/master/dataset/mnist.py

```python
import sys, os
sys.path.append(os.pardir)  # 親ディレクトリのファイルをインポートするための設定
import numpy as np
import pickle
from dataset.mnist import load_mnist
from common.functions import sigmoid, softmax

def get_data():
    # flatten : 1次元配列にする
    # normalize : 0 - 1
    # one-hot : Trueなら1 Falseなら0 に割り振る
    (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
    # (訓練データ,訓練ラベル) (テストデータ,テストラベル)
    return x_test, t_test

def init_network():
    # pickle 実行中のオブジェクトをファイルとして保存する
    with open("sample_weight.pkl", 'rb') as f:
        network = pickle.load(f)
    return network

def predict(network, x):
    W1, W2, W3 = network['W1'], network['W2'], network['W3']
    b1, b2, b3 = network['b1'], network['b2'], network['b3']

    a1 = np.dot(x, W1) + b1
    z1 = sigmoid(a1)
    a2 = np.dot(z1, W2) + b2
    z2 = sigmoid(a2)
    a3 = np.dot(z2, W3) + b3
    y = softmax(a3)

    return y

x, t = get_data()
network = init_network()

# 入力層：784 -> 出力層：10
print(x.shape) # (10000, 784)
print(network['W1'].shape) # (784, 50)
print(network['W2'].shape) # (50, 100)
print(network['W3'].shape) # (100, 10)

print(network['b1'].shape) # (50,)
print(network['b2'].shape) # (100,)
print(network['b3'].shape) # (10,)

batch_size = 100 # バッチの数
accuracy_cnt = 0

# 100枚ずつバッジとして取り出す（計算の高速化） 
for i in range(0, len(x), batch_size):
    x_batch = x[i:i+batch_size] # x[0:100], x[100:200] ...
    y_batch = predict(network, x_batch)
    p = np.argmax(y_batch, axis=1) # 最も確率の高い要素の'インデックス'を取得
    accuracy_cnt += np.sum(p == t[i:i+batch_size])

print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
```

> 参考
[高卒でもわかる機械学習 (2) 単純パーセプトロン](http://hokuts.com/2015/11/25/ml2_perceptron/)
[ニューラルネットワーク入門](http://www-ailab.elcom.nitech.ac.jp/lecture/neuro/menu.html)
[単純パーセプトロンをPythonで組んでみる](http://tjo.hatenablog.com/entry/2013/05/01/190247)