注意
转至末尾 下载完整的示例代码。
MaskedTensor 稀疏性#
在开始本教程之前,请确保您已阅读我们的 MaskedTensor 概述教程 <https://pytorch.ac.cn/tutorials/prototype/maskedtensor_overview.html>。
简介#
稀疏性一直是 PyTorch 中快速发展且重要的领域;如果下面有任何稀疏性术语令人困惑,请参考 稀疏性教程 获取更多详细信息。
稀疏存储格式已被证明在多种方面都非常强大。作为入门,大多数从业者首先想到的用例是当大多数元素等于零时(高稀疏度),但即使在稀疏度较低的情况下,某些格式(例如 BSR)也可以利用矩阵内的子结构。
注意
目前,MaskedTensor 支持 COO 和 CSR 张量,并计划在未来支持其他格式(例如 BSR 和 CSC)。如果您有任何关于其他格式的请求,请在此处提交功能请求 !
原则#
在创建具有稀疏张量的 MaskedTensor 时,必须遵守一些原则:
data和mask必须具有相同的存储格式,无论是torch.strided、torch.sparse_coo还是torch.sparse_csr。data和mask必须具有相同的大小,由size()指示。
稀疏 COO 张量#
根据原则 #1,通过传入两个稀疏 COO 张量来创建一个稀疏 COO MaskedTensor,这些张量可以通过任何构造函数进行初始化,例如 torch.sparse_coo_tensor()。
回顾 稀疏 COO 张量,COO 格式代表“坐标格式”,其中指定的元素存储为其索引的元组和相应的值。也就是说,提供了以下内容:
indices:大小为(ndim, nse)且 dtype 为torch.int64的数组。values:大小为 (nse,) 且 dtype 为任何整数或浮点数的数组。
其中 ndim 是张量的维度,nse 是指定元素的数量。
对于稀疏 COO 和 CSR 张量,您可以通过以下任一方式构造 MaskedTensor:
masked_tensor(sparse_tensor_data, sparse_tensor_mask)dense_masked_tensor.to_sparse_coo()或dense_masked_tensor.to_sparse_csr()。
第二种方法更容易说明,我们在下面展示了这一点,但有关第一种方法及其背后方法的更多信息,请阅读 稀疏 COO 附录。
# Disable prototype warnings and such
稀疏 CSR 张量#
同样,MaskedTensor 也支持 CSR (Compressed Sparse Row) 稀疏张量格式。与存储稀疏 COO 张量的索引元组不同,稀疏 CSR 张量旨在通过存储压缩行索引来减少内存需求。特别是,CSR 稀疏张量由三个一维张量组成:
crow_indices:大小为(size[0] + 1,)的压缩行索引数组。此数组指示给定 values 中的条目属于哪一行。最后一个元素是指定元素的数量,而 crow_indices[i+1] - crow_indices[i] 表示第 i 行中指定元素的数量。col_indices:大小为(nnz,)的数组。指示每个值的列索引。values:大小为(nnz,)的数组。包含 CSR 张量的值。
值得注意的是,稀疏 COO 和 CSR 张量都处于 beta 状态。
举例来说
支持的操作#
一元运算#
所有 一元运算符 都受支持,例如:
二元运算#
也支持 二元运算符,但两个掩码张量的输入掩码必须匹配。有关做出此决定的原因的更多信息,请参阅我们的 MaskedTensor:高级语义教程。
请参阅下面的示例。
规约#
最后,支持 规约。
MaskedTensor 辅助方法#
为了方便起见,MaskedTensor 提供了许多方法来帮助在不同布局之间进行转换并识别当前布局。
设置
MaskedTensor.to_sparse_coo() / MaskedTensor.to_sparse_csr() / MaskedTensor.to_dense() 以帮助在不同布局之间进行转换。
MaskedTensor.is_sparse() — 这将检查 MaskedTensor 的布局是否与任何支持的稀疏布局(目前为 COO 和 CSR)匹配。
MaskedTensor.is_sparse_coo()
MaskedTensor.is_sparse_csr()
附录#
稀疏 COO 构建#
回想我们在 原始示例 中创建了一个 MaskedTensor,然后使用 MaskedTensor.to_sparse_coo() 将其转换为稀疏 COO MaskedTensor。
或者,我们也可以通过传入两个稀疏 COO 张量来直接构造稀疏 COO MaskedTensor。
我们也可以直接创建稀疏 COO 张量,而不是使用 torch.Tensor.to_sparse(),这就引出了一个警告:
警告
当使用像 MaskedTensor.to_sparse_coo() (类似于 Tensor.to_sparse())这样的函数时,如果用户没有像上面示例那样指定索引,那么 0 值将默认被“未指定”。
下面,我们明确指定了 0 值。
请注意,mt 和 mt2 在表面上看起来完全相同,在绝大多数操作中也会产生相同的结果。但这引出了一个实现细节:
对于稀疏 MaskedTensors,data 和 mask – 仅适用于稀疏 MaskedTensors – 在创建时可以有不同数量的元素 (nnz()),但此时 mask 的索引必须是 data 索引的子集。在这种情况下,data 将通过 data = data.sparse_mask(mask) 假定 mask 的形状;换句话说,data 中不在 mask 中为 True (即未指定)的任何元素都将被丢弃。
因此,在底层,数据看起来略有不同;mt2 屏蔽掉了“4”的值,而 mt 完全没有它。它们的底层数据具有不同的形状,这将使 mt + mt2 等操作无效。
稀疏 CSR 构建#
我们也可以使用稀疏 CSR 张量来构造稀疏 CSR MaskedTensor,并且像上面的示例一样,这在底层会导致类似的处理。
结论#
在本教程中,我们介绍了如何将 MaskedTensor 与稀疏 COO 和 CSR 格式一起使用,并讨论了底层的一些细微之处,以防用户直接访问底层数据结构。稀疏存储格式和掩码语义确实具有很强的协同作用,以至于它们有时会互为代理(正如我们将在下一教程中看到的)。未来,我们肯定计划在此方向上投入并继续发展。
进一步阅读#
要继续学习更多内容,您可以找到我们的 使用 MaskedTensor 高效编写 Adagrad 的“稀疏”语义教程,以了解 MaskedTensor 如何使用原生掩码语义简化现有工作流程的示例。
# %%%%%%RUNNABLE_CODE_REMOVED%%%%%%
脚本总运行时间:(0 分 0.002 秒)