python - 在多任务处理中,反向传播后无法创建新的计算图
问题描述
背景:我使用 DQN 和 DDPG 同时解决两个任务。DQN 和DDPGstate(input)
都是两部分。一部分是环境的状态,另一部分是CNN+LSTM从环境中抽象出来的状态。这两个部分分别在forward_dqn()
和forward_actor()
中forward_critic()
连接。
问题1:我依次反向传播loss_dqn
, loss_ddpg_actor
,loss_ddpg_critic
并得到错误“尝试第二次向后遍历图形,但缓冲区已被释放。” 在 的反向传播中loss_ddpg_actor
。由于loss_dqn反向传播后,计算图已经被释放,所以我再次前向传播CNN+LSTM,计算loss_ddpg_actor。为什么无法再次创建计算图?谢谢。
型号:(环境:环境)
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:我写了一个demo来测试传播过程,demo似乎运行良好,因为loss下降正常,测试误差低。所以想问一下这两种代码和型号的区别。
模型:
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
问题3:我在demo的afterloss1.backward()
和before都设置了断点optimizer1.step()
。但是,一方面,Model21的线性层的权重随着优化而变化。另一方面,x._grad
是一个梯度值张量,而x1._grad
是None
。所以我想知道Model21的参数是否优化以及为什么x1._grad
是None。
代码 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()
解决方案
推荐阅读
- vue.js - 我在 asyncData 中处理非常慢的 Axios 请求
- java - 对 recyclerView 中的视图不起作用
- django-rest-framework - 如何创建那些嵌套对象
- c# - 列出分组或排序
- javascript - 单击按钮打开其他页面并向下滚动
- tabs - Symfony 3.4.6 - SonataAdmin - configureFromFields - 选项卡 - 在选项卡上添加图像
- javascript - 当我的障碍列表太大时,为什么会出现此错误?
- c++ - 如何从 txt 文件中导入用户定义的变量
- python - 如何避免创建虚拟文件来获取文件引用
- regex - 如何在perl中将字符串中的字母和数字分开?