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:\Users\Ryzen\PycharmProjects\pyt-1\main.py", line 109, in acc = compute_acc(logits, y, compute_device=device).detach() File "C:\Users\Ryzen\PycharmProjects\pyt-1\main.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 = data_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)