3.0 常见operators算子

1.1 卷积相关

  1)卷积  2)反卷积 (只能做到近似恢复,无法完全恢复原图像)

 参考:https://blog.csdn.net/qq_27261889/article/details/86304061

1.2 线性变换相关

  1)Linear

  2)矩阵相乘类:【mm:二维矩阵相乘;bmm:三维矩阵相乘;matmul:多维矩阵相乘, 只要两个矩阵能够broadcast即可。】

1.3 标准化、归一化相关

  区别在于:计算 均值&方差  所使用得数据范围不同。

  1)Batch_Norm,常用于cv领域;2)Layer_Norm,常用于nlp的RNN中;3)Instance_Norm;4)Group_Norm。

  5)Switchable_Norm,结合BN和LN:E = a1*BN + a2*LN,δ = b1*BN + b2*LN。

  6)RMS_Norm,root mean square均方根,认为LN成功关键是 缩放不变性而不是 平移不变性,所以计算过程:省去了 减均值 操作,只保留了除 方差 操作。

BN对batch_size比较敏感,BN对批次中所有图片的同一层通道做归一化,需要处理的数据能大体代表所有数据整体上的特征分布。因此,batch_size 较大(>16)时,BN才能起到较好的效果。

 

归一化参数(u, δ)在训练和推理时候的联系

  训练时,每个batch得到的参数 按比例累加 得到最终 推理时模型适用的参数。即 移动指数平均法:ui = (1 - β)*ui-1 + β*ui ,β为超参数。

 

LN分别在CV和NLP中的区别(从哪个维度做归一化,取决于传给LN的参数)

CV中:

  LN:input = [N, C, H, W] ,以 [C, H, W] 为单位,在 N 的维度上进行归一化。

NLP中:

在NLP领域,句子中每个词的词向量特征长度相同,但是每个句子中单词的个数不定即 sequence 长度不定。

  LN:input = [N, sentence_length, embedding_dim] ,对每个词向量分别进行归一化。

 

def test_LN():
    # 选择哪个范围内的数据做Norm,取决于定义LN的时候传入的参数
    # 传入三维参数,则所有的后三个维度[1, C,H,W]做一次Norm;传入一维参数,则所有的最后一个维度[1, 1, embedding]做一次Norm
    input_cv = torch.randn(4, 3, 2, 2)
    ln_cv = nn.LayerNorm([3, 2, 2])  # 用 三个维度 定义LN,对 input_cv 计算 3 次 mean和var。
    res_cv = ln_cv(input_cv)
    print('cv__res shape: ', res_cv.shape)
    print('cv__LN weight shape: ', ln_cv.weight.shape)  # [3, 2, 2]

    batch, seq_length, embedding = 20, 5, 10
    input_nlp = torch.randn(batch, seq_length, embedding)
    ln_nlp = nn.LayerNorm(embedding)  # 用 一个维度 定义LN,对 input_nlp 计算 batch*seq_length 次 mean和var。
    res_nlp = ln_nlp(input_nlp)
    print("nlp__res shape: ", res_nlp.shape)
    print("nlp__LN weight shape: ", ln_nlp.weight.shape)  # [10]

 

1.4 Pooling池化相关

  一般在卷积后面会紧跟池化层,池化作用:1)增大感受野,2)减小特征图尺寸但保留重要特征信息,3)抑制噪声,4)降低信息冗余减少计算量, 5)防止过拟合

MaxPooling:更多保留图像纹理信息。

AveragePooling:更多保留图像背景等整体信息。

GlobalAveragePooling:用于模型末尾部分。例如在图像分类中,将中间过程的 [N, C, H, W ] 转换到最终的 [N, 1000] ,最开始用全连接层进行降维但是参数量太大。于是改进操作:将 feature_map 用GAP池化到 [N, C, 1, 1 ],然后 reshape [N, C],最后再用全连接到 [N, 1000]。  改进后:依然可以得到 [N, 1000] 的 Output,且极大减小了计算过程的参数量。( 两种操作,网络结构不同,计算过程不同,模型训练过程中的参数也不同,但是 各自的结构+各自的参数 最终效果是相同。 )

 

