评价此页

MaskedTensor 稀疏性#

在开始本教程之前,请确保您已阅读我们的 MaskedTensor 概述教程 <https://pytorch.ac.cn/tutorials/prototype/maskedtensor_overview.html>

简介#

稀疏性一直是 PyTorch 中快速发展且重要的领域;如果下面有任何稀疏性术语令人困惑,请参考 稀疏性教程 获取更多详细信息。

稀疏存储格式已被证明在多种方面都非常强大。作为入门,大多数从业者首先想到的用例是当大多数元素等于零时(高稀疏度),但即使在稀疏度较低的情况下,某些格式(例如 BSR)也可以利用矩阵内的子结构。

注意

目前,MaskedTensor 支持 COO 和 CSR 张量,并计划在未来支持其他格式(例如 BSR 和 CSC)。如果您有任何关于其他格式的请求,请在此处提交功能请求

原则#

在创建具有稀疏张量的 MaskedTensor 时,必须遵守一些原则:

  1. datamask 必须具有相同的存储格式,无论是 torch.stridedtorch.sparse_coo 还是 torch.sparse_csr

  2. datamask 必须具有相同的大小,由 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

  1. masked_tensor(sparse_tensor_data, sparse_tensor_mask)

  2. 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 值。

请注意,mtmt2 在表面上看起来完全相同,在绝大多数操作中也会产生相同的结果。但这引出了一个实现细节:

对于稀疏 MaskedTensors,datamask – 仅适用于稀疏 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 秒)