PyTorch【2】-Tensor

Tensor 即张量,在 tf 中也有这个概念,tensor 是 pytorch 和 tf 非常重要的数据结构,可以理解为多维数组,它可以是一个数、一个向量、一个矩阵、多维数组;

Tensor 可以用 GPU 加速;

在 pytorch 中其用法类似于 numpy;

创建 Tensor

创建 Tensor,并查看尺寸

  • torch.Tensor(size):
  • torch.empty(size):
  • torch.zeros(size)、torch.zeros_like(input):返回跟 input 同 size 的全 0 tensor
  • torch.ones(size)、torch.ones_like(input)
  • torch.arange(start=0, end, step=1):
  • torch.full(size, value):见示例

查看尺寸用 size 或者 shape

示例

import torch as t

x = t.Tensor(2, 3)      ### 构建 2x3 矩阵
print(t.ones_like(x))
print(t.full((2, 3), 5))
# tensor([[5., 5., 5.],
#         [5., 5., 5.]])
print(t.arange(5))      # tensor([0, 1, 2, 3, 4])

print(x.size())         # torch.Size([2, 3])    ### 查看尺寸
print(x.size()[0])      # 2 查看行数
print(x.size(0))        # 2 查看行数
print(t.Size([2, 3]))
print(x.shape)          # torch.Size([2, 3])

随机初始化

  • torch.rand(size):生成 (0,1) 内均匀分布的随机数
  • torch.randn(size):生成标准正态分布 (0,1) 的随机数
  • torch.normal(mean, std, out=None):生成正态分布的随机数,注意 mean 和 std 都是 tensor 格式,mean 默认 0,std 默认 1

更多的随机抽样方法,参见链接:https://pytorch.org/docs/stable/torch.html#random-sampling

基本操作

有很多操作,这里只介绍简单的,具体查看官网

切片

m = t.Tensor(3, 5)
print(m[:, 1])      # tensor([1.4226e-13, 5.6015e-02, 7.7782e+31])  ### 3 row

合并分割

t.cat(seq, dim, out=None):合并,dim 指定维度

dim 为 0 代表按第 0 维度拼接,确切的说是在第 0 维度上拼接,即在行上拼接,1相反

a = t.ones(1, 2)
b = t.zeros(1, 2)
c = t.cat((a, b), 0)
print(c)
# tensor([[1., 1.],
#         [0., 0.]])

t.chunk(tensor, chunks, dim):分割,chunks 代表分割的块数,dim 代表分割的维度

dim 为 0 代表在第 0 个维度上进行分割,也就是横着切,1 相反

e = t.ones(3, 2)
print(t.chunk(e, 2, 1))
# (tensor([[1.],
#         [1.],
#         [1.]]), tensor([[1.],
#         [1.],
#         [1.]]))
print(t.chunk(e, 2, 0))
# (tensor([[1., 1.],
#         [1., 1.]]), tensor([[1., 1.]]))

分割还有一种方法 t.split(tensor, split_size_or_sections, dim),具体自行尝试

尺寸变换

t.reshape(input, shape) 和 tensor.view(shape) 都可以实现尺寸变换,前者是 tensor 类的一个方法,后者是 tensor 对象的方法,当然 前者也可以用走 tensor 对象的方法;

也就是说 reshape 大于 view;

注意,二者都不会改变原 tensor 的尺寸,除非把结果赋给一个新的对象;

import torch as t

f = t.arange(10)

### 单纯调用 view
print(f.view(2, 5))     ### view 设置了新的尺寸
# tensor([[0, 1, 2, 3, 4],
#         [5, 6, 7, 8, 9]])
print(f)    # tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])    ### 但是并没有改变 原来的 tensor
# print(t.view(f, (2, 5)))    ### view 不能这么用,它不是 torch 的方法

g = f.view(2, 5)    ### 这样会生成新的 tensor

### reshape,也不会改变本身
print(f.reshape(2, 5))
# tensor([[0, 1, 2, 3, 4],
#         [5, 6, 7, 8, 9]])
print(f)    # tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print(t.reshape(f, (2, 5)))     ### reshape 可以作为 torch 的方法
# tensor([[0, 1, 2, 3, 4],
#         [5, 6, 7, 8, 9]])

