【进阶篇】全流程学习《20天掌握Pytorch实战》纪实 | Day05 | 张量数据结构

举报
府学路18号车神 发表于 2022/05/11 15:25:00 2022/05/11
【摘要】 开源自由,知识无价~@TOC所用到的源代码及书籍+数据集以帮各位小伙伴下载放在文末,自取即可~ 一、🎉前言Pytorch的基本数据结构是张量Tensor。张量即多维数组。Pytorch的张量和numpy中的array很类似。本节我们主要介绍张量的数据类型、张量的维度、张量的尺寸、张量和numpy数组等基本概念。文中本章主要介绍一些张量的数据结构相关知识,看懂学会即可。 二、🎉张量的数据类...

开源自由,知识无价~

@TOC

所用到的源代码及书籍+数据集以帮各位小伙伴下载放在文末,自取即可~

一、🎉前言

Pytorch的基本数据结构是张量Tensor。张量即多维数组Pytorch的张量和numpy中的array很类似。

本节我们主要介绍张量的数据类型张量的维度张量的尺寸张量numpy数组等基本概念。

文中本章主要介绍一些张量的数据结构相关知识,看懂学会即可。

二、🎉张量的数据类型

张量的数据类型numpy.array基本一一对应,但是不支持str类型

包括如下:

  • torch.float64(torch.double),

  • torch.float32(torch.float)

  • torch.float16

  • torch.int64(torch.long)

  • torch.int32(torch.int)

  • torch.int16

  • torch.int8

  • torch.uint8

  • torch.bool

一般神经网络建模使用的都是torch.float32类型(==此处划重点==)

import numpy as np
import torch 

# 自动推断数据类型

i = torch.tensor(1);print(i,i.dtype)
x = torch.tensor(2.0);print(x,x.dtype)
b = torch.tensor(True);print(b,b.dtype)

输出可得:

tensor(1) torch.int64
tensor(2.) torch.float32
tensor(True) torch.bool

同理查看类型:

tensor(1, dtype=torch.int32) torch.int32
tensor(2., dtype=torch.float64) torch.float64
  • 使用特定类型构造函数
# 使用特定类型构造函数

i = torch.IntTensor(1);print(i,i.dtype)
x = torch.Tensor(np.array(2.0));print(x,x.dtype) #等价于torch.FloatTensor
b = torch.BoolTensor(np.array([1,0,2,0])); print(b,b.dtype)

查看类型:

tensor([1073741825], dtype=torch.int32) torch.int32
tensor(2.) torch.float32
tensor([ True, False, True, False]) torch.bool
  • 不同类型进行转换
# 不同类型进行转换

i = torch.tensor(1); print(i,i.dtype)
x = i.float(); print(x,x.dtype) #调用 float方法转换成浮点类型
y = i.type(torch.float); print(y,y.dtype) #使用type函数转换成浮点类型
z = i.type_as(x);print(z,z.dtype) #使用type_as方法转换成某个Tensor相同类型

查看类型:

tensor(1) torch.int64
tensor(1.) torch.float32
tensor(1.) torch.float32
tensor(1.) torch.float32

这三种方法都可以进行浮点类型转换,第一种方法简单高效

三、🎉张量的维度

不同类型的数据可以用不同维度(dimension)的张量来表示。

标量0维张量向量1维张量矩阵2维张量

彩色图像rgb三个通道,可以表示为3维张量

视频还有时间维,可以表示为4维张量

可以简单地总结为:有几层中括号,就是多少维的张量。(==划重点==)

下面举例4种维度的示例:

  • 0维向量
scalar = torch.tensor(True)
print(scalar)
print(scalar.dim())  # 标量,0维张量

输出显示:

tensor(True)
0
  • 1维向量
vector = torch.tensor([1.0,2.0,3.0,4.0]) #向量,1维张量
print(vector)
print(vector.dim())

输出:

tensor([1., 2., 3., 4.])
1
  • 2维向量
