Further style fixes in mobilenet

Esse commit está contido em:
Francois Chollet
2017-06-27 15:45:51 -07:00
commit 9a4598da50
+73 -55
Ver Arquivo
@@ -3,40 +3,47 @@
MobileNet is a general architecture and can be used for multiple use cases.
Depending on the use case, it can use different input layer size and
different width factors. This allows different width models to reduce
the number of multiply-adds and thereby reduce inference cost on mobile devices.
the number of multiply-adds and thereby
reduce inference cost on mobile devices.
MobileNets support any input size greater than 32 x 32, with larger image sizes
offering better performance. The number of parameters and number of multiply-adds
can be modified by using the `alpha` parameter, which increases/decreases the number
of filters in each layer. By altering the image size and `alpha` parameter,
offering better performance.
The number of parameters and number of multiply-adds
can be modified by using the `alpha` parameter,
which increases/decreases the number of filters in each layer.
By altering the image size and `alpha` parameter,
all 16 models from the paper can be built, with ImageNet weights provided.
The paper demonstrates the performance of MobileNets using `alpha` values of
1.0 (also called 100 % MobileNet), 0.75, 0.5 and 0.25. For each of these `alpha`
values, weights for 4 different input image sizes are provided (224, 192, 160, 128).
1.0 (also called 100 % MobileNet), 0.75, 0.5 and 0.25.
For each of these `alpha` values, weights for 4 different input image sizes
are provided (224, 192, 160, 128).
The following table describes the size and accuracy of the 100% MobileNet on size 224 x 224
-----------------------------------------------------------------------------------------
Width Multiplier (alpha) | ImageNet Accuracy | Million Multiply-Adds | Million Parameters
-----------------------------------------------------------------------------------------
| 1.0 MobileNet-224 | 70.6 % | 529 | 4.2 |
| 0.75 MobileNet-224 | 68.4 % | 325 | 2.6 |
| 0.50 MobileNet-224 | 63.7 % | 149 | 1.3 |
| 0.25 MobileNet-224 | 50.6 % | 41 | 0.5 |
-----------------------------------------------------------------------------------------
The following table describes the size and accuracy of the 100% MobileNet
on size 224 x 224:
----------------------------------------------------------------------------
Width Multiplier (alpha) | ImageNet Acc | Multiply-Adds (M) | Params (M)
----------------------------------------------------------------------------
| 1.0 MobileNet-224 | 70.6 % | 529 | 4.2 |
| 0.75 MobileNet-224 | 68.4 % | 325 | 2.6 |
| 0.50 MobileNet-224 | 63.7 % | 149 | 1.3 |
| 0.25 MobileNet-224 | 50.6 % | 41 | 0.5 |
----------------------------------------------------------------------------
The following table describes the performance of the 100 % MobileNet on various input sizes
-----------------------------------------------------------------------------------------
Resolution | ImageNet Accuracy | Million Multiply-Adds | Million Parameters
-----------------------------------------------------------------------------------------
| 1.0 MobileNet-224 | 70.6 % | 529 | 4.2 |
| 1.0 MobileNet-192 | 69.1 % | 529 | 4.2 |
| 1.0 MobileNet-160 | 67.2 % | 529 | 4.2 |
| 1.0 MobileNet-128 | 64.4 % | 529 | 4.2 |
-----------------------------------------------------------------------------------------
The following table describes the performance of
the 100 % MobileNet on various input sizes:
------------------------------------------------------------------------
Resolution | ImageNet Acc | Multiply-Adds (M) | Params (M)
------------------------------------------------------------------------
| 1.0 MobileNet-224 | 70.6 % | 529 | 4.2 |
| 1.0 MobileNet-192 | 69.1 % | 529 | 4.2 |
| 1.0 MobileNet-160 | 67.2 % | 529 | 4.2 |
| 1.0 MobileNet-128 | 64.4 % | 529 | 4.2 |
------------------------------------------------------------------------
The weights for all 16 models are obtained and translated from Tensorflow checkpoints
found in https://github.com/tensorflow/models/blob/master/slim/nets/mobilenet_v1.md
The weights for all 16 models are obtained and translated
from Tensorflow checkpoints found at
https://github.com/tensorflow/models/blob/master/slim/nets/mobilenet_v1.md
# Reference
- [MobileNets: Efficient Convolutional Neural Networks for
@@ -353,7 +360,8 @@ def MobileNet(input_shape=None,
if K.backend() != 'tensorflow':
raise RuntimeError('Only Tensorflow backend is currently supported, '
'as other backends do not support depthwise convolution.')
'as other backends do not support '
'depthwise convolution.')
if weights not in {'imagenet', None}:
raise ValueError('The `weights` argument should be either '
@@ -370,7 +378,8 @@ def MobileNet(input_shape=None,
'depth multiplier must be 1')
if alpha not in [0.25, 0.50, 0.75, 1.0]:
raise ValueError('If imagenet weights are being loaded, alpha can be one of'
raise ValueError('If imagenet weights are being loaded, '
'alpha can be one of'
'`0.25`, `0.50`, `0.75` or `1.0` only.')
rows, cols = (0, 1) if K.image_data_format() == 'channels_last' else (1, 2)
@@ -399,8 +408,8 @@ def MobileNet(input_shape=None,
old_data_format = None
# Determine proper input shape. Note, include_top is False by default, as
# input shape can be anything larger than 32x32 and the same number of parameters
# will be used.
# input shape can be anything larger than 32x32
# and the same number of parameters will be used.
input_shape = _obtain_input_shape(input_shape,
default_size=224,
min_size=32,
@@ -416,23 +425,27 @@ def MobileNet(input_shape=None,
img_input = input_tensor
x = _conv_block(img_input, 32, alpha, strides=(2, 2))
x = _depthwise_conv_block(x, 64, alpha, depth_multiplier, id=1)
x = _depthwise_conv_block(x, 64, alpha, depth_multiplier, block_id=1)
x = _depthwise_conv_block(x, 128, alpha, depth_multiplier, strides=(2, 2), id=2)
x = _depthwise_conv_block(x, 128, alpha, depth_multiplier, id=3)
x = _depthwise_conv_block(x, 128, alpha, depth_multiplier,
strides=(2, 2), block_id=2)
x = _depthwise_conv_block(x, 128, alpha, depth_multiplier, block_id=3)
x = _depthwise_conv_block(x, 256, alpha, depth_multiplier, strides=(2, 2), id=4)
x = _depthwise_conv_block(x, 256, alpha, depth_multiplier, id=5)
x = _depthwise_conv_block(x, 256, alpha, depth_multiplier,
strides=(2, 2), block_id=4)
x = _depthwise_conv_block(x, 256, alpha, depth_multiplier, block_id=5)
x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, strides=(2, 2), id=6)
x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, id=7)
x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, id=8)
x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, id=9)
x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, id=10)
x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, id=11)
x = _depthwise_conv_block(x, 512, alpha, depth_multiplier,
strides=(2, 2), block_id=6)
x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=7)
x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=8)
x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=9)
x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=10)
x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=11)
x = _depthwise_conv_block(x, 1024, alpha, depth_multiplier, strides=(2, 2), id=12)
x = _depthwise_conv_block(x, 1024, alpha, depth_multiplier, id=13)
x = _depthwise_conv_block(x, 1024, alpha, depth_multiplier,
strides=(2, 2), block_id=12)
x = _depthwise_conv_block(x, 1024, alpha, depth_multiplier, block_id=13)
if include_top:
if K.image_data_format() == 'channels_first':
@@ -443,7 +456,8 @@ def MobileNet(input_shape=None,
x = GlobalAveragePooling2D()(x)
x = Reshape(shape, name='reshape_1')(x)
x = Dropout(dropout, name='dropout')(x)
x = Convolution2D(classes, (1, 1), padding='same', name='conv_preds')(x)
x = Convolution2D(classes, (1, 1),
padding='same', name='conv_preds')(x)
x = Activation('softmax', name='act_softmax')(x)
x = Reshape((classes,), name='reshape_2')(x)
else:
@@ -543,6 +557,9 @@ def _conv_block(input, filters, alpha, kernel=(3, 3), strides=(1, 1)):
or 4D tensor with shape:
`(samples, new_rows, new_cols, filters)` if data_format='channels_last'.
`rows` and `cols` values might have changed due to stride.
# Returns
Output tensor of block.
"""
channel_axis = 1 if K.image_data_format() == 'channels_first' else -1
filters = int(filters * alpha)
@@ -552,13 +569,11 @@ def _conv_block(input, filters, alpha, kernel=(3, 3), strides=(1, 1)):
strides=strides,
name='conv1')(input)
x = BatchNormalization(axis=channel_axis, name='conv1_bn')(x)
x = Activation(relu6, name='conv1_relu')(x)
return x
return Activation(relu6, name='conv1_relu')(x)
def _depthwise_conv_block(input, pointwise_conv_filters, alpha,
depth_multiplier=1, strides=(1, 1), id=1):
depth_multiplier=1, strides=(1, 1), block_id=1):
"""Adds a depthwise convolution block.
A depthwise convolution block consists of a depthwise conv,
@@ -588,7 +603,7 @@ def _depthwise_conv_block(input, pointwise_conv_filters, alpha,
all spatial dimensions.
Specifying any stride value != 1 is incompatible with specifying
any `dilation_rate` value != 1.
id: Integer, a unique identification designating the block number.
block_id: Integer, a unique identification designating the block number.
# Input shape
4D tensor with shape:
@@ -602,6 +617,9 @@ def _depthwise_conv_block(input, pointwise_conv_filters, alpha,
or 4D tensor with shape:
`(batch, new_rows, new_cols, filters)` if data_format='channels_last'.
`rows` and `cols` values might have changed due to stride.
# Returns
Output tensor of block.
"""
channel_axis = 1 if K.image_data_format() == 'channels_first' else -1
pointwise_conv_filters = int(pointwise_conv_filters * alpha)
@@ -611,14 +629,14 @@ def _depthwise_conv_block(input, pointwise_conv_filters, alpha,
depth_multiplier=depth_multiplier,
strides=strides,
use_bias=False,
name='conv_dw_%d' % id)(input)
x = BatchNormalization(axis=channel_axis, name='conv_dw_%d_bn' % id)(x)
x = Activation(relu6, name='conv_dw_%d_relu' % id)(x)
name='conv_dw_%d' % block_id)(input)
x = BatchNormalization(axis=channel_axis, name='conv_dw_%d_bn' % block_id)(x)
x = Activation(relu6, name='conv_dw_%d_relu' % block_id)(x)
x = Convolution2D(pointwise_conv_filters, (1, 1),
padding='same',
use_bias=False,
strides=(1, 1),
name='conv_pw_%d' % id)(x)
x = BatchNormalization(axis=channel_axis, name='conv_pw_%d_bn' % id)(x)
return Activation(relu6, name='conv_pw_%d_relu' % id)(x)
name='conv_pw_%d' % block_id)(x)
x = BatchNormalization(axis=channel_axis, name='conv_pw_%d_bn' % block_id)(x)
return Activation(relu6, name='conv_pw_%d_relu' % block_id)(x)