PyTorch之张量Tensor笔记
我们人眼看到的图像在计算机中都是以数字进行编码的,所以在神经网络模型中数据的输入都是数字(像素值),比如图像深度为8位的像素值范围在0-255之间,在输入模型之前,这些值需要转换成浮点数作为输入表征,模型内的计算与输出也是浮点数(代表与之对应的概率),AI模型训练需要计算大量的浮点数。
为此,PyTorch引入Tensor张量
,Tensor
是PyTorch
中最基本的数据结构,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中的数字是对象,如上例,a
是int
类的实例。这种方法的劣势:
在计算机中,一个浮点数可能需要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提供的,半精度计算需要的内存和时间较小,同时对于结果的影响也很小。
参考:
- https://mp.weixin.qq.com/s/sQEM2Scpn7mannDDAHq2Dw
- 《PyTorch深度学习实战》