kaeken(嘉永島健司)のTech探究ブログ

主に情報科学/情報技術全般に関する知見をポストします。(最近は、特にData Science、機械学習、深層学習、統計学、Python、数学、ビッグデータ)

手書き数字認識とバッチ処理『ゼロから作るDeep Learning』

『ゼロから作るDeep Learning』3章最後

いよいよ手書き数字認識に入る。ここでは、「学習」フェーズは完了している前提で、「推論」フェーズのみ順方向伝播方式で実施。

# MNISTという手書き数字画像セットを準備
# git clone https://github.com/oreilly-japan/deep-learning-from-scratch.git
# cd deep-learning-from-scratch/ch03
# ls ../dataset/mnist.py
# ../dataset/mnist.py
# cat mnist_check.py

import sys, os
sys.path.append(os.pardir) #親ディレクトリのファイルをインポート
from dataset.mnist import load_mnist

# load_minst((訓練画像、訓練ラベル), (テスト画像、テストラベル)
# 初回呼び出しはネットDL、2回目以降はローカルpickleファイル読込
# 引数
# normalize: 0.0..1.0に正規化
# flatten: 1次元配列化
# one_hot_label: 正解ラベルのみ1でそれ以外は0にするone-hot表現として格納するか
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)

print(x_train.shape) # (60000, 784)
print(t_train.shape) # (60000,)
print(x_test.shape) # (10000, 784)
print(t_test.shape) # (10000,)

続いて、MNIST画像の表示スクリプトmnist_show.pyを参考に、保存処理mnist_save.pyを作って確認

# cat mnist_save.py
# coding: utf-8
import sys, os
sys.path.append(os.pardir)  # 親ディレクトリのファイルをインポートするための設定
import numpy as np
from dataset.mnist import load_mnist
from PIL import Image

def img_save(img):
    pil_img = Image.fromarray(np.uint8(img))
    pil_img.save('mnist_save_sample.png')

(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)

img = x_train[0]
label = t_train[0]
print(label)  # 5

print(img.shape)  # (784,)
img = img.reshape(28, 28)  # 形状を元の画像サイズに変形
print(img.shape)  # (28, 28)

img_save(img)

# py mnist_save.py
5
(784,)
(28, 28)

出力された画像

f:id:kaeken:20161107013732p:plain

続いて、ニューラルネットワークの推論処理を確認

# cat neuralnet_mnist.py
# coding: utf-8
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():
  # 前処理pre-processingとして、正規化normalizationを実施
    (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
    return x_test, t_test

# pickleファイルに保存された学習済重みパラメータの読込
def init_network():
    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()
accuracy_cnt = 0
for i in range(len(x)):
    y = predict(network, x[i])
    p= np.argmax(y) # 最も確率の高い要素のインデックスを取得
    if p == t[i]:
        accuracy_cnt += 1

print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
#=>Accuracy:0.9352で、
# 93.52%正しく分類できた

続いてバッチ処理

バッチbatch:ひとまとまりの入力データ束

バッチ処理によって1枚あたりの処理時間を短縮できる

# cat neuralnet_mnist_batch.py
# coding: utf-8
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():
    (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():
    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()

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

for i in range(0, len(x), batch_size):
    x_batch = x[i:i+batch_size]
    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)))

実際に比較してみると、確かに高速化していることが確認できた

# バッチなし
# time py neuralnet_mnist.py
Accuracy:0.9352

real    0m2.220s
user    0m2.859s
sys 0m0.521s

# バッチあり
# time py neuralnet_mnist_batch.py
Accuracy:0.9352

real    0m0.991s
user    0m0.857s
sys 0m0.312s

出力層の設計(分類問題で使うソフトマックス関数)『ゼロから作るDeep Learning』

『ゼロから作るDeep Learning』3章続き

