(self, X: np.ndarray, y: np.ndarray, epochs: int = 60, batch_size: int = 64)
| 91 | return h, h_relu, logits, probs |
| 92 | |
| 93 | def train(self, X: np.ndarray, y: np.ndarray, epochs: int = 60, batch_size: int = 64): |
| 94 | rng = np.random.RandomState(42) |
| 95 | n = len(X) |
| 96 | Y_onehot = np.zeros((n, 4), dtype=np.float64) |
| 97 | Y_onehot[np.arange(n), y] = 1.0 |
| 98 | |
| 99 | for epoch in range(epochs): |
| 100 | idx = rng.permutation(n) |
| 101 | for start in range(0, n, batch_size): |
| 102 | batch_idx = idx[start:start + batch_size] |
| 103 | Xb, Yb = X[batch_idx], Y_onehot[batch_idx] |
| 104 | bs = len(Xb) |
| 105 | |
| 106 | h, h_relu, logits, probs = self._forward(Xb) |
| 107 | dlogits = (probs - Yb) / bs |
| 108 | |
| 109 | dW2 = h_relu.T @ dlogits |
| 110 | db2 = dlogits.sum(axis=0) |
| 111 | dh_relu = dlogits @ self.W2.T |
| 112 | dh = dh_relu * (h > 0) |
| 113 | dW1 = Xb.T @ dh |
| 114 | db1 = dh.sum(axis=0) |
| 115 | |
| 116 | self.W2 -= self.lr * dW2 |
| 117 | self.b2 -= self.lr * db2 |
| 118 | self.W1 -= self.lr * dW1 |
| 119 | self.b1 -= self.lr * db1 |
| 120 | |
| 121 | def predict(self, X: np.ndarray) -> np.ndarray: |
| 122 | _, _, _, probs = self._forward(X) |
no test coverage detected