# 张量

# 什么是张量

在计算机科学中,张量(Tensor)通常被定义为维空间中的一种量,它具有个分量,这种张量本质上是一个多维数组( multidimensional array)。张量的阶或秩是这个多维数组的维度,或者简单理解为索引张量里的每个元素所需要的索引个数。通常来说,0阶张量被定义为标量(Scalar),1阶张量被定义为向量(vector),而2阶张量被定义为矩阵(matrix)。比如,在一个三维空间中,1阶张量就是空间中点所表示的向量,其中分别表示这个点在三个轴上的坐标。

张量是一种高效的数学建模工具,它可以将复杂的问题通过统一、简洁的方式进行表达。比如,姜英俊同学做饭需要2斤牛肉、5斤土豆,市场上牛肉每斤32元、土豆每斤2元,那么购买这些食物总共花费元。如果用张量来描述,我们可以用一个1阶张量表示所需不同食物的重量。然后用另一个1阶张量表示不同食物的价格。最后,我们用一个0阶张量表示购买这些食物的总价,计算如下

c=a×bT=(25)×(322)=2×32+5×2=74\begin{aligned} c &\ =\ a\ \times\ b^T \\ &\ =\ \left(\begin{matrix}2 & 5\end{matrix}\right)\ \times\ \left(\begin{matrix}32 \\ 2\end{matrix}\right) \\ &\ =\ 2\ \times\ 32\ +\ 5\ \times\ 2 \\ &\ =\ 74 \end{aligned}

其中表示行向量的转置 - 列向量,表示向量的乘法。第二天,姜英俊同学换了一个市场,这里牛肉每斤35元、土豆每斤1元。如果要知道在两个市场分别购物的总价,可以把重新定义为一个2阶张量,总价定义为一个2阶张量。同样有

c=a×bT=(25)×(323521)=(7475)\begin{aligned} c &\ =\ a\ \times\ b^T \\ &\ =\ \left(\begin{matrix}2 & 5\end{matrix}\right)\ \times\ \left(\begin{matrix}32 & 35 \\ 2 & 1\end{matrix}\right) \\ &\ =\ \left(\begin{matrix}74 & 75\end{matrix}\right) \end{aligned}

即,在两个市场分别花费74元和75元。可以看出,利用张量可以对多样、复杂的问题进行建模,比如,可以进一步扩展上述问题中的定义,把它们定义成更高阶的张量,处理不同时间、不同市场、不同菜谱的情况,但是不论情况如何变化,都可以用同一个公式来描述问题。

许多现实世界的问题都可以被描述为张量表达式(expression),也就是把张量的组合、计算描述为算数表达式。这种建模方式也构成了现代神经网络模型及深度学习方法的基础。在许多机器学习工具中,张量计算已经成为了神经网络前向、反向传播等过程的基本单元,应用十分广泛。

# 如何定义张量

如果你是一名C/C++或者Python的使用者,那么在程序中使用NiuTensor定义张量将非常简单。首先,下载NiuTensor的工具包,并解压到任意目录,比如~/NiuTensor目录。我们会在NiuTensor这个目录中找到source子目录,它是存放源代码的目录。对于source子目录的结构,信息如下:

  • ~/NiuTensor/source/tensor/XCall.h - 定义了张量结构XTensor,以及构建和销毁XTensor的接口
  • ~/NiuTensor/source/tensor/core - 存放张量计算的函数声明及函数体实现的源文件
    • arithmetic - 存放有关算术运算的源文件
    • getandset - 存放有关数据存取的源文件
    • math - 存放有关数学运算的源文件
    • movement - 存放有关数据移动的源文件
    • reduce - 存放有关规约操作的源文件
    • shape - 存放有关形状转换的源文件
    • sort - 存放有关排序操作的源文件
  • ~/NiuTensor/source/tensor/function - 存放各种激活函数的源文件
  • ~/NiuTensor/source/tensor/loss - 存放各种损失函数的源文件
  • ~/NiuTensor/source/tensor/test - 存放单元测试的源文件
  • ~/NiuTensor/source/tensor/*.h(cpp) - 与张量定义不相关,后文介绍 😃

以C/C++为例,仅需要在源程序中引用XTensor.h头文件就可以完成张量的定义。下面是一个简单的示例程序sample.cpp

#include "XTensor.h"          // 引用XTensor定义的头文件

using namespace nts;          // 使用XTensor所在的命名空间nts

int main(int argc, const char ** argv)
{
    // 声明一个张量tensor,它的类型是XTensor
    XTensor tensor;                         
    
    // 初始化这个维度为50列*100行的张量(2阶张量,数据类型为X_FLOAT)      
    InitTensor2D(&tensor, 50, 100, X_FLOAT);
    
    // 之后可以使用张量tensor了
    
    return 0;
}

下一步,编译以上源程序,这个过程需要指定XTensor.h头文件所在目录。比如,使用g++编译sample.cpp

g++ sample.cpp -I~/NiuTensor/source/tensor -o sample

在sample.cpp中使用了XTensor,它是NiuTensor里的一个类,这个类定义了张量所需的数据结构,我们可以使用这个类轻松完成对张量的计算、拷贝等各种操作。XTensor类型的变量被声明后,还需要被初始化,或者说被真正指定为一个张量,比如,需要指定张量的各个维度、张量中每个单元的数据类型、给张量分配内存空间等。InitTensor2D就是一个张量初始化函数,它把张量初始化为一个矩阵,有四个参数:指向被初始化的张量的指针,矩阵的列数,矩阵的行数,数据单元的类型。这里X_FLOAT,是NiuTensor自定义的枚举类型,它表示单精度浮点数,我们也可以使用X_INT或X_DOUBLE,将数据类型指定为32bit整数或者双精度浮点数。

NiuTensor也提供了其它方式定义张量。比如可以直接调用一个函数完成张量的创建,而且可以显性释放张量。下面是一段示例代码(sample2.cpp):

#include "XTensor.h"         // 引用XTensor定义的头文件

using namespace nts;         // 使用XTensor所在的命名空间nts

int main(int argc, const char ** argv)
{
    // 构建一个单精度浮点类型张量,张量维度为50列*100行
    XTensor * tensor = NewTensor2D(50, 100, X_FLOAT);  
    
    // 之后就可以使用张量tensor了
    
    // 最后需要释放这个张量
    DelTensor(tensor);
    
    return 0;
}

sample2.cpp中使用的NewTensor2D和DelTensor是一组函数,前者生成张量并返回指向这个张量的指针,后者释放指针所指向张量的内容。这种方法比较适合C/C++风格的开发。

以下是关于张量定义的基础函数,函数接口在NiuTensor/source/tensor/XCall.h中定义:

功能 函数 参数
初始化张量 void InitTensor(
XTensor * tensor,
const int myOrder,
const int * myDimSize,
const TENSOR_DATA_TYPE myDataType,
const int myDevID,
const bool isEnableGrad)
tensor - 指向被初始化张量的指针
myOrder - 张量的维度
myDimSize - 张量每一维的大小,索引0表示第一维
myDataType - 张量的数据类型
myDevID - 张量所在的设备ID
isEnableGrad - 是否允许张量有梯度
创建空张量 XTensor * NewTensor() N/A
创建张量 XTensor * NewTensor(
const int myOrder,
const int * myDimSize,
const TENSOR_DATA_TYPE myDataType,
const int myDevID
const bool isEnableGrad)
myOrder - 张量的维度
myDimSize - 张量每一维的大小,索引0表示第一维
myDataType - 张量的数据类型
myDevID - 张量所在的设备ID
isEnableGrad - 是否允许张量有梯度
销毁张量 void DelTensor(XTensor * tensor) tensor - 指向要被销毁的张量的指针

上述函数中需要说明的是

  • 设备ID是指张量所申请的空间所在CPU或者GPU设备的编号,-1表示CPU
  • TENSOR_DATA_TYPE定义了张量的数据类型,包括:
类型 说明
X_INT 32bit整数
X_FLOAT 32bit浮点数
X_DOUBLE 64bit浮点数
X_INT8 8bit整数(计划支持)
X_FLOAT16 16bit浮点数(计划支持)

此外,NiuTensor也提供了更多种类的张量初始化和创建方法,详见~/NiuTensor/source/tensor/XCall.h。

# 访问张量中的内容

在C/C++中,我们通过XTensor.h访问张量中的内容。 在此部分,我们主要对用户在访问张量内容时涉及到的成员变量及方法进行说明。 在XTensor.h头文件中定义的常用成员变量说明:

成员变量 功能
void * data 保存元素的数据数组
int devID 设备ID,指张量所申请的空间所在CPU或者GPU设备的编号,-1表示CPU
int order 张量的维度,例如:一个矩阵(维度为2)是一个二维张量
int dimSize[MAX_TENSOR_DIM_NUM] 张量中每一维度的大小,索引0表示第1维
TENSOR_DATA_TYPE dataType 每个数据单元的数据类型
int unitSize 数据单元的大小
int unitNum 数据单元的数量
bool isSparse 是否稠密,一个n * m稠密矩阵的数据量大小为n * m,而稀疏(非稠密)矩阵的数据量大小则取决于矩阵中非零元素个数。
float denseRatio 稠密度,指非零单元的比例,是介于0和1之间的一个实数,0表示所有单元全为零,1表示全为非零单元。

在XTensor.h头文件中定义的部分方法说明:

功能 函数 参数
设置张量每一维度的大小 void SetDim(int * myDimSize) myDimSize - 张量每一维度的大小
得到张量中给定的维度大小 int GetDim(const int dim) const dim - 张量的维度
重新调整矩阵维度 void Reshape(
const int order, const int * myDimSize)
order - 张量的维度
myDimSize - 张量每一维的大小
得到张量中元素数量 int GetSize() const N/A
用数组赋值张量 void SetData(
const void * d, int num, int beg)
d - 赋值数组
num - 数组大小
beg - 赋值时从张量的第几位开始
张量中所有元素设置为0 void SetZeroAll(XStream * stream) stream - 多线程流
获取二维张量的值 DTYPE Get2D(int ni, int mi) const ni - 行值
mi - 列值
设置二维张量中
的单元值
bool Set2D(DTYPE value, int ni, int mi) value - 单元值
ni - 行值
mi - 列值
增加二维张量中
的单元值
bool Add2D(DTYPE value, int ni, int mi) value - 单元值
ni - 行值
mi - 列值
将矩阵重置为特定大小 bool Resize(
const int myOrder,
const int * myDimSize,
const TENSOR_DATA_TYPE myDataType,
const float myDenseRatio)
myOrder - 张量的维度
myDimSize - 张量每一维的大小,索引0表示第一维
myDataType - 张量的数据类型
myDenseRatio - 张量的稠密度,1表示稠密张量
将矩阵重置为
另一矩阵大小
bool Resize(
const XTensor * myTensor)
myTensor - 重置矩阵大小的参考矩阵

# 张量计算

NiuTensor提供关于张量计算的函数功能,主要包括一些基本的张量运算以及激活函数,在本节中,主要对这些函数及其用法用例进行介绍。我们以点乘(Multiply)操作为例介绍NiuTensor的几种推荐使用的函数定义形式:

  • Multiply: 输出张量需指定或为函数返回值,同时支持前向和反向操作
  • MultiplyMe: 输出张量与输入张量相同,只支持前向操作

# 代数计算(arithmetic)

此部分主要包括多种数学运算,如张量加法、减法、乘法(矩阵乘法、点乘)、除法、线性变换等。

# 除法(Div)

# 什么是张量的除法?

利用张量的除法运算可以将两个张量相除并得到一个新的张量,两个维度分别为的张量相除过程如下所示:

(0.01.02.03.0)÷(1.01.04.09.0)(0.01.00.50.3333)\left(\begin{matrix}0.0 & 1.0\\2.0 & 3.0\end{matrix}\right)\ ÷\ \left(\begin{matrix}1.0 & 1.0\\4.0 & 9.0\end{matrix}\right)\ \rightarrow\ \left(\begin{matrix}0.0 & 1.0\\0.5 & 0.3333\end{matrix}\right)

# 张量除法的调用

NiuTensor提供了张量的除法操作,函数接口在NiuTensor/source/tensor/core/arithmetic/Div.h中定义,计算方式为:

c(i)=a(i)b(i)+αc(i)c(i)\ =\ \frac{a(i)}{b(i)}\ +\ \alpha\ *\ c(i)

张量除法的调用方式以及参数说明如下所示:

void Div(const XTensor &a, const XTensor &b, XTensor &c, DTYPE alpha = 0.0, int leadingDim = 0)

void DivMe(XTensor &a, const XTensor &b, DTYPE alpha = 0.0, int leadingDim = 0)

XTensor Div(const XTensor &a, const XTensor &b, int leadingDim = 0)

Parameters:

  • a(XTensor&) - 输入张量(对DivMe函数而言,a同时为输出张量)
  • b(XTensor&) - 输入张量
  • c(XTensor&) - 输出张量
  • alpha(DTYPE) - 系数,默认为0
  • leadingDim(int) - 广播维度,沿某一维度执行广播操作,默认为0
# 张量除法片段示例

以最基本的二维矩阵除法为例,张量除法的示例代码为:

/* call Div function */
t = Div(*s1, *s2, 0)

