Ignite: Would it be better to initialize the Engine with nn.Module?

Created on 9 Nov 2019  ·  2Comments  ·  Source: pytorch/ignite

When users create an engine, they use Engine(process_function) and the process_funtion will be saved as self._process_function. The requirements for process_function is that it must be callable and return output for future handlers. Since an nn.Module matchs these requirements, it can be used as an alternative.

And my question is would it be better to use nn.Module and expose it as self.module or self.net?

Here are my reasons:

  1. To use a function, we need define a model out of this function which will make the model a "global variable". However, if we use a model to initialize an engine, it can be a local variable.

  2. By using a model, we can access this model easily and flexibly in other handlers. For example, a user can attach a debugger to a model and call model.debug() to display information in some handlers. Or, when certain events are triggered, the user can change the behavior of the model.

question

Most helpful comment

@lzcn thanks for the feedback and a suggestion. If I understand correctly your point, in this case engine is a sort of associated with a single model, however the role of the engine to be generic and also handle other situations with multiple models: GAN, self-ensembling methods, etc. IMO, adopting your strategy would restrict the usage of the package.

If you would like to avoid global variables for model, criterion, optimizer, you can, for example, put them into engine.state or create a structure holding them:

def process_function(engine, batch):
    model = engine.state.model
    optimizer = engine.state.optimizer
    criterion = engine.state.criterion
    ...

trainer = Engine(process_function)

@trainer.on(Events.STARTED, model, optimizer, criterion)
def initialize_params(engine, _model, _opt, _crit):
     engine.state.model = _model
     engine.state.optimizer = _opt
     engine.state.criterion = _crit

# or simply just put them as attributes of the engine
trainer.model = model
trainer.optimizer = optimizer
trainer.criterion = criterion

What do you think ?

HTH

All 2 comments

@lzcn thanks for the feedback and a suggestion. If I understand correctly your point, in this case engine is a sort of associated with a single model, however the role of the engine to be generic and also handle other situations with multiple models: GAN, self-ensembling methods, etc. IMO, adopting your strategy would restrict the usage of the package.

If you would like to avoid global variables for model, criterion, optimizer, you can, for example, put them into engine.state or create a structure holding them:

def process_function(engine, batch):
    model = engine.state.model
    optimizer = engine.state.optimizer
    criterion = engine.state.criterion
    ...

trainer = Engine(process_function)

@trainer.on(Events.STARTED, model, optimizer, criterion)
def initialize_params(engine, _model, _opt, _crit):
     engine.state.model = _model
     engine.state.optimizer = _opt
     engine.state.criterion = _crit

# or simply just put them as attributes of the engine
trainer.model = model
trainer.optimizer = optimizer
trainer.criterion = criterion

What do you think ?

HTH

@lzcn thanks for the feedback and a suggestion. If I understand correctly your point, in this case engine is a sort of associated with a single model, however the role of the engine to be generic and also handle other situations with multiple models: GAN, self-ensembling methods, etc. IMO, adopting your strategy would restrict the usage of the package.

If you would like to avoid global variables for model, criterion, optimizer, you can, for example, put them into engine.state or create a structure holding them:

def process_function(engine, batch):
    model = engine.state.model
    optimizer = engine.state.optimizer
    criterion = engine.state.criterion
    ...

trainer = Engine(process_function)

@trainer.on(Events.STARTED, model, optimizer, criterion)
def initialize_params(engine, _model, _opt, _crit):
     engine.state.model = _model
     engine.state.optimizer = _opt
     engine.state.criterion = _crit

# or simply just put them as attributes of the engine
trainer.model = model
trainer.optimizer = optimizer
trainer.criterion = criterion

What do you think ?

HTH

I'm so grateful for your solution and it solved my problem completely. :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

samarth-robo picture samarth-robo  ·  3Comments

vfdev-5 picture vfdev-5  ·  3Comments

karfly picture karfly  ·  4Comments

alykhantejani picture alykhantejani  ·  3Comments

sisp picture sisp  ·  3Comments