Commit 8350645b authored by yaysummeriscoming's avatar yaysummeriscoming Committed by Francisco Massa
Browse files

Fixed width multiplier (#1005)

* Fixed width multiplier

Layer channels are now rounded to a multiple of 8, as per the official tensorflow implementation.  I found this fix when looking through: https://github.com/d-li14/mobilenetv2.pytorch

* Channel multiple now a user configurable option

The official tensorflow slim mobilenet v2 implementation rounds the number of channels in each layer to a multiple of 8.  This is now user configurable - 1 turns off rounding

* Fixed whitespace error

Fixed error: ./torchvision/models/mobilenet.py:152:1: W293 blank line contains whitespace
parent d293c4c5
......@@ -10,6 +10,26 @@ model_urls = {
}
def _make_divisible(v, divisor, min_value=None):
"""
This function is taken from the original tf repo.
It ensures that all layers have a channel number that is divisible by 8
It can be seen here:
https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py
:param v:
:param divisor:
:param min_value:
:return:
"""
if min_value is None:
min_value = divisor
new_v = max(min_value, int(v + divisor / 2) // divisor * divisor)
# Make sure that round down does not go down by more than 10%.
if new_v < 0.9 * v:
new_v += divisor
return new_v
class ConvBNReLU(nn.Sequential):
def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1):
padding = (kernel_size - 1) // 2
......@@ -50,7 +70,17 @@ class InvertedResidual(nn.Module):
class MobileNetV2(nn.Module):
def __init__(self, num_classes=1000, width_mult=1.0, inverted_residual_setting=None):
def __init__(self, num_classes=1000, width_mult=1.0, inverted_residual_setting=None, round_nearest=8):
"""
MobileNet V2 main class
Args:
num_classes (int): Number of classes
width_mult (float): Width multiplier - adjusts number of channels in each layer by this amount
inverted_residual_setting: Network structure
round_nearest (int): Round the number of channels in each layer to be a multiple of this number
Set to 1 to turn off rounding
"""
super(MobileNetV2, self).__init__()
block = InvertedResidual
input_channel = 32
......@@ -74,12 +104,12 @@ class MobileNetV2(nn.Module):
"or a 4-element list, got {}".format(inverted_residual_setting))
# building first layer
input_channel = int(input_channel * width_mult)
self.last_channel = int(last_channel * max(1.0, width_mult))
input_channel = _make_divisible(input_channel * width_mult, round_nearest)
self.last_channel = _make_divisible(last_channel * max(1.0, width_mult), round_nearest)
features = [ConvBNReLU(3, input_channel, stride=2)]
# building inverted residual blocks
for t, c, n, s in inverted_residual_setting:
output_channel = int(c * width_mult)
output_channel = _make_divisible(c * width_mult, round_nearest)
for i in range(n):
stride = s if i == 0 else 1
features.append(block(input_channel, output_channel, stride, expand_ratio=t))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment