TypeError: cannot unpack non-iterable int object

username: farazk86
cooked: <p>Hi,</p>
<p>Im trying to make my first CNN using pyTorch and am following online help and code already people wrote. i am trying to reproduce their results. I’m using the Kaggle Dogs Breed Dataset for this and below is the error I get. The trainloader does not return my images and labels and any attempt to get them leads in an error:</p>
<pre><code class="lang-auto">Traceback (most recent call last):
  File "E:\Program Files\JetBrains\PyCharm Community Edition 2018.2.4\helpers\pydev\pydevd.py", line 1664, in &lt;module&gt;
    main()
  File "E:\Program Files\JetBrains\PyCharm Community Edition 2018.2.4\helpers\pydev\pydevd.py", line 1658, in main
    globals = debugger.run(setup['file'], None, None, is_module)
  File "E:\Program Files\JetBrains\PyCharm Community Edition 2018.2.4\helpers\pydev\pydevd.py", line 1068, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "E:\Program Files\JetBrains\PyCharm Community Edition 2018.2.4\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "C:/Users/sbzfk/PycharmProjects/my_FCN_attempt/Kaggle_Dogs_Competition.py", line 85, in &lt;module&gt;
    img, label = next(iter(train_loader))
  File "C:\Users\sbzfk\AppData\Local\Programs\Python\Python37\lib\site-packages\torch\utils\data\dataloader.py", line 314, in __next__
    batch = self.collate_fn([self.dataset[i] for i in indices])
  File "C:\Users\sbzfk\AppData\Local\Programs\Python\Python37\lib\site-packages\torch\utils\data\dataloader.py", line 314, in &lt;listcomp&gt;
    batch = self.collate_fn([self.dataset[i] for i in indices])
  File "C:/Users/sbzfk/PycharmProjects/my_FCN_attempt/Kaggle_Dogs_Competition.py", line 42, in __getitem__
    img = self.transform(img)
  File "C:\Users\sbzfk\AppData\Local\Programs\Python\Python37\lib\site-packages\torchvision\transforms.py", line 34, in __call__
    img = t(img)
  File "C:\Users\sbzfk\AppData\Local\Programs\Python\Python37\lib\site-packages\torchvision\transforms.py", line 187, in __call__
    w, h = img.size
TypeError: cannot unpack non-iterable int object

</code></pre>
<p>Below is my code:</p>
<pre><code class="lang-auto">class DogsDataset(Dataset):

    def __init__(self, filenames, labels, root_dir, transform=None):
        assert len(filenames) == len(labels)        # if the two are not of equal length throw an error
        self.filenames = filenames
        self.labels = labels
        self.root_dir = root_dir
        self.transform = transform

    def __len__(self):
        return len(self.filenames)

    def __getitem__(self, idx):
        this_img = join(self.root_dir, 'train', self.filenames[idx]+'.jpg')
        print(this_img)
        img = io.imread(this_img)
        label = self.labels[idx]
        print(label)

        if self.transform:
            img = self.transform(img)

        return [img, label]



batch_size = 64
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

dataset_root = expanduser(join('~', 'Documents', 'kaggle_dogs_dataset'))
# join will intelligently join directories irrespective of OS, and expanduser will
# replace with /home/ in linux or the username in Windows

csv_file = pd.read_csv(join(dataset_root, 'labels.csv'))        # csv file has two columns, id which are filenames and breed which are labels
filenames = csv_file.id.values              # convert that column to an array, id is the column name and values converty to numpy array
# le = LabelEncoder()
# labels = le.fit_transform(csv_file.breed)           # this will just encode the names between 0 to models-1 , basically changing strings to integers
labels = csv_file.breed.values

filenames_train, filenames_eval, labels_train, labels_eval = train_test_split(filenames, labels,
                                                                              test_size=0.1, stratify=labels)       # this is an import from sklearn as the name implies, it randomly splits data into train and eval, 10% of it to test and rest train

data_transform = transforms.Compose([transforms.Scale(224),
                                     transforms.CenterCrop(224),
                                     transforms.ToTensor(),
                                     transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))])

