paddle点灯人之tensor(代码片段)

风信子的猫Redamancy 风信子的猫Redamancy     2022-12-15     718

关键词:

Paddle 点灯人 之 Tensor

文章目录

Paddle点灯人介绍

Paddle点灯人这个专栏,我希望更多是给予部分已有深度学习基础亦或者是想快速部署应用的进行学习,这样利用paddle做出更简单更好的方法,因为如果从0开始写Paddle的使用和介绍,我相信paddle的文档已经很详细了,如果想从0开始学,可以查看https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/index_cn.html

所以我希望我基于此,更多的是为了,让大家在学习torch的同时,对paddle也有一定了解,可以使用paddle更便捷的部署在自己的项目中,这样能加快学习的效率,也可以免费使用paddle的GPU资源,有更好的产出和应用部署。

Tensor介绍

Tensor,又名张量,读者可能对这个名词似曾相识,可以说他几乎在所有的深度学习框架中都出现过,也是Theano、TensorFlow、
Torch和MxNet中重要的数据结构。关于张量的本质不乏深度的剖析,但从工程角度来讲,可简单地认为它就是一个数组,且支持高效的科学计算。它可以是一个数(标量)、一维数组(向量)、二维数组(矩阵)和更高维的数组(高阶数据)。Tensor和Numpy的ndarrays类似,和pytorch一样的是,他们都可以运行在 GPU 及各种 AI 芯片上,以实现计算加速。

Pytorch和Paddle的相似之处

Paddle和Pytorch是两个流行的深度学习框架。Paddle是由百度开发的开源框架,而Pytorch是由英伟达开发的开源框架。它们都提供了大量的工具和功能,帮助开发人员构建和训练深度学习模型。

那我们为什么写Pytorch版的Paddle呢,这个名字取的有点奇怪哈哈,这就是我的一个小小的理解,或者说,在这一部分,几乎可以认为两者是差不多的,似乎这是一个Pytorch版的paddle,为什么这么说呢,如果你有学习过Pytorch,你会发现其实Paddle的张量很多操作都是类似与Pytorch的方法,这也可能会更好的从Pytorch迁移到Paddle中,两者也更容易进行转化,还是非常方便进行学习迁移和部署的。

不过,Paddle和Pytorch之间也有一些区别。Paddle专注于提供高性能的分布式训练和计算,而Pytorch提供了更多用于计算机视觉和自然语言处理的工具。此外,Paddle和Pytorch使用不同的技术和算法,因此它们可能在某些情况下表现不同。例如,Paddle使用了更多的预训练模型和数据集,而Pytorch则提供了更多的模型自定义选项和更为灵活的模型训练过程。

创建张量Tensor

与 Numpy 创建数组方式类似,通过给定 Python 序列(如列表 list、元组 tuple),可使用 paddle.to_tensor 创建任意维度的 Tensor。示例如下:

(1)创建类似向量(vector)的 1 维 Tensor:

import paddle # 后面的示例代码默认已导入 paddle 模块
ndim_1_Tensor = paddle.to_tensor([2.0, 3.0, 4.0])
print(ndim_1_Tensor)
Tensor(shape=[3], dtype=float32, place=Place(gpu:0), stop_gradient=True,
       [2., 3., 4.])

特殊地,如果仅输入单个标量(scalar)数据(例如 float/int/bool 类型的单个元素),则会创建形状为 [1] 的 Tensor,即 0 维 Tensor:

paddle.to_tensor(2)
paddle.to_tensor([2])
# 上述两种创建方式完全一致,形状均为 [1],输出如下:
Tensor(shape=[1], dtype=int64, place=Place(gpu:0), stop_gradient=True,
       [2])

(2)创建类似矩阵(matrix)的 2 维 Tensor:

ndim_2_Tensor = paddle.to_tensor([[1.0, 2.0, 3.0],
                                  [4.0, 5.0, 6.0]])
print(ndim_2_Tensor)
Tensor(shape=[2, 3], dtype=float32, place=Place(gpu:0), stop_gradient=True,
       [[1., 2., 3.],
        [4., 5., 6.]])

