Ignite, Correct way of using the library, how to pass model to callable

username: damicoedoardo
cooked: <p>Hi everyone,<br>
I’m new to pytorch and ignite libraries, and I’m trying to figure out which is the best way to use them.<br>
I read almost all the tutorial on the ignite library but still I don’t get which is the correct way of use it.</p>
<p>In every tutorial I see that the function used to define an <code>engine</code> is calling inside <code>model</code> but this last is not passed to it as parameters,<br>
what I would have thought is that the correct way to use ignite is to “hide” everything to the final user, so I would have defined every stuff to do during the training inside a fit function of a certain model class</p>
<p>but since I cannot pass parameters to the functions passed to the engine this result more difficult ("'I’m actually passing the model as optional parameter but kinda feel that it is not the correct way")</p>
<p>can anyone explain me the abstract way to use the ignite library in the correct way ??</p>
<p>Thank you all !</p>

username: vfdev-5
cooked: <p><a class="mention" href="/u/damicoedoardo">@damicoedoardo</a>  basical usage of ignite is the following where we highly use global scope variables in majority of handlers:</p>
<pre><code class="lang-python">
def main():

    train_loader, val_loader = get_dataloader(...)
    optimizer = ...
    model = ... 
    criterion = ...

    def train_step(engine, batch):
        model.train()  # model is defined in the scope of main
        optimizer.zero_grad()   # optimizer is defined in the scope of main
        x, y = prepare_batch(batch)
        y_pred = model(x)
        loss = criterion(y_pred, y)   # criterion is defined in the scope of main
        loss.backward()
        optimizer.step()
        return loss.item()        


     trainer = Engine(train_step)
     evaluator = create_supervised_evaluator(model, metrics={'acc': Accuracy()})

    @trainer.on(Events.EPOCH_COMPLETED)
    def run_validation(engine):
        evaluator.run(val_loader)

    trainer.run(train_loader, max_epochs=10)
</code></pre>
<p>If you wish not to use global scope like above, it is possible to do this like</p>
<ol>
<li>define a custom structure <code>Trainer</code> and pass necessary things to it</li>
</ol>
<pre><code class="lang-python">
class SpecificModelTrainer:
    
    def __init__(self, model, optimizer, criterion, *args, **kwargs):
         # ... setup all to self.*

    def train_step(self, engine, batch):
        self.model.train()  # model is defined in the scope of main
        self.optimizer.zero_grad()   # optimizer is defined in the scope of main
        x, y = self.prepare_batch(batch)
        y_pred = self.model(x)
        loss = self.criterion(y_pred, y)   # criterion is defined in the scope of main
        loss.backward()
        self.optimizer.step()
        return loss.item()        
         

def main():
    train_loader, val_loader = get_dataloader(...)
    optimizer = ...
    model = ... 
    criterion = ...

    model_trainer = SpecificModelTrainer(...)

    trainer_engine = Engine(model_trainer.train_step)

    ...
</code></pre>
<ol start="2">
<li>use <code>trainer.state</code> for that</li>
</ol>
<pre><code class="lang-auto">def main():

    train_loader, val_loader = get_dataloader(...)
    optimizer = ...
    model = ... 
    criterion = ...

    def train_step(engine, batch):
        state = engine.state
        state.model.train()  # model is defined in the scope of main
        state.optimizer.zero_grad()   # optimizer is defined in the scope of main
        x, y = state.prepare_batch(batch)
        y_pred = state.model(x)
        loss = state.criterion(y_pred, y)   # criterion is defined in the scope of main
        loss.backward()
        state.optimizer.step()
        return loss.item()        


     trainer = Engine(train_step)
     evaluator = create_supervised_evaluator(model, metrics={'acc': Accuracy()})

    @trainer.on(Events.STARTED, model, optimizer, criterion, prepare_batch)
    def setup_state(engine, m, o, c, p):
         engine.state.model = m
         engine.state.optimizer = o
         engine.state.criterion = c
         engine.state.prepare_batch = p

    @trainer.on(Events.EPOCH_COMPLETED)
    def run_validation(engine):
        evaluator.run(val_loader)

    trainer.run(train_loader, max_epochs=10)
</code></pre>
<p>HTH</p>

username: damicoedoardo
cooked: <p>Thank you very much for the explanation and example of usage!<br>
forgot to say, very good work on Ignite guys !</p>
<p>Keep going!</p>

username: braindotai
cooked: <p>Not to mention how good ignite is, I’d suggest you to checkout pytorch lightning as well.</p>

username: vfdev-5
cooked: <p>And, please, don’t forget others: skorch, fastai, catalyst, …</p>
<aside class="onebox whitelistedgeneric">
  <header class="source">
      <img src="https://i2.wp.com/neptune.ai/wp-content/uploads/2019/03/cropped-Artboard-12.png?fit=32%2C32&amp;ssl=1" class="site-icon" width="32" height="32">
      <a href="https://neptune.ai/blog/model-training-libraries-pytorch-ecosystem" target="_blank" title="02:41PM - 26 February 2020" rel="nofollow noopener">neptune.ai – 26 Feb 20</a>
  </header>
  <article class="onebox-body">
    <div class="aspect-image" style="--aspect-ratio:690/383;"><img src="https://i1.wp.com/neptune.ai/wp-content/uploads/PyTorch-blue.png?fit=1171%2C651&amp;ssl=1" class="thumbnail" width="690" height="383"></div>

<h3><a href="https://neptune.ai/blog/model-training-libraries-pytorch-ecosystem" target="_blank" rel="nofollow noopener">8 Creators and Core Contributors Talk About Their Model Training Libraries...</a></h3>

<p>There are 6 high-level training APIs in the PyTorch Ecosystem. Which one should you choose? I asked the authors to explain the differences between those libraries and that is how this post was created!</p>


  </article>
  <div class="onebox-metadata">
    
    
  </div>
  <div style="clear: both"></div>
</aside>