当前位置: 首页 > article >正文

【Pytorch】学习第一弹——张量数据类型、创建张量、索引与切片、维度变换、Broadcasting、合并与分割、数学运算

一、张量数据类型

        在python中的数据类型有int,float,Int array,Float array,对应到PyTorch中都是一个张量形式的。

        在PyTorch中如何表示string呢?Pytorch不是一个完备的语言库,是一个面对数据计算的内建加速库。我们有两种类型的表示方式:

  • One-hot:pytorch没有内建string支持,需要用到编码的方式进行替代
    • [0,1]dog
    • [1,0]cat
  • Embedding:当上万单词编码的时候会变得很稀疏,且没有进行语义关系的表示,需要用数字方式进行
    • Word2vec
    • glove

        即使同一个数据被放在不同的位置,它的数据类型都是不同的。

1. Type Check

        下面,我们来看一下如何进行数据推断。

a = torch.randn(2,3)
a.type()
# Out: 'torch.FloatTensor'
type(a)
# Out:'torch.Tensor'
isinstance(a, torch.FloatTensor) # 参数的合法化检验
# True

        type方法返回的是一个基本的数据类型,同一个tensor被部署在cpu和gpu上面是不一样的。

isinstance(data, torch.cuda.DoubleTensor)
# Out:False
data=data.cuda()
# 将数据搬运到gpu上面
isinstance(data, torch.cuda.DoubleTensor)
# Out:True

2. Dim 0

        下面,看一下最简单的一种数据类型——标量。标量通常用在loss上。

torch.tensor(1.)
# Out:tensor(1.)
torch.tensor(1.3)
# Out:tensor(1.300)

        如何得到标量的shape呢? 

a=torch.tensor(2.2)
a.shape
# Out: torch.Size([])-0维张量即标量
len(a.shape)
# Out: 0
a.size()
# Out: torch.Size([])

3. Dim1/rank1

        与标量不同的是多了一个[]。dim为1的向量通常用在Bias、Linear Input上。

torch.tensor([1.1])
# Out:tensor([1.1000])

torch.tensor([1.1, 2.2])
# Out: tensor([1.1000, 2.2000])

torch.FloatTensor(1)
# Out:tensor([3.2239e-25])

torch.FloatTensor(2)
# Out:tensor([3.2239e-25,4.5915e-4])

data = np.ones(2)
data
# Out:array([1., 1.])

torch.from_numpy(data)
# tensor([1.,1.], dtype=torch.float64)

        如何得到标量的shape呢? 

a=torch.ones(2)
a.shape
# torch.Size([2])

4. Dim2

a=torch.randn(2,3)
a
# Out:tensor([[-0.4423,0.5949,1.1440],[-2.0935,0.2051,1.2781]])
a.shape
# torch.Size([2,3])
a.size(0)
# 2
a.size(1)
# 3
a.shape[1]
# 3

5. Dim3

a=torch.randn(1,2,3)
a
# Out:tensor([[0.0764,0.2590,0.9816],[0.6798,0.1568,0.7919]])
a.shape
# Out:torch.Size([1,2,3])
a[0]
# Out: tensor([[0.0764,0.2590,0.9816],[0.6798,0.1568,0.7919]])
list(a.shape)
# Out:[1,2,3]

二、创建Tensor

1. import from numpy

a=np.array([2,3.3])
torch.from_numpy(a)
# Out:tensor([2.000,3.3000],dtype=torch.float64)
a=np.ones([2,3])
torch.from_numpy(a)
# Out:tensor([[1.,1.,1.],[1.,1.,1.],dtype=torch.float64])

2. import from list

torch.tensor([2.,3.2])
# Out:tensor([2.0000,3.2000])
torch.FloatTensor([2.,3.2])
# Out:tensor([2.0000,3.2000])
torch.tensor([[2.,3.2],[1.,22.3]])
# Out:tensor([[2.0000,3.2000],[1.0000,22.3000])

3. Unitialized

torch.empty(1)
# Out:tensor([0.])
torch.Tensor(2,3)
# Out:tensor([[3.1921e+27,0.0000e+00,-1.0163e+11],[7.1186e-43,0.0000e+00,-0.0000e+00]])
Torch.IntTensor(2,3)
# Out:tensor([1831143156,0,-776122816],[508,0,-21474836468],dtype=torch.int32)

