1. ホーム
  2. python

[解決済み] PyTorch - contiguous()は何をするのですか?

2022-02-06 02:24:17

質問

githubにあるLSTM言語モデルの例を見ていました。 (リンク) . 一般的に何をするものかは、私にはかなり明確です。しかし、私はまだ、以下を呼び出すことが何であるかを理解するのに苦労しています。 contiguous() は、コードの中で何度も出てきます。

例えば、コードの74/75行目では、LSTMの入力配列とターゲット配列が作成されています。 データ( ids ) は2次元であり、1次元目はバッチサイズである。

for i in range(0, ids.size(1) - seq_length, seq_length):
    # Get batch inputs and targets
    inputs = Variable(ids[:, i:i+seq_length])
    targets = Variable(ids[:, (i+1):(i+1)+seq_length].contiguous())

そこで、簡単な例として、バッチサイズ1を使用し、かつ seq_length 10 inputstargets はこのようになります。

inputs Variable containing:
0     1     2     3     4     5     6     7     8     9
[torch.LongTensor of size 1x10]

targets Variable containing:
1     2     3     4     5     6     7     8     9    10
[torch.LongTensor of size 1x10]

そこで一般的に私が質問したいのは contiguous() また、なぜそれが必要なのでしょうか?

さらに、両方の変数が同じデータで構成されているのに、なぜターゲット配列ではこのメソッドが呼び出され、入力配列では呼び出されないのかが理解できません。

どうして targets は不連続であり inputs は、まだ連続しているのでしょうか?


EDITです。

を呼び出すのを省いてみました。 contiguous() が、損失計算時にエラーメッセージが表示されます。

RuntimeError: invalid argument 1: input is not contiguous at .../src/torch/lib/TH/generic/THTensor.c:231

そのため、明らかに contiguous() が必要です。

どのように解決するのですか?

PyTorchのテンソルには、テンソルの内容を変更せず、データの編成方法を変更する操作がいくつかあります。これらの操作は以下の通りです。

<ブロッククオート

narrow() , view() , expand()transpose()

例えば、こんな感じです。 を呼び出すと transpose() PyTorchは新しいレイアウトのテンソルを生成するのではなく、オフセットとストライドが望ましい新しい形状を表すように、Tensorオブジェクトのメタ情報を変更するだけである。この例では、転置されたテンソルと元のテンソルは同じメモリを共有する。

x = torch.randn(3,2)
y = torch.transpose(x, 0, 1)
x[0, 0] = 42
print(y[0,0])
# prints 42

という概念が生まれたところです。 連続的 が登場します。上の例では x は連続しているが y は、ゼロから作られた同じ形状のテンソルとはメモリレイアウトが異なるため、そうではない。なお 連続した。 というのは、テンソルの中身がメモリブロックに分散しているわけではないので、少し誤解を招きやすいからである。ここでは、バイトはまだ1つのメモリブロックに割り当てられているが、要素の順序は異なっているのだ

を呼び出すと contiguous() このとき、テンソルは同じデータでゼロから作成されたときと同じ順序でメモリ上に配置されるように、実際にコピーを作成する。

通常、このようなことを心配する必要はありません。一般的には、すべてがうまくいくと考えて、そのあと RuntimeError: input is not contiguous ここで、PyTorchは連続したテンソルを期待し、そのために contiguous() .