Why my Train Accuracy and Test Accuracy are not demicals?

Hi, I implemented the code like below:

import torch
from torch.autograd import Variable
import torch.nn as nn
from torchvision import datasets, transforms


transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize([0.5],[0.5])])

data_train = datasets.MNIST(root="./data/", transform=transform, train=True, download=True)
data_test = datasets.MNIST(root="./data/", transform=transform, train=False)

data_loader_train = torch.utils.data.DataLoader(dataset=data_train, batch_size=64, shuffle=True)

data_loader_test = torch.utils.data.DataLoader(dataset=data_test, batch_size=64, shuffle=True)

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

        self.conv = nn.Sequential(
            nn.Conv2d(1, 64, kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(stride=2, kernel_size=2))

        self.dense = nn.Sequential(
            nn.Linear(14*14*128, 1024),
            nn.ReLU(),
            nn.Dropout(p=0.5),
            nn.Linear(1024, 10)
        )

    def forward(self, input):
        output = self.conv(input)
        output = output.view(-1, 14*14*128)
        output = self.dense(output)

        return output


model = Model()
cuda_avail = torch.cuda.is_available()
if cuda_avail:
    model.cuda()
cost = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters())

print(model)

def save_models(epoch):
    torch.save(model.state_dict(), "cifar10model_{}.model".format(epoch))
    print("Chekcpoint saved")

n_epochs = 30

for epoch in range(n_epochs):
    running_loss = 0.0
    running_correct = 0.0
    print("Epoch {}/{}".format(epoch+1, n_epochs))
    for data in data_loader_train:
        x_train, y_train = data
        x_train, y_train = Variable(x_train.cuda()), Variable(y_train.cuda())
        outputs = model(x_train)
        _,pred = torch.max(outputs.data, 1)
        optimizer.zero_grad()
        loss = cost(outputs, y_train)

        loss.backward()
        optimizer.step()
        running_loss += loss.data.item()
        running_correct += torch.sum(pred == y_train.data)
    
    testing_correct = 0.0
    for data in data_loader_test:
        x_test, y_test = data
        x_test, y_test = Variable(x_test.cuda()), Variable(y_test.cuda())
        outputs = model(x_test)
        _,pred = torch.max(outputs.data, 1)
        testing_correct += torch.sum(pred == y_test.data)
    print("Loss is:{:.6f}, Train Accuracy is:{:.6f}%, Test Accuracy is:{:.6f}%".format(running_loss/len(data_train), 100*running_correct/len(data_train), 100*testing_correct/len(data_test)))
    print("-" * 10)

    if epoch == n_epochs-1:
        save_models(epoch)

When run this code above, I got results like below:
Epoch 1/30
Loss is:0.002196, Train Accuracy is:95.000000%, Test Accuracy is:98.000000%

Epoch 2/30
Loss is:0.000748, Train Accuracy is:98.000000%, Test Accuracy is:98.000000%

Epoch 3/30
Loss is:0.000511, Train Accuracy is:98.000000%, Test Accuracy is:98.000000%

My loss is a demical, but why my train accuracy and test accuracy don’t have fractional part like 98.123456%?

Please help me, thank you!

How did you normalize running_correct and testing_correct? In the code you’ve posted you are just summing the number or correct predictions to these values.

Thanks for your reply!
I’m sorry that this is my complete code above.
I only define running_correct =0.0 and testing_correct = 0.0, how can I normalize running_correct and testing_correct, and what role can normalization play?

You are now calculating the number of correctly classified images, not the percentage. To get the relative accuracy you would need to divide by the number of all images in your datasets.

print("Loss is:{:.6f}, Train Accuracy is:{:.6f}%, Test Accuracy is:{:.6f}%".format(running_loss/len(data_train), 100*running_correct/len(data_train), 100*testing_correct/len(data_test)))

I’m sorry that I have divided the number of data, but the accuracy is still integer and doesn’t have fractional part.

What are the lengths of the datasets?
The accuracy could still result in an integer, if your division doesn’t have a remainder.

My train datasets = 50000 and my test datasets = 10000, and I believe that the accuracy cannot always be integer. If my right train datasets = 40050, and my train accuracy will be 80.100000%, but now my accuracy is always int.

Sure, I didn’t mean it will always be an int, but still can be an integer.
Using your code to create a small code snippet works fine:

N = 50000
running_correct = 0.0
running_correct += torch.sum(torch.randint(0, 2, (N,)) == torch.randint(0, 2, (N,)))
running_correct /= N
print(100*running_correct)
> tensor(49.8620)
1 Like

Wow, it works! Thank you very much!

Good to hear that! What did you change that it’s working now?

I change my code like below:

running_loss = running_loss / N_running
running_correct = 100*running_correct.item() / N_running
testing_correct = 100*testing_correct.item() / N_test

Because running_correct and testing_correct are both Tensor, so I use .item().
I found that the tensor type automatically created by pytorch is torch.LongTensor. The operation between int/long in pytorch is still int. Using item() to convert to scalar, that is, to restore the basic python operation.

I found the code like below:

print(1/3)
>>>0.3333
print(torch.tensor([1])/torch.tensor([3]))
>>>tensor([0])

So I change the code like above.