1.5 Dropout相关

1.5.1 目的

  降低神经网络过拟合,正则化技术的一种,减少神经元对部分上层神经元的依赖。

1.5.2 训练&推理过程

  a. 训练过程:

    1)前向传播的时候,每层神经元随机失活一定比例,然后在反向传播的时候对没有失活的神经元的权重进行更新,

    2)恢复被失活的神经元

    3)重复上述 1、2步骤

  b. 推理过程:

    在训练过程随机失活部分神经元是为了降低过拟合,在推理的时候,使用的是整个模型结构,不会对神经元失活处理。

1.5.2 如何平衡训练过程和推理时的差异

  差异性来源于,训练的时候会开启dropout,导致输出结果值偏小,训练时关闭dropout启用全部神经元,导致输出结果偏大。假设dropout_rate = p,有两种解决方案:一是在推理时对推理结果值乘以(1 - p),二是在训练时对没有失活的神经元权重乘以(1 / p)。

1.6 transpose/permute、reshape/view

  pytorchh中,将n维张量在显存中一个一个按序存放的,即:将n维张量打平成一维数组的形式存放。tensor的属性 stride 表示了如何根据索引从这一串数据中找到想要的元素。如:t = torch.tensor(np.arange(24).reshape(2, 3, 4)),张量 t 的stride属性:[12, 4, 1],表示 如果索引为 (x,y,z),则从张量 t 的起始存储位置偏移 12*x + 4*y + z 个单位长度。定义:如果张量的 shape 和stride 符合上述性质,则称数据是连续的

 

'''
transpose/permute 和 reshape/view 都可以修改shape,区别:
    transpose只能换两个轴但可以tensor对象直接调用;permute可以换多个轴但只能通过 Tensor.permute() 的方式来调用。
    
    view必须对连续的数据进行view,view从定义开始就只是视图,没有重新开辟内存的操作。
    reshape如果修改非连续的tensor会重新生成一份新数据,但是对连数据的操作不会复制生成新数据。
    
    transpose和reshape:
        reshape/view 操作后张量的stride会根据变换后的shape计算得到,而transpose操作后的stride是根据换轴操作计算得到的,不再保持连续。
        注:transpose操作只是让stride和shape失去了数据连续的性质,并不会重新复制一份新数据。
'''
import numpy as np
import torch

t = torch.tensor(np.arange(24).reshape(2, 3, 4))
print('t stride: ', t.stride())

view = t.view(6, 4)
print('view stride: ', view.stride())

reshape = t.reshape(6, 4)
print('reshape stride: ', reshape.stride())

trans = t.transpose(0, 1)
print('trans shape: ', trans.shape)
print('trans stride: ', trans.stride())

# 验证 transpose 是否生成了新的张量
print(t.data_ptr())
print(trans.data_ptr())

 

 

 

1.7 其它算子

'''
concat/stack/expand/flatten ,区别:
    concat: 在既有轴上进行拼接;
    stack: 新建轴,并拼接
    expand: 对 在某个维度上的长度为1 的地方扩展到 目标 shape
'''

'''
split/slice,区别:
    split:根据指定的维度进行拆分,如果 split(tensor, 2, dim=0):表对第0维每两个组合拆分出来。
            如果 split(tensor, [1,2,2], dim=0): 表对第0维按照 1 2 2 个组合拆分出来。
    slice:同 python list 的切片
'''

'''
reduce规约类算子:按照指定维度做 reduce
torch.
    mean:(input_tensor: tensor, dim: int, keepdim: bool)
    var:
    sum:
    max:
'''

'''
embedding:
    用于将整数标识符映射到密集向量表示。
这在自然语言处理(NLP)和推荐系统等任务中非常有用。
简单来说,它是一个查找表,将输入的整数索引(例如单词或项的索引)映射到一个向量空间。
'''

 

 

posted @ 2024-04-16 11:54  橘子葡萄火龙果  阅读(8)  评论(0编辑  收藏  举报