PyTorch之张量Tensor笔记

我们人眼看到的图像在计算机中都是以数字进行编码的,所以在神经网络模型中数据的输入都是数字(像素值),比如图像深度为8位的像素值范围在0-255之间,在输入模型之前,这些值需要转换成浮点数作为输入表征,模型内的计算与输出也是浮点数(代表与之对应的概率),AI模型训练需要计算大量的浮点数。

为此,PyTorch引入Tensor张量TensorPyTorch中最基本的数据结构,Tensor这个数据结构操作起来和数组类似,可以用单个索引访问,也可以用多个索引访问。在Python中,NumPy作为最受欢迎的多维数组操作库,已经成为数据科学的通用工具。Tensor可以与NumPy无缝衔接,同时也增加了一些更强大的功能,比如适用于GPU计算,并行计算等。

List与Tensor转换

list转Tensor,直接传入tensor作为参数:

l1 = [1,2,3]
t1 = torch.tensor(l1)
print(t1)

# output
tensor([1,2,3])

tensor转list,tensor对象调用tolist()方法:

t1.tolist()

NumPy与Tensor转换

从numpy转tensor有两种法式,一是通过torch.Tensor(data),二是通过torch.from_numpy(data):

import torch
import numpy as np

l1 = [1,2,3]
nd = np.array(l1)

t1 = torch.Tensor(nd)
print(t1)

# output
 tensor([[1., 2., 3.],
        [4., 5., 6.]])

t2 = torch.from_numpy(nd)
print(t2)

# output
 tensor([[1, 2, 3],
        [4, 5, 6]])

细心的同学可以发现,两种方式创建的tensor有所区别,第一种方式生成的元素带小数点,第二种就是正常的,为什么会这样?

让我们一探究竟。tensor对象有一个storage()方法,用于返回真正存储的内容,同时还会返回元素的类型,

print(t1.storage())
# output
 1.0
 2.0
 3.0
 4.0
 5.0
 6.0
[torch.storage.TypedStorage(dtype=torch.float32, device=cpu) of size 6]

print(t2.storage())
# output
 1
 2
 3
 4
 5
 6
[torch.storage.TypedStorage(dtype=torch.int64, device=cpu) of size 6]

我们看到,两种方式创建的元素类型dtype是不一样的,一个是torch.float32,一个是torch.int64,所以我们也可以猜测,tensor.Torch()方法内部会将数据做一个转换,毕竟模型的计算都是基于浮点数的,而from_numpy就直接讲numpy的内容复制过来,不做任何多余的操作。

Tensor转Numpy:

print(t2.numpy())

# output
[[1 2 3]
 [4 5 6]]

Tensor数据类型

a = 1
print(type(a))

# output
<class 'int'>

首先,讲讲Python中的数字类型。Python中的数字是对象,如上例,aint类的实例。这种方法的劣势:

在计算机中,一个浮点数可能需要32位来表示,而Python中会将数字转换成一个对象,对于存储大量的数据,这种对象的方式就非常低效。Python对列表数据没有提供专门的矩阵运算操作,比如点积向量求和。而且,Python的列表对内存不够友好,因为Python对象指向的是内存中的地址,不一定是连续的。

鉴于以上的原因,Python的列表肯定就不适用于高效的数值计算了,不得不依赖于NumPy或着PyTorch等第三方库。Tensor张量在构造时,可以通过dtype参数指定数据类型,dtype支持的常用数据类型如下:

  • 半精度浮点数:torch.float16或torch.half
  • 32位浮点数:torch.float32或torch.float
  • 64位双精度浮点数:torch.float64或torch.double
  • 8位有符号整数:torch.int8
  • 8位无符号整数:torch.uint8
  • 16位有符号整数:torch.int16或torch.short
  • 32位有符号整数:torch.int32或torch.int
  • 64位有符号整数:torch.int64或torch.long
    默认是32位浮点数。

需要说明的是,精度越高,计算时需要的内存和事件就会越多,还有,16位半精度浮点数在标准CPU中不存在,是给GPU提供的,半精度计算需要的内存和时间较小,同时对于结果的影响也很小。


参考:

posted @ 2022-11-17 14:26  博客圆萌主  阅读(129)  评论(0)    收藏  举报
个人博客 | 个人短链接平台