Commit 3888da80 by liyinqiao

Merge with the branch of xunuo to update the manual.

parent f8ab22b9
......@@ -279,7 +279,7 @@ sample2.cpp中使用的NewTensor2D和DelTensor是一组函数,前者生成张
| bool isSparse | 是否稠密,一个n * m稠密矩阵的数据量大小为n * m,而稀疏(非稠密)矩阵的数据量大小则取决于矩阵中非零元素个数。|
| float denseRatio | 稠密度,指非零单元的比例,是介于0和1之间的一个实数,0表示所有单元全为零,1表示全为非零单元。|
在XTensor.h头文件中定义的部分方法说明,详情参见附录
在XTensor.h头文件中定义的部分方法说明:
| 功能 | 函数 | 参数 |
| - | - | - |
......@@ -346,28 +346,13 @@ Parameters:
##### 张量除法片段示例
张量除法的示例代码为:
以最基本的二维矩阵除法为例,张量除法的示例代码为:
```cpp
XTensor a, b, c;
a.Rand(2, 2);
b.Rand(2, 2);
c = a + b;
a.Dump(stdout, "a");
b.Dump(stdout, "b");
c.Dump(stdout, "c");
/* call Div function */
t = Div(*s1, *s2, 0)
```
输出结果为:
> a order=2 dimsize=2,2 dtype=X_FLOAT dense=1.000000
2.469558e-01 5.701468e-01 3.389996e-01 1.876888e-01
b order=2 dimsize=2,2 dtype=X_FLOAT dense=1.000000
5.639210e-01 3.753777e-03 4.722739e-01 7.217323e-01
c order=2 dimsize=2,2 dtype=X_FLOAT dense=1.000000
8.108768e-01 5.739006e-01 8.112736e-01 9.094211e-01
张量除法的测试文件路径为:
NiuTensor/source/tensor/test/TDiv.cpp
......@@ -531,7 +516,7 @@ $$
```cpp
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)
XTensor MulAndShift(const XTensor &x, const XTensor &w, const XTensor &b, DTYPE alpha = (DTYPE)1.0, XPRunner * parallelRunner = NULL)
```
Parameters:
......@@ -773,7 +758,7 @@ $$
NiuTensor提供了张量的选择操作,调用方法及参数说明如下所示:
第一种选择操由一个0,1构成的index矩阵对张量进行选择:
第一种调用方式是由一个0,1构成的index矩阵对张量进行选择:
```cpp
XTensor Select(const XTensor &a, XTensor &index, int dim)
```
......@@ -799,7 +784,7 @@ Parameters:
##### 张量选择片段示例
张量选择示例代码如下,其中s为输入的待操作张量,t输出结果张量,在第三维上按范围[1,3]进行张量的选择操作:
张量选择示例代码如下,其中s为输入的待操作张量,t输出结果张量,在第三维上按范围[1,3]进行张量的选择操作:
```cpp
/* call SelectRange function */
t = SelectRange(*s, 2, 1, 3);
......@@ -1142,7 +1127,7 @@ Parameters:
##### 张量CopyIndexed片段示例
CopyIndexed示例代码如下,其中s为输入的待操作张量,t输出结果张量,在指定维度上按起始位置索引拷贝一个元素到目标张量:
CopyIndexed示例代码如下,其中s为输入的待操作张量,t输出结果张量,在指定维度上按起始位置索引拷贝一个元素到目标张量:
```cpp
/* call CopyIndexed function */
t = CopyIndexed(*s, dim, srcIndex, indexSize, tgtIndex, 2);
......@@ -1180,7 +1165,7 @@ Parameters:
##### 张量拷贝片段示例
张量拷贝示例代码如下,其中s为输入的待操作张量,t输出结果张量:
张量拷贝示例代码如下,其中s为输入的待操作张量,t输出结果张量:
```cpp
/* call CopyValues function */
t = CopyValues(*s);
......@@ -1218,7 +1203,7 @@ Parameters:
##### 张量聚合片段示例
张量聚合示例代码如下,其中s为输入的待操作张量,t输出结果张量,index是操作索引:
张量聚合示例代码如下,其中s为输入的待操作张量,t输出结果张量,index是操作索引:
```cpp
/* call Gather function */
t = Gather(*s, *index);
......@@ -1595,7 +1580,7 @@ $$
在第二种情况下将两个维度均为$2 \times 3$的张量沿着维度0合并为维度为$4 \times 3$的张量的过程如下所示:
$$
\left(\begin{matrix}0.0 & 2.0 & 3.0\\1.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\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)
$$
......@@ -1706,7 +1691,7 @@ $$
$$
\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 & 2.0 & 3.0\\1.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)
\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)
$$
##### 张量切分的调用
......@@ -2022,7 +2007,7 @@ Parameters:
##### TopK片段示例
TopK示例代码如下,s为输入的待操作张量,t输出结果张量,index为输出结果索引,本例中沿着维度dim取Top-k:
TopK示例代码如下,s为输入的待操作张量,t输出结果张量,index为输出结果索引,本例中沿着维度dim取Top-k:
```cpp
/* call TopK function */
......@@ -2078,9 +2063,8 @@ NiuTensor/tensor/test/TDropout.cpp
##### 什么是HardTanH?
HardTanH是一种激活函数,HardTanH函数定义为:
> y = 1 &nbsp;&nbsp;if x > 1 <br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; x &nbsp;&nbsp;if -1 <= x <= 1 <br />
&nbsp;&nbsp; &nbsp; -1 &nbsp;&nbsp;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调用
......@@ -2115,7 +2099,7 @@ NiuTensor/tensor/test/THardTanH.cpp
##### 什么是Identity?
Identity是一种激活函数,Identity函数定义为:
>y = x
> $y = x$
##### Identity调用
......@@ -2150,7 +2134,7 @@ NiuTensor/tensor/test/TIdentity.cpp
##### 什么是LogSoftmax?
LogSoftmax是一种激活函数,LogSoftmax函数定义为:
>y = log(e^x / \sum_{i} e^{x_i})
> $y = log(\frac{\exp \left(x_{i}\right)}{\sum_{j} \exp \left(x_{j}\right)})$
##### LogSoftmax调用
......@@ -2186,7 +2170,7 @@ NiuTensor/tensor/test/TLogSoftmax.cpp
##### 什么是Rectify?
Rectify是一种激活函数,Rectify函数定义为:
>y = max(0, x)
>$y = max(0, x)$
##### Rectify调用
......@@ -2219,7 +2203,7 @@ NiuTensor/tensor/test/TRectify.cpp
##### 什么是Sigmoid?
Sigmoid是一种激活函数,Sigmoid函数定义为:
>y = 1/(1+exp(-x))
>$y = 1/(1+exp(-x))$
##### Sigmoid调用
......@@ -2250,7 +2234,7 @@ NiuTensor/tensor/test/TSigmoid.cpp
##### 什么是Softmax?
Softmax是一种激活函数,Softmax函数定义为:
>y = e^x / \sum_{i} e^{x_i}
>$y = \frac{\exp \left(x_{i}\right)}{\sum_{j} \exp \left(x_{j}\right)}$
##### Softmax调用
......@@ -2317,7 +2301,7 @@ NiuTensor/tensor/Sample中的具体示例
此外,当系统中存在对GPU设备上的显存空间进行管理的时候,申请、释放操作所产生的时间代价相对普通内存来说更大。不同于内存空间的申请,在申请或释放显存的时候需要对CPU正在执行的操作进行中断,交由GPU设备进行显存的操作,因此这部分产生的时间消耗远比内存申请来说大得多,最终导致频繁地对显存空间进行操作会更严重地拖慢系统整体的执行效率。
针对以上问题,本系统支持使用内存池(Memory Pool)来对系统中的存储空间(包括内存和显存)进行管理。内存池的概念主要是在对存储空间进行使用之前,预先从系统中申请一整块的空间,由程序自身(内存池)对这部分的空间进行管理。这样做的好处在于对存储空间的申请、释放等操作不需要对系统的相应接口进行频繁调用,降低了其中中断、搜寻最优块等操作的耗时,同时也不易产生内存碎片。此外,由于内存池的申请是一次性的操作,因此不会在系统全局产生大规模内存|泄漏的情况,对系统的稳定性会有所助益。
针对以上问题,本系统支持使用内存池(Memory Pool)来对系统中的存储空间(包括内存和显存)进行管理。内存池的概念主要是在对存储空间进行使用之前,预先从系统中申请一整块的空间,由程序自身(内存池)对这部分的空间进行管理。这样做的好处在于对存储空间的申请、释放等操作不需要对系统的相应接口进行频繁调用,降低了其中中断、搜寻最优块等操作的耗时,同时也不易产生内存碎片。此外,由于内存池的申请是一次性的操作,因此不会在系统全局产生大规模内存泄漏的情况,对系统的稳定性会有所助益。
具体来说,想要在NiuTensor的工具包中使用内存池(XMem)进行操作,只需要三个步骤:内存池的定义,使用以及释放。
......@@ -2340,7 +2324,7 @@ XTensor tensor;
// 在内存池上初始化这个变量为50列*100行的矩阵(2阶张量)
InitTensor2D(&tensor, 50, 100, X_FLOAT, -1, mem);
```
我们可以看到,上述代码相对之前之前未使用内存池时的定义方式而言,仅需在定义的时候指定所使用的内存池即可,无需更复杂的操作。
我们可以看到,上述代码相对之前未使用内存池时的定义方式而言,仅需在定义的时候指定所使用的内存池即可,无需更复杂的操作。
* 内存池的释放
......@@ -2750,7 +2734,7 @@ NiuTensor实现了自动计算反向过程求得参数的梯度,只需要通
autoDiffer.Backward(lossTensor);
```
之后,然后采用梯度下降的方法通过反向传播计算得到损失函数L对参数$w_k$的导数$∂L/∂w$,之后我们根据公式
然后采用梯度下降的方法通过反向传播计算得到损失函数L对参数$w_k$的导数$∂L/∂w$,之后我们根据公式
> $w(k+1)= w(k) - η * ∂L/∂w$
......@@ -2778,9 +2762,9 @@ Transfomer是一个基于编码器解码器框架的端到端模型,它使用a
Transformer的输入主要由两部分组成,分别是词汇embedding和位置编码,词汇embedding和位置编码维度相同,通过位置编码公式
$\textrm{PE}(pos,2i) = \textrm{sin} (\frac{pos}{10000^{2i/d_{model}}})$
> $\textrm{PE}(pos,2i) = \textrm{sin} (\frac{pos}{10000^{2i/d_{model}}})$
$\textrm{PE}(pos,2i+1) = \textrm{cos} (\frac{pos}{10000^{2i/d_{model}}})$
> $\textrm{PE}(pos,2i+1) = \textrm{cos} (\frac{pos}{10000^{2i/d_{model}}})$
式中PE($\cdot$)表示位置编码的函数,$pos$表示单词的位置,$i$代表位置编码向量中的第几维。计算得到的词汇位置编码PE($\cdot$)与embedding即e($\cdot$)加和,得到模型的真实输入h($\cdot$)
......@@ -2925,7 +2909,7 @@ XTensor T2TFNN::Make(XTensor &input, bool isTraining)
在之前的Transformer结构图中可以发现encoder中还有两个操作,分别是残差链接和层正则化。残差连接从广义上讲也叫短连接(short-cut connection),指的是这种短距离的连接。它的思想很简单,就是把层和层之间的距离拉近。其计算公式为:
$x_{l+1} = x_l + \digamma (x_l)$
> $x_{l+1} = x_l + \digamma (x_l)$
从上式中可以看出,当$x_{l+1}$对$x_{l}$求导时,无论$\digamma (x_l)$对$x_{l}$有多小,都会有$x_{l}$对$x_{l}$的导数为1。这就极大的缓解了梯度消失的问题。同时,由于引入了残差操作,将前面所有层的输出加到一起。这样会导致不同层(或子层)的结果之间的差异性很大,造成训练过程不稳定、训练时间较长。为了避免这种情况,在每层中加入了层正则化操作。
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论