冒泡 3-D 张量 PyTorch 的非空行
Bubble up non null rows of a 3-D Tensor PyTorch
我在尝试将以下函数转换为仅处理张量的函数时遇到了一些问题。
def valid_sequence_output(sequence_output, valid_mask):
bs, max_len, feat_dim = sequence_output.shape
valid_output = torch.zeros(bs, max_len, feat_dim, dtype=torch.float32)
for i in range(bs):
jj = -1
for j in range(max_len):
if valid_mask[i][j].item() == 1:
jj += 1
valid_output[i][jj] = sequence_output[i][j]
return valid_output
可以按如下方式创建输入张量:
size = ((2,5,2))
sequence_output = torch.randint(0, 250, size=size)
valid_mask = torch.randint(0, 2, size=size[:2])
我的目标基本上是“冒泡” sequence_output
的非空行。例如 sequence_output
等于:
tensor([[[ 0, 0],
[ 15, 47],
[124, 230],
[ 0, 0],
[ 65, 31]],
[[ 0, 0],
[ 0, 0],
[ 0, 0],
[139, 228],
[224, 205]]])
我正在尝试获取以下张量:
tensor([[[ 15, 47],
[124, 230],
[ 65, 31],
[ 0, 0],
[ 0, 0]],
[[139, 228],
[224, 205],
[ 0, 0],
[ 0, 0],
[ 0, 0]]])
如果有人对如何执行此操作有建议,我将不胜感激:D
我想出了一个非常糟糕的解决方案(他可能不是最优的),方法是构建一个由零和零组成的矩阵 A
,在执行矩阵乘法时将交换 X
的行。 ..
def vso(seq_out, valid_mask):
X = torch.where(valid_mask.unsqueeze(-1) == 1, seq_out, torch.zeros_like(seq_out))
bs, max_len, _ = X.shape
tu = torch.unique(torch.nonzero(X)[:, :2], dim=0)
batch_axis = tu[:, 0]
rows_axis = tu[:, 1]
a = torch.arange(bs).repeat(batch_axis.shape).reshape(batch_axis.shape[0], -1).T
T = torch.cumsum(batch_axis == a, dim=1) - 1
cols_axis = T[batch_axis, torch.arange(batch_axis.shape[0])]
A = torch.zeros((bs, max_len, max_len))
A[(batch_axis, cols_axis, rows_axis)] = 1
valid_output = torch.matmul(A, X)
return valid_output
仍在寻找更好的答案!
我在尝试将以下函数转换为仅处理张量的函数时遇到了一些问题。
def valid_sequence_output(sequence_output, valid_mask):
bs, max_len, feat_dim = sequence_output.shape
valid_output = torch.zeros(bs, max_len, feat_dim, dtype=torch.float32)
for i in range(bs):
jj = -1
for j in range(max_len):
if valid_mask[i][j].item() == 1:
jj += 1
valid_output[i][jj] = sequence_output[i][j]
return valid_output
可以按如下方式创建输入张量:
size = ((2,5,2))
sequence_output = torch.randint(0, 250, size=size)
valid_mask = torch.randint(0, 2, size=size[:2])
我的目标基本上是“冒泡” sequence_output
的非空行。例如 sequence_output
等于:
tensor([[[ 0, 0],
[ 15, 47],
[124, 230],
[ 0, 0],
[ 65, 31]],
[[ 0, 0],
[ 0, 0],
[ 0, 0],
[139, 228],
[224, 205]]])
我正在尝试获取以下张量:
tensor([[[ 15, 47],
[124, 230],
[ 65, 31],
[ 0, 0],
[ 0, 0]],
[[139, 228],
[224, 205],
[ 0, 0],
[ 0, 0],
[ 0, 0]]])
如果有人对如何执行此操作有建议,我将不胜感激:D
我想出了一个非常糟糕的解决方案(他可能不是最优的),方法是构建一个由零和零组成的矩阵 A
,在执行矩阵乘法时将交换 X
的行。 ..
def vso(seq_out, valid_mask):
X = torch.where(valid_mask.unsqueeze(-1) == 1, seq_out, torch.zeros_like(seq_out))
bs, max_len, _ = X.shape
tu = torch.unique(torch.nonzero(X)[:, :2], dim=0)
batch_axis = tu[:, 0]
rows_axis = tu[:, 1]
a = torch.arange(bs).repeat(batch_axis.shape).reshape(batch_axis.shape[0], -1).T
T = torch.cumsum(batch_axis == a, dim=1) - 1
cols_axis = T[batch_axis, torch.arange(batch_axis.shape[0])]
A = torch.zeros((bs, max_len, max_len))
A[(batch_axis, cols_axis, rows_axis)] = 1
valid_output = torch.matmul(A, X)
return valid_output
仍在寻找更好的答案!