如前所述,神经网络对输入数据进行数学运算。数据的尺度和分布会显著影响网络有效学习的能力。设想一个数据集,其中包含两个特征:一个范围从 0 到 1,另一个范围从 1,000 到 100,000。在训练期间,特别是在使用基于梯度的优化方法时,值较大的特征可能不成比例地影响网络权重的更新,这可能减缓收敛速度,甚至阻止网络找到一个好的解决方案。特征缩放通过转换数据来处理这个问题,使得所有特征在学习过程中能更平均地发挥作用。两种常用的特征缩放技术是归一化(常被称为最小-最大缩放)和标准化(或 Z-分数归一化)。我们分别查看一下。归一化 (最小-最大缩放)归一化将特征重新缩放到一个固定范围,通常是 [0, 1],有时是 [-1, 1]。缩放到 [0, 1] 的公式如下:$$ x' = \frac{x - min(x)}{max(x) - min(x)} $$这里,$x$ 是原始特征值,$min(x)$ 是该特征在数据集中的最小值,$max(x)$ 是最大值。特征列中的每个值都被转换为介于0到1之间的新值 $x'$。优点:保证数据落在特定范围 ([0, 1]) 内。这对于期望输入在此范围内的算法或激活函数(如 Sigmoid)会有帮助。易于理解和实现。缺点:对异常值高度敏感。一个非常大或非常小的值可以显著地将其余数据压缩到 [0, 1] 范围内的狭窄区间,可能降低缩放的实用性。如果目标是根据特征的分布来比较它们,则它不能很好地处理变化的标准差。考虑一个特征,其值域从 10 到 110。最小值为 10,最大值为 110。值 60 将被归一化为:$(60 - 10) / (110 - 10) = 50 / 100 = 0.5$。最小值 10 变为:$(10 - 10) / (110 - 10) = 0 / 100 = 0$。最大值 110 变为:$(110 - 10) / (110 - 10) = 100 / 100 = 1$。如果出现一个异常值 1000,最大值将变为 1000。现在,值 60 归一化为 $(60 - 10) / (1000 - 10) = 50 / 990 \approx 0.05$,显著压缩了原始范围。标准化 (Z-分数归一化)标准化重新缩放特征,使其平均值 ($\mu$) 为 0,标准差 ($\sigma$) 为 1。公式如下:$$ x' = \frac{x - \mu}{\sigma} $$这里,$x$ 是原始值,$\mu$ 是特征值的平均值,$\sigma$ 是特征值的标准差。结果值 $x'$ 表示原始值 $x$ 偏离平均值的标准差数量。优点:与归一化相比,受异常值影响较小,因为它使用平均值和标准差,这本质上对极端值不如最小/最大值敏感。将数据中心化到零附近。这通常对神经网络训练中使用的梯度下降等优化算法有益。不将数据限制在特定范围,如果异常值有意义且不应过度压缩,这可能更好。缺点:不会产生有界区间内的值,这可能是某些特定算法或情况的要求(尽管对大多数神经网络层来说通常不是问题)。如果一个特征的平均值为 50,标准差为 15:值 65 将被标准化为:$(65 - 50) / 15 = 15 / 15 = 1$。(比平均值高 1 个标准差)值 35 将被标准化为:$(35 - 50) / 15 = -15 / 15 = -1$。(比平均值低 1 个标准差)平均值 50 变为:$(50 - 50) / 15 = 0 / 15 = 0$。下面的可视化图表显示了归一化和标准化对具有不同尺度的合成数据集的影响。{"layout": {"title": "特征缩放效果", "xaxis": {"title": "特征 1 (原始: 20-80)", "range": [-3, 85]}, "yaxis": {"title": "特征 2 (原始: 1千-1万)", "range": [-500, 10500]}, "hovermode": "closest", "legend": {"traceorder": "reversed"}}, "data": [{"x": [25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75], "y": [1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 5500, 6000, 9000], "mode": "markers", "type": "scatter", "name": "原始数据", "marker": {"color": "#495057", "size": 8}}]}原始数据的散点图,其中特征 1 大致范围在 20-80,特征 2 大致范围在 1千-1万。请注意轴上的不同尺度。{"layout": {"title": "特征缩放效果", "xaxis": {"title": "特征 1 (归一化后)", "range": [-0.1, 1.1]}, "yaxis": {"title": "特征 2 (归一化后)", "range": [-0.1, 1.1]}, "hovermode": "closest", "legend": {"traceorder": "reversed"}, "width": 500, "height": 500, "xaxis_domain": [0.55, 1], "yaxis_domain": [0.55, 1], "xaxis2": {"anchor": "y2", "domain": [0.0, 0.45], "title": "特征 1 (标准化后)", "range": [-2, 2]}, "yaxis2": {"anchor": "x2", "domain": [0.0, 0.45], "title": "特征 2 (标准化后)", "range": [-2, 2]}}, "data": [{"x": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 0.0], "y": [0.066, 0.133, 0.2, 0.266, 0.333, 0.4, 0.466, 0.533, 0.6, 0.0, 1.0], "xaxis": "x", "yaxis": "y", "mode": "markers", "type": "scatter", "name": "归一化 [0,1]", "marker": {"color": "#1c7ed6", "size": 8}}, {"x": [-0.86, -0.57, -0.28, 0.0, 0.28, 0.57, 0.86, 1.14, 1.43, 1.71, -1.43], "y": [-1.08, -0.86, -0.64, -0.43, -0.21, 0.0, 0.21, 0.43, 0.64, 0.86, 1.94], "xaxis": "x2", "yaxis": "y2", "mode": "markers", "type": "scatter", "name": "标准化 (Z-分数)", "marker": {"color": "#f03e3e", "size": 8}}]}归一化(右上)将数据缩放到 [0, 1] 区间,标准化(左下)将数据中心化到 (0, 0) 并使方差为 1。由于异常值的影响,相对位置略有变化。归一化与标准化之间的选择没有一个确定的答案,但这里有一些指导原则:标准化 在神经网络训练中通常更受青睐。梯度下降等技术在输入特征中心化到零且具有可比方差时,通常表现更好。它对异常值也更具鲁棒性。许多标准网络初始化和激活函数都隐式地假定输入是标准化的。归一化 可以在以下情况考虑:您需要数据严格在 [0, 1] 或 [-1, 1] 范围内,这可能是由于特定的激活函数选择(尽管像 ReLU 这样的现代激活函数敏感度较低)。您使用的算法明确要求输入在一个有界范围内。您确定没有显著的异常值,或者它们已经单独处理。在实际操作中,标准化 ($x' = \frac{x - \mu}{\sigma}$) 是为深度神经网络准备数据时更常见的选择。重要实施说明一个常见错误是在将数据集划分为训练集、验证集和测试集之前,计算整个数据集的缩放参数(最小/最大值或均值/标准差)。这会引入数据泄露,即验证集和测试集的信息影响了应用于训练集的转换,导致过于乐观的性能评估。正确的步骤是:将您的数据划分为训练集、验证集和测试集。仅 从训练集计算缩放参数($min$,$max$,$\mu$,$\sigma$)。将相同的转换(使用从训练集获得的参数)应用于训练集、验证集和测试集。这保证了在验证集和测试集上的模型评估能够反映模型在仅使用训练数据获得的知识处理后的新、未见过的数据上的表现。像 scikit-learn 这样的库提供了工具(StandardScaler、MinMaxScaler),它们通过其 fit(在训练数据上)和 transform(在所有数据分割上)方法来协助这一正确的流程。