Decoder for multi-resolution encodings.
| 14 | |
| 15 | |
| 16 | class MultiresConvDecoder(nn.Module): |
| 17 | """Decoder for multi-resolution encodings.""" |
| 18 | |
| 19 | def __init__( |
| 20 | self, |
| 21 | dims_encoder: Iterable[int], |
| 22 | dim_decoder: int, |
| 23 | ): |
| 24 | """Initialize multiresolution convolutional decoder. |
| 25 | |
| 26 | Args: |
| 27 | ---- |
| 28 | dims_encoder: Expected dims at each level from the encoder. |
| 29 | dim_decoder: Dim of decoder features. |
| 30 | |
| 31 | """ |
| 32 | super().__init__() |
| 33 | self.dims_encoder = list(dims_encoder) |
| 34 | self.dim_decoder = dim_decoder |
| 35 | self.dim_out = dim_decoder |
| 36 | |
| 37 | num_encoders = len(self.dims_encoder) |
| 38 | |
| 39 | # At the highest resolution, i.e. level 0, we apply projection w/ 1x1 convolution |
| 40 | # when the dimensions mismatch. Otherwise we do not do anything, which is |
| 41 | # the default behavior of monodepth. |
| 42 | conv0 = ( |
| 43 | nn.Conv2d(self.dims_encoder[0], dim_decoder, kernel_size=1, bias=False) |
| 44 | if self.dims_encoder[0] != dim_decoder |
| 45 | else nn.Identity() |
| 46 | ) |
| 47 | |
| 48 | convs = [conv0] |
| 49 | for i in range(1, num_encoders): |
| 50 | convs.append( |
| 51 | nn.Conv2d( |
| 52 | self.dims_encoder[i], |
| 53 | dim_decoder, |
| 54 | kernel_size=3, |
| 55 | stride=1, |
| 56 | padding=1, |
| 57 | bias=False, |
| 58 | ) |
| 59 | ) |
| 60 | |
| 61 | self.convs = nn.ModuleList(convs) |
| 62 | |
| 63 | fusions = [] |
| 64 | for i in range(num_encoders): |
| 65 | fusions.append( |
| 66 | FeatureFusionBlock2d( |
| 67 | num_features=dim_decoder, |
| 68 | deconv=(i != 0), |
| 69 | batch_norm=False, |
| 70 | ) |
| 71 | ) |
| 72 | self.fusions = nn.ModuleList(fusions) |
| 73 |
no outgoing calls
no test coverage detected