(3)创建 3 维 Tensor:

ndim_3_Tensor = paddle.to_tensor([[[1, 2, 3, 4, 5],
                                   [6, 7, 8, 9, 10]],
                                  [[11, 12, 13, 14, 15],
                                   [16, 17, 18, 19, 20]]])
print(ndim_3_Tensor)
Tensor(shape=[2, 2, 5], dtype=int64, place=Place(gpu:0), stop_gradient=True,
       [[[1 , 2 , 3 , 4 , 5 ],
         [6 , 7 , 8 , 9 , 10]],

        [[11, 12, 13, 14, 15],
         [16, 17, 18, 19, 20]]])

上述不同维度的 Tensor 可视化的表示如下图所示:

图 不同维度的 Tensor 可视化表示

图片/文本转Tensor

其实对于pytorch来说,我们有一个东西叫transform,里面可以直接进行ToTensor,也就是将读入的图片直接转化为Tensor张量,同理来说,Paddle也有相类似的方法,里面也有一个tramsforms函数,也有一个ToTensor方法,所以说两者的方法格式还是非常类似的。

  • 对于图像场景,可使用 paddle.vision.transforms.ToTensor 直接将 PIL.Image 格式的数据转为 Tensor,使用 paddle.to_tensor 将图像的标签(Label,通常是 Python 或 Numpy 格式的数据)转为 Tensor。
  • 对于文本场景,需将文本数据解码为数字后,再通过 paddle.to_tensor 转为 Tensor。不同文本任务标签形式不一样,有的任务标签也是文本,有的则是数字,均需最终通过 paddle.to_tensor 转为 Tensor。
import numpy as np
from PIL import Image
import paddle.vision.transforms as T
import paddle.vision.transforms.functional as F

fake_img = Image.fromarray((np.random.rand(224, 224, 3) * 255.).astype(np.uint8)) # 创建随机图片
transform = T.ToTensor()
tensor = transform(fake_img) # 使用 ToTensor()将图片转换为 Tensor
print(tensor)
Tensor(shape=[3, 224, 224], dtype=float32, place=Place(gpu:0), stop_gradient=True,
       [[[0.78039223, 0.72941178, 0.34117648, ..., 0.76470596, 0.57647061, 0.94901967],
         ...,
         [0.49803925, 0.72941178, 0.80392164, ..., 0.08627451, 0.97647065, 0.43137258]]])

有趣的是,我仔细看看打印的结果,在pytorch中的device,在paddle中是place,说明指定的GPU运行,以及pytorch的gradient的自动求导的机制,paddle中为stop_gradient,所以两者还是很类似的。

DataLoader不需要加ToTensor

paddle还有一些不同的点,例如 paddle.io.DataLoader 能够基于原始 Dataset,返回读取 Dataset 数据的迭代器,迭代器返回的数据中的每个元素都是一个 Tensor,不需要类似与Pytorch每次都需要写一个ToTensor

import paddle

from paddle.vision.transforms import Compose, Normalize

transform = Compose([Normalize(mean=[127.5],
                               std=[127.5],
                               data_format='CHW')])

test_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)
print(test_dataset[0][1]) # 打印原始数据集的第一个数据的 label
loader = paddle.io.DataLoader(test_dataset)
for data in enumerate(loader):
    x, label = data[1]
    print(label) # 打印由 DataLoader 返回的迭代器中的第一个数据的 label
    break
[7] # 原始数据中 label 为 Python list
Tensor(shape=[1, 1], dtype=int64, place=Place(gpu_pinned), stop_gradient=True,
       [[7]]) # 由 DataLoader 转换后,label 为 Tensor

Paddle中的 Tensor 的属性

在前文中,可以看到打印 Tensor 时有 shape、dtype、place 等信息,这些都是 Tensor 的重要属性,想要了解如何操作 Tensor 需要对其属性有一定了解,接下来分别展开介绍 Tensor 的属性相关概念。

形状 shape

