可变长度输入序列的数据准备

深度学习库假设您的数据采用向量化表示。

对于变长序列预测问题,这要求您的数据经过转换,使每个序列具有相同的长度。

这种向量化允许代码高效地对您选择的深度学习算法进行批处理矩阵运算。

在本教程中,您将学习如何使用 Python 和 Keras 准备变长序列数据以解决序列预测问题。

完成本教程后,您将了解:

  • 如何用虚拟值填充变长序列。
  • 如何将变长序列填充到新的、更长的所需长度。
  • 如何将变长序列截断到更短的所需长度。

通过我的新书《使用 Python 的长短期记忆网络启动您的项目,包括分步教程和所有示例的Python 源代码文件。

让我们开始吧。

Data Preparation for Variable Length Input Sequences for Sequence Prediction

用于序列预测的变长输入序列的数据准备
图片由 Adam Bautz 拍摄,保留部分权利。

概述

本节分为 3 个部分;它们是

  1. 人为序列问题
  2. 序列填充
  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 个时间步之间,如下所示:

这些可以定义为 Python 中的列表的列表,如下所示(为便于阅读留有空格):

我们将在本教程中以这些序列为基础来探索序列填充。

需要 LSTM 帮助进行序列预测吗?

参加我的免费7天电子邮件课程,了解6种不同的LSTM架构(附代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

序列填充

Keras 深度学习库中的 pad_sequences() 函数可用于填充变长序列。

默认填充值为 0.0,适用于大多数应用程序,尽管可以通过“value”参数指定首选值来更改。例如:

应用于序列开头或结尾的填充,称为序列前填充或序列后填充,可以通过“padding”参数指定,如下所示。

序列前填充

序列前填充是默认设置(padding='pre')。

以下示例演示了使用 0 值对 3 个输入序列进行前填充。

运行示例会打印出用零值前置的 3 个序列。

序列后填充

填充也可以应用于序列的末尾,这可能更适用于某些问题领域。

可以通过将“padding”参数设置为“post”来指定序列后填充。

运行示例会打印出附加了零值的相同序列。

填充序列到指定长度

pad_sequences() 函数还可以用于将序列填充到可能长于任何已观察序列的首选长度。

这可以通过将“maxlen”参数指定为所需长度来完成,然后将对所有序列执行填充以达到所需长度,如下所示。

运行此示例将每个序列填充到所需的 5 个时间步长,尽管观察到的序列的最大长度仅为 4 个时间步长。

序列截断

序列的长度也可以修剪到所需的长度。

序列的所需长度可以用“maxlen”参数指定为时间步数。

序列有两种截断方式:从序列的开头或结尾移除时间步。

序列前截断

默认的截断方法是从序列的开头移除时间步。这被称为序列前截断。

以下示例将序列截断到所需长度 2。

运行此示例会从第一个序列中删除前两个时间步,从第二个序列中删除第一个时间步,并填充最后一个序列。

序列后截断

序列也可以通过从序列末尾移除时间步来修剪。

这种方法可能对某些问题领域更可取。

可以通过将“truncating”参数从默认的“pre”更改为“post”来配置序列后截断,如下所示:

运行示例会从第一个序列中移除最后两个时间步,从第二个序列中移除最后一个时间步,然后再次填充最后一个序列。

总结

在本教程中,您学习了如何准备变长序列数据以用于 Python 中的序列预测问题。

具体来说,你学到了:

  • 如何用虚拟值填充变长序列。
  • 如何将变长序列填充到新的所需长度。
  • 如何将变长序列截断到新的所需长度。

关于准备变长序列,您有任何问题吗?
在评论中提出您的问题,我将尽力回答。

立即开发用于序列预测的 LSTM!

Long Short-Term Memory Networks with Python

在几分钟内开发您自己的 LSTM 模型。

...只需几行python代码

在我的新电子书中探索如何实现
使用 Python 构建长短期记忆网络

它提供关于以下主题的自学教程
CNN LSTM、编码器-解码器 LSTM、生成模型、数据准备、进行预测等等...

最终将 LSTM 循环神经网络引入。
您的序列预测项目。

跳过学术理论。只看结果。

查看内容

对《变长输入序列的数据准备》的 129 条回复

  1. Yuya 2017年6月19日 上午6:46 #

    有没有不使用填充来处理各种长度序列的替代方法?

    • Jason Brownlee 2017年6月19日 上午8:49 #

      是的,有一些想法

      - 您可以截断序列。
      - 您可以连接序列。
      - 您可以自己编写低效的 RNN 实现。

    • Tom 2017年6月19日 上午10:54 #

      如果您知道目标长度,可以尝试插值或扭曲,对吗?但它们比简单地添加零成本更高。

      • Jason Brownlee 2017年6月20日 上午6:33 #

        好建议,汤姆!

      • Deepali Verma 2020年11月7日 上午3:49 #

        先生,我们在这方面如何应用扭曲?

  2. Sudipta Kar 2017年6月23日 上午7:57 #

    我很想知道填充如何影响模型的性能?特别是当数据集包含长文本和非常短的文本时。假设中位数长度为 30 个句子,最大长度为 120,最小长度为 10。序列前填充和序列后填充如何影响性能?

    • Rahul 2017年6月24日 上午3:06 #

      如果我没错,您通常会将长度相似的输入批量处理在一起,所以在这种情况下,您会尝试拥有多个批次,每个批次具有相同的 batch_size 和 30-120 的长度范围

    • Jason Brownlee 2017年6月24日 上午7:52 #

      填充和掩码是最好的,影响很小甚至没有影响。不过我建议进行测试。

    • Ayush 2018年11月25日 上午5:28 #

      阅读关于分桶的内容。它用于处理此类问题

  3. Rahul 2017年6月24日 上午3:06 #

    如果*我

  4. Patrick 2017年9月13日 下午2:11 #

    非常感谢您撰写这些教程。它们在解释其他网站经常一带而过的概念方面非常有效。我有一个关于序列到序列分类问题中填充输出的问题。假设 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)。

    • Jason Brownlee 2017年9月15日 上午11:56 #

      谢谢,帕特里克。

      如果每个序列被分类为 3 个标签之一,为什么需要填充输出?

  5. Rafiya 2017年10月23日 下午9:29 #

    填充可以用于连接变长特征向量吗?

    • Jason Brownlee 2017年10月24日 上午5:31 #

      填充可用于使所有独立的变长输入具有相同的长度。

  6. Siddharth 2017年11月17日 下午11:40 #

    嗨,汤姆,

    对于具有不同标签的变长序列呢?假设我有 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,因为将来,相同的元素集可能以不同的序列出现,我希望我的神经网络能正确预测根元素。

    我们可以这样增量训练吗,或者有其他方法可以处理这种情况吗(我相信有的!)……如果我的问题听起来很幼稚,请原谅。

    • Siddharth 2017年11月17日 下午11:41 #

      对不起,我误将您称为汤姆而不是贾森。

    • Jason Brownlee 2017年11月18日 上午10:19 #

      将每个序列视为一个新的样本进行学习,并将所有序列填充到相同的长度。

  7. Becca 2018年2月20日 上午1:34 #

    嗨,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 Brownlee 2018年2月21日 上午6:28 #

      是的,听起来不错。

      下一步将是尝试允许模型输出长度与模型输入长度不同的模型,例如编码器-解码器架构。我写了一些非常好的关于这个主题的帖子。

      告诉我进展如何。

  8. Nikhil Thakur 2018年3月28日 上午7:50 #

    嗨,Jason,

    我有个疑问。对于任何任务,例如句子分类,填充类型对模型性能有什么影响?

    我所说的填充类型,是指将所有序列填充到最长句子的长度,以及将句子填充到其他长度(更小或更大)

  9. shubham 2018年4月1日 下午11:22 #

    每个批次是否可能具有不同 max_len 的序列,并且可以将其输入到 RNN?

    • Jason Brownlee 2018年4月2日 上午5:23 #

      我相信批次之间的样本数量可以不同,但批次大小将相同。

  10. Amber 2018年4月10日 上午5:44 #

    嗨 Jason,我是机器学习的初学者,我试图理解这一切。填充基本上会使数据集更加稀疏,这是真的吗?所以,我在进行预处理时应该记住这一点?

    • Jason Brownlee 2018年4月10日 上午6:26 #

      是的,但我们可以通过使用掩码层来忽略填充。

  11. Yidnek 2018年5月22日 上午5:36 #

    亲爱的 Jason,感谢您有趣的帖子,
    我刚接触 LSTM 或 DL,我正在尝试使用 LSTM 编写一个简单的 Python POS 标记代码。我看到了不同的 LSTM 资源,包括您的帖子,对我来说似乎缺少的是如何准备一个语句(例如“John is driving his red car.”,或更短的“he is driving a car”)作为 LSTM 的输入。填充能解决 POS 标记的这些特殊问题吗?
    我希望能找到一些实用的东西来阅读和测试
    谢谢你

  12. Emily 2018年6月9日 上午3:27 #

    嗨,Jason,

    您能举一个例子,说明如何在用零填充后使用掩码吗?有些层内置了掩码(例如,在嵌入层中,您可以设置 mask_zero = True),但我遇到了一些层(例如 Conv1D)不支持掩码的问题。我们如何确保掩码在整个网络中发生?

    谢谢!

    • Jason Brownlee 2018年6月9日 上午6:56 #

      是的,我的博客上有很多例子,但都是使用 LSTM 层,而不是 CNN。正如您所说,CNN 不支持它。

      如果前端有 CNN,请尝试直接学习填充数据。

      • ruhama 2021年8月17日 下午11:37 #

        您能告诉我如何使用 word2vec 词汇表大小来训练 BILSTM 模型吗

        • Adrian Tam
          Adrian Tam 2021年8月18日 上午3:21 #

          假设您有一段文章,表示为词序列(例如,此处有 N 个词)。对于每个词,您使用 word2vec 将其转换为 M 个数字的向量。然后输入数据将是一个 MxN 矩阵。现在将其输入到 LSTM 模型中,每个输入步骤都是 M 个数字的向量。

          希望这有帮助。

  13. christian 2018年6月27日 上午6:43 #

    嗨,Jason,凭借您的这些知识,您应该获得教授而非博士学位。如果截断和填充在模型中没有给出好的结果,该怎么办?通常我用较短序列长度的数据进行训练,但预测需要更长的数据集。

    • Jason Brownlee 2018年6月27日 上午8:25 #

      也许可以探索其他问题框架,发挥创造力。

  14. giovanni 2018年7月12日 下午10:57 #

    嗨,Jason,感谢您出色的教程。一个问题。假设我用固定输入大小训练网络,即 (num_samples, num_timesteps, num_features)。我可以在识别阶段只使用掩码输入层吗,因为第二个维度(例如 num_timesteps – x)是可变的?

    • Jason Brownlee 2018年7月13日 上午7:42 #

      输入维度通常是固定的。您可以掩码的是这些维度内的值。

  15. Melina 2018年7月30日 上午1:30 #

    谢谢,这很有帮助!
    但是,我想知道是否/如何可以稍后计算混淆矩阵?
    当较短的序列用零填充时?
    这些不被错误地视为正确预测吗?
    或者如果序列的某个正常元素(例如标签)实际上是零怎么办?

    • Jason Brownlee 2018年7月30日 上午5:52 #

      填充输出序列时,零值可以被评估过程忽略。

  16. Olivier Blais 2018年8月12日 下午10:16 #

    嗨,Jason,顺便说一下,您的博客很棒!

    我目前正在计划一个使用时间序列数据的 LSTM。我的具体问题是有些日子没有活动,这意味着它被传统的填充技术忽略了。我想知道如何有效地处理这个问题?

    提前感谢
    奥利维尔

  17. Neha Sharma 2018年8月13日 下午7:31 #

    嗨 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 Brownlee 2018年8月14日 上午6:17 #

      我不确定我是否理解你所改变的内容以及结果是什么。

      也许你可以提供更多解释?

  18. Julian Arias 2018年9月22日 上午11:58 #

    嗨,Jason,

    如果我感兴趣于训练一个序列到序列的架构,其中输入和输出序列都是可变长度的,我是否应该在编码器和解码器层中都应用填充和掩码?如果我决定不使用掩码,我是否应该对编码器应用序列前填充,对解码器应用序列后填充?

    谢谢你。

  19. jack 2018年10月12日 上午6:36 #

    你好,

    感谢您对LSTM的详细解释。我想知道我们是否可以在没有序列长度的情况下训练LSTM模型。

  20. Rick 2018年10月13日 上午10:21 #

    嗨,Jason,

    我正在训练多个长度不相等的时间序列进行前向预测。我的时间序列也有可变的起始点。

    关于(样本,时间步,特征),
    样本:我将每个时间序列视为一个样本。
    时间步:我使用最大长度作为窗口来捕获该单个时间序列的所有信息。

    我的数据中已经有具有特定意义的0。因此,为了让零填充不干扰我的数据,我正在使用掩码而不是零填充。

    您认为我的模型有任何问题吗?

    此致,
    Rick

    • Jason Brownlee 2018年10月14日 上午5:58 #

      对我来说听起来不错,Rick!

      • Rick 2018年10月30日 上午1:29 #

        嗨,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

        • Jason Brownlee 2018年10月30日 上午6:07 #

          一般来说,LSTM在时间序列预测方面表现不佳,所以我鼓励你尝试MLP和CNN,以及ETS和SARIMA等线性方法作为基线。

          确保在将所有序列填充到相同长度时使用掩码层。
          也许可以改变模型的配置,看看是否存在问题。
          也许你可以使用前向验证方法并一起预测所有序列(例如多元预测)。

          希望这些能作为一个开始有所帮助。

  21. Lilli 2018年11月9日 上午12:28 #

    嗨,Jason,
    很棒的帖子。谢谢你。
    我有一个问题,我想知道是否像你提到的那样填充0是正确的方法。
    我有一个包含5000多个视频的数据集,帧数从17帧到71帧不等,大小为32x48的灰度图像。如果我将所有数据填充0,使其固定大小为71*32*48,那么LSTM或CNN将不得不计算一堆0,这会耗费太多的计算资源,而且实际上没有任何作用,因为它只是填充的帧。有没有办法可以在不填充的情况下处理这些数据?或者我是否遗漏了填充的任何意义?
    此致,
    Lilli

    • Jason Brownlee 2018年11月9日 上午5:25 #

      你可以使用掩码层来忽略那些支持掩码的模型的填充值。

      • Lilli 2018年11月22日 上午1:01 #

        谢谢你 🙂

  22. HW 2018年11月27日 上午3:08 #

    非常感谢您始终如一的高清晰度。一个问题:假设底层序列不是数字,而是由自然语言单词和标点符号组成。在计算长度时,应如何考虑标点符号/标记?

  23. Arjun 2018年12月7日 下午4:51 #

    我其实有一个疑问,可能听起来很傻。为什么需要填充?我在谷歌上查到它可能对批量操作有帮助。如果是这样,我们执行哪些可能的批量操作,如果我在将输入输入神经网络之前不填充它会怎样?

    • Jason Brownlee 2018年12月8日 上午6:59 #

      你可以使用动态RNN,它不需要填充。

      在训练/评估时,将所有数据放入固定大小的向量中可以更有效。

  24. Abey 2018年12月13日 上午1:15 #

    亲爱的 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 Brownlee 2018年12月13日 上午7:55 #

      所有维度都填充为固定长度,但每个维度的长度可以不同。

  25. aravind pai 2018年12月20日 下午9:06 #

    嗨,Jason!这篇帖子很棒!

    我有一个问题!我们定义一个有50个时间步长的RNN。现在,当我们将一个长度为1的序列填充到最大长度时,RNN的输入会是什么?

    它只是一个单词还是用零填充的整个序列?

    • Jason Brownlee 2018年12月21日 上午5:28 #

      是的,你可以使用掩码层来忽略这些零。

      • Oyku Ozlem Ozen 2021年1月21日 上午7:31 #

        嗨,Jason,

        您能提供一个使用掩码层以及如何在训练中同时实现填充和掩码的示例(代码)吗?
        谢谢你

        • Jason Brownlee 2021年1月21日 上午7:44 #

          是的,博客上有很多使用掩码层的例子,请使用搜索框。

          例如
          https://machinelearning.org.cn/handle-missing-timesteps-sequence-prediction-problems-python/

          • Oyku Ozlem Ozen 2021年1月21日 上午9:56 #

            谢谢你:) 我可以使用带有填充掩码的LSTM来处理顺序数据吗?例如,像你提到的IMDB示例那样,包含不同步长(点击)数量的会话ID的点击流数据,同时添加一些额外特征?你有没有这方面的例子?

          • Jason Brownlee 2021年1月22日 上午7:14 #

            也许可以尝试一下。

            抱歉,我没有处理点击流数据的例子。

  26. Molla Hafizur Rahman 2018年12月22日 上午8:14 #

    Jason,帖子很棒。我一直关注你的教程。我有30个数据点,每个数据点都有可变长度的序列,特征数为7。我想根据之前的动作预测下一个动作。在这种情况下,填充的0序列会影响预测准确性吗?

    • Jason Brownlee 2018年12月23日 上午6:02 #

      不会,你可以使用掩码层来忽略填充值。

  27. Hassan Ahmed 2019年5月9日 下午5:31 #

    我有一个简单的问题。我想训练一个简单的SVM模型来对音频信号进行分类。我已经使用numpy填充和切片了数据。如你所知,我们必须将数据填充到固定长度。我想问如何选择那个固定长度?如果我选择最长的向量长度作为我的标准长度,那么就会有问题,因为我的一些信号长度太短,所以会有很多零作为填充。那么这些过多的零会影响我的训练准确性吗?
    我的第二个问题是,是否可以通过填充来使特征向量的长度相等,但在训练期间忽略这些填充的零。(但请记住我正在使用SVM进行分类)

    • Jason Brownlee 2019年5月10日 上午8:14 #

      也许可以尝试不同的长度,并比较它们对模型技能的影响。

      有些算法可以通过掩码来实现这一点。我怀疑SVM可以,但你可能需要自己实现它。

  28. Rahul Krishan 2019年6月11日 下午6:39 #

    嗨,Jason,
    再次感谢这篇出色的博客。我无法理解将输入填充作为LSTM块及其架构的直接结果。如果我们不进行掩码并继续使用可变大小的输入,为什么LSTM块不能处理它,或者它可以吗?

    • Jason Brownlee 2019年6月12日 上午7:54 #

      掩码层允许在处理输入序列时跳过填充值。

  29. Catriona 2019年6月12日 上午12:31 #

    你好,
    感谢分享——这看起来很棒。

    不过,我遇到了一些问题,错误提示是

    TypeError: 稀疏矩阵长度不明确;请使用getnnz()或shape[0]

    你知道如何解决这个问题,以便我仍然可以进行后填充吗?

    谢谢!

  30. Carlos 2019年8月16日 下午7:31 #

    嗨,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行会以某种方式偏向训练过程吗?

    • Jason Brownlee 2019年8月17日 上午5:35 #

      是的,将所有样本用零填充到相同长度。另外,如果您的模型支持掩码层,请尝试使用掩码层来忽略填充。

  31. naren 2019年8月23日 下午1:05 #

    在我的案例中,我有8个时间戳。每个时间戳都获得一个长度为10的特征向量。
    并非所有时间戳都有数据。例如,如果是新入院患者的疾病预测,在第一小时我没有8小时的数据。因此,如果我提供时间戳1的数据并为其他7个时间戳提供7个零向量,那么BTT如何有意义,因为训练会发生。那么如何解决这个问题?

    • Naren 2019年8月23日 下午1:08 #

      更正:我的意思是为所有其他7个时间戳提供长度为10的零向量。

      您知道关于BTT证明的论文/教程链接吗?谢谢。

        • naren 2019年8月23日 下午2:53 #

          谢谢你的链接。我会阅读并推导出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,你的方法是什么?你能建议一下吗,谢谢?

          • Jason Brownlee 2019年8月24日 上午7:44 #

            是的,您可以使用填充或截断来确保所有样本具有相同的形状。我建议使用零填充并使用掩码层来忽略填充的特征/时间步。

            我建议构建描述场景的样本,而不是跨样本学习和管理状态。这只是一个更简单的模型。

  32. Rana 2019年10月20日 下午5:57 #

    感谢你的教程!

    如果我的输入样本由两个矩阵组成,并且我使用五种不同大小的样本(每个矩阵)构建训练数据集,所有样本都经过零填充(到最大尺寸,大于所有原始矩阵)。我是否需要针对每个新的输入尺寸(不包含在训练数据集中)微调我的网络?

    提前感谢你

    • Jason Brownlee 2019年10月21日 上午6:15 #

      我认为不行。

      • Rana 2019年10月24日 下午5:27 #

        感谢您的回复。我尝试在不进行微调的情况下测试新尺寸,但所有预测都为零。

        但是,如果我只对输入层(使用线性激活函数)进行少量 epoch 的微调,它就能很好地工作。这可能吗?

        您认为我应该使用CNN吗?

        感谢您的时间。

        • Jason Brownlee 2019年10月25日 上午6:37 #

          我建议测试一系列问题框架和不同的模型,看看哪种方法最适合您的数据集。

          1DCNN对序列预测非常有效。通常比LSTMs更好更快。

          在训练期间更改激活函数似乎不明智。这是可能的。将权重加载到两种网络类型中并按顺序训练它们。

  33. George 2019年10月24日 上午6:54 #

    你好 Jason:帖子很棒。问题是:如果我有多个图像序列怎么办?LSTM的输入应该是(序列数,时间步数,特征数),对吗?在将图像序列输入LSTM模型之前,我该如何填充它们?

    • Jason Brownlee 2019年10月24日 下午2:01 #

      您可以使用CNN-LSTM,它会将图像的特征提取为向量,从而为每个时间步提供一个特征向量。

      [样本,图像,特征向量]

      这有帮助吗?

  34. Siraj Ahmed 2019年11月8日 下午8:53 #

    Jason,再次感谢您的帖子。您能否指导我如何对可变长度的“浮点”列表而不是可变长度的“整数”列表进行填充?

    • Jason Brownlee 2019年11月9日 上午6:12 #

      您可以使用相同的函数填充浮点数据。

  35. Ahmet Cihat 2019年11月29日 下午7:43 #

    假设你有一个25个样本的信号和另一个3个样本的信号。如果你对3个样本的信号进行填充,你实际上创建了一个几乎是零向量的东西,我不知道它对网络有什么影响。生成这样的数据真的是个好主意吗?

    • Jason Brownlee 2019年11月30日 上午6:29 #

      您可以在某些模型中使用掩码层来忽略填充值。

      也许可以比较几种方法并比较结果?

  36. Fiorella 2019年12月13日 上午10:46 #

    嗨,Jason,

    感谢您的精彩教程,它们总是对我帮助很大!
    我有两个问题,一个关于填充和掩码,另一个关于可变输入长度。

    问题1:假设LSTM模型的输入是一个独热编码向量,其中1和0有特定的含义。那么,使用非零值(例如-1)进行填充和掩码是否明智,以确保实际的零不会被忽略?

    问题2:序列长度是模型学习的变量吗?也就是说,序列长度会影响模型的权重吗?我有一个分类问题,其中可变序列长度可能表示预测输出,但我想确保模型只学习序列中的值,而不是将序列长度作为额外的潜在影响因素。只是想知道可变序列长度是否也是模型学习的东西,并且可能会影响分类结果。

    非常感谢您的帮助!

    • Jason Brownlee 2019年12月13日 下午1:43 #

      不客气。

      是的,您必须使用一个不在输入中的值进行掩码。

      可能不会。

  37. James 2020年1月15日 上午2:50 #

    嗨,Jason,

    我是你的教程的忠实粉丝,感谢你的发布!

    我有一个关于格式化测试数据集的问题。我已将训练数据填充为 (num_samples, num_timesteps, num_features) 的形状,以便所有样本的 num_timesteps 都是相同的。假设 num_timesteps 为 1000,那么训练数据中的每个样本长度都是 1000。我使用掩码并得到一个训练好的 LSTM。现在,测试数据样本的长度是可变的。有没有替代方法可以不将测试数据填充到 1000 个时间步长?我之所以问这个问题,是因为假设我要启动我的 LSTM,我希望在第一个 1000 个时间步长之后,在每个时间步长都运行它。本质上,我能否保持测试数据长度可变,并且仍然获得每个时间步长的预测概率?

    提前感谢!

    • Jason Brownlee 2020 年 1 月 15 日上午 8:29 #

      谢谢,詹姆斯。

      如果我正确理解你的问题,那不太可能。

      如果你使用动态 LSTM,那么就不需要填充。

      • James 2020 年 1 月 16 日上午 6:08 #

        谢谢。我希望不必走动态 RNN 的路线。

  38. Jam 2020 年 4 月 8 日上午 1:58 #

    亲爱的 Jason,
    谢谢,这很有用。但是你有什么关于如何为其特征填充序列的想法吗?
    对于时间步长相同但特征大小不同的数据?
    谢谢

    • Jason Brownlee 2020 年 4 月 8 日上午 7:57 #

      是的,上面的例子应该直接有帮助。

      • Jam 2020 年 4 月 26 日晚上 8:41 #

        抱歉再次提问,我找不到类似的例子。假设我们想将数组 (1,2) 转换为数组 (16,2)。当 LSTM 的特征大小不同时可能会发生这种情况。那么有没有为此的填充解决方案?

        • Jason Brownlee 2020 年 4 月 27 日上午 5:33 #

          是的,你可以填充剩余的 15 个时间步长。

  39. Mariana 2020 年 4 月 10 日上午 4:55 #

    嗨,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')

  40. Hai Yisha 2020 年 6 月 15 日下午 2:51 #

    嗨,Jason!谢谢你的教程。
    一个问题,在文本生成中,如果我用特殊值(如 0)填充了我的序列,那么这行代码中的掩码值应该是什么?

    model.add(Masking(mask_value=???,input_shape=(timesteps, features)))

    它应该是 0 还是 0 的独热编码向量?

    • Jason Brownlee 2020 年 6 月 16 日上午 5:32 #

      如果你用零值填充,那么掩码值将是零。

  41. Will Lxg 2020 年 6 月 27 日上午 5:34 #

    嗨,Jason,

    感谢你的帖子。这很有用。

    我有一个问题,我想用 LSTM 做分类。在训练阶段,我知道输入的真实长度,然后我填充零值。但在预测阶段,我不知道输入的真实长度。我的意思是我不知道真实序列何时结束。

    是否可以用 LSTM 来做到这一点,或者我必须知道输入的真实长度?

    • Jason Brownlee 2020 年 6 月 27 日上午 5:36 #

      是的,但你可能需要将新样本截断为你预定义的固定长度。

      或者你也可以尝试使用动态 LSTM。

  42. Will Lxg 2020 年 6 月 28 日下午 2:31 #

    谢谢,Jason

    我将查看动态 LSTM。

  43. Moctar 2020 年 10 月 2 日晚上 9:04 #

    嗨,Jason,
    我有一个包含多行短语的文本文件,每行一个,总共有数千行。在预处理时,我想在每个短语的开头和结尾添加 符号,但似乎不起作用。我想知道该如何做。

    list(pad_sequence(myfile,
    pad_left=True, left_pad_symbol="",
    pad_right=True, right_pad_symbol="
    ",
    n=2))

    • Jason Brownlee 2020 年 10 月 3 日上午 6:06 #

      抱歉,我不太明白,也许你可以重新表述你的问题。

      • Moctar 2020 年 10 月 3 日下午 12:18 #

        抱歉,我的错,我是 NLP 的新手
        我想说的是,我有一个包含数千行或更多行的 .txt 文件,在预处理阶段,我想在每行上添加特殊的“填充”符号,例如 ……. 所以我想知道如何从文本文件执行此操作。大多数示例都是只用一行文本完成的,因此手动操作很容易。但在我的情况下,我有很多行,所以这并不是一个真正的选择。

        • Jason Brownlee 2020 年 10 月 3 日下午 12:31 #

          你可以在加载每一行时进行操作——例如,在每一行前面加上字符串,然后可以保存填充后的行以便以后重用。

          • Moctar 2020 年 10 月 3 日下午 1:14 #

            谢谢!

          • Jason Brownlee 2020 年 10 月 4 日上午 6:48 #

            不客气。

  44. Moctar 2020 年 10 月 4 日下午 2:13 #

    嗨,jason
    我想知道如何在 NLTK 中训练 Ngrams(N = 1 到 3)模型。据我了解,这只是数据预处理,然后使用 nltk ngrams 库编写代码以获取 unigrams、bigrams 和 trigrams。是这样吗,还是有遗漏的部分?

    • Jason Brownlee 2020 年 10 月 4 日下午 2:59 #

      抱歉,我没有关于这个主题的教程。

  45. ali 2021 年 5 月 19 日晚上 9:26 #

    嗨,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 Brownlee 2021 年 5 月 20 日上午 5:47 #

      也许你需要调整模型学习超参数、架构或数据准备?

  46. Skyler 2021 年 8 月 4 日晚上 10:45 #

    嗨,Jason,
    非常感谢你这篇内容丰富的文章。
    我正在进行声音事件检测任务,我的测试样本长度不同。
    所以我将样本进行 0 填充,使所有样本长度相同,即等于最长样本的长度。但是,我没有得到一个好的测试分数。
    1) 你认为这可能是由于 0 填充造成的吗?因为样本有起始和偏移时间,0 填充后模型发现难以学习特征?
    2) 你能建议一种处理可变长度样本问题的替代方法吗?

    谢谢你

    • Jason Brownlee 2021 年 8 月 5 日上午 5:18 #

      是的,请尝试上面提到的一些方法。

  47. Jinho Ko 2022 年 1 月 14 日晚上 9:58 #

    非常感谢你编写这些教程。

    我想通过不同帧长的运动图像来识别摄像头的运动,但是如果输入长度通过填充统一,我将无法在用摄像头输入帧时捕捉到标准。

    有什么办法吗?

  48. parisa 2022 年 3 月 8 日晚上 8:02 #

    嗨,感谢你的有用帖子。
    我对我的项目感到困惑。
    想象一下语音识别之类的东西。例如,我们有 32 个输入信号(这个数字是固定的),我们有 28 个类对应每个信号。
    之后我们有一个 CTC 解码器来创建输出。
    前 32 个信号的标签是“hello”
    第二个信号的标签是“goodbye”
    等等……
    这些标签仅用于 CTC 损失
    我应该填充它们吗?

  49. dave 2022 年 9 月 14 日上午 12:01 #

    你好 James

    ——我正在从文本数据中提取二元组(两个字符的序列),以进行频率分析并开发一个模型来执行语言分类

    ——现在,频率和相关的五分位数当然会受到文本长度的影响,文本长度在训练集和未来的评分集中都可能有所不同

    ——我寻找了一些正确的方法来避免文本长度的差异影响模型性能。

    似乎有一种方法如下

    “回想一下,对于批处理,我们需要使给定批次中的所有序列具有统一的长度(N 个单词)。

    为此,我们要么

    • (1) 填充比给定长度短的序列,或者

    • (2) 截断比给定长度长的序列。

    • 问题是,我们如何确定这个长度?我们有几个选择

    我们根据训练数据的序列长度特征确定一个全局最大序列长度。“

    这意味着

    1. 在训练集中,在构成文本的单词 N 的分布中,确定最大值或 75% 分位数,并将其用作上限
    2. 根据此值,所有长度大于此值的文本都将被截断

    这种方法在我看来很合理,可以避免文本长度影响二元组分布和模型在评分集上的性能

    不过,我想知道根据你在这个主题上的经验,哪种方法是最好的

发表回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。