# ニューラルネットワークの問題は、回帰問題と分類問題に大別できる
# 回帰問題とは、入力データから数値予測を行う問題(例 入力:人物画像 → 出力:体重予測)
# 分類問題とは、入力データがどのクラスに属するかという問題(例 入力:人物画像 → 出力:男性クラスor女性クラス)
# 回帰問題では恒等関数を使い、分類問題ではソフトマックス関数softmaxを使う
# ソフトマックス関数は、分子に入力信号の指数関数、分母にすべての入力信号の指数関数の和から構成される
def softmax(x):
  return np.exp(x) / np.sum(np.exp(x))

# 指数関数の値が巨大になりすぎる場合のオーバーフロー対策として、
# 補正値を導入する必要がある(通常、補正値は入力信号の中で最大の値)
def softmax(x):
  c = np.max(x) # オーバーフロー対策の補正値
  return np.exp(x - c) / np.sum(np.exp(x - c))

# 例
import numpy as np
import my_module as my

a = np.array([0.3, 2.9, 4.0])
y = my.softmax(a)
print(y) #=> [ 0.01821127  0.24519181  0.73659691]
print(np.sum(y)) #=> 1.0


# ソフトマックス関数の出力は、0から1の間の実数で、総和は1なので確率として解釈できる
# ソフトマックス関数を適用しても、元データの大小関係は変わらない
# 機械学習の問題を解く手順として、「学習」と「推論」の2フェーズのうち、推論フェーズではソフトマックス関数は省略する
# 出力層のニューロン数は、分類したいクラス数に設定する (例 入力:数字画像 → 出力層:10クラス)

ニューラルネットワーク フォワード方向処理『ゼロから作るDeep Learning』3章

『ゼロから作るDeep Learning』3章続き。

ニューラルネットワークの順方向forward処理について。

# 順方向forward処理:入力から出力方向への伝達処理。あとで逆方向backward処理について学ぶ
# 以下3層ニューラルネットワーク構成とする
# 入力層(第0層)
# 隠れ層1(第1層)
# 隠れ層2(第2層)
# 出力層(第3層)

# cat forward.py
#!/usr/bin/env python

import numpy as np
import my_module as my

def init(): #初期化
  n = {}
  # weight
  n['W1'] = np.array([ [0.1, 0.3, 0.5], [0.2, 0.4, 0.6] ])
  n['W2'] = np.array([ [0.1, 0.4], [0.2, 0.5], [0.3, 0.6] ])
  n['W3'] = np.array([ [0.1, 0.3], [0.2, 0.4] ])
  # bias
  n['b1'] = np.array([0.1, 0.2, 0.3])
  n['b2'] = np.array([0.1, 0.2])
  n['b3'] = np.array([0.1, 0.2])

  return n


def forward(n, x): #入力を出力へ変換する処理をまとめた関数
  W1, W2, W3 = n['W1'], n['W2'], n['W3']
  b1, b2, b3 = n['b1'], n['b2'], n['b3']

  # 1層目
  a1 = np.dot(x, W1) + b1
  z1 = my.sigmoid(a1)
  # 2層目
  a2 = np.dot(z1, W2) + b2
  z2 = my.sigmoid(a2)
  # 出力層
  a3 = np.dot(z2, W3) + b3
  y = my.identity(a3) #何もせずそのまま返す恒等関数

  return y


n = init()
x = np.array([1.0, 0.5])
y = forward(n, x)
print(y)

# 実行
 py forward.py
[ 0.31682708  0.69627909]

次は、出力層の設計に入る。

Pythonで自作関数をモジュールとして読み込む

参考: Python3のimport・下位/上位階層のモジュールをインポートしたい【import】【Python3】 - DRYな備忘録

『ゼロから作るDeep Learning』で自作関数がだんだん説明なしに使われていくので、いったんモジュールにまとめて読み込むことにする。

本番環境ならどこに配置するか考える必要はあるが、ひとまず同一ディレクトリ内にmy_module.pyとしてまとめておく。

$ cat my_module.py # 自作関数をまとめたモジュール
import numpy as np

def step(x): #step関数
  return np.array(x > 0, dtype=np.int)

