Repository: pytorch/ignite

Issue:
ModelCheckpoint parameter `save_as_state_dict` should default to True
Given that the recommended way to save model checkpoints is to only serialize the `state_dict` rather than the whole object (see https://pytorch.org/docs/stable/notes/serialization.html), shouldn't `save_as_state_dict` in `ModelCheckpoint` default to `True`?

Maybe I'm nitpicking but I think this would be a better default.

Here's the line: https://github.com/pytorch/ignite/blob/862ab0073e461a32bf5b53fa015f88c143ae9079/ignite/handlers/checkpoint.py#L84


Discussion:
@fabianschilling I agree, thanks for the feedback. We kept it equal False because of backward compatibility to the previous versions. I think since 0.2.0 we can set it to be True by default.
If you would like send a PR with a change, please do no hesitate.


Resolving patch:
diff --git a/ignite/handlers/checkpoint.py b/ignite/handlers/checkpoint.py
--- a/ignite/handlers/checkpoint.py
+++ b/ignite/handlers/checkpoint.py
@@ -81,7 +81,7 @@ def __init__(self, dirname, filename_prefix,
                  n_saved=1,
                  atomic=True, require_empty=True,
                  create_dir=True,
-                 save_as_state_dict=False):
+                 save_as_state_dict=True):
 
         self._dirname = os.path.expanduser(dirname)
         self._fname_prefix = filename_prefix


Test patch:
diff --git a/tests/ignite/handlers/test_checkpoint.py b/tests/ignite/handlers/test_checkpoint.py
--- a/tests/ignite/handlers/test_checkpoint.py
+++ b/tests/ignite/handlers/test_checkpoint.py
@@ -58,7 +58,8 @@ def test_args_validation(dirname):
 
 
 def test_simple_recovery(dirname):
-    h = ModelCheckpoint(dirname, _PREFIX, create_dir=False, save_interval=1)
+    h = ModelCheckpoint(dirname, _PREFIX, create_dir=False, save_interval=1,
+                        save_as_state_dict=False)
     h(None, {'obj': 42})
 
     fname = os.path.join(dirname, '{}_{}_{}.pth'.format(_PREFIX, 'obj', 1))
@@ -70,7 +71,8 @@ def test_simple_recovery_from_existing_non_empty(dirname):
     with open(previous_fname, 'w') as f:
         f.write("test")
 
-    h = ModelCheckpoint(dirname, _PREFIX, create_dir=True, require_empty=False, save_interval=1)
+    h = ModelCheckpoint(dirname, _PREFIX, create_dir=True, require_empty=False,
+                        save_interval=1, save_as_state_dict=False)
     h(None, {'obj': 42})
 
     fname = os.path.join(dirname, '{}_{}_{}.pth'.format(_PREFIX, 'obj', 1))
@@ -87,11 +89,12 @@ def _test_existance(atomic, name, obj, expected):
                             atomic=atomic,
                             create_dir=False,
                             require_empty=False,
-                            save_interval=1)
+                            save_interval=1,
+                            save_as_state_dict=False)
 
         try:
             h(None, {name: obj})
-        except:
+        except Exception:
             pass
 
         fname = os.path.join(dirname, '{}_{}_{}.pth'.format(_PREFIX, name, 1))
@@ -105,7 +108,8 @@ def _test_existance(atomic, name, obj, expected):
 
 
 def test_last_k(dirname):
-    h = ModelCheckpoint(dirname, _PREFIX, create_dir=False, n_saved=2, save_interval=2)
+    h = ModelCheckpoint(dirname, _PREFIX, create_dir=False, n_saved=2,
+                        save_interval=2, save_as_state_dict=False)
     to_save = {'name': 42}
 
     for _ in range(8):
@@ -124,7 +128,8 @@ def score_function(engine):
         return next(scores)
 
     h = ModelCheckpoint(dirname, _PREFIX, create_dir=False,
-                        n_saved=2, score_function=score_function)
+                        n_saved=2, score_function=score_function,
+                        save_as_state_dict=False)
 
     to_save = {'name': 42}
     for _ in range(4):
@@ -144,7 +149,8 @@ def score_function(engine):
         return next(scores_iter)
 
     h = ModelCheckpoint(dirname, _PREFIX, create_dir=False, n_saved=2,
-                        score_function=score_function, score_name="val_loss")
+                        score_function=score_function, score_name="val_loss",
+                        save_as_state_dict=False)
 
     to_save = {'name': 42}
     for _ in range(4):
@@ -164,7 +170,8 @@ def update_fn(engine, batch):
     name = 'model'
     engine = Engine(update_fn)
     handler = ModelCheckpoint(dirname, _PREFIX, create_dir=False,
-                              n_saved=2, save_interval=1)
+                              n_saved=2, save_interval=1,
+                              save_as_state_dict=False)
 
     engine.add_event_handler(Events.EPOCH_COMPLETED, handler, {name: 42})
     engine.run([0], max_epochs=4)