주의 메커니즘 학습 기록

ECANet 채널 어텐션 모듈

먼저 모델 구조:
여기에 이미지 설명 삽입
코드 구현을 살펴보십시오.
여기에 이미지 설명 삽입

import torch
from torch import nn
class eca_layer(nn.Module):
    def __init__(self, channel, k_size=3):
        super(eca_layer, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.conv = nn.Conv1d(1, 1, kernel_size=k_size, padding=(k_size - 1) // 2, bias=False)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        y = self.avg_pool(x)
        y = self.conv(y.squeeze(-1).transpose(-1, -2)).transpose(-1, -2).unsqueeze(-1)
        y = self.sigmoid(y)
        return x * y.expand_as(x)


model = eca_layer(256)
data = torch.randn((2, 3, 224, 224))
feature = model(data)
print(model)

먼저 데이터가 전달됩니다. torch.Size([2, 3, 224, 224])
그런 다음 평균 풀링을 통해 다음과 y = self.avg_pool(x)같이 됩니다. torch.Size([2, 3, 1, 1])
여기서 차원 정보는 분해되어 표시됩니다.
스퀴즈 방법은 차원을 줄이고, 언스퀴즈 방법은 차원을 늘리고, 전치 방법은 차원을 변환합니다.
크기 ([2, 1, 3]) 치수 번호는 앞에서 뒤로 0, 1, 2, 뒤에서 앞으로 -1, -2, -3입니다.

y = self.avg_pool(x)#torch.Size([2, 3, 1, 1])
y=y.squeeze(-1) #torch.Size([2, 3, 1])
y=y.transpose(-1, -2)#torch.Size([2, 1, 3])
y = self.conv(y)#torch.Size([2, 1, 3])
y=y.transpose(-1, -2)#torch.Size([2, 3, 1])
y=y.unsqueeze(-1)#torch.Size([2, 3, 1, 1])
y = self.sigmoid(y)#torch.Size([2, 3, 1, 1])
return x * y.expand_as(x)#torch.Size([2, 3, 224, 224])

마지막으로 컨볼루션으로 얻은 차원 정보: torch.Size([2, 3, 1, 1])
이때 데이터는 다음과 같습니다.

tensor([[[[-0.0002]],
         [[ 0.0001]],
         [[ 0.0010]]],
        [[[ 0.0009]],
         [[ 0.0028]],
         [[-0.0019]]]])

그런 다음 정규화를 위해 시그모이드를 수행합니다.

tensor([[[[0.5000]],
         [[0.5000]],
         [[0.5002]]],
        [[[0.5002]],
         [[0.5007]],
         [[0.4995]]]])

계산을 수행 하여 y.expand_as(x)원래 크기로 되돌립니다 . torch.Size([2, 3, 224, 224])
여기서는 채널이 사용되지 않습니다.

추천

출처blog.csdn.net/pengxiang1998/article/details/131001453