张量分析(由浅入深地带你了解分析张量) 神经网络的输入、输出、权重都是张量,神经网络中的各种计算和变换就是对张量操作,张量这种数据结构是神经网络的基石,可以说没有理解张量就没有真正理解神经网络和人工智能。本文由浅入深地详细讲解分析张量,望能给予读者启发袁宵。 张量的定义 张量(tensor)是一个多维数组(multidimensionalarrays),即一种存储数字集合的数据结构,这些数字可通过索引(index)单独访问,并可通过多个索引进行索引。 张量是将向量和矩阵推广到任意维数。如下图所示,一个张量的维数与张量中用来表示标量值的索引的数量一致。 新张量张量〔索引〕 张量的视图与存储 点击张量的存储。ipynb深入学习,下面是该文件的主要内容: 张量,PyTorch中的基本数据结构 索引并在PyTorch张量上进行操作以探索和处理数据 与NumPy多维数组互操作 将计算移至GPU以提高速度 张量的视图与存储的定义 存储(Storage)是一维的数字数据数组,例如包含给定类型的数字(可能是float或int32)的连续内存块。张量是这样一个存储的视图,它能够通过使用偏移量(offset)和每一维度的步长(perdimensionstrides)索引(index)到该存储中。存储的布局总是一维的,而与可能涉及到它的任何张量的维数无关。 多个张量可以对相同的存储进行索引,即使它们对数据的索引是不同的。但是,底层内存只分配一次,因此不管存储实例管理的数据有多大,都可以快速地创建数据上的替代张量视图。 张量视图的多维性意义 张量的视图就是我们理解张量的方式,比如shape为〔2,4,4,3〕的张量A,我们从逻辑上可以理解为2张图片,每张图片4行4列,每个位置有RGB3个通道的数据;张量的存储体现在张量在内存上保存为一段连续的内存区域,对于同样的存储,我们可以有不同的理解方式,比如上述A,我们可以在不改变张量的存储下,将张量A理解为2个样本,每个样本的特征为长度48的向量。这就是存储与视图的关系。 张量存储的一维性 在存储数据时,内存并不支持这个维度层级概念,只能以平铺方式按序写入内存,因此这种层级关系需要人为管理,也就是说,每个张量的存储顺序需要人为跟踪。为了方便表达,我们把张量shape中相对靠左侧的维度叫做大维度,shape中相对靠右侧的维度叫做小维度,比如〔2,4,4,3〕的张量中,图片数量维度与通道数量相比,图片数量叫做大维度,通道数叫做小维度。在优先写入小维度的设定下,形状(2,3)张量的内存布局为:Tensor:shape(3,2),dtypefloat32,numpyarray(〔〔1。,4。〕,〔2。,1。〕,〔3。,5。〕〕,dtypefloat32)〔1。,4。,2。,1。,3。,5。〕 数据在创建时按着初始的维度顺序写入,改变张量的视图仅仅是改变了张量的理解方式,并不会改变张量的存储顺序,这在一定程度上是从计算效率考虑的,大量数据的写入操作会消耗较多的计算资源。 张量存储的形状(大小)、存储偏移量和步长 为了索引到存储中,张量依赖于一些信息,这些信息连同它们的存储一起明确地定义了它们:大小、存储偏移量和步长(下图)。 中文英文意义形状shape是一个元组,表示张量表示的每个维度上有多少个元素。注意张量的形状(shape)与存储的大小(size)等价。步长stride是一个元组,表示当索引在每个维度上增加1时,必须跳过的存储中的元素数量。存储偏移量storageoffset存储中对应于张量中第一个元素的index。 上图例子中,在二维张量中访问元素(i,j)(i,j)的结果是访问存储中的storageoffsetstride〔0〕istride〔1〕j元素。 更加广义的:对于形状为shape(d1,d2,。。,dn)shape(d1,d2,。。,dn)的张量的视图中的元素E(e1,e2,,en)E(e1,e2,,en),如果该张量的存储的步长为stride(s1,s2,,sn)stride(s1,s2,,sn)、存储偏移量为storageoffsetstorageoffset,那么元素EE的存储位置indexindex是: 由此我们得出了张量视图的计算式子: 张量视图张量存储张量形状张量步长张量偏移 张量存储对张量操作的影响 这种张量和存储之间的间接性导致了一些操作,比如转置一个张量或者提取一个次张量,这些操作是便宜的,因为它们不会导致内存的重新分配;而是,它们包括分配一个新的张量对象,这个张量对象的形状、存储偏移量或步长有不同的值。 子张量的维数变少,而索引的存储空间仍然和原来的点张量一样。改变子张量会对原张量产生副作用(对子张量的修改会影响原张量)。但是这种效果可能并不总是存在,因为可以把子张量克隆成一个新的张量。 没有分配新的内存:只有通过创建一个新的张量实例来获得转置(transpose),这个张量实例的步长与原来的张量不同。可以通过张量的重新布局函数,比如PyTorch中的contiguous()函数,来强制拷贝一份张量,让它的布局和从新创建的张量一样。 张量的视图与存储的区别与联系 联系 对于形状shape为(d1,d2,。。,dn)的张量的视图中的元素E(e1,e2,,en),如果该张量的存储的步长为stride为(s1,s2,,sn)、存储偏移量storageoffset为so,那么元素E的存储位置index是: 张量视图张量存储张量形状张量步长张量偏移 区别 相同存储可以有不同的视图:tensorB。storage()与tensorBtranspose。storage()相同,但是tensorB与tensorBtranspose不同。 相同的视图可以有不同的存储:tensorA与tensorBtranspose相同,但是tensorA。storage()与tensorBtranspose。storage()不同。 总结:张量的视图与存储通过索引来建立关系,它们之间没有必然性,即相同存储可以有不同的视图,相同的视图可以有不同的存储。 张量的操作 点击TensorFlow张量的常用操作。ipynb深入学习,下面是该文件的主要内容:dtypeint32,float32,string,booltf。converttotensor,tf。constant,tf。zeros,tf。ones,tf。zeroslike,tf。fill,tf。random。normal,tf。random。uniform,tf。rangeA〔1〕〔2〕〔1〕,A〔1,2,1〕,A〔:,:,0:3:2〕,A〔。。。,0:3:2〕tf。reshape,tf。expanddims,tf。squeeze,tf。transposetf。tile,,,,,,,tf。pow,tf。square,tf。sqrt,tf。math。log,tf。matmul,tf。concat,tf。stack,tf。split,tf。unstacktf。norm,tf。reducemaxminmeansum,tf。argmax,tf。argmintf。equaltf。pad,tf。keras。preprocessing。sequence。padsequences,tf。tiletf。maximum,tf。minimum,tf。clipbyvaluetf。gather,tf。gatherndtf。booleanmasktf。wheretf。scatterndtf。meshgrid