Tensor创建、随机生成、索引与切片、维度变换

一、Tensor创建

1.import from numpy

  1. torch.from_numpy():从numpy中导入
a = np.array([2,3.3])
# 导入
print(torch.from_numpy(a))
# out : tensor([2.0000, 3.3000], dtype=torch.float64)

2.import from list

  1. torch.tensor([]):接收现有的数据
  2. torch.FloatTensor(shape):一般是接收shape,尽量避免直接接收list
#接收现有的数据 Tensor接收数据的维度
a = torch.tensor([2.,3.2]) 
print(a)
# out : tensor([2.0000, 3.2000])
a = torch.FloatTensor([2.,3.2]) # 一般情况存放shape
print(a)
# out : tensor([2.0000, 3.2000])
a = torch.FloatTensor(2,2,3)
print(a)
# out : tensor([[[7.5555e+31, 1.2705e+31, 3.2611e-12],
#         [7.5555e+31, 1.2705e+31, 1.7225e+22]],
#        [[1.2102e+25, 1.6217e-19, 4.7429e+30],
#         [1.6530e+19, 1.8254e+31, 7.9463e+08]]])
a = torch.tensor([[2.,3.2],[1.,22.3]])
print(a)
# out : tensor([[ 2.0000,  3.2000],
#        [ 1.0000, 22.3000]])

3.初始化tensor

  1. torch.empty(shape):初始化tensor,未初始化的tensor会出现极端数据
  2. torch.FloatTensor(d1,d2,d3):生成Float的Tensor
a = torch.empty(1)
# Out : tensor([0.])

# 未初始化的tensor一定要跟写入数据的后续步骤,比如作为临时容器
torch.FloatTensor(1,2,3)

# 未初始化的tensor出现的问题
b = torch.empty(2,3)
b = torch.Tensor(2,3)

4.设置tensor生成的默认类型

  1. torch.tensor().type():查看tensor生成的数据类型
  2. torch.set_default_tensor_type():改变默认生成的数据类型
# 直接使用tensor的话使用的是自己设定的默认的数据类型
print(torch.tensor([1.2,3]).type())
# out : torch.FloatTensor
#修改默认tensor的数据类型
torch.set_default_tensor_type(torch.DoubleTensor)
print(torch.tensor([1,3.]).type())
# out : torch.DoubleTensor

二、随机生成

1.rand函数

  1. torch.rand(shape):从[0,1]的均匀采样生成
  2. torch.rand_like():接受的是tensor,函数是先求tensor.shape,在传入到rand_like()中
  3. torch.randint(min,max,shape):生成的范围是[min,max)的
  4. torch.randn(shape):正态分布生成
  5. torch.normal(mean=torch.full([10],0),std=torch.arange(1,0,-0.1)):自定义生成10个,均值为0,std为
  6. torch.full():全部赋值为一个元素
  7. torch.randperm():生成[0,x)的下标
# rand函数从[0,1]的均匀采样
a = torch.rand(3,3)
print(a)
# out : tensor([[0.8618, 0.0304, 0.8964],
#        [0.0703, 0.4121, 0.1302],
#        [0.7296, 0.1493, 0.7068]])

# rand_like接受的是tensor
b = torch.rand_like(a)
print(b)
# out : tensor([[0.9976, 0.5621, 0.6491],
#        	   [0.4178, 0.7164, 0.1702],
#              [0.2571, 0.0322, 0.6676]])

# randint(min,max,shap) 范围是[min,max)
c = torch.randint(3,10,[3,3])
print(c)
# out : tensor([[8, 7, 7],
#              [5, 8, 4],
#              [5, 5, 8]])

# 正态分布randn
torch.randn(1,3)
# out : tensor([[-0.8832,  0.2013, -0.5065]])

# N(u,std)
torch.normal(mean=torch.full([10],0),std=torch.arange(1,0,-0.1))
# out : tensor([ 1.2065,  0.5789, -0.1925,  0.2631,  0.5852, -0.6697, -0.6499,  1.0295,
#         0.0067, -0.1699])

# 全部赋值为一个元素
torch.full([2,3],7)
# out : tensor([[7., 7., 7.],
#              [7., 7., 7.]])
torch.full([],7) # 生成dim=0
# out : tensor(7.)
torch.full([1],7)# 生成 dim = 1
# out : tensor([7.])

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

2.arrange、linspace等函数

  1. torch.arange(start,end,step): 生成[start,end)的等差数列
  2. torch.linspace(start,end,steps):生成[start,end]的数量为steps的均分数列
  3. logspace(start,end,steps,base):生成 b a s e s t a r t − > b a s e e n d base^{start}->base^{end} basestart>baseend数量为steps的均分数列
  4. torch.ones():生成全为1的tensor
  5. torch.zeros():生成全为0的tensor
  6. torch.eyes():生成对角线为1的tensor
  7. torch.ones_like(),torch.zeros_like():参数为tensor|
