Commit 2b94b70e authored by Yuxin Wu's avatar Yuxin Wu

update docs

parent a8b72a87
...@@ -58,7 +58,7 @@ implement different distribution strategies. ...@@ -58,7 +58,7 @@ implement different distribution strategies.
They take care of device placement, gradient averaging and synchronoization They take care of device placement, gradient averaging and synchronoization
in the efficient way and all reach the same performance as the in the efficient way and all reach the same performance as the
[official TF benchmarks](https://www.tensorflow.org/performance/benchmarks). [official TF benchmarks](https://www.tensorflow.org/performance/benchmarks).
It takes only one line of code change to use them, i.e. `trainer=SyncMultiGPUTrainerReplicated()`. It takes only one line of code change to use them, e.g. `trainer=SyncMultiGPUTrainerReplicated(...)`.
Note some __common problems__ when using these trainers: Note some __common problems__ when using these trainers:
......
...@@ -7,8 +7,7 @@ when you don't want to customize too much. ...@@ -7,8 +7,7 @@ when you don't want to customize too much.
### With ModelDesc and TrainConfig ### With ModelDesc and TrainConfig
This is an interface that's most familiar to old tensorpack users, This interface is enough for most types of single-cost tasks.
and is used for single-cost tasks only.
A lot of examples are written in this interface. A lot of examples are written in this interface.
[SingleCost trainers](../modules/train.html#tensorpack.train.SingleCostTrainer) [SingleCost trainers](../modules/train.html#tensorpack.train.SingleCostTrainer)
...@@ -20,24 +19,22 @@ class MyModel(ModelDesc): ...@@ -20,24 +19,22 @@ class MyModel(ModelDesc):
def inputs(self): def inputs(self):
return [tf.placeholder(dtype, shape, name), tf.placeholder(dtype, shape, name), ... ] return [tf.placeholder(dtype, shape, name), tf.placeholder(dtype, shape, name), ... ]
def _build_graph(self, inputs): def build_graph(self, tensorA, tensorB, ...): # inputs
tensorA, tensorB = inputs
# build the graph # build the graph
self.cost = xxx # define the cost tensor return cost # returns the cost tensor
def _get_optimizer(self): def optimizer(self):
return tf.train.GradientDescentOptimizer(0.1) return tf.train.GradientDescentOptimizer(0.1)
``` ```
`_get_inputs` should define the metainfo of all the inputs your graph will take to build. `inputs` should define the metainfo of all the inputs your graph will take to build.
`_build_graph` takes a list of `inputs` tensors which will match `_get_inputs`. `build_graph` takes inputs tensors that matches what you've defined in `inputs()`.
You can use any symbolic functions in `_build_graph`, including TensorFlow core library You can use any symbolic functions in `build_graph`, including TensorFlow core library
functions and other symbolic libraries. functions and other symbolic libraries.
`_build_graph` will be the tower function, `build_graph` will be the tower function, so you need to follow [some rules](trainer.md#tower-trainer).
so you need to follow [some rules](trainer.md#tower-trainer). Because this interface is for single-cost training, you need to return the cost tensor.
You also need to set `self.cost` in this function.
After defining such a model, use it with `TrainConfig` and `launch_train_with_config`: After defining such a model, use it with `TrainConfig` and `launch_train_with_config`:
...@@ -61,18 +58,23 @@ and ...@@ -61,18 +58,23 @@ and
[launch_train_with_config](../modules/train.html#tensorpack.train.launch_train_with_config) [launch_train_with_config](../modules/train.html#tensorpack.train.launch_train_with_config)
for detailed functionalities. for detailed functionalities.
### Keras Interface
Some wrappers were made on top of tensorpack trainers, to create a Keras-like
interface. See [Tensorpack+Keras examples](../examples/keras) for details.
### Raw Trainer Interface ### Raw Trainer Interface
To get a lower-level control, you can also access methods of trainer directly: To get a lower-level control, you can also access trainer methods directly:
__Build__ the graph: For general trainer, build the graph by yourself. __Build the graph__:
For single-cost trainer, build the graph by For single-cost trainers, build the graph by calling
[SingleCostTrainer.setup_graph](../modules/train.html#tensorpack.train.SingleCostTrainer.setup_graph). [SingleCostTrainer.setup_graph](../modules/train.html#tensorpack.train.SingleCostTrainer.setup_graph).
__Run__ the iterations: Call __Start training__: Call
[Trainer.train()](../modules/train.html#tensorpack.train.Trainer.train), [Trainer.train()](../modules/train.html#tensorpack.train.Trainer.train),
or or
[Trainer.train_with_defaults()](../modules/train.html#tensorpack.train.Trainer.train_with_defaults) [Trainer.train_with_defaults()](../modules/train.html#tensorpack.train.Trainer.train_with_defaults)
which applies some defaults options for normal use cases. which applies some defaults options for common use cases.
Read the API documentation for detail usage. Read their API documentation for detail usage.
...@@ -139,15 +139,15 @@ def multilevel_rpn_losses( ...@@ -139,15 +139,15 @@ def multilevel_rpn_losses(
assert len(multilevel_box_logits) == num_lvl assert len(multilevel_box_logits) == num_lvl
losses = [] losses = []
for lvl in range(num_lvl):
with tf.name_scope('RPNLoss_Lvl{}'.format(lvl + 2)):
anchors = multilevel_anchors[lvl]
label_loss, box_loss = rpn_losses(
anchors.gt_labels, anchors.encoded_gt_boxes(),
multilevel_label_logits[lvl], multilevel_box_logits[lvl])
losses.extend([label_loss, box_loss])
with tf.name_scope('rpn_losses'): with tf.name_scope('rpn_losses'):
for lvl in range(num_lvl):
with tf.name_scope('Level{}'.format(lvl + 2)):
anchors = multilevel_anchors[lvl]
label_loss, box_loss = rpn_losses(
anchors.gt_labels, anchors.encoded_gt_boxes(),
multilevel_label_logits[lvl], multilevel_box_logits[lvl])
losses.extend([label_loss, box_loss])
total_label_loss = tf.add_n(losses[::2], name='label_loss') total_label_loss = tf.add_n(losses[::2], name='label_loss')
total_box_loss = tf.add_n(losses[1::2], name='box_loss') total_box_loss = tf.add_n(losses[1::2], name='box_loss')
add_moving_summary(total_label_loss, total_box_loss) add_moving_summary(total_label_loss, total_box_loss)
......
...@@ -37,7 +37,6 @@ def rpn_head(featuremap, channel, num_anchors): ...@@ -37,7 +37,6 @@ def rpn_head(featuremap, channel, num_anchors):
return label_logits, box_logits return label_logits, box_logits
@under_name_scope()
def rpn_losses(anchor_labels, anchor_boxes, label_logits, box_logits): def rpn_losses(anchor_labels, anchor_boxes, label_logits, box_logits):
""" """
Args: Args:
......
...@@ -200,8 +200,9 @@ class ResNetC4Model(DetectionModel): ...@@ -200,8 +200,9 @@ class ResNetC4Model(DetectionModel):
if is_training: if is_training:
# rpn loss # rpn loss
rpn_label_loss, rpn_box_loss = rpn_losses( with tf.name_scope('rpn_losses'):
anchors.gt_labels, anchors.encoded_gt_boxes(), rpn_label_logits, rpn_box_logits) rpn_label_loss, rpn_box_loss = rpn_losses(
anchors.gt_labels, anchors.encoded_gt_boxes(), rpn_label_logits, rpn_box_logits)
# fastrcnn loss # fastrcnn loss
matched_gt_boxes = tf.gather(gt_boxes, fg_inds_wrt_gt) matched_gt_boxes = tf.gather(gt_boxes, fg_inds_wrt_gt)
......
...@@ -169,11 +169,11 @@ def get_config(): ...@@ -169,11 +169,11 @@ def get_config():
if __name__ == '__main__': if __name__ == '__main__':
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--gpu', help='comma separated list of GPU(s) to use.') parser.add_argument('--gpu', type=int, help='the GPU to use')
parser.add_argument('--load', help='load model') parser.add_argument('--load', help='load model')
args = parser.parse_args() args = parser.parse_args()
if args.gpu: if args.gpu:
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu os.environ['CUDA_VISIBLE_DEVICES'] = str(args.gpu)
config = get_config() config = get_config()
if args.load: if args.load:
......
...@@ -29,7 +29,7 @@ class CallbackToHook(tf.train.SessionRunHook): ...@@ -29,7 +29,7 @@ class CallbackToHook(tf.train.SessionRunHook):
class HookToCallback(Callback): class HookToCallback(Callback):
""" """
Make a ``tf.train.SessionRunHook`` into a callback. Make a ``tf.train.SessionRunHook`` into a callback.
Note that the `coord` argument in `after_create_session` will be None. Note that when `SessionRunHook.after_create_session` is called, the `coord` argument will be None.
""" """
_chief_only = False _chief_only = False
......
...@@ -9,15 +9,13 @@ __all__ = ['PeriodicTrigger', 'PeriodicCallback', 'EnableCallbackIf'] ...@@ -9,15 +9,13 @@ __all__ = ['PeriodicTrigger', 'PeriodicCallback', 'EnableCallbackIf']
class PeriodicTrigger(ProxyCallback): class PeriodicTrigger(ProxyCallback):
""" """
Schedule to trigger a callback every k global steps or every k epochs by its :meth:`trigger()` method. Trigger a callback every k global steps or every k epochs by its :meth:`trigger()` method.
Most existing callbacks which do something every epoch are implemented Most existing callbacks which do something every epoch are implemented
with :meth:`trigger()` method. with :meth:`trigger()` method.
All other methods (``before/after_run``, ``trigger_step``, etc) are unaffected. All other methods (``before/after_run``, ``trigger_step``, etc) of the input callback are unaffected.
""" """
_chief_only = False
def __init__(self, triggerable, every_k_steps=None, every_k_epochs=None): def __init__(self, triggerable, every_k_steps=None, every_k_epochs=None):
""" """
Args: Args:
...@@ -59,8 +57,6 @@ class PeriodicRunHooks(ProxyCallback): ...@@ -59,8 +57,6 @@ class PeriodicRunHooks(ProxyCallback):
All other methods are untouched. All other methods are untouched.
""" """
_chief_only = False
def __init__(self, callback, every_k_steps): def __init__(self, callback, every_k_steps):
""" """
Args: Args:
...@@ -88,7 +84,7 @@ class PeriodicRunHooks(ProxyCallback): ...@@ -88,7 +84,7 @@ class PeriodicRunHooks(ProxyCallback):
class EnableCallbackIf(ProxyCallback): class EnableCallbackIf(ProxyCallback):
""" """
Enable ``{before,after}_epoch``, ``{before,after}_run``, Enable the ``{before,after}_epoch``, ``{before,after}_run``,
``trigger_{epoch,step}`` ``trigger_{epoch,step}``
methods of a callback, only when some condition satisfies. methods of a callback, only when some condition satisfies.
The other methods are unaffected. The other methods are unaffected.
...@@ -98,8 +94,6 @@ class EnableCallbackIf(ProxyCallback): ...@@ -98,8 +94,6 @@ class EnableCallbackIf(ProxyCallback):
``pred`` will be evaluated only in ``before_run``. ``pred`` will be evaluated only in ``before_run``.
""" """
_chief_only = False
def __init__(self, callback, pred): def __init__(self, callback, pred):
""" """
Args: Args:
...@@ -142,19 +136,15 @@ class EnableCallbackIf(ProxyCallback): ...@@ -142,19 +136,15 @@ class EnableCallbackIf(ProxyCallback):
class PeriodicCallback(EnableCallbackIf): class PeriodicCallback(EnableCallbackIf):
""" """
Make the calls to the following methods of a callback **less** frequent: The ``{before,after}_epoch``, ``{before,after}_run``, ``trigger_{epoch,step}``
``{before,after}_epoch``, ``{before,after}_run``, ``trigger_{epoch,step}``. methods of the given callback will be enabled only when ``global_step % every_k_steps == 0`
These methods will be enabled only when ``global_step % every_k_steps == 0`
or ``epoch_num % every_k_epochs == 0``. The other methods are unaffected. or ``epoch_num % every_k_epochs == 0``. The other methods are unaffected.
Note that this can only makes a callback **less** frequent than before. Note that this can only makes a callback **less** frequent than itself.
:class:`PeriodicTrigger` can If you have a callback that by default runs every epoch by its :meth:`trigger()` method,
make a callback which supports :meth:`trigger()` method more frequent than before. use :class:`PeriodicTrigger` to schedule it more frequent than itself.
""" """
_chief_only = False
def __init__(self, callback, every_k_steps=None, every_k_epochs=None): def __init__(self, callback, every_k_steps=None, every_k_epochs=None):
""" """
Args: Args:
......
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