Fuses the information from the Fast pathway to the Slow pathway. Given the tensors from Slow pathway and Fast pathway, fuse information from Fast to Slow, then return the fused tensors from Slow and Fast pathway in order.
| 94 | |
| 95 | |
| 96 | class FuseFastToSlow(nn.Module): |
| 97 | """ |
| 98 | Fuses the information from the Fast pathway to the Slow pathway. Given the |
| 99 | tensors from Slow pathway and Fast pathway, fuse information from Fast to |
| 100 | Slow, then return the fused tensors from Slow and Fast pathway in order. |
| 101 | """ |
| 102 | |
| 103 | def __init__( |
| 104 | self, |
| 105 | dim_in, |
| 106 | fusion_conv_channel_ratio, |
| 107 | fusion_kernel, |
| 108 | alpha, |
| 109 | eps=1e-5, |
| 110 | bn_mmt=0.1, |
| 111 | inplace_relu=True, |
| 112 | norm_module=nn.BatchNorm3d, |
| 113 | ): |
| 114 | """ |
| 115 | Args: |
| 116 | dim_in (int): the channel dimension of the input. |
| 117 | fusion_conv_channel_ratio (int): channel ratio for the convolution |
| 118 | used to fuse from Fast pathway to Slow pathway. |
| 119 | fusion_kernel (int): kernel size of the convolution used to fuse |
| 120 | from Fast pathway to Slow pathway. |
| 121 | alpha (int): the frame rate ratio between the Fast and Slow pathway. |
| 122 | eps (float): epsilon for batch norm. |
| 123 | bn_mmt (float): momentum for batch norm. Noted that BN momentum in |
| 124 | PyTorch = 1 - BN momentum in Caffe2. |
| 125 | inplace_relu (bool): if True, calculate the relu on the original |
| 126 | input without allocating new memory. |
| 127 | norm_module (nn.Module): nn.Module for the normalization layer. The |
| 128 | default is nn.BatchNorm3d. |
| 129 | """ |
| 130 | super(FuseFastToSlow, self).__init__() |
| 131 | self.conv_f2s = nn.Conv3d( |
| 132 | dim_in, |
| 133 | dim_in * fusion_conv_channel_ratio, |
| 134 | kernel_size=[fusion_kernel, 1, 1], |
| 135 | stride=[alpha, 1, 1], |
| 136 | padding=[fusion_kernel // 2, 0, 0], |
| 137 | bias=False, |
| 138 | ) |
| 139 | self.bn = norm_module( |
| 140 | num_features=dim_in * fusion_conv_channel_ratio, |
| 141 | eps=eps, |
| 142 | momentum=bn_mmt, |
| 143 | ) |
| 144 | self.relu = nn.ReLU(inplace_relu) |
| 145 | |
| 146 | def forward(self, x): |
| 147 | x_s = x[0] |
| 148 | x_f = x[1] |
| 149 | fuse = self.conv_f2s(x_f) |
| 150 | fuse = self.bn(fuse) |
| 151 | fuse = self.relu(fuse) |
| 152 | x_s_fuse = torch.cat([x_s, fuse], 1) |
| 153 | return [x_s_fuse, x_f] |