本教程整理自书籍《深度学习框架PyTorch:入门与实践》
-
torch.Size 是python tuple的子类,.size() 查看tensor的大小
-
x.add_(y)
会改变x本身,x.add(y)
不会改变x本身 -
tensor 和 numpy的转换
numpy = tensor.numpy() tensor = torch.from_numpy(numpy_obj) # example import numpy as np a = np.ones(5) b = t.from_numpy(a) # Numpy->Tensor print(a) print(b) # [1. 1. 1. 1. 1.] #tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
note: tensor 和 numpy共享一块内存,其中一个改变会使得另一个也改变
b.add_(1) # 以`_`结尾的函数会修改自身 print(a) print(b) # Tensor和Numpy共享内存 #[2. 2. 2. 2. 2.] #tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
-
标量(0维tensor)读取
scalar.item()读取0维tensor的值scalar = b[0] scalar.size() print(scalar) # tensor(2., dtype=torch.float64) print(scalar.item()) # 2.0
note:
tensor = torch.tensor([2]) #一维tensor,虽然只有一个值 print(tensor.size(), scalar.size()) #torch.Size([1]), torch.Size([]) # 但是只有一个元素的tensor也可以调用`torch.item()` print(tensor.item(), scalar.item()) # (2, 2.0)
-
torch.tensor() 与np.array()使用方法几乎相同
但是tenor()总会进行数据拷贝,即新tensor和原来的数据不再共享内存,所以如果想共享内存的话,使用tensor.detach()来新建一个tensor或者使用torch.from_numpy()tensor = t.tensor([3,4]) # 新建一个包含 3,4 两个元素的tensor old_tensor = tensor new_tensor = t.tensor(old_tensor) new_tensor[0] = 1111 print(old_tensor, new_tensor) # tensor([3, 4]), tensor([1111, 4]) # 1.0.0 版本推荐使用以下语法从原tensor中拷贝 new_tensor_recommmeded = old_tensor.clone().detach() # or 新tensor可以求梯度 new_tensor_recommmeded_requires_grad = old_tensor.clone().detach().requires_grad_(True) # 共享内存 new_tensor = old_tensor.detach() new_tensor[0] = 1111 print(old_tensor, new_tensor) # tensor([1111, 4]), tensor([1111, 4])
6.autograd
从0.4起, tensor支持Variable实现的自动微分功能,Variable(tensor)实际上啥都没操作。需要使用tensor的autograd功能,只需设置
tensor.required_grad = True
note: tensor有三个属性在反向传播中比较重要- tensor: 保存本身的值
- grad: 保存反向传播的梯度值
- grad_fn: 保存反向传播的计算函数
#为tensor设置 requires_grad 标识,代表着需要求导数 # pytorch 会自动调用autograd 记录操作 x = t.ones(2, 2, requires_grad=True) # 上一步等价于 # x = t.ones(2,2) # x.requires_grad = True x # tensor([[ 1., 1.], # [ 1., 1.]], requires_grad=True) y = x.sum() # tensor(4., grad_fn=<SumBackward0>) y.grad_fn #指向一个function对象,该对象用来反向传播输入的梯度 # <SumBackward0 at 0x25f019eb7b8> y.backward() #反向传播,计算梯度 # y = x.sum() = (x[0][0]+x[0][1]+x[1][0]+x[1][1]) 可以看出每个值的梯度为1 x.grad #保留x每一个变量的梯度值 # tensor([[ 1., 1.], # [ 1., 1.]])
note:
grad
在每一次运行反向传播时,都会累加之前grad
保留的梯度,所以反向传播之前需要把梯度清零y.backward() x.grad # tensor([[ 2., 2.], # [ 2., 2.]]) # 以下划线结束的函数是inplace操作,会修改自身的值 x.grad.zeor_() y.backward() x.grad() # # tensor([[1., 1.], # [1., 1.]])