tensorflow和pytorch的关系,pytorch和tensorflow的区别 知乎
前言:
我们在重新训练网络时,可能希望保留一些网络参数,只调整其中的一部分;可选的,如果你想训练一些分支网络,使其梯度不影响主网络的梯度),你需要使用一个函数来阻止几个分支的反向传播。另一方面,tensor.detach)返回新的张量,它从当前的计算图中分离出来,但指向原变量的存储位置。不同的是requires_grad为假,得到的张量绝对不需要计算梯度,没有grad。
即使之后重新将它的requires_grad置为true,它也不会具有梯度grad
这样我们用这个新的张量继续计算,然后进行反向传播,张量直到调用detach()才会停止,无法继续传播。
注意:
detach返回的张量与原始张量共享相同的内存。也就是说,一个会被修改,一个会改变。
例如,常见的例子有:
importtorcha=torch.tensor ([ 1,2,3。],requires _ grad=True)print)a . grad)out=a . sigmoid)out . sum
importtorcha=torch.tensor ([ 1,2,3。],Requirements _ grad=true)print)a . grad)out=a . sigmoid(oor ch))orad)a . sigmoid的Requirements _ grad是fad backward)) out.sum)。向后))不影响打印)0.9526](,grad _ fn=
C和out的区别在于C没有梯度,而out有梯度。但是,请注意,该报告在以下两种情况下是错误的:
1.1当使用detach()分离tensor但是没有更改这个tensor时,并不会影响backward():
g
导入torch a=torch.tensor ([1,2,3。],requires _ grad=true)print(a . grad)out=a . sigmoid()print(out)# add detach(),C requires_grad为False c=out.detach() print(c) #将新生成的变量用于反向传播c.sum()。backward() print(a.grad) 返回:None Tensor ([0.7311,0.8808,0.9526],grad _ fn=SigmoidBackward)Tensor([0.7311,0.8808,0.9526]) Traceback(最近一次调用last):文件 test.py ,第13行,在模块c.sum()中。backward()File /anaconda 3/envs/deep learning/lib/python 3.6/site-packages/torch/tensor . py ,第102行,在backward torch . autograd . backward(self,gradient,retain_graph,create _ graph)File /anaconda 3/envs/deep learning/lib/python 3.6/site-packages/torch/autograd/_ _ init _ _。py ,第90行,in backward allow _ unreachable=True)# allow _ unreachable flag runtime错误:张量的元素0不需要grad,并且没有grad_fn
1.3当使用detach()分离tensor并且更改这个tensor时,即使再对原来的out求导数,会影响backward(),会出现错误
如果此时C发生变化,这个变化会被autograd跟踪,当out.sum()为backward()时会报错,因为此时值的backward()得到的梯度是错误的:
导入torch a=torch.tensor ([1,2,3。],requires _ grad=true)print(a . grad)out=a . sigmoid()print(out)# add detach(),C requires_grad为false C=out . detach()print(C)C . Zero _()#用in place函数修改它#你会发现修改C也会影响out print(c) print(out) #此时C被改变,所以会影响backward(),此时backward()无法执行,报错:out.sum()。backward () print (a.grad) 返回:none张量([0.7311,0.8808,0.9526],grad _ fn=sigmoid backward)张量([0.7311] 0.8808,0.9526])。 0. 0.])张量([0。 0. 0.],grad _ fn=SigmoidBackward)trace back(最近一次调用last):文件 test.py ,第16行,在模块out.sum()中。backward()File /anaconda 3/envs/deep learning/lib/python 3.6/site-packages/torch/tensor . py ,第102行,在backward torch . autograd . backward(self,gradient,retain_graph,create _ graph)File /anaconda 3/envs/deep learning/lib/python 3.6/site-packages/torch/autograd/_ _ init _ _。py ,第90行,in backward Allow _ Unreachable=True)# Allow _ Unreachable标志运行时错误:梯度计算所需的某个变量已被就地操作“”II修改。tensor.detach_()从创建它的图中分离出一个张量,并将其设置为叶张量。
实际上相当于变量之间的关系是
x - m - y
。这里叶张量是X,但此时对M进行m.detach_()运算,实际上是两个运算:将m的grad_fn的值设置为None,这样m就不再与前一个节点X关联,这里的关系就变成了
x, m - y,
。此时m会变成一个叶子节点,然后将m的requirements _ grad设置为False,这样Y向后()时就不会计算m的梯度。
总结:
其实detach()和detach_()很像。两者的区别在于,detach_()是对自身的改变,而detach()则生成一个新的张量。比如在x-m-y上拆离()m,以后后悔了还是可以操作原来的计算图的。
但是如果进行了detach_()的话,那么原来的计算图也发生了变化,就不能反悔了。