PyTorch学习1

1.PyTorch

1.1 什么是PyTorch?

PyTorch是Torch的python版本,是由Facebook开源的神经网络框架,专门针对 GPU 加速的深度神经网络(DNN)编程。Torch 是一个经典的对多维矩阵数据进行操作的张量(Tensor )库,在机器学习和其他数学密集型应用中有广泛应用。与Tensorflow的静态计算图不同,PyTorch的计算图是动态的,可以根据计算需要实时改变计算图。

1.2 PyTorch包含的功能

  • 张量计算引擎(tensor computation)

    Tensor 计算引擎,类似 numpy 和 matlab,基本对象是Tensor(类比 numpy 中的 ndarray 或 matlab 中的 array)。除提供基于 CPU 的常用操作的实现外,PyTorch还提供了高效的 GPU 实现,这对于深度学习至关重要。

  • 自动求导机制(autograd),自动微分(automatic differentiation)

    由于深度学习模型日趋复杂,因此,对自动求导的支持对于学习框架变得必不可少。PyTorch采用了动态求导机制。作为对比,Theano,Tensorflow 采用静态自动求导机制。

  • 神经网络的高层库(NN)

    PyTorch还提供了高层的API实现常用的网络结构,如全连接、卷积、RNN 等。同时,PyTorch还提供了常用的optimizer。

导入库:

# 导入需要的库
import torch
# 虽然它被称为PyTorch,但是代码中使⽤torch⽽不是pytorch

2.张量

2.1 什么是张量?

在数学中

一个单独的数可以称为标量,一列或者一行数组可以称为向量,一个二维数组称为矩阵,矩阵中的每一个元素都可以被行和列的索引唯一确定,如果数组的维度超过2, 那么我们可以称该数组为张量(Tensor)

在PyTorch中

张量属于一种数据结构,它可以是一个标量、一个向量、一个矩阵,甚至是更高维度的数组,所以PyTorch中Tensor和NumPy库中的数组( ndarray )非常相似,在使用时也会经常将PyTorch中的张量和NumPy中的数组相互转化。在深度网络中,基于PyTorch的相关计算和优化都是在Tensor的基础上完成的。

张量的本质是类(成员如下):

  • data: 被包装的Tensor
  • dtype: 张量的数据类型,如torch.float
  • shape: 张量的形状,如(64, 3, 224, 224)
  • device: 张量所在设备,GPU/CPU,是加速的关键
  • requires_grad: 指示是否需要梯度
  • grad: data的梯度
  • grad_fn: 创建Tensor的Function,是自动求导的关键
  • is_leaf: 指示是否是叶子结点(张量)

2.2 张量的数据类型

不同的Tensor类型之间可以相互转换

Data typedtypeCPU tensorGPU tensor
32-bit 浮点型torch.float32 or torch.floattorch.FloatTensortorch.cuda.FloatTensor
64-bit 浮点型torch.float64 or torch.doubletorch.DoubleTensortorch.cuda.DoubleTensor
16-bit 半精度浮点型torch.float16 or torch.halftorch.HalfTensortorch.cuda.HalfTensor
8-bit无符号整型torch.uint8torch.ByteTensortorch.cuda.ByteTensor
8-bit有符号整型torch.int8torch.CharTensortorch.cuda.CharTensor
16-bit有符号整型torch.int16 or torch.shorttorch.ShortTensortorch.cuda.ShortTensor
32-bit有符号整型torch.int32 or torch.inttorch.IntTensortorch.cuda.IntTensor
64-bit有符号整型torch.int64 or torch.longtorch.LongTensortorch.cuda.LongTensor

2.3 numpy和Tensor的区别

对比项numpyTensor
相同点可以定义多维数组,进行切片、改变维度、数学运算等可以定义多维数组,进行切片、改变维度、数学运算等
不同点1、产生的数组类型为numpy.ndarray;
2、会将ndarray放入CPU中进行运算;
3、导入方式为import numpy as np,后续通过np.array([1,2])建立数组;
4、numpy中没有x.type()的用法,只能使用type(x)。
1、产生的数组类型为torch.Tensor;
2、会将tensor放入GPU中进行加速运算(如果有GPU);
3、导入方式为import torch,后续通过torch.tensor([1,2])或torch.Tensor([1,2])建立数组;
4、Tensor中查看数组类型既可以使用type(x),也可以使用x.type()。但是更加推荐采用x.type()。

2.4 创建张量

函数功能
Tensor(*sizes)基础构造函数
tensor(data,)类似np.array的构造函数
ones(*sizes)全1的Tensor
zeros(*sizes)全0的Tensor
eye(*sizes)对角线为1,其他为0
arange(s,e,step)从s到e,步长为step
linspace(s,e,steps)从s到e,均匀切分成steps份
rand / randn(*sizes)均匀/标准分布
normal(mean,std) / uniform(from,to)正态分布/均匀分布
randperm(m)随机排列
tensor.new_* / torch.*_like创建一个相同size大小,用*类型去填充(如tensor.new_ones就是使用全一的数据去填充)的张量,具有相同的torch.dtype和torch.device

2.4.1 使用tensor()函数创建张量

# 使用torch.tensor()函数生成张量,对于已有的数据(列表,数组等)也可以通过该函数构造张量
A = torch.tensor([[1.0,1.0],[2,2]])

# 获取张量的形状
# 属性
print(A.shape)
# 方法
print(A.size())