4. Set default type

        在Pytorch中,可以使用FloatTensor来创建数据类型,也可以用Tensor,Tensor是一种更加通用的一种情况。在没有任何类型设置的情况下,torch.tensor会创建默认数据类型——FloatTensor,torch.Tensor会创建数据类型——DoubleTensor。

import torch

# 默认情况下,创建一个浮点张量
tensor1 = torch.tensor([1.2, 3])
print(tensor1.type())  # 输出: torch.FloatTensor

# 设置默认的张量类型为 DoubleTensor
torch.set_default_tensor_type(torch.DoubleTensor)

# 现在创建的张量类型为 DoubleTensor
tensor2 = torch.tensor([1.2, 3])
print(tensor2.type())  # 输出: torch.DoubleTensor

 rand/rand_like, randint

rand类型函数特点:

  • [0, 1]:rand()函数取值采样范围
  • [min, max):左闭右开

torch.rand(height, width):生成一个heightxwidth大小的矩阵,每个数的范围为(0,1]

torch.rand_like(matrix):生成一个与matrix同等尺寸大小的矩阵,每个数的范围为(0,1]

torch.randint(min, max, (height, width)):生成一个heightxwidth大小的矩阵,每个数的范围为[min, max)中的整数

import torch

# 1. 使用 rand 生成一个随机浮点数张量,元素在 [0, 1) 之间
x = torch.rand(2, 3)  # 创建一个2x3的张量,元素为[0, 1)之间的随机浮点数
print("rand(2, 3):")
print(x)

# 2. 使用 rand_like 生成一个与已有张量 x 相同形状的随机浮点数张量
y = torch.rand_like(x)  # 根据x的形状生成一个随机张量
print("\nrand_like(x):")
print(y)

# 3. 使用 randint 生成一个随机整数张量,范围是 [0, 10)
z = torch.randint(0, 10, (2, 3))  # 创建一个2x3的张量,元素为[0, 10)之间的随机整数
print("\nrandint(0, 10, (2, 3)):")
print(z)

randn 

torch.randn(height, width):生成heightxwidth的矩阵,每个数的分布为正态分布~N(0, 1)

torch.randn(3,3)
# 创建一个3x3的张量,元素为[0,1)之间的浮点数,服从正态分布
torch.normal(mean=torch.full([10],0), std=torch.arange(1, 0, -0.1))
# 创建一个长度为10的向量,数值为0

full

torch.full([height, width], value):生成一个heightxwidth大小的矩阵,每个数值均为vaue

torch.full([2,3],7)
# 生成一个2x3的矩阵,数值均为7.
torch.full([],7)
# 生成一个标量,数值为7.
torch.full([1],7)
# 生成一个长度为1的向量,数值为7.

arange/range

torch.arange(min, max):生成一个张量,从min到max,其中[min, max)

torch.arange(0,10)
# Out:tensor([0,1,2,3,4,5,6,7,8,9])
torch.arange(0,10,2)
# Out:tensor([0,2,4,6,8])
torch.range(0,10)

linspace/logspace

torch.linspace(value1, value2,steps=value):生成[value1, value2]的数值,按照线性分布分为value份

torch.logspace(value1, value2,steps=value):生成[value1, value2]的数值,按照对数分布分为value份

torch.linspace(0,10,steps=4)
# Out:tensor([0.0000,3.3333,6.6667,10.0000])
torch.linspace(0,10,steps=10)
# Out:tensor([0.0000,1.1111,2.2222,3.3333,4.4444,5.5555,6.6667,7.7778,8.8889,10.0000])
torch.linspace(0,10,steps=11)
# Out:tensor([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.])
torch.logspace(0,-1,steps=10)
# Out:tensor([1.0000,0.7743,0.5995,0.4642,0.3594,0.2783,0.2154,0.1668,0.1292,0.1000])

ones/zeros/eye

torch.ones(height,width):生成全1矩阵,大小为heightxwidth

torch.zeros(height,width):生成全0矩阵,大小为heightxwidth

torch.eye(height,width):生成全对角矩阵,大小为heightxwidth

torch.ones(3,3)
torch.zeros(3,3)
torch.eye(3,4)

randperm

torch.randperm(value):即random.shuffle,将生成

三、索引与切片

1. 索引

