Пример #1
0
    def eval_(self, test_loader, device):
        """Evaluate the model
        
        Parameters
        ----------
        test_loader: generator
            Test data generator
        device: str
            cuda or cpu

        Returns
        -------
        test_loss: Mean
            Class object that collects the test loss
        test_accuracy: Mean
            Class object that collects the test accuracy
        """
        # Test loss for this epoch
        test_loss = Mean()
        # Test accuracy for this epoch
        test_accuracy = Mean()

        for batch_x, batch_y, batch_classes in test_loader:
            batch_x, batch_y = batch_x.to(device), batch_y.to(device)
            
            prediction = self(batch_x)
            loss = F.cross_entropy(prediction, batch_y)
            acc = self.accuracy_(prediction, batch_y)

            test_loss.update(loss.item(), n=len(batch_x))
            test_accuracy.update(acc.item(), n=len(batch_x))

        return test_loss, test_accuracy
    def train_(self, training_loader, device, optimizer):
        """Train the model
        
        Parameters
        ----------
        training_loader: generator
            Training data generator
        device: str
            cuda or cpu
        optimizer: callable
            One of the PyTorch optimizers

        Returns
        -------
        train_loss: Mean
            Class object that collects the train loss
        train_accuracy: Mean
            Class object that collects the train accuracy
        """

        # Train loss for this epoch
        train_loss = Mean()
        # Train accuracy for this epoch
        train_accuracy = Mean()

        for batch_x, batch_y, batch_classes in training_loader:
            batch_x, batch_y = batch_x.to(device), batch_y.to(device)
            batch_classes1 = batch_classes[:, 0].to(device)
            batch_classes2 = batch_classes[:, 1].to(device)

            # Set gradients to zero and Compute gradients for the batch
            optimizer.zero_grad()

            # Calculate loss and accuracy
            predict_digit1, predict_digit2, predict_y = self(batch_x)
            # prediction size: 1000, 10;
            # batch_y size:    1000
            loss = F.cross_entropy(predict_y, batch_y) + \
                   F.cross_entropy(predict_digit1, batch_classes1) + \
                   F.cross_entropy(predict_digit2, batch_classes2)
            acc = self.accuracy_(predict_y, batch_y)

            # Backward propagation of gradients
            loss.backward()

            # Do an optimizer step (updating parameters)
            optimizer.step()

            # Store the statistics
            train_loss.update(loss.item(), n=len(batch_x))
            train_accuracy.update(acc.item(), n=len(batch_x))

        return train_loss, train_accuracy
    def eval_(self, test_loader, device):
        """Evaluate the model
        
        Parameters
        ----------
        test_loader: generator
            Test data generator
        device: str
            cuda or cpu

        Returns
        -------
        test_loss: Mean
            Class object that collects the test loss
        test_accuracy: Mean
            Class object that collects the test accuracy
        """
        # Test loss for this epoch
        test_loss = Mean()
        # Test accuracy for this epoch
        test_accuracy = Mean()

        for batch_x, batch_y, batch_classes in test_loader:
            batch_x, batch_y = batch_x.to(device), batch_y.to(device)
            batch_classes1 = batch_classes[:, 0].to(device)
            batch_classes2 = batch_classes[:, 1].to(device)
            
            # Calculate loss and accuracy
            predict_digit1, predict_digit2, predict_y = self(batch_x)
            loss = F.cross_entropy(predict_y, batch_y) + \
                   F.cross_entropy(predict_digit1, batch_classes1) + \
                   F.cross_entropy(predict_digit2, batch_classes2)
            acc = self.accuracy_(predict_y, batch_y)

            # Store the statistics
            test_loss.update(loss.item(), n=len(batch_x))
            test_accuracy.update(acc.item(), n=len(batch_x))

        return test_loss, test_accuracy