pytorch学习历程1, pytorch基础知识要点autograd,detach等

本教程整理自书籍《深度学习框架PyTorch:入门与实践》

  1. torch.Size 是python tuple的子类,.size() 查看tensor的大小

  2. x.add_(y)会改变x本身,x.add(y)不会改变x本身

  3. 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)
    
  4. 标量(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)
    
  5. 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有三个属性在反向传播中比较重要

    1. tensor: 保存本身的值
    2. grad: 保存反向传播的梯度值
    3. 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=)
       y.grad_fn  #指向一个function对象,该对象用来反向传播输入的梯度
       # 
       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.]])
       
    

你可能感兴趣的:(pytorch,记录)