def sigmoid(x): #シグモイド関数
  return 1 / (1 + np.exp(-x))

def relu(x): #ReLU関数
  return np.maximum(0, x)

def identity(x): #恒等関数
  return x

# 呼び出し
import my_module as my
...
print(my.sigmoid(param))
...

新たに定義された関数はmy_module.pyに追加していく。

ニューラルネットワーク計算準備としてNumPyで多次元配列処理(内積=ドット積)

f:id:kaeken:20161105113024p:plain 『ゼロから作るDeep Learning』3章続き。 ニューラルネットワークの実装で多次元配列が必要。 そこでPythonのNumPyの多次元配列操作を改めて詳しく学ぶ。

>>> import numpy as np
>>> A = np.array([ [1,2], [3,4], [5,6] ])

>>> A
array([[1, 2],
       [3, 4],
       [5, 6]])

>>> A.shape # 配列の各次元の大きさをタプルで返す
(3, 2)

>>> A.ndim # 配列の次元数
2

# 次元が統一されていない場合は、1次元扱いの様子
>>> B = np.array([ [1], [2,3], [4,5,6] ])
>>> B
array([[1], [2, 3], [4, 5, 6]], dtype=object)
>>> B.shape
(3,)
>>> B.ndim
1

>>> C = np.array([ [1,2,3], [4,5], [6] ])
>>> C
array([[1, 2, 3], [4, 5], [6]], dtype=object)
>>> C.shape
(3,)
>>> C.ndim
1

# 続いて内積
# 行列の内積とは、行と列の要素ごとの積と和によって計算する
# 2次元配列は行列matrixと呼び、横方向の行rowと縦方向の列columnがある

>>> A = np.array([ [1,2], [3,4] ]) 
>>> A
array([[1, 2],
       [3, 4]])
>>> A.shape
(2, 2)

>>> B = np.array([ [5,6], [7,8] ])
>>> B
array([[5, 6],
       [7, 8]])
>>> B.shape
(2, 2)

>>> np.dot(A, B) # 行列A,Bの内積(ドット積)
array([[19, 22],
       [43, 50]])

#計算内容内訳
>>> 1*5 + 2*7
19
>>> 3*5 + 4*7
43
>>> 1*6 + 2*8
22
>>> 3*6 + 4*8
50

#行列の積は、被演算子(A,B)の順番が異なると結果も異なる
>>> np.dot(B, A)
array([[23, 34],
       [31, 46]])

#続いて、2x3の行列と3x2の行列の積
>>> C = np.array([ [1,2,3], [4,5,6] ])
>>> C
array([[1, 2, 3],
       [4, 5, 6]])
>>> C.shape
(2, 3)

>>> D = np.array([ [1,2], [3,4], [5,6] ])
>>> D
array([[1, 2],
       [3, 4],
       [5, 6]])
>>> D.shape
(3, 2)

>>> np.dot(C, D)
array([[22, 28],
       [49, 64]])
>>> np.dot(C, D).shape
(2, 2)

#逆
>>> np.dot(D, C)
array([[ 9, 12, 15],
       [19, 26, 33],
       [29, 40, 51]])
>>> np.dot(D, C).shape
(3, 3)


>>> # 内積できる行列の形状には条件がある
... # 行列Aの1次元目の要素数(列数)と
... # 行列Bの0次元目の要素数(行数)を同じにする必要がある

>>> # 2x3行列と3x2行列は内積できるが、
... # 2x3行列と2x3行列の内積はできない

>>> C
array([[1, 2, 3],
       [4, 5, 6]])
>>> E = C
>>> E
array([[1, 2, 3],
       [4, 5, 6]])

>>> C.shape
(2, 3)
>>> E.shape
(2, 3)

>>> np.dot(C, E)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: shapes (2,3) and (2,3) not aligned: 3 (dim 1) != 2 (dim 0)

# 再度確認
>>> C.shape[1]
3
>>> D.shape[0]
3
>>> E.shape[0]
2

