使用一维传感器输入创建 LSTM 层时遇到问题
Trouble with creating a LSTM Layer with a one dimensional Sensor Input
我正在尝试用 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)
这将做:
self.memory.append((state, action, reward, next_state, done)
。动作和奖励都是正常的数字,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,1,364),这是一个很好的时间步长范围还是应该更长?
亲切的问候!
我认为您的基本问题是第 3 维需要添加到 X_batch,而不是 model.fit 中的另一个组件。
特别是,Keras 模型通常不会在模型层中指定 "batch"/"sample" 维度。它是根据 X_batch 输入数据的形状自动推断出来的。在您的情况下,您有一个 SimpleRNN,其中 input_shape=(1,364) 作为第一层。 Keras 将此解释为输入数据 X_batch 的形状应如下所示:
(num_samples, 1, 364).
此外,如果您想创建一系列时间步长,您可以提供 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_sequences=False。)
希望对您有所帮助。
我正在尝试用 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)
这将做:
self.memory.append((state, action, reward, next_state, done)
。动作和奖励都是正常的数字,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,1,364),这是一个很好的时间步长范围还是应该更长?
亲切的问候!
我认为您的基本问题是第 3 维需要添加到 X_batch,而不是 model.fit 中的另一个组件。
特别是,Keras 模型通常不会在模型层中指定 "batch"/"sample" 维度。它是根据 X_batch 输入数据的形状自动推断出来的。在您的情况下,您有一个 SimpleRNN,其中 input_shape=(1,364) 作为第一层。 Keras 将此解释为输入数据 X_batch 的形状应如下所示:
(num_samples, 1, 364).
此外,如果您想创建一系列时间步长,您可以提供 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_sequences=False。)
希望对您有所帮助。