L2 在 Matlab 中归一化 3 维矩阵

L2 Normalize a 3 dimensional matrix in Matlab

在 Matlab 中,是否有一种快速规范化 3 维矩阵的每一行的方法,而无需诉诸缓慢的 for 循环?

假设我的输入数据是这样的:

d(:,:,1) =
 1     2     3
 4     5     6

d(:,:,2) =
 7     8     9
10    11    12

我知道我可以使用

获取每一行的范数
norms = sqrt(sum(d.^2,2))
norms(:,:,1) =
3.7417
8.7750

norms(:,:,2) =
13.9284
19.1050

但是现在如何用这些范数来划分二次元呢? 我知道在 2 dims 中我可以使用 ./ 但这似乎不适用于 3 维数据。

bsxfun是你的朋友:

out = bsxfun(@rdivide, d, norms);

它的作用是临时创建一个 3D 矩阵,该矩阵将 norms 的每一行复制到与 d 中一样多的列,并以元素方式划分每个元素dnorms.

我们得到:

>> d = cat(3, [1 2 3; 4 5 6], [7 8 9; 10 11 12]);
>> norms = sqrt(sum(d.^2,2));
>> out = bsxfun(@rdivide, d, norms)

out(:,:,1) =

    0.2673    0.5345    0.8018
    0.4558    0.5698    0.6838


out(:,:,2) =

    0.5026    0.5744    0.6462
    0.5234    0.5758    0.6281

我们还可以通过独立确定每一行的平方和并确保每个结果总和为 1 来验证每一行是否经过 L2 归一化:

>> sum(out.^2, 2)

ans(:,:,1) =

    1.0000
    1.0000


ans(:,:,2) =

    1.0000
    1.0000

如果 bsxfun 的方法不太合理,您可以使用的替代方法是使用 repmat 创建一个与 d 具有相同维度的矩阵。 ..然后你可以执行你想要的元素划分:

>> out = d ./ repmat(norms, [1 size(d,2) 1])

out(:,:,1) =

    0.2673    0.5345    0.8018
    0.4558    0.5698    0.6838


out(:,:,2) =

    0.5026    0.5744    0.6462
    0.5234    0.5758    0.6281

使用repmat,您可以指定要在每个维度中复制矩阵的次数。我们只希望矩阵在列上复制,而行数和切片数相同...因此向量 [1 size(d,2) 1] 指定您希望矩阵在每个维度上复制多少次。

实际上,这就是 bsxfun 在幕后所做的,您无需处理创建此临时矩阵的麻烦。此复制是为您完成的,无需您考虑。