| 79 | |
| 80 | |
| 81 | class XceptionModule(nn.Module): |
| 82 | def __init__( |
| 83 | self, in_chs, out_chs, stride=1, dilation=1, pad_type='', |
| 84 | start_with_relu=True, no_skip=False, act_layer=nn.ReLU, norm_layer=None): |
| 85 | super(XceptionModule, self).__init__() |
| 86 | out_chs = to_3tuple(out_chs) |
| 87 | self.in_channels = in_chs |
| 88 | self.out_channels = out_chs[-1] |
| 89 | self.no_skip = no_skip |
| 90 | if not no_skip and (self.out_channels != self.in_channels or stride != 1): |
| 91 | self.shortcut = ConvBnAct( |
| 92 | in_chs, self.out_channels, 1, stride=stride, norm_layer=norm_layer, act_layer=None) |
| 93 | else: |
| 94 | self.shortcut = None |
| 95 | |
| 96 | separable_act_layer = None if start_with_relu else act_layer |
| 97 | self.stack = nn.Sequential() |
| 98 | for i in range(3): |
| 99 | if start_with_relu: |
| 100 | self.stack.add_module(f'act{i + 1}', nn.ReLU(inplace=i > 0)) |
| 101 | self.stack.add_module(f'conv{i + 1}', SeparableConv2d( |
| 102 | in_chs, out_chs[i], 3, stride=stride if i == 2 else 1, dilation=dilation, padding=pad_type, |
| 103 | act_layer=separable_act_layer, norm_layer=norm_layer)) |
| 104 | in_chs = out_chs[i] |
| 105 | |
| 106 | def forward(self, x): |
| 107 | skip = x |
| 108 | x = self.stack(x) |
| 109 | if self.shortcut is not None: |
| 110 | skip = self.shortcut(skip) |
| 111 | if not self.no_skip: |
| 112 | x = x + skip |
| 113 | return x |
| 114 | |
| 115 | |
| 116 | class XceptionAligned(nn.Module): |