我已经到处寻找与PyTorch等效的东西,但是我找不到任何东西。
L_1 = np.tril(np.random.normal(scale=1., size=(D, D)), k=0)
L_1[np.diag_indices_from(L_1)] = np.exp(np.diagonal(L_1))
我猜想使用Pytorch没有一种优雅的方式可以替换对角线元素。
有一种更简单的方法来完成它
dest_matrix[range(len(dest_matrix)), range(len(dest_matrix))] = source_vector
dest_matrix = torch.randint(10, (3, 3))
source_vector = torch.randint(100, 200, (len(dest_matrix), ))
print('dest_matrix:\n', dest_matrix)
print('source_vector:\n', source_vector)
dest_matrix[range(len(dest_matrix)), range(len(dest_matrix))] = source_vector
print('result:\n', dest_matrix)
# dest_matrix:
# tensor([[3, 2, 5],
# [0, 3, 5],
# [3, 1, 1]])
# source_vector:
# tensor([182, 169, 147])
# result:
# tensor([[182, 2, 5],
# [ 0, 169, 5],
# [ 3, 1, 147]])
如果dest_matrix
不是正方形,则在range()
中应使用min(dest_matrix.size())
而非len(dest_matrix)
。
这种方法不如numpy
优雅,但它不需要存储新的索引矩阵。
是的,这保留了梯度
我认为目前还没有实现这样的功能。但是,您可以使用mask
来实现相同的功能,方法如下。
# Assuming v to be the vector and a be the tensor whose diagonal is to be replaced
mask = torch.diag(torch.ones_like(v))
out = mask*torch.diag(v) + (1. - mask)*a
L_1 = torch.tril(torch.randn((D, D)))
v = torch.exp(torch.diag(L_1))
mask = torch.diag(torch.ones_like(v))
L_1 = mask*torch.diag(v) + (1. - mask)*L_1
您可以使用 diagonal()
提取对角线元素,然后使用 copy_()
将转换后的值就地赋值:
new_diags = L_1.diagonal().exp()
L_1.diagonal().copy_(new_diags)
为了简单起见,假设您有一个矩阵L_1
并希望用零替换其对角线。 您可以使用多种方法来实现此目的。
使用fill_diagonal_()
:
L_1 = torch.tensor([[1,2,3],[4,5,6],[7,8,9]], dtype=torch.float32)
L_1 = L_1.fill_diagonal_(0.)
L_1 = torch.tensor([[1,2,3],[4,5,6],[7,8,9]], dtype=torch.float32)
length = len(L_1)
zero_vector = torch.zeros(length, dtype=torch.float32)
L_1[range(length), range(length)] = zero_vector
scatter_()
函数:L_1 = torch.tensor([[1,2,3],[4,5,6],[7,8,9]], dtype=torch.float32)
diag_idx = torch.arange(len(L_1)).unsqueeze(1)
zero_matrix = torch.zeros(L_1.shape, dtype=torch.float32)
L_1 = L_1.scatter_(1, diag_idx, zero_matrix)
L_1 = torch.tensor([[1,2,3],[4,5,6],[7,8,9]], dtype=torch.float32)
length = len(L_1)
zero_vector = torch.zeros(length, dtype=torch.float32)
L_1[range(length), range(length)] = zero_vector.data
使用scatter_()
和.data
:
L_1 = torch.tensor([[1,2,3],[4,5,6],[7,8,9]], dtype=torch.float32)
diag_idx = torch.arange(len(L_1)).unsqueeze(1)
zero_matrix = torch.zeros(L_1.shape, dtype=torch.float32)
L_1 = L_1.scatter_(1, diag_idx, zero_matrix.data)
请参考this讨论。