我想創建 2d 張量(或 numpy 陣列,并不重要),其中每一行都將回圈移位第一行。我使用for回圈來做到這一點:
import torch
import numpy as np
a = np.random.rand(33, 11)
miss_size = 64
lp_order = a.shape[1] - 1
inv_a = -np.flip(a, axis=1)
mtx_size = miss_size lp_order # some constant
mtx_row = torch.cat((torch.from_numpy(inv_a), torch.zeros((a.shape[0], miss_size - 1 a.shape[1]))), dim=1)
mtx_full = mtx_row.unsqueeze(1)
for i in range(mtx_size):
mtx_row = torch.roll(mtx_row, 1, 1)
mtx_full = torch.cat((mtx_full, mtx_row.unsqueeze(1)), dim=1)
需要解壓,因為我將 2d 張量堆疊成 3d 張量
有沒有更有效的方法來做到這一點?也許是線性代數技巧或更 Pythonic 的方法。
uj5u.com熱心網友回復:
您可以使用scipy.linalg.circulant():
scipy.linalg.circulant([1, 2, 3])
# array([[1, 3, 2],
# [2, 1, 3],
# [3, 2, 1]])
uj5u.com熱心網友回復:
我相信您可以torch.gather通過構建適當的索引張量來實作這一點。這種方法也適用于批處理。
如果我們采用這種方法,目標是構建一個索引張量,其中每個值都指向一個索引mtx_row(沿著這里的最后一個維度dim=1)。在這種情況下,它的形狀將是(3, 3):
tensor([[0, 1, 2],
[2, 0, 1],
[1, 2, 0]])
您可以通過torch.arange使用自己的轉置進行廣播并對結果矩陣應用模數來實作這一點:
>>> idx = (n-torch.arange(n)[None].T torch.arange(n)[None]) % n
tensor([[0, 1, 2],
[2, 0, 1],
[1, 2, 0]])
讓我們mtx_row塑造(2, 3):
>>> mtx_row
tensor([[0.3523, 0.0170, 0.1875],
[0.2156, 0.7773, 0.4563]])
從那里你需要idx,mtx_row所以他們有相同的形狀:
>>> idx_ = idx[None].expand(len(mtx_row), -1, -1)
>>> val_ = mtx_row[:, None].expand(-1, n, -1)
然后我們可以torch.gather在最后一個維度上應用dim=2:
>>> val_.gather(-1, idx_)
tensor([[[0.3523, 0.0170, 0.1875],
[0.1875, 0.3523, 0.0170],
[0.0170, 0.1875, 0.3523]],
[[0.2156, 0.7773, 0.4563],
[0.4563, 0.2156, 0.7773],
[0.7773, 0.4563, 0.2156]]])
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/338756.html