torch.arange(0,10,2)
# Out : tensor([0, 2, 4, 6, 8])
torch.linspace(0,10,steps=4)
# Out : tensor([ 0.0000,  3.3333,  6.6667, 10.0000])
torch.logspace(0,-1,steps=10,base=10)
# tensor([1.0000, 0.7743, 0.5995, 0.4642, 0.3594, 0.2783, 0.2154, 0.1668, 0.1292, 0.1000])

三、Tensor索引与切片

  1. 在Tensor中根据index选取信息:
a = torch.rand(4,3,28,28) #dim = 4
# 选取第0张图片
print(a[0].shape) # torch.Size([3, 28, 28])
# 选取第0张第0维度的图片
print(a[0,0].shape) # torch.Size([28, 28])
# 选取第0张第0维度行2列4的图片
print(a[0,0,2,4]) # tensor(0.4817)
  1. select first/last N
    1. start:end:step:从start开始步数为step一直到end
    2. torch的index:0,1,2,…或者…,-3,-2,-1
print(a.shape) # torch.Size([4, 3, 28, 28])
print(a[:2].shape) # 第0张图片到第1张图片 torch.Size([2, 3, 28, 28])
print(a[:2,:1,:,:].shape) # torch.Size([2, 1, 28, 28])
print(a[:2,1:,:,:].shape) # 1: 从第一个通道开始一直到最后 torch.Size([2, 2, 28, 28])
# 第二个维度:[0 1 2] idx = 0,1,2 || idx = -3 -2 -1
print(a[:2,-1:,:,:].shape) # -1 代表的是 从最后一个元素到最后一个元素, torch.Size([2, 1, 28, 28])
print(a[:2,:-1].shape) # torch.Size([2, 2, 28, 28])
  1. selcet by steps
print(a[:,:,0:28:2,0:28:2].shape) #隔行取样 torch.Size([4, 3, 14, 14])
print(a[:,:,::2,::2].shape) # start : end : step  torch.Size([4, 3, 14, 14])
  1. selset by specific index
    1. index_select(选取的维度,torch.tensor([ ])):对选取的维度上,根据特殊的index选取信息
# 在 0 维度上, 选取 0,2
print(a.index_select(0,torch.tensor([0,2])).shape) # torch.Size([2, 3, 28, 28])
# 在 1 维度上, 选取 1,2
print(a.index_select(1,torch.tensor([1,2])).shape) # torch.Size([4, 2, 28, 28])
# 在 2 维度上, 选取 0 ~ 20
print(a.index_select(2,torch.arange(20)).shape) # 在行上选取0~20 torch.Size([4, 3, 20, 28])
  1. ...自动补全用法
    1....:会根据你的torch来进行自动补全,相当于:,:的一系列组合
print(a[...].shape) # torch.Size([4, 3, 28, 28])
print(a[1,...].shape) # torch.Size([3, 28, 28])
print(a[0,...,::2].shape) # 取第0张图片,CH全取,W隔行取 torch.Size([3, 28, 14])
  1. select by mask
    1. torch.masked_select(torch,mask):根据所给定的mask来对torch进行取信息
    2. 缺点是将torch打平后在选取数据
x = torch.randn(3,4)
# x 数据: tensor([[-1.2342,  0.5914,  0.1628,  0.4915],
#        [ 0.3317, -0.7959, -1.6929, -0.7628],
#        [ 0.2899,  1.6245,  0.5017,  0.0733]])
mask = x.ge(0.5) #将>=0.5赋值为1
# mask : tensor([[False,  True, False, False],
#        [False, False, False, False],
#        [False,  True,  True, False]])
print(torch.masked_select(x,mask)) # 将大于等于0.5的取出
# tensor([0.5914, 1.6245, 0.5017])
print(torch.masked_select(x,mask).shape) # 弊端是会将数据打平
# torch.Size([3])
  1. selcet by flatten index
    1. torch.take(src,torch.tensor([ ])):对给定的src,根据tensor选择数据
src = torch.tensor([[4,3,5],[6,7,8]])
# src : tensor([[4, 3, 5],
#             [6, 7, 8]])
# 是将src打平后,选取0,2,5的index的数据
print(torch.take(src,torch.tensor([0,2,5]))) 
#  tensor([4, 5, 8])

四、Tensor维度变换

  1. view函数
    1. 原来维度信息[b,c,h,w],view 变换后,会丢失物理信息,会造成数据污染
    2. 必须保持数据不能丢失,及物理意义要符合
a = torch.randn(4,1,28,28) # [b,c,h,w]
a.view(4,1*28*28)
print(a.view(4,1*28*28).shape)
# torch.Size([4, 784]) ,将chw合并
print(a.view(4*1*28,28).shape)
# torch.Size([112, 28])
print(a.view(4*1,28,28).shape)
# torch.Size([4, 28, 28])
  1. squeeze and unsqueeze 函数
    1. unsqueeze函数是将维度展开,增加维度
      1. 范围是index = [-dim-a,dim+1)
      2. 函数内容index:正数的话是在x维度前插入,负数的话是从当前维度后插入
      3. index:说明
        1. 在这里插入图片描述