# バリデーション
>>> if C.shape[1] == D.shape[0]:
...   print('.dot() OK!')
... else:
...   print('.dot() NG!')
...
.dot() OK!

>>> if C.shape[1] == E.shape[0]:
...   print('.dot() OK!')
... else:
...   print('.dot() NG!')
...
.dot() NG!

以上、行列演算を活用してニューラルネットワークの計算を効率化していく。

参考:

行列の乗法 - Wikipedia

『ゼロから作るDeep Learning』ソースコード、正誤表

ソースコードは本を写経していたが、 独自のライブラリを使って説明があったので ソースコードリポジトリを参照した

github.com

正誤表もついていて、間違いを正せる。 5章まるごと「連鎖律」を「連鎖率」に間違えるという
盛大な誤植を見つけたので、ちょっと修正しながら読んでいこう。

3章ニューラルネットワーク(ステップ関数・シグモイド関数・ReLU関数)『ゼロから作るディープラーニング』

3章になって結構重くなってきたので、ゆっくりやっていく。

・活性化関数activation function:入力信号の総和を出力信号に変換する関数
・ステップ関数(階段関数):閾値を境にして出力が切り替わる関数
・パーセプトロンでは、ステップ関数を使っている

def step_function(x):
  if x > 0:
    return 1
  else:
    return 0

#配列引数対応版
def step_function(x):
  y = x > 0 # 配列要素に対して不等号の演算をしてTrue/Falseのbool値を返す
  return y.astype(np.int) # boolからintに型変換

def step_function(x):
  return np.array(x > 0, dtype=np.int) # 圧縮記述

以下、生成されたステップ関数グラフ例

import numpy as np
import matplotlib.pyplot as plt
plt.switch_backend('agg')

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

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

plt.savefig('step_func.png')

f:id:kaeken:20161103223008p:plain

ニューラルネットワークについて。

・ニューラルネットワーク(多層パーセプトロン)では、活性化関数として、ステップ関数とは別の関数を使用する
・よく使われる関数はシグモイド関数sigmoid functionである。シグモイド関数は、
 ネイピア数の2.7182...の実装を表す e の-x乗に1を加えた式の逆数である(ネイピア数をあとで調べる?)

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

import numpy as np
import matplotlib.pyplot as plt
plt.switch_backend('agg')

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.savefig('sigmoid.png')

f:id:kaeken:20161103223450p:plain

ステップ関数とシグモイド関数の比較

・下記合成した図を確認すると、「滑らかさ」が異なることが重要
・ステップは0/1の離散だが、シグモイドは連続的な実数値
・共通点は、入力が小さい時は0に近く、大きくなるに従い1に近づき、常に0から1の間にある非線形関数

f:id:kaeken:20161103225819p:plain

xの範囲を10倍した場合 f:id:kaeken:20161103225848p:plain

・最近はシグモイド関数の代わりにReLU関数(Rectified Linear Unit)が使われている
・ReLUは、入力が0を超えていればその入力をそのまま出力し、0以下なら0を出力する関数

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,)

plt.savefig('relu.png')

f:id:kaeken:20161103232333p:plain

いったんここまで。

ゼロから作るDeep Learningで気になる用語

1章 Python入門
ベクトルvector:1次元配列
行列matrix:2次元配列
テンソルtensor:ベクトルや行列を一般化したもの
ブロードキャストbroadcast:形状の異なる配列同士の演算時に要素が拡大されて演算される機能

2章パーセプトロン
パーセプトロンperceptron:複数の信号を入力とし、ひとつの信号を出力とするアルゴリズム
閾値threshold:重み付けされた入力値の総和が超えた場合に発火する限界値のこと。ニューロンが発火する値
バイアスbias:発火のしやすさを調整するパラメータ
重みweight:入力への重要度をコントロールするパラメータ

読み進めていきながら、順次更新していく。

Pythonでパーセプトロンperceptron関数

『ゼロから作るDeep Learning』(以下、『ゼロからDL』) 2章パーセプトロンのAND,OR,NANDは重みとバイアス値だけが異なる。

