Keras LSTM一次预测1个时间步

Keras LSTM一次预测1个时间步,keras,lstm,Keras,Lstm,编辑以添加: 我找到了我认为有效的解决方案: 我正在尝试使用Conv/LSTM网络来控制机器人。我想我已经准备好了一切,这样我就可以开始用回放存储器中的成批数据来训练它,但我不知道如何实际使用它来控制机器人。简化测试代码如下 import numpy as np from keras.models import Sequential from keras.layers import Dense, Flatten, Input from keras.layers import Convolut

编辑以添加: 我找到了我认为有效的解决方案:


我正在尝试使用Conv/LSTM网络来控制机器人。我想我已经准备好了一切,这样我就可以开始用回放存储器中的成批数据来训练它,但我不知道如何实际使用它来控制机器人。简化测试代码如下

import numpy as np

from keras.models import Sequential
from keras.layers import Dense, Flatten, Input
from keras.layers import Convolution2D
from keras.layers.recurrent import LSTM
from keras.layers.wrappers import TimeDistributed
from keras.utils import to_categorical

def make_model(num_actions, timesteps, input_dim, l2_reg=0.005 ):
    input_shape=(timesteps,) + input_dim
    model = Sequential()
    model.add(TimeDistributed( Convolution2D(8, (3, 3), strides=(2,2), activation='relu' ), input_shape=input_shape) )
    model.add(TimeDistributed( Convolution2D(16, (3, 3), strides=(2,2), activation='relu', ) ))
    model.add(TimeDistributed( Convolution2D(32, (3, 3), strides=(2,2), activation='relu', ) ))
    model.add(TimeDistributed(Flatten()))
    model.add(LSTM(512, return_sequences=True, activation='relu', unroll=True))
    model.add(Dense(num_actions, activation='softmax', ))
    model.compile(loss='categorical_crossentropy', optimizer='adam' )
    return model

batch_size = 16
timesteps = 10
num_actions = 6
model = make_model( num_actions, timesteps, (84,84,3) )
model.summary()

# Fake training batch. Would be pulled from a replay memory
batch = np.random.uniform( low=0, high=255, size=(batch_size,timesteps,84,84,3) )
y = np.random.randint( 0, high=5, size=(160) )
y = to_categorical( y, num_classes=num_actions )
y = y.reshape( batch_size, timesteps, num_actions )
# stateful should be false here
pred = model.train_on_batch( batch, y )

# move trained network to robot

# This works, but it isn't practical to not get outputs (actions) until after 10 timesteps and I don't think the LSTM internal state would be correct if I tried a rolling queue of input images.
batch = np.random.uniform( low=0, high=255, size=(1,timesteps,84,84,3) )
pred = model.predict( batch, batch_size=1 )

# This is what I would need to do on my robot, with the LSTM keeping state between calls to predict
max_time = 10 # or 100000, or forever, etc.
for i in range(max_time) :
    image = np.random.uniform( low=0, high=255, size=(1,1,84,84,3) ) # pull one image from camera
    # stateful should be true here
    pred = model.predict( image, batch_size=1 )
    # take action based on pred