indexing

a=torch.rand(4,3,28,28)
a[0].shape
# out:torch.Size([3, 28, 28])
a[0,0].shape
# out:torch.Size([28,28])
a[0,0,2,4]
# out:tensor(0.8082)

2. 切片

 select first/last N

a.shape
# out:torch.Size([4,3,28,28])
a[:2].shape
# out:torch.Size([2,3,28,28])
a[:2,:1,:,:].shape
# out:torch.Size([2,2,28,28])
a[:2,-1:,:,:].shape
# out:torch.Size([2,1,28,28])

select by steps

1.  :单独出现表示取全部

2. :n表示从前面开始到n,不包括第n个索引; n:表示从第n个开始到最末尾

3.  [start, end)表示从start到end

4. 0:28:1 每隔一个点采样一次

    0:28 从0到28

    0:28:3 每隔三个点采样一次

    ::2 从开始到末尾每隔两个点采样一次

a[:,:,0:28:2,0:28:2].shape
# out:torch.Size([4,3,14,14])隔两个进行取样
a[:,:,::2,::2].shape
# out:torch.Size([4,3,14,14])

select by specific index

.index_select(dim, [value1, value2]):在dim这个维度上进行[value1,value2)的采样,其他维度不变

a.shape
# torch.Size([4,3,28,28])
a.index_select(0,[0,2])
# torch.Size([2,3,28,28])
a.index_select(1,[1,2])
# torch.Size([4,2,28,28])
a.index_select(2,torch.arange(28).shape)
# torch.Size([4,3,28,28])
a.index_select(2,torch.arrange(8).shape)
# torch.Size([4,3,8,28])

......

a.shape
# torch.Size([4,3,28,28])
a[...].shape
# torch.Size([4,3,28,28])
a[0,...].shape
# torch.Size([3,28,28])
a[:,1,...].shape
# torch.Size([4,28,28])
a[...,:2].shape
# torch.Size([4,3,28,2])

select by mask

torch.masked_select():根据mask矩阵中为1的数值,挑选出同等位置的x矩阵中的数值并组合成一组向量。

x = torch.randn(3,4)
# out:torch([[-1.3911,-0.7871,-1.6558,-0.2542],[-0.9011,0.5404,-0.6612,0.3917],[-0.3854,0.2968,1.5771]])
mask = x.ge(0.5)
# 生成元素大于等于0.5的mask矩阵
# out:torch([[0,0,0,0],[0,1,0,0],[0,0,1,1]],dtype=torch.unit8)
torch.masked_select(x, mask)
# out:tensor([0.5404,0.6040,1.5771])
torch.masked_select(x, mask).shape
# out:torch.Size([3])

select by flatten index

torch.take(src, torch.tensor([value1,value2,...])):将src矩阵中的第value1,value2,...,个位置的数值提取出来形成一个向量。

src = torch.tensor([4,3,5],[6,7,8])
torch.take(src,torch.tensor([0,2,5]))
# out:tensor([4,5,8])

四、维度变换

view/reshape

view:会损失维度信息,数据的存储顺序很重要,需要进行额外的恢复和存储 

a=torch.rand(4,1,28,28)
a.shape
# out:torch.Size([4,1,28,28])
a.view(4,28*28)
# 将[4,1,28,28]合并为[4,1*28*28]
a.view(4*28,28)
# 将[4,1,28,28]合并为[4*1*28,28]
a.view(4*1,28,28)
# 将[4,1,28,28]合并为[4*1,28,28]

unsqueeze

[-a.dim()-1,a.dim()+1):可以插入的范围

unsqueeze(value):在value位置上插入新的维度,数值为1,维度的插入不会改变数据本身

a.shape
# out: torch.Size([4,1,28,28])
a.unsqueeze(0).shape
# out: torch.Size([1,4,1,28,28])
a.unsqueeze(-1).shape
# out: torch.Size([4,1,28,28,1])
a.unsqueeze(4).shape
# out: torch.Size([4,1,28,28,1])
a.unsqueeze(-4).shape
# out: torch.Size([4,1,1,28,28])
a.unsqueeze(-5).shape
# out:torch.Size([1,4,1,28,28])
a.unsqueeze(5).shape
# RuntimeError:Dimension out of range

 squeeze

