遇见问题
在用keras实现对某数据利用LSTM做时间序列回归的任务时,若loss出现以下情况:
注意其loss(此处用mean square error作为loss function)在很大的时候就收敛了,且预测值出现下面的情况:
问题解决——属性标准化attribute normalization或scaling
对输入数据进行特征标准化,即将输入数据的每个数据的均值变为0,方差变为1。可使用sklearn.preprocessing.scale(或直接减均值除标准差),设数据集样本数为n,每个样本维度(属性个数)为dim,train_x.shape=(n=2,dim=5),则代码如下:
from sklearn.preporcessing import scale
train_x = preprocessing.scale(train_x,axis=0)
print(train_x.mean(axis=0),train_x.mean(axis=0))
print(train_x.var(axis=0),train_x.var(axis=0))
输出为
[1.00981526e-16 3.12124716e-16 1.28521942e-16 -5.50808322e-17 -1.74422635e-16] 5 //都为非常接近0的值
[1. 1. 1. 1. 1.] 5
若train_x.shape为(dim,n)则上面代码中axis=0。其它设置不变,在进行运算可以得到loss以及预测值情况:
可以看到loss在更低处收敛且预测效果不再为常数。
这一部分的参考:
[1]https://github.com/keras-team/keras/issues/1727
[2]https://www.cnblogs.com/chaosimple/p/4153167.html
简单说说原理
目前本人有下面两种理解:
一、与输入数据的属性之间的数量级有关。scale可以将量级差过于大的伸缩到合适的分布,使得模型在训练时权重更加容易和稳定地学习。设一数据样本x=[attribute1,attribute2]=[[0.1,300],[0.2,200],[0.3,100]],当计算最简单的线性回归时,以x0=[0.1,300]为例:
由于在训练中会更新权重,这样 部分在 稍微改变时就会对 值产生很大影响,故 几乎受 支配,这样对 不公平,因此要将attribute1和attribute2的数量级进行缩放,让他们都在大小相当的范围内,这样可以让各个特征对结果做出的贡献相同。以此提高模型收敛速度和精度尤其“涉及到一些距离计算的算法时效果显著,比如算法要计算欧氏距离”[2]。
二、在除以标准差时若数据原本太过集中,会将数据拉伸,例如我的数据(blue for raw data, red for scaled data):
这样增大了特征间的标准差,特征之间差异也更加明显。
故可以总结这个标准化将数量级过小过大的缩放到合适范围从而提升模型训练速度和精度。
这一部分的参考:
[1]推荐这个视频,可以简单直观的理解“为什么要特征标准化?”
https://morvanzhou.github.io/tutorials/machine-learning/ML-intro/3-02-normalization/
[2]原理
http://www.cnblogs.com/ooon/p/4947347.html
下面的关键词可能对你有帮助:
Feature Scaling,Feature Normalization, Normalization, Standardization, Feature Standardization(UFLDL).
如有错误欢迎指正!