浅谈pytorch中stack和cat的及to_tensor的坑


Posted in Python onMay 20, 2021

初入计算机视觉遇到的一些坑

1.pytorch中转tensor

x=np.random.randint(10,100,(10,10,10))
x=TF.to_tensor(x)
print(x)

这个函数会对输入数据进行自动归一化,比如有时候我们需要将0-255的图片转为numpy类型的数据,则会自动转为0-1之间

2.stack和cat之间的差别

stack

x=torch.randn((1,2,3))
y=torch.randn((1,2,3))
z=torch.stack((x,y))#默认dim=0
print(z.shape)
#torch.Size([2, 1, 2, 3])

所以stack的之后的数据也就很好理解了,z[0,...]的数据是x,z[1,...]的数据是y。

cat

z=torch.cat((x,y))
print(z.size())
#torch.Size([2, 2, 3])

cat之后的数据 z[0,:,:]是x的值,z[1,:,:]是y的值。

其中最关键的是stack之后的数据的size会多出一个维度,而cat则不会,有一个很简单的例子来说明一下,比如要训练一个检测模型,label是一些标记点,eg:[x1,y1,x2,y2]

送入网络的加上batchsize则时Size:[batchsize,4],如果我已经有了两堆数据,data1:Size[128,4],data2:Size[128,4],需要将这两个数据合在一起的话目标data:Size[256,4]。

显然我们要做的是:torch.cat((data1,data2))

如果我们的数据是这样:有100个label,每一个label被放进一个list(data)中,[[x1,y1,x2,y2],[x1,y1,x2,y2],...]其中data是一个list长度为100,而list中每一个元素是张图片的标签,size为[4]我们需要将他们合一起成为一Size:[100,4]的的数据。

显然我们要做的是torch.stack(data)。而且torch.stack的输入参数为list类型!

补充:pytorch中的cat、stack、tranpose、permute、unsqeeze

pytorch中提供了对tensor常用的变换操作。

cat 连接

对数据沿着某一维度进行拼接。cat后数据的总维数不变。

比如下面代码对两个2维tensor(分别为2*3,1*3)进行拼接,拼接完后变为3*3还是2维的tensor。

代码如下:

import torch
torch.manual_seed(1)
x = torch.randn(2,3)
y = torch.randn(1,3)
print(x,y)

结果:

0.6614 0.2669 0.0617
0.6213 -0.4519 -0.1661
[torch.FloatTensor of size 2x3]

-1.5228 0.3817 -1.0276
[torch.FloatTensor of size 1x3]

将两个tensor拼在一起:

torch.cat((x,y),0)

结果:

0.6614 0.2669 0.0617
0.6213 -0.4519 -0.1661
-1.5228 0.3817 -1.0276
[torch.FloatTensor of size 3x3]

更灵活的拼法:

torch.manual_seed(1)
x = torch.randn(2,3)
print(x)
print(torch.cat((x,x),0))
print(torch.cat((x,x),1))

结果

// x
0.6614 0.2669 0.0617
0.6213 -0.4519 -0.1661
[torch.FloatTensor of size 2x3]

// torch.cat((x,x),0)
0.6614 0.2669 0.0617
0.6213 -0.4519 -0.1661
0.6614 0.2669 0.0617
0.6213 -0.4519 -0.1661
[torch.FloatTensor of size 4x3]

// torch.cat((x,x),1)
0.6614 0.2669 0.0617 0.6614 0.2669 0.0617
0.6213 -0.4519 -0.1661 0.6213 -0.4519 -0.1661
[torch.FloatTensor of size 2x6]

stack,增加新的维度进行堆叠

而stack则会增加新的维度。

如对两个1*2维的tensor在第0个维度上stack,则会变为2*1*2的tensor;在第1个维度上stack,则会变为1*2*2的tensor。

见代码:

a = torch.ones([1,2])
b = torch.ones([1,2])
c= torch.stack([a,b],0) // 第0个维度stack

输出:

(0 ,.,.) =
1 1

(1 ,.,.) =
1 1
[torch.FloatTensor of size 2x1x2]

c= torch.stack([a,b],1) // 第1个维度stack

输出:


(0 ,.,.) =

1 1

1 1

[torch.FloatTensor of size 1x2x2]

transpose ,两个维度互换

代码如下:

torch.manual_seed(1)
x = torch.randn(2,3)
print(x)

原来x的结果:

0.6614 0.2669 0.0617

0.6213 -0.4519 -0.1661

[torch.FloatTensor of size 2x3]

将x的维度互换

x.transpose(0,1)

结果

0.6614 0.6213

0.2669 -0.4519

0.0617 -0.1661

[torch.FloatTensor of size 3x2]

permute,多个维度互换,更灵活的transpose

permute是更灵活的transpose,可以灵活的对原数据的维度进行调换,而数据本身不变。

代码如下:

x = torch.randn(2,3,4)
print(x.size())
x_p = x.permute(1,0,2) # 将原来第1维变为0维,同理,0→1,2→2
print(x_p.size())

