用于太空入侵者 RL (Keras) 的 LSTM 网络

Posted

技术标签:

【中文标题】用于太空入侵者 RL (Keras) 的 LSTM 网络【英文标题】:LSTM network for space-invaders RL (Keras) 【发布时间】:2020-05-06 10:50:13 【问题描述】:

我是强化学习的新手,正在尝试使用 LSTM 对太空入侵者代理进行强化学习。 我尝试使用在此paper 中找到的网络,但一直遇到问题:

-如果我使用 conv2D,LSTM 的尺寸不适合,我会收到此错误:

ValueError:输入 0 与层 conv_lst_m2d_1 不兼容: 预期 ndim=5,发现 ndim=4

这是代码:

    self.model = Sequential()
    self.model.add(Conv2D(32,kernel_size=8,strides=4,activation='relu',input_shape=(None,84,84,1)))
    self.model.add(Conv2D(64,kernel_size=4,strides=2,activation='relu'))
    self.model.add(Conv2D(64,kernel_size=3, strides=1,activation='relu'))
    self.model.add(ConvLSTM2D(512, kernel_size=(3,3), padding='same', return_sequences=False))
    self.model.add(Dense(4, activation='relu'))
    self.model.compile(loss='mse', optimizer=Adam(lr=0.0001))
    self.model.summary()

-如果我使用输出 5D 张量的 Conv3D,我不能使用一张图像作为输入:

ValueError:检查输入时出错:预期 conv3d_1_input 有 5 维,但得到了形状为 (1, 84, 84, 1) 的数组

代码:

    self.model.add(Conv3D(32,kernel_size=8,strides=4,activation='relu',input_shape=(None,84,84,1)))
    self.model.add(Conv3D(64,kernel_size=4,strides=2,activation='relu'))
    self.model.add(Conv3D(64,kernel_size=3, strides=1,activation='relu'))
    self.model.add(ConvLSTM2D(512, kernel_size=(3,3), padding='same', return_sequences=False))
    self.model.add(Dense(4, activation='relu'))
    self.model.compile(loss='mse', optimizer=Adam(lr=0.0001))
    self.model.summary()

(编辑)

网络摘要(第二个网络):

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv3d_1 (Conv3D)            (None, None, 20, 20, 32)  16416     
_________________________________________________________________
conv3d_2 (Conv3D)            (None, None, 9, 9, 64)    131136    
_________________________________________________________________
conv3d_3 (Conv3D)            (None, None, 7, 7, 64)    110656    
_________________________________________________________________
conv_lst_m2d_1 (ConvLSTM2D)  (None, 7, 7, 512)         10618880  
_________________________________________________________________
dense_1 (Dense)              (None, 7, 7, 4)           2052      
=================================================================

而数据输入形状为:(84, 84, 1)

【问题讨论】:

您得到的第一个错误是指ConvLSTM2D 层,因此您最初选择的层似乎有效。您可以打印网络摘要并包含在问题中以及输入样本/形状中吗? 第一个网络没有打印摘要,因为网络甚至没有构建......只是意识到另一个网络确实构建了网络并在我们输入图像时输出错误。跨度> 第二个网络正在编译,但 Conv_3D 层的输入形状不适用于您的数据形状。另一方面,第一个网络没有编译,因为最后一个 Conv_2d 层的输出大小与 ConvLSTM 层的输入大小不兼容。 【参考方案1】:

您需要使用TimeDistributed Conv2D,它会告诉您的网络将数据理解为时间数据(我猜这就是您想要的),并将匹配 LSTM 内部形状。

import tensorflow as tf

model = tf.keras.Sequential()

model.add(tf.keras.layers.Input(shape=(None,84,84,1)))

model.add(tf.keras.layers.TimeDistributed(tf.keras.layers.Conv2D(32,kernel_size=8,strides=4,activation='relu')))

model.add(tf.keras.layers.TimeDistributed(tf.keras.layers.Conv2D(64,kernel_size=4,strides=2,activation='relu')))

model.add(tf.keras.layers.TimeDistributed(tf.keras.layers.Conv2D(64,kernel_size=3, strides=1,activation='relu')))

model.add(tf.keras.layers.ConvLSTM2D(512, kernel_size=(3,3), padding='same', return_sequences=False))

model.add(tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(4, activation='relu')))

model.compile(loss='mse', optimizer=tf.keras.optimizers.Adam(lr=0.0001))

model.summary()

编译返回:

Model: "sequential_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
time_distributed_12 (TimeDis (None, None, 20, 20, 32)  2080      
_________________________________________________________________
time_distributed_13 (TimeDis (None, None, 9, 9, 64)    32832     
_________________________________________________________________
time_distributed_14 (TimeDis (None, None, 7, 7, 64)    36928     
_________________________________________________________________
conv_lst_m2d_3 (ConvLSTM2D)  (None, 7, 7, 512)         10618880  
_________________________________________________________________
time_distributed_15 (TimeDis (None, 7, 7, 4)           2052      
=================================================================
Total params: 10,692,772
Trainable params: 10,692,772
Non-trainable params: 0
_________________________________________________________________

【讨论】:

【参考方案2】:

首先尝试打印模型的输入和输出详细信息:-

o/p 会是这样 -

标记模型的输入:

['name': 'input', 'index': 451, 'shape': array([  1, 160, 160,   3],
dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0,
0)]

标记模型的输出:

['name': 'embeddings', 'index': 450, 'shape': array([  1, 512], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)]

一旦你得到详细信息,根据详细信息你必须给出input_shape的值。

【讨论】:

以上是关于用于太空入侵者 RL (Keras) 的 LSTM 网络的主要内容,如果未能解决你的问题,请参考以下文章

用于 LSTM 的 Keras 多元形状

如何用Sprite Kit制作《太空入侵者》

用于时间序列异常检测的 Keras LSTM-VAE(变分自动编码器)

用于 Keras 中句子相似性的具有 LSTM 的连体网络定期给出相同的结果

带有用于可变长度输入的掩蔽层的 Keras lstm

为啥用于预测的 Keras LSTM 批量大小必须与拟合批量大小相同?