大白话 5 分钟带你走进人工智能 - 第十节梯度下降之归一化的各种方式和必要性 (5)

第十节梯度下降之归一化的各种方式和必要性 (5)

上一节中我们讲解了梯度下降的函数最优化算法和梯度下降代码过程,了解了梯度下降的代码实现过程,本节的话我们讲解一个梯度下降之前必要的数据准备,归一化。

先看一个例子,假如你收集到一个数据集,一列是年龄,一列是身高(厘米)。比如体重的数据都是 60,65。身高的数据是 180,185,你发现它的量纲远远大于 age,这样会导致什么?比如身高是 W2,体重是 W1,假如要根据这些数据预测寿命,比如结果是这样的:

体重身高预测年龄
6018070
6518580

因为最后它们相乘相加等于你预测的年龄,那么对数据本身来说量纲比较小的数字,它会乘的 W 比较大一些。因为体重乘上比较小的数字 w1+ 身高乘以比较大的数字 w2,才能等于最后的年龄。这么想好像没什么问题,相当于程序给我们把数据自动修正了,身高数据大,我就自动 W 小点,预测也不会出问题,虽然看起来没问题,但它在梯度下降的效率上会导致一定的问题。会导致一个什么问题呢? 比如 W2 小,它越小,是不是越灵敏相当,那么 W2 动一点就会怎么样?我们先看下上面数据训练模型时如果 不做归一化的损失函数的等高线 如图:

20190318203941223.png

等高线里面,每一个圆的损失函数是一样的 。在这个例子里面,你觉得θ1(即 w1)和θ2(即 w2),谁是 age 谁是 height?实际上θ2 是 height,θ1 是 age,为什么?因为 W2 是不是小,你动一点点,损失函数会变化的很多,所以图中θ2 一点点变化,损失函数就会从一个圆变到另一个圆,所以θ2 对应着身高前面的参数。那么这会导致什么问题?我们看下图中的θ1(即 w1)和θ2(即 w2) 的更新参数:

gif-(1).gif

\frac{\partial J(\theta)}{\theta_{j}}=(h_\theta(x)-y)x_{j}

无论对于 W1 来说还是 W2 来说,(h_\theta(x)-y)x_{j}前边部分有区别吗? 没区别吧?那么体现在更新 W1 和 W2 的更新的不同,是 Xj 不同。在θ2 的方向上,因为 X2 比较大,所以θ2 方向每次加的都很大,而θ1 方向每次加的又比较小,假如最开始在初始点那块,θ2 距离自己的终点也就是最后的最优解的点其实很近,而θ1 距离自己的终点很远,按理说θ1 应该赶紧紧跑两步对不对?而现在变成了θ2 在反复的震荡,而θ1 在不着急得一步一步走,这样的话会导致你的计算效率变得特别慢。梯度下降的过程中,你 想让 W2 是不是每一步更新更加细致一点,更微小一点,更精准一点,让 W1 每一步更大刀阔斧一点 ?所以如果量纲不一致,会导致本来需要一步一步慢慢走的这个维度 W2,反倒震荡的特别厉害。W1 想让它变化快一点,但 X1 比较小,会导致它下降的速度反倒慢了,适得其反。讲到这里,有的人会说我调控每一步下降的gif-(1).gif
中的α,也就是我们的λ, 是不是可以控制下每次减的幅度?这里想让大家想一个问题,λ是只有一个数还是说每个维度各有一个λ?如果每个维度各有一个λ就没这问题了,你自己单独的给它们调一下就行了,但是调参又变得复杂了,你有一千个维度,难道你还要手工设一千个λ,还要细致地调吗?不现实。这数根源就是因为只有一个λ管着我所有的 W,那么需要大的反倒小了,小的反倒大了。 所以我们怎么办?

我们就需要对数据进行一个归一化。比如我原来原始数据身高是 180,170,160,150,我做一个最大最小值归一化,最大最小值归一化公式是:

x^{\prime}=\frac{x-\min (x)}{\max (x)-\min (x)}

我用 X 减去最小的 X,除以 (最大的 X,减去最小的 X),假设这四个数,180,170,160,150。那么此时 180 会变成什么?你们根据这算一下。180 变成 1 了,150 变成什么了?0 了,中间是 0 到 1 的一些数相当于就把所有列,如果你都执行这么一遍的话,是不是就变成了所有数都在 0 到 1 之间了。这样他们的量纲就一样了。这样我们的损失函数就会从一个椭圆特别椭的圆变成一个比较圆的圆。如下面一样:

