Skip to content
This repository was archived by the owner on Jul 7, 2023. It is now read-only.

Commit 9ef2517

Browse files
authored
Merge pull request #255 from rsepassi/push
v1.2.0
2 parents 860fe0a + ab1e766 commit 9ef2517

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+3290
-809
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ and are encoded in
217217
[`tf.contrib.training.HParams`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/training/python/training/hparam.py)
218218
objects. The `HParams` are available to both the problem specification and the
219219
model. A basic set of hyperparameters are defined in
220-
[`common_hparams.py`](https://github.com/tensorflow/tensor2tensor/tree/master/tensor2tensor/models/common_hparams.py)
220+
[`common_hparams.py`](https://github.com/tensorflow/tensor2tensor/tree/master/tensor2tensor/layers/common_hparams.py)
221221
and hyperparameter set functions can compose other hyperparameter set functions.
222222

223223
### Trainer

setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setup(
77
name='tensor2tensor',
8-
version='1.1.9',
8+
version='1.2.0',
99
description='Tensor2Tensor',
1010
author='Google Inc.',
1111
author_email='no-reply@google.com',
@@ -26,8 +26,8 @@
2626
'six',
2727
],
2828
extras_require={
29-
'tensorflow': ['tensorflow>=1.2.0rc1'],
30-
'tensorflow_gpu': ['tensorflow-gpu>=1.2.0rc1'],
29+
'tensorflow': ['tensorflow>=1.3.0'],
30+
'tensorflow_gpu': ['tensorflow-gpu>=1.3.0'],
3131
},
3232
tests_require=['nose'],
3333
test_suite='nose.collector',

tensor2tensor/bin/t2t-datagen

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ from tensor2tensor.data_generators import algorithmic_math
4242
from tensor2tensor.data_generators import all_problems # pylint: disable=unused-import
4343
from tensor2tensor.data_generators import audio
4444
from tensor2tensor.data_generators import generator_utils
45-
from tensor2tensor.data_generators import image
4645
from tensor2tensor.data_generators import lm1b
4746
from tensor2tensor.data_generators import snli
4847
from tensor2tensor.data_generators import wmt
@@ -106,9 +105,6 @@ _SUPPORTED_PROBLEM_GENERATORS = {
106105
lambda: lm1b.generator(FLAGS.tmp_dir, True, characters=True),
107106
lambda: lm1b.generator(FLAGS.tmp_dir, False, characters=True)
108107
),
109-
"image_celeba_tune": (
110-
lambda: image.celeba_generator(FLAGS.tmp_dir, 162770),
111-
lambda: image.celeba_generator(FLAGS.tmp_dir, 19867, 162770)),
112108
"inference_snli32k": (
113109
lambda: snli.snli_token_generator(FLAGS.tmp_dir, True, 2**15),
114110
lambda: snli.snli_token_generator(FLAGS.tmp_dir, False, 2**15),

tensor2tensor/data_generators/algorithmic_test.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121

2222
# Dependency imports
2323

24-
from six.moves import xrange
24+
from six.moves import xrange # pylint: disable=redefined-builtin
25+
2526
from tensor2tensor.data_generators import algorithmic
2627

2728
import tensorflow as tf

tensor2tensor/data_generators/all_problems.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@
4343
pass
4444
# pylint: enable=g-import-not-at-top
4545
# pylint: enable=unused-import
46+

tensor2tensor/data_generators/generator_utils.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,24 @@ def gunzip_file(gz_path, new_path):
301301

302302
def get_or_generate_vocab_inner(data_dir, vocab_filename, vocab_size,
303303
generator_fn):
304-
"""Inner implementation for vocab generators."""
305-
vocab_filepath = os.path.join(data_dir, vocab_filename)
306-
if tf.gfile.Exists(vocab_filepath):
304+
"""Inner implementation for vocab generators.
305+
306+
Args:
307+
data_dir: The base directory where data and vocab files are stored. If None,
308+
then do not save the vocab even if it doesn't exist.
309+
vocab_filename: relative filename where vocab file is stored
310+
vocab_size: target size of the vocabulary constructed by SubwordTextEncoder
311+
generator_fn: a generator that produces tokens from the vocabulary
312+
313+
Returns:
314+
A SubwordTextEncoder vocabulary object.
315+
"""
316+
if data_dir is None:
317+
vocab_filepath = None
318+
else:
319+
vocab_filepath = os.path.join(data_dir, vocab_filename)
320+
321+
if vocab_filepath is not None and tf.gfile.Exists(vocab_filepath):
307322
tf.logging.info("Found vocab file: %s", vocab_filepath)
308323
vocab = text_encoder.SubwordTextEncoder(vocab_filepath)
309324
return vocab
@@ -316,7 +331,9 @@ def get_or_generate_vocab_inner(data_dir, vocab_filename, vocab_size,
316331

317332
vocab = text_encoder.SubwordTextEncoder.build_to_target_size(
318333
vocab_size, token_counts, 1, 1e3)
319-
vocab.store_to_file(vocab_filepath)
334+
335+
if vocab_filepath is not None:
336+
vocab.store_to_file(vocab_filepath)
320337
return vocab
321338

322339

tensor2tensor/data_generators/image.py

Lines changed: 133 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,137 @@ def example_reading_spec(self, label_key=None):
6666
return data_fields, data_items_to_decoders
6767

6868

69-
# French street names dataset.
69+
@registry.register_problem("image_celeba_tune")
70+
class ImageCeleba(ImageProblem):
71+
"""CelebA dataset, aligned and cropped images."""
72+
IMG_DATA = ("img_align_celeba.zip",
73+
"https://drive.google.com/uc?export=download&"
74+
"id=0B7EVK8r0v71pZjFTYXZWM3FlRnM")
75+
LANDMARKS_DATA = ("celeba_landmarks_align",
76+
"https://drive.google.com/uc?export=download&"
77+
"id=0B7EVK8r0v71pd0FJY3Blby1HUTQ")
78+
ATTR_DATA = ("celeba_attr", "https://drive.google.com/uc?export=download&"
79+
"id=0B7EVK8r0v71pblRyaVFSWGxPY0U")
80+
81+
LANDMARK_HEADINGS = ("lefteye_x lefteye_y righteye_x righteye_y "
82+
"nose_x nose_y leftmouth_x leftmouth_y rightmouth_x "
83+
"rightmouth_y").split()
84+
ATTR_HEADINGS = (
85+
"5_o_Clock_Shadow Arched_Eyebrows Attractive Bags_Under_Eyes Bald Bangs "
86+
"Big_Lips Big_Nose Black_Hair Blond_Hair Blurry Brown_Hair "
87+
"Bushy_Eyebrows Chubby Double_Chin Eyeglasses Goatee Gray_Hair "
88+
"Heavy_Makeup High_Cheekbones Male Mouth_Slightly_Open Mustache "
89+
"Narrow_Eyes No_Beard Oval_Face Pale_Skin Pointy_Nose Receding_Hairline "
90+
"Rosy_Cheeks Sideburns Smiling Straight_Hair Wavy_Hair Wearing_Earrings "
91+
"Wearing_Hat Wearing_Lipstick Wearing_Necklace Wearing_Necktie Young"
92+
).split()
93+
94+
def preprocess_examples(self, examples, unused_mode, unused_hparams):
95+
96+
def resize(img, size):
97+
return tf.to_int64(
98+
tf.image.resize_images(img, [size, size], tf.image.ResizeMethod.AREA))
99+
100+
inputs = examples["inputs"]
101+
# Remove boundaries in CelebA images. Remove 40 pixels each side
102+
# vertically and 20 pixels each side horizontally.
103+
inputs = tf.image.crop_to_bounding_box(inputs, 40, 20, 218 - 80, 178 - 40)
104+
examples["inputs"] = resize(inputs, 8)
105+
examples["targets"] = resize(inputs, 32)
106+
return examples
107+
108+
def hparams(self, defaults, model_hparams):
109+
p = defaults
110+
p.input_modality = {"inputs": ("image:identity_no_pad", None)}
111+
p.target_modality = ("image:identity_no_pad", None)
112+
p.batch_size_multiplier = 256
113+
p.max_expected_batch_size_per_shard = 4
114+
p.input_space_id = 1
115+
p.target_space_id = 1
116+
117+
def generator(self, tmp_dir, how_many, start_from=0):
118+
"""Image generator for CELEBA dataset.
119+
120+
Args:
121+
tmp_dir: path to temporary storage directory.
122+
how_many: how many images and labels to generate.
123+
start_from: from which image to start.
124+
125+
Yields:
126+
A dictionary representing the images with the following fields:
127+
* image/encoded: the string encoding the image as JPEG,
128+
* image/format: the string "jpeg" representing image format,
129+
"""
130+
out_paths = []
131+
for fname, url in [self.IMG_DATA, self.LANDMARKS_DATA, self.ATTR_DATA]:
132+
path = generator_utils.maybe_download_from_drive(tmp_dir, fname, url)
133+
out_paths.append(path)
134+
135+
img_path, landmarks_path, attr_path = out_paths # pylint: disable=unbalanced-tuple-unpacking
136+
unzipped_folder = img_path[:-4]
137+
if not tf.gfile.Exists(unzipped_folder):
138+
zipfile.ZipFile(img_path, "r").extractall(tmp_dir)
139+
140+
with tf.gfile.Open(landmarks_path) as f:
141+
landmarks_raw = f.read()
142+
143+
with tf.gfile.Open(attr_path) as f:
144+
attr_raw = f.read()
145+
146+
def process_landmarks(raw_data):
147+
landmarks = {}
148+
lines = raw_data.split("\n")
149+
headings = lines[1].strip().split()
150+
for line in lines[2:-1]:
151+
values = line.strip().split()
152+
img_name = values[0]
153+
landmark_values = [int(v) for v in values[1:]]
154+
landmarks[img_name] = landmark_values
155+
return landmarks, headings
156+
157+
def process_attrs(raw_data):
158+
attrs = {}
159+
lines = raw_data.split("\n")
160+
headings = lines[1].strip().split()
161+
for line in lines[2:-1]:
162+
values = line.strip().split()
163+
img_name = values[0]
164+
attr_values = [int(v) for v in values[1:]]
165+
attrs[img_name] = attr_values
166+
return attrs, headings
167+
168+
img_landmarks, _ = process_landmarks(landmarks_raw)
169+
img_attrs, _ = process_attrs(attr_raw)
170+
171+
image_files = tf.gfile.Glob(unzipped_folder + "/*.jpg")
172+
for filename in image_files[start_from:start_from + how_many]:
173+
img_name = os.path.basename(filename)
174+
landmarks = img_landmarks[img_name]
175+
attrs = img_attrs[img_name]
176+
177+
with tf.gfile.Open(filename, "r") as f:
178+
encoded_image_data = f.read()
179+
yield {
180+
"image/encoded": [encoded_image_data],
181+
"image/format": ["jpeg"],
182+
"attributes": attrs,
183+
"landmarks": landmarks,
184+
}
185+
186+
@property
187+
def train_shards(self):
188+
return 100
189+
190+
@property
191+
def dev_shards(self):
192+
return 10
193+
194+
def generate_data(self, data_dir, tmp_dir, task_id=-1):
195+
generator_utils.generate_dataset_and_shuffle(
196+
self.generator(tmp_dir, 162770), # train
197+
self.training_filepaths(data_dir, self.train_shards, shuffled=False),
198+
self.generator(tmp_dir, 19867, 162770), # dev
199+
self.dev_filepaths(data_dir, self.dev_shards, shuffled=False))
70200

71201

72202
@registry.register_problem
@@ -199,7 +329,7 @@ def generate_data(self, data_dir, tmp_dir, task_id=-1):
199329
"instructions at https://github.com/tensorflow/models/blob/master"
200330
"/inception/README.md#getting-started")
201331

202-
def preprocess_examples(self, examples, mode):
332+
def preprocess_examples(self, examples, mode, _):
203333
return imagenet_preprocess_examples(examples, mode)
204334

205335

@@ -638,7 +768,7 @@ def train_shards(self):
638768
def dev_shards(self):
639769
return 10
640770

641-
def preprocess_examples(self, examples, mode):
771+
def preprocess_examples(self, examples, mode, _):
642772
return imagenet_preprocess_examples(examples, mode)
643773

644774
def generator(self, data_dir, tmp_dir, is_training):
@@ -700,41 +830,3 @@ class ImageMsCocoTokens32k(ImageMsCocoTokens8k):
700830
@property
701831
def targeted_vocab_size(self):
702832
return 2**15 # 32768
703-
704-
705-
# URL and filename for CELEBA data.
706-
_CELEBA_NAME = "img_align_celeba"
707-
_CELEBA_URL = "https://drive.google.com/uc?export=download&id=0B7EVK8r0v71pZjFTYXZWM3FlRnM"
708-
709-
710-
def _get_celeba(directory):
711-
"""Download and extract CELEBA to directory unless it is there."""
712-
# path = os.path.join(directory, _CELEBA_NAME)
713-
path = generator_utils.maybe_download_from_drive(directory, _CELEBA_NAME,
714-
_CELEBA_URL)
715-
if not tf.gfile.Exists(path):
716-
zipfile.ZipFile(path + ".zip", "r").extractall(directory)
717-
718-
719-
def celeba_generator(tmp_dir, how_many, start_from=0):
720-
"""Image generator for CELEBA dataset.
721-
722-
Args:
723-
tmp_dir: path to temporary storage directory.
724-
how_many: how many images and labels to generate.
725-
start_from: from which image to start.
726-
727-
Yields:
728-
A dictionary representing the images with the following fields:
729-
* image/encoded: the string encoding the image as JPEG,
730-
* image/format: the string "jpeg" representing image format,
731-
"""
732-
_get_celeba(tmp_dir)
733-
image_files = tf.gfile.Glob(os.path.join(tmp_dir, _CELEBA_NAME) + "/*.jpg")
734-
for filename in image_files[start_from:start_from + how_many]:
735-
with tf.gfile.Open(filename, "r") as f:
736-
encoded_image_data = f.read()
737-
yield {
738-
"image/encoded": [encoded_image_data],
739-
"image/format": ["jpeg"],
740-
}

tensor2tensor/data_generators/lm1b.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626

2727
# Dependency imports
2828

29-
from six.moves import xrange
29+
from six.moves import xrange # pylint: disable=redefined-builtin
30+
3031
from tensor2tensor.data_generators import generator_utils
3132
from tensor2tensor.data_generators import text_encoder
3233
from tensor2tensor.data_generators import tokenizer

tensor2tensor/data_generators/problem.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,10 @@ class Problem(object):
116116
* generate_data(data_dir, tmp_dir)
117117
- Generate training and dev datasets into data_dir.
118118
- Additonal files, e.g. vocabulary files, should also be written to
119-
data_dir.
119+
data_dir. Vocab files are newline-separated files with each line
120+
containing a token. The standard convention for the filename is to
121+
set it to be
122+
${Problem.vocab_name}.${Problem.targeted_vocab_size}
120123
- Downloads and other files can be written to tmp_dir
121124
- If you have a training and dev generator, you can generate the
122125
training and dev datasets with
@@ -200,22 +203,22 @@ def training_filepaths(self, data_dir, num_shards, shuffled):
200203
file_basename = self.dataset_filename()
201204
if not shuffled:
202205
file_basename += generator_utils.UNSHUFFLED_SUFFIX
203-
return generator_utils.train_data_filenames(
204-
file_basename, data_dir, num_shards)
206+
return generator_utils.train_data_filenames(file_basename, data_dir,
207+
num_shards)
205208

206209
def dev_filepaths(self, data_dir, num_shards, shuffled):
207210
file_basename = self.dataset_filename()
208211
if not shuffled:
209212
file_basename += generator_utils.UNSHUFFLED_SUFFIX
210-
return generator_utils.dev_data_filenames(
211-
file_basename, data_dir, num_shards)
213+
return generator_utils.dev_data_filenames(file_basename, data_dir,
214+
num_shards)
212215

213216
def test_filepaths(self, data_dir, num_shards, shuffled):
214217
file_basename = self.dataset_filename()
215218
if not shuffled:
216219
file_basename += generator_utils.UNSHUFFLED_SUFFIX
217-
return generator_utils.test_data_filenames(
218-
file_basename, data_dir, num_shards)
220+
return generator_utils.test_data_filenames(file_basename, data_dir,
221+
num_shards)
219222

220223
def __init__(self, was_reversed=False, was_copy=False):
221224
"""Create a Problem.
@@ -412,10 +415,8 @@ def generate_data(self, data_dir, tmp_dir, task_id=-1):
412415
generator_utils.shuffle_dataset(all_paths)
413416
else:
414417
generator_utils.generate_dataset_and_shuffle(
415-
self.generator(data_dir, tmp_dir, True),
416-
self.training_filepaths(data_dir, self.num_shards, shuffled=False),
417-
self.generator(data_dir, tmp_dir, False),
418-
self.dev_filepaths(data_dir, self.num_dev_shards, shuffled=False))
418+
self.generator(data_dir, tmp_dir, True), train_paths,
419+
self.generator(data_dir, tmp_dir, False), dev_paths)
419420

420421
def feature_encoders(self, data_dir):
421422
if self.is_character_level:
@@ -435,8 +436,9 @@ def hparams(self, defaults, unused_model_hparams):
435436

436437
if self.has_inputs:
437438
source_vocab_size = self._encoders["inputs"].vocab_size
438-
p.input_modality = {"inputs": (registry.Modalities.SYMBOL,
439-
source_vocab_size)}
439+
p.input_modality = {
440+
"inputs": (registry.Modalities.SYMBOL, source_vocab_size)
441+
}
440442
target_vocab_size = self._encoders["targets"].vocab_size
441443
p.target_modality = (registry.Modalities.SYMBOL, target_vocab_size)
442444
if self.has_inputs:

0 commit comments

Comments
 (0)