Módulo atención canal ECANet
Primero mire la estructura de su modelo:
implementación del código:
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)
En primer lugar, los datos se pasan: torch.Size([2, 3, 224, 224])
luego, a través de la agrupación promedio y = self.avg_pool(x)
, se convierte en: torch.Size([2, 3, 1, 1])
la información dimensional aquí se desmonta y se visualiza:
el método de compresión reduce la dimensión, el método de descompresión aumenta la dimensión y el método de transposición convierte la dimensión
antorcha.Tamaño ([2, 1, 3]) Los números de dimensión son 0, 1, 2 de adelante hacia atrás y -1, -2, -3 de atrás hacia adelante
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])
Finalmente, la información de la dimensión obtenida por convolución: torch.Size([2, 3, 1, 1])
en este momento, los datos son:
tensor([[[[-0.0002]],
[[ 0.0001]],
[[ 0.0010]]],
[[[ 0.0009]],
[[ 0.0028]],
[[-0.0019]]]])
Luego realice sigmoide para la normalización:
tensor([[[[0.5000]],
[[0.5000]],
[[0.5002]]],
[[[0.5002]],
[[0.5007]],
[[0.4995]]]])
y.expand_as(x)
Regrese al tamaño original realizando cálculos: torch.Size([2, 3, 224, 224])
el canal no se usa aquí.