Problem creating a new dataset

karlo: <p>Hello everybody,</p>
<p>I am trying to create a new training subset from two dataset, but I have a problem “Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same”.</p>
<pre><code class="lang-auto">import torch
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
import torchvision
from torchvision import datasets, models, transforms

import torch.nn.functional as F

import numpy as np
import pandas as pd #Agrego para trabajar matriz de resultados
import tqdm
import pickle # Utilizada para almacenar modelos

import os
import copy

import matplotlib.pyplot as plt
%matplotlib inline
</code></pre>
<pre><code class="lang-auto">class CNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)        

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = torch.flatten(x, 1) # flatten all dimensions except batch
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x
    
cnn = CNN() 
</code></pre>
<p>For example, the two dataset are:</p>
<pre><code class="lang-auto">##-----------------## CIFAR10
image_size = 32
batch_size = 4
classes = ('plane', 'car', 'bird', 'cat','deer', 'dog', 'frog', 'horse', 'ship', 'truck')

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

trainset_1 = torchvision.datasets.CIFAR10(root='./data', train=True,download=True, transform=transform)
testset_1 = torchvision.datasets.CIFAR10(root='./data', train=False,download=True, transform=transform)

trainloader_1 = torch.utils.data.DataLoader(trainset_1, batch_size=batch_size,shuffle=True, num_workers=2)
testloader_1 = torch.utils.data.DataLoader(testset_1, batch_size=batch_size,shuffle=False, num_workers=2)

##-----------------## FashionMNIST
image_size = 32
batch_size = 4
classes = ('T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot')

transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Resize(image_size),
     transforms.Lambda(lambda x: x.repeat(3,1,1)),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

trainset_2 = torchvision.datasets.FashionMNIST(root='./data/FashionMNIST', train=True, transform=transform, download=True)
testset_2 = torchvision.datasets.FashionMNIST(root='./data/FashionMNIST', train=False, download=True, transform=transform)

trainloader_2 = torch.utils.data.DataLoader(trainset_2, batch_size=batch_size, shuffle=True, num_workers=0) 
testloader_2 = torch.utils.data.DataLoader(testset_2, batch_size=batch_size, shuffle=False, num_workers=0)
</code></pre>
<p>Here is the problem, when I try to create the new set (now with 20 classes). Taking a subset of one and the other complete.</p>
<pre><code class="lang-auto">evens = list(range(0, len(trainset_1), 10))

sub_trainset_1 = torch.utils.data.Subset(trainset_1, evens)
sub_testset_1 = torch.utils.data.Subset(testset_1, evens)

trainset = torch.utils.data.ConcatDataset([sub_trainset_1, trainset_2]) 
testset = torch.utils.data.ConcatDataset([sub_testset_1, testset_2]) 

trainloader = torch.utils.data.DataLoader(trainset, shuffle=True, num_workers=0, batch_size=4)
testloader = torch.utils.data.DataLoader(testset, shuffle=False, num_workers=0, batch_size=4)
</code></pre>
<p>For train, I have:</p>
<pre><code class="lang-auto">criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(cnn.parameters(), lr=0.001)

num_epochs = 5
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

for epoch in range(num_epochs):
  total_loss = 0
  total_examples = 0

  with tqdm.notebook.tqdm(total=len(trainloader), unit='batch', desc=f'Epoch {epoch+1}/{num_epochs}', 
                          position=100, leave=True) as pbar:  
    for X, Y in trainloader: 

      X = X.to(device)
      Y = Y.to(device)

      # Forward pass
      Y_ = cnn(X)
      loss = criterion(Y_, Y)

      # Backward pass
      optimizer.zero_grad()
      loss.backward()

      # Gradient descent
      optimizer.step()

      total_loss += loss.item()*X.size(0)
      total_examples += X.size(0)

      pbar.set_postfix(loss=total_loss/total_examples)
      pbar.update()
</code></pre>
<p>My output is:</p>
<pre><code class="lang-auto">---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
&lt;ipython-input-29-2eebc2f5e475&gt; in &lt;module&gt;
     14 
     15       # Forward pass