dog_train = DogsDataset(filenames_train, labels_train, dataset_root, transform=data_transform)
train_loader = DataLoader(dog_train, batch_size, shuffle=True)

dog_eval = DogsDataset(filenames_eval, labels_eval, dataset_root, transform=data_transform)
eval_loader = DataLoader(dog_eval, batch_size, shuffle=True)


def im_show(axis, inp):
    """Denormalize and show"""
    inp = inp.numpy().transpose((1, 2, 0))
    mean = np.array([0.485, 0.456, 0.406])
    std = np.array([0.229, 0.224, 0.225])
    inp = std * inp + mean
    axis.imshow(inp)


img, label = next(iter(train_loader))
print(img.size(), label.size())
fig = plt.figure(1, figsize=(16, 4))
grid = ImageGrid(fig, 111, nrows_ncols=(1, 4), axes_pad=0.05)
for i in range(img.size()[0]):
    ax = grid[i]
    im_show(ax, img[i])
</code></pre>

username: ptrblck
cooked: <p>I guess your <code>self.transform</code> contains some image transformations other than <code>ToTensor()</code>, e.g. <code>RandomCrop()</code>.<br>
These transformations currently work on <code>PIL.Images</code>, so if you load your image with <code>img = Image.open(this_img)</code> it should work.</p>

username: farazk86
cooked: <p>Thanks for answering <a class="mention" href="/u/ptrblck">@ptrblck</a>. I didint know that transforms only work with PIL objects.</p>
<p>It allowed me to go further in my code but now I am presented with another error:</p>
<pre><code class="lang-auto"> Traceback (most recent call last):
  File "C:/Users/sbzfk/PycharmProjects/my_FCN_attempt/Kaggle_Dogs_Competition.py", line 113, in &lt;module&gt;
    model = train_model(data_loaders, net, criterion, optimizer, exp_lr_scheduler, num_epochs=2)
  File "C:\Users\sbzfk\PycharmProjects\my_FCN_attempt\TrainModel.py", line 34, in train_model
    loss = criterion(outputs, labels)
  File "C:\Users\sbzfk\AppData\Local\Programs\Python\Python37\lib\site-packages\torch\nn\modules\module.py", line 477, in __call__
    result = self.forward(*input, **kwargs)
  File "C:\Users\sbzfk\AppData\Local\Programs\Python\Python37\lib\site-packages\torch\nn\modules\loss.py", line 862, in forward
    ignore_index=self.ignore_index, reduction=self.reduction)
  File "C:\Users\sbzfk\AppData\Local\Programs\Python\Python37\lib\site-packages\torch\nn\functional.py", line 1550, in cross_entropy
    return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)
  File "C:\Users\sbzfk\AppData\Local\Programs\Python\Python37\lib\site-packages\torch\nn\functional.py", line 1403, in nll_loss
    if input.size(0) != target.size(0):
AttributeError: 'tuple' object has no attribute 'size'
</code></pre>
<p>Apparently the <code>labels</code> list/array is giving problems. Is it because its not a Tensor? But all the examples I read online, none of them convert their labels to tensors, they are used as is as I have done here. The error is from the TrainModel code which is below:</p>
<pre><code class="lang-auto">import time
import torch


