Pytorch изменяет тензорную размерность
Например, у меня есть 1D-вектор с размерностью (5). Я хотел бы переделать его в 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, потому что это будет информация о возврате информации о потерях.
Вот что я имею в Pytorch
>>> 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 в Variable без информации о градиенте потерь. (потому что я буду переходить в другую модель раньше)
Ответы
Ответ 1
Используйте torch.unsqueeze (ввод, затемнение, выход = нет)
>>> 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]
Ответ 2
вы можете использовать
a.view(1,5)
Out:
1 2 3 4 5
[torch.FloatTensor of size 1x5]
Ответ 3
или вы можете использовать это, "-1" означает, что вам не нужно указывать количество элементов.
In [3]: a.view(1,-1)
Out[3]:
1 2 3 4 5
[torch.FloatTensor of size 1x5]
Ответ 4
Для модификации тензора на месте вам обязательно нужно использовать 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
в факеле Tensor, чтобы увеличить размер. Вот пример:
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])
Ответ 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)
Ответ 6
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'
Ответ 7
Предположим, следующий код:
import torch
import numpy as np
a = torch.tensor([1, 2, 3, 4, 5])
Следующие три вызова имеют точно такой же эффект:
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
Другой способ сделать это - использовать 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