| 11 | |
| 12 | |
| 13 | class BatchNormalization(Layer, ParamMixin, PhaseMixin): |
| 14 | def __init__(self, momentum=0.9, eps=1e-5, parameters=None): |
| 15 | super().__init__() |
| 16 | self._params = parameters |
| 17 | if self._params is None: |
| 18 | self._params = Parameters() |
| 19 | self.momentum = momentum |
| 20 | self.eps = eps |
| 21 | self.ema_mean = None |
| 22 | self.ema_var = None |
| 23 | |
| 24 | def setup(self, x_shape): |
| 25 | self._params.setup_weights((1, x_shape[1])) |
| 26 | |
| 27 | def _forward_pass(self, X): |
| 28 | gamma = self._params["W"] |
| 29 | beta = self._params["b"] |
| 30 | |
| 31 | if self.is_testing: |
| 32 | mu = self.ema_mean |
| 33 | xmu = X - mu |
| 34 | var = self.ema_var |
| 35 | sqrtvar = np.sqrt(var + self.eps) |
| 36 | ivar = 1.0 / sqrtvar |
| 37 | xhat = xmu * ivar |
| 38 | gammax = gamma * xhat |
| 39 | return gammax + beta |
| 40 | |
| 41 | N, D = X.shape |
| 42 | |
| 43 | # step1: calculate mean |
| 44 | mu = 1.0 / N * np.sum(X, axis=0) |
| 45 | |
| 46 | # step2: subtract mean vector of every trainings example |
| 47 | xmu = X - mu |
| 48 | |
| 49 | # step3: following the lower branch - calculation denominator |
| 50 | sq = xmu**2 |
| 51 | |
| 52 | # step4: calculate variance |
| 53 | var = 1.0 / N * np.sum(sq, axis=0) |
| 54 | |
| 55 | # step5: add eps for numerical stability, then sqrt |
| 56 | sqrtvar = np.sqrt(var + self.eps) |
| 57 | |
| 58 | # step6: invert sqrtwar |
| 59 | ivar = 1.0 / sqrtvar |
| 60 | |
| 61 | # step7: execute normalization |
| 62 | xhat = xmu * ivar |
| 63 | |
| 64 | # step8: Nor the two transformation steps |
| 65 | gammax = gamma * xhat |
| 66 | |
| 67 | # step9 |
| 68 | out = gammax + beta |
| 69 | |
| 70 | # store running averages of mean and variance during training for use during testing |
nothing calls this directly
no outgoing calls
no test coverage detected