Idea is to simplify current logger's API by creating a shortcut methods:
Currently, to log output parameters and optmizer's params we do (example is for TB, but is generic for others too):
logger = TensorboardLogger(...)
logger.attach(
trainer,
log_handler=OutputHandler(tag="training", metric_names="all"),
event_name=Events.ITERATION_COMPLETED(every=log_every_iters),
)
logger.attach(
trainer,
log_handler=OptimizerParamsHandler(optimizer, param_name="lr", tag=k),
event_name=Events.ITERATION_STARTED(every=log_every_iters),
)
Proposed API:
logger = TensorboardLogger(...)
logger.attach_output_handler(
trainer,
tag="training", metric_names="all", # other args, kwargs of OutputHandler
event_name=Events.ITERATION_COMPLETED(every=log_every_iters),
)
logger.attach_opt_params_handler(
trainer,
optimizer, param_name="lr", tag=k, # other args, kwargs of OutputHandler
event_name=Events.ITERATION_STARTED(every=log_every_iters),
)
In addition, this can fix "bad-practice" current implementation of setup_any_logging taking as input logger and logging_module:
https://github.com/pytorch/ignite/blob/d1aa5fd5e71676032c952aa7470a651c216e2dd9/ignite/contrib/engines/common.py#L209
@sdesrozis any other suggestions for simplified API
cc @sisp (if you have any suggestions too), once this issue is solved we can fix and merge your PR #901
I don't have any suggestion. We might have a generic attachment using getattr.
We might have a generic attachment using getattr.
@sdesrozis, please, this point
We might have a generic attachment using getattr.
@sdesrozis, please, this point
Class is encoded in name of methods. Using __getattr__, I think that it is possible to parse the name and allocate related object in a generic way.
class Obj1:
def __init__(self, name, value):
self.name = name
self.value = value
class Obj2:
def __init__(self, name):
self.name = name
class Logger:
def __init__(self):
self.obj = None
def attach(self, obj):
self.obj = obj
def __getattr__(self, item):
# fake transform to find class
cls = item.replace("attach_", "").replace("_", "").capitalize()
cls = eval(cls)
def wrapper(*args, **kwargs):
self.attach(obj=cls(*args, **kwargs))
return wrapper
if __name__ == '__main__':
logger = Logger()
logger.attach_obj_1(name="ok", value=3)
print(logger.obj)
logger.attach_obj_2(name="ok")
print(logger.obj)
@sdesrozis it's too hacky for me, such approach.
Let's implement the methods logger.attach_output_handler and logger.attach_opt_params_handler. Anyone would like to work on it ?
I will do it this week-end if nobody does ;)
Most helpful comment
@sdesrozis it's too hacky for me, such approach.
Let's implement the methods
logger.attach_output_handlerandlogger.attach_opt_params_handler. Anyone would like to work on it ?