ニューラルネットワークの実装でも非常によく使われている内積計算は、NumPyではnp.dot関数で実装されています。
この記事では、np.dotを使った内積計算の方法の中でも、以下のよく使われるであろうシーンを解説します。
- 一次元配列(ベクトル)の内積
- 二次元配列(行列)の内積
これらの方法がわからないという方は是非、この記事を読んでnp.dotを攻略しちゃいましょう!
※ この記事のコードはPython 3.7, Ubuntu 18.04で動作確認しました。
np.dotを使った内積計算
一次元配列の内積
一次元配列同士の内積は、要素数があっていれば計算ができます。
import numpy as np a = np.array([1,2,3], dtype=np.float64) b = np.array([10,100,1000], dtype=np.float64) print(a.shape, b.shape) np.dot(a, b)
[出力結果]
(3,) (3,) 3210.0
これがもしもあっていなければ、ValueErrorが出て計算ができません。
a = np.array([1,2,3, 4]) b = np.array([10,100,1000]) print(a.shape, b.shape) np.dot(a, b)
[出力結果とエラーメッセージ]
(4,) (3,) --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-46-31f775ca35e3> in <module>() 3 4 print(a.shape, b.shape) ----> 5 np.dot(a, b) ValueError: shapes (4,) and (3,) not aligned: 4 (dim 0) != 3 (dim 0)
二次元配列の内積
二次元配列同士の内積では、一つ目の配列の列数と2つ目の配列の行数があっていれば計算ができます。
a = np.arange(10).reshape(2,5) b = np.arange(20).reshape(5,4) print(a.shape, b.shape) np.dot(a,b)
[出力結果]
(2, 5) (5, 4) array([[120, 130, 140, 150], [320, 355, 390, 425]])
これも一次元配列と同様に、shapeがあっていなければエラーです。
a = np.arange(10).reshape(2,5) b = np.arange(30).reshape(6,5) print(a.shape, b.shape) np.dot(a,b)
[出力結果とエラーメッセージ]
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-49-9fc94d5a7528> in <module>() 3 4 print(a.shape, b.shape) ----> 5 np.dot(a,b) ValueError: shapes (2,5) and (6,5) not aligned: 5 (dim 1) != 6 (dim 0)
エラーメッセージを読んで、何が原因でエラーが起こったのかをしっかり理解できるようになりましょう!
ニューラルネットワークの実装における内積
ニューラルネットワークの実装では、全結合層の計算で内積を使います。ニューラルネットワークのパラメータを配列として持つことで、行列計算の手法を使って実装することができるんですね。
多くの場合、for文などで全結合層の実装をするよりは高速に動きますよ!
data_size = 5 feature_size = 3 hidden_size = 2 X = np.arange(0,data_size*feature_size).reshape(data_size, feature_size) W = np.random.randn(feature_size, hidden_size) b = np.random.randn(hidden_size) print(X.shape, W.shape, b.shape) # 出力結果 ((5, 3), (3, 2), (3,))
このような設定で、全結合層があるときのNumPyでの実装方法は以下の通りです。
np.dot(X, W) + b # 出力結果 array([[ 0.97882172, 2.48169437], [ 1.35011991, 10.6986141 ], [ 1.7214181 , 18.91553384], [ 2.09271629, 27.13245357], [ 2.46401449, 35.34937331]])
この結果をsigmoidなどの活性化関数に通すことでニューラルネットワークの実装ができます。
まとめ
この記事では、NumPyの内積を計算する関数であるnp.dotを紹介しました。機械学習などの実装では、行列計算に直すことで計算の高速化や簡単化ができます。様々なところで登場する内積計算、NumPyで実装できれば高速に使えますね!