Difference between batch and DataLoader

Rocket: <p>Example code for torch is below.</p>
<p>I changed the code as below below.</p>
<pre><code class="lang-auto">import torch

import torch.nn as nn
import torchvision
import torchvision.transforms as transforms
import torchvision.models as models
import torch.optim as optim

# for image
import matplotlib.pyplot as plt
import numpy as np


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

trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False, num_workers=2)

classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

net = models.resnet18()  # torchvision 에 이미 정의된 모델을 가져옵니다.
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

print('\n===&gt; Training Start')

device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
net = net.to(device)
if torch.cuda.device_count() &gt; 1:
    print('\n===&gt; Training on GPU!')
    net = nn.DataParallel(net)

epochs = 2  # dataset을 여러번 사용해 트레이닝을 시킵니다.

for epoch in range(epochs):
    print('\n===&gt; epoch %d' % epoch)
    running_loss = 0.0

    for i, data in enumerate(trainloader, 0):
        # get the inputs
        inputs, labels = data
        inputs, labels = inputs.to(device), labels.to(device)

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()

        if i % 2000 == 1999:  # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))

with torch.no_grad():
    for data in testloader:
        images, labels = data
        images, labels = images.to(device), labels.to(device)
        outputs = net(images)
        _, predicted = torch.max(outputs, 1)  # prediction
        c = (predicted == labels).squeeze()
        for i in range(4):
            label = labels[i]
            class_correct[label] += c[i].item()
            class_total[label] += 1

for i in range(10):
    print('Accuracy of %5s : %2d %%' % (classes[i], 100 * class_correct[i] / class_total[i]))
</code></pre>
<p>I change the code as below</p>
<p>The changes are about batch. DataLoader.</p>
<p>There are pretty difference in final accuracy.</p>
<p>I don’t know what difference is.</p>
<pre><code class="lang-auto">import torch

import torch.nn as nn
import torchvision
import torchvision.transforms as transforms
import torchvision.models as models
import torch.optim as optim

# for image
import matplotlib.pyplot as plt
import numpy as np

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

trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform) # 50000x32x32x3
#trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform) # 10000x32x32x3
testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False, num_workers=2)

classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

net = models.resnet18()  # torchvision 에 이미 정의된 모델을 가져옵니다.
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

print('\n===&gt; Training Start')

device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
net = net.to(device)
if torch.cuda.device_count() &gt; 1:
    print('\n===&gt; Training on GPU!')
    net = nn.DataParallel(net)

epochs = 2  # dataset을 여러번 사용해 트레이닝을 시킵니다.

batch_idx = torch.randperm(trainset.data.shape[0])
batch_size = 4

for epoch in range(epochs):
    print('\n===&gt; epoch %d' % epoch)
    running_loss = 0.0

    for i in range(int(trainset.data.shape[0] / batch_size)):
        inputs=[]
        labels=[]
        mini_idx = batch_idx[i*batch_size:(i+1)*batch_size-1]
        # get the inputs
        for j in range(batch_size):
            temp_inputs, temp_labels = trainset.__getitem__(j)
            inputs.append(np.asarray(temp_inputs))
            labels.append(np.asarray(temp_labels))
        
        inputs = torch.from_numpy(np.array(inputs,dtype='float32')).float()
        labels = torch.from_numpy(np.array(labels,dtype='int64')).long()
        
        inputs, labels = inputs.to(device), labels.to(device)

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)        # 네트워크에 입력은 [데이터수x채널x높이x너비]
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()

        if i % 100 == 99:  # print every 2000 mini-batches
            print('[%d, %5d] loss: %.9f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))

with torch.no_grad():
    for data in testloader:
        images, labels = data
        images, labels = images.to(device), labels.to(device)
        outputs = net(images)
        _, predicted = torch.max(outputs, 1)  # prediction
        c = (predicted == labels).squeeze()
        for i in range(4):
            label = labels[i]
            class_correct[label] += c[i].item()
            class_total[label] += 1

for i in range(10):
    print('Accuracy of %5s : %2d %%' % (classes[i], 100 * class_correct[i] / class_total[i]))
</code></pre>

ptrblck: <p>Is the result reproducible, i.e. are you seeing the difference in accuracy for different runs and seeds?</p>

Rocket: <p>Thank you.</p>
<pre><code class="lang-auto">temp_inputs, temp_labels = trainset.__getitem__(j)

temp_inputs, temp_labels = trainset.__getitem__(mini_idx(j))
</code></pre>

ptrblck: <p>I’m not sure, what these lines mean. Are you seeing a reproducible difference in accuracy using these lines of code?</p>