亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在2D張量中獲取每行的top-k元素?

如何在2D張量中獲取每行的top-k元素?

拉莫斯之舞 2022-08-25 15:25:26
如何以優雅的方式在2D張量中獲取每行的前k個元素,而不是像下面那樣使用for循環?import torchelements = torch.rand(5,10)topk_list = [2,3,1,2,0] # means top2 for 1st row, top3 for 2nd row, top1 for 3rd row,....index_list = [] # record the topk index in elementsfor i in range(5):    index_list.append(elements[i].topk(topk_list[i]))
查看完整描述

2 回答

?
HUX布斯

TA貢獻1876條經驗 獲得超6個贊

如果你的 's 變化不大,并且你想對代碼進行矢量化,你可以先取每行的最大頂部,然后收集所需的結果。kk


# Code from OP

import torch


elements = torch.rand(5,10)

topk_list = [2,3,1,2,0] # means top2 for 1st row, top3 for 2nd row, top1 for 3rd row,....

index_list = [] # record the topk index in elements


for i in range(5):

    index_list.append(elements[i].topk(topk_list[i]))


# Print the result

print(index_list)


# Get topk for max_k

max_k = max(topk_list)

topk_vals, topk_inds = elements.topk(max_k, dim=-1)


# Select desired topk using mask

mask = torch.arange(max_k)[None, :] < torch.tensor(topk_list)[:, None]

vals, inds = topk_vals[mask], topk_inds[mask]

rows, _ = mask.nonzero().T

print("-" * 10)

print("rows", rows)

print("inds", inds)

print("vals", vals)


# Or split

vals_per_row = vals.split(topk_list)

inds_per_row = inds.split(topk_list)

print("-" * 10)

print("vals_per_row", vals_per_row)

print("inds_per_row", inds_per_row)


# Or zip (for loop but should be cheap)

index_list = zip(vals_per_row, inds_per_row)

print("-" * 10)

print("zipped results", list(index_list))

這將給出以下輸出:


[torch.return_types.topk(

values=tensor([0.8148, 0.7443]),

indices=tensor([8, 4])), torch.return_types.topk(

values=tensor([0.7529, 0.7352, 0.6354]),

indices=tensor([8, 1, 9])), torch.return_types.topk(

values=tensor([0.8792]),

indices=tensor([7])), torch.return_types.topk(

values=tensor([0.9626, 0.8728]),

indices=tensor([6, 2])), torch.return_types.topk(

values=tensor([]),

indices=tensor([], dtype=torch.int64))]

----------

rows tensor([0, 0, 1, 1, 1, 2, 3, 3])

inds tensor([8, 4, 8, 1, 9, 7, 6, 2])

vals tensor([0.8148, 0.7443, 0.7529, 0.7352, 0.6354, 0.8792, 0.9626, 0.8728])

----------

vals_per_row (tensor([0.8148, 0.7443]), tensor([0.7529, 0.7352, 0.6354]), tensor([0.8792]), tensor([0.9626, 0.8728]), tensor([]))

inds_per_row (tensor([8, 4]), tensor([8, 1, 9]), tensor([7]), tensor([6, 2]), tensor([], dtype=torch.int64))

----------

zipped results [(tensor([0.8148, 0.7443]), tensor([8, 4])), (tensor([0.7529, 0.7352, 0.6354]), tensor([8, 1, 9])), (tensor([0.8792]), tensor([7])), (tensor([0.9626, 0.8728]), tensor([6, 2])), (tensor([]), tensor([], dtype=torch.int64))]


查看完整回答
反對 回復 2022-08-25
?
躍然一笑

TA貢獻1826條經驗 獲得超6個贊

某件事是否優雅總是有待商榷。在 for 循環中使用固定范圍絕對可以改進,您至少可以使用,以便代碼可以重用于不同的 topk 列表。range(len(topk_list))

您可以通過使用以下命令進一步改進:

for i, n in enumerate(topk_list): 
    index_list.append(elements[i].topk(n))

甚至:

index_list = [ elements[i].topk(n) for i, n in enumerate(topk_list) ]

但這只是語法糖。


查看完整回答
反對 回復 2022-08-25
  • 2 回答
  • 0 關注
  • 103 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號