去量纲:归一化、标准化

  • 1. 去量刚
  • 1.1 归一化(Normalization)
  • Min-Max Normalization
  • 非线性Normalization
  • 1.2 标准化(Standardlization)
  • Z-score Normalization
  • 2. 去量刚加速梯度下降收敛
  • 3. BatchNormalization、 LayerNormalizaiton
  • 3.1 BatchNormalization
  • 3.2 LayerNormalizaiton


normalization

Standardlization


对梯度的影响

1. 去量刚

去量纲化 可以消除特征之间量纲的影响,不同量纲的特征统一到一个大致相同的数值区间内;以便不同量级的指标能够进行比较和加权处理。去量纲化的好处:

(1).消除量纲引起的特征数量级对分析结果的影响,使得不同量纲之间的特征具有可比性;

(2).未归一化的特征数值太大,可能会引起数值计算的问题;

(3).利用梯度下降优化的模型,输入特征归一化处理能够加速算法的收敛过程;(线性回归,逻辑回归,支持向量机,神经网络模型)

去量纲化的方法:
两类常用的方法:归一化标准化

1.1 归一化(Normalization)

Min-Max Normalization

python如何消除量纲的影响 怎么消除量纲_数据

作用: 将原始特征数据线性映射到[0,1]
优点: 线性变换,对数据进行处理,不会改变原有数据的性质
缺点: 新数据加入,python如何消除量纲的影响 怎么消除量纲_深度学习_02可能会发生变化,所有数据需要重新进行归一化处理。

非线性Normalization

对数变换:python如何消除量纲的影响 怎么消除量纲_机器学习_03
反正切变换:python如何消除量纲的影响 怎么消除量纲_数据_04
适用情况:用于数据分化较大的场景,有些数据很大,有些数据很小 。需要依据数据分布情况,决定使用的非线性函数。

1.2 标准化(Standardlization)

Z-score Normalization

零均值标准化
python如何消除量纲的影响 怎么消除量纲_数据_05
其中:python如何消除量纲的影响 怎么消除量纲_数据_06 原始数据均值,python如何消除量纲的影响 怎么消除量纲_机器学习_07原始数据标准差 (数据量很大的情况下,这两个统计量对 加入新数据 不敏感,故可以处理新添加数据的情况);python如何消除量纲的影响 怎么消除量纲_机器学习_08

适用情况: 原始数据分布接近正态分布,将原始数据 标准化 为均值为0 ,方差为1 的分布。
优点: 线性变换,对数据进行处理,不会改变原有数据的性质

2. 去量刚加速梯度下降收敛

涉及数学知识:
1.一个三维曲面python如何消除量纲的影响 怎么消除量纲_深度学习_09被一系列平面python如何消除量纲的影响 怎么消除量纲_归一化_10所截得到一系列等值线。

2.曲面上某点P 梯度方向 定义:函数在该点增长最快的方向。
通过方向导数与python如何消除量纲的影响 怎么消除量纲_python如何消除量纲的影响_11python如何消除量纲的影响 怎么消除量纲_数据_12的关系得出函数在P点增长最快的方向为:python如何消除量纲的影响 怎么消除量纲_数据_13,即为梯度方向。

3.等值线上 P点法线方向,垂直于P点切线方向。P点切线方向python如何消除量纲的影响 怎么消除量纲_深度学习_14,斜率为python如何消除量纲的影响 怎么消除量纲_python如何消除量纲的影响_15, 由隐函数求导规则可得python如何消除量纲的影响 怎么消除量纲_深度学习_16. 则法线斜率为python如何消除量纲的影响 怎么消除量纲_数据_17,即,法线方向为python如何消除量纲的影响 怎么消除量纲_数据_13 .所以曲线上某点的梯度方向,与过该点的等值线的法线方向相同。

4.c=f(x,y)隐函数求导:(两边同时对x求导)
python如何消除量纲的影响 怎么消除量纲_python如何消除量纲的影响_19

5.相互垂直两个向量python如何消除量纲的影响 怎么消除量纲_深度学习_20,夹角python如何消除量纲的影响 怎么消除量纲_机器学习_21
内积定义垂直关系:python如何消除量纲的影响 怎么消除量纲_深度学习_22
坐标垂直关系:python如何消除量纲的影响 怎么消除量纲_python如何消除量纲的影响_23(带入python如何消除量纲的影响 怎么消除量纲_python如何消除量纲的影响_24)
两向量与x轴夹角正玄值关系:python如何消除量纲的影响 怎么消除量纲_深度学习_25


3. BatchNormalization、 LayerNormalizaiton

神经网络 训练过程实际是在 学习数据分布,如果训练数据与测试数据分布不同,那么神经网络表现出泛化能力差的问题。因此在训练开始前要保证训练数据和测试数据分布相同。