matrix = torch.tensor([[1.0,2.0],[3.0,4.0]]) #矩阵, 2维张量
print(matrix)
print(matrix.dim())

输出:

tensor([[1., 2.],
        [3., 4.]])
2
  • 3维向量
tensor3 = torch.tensor([[[1.0,2.0],[3.0,4.0]],[[5.0,6.0],[7.0,8.0]]])  # 3维张量
print(tensor3)
print(tensor3.dim())

输出:

tensor([[[1., 2.],
         [3., 4.]],

        [[5., 6.],
         [7., 8.]]])
3
  • 4维张量
tensor4 = torch.tensor([[[[1.0,1.0],[2.0,2.0]],[[3.0,3.0],[4.0,4.0]]],
                        [[[5.0,5.0],[6.0,6.0]],[[7.0,7.0],[8.0,8.0]]]])  # 4维张量
print(tensor4)
print(tensor4.dim())

输出显示:

tensor([[[[1., 1.],
          [2., 2.]],

         [[3., 3.],
          [4., 4.]]],


        [[[5., 5.],
          [6., 6.]],

         [[7., 7.],
          [8., 8.]]]])
4

三、🎉张量的尺寸

关于张量的尺度,可以使用shape属性或者size()方法查看张量在每一维的长度.

可以使用view方法改变张量的尺寸

如果view方法改变尺寸失败,可以使用reshape方法.

  • size()、shape
scalar = torch.tensor(True)
print(scalar.size())
print(scalar.shape)

输出:

torch.Size([])
torch.Size([])
vector = torch.tensor([1.0,2.0,3.0,4.0])
print(vector.size())
print(vector.shape)

输出:

torch.Size([4])
torch.Size([4])
matrix = torch.tensor([[1.0,2.0],[3.0,4.0]])
print(matrix.size())

输出维度大小:

torch.Size([2, 2])
  • 利用view改变张量的尺寸
# 使用view可以改变张量尺寸

vector = torch.arange(0,12)
print(vector)
print(vector.shape)

matrix34 = vector.view(3,4)
print(matrix34)
print(matrix34.shape)

matrix43 = vector.view(4,-1) #-1表示该位置长度由程序自动推断
print(matrix43)
print(matrix43.shape)

利用view根据张量的个数,设置维度的大小,可按照顺序进行排列,如果和设置的维度不符则会报错

输出:

tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
torch.Size([12])
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]])
torch.Size([3, 4])
tensor([[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8],
        [ 9, 10, 11]])
torch.Size([4, 3])
  • 为了防止view操作的失败,还可以用reshape操作
# 有些操作会让张量存储结构扭曲,直接使用view会失败,可以用reshape方法

matrix26 = torch.arange(0,12).view(2,6)
print(matrix26)
print(matrix26.shape)

# 转置操作让张量存储结构扭曲
matrix62 = matrix26.t()
print(matrix62.is_contiguous())


# 直接使用view方法会失败,可以使用reshape方法
#matrix34 = matrix62.view(3,4) #error!
matrix34 = matrix62.reshape(3,4) #等价于matrix34 = matrix62.contiguous().view(3,4)
print(matrix34)

输出:

tensor([[ 0,  1,  2,  3,  4,  5],
        [ 6,  7,  8,  9, 10, 11]])
torch.Size([2, 6])
False
tensor([[ 0,  6,  1,  7],
        [ 2,  8,  3,  9],
        [ 4, 10,  5, 11]])

整个流程下来很清晰,也容易看明白。

四、🎉张量和numpy数组

可以用numpy方法从Tensor得到numpy数组,也可以用torch.from_numpynumpy数组得到Tensor

这两种方法关联的Tensornumpy数组是==共享数据内存的==。

如果改变其中一个,另外一个的值也会发生改变。

如果有需要,可以用张量的clone方法拷贝张量,中断这种关联。

此外,还可以使用item方法从标量张量得到对应的Python数值

使用tolist方法从张量得到对应的Python数值列表

  • from_numpy函数得到Tensor
import numpy as np
import torch 
#torch.from_numpy函数从numpy数组得到Tensor