def train_model(dataloders, model, criterion, optimizer, scheduler, num_epochs=25):
    use_gpu = torch.cuda.is_available()
    since = time.time()
    best_model_wts = model.state_dict()
    best_acc = 0.0
    dataset_sizes = {'train': len(dataloders['train'].dataset),
                     'valid': len(dataloders['valid'].dataset)}

    for epoch in range(num_epochs):
        for phase in ['train', 'valid']:            # for every epoch first train and that validate, phase will take string of train first and next iter it will be valid
            if phase == 'train':
                scheduler.step()
                model.train(True)
            else:
                model.train(False)                  # set to evaluation mode

            running_loss = 0.0
            running_corrects = 0

            for inputs, labels in dataloders[phase]:            # this will load data from train data loader first and then from validation dataloader
                if use_gpu:
                    inputs, labels = inputs.cuda(), labels.cuda()

                optimizer.zero_grad()

                outputs = model(inputs)
                print(outputs.size())
                print(labels.size())
                _, preds = torch.max(outputs.data, 1)
                loss = criterion(outputs, labels)

                if phase == 'train':
                    loss.backward()
                    optimizer.step()

                running_loss += loss.data[0]
                running_corrects += torch.sum(preds == labels.data)

            if phase == 'train':
                train_epoch_loss = running_loss / dataset_sizes[phase]
                train_epoch_acc = running_corrects / dataset_sizes[phase]
            else:
                valid_epoch_loss = running_loss / dataset_sizes[phase]
                valid_epoch_acc = running_corrects / dataset_sizes[phase]

            if phase == 'valid' and valid_epoch_acc &gt; best_acc:
                best_acc = valid_epoch_acc
                best_model_wts = model.state_dict()

        print('Epoch [{}/{}] train loss: {:.4f} acc: {:.4f} '
              'valid loss: {:.4f} acc: {:.4f}'.format(
            epoch, num_epochs - 1,
            train_epoch_loss, train_epoch_acc,
            valid_epoch_loss, valid_epoch_acc))

    print('Best val Acc: {:4f}'.format(best_acc))

    model.load_state_dict(best_model_wts)
    return model

</code></pre>
<p>The above print lines of <code>print(outputs.size())</code> gives the output torch.Size([64, 10222]) where as the <code>print(labels.size())</code> gives the error: <code>AttributeError: 'tuple' object has no attribute 'size'</code></p>
<p>Can you please help me with this,</p>
<p>Many thanks</p>

username: ptrblck
cooked: <p>Your <code>labels</code> should also be <code>tensors</code> as otherwise you couldn’t even push them onto your GPU:</p>
<pre><code class="lang-python">labels = labels.cuda()
</code></pre>
<p>Are your <code>labels</code> currently stored in a list or a numpy array?<br>
For the former you could just wrap them using <code>torch.tensor(label)</code> in your <code>Dataset</code>, for the latter use <code>torch.from_numpy(label)</code>.</p>

username: RAFAIL_MAHAMMADLI
cooked: <p>Helllo <a class="mention" href="/u/ptrblck">@ptrblck</a> . I trained Resnet50 on my dataset. At the end of training I got following error. Can you please let me know for solving this issue?</p>
<p>Thank you<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/5/d/5db61060d2114a74e5ccc89d57023b60c47de53c.png" data-download-href="https://discuss.pytorch.org/uploads/default/5db61060d2114a74e5ccc89d57023b60c47de53c" title="Screenshot 2022-01-25 at 15.24.34"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/5/d/5db61060d2114a74e5ccc89d57023b60c47de53c_2_690x474.png" alt="Screenshot 2022-01-25 at 15.24.34" data-base62-sha1="dn0trZAnUSGX5UuzfUy3bGXoODi" width="690" height="474" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/5/d/5db61060d2114a74e5ccc89d57023b60c47de53c_2_690x474.png, https://discuss.pytorch.org/uploads/default/original/3X/5/d/5db61060d2114a74e5ccc89d57023b60c47de53c.png 1.5x, https://discuss.pytorch.org/uploads/default/original/3X/5/d/5db61060d2114a74e5ccc89d57023b60c47de53c.png 2x" data-dominant-color="373838"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">Screenshot 2022-01-25 at 15.24.34</span><span class="informations">744×512 42.5 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
<p>This is my code</p>
<h1><a name="just-normalization-for-validation-1" class="anchor" href="#just-normalization-for-validation-1"></a>Just normalization for validation</h1>
<p>data_transforms = {<br>
‘train’: transforms.Compose([<br>
transforms.RandomResizedCrop(224),<br>
transforms.RandomHorizontalFlip(),<br>
transforms.ToTensor(),<br>
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])<br>
]),<br>
‘val’: transforms.Compose([<br>
transforms.Resize(256),<br>
transforms.CenterCrop(224),<br>
transforms.ToTensor(),<br>
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])<br>
]),</p>
<pre><code> 'test': transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
</code></pre>
<p>}</p>
<p>data_dir = ‘/content/drive/MyDrive/raphcatr’<br>
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),<br>
data_transforms<span class="chcklst-box checked fa fa-check-square-o fa-fw"></span>)<br>
for x in [‘train’, ‘val’, ‘test’]}<br>
dataloaders = {x: torch.utils.data.DataLoader(image_datasets<span class="chcklst-box checked fa fa-check-square-o fa-fw"></span>, batch_size=16,<br>
shuffle=True, num_workers=4)<br>
for x in [‘train’, ‘val’, ‘test’]}<br>
dataset_sizes = {x: len(image_datasets<span class="chcklst-box checked fa fa-check-square-o fa-fw"></span>) for x in [‘train’, ‘val’, ‘test’]}<br>
class_names = image_datasets[‘train’].classes</p>
<p>device = torch.device(“cuda:0” if torch.cuda.is_available() else “cpu”)</p>
<p>def train_model(model, criterion, optimizer,  num_epochs=25):<br>
since = time.time()</p>
<pre><code>best_model_wts = copy.deepcopy(model.state_dict())
best_acc = 0.0

