深度学习 Pytorch 张量(Tensor)的创建和常用方法

1 张量的基本创建及其类型

Numpy中的array一样,张量的本质也是结构化地组织了大量的数据。

并且在实际操作中,张量的创建和基本功能也与其非常类似。


1.1 张量(Tensor)函数创建方法

张量的最基本创建方法和Numpy中创建Array的格式一致。

# Numpy创建数组
import numpy as np		#导入numpy
a = np.array([1, 2, 3])
import torch # 首次使用,导入torch包
# 通过列表创建张量
t = torch.tensor([1, 2])
t	# output : tensor([1, 2])
# 通过元组创建张量
t = torch.tensor((1, 2))
t	# output : tensor([1, 2])
# 通过数组创建张量
a = np.array([1, 2])
t = torch.tensor(a)
t	# output : tensor([1, 2],dtype = torch.int32)

通过上述返回结果,我们发现张量也有dtype类型


1.2 张量的类型

张量和数组类似,都拥有dtype方法,可返回张量类型。

来看整型

# 整型数组的dtype方法
np.array([1, 2, 3]).dtype
# output : int32
# 整型张量的dtype方法
torch.tensor([1, 2, 3]).dtype
# output : torch.int64

不难发现,整数型的数组默认创建int32(整型)类型,而张量则默认创建int64(长整型)类型。

如果tensor中传入的参数是array数组类型,那么它将会告诉你生成的是torch.int32类型:

a = np.array([1, 2])
t = torch.tensor(a)
t	# output : tensor([1, 2],dtype = torch.int32)

来看浮点型

# 浮点型数组的dtype方法
np.array([1.1, 2.2]).dtype
# output : float64
# 浮点型张量的dtype方法
torch.tensor([1.1, 2.2]).dtype
# output : torch.float32

不难发现,浮点型的数组默认创建float64(单精度浮点型),而张量则默认创建float32(双精度浮点型)。

如果tensor中传入的是array数组类型,那么它将会告诉你生成的是torch.float64类型:

a = np.array([1.1, 2.2])
t = torch.tensor(a)
t	# output : tensor([1.1000, 2.2000],dtype = torch.float64)

除了数值型张量,常用的张量类型还有布尔型张量,也就是构成张量的各元素都是布尔类型的张量。

t=torch.tensor([True,False])
t.dtype
# output : torch.bool

当然,在PyTorch中也支持复数类型对象创建

t = torch.tensor(1 + 2j)	# 1是实部、2是虚部
t	# output : tensor(1.+2.j)

此外,我们还可以通过dtype参数,在创建张量过程中设置输出结果

# 创建int16整型张量
torch.tensor([1.1, 2.7],dtype = torch.int16)
# output : tensor([1, 2], dtype = torch.int16)

和数组不同,对于张量而言,数值型和布尔型张量就是最常用的两种张量类型,相关类型总结如下:

数据类型dtype
32bit浮点数torch.float32或torch.float
64bit浮点数torch.float64或torch.double
16bit浮点数torch.float16或torch.half
8bit无符号整数torch.unit8
8bit有符号整数torch.int8
16bit有符号整数torch.int16或torch.short
16bit有符号整数torch.int16或torch.short
32bit有符号整数torch.int32或torch.int
64bit有符号整数torch.int64或torch.long
布尔型torch.bool
复数型torch.complex64

1.3 张量类型的转化

张量类型的隐式转化

Numpyarray相同,当各张量类型属于不同类型时,系统会自动进行隐式转化

# 浮点型和整数型的隐式转化
torch.tensor([1.1, 2]).dtype
# output : torch.float
# 布尔型和数值型的隐式转化
torch.tensor([True, 2.0])
# output : torch([1., 2.])

张量类型的转化方法

除了隐式转化,我们还可以使用.float().int()方法对张量类型进行转化

t = torch.tensor([1, 2])	#创建张量t
# 转化为默认浮点型(32位)
t.float()
# output : tensor([1., 2.])
# 转化为双精度浮点型
t.double()
# output : tensor([1., 2.],dtype = torch.float64)
# 转化为16位整数
t.short()
# output : tensor([1, 2],dtype = torch.int16)

