使用一维传感器输入创建LSTM层的问题



我正在尝试用LSTM层替换我的FFNN。作为输入,我得到了360个激光雷达数据点和4个额外的距离值等。算法应该学会在机器人的环境中导航。有了FFNN,它运行得非常好,对于LSTM,我开始是这样的:

# collected data for RL
scan_range = [] #filled with .append, length=360
state = scan_range + [heading, current_distance, obstacle_min_range, obstacle_angle]
return np.asarray(state)

根据这些数据,如果目标实现等,将对下一个状态进行一些分析。数据将存储在内存中:agent.appendMemory(state, action, reward, next_state, done)这将做到:CCD_ 2。动作和奖励是常数值,next_state又是一个数组。

接下来,我用LSTM层构建神经网络

model = Sequential()
model.add(SimpleRNN(64, input_shape=(1,364))) 
model.add(Dense(self.action_size, kernel_initializer='lecun_uniform'))
model.add(Activation('linear'))
model.compile(loss='mse', optimizer=RMSprop(lr=self.learning_rate, rho=0.9, epsilon=1e-06))
model.summary()

然后,它使用一个批次对FFNN进行训练,如下所示:

def trainModel(self, target=False):
mini_batch = random.sample(self.memory, self.batch_size)
X_batch = np.empty((0, self.state_size), dtype=np.float64)
Y_batch = np.empty((0, self.action_size), dtype=np.float64)
for i in range(self.batch_size):
states = mini_batch[i][0]
actions = mini_batch[i][1]
rewards = mini_batch[i][2]
next_states = mini_batch[i][3]
dones = mini_batch[i][4]
q_value = self.model.predict(states.reshape((1, len(states))))
self.q_value = q_value
if target:
next_target = self.target_model.predict(next_states.reshape((1, len(next_states))))
else:
next_target = self.model.predict(next_states.reshape((1, len(next_states))))
next_q_value = self.getQvalue(rewards, next_target, dones)
X_batch = np.append(X_batch, np.array([states.copy()]), axis=0)
Y_sample = q_value.copy()
Y_sample[0][actions] = next_q_value
Y_batch = np.append(Y_batch, np.array([Y_sample[0]]), axis=0)
if dones:
X_batch = np.append(X_batch, np.array([next_states.copy()]), axis=0)
Y_batch = np.append(Y_batch, np.array([[rewards] * self.action_size]), axis=0)
print X_batch.shape
print Y_batch.shape
self.model.fit(X_batch, Y_batch, batch_size=self.batch_size, epochs=1, verbose=0)

当我不更改代码时,我肯定会得到维度的错误:expected simple_rnn_1_input to have 3 dimensions, but got array with shape (1, 364),因为输入仍然是二维的,LSTM需要三维的。然后我尝试手动添加第三个维度,看看是否一切正常:

mini_batch = random.sample(self.memory, self.batch_size)
X_batch = np.empty((0, self.state_size), dtype=np.float64)
Y_batch = np.empty((0, self.action_size), dtype=np.float64)
Z_batch = np.empty((0, 1), dtype=np.float64)
for i in range(self.batch_size):
states = mini_batch[i][0]
actions = mini_batch[i][1]
rewards = mini_batch[i][2]
next_states = mini_batch[i][3]
dones = mini_batch[i][4]
q_value = self.model.predict(states.reshape((1, len(states))))
self.q_value = q_value
if target:
next_target = self.target_model.predict(next_states.reshape((1,1, len(next_states))))
else:
next_target = self.model.predict(next_states.reshape((1,1, len(next_states))))
next_q_value = self.getQvalue(rewards, next_target, dones)
X_batch = np.append(X_batch, np.array([states.copy()]), axis=0)
Y_sample = q_value.copy()
Y_sample[0][actions] = next_q_value
Y_batch = np.append(Y_batch, np.array([Y_sample[0]]), axis=0)
Z_batch = np.append(Z_batch, np.array([[1]]), axis=0)
if dones:
X_batch = np.append(X_batch, np.array([next_states.copy()]), axis=0)
Y_batch = np.append(Y_batch, np.array([[rewards] * self.action_size]), axis=0)
Z_batch = np.append(Z_batch, np.array([[1]]), axis=0)
self.model.fit(X_batch, Y_batch, Z_batch, batch_size=self.batch_size, epochs=1, verbose=0)

执行此操作时,.fit((会给出以下错误:TypeError: fit() got multiple values for keyword argument 'batch_size'我现在的问题是,在这种情况下,.fit((是否适合LSTM框架?在文档中,只给出了x和z。在这种情况下,Z似乎毫无用处,但LSTM仍然需要一个3维作为输入。我的问题是,如果我想正确地使用LSTM框架,而不是使用假人,我必须使用比实际状态更多的东西?那么,我可以把最后10个状态加在一起吗?这样,states.shape=(10,1364(,这是一个好的时间步长范围,还是应该更长?谨致问候!

我认为您的基本问题是需要将第三个维度添加到X_batch,而不是model.fit中的另一个组件。

特别是,Keras模型通常不会在模型层中指定"批次"/"样本"维度。它是根据X_batch输入数据的形状自动推断出来的。在您的例子中,您有一个SimpleRNN,input_shape=(1364(作为第一层。Keras对此的解释是,输入数据X_batch的形状应该是这样的:

(num_samples,1364(。

此外,如果您想创建一个时间步长序列,您可以提供具有以下形状的X_batch:

(num_samples,num_timesteps,364(或类似的东西。

本页有一些很好的讨论:https://keras.io/getting-started/sequential-model-guide/例如,搜索"Stacked LSTM for sequence classification"来帮助说明(尽管要注意return_sequences=True-对于单个LSTM,您可能希望return_seSequences=False。(

我希望这能有所帮助。

最新更新