Commit 629adffa authored by pkulzc's avatar pkulzc Committed by Sergio Guadarrama
Browse files

Internal changes for slim (#3448)

* Merged commit includes the following changes:
186565198  by Sergio Guadarrama:

    Applied random_hsv_in_yiq in inception_preprocessing.

--
186501039  by Sergio Guadarrama:

    Applied random_hsv_in_yiq in inception_preprocessing.

--
186013907  by Sergio Guadarrama:

    Internal change

185715309  by Sergio Guadarrama:

    Obviates the need for prepadding on mobilenet v1 and v2 for fully convolutional models.

--
184266252  by Sergio Guadarrama:

    Give build_nasnet_*() functions an optional flag use_aux_head,
    and add an internal-only arg scope to NasNetA*Cell._apply_drop_path().

--
183865228  by Sergio Guadarrama:

    Internal change

179580924  by Sergio Guadarrama:

    Internal change

177320302  by Sergio Guadarrama:

    Internal change

177130184  by Sergio Guadarrama:

    Make slim nets tests faster by using smaller examples of oversized inputs.

--
176965289  by Sergio Guadarrama:

    Internal change

176585260  by Sergio Guadarrama:

    Internal change

176534973  by Sergio Guadarrama:

    Internal change

175526881  by Sergio Guadarrama:

    Internal change

174967704  by Sergio Guadarrama:

    Treat num_classes=0 same as None in a few slim nets overlooked by the recent
    change.

--
174443227  by Sergio Guadarrama:

    Internal change

174281864  by Sergio Guadarrama:

    Internal change

174249903  by Sergio Guadarrama:

    Fix nasnet image classification and object detection by moving the option to turn ON or OFF batch norm training into it's own arg_scope used only by detection

--
173954505  by Sergio Guadarrama:

    Merge pull request #2651 from sguada/tmp1

    Fixes imports

    Closes #2636

    ORIGINAL_AUTHOR=Jon Shlens <shlens@users.noreply.github.com>
    COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/models/pull/2636 from tensorflow:sguada-patch-1 19ff570f52df5ab655c00fb439129b201c5f2dce

--
173928094  by Sergio Guadarrama:

    Remove pending imports

--

PiperOrigin-RevId: 186565198

* Remove internal links.
parent 599521ef
...@@ -216,7 +216,7 @@ py_library( ...@@ -216,7 +216,7 @@ py_library(
srcs = ["nets/alexnet.py"], srcs = ["nets/alexnet.py"],
srcs_version = "PY2AND3", srcs_version = "PY2AND3",
deps = [ deps = [
# "//tensorflow" # "//tensorflow",
], ],
) )
...@@ -296,7 +296,7 @@ py_library( ...@@ -296,7 +296,7 @@ py_library(
srcs = ["nets/inception_utils.py"], srcs = ["nets/inception_utils.py"],
srcs_version = "PY2AND3", srcs_version = "PY2AND3",
deps = [ deps = [
# "//tensorflow" # "//tensorflow",
], ],
) )
...@@ -345,7 +345,7 @@ py_library( ...@@ -345,7 +345,7 @@ py_library(
srcs = ["nets/inception_resnet_v2.py"], srcs = ["nets/inception_resnet_v2.py"],
srcs_version = "PY2AND3", srcs_version = "PY2AND3",
deps = [ deps = [
# "//tensorflow" # "//tensorflow",
], ],
) )
...@@ -425,7 +425,7 @@ py_library( ...@@ -425,7 +425,7 @@ py_library(
srcs = ["nets/mobilenet_v1.py"], srcs = ["nets/mobilenet_v1.py"],
srcs_version = "PY2AND3", srcs_version = "PY2AND3",
deps = [ deps = [
# "//tensorflow" # "//tensorflow",
], ],
) )
...@@ -511,7 +511,7 @@ py_library( ...@@ -511,7 +511,7 @@ py_library(
srcs = ["nets/overfeat.py"], srcs = ["nets/overfeat.py"],
srcs_version = "PY2AND3", srcs_version = "PY2AND3",
deps = [ deps = [
# "//tensorflow" # "//tensorflow",
], ],
) )
...@@ -531,7 +531,7 @@ py_library( ...@@ -531,7 +531,7 @@ py_library(
srcs = ["nets/pix2pix.py"], srcs = ["nets/pix2pix.py"],
srcs_version = "PY2AND3", srcs_version = "PY2AND3",
deps = [ deps = [
# "//tensorflow" # "//tensorflow",
], ],
) )
...@@ -550,7 +550,7 @@ py_library( ...@@ -550,7 +550,7 @@ py_library(
srcs = ["nets/resnet_utils.py"], srcs = ["nets/resnet_utils.py"],
srcs_version = "PY2AND3", srcs_version = "PY2AND3",
deps = [ deps = [
# "//tensorflow" # "//tensorflow",
], ],
) )
...@@ -607,7 +607,7 @@ py_library( ...@@ -607,7 +607,7 @@ py_library(
srcs = ["nets/vgg.py"], srcs = ["nets/vgg.py"],
srcs_version = "PY2AND3", srcs_version = "PY2AND3",
deps = [ deps = [
# "//tensorflow" # "//tensorflow",
], ],
) )
...@@ -646,6 +646,7 @@ py_test( ...@@ -646,6 +646,7 @@ py_test(
py_binary( py_binary(
name = "train_image_classifier", name = "train_image_classifier",
srcs = ["train_image_classifier.py"], srcs = ["train_image_classifier.py"],
paropts = ["--compress"],
deps = [ deps = [
":dataset_factory", ":dataset_factory",
":model_deploy", ":model_deploy",
...@@ -669,6 +670,7 @@ py_binary( ...@@ -669,6 +670,7 @@ py_binary(
py_binary( py_binary(
name = "export_inference_graph", name = "export_inference_graph",
srcs = ["export_inference_graph.py"], srcs = ["export_inference_graph.py"],
paropts = ["--compress"],
deps = [ deps = [
":dataset_factory", ":dataset_factory",
":nets_factory", ":nets_factory",
......
...@@ -92,9 +92,7 @@ import random ...@@ -92,9 +92,7 @@ import random
import sys import sys
import threading import threading
import google3
import numpy as np import numpy as np
from six.moves import xrange
import tensorflow as tf import tensorflow as tf
tf.app.flags.DEFINE_string('train_directory', '/tmp/', tf.app.flags.DEFINE_string('train_directory', '/tmp/',
......
...@@ -51,7 +51,6 @@ from __future__ import print_function ...@@ -51,7 +51,6 @@ from __future__ import print_function
import os import os
import os.path import os.path
import sys import sys
from six.moves import xrange
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -85,7 +85,6 @@ import glob ...@@ -85,7 +85,6 @@ import glob
import os.path import os.path
import sys import sys
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from six.moves import xrange
class BoundingBox(object): class BoundingBox(object):
......
...@@ -28,7 +28,7 @@ from preprocessing import preprocessing_factory ...@@ -28,7 +28,7 @@ from preprocessing import preprocessing_factory
slim = tf.contrib.slim slim = tf.contrib.slim
tf.app.flags.DEFINE_integer( tf.app.flags.DEFINE_integer(
'batch_size', 50, 'The number of samples in each batch.') 'batch_size', 100, 'The number of samples in each batch.')
tf.app.flags.DEFINE_integer( tf.app.flags.DEFINE_integer(
'max_num_batches', None, 'max_num_batches', None,
......
...@@ -50,7 +50,7 @@ class AlexnetV2Test(tf.test.TestCase): ...@@ -50,7 +50,7 @@ class AlexnetV2Test(tf.test.TestCase):
def testGlobalPool(self): def testGlobalPool(self):
batch_size = 1 batch_size = 1
height, width = 300, 400 height, width = 256, 256
num_classes = 1000 num_classes = 1000
with self.test_session(): with self.test_session():
inputs = tf.random_uniform((batch_size, height, width, 3)) inputs = tf.random_uniform((batch_size, height, width, 3))
......
...@@ -18,7 +18,7 @@ from __future__ import division ...@@ -18,7 +18,7 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
import numpy as np import numpy as np
from six.moves import xrange
import tensorflow as tf import tensorflow as tf
layers = tf.contrib.layers layers = tf.contrib.layers
......
...@@ -19,7 +19,6 @@ from __future__ import print_function ...@@ -19,7 +19,6 @@ from __future__ import print_function
from math import log from math import log
from six.moves import xrange
import tensorflow as tf import tensorflow as tf
slim = tf.contrib.slim slim = tf.contrib.slim
......
...@@ -18,7 +18,6 @@ from __future__ import absolute_import ...@@ -18,7 +18,6 @@ from __future__ import absolute_import
from __future__ import division from __future__ import division
from __future__ import print_function from __future__ import print_function
from six.moves import xrange
import tensorflow as tf import tensorflow as tf
from nets import dcgan from nets import dcgan
......
...@@ -116,7 +116,7 @@ class InceptionTest(tf.test.TestCase): ...@@ -116,7 +116,7 @@ class InceptionTest(tf.test.TestCase):
if endpoint != 'PreAuxLogits': if endpoint != 'PreAuxLogits':
self.assertTrue(out_tensor.op.name.startswith( self.assertTrue(out_tensor.op.name.startswith(
'InceptionResnetV2/' + endpoint)) 'InceptionResnetV2/' + endpoint))
self.assertItemsEqual(endpoints[:index+1], end_points) self.assertItemsEqual(endpoints[:index+1], end_points.keys())
def testBuildAndCheckAllEndPointsUptoPreAuxLogits(self): def testBuildAndCheckAllEndPointsUptoPreAuxLogits(self):
batch_size = 5 batch_size = 5
...@@ -227,8 +227,8 @@ class InceptionTest(tf.test.TestCase): ...@@ -227,8 +227,8 @@ class InceptionTest(tf.test.TestCase):
[batch_size, 3, 3, 1536]) [batch_size, 3, 3, 1536])
def testGlobalPool(self): def testGlobalPool(self):
batch_size = 2 batch_size = 1
height, width = 400, 600 height, width = 330, 400
num_classes = 1000 num_classes = 1000
with self.test_session(): with self.test_session():
inputs = tf.random_uniform((batch_size, height, width, 3)) inputs = tf.random_uniform((batch_size, height, width, 3))
...@@ -238,11 +238,11 @@ class InceptionTest(tf.test.TestCase): ...@@ -238,11 +238,11 @@ class InceptionTest(tf.test.TestCase):
[batch_size, num_classes]) [batch_size, num_classes])
pre_pool = end_points['Conv2d_7b_1x1'] pre_pool = end_points['Conv2d_7b_1x1']
self.assertListEqual(pre_pool.get_shape().as_list(), self.assertListEqual(pre_pool.get_shape().as_list(),
[batch_size, 11, 17, 1536]) [batch_size, 8, 11, 1536])
def testGlobalPoolUnknownImageShape(self): def testGlobalPoolUnknownImageShape(self):
batch_size = 2 batch_size = 1
height, width = 400, 600 height, width = 330, 400
num_classes = 1000 num_classes = 1000
with self.test_session() as sess: with self.test_session() as sess:
inputs = tf.placeholder(tf.float32, (batch_size, None, None, 3)) inputs = tf.placeholder(tf.float32, (batch_size, None, None, 3))
...@@ -257,7 +257,7 @@ class InceptionTest(tf.test.TestCase): ...@@ -257,7 +257,7 @@ class InceptionTest(tf.test.TestCase):
logits_out, pre_pool_out = sess.run([logits, pre_pool], logits_out, pre_pool_out = sess.run([logits, pre_pool],
{inputs: images.eval()}) {inputs: images.eval()})
self.assertTupleEqual(logits_out.shape, (batch_size, num_classes)) self.assertTupleEqual(logits_out.shape, (batch_size, num_classes))
self.assertTupleEqual(pre_pool_out.shape, (batch_size, 11, 17, 1536)) self.assertTupleEqual(pre_pool_out.shape, (batch_size, 8, 11, 1536))
def testUnknownBatchSize(self): def testUnknownBatchSize(self):
batch_size = 1 batch_size = 1
......
...@@ -86,7 +86,7 @@ class InceptionV1Test(tf.test.TestCase): ...@@ -86,7 +86,7 @@ class InceptionV1Test(tf.test.TestCase):
inputs, final_endpoint=endpoint) inputs, final_endpoint=endpoint)
self.assertTrue(out_tensor.op.name.startswith( self.assertTrue(out_tensor.op.name.startswith(
'InceptionV1/' + endpoint)) 'InceptionV1/' + endpoint))
self.assertItemsEqual(endpoints[:index+1], end_points) self.assertItemsEqual(endpoints[:index+1], end_points.keys())
def testBuildAndCheckAllEndPointsUptoMixed5c(self): def testBuildAndCheckAllEndPointsUptoMixed5c(self):
batch_size = 5 batch_size = 5
...@@ -159,8 +159,8 @@ class InceptionV1Test(tf.test.TestCase): ...@@ -159,8 +159,8 @@ class InceptionV1Test(tf.test.TestCase):
def testGlobalPoolUnknownImageShape(self): def testGlobalPoolUnknownImageShape(self):
tf.reset_default_graph() tf.reset_default_graph()
batch_size = 2 batch_size = 1
height, width = 300, 400 height, width = 250, 300
num_classes = 1000 num_classes = 1000
input_np = np.random.uniform(0, 1, (batch_size, height, width, 3)) input_np = np.random.uniform(0, 1, (batch_size, height, width, 3))
with self.test_session() as sess: with self.test_session() as sess:
...@@ -174,7 +174,7 @@ class InceptionV1Test(tf.test.TestCase): ...@@ -174,7 +174,7 @@ class InceptionV1Test(tf.test.TestCase):
feed_dict = {inputs: input_np} feed_dict = {inputs: input_np}
tf.global_variables_initializer().run() tf.global_variables_initializer().run()
pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict) pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict)
self.assertListEqual(list(pre_pool_out.shape), [batch_size, 10, 13, 1024]) self.assertListEqual(list(pre_pool_out.shape), [batch_size, 8, 10, 1024])
def testUnknowBatchSize(self): def testUnknowBatchSize(self):
batch_size = 1 batch_size = 1
......
...@@ -85,7 +85,7 @@ class InceptionV2Test(tf.test.TestCase): ...@@ -85,7 +85,7 @@ class InceptionV2Test(tf.test.TestCase):
inputs, final_endpoint=endpoint) inputs, final_endpoint=endpoint)
self.assertTrue(out_tensor.op.name.startswith( self.assertTrue(out_tensor.op.name.startswith(
'InceptionV2/' + endpoint)) 'InceptionV2/' + endpoint))
self.assertItemsEqual(endpoints[:index+1], end_points) self.assertItemsEqual(endpoints[:index+1], end_points.keys())
def testBuildAndCheckAllEndPointsUptoMixed5c(self): def testBuildAndCheckAllEndPointsUptoMixed5c(self):
batch_size = 5 batch_size = 5
...@@ -273,8 +273,8 @@ class InceptionV2Test(tf.test.TestCase): ...@@ -273,8 +273,8 @@ class InceptionV2Test(tf.test.TestCase):
def testGlobalPoolUnknownImageShape(self): def testGlobalPoolUnknownImageShape(self):
tf.reset_default_graph() tf.reset_default_graph()
batch_size = 2 batch_size = 1
height, width = 300, 400 height, width = 250, 300
num_classes = 1000 num_classes = 1000
input_np = np.random.uniform(0, 1, (batch_size, height, width, 3)) input_np = np.random.uniform(0, 1, (batch_size, height, width, 3))
with self.test_session() as sess: with self.test_session() as sess:
...@@ -288,7 +288,7 @@ class InceptionV2Test(tf.test.TestCase): ...@@ -288,7 +288,7 @@ class InceptionV2Test(tf.test.TestCase):
feed_dict = {inputs: input_np} feed_dict = {inputs: input_np}
tf.global_variables_initializer().run() tf.global_variables_initializer().run()
pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict) pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict)
self.assertListEqual(list(pre_pool_out.shape), [batch_size, 10, 13, 1024]) self.assertListEqual(list(pre_pool_out.shape), [batch_size, 8, 10, 1024])
def testUnknowBatchSize(self): def testUnknowBatchSize(self):
batch_size = 1 batch_size = 1
......
...@@ -88,7 +88,7 @@ class InceptionV3Test(tf.test.TestCase): ...@@ -88,7 +88,7 @@ class InceptionV3Test(tf.test.TestCase):
inputs, final_endpoint=endpoint) inputs, final_endpoint=endpoint)
self.assertTrue(out_tensor.op.name.startswith( self.assertTrue(out_tensor.op.name.startswith(
'InceptionV3/' + endpoint)) 'InceptionV3/' + endpoint))
self.assertItemsEqual(endpoints[:index+1], end_points) self.assertItemsEqual(endpoints[:index+1], end_points.keys())
def testBuildAndCheckAllEndPointsUptoMixed7c(self): def testBuildAndCheckAllEndPointsUptoMixed7c(self):
batch_size = 5 batch_size = 5
...@@ -240,8 +240,8 @@ class InceptionV3Test(tf.test.TestCase): ...@@ -240,8 +240,8 @@ class InceptionV3Test(tf.test.TestCase):
def testGlobalPoolUnknownImageShape(self): def testGlobalPoolUnknownImageShape(self):
tf.reset_default_graph() tf.reset_default_graph()
batch_size = 2 batch_size = 1
height, width = 400, 600 height, width = 330, 400
num_classes = 1000 num_classes = 1000
input_np = np.random.uniform(0, 1, (batch_size, height, width, 3)) input_np = np.random.uniform(0, 1, (batch_size, height, width, 3))
with self.test_session() as sess: with self.test_session() as sess:
...@@ -254,7 +254,7 @@ class InceptionV3Test(tf.test.TestCase): ...@@ -254,7 +254,7 @@ class InceptionV3Test(tf.test.TestCase):
feed_dict = {inputs: input_np} feed_dict = {inputs: input_np}
tf.global_variables_initializer().run() tf.global_variables_initializer().run()
pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict) pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict)
self.assertListEqual(list(pre_pool_out.shape), [batch_size, 11, 17, 2048]) self.assertListEqual(list(pre_pool_out.shape), [batch_size, 8, 11, 2048])
def testUnknowBatchSize(self): def testUnknowBatchSize(self):
batch_size = 1 batch_size = 1
......
...@@ -146,7 +146,7 @@ class InceptionTest(tf.test.TestCase): ...@@ -146,7 +146,7 @@ class InceptionTest(tf.test.TestCase):
inputs, final_endpoint=endpoint) inputs, final_endpoint=endpoint)
self.assertTrue(out_tensor.op.name.startswith( self.assertTrue(out_tensor.op.name.startswith(
'InceptionV4/' + endpoint)) 'InceptionV4/' + endpoint))
self.assertItemsEqual(all_endpoints[:index+1], end_points) self.assertItemsEqual(all_endpoints[:index+1], end_points.keys())
def testVariablesSetDevice(self): def testVariablesSetDevice(self):
batch_size = 5 batch_size = 5
...@@ -177,8 +177,8 @@ class InceptionTest(tf.test.TestCase): ...@@ -177,8 +177,8 @@ class InceptionTest(tf.test.TestCase):
[batch_size, 3, 3, 1536]) [batch_size, 3, 3, 1536])
def testGlobalPool(self): def testGlobalPool(self):
batch_size = 2 batch_size = 1
height, width = 400, 600 height, width = 350, 400
num_classes = 1000 num_classes = 1000
inputs = tf.random_uniform((batch_size, height, width, 3)) inputs = tf.random_uniform((batch_size, height, width, 3))
logits, end_points = inception.inception_v4(inputs, num_classes) logits, end_points = inception.inception_v4(inputs, num_classes)
...@@ -187,11 +187,11 @@ class InceptionTest(tf.test.TestCase): ...@@ -187,11 +187,11 @@ class InceptionTest(tf.test.TestCase):
[batch_size, num_classes]) [batch_size, num_classes])
pre_pool = end_points['Mixed_7d'] pre_pool = end_points['Mixed_7d']
self.assertListEqual(pre_pool.get_shape().as_list(), self.assertListEqual(pre_pool.get_shape().as_list(),
[batch_size, 11, 17, 1536]) [batch_size, 9, 11, 1536])
def testGlobalPoolUnknownImageShape(self): def testGlobalPoolUnknownImageShape(self):
batch_size = 2 batch_size = 1
height, width = 400, 600 height, width = 350, 400
num_classes = 1000 num_classes = 1000
with self.test_session() as sess: with self.test_session() as sess:
inputs = tf.placeholder(tf.float32, (batch_size, None, None, 3)) inputs = tf.placeholder(tf.float32, (batch_size, None, None, 3))
...@@ -206,7 +206,7 @@ class InceptionTest(tf.test.TestCase): ...@@ -206,7 +206,7 @@ class InceptionTest(tf.test.TestCase):
logits_out, pre_pool_out = sess.run([logits, pre_pool], logits_out, pre_pool_out = sess.run([logits, pre_pool],
{inputs: images.eval()}) {inputs: images.eval()})
self.assertTupleEqual(logits_out.shape, (batch_size, num_classes)) self.assertTupleEqual(logits_out.shape, (batch_size, num_classes))
self.assertTupleEqual(pre_pool_out.shape, (batch_size, 11, 17, 1536)) self.assertTupleEqual(pre_pool_out.shape, (batch_size, 9, 11, 1536))
def testUnknownBatchSize(self): def testUnknownBatchSize(self):
batch_size = 1 batch_size = 1
......
...@@ -139,12 +139,39 @@ _CONV_DEFS = [ ...@@ -139,12 +139,39 @@ _CONV_DEFS = [
] ]
def _fixed_padding(inputs, kernel_size, rate=1):
"""Pads the input along the spatial dimensions independently of input size.
Pads the input such that if it was used in a convolution with 'VALID' padding,
the output would have the same dimensions as if the unpadded input was used
in a convolution with 'SAME' padding.
Args:
inputs: A tensor of size [batch, height_in, width_in, channels].
kernel_size: The kernel to be used in the conv2d or max_pool2d operation.
rate: An integer, rate for atrous convolution.
Returns:
output: A tensor of size [batch, height_out, width_out, channels] with the
input, either intact (if kernel_size == 1) or padded (if kernel_size > 1).
"""
kernel_size_effective = [kernel_size[0] + (kernel_size[0] - 1) * (rate - 1),
kernel_size[0] + (kernel_size[0] - 1) * (rate - 1)]
pad_total = [kernel_size_effective[0] - 1, kernel_size_effective[1] - 1]
pad_beg = [pad_total[0] // 2, pad_total[1] // 2]
pad_end = [pad_total[0] - pad_beg[0], pad_total[1] - pad_beg[1]]
padded_inputs = tf.pad(inputs, [[0, 0], [pad_beg[0], pad_end[0]],
[pad_beg[1], pad_end[1]], [0, 0]])
return padded_inputs
def mobilenet_v1_base(inputs, def mobilenet_v1_base(inputs,
final_endpoint='Conv2d_13_pointwise', final_endpoint='Conv2d_13_pointwise',
min_depth=8, min_depth=8,
depth_multiplier=1.0, depth_multiplier=1.0,
conv_defs=None, conv_defs=None,
output_stride=None, output_stride=None,
use_explicit_padding=False,
scope=None): scope=None):
"""Mobilenet v1. """Mobilenet v1.
...@@ -171,6 +198,9 @@ def mobilenet_v1_base(inputs, ...@@ -171,6 +198,9 @@ def mobilenet_v1_base(inputs,
if necessary to prevent the network from reducing the spatial resolution if necessary to prevent the network from reducing the spatial resolution
of the activation maps. Allowed values are 8 (accurate fully convolutional of the activation maps. Allowed values are 8 (accurate fully convolutional
mode), 16 (fast fully convolutional mode), 32 (classification mode). mode), 16 (fast fully convolutional mode), 32 (classification mode).
use_explicit_padding: Use 'VALID' padding for convolutions, but prepad
inputs so that the output dimensions are the same as if 'SAME' padding
were used.
scope: Optional variable_scope. scope: Optional variable_scope.
Returns: Returns:
...@@ -196,8 +226,11 @@ def mobilenet_v1_base(inputs, ...@@ -196,8 +226,11 @@ def mobilenet_v1_base(inputs,
if output_stride is not None and output_stride not in [8, 16, 32]: if output_stride is not None and output_stride not in [8, 16, 32]:
raise ValueError('Only allowed output_stride values are 8, 16, 32.') raise ValueError('Only allowed output_stride values are 8, 16, 32.')
padding = 'SAME'
if use_explicit_padding:
padding = 'VALID'
with tf.variable_scope(scope, 'MobilenetV1', [inputs]): with tf.variable_scope(scope, 'MobilenetV1', [inputs]):
with slim.arg_scope([slim.conv2d, slim.separable_conv2d], padding='SAME'): with slim.arg_scope([slim.conv2d, slim.separable_conv2d], padding=padding):
# The current_stride variable keeps track of the output stride of the # The current_stride variable keeps track of the output stride of the
# activations, i.e., the running product of convolution strides up to the # activations, i.e., the running product of convolution strides up to the
# current network layer. This allows us to invoke atrous convolution # current network layer. This allows us to invoke atrous convolution
...@@ -226,6 +259,8 @@ def mobilenet_v1_base(inputs, ...@@ -226,6 +259,8 @@ def mobilenet_v1_base(inputs,
if isinstance(conv_def, Conv): if isinstance(conv_def, Conv):
end_point = end_point_base end_point = end_point_base
if use_explicit_padding:
net = _fixed_padding(net, conv_def.kernel)
net = slim.conv2d(net, depth(conv_def.depth), conv_def.kernel, net = slim.conv2d(net, depth(conv_def.depth), conv_def.kernel,
stride=conv_def.stride, stride=conv_def.stride,
normalizer_fn=slim.batch_norm, normalizer_fn=slim.batch_norm,
...@@ -239,6 +274,8 @@ def mobilenet_v1_base(inputs, ...@@ -239,6 +274,8 @@ def mobilenet_v1_base(inputs,
# By passing filters=None # By passing filters=None
# separable_conv2d produces only a depthwise convolution layer # separable_conv2d produces only a depthwise convolution layer
if use_explicit_padding:
net = _fixed_padding(net, conv_def.kernel, layer_rate)
net = slim.separable_conv2d(net, None, conv_def.kernel, net = slim.separable_conv2d(net, None, conv_def.kernel,
depth_multiplier=1, depth_multiplier=1,
stride=layer_stride, stride=layer_stride,
......
...@@ -104,7 +104,7 @@ class MobilenetV1Test(tf.test.TestCase): ...@@ -104,7 +104,7 @@ class MobilenetV1Test(tf.test.TestCase):
inputs, final_endpoint=endpoint) inputs, final_endpoint=endpoint)
self.assertTrue(out_tensor.op.name.startswith( self.assertTrue(out_tensor.op.name.startswith(
'MobilenetV1/' + endpoint)) 'MobilenetV1/' + endpoint))
self.assertItemsEqual(endpoints[:index+1], end_points) self.assertItemsEqual(endpoints[:index+1], end_points.keys())
def testBuildCustomNetworkUsingConvDefs(self): def testBuildCustomNetworkUsingConvDefs(self):
batch_size = 5 batch_size = 5
...@@ -137,6 +137,9 @@ class MobilenetV1Test(tf.test.TestCase): ...@@ -137,6 +137,9 @@ class MobilenetV1Test(tf.test.TestCase):
normalizer_fn=slim.batch_norm): normalizer_fn=slim.batch_norm):
_, end_points = mobilenet_v1.mobilenet_v1_base( _, end_points = mobilenet_v1.mobilenet_v1_base(
inputs, final_endpoint='Conv2d_13_pointwise') inputs, final_endpoint='Conv2d_13_pointwise')
_, explicit_padding_end_points = mobilenet_v1.mobilenet_v1_base(
inputs, final_endpoint='Conv2d_13_pointwise',
use_explicit_padding=True)
endpoints_shapes = {'Conv2d_0': [batch_size, 112, 112, 32], endpoints_shapes = {'Conv2d_0': [batch_size, 112, 112, 32],
'Conv2d_1_depthwise': [batch_size, 112, 112, 32], 'Conv2d_1_depthwise': [batch_size, 112, 112, 32],
'Conv2d_1_pointwise': [batch_size, 112, 112, 64], 'Conv2d_1_pointwise': [batch_size, 112, 112, 64],
...@@ -165,10 +168,17 @@ class MobilenetV1Test(tf.test.TestCase): ...@@ -165,10 +168,17 @@ class MobilenetV1Test(tf.test.TestCase):
'Conv2d_13_depthwise': [batch_size, 7, 7, 1024], 'Conv2d_13_depthwise': [batch_size, 7, 7, 1024],
'Conv2d_13_pointwise': [batch_size, 7, 7, 1024]} 'Conv2d_13_pointwise': [batch_size, 7, 7, 1024]}
self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys())
for endpoint_name, expected_shape in endpoints_shapes.items(): for endpoint_name, expected_shape in endpoints_shapes.iteritems():
self.assertTrue(endpoint_name in end_points) self.assertTrue(endpoint_name in end_points)
self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), self.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
expected_shape) expected_shape)
self.assertItemsEqual(endpoints_shapes.keys(),
explicit_padding_end_points.keys())
for endpoint_name, expected_shape in endpoints_shapes.iteritems():
self.assertTrue(endpoint_name in explicit_padding_end_points)
self.assertListEqual(
explicit_padding_end_points[endpoint_name].get_shape().as_list(),
expected_shape)
def testOutputStride16BuildAndCheckAllEndPointsUptoConv2d_13(self): def testOutputStride16BuildAndCheckAllEndPointsUptoConv2d_13(self):
batch_size = 5 batch_size = 5
...@@ -181,6 +191,9 @@ class MobilenetV1Test(tf.test.TestCase): ...@@ -181,6 +191,9 @@ class MobilenetV1Test(tf.test.TestCase):
_, end_points = mobilenet_v1.mobilenet_v1_base( _, end_points = mobilenet_v1.mobilenet_v1_base(
inputs, output_stride=output_stride, inputs, output_stride=output_stride,
final_endpoint='Conv2d_13_pointwise') final_endpoint='Conv2d_13_pointwise')
_, explicit_padding_end_points = mobilenet_v1.mobilenet_v1_base(
inputs, output_stride=output_stride,
final_endpoint='Conv2d_13_pointwise', use_explicit_padding=True)
endpoints_shapes = {'Conv2d_0': [batch_size, 112, 112, 32], endpoints_shapes = {'Conv2d_0': [batch_size, 112, 112, 32],
'Conv2d_1_depthwise': [batch_size, 112, 112, 32], 'Conv2d_1_depthwise': [batch_size, 112, 112, 32],
'Conv2d_1_pointwise': [batch_size, 112, 112, 64], 'Conv2d_1_pointwise': [batch_size, 112, 112, 64],
...@@ -209,10 +222,17 @@ class MobilenetV1Test(tf.test.TestCase): ...@@ -209,10 +222,17 @@ class MobilenetV1Test(tf.test.TestCase):
'Conv2d_13_depthwise': [batch_size, 14, 14, 1024], 'Conv2d_13_depthwise': [batch_size, 14, 14, 1024],
'Conv2d_13_pointwise': [batch_size, 14, 14, 1024]} 'Conv2d_13_pointwise': [batch_size, 14, 14, 1024]}
self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys())
for endpoint_name, expected_shape in endpoints_shapes.items(): for endpoint_name, expected_shape in endpoints_shapes.iteritems():
self.assertTrue(endpoint_name in end_points) self.assertTrue(endpoint_name in end_points)
self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), self.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
expected_shape) expected_shape)
self.assertItemsEqual(endpoints_shapes.keys(),
explicit_padding_end_points.keys())
for endpoint_name, expected_shape in endpoints_shapes.iteritems():
self.assertTrue(endpoint_name in explicit_padding_end_points)
self.assertListEqual(
explicit_padding_end_points[endpoint_name].get_shape().as_list(),
expected_shape)
def testOutputStride8BuildAndCheckAllEndPointsUptoConv2d_13(self): def testOutputStride8BuildAndCheckAllEndPointsUptoConv2d_13(self):
batch_size = 5 batch_size = 5
...@@ -225,6 +245,9 @@ class MobilenetV1Test(tf.test.TestCase): ...@@ -225,6 +245,9 @@ class MobilenetV1Test(tf.test.TestCase):
_, end_points = mobilenet_v1.mobilenet_v1_base( _, end_points = mobilenet_v1.mobilenet_v1_base(
inputs, output_stride=output_stride, inputs, output_stride=output_stride,
final_endpoint='Conv2d_13_pointwise') final_endpoint='Conv2d_13_pointwise')
_, explicit_padding_end_points = mobilenet_v1.mobilenet_v1_base(
inputs, output_stride=output_stride,
final_endpoint='Conv2d_13_pointwise', use_explicit_padding=True)
endpoints_shapes = {'Conv2d_0': [batch_size, 112, 112, 32], endpoints_shapes = {'Conv2d_0': [batch_size, 112, 112, 32],
'Conv2d_1_depthwise': [batch_size, 112, 112, 32], 'Conv2d_1_depthwise': [batch_size, 112, 112, 32],
'Conv2d_1_pointwise': [batch_size, 112, 112, 64], 'Conv2d_1_pointwise': [batch_size, 112, 112, 64],
...@@ -253,10 +276,17 @@ class MobilenetV1Test(tf.test.TestCase): ...@@ -253,10 +276,17 @@ class MobilenetV1Test(tf.test.TestCase):
'Conv2d_13_depthwise': [batch_size, 28, 28, 1024], 'Conv2d_13_depthwise': [batch_size, 28, 28, 1024],
'Conv2d_13_pointwise': [batch_size, 28, 28, 1024]} 'Conv2d_13_pointwise': [batch_size, 28, 28, 1024]}
self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys())
for endpoint_name, expected_shape in endpoints_shapes.items(): for endpoint_name, expected_shape in endpoints_shapes.iteritems():
self.assertTrue(endpoint_name in end_points) self.assertTrue(endpoint_name in end_points)
self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), self.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
expected_shape) expected_shape)
self.assertItemsEqual(endpoints_shapes.keys(),
explicit_padding_end_points.keys())
for endpoint_name, expected_shape in endpoints_shapes.iteritems():
self.assertTrue(endpoint_name in explicit_padding_end_points)
self.assertListEqual(
explicit_padding_end_points[endpoint_name].get_shape().as_list(),
expected_shape)
def testBuildAndCheckAllEndPointsApproximateFaceNet(self): def testBuildAndCheckAllEndPointsApproximateFaceNet(self):
batch_size = 5 batch_size = 5
...@@ -267,6 +297,9 @@ class MobilenetV1Test(tf.test.TestCase): ...@@ -267,6 +297,9 @@ class MobilenetV1Test(tf.test.TestCase):
normalizer_fn=slim.batch_norm): normalizer_fn=slim.batch_norm):
_, end_points = mobilenet_v1.mobilenet_v1_base( _, end_points = mobilenet_v1.mobilenet_v1_base(
inputs, final_endpoint='Conv2d_13_pointwise', depth_multiplier=0.75) inputs, final_endpoint='Conv2d_13_pointwise', depth_multiplier=0.75)
_, explicit_padding_end_points = mobilenet_v1.mobilenet_v1_base(
inputs, final_endpoint='Conv2d_13_pointwise', depth_multiplier=0.75,
use_explicit_padding=True)
# For the Conv2d_0 layer FaceNet has depth=16 # For the Conv2d_0 layer FaceNet has depth=16
endpoints_shapes = {'Conv2d_0': [batch_size, 64, 64, 24], endpoints_shapes = {'Conv2d_0': [batch_size, 64, 64, 24],
'Conv2d_1_depthwise': [batch_size, 64, 64, 24], 'Conv2d_1_depthwise': [batch_size, 64, 64, 24],
...@@ -296,10 +329,17 @@ class MobilenetV1Test(tf.test.TestCase): ...@@ -296,10 +329,17 @@ class MobilenetV1Test(tf.test.TestCase):
'Conv2d_13_depthwise': [batch_size, 4, 4, 768], 'Conv2d_13_depthwise': [batch_size, 4, 4, 768],
'Conv2d_13_pointwise': [batch_size, 4, 4, 768]} 'Conv2d_13_pointwise': [batch_size, 4, 4, 768]}
self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys())
for endpoint_name, expected_shape in endpoints_shapes.items(): for endpoint_name, expected_shape in endpoints_shapes.iteritems():
self.assertTrue(endpoint_name in end_points) self.assertTrue(endpoint_name in end_points)
self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), self.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
expected_shape) expected_shape)
self.assertItemsEqual(endpoints_shapes.keys(),
explicit_padding_end_points.keys())
for endpoint_name, expected_shape in endpoints_shapes.iteritems():
self.assertTrue(endpoint_name in explicit_padding_end_points)
self.assertListEqual(
explicit_padding_end_points[endpoint_name].get_shape().as_list(),
expected_shape)
def testModelHasExpectedNumberOfParameters(self): def testModelHasExpectedNumberOfParameters(self):
batch_size = 5 batch_size = 5
...@@ -310,7 +350,7 @@ class MobilenetV1Test(tf.test.TestCase): ...@@ -310,7 +350,7 @@ class MobilenetV1Test(tf.test.TestCase):
mobilenet_v1.mobilenet_v1_base(inputs) mobilenet_v1.mobilenet_v1_base(inputs)
total_params, _ = slim.model_analyzer.analyze_vars( total_params, _ = slim.model_analyzer.analyze_vars(
slim.get_model_variables()) slim.get_model_variables())
self.assertAlmostEqual(3217920, total_params) self.assertAlmostEqual(3217920L, total_params)
def testBuildEndPointsWithDepthMultiplierLessThanOne(self): def testBuildEndPointsWithDepthMultiplierLessThanOne(self):
batch_size = 5 batch_size = 5
...@@ -398,8 +438,8 @@ class MobilenetV1Test(tf.test.TestCase): ...@@ -398,8 +438,8 @@ class MobilenetV1Test(tf.test.TestCase):
def testGlobalPoolUnknownImageShape(self): def testGlobalPoolUnknownImageShape(self):
tf.reset_default_graph() tf.reset_default_graph()
batch_size = 2 batch_size = 1
height, width = 300, 400 height, width = 250, 300
num_classes = 1000 num_classes = 1000
input_np = np.random.uniform(0, 1, (batch_size, height, width, 3)) input_np = np.random.uniform(0, 1, (batch_size, height, width, 3))
with self.test_session() as sess: with self.test_session() as sess:
...@@ -413,7 +453,7 @@ class MobilenetV1Test(tf.test.TestCase): ...@@ -413,7 +453,7 @@ class MobilenetV1Test(tf.test.TestCase):
feed_dict = {inputs: input_np} feed_dict = {inputs: input_np}
tf.global_variables_initializer().run() tf.global_variables_initializer().run()
pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict) pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict)
self.assertListEqual(list(pre_pool_out.shape), [batch_size, 10, 13, 1024]) self.assertListEqual(list(pre_pool_out.shape), [batch_size, 8, 10, 1024])
def testUnknowBatchSize(self): def testUnknowBatchSize(self):
batch_size = 1 batch_size = 1
......
...@@ -44,8 +44,7 @@ python tensorflow_models/research/slim/eval_image_classifier \ ...@@ -44,8 +44,7 @@ python tensorflow_models/research/slim/eval_image_classifier \
--dataset_name=imagenet \ --dataset_name=imagenet \
--dataset_split_name=validation \ --dataset_split_name=validation \
--model_name=nasnet_mobile \ --model_name=nasnet_mobile \
--eval_image_size=224 \ --eval_image_size=224
--moving_average_decay=0.9999
``` ```
Run eval with the NASNet-A large ImageNet model Run eval with the NASNet-A large ImageNet model
...@@ -61,6 +60,5 @@ python tensorflow_models/research/slim/eval_image_classifier \ ...@@ -61,6 +60,5 @@ python tensorflow_models/research/slim/eval_image_classifier \
--dataset_name=imagenet \ --dataset_name=imagenet \
--dataset_split_name=validation \ --dataset_split_name=validation \
--model_name=nasnet_large \ --model_name=nasnet_large \
--eval_image_size=331 \ --eval_image_size=331
--moving_average_decay=0.9999
``` ```
...@@ -35,13 +35,13 @@ slim = tf.contrib.slim ...@@ -35,13 +35,13 @@ slim = tf.contrib.slim
# cosine (single period) learning rate decay # cosine (single period) learning rate decay
# auxiliary head loss weighting: 0.4 # auxiliary head loss weighting: 0.4
# clip global norm of all gradients by 5 # clip global norm of all gradients by 5
def _cifar_config(is_training=True): def _cifar_config(is_training=True, use_aux_head=True):
drop_path_keep_prob = 1.0 if not is_training else 0.6 drop_path_keep_prob = 1.0 if not is_training else 0.6
return tf.contrib.training.HParams( return tf.contrib.training.HParams(
stem_multiplier=3.0, stem_multiplier=3.0,
drop_path_keep_prob=drop_path_keep_prob, drop_path_keep_prob=drop_path_keep_prob,
num_cells=18, num_cells=18,
use_aux_head=1, use_aux_head=int(use_aux_head),
num_conv_filters=32, num_conv_filters=32,
dense_dropout_keep_prob=1.0, dense_dropout_keep_prob=1.0,
filter_scaling_rate=2.0, filter_scaling_rate=2.0,
...@@ -65,7 +65,7 @@ def _cifar_config(is_training=True): ...@@ -65,7 +65,7 @@ def _cifar_config(is_training=True):
# auxiliary head loss weighting: 0.4 # auxiliary head loss weighting: 0.4
# label smoothing: 0.1 # label smoothing: 0.1
# clip global norm of all gradients by 10 # clip global norm of all gradients by 10
def _large_imagenet_config(is_training=True): def _large_imagenet_config(is_training=True, use_aux_head=True):
drop_path_keep_prob = 1.0 if not is_training else 0.7 drop_path_keep_prob = 1.0 if not is_training else 0.7
return tf.contrib.training.HParams( return tf.contrib.training.HParams(
stem_multiplier=3.0, stem_multiplier=3.0,
...@@ -74,7 +74,7 @@ def _large_imagenet_config(is_training=True): ...@@ -74,7 +74,7 @@ def _large_imagenet_config(is_training=True):
filter_scaling_rate=2.0, filter_scaling_rate=2.0,
num_conv_filters=168, num_conv_filters=168,
drop_path_keep_prob=drop_path_keep_prob, drop_path_keep_prob=drop_path_keep_prob,
use_aux_head=1, use_aux_head=int(use_aux_head),
num_reduction_layers=2, num_reduction_layers=2,
data_format='NHWC', data_format='NHWC',
skip_reduction_layer_input=1, skip_reduction_layer_input=1,
...@@ -92,7 +92,7 @@ def _large_imagenet_config(is_training=True): ...@@ -92,7 +92,7 @@ def _large_imagenet_config(is_training=True):
# auxiliary head weighting: 0.4 # auxiliary head weighting: 0.4
# label smoothing: 0.1 # label smoothing: 0.1
# clip global norm of all gradients by 10 # clip global norm of all gradients by 10
def _mobile_imagenet_config(): def _mobile_imagenet_config(use_aux_head=True):
return tf.contrib.training.HParams( return tf.contrib.training.HParams(
stem_multiplier=1.0, stem_multiplier=1.0,
dense_dropout_keep_prob=0.5, dense_dropout_keep_prob=0.5,
...@@ -100,7 +100,7 @@ def _mobile_imagenet_config(): ...@@ -100,7 +100,7 @@ def _mobile_imagenet_config():
filter_scaling_rate=2.0, filter_scaling_rate=2.0,
drop_path_keep_prob=1.0, drop_path_keep_prob=1.0,
num_conv_filters=44, num_conv_filters=44,
use_aux_head=1, use_aux_head=int(use_aux_head),
num_reduction_layers=2, num_reduction_layers=2,
data_format='NHWC', data_format='NHWC',
skip_reduction_layer_input=0, skip_reduction_layer_input=0,
...@@ -280,9 +280,9 @@ def _cifar_stem(inputs, hparams): ...@@ -280,9 +280,9 @@ def _cifar_stem(inputs, hparams):
def build_nasnet_cifar( def build_nasnet_cifar(
images, num_classes, is_training=True): images, num_classes, is_training=True, use_aux_head=True):
"""Build NASNet model for the Cifar Dataset.""" """Build NASNet model for the Cifar Dataset."""
hparams = _cifar_config(is_training=is_training) hparams = _cifar_config(is_training=is_training, use_aux_head=use_aux_head)
if tf.test.is_gpu_available() and hparams.data_format == 'NHWC': if tf.test.is_gpu_available() and hparams.data_format == 'NHWC':
tf.logging.info('A GPU is available on the machine, consider using NCHW ' tf.logging.info('A GPU is available on the machine, consider using NCHW '
...@@ -325,9 +325,10 @@ build_nasnet_cifar.default_image_size = 32 ...@@ -325,9 +325,10 @@ build_nasnet_cifar.default_image_size = 32
def build_nasnet_mobile(images, num_classes, def build_nasnet_mobile(images, num_classes,
is_training=True, is_training=True,
final_endpoint=None): final_endpoint=None,
use_aux_head=True):
"""Build NASNet Mobile model for the ImageNet Dataset.""" """Build NASNet Mobile model for the ImageNet Dataset."""
hparams = _mobile_imagenet_config() hparams = _mobile_imagenet_config(use_aux_head=use_aux_head)
if tf.test.is_gpu_available() and hparams.data_format == 'NHWC': if tf.test.is_gpu_available() and hparams.data_format == 'NHWC':
tf.logging.info('A GPU is available on the machine, consider using NCHW ' tf.logging.info('A GPU is available on the machine, consider using NCHW '
...@@ -373,9 +374,11 @@ build_nasnet_mobile.default_image_size = 224 ...@@ -373,9 +374,11 @@ build_nasnet_mobile.default_image_size = 224
def build_nasnet_large(images, num_classes, def build_nasnet_large(images, num_classes,
is_training=True, is_training=True,
final_endpoint=None): final_endpoint=None,
use_aux_head=True):
"""Build NASNet Large model for the ImageNet Dataset.""" """Build NASNet Large model for the ImageNet Dataset."""
hparams = _large_imagenet_config(is_training=is_training) hparams = _large_imagenet_config(is_training=is_training,
use_aux_head=use_aux_head)
if tf.test.is_gpu_available() and hparams.data_format == 'NHWC': if tf.test.is_gpu_available() and hparams.data_format == 'NHWC':
tf.logging.info('A GPU is available on the machine, consider using NCHW ' tf.logging.info('A GPU is available on the machine, consider using NCHW '
...@@ -499,7 +502,7 @@ def _build_nasnet_base(images, ...@@ -499,7 +502,7 @@ def _build_nasnet_base(images,
with tf.variable_scope('final_layer'): with tf.variable_scope('final_layer'):
net = tf.nn.relu(net) net = tf.nn.relu(net)
net = nasnet_utils.global_avg_pool(net) net = nasnet_utils.global_avg_pool(net)
if add_and_check_endpoint('global_pool', net) or num_classes is None: if add_and_check_endpoint('global_pool', net) or not num_classes:
return net, end_points return net, end_points
net = slim.dropout(net, hparams.dense_dropout_keep_prob, scope='dropout') net = slim.dropout(net, hparams.dense_dropout_keep_prob, scope='dropout')
logits = slim.fully_connected(net, num_classes) logits = slim.fully_connected(net, num_classes)
......
...@@ -158,6 +158,19 @@ class NASNetTest(tf.test.TestCase): ...@@ -158,6 +158,19 @@ class NASNetTest(tf.test.TestCase):
self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), self.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
expected_shape) expected_shape)
def testNoAuxHeadCifarModel(self):
batch_size = 5
height, width = 32, 32
num_classes = 10
for use_aux_head in (True, False):
tf.reset_default_graph()
inputs = tf.random_uniform((batch_size, height, width, 3))
tf.train.create_global_step()
with slim.arg_scope(nasnet.nasnet_cifar_arg_scope()):
_, end_points = nasnet.build_nasnet_cifar(inputs, num_classes,
use_aux_head=use_aux_head)
self.assertEqual('AuxLogits' in end_points, use_aux_head)
def testAllEndPointsShapesMobileModel(self): def testAllEndPointsShapesMobileModel(self):
batch_size = 5 batch_size = 5
height, width = 224, 224 height, width = 224, 224
...@@ -194,6 +207,19 @@ class NASNetTest(tf.test.TestCase): ...@@ -194,6 +207,19 @@ class NASNetTest(tf.test.TestCase):
self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), self.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
expected_shape) expected_shape)
def testNoAuxHeadMobileModel(self):
batch_size = 5
height, width = 224, 224
num_classes = 1000
for use_aux_head in (True, False):
tf.reset_default_graph()
inputs = tf.random_uniform((batch_size, height, width, 3))
tf.train.create_global_step()
with slim.arg_scope(nasnet.nasnet_mobile_arg_scope()):
_, end_points = nasnet.build_nasnet_mobile(inputs, num_classes,
use_aux_head=use_aux_head)
self.assertEqual('AuxLogits' in end_points, use_aux_head)
def testAllEndPointsShapesLargeModel(self): def testAllEndPointsShapesLargeModel(self):
batch_size = 5 batch_size = 5
height, width = 331, 331 height, width = 331, 331
...@@ -236,6 +262,19 @@ class NASNetTest(tf.test.TestCase): ...@@ -236,6 +262,19 @@ class NASNetTest(tf.test.TestCase):
self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), self.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
expected_shape) expected_shape)
def testNoAuxHeadLargeModel(self):
batch_size = 5
height, width = 331, 331
num_classes = 1000
for use_aux_head in (True, False):
tf.reset_default_graph()
inputs = tf.random_uniform((batch_size, height, width, 3))
tf.train.create_global_step()
with slim.arg_scope(nasnet.nasnet_large_arg_scope()):
_, end_points = nasnet.build_nasnet_large(inputs, num_classes,
use_aux_head=use_aux_head)
self.assertEqual('AuxLogits' in end_points, use_aux_head)
def testVariablesSetDeviceMobileModel(self): def testVariablesSetDeviceMobileModel(self):
batch_size = 5 batch_size = 5
height, width = 224, 224 height, width = 224, 224
......
...@@ -289,8 +289,7 @@ class NasNetABaseCell(object): ...@@ -289,8 +289,7 @@ class NasNetABaseCell(object):
net = slim.conv2d(net, num_filters, 1, scope='1x1') net = slim.conv2d(net, num_filters, 1, scope='1x1')
net = slim.batch_norm(net, scope='beginning_bn') net = slim.batch_norm(net, scope='beginning_bn')
split_axis = get_channel_index() split_axis = get_channel_index()
net = tf.split( net = tf.split(axis=split_axis, num_or_size_splits=1, value=net)
axis=split_axis, num_or_size_splits=1, value=net)
for split in net: for split in net:
assert int(split.shape[split_axis] == int(self._num_conv_filters * assert int(split.shape[split_axis] == int(self._num_conv_filters *
self._filter_scaling)) self._filter_scaling))
...@@ -398,31 +397,52 @@ class NasNetABaseCell(object): ...@@ -398,31 +397,52 @@ class NasNetABaseCell(object):
net = tf.concat(values=states_to_combine, axis=concat_axis) net = tf.concat(values=states_to_combine, axis=concat_axis)
return net return net
def _apply_drop_path(self, net): @tf.contrib.framework.add_arg_scope # No public API. For internal use only.
"""Apply drop_path regularization to net.""" def _apply_drop_path(self, net, current_step=None,
use_summaries=True, drop_connect_version='v3'):
"""Apply drop_path regularization.
Args:
net: the Tensor that gets drop_path regularization applied.
current_step: a float32 Tensor with the current global_step value,
to be divided by hparams.total_training_steps. Usually None, which
defaults to tf.train.get_or_create_global_step() properly casted.
use_summaries: a Python boolean. If set to False, no summaries are output.
drop_connect_version: one of 'v1', 'v2', 'v3', controlling whether
the dropout rate is scaled by current_step (v1), layer (v2), or
both (v3, the default).
Returns:
The dropped-out value of `net`.
"""
drop_path_keep_prob = self._drop_path_keep_prob drop_path_keep_prob = self._drop_path_keep_prob
if drop_path_keep_prob < 1.0: if drop_path_keep_prob < 1.0:
# Scale keep prob by layer number assert drop_connect_version in ['v1', 'v2', 'v3']
assert self._cell_num != -1 if drop_connect_version in ['v2', 'v3']:
# The added 2 is for the reduction cells # Scale keep prob by layer number
num_cells = self._total_num_cells assert self._cell_num != -1
layer_ratio = (self._cell_num + 1)/float(num_cells) # The added 2 is for the reduction cells
with tf.device('/cpu:0'): num_cells = self._total_num_cells
tf.summary.scalar('layer_ratio', layer_ratio) layer_ratio = (self._cell_num + 1)/float(num_cells)
drop_path_keep_prob = 1 - layer_ratio * (1 - drop_path_keep_prob) if use_summaries:
# Decrease the keep probability over time with tf.device('/cpu:0'):
current_step = tf.cast(tf.train.get_or_create_global_step(), tf.summary.scalar('layer_ratio', layer_ratio)
tf.float32) drop_path_keep_prob = 1 - layer_ratio * (1 - drop_path_keep_prob)
drop_path_burn_in_steps = self._total_training_steps if drop_connect_version in ['v1', 'v3']:
current_ratio = ( # Decrease the keep probability over time
current_step / drop_path_burn_in_steps) if not current_step:
current_ratio = tf.minimum(1.0, current_ratio) current_step = tf.cast(tf.train.get_or_create_global_step(),
with tf.device('/cpu:0'): tf.float32)
tf.summary.scalar('current_ratio', current_ratio) drop_path_burn_in_steps = self._total_training_steps
drop_path_keep_prob = ( current_ratio = current_step / drop_path_burn_in_steps
1 - current_ratio * (1 - drop_path_keep_prob)) current_ratio = tf.minimum(1.0, current_ratio)
with tf.device('/cpu:0'): if use_summaries:
tf.summary.scalar('drop_path_keep_prob', drop_path_keep_prob) with tf.device('/cpu:0'):
tf.summary.scalar('current_ratio', current_ratio)
drop_path_keep_prob = (1 - current_ratio * (1 - drop_path_keep_prob))
if use_summaries:
with tf.device('/cpu:0'):
tf.summary.scalar('drop_path_keep_prob', drop_path_keep_prob)
net = drop_path(net, drop_path_keep_prob) net = drop_path(net, drop_path_keep_prob)
return net return net
......
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