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