Pytorch張量維度操作

張量維度擴充

torch.cat(seq,dim=0,out=None)

torch.cat()是將張量序列在維度dim上進行拼接操作。
參數說明

  • seq (sequence of Tensors) - Python序列或相同類型的張量序列
  • dim (int, optional) - 沿着此維度連接張量
  • out (Tensor, optional) - 輸出參數

例子:

import torch 
x = torch.randn(1,2)
print(x)
print(x.size())
# dim = 0
y = torch.cat((x,x),0)
print(y)
print(y.size())
# dim = 1
z = torch.cat((x,x),1)
print(z)
print(z.size())

tensor([[-1.0672, -0.0664]])
torch.Size([1, 2])
tensor([[-1.0672, -0.0664],
[-1.0672, -0.0664]])
torch.Size([2, 2])
tensor([[-1.0672, -0.0664, -1.0672, -0.0664]])
torch.Size([1, 4])

torch.Tensor.expand(*sizes)

返回張量的一個新視圖,可以將張量的單個維度擴大爲更大的尺寸。
張量也可以擴大爲更高維,新增加的維度將附在前面。 擴大張量不需要分配新內存,僅僅是新建一個張量的視圖。任意一個一維張量在不分配新內存情況下都可以擴展爲任意的維度。
傳入-1則意味着維度擴大不涉及這個維度。
參數:
sizes (torch.Size or int…) – 想要擴展的目標維度
例子:

import torch
x = torch.randn(3)
print(x)
print(x.size())
y = x.expand(3,4)
print(y)
print(y.size())

這樣使用,會報錯的,
RuntimeError: The expanded size of the tensor (4) must match the existing size (3) at non-singleton dimension 1. Target sizes: [3, 4]. Tensor sizes: [3]
因爲默認的是向前拓展維度,所以拓展的最後一個維度必須是3,如果想要向後拓展,可以先增加x的一個維度,操作如下:

import torch
x = torch.randn(3)
print(x)
print(x.size())
y = x.unsqueeze(1).expand(3,4)
print(y)
print(y.size())

tensor([0.8265, 0.5117, 0.8278])
torch.Size([3])
tensor([[0.8265, 0.8265, 0.8265, 0.8265],
[0.5117, 0.5117, 0.5117, 0.5117],
[0.8278, 0.8278, 0.8278, 0.8278]])
torch.Size([3, 4])

張量壓縮(刪除是1的維度)

torch.squeeze(input, dim=None, out=None)

除去輸入張量input中數值爲1的維度,並返回新的張量。如果輸入張量的形狀爲Ax1xBx1xC,那麼輸出張量的形狀爲AxBxC。

當通過dim參數指定維度時,維度壓縮操作只會在指定的維度上進行。如果輸入向量的形狀爲Ax1xB,squeeze(input, 0)會保持張量的維度不變,只有在執行squeeze(input, 1)時,輸入張量的形狀會被壓縮至AxB。
如果一個張量只有1個維度,那麼它不會受到上述方法的影響。
輸出的張量與原張量共享內存,如果改變其中的一個,另一個也會改變。
參數:
input (Tensor) – 輸入張量
dim (int, optional) – 如果給定,則只會在給定維度壓縮
out (Tensor, optional) – 輸出張量
例子:

import torch
x = torch.randn((2,1,3,1,4))
print(x)
print(x.size())
# 刪除所有的爲1的維度
y = torch.squeeze(x)
print('刪除所有的爲1的維度')
print(y)
print(y.size())
# 在第0維上壓縮,實際上不變
y = torch.squeeze(x, 0)
print('在第0維上壓縮,實際上不變')
print(y)
print(y.size())
# 在第1維上壓縮
y = torch.squeeze(x, 1)
print('在第1維上壓縮')
print(y)
print(y.size())

