PyTorch:使用backward()时,如何仅保留图形的一部分?

PyTorch:使用backward()时,如何仅保留图形的一部分?,pytorch,Pytorch,我有一个PyTorch计算图,它由一个子图组成,执行一些计算,然后这个计算的结果(我们称之为x)被分支成另外两个子图。这两个子图中的每一个子图都会产生一些标量结果(让我们称它们为y1和y2)。我想对这两个结果中的每一个进行反向传递(也就是说,我想累积两个子图的梯度。我不想执行实际的优化步骤) 现在,由于内存是这里的一个问题,我想按以下顺序执行操作: 首先,计算x。然后,计算y1,执行y1.backward(),同时(这是关键点)保留导致x的图形,但将图形从x释放到y1。然后,计算y2,并执行y2

我有一个PyTorch计算图,它由一个子图组成,执行一些计算,然后这个计算的结果(我们称之为
x
)被分支成另外两个子图。这两个子图中的每一个子图都会产生一些标量结果(让我们称它们为
y1
y2
)。我想对这两个结果中的每一个进行反向传递(也就是说,我想累积两个子图的梯度。我不想执行实际的优化步骤)

现在,由于内存是这里的一个问题,我想按以下顺序执行操作: 首先,计算
x
。然后,计算
y1
,执行
y1.backward()
,同时(这是关键点)保留导致
x
的图形,但将图形从
x
释放到
y1
。然后,计算
y2
,并执行
y2.backward()

换句话说,为了在不牺牲太多速度的情况下节省内存,我想保留
x
,而不需要重新计算,但我想在不再需要它们之后,删除从
x
y1
的所有计算

问题是函数
backward()
的参数
retain\u graph
将保留导致
y1
的整个图形,而我只需要保留导致
x
的部分图形

下面是一个我理想中想要的例子:

导入火炬
w=火炬张量(1.0)
w、 需要梯度(真)
#计算`x的子图`
x=w+10
#用于计算'y1'的子图`
x1=x*x
y1=x1*x1
y1.backward(retain_graph=x)#这不起作用,因为retain_graph是一个布尔值,可以保留整个图,也可以释放它。
#计算'y2'的子图`
x2=火炬。sqrt(x)
y2=x2/2
y2.向后()

如何做到这一点?

参数
retain\u graph
将保留整个图形,而不仅仅是一个子图。但是,我们可以使用垃圾收集来释放图形中不需要的部分。通过从
x
y1
删除对子图的所有引用,此子图将被释放:

导入火炬
w=火炬张量(1.0)
w、 需要梯度(真)
#计算`x的子图`
x=w+10
#用于计算'y1'的子图`
x1=x*x
y1=x1*x1
y1.向后(retain_graph=True)#保留所有图形
#删除图形中不需要的部分。注意,由于python的垃圾收集,这些部分将从内存中释放(即使它们在GPU上)
y1=无
x1=无
#计算'y2'的子图`
x2=火炬。sqrt(x)
y2=x2/2
y2.向后()