print(a.shape)
# torch.Size([4, 1, 28, 28])
print(a.unsqueeze(0).shape)
# torch.Size([1, 4, 1, 28, 28]),在0维度前加入一维
print(a.unsqueeze(-5).shape)
# torch.Size([1, 4, 1, 28, 28]),在-5后加入一维(0维度加一维)
print(a.unsqueeze(4).shape)
# torch.Size([4, 1, 28, 28, 1]),在4前加入一维(第3维度后加入一维)
print(a.unsqueeze(-1).shape)
# torch.Size([4, 1, 28, 28, 1]),在-1后加入一维(第3维度后加入一维)
--------------------------------------------------------------
b = torch.tensor([1,2,3])
print(b.shape)
# torch.Size([3])
print(b.dim())
# dim = 1
print(b.unsqueeze(0))
# tensor([[1, 2, 3]]) 在0维度前加入一维,即将[1,2,3]作为一个整体看待
print(b.unsqueeze(1))
# tensor([[1],
#        [2],
#        [3]])  在1维度前加入一维,即将[1],[2],[3]单独看
--------------------------------------------------------------
bias = torch.rand(32) # bias相当于给每个channel上的所有像素增加一个偏置
f = torch.rand(4,32,14,14)
bias = bias.unsqueeze(1).unsqueeze(2).unsqueeze(0) 
# [32] => [32,1] => [32,1,1] => [1,32,1,1]
print(bias.shape)
# torch.Size([1, 32, 1, 1])
2. `squeeze(index)`函数是将维度挤压,减少维度
	1. `squeeze(index)` 不给参数会将全部都积压,shape = 1才会挤压掉,shape > 1的话当前维度不变
print(bias.shape)
# torch.Size([1, 32, 1, 1])
print(bias.squeeze().shape) # 全部挤压,相当于view(1*32*1*1)
# torch.Size([32])
print(bias.squeeze(0).shape) # 将0维度挤压
# torch.Size([32, 1, 1])
print(bias.squeeze(1).shape) # 32不能挤压,所以不变
# torch.Size([1, 32, 1, 1])
  1. Expand维度扩张函数
    1. expand: 只是增加理解方式,没有对数据进行补充
    2. 前提 参数内的tensor的dim一致,1->n 可以扩张其余不能扩张,维度不变的话写-1
b = torch.rand(1,32,1,1)

print(b.expand(4,32,14,14).shape)
# torch.Size([4, 32, 14, 14])
print(b.expand(-1,-1,-1,-1).shape)
# torch.Size([1, 32, 1, 1])
print(b.expand(-1,32,14,-1).shape)
# torch.Size([1, 32, 14, 1])
-----------------------------
# 错误例子
print(b.expand(10).shape)
# b的dim=4,但是参数内的dim=1
print(b.expand(1,16,1,1).shape)
# 参数内第1维16必须和b的第1维32一致
  1. Repeat维度扩张函数
    1. Repeat:增加了数据的方式是将其他数据进行copy
    2. 接受的参数为每一维度要变化的方式
b = torch.rand(1,32,1,1)
print(b.repeat(4,32,32,1).shape)
# torch.Size([4, 1024, 32, 1]),变换 1*4,32*32,1*32,1*1
print(b.repeat(1,1,1,1).shape)
# torch.Size([1, 32, 1, 1]),变换 1*1,1*32,1*1,1*1
  1. transpose转置函数
    1. 参数为需要交换的两个维度
    2. 进行转置操作时,pytorch并不会创建新的、转置后的tensor,而是修改了tensor中的一些属性(也就是元数据)
b = torch.rand(4,3,32,32); # b c h w
b1 = b.transpose(1,3); # b w h c
# torch.Size([4, 32, 32, 3])
2. 转置逆操作的contiguous函数
	1. 调用contiguous()时,会强制拷贝一份tensor
# contiguous函数是将
# view 要将维度跟踪,每一维度的数量顺序不能乱
b2 = b.transpose(1,3).contiguous().view(4,3*32*32).view(4,32,32,3).transpose(1,3)
# transpose(1,3)后:变为torch.Size([4, 32, 32, 3])
# view(4,3*32*32)后:变为torch.Size([4, 3072])
# view(4,32,32,3)后:变为torch.Size([4, 32, 32, 3])
# transpose(1,3)后:重新恢复
print(torch.all(torch.eq(b,b2)))
# tensor(True)
  1. permute转置函数
    1. 参数:交换后的维度的顺序
a = torch.rand(0,1,2,3)
print(a.permute(0,2,3,1).shape)
# torch.Size([0, 2, 3, 1])
print(a.permute(3,1,2,0).shape)
# torch.Size([3, 1, 2, 0])

你可能感兴趣的:(从零开始学深度学习,pytorch,深度学习,python)