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
添加回答
举报