pytorch的初步使用

1、pytorch基本语法

1.1认识pytorch

什么是pytorch
  • pytorch是一个基于numpy的科学计算包,向它的使用者提供两大功能
    • 向用户提供使用GPU强大功能的能力
    • 作为一款深度学习的平台,向用户提供最大的灵活性与速度
pytorch的基本元素操作
  • tensors张量:张量的概念类似于numpy中的ndarray数据结构,最大的区别在于tensor可以利用GPU的加速功能
  • 我们使用pytorch的时候,常规操作是将torch 引入
import torch
  • 创建矩阵的操作
    • 创建一个没有初始化的矩阵
    x=torch.empty(5,3)
    x
    
    • 输出结果
    tensor([[9.9184e-39, 9.0000e-39, 1.0561e-38],
            [1.0653e-38, 4.1327e-39, 8.9082e-39],
            [9.8265e-39, 9.4592e-39, 1.0561e-38],
            [6.7041e-39, 1.1112e-38, 9.5511e-39],
            [1.0102e-38, 9.0918e-39, 1.0469e-38]])
    
    • 创建一个有初始化的矩阵
    x=torch.rand(5,3)
    x
    
    • 输出结果
    tensor([[0.6362, 0.8270, 0.9099],
            [0.6367, 0.3966, 0.7022],
            [0.6347, 0.6491, 0.7345],
            [0.4258, 0.7607, 0.5514],
            [0.8695, 0.7048, 0.7198]])
    
  • 对比有无初始化的矩阵:当声明一个未初始化的矩阵时,它本身不包含任何确切的值,当创建一个未初始化的矩阵时,分配给矩阵的内存中有什么数值就赋值给了这个矩阵,本质上是毫无意义的数据
  • 创建一个全零矩阵并可指定数据元素的类型为long
    x=torch.zeros(5,3,dtype=torch.long)
    x
    
    • 输出结果
    tensor([[0, 0, 0],
            [0, 0, 0],
            [0, 0, 0],
            [0, 0, 0],
            [0, 0, 0]])
    
  • 直接通过数据创建张量
    x=torch.tensor([2.5,3.5])
    x
    
    • 输出结果
    tensor([2.5000, 3.5000])
    
  • 通过已有的张量创建相同尺寸的新张量
    #利用news_methods方法得到一个张量
    x=x.new_ones(5,3,dtype=torch.double)
    print(x)
    #利用randn_like方法得到相同张量尺寸的一个新张量,并采用随机初始化来对其赋值
    y=torch.rand_like(x,dtype=torch.float)
    y
    
    • 输出结果
    tensor([[1., 1., 1.],
            [1., 1., 1.],
            [1., 1., 1.],
            [1., 1., 1.],
            [1., 1., 1.]], dtype=torch.float64)
    tensor([[0.7829, 0.0101, 0.0631],
            [0.2268, 0.9584, 0.2150],
            [0.0471, 0.2468, 0.4159],
            [0.1639, 0.6118, 0.8197],
            [0.8424, 0.4187, 0.1257]])
    
  • 得到张量的尺寸
    print(x.size())
    print(y.size())
    
    • 输出结果
    
    torch.Size([5, 3])
    torch.Size([5, 3])
    

📌注意

torch.Size函数本质上是返回的一个tuple,因此它支持一切元组的操作

a,b=x.size()
print("a=",a)
print("b=",b)

  • 输出结果
a= 5
b= 3
pytorch的基本运算操作
  • 加法操作
    x=torch.rand(5,3)
    y=torch.rand(5,3)
    x+y
    
    • 输出结果
    tensor([[1.4247, 1.0858, 0.9374],
            [1.6952, 0.6679, 1.7217],
            [0.8453, 1.5807, 0.7486],
            [0.5964, 0.6290, 1.5933],
            [1.7306, 0.9639, 1.3272]])
    
  • 第二种加法方式
    #调用add方法
    print(torch.add(x,y))
    
    
    • 输出结果
    tensor([[0.3530, 1.1992, 1.3401],
            [1.1715, 1.0932, 0.7382],
            [0.2289, 0.4667, 0.1676],
            [0.7239, 1.1013, 1.0996],
            [0.8246, 0.6548, 1.3755]])
    
  • 第三种加法方式
    #提前设定一个空的张量
    result=torch.empty(5,3)
    #将空的张量作为加法的结果存储张量
    torch.add(x,y,out=result)
    result
    
    
    • 输出结果
    tensor([[0.3530, 1.1992, 1.3401],
            [1.1715, 1.0932, 0.7382],
            [0.2289, 0.4667, 0.1676],
            [0.7239, 1.1013, 1.0996],
            [0.8246, 0.6548, 1.3755]])
    
    
  • 第四种加法方式:in-place(原地置换)
    y.add_(x)
    y
    
    • 输出结果
    tensor([[0.3530, 1.1992, 1.3401],
            [1.1715, 1.0932, 0.7382],
            [0.2289, 0.4667, 0.1676],
            [0.7239, 1.1013, 1.0996],
            [0.8246, 0.6548, 1.3755]])
    
    