# 计算张量中所含元素的个数
A.numel()

# 指定张量的数据类型和是否要计算梯度,注意只有浮点数才可以计算梯度
B = torch.tensor((1,2,3), dtype=torch.float32, requires_grad=True)

2.4.2 使用Tensor()类创建张量

# 使用torch.Tensor()类创建张量,可以指定生成张量的形状
# 创建具有特定大小的张量
print(torch.Tensor(2,3))

# torch.Tensor(1)返回一个大小为1的张量,它是初始化的随机值
print(torch.Tensor(1))
# torch.tensor(1)返回一个固定值1
print(torch.tensor(1))

# 使用预先存在的数据创建张量
A = torch.Tensor([1,2,3,4])

# 同样类似的还有torch.FloatTensor,IntTensor等
B = torch.FloatTensor(2,3)
C = torch.DoubleTensor(2,3)

2.4.3 Tensor与numpy的相互转换

# 张量与NumPy的相互转换
# 利用numpy数组生成张量
import numpy as np
F = np.ones((3,3))
# numpy转tensor
# 使用torch.as_tensor()函数,浅拷贝
Ftensor = torch.as_tensor(F)
# 使用torch.from_numpy()函数,浅拷贝
Ftensor = torch.from_numpy(F)
# 使用torch.tensor()函数,深拷贝
Ftensor = torch.tensor(F)
# tensor转numpy
# 使用张量的.numpy()将张量转化为numpy数组
Ftensor.numpy()

2.4.4 随机数生成张量

# 随机数生成张量
# 设置随机数种子
torch.manual_seed(123)
# 通过指定均值和标准差生成随机数
A = torch.normal(mean=0.0, std=torch.arange(1,5.0))
# 可以分别指定每个随机数服从的均值
B = torch.normal(mean = torch.arange(1,5.0), std=torch.arange(1,5.0))
# 在区间[0,1)上生成服从均匀分布的张量
print(torch.rand(3,4))
# 生成与一个张量维度相同的随机数张量
C = torch.ones(2,3)
D = torch.rand_like(C)
# 生成服从标准正态分布的随机数
print(torch.randn(3,3))
print(torch.randn_like(C))
# 将0~10(不包括10)之间的整数随机排序
torch.randperm(10)

2.4.5 批量生成张量

# 使用torch.arange()生成张量
# 在torch.arange()中,参数start指定开始,参数end指定结束,参数step则指定步长
torch.arange(start=0, end = 10, step=2)
# 在范围内生成固定数量的等间隔张量,steps表示分割的点数,默认为100
torch.linspace(start=1, end=10, steps=5)
# 生成以对数间隔的点
torch.logspace(start=0.1, end=1.0, steps=5)

2.4.6生成特定的张量

# 生成特定的张量
# 全0张量
torch.zeros(3,3)
# 全1张量
torch.ones(3,3)
# 单位张量
torch.eye(3)
# 空张量
torch.empty(3,3)
# 使用0.25作为填充的张量
torch.full((3,3),fill_value = 0.25)
# 创建一个与B相同大小和类型的全 1 张量
print(torch.ones_like(B))
# 使用torch.zeros_like()函数生成与B维度相同的全0张量
print(torch.zeros_like(B))
# 使用torch.rand_like()函数生成与B维度相同的随机张量
print(torch.rand_like(B))

2.5 Tensor与图像之间的转换

图像转张量

import torch
import cv2
import numpy as np
from torchvision import transforms


def test():
    # print(torch.__version__)
    # print(torch.cuda.is_available())

    im = cv2.imread("./qi_e.png")
    # 对图像数据做预处理
    transform = transforms.Compose([
        transforms.ToPILImage(),  # 将NumPy数组转换为PIL图像
        transforms.Resize((224, 224)),  # 调整图像大小
        transforms.ToTensor(),  # 转换为张量
    ])
    img = transform(im)
    img = img.cuda()
    print(img)
    print(img.device)


if __name__ == "__main__":
    test()

张量转图像

# 将张量转换为 NumPy 数组
numpy_image = image_tensor.numpy().transpose(1, 2, 0)  # (H, W, C)

# 将图像转换回 BGR 格式(OpenCV 使用 BGR)
bgr_image = cv2.cvtColor(numpy_image, cv2.COLOR_RGB2BGR)

2.6 Tensor的索引

PyTorch的索引与NumPy数组的索引类型,可以按位置索引,可以切片等

A = torch.randn(3, 4)
print("查看第1行结果:", A[0])
print("查看第2列结果:", A[:,1])
print("查看第2行最后两个元素:", A[1, -2:])

2.7 Tensor的基本运算

A = torch.arange(6.0).reshape(2,3)
B = torch.linspace(10,20,steps=6).reshape(2,3)
# print("A:",A)
# print("B:",B)
# 矩阵相乘,×乘,行乘以列
print(A @ B)
print(A.matmul(B))
AB = torch.matmul(A, B)
print(AB)
# 矩阵逐元素相乘,点乘
print(A * B)
# 逐元素相除
print(A / B)
# 逐元素整除
print(B//A)
# 逐元素相加
print(A + B)
# 逐元素相减
print(A - B)
# 张量的幂
print(torch.pow(A, 3))
print(A ** 3)
# 张量的指数
print(torch.exp(A))
# 张量的对数
print(torch.log(A))
# 张量的平方根
print(torch.sqrt(A))
print(A**0.5)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值