如何有效地标准化张量中的元素组

时间:2018-10-23 10:04:58

标签: python conv-neural-network pytorch

上下文:

我正在尝试复制Hinton的“带有EM路由的矩阵胶囊”(https://openreview.net/forum?id=HJWLfGWRb)。

在某些时候,会执行卷积运算(在某种意义上,输出张量连接到输入张量,并且输出张量中的每个元素仅受2D尺寸的蒙版中包含的输入元素影响) K)。

输入 形状为x的张量w_in,w_in 在哪里

  • w_in=14

映射到输入的中间张量 形状为x_mapped的张量w_out,w_out,K,K 在哪里

  • K=3是卷积内核大小
  • w_out=6,是与stride=2卷积的结果

在尺寸2和3上求和(均为K)是指在连接到其位置由尺寸0和1给出的输出元素的输入元素上求和。

问题:

如何根据元素在输入张量x_mapped中的位置,有效地将x中的元素组标准化为1个?

例如:
x_mapped(0,0,2,2)
x_mapped(1,0,0,2)
x_mapped(0,1,2,0)
x_mapped(1,1,0,0)
都连接到x(2,2)(公式为i_out*stride + K_index = i_in)。因此,我希望这4个元素的总和为1。

我想对x_mapped中所有与x中的同一元素“连接”的元素组进行此操作。

我可以通过以下方法弄清楚该怎么做:

  1. 构建一个以输入位置为键,输出元素列表为值的字典
  2. 遍历字典,将给定输入位置的列表中的元素求和,然后除以该总和。

但是对我来说这似乎效率很低。

1 个答案:

答案 0 :(得分:0)

我通过以下方式解决了这个问题:

  1. 创建一个以2元组为键(x中的坐标)并以x_mapped元素列表作为值的字典。
  2. 在字典上循环一遍,将一个字典项的所有元素压缩在一起,然后进行规范化。

代码如下:

from collections import defaultdict
import torch

ho = 6
wo = 6
stride = 2
K = 3

d = defaultdict(list)

x_mapped = torch.arange(0,ho*wo*K*K).view(ho,wo,K,K).type(dtype = torch.DoubleTensor)

for i_out in range(0,ho):
    for j_out in range(0,wo):
        for K_i in range(0,K):
            for K_j in range(0, K):
                i_in = i_out * stride + K_i
                j_in = j_out * stride + K_j

                d[(i_in, j_in)].append((i_out, j_out, K_i, K_j))

for _ , value in d.items():
    ho_list, wo_list, K_i_list, K_j_list = zip(*value)
    x_mapped[ho_list, wo_list, K_i_list, K_j_list] = x_mapped[ho_list, wo_list, K_i_list, K_j_list] / torch.sum(
        x_mapped[ho_list, wo_list, K_i_list, K_j_list])