The ``{before,after}_epoch``, ``{before,after}_run``, ``trigger_{epoch,step}`` methods of the given callback will be enabled only when ``global_step % every_k_steps == 0` or ``epoch_num % every_k_epochs == 0``. The other methods are unaffected. Note that this can only makes a callb
| 118 | |
| 119 | |
| 120 | class PeriodicCallback(EnableCallbackIf): |
| 121 | """ |
| 122 | The ``{before,after}_epoch``, ``{before,after}_run``, ``trigger_{epoch,step}`` |
| 123 | methods of the given callback will be enabled only when ``global_step % every_k_steps == 0` |
| 124 | or ``epoch_num % every_k_epochs == 0``. The other methods are unaffected. |
| 125 | |
| 126 | Note that this can only makes a callback **less** frequent than itself. |
| 127 | If you have a callback that by default runs every epoch by its :meth:`trigger()` method, |
| 128 | use :class:`PeriodicTrigger` to schedule it more frequent than itself. |
| 129 | """ |
| 130 | |
| 131 | def __init__(self, callback, every_k_steps=None, every_k_epochs=None): |
| 132 | """ |
| 133 | Args: |
| 134 | callback (Callback): a Callback instance. |
| 135 | every_k_steps (int): enable the callback when ``global_step % k == 0``. Set to |
| 136 | None to ignore. |
| 137 | every_k_epochs (int): enable the callback when ``epoch_num % k == 0``. |
| 138 | Also enable when the last step finishes (``epoch_num == max_epoch`` |
| 139 | and ``local_step == steps_per_epoch - 1``). Set to None to ignore. |
| 140 | |
| 141 | every_k_steps and every_k_epochs can be both set, but cannot be both None. |
| 142 | """ |
| 143 | assert isinstance(callback, Callback), type(callback) |
| 144 | assert (every_k_epochs is not None) or (every_k_steps is not None), \ |
| 145 | "every_k_steps and every_k_epochs cannot be both None!" |
| 146 | self._step_k = every_k_steps |
| 147 | self._epoch_k = every_k_epochs |
| 148 | super(PeriodicCallback, self).__init__(callback, PeriodicCallback.predicate) |
| 149 | |
| 150 | def predicate(self): |
| 151 | if self._step_k is not None and self.global_step % self._step_k == 0: |
| 152 | return True |
| 153 | if self._epoch_k is not None and self.epoch_num % self._epoch_k == 0: |
| 154 | return True |
| 155 | if self._epoch_k is not None: |
| 156 | if self.local_step == self.trainer.steps_per_epoch - 1 and \ |
| 157 | self.epoch_num == self.trainer.max_epoch: |
| 158 | return True |
| 159 | return False |
| 160 | |
| 161 | def __str__(self): |
| 162 | return "PeriodicCallback-" + str(self.cb) |