我正在Rust中构建自己的Tensor类,我试图让它像PyTorch的实现一样。
以编程方式存储张量的最有效方法是什么,但具体来说,在像Rust这样的强类型语言中? 是否有任何资源可以提供有关如何完成此操作的深入见解?
我目前正在构建一个连续的数组,因此,给定3 x 3 x 3
的维度,我的数组中只有3^3
个元素,这代表张量。但是,这确实使得数组的一些数学运算和操作变得更加困难。
张量的维度应该是动态的,这样我就可以得到一个n
维度的张量。
答案 0 :(得分:4)
存储此类数据的常用方法是在单个数组中,该数组在内存中作为单个连续块进行布局。更具体地说,3x3x3张量将简单地存储为27个值的单个数组,一个接一个地存储。
使用尺寸的唯一地方是计算(多个)坐标与该数组内的偏移之间的映射。例如,要获取项目[3, 1, 1]
,您需要知道它是3x3x3矩阵,9x3x1矩阵还是27x1x1矩阵 - 在所有情况下,"存储"将会有27个项目,但对#34;坐标"的解释会有所不同。如果使用从零开始的索引,则计算很简单,但您需要知道每个维度的长度。
这确实意味着调整大小和类似操作可能需要复制整个阵列,但没关系,您可以权衡这些(罕见)操作的性能,以获得更常见操作的性能,例如:顺序读取。
答案 1 :(得分:3)
PyTorch默认以密集格式存储其张量。根据{{3}},
每个张量都有一个相关的torch.Storage,它保存着它的数据。该 张量类提供存储和存储的多维,跨步视图 定义数字操作。
正如您可能想象的那样,当存储具有许多零的大张量时,使用内存来存储所有值是非常低效的。因此,PyTorch还提供the docs。从该页面:
Torch支持COO(rdinate)格式的稀疏张量,可以 有效地存储和处理大多数的张量 元素是零。
如果您对不同稀疏格式之间的权衡感兴趣,从存储sparse tensors时存在的大量文献开始可能是有用的。用于矩阵的许多技术(实际上是2级张量)转化为多维度。 sparse matrices详细介绍了稀疏张量的实现。
维基百科链接的摘要以及论文是
易于指定和修改的格式通常在计算上效率低下,因此稀疏结构通常使用一个规范构建,但存储在另一个规范中
选择符合预期用途的存储格式非常重要。例如,矩阵 - 矩阵乘法需要有效的列访问,而矩阵向量乘法则需要有效的行访问。
最后,我建议在This masters dissertation查看Rust的一个好的稀疏矩阵库。在寻求扩展到多个维度时,它可能是一个好的开始。