Commit a3453999 authored by Stephen Sinclair's avatar Stephen Sinclair

New upstream version 1.0.6

parent ea00b87b
Metadata-Version: 2.1
Name: Keras_Applications
Version: 1.0.4
Version: 1.0.6
Summary: Reference implementations of popular deep learning models
Home-page: https://github.com/keras-team/keras-applications
Author: Keras Team
License: MIT
Download-URL: https://github.com/keras-team/keras-applications/tarball/1.0.4
Download-URL: https://github.com/keras-team/keras-applications/tarball/1.0.6
Description:
Keras Applications is the `applications` module of
the Keras deep learning library.
......
......@@ -33,7 +33,7 @@ The input size used was 224x224 for all models except NASNetLarge (331x331), Inc
|----------------------------------------------------------------|-------------|-------------|-------------|--------|--------|---------------------------------------------|
| [VGG16](keras_applications/vgg16.py) | 28.732 | 9.950 | 8.834 | 138.4M | 14.7M | [[paper]](https://arxiv.org/abs/1409.1556) [[tf-models]](https://github.com/tensorflow/models/blob/master/research/slim/nets/vgg.py) |
| [VGG19](keras_applications/vgg19.py) | 28.744 | 10.012 | 8.774 | 143.7M | 20.0M | [[paper]](https://arxiv.org/abs/1409.1556) [[tf-models]](https://github.com/tensorflow/models/blob/master/research/slim/nets/vgg.py) |
| [ResNet50](keras_applications/resnet50.py) | 25.296 | 7.980 | 6.852 | 25.6M | 23.6M | [[paper]](https://arxiv.org/abs/1512.03385) [[tf-models]](https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v1.py) |
| [ResNet50](keras_applications/resnet50.py) | 25.072 | 7.940 | 6.828 | 25.6M | 23.6M | [[paper]](https://arxiv.org/abs/1512.03385) [[tf-models]](https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v1.py) |
| [InceptionV3](keras_applications/inception_v3.py) | 22.102 | 6.280 | 5.038 | 23.9M | 21.8M | [[paper]](https://arxiv.org/abs/1512.00567) [[tf-models]](https://github.com/tensorflow/models/blob/master/research/slim/nets/inception_v3.py) |
| [InceptionResNetV2](keras_applications/inception_resnet_v2.py) | 19.744 | 4.748 | 3.962 | 55.9M | 54.3M | [[paper]](https://arxiv.org/abs/1602.07261) [[tf-models]](https://github.com/tensorflow/models/blob/master/research/slim/nets/inception_resnet_v2.py) |
| [Xception](keras_applications/xception.py) | 20.994 | 5.548 | 4.738 | 22.9M | 20.9M | [[paper]](https://arxiv.org/abs/1610.02357) |
......@@ -47,9 +47,9 @@ The input size used was 224x224 for all models except NASNetLarge (331x331), Inc
| [MobileNetV2(alpha=1.0)](keras_applications/mobilenet_v2.py) | 28.664 | 9.858 | 8.322 | 3.5M | 2.3M | [[paper]](https://arxiv.org/abs/1801.04381) [[tf-models]](https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet_v2.py) |
| [MobileNetV2(alpha=1.3)](keras_applications/mobilenet_v2.py) | 25.320 | 7.878 | 6.728 | 5.4M | 3.8M | [[paper]](https://arxiv.org/abs/1801.04381) [[tf-models]](https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet_v2.py) |
| [MobileNetV2(alpha=1.4)](keras_applications/mobilenet_v2.py) | 24.770 | 7.578 | 6.518 | 6.2M | 4.4M | [[paper]](https://arxiv.org/abs/1801.04381) [[tf-models]](https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet_v2.py) |
| [DenseNet121](keras_applications/densenet.py) | 25.480 | 8.022 | 6.842 | 8.1M | 7.0M | [[paper]](https://arxiv.org/abs/1608.06993) [[torch]](https://github.com/liuzhuang13/DenseNet/blob/master/models/densenet.lua) |
| [DenseNet169](keras_applications/densenet.py) | 23.926 | 6.892 | 6.140 | 14.3M | 12.6M | [[paper]](https://arxiv.org/abs/1608.06993) [[torch]](https://github.com/liuzhuang13/DenseNet/blob/master/models/densenet.lua) |
| [DenseNet201](keras_applications/densenet.py) | 22.936 | 6.542 | 5.724 | 20.2M | 18.3M | [[paper]](https://arxiv.org/abs/1608.06993) [[torch]](https://github.com/liuzhuang13/DenseNet/blob/master/models/densenet.lua) |
| [DenseNet121](keras_applications/densenet.py) | 25.028 | 7.742 | 6.522 | 8.1M | 7.0M | [[paper]](https://arxiv.org/abs/1608.06993) [[torch]](https://github.com/liuzhuang13/DenseNet/blob/master/models/densenet.lua) |
| [DenseNet169](keras_applications/densenet.py) | 23.824 | 6.824 | 5.860 | 14.3M | 12.6M | [[paper]](https://arxiv.org/abs/1608.06993) [[torch]](https://github.com/liuzhuang13/DenseNet/blob/master/models/densenet.lua) |
| [DenseNet201](keras_applications/densenet.py) | 22.680 | 6.380 | 5.466 | 20.2M | 18.3M | [[paper]](https://arxiv.org/abs/1608.06993) [[torch]](https://github.com/liuzhuang13/DenseNet/blob/master/models/densenet.lua) |
| [NASNetLarge](keras_applications/nasnet.py) | 17.502 | 3.996 | 3.412 | 93.5M | 84.9M | [[paper]](https://arxiv.org/abs/1707.07012) [[tf-models]](https://github.com/tensorflow/models/blob/master/research/slim/nets/nasnet/nasnet.py) |
| [NASNetMobile](keras_applications/nasnet.py) | 25.634 | 8.146 | 6.758 | 7.7M | 4.3M | [[paper]](https://arxiv.org/abs/1707.07012) [[tf-models]](https://github.com/tensorflow/models/blob/master/research/slim/nets/nasnet/nasnet.py) |
......
......@@ -5,35 +5,33 @@ from __future__ import division
from __future__ import print_function
_KERAS_BACKEND = None
_KERAS_ENGINE = None
_KERAS_LAYERS = None
_KERAS_MODELS = None
_KERAS_UTILS = None
def set_keras_submodules(backend=None,
engine=None,
layers=None,
models=None,
utils=None):
# TODO: remove `engine` argument after release of Keras 2.2.1.
utils=None,
engine=None):
# Deprecated, will be removed in the future.
global _KERAS_BACKEND
global _KERAS_ENGINE
global _KERAS_LAYERS
global _KERAS_MODELS
global _KERAS_UTILS
_KERAS_BACKEND = backend
_KERAS_ENGINE = engine
_KERAS_LAYERS = layers
_KERAS_MODELS = models
_KERAS_UTILS = utils
def get_keras_submodule(name):
if name not in {'backend', 'engine', 'layers', 'models', 'utils'}:
# Deprecated, will be removed in the future.
if name not in {'backend', 'layers', 'models', 'utils'}:
raise ImportError(
'Can only retrieve one of "backend", '
'"engine", "layers", "models", or "utils". '
'"layers", "models", or "utils". '
'Requested: %s' % name)
if _KERAS_BACKEND is None:
raise ImportError('You need to first `import keras` '
......@@ -49,11 +47,49 @@ def get_keras_submodule(name):
'```\n')
if name == 'backend':
return _KERAS_BACKEND
elif name == 'engine':
return _KERAS_ENGINE
elif name == 'layers':
return _KERAS_LAYERS
elif name == 'models':
return _KERAS_MODELS
elif name == 'utils':
return _KERAS_UTILS
def get_submodules_from_kwargs(kwargs):
backend = kwargs.get('backend', _KERAS_BACKEND)
layers = kwargs.get('layers', _KERAS_LAYERS)
models = kwargs.get('models', _KERAS_MODELS)
utils = kwargs.get('utils', _KERAS_UTILS)
for key in kwargs.keys():
if key not in ['backend', 'layers', 'models', 'utils']:
raise TypeError('Invalid keyword argument: %s', key)
return backend, layers, models, utils
def correct_pad(backend, inputs, kernel_size):
"""Returns a tuple for zero-padding for 2D convolution with downsampling.
# Arguments
input_size: An integer or tuple/list of 2 integers.
kernel_size: An integer or tuple/list of 2 integers.
# Returns
A tuple.
"""
img_dim = 2 if backend.image_data_format() == 'channels_first' else 1
input_size = backend.int_shape(inputs)[img_dim:(img_dim + 2)]
if isinstance(kernel_size, int):
kernel_size = (kernel_size, kernel_size)
if input_size[0] is None:
adjust = (1, 1)
else:
adjust = (1 - input_size[0] % 2, 1 - input_size[1] % 2)
correct = (kernel_size[0] // 2, kernel_size[1] // 2)
return ((correct[0] - adjust[0], correct[0]),
(correct[1] - adjust[1], correct[1]))
__version__ = '1.0.6'
......@@ -18,14 +18,7 @@ from __future__ import print_function
import os
from . import get_keras_submodule
backend = get_keras_submodule('backend')
engine = get_keras_submodule('engine')
layers = get_keras_submodule('layers')
models = get_keras_submodule('models')
keras_utils = get_keras_submodule('utils')
from . import get_submodules_from_kwargs
from . import imagenet_utils
from .imagenet_utils import decode_predictions
from .imagenet_utils import _obtain_input_shape
......@@ -53,6 +46,11 @@ DENSENET201_WEIGHT_PATH_NO_TOP = (
BASE_WEIGTHS_PATH +
'densenet201_weights_tf_dim_ordering_tf_kernels_notop.h5')
backend = None
layers = None
models = None
keras_utils = None
def dense_block(x, blocks, name):
"""A dense block.
......@@ -128,7 +126,8 @@ def DenseNet(blocks,
input_tensor=None,
input_shape=None,
pooling=None,
classes=1000):
classes=1000,
**kwargs):
"""Instantiates the DenseNet architecture.
Optionally loads weights pre-trained on ImageNet.
......@@ -147,9 +146,11 @@ def DenseNet(blocks,
to use as image input for the model.
input_shape: optional shape tuple, only to be specified
if `include_top` is False (otherwise the input shape
has to be `(224, 224, 3)` (with `channels_last` data format)
or `(3, 224, 224)` (with `channels_first` data format).
It should have exactly 3 inputs channels.
has to be `(224, 224, 3)` (with `'channels_last'` data format)
or `(3, 224, 224)` (with `'channels_first'` data format).
It should have exactly 3 inputs channels,
and width and height should be no smaller than 32.
E.g. `(200, 200, 3)` would be one valid value.
pooling: optional pooling mode for feature extraction
when `include_top` is `False`.
- `None` means that the output of the model will be
......@@ -172,6 +173,9 @@ def DenseNet(blocks,
ValueError: in case of invalid argument for `weights`,
or invalid input shape.
"""
global backend, layers, models, keras_utils
backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs)
if not (weights in {'imagenet', None} or os.path.exists(weights)):
raise ValueError('The `weights` argument should be either '
'`None` (random initialization), `imagenet` '
......@@ -185,7 +189,7 @@ def DenseNet(blocks,
# Determine proper input shape
input_shape = _obtain_input_shape(input_shape,
default_size=224,
min_size=221,
min_size=32,
data_format=backend.image_data_format(),
require_flatten=include_top,
weights=weights)
......@@ -218,6 +222,7 @@ def DenseNet(blocks,
x = layers.BatchNormalization(
axis=bn_axis, epsilon=1.001e-5, name='bn')(x)
x = layers.Activation('relu', name='relu')(x)
if include_top:
x = layers.GlobalAveragePooling2D(name='avg_pool')(x)
......@@ -231,11 +236,7 @@ def DenseNet(blocks,
# Ensure that the model takes into account
# any potential predecessors of `input_tensor`.
if input_tensor is not None:
if hasattr(keras_utils, 'get_source_inputs'):
get_source_inputs = keras_utils.get_source_inputs
else:
get_source_inputs = engine.get_source_inputs
inputs = get_source_inputs(input_tensor)
inputs = keras_utils.get_source_inputs(input_tensor)
else:
inputs = img_input
......@@ -301,11 +302,13 @@ def DenseNet121(include_top=True,
input_tensor=None,
input_shape=None,
pooling=None,
classes=1000):
classes=1000,
**kwargs):
return DenseNet([6, 12, 24, 16],
include_top, weights,
input_tensor, input_shape,
pooling, classes)
pooling, classes,
**kwargs)
def DenseNet169(include_top=True,
......@@ -313,11 +316,13 @@ def DenseNet169(include_top=True,
input_tensor=None,
input_shape=None,
pooling=None,
classes=1000):
classes=1000,
**kwargs):
return DenseNet([6, 12, 32, 32],
include_top, weights,
input_tensor, input_shape,
pooling, classes)
pooling, classes,
**kwargs)
def DenseNet201(include_top=True,
......@@ -325,14 +330,16 @@ def DenseNet201(include_top=True,
input_tensor=None,
input_shape=None,
pooling=None,
classes=1000):
classes=1000,
**kwargs):
return DenseNet([6, 12, 48, 32],
include_top, weights,
input_tensor, input_shape,
pooling, classes)
pooling, classes,
**kwargs)
def preprocess_input(x, data_format=None):
def preprocess_input(x, data_format=None, **kwargs):
"""Preprocesses a numpy array encoding a batch of images.
# Arguments
......@@ -342,7 +349,8 @@ def preprocess_input(x, data_format=None):
# Returns
Preprocessed array.
"""
return imagenet_utils.preprocess_input(x, data_format, mode='torch')
return imagenet_utils.preprocess_input(x, data_format,
mode='torch', **kwargs)
setattr(DenseNet121, '__doc__', DenseNet.__doc__)
......
......@@ -8,10 +8,7 @@ import json
import warnings
import numpy as np
from . import get_keras_submodule
backend = get_keras_submodule('backend')
keras_utils = get_keras_submodule('utils')
from . import get_submodules_from_kwargs
CLASS_INDEX = None
CLASS_INDEX_PATH = ('https://s3.amazonaws.com/deep-learning-models/'
......@@ -21,7 +18,7 @@ CLASS_INDEX_PATH = ('https://s3.amazonaws.com/deep-learning-models/'
_IMAGENET_MEAN = None
def _preprocess_numpy_input(x, data_format, mode):
def _preprocess_numpy_input(x, data_format, mode, **kwargs):
"""Preprocesses a Numpy array encoding a batch of images.
# Arguments
......@@ -41,6 +38,7 @@ def _preprocess_numpy_input(x, data_format, mode):
# Returns
Preprocessed Numpy array.
"""
backend, _, _, _ = get_submodules_from_kwargs(kwargs)
if not issubclass(x.dtype.type, np.floating):
x = x.astype(backend.floatx(), copy=False)
......@@ -95,7 +93,7 @@ def _preprocess_numpy_input(x, data_format, mode):
return x
def _preprocess_symbolic_input(x, data_format, mode):
def _preprocess_symbolic_input(x, data_format, mode, **kwargs):
"""Preprocesses a tensor encoding a batch of images.
# Arguments
......@@ -117,6 +115,8 @@ def _preprocess_symbolic_input(x, data_format, mode):
"""
global _IMAGENET_MEAN
backend, _, _, _ = get_submodules_from_kwargs(kwargs)
if mode == 'tf':
x /= 127.5
x -= 1.
......@@ -154,7 +154,7 @@ def _preprocess_symbolic_input(x, data_format, mode):
return x
def preprocess_input(x, data_format=None, mode='caffe'):
def preprocess_input(x, data_format=None, mode='caffe', **kwargs):
"""Preprocesses a tensor or Numpy array encoding a batch of images.
# Arguments
......@@ -180,19 +180,22 @@ def preprocess_input(x, data_format=None, mode='caffe'):
# Raises
ValueError: In case of unknown `data_format` argument.
"""
backend, _, _, _ = get_submodules_from_kwargs(kwargs)
if data_format is None:
data_format = backend.image_data_format()
if data_format not in {'channels_first', 'channels_last'}:
raise ValueError('Unknown data_format ' + str(data_format))
if isinstance(x, np.ndarray):
return _preprocess_numpy_input(x, data_format=data_format, mode=mode)
return _preprocess_numpy_input(x, data_format=data_format,
mode=mode, **kwargs)
else:
return _preprocess_symbolic_input(x, data_format=data_format,
mode=mode)
mode=mode, **kwargs)
def decode_predictions(preds, top=5):
def decode_predictions(preds, top=5, **kwargs):
"""Decodes the prediction of an ImageNet model.
# Arguments
......@@ -209,6 +212,9 @@ def decode_predictions(preds, top=5):
(must be 2D).
"""
global CLASS_INDEX
backend, _, _, keras_utils = get_submodules_from_kwargs(kwargs)
if len(preds.shape) != 2 or preds.shape[1] != 1000:
raise ValueError('`decode_predictions` expects '
'a batch of predictions '
......
......@@ -20,14 +20,7 @@ from __future__ import print_function
import os
from . import get_keras_submodule
backend = get_keras_submodule('backend')
engine = get_keras_submodule('engine')
layers = get_keras_submodule('layers')
models = get_keras_submodule('models')
keras_utils = get_keras_submodule('utils')
from . import get_submodules_from_kwargs
from . import imagenet_utils
from .imagenet_utils import decode_predictions
from .imagenet_utils import _obtain_input_shape
......@@ -36,8 +29,13 @@ from .imagenet_utils import _obtain_input_shape
BASE_WEIGHT_URL = ('https://github.com/fchollet/deep-learning-models/'
'releases/download/v0.7/')
backend = None
layers = None
models = None
keras_utils = None
def preprocess_input(x):
def preprocess_input(x, **kwargs):
"""Preprocesses a numpy array encoding a batch of images.
# Arguments
......@@ -46,7 +44,7 @@ def preprocess_input(x):
# Returns
Preprocessed array.
"""
return imagenet_utils.preprocess_input(x, mode='tf')
return imagenet_utils.preprocess_input(x, mode='tf', **kwargs)
def conv2d_bn(x,
......@@ -181,7 +179,8 @@ def InceptionResNetV2(include_top=True,
input_tensor=None,
input_shape=None,
pooling=None,
classes=1000):
classes=1000,
**kwargs):
"""Instantiates the Inception-ResNet v2 architecture.
Optionally loads weights pre-trained on ImageNet.
......@@ -201,7 +200,7 @@ def InceptionResNetV2(include_top=True,
has to be `(299, 299, 3)` (with `'channels_last'` data format)
or `(3, 299, 299)` (with `'channels_first'` data format).
It should have exactly 3 inputs channels,
and width and height should be no smaller than 139.
and width and height should be no smaller than 75.
E.g. `(150, 150, 3)` would be one valid value.
pooling: Optional pooling mode for feature extraction
when `include_top` is `False`.
......@@ -223,6 +222,9 @@ def InceptionResNetV2(include_top=True,
ValueError: in case of invalid argument for `weights`,
or invalid input shape.
"""
global backend, layers, models, keras_utils
backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs)
if not (weights in {'imagenet', None} or os.path.exists(weights)):
raise ValueError('The `weights` argument should be either '
'`None` (random initialization), `imagenet` '
......@@ -237,7 +239,7 @@ def InceptionResNetV2(include_top=True,
input_shape = _obtain_input_shape(
input_shape,
default_size=299,
min_size=139,
min_size=75,
data_format=backend.image_data_format(),
require_flatten=False,
weights=weights)
......@@ -335,11 +337,7 @@ def InceptionResNetV2(include_top=True,
# Ensure that the model takes into account
# any potential predecessors of `input_tensor`.
if input_tensor is not None:
if hasattr(keras_utils, 'get_source_inputs'):
get_source_inputs = keras_utils.get_source_inputs
else:
get_source_inputs = engine.get_source_inputs
inputs = get_source_inputs(input_tensor)
inputs = keras_utils.get_source_inputs(input_tensor)
else:
inputs = img_input
......
......@@ -16,14 +16,7 @@ from __future__ import print_function
import os
from . import get_keras_submodule
backend = get_keras_submodule('backend')
engine = get_keras_submodule('engine')
layers = get_keras_submodule('layers')
models = get_keras_submodule('models')
keras_utils = get_keras_submodule('utils')
from . import get_submodules_from_kwargs
from . import imagenet_utils
from .imagenet_utils import decode_predictions
from .imagenet_utils import _obtain_input_shape
......@@ -38,6 +31,11 @@ WEIGHTS_PATH_NO_TOP = (
'releases/download/v0.5/'
'inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5')
backend = None
layers = None
models = None
keras_utils = None
def conv2d_bn(x,
filters,
......@@ -88,7 +86,8 @@ def InceptionV3(include_top=True,
input_tensor=None,
input_shape=None,
pooling=None,
classes=1000):
classes=1000,
**kwargs):
"""Instantiates the Inception v3 architecture.
Optionally loads weights pre-trained on ImageNet.
......@@ -108,7 +107,7 @@ def InceptionV3(include_top=True,
has to be `(299, 299, 3)` (with `channels_last` data format)
or `(3, 299, 299)` (with `channels_first` data format).
It should have exactly 3 inputs channels,
and width and height should be no smaller than 139.
and width and height should be no smaller than 75.
E.g. `(150, 150, 3)` would be one valid value.
pooling: Optional pooling mode for feature extraction
when `include_top` is `False`.
......@@ -132,6 +131,9 @@ def InceptionV3(include_top=True,
ValueError: in case of invalid argument for `weights`,
or invalid input shape.
"""
global backend, layers, models, keras_utils
backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs)
if not (weights in {'imagenet', None} or os.path.exists(weights)):
raise ValueError('The `weights` argument should be either '
'`None` (random initialization), `imagenet` '
......@@ -146,7 +148,7 @@ def InceptionV3(include_top=True,
input_shape = _obtain_input_shape(
input_shape,
default_size=299,
min_size=139,
min_size=75,
data_format=backend.image_data_format(),
require_flatten=False,
weights=weights)
......@@ -366,11 +368,7 @@ def InceptionV3(include_top=True,
# Ensure that the model takes into account
# any potential predecessors of `input_tensor`.
if input_tensor is not None:
if hasattr(keras_utils, 'get_source_inputs'):
get_source_inputs = keras_utils.get_source_inputs
else:
get_source_inputs = engine.get_source_inputs
inputs = get_source_inputs(input_tensor)
inputs = keras_utils.get_source_inputs(input_tensor)
else:
inputs = img_input
# Create model.
......@@ -397,7 +395,7 @@ def InceptionV3(include_top=True,
return model
def preprocess_input(x):
def preprocess_input(x, **kwargs):
"""Preprocesses a numpy array encoding a batch of images.
# Arguments
......@@ -406,4 +404,4 @@ def preprocess_input(x):
# Returns
Preprocessed array.
"""
return imagenet_utils.preprocess_input(x, mode='tf')
return imagenet_utils.preprocess_input(x, mode='tf', **kwargs)
......@@ -57,14 +57,7 @@ from __future__ import division
import os
import warnings
from . import get_keras_submodule
backend = get_keras_submodule('backend')
engine = get_keras_submodule('engine')
layers = get_keras_submodule('layers')
models = get_keras_submodule('models')
keras_utils = get_keras_submodule('utils')
from . import get_submodules_from_kwargs
from . import imagenet_utils
from .imagenet_utils import decode_predictions
from .imagenet_utils import _obtain_input_shape
......@@ -73,8 +66,13 @@ from .imagenet_utils import _obtain_input_shape
BASE_WEIGHT_PATH = ('https://github.com/fchollet/deep-learning-models/'
'releases/download/v0.6/')
backend = None
layers = None
models = None
keras_utils = None
def preprocess_input(x):
def preprocess_input(x, **kwargs):
"""Preprocesses a numpy array encoding a batch of images.
# Arguments
......@@ -83,7 +81,7 @@ def preprocess_input(x):
# Returns
Preprocessed array.
"""
return imagenet_utils.preprocess_input(x, mode='tf')
return imagenet_utils.preprocess_input(x, mode='tf', **kwargs)
def MobileNet(input_shape=None,
......@@ -94,7 +92,8 @@ def MobileNet(input_shape=None,
weights='imagenet',
input_tensor=None,
pooling=None,
classes=1000):
classes=1000,
**kwargs):
"""Instantiates the MobileNet architecture.
# Arguments
......@@ -149,6 +148,8 @@ def MobileNet(input_shape=None,
RuntimeError: If attempting to run this model with a
backend that does not support separable convolutions.
"""
global backend, layers, models, keras_utils
backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs)
if not (weights in {'imagenet', None} or os.path.exists(weights)):
raise ValueError('The `weights` argument should be either '
......@@ -282,11 +283,7 @@ def MobileNet(input_shape=None,
# Ensure that the model takes into account
# any potential predecessors of `input_tensor`.
if input_tensor is not None:
if hasattr(keras_utils, 'get_source_inputs'):
get_source_inputs = keras_utils.get_source_inputs
else:
get_source_inputs = engine.get_source_inputs
inputs = get_source_inputs(input_tensor)
inputs = keras_utils.get_source_inputs(input_tensor)
else:
inputs = img_input
......
......@@ -80,29 +80,22 @@ import os
import warnings
import numpy as np
from . import get_keras_submodule
backend = get_keras_submodule('backend')
engine = get_keras_submodule('engine')
layers = get_keras_submodule('layers')
models = get_keras_submodule('models')
keras_utils = get_keras_submodule('utils')
from . import imagenet_utils
from . import correct_pad
from . import get_submodules_from_kwargs
from .imagenet_utils import decode_predictions
from .imagenet_utils import _obtain_input_shape
if hasattr(keras_utils, 'get_source_inputs'):
get_source_inputs = keras_utils.get_source_inputs
else:
get_source_inputs = engine.get_source_inputs
# TODO Change path to v1.1
BASE_WEIGHT_PATH = ('https://github.com/JonathanCMitchell/mobilenet_v2_keras/'
'releases/download/v1.1/')
backend = None
layers = None
models = None
keras_utils = None
def preprocess_input(x):
def preprocess_input(x, **kwargs):
"""Preprocesses a numpy array encoding a batch of images.
This function applies the "Inception" preprocessing which converts
......@@ -143,7 +136,8 @@ def MobileNetV2(input_shape=None,
weights='imagenet',
input_tensor=None,
pooling=None,
classes=1000):
classes=1000,
**kwargs):
"""Instantiates the MobileNetV2 architecture.
# Arguments
......@@ -199,6 +193,8 @@ def MobileNetV2(input_shape=None,
or invalid input shape or invalid depth_multiplier, alpha,
rows when weights='imagenet'
"""
global backend, layers, models, keras_utils
backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs)
if not (weights in {'imagenet', None} or os.path.exists(weights)):
raise ValueError('The `weights` argument should be either '
......@@ -218,18 +214,18 @@ def MobileNetV2(input_shape=None,
except ValueError:
try:
is_input_t_tensor = backend.is_keras_tensor(
get_source_inputs(input_tensor))
keras_utils.get_source_inputs(input_tensor))
except ValueError:
raise ValueError('input_tensor: ', input_tensor,
'is not type input_tensor')
if is_input_t_tensor:
if backend.image_data_format == 'channels_first':
if input_tensor._keras_shape[1] != input_shape[1]:
if backend.int_shape(input_tensor)[1] != input_shape[1]:
raise ValueError('input_shape: ', input_shape,
'and input_tensor: ', input_tensor,
'do not meet the same shape requirements')
else:
if input_tensor._keras_shape[2] != input_shape[1]:
if backend.int_shape(input_tensor)[2] != input_shape[1]:
raise ValueError('input_shape: ', input_shape,
'and input_tensor: ', input_tensor,
'do not meet the same shape requirements')
......@@ -251,11 +247,11 @@ def MobileNetV2(input_shape=None,
default_size = 224
elif input_shape is None and backend.is_keras_tensor(input_tensor):
if backend.image_data_format() == 'channels_first':
rows = input_tensor._keras_shape[2]
cols = input_tensor._keras_shape[3]
rows = backend.int_shape(input_tensor)[2]
cols = backend.int_shape(input_tensor)[3]
else:
rows = input_tensor._keras_shape[1]
cols = input_tensor._keras_shape[2]
rows = backend.int_shape(input_tensor)[1]
cols = backend.int_shape(input_tensor)[2]
if rows == cols and rows in [96, 128, 160, 192, 224]:
default_size = rows
......@@ -341,12 +337,14 @@ def MobileNetV2(input_shape=None,
img_input = input_tensor
first_block_filters = _make_divisible(32 * alpha, 8)
x = layers.ZeroPadding2D(padding=correct_pad(backend, img_input, 3),
name='Conv1_pad')(img_input)
x = layers.Conv2D(first_block_filters,
kernel_size=3,
strides=(2, 2),
padding='same',
padding='valid',
use_bias=False,
name='Conv1')(img_input)
name='Conv1')(x)
x = layers.BatchNormalization(
epsilon=1e-3, momentum=0.999, name='bn_Conv1')(x)
x = layers.ReLU(6., name='Conv1_relu')(x)
......@@ -422,7 +420,7 @@ def MobileNetV2(input_shape=None,
# Ensure that the model takes into account
# any potential predecessors of `input_tensor`.
if input_tensor is not None:
inputs = get_source_inputs(input_tensor)
inputs = keras_utils.get_source_inputs(input_tensor)
else:
inputs = img_input
......@@ -458,7 +456,7 @@ def MobileNetV2(input_shape=None,