📌注意

  • 所有in-place的操作函数都有一个下划线的后缀
  • 比如x.copy (y),x.add(y),都会直接改变x的值
  • 用类似于Numpy的方式对张量进行操作
    # 切片操作
    # 取所有的行,第二列的数据
    x[:,1]
    
    • 输出结果
    tensor([0.7256, 0.1973, 0.1387, 0.9497, 0.0471])
    
  • 改变张量的形状:torch.view()
    x=torch.randn(4,4)
    # tensor.view()操作需要保证数据元素的总数量不变
    y=x.view(16)
    # -1代表自动匹配个数
    # 用-1 去匹配行,固定死列数为8
    z=x.view(-1,8)
    print(x.size(),y.size(),z.size())
    
    • 输出结果
    torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])
    
  • 如果张量中只有一个元素,可以用.item()将值取出,作为一个python类型的number
    # 只有一个的时候才可以直接取出该数值
    x=torch.randn(1)
    print(x)
    print(x.item())
    
    • 输出结果
    tensor([-2.0162])
    -2.0162177085876465
    
关于Torch Tensor和Numpy array之间的相互转换
  • Torch Tensor和Numpy array共享底层的内存空间,因此改变其中一个值,另一个也会随之被改变
    a=torch.ones(5)
    a
    
    • 输出结果
    tensor([1., 1., 1., 1., 1.])
    
  • 将Torch Tensor 转换为Numpy array
    b=a.numpy()
    b
    
    • 输出结果
    array([1., 1., 1., 1., 1.], dtype=float32)
    
  • 对其中一个进行加法操作,另一个也随之被改变
    a.add_(1)
    print(a)
    print(b)
    
    • 输出结果
    
    tensor([2., 2., 2., 2., 2.])
    [2. 2. 2. 2. 2.]
    
  • 将Numpy array 转换为Torch Tensor
    import numpy as np
    a=np.ones(5)
    b=torch.from_numpy(a)
    print(a)
    print(b)
    np.add(a,1,out=a)
    print(a)
    print(b)
    
    • 输出结果
    [1. 1. 1. 1. 1.]
    tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
    [2. 2. 2. 2. 2.]
    tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
    

📌注意

  • 所有在CPU上的Tensors,除了CharTensor,都可以转换为Numpy array 并可以反向转换
  • 关于Cuda Tensor :Tensors可以用.to()方法来将其移到到任意设备上
    #判断服务器上是否安装了GPU和CUDA
    if torch.cuda.is_available():
        #定义一个设备对象,这里指定成CUDA,即使用GPU
        device=torch.device("cuda")
        #直接在GPU上创建y,在CPU上创建张量x
        x=torch.randn(1)
        #直接在GPU上创建一个Tensor
        y=torch.ones_like(x,device=device)
        #将在CPU上面的x张量移到GPU上面
        x=x.to(device)
        #此时x和y都在GPU上面,才可以进行加法运算
        z=x+y
        #此处的张量z在GPU上
        print(z)
        #在将z转移到CPU上面进行打印
        print(z.to("cpu",torch.double))
    
    
    • 输出结果
    tensor([0.8107], device='cuda:0')
    tensor([0.8107], dtype=torch.float64)
    

1.1小节总结

  • 什么是pytorch
    • pytorch是一个基于numpy的科学计算包
      • 向用户提供使用GPU强大功能的能力
      • 作为一款深度学习的平台,向用户提供最大的灵活性与速度
  • pytorch基本元素操作
    • 矩阵的初始化
      • torch.enpty()
      • torch.rand(n,m)
      • torch.zeros(n,m,dtype=torch.long)
    • 其他操作
      • x.new_ones(n,m,dtype=torch.doubl)
      • torch.randn_like(x,dtype=torch.float)
      • x.size()
  • pytorch 基本运算操作
    • 加法操作
      • x+y
      • torch.add(x,y)
      • torch.add(x,y,out=result)
      • y.add _(x)
    • 其他操作
      • x.view()
      • x.item()
  • Torch Tensor 和Numpy Array 之间的相互转化
    • Torch Tensor 转化为Numpy Array
      • b=a.numpy()
    • Numpy Array 转化为Torch Tensor
      • b=torch.from_numpy(a)
    • 注意 只有在CPU上的Tensor,除了charTensor,都可以转化为NumpyArray 并可以反向转化
  • 任意Tensors可以使用.to()方法将其移到到任意设备上
    • x=x.to(device)