for epoch in range(num_epochs):
    print('Epoch {}/{}'.format(epoch, num_epochs - 1))
    print('-' * 10)

    # Each epoch has a training and validation phase
    for phase in ['train', 'val']:
        if phase == 'train':
            model.train()  # Set model to training mode
        else:
            model.eval()   # Set model to evaluate mode

        running_loss = 0.0
        running_corrects = 0

        # Iterate over data.
        for inputs, labels in dataloaders[phase]:
            inputs = inputs.to(device)
            labels = labels.to(device)

            # zero the parameter gradients
            optimizer.zero_grad()

            # forward
            # track history if only in train
            with torch.set_grad_enabled(phase == 'train'):
                outputs = model(inputs)
                _, preds = torch.max(outputs, 1)
                loss = criterion(outputs, labels)

                # backward + optimize only if in training phase
                if phase == 'train':
                    loss.backward()
                    optimizer.step()

            # statistics
            running_loss += loss.item() * inputs.size(0)
            running_corrects += torch.sum(preds == labels.data)
        

        epoch_loss = running_loss / dataset_sizes[phase]
        epoch_acc = running_corrects.double() / dataset_sizes[phase]

        print('{} Loss: {:.4f} Acc: {:.4f}'.format(
            phase, epoch_loss, epoch_acc))

        # deep copy the model
        if phase == 'val' and epoch_acc &gt; best_acc:
            best_acc = epoch_acc
            best_model_wts = copy.deepcopy(model.state_dict())

    print()

