pytorch - tensor

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构造

pytorch - tensor_第1张图片

3 tensor索引

pytorch - tensor_第2张图片
points[None] 等价于对 points 添加一个新的维度,等价于 points.unsqueeze(0);

4 Named tensor

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

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

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

pytorch - tensor_第6张图片tensor的那些按照维度进行操作的函数,如sum,可以按照named维度进行操作,如:

在这里插入图片描述
如果想将名字不同的维度进行结合,会报错,如:
pytorch - tensor_第7张图片**rename(None)**可以去掉一个Named tensor的名字,如:
pytorch - tensor_第8张图片named tensor有助于消除维度对齐的错误。

5 tensor支持的数据类型

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

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

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

pytorch中常用的数据类型有:

  • torch.float32 或 torch.float
  • torch.float64 或 torch.double
  • torch.float16 或 torch.half
  • torch.int8
  • torch.uint8
  • torch.int16 或 torch.short
  • torch.int32 或 torch.int
  • torch.int64 或 torch.long
  • torch.bool

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

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

下面的操作会创建一个bool类型的tensor:
pytorch - tensor_第9张图片
设定tensor的数据类型

  • 在构造函数中指定
  • 使用to函数强制转换
    pytorch - tensor_第10张图片

6 tensor是连续内存块的视图

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

storage函数用于查看一个tensor的实际存储,如:
pytorch - tensor_第11张图片
实际存储一定是连续的一维的内存序列

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

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

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

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

7 转换tensor的存储位置

构造函数中,通过device参数设置tensor存储在内存还是显存中,如:
在这里插入图片描述
也可以通过to函数强制改变tensor的存储位置,如:
在这里插入图片描述
还可以通过cuda、cpu函数改变存储位置
pytorch - tensor_第16张图片
cuda(1)表示传输到第二块显卡上,默认参数为0,表示传输到第一块显卡上

8 tensor和ndarray转换

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

9 保存tensor

pytorch底层使用pickle来保存数据,使用torch.save保存tensor,torch.load加载保存结果
pytorch - tensor_第18张图片
pytorch - tensor_第19张图片
保存成HDF5格式:

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

你可能感兴趣的:(pytorch)