
# class Trainer:


#     def __init__(self, model, optimizer, loss_fn):
#         self.model = model
#         self.optimizer = optimizer
#         self.loss_fn = loss_fn

#     def train_step(self, x_batch, y_batch):
#         y_pred = self.model.predict(x_batch)
#         loss = self.loss_fn.forward(y_pred, y_batch)
#         grad = self.loss_fn.backward(y_pred, y_batch)
#         for layer in reversed(self.model.layers):
#             if hasattr(layer, 'backward'):
#                 grad = layer.backward(grad)
#         self.optimizer.update_parameters(self.model.parameters)
#         return loss

#     def fit(self, X_train, y_train, epochs=10, batch_size=32):
#         n = len(X_train)
#         for epoch in range(epochs):
#             total_loss = 0
#             for i in range(0, n, batch_size):
#                 x_batch = X_train[i:i+batch_size]
#                 y_batch = y_train[i:i+batch_size]
#                 loss = self.train_step(x_batch, y_batch)
#                 total_loss += loss
#             avg_loss = total_loss / n
#             print(f"Epoch {epoch+1}/{epochs}, Loss: {avg_loss:.4f}")


# trainer.py

class Trainer:
    """
    كلاس التدريب — يدير عملية التدريب.
    """

    def __init__(self, model, optimizer, loss_fn, batch_size=32, epochs=10):
        self.model = model
        self.optimizer = optimizer
        self.loss_fn = loss_fn
        self.batch_size = batch_size
        self.epochs = epochs

    def train_step(self, x_batch, y_batch):
        """خطوة تدريب واحدة"""
        y_pred = self.model.predict(x_batch)
        loss = self.loss_fn.forward(y_pred, y_batch)
        # حساب التدرجات
        grad = self.loss_fn.backward(y_pred, y_batch)
        for layer in reversed(self.model.layers):
            if hasattr(layer, 'backward'):
                grad = layer.backward(grad)
        # تحديث الأوزان
        self.model.update_parameters(self.optimizer.lr)
        return loss

    def fit(self, X_train, y_train, epochs=10, batch_size=32):
        """تدريب الشبكة"""
        n = len(X_train)
        for epoch in range(epochs):
            total_loss = 0
            for i in range(0, n, batch_size):
                x_batch = X_train[i:i+batch_size]
                y_batch = y_train[i:i+batch_size]
                loss = self.train_step(x_batch, y_batch)
                total_loss += loss
            avg_loss = total_loss / n
            print(f"Epoch {epoch+1}/{epochs}, Loss: {avg_loss:.4f}")