def train(self, X_train, y_train, X_val=None, y_val=None, epochs=10, batch_size=1, clip_value=1.0): for epoch in range(epochs): epoch_losses = [] for i in range(0, len(X_train), batch_size): batch_X = X_train[i:i + batch_size] batch_y = y_train[i:i + batch_size] losses = [] for x, y_true in zip(batch_X, batch_y): y_pred, caches = self.model.forward(x) loss = self.compute_loss(y_pred, y_true.reshape(-1, 1)) losses.append(loss) dy = y_pred - y_true.reshape(-1, 1) grads = self.model.backward(dy, caches, clip_value=clip_value) self.model.update_params(grads, self.learning_rate) batch_loss = np.mean(losses) epoch_losses.append(batch_loss) avg_epoch_loss = np.mean(epoch_losses) self.train_losses.append(avg_epoch_loss) if X_val is not None and y_val is not None: val_loss = self.validate(X_val, y_val) self.val_losses.append(val_loss) if epoch % 10 == 0: print(f'Epoch {epoch + 1}/{epochs} - Loss: {avg_epoch_loss:.5f}, Val Loss: {val_loss:.5f}') self.early_stopping(val_loss) if self.early_stopping.early_stop: print("Early stopping") break else: print(f'Epoch {epoch + 1}/{epochs} - Loss: {avg_epoch_loss:.5f}')