torch.no_grad() 和 detach() 合并
torch.no_grad() and detach() combined
我在选择动作时遇到了很多代码片段,如下所示,其中混合了 torch.no_grad
和 detach
(其中 actor
是某个演员,SomeDistribution
您的首选发行版),我想知道它们是否有意义:
def f():
with torch.no_grad():
x = actor(observation)
dist = SomeDistribution(x)
sample = dist.sample()
return sample.detach()
是否在 return 语句中使用 detach
不是不必要的,因为 x 的 requires_grad
已经设置为 False,所以所有使用 x
的计算应该已经脱离图形?或者在 torch.no_grad
包装器之后的计算以某种方式再次出现在图表上,所以我们需要在最后再次分离它们(在我看来,在这种情况下 no_grad
是不必要的)?
另外,如果我是对的,我想除了省略 detach
之外,还可以省略 torch.no_grad
,并以相同的功能结束,但性能更差,因此 torch.no_grad
是首选?
虽然它可能是多余的,但它取决于 actor
和 SomeDistribution
的内部结构。通常,我可以想到三种情况,在此代码中 detach
是必需的。由于您已经观察到 x
已将 requires_grad
设置为 False
,因此情况 2 和 3 不适用于您的具体情况。
- 如果
SomeDistribution
有内部参数(带有 requires_grad=True
的叶张量),那么 dist.sample()
可能会导致计算图将 sample
连接到这些参数。如果不分离,计算图(包括那些参数)将在 returning 之后不必要地保留在内存中。
torch.no_grad
上下文中的默认行为是 return 将 requires_grad
设置为 False
的张量运算的结果。但是,如果 actor(observation)
由于某种原因在 returning 之前明确地将其 return 值的 requires_grad
设置为 True
,则可以创建一个计算图来连接 x
到 sample
。如果不分离,计算图(包括 x
)将在 returning 后不必要地保留在内存中。
- 这个似乎更不可能,但如果
actor(observation)
实际上只是 return 对 observation
的引用,而 observation.requires_grad
是 True
,那么从observation
到sample
的计算图可以在dist.sample()
. 期间构建
关于去掉[=12=的leu中的no_grad
上下文的建议,这可能会导致构建连接observation
的计算图(如果需要梯度的话)and/or 分配的参数(如果有的话)到x
。该图将在 detach
后被丢弃,但创建计算图确实需要时间和内存,因此可能会降低性能。
总而言之,no_grad
和 detach
两者都做更安全,但其中任何一个的必要性取决于分布和参与者的细节。
我在选择动作时遇到了很多代码片段,如下所示,其中混合了 torch.no_grad
和 detach
(其中 actor
是某个演员,SomeDistribution
您的首选发行版),我想知道它们是否有意义:
def f():
with torch.no_grad():
x = actor(observation)
dist = SomeDistribution(x)
sample = dist.sample()
return sample.detach()
是否在 return 语句中使用 detach
不是不必要的,因为 x 的 requires_grad
已经设置为 False,所以所有使用 x
的计算应该已经脱离图形?或者在 torch.no_grad
包装器之后的计算以某种方式再次出现在图表上,所以我们需要在最后再次分离它们(在我看来,在这种情况下 no_grad
是不必要的)?
另外,如果我是对的,我想除了省略 detach
之外,还可以省略 torch.no_grad
,并以相同的功能结束,但性能更差,因此 torch.no_grad
是首选?
虽然它可能是多余的,但它取决于 actor
和 SomeDistribution
的内部结构。通常,我可以想到三种情况,在此代码中 detach
是必需的。由于您已经观察到 x
已将 requires_grad
设置为 False
,因此情况 2 和 3 不适用于您的具体情况。
- 如果
SomeDistribution
有内部参数(带有requires_grad=True
的叶张量),那么dist.sample()
可能会导致计算图将sample
连接到这些参数。如果不分离,计算图(包括那些参数)将在 returning 之后不必要地保留在内存中。 torch.no_grad
上下文中的默认行为是 return 将requires_grad
设置为False
的张量运算的结果。但是,如果actor(observation)
由于某种原因在 returning 之前明确地将其 return 值的requires_grad
设置为True
,则可以创建一个计算图来连接x
到sample
。如果不分离,计算图(包括x
)将在 returning 后不必要地保留在内存中。- 这个似乎更不可能,但如果
actor(observation)
实际上只是 return 对observation
的引用,而observation.requires_grad
是True
,那么从observation
到sample
的计算图可以在dist.sample()
. 期间构建
关于去掉[=12=的leu中的no_grad
上下文的建议,这可能会导致构建连接observation
的计算图(如果需要梯度的话)and/or 分配的参数(如果有的话)到x
。该图将在 detach
后被丢弃,但创建计算图确实需要时间和内存,因此可能会降低性能。
总而言之,no_grad
和 detach
两者都做更安全,但其中任何一个的必要性取决于分布和参与者的细节。