张量除法的测试文件路径为:

NiuTensor/source/tensor/test/TDiv.cpp

# 张量屏蔽(Mask)

# 什么是张量屏蔽?

利用张量屏蔽,可以根据mask张量将输入张量对应位置的值设置为指定值。如果mask张量某个位置的值为0,则输出张量对应位置设置为(默认为0),否则设置为输入张量对应位置的值。

# 张量屏蔽的调用

NiuTensor提供了张量的屏蔽操作,函数接口在NiuTensor/source/tensor/core/arithmetic/Mask.h中定义。计算方式为:

{a(i)=a(i)ifmask(i)isnonzeroa(i)=αifmask(i)=0\begin{cases} a(i) = a(i) & if \quad mask\ (i) \quad is \quad non-zero \\ a(i) = \alpha & if \quad mask\ (i) = 0 \end{cases}

张量屏蔽的调用方式以及参数说明如下所示:

void Mask(const XTensor &a, const XTensor &mask, XTensor &c, DTYPE alpha = 0.0)

void MaskMe(XTensor &a, const XTensor &mask, DTYPE alpha = 0.0)

XTensor Mask(const XTensor &a, const XTensor &mask, XTensor &c, DTYPE alpha = 0.0)

Parameters:

  • a(XTensor&) - 输入张量(对MaskMe函数而言,a同时为输出张量)
  • mask(XTensor&) - 屏蔽张量
  • c(XTensor&) - 输出张量
  • alpha(DTYPE) - 系数,默认为0

# 矩阵乘法(MatrixMul)

# 什么是张量的矩阵乘法?

利用矩阵乘法可以将矩阵相乘并得到一个新的结果矩阵,两个维度分别为的矩阵相乘过程如下所示,结果矩阵的维度为

(1.02.03.04.05.06.0)×(0.01.01.02.02.01.0)(8.06.017.020.0)\left(\begin{matrix}1.0 & 2.0 & 3.0\\-4.0 & 5.0 & 6.0\end{matrix}\right)\ ×\ \left(\begin{matrix}0.0 & -1.0\\1.0 & 2.0\\2.0 & 1.0\end{matrix}\right) \ \rightarrow\ \left(\begin{matrix}8.0 & 6.0\\17.0 & 20.0\end{matrix}\right)

# 矩阵乘法的调用

NiuTensor提供了矩阵乘法的计算操作,在NiuTensor/tensor/core/arithmetic/MatrixMul.h中定义,函数定义为:

ci,j=trans(ai)trans(bj)α+ci,jβc_{i,j}\ =\ trans(a_i)\ *\ trans(b_j)\ *\ \alpha\ +\ c_{i,j}\ *\ \beta

矩阵乘法的调用方式以及参数说明如下所示:

void MatrixMul(const XTensor &a, MATRIX_TRANS_TYPE transposedA, const XTensor &b, MATRIX_TRANS_TYPE transposedB, XTensor &c,DTYPE alpha = (DTYPE)1.0, DTYPE beta = 0, XPRunner * parallelRunner = NULL)

XTensor MatrixMul(const XTensor &a, MATRIX_TRANS_TYPE transposedA, const XTensor &b, MATRIX_TRANS_TYPE transposedB, DTYPE alpha = (DTYPE)1.0, XPRunner * parallelRunner = NULL)

void MatrixMul(const XTensor &a, const XTensor &b, XTensor &c, DTYPE alpha = (DTYPE)1.0, XPRunner * parallelRunner = NULL)

XTensor MatrixMul(const XTensor &a, const XTensor &b, DTYPE alpha = (DTYPE)1.0, XPRunner * parallelRunner = NULL)

Parameters:

  • a(XTensor&) - 输入张量1
  • transposedA(MATRIX_TRANS_TYPE) - 输入张量1是否进行转置
  • b(XTensor&) - 输入张量2
  • transposedB(MATRIX_TRANS_TYPE) - 输入张量2是否进行转置
  • c(XTensor&) - 输出张量
  • alpha(DTYPE) - 系数,默认为1.0
  • beta(DTYPE) - 系数,默认为0.0
  • parallelRunner(XPRunner*) - 并行处理模块
# 矩阵乘法片段示例

以最基本的二维矩阵乘法为例,矩阵乘法的示例代码为:

/* call MatrixMul function */
t = MatrixMul(*s1, X_NOTRANS, *s2, X_NOTRANS);

矩阵乘法的的测试文件路径为:

NiuTensor/tensor/test/TMatrixMul.cpp

# 矩阵Batch乘法(MatrixMulBatched)

# 什么是张量间矩阵Batch乘法?

利用矩阵Batch乘法可以将矩阵相乘并得到一个新的结果矩阵,两个维度分别为的矩阵相乘过程如下所示,结果矩阵的维度为

((0.01.02.02.01.03.0),(1.02.04.03.01.02.0))×((1.02.04.03.02.06.0),(1.02.03.04.05.06.0))((8.09.04.025.0),(27.034.016.022.0))\begin{aligned} & \left(\left(\begin{matrix}0.0 & -1.0 & 2.0\\2.0 & 1.0 & 3.0\end{matrix}\right),\ \left(\begin{matrix}1.0 & 2.0 & 4.0\\3.0 & 1.0 & 2.0\end{matrix}\right)\right)\\ & \qquad \qquad \qquad \qquad × \\& \left(\left(\begin{matrix}1.0 & 2.0\\-4.0 & 3.0\\2.0 & 6.0\end{matrix}\right),\ \left(\begin{matrix}1.0 & 2.0\\3.0 & 4.0\\5.0 & 6.0\end{matrix}\right)\right) \end{aligned} \rightarrow \left(\left(\begin{matrix}8.0 & 9.0\\4.0 & 25.0\end{matrix}\right),\ \left(\begin{matrix}27.0 & 34.0\\16.0 & 22.0\end{matrix}\right)\right)

# 矩阵Batch乘法的调用

NiuTensor提供了矩阵Batch乘法的计算操作,在NiuTensor/tensor/core/arithmetic/MatrixMulBatched.h中定义,函数定义为:

ci=trans(ai)trans(bi)α+cmβc_i\ =\ trans(a_i)\ *\ trans(b_i)\ *\ \alpha\ +\ c_m\ *\ \beta

矩阵Batch乘法的调用方式以及参数说明如下所示:

XTensor MatrixMulBatched(const XTensor &a, MATRIX_TRANS_TYPE transposedA, const XTensor &b, MATRIX_TRANS_TYPE transposedB,DTYPE alpha = (DTYPE)1.0, XPRunner * parallelRunner = NULL)

XTensor MatrixMulBatched(const XTensor &a, const XTensor &b, DTYPE alpha = (DTYPE)1.0, XPRunner * parallelRunner = NULL)

Parameters:

  • a(XTensor&) - 输入张量1
  • transposedA(MATRIX_TRANS_TYPE) - 输入张量1是否进行转置
  • b(XTensor&) - 输入张量2
  • transposedB(MATRIX_TRANS_TYPE) - 输入张量2是否进行转置
  • alpha(DTYPE) - 系数,默认为1.0
  • parallelRunner(XPRunner*) - 并行处理模块,默认为NULL
# 矩阵Batch乘法片段示例

矩阵Batch乘法的示例代码为:

/* call MatrixMul function */
t = MatrixMulBatched(*s1, X_NOTRANS, *s2, X_NOTRANS);

矩阵Batch乘法的的测试文件路径为:

NiuTensor/tensor/test/TMatrixMulBatched.cpp

# 线性变换(MulAndShift)

# 什么是张量的线性变换?

利用线性变换可以将对输入张量进行线性变换并对结果进行偏移。

# 线性变换的调用

NiuTensor提供了张量线性变换的计算操作,在NiuTensor/tensor/core/arithmetic/MulAndShift.h中定义,函数定义为:

c=xw+bc\ =\ x\ *\ w\ +\ b

张量线性变换的调用方式以及参数说明如下所示:

XTensor MulAndShift(const XTensor &x, MATRIX_TRANS_TYPE transposedX, const XTensor &w, MATRIX_TRANS_TYPE transposedW, const XTensor &b, DTYPE alpha = (DTYPE)1.0, XPRunner * parallelRunner = NULL)

XTensor MulAndShift(const XTensor &x, const XTensor &w, const XTensor &b, DTYPE alpha = (DTYPE)1.0, XPRunner * parallelRunner = NULL)

Parameters:

  • x(XTensor&) - 输入张量
  • transposedX(MATRIX_TRANS_TYPE) - 输入张量是否进行转置
  • w(XTensor&) - 权重张量
  • transposedW(MATRIX_TRANS_TYPE) - 权重张量是否进行转置
  • b(XTensor&) - 偏置张量
  • alpha(DTYPE) - 系数,默认为1.0
  • parallelRunner(XPRunner*) - 并行处理模块,默认为NULL

# 点乘(Multiply)

# 什么是张量点乘?

利用张量间的点乘操作可以进行张量间元素的按位置依次相乘,两个维度分别为的张量点乘过程如下所示:

(0.01.02.03.0)(0.01.02.03.0)(0.01.04.09.0)\left(\begin{matrix}0.0 & 1.0\\2.0 & 3.0\end{matrix}\right)\ ·\ \left(\begin{matrix}0.0 & 1.0\\2.0 & 3.0\end{matrix}\right) \ \rightarrow \ \left(\begin{matrix}0.0 & 1.0\\4.0 & 9.0\end{matrix}\right)

# 张量点乘的调用

NiuTensor提供了张量点乘的计算操作,用来计算张量中元素点乘结果,该函数在NiuTensor/tensor/core/arithmetic/Multiply.h中定义,计算方式为:

ci,j=ai,jbi,j+ci,jαc_{i,j}\ =\ a_{i,j}\ *\ b_{i,j}\ +\ c_{i,j}\ *\ \alpha

张量点乘的调用方式以及参数说明如下所示:

void Multiply(const XTensor &a, const XTensor &b, XTensor &c, DTYPE alpha = 0.0, int leadingDim = 0)

void MultiplyMe(XTensor &a, const XTensor &b, DTYPE alpha = 0.0, int leadingDim = 0)

XTensor Multiply(const XTensor &a, const XTensor &b, DTYPE alpha = 0.0, int leadingDim = 0)

Parameters:

  • a(XTensor&) - 输入张量(对MultiplyMe函数而言,a同时为输出张量)
  • b(XTensor&) - 输入张量
  • c(XTensor&)- 输出张量
  • alpha(DTYPE) - 系数,默认为0.0
  • leadingDim(int) - 沿着指定维度进行点乘操作,默认为0
# 张量点乘片段示例

张量点乘的示例代码为:

/* call multiply function */
t = Multiply(*s1, *s2, 0);

张量点乘的测试文件路径为:

NiuTensor/tensor/test/TMultiply.cpp

# 减法(Sub)

# 什么是张量减法?

张量减法的目的是将两个张量相减得到一个新的结果张量,结果张量某一位置的元素数值为进行操作的张量在该位置上元素的差,在张量减法的计算过程中进行操作的张量与结果张量的维度相同,两个维度为的张量减法过程如下所示:

(0.01.02.03.04.05.0)(0.51.52.53.54.55.5)(0.50.50.50.50.50.5)\left(\begin{matrix}0.0 & 1.0 & 2.0 \\ 3.0 & 4.0 & 5.0\end{matrix}\right)\ -\ \left(\begin{matrix}0.5 & 1.5 & 2.5 \\ 3.5 & 4.5 & 5.5\end{matrix}\right) \ \rightarrow\ \left(\begin{matrix}-0.5 & -0.5 & -0.5 \\ -0.5 & -0.5 & -0.5\end{matrix}\right)

# 张量减法的调用

NiuTensor提供了张量减法的计算操作,在NiuTensor/tensor/core/arithmetic/Sub.h中定义,该操作用来进行张量之间的按元素位置相减,并得到相减的结果张量,计算方式为:

c=abβc\ =\ a\ -\ b\ *\ \beta

其中,a和b为输入张量,c为输出张量,为缩放系数,默认为1.0。

张量减法的调用方式以及参数说明如下所示:

void Sub(const XTensor &a, const XTensor &b, XTensor &c, DTYPE beta = (DTYPE)1.0)

void SubMe(XTensor &a, const XTensor &b, DTYPE beta = (DTYPE)1.0)

XTensor Sub(const XTensor &a, const XTensor &b, DTYPE beta = (DTYPE)1.0)

Parameters:

  • a(XTensor&) - 输入张量(对SubMe函数而言,a同时为输出张量)
  • b(XTensor&) - 输入张量
  • c(XTensor&) - 输出张量
  • beta(DTYPE) - 缩放系数,默认为1.0
# 张量减法片段示例

张量减法的示例代码为:

/* call Sub function */
c = Sub(*a, *b);

张量减法的测试文件路径为:

NiuTensor/tensor/test/TSub.cpp

# 加法(Sum)

# 什么是张量加法?

张量加法的目的是将n个张量相加得到一个新的结果张量,结果张量某一位置的元素数值为进行操作的张量在该位置上元素的求和,在张量加法的计算过程中进行操作的张量与结果张量的维度相同,两个维度为的张量相加过程如下所示:

(0.01.02.03.04.05.0)+(0.51.52.53.54.55.5)(0.52.54.56.58.510.5)\left(\begin{matrix}0.0 & 1.0 & 2.0 \\ 3.0 & 4.0 & 5.0\end{matrix}\right) \ +\ \left(\begin{matrix}0.5 & 1.5 & 2.5 \\ 3.5 & 4.5 & 5.5\end{matrix}\right) \ \rightarrow\ \left(\begin{matrix}0.5 & 2.5 & 4.5 \\ 6.5 & 8.5 & 10.5\end{matrix}\right)

# 张量加法的调用

NiuTensor提供了张量加法的计算操作,在NiuTensor/tensor/core/arithmetic中定义,该操作用来进行张量之间的按元素位置相加,并得到相加的结果张量,计算方式为:

c=a+bβc\ =\ a\ +\ b\ *\ \beta

其中,a和b为输入张量,c为输出张量,为缩放系数,默认为1.0,

张量加法的调用方式以及参数说明如下所示:

void Sum(const XTensor &a, const XTensor &b, XTensor &c, DTYPE beta = (DTYPE)1.0)

void SumMe(XTensor &a, const XTensor &b, DTYPE beta = (DTYPE)1.0)

XTensor Sum(const XTensor &a, const XTensor &b, DTYPE beta = (DTYPE)1.0)

Parameters:

  • a(XTensor&) - 输入张量(对SumMe函数而言,a同时为输出张量)
  • b(XTensor&) - 输入张量
  • c(XTensor&) - 输出张量
  • beta(DTYPE) - 缩放系数,默认为1.0
# 张量加法片段示例

张量加法的示例代码为:

/* call sum function */
c = Sum(*a, *b);

张量加法的测试文件路径为:

NiuTensor/tensor/test/TSum.cpp

# 张量存取(getandset)

此部分包括各种数据类型转化,设置数据、取数据等操作。

# ConvertDataType

# 什么是ConvertDataType?

ConvertDataType的作用是将张量中每个元素的数据类型转换为另一数据类型。

# ConvertDataType调用

NiuTensor提供了张量的ConvertDataType操作,调用方法及参数说明如下所示:

void ConvertDataType(const XTensor & input, XTensor & output, TENSOR_DATA_TYPE dataType)

XTensor ConvertDataType(const XTensor & input, TENSOR_DATA_TYPE dataType)

Parameters:

  • input(XTensor&) - 输入张量
  • output(XTensor&) - 输出张量
  • dataType(TENSOR_DATA_TYPE) - 数据类型
# ConvertDataType片段示例

ConvertDataType示例代码如下,本例中将张量中元素数据类型由flaot32转换为int32。

首先,创建张量时a为flaot32类型,b为int32类型:

/* create tensors */
XTensor * a = NewTensor(aOrder, aDimSize);
XTensor * b = NewTensor(aOrder, aDimSize, X_INT);

调用ConvertDataType函数

/* call ConvertDataType function */
ConvertDataType(*a, *b, X_INT);

有关张量ConvertDataType的详细代码示例见:

NiuTensor/tensor/test/TConvertDataType.cpp

# 选择(Select)

# 什么是张量的选择操作?

Select时按张量指定维度上的指定位置对张量进行选择的操作,一个的张量选择过程如下所示,本例中是选择张量维度2上位置索引为1和2的元素并存入目标张量,得到一个维度为的张量:

((0.01.02.03.04.05.06.07.0),(1.02.03.04.05.06.07.08.0))((1.02.05.06.0),(2.03.06.07.0))\begin{aligned} \Biggl( & \left( \begin{matrix}0.0 & 1.0 & 2.0 & 3.0\\4.0 & 5.0 & 6.0 & 7.0\end{matrix}\right),\\ & \left( \begin{matrix}1.0 & 2.0 & 3.0 & 4.0\\5.0 & 6.0 & 7.0 & 8.0\end{matrix} \right) \Biggr) \end{aligned}\ \rightarrow \ \begin{aligned} \Biggl( & \left( \begin{matrix}1.0 & 2.0\\5.0 & 6.0\end{matrix} \right),\\ & \left( \begin{matrix}2.0 & 3.0\\6.0 & 7.0\end{matrix} \right) \Biggr) \end{aligned}

# 张量选择的调用

NiuTensor提供了张量的选择操作,调用方法及参数说明如下所示:

第一种调用方式是由一个0,1构成的index矩阵对张量进行选择:

XTensor Select(const XTensor &a, XTensor &index, int dim)

Parameters:

  • a(XTensor&) - 输入张量
  • index(XTensor&) - 张量选择索引
  • dim(int) - 在哪一维对张量进行张量选择操作

第二种调用方式是按位置范围对张量进行选择:

XTensor SelectRange(const XTensor &a, int dim, int low, int high)

Parameters:

  • a(XTensor&) - 输入张量
  • dim(int) - 在哪一维对张量进行张量选择操作
  • low(int) - 张量选择范围的下限
  • high(int) - 张量选择范围的上限

需要注意的是,当张量选择的取值范围为[1,3]时意味着选择的是索引位置为1和2的值

# 张量选择片段示例

张量选择示例代码如下,其中s为输入的待操作张量,t为输出结果张量,在第三维上按范围[1,3]进行张量的选择操作:

/* call SelectRange function */
t = SelectRange(*s, 2, 1, 3);

有关张量选择的详细代码示例见:

NiuTensor/tensor/test/TSelect.cpp

# SetData

# 什么是SetData?

SetData的作用是将张量在一定取值范围内随机进行初始化设置,一个的张量在[0.0,1.0]的取值范围SetData过程如下所示:

(0.00.00.00.00.00.00.00.0)(0.10.50.30.90.80.50.50.2)\left(\begin{matrix}0.0 & 0.0 & 0.0 & 0.0\\0.0 & 0.0 & 0.0 & 0.0\end{matrix}\right)\ \rightarrow \ \left(\begin{matrix}0.1 & 0.5 & 0.3 & 0.9\\0.8 & 0.5 & 0.5 & 0.2\end{matrix}\right)

# SetData调用

NiuTensor提供了张量的SetData操作,调用方法及参数说明如下所示:

设置张量中每个元素为模板T类型的值:

template<class T>
void _SetDataFixed(XTensor * tensor, T value)

Parameters:

  • tensor(XTensor*) - 输入张量
  • value(T) - 设定的值

设置张量中部分元素为模板T类型的值(函数根据条件张量中非零元素的位置,将输入张量对应位置的值设置为特定值):

template<class T>
void _SetDataFixedCond(XTensor* tensor, XTensor* condition, T value)

Parameters:

  • tensor(XTensor*) - 输入张量
  • condition(XTensor*) - 条件张量
  • value(T) - 设定的值

沿指定维度设置张量中部分元素为模板T类型的值:

template<class T>
void _SetDataDim(XTensor * tensor, int beg, int len, int dim, T p)

Parameters:

  • tensor(XTensor*) - 输入张量
  • beg(int) - 起始位置
  • len(int) - 设置长度
  • dim(int) - 指定维度
  • p(T) - 设定的值

沿指定维度设置张量中部分元素为其他张量元素值:

void _SetDataIndexed(XTensor * source, XTensor * modify, int dim, int index)

Parameters:

  • source(XTensor*) - 输入张量
  • modify(XTensor*) - 参考张量
  • dim(int) - 指定维度
  • index(int) - 指定维度上的索引值

设置张量后两维为下三角矩阵并指定其元素值:

void _SetDataLowTri(XTensor * tensor, DTYPE p, int shift)

Parameters:

  • tensor(XTensor*) - 输入张量
  • p(DTYPE) - 设定的值
  • shift(int) - 下三角矩阵沿对角方向偏移大小

根据0-1之间的均匀分布随机设置张量值:

void _SetDataRand(XTensor * tensor, int rNum, int cNum)
  • tensor(XTensor*) - 输入张量
  • rNum(int) - 二维矩阵中的行大小
  • cNum(int) - 二维矩阵中的列大小

根据指定界限内的均匀分布随机设置张量值

void _SetDataRand(XTensor * tensor, DTYPE low, DTYPE upper)
  • tensor(XTensor*) - 输入张量
  • low(DTYPE) - 取值下限
  • upper(DTYPE) - 取值上限

根据指定界限内的等距增长设置张量值

void _SetDataRange(XTensor * tensor, DTYPE lower, DTYPE upper, DTYPE step)
  • tensor(XTensor*) - 输入张量
  • low(DTYPE) - 取值下限
  • upper(DTYPE) - 取值上限
  • step(DTYPE) - 每次增长大小

根据指定界限内的均匀分布随机设置张量值,同时对于高于界限的元素值将其置为指定值,低于界限的元素值将其置为0

void _SetDataRandP(XTensor * tensor, DTYPE lower, DTYPE upper, DTYPE p, DTYPE value)
  • tensor(XTensor*) - 输入张量
  • low(DTYPE) - 取值下限
  • upper(DTYPE) - 取值上限
  • p(DTYPE) - 张量元素值界限
  • value(DTYPE) - 设定的值

设置张量为正态分布:

void _SetDataRandN(XTensor * tensor, DTYPE mean = 0.0F, DTYPE standardDeviatioF = 1.0F)

Parameters:

  • tensor(XTensor*) - 输入张量
  • mean(DTYPE) - 均值
  • standardDeviation(DTYPE) - 标准差
# SetData片段示例

SetData示例代码如下,本例中是在[0.0,1.0]取值范围内对张量s进行随机初始化:

/* call SetData function */
SetDataRand(*s, 0.0, 1.0);

有关张量SetData的详细代码示例见:

NiuTensor/tensor/test/TSetData.cpp

# 数学运算(math)

此部分包括各种非基本代数操作,包括:一元操作(如Absolute、Exp、Log等)、二元操作(如Mod、Power、Scale等)以及其他复杂操作(如ScaleAndShift、Clip等)。

# 一元操作(Unary)

# 什么是张量的一元操作?

张量的一元操作主要包括张量的取绝对值(Absolute)、取指(Exp)、取对数(Log)等只需使用单个变量(张量或标量)进行操作的函数。

# 张量一元操作的调用

NiuTensor提供了一些关于张量的一元操作,主要包括Absolute、Ceil、Exp、Floor、IsNonZero、IsZero、Log、Negate、Round、Sign、Sqrt、Square、Sin、Cos、Tan,调用方法详见NiuTensor/tensor/core/math/Unary.h

# 二元操作(Binary)

# 什么是张量的二元操作?

张量的二元操作主要包括张量的取余(Mod)、求幂(Power)、放缩(Scale)等需要使用两个变量(张量或标量)进行操作的函数。

# 张量二元操作的调用

NiuTensor提供了一些关于张量的二元操作,主要包括Descale、Mod、Power、Scale、Shift,调用方法详见NiuTensor/tensor/core/math/Binary.h

# 张量裁剪(Clip)

# 什么是张量的裁剪操作?

张量的裁剪即将张量中每一元素都通过裁剪操作限定在某一范围内从而得到一个新的张量。

一个的张量在裁剪至[2, 5]的取值范围过程如下所示:

(0.01.02.03.04.05.06.07.0)(2.02.02.03.04.05.05.05.0)\left(\begin{matrix} 0.0 & 1.0 & 2.0 & 3.0\\4.0 & 5.0 & 6.0 & 7.0\end{matrix}\right)\ \rightarrow \ \left(\begin{matrix} 2.0 & 2.0 & 2.0 & 3.0\\4.0 & 5.0 & 5.0 & 5.0\end{matrix}\right)

张量中原始元素值小于2的被设置为2,大于5的值被设置为5。

# Clip调用

NiuTensor提供了张量的Clip操作,调用方法及参数说明如下所示:

void Clip(const XTensor & a, XTensor & b, DTYPE lower, DTYPE upper)

void ClipMe(XTensor & a, DTYPE lower, DTYPE upper)

XTensor Clip(const XTensor & a, DTYPE lower, DTYPE upper)

Parameters:

  • a(XTensor&) - 输入张量(对ClipMe函数而言,a同时为输出张量)
  • b(XTensor&) - 输出张量
  • lower(DTYPE) - 裁剪范围下限
  • upper(DTYPE) - 裁剪范围上限
# Clip片段示例

Clip示例代码如下所示:

/* call Clip function */
b = Clip(*a, -1.0, 1.0);

有关Clip的详细代码示例见:

NiuTensor/tensor/test/TClip.cpp

# Compare

# 什么是Compare?

Compare的作用是对输入的两个张量中元素的值进行比较。

# Compare的调用

NiuTensor提供了一些关于张量的Compare操作,主要包括Equal、NotEqual、Max、Min,调用方法详见NiuTensor/tensor/core/math/Compare.h

# 张量Compare操作示例

有关张量Compare操作的详细代码示例见:

NiuTensor/tensor/test/TCompare.cpp

# 标准化(Normalize)

# 什么是张量的标准化?

张量的标准化(Normalize)是神经网络中常用的操作,这样做是为了弱化某些变量的值较大而对模型产生影响,Normalize函数定义为:

y = a * (x-mean)/sqrt(variance+ ) + b

其中a为缩放因子,b为偏置,mean为输入的均值,variance为方差,为方差调节参数。

# Normalize调用

NiuTensor提供了张量的Normalize操作,调用方法及参数说明如下所示:

void Normalize(const XTensor &input, XTensor &output, int dim, const XTensor &mean, const XTensor &var, const XTensor &a, const XTensor &b, DTYPE epsilon)
  
void NormalizeMe(XTensor & input, int dim, const XTensor & mean, const XTensor & var, const XTensor & a, const XTensor & b, DTYPE epsilon)

XTensor Normalize(const XTensor &input, int dim, const XTensor &mean, const XTensor &var, const XTensor &a, const XTensor &b, DTYPE epsilon)

Parameters:

  • input(XTensor&) - 输入张量(对NormalizeMe函数而言,input同时为输出张量)
  • output(XTensor&) - 输出张量
  • dim(int) - 沿着指定维度产生均值和方差
  • mean(XTensor&) - 均值
  • var(XTensor&) - 方差
  • a(XTensor&) - 缩放
  • b(XTensor&) - 偏置
  • epsilon(DTYPE) - 防止方差为0的参数
# Normalize片段示例

Normalize示例代码如下所示:

/* call normalize function */
t = Normalize(*s, 0, *mean, *var, *a, *b, 0.0F);

有关Normalize的详细代码示例见:

NiuTensor/tensor/test/TNormalize.cpp

# 缩放和偏移(ScaleAndShift)

# 什么是张量的缩放和偏移?

张量的缩放和偏移计算公式为:b = a * scale + shift,其中scale和shift分别为张量缩放和偏移的参数,一个的张量进行缩放和偏移的过程如下所示,缩放参数取2.0,偏移参数取0.5:

(0.01.02.03.04.05.06.07.0)(0.52.54.56.58.510.512.514.5)\left(\begin{matrix}0.0 & 1.0 & 2.0 & 3.0\\4.0 & 5.0 & 6.0 & 7.0\end{matrix}\right)\ \rightarrow\ \left(\begin{matrix}0.5 & 2.5 & 4.5 & 6.5\\8.5 & 10.5 & 12.5 & 14.5\end{matrix}\right)

# 张量缩放和偏移的调用

NiuTensor提供了张量的缩放和偏移操作,调用方法为:

void ScaleAndShift(const XTensor &a, XTensor &b, DTYPE scale, DTYPE shift = 0)

void ScaleAndShiftMe(XTensor & a, DTYPE scale, DTYPE shift = 0)

XTensor ScaleAndShift(const XTensor &a, DTYPE scale, DTYPE shift = 0)

张量的缩放和偏移操作结果为:b = a * scale + shift,其中scale和shift分别为张量的缩放和偏移参数,张量缩放和偏移操作的参数说明如下表所示:

Parameters:

  • a(XTensor&) - 输入张量(对ScaleAndShiftMe函数而言,a同时为输出张量)
  • b(XTensor&) - 输出张量
  • scale(DTYPE) - 缩放参数
  • shift(DTYPE) - 偏移参数,默认值为0
# 张量缩放和偏移片段示例

张量缩放和偏移示例代码如下,input为输入的待操作张量,scaleFactor为缩放参数,shiftFactor为偏移参数:

/* call ScaleAndShift function */
t = ScaleAndShift(*s, 2.0F, 0.5F);

有关张量缩放和偏移的详细代码示例见:

NiuTensor/tensor/test/TScaleAndShift.cpp

# 数据移动(movement)

此部分主要是介绍有关数据拷贝的相关函数。

# CopyIndexed

# 什么是张量的CopyIndexed操作?

CopyIndexed,即按指定索引位置拷贝张量,一个的张量拷贝过程如下所示,本例中是对张量维度2上起始位置索引为0和2的1个元素进行拷贝,所得张量维度为

((0.01.02.02.01.03.0),(1.02.04.03.01.02.0),(1.03.02.01.01.00.0))\begin{aligned}\Biggl( & \left( \begin{matrix}0.0 & -1.0 & 2.0\\2.0 & 1.0 & 3.0\end{matrix}\right), &\left( \begin{matrix}1.0 & 2.0 & 4.0\\3.0 & 1.0 & 2.0\end{matrix}\right),\ \ &\left( \begin{matrix}-1.0 & 3.0 & 2.0\\1.0 & -1.0 & 0.0\end{matrix}\right) \Biggr)\end{aligned}

\downarrow

((0.02.02.03.0),(1.04.03.02.0),(1.02.01.00.0))\begin{aligned}\Biggl( & \left(\begin{matrix}0.0 & 2.0\\2.0 & 3.0\end{matrix}\right), & \left( \begin{matrix}1.0 & 4.0\\3.0 & 2.0\end{matrix}\right),\ \ & \left( \begin{matrix}-1.0 & 2.0\\1.0 & 0.0\end{matrix}\right) \Biggr)\end{aligned}

# 张量CopyIndexed的调用

NiuTensor提供了张量的CopyIndexed操作,调用方法及参数说明如下所示:

XTensor CopyIndexed(const XTensor & s, int dim, const XTensor & srcIndex, const XTensor & tgtIndex, int copyNum = 1)

Parameters:

  • s(XTensor&) - 输入张量
  • dim(int) - 在哪一维对张量进行CopyIndexed操作
  • srcIndex(XTensor&) - 源索引,即在指定dim上进行赋值的值的索引
  • tgtIndex(XTensor&) - 目标索引,所赋值的值在输出张量中的索引
  • copyNum(int) - 以源索引为起始位置拷贝的元素个数,默认为1
# 张量CopyIndexed片段示例

CopyIndexed示例代码如下,其中s为输入的待操作张量,t为输出结果张量,在指定维度上按起始位置索引拷贝一个元素到目标张量:

/* call CopyIndexed function */
t = CopyIndexed(*s, dim, srcIndex, indexSize, tgtIndex, 2);

有关CopyIndexed的详细代码示例见:

NiuTensor/tensor/test/TCopyIndexed.cpp

# 拷贝(CopyValues)

# 什么是张量的拷贝操作?

拷贝,即将一个张量的值赋给另一个张量,也就是对张量进行拷贝操作,一个的张量拷贝过程如下所示:

(5.01.02.08.04.03.07.06.0)(5.01.02.08.04.03.07.06.0)\left(\begin{matrix}5.0 & 1.0 & 2.0 & 8.0\\4.0 & 3.0 & 7.0 & 6.0\end{matrix}\right)\ \rightarrow\ \left( \begin{matrix}5.0 & 1.0 & 2.0 & 8.0\\4.0 & 3.0 & 7.0 & 6.0\end{matrix}\right)

# 张量拷贝操作的调用

NiuTensor提供了张量的拷贝操作,调用方法及参数说明如下所示:

void CopyValues(const XTensor &s, XTensor &t, XStream * stream = NULL)

XTensor CopyValues(const XTensor &s, XStream * stream = NULL)

Parameters:

  • s(XTensor&) - 输入张量
  • t(XTensor&) - 输出张量
  • stream(XStream*) - 多线程流,默认为NULL
# 张量拷贝片段示例

张量拷贝示例代码如下,其中s为输入的待操作张量,t为输出结果张量:

/* call CopyValues function */
t = CopyValues(*s);

有关张量拷贝的详细代码示例见:

NiuTensor/tensor/test/TCopyValues.cpp

# 聚合(Gather)

# 什么是张量的聚合操作?

沿给定轴 dim ,将输入索引张量 index 指定位置的值进行聚合,一个的张量沿着第0维进行聚合的过程如下所示:

inputTensor:(1.02.03.04.05.06.0)+indexTensor:(0120)(1.02.06.04.0)\begin{aligned} inputTensor: & \left( \begin{matrix}1.0 & 2.0 & 3.0\\4.0 & 5.0 & 6.0\end{matrix}\right)\\ + \\ indexTensor: & \left( \begin{matrix}0 & 1\\2 & 0\end{matrix}\right) \end{aligned}\ \rightarrow \ \left(\begin{matrix}1.0 & 2.0\\ 6.0 & 4.0\end{matrix}\right)

# 张量聚合操作的调用

NiuTensor提供了张量的拷贝操作,调用方法及参数说明如下所示:

XTensor Gather(XTensor &s, XTensor &index)

Parameters:

  • s(XTensor&) - 输入张量
  • index(XTensor&) - 聚合操作的索引
# 张量聚合片段示例

张量聚合示例代码如下,其中s为输入的待操作张量,t为输出结果张量,index是操作索引:

/* call Gather function */
t = Gather(*s, *index);

有关张量拷贝的详细代码示例见:

NiuTensor/tensor/test/TGather.cpp

# 扩展(Spread)

# 什么是张量的扩展操作?

沿给定轴 dim ,将输入索引张量 index 指定位置的值进行扩展。

# 规约操作(reduce)

# 归约取最大值(ReduceMax)

# 什么是张量的归约取最大值?

张量的归约取最大值操作是沿着张量的某一维度,取得该向量在该维度中的最大值,一个的张量在维度0和维度1进行取最大值操作的过程分别如下所示:

(0.01.02.03.04.05.06.07.0)(4.05.06.07.0)(0.01.02.03.04.05.06.07.0)(3.07.0)\begin{aligned} \left(\begin{matrix}0.0 & 1.0 & 2.0 & 3.0\\4.0 & 5.0 & 6.0 & 7.0\end{matrix}\right)\ &\rightarrow\ \left(\begin{matrix}4.0 & 5.0 & 6.0 & 7.0\end{matrix}\right) \\ \left(\begin{matrix}0.0 & 1.0 & 2.0 & 3.0\\4.0 & 5.0 & 6.0 & 7.0\end{matrix}\right)\ &\rightarrow\ \left(\begin{matrix}3.0\\7.0\end{matrix}\right) \end{aligned}

# 张量归约取最大值操作的调用

NiuTensor提供了张量的ReduceMax操作,用来获得张量中沿指定维度取得的最大值,张量归约取最大值操作的调用方式及参数说明如下所示:

XTensor ReduceMax(const XTensor &input, int dim)

Parameters:

  • input(XTensor&) - 输入张量
  • dim(int) - 沿着指定维度进行取最大值操作
# 张量归约取最大值片段示例

调用ReduceMax进行张量归约取最大值操作的示例代码如下所示,代码中两行分别表示沿着维度0和维度1进行取值:

/* call reduce max function */
t = ReduceMax(*s, 0);
t = ReduceMax(*s, 1);

有关张量归约取最大值的详细代码示例见:

NiuTensor/tensor/test/TReduceMax.cpp

# 归约取均值(ReduceMean)

# 什么是张量的归约取均值操作?

张量的归约取均值操作是沿着张量的某一维度,计算该张量在该维度的均值,一个的张量在维度0和维度1进行取均值操作的过程分别如下所示:

(0.01.02.03.04.05.06.07.0)(2.03.04.05.0)(0.01.02.03.04.05.06.07.0)(1.55.5)\begin{aligned} \left(\begin{matrix}0.0 & 1.0 & 2.0 & 3.0\\4.0 & 5.0 & 6.0 & 7.0\end{matrix}\right)\ &\rightarrow\ \left(\begin{matrix}2.0 & 3.0 & 4.0 & 5.0\end{matrix}\right) \\ \left(\begin{matrix}0.0 & 1.0 & 2.0 & 3.0\\4.0 & 5.0 & 6.0 & 7.0\end{matrix}\right)\ &\rightarrow\ \left(\begin{matrix}1.5\\5.5\end{matrix}\right) \end{aligned}

# 张量归约取均值操作的调用

NiuTensor提供了张量的ReduceMean操作,调用方法为:

void ReduceMean(const XTensor &input, XTensor &output, int dim)

XTensor ReduceMean(const XTensor &input, int dim)

ReduceMean用来获得张量中沿指定维度取得的数值均值,张量归约取均值的参数说明如下所示:

Parameters:

  • input(XTensor&) - 输入张量
  • output(XTensor&) - 输出张量
  • dim(int) - 沿着指定维度进行取平均值操作
# 张量归约取均值片段示例

调用ReduceMean进行张量归约取均值操作的示例代码如下所示,代码中两行分别表示沿着维度0和维度1进行取值:

/* call reduce mean function */
t = ReduceMean(*s, 0);
t = ReduceMean(*s, 1);

有关张量归约取均值的详细代码示例见:

NiuTensor/tensor/test/TReduceMean.cpp

# 归约求和(ReduceSum)

# 什么是张量的归约求和操作?

张量的归约求和操作是沿着张量的某一维度,计算该张量在该维度的和,一个的张量在维度0和维度1进行求和操作的过程分别如下所示:

(0.01.02.03.04.05.06.07.0)(4.06.08.010.0)(0.01.02.03.04.05.06.07.0)(6.022.0)\begin{aligned} \left(\begin{matrix}0.0 & 1.0 & 2.0 & 3.0\\4.0 & 5.0 & 6.0 & 7.0\end{matrix}\right) &\ \rightarrow\ \left(\begin{matrix}4.0 & 6.0 & 8.0 & 10.0\end{matrix}\right) \\ \left(\begin{matrix}0.0 & 1.0 & 2.0 & 3.0\\4.0 & 5.0 & 6.0 & 7.0\end{matrix}\right) &\ \rightarrow\ \left(\begin{matrix}6.0\\22.0\end{matrix}\right) \end{aligned}

# 张量归约求和操作的调用

NiuTensor提供了张量的ReduceSum操作,调用方法为:

void ReduceSum(const XTensor &input, XTensor &output, int dim, const XTensor &shift, DTYPE power = (DTYPE)1.0F, bool isExp = false)

void ReduceSum(const XTensor &input, XTensor &output, int dim, DTYPE power = (DTYPE)1.0F, bool isExp = false)

XTensor ReduceSum(const XTensor &input, int dim, const XTensor &shift, DTYPE power = (DTYPE)1.0F, bool isExp = false)

XTensor ReduceSum(const XTensor &input, int dim, DTYPE power = (DTYPE)1.0F, bool isExp = false)

其中power默认为1.0F,isExp默认为false,张量归约求和操作的参数说明如下所示:

Parameters:

  • input(XTensor&) - 输入张量
  • output(XTensor&) - 输出张量
  • dim(int) - 沿着指定维度进行取最大值操作
  • shift(XTensor&) - 输入的偏移
  • power(DTYPE) - 元素的幂,默认为1.0F
  • isExp(bool) - 是否取指,默认为false
# 张量归约求和片段示例

调用ReduceSum进行张量归约求和操作的示例代码如下所示,代码中两行分别表示沿着维度0和维度1进行取值:

/* call reduce sum function */
t1 = ReduceSum(*s, 0, *shift1);
t2 = ReduceSum(*s, 1, *shift2);

有关张量归约求和的详细代码示例见:

NiuTensor/tensor/test/TReduceSum.cpp

# 归约求总和(ReduceSumAll)

# 什么是张量的归约求总和操作?

张量的归约求总和操作是沿着张量的某一维度,计算该张量的总和,一个的张量在维度0进行取方差操作的过程如下所示:

(0.01.02.03.04.05.06.07.0)28\left(\begin{matrix}0.0 & 1.0 & 2.0 & 3.0\\4.0 & 5.0 & 6.0 & 7.0\end{matrix}\right)\ \rightarrow\ 28

# 张量归约求总和操作的调用

NiuTensor提供了张量的ReduceSumAll操作,调用方法为:

XTensor ReduceSumAll(const XTensor & source)

DTYPE ReduceSumAllValue(const XTensor & source)

ReduceSumAll以及ReduceSumAllValue用来计算张量的总和,二者的差别在于计算结果存放方式为XTensor所表示的标量还是DTYPE类型的数值,张量归约取方差操作的参数说明如下所示:

Parameters:

  • source(XTensor&) - 输入张量
# 张量归约求总和片段示例

调用ReduceSumAll进行张量归约求总和操作的示例代码如下所示:

/* call reduce sum all function */
t = ReduceSumAll(*s);
tValue = ReduceSumAllValue(*s);

有关张量归约求总和的详细代码示例见:

NiuTensor/tensor/test/TReduceSumAll.cpp

# 归约取平方和(ReduceSumSquared)

# 什么是张量的归约取平方和操作?

张量的归约取平方和操作是沿着张量的某一维度,计算该张量在该维度的平方和,一个的张量在维度0进行取方差操作的过程如下所示:

(0.01.02.03.04.05.06.07.0)(16.026.040.058.0)\left(\begin{matrix}0.0 & 1.0 & 2.0 & 3.0\\4.0 & 5.0 & 6.0 & 7.0\end{matrix}\right)\ \rightarrow\ \left(\begin{matrix}16.0 & 26.0 & 40.0 & 58.0\end{matrix}\right)

# 张量归约取平方和操作的调用

NiuTensor提供了张量的ReduceSumSquared操作,调用方法为:

void ReduceSumSquared(const XTensor &input, XTensor &output, int dim, const XTensor &shift)

XTensor ReduceSumSquared(const XTensor &input, int dim, const XTensor &shift)

ReduceSumSquared用来计算张量的沿着某一维度元素的方差,张量归约取方差操作的参数说明如下所示:

Parameters:

  • input(XTensor&) - 输入张量
  • output(XTensor&) - 输出张量
  • dim(int) - 沿着指定维度进行取平均值操作
  • shift(XTensor&) - 输入的偏移
# 张量归约取平方和片段示例

调用ReduceSumSquared进行张量归约取平方和操作的示例代码如下所示:

/* call reduce sum squared function */
t = ReduceSumSquared(*s, 0, *shift);

有关张量归约取平方和的详细代码示例见:

NiuTensor/tensor/test/TReduceSumSquared.cpp

# 归约取方差(ReduceVariance)

# 什么是张量的归约取方差操作?

张量的归约取方差操作是沿着张量的某一维度,计算该张量在该维度的标准差,一个的张量在维度0进行取标准差操作的过程如下所示:

(0.01.02.03.04.05.06.07.0)(8.08.08.08.0)\left(\begin{matrix}0.0 & 1.0 & 2.0 & 3.0\\4.0 & 5.0 & 6.0 & 7.0\end{matrix}\right)\ \rightarrow\ \left(\begin{matrix}8.0 & 8.0 & 8.0 & 8.0\end{matrix}\right)

# 张量归约取方差操作的调用

NiuTensor提供了张量的ReduceVariance操作,调用方法为:

void ReduceVariance(const XTensor &input, XTensor &output, int dim, const XTensor &mean)

XTensor ReduceVariance(const XTensor &input, int dim, const XTensor &mean)

ReduceVariance用来计算张量的沿着某一维度元素的方差,张量归约取方差操作的参数说明如下所示:

Parameters:

  • input(XTensor&) - 输入张量
  • output(XTensor&) - 输出张量
  • dim(int) - 沿着指定维度进行取标准差操作
  • mean(XTensor&) - 均值
# 张量归约取方差片段示例

调用ReduceVariance进行张量归约取方差操作的示例代码如下所示:

/* call reduce variance function */
t = ReduceVariance(*s, 0, *mean);

有关张量归约取方差的详细代码示例见:

NiuTensor/tensor/test/TReduceVariance.cpp

# 形状转换(shape)

此部分主要包括关于形状改变的函数,比如:级联(Concatenate)、合并(Merge)、分割(Split)等。

# 级联(Concatenate)

# 什么是张量的级联操作?

张量间的级联操作是沿着张量的某一维度,将若干张量连接在一起组成一个更大的张量的操作,将维度分别为的两个张量沿维度1进行级联过程如下所示:

Concatenate[(0.01.0),(2.03.04.05.0)](0.02.03.01.04.05.0)Concatenate \left[ \left(\begin{matrix}0.0\\1.0\end{matrix}\right) , \left(\begin{matrix}2.0 & 3.0\\4.0 & 5.0\end{matrix}\right) \right] \ \rightarrow\ \left(\begin{matrix}0.0 & 2.0 & 3.0\\1.0 & 4.0 & 5.0\end{matrix}\right)

# 张量级联的调用

NiuTensor提供了张量间的级联操作,调用方法为:

第一种调用方法中的操作对象是列表,将进行级联操作的张量存入列表smalls中,级联结果存入张量big中:

void Concatenate(const TensorList & smalls, XTensor & big, int dim)

XTensor Concatenate(const TensorList &smalls, int dim)

Parameters:

  • smalls(TensorList&) - 进行级联张量的列表
  • big(XTensor&) - 输出张量
  • dim(int) - 在指定维度进行级联

第二种方法操作对象不再是列表中的张量而是直接对一系列张量进行级联操作:

XTensor Concatenate(const XTensor &smallA, const XTensor &smallB, int dim)

Parameters:

  • smallA(XTensor&) - 输入张量1
  • smallB(XTensor&) - 输入张量2
  • dim(int) - 进行级联的维度
# 张量级联片段示例

通过操作张量列表进行张量的级联操作片段示例如下所示,sList为存放进行级联张量的列表,t为结果张量:

/* call concatenate function */
t = Concatenate(*sList, 1);

直接通过操作一系列张量进行张量的级联操作片段示例如下所示,s1、s2为需要进行级联的张量,t为结果张量:

/* call concatenate function */
t = Concatenate(*s1, *s2, 1);

有关张量级联的详细代码示例见:

NiuTensor/tensor/test/TConcatenate.cpp

# IsSameShaped

# 什么是张量的IsSameShaped操作?

IsSameShaped操作用于判断多个矩阵大小和类型是否一致。

# 张量IsSameShaped操作的调用

NiuTensor提供了张量的IsSameShaped操作,调用方法为:

bool IsSameShaped(const XTensor & a, const XTensor & b)

bool IsSameShaped(const XTensor & a, const XTensor & b, const XTensor & c)

Parameters:

  • a(XTensor&) - 输入张量
  • b(XTensor&) - 输入张量
  • c(XTensor&) - 输入张量
# 张量IsSameShaped片段示例

s1、s2为需要进行比较的张量,t为结果(bool):

/* call IsSameShaped function */
t = IsSameShaped(*s1, *s2);

# 合并(Merge)

# 什么是张量的合并操作?

张量间的合并操作是沿着张量的某一维度,可以将一个张量合并为另一个维度不同的张量,也可以将一个列表中的所有张量合并在一起组成一个更大的张量。

在第一种情况下将维度为的张量在维度1进行合并,进行合并的维度为0,得到维度为的张量的过程如下所示:

((0.01.02.03.04.05.0),(0.11.12.13.14.15.1))(0.01.02.03.04.05.00.11.12.13.14.15.1)\begin{aligned} \Biggl( & \left( \begin{matrix}0.0 & 1.0 & 2.0\\3.0 & 4.0 & 5.0\end{matrix}\right), \\ & \left( \begin{matrix}0.1 & 1.1 & 2.1\\3.1 & 4.1 & 5.1\end{matrix} \right) \Biggr) \end{aligned}\ \rightarrow\ \left(\begin{matrix}0.0 & 1.0 & 2.0\\3.0 & 4.0 & 5.0\\0.1 & 1.1 & 2.1\\3.1 & 4.1 & 5.1\end{matrix}\right)

在第二种情况下将两个维度均为的张量沿着维度0合并为维度为的张量的过程如下所示:

(0.01.02.03.04.05.0)+(0.11.12.13.14.15.1)(0.01.02.03.04.05.00.11.12.13.14.15.1)\left(\begin{matrix}0.0 & 1.0 & 2.0\\3.0 & 4.0 & 5.0\end{matrix}\right)\ +\ \left(\begin{matrix}0.1 & 1.1 & 2.1\\3.1 & 4.1 & 5.1\end{matrix}\right) \ \rightarrow\ \left(\begin{matrix}0.0 & 1.0 & 2.0\\3.0 & 4.0 & 5.0\\0.1 & 1.1 & 2.1\\3.1 & 4.1 & 5.1\end{matrix}\right)

# 张量合并操作的调用

NiuTensor提供了张量的合并操作,调用方法为:

在第一种调用方法中是沿源张量中的某一维度进行Merge操作,Merge结果为张量t,whereToMerge为指定进行Merge操作的维度,leadingDim为指定将哪一维度Merge,例如:(N/2, 2, M) -> (N, M),参数说明如下表所示:

void Merge(const XTensor &s, XTensor &t, int whereToMerge, int leadingDim = -1)

XTensor Merge(const XTensor &s, int whereToMerge, int leadingDim = -1)

Parameters:

  • s(XTensor&) - 输入张量
  • t(XTensor&) - 输出张量
  • whereToMerge(int) - 沿着指定维度进行Merge操作
  • leadingDim(int) - 把指定维度进行Merge操作,默认为-1

在第二种调用方法中是将若干彼此独立的张量合并到一起,操作结果为张量t,whereToMerge为指定进行Merge操作的维度,例如:2 * (N/2, M) -> (N, M),参数说明如下表所示:

void Merge(const TensorList &smalls, XTensor &t, int whereToMerge)

XTensor Merge(const TensorList &smalls, int whereToMerge)

XTensor Merge(const XTensor &smallA, const XTensor &smallB, int whereToMerge)

Parameters:

  • smalls(TensorList&) - 存放进行合并张量的列表
  • smallA(XTensor&) - 输入张量1
  • smallB(XTensor&) - 输入张量2
  • t(XTensor&) - 输出张量
  • whereToMerge(int) - 沿着指定维度进行Merge操作
# 张量合并片段示例

上述第一种张量合并片段示例如下所示,s为进行合并的张量,t为结果张量,1表示在维度1进行合并操作,0表示将维度0进行合并操作:

/* call merge function */
t = Merge(*s, 1, 0);

上述第二种张量合并片段示例如下所示,sList为要进行合并的张量列表,t为结果张量,0表示沿着维度0进行合并操作:

/* call merge function */
t = Merge(*sList, 0);

有关张量合并的详细代码示例见:

NiuTensor/tensor/test/TMerge.cpp

# 变形(Reshape)

张量的变形操作是将张量改变形状的操作。将维度为的张量变换为的张量过程如下所示:

(0.01.02.03.04.05.0)(0.01.02.03.04.05.0)\left(\begin{matrix}0.0 & 1.0 & 2.0 & 3.0 & 4.0 & 5.0\end{matrix}\right) \ \rightarrow\ \left(\begin{matrix}0.0 & 1.0 & 2.0\\3.0 & 4.0 & 5.0\end{matrix}\right)

# 张量变形的调用

NiuTensor提供了张量间的级联操作,调用方法为:

void Reshape(XTensor &s, XTensor &t, int order, int * dimSize)

XTensor Reshape(XTensor &s, int order, int * dimSize)

Parameters:

  • s(XTensor&) - 输入张量
  • t(XTensor&) - 输出张量
  • order(int) - 张量的阶数
  • dimsize(int*) - 维度大小
# 张量变形片段示例

上述第一种张量变形片段示例如下所示,s为原始张量,t为结果张量,2表示生成的张量t是一个二维张量,dims表示目标张量中每一维的大小:

/* call reshape function */
t = Reshape(*s, 2, dims);

# 切分(Split)

# 什么是张量的切分操作?

张量间的切分操作是沿着张量的某一维度,可以将一个张量切分成另一张量,也可以将一个大的张量切分成n个小的张量集合的列表。

第一种情况下将维度为张量沿着维度0进行切分,切分份数为2,得到维度为的张量的过程如下所示:

(0.01.02.03.04.05.00.11.12.13.14.15.1)((0.01.02.03.04.05.0),(0.11.12.13.14.15.1))\left(\begin{matrix}0.0 & 1.0 & 2.0\\3.0 & 4.0 & 5.0\\0.1 & 1.1 & 2.1\\3.1 & 4.1 & 5.1\end{matrix}\right)\ \rightarrow\ \begin{aligned} \Biggl( & \left( \begin{matrix}0.0 & 1.0 & 2.0\\3.0 & 4.0 & 5.0\end{matrix}\right), & \left( \begin{matrix}0.1 & 1.1 & 2.1\\3.1 & 4.1 & 5.1\end{matrix} \right) \Biggr) \end{aligned}

在第二种情况下将维度为张量沿着维度0进行切分,切分份数为2,得到两个维度均为的张量的过程如下所示:

(0.01.02.03.04.05.00.11.12.13.14.15.1)(0.01.02.03.04.05.0)+(0.11.12.13.14.15.1)\left(\begin{matrix}0.0 & 1.0 & 2.0\\3.0 & 4.0 & 5.0\\0.1 & 1.1 & 2.1\\3.1 & 4.1 & 5.1\end{matrix}\right)\ \rightarrow\ \left(\begin{matrix}0.0 & 1.0 & 2.0\\3.0 & 4.0 & 5.0\end{matrix}\right)\ +\ \left(\begin{matrix}0.1 & 1.1 & 2.1\\3.1 & 4.1 & 5.1\end{matrix}\right)

# 张量切分的调用

NiuTensor提供了两种张量切分操作,调用方法为:

在第一种调用方法中是将源张量中的某一维度进行Split操作,Split结果为张量t,whereToSplit为在哪一维度进行split操作,splitNum表示分成多少份,例如:(N, M) -> (N/3, M, 3),参数说明如下所示:

void Split(const XTensor &s, XTensor &t, int whereToSplit, int splitNum)

XTensor Split(const XTensor &s, int whereToSplit, int splitNum)

Parameters:

  • s(XTensor&) - 输入张量
  • t(XTensor&) - 输出张量
  • whereToSplit(int) - 在指定维度进行split操作
  • splitNum(int) - 分成多少份

在第二种调用方法中是将所操作张量big按某一维度whereToSplit进行Split操作,操作结果为包含若干更小维度张量的列表smalls,splitNum表示分成多少份,例如:(N, M) -> 2 * (N/2, M),参数说明如下所示:

void Split(const XTensor &big, TensorList &smalls, int whereToSplit, int splitNum)

Parameters:

  • big(XTensor&) - 输入张量
  • smalls(TensorList&) - 存放切分出张量的列表
  • whereToSplit(int) - 在指定维度进行split操作
  • splitNum(int) - 分成多少份
# 张量切分片段示例

上述第一种张量切分片段示例如下所示,s为切分的张量,t为结果张量,0表示沿着维度0进行切分操作,2表示切分份数为2:

/* call split function */
t = Split(*s, 0, 2);

上述第二种张量切分片段示例如下所示,s为进行切分的张量,tList为存放结果张量的列表,1表示沿着维度1进行切分操作,2表示切分份数为2:

/* call split function */
Split(*s, *tList, 1, 2);

有关张量切分的详细代码示例见:

NiuTensor/tensor/test/TSplit.cpp

# Squeeze

# 什么是Squeeze?

Squeeze的作用是通过对张量进行压缩操作,返回一个新的在指定维度删除该维度的张量,这个返回的张量与源张量共享相同的基础数据。如下图所示:

((0.01.02.03.04.05.0))(0.01.02.03.04.05.0)\begin{aligned} \Biggl( & \left( \begin{matrix}0.0 & 1.0 & 2.0\\3.0 & 4.0 & 5.0\end{matrix}\right) \Biggr) \end{aligned}\ \rightarrow\ \begin{aligned} \left( \begin{matrix}0.0 & 1.0 & 2.0\\3.0 & 4.0 & 5.0\end{matrix}\right) \end{aligned}

# Squeeze的调用

NiuTensor提供了张量的Squeeze操作,调用方法及参数说明如下所示:

void Squeeze(XTensor & source, XTensor & target, int leadingDim = -1)

void SqueezeMe(XTensor & source, int leadingDim = -1)

XTensor Squeeze(XTensor & source, int leadingDim = -1)

Parameters:

  • source(XTensor&) - 输入张量(对SqueezeMe函数而言,source同时为输出张量)
  • target(XTensor&) - 输出张量
  • leadingDim(int) - 沿着指定维度进行操作,默认为-1
# Squeeze片段示例

Squeeze示例代码如下,其中s为输入的待操作张量,t代表输出结果张量,以下两行分别表示在维度1和维度2上插入的维度大小为2:

/* call Squeeze function */
t = Squeeze(*s);

有关张量Squeeze的详细代码示例见:

NiuTensor/tensor/test/TSqueeze.cpp

# 张量堆叠(Stack)

# 什么是张量堆叠?

张量堆叠操作是按照指定维度将小矩阵延某一维度堆叠成为大矩阵。现对两个矩阵在0维进行堆叠。如下图所示:

(0.01.00.02.03.02.0)(4.05.04.06.07.06.0)((0.01.00.02.03.02.0),(4.05.04.06.07.06.0))\begin{aligned} \left( \begin{matrix}0.0 & 1.0 & 0.0 \\2.0 & 3.0 & 2.0 \end{matrix}\right),\left( \begin{matrix}4.0 & 5.0 & 4.0\\6.0 & 7.0 & 6.0\end{matrix} \right)\ \rightarrow \\ \begin{aligned} \Biggl( & \left( \begin{matrix}0.0 & 1.0 & 0.0\\2.0 & 3.0 & 2.0\end{matrix}\right), & \left( \begin{matrix}4.0 & 5.0 & 4.0\\6.0 & 7.0 & 6.0\end{matrix} \right) \Biggr) \end{aligned} \end{aligned}

# Stack的调用

NiuTensor提供了张量的Stack操作,调用方法及参数说明如下所示:

void Stack(const TensorList &smalls, XTensor &t, int dim)

XTensor Stack(const TensorList &smalls, int dim)

Parameters:

  • smalls(TensorList&) - 输入张量
  • t(XTensor&) - 输出张量
  • dim(int) - 沿着指定维度进行操作
# Stack片段示例

Stack示例代码如下,其中sList为输入的待操作张量列表,t代表输出结果张量,以下表示在维度0上进行堆叠:

/* call Stack function */
t = Stack(*sList, 0);

# 张量维度转换(Transpose)

# 什么是张量维度转换?

张量的维度转换操作将输入张量的指定维度进行调换,一个的张量进行Transpose操作后变为的张量,如下所示:

(0.01.02.03.04.05.0)(0.03.01.04.02.05.0)\left(\begin{matrix}0.0 & 1.0 & 2.0\\3.0 & 4.0 & 5.0\end{matrix}\right) \ \rightarrow\ \left( \begin{matrix}0.0 & 3.0\\ 1.0 & 4.0 \\ 2.0 & 5.0\end{matrix}\right)

# Transpose的调用

NiuTensor提供了张量的Transpose操作,调用方法及参数说明如下所示:

XTensor Transpose(const XTensor &a, const int i, const int j)

Parameters:

  • a(XTensor&) - 输入张量
  • i(int) - 进行操作的维度1
  • j(int) - 进行操作的维度2
# Transpose片段示例

Transpose示例代码如下,其中s为输入的待操作张量,t代表输出结果张量,其示在将张量s中维度0和维度1的顺序进行调换:

/* call Transpose function */
t = Transpose(*s, 0, 1);

有关张量Transpose的详细代码示例见:

NiuTensor/tensor/test/TTranspose.cpp

# Unsqueeze

# 什么是Unsqueeze?

Unsqueeze的作用是通过对张量进行拓展操作,返回一个新的在指定维度插入新维度的张量,这个返回的张量与源张量共享相同的基础数据,一个的张量在维度1和2分别进行Unsqueeze的操作如下所示,插入新的维度大小均为2:

(0.01.02.03.04.05.0)((0.01.02.00.01.02.0),(3.04.05.03.04.05.0))\left(\begin{matrix}0.0 & 1.0 & 2.0\\3.0 & 4.0 & 5.0\end{matrix}\right) \ \rightarrow\ \begin{aligned} \Biggl( & \left( \begin{matrix}0.0 & 1.0 & 2.0\\0.0 & 1.0 & 2.0\end{matrix}\right), \\ & \left( \begin{matrix}3.0 & 4.0 & 5.0\\3.0 & 4.0 & 5.0\end{matrix} \right) \Biggr) \end{aligned}

(0.01.02.03.04.05.0)((0.00.01.01.02.02.0),(3.03.04.04.05.05.0))\left(\begin{matrix}0.0 & 1.0 & 2.0\\3.0 & 4.0 & 5.0\end{matrix}\right) \ \rightarrow\ \begin{aligned} \Biggl( & \left( \begin{matrix}0.0 & 0.0\\1.0 & 1.0\\2.0 & 2.0\end{matrix}\right), \\ & \left( \begin{matrix}3.0 & 3.0\\4.0 & 4.0\\5.0 & 5.0\end{matrix} \right) \Biggr) \end{aligned}

# Unsqueeze的调用

NiuTensor提供了张量的Unsqueeze操作,调用方法及参数说明如下所示:

void Unsqueeze(const XTensor &a, XTensor &b, int dim, int dSize)

XTensor Unsqueeze(const XTensor &a, int dim, int dSize)

Parameters:

  • a(XTensor&) - 输入张量
  • b(XTensor&) - 输出张量
  • dim(int) - 在指定维度进行Unsqueeze操作
  • dSize(int) - 插入维度的大小
# Unsqueeze片段示例

Unsqueeze示例代码如下,其中s为输入的待操作张量,t1、t2代表输出结果张量,以下两行分别表示在维度1和维度2上插入的维度大小为2:

/* call Unsqueeze function */
t1 = Unsqueeze(*s, 1, 2);
t2 = Unsqueeze(*s, 2, 2);

有关张量Unsqueeze的详细代码示例见:

NiuTensor/tensor/test/TUnsqueeze.cpp

# 排序操作(sort)

此部分主要介绍排序相关的函数,如:sort、topk等。

# Sort

# 什么是Sort?

Sort操作是对张量中元素沿着指定的维度进行排序,一个的张量沿着维度0进行Sort操作过程如下所示:

(0.01.02.03.04.05.06.07.0)(4.05.06.07.00.01.02.03.0)\left(\begin{matrix}0.0 & 1.0 & 2.0 & 3.0\\4.0 & 5.0 & 6.0 & 7.0\end{matrix}\right)\ \rightarrow\ \left(\begin{matrix}4.0 & 5.0 & 6.0 & 7.0\\0.0 & 1.0 & 2.0 & 3.0\end{matrix}\right)

# Sort的调用

NiuTensor提供了张量的Sort操作,调用方法及参数说明如下所示:

void Sort(XTensor & a, XTensor & b, XTensor & index, int dim)

void SortMe(XTensor & a, XTensor & index, int dim)

Parameters:

  • a(XTensor&) - 输入张量(对SortMe函数而言,a同时为输出张量)
  • b(XTensor&) - 输出张量
  • index(XTensor&) - 输出张量中元素的索引
  • dim(int) - 沿着指定维度进行Sort操作
# Sort片段示例

Sort示例代码如下所示,a为进行操作的张量,index为结果张量中元素的索引,本例中沿着维度0进行Sort操作:

/* call Sort function */
Sort(*a, *b, *index, 0)

有关Sort的详细代码示例见:

NiuTensor/tensor/test/TSort.cpp

# TopK

# 什么是TopK?

TopK操作是通过对张量中元素进行排序,得到最大或最小的k个元素值及其对应的索引值,在张量中,可以沿着某一维度进行TopK操作,一个的张量沿着维度0进行Top-2操作过程如下所示:

(5.01.02.08.04.03.07.06.0)outputAnswer:(5.03.07.08.04.01.02.06.0)+indexAnswer:(01101001)\left(\begin{matrix}5.0 & 1.0 & 2.0 & 8.0\\4.0 & 3.0 & 7.0 & 6.0\end{matrix}\right)\ \rightarrow\ \begin{aligned} outputAnswer: & \left( \begin{matrix}5.0 & 3.0 & 7.0 & 8.0\\4.0 & 1.0 & 2.0 & 6.0\end{matrix}\right)\\ + \\ indexAnswer: & \left( \begin{matrix}0 & 1 & 1 & 0\\1 & 0 & 0 & 1\end{matrix}\right) \end{aligned}

# TopK的调用

NiuTensor提供了张量的TopK操作,调用方法及参数说明如下所示:

void TopK(XTensor &a, XTensor &b, XTensor &index, int dim, int k, bool isSorted = false)

Parameters:

  • a(XTensor&) - 输入张量
  • b(XTensor&) - 输出张量
  • index(XTensor&) - 输出结果索引
  • dim(int) - 沿着指定维度进行TopK操作
  • k(int) - TopK中k代表取最大的k个值
  • isSorted(bool) - 是否排序,默认值为false
# TopK片段示例

TopK示例代码如下,s为输入的待操作张量,t为输出结果张量,index为输出结果索引,本例中沿着维度dim取Top-k:

/* call TopK function */
TopK(s, t, index, 0, 2);

有关TopK的详细代码示例见:

NiuTensor/tensor/test/TTopK.cpp

# 激活函数(function)

此部分主要介绍一些激活函数(如HardTanH、Rectify等)和损失函数(LogSoftmax等)。

# Dropout

# 什么是Dropout?

Dropout是一种在深度学习环境中应用的正规化手段,目的是在每次进行神经网络循环时随机对一些单元进行隐藏,从而达到防治过拟合的目的。

# Dropout调用

NiuTensor提供了张量的Dropout激活函数,调用方法及参数说明如下所示:

XTensor Dropout(const XTensor &x, DTYPE dropProb, int leadingDim = -1, int leadingDim2 = -1)

XTensor DropoutWithoutBroadcast(const XTensor &x, DTYPE dropProb)

Parameters:

  • x(XTensor&) - 输入张量
  • dropProb(DTYPE) - 随机将单元隐藏的概率
  • leadingDim(int) - 沿着指定维度进行操作,默认为-1
  • leadingDim2(int) - 沿着另一个指定维度进行操作,默认为-1
# Dropout片段示例

Dropout示例代码如下:

/* call Dropout function */
y = Dropout(*x, 0.2F);

有关Dropout的详细代码示例见:

NiuTensor/tensor/test/TDropout.cpp

# HardTanH

# 什么是HardTanH?

HardTanH是一种激活函数,HardTanH函数定义为:

y=1 if x>1x if 1<=x<=11 if x<1\begin{aligned} y=1 & \text { if } x>1 \\ x & \text { if }-1<=x<=1 \\-1 & \text { if } x<-1 \end{aligned}

# HardTanH调用

NiuTensor提供了张量的HardTanH激活函数,调用方法及参数说明如下所示:

void HardTanH(const XTensor &x, XTensor &y)

XTensor HardTanH(const XTensor &x)

Parameters:

  • x(XTensor&) - 输入张量
  • y(XTensor&) - 输出张量
# HardTanH片段示例

HardTanH示例代码如下,其中x为输入的向量,y为输入的张量:

/* call hardtanh function */
y = HardTanH(*x);

有关HardTanH的详细代码示例见:

NiuTensor/tensor/test/THardTanH.cpp

# Identity

# 什么是Identity?

Identity是一种激活函数,Identity函数定义为:

# Identity调用

NiuTensor提供了张量的Identity激活函数,调用方法及参数说明如下所示:

void Identity(const XTensor &x, XTensor &y)

XTensor Identity(const XTensor &x)

Parameters:

  • x(XTensor&) - 输入张量
  • y(XTensor&) - 输出张量
# Identity片段示例

Identity示例代码如下,其中x为输入的向量,y为输入的张量:

/* call Identity function */
y = Identity(*x);

有关Identity的详细代码示例见:

NiuTensor/tensor/test/TIdentity.cpp

# LogSoftmax

# 什么是LogSoftmax?

LogSoftmax是一种激活函数,LogSoftmax函数定义为:

# LogSoftmax调用

NiuTensor提供了张量的LogSoftmax激活函数,调用方法及参数说明如下所示:

void LogSoftmax(const XTensor &x, XTensor &y, int leadDim)

XTensor LogSoftmax(const XTensor &x, int leadDim)

Parameters:

  • x(XTensor&) - 输入张量
  • y(XTensor&) - 输出张量
  • leadDim(int) - 沿着指定维度进行操作
# LogSoftmax片段示例

LogSoftmax示例代码如下,其中x为输入的向量,y为输入的张量,本例中沿着维度1进行LogSoftmax操作:

/* call LogSoftmax function */
y = LogSoftmax(*x, 1);

有关LogSoftmax的详细代码示例见:

NiuTensor/tensor/test/TLogSoftmax.cpp

# Rectify

# 什么是Rectify?

Rectify是一种激活函数,Rectify函数定义为:

# Rectify调用

NiuTensor提供了张量的Rectify激活函数,调用方法及参数说明如下所示:

void Rectify(const XTensor &x, XTensor &y)

XTensor Rectify(const XTensor &x)

Parameters:

  • x(XTensor&) - 输入张量
  • y(XTensor&) - 输出张量
# Rectify片段示例

Rectify示例代码如下,其中x为输入的向量,y为输入的张量:

/* call Rectify function */
y = Rectify(*x);

有关Rectify的详细代码示例见:

NiuTensor/tensor/test/TRectify.cpp

# Sigmoid

# 什么是Sigmoid?

Sigmoid是一种激活函数,Sigmoid函数定义为:

# Sigmoid调用

NiuTensor提供了张量的Sigmoid激活函数,调用方法及参数说明如下所示:

void Sigmoid(const XTensor &x, XTensor &y)

XTensor Sigmoid(const XTensor &x)

Parameters:

  • x(XTensor&) - 输入张量
  • y(XTensor&) - 输出张量
# Sigmoid片段示例

Sigmoid示例代码如下,其中x为输入的向量,y为输入的张量:

/* call Sigmoid function */
y = Sigmoid(*x);

有关Sigmoid的详细代码示例见:

NiuTensor/tensor/test/TSigmoid.cpp

# Softmax

# 什么是Softmax?

Softmax是一种激活函数,Softmax函数定义为:

# Softmax调用

NiuTensor提供了张量的Softmax激活函数,调用方法及参数说明如下所示:

void Softmax(const XTensor &x, XTensor &y, int leadDim)

XTensor Softmax(const XTensor &x, int leadDim)

Parameters:

  • x(XTensor&) - 输入张量
  • y(XTensor&) - 输出张量
  • leadDim(int) - 沿着指定维度进行操作
# Softmax片段示例

Softmax示例代码如下,其中x为输入的向量,y为输入的张量,本例中沿着维度1进行Softmax操作:

/* call Softmax function */
y = Softmax(*x, 1);

有关Softmax的详细代码示例见:

NiuTensor/tensor/test/TSoftmax.cpp