如何高效对形状为(60000,1,28,28)的ndarray做矩阵L2范数归一化
问题解决:按样本自身L2范数归一化ndarray
你的问题出在np.linalg.norm的axis参数选得不对,原代码里axis=0是沿着第一个维度(60000个样本的维度)计算对应位置元素的范数,完全不是每个28×28矩阵自己的L2范数,这就导致后续除法时维度不匹配,还会出现除以0的情况,最终得到大量0和NaN。
正确的做法是指定计算范数的维度为每个样本内部的维度,同时保持维度匹配以便广播:
import numpy as np # 假设training_data是形状(60000, 1, 28, 28)的ndarray eps = 1e-8 # 防止除以0 # 计算每个样本的L2范数,axis=(1,2,3)对应每个样本的(1,28,28)维度,keepdims保持维度匹配 norms = np.linalg.norm(training_data, ord=2, axis=(1,2,3), keepdims=True) # 归一化,加上eps避免范数为0时出现NaN normalized_training_data = training_data / (norms + eps)
代码说明
axis=(1,2,3):明确告诉numpy,要对每个样本(第一个维度的每个元素)内部的所有像素值计算L2范数,这样每个样本会得到一个对应的标量范数。keepdims=True:让计算出的norms形状保持为(60000,1,1,1),和原数组(60000,1,28,28)的维度数一致,numpy就能自动完成广播除法,不需要循环。- 加入
eps:如果某个样本的所有像素值都是0,它的L2范数会是0,直接除以0会得到NaN,加一个极小值就能避免这种情况。
内容的提问来源于stack exchange,提问作者Anony mouse
相关产品推荐
相关产品推荐