我在“model.predict(image…”行中得到的错误是:

ValueError:检查时出错:预期时间_分配_1_输入具有形状(无,10,84,84,3),但获得具有形状(1,1,84,84,3)的数组

这是可以理解的,但我找不到解决的办法。 我不太清楚,甚至不知道我是否正确使用了时间分布层

那么,这在Keras中可能吗?如果可能,怎么可能

如果不是,在TF或Pytork中是否可能

谢谢你的建议

编辑以添加运行代码,尽管不一定正确。仍然需要在OpenAI gym任务上进行测试

import numpy as np

from keras.models import Sequential
from keras.layers import Dense, Flatten, Input
from keras.layers import Convolution2D
from keras.layers.recurrent import LSTM
from keras.layers.wrappers import TimeDistributed
from keras.utils import to_categorical

def make_model(num_actions, timesteps, input_dim, l2_reg=0.005 ):
    input_shape=(1,None) + input_dim
    model = Sequential()
    model.add(TimeDistributed( Convolution2D(8, (3, 3), strides=(2,2), activation='relu' ), batch_input_shape=input_shape) )
    model.add(TimeDistributed( Convolution2D(16, (3, 3), strides=(2,2), activation='relu', ) ))
    model.add(TimeDistributed( Convolution2D(32, (3, 3), strides=(2,2), activation='relu', ) ))
    model.add(TimeDistributed(Flatten()))
    model.add(LSTM(512, return_sequences=True, activation='relu', stateful=True))
    model.add(Dense(num_actions, activation='softmax', ))
    model.compile(loss='categorical_crossentropy', optimizer='adam' )
    return model

batch_size = 16
timesteps = 10
num_actions = 6
model = make_model( num_actions, 1, (84,84,3) )
model.summary()

# Fake training batch. Would be pulled from a replay memory
batch = np.random.uniform( low=0, high=255, size=(batch_size,timesteps,84,84,3) )
y = np.random.randint( 0, high=5, size=(160) )
y = to_categorical( y, num_classes=num_actions )
y = y.reshape( batch_size, timesteps, num_actions )

# Need to find a way to prevent the optimizer from updating every b, but accumulate updates over an entire batch (batch_size).
for b in range(batch_size):
    pred = model.train_on_batch( np.reshape(batch[b,:], (1,timesteps,84,84,3)), np.reshape(y[b,:], (1,timesteps,num_actions)) )
    #for t in range(timesteps):
    #    pred = model.train_on_batch( np.reshape(batch[b,t,:], (1,1,84,84,3)), np.reshape(y[b,t,:], (1,1,num_actions)) )
    model.reset_states() # Don't carry internal state between batches

# move trained network to robot

# This works, but it isn't practical to not get outputs (actions) until after 10 timesteps
#batch = np.random.uniform( low=0, high=255, size=(1,timesteps,84,84,3) )
#pred = model.predict( batch, batch_size=1 )

# This is what I would need to do on my robot, with the LSTM keeping state between calls to predict
max_time = 10 # or 100000, or forever, etc.
for i in range(max_time) :
    image = np.random.uniform( low=0, high=255, size=(1,1,84,84,3) ) # pull one image from camera
    # stateful should be true here
    pred = model.predict( image, batch_size=1 )
    # take action based on pred
    print( pred )

您需要做的第一件事是了解您的数据

这5个维度有什么意义吗

我试着猜一下:

- 1 learning example
- 1 time step (this is added by TimeDistributed, normal 2D convolutions don't take this)
- 84 image side
- 84 another image side
- 3 channels (RGB)
TimeDistributed
的目的是添加额外的
timesteps
维度,以便您可以在不应使用序列的层中模拟序列

您的错误消息告诉您:

  • 您的
    input\u shape
    参数是
    (None,10,84,84,3)
    ,其中None是批量大小(样本数/示例数)
  • 您输入的
    数据
    ,即代码中的
    批处理
    ,即
    (1,1,84,84,3)
存在不匹配,您应该使用包含10个时间步的批处理(由您的
input\u shape
定义)。对于
stateful=False
模型,可以在批处理中打包10个图像并进行训练

但是稍后,在
stateful=True
的情况下,您需要将
input\u shape
作为一个步骤。(您可以创建一个仅用于预测的新模型,并将所有权重从训练模型复制到预测模型,也可以尝试在该时间步长维度中使用
None
,这意味着您可以使用不同数量的时间步长进行训练和预测)

现在,与卷积不同的是,LSTM层已经预期了时间步长。因此,您应该找到一种将数据压缩到更小维度的方法

LSTM需要
(无、时间步、功能)
。时间步与前一个相同。10用于培训,1用于预测,您可以尝试使用
None

因此,与其在
TimeDistributed
中使用
flatte()
,不如简单地重塑数据,压缩不是批量大小或步骤的维度:

model.add(Reshape((8,9*9*32))) #the batch size doesn't participate in this definition, and it will remain as it is. 
9*9*32
是前面卷积滤波器及其32个滤波器的边。(我只是不确定边是9,可能是8,你可以在当前的
model.summary()中看到)


最后,对于
stateful=True
情况,必须使用
batch\u shape
而不是
input\u shape
来定义模型。批中的样本数量必须是一个固定数字,因为模型将假定第二批中的样本是属于前一批中样本的新步骤。(所有批次的样本数量都必须相同)。

首先需要了解数据

这5个维度有什么意义吗

我试着猜一下:

- 1 learning example
- 1 time step (this is added by TimeDistributed, normal 2D convolutions don't take this)
- 84 image side
- 84 another image side
- 3 channels (RGB)
TimeDistributed
的目的是添加额外的
timesteps
维度,以便您可以在不应使用序列的层中模拟序列

您的错误消息告诉您:

  • 您的
    input\u shape
    参数是
    (None,10,84,84,3)
    ,其中None是批量大小(样本数/示例数)
  • 您输入的
    数据
    ,即代码中的
    批处理
    ,即
    (1,1,84,84,3)
存在不匹配,您应该使用包含10个时间步的批处理(由您的
input\u shape
定义)。对于
stateful=False
模型,可以在批处理中打包10个图像并进行训练

但是稍后,在
stateful=True
的情况下,您需要将
input\u shape
作为一个步骤。(您可以创建一个仅用于预测的新模型,并将所有权重从训练模型复制到预测模型,也可以尝试在该时间步长维度中使用
None
,这意味着您可以使用不同数量的时间步长进行训练和预测)

现在,与卷积不同的是,LSTM层已经预期了时间步长。因此,您应该找到一种将数据压缩到更小维度的方法

LSTM需要
(无、时间步、功能)
。时间步与前一个相同。10用于培训,1用于预测,您可以尝试使用
None

因此,与其在
TimeDistributed
中使用
flatte()
,不如简单地重塑数据,压缩不是批量大小或步骤的维度:

model.add(Reshape((8,9*9*32))) #the batch size doesn't participate in this definition, and it will remain as it is. 
9*9*32
是前面卷积滤波器及其32个滤波器的边。(我只是不确定边是9,可能是8,你可以在当前的
model.summary()中看到)


最后,对于
stateful=True
情况,必须使用
batch\u shape
而不是
input\u shape
来定义模型。批中的样本数量必须是一个固定数字,因为模型将假定第二批中的样本是属于前一批中样本的新步骤。(所有批次的样本数量都必须相同)。

您的机器人是否正在处理图像?这就是84 x 84的假设吗