Я пытаюсь заменить свой FFNN слоем LSTM. В качестве входных данных я получаю 360 Lidar Data Point и 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 снова массивследующее для 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), это хороший диапазон временного шага или он должен быть длиннее? С уважением!