Repository: catalyst-team/catalyst

Issue:
SupervisedWandbRunner logs wrong number of epochs to WandB
**Describe the bug**
Catalyst 20.02.4
`WandbRunner` is logging wrong number of epochs to WandB

**To Reproduce**
Steps to reproduce the behavior:
```
from catalyst import dl
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset

class Projector(nn.Module):
    def __init__(self, input_size):
        super().__init__()
        self.linear = nn.Linear(input_size, 1)
        
    def forward(self, X):
        return self.linear(X).squeeze(-1)

X = torch.rand(16, 10)
y = torch.rand(X.shape[0])
model = Projector(X.shape[1])
dataset = TensorDataset(X, y)
loader = DataLoader(dataset, batch_size=8)
runner = dl.SupervisedWandbRunner()

runner.train(
    model=model,
    loaders={
        "train": loader,
        "valid": loader
    },
    criterion=nn.MSELoss(),
    optimizer=optim.Adam(model.parameters()),
    logdir="log_xxx_000",
    monitoring_params={
        "project": "wandb_wrong_epochs"
    },
    num_epochs=10
)
```

**Expected behavior**
In WandB I see two plots with `MSELoss` with exactly 10 epochs

**Actual behaviour**
In WandB I see two plots with `MSELoss` with 20 epochs (but each has exactly 10 dots)

**Screenshots**
Look on number of steps. It has 20 steps. But should have 10.
![image](https://user-images.githubusercontent.com/9883873/75762200-564c6900-5d4b-11ea-87e3-20ef0e840725.png)



Discussion:

Resolving patch:
diff --git a/catalyst/contrib/dl/runner/wandb.py b/catalyst/contrib/dl/runner/wandb.py
--- a/catalyst/contrib/dl/runner/wandb.py
+++ b/catalyst/contrib/dl/runner/wandb.py
@@ -15,7 +15,9 @@ class WandbRunner(Runner):
     Runner wrapper with wandb integration hooks.
     """
     @staticmethod
-    def _log_metrics(metrics: Dict, mode: str, suffix: str = ""):
+    def _log_metrics(
+        metrics: Dict, mode: str, suffix: str = "", commit: bool = True
+    ):
         def key_locate(key: str):
             """
             Wandb uses first symbol _ for it service purposes
@@ -34,7 +36,7 @@ def key_locate(key: str):
             f"{key_locate(key)}/{mode}{suffix}": value
             for key, value in metrics.items()
         }
-        wandb.log(metrics)
+        wandb.log(metrics, commit=commit)
 
     def _init(
         self,
@@ -123,7 +125,10 @@ def _run_batch(self, batch):
             mode = self.state.loader_name
             metrics = self.state.batch_metrics
             self._log_metrics(
-                metrics=metrics, mode=mode, suffix=self.batch_log_suffix
+                metrics=metrics,
+                mode=mode,
+                suffix=self.batch_log_suffix,
+                commit=True
             )
 
     def _run_epoch(self, stage: str, epoch: int):
@@ -136,17 +141,26 @@ def _run_epoch(self, stage: str, epoch: int):
             )
             for mode, metrics in mode_metrics.items():
                 self._log_metrics(
-                    metrics=metrics, mode=mode, suffix=self.epoch_log_suffix
+                    metrics=metrics,
+                    mode=mode,
+                    suffix=self.epoch_log_suffix,
+                    commit=False
                 )
+            wandb.log(commit=True)
 
     def run_experiment(self, experiment: Experiment):
+        """Starts experiment
+
+        Args:
+            experiment (Experiment): experiment class
+        """
         self._pre_experiment_hook(experiment=experiment)
         super().run_experiment(experiment=experiment)
         self._post_experiment_hook(experiment=experiment)
 
 
 class SupervisedWandbRunner(WandbRunner, SupervisedRunner):
-    pass
+    """SupervisedRunner with WandB"""
 
 
 __all__ = ["WandbRunner", "SupervisedWandbRunner"]


Test patch: