错误说明
在使用PyTorch自带的TensorBoard的add_graph
方法将网络图结构添加到监测信息中时,遇到如下报错:
1 | RuntimeError: Cannot insert a Tensor that requires grad as a constant. Consider making it a parameter or input, or detaching the gradient. |
这个信息其实有些tricky:
- 告诉了是
add_graph
这一步有问题,但是具体哪个变量是带有不符合要求的属性不得而知 - 格式是按照api照猫画虎的,怎么会不符合要求呢?
Debug过程
搜遍全网也没有找到结果,根据一些相关信息(见参考)的蛛丝马迹,首先怀疑是传入模型的Tensor的
requires_grad
设置问题,debug后发现其值为False
(也应该是False,因为是从原始文件读入的数据)。接下来,怀疑是模型output的Tensor的
requires_grad
的问题,但是没想到如何简便地更改add_graph
中的模型输出Tensor的属性,因为这一步是在add_graph
源码中的,当然也可以更改源码中的model(input_to_model)
这里,使其所有输出的属性符合要求,但是这有点不elegant。接下来从参考链接2中获得了一些启发,想到我使用的是多GPU训练,会不会是
Dataparallel
的问题呢?接下来又想到之前在知乎(链接3)看到关于读写Dataparallel
的一些技巧,马上“灵光一闪”。先尝试了将add_graph
放到模型并行化之前,果然没有报错,基本确定是Dataparallel
的问题。然后根据参考链接2和3,想到把模型先从并行化容器中取出来,再执行,果然问题完美解决。相关代码如下
1
2
3
4
5
6# setup the summary writer
train_data_sample, label_sample = iter(dataloader_train).next()
writer = SummaryWriter(args.summary_path, flush_secs=120)
with writer:
writer.add_graph(model.module,train_data_sample.to(device)) # model graph, with input重点就在
model.module
,这句话讲模型从并行化后的容器中取出来,以未并行化的模型(原始模型)返回,这样再执行就没有问题了。