tensor([[[[[ 1.0232, -0.0252, -0.1088, -1.8738]],
[[-1.5453, 0.1855, -1.1249, 1.4581]],
[[ 0.5415, -0.3716, 0.2359, 0.9390]]]],
[[[[-0.8668, 0.5324, 0.7221, 0.6134]],
[[-0.4285, 0.5667, 0.5340, -0.6971]],
[[ 1.8294, 0.0185, -0.2730, 0.0775]]]]])
torch.Size([2, 1, 3, 1, 4])
刪除所有的爲1的維度
tensor([[[ 1.0232, -0.0252, -0.1088, -1.8738],
[-1.5453, 0.1855, -1.1249, 1.4581],
[ 0.5415, -0.3716, 0.2359, 0.9390]],
[[-0.8668, 0.5324, 0.7221, 0.6134],
[-0.4285, 0.5667, 0.5340, -0.6971],
[ 1.8294, 0.0185, -0.2730, 0.0775]]])
torch.Size([2, 3, 4])
在第0維上壓縮,實際上不變
tensor([[[[[ 1.0232, -0.0252, -0.1088, -1.8738]],
[[-1.5453, 0.1855, -1.1249, 1.4581]],
[[ 0.5415, -0.3716, 0.2359, 0.9390]]]],
[[[[-0.8668, 0.5324, 0.7221, 0.6134]],
[[-0.4285, 0.5667, 0.5340, -0.6971]],
[[ 1.8294, 0.0185, -0.2730, 0.0775]]]]])
torch.Size([2, 1, 3, 1, 4])
在第1維上壓縮
tensor([[[[ 1.0232, -0.0252, -0.1088, -1.8738]],
[[-1.5453, 0.1855, -1.1249, 1.4581]],
[[ 0.5415, -0.3716, 0.2359, 0.9390]]],
[[[-0.8668, 0.5324, 0.7221, 0.6134]],
[[-0.4285, 0.5667, 0.5340, -0.6971]],
[[ 1.8294, 0.0185, -0.2730, 0.0775]]]])
torch.Size([2, 3, 1, 4])

重複張量

torch.Tensor.repeat(*sizes)

沿着指定的維度重複張量。不同於expand()方法,本函數複製的是張量中的數據。
參數:
size (torch.size ot int…) - 沿着每一維重複的次數
例子:

import torch
x = torch.randn((2))
print(x)
print(x.size())
# 行方向複製3倍,列方向複製4倍,整體複製
y = x.repeat(3,4)
print(y)
print(y.size())

tensor([ 1.4610, -0.1669])
torch.Size([2])
tensor([[ 1.4610, -0.1669, 1.4610, -0.1669, 1.4610, -0.1669, 1.4610, -0.1669],
[ 1.4610, -0.1669, 1.4610, -0.1669, 1.4610, -0.1669, 1.4610, -0.1669],
[ 1.4610, -0.1669, 1.4610, -0.1669, 1.4610, -0.1669, 1.4610, -0.1669]])
torch.Size([3, 8])

torch.Tensor.unfold(dim, size, step)
返回一個新的張量,其中元素複製於有原張量在dim維度上的數據,複製重複size次,複製時的步進值爲step。
參數:
dim (int) - 目標維度
size (int) - 複製重複的次數(展開維度)
step (int) - 步長
例子:

import torch
x = torch.randn((5))
print(x)
print(x.size())
# 複製第0維上的數據,複製2次,複製的步長爲1
y = x.unfold(0,2,1)
print(y)
print(y.size())

tensor([ 0.0283, 0.1335, -1.2315, -0.8102, 1.2055])
torch.Size([5])
tensor([[ 0.0283, 0.1335],
[ 0.1335, -1.2315],
[-1.2315, -0.8102],
[-0.8102, 1.2055]])
torch.Size([4, 2])

縮小張量

torch.Tensor.narrow(dimension, start, length)

返回一個經過縮小後的張量,多餘的元素刪除。操作的維度由dimension指定。縮小範圍是從start開始到start+length。執行本方法的張量與返回的張量共享相同的底層內存。
參數:
dimension (int) – 要進行縮小的維度
start (int) – 維度索引的起始位
length (int) – 保留車長度
例子:

import torch
x = torch.randn((3,3))
print(x)
print(x.size())
# 在維度0上縮小,從0開始,數兩個
y = x.narrow(0,0,2)
print('*******')
print(y)
print(y.size())
# 在維度0上縮小,從1開始,數兩個
y = x.narrow(0,1,2)
print('*******')
print(y)
print(y.size())
# 在維度1上縮小,從0開始,數兩個
y = x.narrow(1,0,2)
print('*******')
print(y)
print(y.size())

