- torch.Tensor 和torch.tensor的区别
torch.Tensor(data)是类,将输入的data转化torch.FloatTensortorch.tensor(data)是函数,(当你未指定dype的类型时)将data转化为torch.FloatTensor、torch.LongTensor、torch.DoubleTensor等类型,转化类型依据于data的类型或者dtype的值
- requires_grad_(), detach(), torch.no_grad()的区别
>>> a = torch.tensor([1.0])
>>> a.data
tensor([1.])
>>> a.grad
>>> a.requires_grad#是否需要计算梯度
False
>>> a.dtype
torch.float32
>>> a.item()#得到一个python数字
1.0
>>> type(a.item())
<class 'float'>
>>> a = torch.tensor([1.0, 2.0], requires_grad=True)
>>> with torch.no_grad():#上下文管理器,禁止梯度计算
... b = n.pow(2).sum()
...
>>> b
tensor(5.)
>>> b.requires_grad
False
>>> c = a.pow(2).sum()
>>> c.requires_grad
True
>>> a = torch.tensor([1.0, 2.0])
>>> b = a.data #.data返回新Tensor对象,不是一个tensor但是共享数据存储空间
>>> id(b)
139808984381768
>>> id(a)
139811772112328
>>> b.grad
>>> a.grad
>>> b[0] = 5.0
>>> b
tensor([5., 2.])
>>> a
tensor([5., 2.])
>>> a = torch.tensor([1.0, 2.0])
>>> a.data
tensor([1., 2.])
>>> a.grad
>>> a.requires_grad
False
>>> a.requires_grad_()#原位操作in place,默认操作为true
tensor([1., 2.], requires_grad=True)
>>> c = a.pow(2).sum()
>>> c.backward()
>>> a.grad
tensor([2., 4.])
>>> b = a.detach()#返回新的Tensor对象b,共享内存,但是requires_grad为false,不在计算图里
>>> b.grad
>>> b.requires_grad
False
>>> b
tensor([1., 2.])
>>> b[0] = 6
>>> b
tensor([6., 2.])
>>> a
tensor([6., 2.], requires_grad=True)
- .data与.detach()都生成新的Tensor且共享内存,grad都是false;区别是.data不会被autograd追踪,这样当进行backward()时它不会报错,回得到一个错误的backward值;.detach()会被跟踪,可能出错;.detach_():变量之间的关系本来是x -> m -> y,这里的叶子是x,但是这个时候对m进行了.detach_()操作,其实就是进行了两个操作:将m的grad_fn的值设置为None,变成x, m -> y,此时的m就变成了叶子结点,然后会将m的requires_grad设置为False,这样对y进行backward()时就不会求m的梯度。
a = torch.tensor([1, 2, 3.], requires_grad=True)
print(a.grad)
out = a.sigmoid()
print(out)
c = out.data
print(c)
c.zero_() #使用in place函数对其进行修改
#会发现c的修改同时也会影响out的值
print(c)
print(out)
#这里的不同在于.data的修改不会被autograd追踪,这样当进行backward()时它不会报错,回得到一个错误的backward值
out.sum().backward()
print(a.grad)
a = torch.tensor([1, 2, 3.], requires_grad=True)
print(a.grad)
out = a.sigmoid()
print(out)
c = out.data
print(c)
c.zero_() #使用in place函数对其进行修改
#会发现c的修改同时也会影响out的值
print(c)
print(out)
#这里的不同在于.data的修改不会被autograd追踪,这样当进行backward()时它不会报错,回得到一个错误的backward值
out.sum().backward()
print(a.grad)
```python
a = torch.tensor([1, 2, 3.], requires_grad=True)
print(a.grad)
out = a.sigmoid()
c = out.data#用detach的话,对c和out调用sum().backward()都会报错,但是如果用out = a.sigmoid().sum(),最后out.backward则不会
c.zero_() #使用in place函数对其进行修改
#会发现c的修改同时也会影响out的值
print(c)
print(out)
#这里的不同在于.data的修改不会被autograd追踪,这样当进行backward()时它不会报错,回得到一个错误的backward值
out.sum().backward()
print(a.grad)
原因:所有的Variable都会记录用在他们身上的 in-place operations。如果pytorch检测到variable在一个Function中已经被保存用来backward,但是之后它又被in-place operations修改。当这种情况发生时,在backward的时候,pytorch就会报错。这种机制保证了,如果你用了in-place operations,但是在backward过程中没有报错,那么梯度的计算就是正确的。
- pytorch里functional和module有什么区别?
- nn.Module实现的layer是由class Layer(nn.Module)定义的特殊类,会自动提取可学习参数nn.Parameter
- nn.functional中的函数更像是纯函数,由def function(input)定义.
- 对于激活函数和池化层,由于没有可学习参数,一般使用nn.functional完成,其他的有学习参数的部分则使用类。但是Droupout由于在训练和测试时操作不同,所以建议使用nn.Module实现,它能够通过model.eval加以区分。