2

I am trying to understand deep-learning with pytorch. I read the pytorch tutorial: https://pytorch.org/tutorials/beginner/blitz/neural_networks_tutorial.html, and its written:

''torch.nn only supports mini-batches. The entire torch.nn package only supports inputs that are a mini-batch of samples, and not a single sample. For example, nn.Conv2d will take in a 4D Tensor of nSamples x nChannels x Height x Width. If you have a single sample, just use input.unsqueeze(0) to add a fake batch dimension.''

I am not sure to understand what it means. Indeed, I have made a simple feed-forward neural network (cf below code), on which I used a really small dataset (the idea is to learn how it works without mini-batches first, not really to have anything useful), and hence don't need to use mini-batches. Hence, I introduce directly all the sample at each epochs. If I understand it correctly, I should add 'train_data = train_data.unsqueeze(0) '. But I am not sure where, as it seems to change the data size to 1. Also, it works without adding this line so why should I really use it?

Any help would be highly appreciated!

import torch
import torchvision
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import pandas as pd
import os
import numpy as np

# Download data
#... 

# Construct network
len_input = len(data[0])
len_output = nbr_class
print('There is %d classes used for classification'%nbr_class)

#defining a new class: Net, that extended nn.Module
#setup the “skeleton” of our network architecture
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        #creation of fully connected. A fully connected neural network layer is represented by the nn.Linear object, 
        #with the first argument in the definition being the number of nodes in layer l and the next argument being 
        #the number of nodes in layer l+1
        self.fc1 = nn.Linear(len_input, 200)
        self.fc2 = nn.Linear(200, 200)
        self.fc3 = nn.Linear(200, len_output)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return F.log_softmax(x)

# Create initial network
epochs = 3000
model = Net()
criterion = nn.NLLLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

# Train & test network
def train(data, target, epoch):
    model.train() # set the model in "training mode"
    # run the main training loop
    #no need batch size as small number of sample! like this the process is more exact
    #zero our gradients before calling .backward() which is necessary for new sum of gradients
    optimizer.zero_grad()
    target_pred = model(data)
    loss = criterion(target_pred, target)
    #Propagate the gradients back through the network
    loss.backward()
    #update the weights
    #tell our optimizer to “step”, meaning that the weights will be updated using the calculated gradients 
    #according to our rule. perform model parameter update (update weights)
    optimizer.step()
    # for graphing puposes
    loss_array.append(loss.data[0])

    if epoch in list(range(0,20000,100)):
        print('Train Epoch: {} \tLoss: {:.6f}'.format(epoch, loss.data[0]))

def test(epoch, test_data, test_target):
    #eval mode to turn Dropout and BatchNorm off
    model.eval()
    test_loss = 0
    correct = 0
    test_target_pred = model(test_data)
    criterion = nn.NLLLoss()
    # sum up batch loss
    test_loss += criterion(test_target_pred, test_target).data[0]
    pred = test_target_pred.data.max(1)[1]  # get the index of the max log-probability
    correct += pred.eq(test_target.data).sum()
    if epoch in list(range(0,20000,100)):
        print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
            test_loss, correct, len(test_target), 100. * correct / len(test_target)))

if __name__ == '__main__':
    for epoch in range(epochs):
        train(data = train_data, target=train_target, epoch=epoch)
        test(epoch, test_data, test_target)
miki
  • 639
  • 2
  • 6
  • 16
  • 1
    "torch.nn only supports mini-batches" What this means is the input needs to be 4 dimensional. When you load your single image (e.g. RGB-> 3 x 128 x 128), you need to convert it to an ndarray or a torch.Tensor with 4 dimensions. In this case the resulting array or tensor should have the dimensions of 1 x 3 x 128 x 128. – Tyathalae Jun 14 '18 at 11:35
  • Thank you very much for your answer @Tyathalae! Still, I don’t understand why they use the term “mini-batches” for this. Indeed to me being in mini batches mode means that the batch size is strictly less than the whole sample (meaning that their is several iterations per epoch). – miki Jun 15 '18 at 06:08
  • Yes that is correct. In mini-batch mode if you have 1000 training images, you can use 10 of them in each mini-batch therefore, 100 iterations per epoch. This is preferred because of faster and better convergence plus memory reasons. You cannot load 10 million images into the memory and if you process images 1 at a time, it will take a very long time and you will not utilize parallelization. – Tyathalae Jun 19 '18 at 07:56
  • @Tyathalae so we agree on this :). Hence for me “torch.nn only supports mini-batches” means that we can not run all the sample in one epochs. But when the sample is small, then we could want for accuracy to run all at once... so I really don’t understand – miki Jun 19 '18 at 08:01
  • You *can* run all samples in one iteration. It is discouraged because of high memory use and worse convergence rate. However in your case, if you have say 10 training images, you can choose to load them all into 10 x 3 x 128 x 128 tensor (which would be batch mode [no mini]) or you can load 2 images 2 x 3 x 128 x 128 per mini-batch and do 5 iterations per epoch. You will not necessarily get better accuracy if you use batch mode rather than mini-batch (all images vs subsets). – Tyathalae Jun 19 '18 at 08:04
  • 1 addition: Try to use DataLoader, you can check here: https://pytorch.org/tutorials/beginner/data_loading_tutorial.html#iterating-through-the-dataset – Tyathalae Jun 19 '18 at 08:06
  • @Tyathalae thank you for your help! So actually it also support batch mode (case of 10x3x128x128) Not only mini batches? Yes I will have a look at DataLoader, thank you! – miki Jun 19 '18 at 08:20

0 Answers0