cross channel pooling 的原理与代码实现

普通的 pooling,是 channel 之间独立做的,只是在每个 feature map 空间维度上去做pooling,pooling 完 channel 数是不会改变的。

cross channel pooling,是在 channel 维度上去做,比如现在有 50 个 feature map,想通过 cross channel pooling 去得到5个feature map。做法就是把 50 个 feature map 分成 5 组,每组内的 10 个 feature map 在 channel 维度上做 pooling 生成 1 个新的 feature map。
在这里插入图片描述
如上图所示:对 channel 1 的 4x4 特征图和 channel 2 的 4x4 特征图使用最大池化做 cross channel pooling,得到一张 4x4 的特征图。两个通道的左上角分别为 0.2,0.1,最大池化后,选出0.2。同理,依此类推,右下角是 0.4 和 0.1 比较,选出0.4。
cross channel pooling 是操作不同通道的同一个位置,而普通 pooling 是操作同一通道不同位置。

cross channel pooling 和1x1卷积的关系,一般 1x1 既可以用来升维也可以降维,但是 cross channel pooling 只能用来降维,而且没有参数可以学习,1x1 卷积相当于channel 之间的加权和。

代码实现:

import torch
import numpy as np
from torch.autograd import Variable
from torch.nn.modules.module import Module
import torch.nn.functional as F

class my_MaxPool2d(Module):

    def __init__(self, kernel_size, stride):
        super(my_MaxPool2d, self).__init__()
        self.kernel_size = kernel_size
        self.stride = stride
    def forward(self, input):
    # 如维度为(3, 6, 4, 4) 交换为 (3, 4, 4, 6)
        print('input:',input.shape)
        input = input.transpose(3,1)
        print('input.transpose:',input.shape)
        input = F.max_pool2d(input, self.kernel_size, self.stride)
        print("max_pool.",input.shape)
        input = input.transpose(3,1).contiguous()
        print("final_cross",input.shape)
        return input
# kernel 和 sride 都是二维的。表示不同方向池化尺寸不一样。
m = my_MaxPool2d((1, 2), stride=(1, 2))
input = Variable(torch.randn(3, 6, 4, 4))
output = m(input)
'''
input: torch.Size([3, 6, 4, 4])
input.transpose: torch.Size([3, 4, 4, 6])
max_pool. torch.Size([3, 4, 4, 3])
final_cross torch.Size([3, 3, 4, 4])
'''

通过 cross channel pooling 后,原本 shape 为 [3, 6, 4, 4] 的 feature 变为 shape 为 [3, 3, 4, 4] 的 feature。其中,需要经过两次transpose转换维度,代码中 transpose 函数,参考另一篇博客:pytorch中reshape()、view()、permute()、transpose()总结。中间过程图示:
在这里插入图片描述
参考链接:
Cross channel pooling的理解?

  • 9
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 DSAN 模型的 Keras 代码实现: ```python from keras import layers from keras.models import Model from keras.optimizers import Adam def DSAN(input_shape, num_classes): inputs = layers.Input(shape=input_shape) # Spatial Attention Module x1 = layers.Conv2D(filters=64, kernel_size=(3,3), strides=(1,1), padding="same", activation="relu")(inputs) x2 = layers.Conv2D(filters=64, kernel_size=(3,3), strides=(2,2), padding="same", activation="relu")(x1) x3 = layers.Conv2D(filters=64, kernel_size=(3,3), strides=(2,2), padding="same", activation="relu")(x2) x4 = layers.Conv2D(filters=64, kernel_size=(3,3), strides=(2,2), padding="same", activation="relu")(x3) # Channel Attention Module avg_pool = layers.GlobalAveragePooling2D()(x4) max_pool = layers.GlobalMaxPooling2D()(x4) a = layers.Dense(units=64, activation='relu')(layers.concatenate([avg_pool, max_pool])) a = layers.Dense(units=64, activation='sigmoid')(a) a = layers.Reshape((1,1,64))(a) x5 = layers.Multiply()([x4, a]) # Classification x6 = layers.Flatten()(x5) x6 = layers.Dense(units=256, activation='relu')(x6) outputs = layers.Dense(units=num_classes, activation='softmax')(x6) model = Model(inputs, outputs) model.compile(optimizer=Adam(lr=0.001), loss='categorical_crossentropy', metrics=['accuracy']) return model ``` 以上代码实现了 DSAN 模型的网络结构,包括空间注意力模块和通道注意力模块。其中,空间注意力模块包括四个卷积层,每个卷积层的步长为2,用于逐渐减少特征图的大小。通道注意力模块包括两个全连接层和一个 sigmoid 激活函数,用于计算特征图中每个通道的权重。最终,将空间注意力模块和通道注意力模块结合起来,进行分类任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值