在PyTorch中如何构造包含一维向量所有滚动结果的n×n矩阵?
在PyTorch中高效构造含一维向量所有滚动向量的n×n矩阵
给定大小为n的一维向量x,我们需要生成一个n×n矩阵X,其中每一行都是x的一个滚动结果。比如输入x = torch.tensor([1,2,3,4]),预期输出为:
tensor([[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]])
你提供的基于循环+torch.roll的实现虽然可行,但在n较大时效率偏低——循环会导致多次张量操作,无法充分利用PyTorch的向量化加速能力。以下是两种更高效的向量化实现方案:
方案1:利用torch.cat + torch.unfold
这种方法通过扩展向量后提取滑动窗口,全程无循环,代码简洁且性能优异:
import torch x = torch.tensor([1,2,3,4]) n = x.shape[0] # 将x扩展为x + x[:-1],得到包含所有滚动可能的长向量 extended_x = torch.cat([x, x[:-1]]) # 提取长度为n、步长为1的滑动窗口,直接得到目标矩阵 X = extended_x.unfold(0, n, 1) print(X)
方案2:利用torch.as_strided(性能最优)
该方法直接操作张量的内存 stride,不会复制数据,是效率最高的实现方式,但需要注意张量的内存布局:
import torch x = torch.tensor([1,2,3,4]) n = x.shape[0] extended_x = torch.cat([x, x[:-1]]) # 构造目标矩阵的size和stride:行长度为n,共n行;每行元素步长为1,行之间步长也为1 X = torch.as_strided(extended_x, size=(n, n), stride=(1, 1)) print(X)
注意:
torch.as_strided生成的是原张量的视图,修改原张量会同步影响X,使用时需留意这一特性。
性能对比
原循环实现会逐行调用torch.roll并赋值,n越大,冗余操作越多;而上述两种向量化方案均为单次张量操作,能充分利用CPU/GPU的并行计算能力,在n较大时性能提升非常明显。
内容的提问来源于stack exchange,提问作者Vezen BU
相关产品推荐
相关产品推荐

