(N=15)
| 1065 | |
| 1066 | |
| 1067 | def test_RNNCell(N=15): |
| 1068 | from numpy_ml.neural_nets.layers import RNNCell |
| 1069 | |
| 1070 | N = np.inf if N is None else N |
| 1071 | |
| 1072 | np.random.seed(12345) |
| 1073 | |
| 1074 | i = 1 |
| 1075 | while i < N + 1: |
| 1076 | n_ex = np.random.randint(1, 10) |
| 1077 | n_in = np.random.randint(1, 10) |
| 1078 | n_out = np.random.randint(1, 10) |
| 1079 | n_t = np.random.randint(1, 10) |
| 1080 | X = random_tensor((n_ex, n_in, n_t), standardize=True) |
| 1081 | |
| 1082 | # initialize RNN layer |
| 1083 | L1 = RNNCell(n_out=n_out) |
| 1084 | |
| 1085 | # forward prop |
| 1086 | y_preds = [] |
| 1087 | for t in range(n_t): |
| 1088 | y_pred = L1.forward(X[:, :, t]) |
| 1089 | y_preds += [y_pred] |
| 1090 | |
| 1091 | # backprop |
| 1092 | dLdX = [] |
| 1093 | dLdAt = np.ones_like(y_preds[t]) |
| 1094 | for t in reversed(range(n_t)): |
| 1095 | dLdXt = L1.backward(dLdAt) |
| 1096 | dLdX.insert(0, dLdXt) |
| 1097 | dLdX = np.dstack(dLdX) |
| 1098 | |
| 1099 | # get gold standard gradients |
| 1100 | gold_mod = TorchRNNCell(n_in, n_out, L1.parameters) |
| 1101 | golds = gold_mod.extract_grads(X) |
| 1102 | |
| 1103 | params = [ |
| 1104 | (X, "X"), |
| 1105 | (np.array(y_preds), "y"), |
| 1106 | (L1.parameters["ba"].T, "ba"), |
| 1107 | (L1.parameters["bx"].T, "bx"), |
| 1108 | (L1.parameters["Wax"].T, "Wax"), |
| 1109 | (L1.parameters["Waa"].T, "Waa"), |
| 1110 | (L1.gradients["ba"].T, "dLdBa"), |
| 1111 | (L1.gradients["bx"].T, "dLdBx"), |
| 1112 | (L1.gradients["Wax"].T, "dLdWax"), |
| 1113 | (L1.gradients["Waa"].T, "dLdWaa"), |
| 1114 | (dLdX, "dLdX"), |
| 1115 | ] |
| 1116 | |
| 1117 | print("Trial {}".format(i)) |
| 1118 | for ix, (mine, label) in enumerate(params): |
| 1119 | np.testing.assert_allclose( |
| 1120 | mine, |
| 1121 | golds[label], |
| 1122 | err_msg=err_fmt(params, golds, ix), |
| 1123 | atol=1e-3, |
| 1124 | rtol=1e-3, |
nothing calls this directly
no test coverage detected