我正在使用LSTM处理时间序列预测问题.输入包含多个功能,因此我使用的是多变量LSTM.问题是存在一些缺失值,例如:
Feature 1 Feature 2 ... Feature n
1 2 4 nan
2 5 8 10
3 8 8 5
4 nan 7 7
5 6 nan 12
Run Code Online (Sandbox Code Playgroud)
而不是插入缺失值,这可能会在结果中引入偏差,因为有时在同一个特征上有很多连续的时间戳和缺失值,我想知道是否有办法让LSTM学习缺失值,例如,使用掩蔽层或类似的东西?有人可以向我解释一下处理这个问题的最佳方法是什么?我正在使用Tensorflow和Keras.
问题陈述
我在带有 tensorflow 后端(tf 版本 1.13.1)的 keras 中训练多对多 LSTM,用于标记文本序列,以使用预训练的 GloVe 嵌入来预测序列中每个元素的标记。我的训练方案涉及小批量随机梯度下降,每个小批量矩阵按列填充零以确保输入到网络的长度相等。
至关重要的是,由于任务和数据的性质对我的小批量进行自定义限制,我没有使用 keras 嵌入层。我的目标是为我的零填充单元实现屏蔽机制,以确保损失计算不会将这些单元虚假地视为真正的数据点。
方法
正如 keras文档中所解释的,keras 提供了三种设置掩蔽层的方法:
keras.layers.Embedding图层配置mask_zero
为True。keras.layers.Masking图层;因为我没有使用嵌入层来编码我的训练数据,所以我无法使用带有掩码嵌入层的选项 (1)。因此,我选择了 (2) 并在初始化我的模型后立即添加了一个遮罩层。然而,这种变化似乎没有产生影响。事实上,不仅我的模型的准确性没有提高,在预测阶段模型仍然产生零预测。为什么我的屏蔽层不屏蔽零填充的单元格?这是否与在我的密集层中指定 3 个类而不是 2 个(因此将 0 作为单独的类包括在内)的事实有关?
现有资源的限制
已经提出并回答了类似的问题,但我无法使用它们来解决我的问题。虽然这篇文章没有得到直接回应,但评论中提到的一个链接帖子侧重于如何预处理数据以分配掩码值,这在这里没有争议。然而,掩蔽层初始化与此处使用的相同。这篇文章提到了同样的问题 - 遮罩层对性能没有影响 - 答案以与我相同的方式定义遮罩层,但再次侧重于将特定值转换为遮罩值。最后,这篇文章中的答案提供了相同的层初始化,而无需进一步详细说明。
玩具数据生成
为了重现我的问题,我生成了一个包含两个类 (1,2) 的玩具 10 批次数据集。批是一个可变长度的序列,后填充零,最大长度为 20 个嵌入,每个嵌入向量由 5 个单元组成,因此input_shape=(20,5). 这两个类的嵌入值是从不同但部分重叠的截断正态分布生成的,从而为网络创建了一个可学习但并非微不足道的问题。我在下面包含了玩具数据,以便您可以重现该问题。
import pandas as pd
from keras.models import Sequential
from keras.layers import LSTM, …Run Code Online (Sandbox Code Playgroud)