From ec6e4d1016f20783786182ef43ed4e7ddc279fd0 Mon Sep 17 00:00:00 2001 From: "Takuya.Yashima" Date: Thu, 21 Feb 2019 16:40:21 +0900 Subject: [PATCH] added inception model --- doc/python/api/models/imagenet.rst | 4 + python/src/nnabla/models/imagenet/__init__.py | 1 + .../src/nnabla/models/imagenet/inception.py | 93 +++++++++++++++++++ python/test/models/test_imagenet.py | 1 + 4 files changed, 99 insertions(+) create mode 100644 python/src/nnabla/models/imagenet/inception.py diff --git a/doc/python/api/models/imagenet.rst b/doc/python/api/models/imagenet.rst index 23f535255..f96bff958 100644 --- a/doc/python/api/models/imagenet.rst +++ b/doc/python/api/models/imagenet.rst @@ -65,6 +65,7 @@ Available models are summarized in the following table. Error rates are calculat "VGG-16", "VGG", 29.03, 10.07, Neural Network Console "NIN", "NIN", 42.91, 20.66, Neural Network Console "DenseNet-161", "DenseNet", 23.82, 7.02, Neural Network Console + "InceptionV3", "InceptionV3", 21.82, 5.88, Neural Network Console Common interfaces @@ -103,3 +104,6 @@ List of models .. autoclass:: DenseNet :members: + +.. autoclass:: InceptionV3 + :members: diff --git a/python/src/nnabla/models/imagenet/__init__.py b/python/src/nnabla/models/imagenet/__init__.py index 44b1ee3d6..7b5653562 100644 --- a/python/src/nnabla/models/imagenet/__init__.py +++ b/python/src/nnabla/models/imagenet/__init__.py @@ -19,3 +19,4 @@ from .vgg import VGG from .nin import NIN from .densenet import DenseNet +from .inception import InceptionV3 diff --git a/python/src/nnabla/models/imagenet/inception.py b/python/src/nnabla/models/imagenet/inception.py new file mode 100644 index 000000000..9bad53962 --- /dev/null +++ b/python/src/nnabla/models/imagenet/inception.py @@ -0,0 +1,93 @@ +# Copyright (c) 2017 Sony Corporation. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import +import nnabla as nn +from nnabla.utils.nnp_graph import NnpNetworkPass + +from nnabla import logger + +from .base import ImageNetBase + + +class InceptionV3(ImageNetBase): + ''' + InceptionV3 architecture. + The following is a list of string that can be specified to ``use_up_to`` option in ``__call__`` method; + * ``'classifier'`` (default): The output of the final affine layer for classification. + * ``'pool'``: The output of the final global average pooling. + * ``'prepool'``: The input of the final global average pooling, i.e. the output of the final inception block. + References: + * `Szegedy et al., Rethinking the Inception Architecture for Computer Vision. + `_ + ''' + + _KEY_VARIABLE = { + 'classifier': 'Affine', + 'pool': 'AveragePooling_2', + 'prepool': 'Inception_11/Concatenate', + '_aux_classifier': 'Affine_2', + '_include_no_aux': 'Conv_6/Convolution' + } + + def __init__(self): + self._load_nnp('Inception-v3.nnp', 'Inception-v3/Inception-v3.nnp') + + def _input_shape(self): + return (3, 299, 299) + + def __call__(self, input_var=None, use_from=None, use_up_to='classifier', training=False, force_global_pooling=False, check_global_pooling=True, returns_net=False, verbose=0, with_aux_tower=False): + if not training: + assert not with_aux_tower, "Aux Tower should be disabled when inference process." + + input_var = self.get_input_var(input_var) + + callback = NnpNetworkPass(verbose) + callback.remove_and_rewire('ImageAugmentation') + callback.set_variable('Iv3TrainInput', input_var) + self.configure_global_average_pooling( + callback, force_global_pooling, check_global_pooling, 'AveragePooling_2') + callback.set_batch_normalization_batch_stat_all(training) + if with_aux_tower: + self.use_up_to('_aux_classifier', callback) + funcs_to_drop = ("Affine_2", + "SoftmaxCrossEntropy_2", + "MulScalar_2") + else: + self.use_up_to('_include_no_aux', callback) + funcs_to_drop = ("Conv_6/Convolution", + "Conv_6/BatchNormalization", + "Conv_6/ReLU", + "AveragePooling", + "Conv_7/Convolution", + "Conv_7/BatchNormalization", + "Conv_7/ReLU", + "Affine_2", + "SoftmaxCrossEntropy_2", + "MulScalar_2") + + callback.drop_function(*funcs_to_drop) + if not training: + callback.remove_and_rewire('Dropout') + callback.fix_parameters() + self.use_up_to(use_up_to, callback) + batch_size = input_var.shape[0] + net = self.nnp.get_network( + 'Train', batch_size=batch_size, callback=callback) + if returns_net: + return net + elif with_aux_tower: + return list(net.outputs.values()) + else: + return list(net.outputs.values())[0] diff --git a/python/test/models/test_imagenet.py b/python/test/models/test_imagenet.py index e53313a06..528243362 100644 --- a/python/test/models/test_imagenet.py +++ b/python/test/models/test_imagenet.py @@ -88,6 +88,7 @@ def _execute(): ('SENet', ['classifier', 'pool', 'lastconv', 'lastconv+relu']), ('SqueezeNet', ['classifier', 'pool', 'lastconv', 'lastconv+relu']), ('DenseNet', ['classifier', 'pool', 'lastconv', 'lastconv+relu']), + ('InceptionV3', ['classifier', 'pool', 'prepool']), ]) @pytest.mark.parametrize('image_size_factor', [1, 2]) @pytest.mark.parametrize('batch_size', [1, 5])