【问题标题】:How model a 1D CNN + LSTM network where each time-step is a set of 1D arrays?如何对每个时间步长都是一组一维数组的一维 CNN + LSTM 网络进行建模?
【发布时间】:2019-07-03 00:08:53
【问题描述】:

我正在尝试使用一组 1D CNN 和 LSTM 层对基于 Keras 的网络进行建模。网络上的大多数可用示例都使用 (1, 30, 50) 等形状的数据(1 个样本包含 30 个时间步长,每个时间步长 50 个特征)。

但是,我的数据集中的每个时间步长都由许多一维数组组成。一个 10 个时间步的样本将是 (1, 10, 100, 384)(1 个批次 - 一个样本,10 个时间步,每个包含 100 个具有 384 个特征的数组)。那么,我应该如何定义具有这种形状的模型呢?

我真的可以将每个时间步长数据展平(100*384),但这似乎很不够,因为可能会使所有 CNN 处理无效...另外,每个时间步长数据实际上是一维的:不是空间数据

我已经定义了一个简单的模型,如下所示,但我认为它错误地使用了输入形状的batch_size。我认为它试图从“482 个样本”中学习,而不是从具有“482 个时间步长”的单个样本中学习......

data_input_shape = (482, 100, 384)

model = Sequential()
model.add(Conv1D(300, 1, activation="relu", input_shape=(100,384)))
model.add(MaxPooling1D(4))
model.add(Conv1D(256, 1, activation="relu"))
model.add(MaxPooling1D(4))
model.add(Conv1D(128, 1, activation="relu"))
model.add(MaxPooling1D(5))

model.add(LSTM(200, return_sequences=True))
model.add(LSTM(200, return_sequences=True))
model.add(LSTM(200, return_sequences=True))
model.add(Dense(1, activation='sigmoid'))

有什么建议吗?

【问题讨论】:

  • 你是对的,当前模型从 482 个样本中学习,每个样本有 100 个时间步长和 384 个特征,这似乎不是你想要的。这 100 个数组有什么共同点吗?比如,数组 0 的特征 0 是否与数组 1 的特征 0 的类型相同?
  • @SaTa:这些是直接从输入图像中提取的局部特征。因此,每张图像由 100 个向量表示,每个向量有 384 个值。时态 CNN 的目的是掌握这些数据之间的某种关系,再加上 RNN,因为每张图像都与前 N 幅图像密切相关。

标签: keras lstm


【解决方案1】:

让我们假设以下两种情况,因为您已经提到 100 个数组在空间上不相关:

  1. 每个要素的 384 个值在空间上是独立的。
  2. 每个要素的 384 个值在空间上是相关的。例如,它们是经过一些 FFT 或类似操作后跨频率范围的值。

在情况 1 中,您基本上拥有 100x384 的独立特征。所以扁平化似乎是一种选择。

不过,在情况 2 中,跨特征应用 2D 卷积可能是有意义的。方法如下:

首先,您应该以正确的格式准备数据。假设您的数据有 482 个时间步长,您应该决定您希望在每个样本中有多少个时间步长。例如,您可以决定在每个样本中设置 10 个时间步长,如果样本之间没有重叠,则将为您提供大约 48 个样本。所以现在的数据将是形状(48、10、100、384)。此外,我们应该添加一个额外的维度作为通道,以便能够在 Keras 中应用 2D 卷积。所以你的数据会变成形状 (48, 10, 100, 384, 1)

接下来,您可以决定架构。我们将在每个时间步将 Conv2D 应用于每个数组。我们使用 (1, x) 或 (100, x) 的内核大小,因为您的数组在空间上不相关。这是一个示例架构:

model = Sequential()
model.add(TimeDistributed(Conv2D(16, (1, 5), activation="relu"), input_shape=(10, 100, 384, 1)))
model.add(TimeDistributed(MaxPooling2D((1, 2))))
model.add(TimeDistributed(Conv2D(32, (100, 9), activation="relu"), input_shape=(10, 100, 384, 1)))
model.add(TimeDistributed(MaxPooling2D((1, 4))))
model.add(TimeDistributed(Flatten()))
model.add(LSTM(16, return_sequences=True))
model.add(Dense(1, activation='sigmoid'))

一些补充说明:

  • 您当然可以为每种类型添加更多层。
  • TimeDistruted 是上面新增的。你可以阅读它here
  • 如果您有图像,请考虑从一开始就使用 CNN/LSTM 混合或 Conv3D,而不是从图像中提取 100 个数组。
  • 看看 ConvLSTM2D here 组合 CNN 和 LSTM 层。

【讨论】:

  • 感谢您的帮助。这应该有助于开发更好的模型来解决我的问题...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多