首先shape大家其实已经很了解了,这里主要介绍一下,修改shape的一些方法,有

  • paddle.reshape 可重置 Tensor 的形状

  • paddle.squeeze,可实现 Tensor 的降维操作,即把 Tensor 中尺寸为 1 的维度删除。

  • paddle.unsqueeze,可实现 Tensor 的升维操作,即向 Tensor 中某个位置插入尺寸为 1 的维度。

  • paddle.flatten,将 Tensor 的数据在指定的连续维度上展平。

  • paddle.transpose,对 Tensor 的数据进行重排。

数据类型(dtype)

Tensor 的数据类型 dtype 可以通过 Tensor.dtype 查看,支持类型包括:boolfloat16float32float64uint8int8int16int32int64complex64complex128

同一 Tensor 中所有元素的数据类型均相同,通常通过如下方式指定:

  • 通过给定 Python 序列创建的 Tensor,可直接使用 dtype 参数指定。如果未指定:
    • 对于 Python 整型数据,默认会创建 int64 型 Tensor;
    • 对于 Python 浮点型数据,默认会创建 float32 型 Tensor,并且可以通过 paddle.set_default_dtype 来调整浮点型数据的默认类型。

Tensor 的设备位置(place)

初始化 Tensor 时可以通过 Tensor.place 来指定其分配的设备位置,可支持的设备位置有:CPU、GPU、固定内存、XPU(Baidu Kunlun)、NPU(Huawei)、MLU(寒武纪)、IPU(Graphcore)等。其中固定内存也称为不可分页内存或锁页内存,其与 GPU 之间具有更高的读写效率,并且支持异步传输,这对网络整体性能会有进一步提升,但其缺点是分配空间过多时可能会降低主机系统的性能,因为其减少了用于存储虚拟内存数据的可分页内存。

说明:

  • 当未指定 place 时,Tensor 默认设备位置和安装的飞桨框架版本一致。如安装了 GPU 版本的飞桨,则设备位置默认为 GPU,即 Tensor 的place 默认为 paddle.CUDAPlace
  • 使用 paddle.device.set_device 可设置全局默认的设备位置。Tensor.place 的指定值优先级高于全局默认值。

以下示例分别创建了 CPU、GPU 和固定内存上的 Tensor,并通过 Tensor.place 查看 Tensor 所在的设备位置:

  • 创建 CPU 上的 Tensor
cpu_Tensor = paddle.to_tensor(1, place=paddle.CPUPlace())
print(cpu_Tensor.place)
Place(cpu)
  • 创建 GPU 上的 Tensor
gpu_Tensor = paddle.to_tensor(1, place=paddle.CUDAPlace(0))
print(gpu_Tensor.place) # 显示 Tensor 位于 GPU 设备的第 0 张显卡上
Place(gpu:0)
  • 创建固定内存上的 Tensor
pin_memory_Tensor = paddle.to_tensor(1, place=paddle.CUDAPinnedPlace())
print(pin_memory_Tensor.place)
Place(gpu_pinned)

stop_gradient 属性

这个属性很像Pytorch,也就是说明是否求导,也就是是否计算梯度,stop_gradient 表示是否停止计算梯度,默认值为 True,表示停止计算梯度,梯度不再回传。在设计网络时,如不需要对某些参数进行训练更新,可以将参数的 stop_gradient 设置为 True。可参考以下代码直接设置 stop_gradient 的值。

eg = paddle.to_tensor(1)
print("Tensor stop_gradient:", eg.stop_gradient)
eg.stop_gradient = False
print("Tensor stop_gradient:", eg.stop_gradient)
Tensor stop_gradient: True
Tensor stop_gradient: False

Tensor 与 Numpy 数组相互转换

