たとえば、次元(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テンソルの次元のサイズを変更したり変更したりすることはできますか? (前に戻る前に別のモデルにフィードするため)
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]
あなたは使うかもしれません
a.view(1,5)
Out:
1 2 3 4 5
[torch.FloatTensor of size 1x5]
テンソルの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])
この質問はすでに完全に回答されていますが、経験の浅い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)
または、これを使用できます。「-1」は、要素の数を指定する必要がないことを意味します。
In [3]: a.view(1,-1)
Out[3]:
1 2 3 4 5
[torch.FloatTensor of size 1x5]
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'
次のコードを想定します。
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