pytorch - tensor

tech2023-10-12  123

1 tensor概念

tensor是pyTorch的基本数据结构,可以表示任意维度的多维数组;

pyTorch tensor可以和Numpy array无缝的互操作,pyTorch tensor相对Numpy array的优点是:

tensor可以在Gpu上操作;tensor可以在多台设备上分布式运行;tensor可以记录其创建过程以便进行autograd操作。

python list或tuple中存储的是单独分配在内存中的python对象的集合,而numpy array和pytorch tensor中存储的是连续内存块的视图,该内存块中存储的是未封装的C语言数值类型;

2 tensor构造

3 tensor索引

points[None] 等价于对 points 添加一个新的维度,等价于 points.unsqueeze(0);

4 Named tensor

tensor的维度常用来进行索引,如表示像素位置或颜色channel。这意味着如果我们要对某个tensor进行索引,就需要记清各个维度的顺序,但如果某个tensor进行了很复杂的处理过程,往往很容易因为记混tensor的各个维度的含义而造成错误。

pytorch 1.3版本开始引入了named tensor,即给tensor的各个维度进行命名,如:

refine_names 函数用于对一个未命名的tensor添加name,如下所示: align_as返回一个tensor,自动补充缺失的维度,并且按名字将维度调整为正确的顺序:

tensor的那些按照维度进行操作的函数,如sum,可以按照named维度进行操作,如:

如果想将名字不同的维度进行结合,会报错,如: **rename(None)**可以去掉一个Named tensor的名字,如: named tensor有助于消除维度对齐的错误。

5 tensor支持的数据类型

为什么不用python原生的数据类型进行大规模的矩阵运算 ?

答案: python原生的数据类型都是封装过的数据,添加了引用计数这些信息,大规模计算时效率低。numpy array和pytorch tensor提供的api都是在底层封装的是C语言实现的数据计算,效率更高。

pytorch tensor中存储的是同类型的数据,可以在构造函数中通过dtype指定创建的tensor的数据类型。

pytorch中常用的数据类型有:

torch.float32 或 torch.floattorch.float64 或 torch.doubletorch.float16 或 torch.halftorch.int8torch.uint8torch.int16 或 torch.shorttorch.int32 或 torch.inttorch.int64 或 torch.longtorch.bool

默认的数据类型是 32位单精度浮点数。

CPU不支持半精度浮点数运算,但GPU支持,将单精度浮点数改为半精度浮点数,可以减少显存占用且对模型的准确率影响很小,这也是混合精度训练能够成功的原因。

下面的操作会创建一个bool类型的tensor: 设定tensor的数据类型:

在构造函数中指定;使用to函数强制转换;

6 tensor是连续内存块的视图

tensor是连续内存块的视图,通过offset和每一维的stride索引到实际的内存。

storage函数用于查看一个tensor的实际存储,如: 实际存储一定是连续的一维的内存序列。

改变storage中的数据之后,tensor的内容也会跟着改变: tensor的带下划线的函数,如zero_都是对tensor进行in-place操作,直接修改了tensor本身。

tensor的size()函数和shape属性查看tensor的各个维度的大小;storage_offset函数查看tensor相比对实际存储的起始位置的距离;stride函数查看在tensor的每个维度上前移一位对应到实际存储上需要移动的位数。 2D tensor中第(i,j)个元素在实际存储中的位置为 storage_offset + i * stride[0] + j * stride[1].

tensor只是实际内存的视图,因此很多操作,如transpose和subtensor的效率很高,因为并未进行实际存储的改变,只是改变了tensor的属性(size,storage_offset和stride)。

clone函数是深拷贝tensor,进行了新的内存分配: contiguous函数是将一个tensor的存储变为连续队列,如: z是y的转置,其存储对z来说是不连续的,执行contiguous函数后,存储对z来说变成连续的了。

7 转换tensor的存储位置

构造函数中,通过device参数设置tensor存储在内存还是显存中,如: 也可以通过to函数强制改变tensor的存储位置,如: 还可以通过cuda、cpu函数改变存储位置: cuda(1)表示传输到第二块显卡上,默认参数为0,表示传输到第一块显卡上。

8 tensor和ndarray转换

numpy函数将tensor转换为ndarray;from_numpy将numpy转换为tensor。 numpy函数返回的ndarray与tensor共享内存,因此如果tensor本身就放在内存上,那么这个转换基本上是没有开销的。但如果tensor本身放在显存上,则需要先将数据拷贝到内存上,并基于该内存块构建一个tensor。

9 保存tensor

pytorch底层使用pickle来保存数据,使用torch.save保存tensor,torch.load加载保存结果。 保存成HDF5格式:

打开hdf5文件时并没有真正的加载数据,直到访问数据时才会真正的加载数据。存储和加载回来的数据是ndarray类型。

最新回复(0)