20190406171856702.png

因为各个维度的数值通过最大最小值归一化之后会让它两边的步伐速度是一致的,不会存在谁等谁的情况,所以损失函数等高线的图就近似一个相对比较圆的圆。这样会带来更快的收敛步数和更快的收敛速度。除此之外,归一化还有什么好处?对 one-hot 编码来说,有的维度转变成 one-hot 编码,比如 性别转成 one-hot 之后男的是 0-1 女的是 1-0两个维度标识性别 ,这样相对公平,不至于男的性别是 1 ,女的性别是 0,这样会给机器学习一种错误的输入,男的比女的大的错误信息,因此需要转成 one-hot 编码。但假如有的没转成 one-hot 编码,比如身高,没转 one_hot 编码的这些维度如果经过最大最小值归一化都给它缩放到零和一之间后,这样跟经过 one-hot 编码的那些维度的量纲也都一致了,在训练模型的时候,经过处理过的训练集就是一堆你看不懂的数了,比如身高它就不再代表实际物理意义上的高度有多高了,但它是一个高度的评分,越近越 1 越代表你在这里边越高。例如 170 和 160, 经过最大值最小值归一化之后,肯定 170 更接近数值 1。

那么当 预测一条新数据 的时候,怎么预测? 你还能把原始数据直接丢进去算吗?你是不是需要对新的数据要做最大最小值归一化,用谁的最大值?谁的最小值?用你的 训练集中的最大值和训练集中的最小值做归一化,我们称它为经验最大值和经验最小值 。好在这些事情不需要你来手工处理,只要你把 normalize=true,就可以了。

 lin_reg = LinearRegression(normalize=True)

这一切的一切底层就帮你做好了。 它做的不光是最大最小值归一化,它还要做零均值化 ,它要把每一个 X 都减去这一列的平均值。为什么要这么做?比如看下面的例子:

20190318203941223.png

假如你随机到图中这个点了,再接着往下,θ1 需要增大减小?增大,对吧?θ2 需要增大还是减小? 减小。所以θ1 需要增大,θ2 需要减小,但θ1 和θ2 怎么算的?咱们看随机梯度下降,对于θ1 也好,θ2 也好,(h_\theta(x)-y)x_{j}(h_\theta(x)-y)这一项都一样,能影响它到底增大还是减小,是不是取决于它 Xj? 所以对于θ1 就把 X1 带进去,对于θ2 就把 X2 代进去。通常训练集里的数据是不是都是正数?如果你不做零均值化的话,所有 X 都是正数,是不是所有的θ要增都增要减都减。对于这个例子,要想走到最优解,应该这样走,如图:

20190406171856702.png

如果不去处理归一化的话,这会只能θ1 也增θ2 也增, 第一步θ2 先少增一点,尽量等一下θ1,θ1 多走点, 甚至走过θ1 的最优值,然后,θ1 减,θ2 也减才能走到最后最优解的那个点,它不具备同时一个参数增另一个参数减的这么一个功能。但假如你对它做一个零均值化,比如第二列 X2,1.8 米,1.7 米,1.6 米,1.5 米,都减去均值后,这就变成了 +1.5,+0.5,-0.5,-1.5,这会 X 是不是就有正有负了?有正有负了之后,是不是它就有可能进行这种有的增有的减的这种下降?所以说 normalize 里面至少会同时做最大最小值归一化来保证量纲一样和零均值化让所有的维度数值有大有小,这样才能获得更好的梯度下降效率。 如果你不做这些也能得到最优解,就是人家走 10 步你可能走 15 步这么一个概念,它效率更低,做了这个能够帮助你下降的更快,更好的找到这个结果。那么来一条新数据,是不是也得减去平均值,减谁的平均值?减你训练集里边的算出来平均值,能理解吗?这个也叫 经验平均值。 经验平均值这个东西在深度学习里面一样要这么处理。只要用到梯度下降,就都需要这么处理。只要有梯度下降,均值归一化是必须的,没有均值归一化的话,它下降速率一定会慢好多,因为它老要走曲折的弯路。

对于有些算法,还会使用 方差均值标准化来调整数据使模型训练拥有更好的性能。 即:

x^{\prime}=\frac{x-\overline{x}}{\sigma}

所以归一化方式是进行模型训练前的必要步骤,也是数据处理的关键步骤。下面一节我们将手动实现批量梯度下降和随机梯下降的方式,不调 sklearn 里面的 api