Implementation of early stopping in PyTorch, eval() considered as not propper Attribute of Tensor / model

Issue

This Content is from Stack Overflow. Question asked by PrertoQuebas

I have encountered some problems adding ‘early stopping’ functionality to CNN / MNIST project. I have used the whole function compute_acc() from Sebastian Raschka DL book, but project unfortunatelly raise Attribute Error:

Error I got:

Traceback (most recent call last): File
“C:UsersRyzenPycharmProjectspyt-1main.py”, line 109, in
acc = compute_acc(logits, y, compute_device=device).detach() File “C:UsersRyzenPycharmProjectspyt-1main.py”, line 52, in
compute_acc
data_model.eval() AttributeError: ‘Tensor’ object has no attribute ‘eval’. Did you mean: ‘equal’?

Here is my full code:

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils import data
from torchvision import datasets
from torchvision import transforms


class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()

        self.conv1 = nn.Conv2d(in_channels=1, out_channels=6,
                               kernel_size=5, stride=1, padding=0)
        self.conv2 = nn.Conv2d(in_channels=6, out_channels=16,
                               kernel_size=5, stride=1, padding=0)
        self.conv3 = nn.Conv2d(in_channels=16, out_channels=120,
                               kernel_size=5, stride=1, padding=0)
        self.linear1 = nn.Linear(120, 84)
        self.linear2 = nn.Linear(84, 10)
        self.tanh = nn.Tanh()
        self.avgpool = nn.AvgPool2d(kernel_size=2, stride=2)

    def forward(self, x):
        x = self.conv1(x)
        x = self.tanh(x)
        x = self.avgpool(x)
        x = self.conv2(x)
        x = self.tanh(x)
        x = self.avgpool(x)
        x = self.conv3(x)
        x = self.tanh(x)
        x = x.reshape(x.shape[0], -1)
        x = self.linear1(x)
        x = self.tanh(x)
        x = self.linear2(x)
        return x


def compute_acc(data_model, data_loader, compute_device):
    correct_pred, num_examples = 0, 0
    data_model.eval()
    for i, (features, targets) in enumerate(data_loader):
        features = features.to(compute_device)
        targets = targets.to(compute_device)

        logits, probas = model(features)
        _, predicted_labels = torch.max(probas, 1)
        num_examples += targets.size(0)
        assert predicted_labels.size() == targets.size()
        correct_pred += (predicted_labels == targets).sum()
    return correct_pred.float() / num_examples * 100


if __name__ == '__main__':
    transforms = transforms.Compose([transforms.Resize((32, 32)),
                                     transforms.ToTensor()])

    mnist_train = datasets.MNIST(root='mnist_data',
                                 train=True,
                                 transform=transforms,
                                 download=False)

    mnist_validation = datasets.MNIST(root='mnist_data',
                                      train=False,
                                      transform=transforms)

    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

    model = LeNet()
    cost = torch.nn.CrossEntropyLoss()
    opt = optim.Adam(model.parameters())

    train_loss = []
    validation_acc = []
    best_model = None
    best_acc = None
    best_epoch = None
    max_epoch = 10000
    no_improvement = 5
    batch_size = 512

    for n_epoch in range(max_epoch):
        model.train()
        loader = data.DataLoader(mnist_train, batch_size=batch_size, shuffle=True, num_workers=1)
        epoch_loss = []
        for X_batch, y_batch in loader:
            opt.zero_grad()
            logits = model(X_batch)
            loss = cost(logits, y_batch)
            loss.backward()
            opt.step()
            epoch_loss.append(loss.detach())
        train_loss.append(torch.tensor(epoch_loss).mean())
        model.eval()
        loader = data.DataLoader(mnist_validation, batch_size=len(mnist_validation), shuffle=False)
        X, y = next(iter(loader))
        logits = model(X)
        acc = compute_acc(logits, y, compute_device=device).detach()
        validation_acc.append(acc)
        if best_acc is None or acc > best_acc:
            best_acc = acc
            best_model = model.state_dict()
            best_epoch = n_epoch
        if best_epoch + no_improvement <= n_epoch:
            break

    model.load_state_dict(best_model)



Solution

This question is not yet answered, be the first one who answer using the comment. Later the confirmed answer will be published as the solution.

This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?