torch/nn - 明智地连接张量数组
torch/nn - Joining arrays of Tensors element wise
这个问题的主题是将神经网络的张量与 torch/nn 和 torch/nn 图库连接起来 Lua。我几周前在 Lua 开始编码,所以我的经验非常少。在下面的文本中,我将 lua tables 称为数组。
上下文
我正在使用循环神经网络进行语音识别。
在网络中的某个点,有 N
个 m
张量数组。
a = {a1, a2, ..., aM},
b = {b1, b2, ..., bM},
... N times
其中ai
和bi
是张量,{}
代表数组。
需要做的是按元素连接所有这些数组,以便 output
是 M
个张量的数组,其中 output[i]
是连接每个第 i 个张量的结果N
个二维数组。
output = {z1, z2, ..., zM}
例子
||
用来表示张量
x = {|1 1|, |2 2|}
|1 1| |2 2|
Tensors of size 2x2
y = {|3 3 3|, |4 4 4|}
|3 3 3| |4 4 4|
Tensors of size 2x3
|
| Join{x,y}
\/
z = {|1 1 3 3 3|, |2 2 4 4 4|}
|1 1 3 3 3| |2 2 4 4 4|
Tensors of size 2x5
因此,第一个 x
大小为 2x2 的张量与第一个 y
大小为 2x3 的张量在第二个维度上连接,每个数组的第二个张量也相同,导致 z
张量数组 2x5.
问题
现在这是一个基本的串联,但我似乎无法在 torch/nn 库中找到允许我这样做的模块。我当然可以编写自己的模块,但是如果已经存在的模块可以做到,那么我宁愿使用它。
我所知道的唯一连接 table 的现有模块是(显然)JoinTable。它需要一组张量并将它们连接在一起。我想按元素加入张量数组。
此外,当我们向网络提供输入时,N
数组中的张量数量会发生变化,因此上述上下文中的 m
不是常数。
想法
为了使用 JoinTable 模块,我认为我可以做的是将我的数组转换为张量,然后 JoinTable
在转换后的 N
张量上。但是话又说回来,我需要一个模块来进行这种转换,另一个模块将其转换回数组,以便将其提供给网络的下一层。
不得已
编写一个新模块,迭代所有给定的数组并按元素连接。当然它是可行的,但是这个 post 的全部目的是找到一种避免编写臭模块的方法。这样的模块尚不存在,我觉得很奇怪。
结论
我终于决定按照我在不得已中写的去做。我编写了一个新模块,它遍历所有给定的数组并按元素连接。
不过,@fmguler 给出的答案无需编写新模块即可实现同样的效果。
你可以像这样用 nn.SelectTable 和 nn.JoinTable 来做;
require 'nn'
x = {torch.Tensor{{1,1},{1,1}}, torch.Tensor{{2,2},{2,2}}}
y = {torch.Tensor{{3,3,3},{3,3,3}}, torch.Tensor{{4,4,4},{4,4,4}}}
res = {}
res[1] = nn.JoinTable(2):forward({nn.SelectTable(1):forward(x),nn.SelectTable(1):forward(y)})
res[2] = nn.JoinTable(2):forward({nn.SelectTable(2):forward(x),nn.SelectTable(2):forward(y)})
print(res[1])
print(res[2])
如果您希望在模块中完成此操作,请将其包装在 nnGraph 中;
require 'nngraph'
x = {torch.Tensor{{1,1},{1,1}}, torch.Tensor{{2,2},{2,2}}}
y = {torch.Tensor{{3,3,3},{3,3,3}}, torch.Tensor{{4,4,4},{4,4,4}}}
xi = nn.Identity()()
yi = nn.Identity()()
res = {}
--you can loop over columns here>>
res[1] = nn.JoinTable(2)({nn.SelectTable(1)(xi),nn.SelectTable(1)(yi)})
res[2] = nn.JoinTable(2)({nn.SelectTable(2)(xi),nn.SelectTable(2)(yi)})
module = nn.gModule({xi,yi},res)
--test like this
result = module:forward({x,y})
print(result)
print(result[1])
print(result[2])
--gives the result
th> print(result)
{
1 : DoubleTensor - size: 2x5
2 : DoubleTensor - size: 2x5
}
th> print(result[1])
1 1 3 3 3
1 1 3 3 3
[torch.DoubleTensor of size 2x5]
th> print(result[2])
2 2 4 4 4
2 2 4 4 4
[torch.DoubleTensor of size 2x5]
这个问题的主题是将神经网络的张量与 torch/nn 和 torch/nn 图库连接起来 Lua。我几周前在 Lua 开始编码,所以我的经验非常少。在下面的文本中,我将 lua tables 称为数组。
上下文
我正在使用循环神经网络进行语音识别。
在网络中的某个点,有 N
个 m
张量数组。
a = {a1, a2, ..., aM},
b = {b1, b2, ..., bM},
... N times
其中ai
和bi
是张量,{}
代表数组。
需要做的是按元素连接所有这些数组,以便 output
是 M
个张量的数组,其中 output[i]
是连接每个第 i 个张量的结果N
个二维数组。
output = {z1, z2, ..., zM}
例子
||
用来表示张量
x = {|1 1|, |2 2|}
|1 1| |2 2|
Tensors of size 2x2
y = {|3 3 3|, |4 4 4|}
|3 3 3| |4 4 4|
Tensors of size 2x3
|
| Join{x,y}
\/
z = {|1 1 3 3 3|, |2 2 4 4 4|}
|1 1 3 3 3| |2 2 4 4 4|
Tensors of size 2x5
因此,第一个 x
大小为 2x2 的张量与第一个 y
大小为 2x3 的张量在第二个维度上连接,每个数组的第二个张量也相同,导致 z
张量数组 2x5.
问题
现在这是一个基本的串联,但我似乎无法在 torch/nn 库中找到允许我这样做的模块。我当然可以编写自己的模块,但是如果已经存在的模块可以做到,那么我宁愿使用它。
我所知道的唯一连接 table 的现有模块是(显然)JoinTable。它需要一组张量并将它们连接在一起。我想按元素加入张量数组。
此外,当我们向网络提供输入时,N
数组中的张量数量会发生变化,因此上述上下文中的 m
不是常数。
想法
为了使用 JoinTable 模块,我认为我可以做的是将我的数组转换为张量,然后 JoinTable
在转换后的 N
张量上。但是话又说回来,我需要一个模块来进行这种转换,另一个模块将其转换回数组,以便将其提供给网络的下一层。
不得已
编写一个新模块,迭代所有给定的数组并按元素连接。当然它是可行的,但是这个 post 的全部目的是找到一种避免编写臭模块的方法。这样的模块尚不存在,我觉得很奇怪。
结论
我终于决定按照我在不得已中写的去做。我编写了一个新模块,它遍历所有给定的数组并按元素连接。
不过,@fmguler 给出的答案无需编写新模块即可实现同样的效果。
你可以像这样用 nn.SelectTable 和 nn.JoinTable 来做;
require 'nn'
x = {torch.Tensor{{1,1},{1,1}}, torch.Tensor{{2,2},{2,2}}}
y = {torch.Tensor{{3,3,3},{3,3,3}}, torch.Tensor{{4,4,4},{4,4,4}}}
res = {}
res[1] = nn.JoinTable(2):forward({nn.SelectTable(1):forward(x),nn.SelectTable(1):forward(y)})
res[2] = nn.JoinTable(2):forward({nn.SelectTable(2):forward(x),nn.SelectTable(2):forward(y)})
print(res[1])
print(res[2])
如果您希望在模块中完成此操作,请将其包装在 nnGraph 中;
require 'nngraph'
x = {torch.Tensor{{1,1},{1,1}}, torch.Tensor{{2,2},{2,2}}}
y = {torch.Tensor{{3,3,3},{3,3,3}}, torch.Tensor{{4,4,4},{4,4,4}}}
xi = nn.Identity()()
yi = nn.Identity()()
res = {}
--you can loop over columns here>>
res[1] = nn.JoinTable(2)({nn.SelectTable(1)(xi),nn.SelectTable(1)(yi)})
res[2] = nn.JoinTable(2)({nn.SelectTable(2)(xi),nn.SelectTable(2)(yi)})
module = nn.gModule({xi,yi},res)
--test like this
result = module:forward({x,y})
print(result)
print(result[1])
print(result[2])
--gives the result
th> print(result)
{
1 : DoubleTensor - size: 2x5
2 : DoubleTensor - size: 2x5
}
th> print(result[1])
1 1 3 3 3
1 1 3 3 3
[torch.DoubleTensor of size 2x5]
th> print(result[2])
2 2 4 4 4
2 2 4 4 4
[torch.DoubleTensor of size 2x5]