前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PyTorch1: 张量的性质

PyTorch1: 张量的性质

作者头像
小胡胡说
修改2020-08-05 09:56:27
1.5K0
修改2020-08-05 09:56:27
举报
文章被收录于专栏:小胡学编程小胡学编程

1.张量


张量的概念在深度学习领域里,是可以使用GPU进行运算的多维数组。

  • 0维张量是一个标量(scalar);
  • 1维张量是一个矢量(vector);
  • 2维张量是一个矩阵(matrix);
  • 3维以上的张量并没有通俗的表示方式。

2.张量的数据类型


张量一共有三种类型,分别是:整数型、浮点型和布尔型。其中整数型和浮点型张量的精度分别有8位、

16位、32位和64位。

整数型:

  • 8位:torch.int8
  • 16位:torch.int16 或 torch.short
  • 32位:torch.int32 或 torch.int
  • 64位:torch.int64 或 torch.long

浮点型:

  • 16位:torch.float16 或 torch.half
  • 32位:torch.float32 或 torch.float
  • 64位:torch.float64 或 torch.double

布尔型:

  • torch.bool

获得一个张量的数据类型可以通过指令 Tensor.dtype 实现;

如果给这个表达式赋值,则将这个张量的数据类型改为目标类型。

3.PyTorch的不同形态


PyTorch可以通过不同方式形态达到同样的目的。

3.1 函数功能:torch.function()与Tensor.function()


约定:如果有写Tensor.xxx(),那么这个Tensor指的是一个具体的张量。

在Pytorch中,张量的很多运算既可以通过它自身的方法,也可以作为Pytorch中的一个低级函数来实现。

比如两个张量ab相加,既可以写成torch.add(a,b),也可以写成a.add(b)

3.2 赋值语句:


很多张量的属性既可以在创建时声明,也可以在之后任何时间声明。

比如把一个值为1的 32 位整数张量赋给变量a,可以在生成时一步到位,

代码语言:javascript
复制
a = torch.tensor(1, dtype=torch.int32)

也可以先生成a的张量,然后再改变它的数据类型。

代码语言:javascript
复制
a = torch.tenor(1)
a.dtype = torch.int32

4.张量的存储


张量存储在连续的内存中,被torch.Storage 控制。

一个Storage是一个一维的包含数据类型的内存块。

一个 PyTorch 的Tensor本质上是一个能够索引一个Storage的视角。

例如:你可以访问一个Tensor的Storage:

代码语言:javascript
复制
>>> points = torch.tensor([[1.0, 4.0], [2.0, 1.0], [3.0, 5.0]])
>>> points.storage()
1.0
4.0 
2.0 
1.0 
3.0 
5.0
[torch.FloatStorage of size 6]

你不能对一个Storage进行二维索引。

因为Storage是一维的张量的存储,修改它同样会改变张量本身。

5.张量的size,storage offset 和stride


我们先定义一个张量:

代码语言:javascript
复制
>>> points = torch.tensor([[1.0, 4.0], [2.0, 1.0], [3.0, 5.0]])
>>> points
tensor([[1., 4.],
        [2., 1.],
        [3., 5.]])

5.1 张量的 size


获得一个张量的形状有四种方法:

  • Tensor.size()
代码语言:javascript
复制
>>> points.size()
torch.Size([3, 2])
  • Tensor.shape
代码语言:javascript
复制
>>> points.shape
torch.Size([3, 2])

可以看出,两者的区别在于 Tensor.shape 没有 ()

  • Tensor.numel()

查看 tensor 内的元素个数。

代码语言:javascript
复制
>>> points.numel()
6
  • Tensor.dim()Tensor.ndim

查看张量的维数,即有几维。

5.2 张量的 storage offset


查看张量内的相应元素与内存中第一个元素的相对位移。

代码语言:javascript
复制
>>> second_point = points[1]
>>> second_point.storage_offset()
2 

因为 pointsstorage1.0, 4.0, 2.0, 1.0, 3.0, 5.0second_point 距离这个张量在内存中的第一个元素的距离是 2。

5.3 张量的 stride


指的是当索引增加 1 时,每个维度内需要跳过的元素个数,是一个元组。

代码语言:javascript
复制
>>> points.stride()
(2, 1)

6. 张量的变形、升维与降维


6.1 张量的变形:Tensor.view()Tensor.reshape() Tensor.resize()


括号里面的数值用小括号、中括号或者不用括号括起来都可以,维数自定,只要所有数字的乘积与原尺寸的乘积相同即可。Tensor.view()Tensor.reshape() 的维度中可以有一个 -1,表示该维的长度由其他维度决定。Tensor.resize() 的维度中不能有 -1。

