web-dev-qa-db-ja.com

パイトーチはテンソル次元を変形します

たとえば、次元(5)の1Dベクトルがあります。 2Dマトリックス(1,5)に再形成したいと思います。

ここに私がnumpyでそれをする方法があります

>>> import numpy as np
>>> a = np.array([1,2,3,4,5])
>>> a.shape
(5,)
>>> a = np.reshape(a, (1,5))
>>> a.shape
(1, 5)
>>> a
array([[1, 2, 3, 4, 5]])
>>> 

しかし、Pytorch Tensor(およびVariable)を使用してこれを行うにはどうすればよいですか。 numpyに戻り、Torch変数に再度切り替えたくないのは、逆伝播情報が失われるためです。

これが私がパイトーチに持っているものです

>>> import torch
>>> from torch.autograd import Variable
>>> a = torch.Tensor([1,2,3,4,5])
>>> a

 1
 2
 3
 4
 5
[torch.FloatTensor of size 5]

>>> a.size()
(5L,)
>>> a_var = variable(a)
>>> a_var = Variable(a)
>>> a_var.size()
(5L,)
.....do some calculation in forward function
>>> a_var.size()
(5L,)

ここで、サイズを(1、5)にする必要があります。変数のpytorchテンソルの次元のサイズを変更したり変更したりすることはできますか? (前に戻る前に別のモデルにフィードするため)

27
Haha TTpro

torch.unsqueeze(input、dim、out = None) を使用します

>>> import torch
>>> a = torch.Tensor([1,2,3,4,5])
>>> a

 1
 2
 3
 4
 5
[torch.FloatTensor of size 5]

>>> a = a.unsqueeze(0)
>>> a

 1  2  3  4  5
[torch.FloatTensor of size 1x5]
22
Haha TTpro

あなたは使うかもしれません

a.view(1,5)
Out: 

 1  2  3  4  5
[torch.FloatTensor of size 1x5]
14
Lelik

テンソルのin-place変更の場合、間違いなく tensor.resize _() を使用する必要があります。

In [23]: a = torch.Tensor([1, 2, 3, 4, 5])

In [24]: a.shape
Out[24]: torch.Size([5])


# tensor.resize_((`new_shape`))    
In [25]: a.resize_((1,5))
Out[25]: 

 1  2  3  4  5
[torch.FloatTensor of size 1x5]

In [26]: a.shape
Out[26]: torch.Size([1, 5])

PyTorchでは、操作の最後にアンダースコアがある場合(tensor.resize_()など)、その操作は元のテンソルに対してin-place変更を行います。


また、トーチテンソルでnp.newaxisを使用して、寸法を増やすことができます。以下に例を示します。

In [34]: list_ = range(5)
In [35]: a = torch.Tensor(list_)
In [36]: a.shape
Out[36]: torch.Size([5])

In [37]: new_a = a[np.newaxis, :]
In [38]: new_a.shape
Out[38]: torch.Size([1, 5])
7
kmario23

この質問はすでに完全に回答されていますが、経験の浅いpython開発者のために、view()とともに*演算子が役立つと思うかもしれません。

たとえば、データの異なるテンソルに準拠させる特定のテンソルサイズがある場合は、次のことを試してください。

img = Variable(tensor.randn(20,30,3)) # tensor with goal shape
flat_size = 20*30*3
X = Variable(tensor.randn(50, flat_size)) # data tensor

X = X.view(-1, *img.size()) # sweet maneuver
print(X.size()) # size is (50, 20, 30, 3)

これはnumpy shapeでも動作します:

img = np.random.randn(20,30,3)
flat_size = 20*30*3
X = Variable(tensor.randn(50, flat_size))
X = X.view(-1, *img.shape)
print(X.size()) # size is (50, 20, 30, 3)
4
saetch_g

または、これを使用できます。「-1」は、要素の数を指定する必要がないことを意味します。

In [3]: a.view(1,-1)
Out[3]:

 1  2  3  4  5
[torch.FloatTensor of size 1x5]
4
Mou Cai
import torch
>>>a = torch.Tensor([1,2,3,4,5])
>>>a.size()
torch.Size([5])
#use view to reshape

>>>b = a.view(1,a.shape[0])
>>>b
tensor([[1., 2., 3., 4., 5.]])
>>>b.size()
torch.Size([1, 5])
>>>b.type()
'torch.FloatTensor'
1
hindamosh

次のコードを想定します。

import torch
import numpy as np
a = torch.tensor([1, 2, 3, 4, 5])

次の3つの呼び出しの効果はまったく同じです。

res_1 = a.unsqueeze(0)
res_2 = a.view(1, 5)
res_3 = a[np.newaxis,:]
res_1.shape == res_2.shape == res_3.shape == (1,5)  # Returns true

結果のテンソルのいずれかで、それらのデータを変更すると、データのコピーも持たず、aの元のデータを参照するため、aのデータも変更していることに注意してください。

res_1[0,0] = 2
a[0] == res_1[0,0] == 2  # Returns true

もう1つの方法は、resize_ in place操作を使用することです。

a.shape == res_1.shape  # Returns false
a.reshape_((1, 5))
a.shape == res_1.shape # Returns true

resize_またはその他のインプレース操作をautogradとともに使用する場合は注意してください。次の説明を参照してください。 https://pytorch.org/docs/stable/notes/autograd.html#in-place-operations-with-autograd

0
Jadiel de Armas