【问题标题】:How to create n-dimensional sparse tensor? (pytorch)如何创建n维稀疏张量? (火炬)
【发布时间】:2021-08-06 18:05:52
【问题描述】:

我想将张量初始化为稀疏张量。 当张量的维数为2时,我可以使用torch.nn.init.sparse(tensor, sparsity=0.1)

import torch
dim = torch.Size([3,2])
w = torch.Tensor(dim)
torch.nn.init.sparse_(w, sparsity=0.1)

结果

tensor([[ 0.0000,  0.0147],
        [-0.0190,  0.0004],
        [-0.0004,  0.0000]])

但是当张量维度 > 2 时,这个功能就不起作用了。

v = torch.Tensor(torch.Size([5,5,30,2]))
torch.nn.init.sparse_(v, sparsity=0.1)

结果

ValueError: Only tensors with 2 dimensions are supported

我需要这个,因为我想用它来初始化卷积权重。

torch.nn.init.sparse_() 函数的定义如下

def sparse_(tensor, sparsity, std=0.01):
    r"""Fills the 2D input `Tensor` as a sparse matrix, where the
    non-zero elements will be drawn from the normal distribution
    :math:`\mathcal{N}(0, 0.01)`, as described in `Deep learning via
    Hessian-free optimization` - Martens, J. (2010).

    Args:
        tensor: an n-dimensional `torch.Tensor`
        sparsity: The fraction of elements in each column to be set to zero
        std: the standard deviation of the normal distribution used to generate
            the non-zero values

    Examples:
        >>> w = torch.empty(3, 5)
        >>> nn.init.sparse_(w, sparsity=0.1)
    """
    if tensor.ndimension() != 2:
        raise ValueError("Only tensors with 2 dimensions are supported")

    rows, cols = tensor.shape
    num_zeros = int(math.ceil(sparsity * rows))

    with torch.no_grad():
        tensor.normal_(0, std)
        for col_idx in range(cols):
            row_indices = torch.randperm(rows)
            zero_indices = row_indices[:num_zeros]
            tensor[zero_indices, col_idx] = 0
    return tensor

如何制作 n 维稀疏张量?

pytorch 中有没有办法创建这种张量?

或者我可以换一种方式吗?

【问题讨论】:

    标签: python python-3.x pytorch


    【解决方案1】:

    此函数是以下方法的实现:

    我们发现的最佳随机初始化方案是我们自己的设计之一,“稀疏初始化”。在这个方案中,我们硬限制 每个非零传入连接权重的数量 单位(我们在实验中使用了 15)并将偏差设置为 0(或 0.5 为 tanh 单位)。

    • 通过无 Hessian 优化进行深度学习 - Martens, J. (2010)。

    高阶张量不支持它的原因是因为它在每列中保持相同比例的零,并且不清楚对于高阶张量,该条件应保持在哪些维度[子集]。

    您可以使用dropout 或等效函数来实现此初始化策略,例如:

    def sparse_(tensor, sparsity, std=0.01):
        with torch.no_grad():
            tensor.normal_(0, std)
            tensor = F.dropout(tensor, sparsity)
        return tensor
    

    如果您希望强制执行列、通道等方面的零比例(而不仅仅是总比例),您可以实现类似于原始函数的逻辑。

    【讨论】:

      猜你喜欢
      • 2022-07-20
      • 2021-08-25
      • 2021-09-27
      • 2021-09-22
      • 1970-01-01
      • 2020-10-26
      • 2021-10-26
      • 1970-01-01
      • 2021-02-08
      相关资源
      最近更新 更多