Справочная информация: я использую DQN и DDPG для одновременного решения двух задач state(input)
DQN и DDPG - это две части. Одна часть - это состояния окружающей среды, а другая - состояния, абстрагированные от среды CNN + LSTM. Две части объединены в forward_dqn()
, forward_actor()
и forward_critic()
соответственно.
Question1:
Я возвращаю в обратном порядке последовательности loss_dqn
, loss_ddpg_actor
и loss_ddpg_critic
и получаю сообщение об ошибке «Попытка выполнить обратный просмотр графа во второй раз, но буферы уже освобождены». в обратном распространении loss_ddpg_actor
. Так как после обратного распространения loss_dqn, вычислительный граф был освобожден, поэтому я снова перешёл вперед CNN + LSTM, чтобы вычислить loss_ddpg_actor. Почему вычислительный граф не может быть создан снова? Спасибо.
Модель: (env: environment)
output_cnnlstm = cnnlstm.forward(env)
DQN_output = dqn.forward(cat(output_cnnlstm, state_env))
Actor_output = actor.forward(cat(output_cnnlstm, state_env))
Critic_output = critic.forward(cat(output_cnnlstm, state_env))
Код 1 (Q1):
# dqn
# forward: cnnlstm
s_cnnlstm_out, _, _ = self.model.forward_cnnlstm(s_cnnlstm, flag_optim=True)
# forward: dqn
q_eval_dqn = self.model.forward_dqn_eval(s_dqn, s_cnnlstm_out).gather(1, a_dqn)
q_next_dqn = self.model.forward_dqn_target(s_dqn_next, s_cnnlstm_out).detach()
q_target_dqn = r + GAMMA_DQN * q_next_dqn.max(dim=1)[0].reshape(SIZE_BATCH * SIZE_TRANSACTION, 1)
# optimzie: dqn
loss_dqn = self.loss_dqn(q_eval_dqn, q_target_dqn)
self.optimizer_cnnlstm.zero_grad()
self.optimizer_dqn.zero_grad()
loss_dqn.backward()
self.optimizer_cnnlstm.step()
self.optimizer_dqn.step()
loss_dqn = loss_dqn.detach().numpy()
# ddpg
# actor
# forward: cnnlstm
s_cnnlstm_out, _, _ = self.model.forward_cnnlstm(s_cnnlstm, flag_optim=True)
# forward: ddpg: actor
a_eval_ddpg = self.model.forward_actor_eval(s_ddpg, s_cnnlstm_out)
# optimze: ddpg: cnnlstm + actor
loss_ddpg_actor = - self.model.forward_cirtic_eval(s_ddpg, a_eval_ddpg, s_cnnlstm_out).mean()
self.optimizer_cnnlstm.zero_grad()
self.optimizer_actor.zero_grad()
loss_ddpg_actor.backward()
self.optimizer_cnnlstm.step()
self.optimizer_actor.step()
loss_ddpg_actor = loss_ddpg_actor.detach().numpy()
Вопрос2:
Я пишу демо-версию для тестирования процесса распространения, и демо-версия, кажется, работает хорошо, так как потери снижаются нормально, а ошибка теста низкая. Поэтому я хочу спросить разницу между двумя кодами и моделями.
Модель:
output_model1 = model1.forward(x)
output_model21 = model21.forward(cat(output_model1, x1))
output_model22 = model221.forward(cat(output_model1, x2))
по сравнению с моделью Q1, output_model1 ~ cnnlstm, output_model21 ~ DQN, output_model22 ~ Actor
Question3:
Я устанавливаю точку останова в демоверсии после loss1.backward()
и до optimizer1.step()
. Однако, с одной стороны, вес линейного слоя Model21 изменяется с оптимизацией. С другой стороны, x._grad
- это тензор градиента, а x1._grad
- None
. Поэтому мне интересно, оптимизированы ли параметры Model21, и почему x1._grad
отсутствует.
Код 2 (Q2 и Q3):
for i in range(NUM_OPTIM):
# optimize task 1
y1_pred = self.model.forward_task1(x, x1)
loss1 = self.loss_21(y1_pred, y1)
self.optimizer1.zero_grad()
self.optimizer21.zero_grad()
loss1.backward()
self.optimizer1.step()
self.optimizer21.step(
# optimze task 2
y2_pred = self.model.forward_task2(x, x2)
loss2 = self.loss_22(y2_pred, y2)
self.optimizer1.zero_grad()
self.optimizer22.zero_grad()
loss2.backward()
self.optimizer1.step()
self.optimizer22.step()