我需要在 PyTorch 中撰寫自定義損失函式,但由于 PyTorch 與 NumPy 的相似性,基于 Numpy 的解決方案也可以作業。
我有兩個張量(Numpy 陣列)p和q形狀(b,...)。對于中的每個批處理元素,p我希望計算 . 的任何批處理元素的最小差異q。示例代碼如下:
loss = 0
for outer in range(b):
tmp_min = 1e 5
for inner in range(b):
tmp_loss = torch.abs(p[outer,...] - q[inner,...]) # np.abs(p[outer,...] - q[inner,...])
if tmp_loss<tmp_min:
tmp_min = tmp_loss
loss = loss tmp_min
由于我將不得不多次計算這個損失,有沒有辦法在沒有 FOR 和 IF 陳述句的情況下做到這一點?
最后,我希望計算這兩個方向的損失。p那么,除了重復上面的代碼并q交換之外,還有其他選擇嗎?
uj5u.com熱心網友回復:
您可以在執行以下操作時添加一個單例維度以p利用廣播p-q:(p[:, None, ...] - q[:, ...]).shape == (B, B, ...)。
它將按如下方式作業:
def loss_vec(p, q):
B = p.shape[0]
assert q.shape[0] == B
p = p.reshape(B, -1)
q = q.reshape(B, -1)
return (p[:, None, :] - q).abs().sum(axis=-1).min(axis=-1).values.sum()
def loss_op(p, q):
"""OP solution as oneliner"""
return torch.tensor([min([torch.abs(x - y).sum() for y in q]) for x in p]).sum()
B, K, M, N = 11, 3, 5, 7
p = torch.rand(B, K, M, N)
q = torch.rand(B, K, M, N)
value_op_pq = loss_op(p, q)
value_vec_pq = loss_vec(p, q)
assert value_op_pq == value_vec_pq
要在兩個方向上計算,只需axis=...在計算 時更改min:
def loss_vec_bi(p, q):
"""Returns the loss in both directions"""
B = p.shape[0]
assert q.shape[0] == B
p = p.reshape(B, -1)
q = q.reshape(B, -1)
losses = (p[:, None, :] - q).abs().sum(axis=-1)
return losses.min(axis=-1).values.sum(), losses.min(axis=0).values.sum()
value_op_qp = loss_op(q, p)
value_vec_pq, value_vec_qp = loss_vec_bi(p, q)
assert value_op_pq == value_vec_pq
assert value_op_qp == value_vec_qp
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/516061.html
標籤:Python麻木的火炬
