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(
srcs = ["nets/alexnet.py"],
srcs_version = "PY2AND3",
deps = [
# "//tensorflow"
# "//tensorflow",
],
)
......@@ -296,7 +296,7 @@ py_library(
srcs = ["nets/inception_utils.py"],
srcs_version = "PY2AND3",
deps = [
# "//tensorflow"
# "//tensorflow",
],
)
......@@ -345,7 +345,7 @@ py_library(
srcs = ["nets/inception_resnet_v2.py"],
srcs_version = "PY2AND3",
deps = [
# "//tensorflow"
# "//tensorflow",
],
)
......@@ -425,7 +425,7 @@ py_library(
srcs = ["nets/mobilenet_v1.py"],
srcs_version = "PY2AND3",
deps = [
# "//tensorflow"
# "//tensorflow",
],
)
......@@ -511,7 +511,7 @@ py_library(
srcs = ["nets/overfeat.py"],
srcs_version = "PY2AND3",
deps = [
# "//tensorflow"
# "//tensorflow",
],
)
......@@ -531,7 +531,7 @@ py_library(
srcs = ["nets/pix2pix.py"],
srcs_version = "PY2AND3",
deps = [
# "//tensorflow"
# "//tensorflow",
],
)
......@@ -550,7 +550,7 @@ py_library(
srcs = ["nets/resnet_utils.py"],
srcs_version = "PY2AND3",
deps = [
# "//tensorflow"
# "//tensorflow",
],
)
......@@ -607,7 +607,7 @@ py_library(
srcs = ["nets/vgg.py"],
srcs_version = "PY2AND3",
deps = [
# "//tensorflow"
# "//tensorflow",
],
)
......@@ -646,6 +646,7 @@ py_test(
py_binary(
name = "train_image_classifier",
srcs = ["train_image_classifier.py"],
paropts = ["--compress"],
deps = [
":dataset_factory",
":model_deploy",
......@@ -669,6 +670,7 @@ py_binary(
py_binary(
name = "export_inference_graph",
srcs = ["export_inference_graph.py"],
paropts = ["--compress"],
deps = [
":dataset_factory",
":nets_factory",
......
......@@ -92,9 +92,7 @@ import random
import sys
import threading
import google3
import numpy as np
from six.moves import xrange
import tensorflow as tf
tf.app.flags.DEFINE_string('train_directory', '/tmp/',
......
......@@ -51,7 +51,6 @@ from __future__ import print_function
import os
import os.path
import sys
from six.moves import xrange
if __name__ == '__main__':
......
......@@ -85,7 +85,6 @@ import glob
import os.path
import sys
import xml.etree.ElementTree as ET
from six.moves import xrange
class BoundingBox(object):
......
......@@ -28,7 +28,7 @@ from preprocessing import preprocessing_factory
slim = tf.contrib.slim
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(
'max_num_batches', None,
......
......@@ -50,7 +50,7 @@ class AlexnetV2Test(tf.test.TestCase):
def testGlobalPool(self):
batch_size = 1
height, width = 300, 400
height, width = 256, 256
num_classes = 1000
with self.test_session():
inputs = tf.random_uniform((batch_size, height, width, 3))
......
......@@ -18,7 +18,7 @@ from __future__ import division
from __future__ import print_function
import numpy as np
from six.moves import xrange
import tensorflow as tf
layers = tf.contrib.layers
......
......@@ -19,7 +19,6 @@ from __future__ import print_function
from math import log
from six.moves import xrange
import tensorflow as tf
slim = tf.contrib.slim
......
......@@ -18,7 +18,6 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from six.moves import xrange
import tensorflow as tf
from nets import dcgan
......
......@@ -116,7 +116,7 @@ class InceptionTest(tf.test.TestCase):
if endpoint != 'PreAuxLogits':
self.assertTrue(out_tensor.op.name.startswith(
'InceptionResnetV2/' + endpoint))
self.assertItemsEqual(endpoints[:index+1], end_points)
self.assertItemsEqual(endpoints[:index+1], end_points.keys())
def testBuildAndCheckAllEndPointsUptoPreAuxLogits(self):
batch_size = 5
......@@ -227,8 +227,8 @@ class InceptionTest(tf.test.TestCase):
[batch_size, 3, 3, 1536])
def testGlobalPool(self):
batch_size = 2
height, width = 400, 600
batch_size = 1
height, width = 330, 400
num_classes = 1000
with self.test_session():
inputs = tf.random_uniform((batch_size, height, width, 3))
......@@ -238,11 +238,11 @@ class InceptionTest(tf.test.TestCase):
[batch_size, num_classes])
pre_pool = end_points['Conv2d_7b_1x1']
self.assertListEqual(pre_pool.get_shape().as_list(),
[batch_size, 11, 17, 1536])
[batch_size, 8, 11, 1536])
def testGlobalPoolUnknownImageShape(self):
batch_size = 2
height, width = 400, 600
batch_size = 1
height, width = 330, 400
num_classes = 1000
with self.test_session() as sess:
inputs = tf.placeholder(tf.float32, (batch_size, None, None, 3))
......@@ -257,7 +257,7 @@ class InceptionTest(tf.test.TestCase):
logits_out, pre_pool_out = sess.run([logits, pre_pool],
{inputs: images.eval()})
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):
batch_size = 1
......
......@@ -86,7 +86,7 @@ class InceptionV1Test(tf.test.TestCase):
inputs, final_endpoint=endpoint)
self.assertTrue(out_tensor.op.name.startswith(
'InceptionV1/' + endpoint))
self.assertItemsEqual(endpoints[:index+1], end_points)
self.assertItemsEqual(endpoints[:index+1], end_points.keys())
def testBuildAndCheckAllEndPointsUptoMixed5c(self):
batch_size = 5
......@@ -159,8 +159,8 @@ class InceptionV1Test(tf.test.TestCase):
def testGlobalPoolUnknownImageShape(self):
tf.reset_default_graph()
batch_size = 2
height, width = 300, 400
batch_size = 1
height, width = 250, 300
num_classes = 1000
input_np = np.random.uniform(0, 1, (batch_size, height, width, 3))
with self.test_session() as sess:
......@@ -174,7 +174,7 @@ class InceptionV1Test(tf.test.TestCase):
feed_dict = {inputs: input_np}
tf.global_variables_initializer().run()
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):
batch_size = 1
......
......@@ -85,7 +85,7 @@ class InceptionV2Test(tf.test.TestCase):
inputs, final_endpoint=endpoint)
self.assertTrue(out_tensor.op.name.startswith(
'InceptionV2/' + endpoint))
self.assertItemsEqual(endpoints[:index+1], end_points)
self.assertItemsEqual(endpoints[:index+1], end_points.keys())
def testBuildAndCheckAllEndPointsUptoMixed5c(self):
batch_size = 5
......@@ -273,8 +273,8 @@ class InceptionV2Test(tf.test.TestCase):
def testGlobalPoolUnknownImageShape(self):
tf.reset_default_graph()
batch_size = 2
height, width = 300, 400
batch_size = 1
height, width = 250, 300
num_classes = 1000
input_np = np.random.uniform(0, 1, (batch_size, height, width, 3))
with self.test_session() as sess:
......@@ -288,7 +288,7 @@ class InceptionV2Test(tf.test.TestCase):
feed_dict = {inputs: input_np}
tf.global_variables_initializer().run()
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):
batch_size = 1
......
......@@ -88,7 +88,7 @@ class InceptionV3Test(tf.test.TestCase):
inputs, final_endpoint=endpoint)
self.assertTrue(out_tensor.op.name.startswith(
'InceptionV3/' + endpoint))
self.assertItemsEqual(endpoints[:index+1], end_points)
self.assertItemsEqual(endpoints[:index+1], end_points.keys())
def testBuildAndCheckAllEndPointsUptoMixed7c(self):
batch_size = 5
......@@ -240,8 +240,8 @@ class InceptionV3Test(tf.test.TestCase):
def testGlobalPoolUnknownImageShape(self):
tf.reset_default_graph()
batch_size = 2
height, width = 400, 600
batch_size = 1
height, width = 330, 400
num_classes = 1000
input_np = np.random.uniform(0, 1, (batch_size, height, width, 3))
with self.test_session() as sess:
......@@ -254,7 +254,7 @@ class InceptionV3Test(tf.test.TestCase):
feed_dict = {inputs: input_np}
tf.global_variables_initializer().run()
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):
batch_size = 1
......
......@@ -146,7 +146,7 @@ class InceptionTest(tf.test.TestCase):
inputs, final_endpoint=endpoint)
self.assertTrue(out_tensor.op.name.startswith(
'InceptionV4/' + endpoint))
self.assertItemsEqual(all_endpoints[:index+1], end_points)
self.assertItemsEqual(all_endpoints[:index+1], end_points.keys())
def testVariablesSetDevice(self):
batch_size = 5
......@@ -177,8 +177,8 @@ class InceptionTest(tf.test.TestCase):
[batch_size, 3, 3, 1536])
def testGlobalPool(self):
batch_size = 2
height, width = 400, 600
batch_size = 1
height, width = 350, 400
num_classes = 1000
inputs = tf.random_uniform((batch_size, height, width, 3))
logits, end_points = inception.inception_v4(inputs, num_classes)
......@@ -187,11 +187,11 @@ class InceptionTest(tf.test.TestCase):
[batch_size, num_classes])
pre_pool = end_points['Mixed_7d']
self.assertListEqual(pre_pool.get_shape().as_list(),
[batch_size, 11, 17, 1536])
[batch_size, 9, 11, 1536])
def testGlobalPoolUnknownImageShape(self):
batch_size = 2
height, width = 400, 600
batch_size = 1
height, width = 350, 400
num_classes = 1000
with self.test_session() as sess:
inputs = tf.placeholder(tf.float32, (batch_size, None, None, 3))
......@@ -206,7 +206,7 @@ class InceptionTest(tf.test.TestCase):
logits_out, pre_pool_out = sess.run([logits, pre_pool],
{inputs: images.eval()})
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):
batch_size = 1
......
......@@ -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,
final_endpoint='Conv2d_13_pointwise',
min_depth=8,
depth_multiplier=1.0,
conv_defs=None,
output_stride=None,
use_explicit_padding=False,
scope=None):
"""Mobilenet v1.
......@@ -171,6 +198,9 @@ def mobilenet_v1_base(inputs,
if necessary to prevent the network from reducing the spatial resolution
of the activation maps. Allowed values are 8 (accurate fully convolutional
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.
Returns:
......@@ -196,8 +226,11 @@ def mobilenet_v1_base(inputs,
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.')
padding = 'SAME'
if use_explicit_padding:
padding = 'VALID'
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
# activations, i.e., the running product of convolution strides up to the
# current network layer. This allows us to invoke atrous convolution
......@@ -226,6 +259,8 @@ def mobilenet_v1_base(inputs,
if isinstance(conv_def, Conv):
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,
stride=conv_def.stride,
normalizer_fn=slim.batch_norm,
......@@ -239,6 +274,8 @@ def mobilenet_v1_base(inputs,
# By passing filters=None
# 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,
depth_multiplier=1,
stride=layer_stride,
......
......@@ -104,7 +104,7 @@ class MobilenetV1Test(tf.test.TestCase):
inputs, final_endpoint=endpoint)
self.assertTrue(out_tensor.op.name.startswith(
'MobilenetV1/' + endpoint))
self.assertItemsEqual(endpoints[:index+1], end_points)
self.assertItemsEqual(endpoints[:index+1], end_points.keys())
def testBuildCustomNetworkUsingConvDefs(self):
batch_size = 5
......@@ -137,6 +137,9 @@ class MobilenetV1Test(tf.test.TestCase):
normalizer_fn=slim.batch_norm):
_, end_points = mobilenet_v1.mobilenet_v1_base(
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],
'Conv2d_1_depthwise': [batch_size, 112, 112, 32],
'Conv2d_1_pointwise': [batch_size, 112, 112, 64],
......@@ -165,10 +168,17 @@ class MobilenetV1Test(tf.test.TestCase):
'Conv2d_13_depthwise': [batch_size, 7, 7, 1024],
'Conv2d_13_pointwise': [batch_size, 7, 7, 1024]}
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.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
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):
batch_size = 5
......@@ -181,6 +191,9 @@ class MobilenetV1Test(tf.test.TestCase):
_, end_points = mobilenet_v1.mobilenet_v1_base(
inputs, output_stride=output_stride,
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],
'Conv2d_1_depthwise': [batch_size, 112, 112, 32],
'Conv2d_1_pointwise': [batch_size, 112, 112, 64],
......@@ -209,10 +222,17 @@ class MobilenetV1Test(tf.test.TestCase):
'Conv2d_13_depthwise': [batch_size, 14, 14, 1024],
'Conv2d_13_pointwise': [batch_size, 14, 14, 1024]}
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.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
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):
batch_size = 5
......@@ -225,6 +245,9 @@ class MobilenetV1Test(tf.test.TestCase):
_, end_points = mobilenet_v1.mobilenet_v1_base(
inputs, output_stride=output_stride,
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],
'Conv2d_1_depthwise': [batch_size, 112, 112, 32],
'Conv2d_1_pointwise': [batch_size, 112, 112, 64],
......@@ -253,10 +276,17 @@ class MobilenetV1Test(tf.test.TestCase):
'Conv2d_13_depthwise': [batch_size, 28, 28, 1024],
'Conv2d_13_pointwise': [batch_size, 28, 28, 1024]}
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.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
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):
batch_size = 5
......@@ -267,6 +297,9 @@ class MobilenetV1Test(tf.test.TestCase):
normalizer_fn=slim.batch_norm):
_, end_points = mobilenet_v1.mobilenet_v1_base(
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
endpoints_shapes = {'Conv2d_0': [batch_size, 64, 64, 24],
'Conv2d_1_depthwise': [batch_size, 64, 64, 24],
......@@ -296,10 +329,17 @@ class MobilenetV1Test(tf.test.TestCase):
'Conv2d_13_depthwise': [batch_size, 4, 4, 768],
'Conv2d_13_pointwise': [batch_size, 4, 4, 768]}
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.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
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):
batch_size = 5
......@@ -310,7 +350,7 @@ class MobilenetV1Test(tf.test.TestCase):
mobilenet_v1.mobilenet_v1_base(inputs)
total_params, _ = slim.model_analyzer.analyze_vars(
slim.get_model_variables())
self.assertAlmostEqual(3217920, total_params)
self.assertAlmostEqual(3217920L, total_params)
def testBuildEndPointsWithDepthMultiplierLessThanOne(self):
batch_size = 5
......@@ -398,8 +438,8 @@ class MobilenetV1Test(tf.test.TestCase):
def testGlobalPoolUnknownImageShape(self):
tf.reset_default_graph()
batch_size = 2
height, width = 300, 400
batch_size = 1
height, width = 250, 300
num_classes = 1000
input_np = np.random.uniform(0, 1, (batch_size, height, width, 3))
with self.test_session() as sess:
......@@ -413,7 +453,7 @@ class MobilenetV1Test(tf.test.TestCase):
feed_dict = {inputs: input_np}
tf.global_variables_initializer().run()
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):
batch_size = 1
......
......@@ -44,8 +44,7 @@ python tensorflow_models/research/slim/eval_image_classifier \
--dataset_name=imagenet \
--dataset_split_name=validation \
--model_name=nasnet_mobile \
--eval_image_size=224 \
--moving_average_decay=0.9999
--eval_image_size=224
```
Run eval with the NASNet-A large ImageNet model
......@@ -61,6 +60,5 @@ python tensorflow_models/research/slim/eval_image_classifier \
--dataset_name=imagenet \
--dataset_split_name=validation \
--model_name=nasnet_large \
--eval_image_size=331 \
--moving_average_decay=0.9999
--eval_image_size=331
```
......@@ -35,13 +35,13 @@ slim = tf.contrib.slim
# cosine (single period) learning rate decay
# auxiliary head loss weighting: 0.4
# 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
return tf.contrib.training.HParams(
stem_multiplier=3.0,
drop_path_keep_prob=drop_path_keep_prob,
num_cells=18,
use_aux_head=1,
use_aux_head=int(use_aux_head),
num_conv_filters=32,
dense_dropout_keep_prob=1.0,
filter_scaling_rate=2.0,
......@@ -65,7 +65,7 @@ def _cifar_config(is_training=True):
# auxiliary head loss weighting: 0.4
# label smoothing: 0.1
# 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
return tf.contrib.training.HParams(
stem_multiplier=3.0,
......@@ -74,7 +74,7 @@ def _large_imagenet_config(is_training=True):
filter_scaling_rate=2.0,
num_conv_filters=168,
drop_path_keep_prob=drop_path_keep_prob,
use_aux_head=1,
use_aux_head=int(use_aux_head),
num_reduction_layers=2,
data_format='NHWC',
skip_reduction_layer_input=1,
......@@ -92,7 +92,7 @@ def _large_imagenet_config(is_training=True):
# auxiliary head weighting: 0.4
# label smoothing: 0.1
# 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(
stem_multiplier=1.0,
dense_dropout_keep_prob=0.5,
......@@ -100,7 +100,7 @@ def _mobile_imagenet_config():
filter_scaling_rate=2.0,
drop_path_keep_prob=1.0,
num_conv_filters=44,
use_aux_head=1,
use_aux_head=int(use_aux_head),
num_reduction_layers=2,
data_format='NHWC',
skip_reduction_layer_input=0,
......@@ -280,9 +280,9 @@ def _cifar_stem(inputs, hparams):
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."""
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':
tf.logging.info('A GPU is available on the machine, consider using NCHW '
......@@ -325,9 +325,10 @@ build_nasnet_cifar.default_image_size = 32
def build_nasnet_mobile(images, num_classes,
is_training=True,
final_endpoint=None):
final_endpoint=None,
use_aux_head=True):
"""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':
tf.logging.info('A GPU is available on the machine, consider using NCHW '
......@@ -373,9 +374,11 @@ build_nasnet_mobile.default_image_size = 224
def build_nasnet_large(images, num_classes,
is_training=True,
final_endpoint=None):
final_endpoint=None,
use_aux_head=True):
"""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':
tf.logging.info('A GPU is available on the machine, consider using NCHW '
......@@ -499,7 +502,7 @@ def _build_nasnet_base(images,
with tf.variable_scope('final_layer'):
net = tf.nn.relu(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
net = slim.dropout(net, hparams.dense_dropout_keep_prob, scope='dropout')
logits = slim.fully_connected(net, num_classes)
......
......@@ -158,6 +158,19 @@ class NASNetTest(tf.test.TestCase):
self.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
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):
batch_size = 5
height, width = 224, 224
......@@ -194,6 +207,19 @@ class NASNetTest(tf.test.TestCase):
self.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
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):
batch_size = 5
height, width = 331, 331
......@@ -236,6 +262,19 @@ class NASNetTest(tf.test.TestCase):
self.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
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):
batch_size = 5
height, width = 224, 224
......
......@@ -289,8 +289,7 @@ class NasNetABaseCell(object):
net = slim.conv2d(net, num_filters, 1, scope='1x1')
net = slim.batch_norm(net, scope='beginning_bn')
split_axis = get_channel_index()
net = tf.split(
axis=split_axis, num_or_size_splits=1, value=net)
net = tf.split(axis=split_axis, num_or_size_splits=1, value=net)
for split in net:
assert int(split.shape[split_axis] == int(self._num_conv_filters *
self._filter_scaling))
......@@ -398,29 +397,50 @@ class NasNetABaseCell(object):
net = tf.concat(values=states_to_combine, axis=concat_axis)
return net
def _apply_drop_path(self, net):
"""Apply drop_path regularization to net."""
@tf.contrib.framework.add_arg_scope # No public API. For internal use only.
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
if drop_path_keep_prob < 1.0:
assert drop_connect_version in ['v1', 'v2', 'v3']
if drop_connect_version in ['v2', 'v3']:
# Scale keep prob by layer number
assert self._cell_num != -1
# The added 2 is for the reduction cells
num_cells = self._total_num_cells
layer_ratio = (self._cell_num + 1)/float(num_cells)
if use_summaries:
with tf.device('/cpu:0'):
tf.summary.scalar('layer_ratio', layer_ratio)
drop_path_keep_prob = 1 - layer_ratio * (1 - drop_path_keep_prob)
if drop_connect_version in ['v1', 'v3']:
# Decrease the keep probability over time
if not current_step:
current_step = tf.cast(tf.train.get_or_create_global_step(),
tf.float32)
drop_path_burn_in_steps = self._total_training_steps
current_ratio = (
current_step / drop_path_burn_in_steps)
current_ratio = current_step / drop_path_burn_in_steps
current_ratio = tf.minimum(1.0, current_ratio)
if use_summaries:
with tf.device('/cpu:0'):
tf.summary.scalar('current_ratio', current_ratio)
drop_path_keep_prob = (
1 - current_ratio * (1 - drop_path_keep_prob))
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)
......
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