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

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

ゼロから作る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

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