【问题标题】:Tensorflow 2.0 Combine CNN + LSTMTensorflow 2.0 结合 CNN + LSTM
【发布时间】:2020-01-20 01:24:37
【问题描述】:

如何在 Tensorflow 2.0 / Keras 中(扁平化)conv2d 层之后添加 LSTM 层?我的训练输入数据具有以下形状(大小、序列长度、高度、宽度、通道)。对于卷积层,我一次只能处理一个图像,对于 LSTM 层,我需要一系列特征。有没有办法在 LSTM 层之前重塑数据,以便将两者结合起来?

【问题讨论】:

  • 我认为 TimeDistributed 层是为此而设计的,但是当我使用它时,我会遇到内存泄漏,并且在几次迭代后会引发 OOM 异常。你搞清楚了吗?

标签: python tensorflow keras lstm


【解决方案1】:

从您提供的形状概述((size, sequence_length, height, width, channels))来看,您似乎有每个标签的图像序列。为此,我们通常使用Conv3D。我在下面附上了一个示例代码:

import tensorflow as tf

SIZE = 64
SEQUENCE_LENGTH = 50
HEIGHT = 128
WIDTH = 128
CHANNELS = 3

data = tf.random.normal((SIZE, SEQUENCE_LENGTH, HEIGHT, WIDTH, CHANNELS))

input = tf.keras.layers.Input((SEQUENCE_LENGTH, HEIGHT, WIDTH, CHANNELS))
hidden = tf.keras.layers.Conv3D(32, (3, 3, 3))(input)
hidden = tf.keras.layers.Reshape((-1, 32))(hidden)
hidden = tf.keras.layers.LSTM(200)(hidden)

model = tf.keras.models.Model(inputs=input, outputs=hidden)
model.summary()

输出:

Model: "model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 50, 128, 128, 3)] 0         
_________________________________________________________________
conv3d (Conv3D)              (None, 48, 126, 126, 32)  2624      
_________________________________________________________________
reshape (Reshape)            (None, None, 32)          0         
_________________________________________________________________
lstm (LSTM)                  (None, 200)               186400    
=================================================================
Total params: 189,024
Trainable params: 189,024
Non-trainable params: 0

如果您仍想使用在您的情况下不建议使用的Conv2D,则必须执行如下所示的操作。基本上,您是在高度维度上附加图像序列,这将使您失去时间维度。

import tensorflow as tf

SIZE = 64
SEQUENCE_LENGTH = 50
HEIGHT = 128
WIDTH = 128
CHANNELS = 3

data = tf.random.normal((SIZE, SEQUENCE_LENGTH, HEIGHT, WIDTH, CHANNELS))

input = tf.keras.layers.Input((SEQUENCE_LENGTH, HEIGHT, WIDTH, CHANNELS))
hidden = tf.keras.layers.Reshape((SEQUENCE_LENGTH * HEIGHT, WIDTH, CHANNELS))(input)
hidden = tf.keras.layers.Conv2D(32, (3, 3))(hidden)
hidden = tf.keras.layers.Reshape((-1, 32))(hidden)
hidden = tf.keras.layers.LSTM(200)(hidden)

model = tf.keras.models.Model(inputs=input, outputs=hidden)
model.summary()

输出:

Model: "model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 50, 128, 128, 3)] 0         
_________________________________________________________________
reshape (Reshape)            (None, 6400, 128, 3)      0         
_________________________________________________________________
conv2d (Conv2D)              (None, 6398, 126, 32)     896       
_________________________________________________________________
reshape_1 (Reshape)          (None, None, 32)          0         
_________________________________________________________________
lstm (LSTM)                  (None, 200)               186400    
=================================================================
Total params: 187,296
Trainable params: 187,296
Non-trainable params: 0
_________________________________________________________________

【讨论】:

  • 非常感谢您的回答。它真的对我有很大帮助。我刚刚阅读了有关 TimeDistributed 层的信息。你也可以用它作为替代品吗?
  • 每一层的用例都不同。您必须根据自己的要求应用每一层。
  • 我们不应该在那里添加batch_normalization吗?就像在 Conv3d 之后
  • 如果您能解释“为此,我们通常使用 Conv3D”的原因,这将是非常大的帮助
猜你喜欢
  • 2019-03-02
  • 2017-06-17
  • 2021-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多