这一部分也几乎和Pytorch是一模一样的,所以如果你已熟悉 Numpy,通过以下要点,可以方便地理解和迁移到 Tensor 的使用上:

  • Tensor 的很多基础操作 API 和 Numpy 在功能、用法上基本保持一致。如前文中介绍的指定数据、形状、区间创建 Tensor,Tensor 的形状、数据类型属性,Tensor 的各种操作,以及 Tensor 的广播,可以很方便地在 Numpy 中找到相似操作。
  • 但是,Tensor 也有一些独有的属性和操作,而 Numpy 中没有对应概念或功能,这是为了更好地支持深度学习任务。如前文中介绍的通过图像、文本等原始数据手动或自动创建 Tensor 的功能,能够更便捷地处理数据,Tensor 的设备位置属性,可以很方便地将 Tensor 迁移到 GPU 或各种 AI 加速硬件上,Tensor 的 stop_gradient 属性,也是 Tensor 独有的,以便更好地支持深度学习任务。

如果已有 Numpy 数组,可使用 paddle.to_tensor 创建任意维度的 Tensor,创建的 Tensor 与原 Numpy 数组具有相同的形状与数据类型。

tensor_temp = paddle.to_tensor(np.array([1.0, 2.0]))
print(tensor_temp)
Tensor(shape=[2], dtype=float64, place=Place(gpu:0), stop_gradient=True,
       [1., 2.])

注意:

  • 基于 Numpy 数组创建 Tensor 时,飞桨是通过拷贝方式创建,与原始数据不共享内存。

相对应地,飞桨也支持将 Tensor 转换为 Numpy 数组,可通过 Tensor.numpy 方法实现。

tensor_to_convert = paddle.to_tensor([1.,2.])
tensor_to_convert.numpy()
array([1., 2.], dtype=float32)

总结

在学习过程中,我发现对于这一部分来说,Paddle和Pytorch有高度相似性,如果掌握了其中一个,另一个的Tensor张量操作就已经拿捏了,因为两者是非常之像的,可以互通的。

此外,这一部分参考了一下Paddle的文档https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/beginner/tensor_cn.html,里面写的更详细更全面,如果你从0开始学起可以看看整篇文档。

paddle点灯人之10分钟快速上手paddle(代码片段)

Paddle点灯人之10分钟快速上手Paddle文章目录Paddle点灯人之10分钟快速上手Paddle一、快速安装飞桨二、导入飞桨三、实践:手写数字识别任务3.1数据集定义与加载3.2模型组网3.3模型训练与评估3.3.1模型训练3.3.2模型评估3.4模型推... 查看详情

paddle点灯人之paddle介绍

Paddle点灯人之Paddle介绍文章目录Paddle点灯人之Paddle介绍选择Paddle学习的原因Paddle免费提供的强大算力资源Paddle简单介绍Paddle的优势Paddle相关资料汇总选择Paddle学习的原因首先,我想讲一下,为什么我想学习paddle,或者... 查看详情

paddle网络中的tensor数据结构(代码片段)

简介:※Tensor是Paddle深度框架中的重要概念。对于Tensor概念介绍-使用文档-PaddlePaddle深度学习平台文档中的概念进行学习和测试,对比了Tensor于numpy中的ndarray之间的差异。关键词:Tensor,numpy,paddle#mermaid-svg-SFv... 查看详情

paddle下的tensor运算以及简单回归问题(代码片段)

简介:※在Paddle下利用其中的基本函数设计了对于普通线性和Logistic回归问题,特别是针对网络系数的结构的观察,这位之后能够对于网络进行修改打下基础。关键词:Paddle,线性回归,Logistics#mermaid-svg-tOV... 查看详情

pytorch中torch.cat()和paddle中的paddle.concat()函数用法(代码片段)

...着dim=n的方向进行拼接;x必须是list或者tuple类型的tensor.例子:importtorchx1=torch.tensor([[1,2,3],[4,5,6]])x2=torch.tensor([[11,12,13],[14,15,16]])x3=torch.tensor([[21,22],[23,24]])out1=torch.cat([x1,x2,x3],dim=-1)#(dim=-1:横着拼接... 查看详情

paddle报valueerror:thetypeofdatawearetryingtoretrievedoesnotmatchthetype(代码片段)

