torch/nn - Tensors张量的逐元素拼接
这个问题的主题是使用torch/nn和torch/nngraph Lua库来为神经网络拼接张量。我几周前才开始使用Lua编程,所以我的经验非常有限。在下面的文本中,我将lua表称为数组。
背景
我正在为语音识别构建一个递归神经网络。
在网络中的某个时刻,有N个大小为m的张量数组。
a = {a1, a2, ..., aM},
b = {b1, b2, ..., bM},
... N次
其中ai和bi是张量,{}表示一个数组。
需要做的是逐元素拼接所有这些数组,以便output是一个由M个张量组成的数组,其中output [i]是第二个维度上从N个数组的每个第i个张量拼接的结果。
output = {z1, z2, ..., zM}
示例
用||表示张量
x = {|1 1|, |2 2|}
|1 1| |2 2|
2x2大小的张量
y = {|3 3 3|, |4 4 4|}
|3 3 3| |4 4 4|
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|
2x5大小的张量
因此,第一个大小为2x2的x张量与第一个大小为2x3的y张量在第二维上拼接,每个数组的第二个张量也是如此,从而导致z是一个张量数组大小为2x5。
问题
现在这是一个基本的拼接,但是我似乎找不到一个可以让我这么做的torch/nn库中的模块。当然我可以编写自己的模块,但是如果已经存在的模块可以做到这一点,那么我宁愿选择那种方式。
我所知道的唯一现有模块是JoinTable,它接受大小相同的张量数组并将它们拼接在一起。但我想逐元素拼接张量数组。
另外,当我们将输入馈送到我们的网络时,N个数组中的张量数量会发生变化,因此上下文中的m不是常数。
想法
为了使用JoinTable模块,我想我可以将我的数组转换为张量,然后在转换的N张量上进行JoinTable。但是再次,我需要一个执行这种转换的模块,以及另一个将其转换回一个数组的模块,以便将其馈送到网络的下一层。
最后的手段
编写一个新模块,迭代所有给定的数组并按元素拼接。当然可行,但是这篇文章的整个目的是找到一种避免编写不好模块的方法。我觉得这样的模块不存在很奇怪。
结论
最后我决定按照我在最后的手段中写的那样做。我编写了一个新模块,迭代所有给定的数组并按元素拼接。
尽管如此,@fmguler给出的答案也可以在不编写新模块的情况下完成相同的工作。
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
你可以使用
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]其中,
nn.Identity可以看作是一个函数,nn.JoinTable和nn.SelectTable是层级存储的模块。内层的nn.SelectTable可以依次选择输入的Tensor中的第 $1$ 到 $d$ 列(即第一行坐标)。外层的nn.JoinTable可以按列或者按行将输入合并起来,从而生成一个新的Tensor。使用
nnGraph可以将 “张量到张量” 的映射表示成图中的结点,非线性层向前传播的过程可通过对图中对应映射的结点进行计算实现。这种高度抽象的表达方式非常方便且直观。