1 回答

TA貢獻1802條經驗 獲得超10個贊
這個問題可能比你提出的問題簡單得多。如果您沿最后np.tensordot一個軸應用一對 shape 數組(w, h, 2),您將得到 shape 的結果(w, h, w, h)。這不是你想要的。這里有三種簡單的方法。除了顯示選項之外,我還展示了一些提示和技巧,可以在不更改任何基本功能的情況下使代碼更簡單:
手動進行求和縮減(使用+和*):
def average_angular_error(estimated_oc : np.ndarray, target_oc : np.ndarray):
# If you want to do in-place normalization, do x /= ... instead of x = x / ...
estimated_oc = estimated_oc / np.linalg.norm(estimated_oc, axis=-1, keepdims=True)
target_oc = target_oc / np.linalg.norm(target_oc, axis=-1, keepdims=True)
# Use plain element-wise multiplication
dots = np.sum(estimated_oc * target_oc, axis=-1)
return np.arccos(dots).mean()
使用np.matmul(aka @) 和正確廣播的維度:
def average_angular_error(estimated_oc : np.ndarray, target_oc : np.ndarray):
estimated_oc = estimated_oc / np.linalg.norm(estimated_oc, axis=-1, keepdims=True)
target_oc = target_oc / np.linalg.norm(target_oc, axis=-1, keepdims=True)
# Matrix multiplication needs two dimensions to operate on
dots = estimated_oc[..., None, :] @ target_oc[..., :, None]
return np.arccos(dots).mean()
np.matmul兩者np.dot都要求第一個數組的最后一個維度與第二個數組的倒數第二個維度匹配,就像普通矩陣乘法一樣。None是 的別名np.newaxis,它在您選擇的位置引入一個大小為 1 的新軸。在本例中,我制作了第一個數組(w, h, 1, 2)和第二個數組(w, h, 2, 1)。這確保最后兩個維度在每個相應元素處作為轉置向量和正則向量相乘。
用途np.einsum:
def average_angular_error(estimated_oc : np.ndarray, target_oc : np.ndarray):
estimated_oc = estimated_oc / np.linalg.norm(estimated_oc, axis=-1, keepdims=True)
target_oc = target_oc / np.linalg.norm(target_oc, axis=-1, keepdims=True)
# Matrix multiplication needs two dimensions to operate on
dots = np.einsum('ijk,ijk->ik', estimated_oc, target_oc)
return np.arccos(dots).mean()
您不能為此使用np.dotor 。并保留兩個數組的未更改維度,如前所述。將它們一起廣播,這就是您想要的。np.tensordotdottensordotmatmul
添加回答
舉報