パーセプトロンとは、
複数の信号を入力として受け取り、一つの信号を出力する処理。
信号は、「流す:1」「流さない:0」の2値のみ。

今後、
ニューラルネットワークや
ディープラーニングへと進む上で必要な考え方。
# cat and.py

import numpy as np

# 重みとバイアスを用いたANDゲート
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

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


# cat nand.py
import numpy as np

# 重みとバイアスを用いたNANDゲート
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

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

# cat or.py
import numpy as np

# 重みとバイアスを用いたORゲート
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

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

実行結果 (.bashrcでalias py='python'にしてる)

py and.py
0 0 0 1
py nand.py
1 1 1 0
py or.py
0 1 1 1

ついでにNOR

# cat nor.py
import numpy as np

# 重みとバイアスを用いたNORゲート
def NOR(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

print(NOR(0,0), NOR(0,1), NOR(1,0), NOR(1,1))

→1 0 0 0 になった。

単体のパーセプトロンには限界があり、
排他的論理和XORゲートを実装するには、
複数のゲートを組み合わせて
多層パーセプトロンにする必要がある。

結論から言えば、
NANDとORを
ANDでつなぐ
# cat xor.py
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.2
  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), XOR(0,1), XOR(1,0), XOR(1,1))
#=> 0 1 1 0 排他的論理和になった

Python×数学×人工知能を平行して勉強していく

機械学習や深層学習など人工知能の技術は数学が必須だ。
ライブラリが細かい計算を隠蔽してくれるとはいえ、
「何のためにこの数式を使うか」を理解していないと、
使い方を間違えるし、変更することもできない。

数学は遠い昔にやったが忘れているので、
復習&新規分野を学習していく。

とはいえ、鉛筆を使って勉強するのもだるいので、
ここはプログラマらしくプログラミングしながら学ぶ。
以下、オライリーの既刊本からピックアップして、
人工知能プログラミングと平行してやっていこう。

また、
Pythonは書いていくうちに、
手に馴染んでくる。
Rubyほどの衝撃はないが、
確かに書きやすい言語みたいだ。

Python
数学
人工知能

三本柱で集中的に取り組んでいく。

http://www.oreilly.co.jp/catalog/

www.oreilly.co.jp www.oreilly.co.jp www.oreilly.co.jp www.oreilly.co.jp www.oreilly.co.jpwww.oreilly.co.jp

次にグラフ描画用にmatplotlib.pyplotモジュール

いきなりエラッタのでyum

>>> import matplotlib.pyplot as plt
...
ImportError: libXext.so.6: cannot open shared object file: No such file or directory
yum install libXext.x86_64
yum install libSM.x86_64
yum install libXrender.x86_64

気を取り直して、importしたら成功したがplotでXの指定がないのでコケた

>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> x = np.arange(0,6, 0.1)
>>> y = np.sin(x)
>>> plt.plot(x,y)
...
    raise RuntimeError('Invalid DISPLAY variable')
RuntimeError: Invalid DISPLAY variable


#以下をimport後に指定すればよいらしい
>>> plt.switch_backend('agg')
#すると
>>> plt.plot(x,y)
>>> plt.savefig('sin.png')
# これで画像が生成された

f:id:kaeken:20161103004351p:plain

さすがに対話モードは面倒なのでファイルに変更

import numpy as np
import matplotlib.pyplot as plt
plt.switch_backend('agg')

x = np.arange(0, 6, 0.1)
y1 = np.sin(x)
y2 = np.cos(x)

plt.plot(x, y1, label='sin')
plt.plot(x, y2, linestyle = '--', label='cos')
plt.xlabel('x')
plt.ylabel('y')
plt.title('sin & cos')
plt.legend()


plt.savefig('sin_cos.png')

sinとcos f:id:kaeken:20161103005056p:plain

あと画像読込もできるとのこと(未確認)

import matplotlib.pyplot as plt
from matplotlib.image import imread

