张量常用操作以及归一化

一.归一化

归一化的原因:不同评价指标(即特征向量中的不同特征就是所述的不同评价指标)往往具有不同的量纲和量纲单位,这样的情况会影响到数据分析的结果,为了消除指标之间的量纲影响,需要进行数据标准化处理,以解决数据指标之间的可比性。

归一化的目的:就是使得预处理的数据被限定在一定的范围内(比如[0,1]或者[-1,1]),从而消除奇异样本数据导致的不良影响。

所有TorchVision 数据集都有两个参数

transform修改特征

target_transform修改标签 - 接受包含转换逻辑的可调用对象。

对于训练,我们需要将特征作为归一化张量,将标签作为单热编码张量。为了进行这些转换,我们使用ToTensorLambda。 

transform=ToTensor(),
    target_transform=Lambda(lambda y: torch.zeros(10, dtype=torch.float).scatter_(0, torch.tensor(y), value=1))

注意:ToTensor 将 PIL 图像或 NumPyndarray转换为FloatTensor. 并在 [0., 1.] 范围内缩放图像的像素强度值;

Lambda 转换适用于任何用户定义的 lambda 函数。在这里,我们定义了一个函数来将整数转换为单热编码的张量。它首先创建一个大小为 10(我们数据集中的标签数量)的零张量,并调用 scatter_,它value=1在标签给定的索引上分配 a y

二.维度变换 

2.1 squeeze vs unsqueeze 维度增减

  • squeeze():对 tensor 进行维度的压缩,去掉维数为 1 的维度。用法:torch.squeeze(a) 将 a 中所有为 1 的维度都删除,或者 a.squeeze(1) 是去掉 a中指定的维数为 1 的维度。
  • unsqueeze():对数据维度进行扩充,给指定位置加上维数为 1 的维度。用法:torch.unsqueeze(a, N),或者 a.unsqueeze(N),在 a 中指定位置 N 加上一个维数为 1 的维度。

squeeze 用例程序如下:

a = torch.rand(1,1,3,3)
b = torch.squeeze(a)
c = a.squeeze(1)
print(b.shape)
print(c.shape)

程序输出结果如下:

torch.Size([3, 3]) torch.Size([1, 3, 3])

unsqueeze 用例程序如下:

x = torch.rand(3,3)
y1 = torch.unsqueeze(x, 0)
y2 = x.unsqueeze(0)
print(y1.shape)
print(y2.shape)

程序输出结果如下: 

torch.Size([1, 3, 3]) torch.Size([1, 3, 3])

 2.2 transpose vs permute 维度交换

torch.transpose() 只能交换两个维度,而 .permute() 可以自由交换任意位置。函数定义如下:

 
  1. transpose(dim0, dim1) → Tensor # See torch.transpose()

  2. permute(*dims) → Tensor # dim(int). Returns a view of the original tensor with its dimensions permuted.

在 CNN 模型中,我们经常遇到交换维度的问题,举例:四个维度表示的 tensor:[batch, channel, h, w]nchw),如果想把 channel 放到最后去,形成[batch, h, w, channel]nhwc),如果使用 torch.transpose() 方法,至少要交换两次(先 1 3 交换再 1 2 交换),而使用 .permute() 方法只需一次操作,更加方便。例子程序如下:

import torch
input = torch.rand(1,3,28,32) # torch.Size([1, 3, 28, 32]
print(b.transpose(1, 3).shape) # torch.Size([1, 32, 28, 3])
print(b.transpose(1, 3).transpose(1, 2).shape) # torch.Size([1, 28, 32, 3])
print(b.permute(0,2,3,1).shape) # torch.Size([1, 28, 28, 3]

三.合并分割 

 3.1,torch.cat 和 torch.stack

可以用 torch.cat 方法和 torch.stack 方法将多个张量合并,也可以用 torch.split方法把一个张量分割成多个张量。torch.cat 和 torch.stack 有略微的区别,torch.cat 是连接,不会增加维度,而 torch.stack 是堆叠,会增加一个维度。

>>> a = torch.arange(0,9).view(3,3)
>>> b = torch.arange(10,19).view(3,3)
>>> c = torch.arange(20,29).view(3,3)
>>> cat_abc = torch.cat([a,b,c], dim=0)
>>> print(cat_abc.shape)
torch.Size([9, 3])
>>> print(cat_abc)
tensor([[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8],
        [10, 11, 12],
        [13, 14, 15],
        [16, 17, 18],
        [20, 21, 22],
        [23, 24, 25],
        [26, 27, 28]])
>>> stack_abc = torch.stack([a,b,c], axis=0)  # torch中dim和axis参数名可以混用
>>> print(stack_abc.shape)
torch.Size([3, 3, 3])
>>> print(stack_abc)
tensor([[[ 0,  1,  2],
         [ 3,  4,  5],
         [ 6,  7,  8]],
 
        [[10, 11, 12],
         [13, 14, 15],
         [16, 17, 18]],
 
        [[20, 21, 22],
         [23, 24, 25],
         [26, 27, 28]]])
>>> chunk_abc = torch.chunk(cat_abc, 3, dim=0)
>>> chunk_abc
(tensor([[0, 1, 2],
         [3, 4, 5],
         [6, 7, 8]]),
 tensor([[10, 11, 12],
         [13, 14, 15],
         [16, 17, 18]]),
 tensor([[20, 21, 22],
         [23, 24, 25],
         [26, 27, 28]]))

3.2,torch.split 和 torch.chunk

torch.split() 和 torch.chunk() 可以看作是 torch.cat() 的逆运算。

split() 作用是将张量拆分为多个块,每个块都是原始张量的视图。

torch.split(tensor, split_size_or_sections, dim=0)

chunk() 作用是将 tensor 按 dim(行或列)分割成 chunks 个 tensor 块,返回的是一个元组。

torch.chunk(input, chunks, dim=0) → List of Tensors

实例如下:

>>> a = torch.arange(10).reshape(5,2)
>>> a
tensor([[0, 1],
        [2, 3],
        [4, 5],
        [6, 7],
        [8, 9]])
>>> torch.split(a, 2)
(tensor([[0, 1],
         [2, 3]]),
 tensor([[4, 5],
         [6, 7]]),
 tensor([[8, 9]]))
>>> torch.split(a, [1,4])
(tensor([[0, 1]]),
 tensor([[2, 3],
         [4, 5],
         [6, 7],
         [8, 9]]))
>>> torch.chunk(a, 2, dim=1)
(tensor([[0],
        [2],
        [4],
        [6],
        [8]]), 
tensor([[1],
        [3],
        [5],
        [7],
        [9]]))

 参考链接:https://blog.csdn.net/qq_38331273/article/details/116862548?utm_term=%E5%BC%A0%E9%87%8F%E7%9A%84%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduweb~default-0-116862548&spm=3001.4430

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值