pytorch,将一个向量的置换添加到矩阵的项时摆脱for循环?

问题描述

我正在尝试实施本文,并坚持了这一简单步骤。尽管这是要引起注意的,但我坚持要做的只是如何在不使用for循环的情况下实现添加到矩阵的向量的排列。

注意力得分上添加一个学习的偏向矢量,理论上讲,它对得分代表

enter image description here

的两个标记的相对位置(j-i)进行编码 因此,alpha是一个T x T矩阵,T取决于要转发的批次,而B是一个学习的偏差矢量,其长度必须固定且最大为2T。我相信本文所建议的当前实现是:

    def __init__(...):
       ...
        self.bias = torch.nn.Parameter(torch.randn(config.n),requires_grad = True)
        stdv = 1. / math.sqrt(self.bias.data.size(0))
        self.bias.data.uniform_(-stdv,stdv)
     def forward(..)
        ...
        #n = 201  (2* max_seq_len + 1)

        B_matrix = torch.zeros(self.T,self.T) # 60 x 60
        for i in range(self.T):
          B_matrix[i] = self.bias[torch.arange(start=n//2-i,end=n//2-i+T)])]

        attention_scores = attention_scores + B_matrix.unsqueeze(0)
        # 64 x 60 x 60   
        ...

这是唯一相关的部分

B_matrix = torch.zeros(self.T,end=n//2-i+T)])]

基本上试图不使用for循环遍历每一行。

但我知道这在模型很大时肯定是效率低下的,而且成本很高。我正在对每行进行显式的for循环,以获取学习到的偏差向量的排列。

有人可以通过智能广播帮助我更好的方法吗?

考虑之后,我不需要实例化零矩阵,但是仍然不能摆脱for循环吗?并且不能使用Gather,因为B_matrix的大小不同于平铺的b向量。

functor = lambda i : bias[torch.arange(start=n//2-i,end=n//2-i+T)]
B_matrix = torch.stack([functor(i) for i in torch.arange(T)])

解决方法

我无法弄清楚应该在您的代码中使用n是什么,但是我认为以下使用torch.meshgrid的示例可以满足您的需求。

假设

n,m = 10,20   # arbitrary
a = torch.randn(n,m)
b = torch.randn(n + m)

然后

for i in range(n):
    for j in range(m):
        a[i,j] = a[i,j] + b[n - i + j]

等同于

ii,jj = torch.meshgrid(torch.arange(n),torch.arange(m))
a = a + b[n - ii + jj]

尽管后者是不适当的操作,这通常是一件好事。如果您确实需要就地操作,则将a =替换为a[...] =

请注意,这是integer array indexing的示例,其中我们使用与b相同形状的张量来索引a

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...