squeeze(value):将第value个维度进行挤压,如果这个维度值是1的话,便可以进行挤压,如果这个维度值不是1,则返回原来的张量

b.shape
# out:torch.Size([1,32,1,1])
b.squeeze().shape
# out:torch.Size([32])
b.squeeze(0).shape
# out:torch.Size([32,1,1])
b.squeeze(-1).shape
# out:torch.Size([1,32,1])
b.squeeze(1).shape
# out:torch.Size([1,32,1,1])
b.squeeze(-4).shape
# out:torch.Size([32,1,1])

 expand/expand_as 

a=torch.rand(4,32,14,14)
b.shape
# out: torch.Size([1,32,1,1])
b.expand(4,32,14,14).shape
# out: torch.Size([4,32,14,14])
b.expand(-1,32,-1,-1).shape
# out:torch.Size([1,32,1,1])
b.expand(-1,32,-1,-4).shape
# out: torch.Size([1,32,1,-4])

repeat

b.shape
# out:torch.Size([1,32,1,1])
b.repeat(4,32,1,1).shape
# out:torch.Size([4,1024,1,1])
b.repeat(4,1,1,1).shape
# out:torch.Size([4,32,1,1])
b.repeat(4,1,32,32).shape
# out:torch.Size([4,32,32,32])

.t

a = torch.randn(3,4)
a.t()

.t() tensor只能适用于2D,对于4D等会产生报错 

transpose

a.shape
# [4,3,32,32]
a1 = a.transpose(1,3).contiguous().view(4,3*32*32).view(4,3,32,32)
# [b,c,h,w]-[b,w,h,c]-[b,whc]-x[b,c,h,w]
a2 = a.transpose(1,3).contiguous().view(4,3*32*32).view(4,32,32,3).transpose(1,3)
# [b,c,h,w]-[b,w,h,c]-[b,whc]-[b,w,h,c]-[b,c,h,w]

a1.shape,a2.shape
# out: (torch.Size([4,3,32,32]),torch.Size([4,3,32,32]))
torch.all(torch.eq(a,a1))
# out: tensor(0,dtype=torch.unit8)
torch.al(torch.eq(a,a2))
# out: tensor(1,dtype=torch.unit8)

permute

a=torch.rand(4,3,28,28)
a.transpose(1,3).shape
# out:torch.Size([4,28,28,3])
b=torch.rand(4,3,28,32)
# out:torch.Size([4,3,28,32])
b.transpose(1,3).shape
# out:torch.Size([4,32,28,3])
b.transpose(1,3).transpose(1,2).shape
# out:torch.Size([4,28,32,3])
b.permute(0,2,3,1).shape
# out:torch.Size([4,28,32,3])

五、Broadcasting

1. Why broadcasting?

for actual demanding

  • [class, students, scores]
  • add bias for every students:+5
  • [4,32,8]+[4,32,8]
  • [4,32,8]+[5.0]

memory consumption

  • [4,32,8]=>1024
  • [5.0]=>1

2.  Is it broadcasting-able?

match from last dim:

  • if current dim=1, expand to the same
    •  [4,32,14,14], [1,32,1,1]=>[4,32,14,14]
  • if either has no dim, insert one dim and expand to same
    • [4,32,14,14], [14,14]=>[1,1,14,14]=>[4,32,14,14]
  • otherwise, not broadcasting-able
    • [4,32,14,14], [2,32,14,14],不符合broadcast情景,需要手动完成拓展成四张图片

六、合并与分割 

cat

torch.cat([matrix1, matrix2],dim=value): 将matrix1和matrix2在value这个维度上进行拼接

需要保持除了value这个维度的其他维度都相同

a=torch.rand(4,32,8)
b=torch.rand(5,32,8)
torch.cat([a,b],dim=0).shape
# out:torch.Size([9,32,8])

stack

torch.stack([matrix1, matrix2],dim=value): 创建一个新的维度dim=value,其他的维度必须完全一摸一样

torch.cat([a1,a2],dim=2).shape
# out:torch.Size([4,3,32,32])
torch.stack([a1,a2],dim=2).shape
# out:torch.Size([4,3,2,16,32]),重新加入一个新的维度,在dim=2的地方
a=torch.rand(32,8)
b=torch.rand(32,8)
torch.stack([a,b],dim=0).shape
# out:torch.Size([2,32,8])

