Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ad386df
Pass datasets_num_private_threads flag into Keras resnet model. (#6211)
Feb 19, 2019
c40b46f
Rename deetection_inference.py to detection_inference.py (#6199)
ctessum Feb 21, 2019
733535d
Add gitignore entries for word-embedding tutorial training data files…
marpaia Feb 21, 2019
4571d3f
Add flag to enable XLA in Keras models (#6240)
haoyuz Feb 21, 2019
9bf1fd0
Fix import statement in OD g3doc (#6239)
chardch Feb 21, 2019
f2e9094
Multi-worker support for Resnet. (#6206)
dubey Feb 21, 2019
5c6fa14
Allow user to specify root_data_dir in the benchmark class constructo…
lindong28 Feb 22, 2019
5f4d34f
Add kwargs to make the benchmark class constructor forward compatible…
lindong28 Feb 22, 2019
21a4ad7
Remove isintance change for contrib strategy (#6250)
guptapriya Feb 22, 2019
da1d3e6
Set data_dir to cifar-10-batches-bin in keras_cifar_benchmark.py (#6251)
lindong28 Feb 22, 2019
a432998
optional parameter error in calling _build_faster_rcnn_feature_extrac…
haichaoyu Feb 23, 2019
2c96211
Open source deeplab changes. Check change log in README.md for detail…
huihui-personal Feb 24, 2019
338088d
Add root_data_dir to constructor of Resnet50KerasBenchmarkSynth and R…
lindong28 Feb 25, 2019
5274ec8
Fixed incorrect tensor and python3 compatibility (#6280)
adrianboguszewski Feb 27, 2019
e1ae37c
Open-source FEELVOS model, which was developed by Paul Voigtlaender d…
aquariusjay Feb 27, 2019
4b566d4
Updating stale DistributionStrategy test. (#6281)
tayo Feb 28, 2019
f0899f1
Update the codes due to recent change in DeepLab. (#6287)
aquariusjay Feb 28, 2019
54dffe2
Add benchmarks for thread tuning. (#6283)
Feb 28, 2019
d793ea8
Change `CollectiveAllReduceStrategy` to `MultiWorkerMirroredStrategy`…
dubey Feb 28, 2019
a76cd3a
Update imagenet_preprocessing.py (#6291)
yashk2810 Mar 1, 2019
fa9ed45
Add Keras XLA Tests (#6286)
haoyuz Mar 1, 2019
048e5bf
Keras-fy NCF Model (#6092)
seemuch Mar 1, 2019
8367cf6
fix resnet breakage and add keras end-to-end tests (#6295)
Mar 2, 2019
e4a046e
Mixed precision support (#6309)
reedwm Mar 6, 2019
cce6c09
speedup caption generator on im2txt (#6255)
rola93 Mar 6, 2019
258b77c
Add fp16 to keras benchmarks (#6314)
reedwm Mar 7, 2019
05a79f5
Add command line option for multi worker collective implementations, …
dubey Mar 7, 2019
8cf8446
Adding panoptic evaluation tools and update internal changes. (#6320)
YknZhu Mar 7, 2019
a5db442
No checkpointing only if multi worker strategy. (#6322)
dubey Mar 7, 2019
0558408
Merged commit includes the following changes: (#6315)
pkulzc Mar 7, 2019
0473c61
Removed resize from training graph
DragosBobolea Feb 27, 2018
9f53fad
fix eval.py for python3
DragosBobolea Mar 8, 2019
191c86a
resnet 18 support
AdamStefan May 20, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,8 @@ ENV/
# For mac
.DS_Store

# Training data for word embedding tutorial
tutorials/embedding/text8
tutorials/embedding/questions-words.txt

samples/outreach/blogs/segmentation_blogpost/carvana-image-masking-challenge/
7 changes: 6 additions & 1 deletion official/recommendation/data_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ def data_generator(self, epochs_between_evals):
self._result_reuse.append(result)
yield result

def increment_request_epoch(self):
self._epochs_requested += 1

def get_dataset(self, batch_size, epochs_between_evals):
"""Construct the dataset to be used for training and eval.
Expand All @@ -248,7 +250,7 @@ def get_dataset(self, batch_size, epochs_between_evals):
epochs_between_evals: How many epochs worth of data to yield.
(Generator mode only.)
"""
self._epochs_requested += 1
self.increment_request_epoch()
if self._stream_files:
if epochs_between_evals > 1:
raise ValueError("epochs_between_evals > 1 not supported for file "
Expand Down Expand Up @@ -626,6 +628,9 @@ def make_input_fn(self, is_training):
self._train_dataset.make_input_fn(self.train_batch_size) if is_training
else self._eval_dataset.make_input_fn(self.eval_batch_size))

def increment_request_epoch(self):
self._train_dataset.increment_request_epoch()


class DummyConstructor(threading.Thread):
"""Class for running with synthetic data."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,131 +12,62 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""NCF framework to train and evaluate the NeuMF model.

The NeuMF model assembles both MF and MLP models under the NCF framework. Check
`neumf_model.py` for more details about the models.
"""Common functionalities used by both Keras and Estimator implementations.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import contextlib
import heapq
import json
import logging
import math
import multiprocessing
import os
import signal
import typing

# pylint: disable=g-bad-import-order
import numpy as np
from absl import app as absl_app
from absl import flags
import tensorflow as tf
# pylint: enable=g-bad-import-order

from tensorflow.contrib.compiler import xla
from official.datasets import movielens
from official.recommendation import constants as rconst
from official.recommendation import data_pipeline
from official.recommendation import data_preprocessing
from official.recommendation import neumf_model
from official.utils.flags import core as flags_core
from official.utils.logs import hooks_helper
from official.utils.logs import logger
from official.utils.logs import mlperf_helper
from official.utils.misc import distribution_utils
from official.utils.misc import model_helpers


FLAGS = flags.FLAGS


def construct_estimator(model_dir, params):
"""Construct either an Estimator or TPUEstimator for NCF.

Args:
model_dir: The model directory for the estimator
params: The params dict for the estimator

Returns:
An Estimator or TPUEstimator.
"""

if params["use_tpu"]:
# Some of the networking libraries are quite chatty.
for name in ["googleapiclient.discovery", "googleapiclient.discovery_cache",
"oauth2client.transport"]:
logging.getLogger(name).setLevel(logging.ERROR)

tpu_cluster_resolver = tf.contrib.cluster_resolver.TPUClusterResolver(
tpu=params["tpu"],
zone=params["tpu_zone"],
project=params["tpu_gcp_project"],
coordinator_name="coordinator"
)

tf.logging.info("Issuing reset command to TPU to ensure a clean state.")
tf.Session.reset(tpu_cluster_resolver.get_master())

# Estimator looks at the master it connects to for MonitoredTrainingSession
# by reading the `TF_CONFIG` environment variable, and the coordinator
# is used by StreamingFilesDataset.
tf_config_env = {
"session_master": tpu_cluster_resolver.get_master(),
"eval_session_master": tpu_cluster_resolver.get_master(),
"coordinator": tpu_cluster_resolver.cluster_spec()
.as_dict()["coordinator"]
}
os.environ['TF_CONFIG'] = json.dumps(tf_config_env)
def get_inputs(params):
"""Returns some parameters used by the model."""
if FLAGS.download_if_missing and not FLAGS.use_synthetic_data:
movielens.download(FLAGS.dataset, FLAGS.data_dir)

distribution = tf.contrib.distribute.TPUStrategy(
tpu_cluster_resolver, steps_per_run=100)
if FLAGS.seed is not None:
np.random.seed(FLAGS.seed)

if FLAGS.use_synthetic_data:
producer = data_pipeline.DummyConstructor()
num_users, num_items = data_preprocessing.DATASET_TO_NUM_USERS_AND_ITEMS[
FLAGS.dataset]
num_train_steps = rconst.SYNTHETIC_BATCHES_PER_EPOCH
num_eval_steps = rconst.SYNTHETIC_BATCHES_PER_EPOCH
else:
distribution = distribution_utils.get_distribution_strategy(
num_gpus=params["num_gpus"])
num_users, num_items, producer = data_preprocessing.instantiate_pipeline(
dataset=FLAGS.dataset, data_dir=FLAGS.data_dir, params=params,
constructor_type=FLAGS.constructor_type,
deterministic=FLAGS.seed is not None)

run_config = tf.estimator.RunConfig(train_distribute=distribution,
eval_distribute=distribution)

model_fn = neumf_model.neumf_model_fn
if params["use_xla_for_gpu"]:
tf.logging.info("Using XLA for GPU for training and evaluation.")
model_fn = xla.estimator_model_fn(model_fn)
estimator = tf.estimator.Estimator(model_fn=model_fn, model_dir=model_dir,
config=run_config, params=params)
return estimator


def log_and_get_hooks(eval_batch_size):
"""Convenience function for hook and logger creation."""
# Create hooks that log information about the training and metric values
train_hooks = hooks_helper.get_train_hooks(
FLAGS.hooks,
model_dir=FLAGS.model_dir,
batch_size=FLAGS.batch_size, # for ExamplesPerSecondHook
tensors_to_log={"cross_entropy": "cross_entropy"}
)
run_params = {
"batch_size": FLAGS.batch_size,
"eval_batch_size": eval_batch_size,
"number_factors": FLAGS.num_factors,
"hr_threshold": FLAGS.hr_threshold,
"train_epochs": FLAGS.train_epochs,
}
benchmark_logger = logger.get_benchmark_logger()
benchmark_logger.log_run_info(
model_name="recommendation",
dataset_name=FLAGS.dataset,
run_params=run_params,
test_id=FLAGS.benchmark_test_id)
num_train_steps = (producer.train_batches_per_epoch //
params["batches_per_step"])
num_eval_steps = (producer.eval_batches_per_epoch //
params["batches_per_step"])
assert not producer.train_batches_per_epoch % params["batches_per_step"]
assert not producer.eval_batches_per_epoch % params["batches_per_step"]

return benchmark_logger, train_hooks
return num_users, num_items, num_train_steps, num_eval_steps, producer


def parse_flags(flags_obj):
Expand Down Expand Up @@ -174,112 +105,62 @@ def parse_flags(flags_obj):
"match_mlperf": flags_obj.ml_perf,
"use_xla_for_gpu": flags_obj.use_xla_for_gpu,
"epochs_between_evals": FLAGS.epochs_between_evals,
"turn_off_distribution_strategy": FLAGS.turn_off_distribution_strategy,
}


def main(_):
with logger.benchmark_context(FLAGS), \
mlperf_helper.LOGGER(FLAGS.output_ml_perf_compliance_logging):
mlperf_helper.set_ncf_root(os.path.split(os.path.abspath(__file__))[0])
run_ncf(FLAGS)


def run_ncf(_):
"""Run NCF training and eval loop."""
if FLAGS.download_if_missing and not FLAGS.use_synthetic_data:
movielens.download(FLAGS.dataset, FLAGS.data_dir)

if FLAGS.seed is not None:
np.random.seed(FLAGS.seed)

params = parse_flags(FLAGS)
total_training_cycle = FLAGS.train_epochs // FLAGS.epochs_between_evals

if FLAGS.use_synthetic_data:
producer = data_pipeline.DummyConstructor()
num_users, num_items = data_preprocessing.DATASET_TO_NUM_USERS_AND_ITEMS[
FLAGS.dataset]
num_train_steps = rconst.SYNTHETIC_BATCHES_PER_EPOCH
num_eval_steps = rconst.SYNTHETIC_BATCHES_PER_EPOCH
else:
num_users, num_items, producer = data_preprocessing.instantiate_pipeline(
dataset=FLAGS.dataset, data_dir=FLAGS.data_dir, params=params,
constructor_type=FLAGS.constructor_type,
deterministic=FLAGS.seed is not None)

num_train_steps = (producer.train_batches_per_epoch //
params["batches_per_step"])
num_eval_steps = (producer.eval_batches_per_epoch //
params["batches_per_step"])
assert not producer.train_batches_per_epoch % params["batches_per_step"]
assert not producer.eval_batches_per_epoch % params["batches_per_step"]
producer.start()

params["num_users"], params["num_items"] = num_users, num_items
model_helpers.apply_clean(flags.FLAGS)

estimator = construct_estimator(model_dir=FLAGS.model_dir, params=params)

benchmark_logger, train_hooks = log_and_get_hooks(params["eval_batch_size"])

target_reached = False
mlperf_helper.ncf_print(key=mlperf_helper.TAGS.TRAIN_LOOP)
for cycle_index in range(total_training_cycle):
assert FLAGS.epochs_between_evals == 1 or not mlperf_helper.LOGGER.enabled
tf.logging.info("Starting a training cycle: {}/{}".format(
cycle_index + 1, total_training_cycle))

mlperf_helper.ncf_print(key=mlperf_helper.TAGS.TRAIN_EPOCH,
value=cycle_index)

train_input_fn = producer.make_input_fn(is_training=True)
estimator.train(input_fn=train_input_fn, hooks=train_hooks,
steps=num_train_steps)
def get_optimizer(params):
optimizer = tf.train.AdamOptimizer(
learning_rate=params["learning_rate"],
beta1=params["beta1"],
beta2=params["beta2"],
epsilon=params["epsilon"])
if params["use_tpu"]:
optimizer = tf.contrib.tpu.CrossShardOptimizer(optimizer)

tf.logging.info("Beginning evaluation.")
eval_input_fn = producer.make_input_fn(is_training=False)
return optimizer

mlperf_helper.ncf_print(key=mlperf_helper.TAGS.EVAL_START,
value=cycle_index)
eval_results = estimator.evaluate(eval_input_fn, steps=num_eval_steps)
tf.logging.info("Evaluation complete.")

hr = float(eval_results[rconst.HR_KEY])
ndcg = float(eval_results[rconst.NDCG_KEY])
loss = float(eval_results["loss"])
def get_distribution_strategy(params):
"""Returns the distribution strategy to use."""
if params["turn_off_distribution_strategy"]:
return None

mlperf_helper.ncf_print(
key=mlperf_helper.TAGS.EVAL_TARGET,
value={"epoch": cycle_index, "value": FLAGS.hr_threshold})
mlperf_helper.ncf_print(key=mlperf_helper.TAGS.EVAL_ACCURACY,
value={"epoch": cycle_index, "value": hr})
mlperf_helper.ncf_print(
key=mlperf_helper.TAGS.EVAL_HP_NUM_NEG,
value={"epoch": cycle_index, "value": rconst.NUM_EVAL_NEGATIVES})
if params["use_tpu"]:
# Some of the networking libraries are quite chatty.
for name in ["googleapiclient.discovery", "googleapiclient.discovery_cache",
"oauth2client.transport"]:
logging.getLogger(name).setLevel(logging.ERROR)

mlperf_helper.ncf_print(key=mlperf_helper.TAGS.EVAL_STOP, value=cycle_index)
tpu_cluster_resolver = tf.contrib.cluster_resolver.TPUClusterResolver(
tpu=params["tpu"],
zone=params["tpu_zone"],
project=params["tpu_gcp_project"],
coordinator_name="coordinator"
)

# Benchmark the evaluation results
benchmark_logger.log_evaluation_result(eval_results)
# Log the HR and NDCG results.
tf.logging.info(
"Iteration {}: HR = {:.4f}, NDCG = {:.4f}, Loss = {:.4f}".format(
cycle_index + 1, hr, ndcg, loss))
tf.logging.info("Issuing reset command to TPU to ensure a clean state.")
tf.Session.reset(tpu_cluster_resolver.get_master())

# If some evaluation threshold is met
if model_helpers.past_stop_threshold(FLAGS.hr_threshold, hr):
target_reached = True
break
# Estimator looks at the master it connects to for MonitoredTrainingSession
# by reading the `TF_CONFIG` environment variable, and the coordinator
# is used by StreamingFilesDataset.
tf_config_env = {
"session_master": tpu_cluster_resolver.get_master(),
"eval_session_master": tpu_cluster_resolver.get_master(),
"coordinator": tpu_cluster_resolver.cluster_spec()
.as_dict()["coordinator"]
}
os.environ['TF_CONFIG'] = json.dumps(tf_config_env)

mlperf_helper.ncf_print(key=mlperf_helper.TAGS.RUN_STOP,
value={"success": target_reached})
producer.stop_loop()
producer.join()
distribution = tf.contrib.distribute.TPUStrategy(
tpu_cluster_resolver, steps_per_run=100)

# Clear the session explicitly to avoid session delete error
tf.keras.backend.clear_session()
else:
distribution = distribution_utils.get_distribution_strategy(
num_gpus=params["num_gpus"])

mlperf_helper.ncf_print(key=mlperf_helper.TAGS.RUN_FINAL)
return distribution


def define_ncf_flags():
Expand Down Expand Up @@ -421,6 +302,12 @@ def define_ncf_flags():
name="seed", default=None, help=flags_core.help_wrap(
"This value will be used to seed both NumPy and TensorFlow."))

flags.DEFINE_boolean(
name="turn_off_distribution_strategy",
default=False,
help=flags_core.help_wrap(
"If set, do not use any distribution strategy."))

@flags.validator("eval_batch_size", "eval_batch_size must be at least {}"
.format(rconst.NUM_EVAL_NEGATIVES + 1))
def eval_size_check(eval_batch_size):
Expand All @@ -438,7 +325,10 @@ def xla_validator(flag_dict):
return not flag_dict["use_xla_for_gpu"] or not flag_dict["tpu"]


if __name__ == "__main__":
tf.logging.set_verbosity(tf.logging.INFO)
define_ncf_flags()
absl_app.run(main)
def convert_to_softmax_logits(logits):
'''Convert the logits returned by the base model to softmax logits.

Softmax with the first column of zeros is equivalent to sigmoid.
'''
softmax_logits = tf.concat([logits * 0, logits], axis=1)
return softmax_logits
Loading