0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

张量类Tensor的实现

jf_pmFSk4VX 来源:GiantPandaCV 2023-01-13 11:51 次阅读

关于维度的预备知识

Tensor张量中,共有三维数据进行顺序存放,分别是Channels(维度),Rows(行高), Cols(行宽),三维矩阵我们可以看作多个连续的二维矩阵组成,最简单的方法就是使用嵌套的vector数组,但是这种方法非常不利于数据的访问(尤其是内存不连续的问题)修改以及查询,特别是在扩容的时候非常不方便,能满足使用需求。

因此,综合考虑灵活性和开发的难易度,我们会以Armadillo类中的arma::mat(矩阵 matrix)类和arma::cube作为数据管理(三维矩阵)类来实现Tensor 我们库中类的主体,一个cube由多个matrix组成,cube又是Tensor类中的数据实际管理者。

首先我们讲讲Tensor类和Armadillo中两个类的关系,可以从下方图看出Tensor类中的数据均由arma::cube类进行管理扩充,我们设计的类以arma::cube为基础实现了Tensor类,我们主要是提供了更方便的访问方式和对外接口

5b93a7ea-82d5-11ed-bfe3-dac502259ad0.jpg

arma::cube是一个三维矩阵,分别是通道维度(slices或者channels),行维度(rows)和列维度(cols),请看下图1, 图中是两个5行3列的矩阵,蓝色的区域是数据的实际存储区,灰色和和白色部分仅用作示意,在内存中实际不存在。

5bbbaa06-82d5-11ed-bfe3-dac502259ad0.jpg

一个cube类由多个这样的Matrix组成,图1中表示的情况是arma::cube(2, 5, 3), 表示当前的三维矩阵共有2个矩阵构成,每个矩阵都是5行3列的。如果放在我们项目中会以这形式提供 Tensor tensor(2, 5, 3).

下图2是这种情况下的三维结构图,可以看出一个Cube一共有两个Matrix,也就是共有两个Channel. 一个Channel放一个Matrix. Matrix的行宽均为Rows和Cols.

5c0fda2c-82d5-11ed-bfe3-dac502259ad0.jpg

Tensor方法总览

我们从上面可以知道,我们的Tensor类是对armdillo库中cube类的封装,cube是多个Matrix的集合(二维矩阵的集合),关系图如上图1、图2. 我们在这里对KuiperInfer中Tensor类的方法进行一个总览,其中我们会让大家亲自动手实现两个方法(加粗的两个),只有动手起来才能参与其中。

类名 功能
rows() 返回Tensor的行数
cols() 返回Tensor的列数
Fill(float value) 填充Cube中的数据,以value值填充
「Padding(std::vectorvalues)」 调整Matrix的维度,让Rows和Cols变大一点:)
at(uint32_t channel, row, col) 返回Cube中第channel维,第row行,第col列的数据。
index(uint32_t offset) 以另外一种方法来返回数据,返回Cube中第offset个数据,比如说在row行,col列,c维的一个数据,除了可以用tensor.at(c, row, col)方法访问。我们也可以通过tensor.index(c × Rows × Cols + row × Cols + col)这种方式来访问。可以参考图4, 展平后的Matrix, at接口更适合用来存放展平后的数据。
「Fill(std::vectorvalues)」 另外一个Fill方法, 我们需要以values中的所有数据去填充Tensor中的数据管理器cube类,注意values中数据的数量要等于Cube的行数×列数×维度
Flatten() 将三维的矩阵展开铺平为一维的。

5c1b2b16-82d5-11ed-bfe3-dac502259ad0.jpg

Tensor类模板

Tensor共有两个类型,一个类型是Tensor,另一个类型是Tensor, Tensor 可能会在后续的量化课程中进行使用,目前还暂时未实现,所以在之后的文章中我们以Tensor来指代Tensor.

如何创建一个Tensor