代码语言:javascript
复制
>>> points.reshape((1, 2, 1, -1))
tensor([[[[1., 4., 2.]],
         [[1., 3., 5.]]]])

6.2 张量的转置:Tensor.t() Tensor.T Tensor.transpose(dim1, dim2)


Tensor.t()只能转置维度小于等于 2 的张量,转置第 0、1 维。

代码语言:javascript
复制
>>> a = torch.arange(4).reshape(2, 2)
>>> a.t()
tensor([[0, 2],
        [1, 3]])

Tensor.T 把整个张量的维度进行颠倒。

代码语言:javascript
复制
>>> new_points = points.reshape(1, 2, -1, 1, 3)
>>> new_points.shape
torch.Size([1, 2, 1, 1, 3])
>>> new = new_points.T
>>> new.shape
torch.Size([3, 1, 1, 2, 1])

Tensor.transpose(dim1, dim2) 可以转置任意两个维度。

代码语言:javascript
复制
>>> new2 = new_points.transpose(1, 4)
>>> new2.shape
torch.Size([1, 3, 1, 1, 2])

6.3 张量的降维:Tensor.squeeze()


所谓降维,就是消去元素个数为 1 的维度。可以指定想消去的维度,若该维度不能消去,则该命令无效,但是不报错。若没有指定维度,则消去所有长度为 1 的维度。

代码语言:javascript
复制
>>> new_points2 = new.squeeze(1)
>>> new_points2.shape # 降维成功
torch.Size([3, 1, 2, 1])
>>> new_points3 = new.squeeze(0)
>>> new_points3.shape # 降维失败
torch.Size([3, 1, 1, 2, 1])
>>> new_points4 = new_points.squeeze()
>>> new_points4.shape # 降维成功
torch.Size([2, 3])

6.4 张量的升维:Tensor.unsqueeze()


升维必须指定增加的维度,必须在张量的已有维度 (-dim-1, dim+1) 之间。相当于在两个维度之间“加塞”,后面的维度顺移一位。

代码语言:javascript
复制
>>> new_points4.unsqueeze(2).shape
torch.Size([2, 3, 1])

7. 张量的复制与原地修改


因为张量本质上是连续内存地址的索引,我们把一段内存赋值给一个变量,再赋值给另一个变量后,修改一个变量中的索引往往会改变另一个变量的相同索引:

代码语言:javascript
复制
>>> a = torch.tensor([1, 2, 3, 4])
>>> b = a
>>> b[1] = 10
>>> a, b
(tensor([ 1, 10,  3,  4]), tensor([ 1, 10,  3,  4]))

我们希望能够控制这种现象。

7.1 张量的复制


使用 Tensor.clone() 复制一段内存上的数据到另一段内存上,这两个张量相互独立。

代码语言:javascript
复制
>>> a = torch.tensor([1, 2, 3, 4])
>>> b = a.clone()
>>> b[1] = 10
>>> a, b
(tensor([ 1, 10,  3,  4]), tensor([ 1, 10,  3,  4]))

7.2 张量的原地修改


如果我们能够避免引入新张量,直接在原始张量上修改,不就可以避免混淆了吗?很多张量操作都支持原地(in-place)操作,只要在原始函数后面加上 _ 就表明是原地修改。比如:

代码语言:javascript
复制
>>> a = torch.ones(2, 2) # 创建一个 2 x 2 的全 1 张量
>>> a
tensor([[1., 1.],
        [1., 1.]])
>>> a.add_(1) # 原地每个元素加 1
>>> a
tensor([[2., 2.],
        [2., 2.]])

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.张量
  • 2.张量的数据类型
    • 整数型:
      • 浮点型:
        • 布尔型:
        • 3.PyTorch的不同形态
          • 3.1 函数功能:torch.function()与Tensor.function()
            • 3.2 赋值语句:
            • 4.张量的存储
            • 5.张量的size,storage offset 和stride
              • 5.1 张量的 size
                • 5.2 张量的 storage offset
                  • 5.3 张量的 stride
                  • 6. 张量的变形、升维与降维
                    • 6.1 张量的变形:Tensor.view(),Tensor.reshape() 或 Tensor.resize()
                      • 6.2 张量的转置:Tensor.t() Tensor.T 或 Tensor.transpose(dim1, dim2)
                        • 6.3 张量的降维:Tensor.squeeze()
                          • 6.4 张量的升维:Tensor.unsqueeze()
                          • 7. 张量的复制与原地修改
                            • 7.1 张量的复制
                              • 7.2 张量的原地修改
                              相关产品与服务
                              对象存储
                              对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                              领券
                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档