img = imread('lena.png')
plt.imshow(img)

plt.show()

まずはNumPy配列操作

『ゼロから作るDeep Learning』でディープラーニングに必要な行列処理をPythonでやるための準備。まずは、NumPyで配列操作を学ぶ。

>>> import numpy as np
>>> x = np.array([1.0, 2.0, 3.0])
>>> x
array([ 1.,  2.,  3.])
>>> type(x)
<class 'numpy.ndarray'>
>>> y = np.array([2.0, 4.0, 6.0])
>>> x+y
array([ 3.,  6.,  9.])
>>> x*y
array([  2.,   8.,  18.])
>>> x/y
array([ 0.5,  0.5,  0.5])


>>> x
array([ 1.,  2.,  3.])
>>> x/2 #ブロードキャスト機能
array([ 0.5,  1. ,  1.5])

# N次元配列
>>> A = np.array([[1,2], [3,4]])
>>> A
array([[1, 2],
       [3, 4]])
>>> A.shape
(2, 2)
>>> A.dtype
dtype('int64')

>>> A
array([[1, 2],
       [3, 4]])
>>> B = np.array([[3,0],[0,6]])
>>> B
array([[3, 0],
       [0, 6]])
>>> A+B
array([[ 4,  2],
       [ 3, 10]])
>>> A*B
array([[ 3,  0],
       [ 0, 24]])


>>> A
array([[1, 2],
       [3, 4]])
>>> A*10
array([[10, 20],
       [30, 40]])
>>> C = np.array([10,20])
>>> A*C
array([[10, 40],
       [30, 80]])

>>> X = np.array([[51,55],[14,19],[0,4]])
>>> X
array([[51, 55],
       [14, 19],
       [ 0,  4]])
>>> X[0]
array([51, 55])
>>> X[0][1]
55
>>> for row in X:
...   print(row*2)
...
[102 110]
[28 38]
[0 8]

>>> x = X.flatten()
>>> x
array([51, 55, 14, 19,  0,  4])
>>> x[np.array([0,2,4])]
array([51, 14,  0])
>>> x > 15
array([ True,  True, False,  True, False, False], dtype=bool)
>>> x[x>15]
array([51, 55, 19])
# この不等号が使える文法は特徴的


printとかarrayとか もっと短くしたいが あまり言語文法を弄っても仕方がないので、 甘受しよう。

さくらVPS CentOS7にPython3を入れる&ディープラーニング実装環境準備

さくらVPS CentOS7にPython3を入れる

# yum install gcc zlib-devel bzip2 bzip2-devel readline readline-devel sqlite sqlite-devel openssl openssl-devel git
# git clone https://github.com/yyuu/pyenv.git ~/.pyenv

# vim .bash_profile
下記を追記
# pyenv
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

# source .bash_profile

# pyenv install --list

# pyenv install 3.5.1

# pyenv global 3.5.1
# pyenv rehash
# python --version
Python 3.5.1

追記:

pyenvで生pythonを入れたが、 分析環境はAnacondaが良いとのことなので、 以下を参考に入れ直し。

データサイエンティストを目指す人のpython環境構築 2016 - Qiita

pyenv install anaconda3-4.1.1

続いて『ゼロから作るDeep Learning』本を参考に、ライブラリ準備

