标准化
BN与LN的区别
Batch normalization和Layer normalization的处理方向垂直,BN是对batch中每个样本的同一channel做normalization;LN是对一个样本的所有channel做normalization。当batch太小时BN不适合,同样当channel太少时LN不适合。
卷积操作
卷积核是一组可训练的矩阵,卷积操作时每个channel的kernel是不同的,且可训练,这样能保留每个channel的信息。
卷积下采样过程中,随着每个channel的尺寸的减小,channel数需要相应增加,这样才能保证不丢失过多信息。每个channel对应一个kernel,表示对输入特征的一种观察,多个channel组合起来体现对输入特征的综合理解。
连续卷积时,当前每个kernel是对输入的每个channel进行滤波,然后求和,见以下示意图:
注:假设输入channel为M,输出channel为N,kernel数应该是N还是M*N存疑,高级计算机视觉课程ppt采用后者
卷积核为1的卷积操作
当kernel size=1,padding=0,stride=1时,卷积层等价于对channel进行线性映射。
import torch
conv1 = nn.Conv1d(in_channels=3, out_channels=5,kernel_size=1)
conv1.weight,conv1.bias
使用卷积层的线性映射等价于如下操作:
先交换输入矩阵最后两维,然后进行普通线性映射,最后再交换最后两维
实验如下: 赋予两个layer同样的权重矩阵,然后对同一输入数据进行操作,比较两者的结果是否相同,相同则证明两者等价,否则不等价。
import torch
from torch import nn
#layers
conv = nn.Conv1d(in_channels=3, out_channels=2, kernel_size=1)
lin = nn.Linear(in_features=3, out_features=2)
#将两个layer的权重矩阵设置为一样,方便比较结果
#for conv layer
dict_conv = conv.state_dict()
dict_conv['weight'] = torch.ones_like(dict_conv['weight'])
dict_conv['bias'] = torch.zeros_like(dict_conv['bias'])
conv.load_state_dict(dict_conv)
#for lin layer
dict_lin = lin.state_dict()
dict_lin['weight'] = torch.ones_like(dict_lin['weight'])
dict_lin['bias'] = torch.zeros_like(dict_lin['bias'])
lin.load_state_dict(dict_lin)
#data
data = torch.rand(1,3,5)
# forward
out_conv = conv(data)
out_lin = lin(data.transpose(1,2)).transpose(1,2) #两次交换最后两维
#output
print('data:\n',data)
print('output of Conv1d layer:\n',out_conv)
print('output of Linear layer:\n',out_lin)
结果:
可见,两种操作确实等价
稀疏张量表示
某些情况下使用的张量本身具有很大的shape,但其中的元素大部分都是0(或其他固定值),这种张量被称为稀疏张量。稀疏张量如果直接存储会极大浪费存储空间,因此发展出了多种压缩存储的方式。
参考:知乎
最直观的是数据结构中常讲的三元组存储方式,把每个非零元素的坐标和值进行存储,但这种方式最大的问题是不方便进行矩阵索引、切片以及矩阵运算。
这里重点讲一下CSR格式,CSR格式通过4个参数确定一个稀疏矩阵:
indptr: 一维整数张量, len(indptr)=shape[0]+1,第i个元素表示第i行之前的非零元素个数,每两个相邻元素可看作一个切片索引,表示稀疏数据每一行的非零元素在values中的起始位置和终止位置;
indices: 一维整数张量,表示稀疏张量非零元素在列中的位置, 与values长度相等;
values: 一维张量,表示对应的非零元素的值,与indices长度相等;
shape: 表示被压缩的稀疏张量的形状。
例子(基于mindspore实现):
indptr = Tensor([0, 1, 2])
indices = Tensor([0, 1])
values = Tensor([1, 2], dtype=mindspore.float32)
shape = (2, 4)
# Make a CSRTensor
csr_tensor = CSRTensor(indptr, indices, values, shape)
print(csr_tensor.astype(mindspore.float64).dtype)
对应矩阵: