1

私は最適化しようとしているリアルタイムの画像処理プログラムを持っていますが、それはすべて行列の乗算に要約されます。初期化段階で計算している 3 つのテンソルを考えてみましょう。

  1. A = np.arange(35 * 51 * 59).reshape([35, 51, 59])
  2. B = np.arange(37 * 51 * 51 * 59).reshape([37, 51, 51, 59])
  3. C = np.arange(59 * 27).reshape([59, 27])

各フレームで、4 番目のテンソルの形式で新しいデータを取得しています。

  • M = np.arange(35 * 37 * 59).reshape([35, 37, 59]).

現在、私は を計算D = np.einsum('xyf,xtf,ytpf,fr->tpr', M, A, B, C)していますが、Dこれは私の希望する結果であり、プログラムの主要なボトルネックです。それを最適化するために私が従おうとしている2つの方向があります。

まず、事前に計算できるT関数である tensorを考えてみました。私は成功しませんでした。私はそれに多くの時間を費やしましたが、それはまったく可能ですか?A, B, C, DD = np.tensordot(M, T, axes=..)

また、プログラム自体はMATLABで書かれています。組み込みのテンソル乗算関数 (einsumまたはtensordot同等のもの) がないため、現在tprodツールボックスを使用して、次のことを行っています。

temp1 = etprod('dcb', A, 'abc', M, 'adc');
temp2 = etprod('dbc', B, 'abcd', temp1, 'adb');
D = etprod('cdb', C, 'ab', temp2, 'acd');

MATLAB の既定の内積関数 (2D 行列用) は よりもはるかに高速であるため、手書きのループを使用せずに、既定の関数を使用して複数の 2D 行列を作成できるように 2D 配列にetprod再形成することについて考えました。私もそれで成功しませんでした。A, B, C, Dfor

何かご意見は?ありがとう!

4

1 に答える 1

1

この操作が M の異なる値で何度も行われる場合、次のように定義できます。

D0 = np.einsum('xft,fr->tpr',A, B, C)

操作全体は、バイナリ ステップに分割できます。

D0=np.einsum('xtf,ytpf->xyptf',A,B)
D0=np.einsum('xyptf,fr->xyftpr',D0,C)
D=np.einsum('tprxfy,xfy->tpr',D0,M)

最後の演算は D0 と M を使用し、行列ベクトル演算としてコーディングできます。Matlabでは、

D=reshape(D0.[],numel(M))*M(:);

その後、必要に応じて並べ替えることができます。この順序を (((A,B),C),M) と書くことができます

ただし、((M,C),A,B) を使用する方がよい場合があります。

D=np.einsum('xyf,fr->xyfr',M,C)
D0=np.einsum('xyfr,xtf->ytfr',D,A)
D=np.einsum('ytfr,ytpf->tpr',D,B)

この操作の順序付けには、6 つのインデックスではなく 4 つのインデックスのみを持つ中間配列があります。各操作が単一の操作よりもはるかに高速である場合、これは利点になる可能性があります。

于 2020-12-24T22:50:46.293 に答える