>>>import numpy as np
>>> np.random.rand(100)
array([ 0.86892336,  0.66170946,  0.05887993,  0.42099383,  0.80438276,
        0.19044123,  0.23335116,  0.31559316,  0.88670526,  0.82667895,
        0.79776356,  0.80881683,  0.99474501,  0.05019365,  0.19625688,
        0.86203096,  0.29162751,  0.72087276,  0.40451478,  0.36296256,
        0.89809188,  0.46221825,  0.5993458 ,  0.0626044 ,  0.68405878,
        0.01012476,  0.83778932,  0.56676707,  0.18140237,  0.97366154,
        0.49387919,  0.57424144,  0.44275469,  0.14197617,  0.04196403,
        0.9784503 ,  0.59244845,  0.09614099,  0.58814902,  0.18990487,
        0.62918135,  0.33347414,  0.86367738,  0.89845232,  0.13748251,
        0.03077333,  0.08952327,  0.95140962,  0.76248493,  0.37645204,
        0.59090669,  0.33756122,  0.94142886,  0.37007636,  0.35679969,
        0.50614196,  0.20450811,  0.94660012,  0.95909313,  0.84177225,
        0.79149603,  0.5654826 ,  0.38281388,  0.70233475,  0.34317186,
        0.40587616,  0.50553225,  0.60524493,  0.08440945,  0.74772122,
        0.9691486 ,  0.00477779,  0.8752755 ,  0.33538002,  0.73304029,
        0.12212355,  0.47077921,  0.92045206,  0.52865073,  0.2070013 ,
        0.72662729,  0.0087631 ,  0.26692977,  0.63211109,  0.56244538,
        0.51641049,  0.67545334,  0.79915446,  0.28771985,  0.34116686,
        0.24343494,  0.18029586,  0.98822042,  0.10098339,  0.75538892,
        0.60376798,  0.03763307,  0.09447491,  0.24395278,  0.81511218])

Python3系の最速文法メモは以下。

qiita.com

『ゼロから作るDeepLearning』入手

人工知能関連の記事を書いていく。

 

まず、まったく何から初めてよいのか分からないが、

ひとまずオライリーで入門書を探す。

『ゼロから作るDeepLearning』という書籍が良さそうなので買ってきた。

 

www.oreilly.co.jp

目次

1章 Python入門
1.1 Pythonとは
1.2 Pythonのインストール
1.3 Pythonインタプリタ
1.4 Pythonスクリプトファイル
1.5 NumPy
1.6 Matplotlib
1.7 まとめ

2章 パーセプトロン
2.1 パーセプトロンとは
2.2 単純な論理回路
2.3 パーセプトロンの実装
2.4 パーセプトロンの限界
2.5 多層パーセプトロン
2.6 NANDからコンピュータへ
2.7 まとめ

3章 ニューラルネットワーク
3.1 パーセプトロンからニューラルネットワーク
3.2 活性化関数
3.3 多次元配列の計算
3.4 3層ニューラルネットワークの実装
3.5 出力層の設計
3.6 手書き数字認識
3.7 まとめ

4章 ニューラルネットワークの学習
4.1 データから学習する
4.2 損失関数
4.3 数値微分
4.4 勾配
4.5 学習アルゴリズムの実装
4.6 まとめ

5章 誤差逆伝播
5.1 計算グラフ
5.2 連鎖率
5.3 逆伝播
5.4 単純なレイヤの実装
5.5 活性化関数レイヤの実装
5.6 A.ne/Softmaxレイヤの実装
5.7 誤差逆伝播法の実装
5.8 まとめ

6章 学習に関するテクニック
6.1 パラメータの更新
6.2 重みの初期値
6.3 Batch Normalization
6.4 正則化
6.5 ハイパーパラメータの検証
6.6 まとめ

7章 畳み込みニューラルネットワーク
7.1 全体の構造
7.2 畳み込み層
7.3 プーリング層
7.4 Convolution/Poolingレイヤの実装
7.5 CNNの実装
7.6 CNNの可視化
7.7 代表的なCNN
7.8 まとめ

8章 ディープラーニング
8.1 ネットワークをより深く
8.2 ディープラーニングの小歴史
8.3 ディープラーニングの高速化
8.4 ディープラーニングの実用例
8.5 ディープラーニングの未来
8.6 まとめ

 

 

サンプルコード

 

https://github.com/oreilly-japan/deep-learning-from-scratch

 

さっそく6章まで読んだが、

5章誤差逆伝播法から疑問点が増えてきた。

高校数学は理系できっちり学習したが、

忘れているようなので、復習が必要。

 

PHP,Rubyばかりで、

少し使っていたPython

本格的に取り組んでいきたい。