覚え書きブログ

Pythonによる機械学習1(Pythonの基礎 2/4)

<< Pythonによる機械学習1(Pythonの基礎 1/4)
【Pythonによる機械学習1(Pythonの基礎 2/4)の目次】



数値演算のスクリプトの例

以下は、数値計算用のライブライnumpyを用いた線形代数の行列演算を実行するスクリプトの例です。
具体的には、3x3の行列W、Hおよび3次元の列ベクトルx、bに対して、
1) 逆行列、転置行列、行列とベクトルの掛け算および足し算:
f:id:hirotaka_hachiya:20171213114133p:plain

2) 行ベクトルと列ベクトルの掛け算
f:id:hirotaka_hachiya:20171213235125p:plain
W_iは、行列Wのi列目のベクトル表します

3) 列ベクトルと行ベクトルの掛け算
f:id:hirotaka_hachiya:20171213235200p:plain

4) pythonの標準の演算子を用いたアダマール積(要素ごとの積):
f:id:hirotaka_hachiya:20171213114405p:plain
を計算しています。

# -*- coding: utf-8 -*-

# 数値計算用のライブラリnumpyをnpとしてインポート
import numpy as np
import pdb

# 3x3のnumpy配列(行列)
W = np.array([ [1,0,0], [0,1/2,0], [0,0,1/3] ])
H = np.array([ [1,0,0], [0,2,0], [0,0,3] ])
print(f"W:\n{W}\nH:\n{H}\n")

# 3x1のnumpy配列(ベクトル)
x = np.array([ [1], [2], [3] ])
b = np.array([ [1], [2], [3] ])
print(f"x:\n{x}\nb:\n{b}\n")

# 逆行列の計算
W_inv = np.linalg.inv(W)
print(f"W_inv:\n{W_inv}\n")

# 行列W_invの転置とベクトルxの掛け算とbとの足し算
W_inv_transpose = W_inv.T
f_x = np.matmul(W_inv_transpose,x) 
f_x = f_x + b
print(f"W_inv_transpose:\n{W_inv_transpose}\n")
print(f"f_x:\n{f_x}\n")

# Wの1列目の転置
row1W = W[:,[0]].T

# Wの2列目
col2W = W[:,[1]]
print(f"1st row of W:\n{row1W}\n2nd colmn of W:\n{col2W}\n")

# 行ベクトルと列ベクトルの掛け算
rowXcol = np.matmul(row1W,col2W)
print(f"row x col vectors:\n{rowXcol}\n")

# 列ベクトルと行ベクトルの掛け算
colXrow = np.matmul(col2W,row1W)
print(f"col x row vectors:\n{colXrow}\n")

# 行列のアダマール(要素ごとの積)積
g_H = W*H
print("g(H):\n{}\n".format(g_H))

上記のスクリプトをファイルlinearAlgebra.pyに保存し以下のように実行します。

> python linearAlgebra.py
W:
[[ 1.          0.          0.        ]
 [ 0.          0.5         0.        ]
 [ 0.          0.          0.33333333]]
H:
[[1 0 0]
 [0 2 0]
 [0 0 3]]

x:
[[1]
 [2]
 [3]]
b:
[[1]
 [2]
 [3]]

W_inv:
[[ 1.  0.  0.]
 [ 0.  2.  0.]
 [ 0.  0.  3.]]

W_inv_transpose:
[[ 1.  0.  0.]
 [ 0.  2.  0.]
 [ 0.  0.  3.]]

f_x:
[[  2.]
 [  6.]
 [ 12.]]

1st row of W:
[ 1.  0.  0.]
2nd colmn of W:
[[ 0. ]
 [ 0.5]
 [ 0. ]]

row x col vectors:
[ 0.]

col x row vectors:
[[ 0.   0.   0. ]
 [ 0.5  0.   0. ]
 [ 0.   0.   0. ]]

g_x:
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]

numpy.ndarray.Tは行列の転置、numpy.matmulは行列・ベクトルの掛け算を返します。詳細は、以下を参照してください。
https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.ndarray.T.html
https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.matmul.html




pdbを用いたデバッグ

以下のように、pdbモジュールをインポートし、スクリプトの任意の行に「pdb.set_trace()」を設置すると、その処理を止めて、途中経過を確認することができます。

# デバッガをインポート
import pdb

pdb.set_trace()

スクリプトlinearAlgebra.pyの17行目に「pdb.set_trace()」を設置し、実行してみましょう。

16  # 逆行列の計算
17  pdb.set_trace()
18  W_inv = np.linalg.inv(W)
19  print("W_inv:\n{}\n".format(W_inv))
> python linearAlgebra.py
> /home/staff/hhachiya/Works/intelligentSystemTraining/linearAlgebra.py(19)<module>()
-> W_inv = np.linalg.inv(W)
(Pdb) 

pdb.set_trace()をで処理が「l」を入力し、Enterを押すと、現在実行中のコードを表示できます。

(Pdb) l
 14  	b = np.array([ [1], [2], [3] ])
 15  	print("x:\n{}\nb:\n{}\n".format(x,b))
 16  	
 17  	# 逆行列の計算
 18  	pdb.set_trace()
 19  ->	W_inv = np.linalg.inv(W)
 20  	print("W_inv:\n{}\n".format(W_inv))
 21  	
 22  	# 行列Wの転置とベクトルxの掛け算とbとの足し算
 23  	W_inv_transpose = W_inv.T
 24  	f_x = np.matmul(W_inv_transpose,x)
(Pdb) 

次に、変数名「W」を入力し、Enterを押すことにより、処理途中の変数f_xの値を表示できます。

(Pdb) W
array([[ 1.        ,  0.        ,  0.        ],
       [ 0.        ,  0.5       ,  0.        ],
       [ 0.        ,  0.        ,  0.33333333]])
(Pdb)

現在の行を実行するために「n」を入力し、Enterを押します。そして、「W_inv」を入力し、Enterを押すと更新された変数f_xの値を表示できます。

(Pdb) n
> /home/staff/hhachiya/Works/intelligentSystemTraining/linearAlgebra.py(20)<module>()
-> print("W_inv:\n{}\n".format(W_inv))
(Pdb) W_inv
array([[ 1.,  0.,  0.],
       [ 0.,  2.,  0.],
       [ 0.,  0.,  3.]])

最後に「c」を入力し、Enterを押すと終了(実際には次のpdb.set_trace()まで実行)します。
このように、任意の行で処理を止めて、処理途中の変数の値を確認したり、新たな処理を試したりすることが出来るので、効率よく実装ができます。

演習2

次の行列Aを定義し、その逆行列A^-1および行列Aと逆行列A^-1の積を計算し出力してみましょう。
f:id:hirotaka_hachiya:20181114211859p:plain

作成したスクリプトおよび出力結果を、Moodleにて提出してください。

宿題1

指数関数numpy.expと、和を求める関数numpy.sumを使って、ソフトマックスの計算をlinearAlgebra.pyに追加してみましょう。
f:id:hirotaka_hachiya:20171213232025p:plain

ここで、W_iは行列Wのi列のベクトルを意味します。
また、b_iはベクトルbのi番目の要素(スカラー)を意味します。
numpy.expとnumpy.sumの詳細については以下を参照してください。
https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.exp.html
https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.sum.html

また、行列W、ベクトルxおよびbは、linearAlgebra.pyにて既に設定されているものを利用してください。

作成したスクリプトおよび出力結果を、次週までにMoodleにて提出してください。

Pythonによる機械学習1(Pythonの基礎 3/4)>>