深度学习与Pytorch入门实战(一)Pytorch张量操作
1. 数据类型
如何表示string?
One-hot
- [0, 1, 0, 0, ...]
Embedding
Word2vec
glove
类型推断
import torch# type check
a = torch.randn(2, 3)
print(a.type()) #torch.FloatTensor
print(type(a)) #<class 'torch.Tensor'> 这种情况比较少
print(isinstance(a, torch.FloatTensor)) #True
标量
- 标量 dimension 0/rank 0(常用于loss)
# 标量 dimension 0/rank 0(常用于loss)
b = torch.tensor(1.3)
print(b) # tensor(1.3000)
print(b.shape) # torch.Size([]) 成员
print(len(b.shape)) # 0
print(b.size()) # torch.Size([]) 成员函数
张量(tensor)
- 张量 dimension 1(常用于bias)
# 张量 dimension 1(常用于bias)
print(torch.tensor([1.1])) # tensor([1.1000]) 指定具体数据,可以是 N 维print(torch.FloatTensor(1)) # tensor([9.6429e-39]) 指定第一维度的长度,随机初始化data = np.ones(2) # 长度为2的numpy array
print(data) # array([1., 1.])
print(torch.from_numpy(data)) # tensor([1., 1.], dtype=torch.float64) 从numpy引入c = torch.ones(2)
print(c.shape) # torch.Size([2]), 第一维的长度为2
- 张量 dimension 2(常用于batch等)
# 张量 dimension 2
d = torch.randn(2, 3)
print(d)
#tensor([[-1.8543, -0.7280, 0.6671],
# [ 1.1492, -0.6379, -0.4835]])
print(d.shape) # torch.Size([2, 3]),第一维长度为2,第二维长度为3(两行3列)
print(d.shape[0]) # 2
print(d.size(1)) # 或者d.shape[1],3
- 张量 dimension 3(常用于RNN等)
# 张量 dimension 3
f = torch.rand(1,2,3) # 理解:1个数据集,2个Tx,每个Tx有3个输出
print(f)
#tensor([[[0.3690, 0.5702, 0.2382],
# [0.3130, 0.5591, 0.3829]]])print(f.shape) # torch.Size([1, 2, 3])
print(f[0]) # 取第一个维度
#tensor([[0.4535, 0.4307, 0.6469],
# [0.1591, 0.0778, 0.4489]])
print(f[0][1]) # tensor([0.1591, 0.0778, 0.4489])
- 张量 dimension 4(常用于表示图片类型)
eg:a = torch.rand(b,c,h,w) 表示b张 c通道、h*w的图片
a = torch.rand(2,3,28,28) # 2张图片,每张图片3通道,大小为28x28
print(a)print(a.shape)
print(a.numel()) # 2x3x28x28=4704, 全部元素个数
print(a.dim()) # 4, 维度数量
tensor([[[[0.2607, 0.6929, 0.4447, ..., 0.7346, 0.1117, 0.6536],...,[0.4591, 0.7439, 0.0944, ..., 0.0986, 0.9818, 0.9580]],[[0.2049, 0.2220, 0.6390, ..., 0.7402, 0.0301, 0.1057],...,[0.4375, 0.9904, 0.0813, ..., 0.5896, 0.6167, 0.2628]],[[0.4288, 0.6137, 0.6558, ..., 0.0282, 0.5398, 0.0905],...,[0.0021, 0.2103, 0.1029, ..., 0.4861, 0.5915, 0.4245]]],[[[0.4978, 0.4922, 0.8510, ..., 0.7856, 0.6859, 0.7466],...,[0.7721, 0.9057, 0.9594, ..., 0.8764, 0.0646, 0.3901]],[[0.0570, 0.9745, 0.9952, ..., 0.8184, 0.5966, 0.6161],...,[0.1213, 0.6930, 0.9880, ..., 0.6633, 0.0317, 0.9526]],[[0.6238, 0.6210, 0.7574, ..., 0.1725, 0.6625, 0.9828],...,[0.6864, 0.2697, 0.2041, ..., 0.9683, 0.6482, 0.1793]]]])
torch.Size([2, 3, 28, 28])
4704
4
2. 创建Tensor
import torch
import numpy as np# 方法一:import from numpy
a = np.ones([2,3])
print(torch.from_numpy(a))#tensor([[1., 1., 1.],
# [1., 1., 1.]], dtype=torch.float64)# 方法二:import from List
print(torch.tensor([[2.,3.2],[1.,22.3]]))# tensor([[ 2.0000, 3.2000],
# [ 1.0000, 22.3000]])# 方法三:接受shape或者现成数据
print(torch.Tensor(2, 3))
print(torch.FloatTensor(2, 4))# tensor([[0., 0., 0.],
# [0., 0., 0.]])
# tensor([[0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00],
# [0.0000e+00, 1.8750e+00, 4.3485e-05, 1.6595e-07]], dtype=torch.float32)
Tips:
torch.tensor:接受现成的数据
torch.Tensor/torch.FloatTensor:接受shape或者现成的数据
未初始化的方法(作为容器,要用其他类型把数据覆盖掉!):
torch.empty()
torch.FloatTensor(d1, d2, d3)
torch.IntTensor(d1,d2,d3)
print(torch.empty(1, 2))
print(torch.FloatTensor(1, 2))
print(torch.IntTensor(2, 3))# tensor([[ 0.0000e+00, 2.1220e-314]])
# tensor([[0., 0.]], dtype=torch.float32)
# tensor([[1664692530, 1630878054, 1681351009],
# [ 842019426, 1664312883, 828728417]], dtype=torch.int32)
设置默认类型
- torch.set_default_tensor_type
# 设置默认类型
print(torch.tensor([1.2,3]).type()) # torch.FloatTensor(不设定的话,默认值)torch.set_default_tensor_type(torch.DoubleTensor)
print(torch.tensor([1.2,3]).type()) # torch.DoubleTensor
随机初始化
- rand/rand_like, randint
# rand [0,1]
a = torch.rand(2,2)
print(a)# tensor([[0.9422, 0.6025],
# [0.1540, 0.6282]])print(torch.rand_like(a)) # 根据a的形状生成,也可用dtype指定新类型# tensor([[0.4822, 0.6752],
# [0.3491, 0.8990]])# randint [min,max) 不包含max
print(torch.randint(1,10, [3,3])) # 第1个参数是min,第二个参数是max,第三个参数是shape# tensor([[8, 9, 7],
# [5, 7, 5],
# [9, 6, 9]])
正态分布
print(torch.full([2, 3], 2.3)) # 2维3列,全部为2.3的tensor# tensor([[2.3000, 2.3000, 2.3000],
# [2.3000, 2.3000, 2.3000]])
# 正态分布
print(torch.randn(3,3)) # N(0,1), 均值为0,方差为1
# tensor([[-1.6209, 0.0208, -0.8792],
# [ 2.4513, -0.1906, 3.4904],
# [ 0.5434, 0.8524, 0.6850]])print(torch.normal(mean=torch.full([10], 0),std = torch.arange(1,0,-0.1))) # normal得到的维度为1,均值为0,方差为1
# tensor([ 0.1445, -0.5133, -0.5565, 0.0831, 0.1350, 0.1023, -0.6264, -0.1651, 0.2856, 0.0187])
其他
torch.full
torch.arange
torch.linspace
torch.logspace(0, 1, step=10): \(10^0 \to 10^{1}\)
torch.randperm
# ones全1,zeros全0,eye对角,ones_like
print(torch.full([2,3],7)) # 第一个参数是shape,第二个参数是value
# tensor([[7., 7., 7.],
# [7., 7., 7.]])
print(torch.full([], 7)) # tensor(7.) 生成标量# 生成 [0, n-1]的等差数列
print(torch.arange(0,10,2)) # tensor([0, 2, 4, 6, 8])# [0,10]等间距切割成steps份
print(torch.linspace(0, 10, steps=6)) # tensor([ 0., 2., 4., 6., 8., 10.])
print(torch.logspace(0, 1, steps=5)) # tensor([ 1.0000, 1.7783, 3.1623, 5.6234, 10.0000])# randperm: [0, n-1]打乱出现,不重复
print(torch.randperm(10)) # tensor([8, 5, 2, 4, 7, 1, 3, 9, 6, 0])a = torch.rand(2, 3)
idx = torch.randperm(2)
print(idx) # tensor([1, 0])
print(a)
print(a[idx])# tensor([[0.7896, 0.0143, 0.7092],
# [0.8881, 0.5194, 0.6708]])
# tensor([[0.8881, 0.5194, 0.6708],
# [0.7896, 0.0143, 0.7092]])
3. 索引与切片
# 切片与索引
a = torch.rand(4, 3, 28, 28) # 4张图片,每张图片有3个channel,每个通道图片大小:28x28
print(a[0].shape) # torch.Size([3, 28, 28])
print(a[0,0].shape) # torch.Size([28, 28])
print(a[0,0,2,4]) # tensor(0.5385)print(a[:2,:1].shape) # torch.Size([2, 1, 28, 28]) 等价于a[:2,:1,:,:].shape
print(a[:,:,::2,::2].shape) # torch.Size([4, 3, 14, 14])
使用特定索引 index_select
#select by specific index
print(a.index_select(2, torch.arange(8)).shape) # torch.Size([4, 3, 8, 28]) 第1个参数:选择的维度,第2个参数:索引号(Tensor类型)# ...表示任意多的维度
print(a[0, ...].shape) # torch.Size([3, 28, 28])
print(a[:, 1, ...].shape) # torch.Size([4, 28, 28])
使用掩码索引 masked_select
- torch.masked_select(x, mask)后变成一维
x = torch.randn(3,4)
print(x)mask = x.ge(0.5) # greater equal: >=
print(mask)# select by mask
torch.masked_select(x, mask) # 维度为1# tensor([[ 0.2953, -2.4538, -0.0996, 1.6746],
# [ 0.5318, -1.2000, -0.8475, 0.3967],
# [-1.2162, -1.4913, 0.5404, -0.1377]])# tensor([[False, False, False, True],
# [ True, False, False, False],
# [False, False, True, False]])# tensor([1.6746, 0.5318, 0.5404])
take索引
- take: 在原来Tensor的shape基础上打平,然后在打平后的Tensor上进行索引)
# select by flatten index
src = torch.tensor([[4, 3, 5], [6, 7, 8]])print(torch.take(src, torch.tensor([0, 2, 5]))) # tensor([4, 5, 8])
4. 维度变换
reshape/view
可以调整Tensor的shape,返回一个新shape的Tensor
要记住维度展开的顺序,如果要还原维度,就得按原来顺序还原
a = torch.rand(4, 1, 28, 28)print(a.view(4, 28*28).shape) # torch.Size([4, 784]), 语法没错,数据被破坏了
print(a.reshape(4*28, 28).shape) # torch.Size([112, 28])
unsqueeze(index)增加维度
index的范围: [-a.dim()-1, a.dim()+1)
- 如:a.unsqueeze(2): 在二维处添加一维。若 a 的维度=4,index范围是[-5,5)
新增加的这一个维度,不会改变数据本身,只是为数据新增加了一个组别,这个组别是什么由我们自己定义。
a = torch.rand(4,1,28,28)
print(a.shape) # torch.Size([4, 1, 28, 28])
print(a.unsqueeze(0).shape) # torch.Size([1, 4, 1, 28, 28]print('='*30)
b = torch.tensor([1.2, 2.3]) # torch.Size([2])
print(b)
print(b.unsqueeze(0)) # tensor([[1.2000, 2.3000]]) torch.Size([1, 2])
print(b.unsqueeze(-1)) # torch.Size([2, 1])
print(b.unsqueeze(1)) # torch.Size([2, 1])
# tensor([[1.2000],
# [2.3000]])print('='*30)
x = torch.rand(32)
print(x.shape) # torch.Size([32])
print(x.unsqueeze(1).shape) # torch.Size([32, 1])
print(x.unsqueeze(1).unsqueeze(2).shape) # torch.Size([32, 1, 1])
x = x.unsqueeze(1).unsqueeze(2).unsqueeze(0) # torch.Size([1, 32, 1, 1])
print(x.shape) # torch.Size([1, 32, 1, 1])) 再进行扩展即可计算x+y
squeeze(index)删减维度
删除 size=1 的维度
size不等于1,删减不了
a=torch.rand(1,32,1,1)print(a.squeeze().shape) # torch.Size([32]) 不指定维度就挤压全部
print(a.squeeze(0).shape) # torch.Size([32, 1, 1])
print(a.squeeze(-1).shape) # torch.Size([1, 32, 1])
print(a.squeeze(1).shape) # torch.Size([1, 32, 1, 1]) size不等于1,删减不了
expand维度扩展:broadcasting(只是改变了理解方式,并没有增加数据)
某个 size=1 的维度上扩展到size, 缺失处填补该维度的数
-1 指该维度不变
x = torch.rand(3)
x = x.unsqueeze(1).unsqueeze(2).unsqueeze(0) # [3]->[3,1]->[3,1,1]->[1,3,1,1]
print(x.shape) # torch.Size([1, 3, 1, 1])
print(x)# tensor([[[[0.5826]],# [[0.6370]],# [[0.6199]]]])print(x.expand(-1, 3, 3, 2))# tensor([[[[0.3054, 0.3054],
# [0.3054, 0.3054],
# [0.3054, 0.3054]],# [[0.4798, 0.4798],
# [0.4798, 0.4798],
# [0.4798, 0.4798]],# [[0.7628, 0.7628],
# [0.7628, 0.7628],
# [0.7628, 0.7628]]]])y = torch.rand(4, 3, 14, 14)print(x.expand(4,3,14,14).shape) # torch.Size([4, 3, 14, 14])
print(x.expand(-1,3,3,-1).shape) # torch.Size([1, 3, 3, 1]) -1:指该维度不变print((x.expand(4, 3, 14, 14) + y).shape) # torch.Size([4, 3, 14, 14])
repeat维度重复:memory copied(增加了数据)
- repeat会重新申请内存空间,repeat()参数表示各个维度指定的重复次数。
a = torch.rand(1,32,1,1)print(a.repeat(4,32,1,1).shape) # torch.Size([1x4, 32x32, 1x1, 1x1])->torch.Size([4, 1024, 1, 1])
print(a.repeat(4,1,1,1).shape) # torch.Size([4, 32, 1, 1])y = torch.rand(5)
print(y.shape) # torch.Size([5])
y_unsqueeze = y.unsqueeze(1)
print(y_unsqueeze.shape) # torch.Size([5, 1])
print(y_unsqueeze)# tensor([[0.3372],
# [0.1044],
# [0.8305],
# [0.1960],
# [0.7674]])print(y_unsqueeze.repeat(2, 2))# tensor([[0.3372, 0.3372],
# [0.1044, 0.1044],
# [0.8305, 0.8305],
# [0.1960, 0.1960],
# [0.7674, 0.7674],
# [0.3372, 0.3372],
# [0.1044, 0.1044],
# [0.8305, 0.8305],
# [0.1960, 0.1960],
# [0.7674, 0.7674]])
转置操作
.t
操作指适用于矩阵
a = torch.rand(3, 4)
print(a.t().shape) #torch.Size([4, 3])
transpose维度交换
a = torch.rand(4,3,32,32)
print(a.transpose(1, 3).shape) # torch.Size([4, 32, 32, 3])
print(a.transpose(1, 3).contiguous().view(4, 3*32*32).shape) # torch.Size([4, 3072]), 如果不加contiguous就需要把view改成reshape,contiguous是把数据重新变成连续
print(a.transpose(1, 3).contiguous().view(4, 3*32*32).reshape(4, 32, 32, 3).shape) # torch.Size([4, 32, 32, 3])a1 = a.transpose(1, 3).contiguous().view(4, 3*32*32).view(4, 3, 32, 32)
b = a.transpose(1, 3).contiguous().view(4, 3*32*32).view(4,32,32,3).transpose(1, 3) # view(4,3*32*32).view(4,3,32,32)这样写就错了
# [b,c,h,w]->[b,w,h,c]->[b,whc]->[b,w,h,c]->[b,c,h,w] 展开时按原来的顺序展开whc对应32,32,3print(a.shape, b.shape)print(torch.all(torch.eq(a, b))) # tensor(True)
print(torch.all(torch.eq(a, a1))) # tensor(False)
t = torch.IntTensor([[[1,2,3],[4,5,6]], [[6,7,8],[9,10,11]]])
print(t, t.shape)
print(t.transpose(0, 2).contiguous().view(3, 4).view(2, 2, 3)) # 并没有恢复成原来的数据# tensor([[[ 1, 6, 4],
# [ 9, 2, 7]],# [[ 5, 10, 3],
# [ 8, 6, 11]]], dtype=torch.int32)# 正确写法
print(t.transpose(0, 2).contiguous().view(3, 4).view(3, 2, 2).transpose(0, 2))# tensor([[[ 1, 2, 3],
# [ 4, 5, 6]],# [[ 6, 7, 8],
# [ 9, 10, 11]]], dtype=torch.int32)
permute(区别 transpose)
四个维度表示的[batch,channel,h,w],如果想把channel放到最后去,形成[batch,h,w,channel]
那么如果使用前面的维度交换,至少要交换两次(先13交换再12交换)
而使用permute 可以 直接指定维度新的所处位置,更加方便。
b = torch.rand(4,3,28,32)print(b.transpose(1, 3).shape) #torch.Size([4, 32, 28, 3])
print(b.transpose(1, 3).transpose(1, 2).shape) #torch.Size([4, 28, 32, 3])print(b.permute(0,2,3,1).shape) #torch.Size([4, 28, 32, 3]
深度学习与Pytorch入门实战(一)Pytorch张量操作相关推荐
- 网易云课程:深度学习与PyTorch入门实战
网易云课程:深度学习与PyTorch入门实战 01 深度学习初见 1.1 深度学习框架简介 1.2 pytorch功能演示 2开发环境安装 3回归问题 3.1简单的回归问题(梯度下降算法) 3.3回归 ...
- 视频教程-深度学习与PyTorch入门实战教程-深度学习
深度学习与PyTorch入门实战教程 新加坡国立大学研究员 龙良曲 ¥399.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅课程,领取优惠,最少立减5元 ↓ ...
- PyTorch 入门实战
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_36556893/article/ ...
- Pytorch入门+实战系列七:图片风格迁移和GAN
Pytorch官方文档:https://pytorch.org/docs/stable/torch.html? 1. 写在前面 今天开始,兼顾Pytorch学习, 如果刚刚接触深度学习并且想快速搭建神 ...
- 2_初学者快速掌握主流深度学习框架Tensorflow、Keras、Pytorch学习代码(20181211)
初学者快速掌握主流深度学习框架Tensorflow.Keras.Pytorch学习代码 一.TensorFlow 1.资源地址: 2.资源介绍: 3.配置环境: 4.资源目录: 二.Keras 1.资 ...
- 15个小时彻底搞懂NLP自然语言处理(2021最新版附赠课件笔记资料)【LP自然语言处理涉及到深度学习和神经网络的介绍、 Pytorch、 RNN自然语言处理】 笔记
15个小时彻底搞懂NLP自然语言处理(2021最新版附赠课件笔记资料)[LP自然语言处理涉及到深度学习和神经网络的介绍. Pytorch. RNN自然语言处理] 笔记 教程与代码地址 P1 机器学习与 ...
- 深度学习报错 | THCudaCheck FAIL file=/pytorch/aten/src/THC/THCGeneral.cpp
深度学习报错 | THCudaCheck FAIL file=/pytorch/aten/src/THC/THCGeneral.cpp 错误定位 解决历程 错误定位 近日在自己的服务器上跑别人的代码时 ...
- 基于深度学习的口罩识别与检测PyTorch实现
基于深度学习的口罩识别与检测PyTorch实现 1. 设计思路 1.1 两阶段检测器:先检测人脸,然后将人脸进行分类,戴口罩与不戴口罩. 1.2 一阶段检测器:直接训练口罩检测器,训练样本为人脸的标注 ...
- OpenCV-Python实战(18)——深度学习简介与入门示例
OpenCV-Python实战(18)--深度学习简介与入门示例 0. 前言 1. 计算机视觉中的深度学习简介 1.1 深度学习的特点 1.2 深度学习大爆发 2. 用于图像分类的深度学习简介 3. ...
- 深度学习笔记其七:计算机视觉和PYTORCH
深度学习笔记其七:计算机视觉和PYTORCH 1. 图像增广 1.1 常用的图像增广方法 1.1.1 翻转和裁剪 1.1.2 改变颜色 1.1.3 结合多种图像增广方法 1.2 使用图像增广进行训练 ...
最新文章
- 深入理解groupByKey、reduceByKey区别——本质就是一个local machine的reduce操作
- Matlab设置Legend横排、分块
- Leetcode 137. 只出现一次的数字 II 解题思路及C++实现
- c#代码实现GPS数据的有效性校验
- 解决: Elements in iteration expect to have ‘v-bind:key‘ directives
- ubuntu 安装 wifi 驱动_论如何在 MacBook Pro 安装 Ubuntu 18.04(解决 wifi、触摸板、键盘驱动)...
- 使用Keil5构建GD32450i-EVAL工程
- 快速寻找发外链论坛的方法
- Git for Windows安装和基本设置
- TeraTerm自动登录(Login)
- cadence PCB走等长线设置
- vs2019安装时,一直卡在正在提取文件
- TOEFL 9个托福独立写作模板总结
- 公司数百人尽数被抓,只因旗下程序员写了这样一个爬虫!
- 聊聊被注销的TMQ公众号
- 【转载】SCI投稿过程总结、投稿状态解析、拒稿后对策及接受后期相关问答
- 多线程模式下保证事物的一致性
- BZOJ3238[Ahoi2013]差异
- css自适应图片样式,css怎么让图片自适应?css图片自适应大小的方法介绍
- 机器学习之必备知识篇