1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| class RESSENet(nn.Module): """ RES-SE-CNN 完整网络 论文Table 1配置: - RES-SE-18: [2, 2, 2, 2] - RES-SE-34: [3, 4, 6, 3] - RES-SE-50: [3, 4, 6, 3] (使用Bottleneck) """ def __init__(self, block: nn.Module, layers: list, num_classes: int = 10): super(RESSENet, self).__init__() self.in_channels = 64 self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False) self.bn1 = nn.BatchNorm2d(64) self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) self.layer1 = self._make_layer(block, 64, layers[0], stride=1) self.layer2 = self._make_layer(block, 128, layers[1], stride=2) self.layer3 = self._make_layer(block, 256, layers[2], stride=2) self.layer4 = self._make_layer(block, 512, layers[3], stride=2) self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) self.fc = nn.Linear(512, num_classes) for m in self.modules(): if isinstance(m, nn.Conv2d): nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') elif isinstance(m, nn.BatchNorm2d): nn.init.constant_(m.weight, 1) nn.init.constant_(m.bias, 0) def _make_layer(self, block: nn.Module, out_channels: int, blocks: int, stride: int = 1) -> nn.Sequential: """构建RES-SE层""" layers = [] layers.append(block(self.in_channels, out_channels, stride)) self.in_channels = out_channels for _ in range(1, blocks): layers.append(block(out_channels, out_channels)) return nn.Sequential(*layers) def forward(self, x: torch.Tensor) -> torch.Tensor: """ 前向传播 Args: x: 输入图像, shape=(B, 3, 224, 224) Returns: 分类logits, shape=(B, num_classes) """ x = F.relu(self.bn1(self.conv1(x))) x = self.maxpool(x) x = self.layer1(x) x = self.layer2(x) x = self.layer3(x) x = self.layer4(x) x = self.avgpool(x) x = torch.flatten(x, 1) x = self.fc(x) return x
def resse18(num_classes: int = 10) -> RESSENet: """RES-SE-18模型""" return RESSENet(RESSEBlock, [2, 2, 2, 2], num_classes)
def resse34(num_classes: int = 10) -> RESSENet: """RES-SE-34模型 (论文主要架构)""" return RESSENet(RESSEBlock, [3, 4, 6, 3], num_classes)
|