2 张量的维度与形变

张量作为一组数的结构化表示,同样具有维度的概念。

简单理解,向量就是一维的数组,而矩阵就是二维的数组。

在张量中,我们还可以定义更高维度的数组。

当然,张量的高维数组和NumpyArray概念类似。


2.1 创建高维张量

用简单序列创建一维数组

t = torch.tensor([1, 2])
# 使用ndim属性查看张量的维度
t.ndim
# output : 1
# 使用shape查看形状
t.shape
# output : torch.Size([2])
# 和shape函数相同
t.shape()
# output : torch.Size([2])

注:和Numpy不同,PyTorchsize方法返回结果和shape属性返回结果一致

此外,还需要注意有两个常用的函数/方法,用来查看张量的形状

# 返回拥有几个(N-1)维张量
len(t1)
# output : 2,表示有两个0维张量
# 比如对二维张量采用len()方法,返回的就是多少个一维张量
# 返回总共拥有几个数
t.numel()
# output : 2

注:一维张量lennumel返回结果相同,但更高维度张量则不然


用“序列”的“序列”创建二维数组

以此类推,我们还可以用形状相同的序列组成一个新的序列,进而将其转化为二维张量。

# 用list的list创建二维数组
t = torch.tensor([[1, 2], [3, 4]])
t	
# output:
tensor([[1, 2],[3, 4]])
# 查看维度
t.ndim
# output : 2# 查看形状
t.shape
# output : torch.Size([2, 2])# 查看形状
t.size()
# output : torch.Size([2, 2])# 查看有几个(N-1)维张量
len(t)
# output : 2,表示由两个一维张量构成# 查看拥有几个数
t.numel()
# output : 4

“零”维张量

Pytorch中,还有一类特殊的张量被称为零维张量。该类张量只包含一个元素,但又不是单独一个数。

t=torch.tensor(1)
t	# output : tensor(1)
t.ndim	# output : 0
t.shape		# output : torch.Size([])
t.numel()	# output : 1

理解:我们可以将零维张量视为拥有张量属性的单独一个数。

