一、張量的維度操作
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