The kernel size for the layers in efficientnet changes and can be an odd or even number. If the kernel size is an odd number, margins for padding can be calculated with kernel_size // 2
, however if the kernel size is an odd number this won't work.
ConvLayerDynamicPadding
expands the fastai ConvLayer
function with an extra padding layer, ensuring padding is sufficient regardless of kernel size.
ConvLayerDynamicPadding(ni=3, nf=64, ks=(2,7,5), ndim=3)(torch.randn(1, 3, 10, 10, 10)).size()
EfficientNet uses DopConnect and DropOut. DropConnect needs to be implemented as Module to work with nn.Sequential
.
See paper about stochastic depth for the reason drop connect and skip connections are used.
DropConnect(0.5)(torch.randn(16, 1, 1, 1, 1)).flatten()
Mobile Inverted Residual Bottleneck Block is the main block of convolutional layers in each EfficientNet.
The Mobile Inverted Residual Bottleneck Block is the main building block of the efficientnet. It is based on this paper: https://arxiv.org/pdf/1801.04381.pdf
MBConvBlock(80, 112, 4, 1, 0.25, True, 6)(torch.randn(1, 80, 10, 14, 14)).size()
EfficientNet(num_classes = 2)(torch.randn(1, 3, 10, 224, 224))
Calling models follows the torchvision
approach taken for ResNets. We have private function _efficientnet
which passes the building arguments to the EfficientNet
class and a single function for each class (efficientnet_b0
, efficientnet_b1
) which will give the respective model.
Overview of building arguments for the different efficientnets. Keep in mind, that image size is important for the model. Progressize resizing with efficiennets must be done very carefull.
model name | width_coeff | depth_coeff | image_size | dropout |
---|---|---|---|---|
'efficientnet_b0' | 1.0 | 1.0 | 224 | 0.2 |
'efficientnet_b1' | 1.0 | 1.1 | 240 | 0.2 |
'efficientnet_b2' | 1.1 | 1.2 | 260 | 0.3 |
'efficientnet_b3' | 1.2 | 1.4 | 300 | 0.3 |
'efficientnet_b4' | 1.4 | 1.8 | 380 | 0.4 |
'efficientnet_b5' | 1.6 | 2.2 | 456 | 0.4 |
'efficientnet_b6' | 1.8 | 2.6 | 528 | 0.5 |
'efficientnet_b7' | 2.0 | 3.1 | 600 | 0.5 |
'efficientnet_b8' | 2.2 | 3.6 | 672 | 0.5 |
'efficientnet_l2' | 4.3 | 5.3 | 800 | 0.5 |
efficientnet_b0(num_classes = 2)(torch.randn(1, 3, 10, 224, 224))