作者:春阳 | 来源:互联网 | 2024-10-20 17:05
可以自适应的调整各通道的特征响应值,对通道间的内部依赖关系进行建模,主要为下面三个步骤:Squeeze:沿着空间维度进行特征压缩,将每个二维的特征通道变成一个数,是具有全局的感受野
可以自适应地调整每个通道的特征响应值,以建立通道之间的内部依赖关系模型。 主要有以下三个步骤。
Squeeze:通过沿空间维度进行特征压缩并将每个二维的特征通道改变为一个维度来具有全局感知范围。 进行全局平均轮询,可以得到大小的特征图,可以理解为该特征图具有全局感受野。
扩展:每个要素通道生成表示该要素通道重要性的权重。 使用全连接神经网络,对Sequeeze后的结果进行非线性变换。
re weight :将扩展输出的权重视为每个特征通道的重要性,并通过乘法作用于每个通道。
SE block在较低级别偏向于提取任务之间的共享特征,而在较高级别偏向于提取与任务相关的特征。
代码的实现大致如下。
classselayer(nn.module ) :def_init_ ) self,channel,reduction=16 ) :super ) selayer, self(_init_ ) self.avg _ pool=nn.adaptiveavgpool 2d (1) self.fc=nn.sequential (nn.linear ) ) chinear _=x.size(y=self.avg_pool ) x ).view ) b,c ) # squeeze操作y=self.fc(y ).view ) b,c,1,1 ) # FC是
classsqueezeblock(nn.module ) :def_init_ ) self,exp_size,divide=4.0 ) 3360super ) squeezeblock, self(_init_ ) ifdivide 1: self.dense=nn.sequential (nn.linear (exp _ size,int ) exp _ size/dize nn . # jing ) else : self.dense=nn.sequential (nn.linear (exp_size,exp_size )、#nn.prelu ) exp _ size ) nn width=x.size (out=torch.nn.functional.avg _ pool 2d ) x,kernel_size=-1 ) out=self.dense(out ) out=1 ) #out=hard_sigmoid ) out ) return out * x SE squeeze方式:我只是比较了max和avg,发现avg更好一些。 扩展方式:使用了ReLU、Tanh、Sigmoid,但可知Sigmoid较好,这里指的是第二个激活函数。 stage: resnet50具有多个阶段,实验表明se应用于所有阶段效果最好。 整合策略:发现将se放置在残差单元的前部,后部与残差单元平行放置,或最终放置在前部比较好。 # seres net 50 fromtorchimportnnclassselayer (nn.module ) :def_init_(self,channel, reduction=16 ) 3360SF self(_init_ ) ) self.avg _ pool=nn.adaptiveavgpool 2d (1) self.fc=nn.sequential ) nn nn.linear ) channel//reduction,channel,bias=False ),nn.Sigmoid ) ) defforward ) )。 _=x.size(y=self.AVG_pool ) x ).view ) b,c ) y=self.fc(y ).view ) b,c,1,1 ) returnx * y.eew inplanence reduction=16 ) :super(sebasicblock,self(_init_ ) ) self.conV1=conV3x3) planes,planes, stride(self.bn1=nn.batchnorm2d ) planes ) self.relu=nn.relu(inplace=true ) self.conV2=conV3x3) planes, 1 ) self.bn2=nn.batchnorm2d(planes ) self.se=selayer ) planes, reduction ) self.down sample=down sample self.self ) sample x ) : residual=xout=self.con v1 (x ) out=self.bn1 ) . downsampleisnotnone : residual=self.down sample (x ) out=residualout=self.relu ) out ) return out