Backprop from layer outputs to inputs. Parameters ---------- dLdY : :py:class:`ndarray ` of shape `(n_ex, n_in)` The gradient of the loss wrt. the layer output `Y`. retain_grads : bool Whether to include the intermediat
(self, dLdy, retain_grads=True)
| 1388 | return y |
| 1389 | |
| 1390 | def backward(self, dLdy, retain_grads=True): |
| 1391 | """ |
| 1392 | Backprop from layer outputs to inputs. |
| 1393 | |
| 1394 | Parameters |
| 1395 | ---------- |
| 1396 | dLdY : :py:class:`ndarray <numpy.ndarray>` of shape `(n_ex, n_in)` |
| 1397 | The gradient of the loss wrt. the layer output `Y`. |
| 1398 | retain_grads : bool |
| 1399 | Whether to include the intermediate parameter gradients computed |
| 1400 | during the backward pass in the final parameter update. Default is |
| 1401 | True. |
| 1402 | |
| 1403 | Returns |
| 1404 | ------- |
| 1405 | dX : :py:class:`ndarray <numpy.ndarray>` of shape `(n_ex, n_in)` |
| 1406 | The gradient of the loss wrt. the layer input `X`. |
| 1407 | """ |
| 1408 | assert self.trainable, "Layer is frozen" |
| 1409 | if not isinstance(dLdy, list): |
| 1410 | dLdy = [dLdy] |
| 1411 | |
| 1412 | dX = [] |
| 1413 | X = self.X |
| 1414 | for dy, x in zip(dLdy, X): |
| 1415 | dx, dScaler, dIntercept = self._bwd(dy, x) |
| 1416 | dX.append(dx) |
| 1417 | |
| 1418 | if retain_grads: |
| 1419 | self.gradients["scaler"] += dScaler |
| 1420 | self.gradients["intercept"] += dIntercept |
| 1421 | |
| 1422 | return dX[0] if len(X) == 1 else dX |
| 1423 | |
| 1424 | def _bwd(self, dLdy, X): |
| 1425 | """Computation of gradient of loss wrt X, scaler, and intercept""" |