次の機械翻訳の問題を考えてみましょう。s
をソース文、t
ターゲット文とする。両方の文は、概念的にインデックスのリストとして表されます。インデックスは、関連する辞書内の単語の位置に対応します。例:
s = [34, 68, 91, 20]
t = [29, 0, 43]
s
とt
は必ずしも同じ長さではないことに注意してください。S
とT
をそのようなインスタンスのセットとします。つまり、対訳コーパスです。例:
S = [[34, 68, 91, 20], [4, 7, 1]]
T = [[29, 0, 43], [190, 37, 25, 60]]
s
すべてのS
が同じ長さであるとは限らないことに注意してください。つまり、文にはさまざまな数の単語があります。
私は Theano で機械翻訳システムを実装しています。最初の設計上の決定は、 と に使用するデータ構造の種類S
ですT
。Matrices with different row lengths in numpyに投稿された回答の 1 つから、型付きリストが可変長テンソルを格納するための優れたソリューションであることを学びました。
ただし、コードが非常に複雑になることに気付きました。一例を挙げましょう。2 つの型付きリストがy
ありp_y_given_x
、負の損失可能性を計算することを目的としているとします。それらが通常のテンソルである場合、次のような単純なステートメントで十分です。
loss = t.mean(t.nnet.categorical_crossentropy(p_y_given_x, y))
ただしcategorical_crossentropy
、テンソルにのみ適用できるため、型付きリストの場合は、それらを反復処理して、関数を各要素に個別に適用する必要があります。
_loss, _ = theano.scan(fn=lambda i, p, y: t.nnet.categorical_crossentropy(p[i], y[i]),
non_sequences=[p_y_given_x, y],
sequences=[t.arange(y.__len__(), dtype='int64')])
loss = t.mean(_loss)
コードがますます乱雑になるだけでなく、これらの問題が伝播します。たとえば、損失の勾配を計算したい場合、次は機能しなくなります。
grad_params = t.grad(loss, params)
なぜうまくいかないのか、正確にはわかりません。のタイプに関係していると確信していますが、loss
それを機能させる方法をこれ以上調査することに興味はありません。混乱は指数関数的に増大しており、私が知りたいのは、型付きリストを間違った方法で使用していないか、それともまだ十分にサポートされていないためにそれらをあきらめる時が来たかどうかを知ることです.