    def apply(self, num_updates: Optional[int] = None) -> None:
        """
        Apply exponential moving average to `named_parameters` if specified,
        or we will apply this to all the trainable parameters of the model.

        The optional `num_updates` parameter allows one to tweak the decay rate
        dynamically. If passed, the actual decay rate used is:

            `min(decay, (numerator + num_updates) / (denominator + num_updates))`

        (This logic is based on the Tensorflow exponential moving average
         <https://www.tensorflow.org/api_docs/python/tf/train/ExponentialMovingAverage>)
        """
        if num_updates is not None:
            decay = min(
                self._decay, (self._numerator + num_updates) / (self._denominator + num_updates)
            )
        else:
            decay = self._decay

        for name, parameter in self._parameters:
            self._shadows[name].mul_(decay).add_((1 - decay) * parameter.data)
Apply exponential moving average to `named_parameters` if specified,
or we will apply this to all the trainable parameters of the model.

The optional `num_updates` parameter allows one to tweak the decay rate
dynamically. If passed, the actual decay rate used is:

`min(decay, (numerator + num_updates) / (denominator + num_updates))`

(This logic is based on the Tensorflow exponential moving average
<https://www.tensorflow.org/api_docs/python/tf/train/ExponentialMovingAverage>)
allennlp/training/moving_average.py