数学运算

加法:有 3 种方式,+,add,add_

import torch as t
y = t.rand(2, 3)        ### 使用[0,1]均匀分布构建矩阵
z = t.ones(2, 3)        ### 2x3 的全 1 矩阵
print(y + z)            ### 加法1
t.add(y, z)             ### 加法2
### 加法的第三种写法
result = t.Tensor(2, 3) ### 预先分配空间
t.add(y, z, out=result) ### 指定加法结果的输出目标
print(result)

add_ 与 add 的区别在于,add 不会改变原来的 tensor,而 add_会改变原来的 tensor;

在 pytorch 中,方法后面加  _ 都会改变原来的对象,相当于 inplace 的作用

print(y)
# tensor([[0.4083, 0.3017, 0.9511],
#         [0.4642, 0.5981, 0.1866]])
y.add(z)
print(y)                ### y 不变
# tensor([[0.4083, 0.3017, 0.9511],
#         [0.4642, 0.5981, 0.1866]])
y.add_(z)
print(y)                ### y 变了,相当于 inplace
# tensor([[1.4083, 1.3017, 1.9511],
#         [1.4642, 1.5981, 1.1866]])

其他运算

t.mul(input, other, out=None):乘法

t.div(input, other, out=None):除法

t.pow(input, other, out=None):指数

t.sqrt(input, out=None):开方

t.round(input, out=None):四舍五入到整数

t.abs(input, out=None):绝对值

t.ceil(input, out=None):向上取整

t.clamp(input, min, max, out=None):把 input 规范在 min 到 max 之间,超出用 min 和 max 代替,可理解为削尖函数

t.argmax(input, dim=None, keepdim=False):返回指定维度最大值的索引

t.sigmoid(input, out=None)

t.tanh(input, out=None)

Tensor-Numpy 互转

操作如下

n = t.ones(2, 3)
print(n.numpy())    ### Tensor 转 Numpy
# [[1. 1. 1.]
#  [1. 1. 1.]]

import numpy as np
p = np.ones((2, 3))
q = t.from_numpy(p)      ### Numpy 转 Tensor
print(p)
# tensor([[1., 1., 1.],
#         [1., 1., 1.]], dtype=torch.float64)

Tensor 与 Numpy 共享内存,使得他们之间的转换很快,而且几乎不会消耗资源;

共享内存意味着,一个变了,另一个也跟着变;

q.add_(n)       ### q 被改变
print(q)        ###
# tensor([[2., 2., 2.],
#         [2., 2., 2.]], dtype=torch.float64)
print(p)        ### p 竟然也被改变了
# [[2. 2. 2.]
#  [2. 2. 2.]]

GPU 加速

注意,GPU 的优势体现在大规模数据集和复杂运算上,把数据从内存转移到显存产生额外开销,导致小数据反而不占优势

print(t.cuda.is_available())    # False
if t.cuda.is_available():
    x = x.cuda()        ### Tensor 通过 cuda 方法转换为 GPU 的 Tensor
    y = y.cuda()
    x + y

参考资料:

《深度学习框架PyTorch:入门与实践_陈云(著)》

https://www.jianshu.com/p/7dbfc7076e5a

原文地址:https://www.cnblogs.com/yanshw/p/12188478.html

时间: 2024-08-30 17:31:34

PyTorch【2】-Tensor的相关文章

PyTorch【1】-入门与安装

tensorflow vs pytorch 现在关于深度学习的框架很多,详情请百度,或者参考本文参考资料1,本文对比两种: tensorflow 是当前最流行的深度学习框架,但是 pytorch 有后来居上的意思,其实二者有一定联系: 联系:都是基于计算图的,计算图包括计算节点和边,计算节点代表运算,边代表数据传输: 区别: 1. 计算图又分为静态图和动态图两种,类似于静态语言和动态语言,区别在于:静态图需要先声明再运行,一次声明多次运行:动态图在运行过程中被定义,可以多次构建多次运行: ten

PyTorch【6】-线性回归_SGD_动量梯度下降