---&gt; 16       Y_ = cnn(X)
     17       loss = criterion(Y_, Y)
     18 

c:\users\xyz\anaconda3\envs\envgene\lib\site-packages\torch\nn\modules\module.py in _call_impl(self, *input, **kwargs)
    887             result = self._slow_forward(*input, **kwargs)
    888         else:
--&gt; 889             result = self.forward(*input, **kwargs)
    890         for hook in itertools.chain(
    891                 _global_forward_hooks.values(),

&lt;ipython-input-2-fbd28d5a9e42&gt; in forward(self, x)
     10 
     11     def forward(self, x):
---&gt; 12         x = self.pool(F.relu(self.conv1(x)))
     13         x = self.pool(F.relu(self.conv2(x)))
     14         x = torch.flatten(x, 1) # flatten all dimensions except batch

c:\users\xyz\anaconda3\envs\envgene\lib\site-packages\torch\nn\modules\module.py in _call_impl(self, *input, **kwargs)
    887             result = self._slow_forward(*input, **kwargs)
    888         else:
--&gt; 889             result = self.forward(*input, **kwargs)
    890         for hook in itertools.chain(
    891                 _global_forward_hooks.values(),

c:\users\xyz\anaconda3\envs\envgene\lib\site-packages\torch\nn\modules\conv.py in forward(self, input)
    397 
    398     def forward(self, input: Tensor) -&gt; Tensor:
--&gt; 399         return self._conv_forward(input, self.weight, self.bias)
    400 
    401 class Conv3d(_ConvNd):

c:\users\xyz\anaconda3\envs\envgene\lib\site-packages\torch\nn\modules\conv.py in _conv_forward(self, input, weight, bias)
    394                             _pair(0), self.dilation, self.groups)
    395         return F.conv2d(input, weight, bias, self.stride,
--&gt; 396                         self.padding, self.dilation, self.groups)
    397 
    398     def forward(self, input: Tensor) -&gt; Tensor:

RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same
</code></pre>
<p>Do you know this problem? I have tried without good results.</p>
<p>Thankful for the feedback<br>
K.</p>

eqy: <p>Are you trying to run the model on GPU or CPU? You need to make sure the input and the model device type match (e.g., call <code>input = input.cuda()</code> and <code>model = model.cuda()</code> where necessary).</p>

karlo: <p>Thank <a class="mention" href="/u/eqy">@eqy</a>, It works now.</p>
<p>now, if you continue running, I have two problems:</p>
<ul>
<li>In the evaluation of the model, with 20 classes… it indicates a problem with “out of bounds”.</li>
</ul>
<pre><code class="lang-auto">    classes = ['plane', 'car', 'bird', 'cat','deer', 'dog', 'frog', 'horse', 'ship', 'truck','T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

    correct = [0]*len(classes)
    total = [0]*len(classes)
    acc = [0]*len(classes)

    cnn.eval()
    with tqdm.notebook.tqdm(total=len(testloader), unit='batch', desc=f'Evaluation', 
                            position=100, leave=True) as pbar:  

          for X, Y in testloader:
            X, Y = X.cuda(), Y.cuda()                
            X = X.to(device)
            Y = Y.to(device)

            _, Y_ = torch.max(cnn(X.cuda()).data, 1)

            for y, y_ in zip(Y, Y_):
              if y == y_:
                  correct[y] += 1
              total[y] += 1
              acc[y] = correct[y]/total[y]

            pbar.set_postfix(accuracy=sum(acc)/len(classes))
            pbar.update()   

    #--# Results
    for class_name,class_acc in zip(classes,acc):
        print(f'Accuracy para la clase {str(class_name):10s}: {class_acc:.2f}')
    print(f'Accuracy promedio (balanceado): {sum(acc)/len(classes):.2f}')
</code></pre>
<p>The evaluation-output is:</p>
<pre><code class="lang-auto">---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
&lt;ipython-input-48-a5f1fa2cc744&gt; in &lt;module&gt;
      8                         position=100, leave=True) as pbar:  
      9 
---&gt; 10       for X, Y in testloader:
     11         X, Y = X.cuda(), Y.cuda()
     12         X = X.to(device)

c:\users\xyz\anaconda3\envs\envgene\lib\site-packages\torch\utils\data\dataloader.py in __next__(self)
    515             if self._sampler_iter is None:
    516                 self._reset()
--&gt; 517             data = self._next_data()
    518             self._num_yielded += 1
    519             if self._dataset_kind == _DatasetKind.Iterable and \

c:\users\xyz\anaconda3\envs\envgene\lib\site-packages\torch\utils\data\dataloader.py in _next_data(self)
    555     def _next_data(self):
    556         index = self._next_index()  # may raise StopIteration
--&gt; 557         data = self._dataset_fetcher.fetch(index)  # may raise StopIteration
    558         if self._pin_memory:
    559             data = _utils.pin_memory.pin_memory(data)

c:\users\xyz\anaconda3\envs\envgene\lib\site-packages\torch\utils\data\_utils\fetch.py in fetch(self, possibly_batched_index)
     42     def fetch(self, possibly_batched_index):
     43         if self.auto_collation:
---&gt; 44             data = [self.dataset[idx] for idx in possibly_batched_index]
     45         else:
     46             data = self.dataset[possibly_batched_index]

c:\users\xyz\anaconda3\envs\envgene\lib\site-packages\torch\utils\data\_utils\fetch.py in &lt;listcomp&gt;(.0)
     42     def fetch(self, possibly_batched_index):
     43         if self.auto_collation:
---&gt; 44             data = [self.dataset[idx] for idx in possibly_batched_index]
     45         else:
     46             data = self.dataset[possibly_batched_index]

c:\users\xyz\anaconda3\envs\envgene\lib\site-packages\torch\utils\data\dataset.py in __getitem__(self, idx)
    217         else:
    218             sample_idx = idx - self.cumulative_sizes[dataset_idx - 1]
--&gt; 219         return self.datasets[dataset_idx][sample_idx]
    220 
    221     @property

c:\users\xyz\anaconda3\envs\envgene\lib\site-packages\torch\utils\data\dataset.py in __getitem__(self, idx)
    328 
    329     def __getitem__(self, idx):
--&gt; 330         return self.dataset[self.indices[idx]]
    331 
    332     def __len__(self):

c:\users\xyz\anaconda3\envs\envgene\lib\site-packages\torchvision\datasets\cifar.py in __getitem__(self, index)
    111             tuple: (image, target) where target is index of the target class.
    112         """
--&gt; 113         img, target = self.data[index], self.targets[index]
    114 
    115         # doing this so that it is consistent with all other datasets

IndexError: index 10000 is out of bounds for axis 0 with size 10000
</code></pre>
<p>I do not understand, what is the reason for dimension problems?</p>
<ul>
<li>The classes function does not work the same, why is this?</li>
</ul>
<pre><code class="lang-auto">trainset_1.classes
['airplane',
 'automobile',
 'bird',
 'cat',
 'deer',
 'dog',
 'frog',
 'horse',
 'ship',
 'truck']

trainset_2.classes
['T-shirt/top',
 'Trouser',
 'Pullover',
 'Dress',
 'Coat',
 'Sandal',
 'Shirt',
 'Sneaker',
 'Bag',
 'Ankle boot']
</code></pre>
<p>Is it required to do something in dataset before?</p>
<pre><code class="lang-auto">trainset = torch.utils.data.ConcatDataset([trainset_1, trainset_2]) 
trainset.classes

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
&lt;ipython-input-51-fe0a9b13bfd7&gt; in &lt;module&gt;
      1 trainset = torch.utils.data.ConcatDataset([trainset_1, trainset_2])
----&gt; 2 trainset.classes

AttributeError: 'ConcatDataset' object has no attribute 'classes'
</code></pre>
<p>Appreciating the comments</p>
<p>Greetings<br>
K</p>

eqy: <p>I’m not sure that <code>ConcatDataset</code> is intended to be used with two datasets that have completely different classes. You might want to iterate through it without training the model as a sanity check to see you do get 20 classes. After checking that it should be easier to take a look at the TestLoader and see what is causing the mismatch between the reported length and the actual length.</p>