Tensor tensor(3, 5, 3). 在我们的KuiperInfer项目中,我们可以用一个非常简单的方式来创建一个张量实例,在如上的定义中,我们得到了一个通道数量为3,行数(rows)为5,列数(cols)为3的tensor变量。

如何访问Tensor中数据(我们要大家实现的功能)

我们将在这个项目中为Tensor类定义多种访问内部数据的方式。首先要讲的是顺序访问方式,在tensor变量中,我们可以使用tensor.at(0, 1, 2)得到tensor变量中第0通道,第1行,第2列中存放的元素。

另外一种,我们可以使用tensor.index(0)这种方法来得到tensor变量中第0个数据 。我会在作业系统中给予大家充分的提示,让大家准确无误地把代码写出来。从下图中可以看出,tensor.at(0,1,2)就是访问图中对应位置的点。第1个矩阵(channel = 0)中第2行(row = 1),第3列(col=2)中的数据。

5c331d5c-82d5-11ed-bfe3-dac502259ad0.jpg

再谈谈Tensor类中数据的排布

我们以具体的图片作为例子,来讲讲Tensor中数据管理类arma::cube的数据排布方式,Tensor类是arma::cube对外更方便的接口,所以说armadillo::cube怎么管理内存的,Tensor类就是怎么管理内存的,希望大家的能理解到位。

如下图中的一个Cube,Cube的维度是2,每个维度上存放的是一个Matrix,一个Matrix中的存储空间被用来存放一张图像(lena) . 一个框内(channel) 是一个Matrix,Matrix1存放在Cube第1维度(channel 1)上,Matrix2存放在Cube的第2维度上(channel 2). Matrix1和Matrix2的Rows和Cols均代表着图像的高和宽,在本例中就是512和384.

5c478828-82d5-11ed-bfe3-dac502259ad0.jpg

如果将顺序的一组数据[0,1,2,3,4,5....128]存放到一个大小为4×4的Matrix中,那么大家需要注意一个问题,我们的数据管理类Tensor(arma::cube)是列主序的,这一点和Opencv cv::Mat或者python numpy有一些不同。列主序在内存中的顺序如下表:

5c5e2164-82d5-11ed-bfe3-dac502259ad0.jpg





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • tensorflow
    +关注

    关注

    13

    文章

    313

    浏览量

    60308

原文标题:自制深度学习推理框架-张量类Tensor的实现-第二课

