Commit 1498d941 authored by Yukun Zhu's avatar Yukun Zhu Committed by aquariusjay
Browse files

Update for py3 and some internal changes (#7786)

parent 42c3b8f0
# Lint as: python2, python3
# Copyright 2018 The TensorFlow Authors All Rights Reserved. # Copyright 2018 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
...@@ -25,10 +26,11 @@ from __future__ import division ...@@ -25,10 +26,11 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
import tensorflow as tf import tensorflow as tf
from tensorflow.contrib import slim as contrib_slim
from deeplab.core import utils from deeplab.core import utils
slim = tf.contrib.slim slim = contrib_slim
# Local constants. # Local constants.
_META_ARCHITECTURE_SCOPE = 'meta_architecture' _META_ARCHITECTURE_SCOPE = 'meta_architecture'
......
# Lint as: python2, python3
# Copyright 2018 The TensorFlow Authors All Rights Reserved. # Copyright 2018 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
......
# Lint as: python2, python3
# Copyright 2018 The TensorFlow Authors All Rights Reserved. # Copyright 2018 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
...@@ -14,6 +15,11 @@ ...@@ -14,6 +15,11 @@
# ============================================================================== # ==============================================================================
"""Utility functions related to preprocessing inputs.""" """Utility functions related to preprocessing inputs."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from six.moves import range
from six.moves import zip
import tensorflow as tf import tensorflow as tf
...@@ -63,7 +69,7 @@ def _image_dimensions(image, rank): ...@@ -63,7 +69,7 @@ def _image_dimensions(image, rank):
"""Returns the dimensions of an image tensor. """Returns the dimensions of an image tensor.
Args: Args:
image: A rank-D Tensor. For 3-D of shape: `[height, width, channels]`. image: A rank-D Tensor. For 3-D of shape: `[height, width, channels]`.
rank: The expected rank of the image rank: The expected rank of the image
Returns: Returns:
...@@ -81,6 +87,27 @@ def _image_dimensions(image, rank): ...@@ -81,6 +87,27 @@ def _image_dimensions(image, rank):
] ]
def get_label_resize_method(label):
"""Returns the resize method of labels depending on label dtype.
Args:
label: Groundtruth label tensor.
Returns:
tf.image.ResizeMethod.BILINEAR, if label dtype is floating.
tf.image.ResizeMethod.NEAREST_NEIGHBOR, if label dtype is integer.
Raises:
ValueError: If label is neither floating nor integer.
"""
if label.dtype.is_floating:
return tf.image.ResizeMethod.BILINEAR
elif label.dtype.is_integer:
return tf.image.ResizeMethod.NEAREST_NEIGHBOR
else:
raise ValueError('Label type must be either floating or integer.')
def pad_to_bounding_box(image, offset_height, offset_width, target_height, def pad_to_bounding_box(image, offset_height, offset_width, target_height,
target_width, pad_value): target_width, pad_value):
"""Pads the given image with the given pad_value. """Pads the given image with the given pad_value.
...@@ -200,7 +227,7 @@ def _crop(image, offset_height, offset_width, crop_height, crop_width): ...@@ -200,7 +227,7 @@ def _crop(image, offset_height, offset_width, crop_height, crop_width):
tf.greater_equal(original_shape[1], crop_width)), tf.greater_equal(original_shape[1], crop_width)),
['Crop size greater than the image size.']) ['Crop size greater than the image size.'])
offsets = tf.to_int32(tf.stack([offset_height, offset_width, 0])) offsets = tf.cast(tf.stack([offset_height, offset_width, 0]), tf.int32)
# Use tf.slice instead of crop_to_bounding box as it accepts tensors to # Use tf.slice instead of crop_to_bounding box as it accepts tensors to
# define the crop size. # define the crop size.
...@@ -352,10 +379,11 @@ def randomly_scale_image_and_label(image, label=None, scale=1.0): ...@@ -352,10 +379,11 @@ def randomly_scale_image_and_label(image, label=None, scale=1.0):
new_dim, new_dim,
align_corners=True), [0]) align_corners=True), [0])
if label is not None: if label is not None:
label = tf.squeeze(tf.image.resize_nearest_neighbor( label = tf.image.resize(
tf.expand_dims(label, 0), label,
new_dim, new_dim,
align_corners=True), [0]) method=get_label_resize_method(label),
align_corners=True)
return image, label return image, label
...@@ -394,6 +422,7 @@ def resize_to_range(image, ...@@ -394,6 +422,7 @@ def resize_to_range(image,
min_size=None, min_size=None,
max_size=None, max_size=None,
factor=None, factor=None,
keep_aspect_ratio=True,
align_corners=True, align_corners=True,
label_layout_is_chw=False, label_layout_is_chw=False,
scope=None, scope=None,
...@@ -415,8 +444,12 @@ def resize_to_range(image, ...@@ -415,8 +444,12 @@ def resize_to_range(image,
min_size: (scalar) desired size of the smaller image side. min_size: (scalar) desired size of the smaller image side.
max_size: (scalar) maximum allowed size of the larger image side. Note max_size: (scalar) maximum allowed size of the larger image side. Note
that the output dimension is no larger than max_size and may be slightly that the output dimension is no larger than max_size and may be slightly
smaller than min_size when factor is not None. smaller than max_size when factor is not None.
factor: Make output size multiple of factor plus one. factor: Make output size multiple of factor plus one.
keep_aspect_ratio: Boolean, keep aspect ratio or not. If True, the input
will be resized while keeping the original aspect ratio. If False, the
input will be resized to [max_resize_value, max_resize_value] without
keeping the original aspect ratio.
align_corners: If True, exactly align all 4 corners of input and output. align_corners: If True, exactly align all 4 corners of input and output.
label_layout_is_chw: If true, the label has shape [channel, height, width]. label_layout_is_chw: If true, the label has shape [channel, height, width].
We support this case because for some instance segmentation dataset, the We support this case because for some instance segmentation dataset, the
...@@ -441,8 +474,7 @@ def resize_to_range(image, ...@@ -441,8 +474,7 @@ def resize_to_range(image,
# Modify the max_size to be a multiple of factor plus 1 and make sure the # Modify the max_size to be a multiple of factor plus 1 and make sure the
# max dimension after resizing is no larger than max_size. # max dimension after resizing is no larger than max_size.
if factor is not None: if factor is not None:
max_size = (max_size + (factor - (max_size - 1) % factor) % factor max_size = (max_size - (max_size - 1) % factor)
- factor)
[orig_height, orig_width, _] = resolve_shape(image, rank=3) [orig_height, orig_width, _] = resolve_shape(image, rank=3)
orig_height = tf.cast(orig_height, tf.float32) orig_height = tf.cast(orig_height, tf.float32)
...@@ -451,8 +483,8 @@ def resize_to_range(image, ...@@ -451,8 +483,8 @@ def resize_to_range(image,
# Calculate the larger of the possible sizes # Calculate the larger of the possible sizes
large_scale_factor = min_size / orig_min_size large_scale_factor = min_size / orig_min_size
large_height = tf.to_int32(tf.ceil(orig_height * large_scale_factor)) large_height = tf.cast(tf.floor(orig_height * large_scale_factor), tf.int32)
large_width = tf.to_int32(tf.ceil(orig_width * large_scale_factor)) large_width = tf.cast(tf.floor(orig_width * large_scale_factor), tf.int32)
large_size = tf.stack([large_height, large_width]) large_size = tf.stack([large_height, large_width])
new_size = large_size new_size = large_size
...@@ -461,8 +493,9 @@ def resize_to_range(image, ...@@ -461,8 +493,9 @@ def resize_to_range(image,
# is too big. # is too big.
orig_max_size = tf.maximum(orig_height, orig_width) orig_max_size = tf.maximum(orig_height, orig_width)
small_scale_factor = max_size / orig_max_size small_scale_factor = max_size / orig_max_size
small_height = tf.to_int32(tf.ceil(orig_height * small_scale_factor)) small_height = tf.cast(
small_width = tf.to_int32(tf.ceil(orig_width * small_scale_factor)) tf.floor(orig_height * small_scale_factor), tf.int32)
small_width = tf.cast(tf.floor(orig_width * small_scale_factor), tf.int32)
small_size = tf.stack([small_height, small_width]) small_size = tf.stack([small_height, small_width])
new_size = tf.cond( new_size = tf.cond(
tf.cast(tf.reduce_max(large_size), tf.float32) > max_size, tf.cast(tf.reduce_max(large_size), tf.float32) > max_size,
...@@ -471,19 +504,28 @@ def resize_to_range(image, ...@@ -471,19 +504,28 @@ def resize_to_range(image,
# Ensure that both output sides are multiples of factor plus one. # Ensure that both output sides are multiples of factor plus one.
if factor is not None: if factor is not None:
new_size += (factor - (new_size - 1) % factor) % factor new_size += (factor - (new_size - 1) % factor) % factor
new_tensor_list.append(tf.image.resize_images( if not keep_aspect_ratio:
# If not keep the aspect ratio, we resize everything to max_size, allowing
# us to do pre-processing without extra padding.
new_size = [tf.reduce_max(new_size), tf.reduce_max(new_size)]
new_tensor_list.append(tf.image.resize(
image, new_size, method=method, align_corners=align_corners)) image, new_size, method=method, align_corners=align_corners))
if label is not None: if label is not None:
if label_layout_is_chw: if label_layout_is_chw:
# Input label has shape [channel, height, width]. # Input label has shape [channel, height, width].
resized_label = tf.expand_dims(label, 3) resized_label = tf.expand_dims(label, 3)
resized_label = tf.image.resize_nearest_neighbor( resized_label = tf.image.resize(
resized_label, new_size, align_corners=align_corners) resized_label,
new_size,
method=get_label_resize_method(label),
align_corners=align_corners)
resized_label = tf.squeeze(resized_label, 3) resized_label = tf.squeeze(resized_label, 3)
else: else:
# Input label has shape [height, width, channel]. # Input label has shape [height, width, channel].
resized_label = tf.image.resize_images( resized_label = tf.image.resize(
label, new_size, method=tf.image.ResizeMethod.NEAREST_NEIGHBOR, label,
new_size,
method=get_label_resize_method(label),
align_corners=align_corners) align_corners=align_corners)
new_tensor_list.append(resized_label) new_tensor_list.append(resized_label)
else: else:
......
# Lint as: python2, python3
# Copyright 2018 The TensorFlow Authors All Rights Reserved. # Copyright 2018 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
...@@ -14,10 +15,14 @@ ...@@ -14,10 +15,14 @@
# ============================================================================== # ==============================================================================
"""Tests for preprocess_utils.""" """Tests for preprocess_utils."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import numpy as np import numpy as np
from six.moves import range
import tensorflow as tf import tensorflow as tf
from tensorflow.python.framework import errors
from deeplab.core import preprocess_utils from deeplab.core import preprocess_utils
...@@ -105,7 +110,7 @@ class PreprocessUtilsTest(tf.test.TestCase): ...@@ -105,7 +110,7 @@ class PreprocessUtilsTest(tf.test.TestCase):
[[3., 4.], [[3., 4.],
[5., 3.]]]) [5., 3.]]])
image = tf.convert_to_tensor(numpy_image) image = tf.convert_to_tensor(numpy_image)
tf.set_random_seed(53) tf.compat.v1.set_random_seed(53)
with self.test_session() as sess: with self.test_session() as sess:
actual, is_flipped = preprocess_utils.flip_dim( actual, is_flipped = preprocess_utils.flip_dim(
...@@ -150,7 +155,7 @@ class PreprocessUtilsTest(tf.test.TestCase): ...@@ -150,7 +155,7 @@ class PreprocessUtilsTest(tf.test.TestCase):
crop_height, crop_width = 10, 20 crop_height, crop_width = 10, 20
image = np.random.randint(0, 256, size=(100, 200, 3)) image = np.random.randint(0, 256, size=(100, 200, 3))
tf.set_random_seed(37) tf.compat.v1.set_random_seed(37)
image_placeholder = tf.placeholder(tf.int32, shape=(None, None, 3)) image_placeholder = tf.placeholder(tf.int32, shape=(None, None, 3))
[cropped] = preprocess_utils.random_crop( [cropped] = preprocess_utils.random_crop(
[image_placeholder], crop_height, crop_width) [image_placeholder], crop_height, crop_width)
...@@ -160,7 +165,7 @@ class PreprocessUtilsTest(tf.test.TestCase): ...@@ -160,7 +165,7 @@ class PreprocessUtilsTest(tf.test.TestCase):
self.assertTupleEqual(cropped_image.shape, (crop_height, crop_width, 3)) self.assertTupleEqual(cropped_image.shape, (crop_height, crop_width, 3))
def testReturnDifferentCropAreasOnTwoEvals(self): def testReturnDifferentCropAreasOnTwoEvals(self):
tf.set_random_seed(0) tf.compat.v1.set_random_seed(0)
crop_height, crop_width = 2, 3 crop_height, crop_width = 2, 3
image = np.random.randint(0, 256, size=(100, 200, 3)) image = np.random.randint(0, 256, size=(100, 200, 3))
...@@ -174,7 +179,7 @@ class PreprocessUtilsTest(tf.test.TestCase): ...@@ -174,7 +179,7 @@ class PreprocessUtilsTest(tf.test.TestCase):
self.assertFalse(np.isclose(crop0, crop1).all()) self.assertFalse(np.isclose(crop0, crop1).all())
def testReturnConsistenCropsOfImagesInTheList(self): def testReturnConsistenCropsOfImagesInTheList(self):
tf.set_random_seed(0) tf.compat.v1.set_random_seed(0)
height, width = 10, 20 height, width = 10, 20
crop_height, crop_width = 2, 3 crop_height, crop_width = 2, 3
...@@ -203,7 +208,7 @@ class PreprocessUtilsTest(tf.test.TestCase): ...@@ -203,7 +208,7 @@ class PreprocessUtilsTest(tf.test.TestCase):
[image1, image2], crop_height, crop_width) [image1, image2], crop_height, crop_width)
with self.test_session() as sess: with self.test_session() as sess:
with self.assertRaises(errors.InvalidArgumentError): with self.assertRaises(tf.errors.InvalidArgumentError):
sess.run(cropped, feed_dict={image1: np.random.rand(4, 5, 3), sess.run(cropped, feed_dict={image1: np.random.rand(4, 5, 3),
image2: np.random.rand(4, 6, 1)}) image2: np.random.rand(4, 6, 1)})
...@@ -216,7 +221,7 @@ class PreprocessUtilsTest(tf.test.TestCase): ...@@ -216,7 +221,7 @@ class PreprocessUtilsTest(tf.test.TestCase):
with self.test_session() as sess: with self.test_session() as sess:
with self.assertRaisesWithPredicateMatch( with self.assertRaisesWithPredicateMatch(
errors.InvalidArgumentError, tf.errors.InvalidArgumentError,
'Wrong height for tensor'): 'Wrong height for tensor'):
sess.run(cropped, feed_dict={image1: np.random.rand(4, 5, 3), sess.run(cropped, feed_dict={image1: np.random.rand(4, 5, 3),
image2: np.random.rand(3, 5, 1)}) image2: np.random.rand(3, 5, 1)})
...@@ -230,7 +235,7 @@ class PreprocessUtilsTest(tf.test.TestCase): ...@@ -230,7 +235,7 @@ class PreprocessUtilsTest(tf.test.TestCase):
with self.test_session() as sess: with self.test_session() as sess:
with self.assertRaisesWithPredicateMatch( with self.assertRaisesWithPredicateMatch(
errors.InvalidArgumentError, tf.errors.InvalidArgumentError,
'Crop size greater than the image size.'): 'Crop size greater than the image size.'):
sess.run(cropped, feed_dict={image1: np.random.rand(4, 5, 3), sess.run(cropped, feed_dict={image1: np.random.rand(4, 5, 3),
image2: np.random.rand(4, 5, 1)}) image2: np.random.rand(4, 5, 1)})
...@@ -284,13 +289,13 @@ class PreprocessUtilsTest(tf.test.TestCase): ...@@ -284,13 +289,13 @@ class PreprocessUtilsTest(tf.test.TestCase):
padded_image = preprocess_utils.pad_to_bounding_box( padded_image = preprocess_utils.pad_to_bounding_box(
image_placeholder, 0, 0, 2, 1, 255) image_placeholder, 0, 0, 2, 1, 255)
with self.assertRaisesWithPredicateMatch( with self.assertRaisesWithPredicateMatch(
errors.InvalidArgumentError, tf.errors.InvalidArgumentError,
'target_width must be >= width'): 'target_width must be >= width'):
padded_image.eval(feed_dict={image_placeholder: image}) padded_image.eval(feed_dict={image_placeholder: image})
padded_image = preprocess_utils.pad_to_bounding_box( padded_image = preprocess_utils.pad_to_bounding_box(
image_placeholder, 0, 0, 1, 2, 255) image_placeholder, 0, 0, 1, 2, 255)
with self.assertRaisesWithPredicateMatch( with self.assertRaisesWithPredicateMatch(
errors.InvalidArgumentError, tf.errors.InvalidArgumentError,
'target_height must be >= height'): 'target_height must be >= height'):
padded_image.eval(feed_dict={image_placeholder: image}) padded_image.eval(feed_dict={image_placeholder: image})
...@@ -304,7 +309,7 @@ class PreprocessUtilsTest(tf.test.TestCase): ...@@ -304,7 +309,7 @@ class PreprocessUtilsTest(tf.test.TestCase):
padded_image = preprocess_utils.pad_to_bounding_box( padded_image = preprocess_utils.pad_to_bounding_box(
image_placeholder, 3, 0, 4, 4, 255) image_placeholder, 3, 0, 4, 4, 255)
with self.assertRaisesWithPredicateMatch( with self.assertRaisesWithPredicateMatch(
errors.InvalidArgumentError, tf.errors.InvalidArgumentError,
'target size not possible with the given target offsets'): 'target size not possible with the given target offsets'):
padded_image.eval(feed_dict={image_placeholder: image}) padded_image.eval(feed_dict={image_placeholder: image})
...@@ -316,7 +321,7 @@ class PreprocessUtilsTest(tf.test.TestCase): ...@@ -316,7 +321,7 @@ class PreprocessUtilsTest(tf.test.TestCase):
padded_image = preprocess_utils.pad_to_bounding_box( padded_image = preprocess_utils.pad_to_bounding_box(
image_placeholder, 0, 0, 2, 2, 255) image_placeholder, 0, 0, 2, 2, 255)
with self.assertRaisesWithPredicateMatch( with self.assertRaisesWithPredicateMatch(
errors.InvalidArgumentError, tf.errors.InvalidArgumentError,
'Wrong image tensor rank'): 'Wrong image tensor rank'):
padded_image.eval(feed_dict={image_placeholder: image}) padded_image.eval(feed_dict={image_placeholder: image})
...@@ -331,7 +336,7 @@ class PreprocessUtilsTest(tf.test.TestCase): ...@@ -331,7 +336,7 @@ class PreprocessUtilsTest(tf.test.TestCase):
(50, 100, 3), (50, 100, 3),
(30, 100, 3)] (30, 100, 3)]
for i, test_shape in enumerate(test_shapes): for i, test_shape in enumerate(test_shapes):
image = tf.random_normal([test_shape[0], test_shape[1], 3]) image = tf.random.normal([test_shape[0], test_shape[1], 3])
new_tensor_list = preprocess_utils.resize_to_range( new_tensor_list = preprocess_utils.resize_to_range(
image=image, image=image,
label=None, label=None,
...@@ -357,8 +362,8 @@ class PreprocessUtilsTest(tf.test.TestCase): ...@@ -357,8 +362,8 @@ class PreprocessUtilsTest(tf.test.TestCase):
(49, 97, 1), (49, 97, 1),
(33, 97, 1)] (33, 97, 1)]
for i, test_shape in enumerate(test_shapes): for i, test_shape in enumerate(test_shapes):
image = tf.random_normal([test_shape[0], test_shape[1], 3]) image = tf.random.normal([test_shape[0], test_shape[1], 3])
label = tf.random_normal([test_shape[0], test_shape[1], 1]) label = tf.random.normal([test_shape[0], test_shape[1], 1])
new_tensor_list = preprocess_utils.resize_to_range( new_tensor_list = preprocess_utils.resize_to_range(
image=image, image=image,
label=label, label=label,
...@@ -385,8 +390,8 @@ class PreprocessUtilsTest(tf.test.TestCase): ...@@ -385,8 +390,8 @@ class PreprocessUtilsTest(tf.test.TestCase):
(5, 49, 97), (5, 49, 97),
(5, 33, 97)] (5, 33, 97)]
for i, test_shape in enumerate(test_shapes): for i, test_shape in enumerate(test_shapes):
image = tf.random_normal([test_shape[0], test_shape[1], 3]) image = tf.random.normal([test_shape[0], test_shape[1], 3])
label = tf.random_normal([5, test_shape[0], test_shape[1]]) label = tf.random.normal([5, test_shape[0], test_shape[1]])
new_tensor_list = preprocess_utils.resize_to_range( new_tensor_list = preprocess_utils.resize_to_range(
image=image, image=image,
label=label, label=label,
...@@ -415,14 +420,90 @@ class PreprocessUtilsTest(tf.test.TestCase): ...@@ -415,14 +420,90 @@ class PreprocessUtilsTest(tf.test.TestCase):
(49, 97, 1), (49, 97, 1),
(33, 97, 1)] (33, 97, 1)]
for i, test_shape in enumerate(test_shapes): for i, test_shape in enumerate(test_shapes):
image = tf.random_normal([test_shape[0], test_shape[1], 3]) image = tf.random.normal([test_shape[0], test_shape[1], 3])
label = tf.random_normal([test_shape[0], test_shape[1], 1]) label = tf.random.normal([test_shape[0], test_shape[1], 1])
new_tensor_list = preprocess_utils.resize_to_range(
image=image,
label=label,
min_size=min_size,
max_size=max_size,
factor=factor,
align_corners=True)
with self.test_session() as session:
new_tensor_list = session.run(new_tensor_list)
self.assertEqual(new_tensor_list[0].shape, expected_image_shape_list[i])
self.assertEqual(new_tensor_list[1].shape, expected_label_shape_list[i])
def testResizeTensorsToRangeWithEqualMaxSize(self):
test_shapes = [[97, 38],
[96, 97]]
# Make max_size equal to the larger value of test_shapes.
min_size = 97
max_size = 97
factor = 8
expected_image_shape_list = [(97, 41, 3),
(97, 97, 3)]
expected_label_shape_list = [(97, 41, 1),
(97, 97, 1)]
for i, test_shape in enumerate(test_shapes):
image = tf.random.normal([test_shape[0], test_shape[1], 3])
label = tf.random.normal([test_shape[0], test_shape[1], 1])
new_tensor_list = preprocess_utils.resize_to_range(
image=image,
label=label,
min_size=min_size,
max_size=max_size,
factor=factor,
align_corners=True)
with self.test_session() as session:
new_tensor_list = session.run(new_tensor_list)
self.assertEqual(new_tensor_list[0].shape, expected_image_shape_list[i])
self.assertEqual(new_tensor_list[1].shape, expected_label_shape_list[i])
def testResizeTensorsToRangeWithPotentialErrorInTFCeil(self):
test_shape = [3936, 5248]
# Make max_size equal to the larger value of test_shapes.
min_size = 1441
max_size = 1441
factor = 16
expected_image_shape = (1089, 1441, 3)
expected_label_shape = (1089, 1441, 1)
image = tf.random.normal([test_shape[0], test_shape[1], 3])
label = tf.random.normal([test_shape[0], test_shape[1], 1])
new_tensor_list = preprocess_utils.resize_to_range(
image=image,
label=label,
min_size=min_size,
max_size=max_size,
factor=factor,
align_corners=True)
with self.test_session() as session:
new_tensor_list = session.run(new_tensor_list)
self.assertEqual(new_tensor_list[0].shape, expected_image_shape)
self.assertEqual(new_tensor_list[1].shape, expected_label_shape)
def testResizeTensorsToRangeWithEqualMaxSizeWithoutAspectRatio(self):
test_shapes = [[97, 38],
[96, 97]]
# Make max_size equal to the larger value of test_shapes.
min_size = 97
max_size = 97
factor = 8
keep_aspect_ratio = False
expected_image_shape_list = [(97, 97, 3),
(97, 97, 3)]
expected_label_shape_list = [(97, 97, 1),
(97, 97, 1)]
for i, test_shape in enumerate(test_shapes):
image = tf.random.normal([test_shape[0], test_shape[1], 3])
label = tf.random.normal([test_shape[0], test_shape[1], 1])
new_tensor_list = preprocess_utils.resize_to_range( new_tensor_list = preprocess_utils.resize_to_range(
image=image, image=image,
label=label, label=label,
min_size=min_size, min_size=min_size,
max_size=max_size, max_size=max_size,
factor=factor, factor=factor,
keep_aspect_ratio=keep_aspect_ratio,
align_corners=True) align_corners=True)
with self.test_session() as session: with self.test_session() as session:
new_tensor_list = session.run(new_tensor_list) new_tensor_list = session.run(new_tensor_list)
......
# Lint as: python2, python3
# Copyright 2018 The TensorFlow Authors All Rights Reserved. # Copyright 2018 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
...@@ -15,11 +16,15 @@ ...@@ -15,11 +16,15 @@
"""Converts ADE20K data to TFRecord file format with Example protos.""" """Converts ADE20K data to TFRecord file format with Example protos."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import math import math
import os import os
import random import random
import sys import sys
import build_data import build_data
from six.moves import range
import tensorflow as tf import tensorflow as tf
FLAGS = tf.app.flags.FLAGS FLAGS = tf.app.flags.FLAGS
...@@ -73,7 +78,7 @@ def _convert_dataset(dataset_split, dataset_dir, dataset_label_dir): ...@@ -73,7 +78,7 @@ def _convert_dataset(dataset_split, dataset_dir, dataset_label_dir):
seg_names.append(seg) seg_names.append(seg)
num_images = len(img_names) num_images = len(img_names)
num_per_shard = int(math.ceil(num_images / float(_NUM_SHARDS))) num_per_shard = int(math.ceil(num_images / _NUM_SHARDS))
image_reader = build_data.ImageReader('jpeg', channels=3) image_reader = build_data.ImageReader('jpeg', channels=3)
label_reader = build_data.ImageReader('png', channels=1) label_reader = build_data.ImageReader('png', channels=1)
......
# Lint as: python2, python3
# Copyright 2018 The TensorFlow Authors All Rights Reserved. # Copyright 2018 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
...@@ -59,12 +60,16 @@ The Example proto contains the following fields: ...@@ -59,12 +60,16 @@ The Example proto contains the following fields:
image/segmentation/class/encoded: encoded semantic segmentation content. image/segmentation/class/encoded: encoded semantic segmentation content.
image/segmentation/class/format: semantic segmentation file format. image/segmentation/class/format: semantic segmentation file format.
""" """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import glob import glob
import math import math
import os.path import os.path
import re import re
import sys import sys
import build_data import build_data
from six.moves import range
import tensorflow as tf import tensorflow as tf
FLAGS = tf.app.flags.FLAGS FLAGS = tf.app.flags.FLAGS
...@@ -137,7 +142,7 @@ def _convert_dataset(dataset_split): ...@@ -137,7 +142,7 @@ def _convert_dataset(dataset_split):
label_files = _get_files('label', dataset_split) label_files = _get_files('label', dataset_split)
num_images = len(image_files) num_images = len(image_files)
num_per_shard = int(math.ceil(num_images / float(_NUM_SHARDS))) num_per_shard = int(math.ceil(num_images / _NUM_SHARDS))
image_reader = build_data.ImageReader('png', channels=3) image_reader = build_data.ImageReader('png', channels=3)
label_reader = build_data.ImageReader('png', channels=1) label_reader = build_data.ImageReader('png', channels=1)
......
# Lint as: python2, python3
# Copyright 2018 The TensorFlow Authors All Rights Reserved. # Copyright 2018 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
...@@ -50,10 +51,14 @@ The Example proto contains the following fields: ...@@ -50,10 +51,14 @@ The Example proto contains the following fields:
image/segmentation/class/encoded: encoded semantic segmentation content. image/segmentation/class/encoded: encoded semantic segmentation content.
image/segmentation/class/format: semantic segmentation file format. image/segmentation/class/format: semantic segmentation file format.
""" """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import math import math
import os.path import os.path
import sys import sys
import build_data import build_data
from six.moves import range
import tensorflow as tf import tensorflow as tf
FLAGS = tf.app.flags.FLAGS FLAGS = tf.app.flags.FLAGS
...@@ -94,7 +99,7 @@ def _convert_dataset(dataset_split): ...@@ -94,7 +99,7 @@ def _convert_dataset(dataset_split):
sys.stdout.write('Processing ' + dataset) sys.stdout.write('Processing ' + dataset)
filenames = [x.strip('\n') for x in open(dataset_split, 'r')] filenames = [x.strip('\n') for x in open(dataset_split, 'r')]
num_images = len(filenames) num_images = len(filenames)
num_per_shard = int(math.ceil(num_images / float(_NUM_SHARDS))) num_per_shard = int(math.ceil(num_images / _NUM_SHARDS))
image_reader = build_data.ImageReader('jpeg', channels=3) image_reader = build_data.ImageReader('jpeg', channels=3)
label_reader = build_data.ImageReader('png', channels=1) label_reader = build_data.ImageReader('png', channels=1)
...@@ -113,13 +118,13 @@ def _convert_dataset(dataset_split): ...@@ -113,13 +118,13 @@ def _convert_dataset(dataset_split):
# Read the image. # Read the image.
image_filename = os.path.join( image_filename = os.path.join(
FLAGS.image_folder, filenames[i] + '.' + FLAGS.image_format) FLAGS.image_folder, filenames[i] + '.' + FLAGS.image_format)
image_data = tf.gfile.FastGFile(image_filename, 'rb').read() image_data = tf.gfile.GFile(image_filename, 'rb').read()
height, width = image_reader.read_image_dims(image_data) height, width = image_reader.read_image_dims(image_data)
# Read the semantic segmentation annotation. # Read the semantic segmentation annotation.
seg_filename = os.path.join( seg_filename = os.path.join(
FLAGS.semantic_segmentation_folder, FLAGS.semantic_segmentation_folder,
filenames[i] + '.' + FLAGS.label_format) filenames[i] + '.' + FLAGS.label_format)
seg_data = tf.gfile.FastGFile(seg_filename, 'rb').read() seg_data = tf.gfile.GFile(seg_filename, 'rb').read()
seg_height, seg_width = label_reader.read_image_dims(seg_data) seg_height, seg_width = label_reader.read_image_dims(seg_data)
if height != seg_height or width != seg_width: if height != seg_height or width != seg_width:
raise RuntimeError('Shape mismatched between image and label.') raise RuntimeError('Shape mismatched between image and label.')
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
# Cityscapes at https://github.com/mcordts/cityscapesScripts. # Cityscapes at https://github.com/mcordts/cityscapesScripts.
# #
# Usage: # Usage:
# bash ./preprocess_cityscapes.sh # bash ./convert_cityscapes.sh
# #
# The folder structure is assumed to be: # The folder structure is assumed to be:
# + datasets # + datasets
......
# Lint as: python2, python3
# Copyright 2018 The TensorFlow Authors All Rights Reserved. # Copyright 2018 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
...@@ -68,10 +69,12 @@ DatasetDescriptor = collections.namedtuple( ...@@ -68,10 +69,12 @@ DatasetDescriptor = collections.namedtuple(
]) ])
_CITYSCAPES_INFORMATION = DatasetDescriptor( _CITYSCAPES_INFORMATION = DatasetDescriptor(
splits_to_sizes={ splits_to_sizes={'train_fine': 2975,
'train': 2975, 'train_coarse': 22973,
'val': 500, 'trainval_fine': 3475,
}, 'trainval_coarse': 23473,
'val_fine': 500,
'test_fine': 1525},
num_classes=19, num_classes=19,
ignore_label=255, ignore_label=255,
) )
......
# Lint as: python2, python3
# Copyright 2018 The TensorFlow Authors All Rights Reserved. # Copyright 2018 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
...@@ -14,10 +15,13 @@ ...@@ -14,10 +15,13 @@
# ============================================================================== # ==============================================================================
"""Tests for deeplab.datasets.data_generator.""" """Tests for deeplab.datasets.data_generator."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function from __future__ import print_function
import collections import collections
from six.moves import range
import tensorflow as tf import tensorflow as tf
from deeplab import common from deeplab import common
...@@ -60,13 +64,10 @@ class DatasetTest(tf.test.TestCase): ...@@ -60,13 +64,10 @@ class DatasetTest(tf.test.TestCase):
batch = iterator.get_next() batch = iterator.get_next()
batch, = sess.run([batch]) batch, = sess.run([batch])
image_attributes = _get_attributes_of_image(i) image_attributes = _get_attributes_of_image(i)
self.assertAllEqual(batch[common.IMAGE][0], image_attributes.image)
self.assertAllEqual(batch[common.LABEL][0], image_attributes.label)
self.assertEqual(batch[common.HEIGHT][0], image_attributes.height) self.assertEqual(batch[common.HEIGHT][0], image_attributes.height)
self.assertEqual(batch[common.WIDTH][0], image_attributes.width) self.assertEqual(batch[common.WIDTH][0], image_attributes.width)
self.assertEqual(batch[common.IMAGE_NAME][0], self.assertEqual(batch[common.IMAGE_NAME][0],
image_attributes.image_name) image_attributes.image_name.encode())
# All data have been read. # All data have been read.
with self.assertRaisesRegexp(tf.errors.OutOfRangeError, ''): with self.assertRaisesRegexp(tf.errors.OutOfRangeError, ''):
...@@ -87,22 +88,22 @@ def _get_attributes_of_image(index): ...@@ -87,22 +88,22 @@ def _get_attributes_of_image(index):
""" """
if index == 0: if index == 0:
return ImageAttributes( return ImageAttributes(
image=IMAGE_1, image=None,
label=LABEL_1, label=None,
height=366, height=366,
width=500, width=500,
image_name='2007_000033') image_name='2007_000033')
elif index == 1: elif index == 1:
return ImageAttributes( return ImageAttributes(
image=IMAGE_2, image=None,
label=LABEL_2, label=None,
height=335, height=335,
width=500, width=500,
image_name='2007_000042') image_name='2007_000042')
elif index == 2: elif index == 2:
return ImageAttributes( return ImageAttributes(
image=IMAGE_3, image=None,
label=LABEL_3, label=None,
height=333, height=333,
width=500, width=500,
image_name='2007_000061') image_name='2007_000061')
...@@ -110,113 +111,5 @@ def _get_attributes_of_image(index): ...@@ -110,113 +111,5 @@ def _get_attributes_of_image(index):
raise ValueError('Index can only be 0, 1 or 2.') raise ValueError('Index can only be 0, 1 or 2.')
IMAGE_1 = (
(
(57., 41., 18.),
(151.5, 138., 111.5),
(107., 158., 143.),
),
(
(104.5, 141., 191.),
(101.75, 72.5, 120.75),
(86.5, 139.5, 120.),
),
(
(96., 85., 145.),
(123.5, 107.5, 97.),
(61., 148., 116.),
),
)
LABEL_1 = (
(
(70,),
(227,),
(251,),
),
(
(101,),
(0,),
(10,),
),
(
(145,),
(245,),
(146,),
),
)
IMAGE_2 = (
(
(94., 64., 98.),
(145.5, 136.5, 134.5),
(108., 162., 172.),
),
(
(168., 157., 213.),
(161.5, 154.5, 148.),
(25., 46., 93.),
),
(
(255., 204., 237.),
(124., 102., 126.5),
(155., 181., 82.),
),
)
LABEL_2 = (
(
(44,),
(146,),
(121,),
),
(
(108,),
(118,),
(6,),
),
(
(246,),
(121,),
(108,),
),
)
IMAGE_3 = (
(
(235., 173., 150.),
(145.5, 83.5, 102.),
(82., 149., 158.),
),
(
(130., 95., 14.),
(132.5, 141.5, 93.),
(119., 85., 86.),
),
(
(127.5, 127.5, 127.5),
(127.5, 127.5, 127.5),
(127.5, 127.5, 127.5),
),
)
LABEL_3 = (
(
(91,),
(120,),
(132,),
),
(
(135,),
(139,),
(72,),
),
(
(255,),
(255,),
(255,),
),
)
if __name__ == '__main__': if __name__ == '__main__':
tf.test.main() tf.test.main()
...@@ -291,7 +291,7 @@ ...@@ -291,7 +291,7 @@
"url for inference.\n", "url for inference.\n",
"\n", "\n",
"Note that this colab uses single scale inference for fast computation,\n", "Note that this colab uses single scale inference for fast computation,\n",
"so the results may slightly differ from the visualizations in the \n", "so the results may slightly differ from the visualizations in the\n",
"[README](https://github.com/tensorflow/models/blob/master/research/deeplab/README.md) file,\n", "[README](https://github.com/tensorflow/models/blob/master/research/deeplab/README.md) file,\n",
"which uses multi-scale and left-right flipped inputs." "which uses multi-scale and left-right flipped inputs."
] ]
......
# Lint as: python2, python3
# Copyright 2018 The TensorFlow Authors All Rights Reserved. # Copyright 2018 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
...@@ -51,8 +52,9 @@ References: ...@@ -51,8 +52,9 @@ References:
import collections import collections
import os.path import os.path
import tensorflow as tf import tensorflow as tf
from tensorflow.contrib import slim as contrib_slim
slim = tf.contrib.slim slim = contrib_slim
dataset = slim.dataset dataset = slim.dataset
......
# Lint as: python2, python3
# Copyright 2018 The TensorFlow Authors All Rights Reserved. # Copyright 2018 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
...@@ -17,7 +18,13 @@ ...@@ -17,7 +18,13 @@
See model.py for more details and usage. See model.py for more details and usage.
""" """
import numpy as np
import six
import tensorflow as tf import tensorflow as tf
from tensorflow.contrib import metrics as contrib_metrics
from tensorflow.contrib import quantize as contrib_quantize
from tensorflow.contrib import tfprof as contrib_tfprof
from tensorflow.contrib import training as contrib_training
from deeplab import common from deeplab import common
from deeplab import model from deeplab import model
from deeplab.datasets import data_generator from deeplab.datasets import data_generator
...@@ -149,12 +156,44 @@ def main(unused_argv): ...@@ -149,12 +156,44 @@ def main(unused_argv):
predictions_tag += '_flipped' predictions_tag += '_flipped'
# Define the evaluation metric. # Define the evaluation metric.
miou, update_op = tf.metrics.mean_iou( metric_map = {}
predictions, labels, dataset.num_of_classes, weights=weights) num_classes = dataset.num_of_classes
tf.summary.scalar(predictions_tag, miou) metric_map['eval/%s_overall' % predictions_tag] = tf.metrics.mean_iou(
labels=labels, predictions=predictions, num_classes=num_classes,
summary_op = tf.summary.merge_all() weights=weights)
summary_hook = tf.contrib.training.SummaryAtEndHook( # IoU for each class.
one_hot_predictions = tf.one_hot(predictions, num_classes)
one_hot_predictions = tf.reshape(one_hot_predictions, [-1, num_classes])
one_hot_labels = tf.one_hot(labels, num_classes)
one_hot_labels = tf.reshape(one_hot_labels, [-1, num_classes])
for c in range(num_classes):
predictions_tag_c = '%s_class_%d' % (predictions_tag, c)
tp, tp_op = tf.metrics.true_positives(
labels=one_hot_labels[:, c], predictions=one_hot_predictions[:, c],
weights=weights)
fp, fp_op = tf.metrics.false_positives(
labels=one_hot_labels[:, c], predictions=one_hot_predictions[:, c],
weights=weights)
fn, fn_op = tf.metrics.false_negatives(
labels=one_hot_labels[:, c], predictions=one_hot_predictions[:, c],
weights=weights)
tp_fp_fn_op = tf.group(tp_op, fp_op, fn_op)
iou = tf.where(tf.greater(tp + fn, 0.0),
tp / (tp + fn + fp),
tf.constant(np.NaN))
metric_map['eval/%s' % predictions_tag_c] = (iou, tp_fp_fn_op)
(metrics_to_values,
metrics_to_updates) = contrib_metrics.aggregate_metric_map(metric_map)
summary_ops = []
for metric_name, metric_value in six.iteritems(metrics_to_values):
op = tf.summary.scalar(metric_name, metric_value)
op = tf.Print(op, [metric_value], metric_name)
summary_ops.append(op)
summary_op = tf.summary.merge(summary_ops)
summary_hook = contrib_training.SummaryAtEndHook(
log_dir=FLAGS.eval_logdir, summary_op=summary_op) log_dir=FLAGS.eval_logdir, summary_op=summary_op)
hooks = [summary_hook] hooks = [summary_hook]
...@@ -163,19 +202,19 @@ def main(unused_argv): ...@@ -163,19 +202,19 @@ def main(unused_argv):
num_eval_iters = FLAGS.max_number_of_evaluations num_eval_iters = FLAGS.max_number_of_evaluations
if FLAGS.quantize_delay_step >= 0: if FLAGS.quantize_delay_step >= 0:
tf.contrib.quantize.create_eval_graph() contrib_quantize.create_eval_graph()
tf.contrib.tfprof.model_analyzer.print_model_analysis( contrib_tfprof.model_analyzer.print_model_analysis(
tf.get_default_graph(), tf.get_default_graph(),
tfprof_options=tf.contrib.tfprof.model_analyzer. tfprof_options=contrib_tfprof.model_analyzer
TRAINABLE_VARS_PARAMS_STAT_OPTIONS) .TRAINABLE_VARS_PARAMS_STAT_OPTIONS)
tf.contrib.tfprof.model_analyzer.print_model_analysis( contrib_tfprof.model_analyzer.print_model_analysis(
tf.get_default_graph(), tf.get_default_graph(),
tfprof_options=tf.contrib.tfprof.model_analyzer.FLOAT_OPS_OPTIONS) tfprof_options=contrib_tfprof.model_analyzer.FLOAT_OPS_OPTIONS)
tf.contrib.training.evaluate_repeatedly( contrib_training.evaluate_repeatedly(
master=FLAGS.master,
checkpoint_dir=FLAGS.checkpoint_dir, checkpoint_dir=FLAGS.checkpoint_dir,
eval_ops=[update_op], master=FLAGS.master,
eval_ops=list(metrics_to_updates.values()),
max_number_of_evaluations=num_eval_iters, max_number_of_evaluations=num_eval_iters,
hooks=hooks, hooks=hooks,
eval_interval_secs=FLAGS.eval_interval_secs) eval_interval_secs=FLAGS.eval_interval_secs)
......
# Lint as: python2, python3
# Copyright 2019 The TensorFlow Authors All Rights Reserved. # Copyright 2019 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
......
# Lint as: python2, python3
# Copyright 2019 The TensorFlow Authors All Rights Reserved. # Copyright 2019 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
...@@ -52,7 +53,8 @@ class EvalCocoFormatTest(absltest.TestCase): ...@@ -52,7 +53,8 @@ class EvalCocoFormatTest(absltest.TestCase):
ignored_label=0, ignored_label=0,
max_instances_per_category=256, max_instances_per_category=256,
intersection_offset=(256 * 256)) intersection_offset=(256 * 256))
self.assertCountEqual(deeplab_results.keys(), ['All', 'Things', 'Stuff']) self.assertCountEqual(
list(deeplab_results.keys()), ['All', 'Things', 'Stuff'])
for cat_group in ['All', 'Things', 'Stuff']: for cat_group in ['All', 'Things', 'Stuff']:
self.assertCountEqual(deeplab_results[cat_group], ['pq', 'sq', 'rq', 'n']) self.assertCountEqual(deeplab_results[cat_group], ['pq', 'sq', 'rq', 'n'])
for metric in ['pq', 'sq', 'rq', 'n']: for metric in ['pq', 'sq', 'rq', 'n']:
...@@ -77,7 +79,8 @@ class EvalCocoFormatTest(absltest.TestCase): ...@@ -77,7 +79,8 @@ class EvalCocoFormatTest(absltest.TestCase):
max_instances_per_category=256, max_instances_per_category=256,
intersection_offset=(256 * 256), intersection_offset=(256 * 256),
normalize_by_image_size=False) normalize_by_image_size=False)
self.assertCountEqual(deeplab_results.keys(), ['All', 'Things', 'Stuff']) self.assertCountEqual(
list(deeplab_results.keys()), ['All', 'Things', 'Stuff'])
for cat_group in ['All', 'Things', 'Stuff']: for cat_group in ['All', 'Things', 'Stuff']:
self.assertCountEqual(deeplab_results[cat_group], ['pc', 'n']) self.assertCountEqual(deeplab_results[cat_group], ['pc', 'n'])
self.assertAlmostEqual(deeplab_results['All']['pc'], 0.68210561) self.assertAlmostEqual(deeplab_results['All']['pc'], 0.68210561)
...@@ -105,7 +108,8 @@ class EvalCocoFormatTest(absltest.TestCase): ...@@ -105,7 +108,8 @@ class EvalCocoFormatTest(absltest.TestCase):
max_instances_per_category=256, max_instances_per_category=256,
intersection_offset=(256 * 256), intersection_offset=(256 * 256),
normalize_by_image_size=True) normalize_by_image_size=True)
self.assertCountEqual(deeplab_results.keys(), ['All', 'Things', 'Stuff']) self.assertCountEqual(
list(deeplab_results.keys()), ['All', 'Things', 'Stuff'])
self.assertAlmostEqual(deeplab_results['All']['pc'], 0.68214908840) self.assertAlmostEqual(deeplab_results['All']['pc'], 0.68214908840)
def test_pc_with_multiple_workers(self): def test_pc_with_multiple_workers(self):
...@@ -127,7 +131,8 @@ class EvalCocoFormatTest(absltest.TestCase): ...@@ -127,7 +131,8 @@ class EvalCocoFormatTest(absltest.TestCase):
intersection_offset=(256 * 256), intersection_offset=(256 * 256),
num_workers=3, num_workers=3,
normalize_by_image_size=False) normalize_by_image_size=False)
self.assertCountEqual(deeplab_results.keys(), ['All', 'Things', 'Stuff']) self.assertCountEqual(
list(deeplab_results.keys()), ['All', 'Things', 'Stuff'])
self.assertAlmostEqual(deeplab_results['All']['pc'], 0.68210561668) self.assertAlmostEqual(deeplab_results['All']['pc'], 0.68210561668)
......
# Lint as: python2, python3
# Copyright 2019 The TensorFlow Authors All Rights Reserved. # Copyright 2019 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
......
# Lint as: python2, python3
# Copyright 2019 The TensorFlow Authors All Rights Reserved. # Copyright 2019 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
......
# Lint as: python2, python3
# Copyright 2019 The TensorFlow Authors All Rights Reserved. # Copyright 2019 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
......
# Lint as: python2, python3
# Copyright 2019 The TensorFlow Authors All Rights Reserved. # Copyright 2019 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
......
# Lint as: python2, python3
# Copyright 2019 The TensorFlow Authors All Rights Reserved. # Copyright 2019 The TensorFlow Authors All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
......
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