split: by length

split([value1,value2,...],dim=value):在value维度上,将张量拆分成n个张量,长度分别为value1,...,valuen

c.shape
# out:torch.Size([2,32,8])
a,b = c.split([1,1],dim=0)
# out:(torch.Size([1,32,8]),torch.Size([1,32,8]))
a,b = c.split(1,dim=0)
# out:(torch.Size([1,32,8]),torch.Size([1,32,8]))
a,b = c.split(1,dim=0)
# ValueError:not enough values to unpack

chunk: by num

chunk(num,dim=value):在value维度上,将张量拆分成num个张量

c.shape
# out:torch.Size([2,32,8])
a, b = c.chunk(2, dim=0)
# out:(torch.Size([1,32,8],torch.Size([1,32,8]))

 七、数学运算

basic

a=torch.rand(3,4)
b=torch.rand(4)
a+b,a-b,a*b,a/b
torch.add(a,b)
torch.sub(a,b)
torch.mul(a,b)
torch.div(a,b)
torch.all(torch.eq(a-b,torch.sub(a,b)))
# out:tensor(1, dtype=torch.uint8)

matmul

torch.mm只适用于2d,torch.matmul可以多维,但是只是进行后两维的运算,前两维遵循broadcast机制规律。

a,b
# out:(tensor([3.,3.],[3.,3.]),tensor([1.,1.],[1.,1.])
torch.mm(a,b)
# out:tensor([6.,6.],[6.,6.],只适用于2d
torch.matmul(a,b)
# out:tensor([6.,6.],[6.,6.]
a@b
# out:tensor([6.,6.],[6.,6.]

power

a=torch.full([2,2],3)
# 平方
a**2
a.pow(2)
# 平方根
a**(0.5)
a.sqrt()
# 平方根的导数
a.rsqrt()

 Exp log

a=torch.exp(torch.ones(2,2))
# 以e为底的指数
torch.log(a)
# 以e为底的对数

Approximation 

.floor():向下取整

.ceil():向上取整

.trunc():裁剪保留整数

.frac():裁剪保留小数

.round():四舍五入

a=torch.tensor(3.14)
a.floor(),a.ceil(),a.trunc(),a.frac()
# out:tensor(3.),tensor(4.),tensor(3.),tensor(0.1400)
a.round()
# out:tensor(3.)

 clamp

grad=torch.rand(2,3)*15
grad.max()
# 矩阵中的最大值
grad.median()
# 矩阵中的中位数
grad.clamp(10)
# 矩阵中小于10的变成10
grad
grad.clamp(0,10)
# 矩阵中的数值保持在[0,10]


http://www.kler.cn/a/427949.html

相关文章:

  • 学习串行通信
  • Linux 进程概念
  • Origami Agents:AI驱动的销售研究工具,助力B2B销售团队高效增长
  • 【C语言】内存函数
  • SQL注入漏洞之高阶手法 宽字节注入以及编码解释 以及堆叠注入原理说明
  • 关于el-table翻页后序号列递增的组件封装
  • Django drf基于APIView 快速使用
  • 网络渗透实验四(渗透课)
  • 《Opencv》Canny边缘检测操作
  • 代码随想录-算法训练营day45(动态规划07:爬楼梯进阶本,零钱兑换,完全平方数)
  • 健康养生:身心和谐的生活艺术
  • 算法日记 43-44 day 图论(深搜,广搜)
  • 【ESP32】ESP-IDF开发 | DAC数模转换器+余弦波输出例程
  • Flink:入门介绍
  • deepsort复现报错TypeError: tuple indices must be integers or slices, not tuple 解决
  • CSES-1141 Playlist
  • RoformerBERT介绍
  • 架构10-可观测性
  • Unity 设计模式-观察者模式(Observer Pattern)详解
  • 3D 生成重建019-LERF用文本在Nerf中开启上帝之眼
  • 算法训练-位运算
  • Next.js系统性教学:服务器操作与数据变更
  • 毕设记录_论文阅读(动磁式音圈电机的开发与应用)_20241207
  • 保姆级教学 uniapp绘制二维码海报并保存至相册,真机正常展示图片二维码
  • SAP SD学习笔记19 - 形式发票(Proforma Invoice)
  • Oracle 11g ADG 单实例 DG Broker 配置指南