Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
seminar-breakout
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Shashank Suhas
seminar-breakout
Commits
0018fc13
Commit
0018fc13
authored
Feb 20, 2018
by
Yuxin Wu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add PeriodicCallback (fix #651)
parent
a5dc2dd8
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
79 additions
and
34 deletions
+79
-34
tensorpack/callbacks/graph.py
tensorpack/callbacks/graph.py
+2
-2
tensorpack/callbacks/monitor.py
tensorpack/callbacks/monitor.py
+16
-15
tensorpack/callbacks/saver.py
tensorpack/callbacks/saver.py
+1
-1
tensorpack/callbacks/stats.py
tensorpack/callbacks/stats.py
+2
-2
tensorpack/callbacks/trigger.py
tensorpack/callbacks/trigger.py
+58
-14
No files found.
tensorpack/callbacks/graph.py
View file @
0018fc13
...
@@ -29,9 +29,9 @@ class RunOp(Callback):
...
@@ -29,9 +29,9 @@ class RunOp(Callback):
op (tf.Operation or function): an Op, or a function that returns the Op in the graph.
op (tf.Operation or function): an Op, or a function that returns the Op in the graph.
The function will be called later (in the `setup_graph` callback).
The function will be called later (in the `setup_graph` callback).
run_before (bool): run the Op before training
run_before (bool): run the Op before training
run_as_trigger (bool): run the Op on every
trigger
run_as_trigger (bool): run the Op on every
:meth:`trigger()` call.
run_step (bool): run the Op every step (along with training)
run_step (bool): run the Op every step (along with training)
verbose (bool): prin
g
logs when the op is run.
verbose (bool): prin
t
logs when the op is run.
Examples:
Examples:
The `DQN Example
The `DQN Example
...
...
tensorpack/callbacks/monitor.py
View file @
0018fc13
...
@@ -266,7 +266,7 @@ class JSONWriter(TrainingMonitor):
...
@@ -266,7 +266,7 @@ class JSONWriter(TrainingMonitor):
self
.
_fname
=
os
.
path
.
join
(
self
.
_dir
,
self
.
FILENAME
)
self
.
_fname
=
os
.
path
.
join
(
self
.
_dir
,
self
.
FILENAME
)
if
os
.
path
.
isfile
(
self
.
_fname
):
if
os
.
path
.
isfile
(
self
.
_fname
):
logger
.
info
(
"Found
existing
JSON at {}, will append to it."
.
format
(
self
.
_fname
))
logger
.
info
(
"Found JSON at {}, will append to it."
.
format
(
self
.
_fname
))
with
open
(
self
.
_fname
)
as
f
:
with
open
(
self
.
_fname
)
as
f
:
self
.
_stats
=
json
.
load
(
f
)
self
.
_stats
=
json
.
load
(
f
)
assert
isinstance
(
self
.
_stats
,
list
),
type
(
self
.
_stats
)
assert
isinstance
(
self
.
_stats
,
list
),
type
(
self
.
_stats
)
...
@@ -277,7 +277,7 @@ class JSONWriter(TrainingMonitor):
...
@@ -277,7 +277,7 @@ class JSONWriter(TrainingMonitor):
pass
pass
else
:
else
:
# TODO is this a good idea?
# TODO is this a good idea?
logger
.
info
(
"Found
training history from JSON, now starting from epoch number
{}."
.
format
(
epoch
))
logger
.
info
(
"Found
history statistics from JSON. Rename the first epoch of this training to epoch #
{}."
.
format
(
epoch
))
self
.
trainer
.
loop
.
starting_epoch
=
epoch
self
.
trainer
.
loop
.
starting_epoch
=
epoch
self
.
trainer
.
loop
.
_epoch_num
=
epoch
-
1
self
.
trainer
.
loop
.
_epoch_num
=
epoch
-
1
else
:
else
:
...
@@ -289,16 +289,19 @@ class JSONWriter(TrainingMonitor):
...
@@ -289,16 +289,19 @@ class JSONWriter(TrainingMonitor):
def
_trigger_step
(
self
):
def
_trigger_step
(
self
):
# will do this in trigger_epoch
# will do this in trigger_epoch
if
self
.
local_step
!=
self
.
trainer
.
steps_per_epoch
-
1
:
if
self
.
local_step
!=
self
.
trainer
.
steps_per_epoch
-
1
:
self
.
_
push
()
self
.
_
trigger
()
def
_trigger_epoch
(
self
):
def
_trigger_epoch
(
self
):
self
.
_
push
()
self
.
_
trigger
()
def
process_scalar
(
self
,
name
,
val
):
def
process_scalar
(
self
,
name
,
val
):
self
.
_stat_now
[
name
]
=
val
self
.
_stat_now
[
name
]
=
val
def
_push
(
self
):
def
_trigger
(
self
):
""" Note that this method is idempotent"""
"""
Add stats to json and dump to disk.
Note that this method is idempotent.
"""
if
len
(
self
.
_stat_now
):
if
len
(
self
.
_stat_now
):
self
.
_stat_now
[
'epoch_num'
]
=
self
.
epoch_num
self
.
_stat_now
[
'epoch_num'
]
=
self
.
epoch_num
self
.
_stat_now
[
'global_step'
]
=
self
.
global_step
self
.
_stat_now
[
'global_step'
]
=
self
.
global_step
...
@@ -354,20 +357,21 @@ class ScalarPrinter(TrainingMonitor):
...
@@ -354,20 +357,21 @@ class ScalarPrinter(TrainingMonitor):
if
self
.
_enable_step
:
if
self
.
_enable_step
:
if
self
.
local_step
!=
self
.
trainer
.
steps_per_epoch
-
1
:
if
self
.
local_step
!=
self
.
trainer
.
steps_per_epoch
-
1
:
# not the last step
# not the last step
self
.
_
print_stat
()
self
.
_
trigger
()
else
:
else
:
if
not
self
.
_enable_epoch
:
if
not
self
.
_enable_epoch
:
self
.
_
print_stat
()
self
.
_
trigger
()
# otherwise, will print them together
# otherwise, will print them together
def
_trigger_epoch
(
self
):
def
_trigger_epoch
(
self
):
if
self
.
_enable_epoch
:
if
self
.
_enable_epoch
:
self
.
_
print_stat
()
self
.
_
trigger
()
def
process_scalar
(
self
,
name
,
val
):
def
process_scalar
(
self
,
name
,
val
):
self
.
_dic
[
name
]
=
float
(
val
)
self
.
_dic
[
name
]
=
float
(
val
)
def
_print_stat
(
self
):
def
_trigger
(
self
):
# Print stats here
def
match_regex_list
(
regexs
,
name
):
def
match_regex_list
(
regexs
,
name
):
for
r
in
regexs
:
for
r
in
regexs
:
if
r
.
search
(
name
)
is
not
None
:
if
r
.
search
(
name
)
is
not
None
:
...
@@ -438,12 +442,9 @@ class SendMonitorData(TrainingMonitor):
...
@@ -438,12 +442,9 @@ class SendMonitorData(TrainingMonitor):
self
.
dic
[
name
]
=
val
self
.
dic
[
name
]
=
val
def
_trigger_step
(
self
):
def
_trigger_step
(
self
):
self
.
_try_send
()
self
.
_trigger
()
def
_trigger_epoch
(
self
):
self
.
_try_send
()
def
_tr
y_send
(
self
):
def
_tr
igger
(
self
):
try
:
try
:
v
=
{
k
:
self
.
dic
[
k
]
for
k
in
self
.
names
}
v
=
{
k
:
self
.
dic
[
k
]
for
k
in
self
.
names
}
except
KeyError
:
except
KeyError
:
...
...
tensorpack/callbacks/saver.py
View file @
0018fc13
...
@@ -15,7 +15,7 @@ __all__ = ['ModelSaver', 'MinSaver', 'MaxSaver']
...
@@ -15,7 +15,7 @@ __all__ = ['ModelSaver', 'MinSaver', 'MaxSaver']
class
ModelSaver
(
Callback
):
class
ModelSaver
(
Callback
):
"""
"""
Save the model
every epoch
.
Save the model
once triggered
.
"""
"""
def
__init__
(
self
,
max_to_keep
=
10
,
def
__init__
(
self
,
max_to_keep
=
10
,
...
...
tensorpack/callbacks/stats.py
View file @
0018fc13
...
@@ -33,7 +33,7 @@ class InjectShell(Callback):
...
@@ -33,7 +33,7 @@ class InjectShell(Callback):
"""
"""
Allow users to create a specific file as a signal to pause
Allow users to create a specific file as a signal to pause
and iteratively debug the training.
and iteratively debug the training.
When
triggered, it detects whether the file exists, and opens an
Once
triggered, it detects whether the file exists, and opens an
IPython/pdb shell if yes.
IPython/pdb shell if yes.
In the shell, `self` is this callback, `self.trainer` is the trainer, and
In the shell, `self` is this callback, `self.trainer` is the trainer, and
from that you can access everything else.
from that you can access everything else.
...
@@ -71,7 +71,7 @@ class InjectShell(Callback):
...
@@ -71,7 +71,7 @@ class InjectShell(Callback):
class
DumpParamAsImage
(
Callback
):
class
DumpParamAsImage
(
Callback
):
"""
"""
Dump a tensor to image(s) to ``logger.get_logger_dir()``
after every epoch
.
Dump a tensor to image(s) to ``logger.get_logger_dir()``
once triggered
.
Note that it requires the tensor is directly evaluable, i.e. either inputs
Note that it requires the tensor is directly evaluable, i.e. either inputs
are not its dependency (e.g. the weights of the model), or the inputs are
are not its dependency (e.g. the weights of the model), or the inputs are
...
...
tensorpack/callbacks/trigger.py
View file @
0018fc13
...
@@ -5,15 +5,16 @@
...
@@ -5,15 +5,16 @@
from
.base
import
ProxyCallback
,
Callback
from
.base
import
ProxyCallback
,
Callback
__all__
=
[
'PeriodicTrigger'
,
'Periodic
RunHooks
'
,
'EnableCallbackIf'
]
__all__
=
[
'PeriodicTrigger'
,
'Periodic
Callback
'
,
'EnableCallbackIf'
]
class
PeriodicTrigger
(
ProxyCallback
):
class
PeriodicTrigger
(
ProxyCallback
):
"""
"""
Schedule to trigger a callback every k global steps or every k epochs by its ``trigger()`` method.
Schedule to 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
with :meth:`trigger()` method.
Note that it does not touch other methods (``before/after_run``,
All other methods (``before/after_run``, ``trigger_step``, etc) are unaffected.
``trigger_step``, etc).
"""
"""
_chief_only
=
False
_chief_only
=
False
...
@@ -21,11 +22,11 @@ class PeriodicTrigger(ProxyCallback):
...
@@ -21,11 +22,11 @@ class PeriodicTrigger(ProxyCallback):
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:
triggerable (Callback): a Callback instance with a
_
trigger method to be called.
triggerable (Callback): a Callback instance with a trigger method to be called.
every_k_steps (int): trigger when ``global_step
%
k == 0``. Set to
every_k_steps (int): trigger when ``global_step
%
k == 0``. Set to
None to
disabl
e.
None to
ignor
e.
every_k_epochs (int): trigger when ``epoch_num
%
k == 0``. Set to
every_k_epochs (int): trigger when ``epoch_num
%
k == 0``. Set to
None to
disabl
e.
None to
ignor
e.
every_k_steps and every_k_epochs can be both set, but cannot be both None.
every_k_steps and every_k_epochs can be both set, but cannot be both None.
"""
"""
...
@@ -37,6 +38,7 @@ class PeriodicTrigger(ProxyCallback):
...
@@ -37,6 +38,7 @@ class PeriodicTrigger(ProxyCallback):
self
.
_epoch_k
=
every_k_epochs
self
.
_epoch_k
=
every_k_epochs
def
_trigger_step
(
self
):
def
_trigger_step
(
self
):
self
.
cb
.
trigger_step
()
if
self
.
_step_k
is
None
:
if
self
.
_step_k
is
None
:
return
return
if
self
.
global_step
%
self
.
_step_k
==
0
:
if
self
.
global_step
%
self
.
_step_k
==
0
:
...
@@ -54,7 +56,7 @@ class PeriodicTrigger(ProxyCallback):
...
@@ -54,7 +56,7 @@ class PeriodicTrigger(ProxyCallback):
class
PeriodicRunHooks
(
ProxyCallback
):
class
PeriodicRunHooks
(
ProxyCallback
):
"""
"""
Schedu
le the ``{before,after}_run`` methods of a callback every k global steps.
Enab
le the ``{before,after}_run`` methods of a callback every k global steps.
All other methods are untouched.
All other methods are untouched.
"""
"""
...
@@ -87,9 +89,10 @@ class PeriodicRunHooks(ProxyCallback):
...
@@ -87,9 +89,10 @@ class PeriodicRunHooks(ProxyCallback):
class
EnableCallbackIf
(
ProxyCallback
):
class
EnableCallbackIf
(
ProxyCallback
):
"""
"""
Enable ``{before,after}_epoch``, ``{before,after}_run``, ``trigger*``
Enable ``{before,after}_epoch``, ``{before,after}_run``,
``trigger_{epoch,step}``
methods of a callback, only when some condition satisfies.
methods of a callback, only when some condition satisfies.
The other methods
will be called the same
.
The other methods
are unaffected
.
Note:
Note:
If you use ``{before,after}_run``,
If you use ``{before,after}_run``,
...
@@ -126,10 +129,6 @@ class EnableCallbackIf(ProxyCallback):
...
@@ -126,10 +129,6 @@ class EnableCallbackIf(ProxyCallback):
if
self
.
_pred
(
self
):
if
self
.
_pred
(
self
):
super
(
EnableCallbackIf
,
self
)
.
_after_epoch
()
super
(
EnableCallbackIf
,
self
)
.
_after_epoch
()
def
_trigger
(
self
):
if
self
.
_pred
(
self
):
super
(
EnableCallbackIf
,
self
)
.
_trigger
()
def
_trigger_epoch
(
self
):
def
_trigger_epoch
(
self
):
if
self
.
_pred
(
self
):
if
self
.
_pred
(
self
):
super
(
EnableCallbackIf
,
self
)
.
_trigger_epoch
()
super
(
EnableCallbackIf
,
self
)
.
_trigger_epoch
()
...
@@ -140,3 +139,48 @@ class EnableCallbackIf(ProxyCallback):
...
@@ -140,3 +139,48 @@ class EnableCallbackIf(ProxyCallback):
def
__str__
(
self
):
def
__str__
(
self
):
return
"EnableCallbackIf-"
+
str
(
self
.
cb
)
return
"EnableCallbackIf-"
+
str
(
self
.
cb
)
class
PeriodicCallback
(
EnableCallbackIf
):
"""
Make the calls to the following methods of a callback **less** frequent:
``{before,after}_epoch``, ``{before,after}_run``, ``trigger_{epoch,step}``.
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.
Note that this can only makes a callback **less** frequent than before.
:class:`PeriodicTrigger` can
make a callback which supports :meth:`trigger()` method more frequent than before.
"""
_chief_only
=
False
def
__init__
(
self
,
callback
,
every_k_steps
=
None
,
every_k_epochs
=
None
):
"""
Args:
callback (Callback): a Callback instance.
every_k_steps (int): enable the callback when ``global_step
%
k == 0``. Set to
None to ignore.
every_k_epochs (int): enable the callback when ``epoch_num
%
k == 0``. Set to
None to ignore.
every_k_steps and every_k_epochs can be both set, but cannot be both None.
"""
assert
isinstance
(
callback
,
Callback
),
type
(
callback
)
assert
(
every_k_epochs
is
not
None
)
or
(
every_k_steps
is
not
None
),
\
"every_k_steps and every_k_epochs cannot be both None!"
self
.
_step_k
=
every_k_steps
self
.
_epoch_k
=
every_k_epochs
super
(
PeriodicCallback
,
self
)
.
__init__
(
callback
,
PeriodicCallback
.
predicate
)
def
predicate
(
self
):
if
self
.
_step_k
is
not
None
and
self
.
global_step
%
self
.
_step_k
==
0
:
return
True
if
self
.
_epoch_k
is
not
None
and
self
.
epoch_num
%
self
.
_epoch_k
==
0
:
return
True
return
False
def
__str__
(
self
):
return
"PeriodicCallback-"
+
str
(
self
.
cb
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment