Run a forward pass across all timesteps in the input. Parameters ---------- X : :py:class:`ndarray ` of shape `(n_ex, n_in, n_t)` Input consisting of `n_ex` examples each of dimensionality `n_in` and extending for `n_t` timeste
(self, X)
| 1047 | ) |
| 1048 | |
| 1049 | def forward(self, X): |
| 1050 | """ |
| 1051 | Run a forward pass across all timesteps in the input. |
| 1052 | |
| 1053 | Parameters |
| 1054 | ---------- |
| 1055 | X : :py:class:`ndarray <numpy.ndarray>` of shape `(n_ex, n_in, n_t)` |
| 1056 | Input consisting of `n_ex` examples each of dimensionality `n_in` |
| 1057 | and extending for `n_t` timesteps. |
| 1058 | |
| 1059 | Returns |
| 1060 | ------- |
| 1061 | Y : :py:class:`ndarray <numpy.ndarray>` of shape `(n_ex, n_out, n_t)` |
| 1062 | The value of the hidden state for each of the `n_ex` examples |
| 1063 | across each of the `n_t` timesteps. |
| 1064 | """ |
| 1065 | Y_fwd, Y_bwd, Y = [], [], [] |
| 1066 | n_ex, self.n_in, n_t = X.shape |
| 1067 | |
| 1068 | # forward LSTM |
| 1069 | for t in range(n_t): |
| 1070 | yt, ct = self.cell_fwd.forward(X[:, :, t]) |
| 1071 | Y_fwd.append(yt) |
| 1072 | |
| 1073 | # backward LSTM |
| 1074 | for t in reversed(range(n_t)): |
| 1075 | yt, ct = self.cell_bwd.forward(X[:, :, t]) |
| 1076 | Y_bwd.insert(0, yt) |
| 1077 | |
| 1078 | # merge forward and backward states |
| 1079 | for t in range(n_t): |
| 1080 | if self.merge_mode == "concat": |
| 1081 | Y.append(np.concatenate([Y_fwd[t], Y_bwd[t]], axis=1)) |
| 1082 | elif self.merge_mode == "sum": |
| 1083 | Y.append(Y_fwd[t] + Y_bwd[t]) |
| 1084 | elif self.merge_mode == "average": |
| 1085 | Y.append((Y_fwd[t] + Y_bwd[t]) / 2) |
| 1086 | elif self.merge_mode == "multiply": |
| 1087 | Y.append(Y_fwd[t] * Y_bwd[t]) |
| 1088 | |
| 1089 | self.Y_fwd, self.Y_bwd = Y_fwd, Y_bwd |
| 1090 | return np.dstack(Y) |
| 1091 | |
| 1092 | def backward(self, dLdA): |
| 1093 | """ |