time_elapsed = time.time() - since
print('Training complete in {:.0f}m {:.0f}s'.format(
    time_elapsed // 60, time_elapsed % 60))
print('Best val Acc: {:4f}'.format(best_acc))

# load best model weights
model.load_state_dict(best_model_wts)
return model
</code></pre>
<p>model = models.resnet50(pretrained=True)<br>
# Freeze training for all “features” layers<br>
for param in model.parameters():<br>
param.requires_grad = False</p>
<p>classifier = nn.Sequential(<br>
nn.Linear(2048,512),<br>
nn.ReLU(),<br>
nn.Dropout(p=0.5),<br>
nn.Linear(512, 3))</p>
<p>model.fc = classifier</p>
<p>class_weights = torch.FloatTensor([1./127, 1./141, 1./257]) * 100</p>
<p>criterion = nn.CrossEntropyLoss(weight = class_weights).to(device)</p>
<h1><a name="only-train-the-classifier-parameters-feature-parameters-are-frozen-2" class="anchor" href="#only-train-the-classifier-parameters-feature-parameters-are-frozen-2"></a>Only train the classifier parameters, feature parameters are frozen</h1>
<p>optimizer = optim.Adam(model.fc.parameters(), lr=0.0002)</p>
<p>from PIL import Image, ImageFile<br>
ImageFile.LOAD_TRUNCATED_IMAGES=True</p>
<p>resnet_model, history = train_model(model, criterion, optimizer,<br>
num_epochs=25)</p>

username: ptrblck
cooked: <p>You are returning the <code>model</code> only, while trying to assign <code>resnet_model, history</code> as seen here:</p>
<pre><code class="lang-python">def fun():
    model = models.resnet18()
    return model

model = fun() # works
model, history = fun()
# &gt; TypeError: cannot unpack non-iterable ResNet object
</code></pre>

username: RAFAIL_MAHAMMADLI
cooked: <p>I see it. Thank you very much <a class="mention" href="/u/ptrblck">@ptrblck</a></p>

username: RAFAIL_MAHAMMADLI
cooked: <p>Hi <a class="mention" href="/u/ptrblck">@ptrblck</a></p>
<p>How can I plot train loss and val loss in my code?</p>
<p>Thank you</p>

username: ptrblck
cooked: <p>Store the losses in e.g. a <code>list</code>, transform them to e.g. numpy arrays, and plot them via e.g. <code>matplotlib</code>.</p>

username: RAFAIL_MAHAMMADLI
cooked: <p>Hi <a class="mention" href="/u/ptrblck">@ptrblck</a></p>
<p>Thank you for your response. Do i missing something to plot train acc and val acc, as well as train loss and val loss?</p>
<p>My code: This is actually original pytorch tutorial code . I would like to plot train acc and val acc ,  train loss and val loss separately</p>
<p>def train_model(model, criterion, optimizer, scheduler, num_epochs=25):<br>
since = time.time()<br>
history=[]</p>
<pre><code>best_model_wts = copy.deepcopy(model.state_dict())
best_acc = 0.0

for epoch in range(num_epochs):
    print('Epoch {}/{}'.format(epoch, num_epochs - 1))
    print('-' * 10)

    # Each epoch has a training and validation phase
    for phase in ['train', 'val']:
        if phase == 'train':
            model.train()  # Set model to training mode
        else:
            model.eval()   # Set model to evaluate mode

        running_loss = 0.0
        running_corrects = 0

        # Iterate over data.
        for inputs, labels in dataloaders[phase]:
            inputs = inputs.to(device)
            labels = labels.to(device)

            # zero the parameter gradients
            optimizer.zero_grad()

            # forward
            # track history if only in train
            with torch.set_grad_enabled(phase == 'train'):
                outputs = model(inputs)
                _, preds = torch.max(outputs, 1)
                loss = criterion(outputs, labels)

                # backward + optimize only if in training phase
                if phase == 'train':
                    loss.backward()
                    optimizer.step()

            # statistics
            running_loss += loss.item() * inputs.size(0)
            running_corrects += torch.sum(preds == labels.data)
        if phase == 'train':
            scheduler.step()

        epoch_loss = running_loss / dataset_sizes[phase]
        epoch_acc = running_corrects.double() / dataset_sizes[phase]

        print('{} Loss: {:.4f} Acc: {:.4f}'.format(
            phase, epoch_loss, epoch_acc))

        # deep copy the model
        if phase == 'val' and epoch_acc &gt; best_acc:
            best_acc = epoch_acc
            best_model_wts = copy.deepcopy(model.state_dict())

    print()

time_elapsed = time.time() - since
print('Training complete in {:.0f}m {:.0f}s'.format(
    time_elapsed // 60, time_elapsed % 60))
print('Best val Acc: {:4f}'.format(best_acc))

# load best model weights
model.load_state_dict(best_model_wts)
history.append(epoch_acc, epoch_loss)

return model, history
</code></pre>
<p>import matplotlib.pyplot as plt<br>
import numpy as np</p>
<p>history = np.array(history)</p>
<p>plt.plot(history[:,0:2])</p>

username: ptrblck
cooked: <p>Based on your code it seems you are appending <code>epoch_acc</code> and <code>epoch_loss</code> only once after the training is done so I would assume <code>plt.plot</code> just plots one point?<br>
I guess you want to append all epoch stats so move the <code>history.append</code> into the epoch loop?</p>