【问题标题】:Time series CNN, trying to use 1,1 input shape时间序列 CNN,尝试使用 1,1 输入形状
【发布时间】:2019-07-30 08:56:00
【问题描述】:

我正在尝试为时间序列制作 CNN 1D。

第一期: 尝试使用 [1,1] 的输入形状时出现错误:

Error: Negative dimension size caused by adding layer average_pooling1d_AveragePooling1D1 with input shape [,0,128]

第二期 我的数据有 2 个不同的数组 (1d):第一个数组是包含时间序列的输入数据,第二个数组包含具有股票闭合值的输出数据。

让我获得更多结果的原因是将输入形状设置为 [6,1]。

模型总结:

_________________________________________________________________
Layer (type)                 Output shape              Param #   
=================================================================
conv1d_Conv1D1 (Conv1D)      [null,5,128]              384       
_________________________________________________________________
average_pooling1d_AveragePoo [null,4,128]              0         
_________________________________________________________________
conv1d_Conv1D2 (Conv1D)      [null,3,64]               16448     
_________________________________________________________________
average_pooling1d_AveragePoo [null,2,64]               0         
_________________________________________________________________
conv1d_Conv1D3 (Conv1D)      [null,1,16]               2064      
_________________________________________________________________
average_pooling1d_AveragePoo [null,0,16]               0         
_________________________________________________________________
flatten_Flatten1 (Flatten)   [null,0]                  0         
_________________________________________________________________
dense_Dense1 (Dense)         [null,1]                  1         
=================================================================

在这里训练模型让我陷入了困境:

const trainX = tf.tensor1d(data.inTime).reshape([100, 6, 1])

100 - 我的数组的大小 6 - 特点 1 - 1 个单位作为输出

Error: Size(100) must match the product of shape 100,6,1

我被困在训练步骤,因为我不知道如何训练它。 我希望有一个 [1,1] 输入形状,只给出 1 个时间序列并从中获得 1 个输出。

型号

async function buildModel() {
  const model = tf.sequential()

  // settings
  const kernelSize = 2
  const poolSize = [2]

  // tf layers
  model.add(tf.layers.conv1d({
    inputShape: [6, 1],
    kernelSize: kernelSize,
    filters: 128,
    strides: 1,
    useBias: true,
    activation: 'relu',
    kernelInitializer: 'varianceScaling'
  }))
  model.add(tf.layers.averagePooling1d({poolSize: poolSize, strides: [1]}))

  // 2nd layer
  model.add(tf.layers.conv1d({
    kernelSize: kernelSize,
    filters: 64,
    strides: 1,
    useBias: true,
    activation: 'relu',
    kernelInitializer: 'varianceScaling'
  }))
  model.add(tf.layers.averagePooling1d({poolSize: poolSize, strides: [1]}))

  model.add(tf.layers.conv1d({
    kernelSize: kernelSize,
    filters: 16,
    strides: 1,
    useBias: true,
    activation: 'relu',
    kernelInitializer: 'varianceScaling'
  }))
  model.add(tf.layers.averagePooling1d({poolSize: poolSize, strides: [1]}))

  model.add(tf.layers.flatten())

  model.add(tf.layers.dense({
    units: 1,
    kernelInitializer: 'VarianceScaling',
    activation: 'linear'
  }))

  // optimizer + learning rate
  const optimizer = tf.train.adam(0.0001)
  model.compile({
    optimizer: optimizer,
    loss: 'meanSquaredError',
    metrics: ['accuracy'],
  })

  return model
}

在发生错误的地方进行培训

async function train(model, data) {
  console.log(`MODEL SUMMARY:`)
  model.summary()
  // Train the model
  const epochs = 2
  // train data size, 28, 28, 1
  const trainX = tf.tensor1d(data.inTime).reshape([100, 6, 1])
  const trainY = tf.tensor([data.outClosed], [1, data.size, 1])

  let result = await model.fit(trainX, trainY, {
      epochs: epochs
  })

  print("Loss after last Epoch (" + result.epoch.length + ") is: " + result.history.loss[result.epoch.length-1])
  return result
}

任何关于如何解决它的想法将不胜感激!

【问题讨论】:

  • 也许有一些建议,为什么它更喜欢作为输入参数发送多个时间序列而不是一个,因为这是我在网络上的大多数示例中看到的。
  • 能否将模型添加到您的问题中?
  • 是的,现在添加它
  • 你能用 stackblitz.com 来演示这个问题吗?发现错误会更容易

标签: tensorflow tensorflow.js


【解决方案1】:

时间序列 是根据wikipedia 在连续等距时间点拍摄的序列。用于时间序列的神经网络 NN 的目标是找到数据序列之间的模式。 Convolutiona Neural Networks CNN 很少(如果不是从未用于此类数据)。其他经常使用的 NN 是 RNN 和 LSTM。如果我们有兴趣在一系列数据中找到一个模式,那么 inputShape 不能是 [1, 1];否则这将意味着在一个独特的点上找到一个模式。理论上可以做到,但实际上并没有抓住时间序列的本质。

这里使用的模型是使用带有平均池化层的 CNN。当然,池化层不能应用在池化大小大于层形状的层上,从而引发错误:

错误:添加层 average_pooling1d_AveragePooling1D1 与输入形状 [,0,128] 导致负维度大小

最后一个错误:

错误:Size(100) 必须与形状 100,6,1 的乘积相匹配

表示张量大小不匹配。

张量中有 100 * 6 * 1 = 600 个元素(大小 =600),而输入张量有 100 个元素会导致错误。

【讨论】:

  • 非常感谢@edkeveked 提供所有这些信息。现在我更清楚该做什么了。什么是我的 Size(100) 的有效输入。例如,我尝试使用 16,6,1 - 96 个元素运行它,但没有成功。
  • 它不起作用,因为 96 与 100 不同。您必须使用组合使大小与 100 匹配,例如 [10, 10, 1], [2, 50, 1], [ 2, 25, 2] 等...但请记住,它会影响模型的 inputShape
  • 我明白你的意思了,谢谢!我将着手更改元素的形状并重试。非常感谢,我当时被卡住了,我不知道如何绕过它。
  • 可能的数量是 C(3,1) * C(3,1) * 3! = 27。所以有 27 种可能的形状。
猜你喜欢
  • 2018-08-23
  • 2021-05-19
  • 2020-10-20
  • 1970-01-01
  • 1970-01-01
  • 2020-06-30
  • 2019-04-22
  • 2020-11-02
  • 1970-01-01
相关资源
最近更新 更多