在进行深度学习时绕不过去的就是张量概念了,作为我们学习深度学习路上的第一块绊脚石,我就斗胆向你们介绍一下张量的概念,移除你们学习路上的绊脚石,希望本篇文章对你们能够有所帮助。
什么是张量?
按照我们的惯例,我们先去官网上查看一下官方文档是怎样描述张量的
张量
张量是一个类似于数组与矩阵的专用的数据类型。在PyTorch中,我们使用张量来编码模型的输入输出与模型的参数。
除了张量可以在GPU或者其他硬件加速器上运行之外,张量类似于NumPy的n维数组。实际上,张量和NumPy数组通常可以共用底层内存,从而消除复制数据的需要。张量也对自动微分进行了优化(我们将在后面的Autograd一节中看到更多相关内容),如果你对n维数组熟悉的化,那你也将对张量API非常熟悉。如果不熟悉的话,跟着做。
可以看到官方的描述中说,张量是一种数据类型,可以在硬件上进行加速。
那么到底什么是张量呢?我相信小伙伴对此依然一头雾水,你们也许会说:“是的,我们虽然对张量有一定的了解了,知道这种数据类型与数组和矩阵类似,但是它究竟是什么呢?”接下来就让我带着你们去揭开张量神秘的面纱(当然这只是简单的让你们了解一下,毕竟以我的知识储备还不足以理解张量,所以我所能够带给你的只是对张量最浅显的理解)。
张量的关键属性
张量的关键属性有三个,1.轴的个数,2.张量的形状,3.张量的数据类型,4.储存张量的设备
1、轴的个数,我们可以理解为阶数,几阶张量就有几个轴,如一阶张量具有一个轴,二阶张量具有两个轴。
2、张量的形状,张量的形状描述了张量在具体轴上的长度,例如,假设我们有如下张量
我们说这是一个(2, 5)的张量,表示在轴0上的长度为2,在轴1上的长度为5.张量的形状则告诉了我们张量沿每个轴的长度。
3、数据类型,张量中数据的类型,张量有八种数据类型,这八种数据类型分别是
4、储存张量的设备,这一属性描述了数据储存在什么设备上,如CPU,GPU
下面代码可以将张量的属性打印出来,我们可以运行一下试试
# 创建一个形状是(3,4)的张量其中数据是随机的
tensor = torch.rand(3,4)
# 打印张量的形状
print(f"Shape of tensor: {tensor.shape}")
# 打印张量的数据类型
print(f"Datatype of tensor: {tensor.dtype}")
# 打印张量储存在什么设备上
print(f"Device tensor is stored on: {tensor.device}")
结果如下:
Shape of tensor: torch.Size([3, 4])
Datatype of tensor: torch.float32
Device tensor is stored on: cpu
我们可以将张量理解为多维数组,当张量为0阶时,我们可以理解为这是一个数,当张量为1阶时我们可以将其理解为一个向量,当张量为2阶时,我们可以将其理解为这是一个矩阵,当张量为3阶时,我们可以将其理解为这是一个立体矩阵。我试着画图表示一下这四种张量(画出图只是为了让你们更好的理解,并不代表数据就是这样的),图示如下:
相信这样能够让你对张量有一点点直观上的了解,或许你可以想象一下更高阶的张量。
相信大家看到这里大家对于张量有了一点朦胧的感觉(尽管是最浅显的理解),接下来我们带你们了解一下如何创建张量。
如何创建张量?(下面信息来自官方网站,有兴趣的小伙伴可以去看看,链接贴在下面)
张量的创建方法有四种,分别是1.从已有的数据直接转换成张量,2.从Numpy数组转化成张量,3.创建一个随机值的张量或者创建一个常数值张量。4.从另一个张量中得到一个张量
下面我们分别进行演示。
第一种方法:从已有数据直接转化成张量
# 导入演示所需包
import torch
# 创建一个空列表接受数据
num = []
for i in range(10):
num.append(i)
# 得到一个从已有数据创建的张量
x = torch.tensor(num)
# 打印张量的内容
print(x)
# 打印张量的数据类型
print(x.type())
输出结果如下
第二种方法:从Numpy数组转换过来
利用到的函数为torch.from_numpy()
关于torch.from_numpy()的官方文档描述如下:
从numpy的多维数组中创建一个张量,这个返回的张量和多维数组共享内存,修改张量的值会反应在多维数组中,反之亦然。返回的张量不可以再修改形状。
# 创建一个多维数组
a = numpy.array([1, 2, 3])
# 转换成张量
t = torch.from_numpy(a)
# 打印张量t中的内容
print(t)
# 通过张量修改值
t[0] = -1
# 打印多维数组的值,看是否被修改
print(a)
输出结果如下
tensor([ 1, 2, 3])tensor([-1, 2, 3])
第三种方法:创建一个随机值张量,或者常数值张量(张量中的值是随机值,或是张量中的值为常数值)
# shape是要创建的张量的形状,是一个元组
# 每一个数字代表了张量在对应轴上的长度
shape = (2,3,)
# 创建一个随机张量
rand_tensor = torch.rand(shape)
# 创建一个全为1的张量
ones_tensor = torch.ones(shape)
# 创建一个全为0的张量
zeros_tensor = torch.zeros(shape)
# 分别打印上面的张量
# 随机张量,因为随机每一次输出与上一次不相同是很正常的情况
print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")
下面是输出的结果:
Random Tensor:
tensor([[0.6764, 0.3261, 0.2462],
[0.0094, 0.8568, 0.8560]])Ones Tensor:
tensor([[1., 1., 1.],
[1., 1., 1.]])Zeros Tensor:
tensor([[0., 0., 0.],
[0., 0., 0.]])
第四种方法:从已有张量中创建张量
这种方法创建的张量与原先的张量具有相同的形状,我给你们打一个不恰当的比方,假设原先的张量是一个箱子,这一个箱子装的是玩具,我们这一种创建张量的方式是创建一个箱子与原先的箱子一样,但是这个箱子里装的东西可以与原先不一样。
data = [[1, 2],[3, 4]]
x_data = torch.tensor(data)
# 创建一个张量,此张量的形状与x_data形状一样,但是里面的数据全是1
x_ones = torch.ones_like(x_data) # retains the properties of x_data
print(f"Ones Tensor: \n {x_ones} \n")
# 创建一个张量,此张量的形状与x_data形状一样,但是里面的数据全是随机的
x_rand = torch.rand_like(x_data, dtype=torch.float) # overrides the datatype of x_data
print(f"Random Tensor: \n {x_rand} \n")
输出结果为:
Ones Tensor:
tensor([[1, 1],
[1, 1]])Random Tensor:
tensor([[0.3189, 0.1517],
[0.0728, 0.4654]])
以上就是创建张量的四种方法,我只是向你们阐述一下我浅显的认识,如果有什么不足,或者有不对的地方还请大家指出。
以上就是我要在这一篇文章中所要讲述的全部内容了,在后续的文章中我会讲述张量的一些操作,
如果你觉得本篇文章对你有用的话,请动一动手指帮博主点一个赞,你的支持就是我更新的动力。
我是apprentice_eye,一个致力于让知识变的易懂的博主
小伙伴们,点个关注再走吧!!!