在网络前向传播的过程中,每个中间层 会改变其输出特征的分布,(从而导致一批数据的分布发生改变)(糟糕的情况下)每一层都要拟合不同的数据分布,增大了网络训练的复杂度。为了降低训练难度和减小拟合风险,就引入了不同的normalization方法。

  1. normalization 沿着数据不同的轴做(剩余的轴拉成一条轴) 就区分出 BN, LN
  2. normalization 位于每一层的输出,和下一层的输入之间。

3.1 BatchNormalization

BatchNormalization - 沿着B轴作normalization, 对一个batch内的每个样本做。

  1. step1: 在前一层的输出 和 后一层的输入之间加一层BN,这一批数据在经过 BN处理后恢复至N(0, 1)的分布(每一个特征位都是一个正态分布)
  2. step2: 之后还将重新接一个仿射变换,由可学习参数python如何消除量纲的影响 怎么消除量纲_深度学习_26python如何消除量纲的影响 怎么消除量纲_python如何消除量纲的影响_27恢复上一层输出的分布。
  3. 由于对一个batch内的每个样本做,在BN层,会维持一个均值和方差特征tensor,上一层的输出特征的每个特征位做减均值除方差的操作,均值和方差用估计量的方式增量更新。
  4. train eval 时会有差别,train 时会更新均值和方差的估计量,eval时直接使用

优点:不做BN操作,前一层网络权重 需要完美的拟合数据分布,但是引入python如何消除量纲的影响 怎么消除量纲_python如何消除量纲的影响_28python如何消除量纲的影响 怎么消除量纲_数据_29后,可以期待他们两取恢复最优的数据分布,减轻了上一层 参数任务的复杂度,从而更有利于提高模型的泛化能力。

[todo]手动实现

3.2 LayerNormalizaiton

LayerNormalization - 沿着某一特征维度作normalization,NLP 里用多用处理序列长度(句子长度不同引入的问题)
[todo]概述说明。

import torch
import torch.nn as nn

def LN_test():
    """
    @note 手动实现 LN, 深度理解LN
    """
    # for cv
    N, C, H, W = 20, 5, 10, 10
    cv_input = torch.randn(N, C, H, W)
    cv_LN = nn.LayerNorm([C, H, W])
    cv_output = cv_LN(cv_input)       # [N, C, G, W]

    # for nlp
    batch, sentence_lenth, embedding_dim = 20, 5, 10
    nlp_input = torch.randn(batch, sentence_lenth, embedding_dim)
    nlp_LN = nn.LayerNorm(embedding_dim)       # 不会说的是sentence的长度都变成1,embedding_dim是特征轴长度,每一纬 沿着sentence_lenth收集均值方差
    nlp_output = nlp_LN(nlp_input)

    # self implementation
    input_data = torch.randn(2, 2, 3, 4)
    build_in_LN = nn.LayerNorm(normalized_shape=[2, 3, 4],  elementwise_affine=False)  # 对input 后3维(len([2, 3, 4]))做ln,
    # print_module(build_in_LN, "build_in_LN")
    build_in_LN_output = build_in_LN(input_data)

    mean = torch.mean(input_data, dim=[1, 2, 3], keepdim=True)                # [2, 1, 1, 1]  后三个dime的元素全部求均值和方差了
    var = torch.var(input_data, dim=[1, 2, 3], keepdim=True, unbiased=False)  # [2, 1, 1, 1]
    self_implement_output = (input_data - mean) / (torch.sqrt(var) + build_in_LN.eps) # [2, 2, 3, 4]
    assert torch.allclose(self_implement_output, build_in_LN_output, rtol=1e-4)

    build_in_LN2 = nn.LayerNorm(normalized_shape=[3, 4],  elementwise_affine=False)  # 3 * 4 特征面面
    build_in_LN_output2 = build_in_LN2(input_data)
    mean2 = torch.mean(input_data, dim=[2, 3], keepdim=True)                # [2, 2, 1, 1] 3 * 4 特征面的均值
    var2 = torch.var(input_data, dim=[2, 3], keepdim=True, unbiased=False)  # [2, 2, 1, 1] 3 * 4 特征面方差
    self_implement_output2 = (input_data - mean2) / (torch.sqrt(var2) + build_in_LN2.eps) # [2, 2, 3, 4] 所有元素对 特征平面均值方差 做归一化。
    assert torch.allclose(self_implement_output2, build_in_LN_output2, rtol=1e-4)

Reference From:
Layer Normalization(LN) 层标准化 (为什么Transformer用LN)(手写手动实现LN)Layer Normalization 和 Batch NormalizationLayer Normalization


参考博文: 1.等值线与梯度的几何意义  2.归一化 (Normalization)、标准化 (Standardization)和中心化/零均值化 (Zero-centered)(简书)