Commit 865631be authored by A. Unique TensorFlower's avatar A. Unique TensorFlower
Browse files

Internal change

PiperOrigin-RevId: 341966519
parent b15a86fc
...@@ -296,12 +296,78 @@ MNV3EdgeTPU_BLOCK_SPECS = { ...@@ -296,12 +296,78 @@ MNV3EdgeTPU_BLOCK_SPECS = {
] ]
} }
"""
Architecture: https://arxiv.org/pdf/2008.08178.pdf
"Discovering Multi-Hardware Mobile Models via Architecture Search"
Grace Chu, Okan Arikan, Gabriel Bender, Weijun Wang,
Achille Brighton, Pieter-Jan Kindermans, Hanxiao Liu,
Berkin Akin, Suyog Gupta, and Andrew Howard
"""
MNMultiMAX_BLOCK_SPECS = {
'spec_name': 'MobileNetMultiMAX',
'block_spec_schema': ['block_fn', 'kernel_size', 'strides', 'filters',
'activation', 'expand_ratio',
'use_normalization', 'use_bias'],
'block_specs': [
('convbn', 3, 2, 32, 'relu', None, True, False),
('invertedbottleneck', 3, 2, 32, 'relu', 3., None, False),
('invertedbottleneck', 5, 2, 64, 'relu', 6., None, False),
('invertedbottleneck', 3, 1, 64, 'relu', 2., None, False),
('invertedbottleneck', 3, 1, 64, 'relu', 2., None, False),
('invertedbottleneck', 5, 2, 128, 'relu', 6., None, False),
('invertedbottleneck', 3, 1, 128, 'relu', 4., None, False),
('invertedbottleneck', 3, 1, 128, 'relu', 3., None, False),
('invertedbottleneck', 3, 1, 128, 'relu', 3., None, False),
('invertedbottleneck', 3, 1, 128, 'relu', 6., None, False),
('invertedbottleneck', 3, 1, 128, 'relu', 3., None, False),
('invertedbottleneck', 3, 2, 160, 'relu', 6., None, False),
('invertedbottleneck', 5, 1, 160, 'relu', 4., None, False),
('invertedbottleneck', 3, 1, 160, 'relu', 5., None, False),
('invertedbottleneck', 5, 1, 160, 'relu', 4., None, False),
('convbn', 1, 1, 960, 'relu', None, True, False),
('gpooling', None, None, None, None, None, None, None),
('convbn', 1, 1, 1280, 'relu', None, False, True),
]
}
MNMultiAVG_BLOCK_SPECS = {
'spec_name': 'MobileNetMultiAVG',
'block_spec_schema': ['block_fn', 'kernel_size', 'strides', 'filters',
'activation', 'expand_ratio',
'use_normalization', 'use_bias'],
'block_specs': [
('convbn', 3, 2, 32, 'relu', None, True, False),
('invertedbottleneck', 3, 2, 32, 'relu', 3., None, False),
('invertedbottleneck', 3, 1, 32, 'relu', 2., None, False),
('invertedbottleneck', 5, 2, 64, 'relu', 5., None, False),
('invertedbottleneck', 3, 1, 64, 'relu', 3., None, False),
('invertedbottleneck', 3, 1, 64, 'relu', 2., None, False),
('invertedbottleneck', 3, 1, 64, 'relu', 3., None, False),
('invertedbottleneck', 5, 2, 128, 'relu', 6., None, False),
('invertedbottleneck', 3, 1, 128, 'relu', 3., None, False),
('invertedbottleneck', 3, 1, 128, 'relu', 3., None, False),
('invertedbottleneck', 3, 1, 128, 'relu', 3., None, False),
('invertedbottleneck', 3, 1, 160, 'relu', 6., None, False),
('invertedbottleneck', 3, 1, 160, 'relu', 4., None, False),
('invertedbottleneck', 3, 2, 192, 'relu', 6., None, False),
('invertedbottleneck', 5, 1, 192, 'relu', 4., None, False),
('invertedbottleneck', 5, 1, 192, 'relu', 4., None, False),
('invertedbottleneck', 5, 1, 192, 'relu', 4., None, False),
('convbn', 1, 1, 960, 'relu', None, True, False),
('gpooling', None, None, None, None, None, None, None),
('convbn', 1, 1, 1280, 'relu', None, False, True),
]
}
SUPPORTED_SPECS_MAP = { SUPPORTED_SPECS_MAP = {
'MobileNetV1': MNV1_BLOCK_SPECS, 'MobileNetV1': MNV1_BLOCK_SPECS,
'MobileNetV2': MNV2_BLOCK_SPECS, 'MobileNetV2': MNV2_BLOCK_SPECS,
'MobileNetV3Large': MNV3Large_BLOCK_SPECS, 'MobileNetV3Large': MNV3Large_BLOCK_SPECS,
'MobileNetV3Small': MNV3Small_BLOCK_SPECS, 'MobileNetV3Small': MNV3Small_BLOCK_SPECS,
'MobileNetV3EdgeTPU': MNV3EdgeTPU_BLOCK_SPECS, 'MobileNetV3EdgeTPU': MNV3EdgeTPU_BLOCK_SPECS,
'MobileNetMultiMAX': MNMultiMAX_BLOCK_SPECS,
'MobileNetMultiAVG': MNMultiAVG_BLOCK_SPECS,
} }
......
...@@ -26,9 +26,15 @@ from official.vision.beta.modeling.backbones import mobilenet ...@@ -26,9 +26,15 @@ from official.vision.beta.modeling.backbones import mobilenet
class MobileNetTest(parameterized.TestCase, tf.test.TestCase): class MobileNetTest(parameterized.TestCase, tf.test.TestCase):
@parameterized.parameters('MobileNetV1', 'MobileNetV2', @parameterized.parameters(
'MobileNetV3Large', 'MobileNetV3Small', 'MobileNetV1',
'MobileNetV3EdgeTPU') 'MobileNetV2',
'MobileNetV3Large',
'MobileNetV3Small',
'MobileNetV3EdgeTPU',
'MobileNetMultiAVG',
'MobileNetMultiMAX',
)
def test_serialize_deserialize(self, model_id): def test_serialize_deserialize(self, model_id):
# Create a network object that sets all of its config options. # Create a network object that sets all of its config options.
kwargs = dict( kwargs = dict(
...@@ -62,9 +68,18 @@ class MobileNetTest(parameterized.TestCase, tf.test.TestCase): ...@@ -62,9 +68,18 @@ class MobileNetTest(parameterized.TestCase, tf.test.TestCase):
self.assertAllEqual(network.get_config(), new_network.get_config()) self.assertAllEqual(network.get_config(), new_network.get_config())
@parameterized.parameters( @parameterized.parameters(
itertools.product((1, 3), itertools.product(
('MobileNetV1', 'MobileNetV2', 'MobileNetV3Large', [1, 3],
'MobileNetV3Small', 'MobileNetV3EdgeTPU'))) [
'MobileNetV1',
'MobileNetV2',
'MobileNetV3Large',
'MobileNetV3Small',
'MobileNetV3EdgeTPU',
'MobileNetMultiAVG',
'MobileNetMultiMAX',
],
))
def test_input_specs(self, input_dim, model_id): def test_input_specs(self, input_dim, model_id):
"""Test different input feature dimensions.""" """Test different input feature dimensions."""
tf.keras.backend.set_image_data_format('channels_last') tf.keras.backend.set_image_data_format('channels_last')
...@@ -75,182 +90,88 @@ class MobileNetTest(parameterized.TestCase, tf.test.TestCase): ...@@ -75,182 +90,88 @@ class MobileNetTest(parameterized.TestCase, tf.test.TestCase):
inputs = tf.keras.Input(shape=(128, 128, input_dim), batch_size=1) inputs = tf.keras.Input(shape=(128, 128, input_dim), batch_size=1)
_ = network(inputs) _ = network(inputs)
@parameterized.parameters(32, 224) @parameterized.parameters(
def test_mobilenet_v1_creation(self, input_size): itertools.product(
"""Test creation of EfficientNet family models.""" [
tf.keras.backend.set_image_data_format('channels_last') 'MobileNetV1',
'MobileNetV2',
network = mobilenet.MobileNet(model_id='MobileNetV1', 'MobileNetV3Large',
filter_size_scale=0.75) 'MobileNetV3Small',
'MobileNetV3EdgeTPU',
inputs = tf.keras.Input(shape=(input_size, input_size, 3), batch_size=1) 'MobileNetMultiAVG',
endpoints = network(inputs) 'MobileNetMultiMAX',
],
self.assertAllEqual([1, input_size / 2 ** 1, input_size / 2 ** 1, 24], [32, 224],
endpoints[1].shape.as_list()) ))
self.assertAllEqual([1, input_size / 2 ** 1, input_size / 2 ** 1, 48], def test_mobilenet_creation(self, model_id,
endpoints[2].shape.as_list()) input_size):
self.assertAllEqual([1, input_size / 2 ** 2, input_size / 2 ** 2, 96], """Test creation of MobileNet family models."""
endpoints[3].shape.as_list())
self.assertAllEqual([1, input_size / 2 ** 2, input_size / 2 ** 2, 96],
endpoints[4].shape.as_list())
@parameterized.parameters(32, 224)
def test_mobilenet_v2_creation(self, input_size):
"""Test creation of EfficientNet family models."""
tf.keras.backend.set_image_data_format('channels_last')
network = mobilenet.MobileNet(model_id='MobileNetV2',
filter_size_scale=1.0)
inputs = tf.keras.Input(shape=(input_size, input_size, 3), batch_size=1)
endpoints = network(inputs)
self.assertAllEqual([1, input_size / 2 ** 1, input_size / 2 ** 1, 32],
endpoints[1].shape.as_list())
self.assertAllEqual([1, input_size / 2 ** 1, input_size / 2 ** 1, 16],
endpoints[2].shape.as_list())
self.assertAllEqual([1, input_size / 2 ** 2, input_size / 2 ** 2, 24],
endpoints[3].shape.as_list())
self.assertAllEqual([1, input_size / 2 ** 2, input_size / 2 ** 2, 24],
endpoints[4].shape.as_list())
@parameterized.parameters(32, 224)
def test_mobilenet_v3_small_creation(self, input_size):
"""Test creation of EfficientNet family models."""
tf.keras.backend.set_image_data_format('channels_last')
network = mobilenet.MobileNet(model_id='MobileNetV3Small',
filter_size_scale=0.75)
inputs = tf.keras.Input(shape=(input_size, input_size, 3), batch_size=1)
endpoints = network(inputs)
self.assertAllEqual([1, input_size / 2 ** 1, input_size / 2 ** 1, 16],
endpoints[1].shape.as_list())
self.assertAllEqual([1, input_size / 2 ** 2, input_size / 2 ** 2, 16],
endpoints[2].shape.as_list())
self.assertAllEqual([1, input_size / 2 ** 3, input_size / 2 ** 3, 24],
endpoints[3].shape.as_list())
self.assertAllEqual([1, input_size / 2 ** 3, input_size / 2 ** 3, 24],
endpoints[4].shape.as_list())
@parameterized.parameters(32, 224)
def test_mobilenet_v3_large_creation(self, input_size):
"""Test creation of EfficientNet family models."""
tf.keras.backend.set_image_data_format('channels_last') tf.keras.backend.set_image_data_format('channels_last')
network = mobilenet.MobileNet(model_id='MobileNetV3Large', mobilenet_layers = {
filter_size_scale=0.75) # The stride (relative to input) and number of filters
# of first few layers for filter_size_scale = 0.75
inputs = tf.keras.Input(shape=(input_size, input_size, 3), batch_size=1) 'MobileNetV1': [(1, 24), (1, 48), (2, 96), (2, 96)],
endpoints = network(inputs) 'MobileNetV2': [(1, 24), (1, 16), (2, 24), (2, 24)],
'MobileNetV3Small': [(1, 16), (2, 16), (3, 24), (3, 24)],
self.assertAllEqual([1, input_size / 2 ** 1, input_size / 2 ** 1, 16], 'MobileNetV3Large': [(1, 16), (1, 16), (2, 24), (2, 24)],
endpoints[1].shape.as_list()) 'MobileNetV3EdgeTPU': [(1, 24), (1, 16), (2, 24), (2, 24)],
self.assertAllEqual([1, input_size / 2 ** 1, input_size / 2 ** 1, 16], 'MobileNetMultiMAX': [(1, 24), (2, 24), (3, 48), (3, 48)],
endpoints[2].shape.as_list()) 'MobileNetMultiAVG': [(1, 24), (2, 24), (2, 24), (3, 48)],
self.assertAllEqual([1, input_size / 2 ** 2, input_size / 2 ** 2, 24], }
endpoints[3].shape.as_list())
self.assertAllEqual([1, input_size / 2 ** 2, input_size / 2 ** 2, 24],
endpoints[4].shape.as_list())
@parameterized.parameters(32, 224)
def test_mobilenet_v3_edgetpu_creation(self, input_size):
"""Test creation of EfficientNet family models."""
tf.keras.backend.set_image_data_format('channels_last')
network = mobilenet.MobileNet(model_id='MobileNetV3EdgeTPU', network = mobilenet.MobileNet(model_id=model_id,
filter_size_scale=0.75) filter_size_scale=0.75)
inputs = tf.keras.Input(shape=(input_size, input_size, 3), batch_size=1) inputs = tf.keras.Input(shape=(input_size, input_size, 3), batch_size=1)
endpoints = network(inputs) endpoints = network(inputs)
self.assertAllEqual([1, input_size / 2 ** 1, input_size / 2 ** 1, 24], for idx, (stride, num_filter) in enumerate(mobilenet_layers[model_id]):
endpoints[1].shape.as_list()) self.assertAllEqual(
self.assertAllEqual([1, input_size / 2 ** 1, input_size / 2 ** 1, 16], [1, input_size / 2 ** stride, input_size / 2 ** stride, num_filter],
endpoints[2].shape.as_list()) endpoints[idx+1].shape.as_list())
self.assertAllEqual([1, input_size / 2 ** 2, input_size / 2 ** 2, 24],
endpoints[3].shape.as_list())
self.assertAllEqual([1, input_size / 2 ** 2, input_size / 2 ** 2, 24],
endpoints[4].shape.as_list())
@parameterized.parameters(1.0, 0.75)
def test_mobilenet_v1_scaling(self, filter_size_scale):
mobilenet_v1_params = {
1.0: 3228864,
0.75: 1832976
}
input_size = 224 @parameterized.parameters(
network = mobilenet.MobileNet(model_id='MobileNetV1', itertools.product(
filter_size_scale=filter_size_scale) [
self.assertEqual(network.count_params(), 'MobileNetV1',
mobilenet_v1_params[filter_size_scale]) 'MobileNetV2',
'MobileNetV3Large',
inputs = tf.keras.Input(shape=(input_size, input_size, 3), batch_size=1) 'MobileNetV3Small',
_ = network(inputs) 'MobileNetV3EdgeTPU',
'MobileNetMultiAVG',
@parameterized.parameters(1.0, 0.75) 'MobileNetMultiMAX',
def test_mobilenet_v2_scaling(self, filter_size_scale): ],
mobilenet_v2_params = { [1.0, 0.75],
1.0: 2257984, ))
0.75: 1382064 def test_mobilenet_scaling(self, model_id,
} filter_size_scale):
"""Test for creation of a MobileNet classifier."""
input_size = 224 mobilenet_params = {
network = mobilenet.MobileNet(model_id='MobileNetV2', ('MobileNetV1', 1.0): 3228864,
filter_size_scale=filter_size_scale) ('MobileNetV1', 0.75): 1832976,
self.assertEqual(network.count_params(), ('MobileNetV2', 1.0): 2257984,
mobilenet_v2_params[filter_size_scale]) ('MobileNetV2', 0.75): 1382064,
('MobileNetV3Large', 1.0): 4226432,
inputs = tf.keras.Input(shape=(input_size, input_size, 3), batch_size=1) ('MobileNetV3Large', 0.75): 2731616,
_ = network(inputs) ('MobileNetV3Small', 1.0): 1529968,
('MobileNetV3Small', 0.75): 1026552,
@parameterized.parameters(1.0, 0.75) ('MobileNetV3EdgeTPU', 1.0): 2849312,
def test_mobilenet_v3_large_scaling(self, filter_size_scale): ('MobileNetV3EdgeTPU', 0.75): 1737288,
mobilenet_v3_large_params = { ('MobileNetMultiAVG', 1.0): 3700576,
1.0: 4226432, ('MobileNetMultiAVG', 0.75): 2345864,
0.75: 2731616 ('MobileNetMultiMAX', 1.0): 3170720,
} ('MobileNetMultiMAX', 0.75): 2041976,
input_size = 224
network = mobilenet.MobileNet(model_id='MobileNetV3Large',
filter_size_scale=filter_size_scale)
self.assertEqual(network.count_params(),
mobilenet_v3_large_params[filter_size_scale])
inputs = tf.keras.Input(shape=(input_size, input_size, 3), batch_size=1)
_ = network(inputs)
@parameterized.parameters(1.0, 0.75)
def test_mobilenet_v3_small_scaling(self, filter_size_scale):
mobilenet_v3_small_params = {
1.0: 1529968,
0.75: 1026552
} }
input_size = 224 input_size = 224
network = mobilenet.MobileNet(model_id='MobileNetV3Small', network = mobilenet.MobileNet(model_id=model_id,
filter_size_scale=filter_size_scale) filter_size_scale=filter_size_scale)
self.assertEqual(network.count_params(), self.assertEqual(network.count_params(),
mobilenet_v3_small_params[filter_size_scale]) mobilenet_params[(model_id, filter_size_scale)])
inputs = tf.keras.Input(shape=(input_size, input_size, 3), batch_size=1) inputs = tf.keras.Input(shape=(input_size, input_size, 3), batch_size=1)
_ = network(inputs) _ = network(inputs)
@parameterized.parameters(1.0, 0.75) if __name__ == '__main__':
def test_mobilenet_v3_edgetpu_scaling(self, filter_size_scale): tf.test.main()
mobilenet_v3_edgetpu_params = {
1.0: 2849312,
0.75: 1737288
}
input_size = 224
network = mobilenet.MobileNet(model_id='MobileNetV3EdgeTPU',
filter_size_scale=filter_size_scale)
self.assertEqual(network.count_params(),
mobilenet_v3_edgetpu_params[filter_size_scale])
inputs = tf.keras.Input(shape=(input_size, input_size, 3), batch_size=1)
_ = network(inputs)
...@@ -84,7 +84,9 @@ class ClassificationNetworkTest(parameterized.TestCase, tf.test.TestCase): ...@@ -84,7 +84,9 @@ class ClassificationNetworkTest(parameterized.TestCase, tf.test.TestCase):
'MobileNetV2', 'MobileNetV2',
'MobileNetV3Large', 'MobileNetV3Large',
'MobileNetV3Small', 'MobileNetV3Small',
'MobileNetV3EdgeTPU' 'MobileNetV3EdgeTPU',
'MobileNetMultiAVG',
'MobileNetMultiMAX',
], ],
filter_size_scale=[1.0, 0.75], filter_size_scale=[1.0, 0.75],
)) ))
...@@ -102,6 +104,10 @@ class ClassificationNetworkTest(parameterized.TestCase, tf.test.TestCase): ...@@ -102,6 +104,10 @@ class ClassificationNetworkTest(parameterized.TestCase, tf.test.TestCase):
('MobileNetV3Small', 0.75): 2052577, ('MobileNetV3Small', 0.75): 2052577,
('MobileNetV3EdgeTPU', 1.0): 4131593, ('MobileNetV3EdgeTPU', 1.0): 4131593,
('MobileNetV3EdgeTPU', 0.75): 3019569, ('MobileNetV3EdgeTPU', 0.75): 3019569,
('MobileNetMultiAVG', 1.0): 4982857,
('MobileNetMultiAVG', 0.75): 3628145,
('MobileNetMultiMAX', 1.0): 4453001,
('MobileNetMultiMAX', 0.75): 3324257,
} }
inputs = np.random.rand(2, 224, 224, 3) inputs = np.random.rand(2, 224, 224, 3)
......
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