文章出处:【微信号:GiantPandaCV,微信公众号:GiantPandaCV】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    TensorFlow获取张量形状的操作tfshape属性shape及方法

    TensorFlow 获取张量形状的操作 tfshape()、属性shape 及 方法get_shape() 的基本用法及实例代码
    发表于 06-13 15:03

    TensorFlow常量、变量和占位符详解

    以下三种类型的张量:常量:常量是其值不能改变的张量。变量:当一个量在会话中的值需要更新时,使用变量来表示。例如,在神经网络中,权重需要在训练期间更新,可以通过将权重声明为变量来实现。变量在使用前需要
    发表于 07-22 16:12

    TensorFlow教程|张量的阶、形状、数据类型

    TensorFlow用张量这种数据结构来表示所有的数据.你可以把一个张量想象成一个n维的数组或列表.一个张量有一个静态类型和动态类型的维数.张量可以在图中的节点之间流通.阶在Tenso
    发表于 07-27 18:30

    什么是Tensor Flow Lite?

    Tensor Flow Lite 是Google I/O 2017大会上的推出的,是专门针对移动设备上可运行的深度网络模型简单版。
    发表于 11-23 12:16

    yolov5训练的tflite模型进行对象检测不适用于NNStreamer 2.2.0-r0?

    ,格式=RGB!张量转换器!tensor_filter framework=tensorflow2-lite model=./my_model-int8.tflite accelerator=true
    发表于 05-17 12:44

    使用OpenVINO运行C++ API创建输入tensor并执行推理遇到的问题求解

    使用 OpenVINO™ 运行时 C++ API 创建输入 tensor 并执行推理: ov::Tensor input_tensor = ov::Tensor(input_type
    发表于 08-15 08:22

    NVIDIA Volta GPU中内置的Tensor Core GPU架构是NVIDIA深度学习平台的巨大进步

    Tensor Core所运行的张量应位于存储器的channel-interleaved型数据布局(数量-高度-宽度-通道数,通常称为NHWC),以实现最佳性能。训练框架预期的内存布局是通道主序的数据
    的头像 发表于 05-21 17:35 8988次阅读
    NVIDIA Volta GPU中内置的<b class='flag-5'>Tensor</b> Core GPU架构是NVIDIA深度学习平台的巨大进步

    探索一下机器学习领域中最受欢迎的十大框架或工具库

    Tensorflow 把神经网络运算抽象成运算图(Graph),一个运算图中包含了大量的张量Tensor)运算。而张量实际上就是 N 维数据的集合。神经网络运算的本质是通过张量运算来
    的头像 发表于 10-04 09:21 1996次阅读

    谷歌宣布开源张量计算库TensorNetwork及其API

    张量是一种多维数组,根据数组元素的顺序按层级分类:例如,普通数是零阶张量(也称为标量),向量可视为一阶张量,矩阵可视为二阶张量等等。低阶张量
    的头像 发表于 06-23 09:54 3400次阅读
    谷歌宣布开源<b class='flag-5'>张量</b>计算库TensorNetwork及其API

    Vitis AI - 如何利用张量提升内存使用效率达到内存优化效果

    张量tensor) 的神奇之处在于多个张量可以引用同一存储空间(即包含给定类型的数字的连续内存区块)。此行为由 torch.storage 进行管理。 每个张量都包含 .sto
    的头像 发表于 09-29 10:35 1783次阅读

    五个简单步骤掌握TensorFlow中的Tensor

    在这篇文章中,我们将深入研究Tensorflow Tensor实现细节。我们将在以下五个简单步骤中介绍与Tensorflow的Tensor中相关的所有主题:第一步:张量的定义→什么是
    的头像 发表于 12-24 14:35 762次阅读

    基于张量的车辆交通数据缺失估计方法

    ( IntegrateBayesian Tensor Decomposition,IBTD)。该算法在数据模型构建阶段,利用随机采样原理,将缺失数据随机抽取生成数据子集,并用优化后的贝叶斯张量分解算法进行插补。引入集成思想,将多个插补后的误差结果进行分析排序,考虑
    发表于 06-17 15:39 5次下载

    什么是张量处理单元(TPU)

    该项目的目的是创建一个与谷歌的张量处理单元具有相似架构的机器学习协处理器。该实现的资源可定制,可以以不同的尺寸使用以适应每种类型的 FPGA。这允许在嵌入式系统和物联网设备中部署该协处理器
    的头像 发表于 04-27 09:27 3322次阅读

    如何使用张量核在CUDA C++设备代码中编程

      新 Volta GPU 架构的一个定义性特征是它的 张量核 ,它使 Tesla V100 加速器的峰值吞吐量是上一代 Tesla P100 的 32 位浮点吞吐量的 12 倍。张量核心使人工智能程序员能够使用 混合精度 来实现
    的头像 发表于 04-28 16:45 1717次阅读
    如何使用<b class='flag-5'>张量</b>核在CUDA C++设备代码中编程

    PyTorch的简单实现

    PyTorch 的关键数据结构是张量,即多维数组。其功能与 NumPy 的 ndarray 对象类似,如下我们可以使用 torch.Tensor() 创建张量。如果你需要一个兼容 NumPy 的表征,或者你想从现有的 NumPy
    的头像 发表于 01-11 16:29 1037次阅读
    PyTorch的简单<b class='flag-5'>实现</b>