arr = np.zeros(3)
tensor = torch.from_numpy(arr)
print("before add 1:")
print(arr)
print(tensor)

print("\nafter add 1:")
np.add(arr,1, out = arr) #给 arr增加1,tensor也随之改变
print(arr)
print(tensor)
before add 1:
[0. 0. 0.]
tensor([0., 0., 0.], dtype=torch.float64)

after add 1:
[1. 1. 1.]
tensor([1., 1., 1.], dtype=torch.float64)
  • numpy方法从Tensor得到numpy数组
# numpy方法从Tensor得到numpy数组

tensor = torch.zeros(3)
arr = tensor.numpy()
print("before add 1:")
print(tensor)
print(arr)

print("\nafter add 1:")

#使用带下划线的方法表示计算结果会返回给调用 张量
tensor.add_(1) #给 tensor增加1,arr也随之改变 
#或: torch.add(tensor,1,out = tensor)
print(tensor)
print(arr)
before add 1:
tensor([0., 0., 0.])
[0. 0. 0.]

after add 1:
tensor([1., 1., 1.])
[1. 1. 1.]
  • clone方法打断关联
# 可以用clone() 方法拷贝张量,中断这种关联

tensor = torch.zeros(3)

#使用clone方法拷贝张量, 拷贝后的张量和原始张量内存独立
arr = tensor.clone().numpy() # 也可以使用tensor.data.numpy()
print("before add 1:")
print(tensor)
print(arr)

print("\nafter add 1:")

#使用 带下划线的方法表示计算结果会返回给调用 张量
tensor.add_(1) #给 tensor增加1,arr不再随之改变
print(tensor)
print(arr)
before add 1:
tensor([0., 0., 0.])
[0. 0. 0.]

after add 1:
tensor([1., 1., 1.])
[0. 0. 0.]

由此可知,clone方法打断了Tensornumpy之间的关联。

  • tolist和item方法转换python数值列表和数值
# item方法和tolist方法可以将张量转换成Python数值和数值列表
scalar = torch.tensor(1.0)
s = scalar.item()
print(s)
print(type(s))

tensor = torch.rand(2,2)
t = tensor.tolist()
print(t)
print(type(t))

输出可知,有效将Tensor转换为Python数值及列表:

1.0
<class 'float'>
[[0.753241777420044, 0.34639132022857666], [0.6001826524734497, 0.7457776665687561]]
<class 'list'>

关于张量数据结构的基本操作如上所述,更细节的可以在Torch官方文档找到。

🤗往期纪实

Date 《20天掌握Pytorch实战》
Day01 【进阶篇】全流程学习《20天掌握Pytorch实战》纪实 | Day01 | 结构化数据建模流程范例
Day02 【进阶篇】全流程学习《20天掌握Pytorch实战》纪实| Day02 | 图片数据建模流程范例
Day03 【进阶篇】全流程学习《20天掌握Pytorch实战》纪实 | Day03 | 文本数据建模流程范例
Day04 【进阶篇】全流程学习《20天掌握Pytorch实战》纪实 | Day04 | 时间序列建模流程范例

🥇总结

从数据建模的流程开始学习,按照准备数据、定义模型、训练模型、评估模型、使用模型、保存模型这六大常规思路,简单数据集入手。

本文示例主要解释了张量数据结构的基本操作。对于0基础的同学来说可能还是稍有难度,因此,本文中给出了大部分使用到的库的解释,同时给出了部分代码的注释,以便小伙伴的理解,仅供参考,如有错误,请留言指出,最后一句:开源万岁~

同时为原作者打Call

如果本书对你有所帮助,想鼓励一下作者,记得给本项目加一颗星星star⭐️,并分享给你的朋友们喔😊!

地址在这里哦:https://github.com/lyhue1991/eat_pytorch_in_20_days

😊Reference

书籍源码在此:
链接:https://pan.baidu.com/s/1P3WRVTYMpv1DUiK-y9FG3A
提取码:yyds

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。