例如,张量可以存在GPU上,但``Python`原生的数值型对象不行,而零维张量可以。

从学术名称来说,Python中单独一个数是scalars(标量),而零维的张量则是tensor


高维张量

三维及三维以上的张量称其为高维张量。

a1 = np.array([[1, 2, 2], [3, 4, 4]])
a1
# output : 
array([[1, 2, 2][3, 4, 4]])
a2 = np.array([[5, 6, 6], [7, 8, 8]])
a2
# output : 
array([[5, 6, 6][7, 8, 8]])
# 由两个形状相同的二维数组创建一个三维的张量
t3 = torch.tensor([a1, a2])
t3
# output :
tensor([[[1, 2, 2],[3, 4, 4]],[[5, 6, 6],[7, 8, 8]]], dtype=torch.int32)
t3.ndim
# output : 3
t3.shape
# output : torch.Size([2, 2, 3])	包含两个,两行三列的矩阵的张量
len(t3)
# output : 2
t3.numel()
# output : 12

2.2 张量的形变

张量作为数字的结构化集合,其结构也是可以根据实际需求灵活调整的


flatten拉平:将任意维度张量转化为一维张量

t2 = torch.tensor([[1, 2], [3, 4]])	#二维张量
t2.flatten()
# output : tensor([1, 2, 3, 4])
t3 = torch.tensor([a1, a2])		#三维张量
t3.flatten()
# output : tensor([1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8], dtype = int32)

注:如果将零维张量使用flatten,则会转化为一维张量

t = torch.tensor(1)		# 零维张量
t.flatten()
# output : tensor([1])

reshape方法:任意变形

t1 = torch.tensor([1, 2])
# 转化为两行、一列的向量
t1.reshape(2, 1)
# output :
tensor([[1],[2]])

注意reshape转化后的维度由该方法输入的参数个数决定


转化后生成一维张量

t1.reshape(2)
# output : tensor([1, 2])
# 另一种表达形式
t1.reshape(2, )
t1.reshape(2).ndim
# output : 1

转化后生成二维张量

t1.reshape(1, 2)
# output : tensor([[1, 2]])
t1.reshape(1, 2).ndim
# output : 2

转化后生成三维张量

t1.reshape(1, 1, 2)
# output : tensor([[[1, 2]]])
t1.reshape(1, 2, 1)
# output :
tensor([[[1],[2]]])
# 注意转化过程维度的变化
t1.reshape(1, 2, 1).ndim
# output : 3

3 特殊张量的创建方法

在很多数学科学计算过程中,会创建一些特殊取值的张量用于模拟特殊取值的矩阵。如全0矩阵、对角矩阵等。

因此,PyTorch中也存在很多创建特殊张量的函数。


3.1 特殊取值的张量创建方法

全0张量

torch.zeros([2, 3])		#创建全是0的两行、三列的张量(矩阵)
# output :
tensor([[0., 0., 0.],[0., 0., 0.]])

由于zeros就已经确定了张量元素取值,因此该函数传入的参数实际上决定了张量的形状


全1张量

torch.ones([2, 3])
# output :
tensor([[1., 1., 1.],[1., 1., 1.]])

单位矩阵

torch.eye(5)
# output :
tensor([[1., 0., 0., 0., 0.],[0., 1., 0., 0., 0.],[0., 0., 1., 0., 0.],[0., 0., 0., 1., 0.],[0., 0., 0., 0., 1.]])

对角矩阵

pytorch中,需要利用一维张量去创建对角矩阵

t1 = torch.tensor([1, 2])
torch.diag(t1)
# output :
tensor([[1, 0],[0, 2]])

千万不能直接使用list创建对角矩阵.


rand:服从0-1均匀分布的张量

torch.rand(2, 3)
# output :
tensor([[0.0214, 0.3989, 0.0814],[0.8888, 0.1773, 0.2567]])

randn:服从标准正态分布的张量

torch.randn(2, 3)
# output :
tensor([[-0.8638,  1.0079,  0.0267],[ 1.3223,  0.0856, -0.7271]])

normal:服从指定正态分布的张量

torch.normal(2, 3, size=(2, 2))		# 均值为2,标准差为3的张量
# output :
tensor([[ 1.5616, -0.9688],[ 3.4087, -0.0917]])

randint:整数随机采样结果

torch.randint(1, 10, [2, 4])	# 在1-10之间随机抽取整数,组成两行四列的张量
# output :
tensor([[4, 1, 9, 8],[4, 2, 5, 7]])

arange/linspace:生成数列

torch.arange(5)	# 和range相同
# output : tensor([0, 1, 2, 3, 4])
torch.arange(1, 5, 0.5)		# 从1到5(左闭右开),每隔0.5取值一个
# output :
tensor([1.0000, 1.5000, 2.0000, 2.5000, 3.0000, 3.5000, 4.0000, 4.5000])
torch.linspace(1, 5, 3)		# 从1到5(左右都包含),等距取三个数
# output :
tensor([1., 3., 5.])

empty:生成未初始化的指定形状矩阵

torch.empty(2, 3)	# 生成的值只是内存中的原始字节
# output :
tensor([[3.1056e-33, 1.8203e-42, 0.0000e+00],[0.0000e+00, 0.0000e+00, 0.0000e+00]])

full:根据指定形状,填充指定数值

torch.full([2, 4], 2)
# output :
tensor([[2, 2, 2, 2],[2, 2, 2, 2]])

3.2 创建指定形状的数组

我们还可以根据指定对象的形状进行数值填充,只需要在上述函数后面加上_like即可

t1 = torch.tensor([1, 2])
t2 = torch.tensor([[1, 2], [3, 4]])
torch.full_like(t1, 2)		# 根据t1形状,填充数值2
# output : tensor([2, 2])
torch.randint_like(t2, 1, 10)
# output :
tensor([[1, 1],[2, 9]])
torch.zeros_like(t1)
# output : tensor([0, 0])

需要注意的是,_like函数需要注意转化前后数据类型一致的问题。

t10 = torch.tensor([1.1, 2.2])	# 传入randn_like的参数必须为浮点型
torch.randn_like(t10)
# output :
tensor([1.0909, 0.0379])

4 张量和其它相关类型之间的转化方法

张量、数组和列表是较为相似的三种类型对象。在实际操作中,经常会涉及三种对象的相互转化。

在前面中torch.tensor函数可以直接将数组或者列表转化为张量,我们也可以将张量转化为数组或者列表


.numpy方法:张量转化为数组

t = torch.tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
t.numpy()
# output :
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype = int64)
# 也可以用np.array函数直接转化为array
np.array(t)

.tolist方法:张量转化为列表

t.tolist()
# output : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list函数:张量转化为列表

list(t)
# output :
[tensor(1),tensor(2),tensor(3),tensor(4),tensor(5),tensor(6),tensor(7),tensor(8),tensor(9),tensor(10)]

此时转化的列表是由一个个零维张量构成的列表,而非张量的数值组成的列表


.item()方法:转化为数值

在很多情况下,我们需要将最终计算的结果作为单独的数值进行输出

n = torch.tensor(1)
n.item()
# output : 1

5 张量的深拷贝

张量和python一样,等号赋值操作实际上是浅拷贝。

进行深拷贝时需要使用clone方法

t1 = torch.tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
t2 = t1
t1[1] = 10
t2	#浅拷贝会和t2的值一起修改
# output : tensor([ 1, 10, 3, 4, 5, 6, 7, 8, 9, 10])

此时t1t2指向相同的对象。要使t2不随t1对象改变而改变,则需要对t2进行深拷贝,独自拥有一份对象。

t3 = t1.clone()
t1[0] = 100
t3
# output : tensor([ 1, 10, 3, 4, 5, 6, 7, 8, 9, 10])

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/67471.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 Continue 插件时,发现调用外部地址

https://us.i.posthog.com/e/?ip1&_1737025525924&ver1.163.0&compressiongzip-js 看是一个帮助改善产品的网址。估计类似某推广流量监控的插件工具吧。网上没用查到其他说明,可能国内使用不多的原因。 但是发送的数据看不出来是个什么内容。 我用来搜…

【PyQt】图像处理系统

[toc]pyqt实现图像处理系统 图像处理系统 1.创建阴影去除ui文件 2.阴影去除代码 1.创建阴影去除ui文件 UI文件效果图: 1.1QT Desiger设置组件 1.两个Pushbutton按钮 2.两个label来显示图像 3.Text Browser来显示输出信息 1.2布局的设置 1.先不使用任何La…

【Idea】编译Spring源码 read timeout 问题

Idea现在是大家工作中用的比较多的开发工具,尤其是做java开发的,那么做java开发,了解spring框架源码是提高自己技能水平的一个方式,所以会从spring 官网下载源码,导入到 Idea 工具并编译,但是发现build的时…

Linux 音视频入门到实战专栏(视频篇)视频编解码 MPP

文章目录 一、MPP 介绍二、获取和编译RKMPP库三、视频解码四、视频编码 沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍如何调用alsa api来进行音频数据的播放和录制。 一、MPP 介绍 瑞芯微提供的媒体处理软件平台…

爬虫后的数据处理与使用(使用篇--实现分类预测)

()紧接上文,在完成基本的数据处理后,接下来就是正常的使用了。当然怎么用,确实需要好好思考一下~ 上文:爬虫后的数据处理与使用(处理篇) 前言: 一般来说,我…

RabbitMQ--延迟队列

(一)延迟队列 1.概念 延迟队列是一种特殊的队列,消息被发送后,消费者并不会立刻拿到消息,而是等待一段时间后,消费者才可以从这个队列中拿到消息进行消费 2.应用场景 延迟队列的应用场景很多,…

flutter开发-figma交互设计图可以转换为flutter源代码-如何将设计图转换为flutter源代码-优雅草央千澈

flutter开发-figma交互设计图可以转换为flutter源代码-如何将设计图转换为flutter源代码-优雅草央千澈 开发背景 可能大家听过过蓝湖可以转ui设计图为vue.js,react native代码,那么请问听说过将figma的设计图转换为flutter源代码吗?本文优雅草央千澈带…

当设置dialog中有el-table时,并设置el-table区域的滚动,看到el-table中多了一条横线

问题:当设置dialog中有el-table时,并设置el-table区域的滚动,看到el-table中多了一条横线; 原因:el-table有一个before的伪元素作为表格的下边框下,初始的时候已设置,在滚动的时候并没有重新设置…

代理模式实现

一、概念:代理模式属于结构型设计模式。客户端不能直接访问一个对象,可以通过代理的第三者来间接访问该对象,代理对象控制着对于原对象的访问,并允许在客户端访问对象的前后进行一些扩展和处理;这种设置模式称为代理模…

windows 搭建flutter环境,开发windows程序

环境安装配置: 下载flutter sdk https://docs.flutter.dev/get-started/install/windows 下载到本地后,随便找个地方解压,然后配置下系统环境变量 编译windows程序本地需要安装vs2019或更新的开发环境 主要就这2步安装后就可以了&#xff0…

Redis系列之底层数据结构字典Dict

Redis系列之底层数据结构字典Dict Dict数据结构 Dict是Redis数据结构中使用最为频繁的复合型数据结构,本质上是一个哈希表 查看redis6.0版本的源码,链接:https://github.com/redis/redis/blob/6.0/src/dict.h 哈希表的结构定义&#xff1…

【Azure 架构师学习笔记】- Azure Function (2) --实操1

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Function 】系列。 接上文【Azure 架构师学习笔记】- Azure Function (1) --环境搭建和背景介绍 前言 上一文介绍了环境搭建,接下来就在本地环境下使用一下。 环境准备 这里我下载了最新的VS studio&…

【NextJS】PostgreSQL 遇上 Prisma ORM

NextJS 数据库 之 遇上Prisma ORM 前言一、环境要求二、概念介绍1、Prisma Schema Language(PSL) 结构描述语言1.1 概念1.2 组成1.2.1 Data Source 数据源1.2.2 Generators 生成器1.2.3 Data Model Definition 数据模型定义字段(数据)类型和约束关系&…

左神算法基础提升--3

文章目录 Manacher 算法经典算法Manacher算法原理 单调栈或单调队列 Manacher 算法 经典算法 在每学习Manacher算法之前我们可能会使用一种比较经典暴力的算法:遍历str字符串,将字符串中的每个字符作为对称点,向两边扩散找到回文字段&#x…

浅谈操作系统与初识Linux

一、Linux操作系统的出现 1.1操作系统的出现以及相关的四个要素 1.2最早出现的操作系统及其创始人 起初,IBM为了让计算机可以以更低技术成本进行使用,以此来售卖计算机; 为计算机搭载上了Unix操作系统,Unix由肯汤普森用汇编语…

ElasticSearch下

DSL查询 叶子查询:在特定字段里查询特定值,属于简单查询,很少单独使用复合查询:以逻辑方式组合多个叶子查询或更改叶子查询的行为方式 在查询后还可以对查询结果做处理: 排序:按照1个或多个字段做排序分页…

java根据模板导出word,并在word中插入echarts相关统计图片以及表格

引入依赖创建word模板创建ftl模板文件保存的ftl可能会出现占位符分割的问题,需要处理将ftl文件中的图片的Base64删除,并使用占位符代替插入表格,并指定表格的位置在图片下方 Echarts转图片根据模板生成word文档DocUtil导出word文档 生成的wor…

链式前向星的写法

【图论02】动画说图的三种保存方式 降低理解门槛 邻接表 链式前向星 邻接矩阵_哔哩哔哩_bilibili 杭电ACM刘老师-算法入门培训-第12讲-拓扑排序及链式前向星_哔哩哔哩_bilibili 图论003链式前向星_哔哩哔哩_bilibili(链式前向星的遍历) head数组的下标…

想品客老师的第一天:值类型使用

前面两章的摘要 ECMAscript(也就是ES)是JavaScript的一个标准,就像c的c11和c99一样,几把的一年出一套标准 freeze()是一个对象方法,表示锁定、固定一个对象不可改变(因为const对于标量不可变,…

贪心算法(题1)区间选点

输出 2 #include <iostream> #include<algorithm>using namespace std;const int N 100010 ;int n; struct Range {int l,r;bool operator <(const Range &W)const{return r<W.r;} }range[N];int main() {scanf("%d",&n);for(int i0;i&l…