バッチでベクトルの内積を計算する [Chainer]
Chainer(本記事の執筆時点で最新版は v4.3.0)の標準関数でサポートされていない(と思う)のでメモ。
次のコードでベクトルの内積が計算できます。
import numpy as np import chainer.functions as F from chainer import Variable def inner_product(a, b): return F.sum(a * b, axis=1) # [0.1, 0.2] と [-0.5, 0.4] の内積 -> 0.03 # [0.3, 0.4] と [-0.3, 0.2] の内積 -> -0.01 a = Variable(np.array([[0.1, 0.2], [0.3, 0.4]], dtype=np.float32)) b = Variable(np.array([[-0.5, 0.4], [-0.3, 0.2]], dtype=np.float32)) inner_product(a, b) # => variable([ 0.03 -0.01])
もうこれで十分な気がしますが、一応詳細を説明します。
ベクトル と の内積は次のように表されます。
つまり、各成分の積を足していけば OK です。
冒頭のコードでは、a * b
で要素(成分)ごとの積を求めています。そして、F.sum()
で axis=1
として、バッチ内のインスタンス単位で要素の総和を計算しています。
余談: 要素積を求めるのに *
演算子を使えば良いことに気づくまでしばらくかかりました。該当する関数が無いか、かなりドキュメントを漁っていました…。