本篇是一个练手项目,目的在于: 1. 熟悉 pytorch 2. 实现 SGD 与 动量梯度下降,并对比收敛性 手动实现线性回归模型,一个很简单的模型,不多介绍,直接上代码 import torch as t import matplotlib.pylab as plt ### 制造数据 def make_data(): # y = 2x+3 x = t.rand(1, 10) * 20 y = x * 2 + 3 + t.randn(1, 10) return x, y ### 初始化参数 t

【分享】近4000份数学学习资源免费分享给大家

一直以来喜欢收集数学类的教程资源,于是费了好大劲从万千合集站上扒拉了下来,总结归类了一下,一共有将近4000本电子书.经测试,均可免费下载,可能会弹出小广告,可不必理会之.[仅供学术学习和交流,请无用于商业用途.]另外,如有可能,还请尽量支持正版纸质书.   数学史(54)     数学史.rar 55.6 MB   数学的起源与发展.rar 4.3 MB   费马大定理—一个困惑了世间智者358年的谜.pdf 9.5 MB   通俗数学名著译丛14-无穷之旅:关于无穷大的文化史.pdf 14.

给企业研发人员列一张数学清单【转载】

[转载] 原帖:http://blog.sciencenet.cn/home.php?mod=space&uid=485553&do=blog&id=746079 工作以来,逐渐发现企业有个较为普遍的现象,那就是企业的研发人员——从普通技术员到总工,往往难以看懂深入的专业书籍,其主要原因是数学基础差.虽然工科学生大学阶段都学过<高等数学>,<线性代数>,<概率与数理统计>,但工科数学过于肤浅,加上学习过程浮光掠影,造成工科毕业生日后深入的专业学习

【Gamma】项目展示(未完成)

团队成员介绍 大娃 :后端开发人员,主要工作为后端开发,文档撰写. 大娃的个人博客 二娃 PM,主要工作为项目进度把控,例会博客撰写. 二娃的个人博客 三娃* PM,主要工作为项目进度把控,用户需求分析,组织平日例会,各类博客的撰写和项目推广. 三娃的个人博客 四娃 前端开发人员,主要工作为网页各项功能的实现,文档撰写. 四娃的个人博客 五娃 前端开发人员,主要工作为页面开发,文档撰写. 五娃的个人博客 WF 测试,主要工作为测试前后端代码,发现bug交付给开发组. WF的个人博客 七弟 前端开

【Kettle】4、SQL SERVER到SQL SERVER数据转换抽取实例

1.系统版本信息 System:Windows旗舰版 Service Pack1 Kettle版本:6.1.0.1-196 JDK版本:1.8.0_72 2.连接数据库 本次实例连接数据库时使用全局变量. 2.1 创建新转换:spoon启动后,点击Ctrl+N创建新转换 2.2 在新转换界面中,右键点击DB连接,系统会弹出[数据库连接]界面. windows系统环境下,可用${}获取变量的内容. 说明: 连接名称:配置数据源使用名称.(必填) 主机名称:数据库主机IP地址,此处演示使用本地IP(

详解go语言的array和slice 【二】

上一篇  详解go语言的array和slice [一]已经讲解过,array和slice的一些基本用法,使用array和slice时需要注意的地方,特别是slice需要注意的地方比较多.上一篇的最后讲解到创建新的slice时使用第三个索引来限制slice的容量,在操作新slice时,如果新slice的容量大于长度时,添加新元素依然后使源的相应元素改变.这一篇里我会讲解到如何避免这些问题,以及迭代.和做为方法参数方面的知识点. slice的长度和容量设置为同一个值 如果在创建新的slice时我们把

【转载】C++拷贝构造函数(深拷贝,浅拷贝)

对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. #include <iostream>using namespace std;class CExample {private:     int a;public:     CExample(int b)     { a=b;}     void Show ()     {        cout<

【BZOJ】1799: [Ahoi2009]self 同类分布

[题意]给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数.1 ≤ a ≤ b ≤ 10^18 [算法]数位DP [题解] 感觉这种方法很暴力啊. 枚举数位和1~162(不能枚举0,不然会模0,相当于除0),记忆化f[pos][sum][val],sum表示当前数位和,val表示数字取模枚举的数位和. 每次sum+i和(val*10+i)%MOD转移. sum用减法优化,即记忆化(MOD-sum),但是枚举过程中都要memset,导致效率低下,记忆化效果很差. 要什么方法才能跑1.3s