【问题标题】:Fast way to initialize a tensor in torch7在torch7中初始化张量的快速方法
【发布时间】:2015-08-14 00:34:07
【问题描述】:

我需要在torch7中初始化一个具有索引相关函数的3D张量,即

func = function(i,j,k)  --i, j is the index of an element in the tensor
    return i*j*k        --do operations within func which're dependent of i, j
end

然后我像这样初始化一个 3D 张量 A:

for i=1,A:size(1) do
    for j=1,A:size(2) do
        for k=1,A:size(3) do
            A[{i,j,k}] = func(i,j,k)
        end
    end
end

但是这段代码运行速度很慢,我发现它占用了总运行时间的 92%。有没有更有效的方法在 torch7 中初始化 3D 张量?

【问题讨论】:

  • A的大小是多少?

标签: for-loop matrix lua deep-learning torch


【解决方案1】:

请参阅Tensor:apply 的文档

这些函数对张量的每个元素应用一个函数 该方法称为(self)。这些方法比 在 Lua 中使用 for 循环。

文档中的示例基于其索引 i(在内存中)初始化 2D 数组。下面是 3 维的扩展示例,下面是 N-D 张量的扩展示例。在我的机器上使用 apply 方法要快得多,快得多:

require 'torch'

A = torch.Tensor(100, 100, 1000)
B = torch.Tensor(100, 100, 1000)

function func(i,j,k) 
    return i*j*k    
end

t = os.clock()
for i=1,A:size(1) do
    for j=1,A:size(2) do
        for k=1,A:size(3) do
            A[{i, j, k}] = i * j * k
        end
    end
end
print("Original time:", os.difftime(os.clock(), t))

t = os.clock()
function forindices(A, func)
  local i = 1
  local j = 1
  local k = 0
  local d3 = A:size(3)
  local d2 = A:size(2) 
  return function()
    k = k + 1
    if k > d3 then
      k = 1
      j = j + 1
      if j > d2 then
        j = 1
        i = i + 1
      end
    end
    return func(i, j, k)
  end
end

B:apply(forindices(A, func))
print("Apply method:", os.difftime(os.clock(), t))

编辑

这适用于任何张量对象:

function tabulate(A, f)
  local idx = {}
  local ndims = A:dim()
  local dim = A:size()
  idx[ndims] = 0
  for i=1, (ndims - 1) do
    idx[i] = 1
  end
  return A:apply(function()
    for i=ndims, 0, -1 do
      idx[i] = idx[i] + 1
      if idx[i] <= dim[i] then
        break
      end
      idx[i] = 1
    end
    return f(unpack(idx))
  end)
end

-- usage for 3D case.
tabulate(A, function(i, j, k) return i * j * k end)

【讨论】:

  • 不客气! (评论已删除,因为在此 edit 之后不再相关)
  • 很好的答案!只要仿函数可以正确地进行 JIT 编译,它就会非常快(接近 C 速度)
  • 非常感谢@rpattiso。这正是我正在寻找的,尽管我花了一些时间弄清楚 forindices() 是如何工作的。这真的很有帮助。顺便问一下,你是怎么想到这个功能的?你读过 Torch7 的 C 源代码吗?
  • @MarsPlus 我很高兴它有帮助!我阅读了文档,看到他们如何使用全局变量 i 将张量初始化为序列,并在传递给应用的函数中递增它。然后我将其扩展到 3d 我模仿循环。
猜你喜欢
  • 2018-04-05
  • 1970-01-01
  • 2011-01-17
  • 1970-01-01
  • 2023-03-06
  • 2015-04-10
  • 1970-01-01
  • 2016-02-16
  • 2016-06-30
相关资源
最近更新 更多