张量类Tensor的实现

关于维度的预备知识
在tensor张量中,共有三维数据进行顺序存放,分别是channels(维度),rows(行高), cols(行宽),三维矩阵我们可以看作多个连续的二维矩阵组成,最简单的方法就是使用嵌套的vector数组,但是这种方法非常不利于数据的访问(尤其是内存不连续的问题)修改以及查询,特别是在扩容的时候非常不方便,能满足使用需求。
因此,综合考虑灵活性和开发的难易度,我们会以armadillo类中的arma::mat(矩阵 matrix)类和arma::cube作为数据管理(三维矩阵)类来实现tensor 我们库中类的主体,一个cube由多个matrix组成,cube又是tensor类中的数据实际管理者。
首先我们讲讲tensor类和armadillo中两个类的关系,可以从下方图看出tensor类中的数据均由arma::cube类进行管理扩充,我们设计的类以arma::cube为基础实现了tensor类,我们主要是提供了更方便的访问方式和对外接口。
arma::cube是一个三维矩阵,分别是通道维度(slices或者channels),行维度(rows)和列维度(cols),请看下图1, 图中是两个5行3列的矩阵,蓝色的区域是数据的实际存储区,灰色和和白色部分仅用作示意,在内存中实际不存在。
一个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.
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() 将三维的矩阵展开铺平为一维的。
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)中的数据。
再谈谈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.
如果将顺序的一组数据[0,1,2,3,4,5....128]存放到一个大小为4×4的matrix中,那么大家需要注意一个问题,我们的数据管理类tensor(arma::cube)是列主序的,这一点和opencv cv::mat或者python numpy有一些不同。列主序在内存中的顺序如下表:


通过单个PMIC为您的计算密集型应用处理器供电
水质检测器电路
在Java中如何使用API来完成邮件的接收与发送
视频结构化怎样实现突破
芯动科技风华系列芯片填补国内高性能数据中心显卡空白
张量类Tensor的实现
半入耳式蓝牙耳机推荐,半入耳蓝牙耳机推荐高性价比
Qualcomm推出面向Windows 10 PC的骁龙850移动计算平台
8月比亚迪销量出炉!三款热销车型详解
vga线接头焊接方法(vga接口图)
5G和Wi-Fi 6促进发展,预计到2025年全球联网设备的数量将翻一番多
莱迪思MachXO3 FPGA系列 助力新兴互连接口设计
和沐渥一起探讨:常用的控制板加工制造设备有哪些?
物联网风险意识在消费者和企业之间存在差异
十款智能遥控小车设计
索尼将发售限量版PS4 TPCast多用户无线VR套件正式面向欧洲发布
切比雪夫综合法的Matlab程序
夜视应用的CMOS图像传感器的特性和说明
一加5什么时候发布?会不会又是有价无市?
英国首相表示就美国政府对华为制裁所产生的影响