1.2 pytorch 中的autograd

学习目标

  • 掌握自动求导中的tensor概念和操作
  • 掌握自动求导中的梯度Gradients概念和操作

  • 在整个pytorch框架中,所有的神经网络本质上都是一个autograd package(自动求导工具包)
    • autograd package 提供了一个对 Tensors上所有的操作进行自动微分的功能

关于torch.tensor
  • torch.tensor 是整个package中的核心类,如果属性requires_grad设置为True,它将追踪在这个类上定义的所有操作。当代码要进行反向传播时,直接调用.backward()就可以自动计算所有的梯度。在这个tensor上的所有梯度将被累加进属性.gard中
  • 如果想终止一个tensor在计算图中的追踪回溯,只需要执行.detach()就可以将该tensor从计算图中撤下,在未来的回溯计算中也不会再计算该tensor。
  • 除了.detach(),如果要终止对计算图的回溯,也就是不再进行方向传播求导数的过程;也可以采用代码块方式with.torch.no_gard(),这种方法非常适合于对模型进行预测的时候,因为预测阶段不再需要对梯度进行计算。

  • 关于torch.function
    • function类和tensor类同等重要的一个核心类,它和tensor共同构建了一个完整的类,每一个tensor拥有一个.grad_fn属性,代表引用了那个具体的function创建了该tensor
    • 如果某个张量tensor是用户自定义的,则对应的grad_fn is None
关于tensor的操作
x1=torch.ones(3,3)
print(x1)
x=torch.ones(2,2,requires_grad=True)
print(x)

  • 结果
    tensor([[1., 1., 1.],
            [1., 1., 1.],
            [1., 1., 1.]])
    tensor([[1., 1.],
            [1., 1.]], requires_grad=True)
    

  • 在具有requires_grad=True 的tensor上进行一个加法操作
y=x+2
print(y)

  • 结果
    tensor([[3., 3.],
            [3., 3.]], grad_fn=<AddBackward0>)
    
  • 打印tensor的grad_fn 属性
print(x.grad_fn)
print(y.grad_fn)
  • 结果
    None
    <AddBackward0 object at 0x000002185AE06BE0>
    
  • 在tensor上执行更复杂的操作
z=y*y*3
out=z.mean()
print(z,out)
  • 结果
    tensor([[27., 27.],
            [27., 27.]], grad_fn=<MulBackward0>) tensor(27., grad_fn=<MeanBackward0>)
    
  • 关于方法.requires_grad_() 该方法可以原地改变tensor的属性 requires_grad的值 如果没有主动设定默认为False
a=torch.randn(2,2)
a=((a*3)/(a-1))
print(a.requires_grad)
a.requires_grad_(True)
print(a.requires_grad)
b=(a*a).sum()
print()
print(b.grad_fn)
  • 结果
    False
    True
    <SumBackward0 object at 0x000002185AE066A0>
    
关于梯度gradients
  • 在pytorch中,反向传播是依靠.backward()实现的
out.backward()
print(x.grad)
  • 结果
    tensor([[4.5000, 4.5000],
            [4.5000, 4.5000]])
    
  • 关于自动求导的属性设置 可以通过设置.requires_grad=True 来执行自动求导,也可以通过代码块的限制来停止自动求导
print(x.requires_grad)
print((x**2).requires_grad)
#终止自动求导
with torch.no_grad():
    print((x**2).requires_grad)
  • 结果
True
True
False
  • 可以通过.detach()获得一个新的tensor,拥有相同的内容但不需要自动求导
#通过.detach()方法获得新的tensor
print(x.requires_grad)
y=x.detach()
print(y.requires_grad)
print(x.eq(y).all())# eq()是数值上的比较
  • 结果
True
False
tensor(True)

1.2 小节总结

  • torch.tensor类的相关概念
    • torch.tensor 是整个package中的核心类,如果属性requires_grad设置为True,它将追踪在这个类上定义的所有操作。当代码要进行反向传播时,直接调用.backward()就可以自动计算所有的梯度。在这个tensor上的所有梯度将被累加进属性.gard中
    • 执行.detach()命令,就可以将该tensor从计算图中撤下,在未来的回溯计算中也不会再计算该tensor。
    • 采用代码块的方式也可以终止对计算图的回溯
      • with.torch.no_grad():
  • 关于tensor 的若干操作
    • torch.ones(n,n,requires_grad=True)
    • x.grad_fn
    • a.requires_grad_(True)
  • 关于gradients的属性
    • x.grad
    • 通过.detach()获得一个新的tensor,拥有相同的内容但不需要自动求导
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值