pytorch 花式張量(Tensor)操作


 一、張量的維度操作

1.squezee & unsqueeze

x = torch.rand(5,1,2,1)
x = torch.squeeze(x)#x.squeeze()去掉大小為1的維度,x.shape =(5,2)
x = torch.unsqueeze(x,2)#x.unsqueeze(2)和squeeze相反在第三維上擴展,x.shape = (5,2,1)

2.張量擴散,在指定維度上將原來的張量擴展到指定大小,比如原來x是31,輸入size為[3, 4],可以將其擴大成34,4為原來1個元素的復制

x = x.expand(*size)
x = x.expand_as(y)# y:[3,4

3.轉置,torch.transpose 只能交換兩個維度 permute沒有限制

x = torch.transpose(x, 1, 2) # 交換1和2維度
x = x.permute(1, 2, 3, 0) # 進行維度重組

4.改變形狀,view&reshape 兩者作用一樣,區別在於是當從多的維度變到少的維度時,如果張量不是在連續內存存放,則view無法變成合並維度,會報錯

x = x.view(1, 2, -1)#把原先tensor中的數據按照行優先的順序排成一個一維的數據(這里應該是因為要求地址是連續存儲的),然后按照參數組合成其他維度的tensor
x = x.reshape(1, 2, -1)

5.張量拼接 cat & stack

torch.cat(a_tuple, dim)#tuple 是一個張量或者元組,在指定維度上進行拼接
torch.stack(a_tuple, dim)#與cat不同的在於,cat只能在原有的某一維度上進行連接,stack可以創建一個新的維度,將原有維度在這個維度上進行順序排列
#比如說,有2個4x4的張量,用cat就只能把它們變成一個8x4或4x8的張量,用stack可以變成2x4x4.

6.張量拆分,chunk & split

torch.chunk(a, chunk_num, dim)#在指定維度上將a變成chunk_num個大小相等的chunk,返回一個tuple。如果最后一個不夠chunk_num,就返回剩下的
torch.split(a, chunk_size, dim)#與chunk相似,只是第二次參數變成了chunk_size

一、張量的乘法操作

1 * 點乘 & torch.mul 兩者用法相同,后者用了broadcast概念

#標量k做*乘法的結果是Tensor的每個元素乘以k(相當於把k復制成與lhs大小相同,元素全為k的Tensor
a = torch.ones(3,4)
a = a * 2
''' tensor([[2., 2., 2., 2.],
        [2., 2., 2., 2.],
        [2., 2., 2., 2.]])'''
#與行向量相乘向量作乘法 每列乘以行向量對應列的值(相當於把行向量的行復制,A的列數和向量數目相同),與列向量同理
b = torch.Tensor([1,2,3,4])
a*b
'''
tensor([[1., 2., 3., 4.],
     [1., 2., 3., 4.],
     [1., 2., 3., 4.]])
'''
# 向量*向量,element-wise product

2.torch.mm&torch.matmul兩者用法相同,后者用了broadcast概念

torch.matmul(input, other, out=None) → Tensor
#兩個張量的矩陣乘積。行為取決於張量的維數,如下所示:
#1. 如果兩個張量都是一維的,則返回點積(標量)。
# vector x vector
 tensor1 = torch.randn(3)
 tensor2 = torch.randn(3)
 torch.matmul(tensor1, tensor2).size()
torch.Size([])
#2. 如果兩個參數都是二維的,則返回矩陣矩陣乘積。
# matrix x matrix
 tensor1 = torch.randn(3, 4)
 tensor2 = torch.randn(4, 5)
 torch.matmul(tensor1, tensor2).size() #torch.Size([3, 5])
#3. 如果第一個參數是一維的,而第二個參數是二維的,則為了矩陣乘法,會將1附加到其維數上。矩陣相乘后,將刪除前置尺寸。
# 也就是讓tensor2變成矩陣表示,1x3的矩陣和 3x4的矩陣,得到1x4的矩陣,然后刪除1
 tensor1 = torch.randn(3, 4)
 tensor2 = torch.randn(3)
 torch.matmul(tensor2, tensor1).size() #torch.Size([4])
#4. 如果第一個參數為二維,第二個參數為一維,則返回矩陣向量乘積。
# matrix x vector
 tensor1 = torch.randn(3, 4)
 tensor2 = torch.randn(4)
 torch.matmul(tensor1, tensor2).size()#torch.Size([3])
#5. 如果兩個自變量至少為一維且至少一個自變量為N維(其中N> 2),則返回批處理矩陣乘法。
#如果第一個參數是一維的,則在其維數之前添加一個1,以實現批量矩陣乘法並在其后刪除。
#如果第二個參數為一維,則將1附加到其維上,以實現成批矩陣倍數的目的,然后將其刪除。
#非矩陣(即批量)維度可以被廣播(因此必須是可廣播的)。
#例如,如果input為(jx1xnxm)張量,而other為(k×m×p)張量,out將是(j×k×n×p)張量。最后兩維必須,滿足矩陣乘法
 # batched matrix x broadcasted vector
 tensor1 = torch.randn(10, 3, 4)
 tensor2 = torch.randn(4)
 torch.matmul(tensor1, tensor2).size()#torch.Size([10, 3])
 # batched matrix x batched matrix
 tensor1 = torch.randn(10, 3, 4)
 tensor2 = torch.randn(10, 4, 5)
 torch.matmul(tensor1, tensor2).size()#torch.Size([10, 3, 5])
 # batched matrix x broadcasted matrix
 tensor1 = torch.randn(10, 3, 4)
 tensor2 = torch.randn(4, 5)
 torch.matmul(tensor1, tensor2).size()#torch.Size([10, 3, 5])
 tensor1 = torch.randn(10, 1, 3, 4)
 tensor2 = torch.randn(2, 4, 5)
 torch.matmul(tensor1, tensor2).size()#torch.Size([10, 2, 3, 5])

3.通用乘法:torch.tensordot

#可以表示任意多維,任意組合形式的矩陣相乘
# 如果 a = torch.Tensor([1, 2, 3, 4]), b = torch.tensor([2, 3, 4, 5])
# 想表示內積,直接令 dims=1 即可
# 如果dimss=0則按照逐元素挨個相乘累加
# dimss可以為二維數組,(dims_a, dims_b),指定兩個張量任意維度相乘
c = torch.tensordot(a, b, dims)
# a: B N F  b: P F
c = torch.tensordot(a,b,dims=([-1],[-1])) # c: B N P

4.einsum

#使用愛因斯坦求和約定來計算多線性表達式(即乘積和)的方法,能夠以一種統一的方式表示各種各樣的張量運算(內積、外積、轉置、點乘、矩陣的跡、其他自定義運算)。
#a: i k , b: j k
c = torch.enisum('ik, jk -> ij', a,b) # c : i j 及為下面的公式

其他可參考https://blog.csdn.net/a2806005024/article/details/96462827

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM