コードを高速化するために、多次元 sumproduct 関数を Python から Theano に変換しています。私の Theano コードは同じ結果に達しますが、一度に 1 つの次元の結果しか計算しないため、Python の for ループを使用して最終結果を取得する必要があります。Theano は複数の関数呼び出し間で (gpu の) メモリ使用量と転送を最適化できないため、コードが遅くなると思います。それともこれは間違った仮定ですか?
では、sumprod が 1 回の関数呼び出しで計算されるように、Theano コードを変更するにはどうすればよいでしょうか?
元の Python 関数:
def sumprod(a1, a2):
"""Sum the element-wise products of the `a1` and `a2`."""
result = numpy.zeros_like(a1[0])
for i, j in zip(a1, a2):
result += i*j
return result
次の入力について
a1 = ([1, 2, 4], [5, 6, 7])
a2 = ([1, 2, 4], [5, 6, 7])
出力は次のようになります。[ 26. 40. 65.]
つまり、1*1 + 5*5、2*2 + 6*6、および 4*4 + 7*7 です。
Theano バージョンのコード:
import theano
import theano.tensor as T
import numpy
a1 = ([1, 2, 4], [5, 6, 7])
a2 = ([1, 2, 4], [5, 6, 7])
# wanted result: [ 26. 40. 65.]
# that is 1*1 + 5*5, 2*2 + 6*6 and 4*4 + 7*7
Tk = T.iscalar('Tk')
Ta1_shared = theano.shared(numpy.array(a1).T)
Ta2_shared = theano.shared(numpy.array(a2).T)
outputs_info = T.as_tensor_variable(numpy.asarray(0, 'float64'))
Tsumprod_result, updates = theano.scan(fn=lambda Ta1_shared, Ta2_shared, prior_value:
prior_value + Ta1_shared * Ta2_shared,
outputs_info=outputs_info,
sequences=[Ta1_shared[Tk], Ta2_shared[Tk]])
Tsumprod_result = Tsumprod_result[-1]
Tsumprod = theano.function([Tk], outputs=Tsumprod_result)
result = numpy.zeros_like(a1[0])
for i in range(len(a1[0])):
result[i] = Tsumprod(i)
print result