...l::CppTypeToDataType<T>::Type():13.](at/paddle/paddle/phi/core/dense_tensor.cc:137)[operator<matmu 查看详情

paddle报valueerror:thetypeofdatawearetryingtoretrievedoesnotmatchthetype(代码片段)

...l::CppTypeToDataType<T>::Type():13.](at/paddle/paddle/phi/core/dense_tensor.cc:137)[operator<matmu 查看详情

aistudio:利用paddle框架中的极简框架识别mnist(代码片段)

...熟悉了Paddle下的网络架构方式。对于如果从numpy到Paddle的tensor转换程序中也给出了示例。关键词:AIStudio,Paddle,MNIST#mermaid-svg-chCkFdVHfPP37ZB6.labelfont-family:\'trebuchetms\',verdana,arial;font-family:var(--mermaid-font-family);fill:#333;color:... 查看详情

paddle实践(代码片段)

Dockerimage阅读:https://github.com/PaddlePaddle/book/blob/develop/README.cn.mddockerrun-d-p8888:8888paddlepaddle/book 查看详情

安装paddle-使用百度镜像(代码片段)

安装paddle使用百度镜像pipinstallpaddlepaddle==2.2.1-ihttps://mirror.baidu.com/pypi/simple普通安装方式,报错。Lookinginindexes:https://pypi.tuna.tsinghua.edu.cn/simpleCollectingpaddleUsingcachedhttps://py 查看详情

paddle关于[paddle.load]文档超链接显示问题的pr日志(代码片段)

1.Issue信息操作路径:使用指南⇒模型保存与加载⇒关键字:加载时还需要之前的模型组网代码Develop链接Develop-paddle.load2.PR修改过程添加修改记录:gitadd. 查看详情

paddle设计思想

...一个ProgramDesc,用户通过调用paddle提供算子来向Program添加tensor以及对变量的操作Operators,用户只需描述前向计算,原始的programDesc转化为一个中间语言Transplier。  一个paddle中通常存在两个program,  fluid.default_star 查看详情

炫酷rgb之.netnanoframework点灯大师(代码片段)

...HSV、PWM等相关知识。1.背景ESP32开发第一步,基本是先点灯吧?点灯,点灯,点灯 查看详情

arduinoesp32入门点灯程序(代码片段)

ArduinoESP32入门点灯程序点灯前提是,你需要提前安装esp32支持固件包。ESP32开发资料1.74G,从入门到入土。链接:https://pan.baidu.com/s/1kSxiO9kwWGMhzr6WCPdVYw提取码:8x8m示例程序:呼吸灯效果示例程序需要修改板子led... 查看详情

micropythonrp2040点灯实验(代码片段)

MicroPythonRP2040点灯实验本实验基于Thonny平台本示例所使用的版本;YD-RP2040版(源地YD-RP2040)源地YD-RP2040开发板资料:http://152.32.187.208:8080/yd-data/YD-RP2040/本实验YD-RP2040开发板所烧录的固件:PimoroniPicoLiPo固件下载地址:https 查看详情

paddle实现resnet复现(代码片段)

文章目录一、介绍二、对总体网络的介绍1、网络亮点2、网络构成3、网络结构三、论文复现3.1导入工具包3.2建立Basicblock3.3建立Bottleneckblock3.4搭建Resnet的主干3.5具象化网络四、查看网络结构五、测试网络是否可以使用一、介绍ResNe... 查看详情

paddle报valueerror:thetypeofdatawearetryingtoretrievedoesnotmatchthetype(代码片段)

错误原因在使用paddlepaddle训练模型的时候,使用numpy随机生成一些数据来训练一个线程模型的时候报Thetypeofdatawearetryingtoretrievedoesnotmatchthetypeofdatacurrentlycontainedinthecontainer错误信息 pre_bias=_C_ops.matmul_v2(x,weight, 查看详情

micropythonesp32/8266ap模式下网页点灯控制示例(代码片段)

【Micropythonesp32/8266】AP模式下网页点灯控制示例📍相关篇《【Micropythonesp32/8266】网页点灯控制示例》⛳####前面一篇是关于STA模式下网页控制,本次带来的是Micropython设备作为AP模式下,去访问设备,并控制点灯程... 查看详情