requires_grad_()会修改Tensor的requires_grad属性。
detach()会返回一个与计算图分离的新Tensor,新Tensor不会在反向传播中计算梯度,会在特定场合使用。
torch.no_grad()更节省计算资源和存储资源,其作用域范围内的操作不会构建计算图,常用在网络推断中。
代码中的detach和required_grad的引入是减少了计算量,required_grad=false会计算误差,不计算wb的梯度
(原因在于一个网路如果是ABC层这样的连接方式,B不求梯度,但是A还是会获得梯度,这就需要计算B的误差,从而传播到A,而计算B中参数的梯度就没有必要了)
而detach会切断反向传播,不计算误差也不计算梯度。
参数 requires_grad 的含义及标志位说明:
- 如果对于某Variable 变量 x ,其x.requires_grad == True , 则表示它可以参与求导,也可以从它向后求导。默认情况下,一个新的Variables 的 requires_grad 和 volatile 都等于 False 。
- requires_grad == True 具有传递性,例如:
x.requires_grad == True ,y.requires_grad == False , z=f(x,y)
则, z.requires_grad == True。 - 凡是参与运算的变量(包括 输入量,中间输出量,输出量,网络权重参数等),都可以设置 requires_grad 。
- volatile==True 就等价于 requires_grad==False 。 volatile==True 同样具有传递性。一般只用在inference(推理)过程中。若是某个过程,从 x 开始都只需做预测,不需反传梯度的话,那么只需设置x.volatile=True ,那么 x 以后的运算过程的输出均为 volatile==True ,即 requires_grad==False 。
由于inference 过程不必backward(),所以requires_grad 的值为False 或 True,对结果是没有影响的,但是对程序的运算效率有直接影响;因此,在inference过程中,使用volatile=True ,就不必把运算过程中所有参数都手动设一遍requires_grad=False 了,方便快捷。 - detach() :如果 x 为中间输出,x’ = x.detach 表示创建一个与 x 相同,但requires_grad==False 的variable,(实际上是把x’ 以前的计算图 grad_fn 都消除了),x’ 也就成了叶节点。原先反向传播时,回传到x时还会继续,而现在回到x’处后,就结束了,不继续回传求到了。另外值得注意,x (variable类型) 和 x’ (variable类型)都指向同一个Tensor ,即 x.data,因此,detach_() 表示不创建新变量,而是直接修改 x 本身。
- retain_graph:每次 backward() 时,默认会把整个计算图free掉。一般情况下是每次迭代,只需一次 forward() 和一次 backward() ,前向运算forward() 和反向传播backward()是成对存在的,一般一次backward()也是够用的。但是不排除,由于自定义loss等的复杂性,需要一次forward()之后,通过多个不同loss的backward()来累积同一个网络的grad,进行参数更新。于是,若在当前backward()后,不执行forward() 而可以执行另一个backward(),需要在当前backward()时,指定保留计算图,即backward(retain_graph)。
讲的极好