xとWのshapeが様々なパターンのときの、a = np.dot(x, W) の結果のaのshapeを観察すると以下のようになっている。
x.shape | W.shape | a.shape |
---|---|---|
(D,) | (D,) | scalar |
(D,) | (D, 1) | (1,) |
(D,) | (D, K) | (K,) |
(N, D) | (D, K) | (N, K) |
(T, N, D) | (D, K) | (T, N, K) |
(T, N, D) | (M, D, K) | (T, N, M, K) |
xとWが両方ともベクトルである特殊ケースを除くと、np.dotは以下のように動作している。
- xは 「x.shape[-1]次元の横ベクトル」 を「要素」としてもつ「多次元配列」として捉える。表の最後の例では、D次元横ベクトルを要素にもつ、shapeが(T, N)の2次元配列と捉える。
- Wは 「行と列がW.shape[-2:]の行列」 を要素としてもつ多次元配列として捉える。表の最後の例では、$D \times K$行列を要素にもつ、長さがMの配列と捉える。
- 上記をふまえると、np.dotは基本的には 横ベクトルxに右から行列Wを掛け、ベクトルaを返す 演算だといえる。
- さらにこのとき、横ベクトルxや行列Wが(多次元)配列になっていることが許されており、その場合aはベクトルを要素としてもつ多次元配列となる。