阅读 459

深度学习的基础设施— Tensor (Pytorch 版)

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

有关张量定义和理解,我根据自己认知跟大家聊一聊,个人认知有限,对于张量仅是停留在表面上。因为 Tensor 的确过于复杂,个人仅是从深度学习角度来解释张量,以及为什么深度学习要引入张量的概念。

什么是 Tensor

在深度学习框架中,大部分数据都是以 Tensor 这样数据格式存在,大家可能会疑惑什么是 Tensor(张量)。我们先给出张量的定义,一个量, 在不同的参考系下按照某种特定的法则进行变换, 就是张量. 张量好处就是物理定律是不会随参考系的变化而变化的,所以通过在深度学习中,而且 Tensor 这种数据结构可以表示大多世界上的事物,所以深度学习才采用张量作为基础的数据结构。

在深度学习中,我们需要用一种结构化数据来描述事物。例如天气的温度,只有数值大小,是一个标量,标量可以理解为 0 维张量。其实所谓标量就是空间的一个点,如果我们选择不同坐标系其取值也不同 x=f(x)x^{\prime} = f(x) 这里 f 表示一种测量手段,其实 xxxx^{\prime}

速度是一个既有大小又有方向的量,我们通常用向量来表示,向量可以分解到 x 和 y 上分量,向量可以表示两个 2 分量的线性组合,向量是一个 1 维张量,可能是因为其每个分量都是 1 维的,所以向量是 1 阶的张量

接下来聊一聊矩阵,一个 3 维矩阵可以通过一下 xy, zy, yx,zx, zy,zx 分量组合来表示一个矩阵,如果在一个平面分别受到垂直平面和与沿平面的的力,那么我们需要用多维张量来表示。

环境搭建

  • 需要先安装 Anaconda
  • 安装 Pytorch

有关 Anaconda 和 Pytorch 安装这里不做过多介绍,

import torch
import numpy as np
复制代码
# 创建了 2 行 3 列,
a = torch.randn(2,3)
复制代码

获取 Tensor 的类型

在 pytorch 中有关 tensor 类型判断,提供了两种方式,一种通过调用 tensor 对象的 type 方法,另一种是使用 isinstance 来对 tensor 类型进行判断,如果使用 type 来获取 tensor类型,获取类型信息没有使用 type 或 isinstance 获取类型信息更详细。所以建议使用 tensor.type()方法或者 isinstance 来对 tensor 进行类型判断。

a.type()#'torch.FloatTensor'
复制代码

注意这里如果使用 type 来输出 a 类型,仅提供 a 为 torch.Tensor 的类型,并没有提供更详细、更准确类型。注意 a.type() 是方法返回

type(a)#torch.Tensor
复制代码
isinstance(a,torch.FloatTensor)#True
复制代码
isinstance(a,torch.cuda.DoubleTensor)#False
复制代码

`

0 维 Tensor(标量)

0 维的 Tensor 可以看作标量,在 pytorch 中 0 维的 tensor 的 shape 通常都是为 0,调用 const_2 的 shape 来查看标量 const_2 类型为 torch.Size([])。这里的 torch.Size([]) 是表示维类型,而不是表示为空的[]的 tensor。

const_1 = torch.tensor(1.)
const_1 #tensor(1.)
复制代码
const_2 = torch.tensor(1.3)
const_2#tensor(1.3000)
复制代码
const_2.shape#torch.Size([])
复制代码

可以通过调用 shape 和 dim 来查看 const_2 的类型

len(const_2.shape) #0
复制代码
const_2.dim() #0
复制代码
const_2.size()#torch.Size([])
复制代码

1 维 Tensor(向量)

在 pytorch 中,1 维 Tensor 可以看作向量,那么在神经网中,什么地方会用到向量呢,其实我们每个隐含层都是由 weight 和 bias(偏置值)来表示。

# 创建一个 tensor
vec_1 = torch.tensor([1.2])
vec_1 #tensor([1.2000])
复制代码
vec_2 = torch.tensor([1.2,1.3])
vec_2 #tensor([1.2000, 1.3000])
复制代码
vec_3 = torch.FloatTensor(1)
vec_3 #tensor([0.])
复制代码
vec_5 = torch.FloatTensor(2)
vec_5 #tensor([1.4569e-19, 6.4069e+02])
复制代码
data = np.ones(2)
data #array([1., 1.])
复制代码
vec_6 = torch.from_numpy(data)
vec_6 #tensor([1., 1.], dtype=torch.float64)
复制代码
# ones 创建 2 
a = torch.ones(2)
a #tensor([1., 1.])
复制代码
b = torch.Size([2])
b #torch.Size([2])
复制代码

2 维 Tensor(矩阵)

在 pytorch 中,2 维矩阵主要用于表示图片,在计算机中,我们是用 2 维矩阵表示图片每一个像素位置,然后在通过一个通道维度表示像素的颜色和透明度的信息。 在 mnist 数据集为例来说明 2 维矩阵在神经网络中的用途,输入图片为 28×2828 \times 28,然后将 2 维图图像展平为 1 维 784 维,然后如果一次输入多长图片,就是32×78432 \times 784 表示每一个批次为 32

a = torch.rand(2,3)
a
复制代码
tensor([[0.5607, 0.9660, 0.3631],
        [0.9655, 0.8591, 0.2379]])
复制代码
a.shape #torch.Size([2, 3])
复制代码
a.size(0)#2
复制代码
a.size(1)#3
复制代码
a.shape[0] #2
复制代码

如何使用 Tensor 表示文本

关于 3 维 Tensor 我们还是从实际出发,在 RNN 网络中,就会用到 3 维 Tensor,接下来我们来看看,输入就是 3 维张量,[10,20,100] 我们来看这个 3 维 tensor,10 表示每次句话 10 单词、20 表示每次批次 20 句话、100 表示用 100 维向量来表示一个单词

a = torch.rand(1,2,3)
a
复制代码
tensor([[[0.0202, 0.9752, 0.4535],
         [0.7427, 0.5266, 0.2373]]])
复制代码
a.shape #torch.Size([1, 2, 3])
复制代码
list(a.shape)#[1, 2, 3]
复制代码
a[0]
复制代码
tensor([[0.0202, 0.9752, 0.4535],
        [0.7427, 0.5266, 0.2373]])
复制代码
a[0][0] #tensor([0.0202, 0.9752, 0.4535])


复制代码
a[0][0][0] #tensor(0.0202)
复制代码

如何使用 Tensor 表示图像

例如我们有两张图片要输入到网络,对于卷积神经网,想要保留图片位置信息,就会需要图片位置信息使用两个维度来表示图片每一个像素位置,也就是 28 和 28 ,最后用 1 维度表示每个像素的通道数,例如可以是 3 通道表示 RGB ,也可以 1 表示灰度信息。

a = torch.rand(2,3,28,28)
复制代码
# a
a.shape #torch.Size([2, 3, 28, 28])
复制代码

a.numel() #4704
复制代码
文章分类
人工智能