web-dev-qa-db-ja.com

PyTorchのtorch.inverse()関数をバッチ内のすべてのサンプルに適用する方法は?

これは基本的な質問のように思えるかもしれませんが、それを処理することはできません。

ニューラルネットワークのフォワードパスには、8x3x3の形状の出力テンソルがあります。8はバッチサイズです。各3x3テンソルは非特異行列であると想定できます。これらの行列の逆を見つける必要があります。 PyTorch inverse() 関数は正方行列でのみ機能します。これで8x3x3になったので、この関数をバッチ内のすべてのマトリックスに差別化して適用するにはどうすればよいですか?

サンプルを反復処理し、その逆をpythonリストに追加します。これをPyTorchテンソルに変換します。バックプロップ中に問題が発生しますか?(PyTorchテンソルを一部の操作を実行してテンソルに戻るためのnumpyは、そのような操作のbackprop中に勾配を計算しません)

そのようなことをしようとすると、次のエラーも表示されます。

a = torch.arange(0,8).view(-1,2,2)
b = [m.inverse() for m in a]
c = torch.FloatTensor(b)

TypeError: 'torch.FloatTensor'オブジェクトはインデックス作成をサポートしていません

6
phoenixwing

編集:

Pytorchバージョン1.0以降、torch.inverseはテンソルのバッチをサポートするようになりました。 こちら を参照してください。したがって、組み込み関数torch.inverseを使用するだけで済みます。

古い答え

バッチインバースをすぐに実装する計画があります。説明については、たとえば issue 75 または issue 9102 を参照してください。ただし、執筆時点では、現在の安定バージョン(0.4.1)では、バッチの逆操作は利用できません。

そうは言っても、最近torch.gesvのバッチサポートが追加されました。これは、次の行に沿って独自のバッチ逆演算を定義するために(ab)使用できます。

def b_inv(b_mat):
    eye = b_mat.new_ones(b_mat.size(-1)).diag().expand_as(b_mat)
    b_inv, _ = torch.gesv(eye, b_mat)
    return b_inv

これにより、GPUで実行する場合にforループよりも速度が向上することがわかりました。

8
mexmex

torch.functional.unbind()を使用してテンソルを分割し、結果のすべての要素に逆を適用してから、積み重ねることができます。

a = torch.arange(0,8).view(-1,2,2)
b = [t.inverse() for t in torch.functional.unbind(a)]
c = torch.functional.stack(b)
0