def _train_autoencoder(self, train_loader):
        """Train the autoencoder.

        Parameters
        ----------
        train_loader : torch.utils.data.DataLoader
            DataLoader for the training data.
        """
        optimizer = torch.optim.Adam(self.model.parameters(),
                                     lr=self.learning_rate,
                                     weight_decay=self.weight_decay)
        self.best_loss = float('inf')
        self.best_model_dict = None

        for epoch in range(self.epochs):
            overall_loss = []
            for data, data_idx in train_loader:
                data = data.to(self.device).float()
                reconstructions, rff_features = self.model(data)
                recon_loss = self.loss_fn(data, reconstructions)
                svm_scores = self.model.svm_decision_function(rff_features)
                svm_loss = torch.mean(torch.clamp(1 - svm_scores, min=0))

                loss = self.alpha * recon_loss + svm_loss
                self.model.zero_grad()
                loss.backward()
                optimizer.step()
                overall_loss.append(loss.item())
            if (epoch + 1) % 10 == 0:
                print(
                    f'Epoch {epoch + 1}/{self.epochs}, Loss: {np.mean(overall_loss)}')

            if np.mean(overall_loss) < self.best_loss:
                self.best_loss = np.mean(overall_loss)
                self.best_model_dict = self.model.state_dict()
Train the autoencoder.

        Parameters
        ----------
        train_loader : torch.utils.data.DataLoader
            DataLoader for the training data.
        
pyod/models/ae1svm.py