tensor([[ 0.6879, -0.9074, -0.8069],
[-1.4223, 0.7848, -1.0517],
[-0.8015, 0.5503, 1.1616]])
torch.Size([3, 3])


tensor([[ 0.6879, -0.9074, -0.8069],
[-1.4223, 0.7848, -1.0517]])
torch.Size([2, 3])


tensor([[-1.4223, 0.7848, -1.0517],
[-0.8015, 0.5503, 1.1616]])
torch.Size([2, 3])


tensor([[ 0.6879, -0.9074],
[-1.4223, 0.7848],
[-0.8015, 0.5503]])
torch.Size([3, 2])

張量變形

torch.Tensor.view(*args)

返回一個有相同數據但是不同形狀的新的向量。
返回的裝兩必須與原張量有相同的數據和相同的元素個數,但是可以有不同的尺寸。
參數:
args (torch.Size or int…) - 理想的指定尺寸
例子:

import torch
x = torch.randn((3,4))
print(x)
print(x.size())
# 改變形狀,按行掃描
y = x.view(2,6)
print('*******')
print(y)
print(y.size())

tensor([[ 0.2112, 1.5160, 1.8517, -0.1830],
[-0.5600, -0.5484, -0.0596, -0.0722],
[ 0.3125, -0.4918, -1.5547, 0.3193]])
torch.Size([3, 4])


tensor([[ 0.2112, 1.5160, 1.8517, -0.1830, -0.5600, -0.5484],
[-0.0596, -0.0722, 0.3125, -0.4918, -1.5547, 0.3193]])
torch.Size([2, 6])

重設張量尺寸

torch.Tensor.resize_(*sizes)

將張量的尺寸調整爲指定的大小。如果元素個數比當前的內存大小大,就將底層存儲大小調整爲與新元素數目一致的大小。
如果元素個數比當前內存小,則底層存儲不會被改變。原來張量中被保存下來的元素將保持不變,但新內存將不會被初始化。
參數:
sizes (torch.Size or int…) - 需要調整的大小
例子:

import torch
x = torch.randn((3,4))
print(x)
print(x.size())

y = x.resize_(3,3)
print('*******')
print(y)
print(y.size())

y = x.resize_(4,4)
print('*******')
print(y)
print(y.size())

tensor([[ 0.2470, -0.7461, 0.3314, 0.1723],
[-0.3906, -0.3396, -2.2285, 1.7582],
[-0.9763, 1.9427, 0.3674, 1.3971]])
torch.Size([3, 4])


tensor([[ 0.2470, -0.7461, 0.3314],
[ 0.1723, -0.3906, -0.3396],
[-2.2285, 1.7582, -0.9763]])
torch.Size([3, 3])


tensor([[ 2.4695e-01, -7.4609e-01, 3.3135e-01, 1.7228e-01],
[-3.9056e-01, -3.3962e-01, -2.2285e+00, 1.7582e+00],
[-9.7632e-01, 1.9427e+00, 3.6742e-01, 1.3971e+00],
[ 0.0000e+00, 4.2246e-39, 0.0000e+00, 0.0000e+00]])
torch.Size([4, 4])

調換張量的維度

torch.Tensor.permute(*dims)

將執行本方法的張量的維度換位。
參數:
dim (int) - 指定換位順序
例子:

import torch
x = torch.randn((1,2,3))
print(x)
print(x.size())

y = x.permute(2,0,1)
print('*******')
print(y)
print(y.size())

tensor([[[ 0.3598, 0.9950, 0.0607],
[-0.6146, 0.4286, 1.9699]]])
torch.Size([1, 2, 3])


tensor([[[ 0.3598, -0.6146]],
[[ 0.9950, 0.4286]],
[[ 0.0607, 1.9699]]])
torch.Size([3, 1, 2])

查看張量單個元素的字節數

torch.Tensor.element_size()

查看某類型張量單個元素的字節數。
例子:

import torch
x = torch.randn((1,2,3))
print(x.element_size())

4

原文鏈接:https://zhuanlan.zhihu.com/p/31495102

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章