【NumPy入門 np.dot】行列計算の基礎!np.dotでの内積計算の仕方!

ニューラルネットワークの実装でも非常によく使われている内積計算は、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で実装できれば高速に使えますね!

この記事を書いた人

第一言語はPythonです。
皆さんRustやりましょう。

目次