深度学习库假设您的数据采用向量化表示。
对于变长序列预测问题,这要求您的数据经过转换,使每个序列具有相同的长度。
这种向量化允许代码高效地对您选择的深度学习算法进行批处理矩阵运算。
在本教程中,您将学习如何使用 Python 和 Keras 准备变长序列数据以解决序列预测问题。
完成本教程后,您将了解:
- 如何用虚拟值填充变长序列。
- 如何将变长序列填充到新的、更长的所需长度。
- 如何将变长序列截断到更短的所需长度。
通过我的新书《使用 Python 的长短期记忆网络》启动您的项目,包括分步教程和所有示例的Python 源代码文件。
让我们开始吧。

用于序列预测的变长输入序列的数据准备
图片由 Adam Bautz 拍摄,保留部分权利。
概述
本节分为 3 个部分;它们是
- 人为序列问题
- 序列填充
- 序列截断
环境
本教程假定您已安装 Python SciPy 环境。您可以使用 Python 2 或 3。
本教程假定您已安装 Keras (v2.0.4+),并使用 TensorFlow (v1.1.0+) 或 Theano (v0.9+) 作为后端。
本教程还假定您已安装 scikit-learn、Pandas、NumPy 和 Matplotlib。
如果您需要帮助设置 Python 环境,请参阅此帖子
人为序列问题
我们可以为了本教程的目的设计一个简单的序列问题。
问题定义为整数序列。有三个序列,长度介于 1 到 4 个时间步之间,如下所示:
1 2 3 |
1, 2, 3, 4 1, 2, 3 1 |
这些可以定义为 Python 中的列表的列表,如下所示(为便于阅读留有空格):
1 2 3 4 5 |
序列 = [ [1, 2, 3, 4], [1, 2, 3], [1] ] |
我们将在本教程中以这些序列为基础来探索序列填充。
需要 LSTM 帮助进行序列预测吗?
参加我的免费7天电子邮件课程,了解6种不同的LSTM架构(附代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
序列填充
Keras 深度学习库中的 pad_sequences() 函数可用于填充变长序列。
默认填充值为 0.0,适用于大多数应用程序,尽管可以通过“value”参数指定首选值来更改。例如:
1 |
pad_sequences(..., value=99) |
应用于序列开头或结尾的填充,称为序列前填充或序列后填充,可以通过“padding”参数指定,如下所示。
序列前填充
序列前填充是默认设置(padding='pre')。
以下示例演示了使用 0 值对 3 个输入序列进行前填充。
1 2 3 4 5 6 7 8 9 10 |
from keras.preprocessing.sequence import pad_sequences # 定义序列 sequences = [ [1, 2, 3, 4], [1, 2, 3], [1] ] # 填充序列 padded = pad_sequences(sequences) print(padded) |
运行示例会打印出用零值前置的 3 个序列。
1 2 3 |
[[1 2 3 4] [0 1 2 3] [0 0 0 1] |
序列后填充
填充也可以应用于序列的末尾,这可能更适用于某些问题领域。
可以通过将“padding”参数设置为“post”来指定序列后填充。
1 2 3 4 5 6 7 8 9 10 |
from keras.preprocessing.sequence import pad_sequences # 定义序列 sequences = [ [1, 2, 3, 4], [1, 2, 3], [1] ] # 填充序列 padded = pad_sequences(sequences, padding='post') print(padded) |
运行示例会打印出附加了零值的相同序列。
1 2 3 |
[[1 2 3 4] [1 2 3 0] [1 0 0 0]] |
填充序列到指定长度
pad_sequences() 函数还可以用于将序列填充到可能长于任何已观察序列的首选长度。
这可以通过将“maxlen”参数指定为所需长度来完成,然后将对所有序列执行填充以达到所需长度,如下所示。
1 2 3 4 5 6 7 8 9 10 |
from keras.preprocessing.sequence import pad_sequences # 定义序列 sequences = [ [1, 2, 3, 4], [1, 2, 3], [1] ] # 填充序列 padded = pad_sequences(sequences, maxlen=5) print(padded) |
运行此示例将每个序列填充到所需的 5 个时间步长,尽管观察到的序列的最大长度仅为 4 个时间步长。
1 2 3 |
[[0 1 2 3 4] [0 0 1 2 3] [0 0 0 0 1]] |
序列截断
序列的长度也可以修剪到所需的长度。
序列的所需长度可以用“maxlen”参数指定为时间步数。
序列有两种截断方式:从序列的开头或结尾移除时间步。
序列前截断
默认的截断方法是从序列的开头移除时间步。这被称为序列前截断。
以下示例将序列截断到所需长度 2。
1 2 3 4 5 6 7 8 9 10 |
from keras.preprocessing.sequence import pad_sequences # 定义序列 sequences = [ [1, 2, 3, 4], [1, 2, 3], [1] ] # 截断序列 truncated= pad_sequences(sequences, maxlen=2) print(truncated) |
运行此示例会从第一个序列中删除前两个时间步,从第二个序列中删除第一个时间步,并填充最后一个序列。
1 2 3 |
[[3 4] [2 3] [0 1]] |
序列后截断
序列也可以通过从序列末尾移除时间步来修剪。
这种方法可能对某些问题领域更可取。
可以通过将“truncating”参数从默认的“pre”更改为“post”来配置序列后截断,如下所示:
1 2 3 4 5 6 7 8 9 10 |
from keras.preprocessing.sequence import pad_sequences # 定义序列 sequences = [ [1, 2, 3, 4], [1, 2, 3], [1] ] # 截断序列 truncated= pad_sequences(sequences, maxlen=2, truncating='post') print(truncated) |
运行示例会从第一个序列中移除最后两个时间步,从第二个序列中移除最后一个时间步,然后再次填充最后一个序列。
1 2 3 |
[[1 2] [1 2] [0 1]] |
总结
在本教程中,您学习了如何准备变长序列数据以用于 Python 中的序列预测问题。
具体来说,你学到了:
- 如何用虚拟值填充变长序列。
- 如何将变长序列填充到新的所需长度。
- 如何将变长序列截断到新的所需长度。
关于准备变长序列,您有任何问题吗?
在评论中提出您的问题,我将尽力回答。
有没有不使用填充来处理各种长度序列的替代方法?
是的,有一些想法
- 您可以截断序列。
- 您可以连接序列。
- 您可以自己编写低效的 RNN 实现。
如果您知道目标长度,可以尝试插值或扭曲,对吗?但它们比简单地添加零成本更高。
好建议,汤姆!
先生,我们在这方面如何应用扭曲?
我很想知道填充如何影响模型的性能?特别是当数据集包含长文本和非常短的文本时。假设中位数长度为 30 个句子,最大长度为 120,最小长度为 10。序列前填充和序列后填充如何影响性能?
如果我没错,您通常会将长度相似的输入批量处理在一起,所以在这种情况下,您会尝试拥有多个批次,每个批次具有相同的 batch_size 和 30-120 的长度范围
填充和掩码是最好的,影响很小甚至没有影响。不过我建议进行测试。
阅读关于分桶的内容。它用于处理此类问题
如果*我
非常感谢您撰写这些教程。它们在解释其他网站经常一带而过的概念方面非常有效。我有一个关于序列到序列分类问题中填充输出的问题。假设 X 的形状是 (100, 50, 10),y 的形状是 (100, 50, 3)。X 由 100 个时间序列组成,每个时间序列有 50 个时间步,每个时间步有 10 个特征。y 每个时间步有三个可能的独热编码类别。X 的样本长度可变,因此较短的样本用 0 预填充。对于对应于预填充的 X 时间步的 y 标签,它们应该是 [0, 0, 0] 吗?或者应该为预填充的时间步创建一个新的第四个标签 [0, 0, 0, 1],从而将 y 的形状更改为 (100, 100, 4)。
谢谢,帕特里克。
如果每个序列被分类为 3 个标签之一,为什么需要填充输出?
填充可以用于连接变长特征向量吗?
填充可用于使所有独立的变长输入具有相同的长度。
嗨,汤姆,
对于具有不同标签的变长序列呢?假设我有 3 组可能的带标签特征,它们以不同的组合出现,
特征集 1:A、B、C,标签为 A
特征集 2:D、E、F、V,标签为 D
特征集 3:A、F、J、K、L,标签为 L。序列长度和标签都不同。
我该如何用序列分类来处理这个问题?
我应该使用包含该序列不同元素组合的训练/测试数据来训练每个特征集吗?
如果 A、B、C 是元素,A 是标签目标,A 是所有 3 个元素的根元素。我将创建包含 A、B、C 不同组合的训练数据,并训练 LSTM 将其分类为 A,无论序列中元素的顺序如何。
同样,我为所有特征集重复上述操作……单独训练 LSTM,因为将来,相同的元素集可能以不同的序列出现,我希望我的神经网络能正确预测根元素。
我们可以这样增量训练吗,或者有其他方法可以处理这种情况吗(我相信有的!)……如果我的问题听起来很幼稚,请原谅。
对不起,我误将您称为汤姆而不是贾森。
不客气。
将每个序列视为一个新的样本进行学习,并将所有序列填充到相同的长度。
嗨,Jason,
非常感谢您的许多有用帖子。有一个问题我找不到答案,而且我不太确定我的代码处理是否正确。也许您可以帮助我?
我的网络输入形式为 (num_samples, num_timesteps, num_features),其中 num_timesteps 可变。为了能够将所有样本输入到网络中,我用零进行预填充。所以,假设最大时间步数为 3,特征为 a 和 b,当前样本只有 2 个时间步。那么我将把 [[a1,b1],[a2,b2]] 预填充为 [[0.,0.],[a1,b1],[a2,b2]]。这样,我所有的样本都将是 (3,2) 的形状。
由于 Keras 期望输出与输入长度相同,我觉得我也需要填充输出,例如从 [[y1],[y2]] 到 [0.,[y1],[y2]]。这是正确的吗?如果正确,Keras 会忽略输出中预填充的零吗?我担心网络不会忽略它,从而试图学习与预期不同的东西。
任何帮助将不胜感激!
提前致谢 🙂
是的,听起来不错。
下一步将是尝试允许模型输出长度与模型输入长度不同的模型,例如编码器-解码器架构。我写了一些非常好的关于这个主题的帖子。
告诉我进展如何。
嗨,Jason,
我有个疑问。对于任何任务,例如句子分类,填充类型对模型性能有什么影响?
我所说的填充类型,是指将所有序列填充到最长句子的长度,以及将句子填充到其他长度(更小或更大)
您可以使用掩码输入层,它将忽略填充值。这意味着填充输入对学习没有影响。
你好,你能给我代码如何在 Keras 中添加掩码层来忽略填充值吗?谢谢。
是的,我有一些例子,可以从这里开始
https://machinelearning.org.cn/handle-missing-timesteps-sequence-prediction-problems-python/
每个批次是否可能具有不同 max_len 的序列,并且可以将其输入到 RNN?
我相信批次之间的样本数量可以不同,但批次大小将相同。
嗨 Jason,我是机器学习的初学者,我试图理解这一切。填充基本上会使数据集更加稀疏,这是真的吗?所以,我在进行预处理时应该记住这一点?
是的,但我们可以通过使用掩码层来忽略填充。
亲爱的 Jason,感谢您有趣的帖子,
我刚接触 LSTM 或 DL,我正在尝试使用 LSTM 编写一个简单的 Python POS 标记代码。我看到了不同的 LSTM 资源,包括您的帖子,对我来说似乎缺少的是如何准备一个语句(例如“John is driving his red car.”,或更短的“he is driving a car”)作为 LSTM 的输入。填充能解决 POS 标记的这些特殊问题吗?
我希望能找到一些实用的东西来阅读和测试
谢谢你
抱歉,我没有任何 POS 标注的例子。
嗨,Jason,
您能举一个例子,说明如何在用零填充后使用掩码吗?有些层内置了掩码(例如,在嵌入层中,您可以设置 mask_zero = True),但我遇到了一些层(例如 Conv1D)不支持掩码的问题。我们如何确保掩码在整个网络中发生?
谢谢!
是的,我的博客上有很多例子,但都是使用 LSTM 层,而不是 CNN。正如您所说,CNN 不支持它。
如果前端有 CNN,请尝试直接学习填充数据。
您能告诉我如何使用 word2vec 词汇表大小来训练 BILSTM 模型吗
假设您有一段文章,表示为词序列(例如,此处有 N 个词)。对于每个词,您使用 word2vec 将其转换为 M 个数字的向量。然后输入数据将是一个 MxN 矩阵。现在将其输入到 LSTM 模型中,每个输入步骤都是 M 个数字的向量。
希望这有帮助。
嗨,Jason,凭借您的这些知识,您应该获得教授而非博士学位。如果截断和填充在模型中没有给出好的结果,该怎么办?通常我用较短序列长度的数据进行训练,但预测需要更长的数据集。
也许可以探索其他问题框架,发挥创造力。
嗨,Jason,感谢您出色的教程。一个问题。假设我用固定输入大小训练网络,即 (num_samples, num_timesteps, num_features)。我可以在识别阶段只使用掩码输入层吗,因为第二个维度(例如 num_timesteps – x)是可变的?
输入维度通常是固定的。您可以掩码的是这些维度内的值。
谢谢,这很有帮助!
但是,我想知道是否/如何可以稍后计算混淆矩阵?
当较短的序列用零填充时?
这些不被错误地视为正确预测吗?
或者如果序列的某个正常元素(例如标签)实际上是零怎么办?
填充输出序列时,零值可以被评估过程忽略。
嗨,Jason,顺便说一下,您的博客很棒!
我目前正在计划一个使用时间序列数据的 LSTM。我的具体问题是有些日子没有活动,这意味着它被传统的填充技术忽略了。我想知道如何有效地处理这个问题?
提前感谢
奥利维尔
忽略没有活动的日子有什么问题?
嗨 Jason,
通过您的序列预测多对一 LSTM 帖子,我尝试使用我的数据实现模型。来自您页面的代码如下:
model = Sequential()
model.add(LSTM(5, input_shape=(5, 1)))
model.add(Dense(length))
model.compile(loss='mean_squared_error', optimizer='adam')
打印(model.summary())
如果我使用具有相同时间步数的训练和测试数据进行训练和预测,它会完美运行。
如果我想用较少的时间步进行预测,模型会抛出错误。
所以在这种情况下,我假设我需要进行序列前截断。
请确认这是否是正确和可接受的方式。
我不确定我是否理解你所改变的内容以及结果是什么。
也许你可以提供更多解释?
嗨,Jason,
如果我感兴趣于训练一个序列到序列的架构,其中输入和输出序列都是可变长度的,我是否应该在编码器和解码器层中都应用填充和掩码?如果我决定不使用掩码,我是否应该对编码器应用序列前填充,对解码器应用序列后填充?
谢谢你。
是的,使用序列后填充和输入掩码。
你好,
感谢您对LSTM的详细解释。我想知道我们是否可以在没有序列长度的情况下训练LSTM模型。
这是可能的,但在Keras中很难实现。
您能给我一些建议从哪里开始吗?或者是否有比Keras更适合的库?
谢谢你
这是一个逐步使用的模型的例子。
https://machinelearning.org.cn/develop-encoder-decoder-model-sequence-sequence-prediction-keras/
谢谢你
嗨,Jason,
我正在训练多个长度不相等的时间序列进行前向预测。我的时间序列也有可变的起始点。
关于(样本,时间步,特征),
样本:我将每个时间序列视为一个样本。
时间步:我使用最大长度作为窗口来捕获该单个时间序列的所有信息。
我的数据中已经有具有特定意义的0。因此,为了让零填充不干扰我的数据,我正在使用掩码而不是零填充。
您认为我的模型有任何问题吗?
此致,
Rick
对我来说听起来不错,Rick!
嗨,Jason,
感谢您之前的回复。
关于我上面提到的问题,我有点担心如果我将每个时间序列视为一个样本,LSTM的序列特性是否会被考虑进去。
我正在训练多个时间序列进行前向预测。
关于(样本,时间步,特征),
样本:我将每个时间序列视为一个样本。
时间步:我使用最大长度作为窗口来捕获该单个时间序列的所有信息。
假设我有4个时间序列,每个都有76个步长。因此,如果我将前75个步长作为我的X,第76个步长作为我的Y,对于训练模型,模型不会学习这75个步长的序列特性。因此,输入是(4,75,1),输出是(4,)
X Y
1 2 3 4 5 6 7 8 9 …………………………….75 (时间序列 1) 76
1 2 3 4 5 6 7 8 9 ……………………………75 (时间序列 2) 76
1 2 3 4 5 6 7 8 9 ……………………………75 (时间序列 3) 76
1 2 3 4 5 6 7 8 9 ……………………………75 (时间序列 4) 76
另一方面,如果我将一个时间序列的数据排列成以下形式:步长1预测2,步长1-2预测3,步长1-2-3预测4……然后步长1-75预测76。这考虑了时间序列的顺序特性,但现在,我不能同时将其应用于多个时间序列。我需要时间序列能够同时进行预测,并且相互泛化(如果时间序列之间存在一些普遍趋势,它们必须被模型捕获)。那么,我该怎么办?有没有办法使用简单的LSTM来实现这一点?有没有其他序列模型架构在这里效果很好?
X Y
————————————1 2
———————————1 2 3
—————————–1 2 3 4
……………………………………… ..
…………………………………….. ..
1 2 3…………………………. 75 76
此致,
Rick
一般来说,LSTM在时间序列预测方面表现不佳,所以我鼓励你尝试MLP和CNN,以及ETS和SARIMA等线性方法作为基线。
确保在将所有序列填充到相同长度时使用掩码层。
也许可以改变模型的配置,看看是否存在问题。
也许你可以使用前向验证方法并一起预测所有序列(例如多元预测)。
希望这些能作为一个开始有所帮助。
嗨,Jason,
很棒的帖子。谢谢你。
我有一个问题,我想知道是否像你提到的那样填充0是正确的方法。
我有一个包含5000多个视频的数据集,帧数从17帧到71帧不等,大小为32x48的灰度图像。如果我将所有数据填充0,使其固定大小为71*32*48,那么LSTM或CNN将不得不计算一堆0,这会耗费太多的计算资源,而且实际上没有任何作用,因为它只是填充的帧。有没有办法可以在不填充的情况下处理这些数据?或者我是否遗漏了填充的任何意义?
此致,
Lilli
你可以使用掩码层来忽略那些支持掩码的模型的填充值。
谢谢你 🙂
非常感谢您始终如一的高清晰度。一个问题:假设底层序列不是数字,而是由自然语言单词和标点符号组成。在计算长度时,应如何考虑标点符号/标记?
序列必须首先进行整数编码。我举了一些例子,也许可以从这里开始。
https://machinelearning.org.cn/start-here/#nlp
我其实有一个疑问,可能听起来很傻。为什么需要填充?我在谷歌上查到它可能对批量操作有帮助。如果是这样,我们执行哪些可能的批量操作,如果我在将输入输入神经网络之前不填充它会怎样?
你可以使用动态RNN,它不需要填充。
在训练/评估时,将所有数据放入固定大小的向量中可以更有效。
亲爱的 Jason,
再次感谢您的精彩博客。
我有一个问题,希望您能为我澄清。
我的数据框看起来像这样。
Col1 Col_2…, Col_j, Col_M
[A_11, A_12, …, A_ij,…, A_1M]
[A_21, A_22, …, A_ij,…, A_2M]
. . .
[A_N1, A_N2, …, A_ij,…, A_PM]
[B_11, B_12, …, B_ij,…, B_1M]
[B_21, B_22, …, B_ij,…, B_2M]
. . .
[B_N1, B_N2, …, B_ij,…, B_QM]
.
[C_11, C_12, …, C_ij,…, C_1M],
[C_21, C_22, …, C_ij,…, C_2M]
. . .
[C_N1, C_N2, …, C_ij,…, C_RM]
所以,样本A、B和C的长度分别为P、Q和R。其中P < Q < R。基本上,我的所有样本都有不同的长度。
所以,假设我选择六个样本的批次大小,那么后续的每个批次大小都将有不同的长度。
我该如何解决这个问题?或者
是否需要对整个数据框应用填充,以使P = Q = … = R?
所有维度都填充为固定长度,但每个维度的长度可以不同。
嗨,Jason!这篇帖子很棒!
我有一个问题!我们定义一个有50个时间步长的RNN。现在,当我们将一个长度为1的序列填充到最大长度时,RNN的输入会是什么?
它只是一个单词还是用零填充的整个序列?
是的,你可以使用掩码层来忽略这些零。
嗨,Jason,
您能提供一个使用掩码层以及如何在训练中同时实现填充和掩码的示例(代码)吗?
谢谢你
是的,博客上有很多使用掩码层的例子,请使用搜索框。
例如
https://machinelearning.org.cn/handle-missing-timesteps-sequence-prediction-problems-python/
谢谢你:) 我可以使用带有填充掩码的LSTM来处理顺序数据吗?例如,像你提到的IMDB示例那样,包含不同步长(点击)数量的会话ID的点击流数据,同时添加一些额外特征?你有没有这方面的例子?
也许可以尝试一下。
抱歉,我没有处理点击流数据的例子。
Jason,帖子很棒。我一直关注你的教程。我有30个数据点,每个数据点都有可变长度的序列,特征数为7。我想根据之前的动作预测下一个动作。在这种情况下,填充的0序列会影响预测准确性吗?
不会,你可以使用掩码层来忽略填充值。
我有一个简单的问题。我想训练一个简单的SVM模型来对音频信号进行分类。我已经使用numpy填充和切片了数据。如你所知,我们必须将数据填充到固定长度。我想问如何选择那个固定长度?如果我选择最长的向量长度作为我的标准长度,那么就会有问题,因为我的一些信号长度太短,所以会有很多零作为填充。那么这些过多的零会影响我的训练准确性吗?
我的第二个问题是,是否可以通过填充来使特征向量的长度相等,但在训练期间忽略这些填充的零。(但请记住我正在使用SVM进行分类)
也许可以尝试不同的长度,并比较它们对模型技能的影响。
有些算法可以通过掩码来实现这一点。我怀疑SVM可以,但你可能需要自己实现它。
嗨,Jason,
再次感谢这篇出色的博客。我无法理解将输入填充作为LSTM块及其架构的直接结果。如果我们不进行掩码并继续使用可变大小的输入,为什么LSTM块不能处理它,或者它可以吗?
掩码层允许在处理输入序列时跳过填充值。
你好,
感谢分享——这看起来很棒。
不过,我遇到了一些问题,错误提示是
TypeError: 稀疏矩阵长度不明确;请使用getnnz()或shape[0]
你知道如何解决这个问题,以便我仍然可以进行后填充吗?
谢谢!
也许使用稠密矩阵而不是稀疏矩阵?
嗨,Jason,
我正在为CNN准备时间序列数据,并将我的4个传感器信号窗口化为50个样本的窗口,例如每个窗口是一个50 x 4的矩阵。然而,最后一个窗口通常样本较少,例如7 x 4或21 x 4。
将额外的行填充为零以使该矩阵的维度变为50 x 4是否明智?例如,我的7 x 4样本窗口将变为50 x 4,但有43行全是零。这对于CNN输入来说仍然可以吗?或者额外的0行会以某种方式偏向训练过程吗?
是的,将所有样本用零填充到相同长度。另外,如果您的模型支持掩码层,请尝试使用掩码层来忽略填充。
在我的案例中,我有8个时间戳。每个时间戳都获得一个长度为10的特征向量。
并非所有时间戳都有数据。例如,如果是新入院患者的疾病预测,在第一小时我没有8小时的数据。因此,如果我提供时间戳1的数据并为其他7个时间戳提供7个零向量,那么BTT如何有意义,因为训练会发生。那么如何解决这个问题?
更正:我的意思是为所有其他7个时间戳提供长度为10的零向量。
您知道关于BTT证明的论文/教程链接吗?谢谢。
也许这会有帮助。
https://machinelearning.org.cn/gentle-introduction-backpropagation-time/
谢谢你的链接。我会阅读并推导出BTT。同时,你能回答我上面另一个问题吗?
在我的案例中,我有8个时间戳。每个时间戳都有一个长度为10的特征向量。目标是预测8小时内患病的可能性。即使我只有1小时的数据,我也应该能够检测出患者在8小时后是否会患病。
并非总是所有时间戳都有数据。例如,如果是新入院患者的疾病预测,在第一个小时我没有8小时的数据。因此,如果我给时间戳1提供小时1的数据,并为剩余的7个时间戳提供长度为10的零向量,那么BTT如何有意义,因为训练会发生。那么如何解决这个问题呢?
我还在训练一个时间戳为1的有状态LSTM,并使其对该患者的记录数有状态,并重置状态。例如,有一个病人有11条记录,然后我以下列方式生成数据,并在每种数据可能性场景后重置状态。[1],重置 [1,2],重置 [1,2,3]..重置.. [1,2,…11]。这种训练时间太长了。但是,你的方法会是什么?
还没有尝试使用注意力网络来解决这个问题。但是,如果我想使用通用LSTM或GRU,你的方法是什么?你能建议一下吗,谢谢?
是的,您可以使用填充或截断来确保所有样本具有相同的形状。我建议使用零填充并使用掩码层来忽略填充的特征/时间步。
我建议构建描述场景的样本,而不是跨样本学习和管理状态。这只是一个更简单的模型。
感谢你的教程!
如果我的输入样本由两个矩阵组成,并且我使用五种不同大小的样本(每个矩阵)构建训练数据集,所有样本都经过零填充(到最大尺寸,大于所有原始矩阵)。我是否需要针对每个新的输入尺寸(不包含在训练数据集中)微调我的网络?
提前感谢你
我认为不行。
感谢您的回复。我尝试在不进行微调的情况下测试新尺寸,但所有预测都为零。
但是,如果我只对输入层(使用线性激活函数)进行少量 epoch 的微调,它就能很好地工作。这可能吗?
您认为我应该使用CNN吗?
感谢您的时间。
我建议测试一系列问题框架和不同的模型,看看哪种方法最适合您的数据集。
1DCNN对序列预测非常有效。通常比LSTMs更好更快。
在训练期间更改激活函数似乎不明智。这是可能的。将权重加载到两种网络类型中并按顺序训练它们。
你好 Jason:帖子很棒。问题是:如果我有多个图像序列怎么办?LSTM的输入应该是(序列数,时间步数,特征数),对吗?在将图像序列输入LSTM模型之前,我该如何填充它们?
您可以使用CNN-LSTM,它会将图像的特征提取为向量,从而为每个时间步提供一个特征向量。
[样本,图像,特征向量]
这有帮助吗?
Jason,再次感谢您的帖子。您能否指导我如何对可变长度的“浮点”列表而不是可变长度的“整数”列表进行填充?
您可以使用相同的函数填充浮点数据。
假设你有一个25个样本的信号和另一个3个样本的信号。如果你对3个样本的信号进行填充,你实际上创建了一个几乎是零向量的东西,我不知道它对网络有什么影响。生成这样的数据真的是个好主意吗?
您可以在某些模型中使用掩码层来忽略填充值。
也许可以比较几种方法并比较结果?
嗨,Jason,
感谢您的精彩教程,它们总是对我帮助很大!
我有两个问题,一个关于填充和掩码,另一个关于可变输入长度。
问题1:假设LSTM模型的输入是一个独热编码向量,其中1和0有特定的含义。那么,使用非零值(例如-1)进行填充和掩码是否明智,以确保实际的零不会被忽略?
问题2:序列长度是模型学习的变量吗?也就是说,序列长度会影响模型的权重吗?我有一个分类问题,其中可变序列长度可能表示预测输出,但我想确保模型只学习序列中的值,而不是将序列长度作为额外的潜在影响因素。只是想知道可变序列长度是否也是模型学习的东西,并且可能会影响分类结果。
非常感谢您的帮助!
不客气。
是的,您必须使用一个不在输入中的值进行掩码。
可能不会。
嗨,Jason,
我是你的教程的忠实粉丝,感谢你的发布!
我有一个关于格式化测试数据集的问题。我已将训练数据填充为 (num_samples, num_timesteps, num_features) 的形状,以便所有样本的 num_timesteps 都是相同的。假设 num_timesteps 为 1000,那么训练数据中的每个样本长度都是 1000。我使用掩码并得到一个训练好的 LSTM。现在,测试数据样本的长度是可变的。有没有替代方法可以不将测试数据填充到 1000 个时间步长?我之所以问这个问题,是因为假设我要启动我的 LSTM,我希望在第一个 1000 个时间步长之后,在每个时间步长都运行它。本质上,我能否保持测试数据长度可变,并且仍然获得每个时间步长的预测概率?
提前感谢!
谢谢,詹姆斯。
如果我正确理解你的问题,那不太可能。
如果你使用动态 LSTM,那么就不需要填充。
谢谢。我希望不必走动态 RNN 的路线。
亲爱的 Jason,
谢谢,这很有用。但是你有什么关于如何为其特征填充序列的想法吗?
对于时间步长相同但特征大小不同的数据?
谢谢
是的,上面的例子应该直接有帮助。
抱歉再次提问,我找不到类似的例子。假设我们想将数组 (1,2) 转换为数组 (16,2)。当 LSTM 的特征大小不同时可能会发生这种情况。那么有没有为此的填充解决方案?
是的,你可以填充剩余的 15 个时间步长。
嗨,Jason!你的博客解决了我的很多问题。
我还有一个关于我计划构建的 LSTM 的问题。
想法是向神经网络输入一个 2D 张量(300 个时间步长,5 个特征)
每 300 个时间步长,我都需要将每个时间步长分类为 {0,1,2}。
t 特征 1 2 3 4 5 标签
1 0
2 0
3 1
. 1
. 0
. 2
300 2
大小是固定的,我总是会收到 300 个样本。但是,我对如何训练模型感到困惑。到目前为止,我有 (80,300,5),80 个样本,每个样本有 300 个时间步长和 5 个特征。
输入:(300,5)
输出:(300,1) –> 多标签分类
训练:(80,300,5)
我应该如何定义模型?
# 定义模型
model = Sequential()
model.add(Masking(mask_value=-1, input_shape=(300, 5)))
model.add(LSTM(5))
model.add(Dense(3))
model.compile(loss='mean_squared_error', optimizer='adam')
也许可以参考这里列出的一个教程进行调整
https://machinelearning.org.cn/start-here/#deep_learning_time_series
嗨,Jason!谢谢你的教程。
一个问题,在文本生成中,如果我用特殊值(如 0)填充了我的序列,那么这行代码中的掩码值应该是什么?
model.add(Masking(mask_value=???,input_shape=(timesteps, features)))
它应该是 0 还是 0 的独热编码向量?
如果你用零值填充,那么掩码值将是零。
嗨,Jason,
感谢你的帖子。这很有用。
我有一个问题,我想用 LSTM 做分类。在训练阶段,我知道输入的真实长度,然后我填充零值。但在预测阶段,我不知道输入的真实长度。我的意思是我不知道真实序列何时结束。
是否可以用 LSTM 来做到这一点,或者我必须知道输入的真实长度?
是的,但你可能需要将新样本截断为你预定义的固定长度。
或者你也可以尝试使用动态 LSTM。
谢谢,Jason
我将查看动态 LSTM。
不客气,祝你好运!
嗨,Jason,符号,但似乎不起作用。我想知道该如何做。
我有一个包含多行短语的文本文件,每行一个,总共有数千行。在预处理时,我想在每个短语的开头和结尾添加
list(pad_sequence(myfile,
pad_left=True, left_pad_symbol="
",",pad_right=True, right_pad_symbol="
n=2))
抱歉,我不太明白,也许你可以重新表述你的问题。
抱歉,我的错,我是 NLP 的新手
我想说的是,我有一个包含数千行或更多行的 .txt 文件,在预处理阶段,我想在每行上添加特殊的“填充”符号,例如
…….所以我想知道如何从文本文件执行此操作。大多数示例都是只用一行文本完成的,因此手动操作很容易。但在我的情况下,我有很多行,所以这并不是一个真正的选择。你可以在加载每一行时进行操作——例如,在每一行前面加上字符串,然后可以保存填充后的行以便以后重用。
谢谢!
不客气。
嗨,jason
我想知道如何在 NLTK 中训练 Ngrams(N = 1 到 3)模型。据我了解,这只是数据预处理,然后使用 nltk ngrams 库编写代码以获取 unigrams、bigrams 和 trigrams。是这样吗,还是有遗漏的部分?
抱歉,我没有关于这个主题的教程。
嗨,Jason,
我有一个形状为 (#样本, #时间步, #特征) 的数据集,我用零填充序列。我使用 BLSTM 模型进行分类任务,但在 BLSTM 层之前添加了一个 mask_value=0 的 Masking 层后,结果没有改变……
你能告诉我发生了什么以及为什么结果仍然相同吗?
model = Sequential()
model.add(Masking(input_shape=(N_FRAMES, N_FEATURES)))
model.add(Bidirectional(LSTM(512)))
model.add(Dense(5, activation=’softmax’))
也许你需要调整模型学习超参数、架构或数据准备?
嗨,Jason,
非常感谢你这篇内容丰富的文章。
我正在进行声音事件检测任务,我的测试样本长度不同。
所以我将样本进行 0 填充,使所有样本长度相同,即等于最长样本的长度。但是,我没有得到一个好的测试分数。
1) 你认为这可能是由于 0 填充造成的吗?因为样本有起始和偏移时间,0 填充后模型发现难以学习特征?
2) 你能建议一种处理可变长度样本问题的替代方法吗?
谢谢你
是的,请尝试上面提到的一些方法。
非常感谢你编写这些教程。
我想通过不同帧长的运动图像来识别摄像头的运动,但是如果输入长度通过填充统一,我将无法在用摄像头输入帧时捕捉到标准。
有什么办法吗?
嗨,Jinho……虽然我不能谈论你的具体应用,但我强烈推荐以下资源
https://machinelearning.org.cn/deep-learning-for-computer-vision/
嗨,感谢你的有用帖子。
我对我的项目感到困惑。
想象一下语音识别之类的东西。例如,我们有 32 个输入信号(这个数字是固定的),我们有 28 个类对应每个信号。
之后我们有一个 CTC 解码器来创建输出。
前 32 个信号的标签是“hello”
第二个信号的标签是“goodbye”
等等……
这些标签仅用于 CTC 损失
我应该填充它们吗?
嗨 Parisa…这个讨论可能有助于澄清
https://stackoverflow.com/questions/44579161/why-do-we-do-padding-in-nlp-tasks#:~:text=As%20in%20the%20NER%20problem,trained%20sentence%2Dby%2Dsentence.
你好 James
——我正在从文本数据中提取二元组(两个字符的序列),以进行频率分析并开发一个模型来执行语言分类
——现在,频率和相关的五分位数当然会受到文本长度的影响,文本长度在训练集和未来的评分集中都可能有所不同
——我寻找了一些正确的方法来避免文本长度的差异影响模型性能。
似乎有一种方法如下
“回想一下,对于批处理,我们需要使给定批次中的所有序列具有统一的长度(N 个单词)。
为此,我们要么
• (1) 填充比给定长度短的序列,或者
• (2) 截断比给定长度长的序列。
• 问题是,我们如何确定这个长度?我们有几个选择
我们根据训练数据的序列长度特征确定一个全局最大序列长度。“
这意味着
1. 在训练集中,在构成文本的单词 N 的分布中,确定最大值或 75% 分位数,并将其用作上限
2. 根据此值,所有长度大于此值的文本都将被截断
这种方法在我看来很合理,可以避免文本长度影响二元组分布和模型在评分集上的性能
不过,我想知道根据你在这个主题上的经验,哪种方法是最好的