如h=ax+by+c,x在0到1之间,y在1000到5000之间。
不进行归一化,代价函数等值线图会非常扁;进行归一化后,代价函数等值线图会向圆趋近。
对于偏圆的而言,对它进行梯度下降的迭代次数比偏扁的那个迭代次数要少很多,这个很好理解,让人困惑的是,缩放前后,代价函数不是变了吗,最后收敛的参数不也变了吗,怎么就正确了?
其实,我们完全可以将缩放前后的训练集理解成两个训练集。对这两个训练集的梯度下降当然是不同的,但确实是有联系的。
缩放前,输入原始x、原始y、原始正确结果,通过梯度下降,去拟合原始正确结果,得到假设函数h,而通过h,我们就可以再通过输入原始x原始y得到"正确的"预测结果。
缩放后,输入原始x、线性变化后的y、原始正确结果,通过梯度下降,同样是去拟合原始正确结果,得到假设函数h。不同的在于,不能再用原始x原始y作为特征传入h得到"正确的"预测结果,原始xy必须通过同样的线性变换(原始x线性变换后y),即与缩放后的h函数的训练样本同质,这样再传入进h,才可得到"正确的"预测结果。
讲到这,我们来具体解释,为何缩放后能更快收敛成功,而缩放前要迭代更多次才能收敛成功,我认为关键在于a与b对学习率alpha的要求不同。
缩放前,由于y量纲特别大,导致代价函数j对b十分敏感,这要求alpha特别小,否则就可能无法收敛甚至发散。而与此同时,j对a不那么敏感,这就使得a要求alpha稍微大些,不然收敛速度太慢。而由于a与b对所要求的alpha冲突,只能遵循一个,那就只能alpha选得特别小,慢点就慢点吧,不然b无法收敛。
我们观察缩放前ab在j等值线图上的移动。它会先是在b方向上迅速收敛,与此同时,a在慢慢收敛;当b收敛后,已经满足b的迭代退出要求了,可它要等待a收敛完毕,只有ab都收敛了才可退出梯度下降算法。这就使得b收敛后要等待a收敛,a在慢慢收敛时,b的偏导一直在正负变化,即b一直在一个区间内不停波动,直到a收敛后,退出迭代。
我认为,b在等待a收敛时的这种波动是无法通过再调小alpha来消除的,因为alpha调小后,b的步子是变小了,但a的步子同样会小,最终b还是会大幅度领先a达到收敛,然后要更长时间的等待a收敛。调小alpha,不会消除波动本身,而是让波动幅度减小,频率更高,要波动更多次才能退出迭代。
而为何缩放后,就能更快的退出迭代呢?因为我们让xy处于同一个量纲后,ab对alpha的要求就相近了。我们对y进行y=(y-y.mean)/y.std,使得j对b不那么敏感了,其实也就是在b方向上拉宽了等值线图,使得等值线图趋于圆。由于不那么敏感了,我们就能选择更大的alpha而不会使得b发散,且ab都会在差不多的迭代次数后达到收敛,整个梯度下降过程会更快。
缩放前后收敛点(a1、b1)与(a2、b2)是不同的,但由于本例只是在b的方向上拉宽j等值图,所以a1应该是与a2相等的,而b1与b2的关系接近于b2=b1*y.std,确实是在b方向上拉宽了(我自己试的)。