结果:

torch.Size([2, 3, 4])

torch.Size([3, 2, 4])

squeeze 和 unsqueeze

常用来增加或减少维度,如没有batch维度时,增加batch维度为1。

squeeze(dim_n)压缩,减少dim_n维度 ,即去掉元素数量为1的dim_n维度。

unsqueeze(dim_n),增加dim_n维度,元素数量为1。

上代码:

# 定义张量
import torch

b = torch.Tensor(2,1)
b.shape
Out[28]: torch.Size([2, 1])

# 不加参数,去掉所有为元素个数为1的维度
b_ = b.squeeze()
b_.shape
Out[30]: torch.Size([2])

# 加上参数,去掉第一维的元素为1,不起作用,因为第一维有2个元素
b_ = b.squeeze(0)
b_.shape 
Out[32]: torch.Size([2, 1])

# 这样就可以了
b_ = b.squeeze(1)
b_.shape
Out[34]: torch.Size([2])

# 增加一个维度
b_ = b.unsqueeze(2)
b_.shape
Out[36]: torch.Size([2, 1, 1])

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
用python写asp详细讲解
Dec 16 Python
python实现从一组颜色中找出与给定颜色最接近颜色的方法
Mar 19 Python
自动化Nginx服务器的反向代理的配置方法
Jun 28 Python
Python内置数据结构与操作符的练习题集锦
Jul 01 Python
详解python之配置日志的几种方式
May 22 Python
Python将list中的string批量转化成int/float的方法
Jun 26 Python
python实现梯度下降算法
Mar 24 Python
Python变量类型知识点总结
Feb 18 Python
浅谈keras保存模型中的save()和save_weights()区别
May 21 Python
用python制作个音乐下载器
Jan 30 Python
简单且有用的Python数据分析和机器学习代码
Jul 02 Python
Python+Pillow+Pytesseract实现验证码识别
May 11 Python
pytorch实现手写数字图片识别
解决python3安装pandas出错的问题
May 20 #Python
python 如何在list中找Topk的数值和索引
May 20 #Python
Requests什么的通通爬不了的Python超强反爬虫方案!
python使用glob检索文件的操作
python opencv通过按键采集图片源码
python 如何执行控制台命令与操作剪切板
You might like
PHP安全技术之 实现php基本安全
2010/09/04 PHP
PHP如何解决网站大流量与高并发的问题
2011/06/25 PHP
PHP快速生成各种信息提示框的方法
2016/02/03 PHP
PHP性能分析工具xhprof的安装使用与注意事项
2017/12/19 PHP
splice slice区别
2006/10/09 Javascript
使用jQuery.fn自定义jQuery翻页插件
2013/01/20 Javascript
用js提交表单解决一个页面有多个提交按钮的问题
2014/09/01 Javascript
扒一扒JavaScript 预解释
2015/01/28 Javascript
JS中获取函数调用链所有参数的方法
2015/05/07 Javascript
JS实现浏览器状态栏显示时间的方法
2015/10/27 Javascript
Angularjs实现mvvm式的选项卡示例代码
2016/09/08 Javascript
vue项目中用cdn优化的方法
2018/01/03 Javascript
让Vue响应Map或Set的变化操作
2020/11/11 Javascript
[01:22:10]Ti4 循环赛第二日 DK vs Empire
2014/07/11 DOTA
[44:40]2018DOTA2亚洲邀请赛3月30日 小组赛A组Liquid VS OG
2018/03/31 DOTA
Python3基础之函数用法
2014/08/13 Python
基于python的七种经典排序算法(推荐)
2016/12/08 Python
小白如何入门Python? 制作一个网站为例
2018/03/06 Python
Python实现多级目录压缩与解压文件的方法
2018/09/01 Python
Python创建一个空的dataframe,并循环赋值的方法
2018/11/08 Python
django admin组件使用方法详解
2019/07/19 Python
python爬虫 execjs安装配置及使用
2019/07/30 Python
Windows系统Python直接调用C++ DLL的方法
2019/08/01 Python
Python 异常处理Ⅳ过程图解
2019/10/18 Python
PyTorch 随机数生成占用 CPU 过高的解决方法
2020/01/13 Python
python3实现网页版raspberry pi(树莓派)小车控制
2020/02/12 Python
PyTorch中Tensor的数据统计示例
2020/02/17 Python
谈谈Python:为什么类中的私有属性可以在外部赋值并访问
2020/03/05 Python
Anaconda的安装与虚拟环境建立
2020/11/18 Python
什么造成了Java里面的异常
2016/04/24 面试题
介绍一下.net和Java的特点和区别
2012/09/26 面试题
servlet面试题
2012/08/20 面试题
师范大学生求职信
2014/06/13 职场文书
房屋租赁协议书(标准版)
2014/10/02 职场文书
幼儿园安全教育月活动总结
2015/05/08 职场文书
pytorch显存一直变大的解决方案
2021/04/08 Python