Ignite: Simplified base logger's API

Created on 25 Apr 2020  路  6Comments  路  Source: pytorch/ignite

馃殌 Feature

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

enhancement good first issue help wanted

Most helpful comment

@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 ?

All 6 comments

@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 ;)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

samarth-robo picture samarth-robo  路  3Comments

vfdev-5 picture vfdev-5  路  3Comments

vfdev-5 picture vfdev-5  路  3Comments

vfdev-5 picture vfdev-5  路  4Comments

TheCodez picture TheCodez  路  3Comments