From c502090b72bbca53b89c093d38fee98fda3a9c93 Mon Sep 17 00:00:00 2001 From: Javier Rey Date: Tue, 19 Sep 2017 23:00:31 -0300 Subject: [PATCH] Adds seed to config (and to evaluation tool) --- luminoth/datasets/object_detection_dataset.py | 4 ++-- .../datasets/object_detection_dataset_test.py | 1 + luminoth/eval.py | 18 ++++++++---------- luminoth/models/fasterrcnn/base_config.yml | 2 ++ luminoth/models/fasterrcnn/network.py | 5 ++--- luminoth/models/fasterrcnn/network_test.py | 13 ++++++------- luminoth/train.py | 15 +++++++-------- 7 files changed, 28 insertions(+), 30 deletions(-) diff --git a/luminoth/datasets/object_detection_dataset.py b/luminoth/datasets/object_detection_dataset.py index c5d27f29..52efcc93 100644 --- a/luminoth/datasets/object_detection_dataset.py +++ b/luminoth/datasets/object_detection_dataset.py @@ -33,7 +33,7 @@ class ObjectDetectionDataset(snt.AbstractModule): random_shuffle (bool): To consume the dataset using random shuffle or to just use a regular FIFO queue. """ - def __init__(self, config, seed=None, **kwargs): + def __init__(self, config, **kwargs): """ Save general purpose attributes for Dataset module. @@ -50,7 +50,7 @@ def __init__(self, config, seed=None, **kwargs): self._random_shuffle = config.train.random_shuffle # In case no keys are defined, default to empty list. self._data_augmentation = config.dataset.data_augmentation or [] - self._seed = seed + self._seed = config.train.seed def _build(): pass diff --git a/luminoth/datasets/object_detection_dataset_test.py b/luminoth/datasets/object_detection_dataset_test.py index f0d1a619..20bb4b39 100644 --- a/luminoth/datasets/object_detection_dataset_test.py +++ b/luminoth/datasets/object_detection_dataset_test.py @@ -22,6 +22,7 @@ def setUp(self): 'num_epochs': 1, 'batch_size': 1, 'random_shuffle': False, + 'seed': None, } }) diff --git a/luminoth/eval.py b/luminoth/eval.py index ab6f96d4..f6ec5f02 100644 --- a/luminoth/eval.py +++ b/luminoth/eval.py @@ -7,7 +7,7 @@ from luminoth.datasets import TFRecordDataset from luminoth.models import get_model from luminoth.utils.config import ( - load_config, merge_into, parse_override + get_model_config ) from luminoth.utils.bbox_overlap import bbox_overlap @@ -28,18 +28,12 @@ def evaluate(model_type, dataset_split, config_file, job_dir, watch, model_cls = get_model(model_type) config = model_cls.base_config - if config_file: - # If we have a custom config file overwritting default settings - # then we merge those values to the base_config. - custom_config = load_config(config_file) - config = merge_into(custom_config, config) + config = get_model_config( + model_cls.base_config, config_file, override_params + ) config.train.job_dir = job_dir or config.train.job_dir - if override_params: - override_config = parse_override(override_params) - config = merge_into(override_config, config) - if config.train.debug or config.train.tf_debug: tf.logging.set_verbosity(tf.logging.DEBUG) else: @@ -53,6 +47,10 @@ def evaluate(model_type, dataset_split, config_file, job_dir, watch, # Only a single run over the dataset to calculate metrics. config.train.num_epochs = 1 + # Seed setup + if config.train.seed: + tf.set_random_seed(config.train.seed) + # Set pretrained as not training config.pretrained.trainable = False diff --git a/luminoth/models/fasterrcnn/base_config.yml b/luminoth/models/fasterrcnn/base_config.yml index 6af723a0..fb1efc47 100644 --- a/luminoth/models/fasterrcnn/base_config.yml +++ b/luminoth/models/fasterrcnn/base_config.yml @@ -1,6 +1,8 @@ train: # Run on debug mode (which enables more logging) debug: False + # Seed for random operations + seed: # Training batch size for images. FasterRCNN currently only supports 1 batch_size: 1 # Directory in which model checkpoints & summaries (for Tensorboard) will be saved diff --git a/luminoth/models/fasterrcnn/network.py b/luminoth/models/fasterrcnn/network.py index da7352cd..c59d390f 100644 --- a/luminoth/models/fasterrcnn/network.py +++ b/luminoth/models/fasterrcnn/network.py @@ -23,8 +23,7 @@ class FasterRCNN(snt.AbstractModule): base_config = get_base_config(__file__) - def __init__(self, config, with_rcnn=True, num_classes=None, debug=False, - seed=None, name='fasterrcnn'): + def __init__(self, config, name='fasterrcnn'): super(FasterRCNN, self).__init__(name=name) # Main configuration object, it holds not only the necessary @@ -43,7 +42,7 @@ def __init__(self, config, with_rcnn=True, num_classes=None, debug=False, # Turn on debug mode with returns more Tensors which can be used for # better visualization and (of course) debugging. self._debug = config.train.debug - self._seed = seed + self._seed = config.train.seed # Anchor config, check out the docs of base_config.yml for a better # understanding of how anchors work. diff --git a/luminoth/models/fasterrcnn/network_test.py b/luminoth/models/fasterrcnn/network_test.py index ae79e1c1..37a5106e 100644 --- a/luminoth/models/fasterrcnn/network_test.py +++ b/luminoth/models/fasterrcnn/network_test.py @@ -17,7 +17,8 @@ def setUp(self): 'with_rcnn': True }, 'train': { - 'debug': True + 'debug': True, + 'seed': None, }, 'anchors': { 'base_size': 256, @@ -48,8 +49,7 @@ def setUp(self): 'type': 'variance_scaling_initializer', 'factor': 1.0, 'uniform': 'True', - 'mode': 'FAN_AVG', - 'seed': 0 + 'mode': 'FAN_AVG' }, 'roi': { 'pooling_mode': 'crop', @@ -76,8 +76,7 @@ def setUp(self): 'initializer': { 'type': 'truncated_normal_initializer', 'mean': 0.0, - 'stddev': 0.01, - 'seed': 0 + 'stddev': 0.01 }, 'activation_function': 'relu6', 'l2_regularization_scale': 0.0005, @@ -112,7 +111,7 @@ def _run_network(self): tf.float32, shape=self.image.shape) gt_boxes = tf.placeholder( tf.float32, shape=self.gt_boxes.shape) - model = FasterRCNN(self.config, debug=True) + model = FasterRCNN(self.config) results = model(image, gt_boxes) @@ -127,7 +126,7 @@ def _run_network(self): def _gen_anchors(self, config, feature_map): feature_map_tf = tf.placeholder( tf.float32, shape=feature_map.shape) - model = FasterRCNN(config, debug=True) + model = FasterRCNN(config) results = model._generate_anchors(feature_map) diff --git a/luminoth/train.py b/luminoth/train.py index 5ed96658..364ffa2f 100644 --- a/luminoth/train.py +++ b/luminoth/train.py @@ -15,12 +15,8 @@ ) -def run(model_type, config_file, override_params, seed, target='', - cluster_spec=None, is_chief=True, job_name=None, task_index=None, - **kwargs): - - if seed: - tf.set_random_seed(seed) +def run(model_type, config_file, override_params, target='', cluster_spec=None, + is_chief=True, job_name=None, task_index=None, **kwargs): model_class = get_model(model_type) @@ -28,6 +24,9 @@ def run(model_type, config_file, override_params, seed, target='', model_class.base_config, config_file, override_params, **kwargs ) + if config.train.seed is not None: + tf.set_random_seed(config.train.seed) + log_prefix = '[{}-{}] - '.format(job_name, task_index) \ if job_name is not None and task_index is not None else '' @@ -36,7 +35,7 @@ def run(model_type, config_file, override_params, seed, target='', else: tf.logging.set_verbosity(tf.logging.INFO) - model = model_class(config, seed=seed) + model = model_class(config) # Placement of ops on devices using replica device setter # which automatically places the parameters on the `ps` server @@ -45,7 +44,7 @@ def run(model_type, config_file, override_params, seed, target='', # See: # https://www.tensorflow.org/api_docs/python/tf/train/replica_device_setter with tf.device(tf.train.replica_device_setter(cluster=cluster_spec)): - dataset = TFRecordDataset(config, seed=seed) + dataset = TFRecordDataset(config) train_dataset = dataset() train_image = train_dataset['image']