当前位置:   article > 正文

对SKnet的研究学习_def __init__(self, in_channels, out_channels, stri

def __init__(self, in_channels, out_channels, stride=1,num_classes=10):

1.代码部分

持续更新

  1. import torch.nn as nn
  2. import torch
  3. from functools import reduce
  4. class SKConv(nn.Module):
  5. def __init__(self,in_channels,out_channels,stride=1,M=2,r=16,L=32):
  6. '''
  7. :param in_channels: 输入通道维度
  8. :param out_channels: 输出通道维度 原论文中 输入输出通道维度相同
  9. :param stride: 步长,默认为1
  10. :param M: 分支数
  11. :param r: 特征Z的长度,计算其维度d 时所需的比率(论文中 特征S->Z 是降维,故需要规定 降维的下界)
  12. :param L: 论文中规定特征Z的下界,默认为32
  13. '''
  14. super(SKConv,self).__init__()
  15. d=max(in_channels//r,L) # 计算向量Z 的长度d
  16. self.M=M
  17. self.out_channels=out_channels
  18. self.conv=nn.ModuleList() # 根据分支数量 添加 不同核的卷积操作
  19. for i in range(M):
  20. # 为提高效率,原论文中 扩张卷积5x5为 (3X3,dilation=2)来代替。 且论文中建议组卷积G=32
  21. self.conv.append(nn.Sequential(nn.Conv2d(in_channels,out_channels,3,stride,padding=1+i,dilation=1+i,groups=32,bias=False),
  22. nn.BatchNorm2d(out_channels),
  23. nn.ReLU(inplace=True)))
  24. self.global_pool=nn.AdaptiveAvgPool2d(1) # 自适应pool到指定维度 这里指定为1,实现 GAP
  25. self.fc1=nn.Sequential(nn.Conv2d(out_channels,d,1,bias=False),
  26. nn.BatchNorm2d(d),
  27. nn.ReLU(inplace=True)) # 降维
  28. self.fc2=nn.Conv2d(d,out_channels*M,1,1,bias=False) # 升维
  29. self.softmax=nn.Softmax(dim=1) # 指定dim=1 使得两个全连接层对应位置进行softmax,保证 对应位置a+b+..=1
  30. def forward(self, input):
  31. batch_size=input.size(0)
  32. output=[]
  33. #the part of split
  34. for i,conv in enumerate(self.conv):
  35. #print(i,conv(input).size())
  36. output.append(conv(input))
  37. #the part of fusion
  38. U=reduce(lambda x,y:x+y,output) # 逐元素相加生成 混合特征U
  39. s=self.global_pool(U)
  40. z=self.fc1(s) # S->Z降维
  41. a_b=self.fc2(z) # Z->a,b 升维 论文使用conv 1x1表示全连接。结果中前一半通道值为a,后一半为b
  42. a_b=a_b.reshape(batch_size,self.M,self.out_channels,-1) #调整形状,变为 两个全连接层的值
  43. a_b=self.softmax(a_b) # 使得两个全连接层对应位置进行softmax
  44. #the part of selection
  45. a_b=list(a_b.chunk(self.M,dim=1))#split to a and b chunk为pytorch方法,将tensor按照指定维度切分成 几个tensor块
  46. a_b=list(map(lambda x:x.reshape(batch_size,self.out_channels,1,1),a_b)) # 将所有分块 调整形状,即扩展两维
  47. V=list(map(lambda x,y:x*y,output,a_b)) # 权重与对应 不同卷积核输出的U 逐元素相乘
  48. V=reduce(lambda x,y:x+y,V) # 两个加权后的特征 逐元素相加
  49. return V
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/article/detail/73027
推荐阅读
相关标签
  

闽ICP备14008679号