mirror of
https://github.com/wassname/pytorch-lightning.git
synced 2026-09-09 11:32:07 +08:00
Adds the option of saving the last model on checkpoint (#1908)
* saves model every epoch * implement test for save_last * Update CHANGELOG.md * Update CHANGELOG.md * changes test description Co-authored-by: Jeremy Jordan <13970565+jeremyjordan@users.noreply.github.com> Co-authored-by: Jeremy Jordan <13970565+jeremyjordan@users.noreply.github.com>
This commit is contained in:
co-authored by
Jeremy Jordan
parent
a34eb9e169
commit
112dd5c4f6
@@ -14,6 +14,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
- Allow dataloaders without sampler field present ([#1907](https://github.com/PyTorchLightning/pytorch-lightning/pull/1907))
|
||||
|
||||
- Added option `save_last` to save the model at the end of every epoch in `ModelCheckpoint` [(#1908)](https://github.com/PyTorchLightning/pytorch-lightning/pull/1908)
|
||||
|
||||
### Changed
|
||||
|
||||
- Allow user to select individual TPU core to train on ([#1729](https://github.com/PyTorchLightning/pytorch-lightning/pull/1729))
|
||||
|
||||
@@ -43,6 +43,7 @@ class ModelCheckpoint(Callback):
|
||||
|
||||
monitor: quantity to monitor.
|
||||
verbose: verbosity mode. Default: ``False``.
|
||||
save_last: always saves the model at the end of the epoch. Default: ``False``.
|
||||
save_top_k: if `save_top_k == k`,
|
||||
the best k models according to
|
||||
the quantity monitored will be saved.
|
||||
@@ -83,7 +84,7 @@ class ModelCheckpoint(Callback):
|
||||
"""
|
||||
|
||||
def __init__(self, filepath: Optional[str] = None, monitor: str = 'val_loss', verbose: bool = False,
|
||||
save_top_k: int = 1, save_weights_only: bool = False,
|
||||
save_last: bool = False, save_top_k: int = 1, save_weights_only: bool = False,
|
||||
mode: str = 'auto', period: int = 1, prefix: str = ''):
|
||||
super().__init__()
|
||||
if save_top_k > 0 and filepath is not None and os.path.isdir(filepath) and len(os.listdir(filepath)) > 0:
|
||||
@@ -103,6 +104,7 @@ class ModelCheckpoint(Callback):
|
||||
else:
|
||||
self.dirpath, self.filename = os.path.split(filepath)
|
||||
os.makedirs(self.dirpath, exist_ok=True)
|
||||
self.save_last = save_last
|
||||
self.save_top_k = save_top_k
|
||||
self.save_weights_only = save_weights_only
|
||||
self.period = period
|
||||
@@ -217,6 +219,10 @@ class ModelCheckpoint(Callback):
|
||||
|
||||
self.epoch_last_check = epoch
|
||||
|
||||
if self.save_last:
|
||||
filepath = os.path.join(self.dirpath, self.prefix + 'last.ckpt')
|
||||
self._save_model(filepath)
|
||||
|
||||
filepath = self.format_checkpoint_name(epoch, metrics)
|
||||
version_cnt = 0
|
||||
while os.path.isfile(filepath):
|
||||
|
||||
@@ -229,19 +229,21 @@ def test_dp_output_reduce():
|
||||
assert reduced['b']['c'] == out['b']['c']
|
||||
|
||||
|
||||
@pytest.mark.parametrize(["save_top_k", "file_prefix", "expected_files"], [
|
||||
pytest.param(-1, '', {'epoch=4.ckpt', 'epoch=3.ckpt', 'epoch=2.ckpt', 'epoch=1.ckpt', 'epoch=0.ckpt'},
|
||||
@pytest.mark.parametrize(["save_top_k", "save_last", "file_prefix", "expected_files"], [
|
||||
pytest.param(-1, False, '', {'epoch=4.ckpt', 'epoch=3.ckpt', 'epoch=2.ckpt', 'epoch=1.ckpt', 'epoch=0.ckpt'},
|
||||
id="CASE K=-1 (all)"),
|
||||
pytest.param(1, 'test_prefix_', {'test_prefix_epoch=4.ckpt'},
|
||||
pytest.param(1, False, 'test_prefix_', {'test_prefix_epoch=4.ckpt'},
|
||||
id="CASE K=1 (2.5, epoch 4)"),
|
||||
pytest.param(2, '', {'epoch=4.ckpt', 'epoch=2.ckpt'},
|
||||
pytest.param(2, False, '', {'epoch=4.ckpt', 'epoch=2.ckpt'},
|
||||
id="CASE K=2 (2.5 epoch 4, 2.8 epoch 2)"),
|
||||
pytest.param(4, '', {'epoch=1.ckpt', 'epoch=4.ckpt', 'epoch=3.ckpt', 'epoch=2.ckpt'},
|
||||
pytest.param(4, False, '', {'epoch=1.ckpt', 'epoch=4.ckpt', 'epoch=3.ckpt', 'epoch=2.ckpt'},
|
||||
id="CASE K=4 (save all 4 base)"),
|
||||
pytest.param(3, '', {'epoch=2.ckpt', 'epoch=3.ckpt', 'epoch=4.ckpt'},
|
||||
pytest.param(3, False, '', {'epoch=2.ckpt', 'epoch=3.ckpt', 'epoch=4.ckpt'},
|
||||
id="CASE K=3 (save the 2nd, 3rd, 4th model)"),
|
||||
pytest.param(1, True, '', {'epoch=4.ckpt', 'last.ckpt'},
|
||||
id="CASE K=1 (save the 4th model and the last model)"),
|
||||
])
|
||||
def test_model_checkpoint_options(tmpdir, save_top_k, file_prefix, expected_files):
|
||||
def test_model_checkpoint_options(tmpdir, save_top_k, save_last, file_prefix, expected_files):
|
||||
"""Test ModelCheckpoint options."""
|
||||
|
||||
def mock_save_function(filepath, *args):
|
||||
@@ -250,7 +252,8 @@ def test_model_checkpoint_options(tmpdir, save_top_k, file_prefix, expected_file
|
||||
# simulated losses
|
||||
losses = [10, 9, 2.8, 5, 2.5]
|
||||
|
||||
checkpoint_callback = ModelCheckpoint(tmpdir, save_top_k=save_top_k, prefix=file_prefix, verbose=1)
|
||||
checkpoint_callback = ModelCheckpoint(tmpdir, save_top_k=save_top_k, save_last=save_last,
|
||||
prefix=file_prefix, verbose=1)
|
||||
checkpoint_callback.save_function = mock_save_function
|
||||
trainer = Trainer()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user