CocoDetection with transforms not working

username: reallyclean-sauce
cooked: <p>My goal is to train a pre-trained object segmentation model using my own dataset with its own classes. So, I created my own dataset using the COCO Dataset format.</p>
<p>Here below, you can see that I am trying to create a Dataset using the function CocoDetection.</p>
<pre><code class="lang-auto">import torchvision.datasets as dset

def get_transform():
    custom_transforms = []
    custom_transforms.append(T.ToTensor())
    return T.Compose(custom_transforms)

coco_test = dset.CocoDetection(root = root_dir,
                                annFile = test_json,
                                transforms=get_transform())

# Test if dataset is working
for i in range(len(coco_train)):
  sample = coco_train[i]
  print(sample[0])

  if i == 3:
    break
</code></pre>
<p>At first, I tried without applying any transformations at all and it worked. However, after I added a transform on the function, it did not work. I checked the error and it says that the <strong>call</strong> takes 2 positional argument, but 3 were given. But, I inspected the source code, and I am giving it 2 arguments. I don’t know what’s the problem. I don’t know what to do next. Please help. Here’s the full error. By the way, I am using Google Colab.</p>
<pre><code class="lang-auto">---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

&lt;ipython-input-13-bc0dddb4b6c5&gt; in &lt;module&gt;()
      1 for i in range(len(coco_train)):
----&gt; 2   sample = coco_train[i]
      3   print(sample[0])
      4 
      5   if i == 3:

/usr/local/lib/python3.6/dist-packages/torchvision/datasets/coco.py in __getitem__(self, index)
    116         img = Image.open(os.path.join(self.root, path)).convert('RGB')
    117         if self.transforms is not None:
--&gt; 118             img, target = self.transforms(img, target)
    119 
    120         return img, target

TypeError: __call__() takes 2 positional arguments but 3 were given
</code></pre>

username: ptrblck
cooked: <p>From the <a href="https://pytorch.org/docs/stable/torchvision/datasets.html#torchvision.datasets.CocoDetection">docs</a> for <code>CocoDetection</code>:</p>
<blockquote>
<ul>
<li><strong>transform</strong>  ( <em>callable</em> <em>,</em>  <em>optional</em> ) – A function/transform that takes in an PIL image and returns a transformed version. E.g,  <code>transforms.ToTensor</code></li>
<li><strong>target_transform</strong>  ( <em>callable</em> <em>,</em>  <em>optional</em> ) – A function/transform that takes in the target and transforms it.</li>
<li><strong>transforms</strong>  ( <em>callable</em> <em>,</em>  <em>optional</em> ) – A function/transform that takes input sample and its target as entry and returns a transformed version.</li>
</ul>
</blockquote>
<p>You could either pass the <code>transform</code> and <code>target_transform</code> separately or use a <code>transforms</code> function, which accepts the image and target.</p>

username: reallyclean-sauce
cooked: <p>I don’t get it. So, is there something wrong to what I did? I read other codes and they also created a list for transforms too. And why would the number of positional arguments I passed be 3, when it is clearly two? Do you think maybe it is just not maintained to the latest version?</p>

username: ptrblck
cooked: <p>In other code snippets the transformation was most likely only applied to the data, so a single <code>transform</code> argument was passed.<br>
For the <code>CocoDetection</code> dataset, you are transforming the data and target, so you should either pass the transformations separately or provide a transformation function, which accepts the data and the target as arguments.</p>
<aside class="quote no-group" data-username="reallyclean-sauce" data-post="3" data-topic="82147">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/reallyclean-sauce/48/12132_2.png" class="avatar"> reallyclean-sauce:</div>
<blockquote>
<p>And why would the number of positional arguments I passed be 3, when it is clearly two?</p>
</blockquote>
</aside>
<p>The <code>self</code> argument is also counted in Python.</p>
<aside class="quote no-group" data-username="reallyclean-sauce" data-post="3" data-topic="82147">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/reallyclean-sauce/48/12132_2.png" class="avatar"> reallyclean-sauce:</div>
<blockquote>
<p>Do you think maybe it is just not maintained to the latest version?</p>
</blockquote>
</aside>
<p>No, I don’t think so.</p>
<p>EDIT: Note that these arguments are optional, so you can also pass your transformation as <code>transform=get_transform()</code> only to skip the target transformation.</p>

username: reallyclean-sauce
cooked: <p>Ohh right, the self is also counted as an argument. Thanks for the reminder!<br>
Anyway, I just solved my problem. It appears that I am using the wrong <code>CocoDetection</code> Dataset class. I orginally used:</p>
<pre><code class="lang-auto">import torchvision.datasets as dset
# and then
coco_test = dset.CocoDetection(root = root_dir,
                                annFile = test_json,
                                transforms=get_transform())
</code></pre>
<p>When what I should’ve used is:</p>
<pre><code class="lang-auto">from torchvision.datasets.coco import CocoDetection
# and then
coco_test = CocoDetection(root = root_dir,
                                annFile = test_json,
                                transforms=get_transform())
</code></pre>
<p>And it worked!</p>
<p>So, it appears that there are two <code>CocoDetection</code> classes. One in <code>torchvision.datasets</code>, another in <code>torchvision.datasets.coco</code>. Should I inform them about this duplicate code? And if so, how should I inform them about this?</p>

username: ptrblck
cooked: <p>Both classes are pointing to the same implementation and I’m wondering how you solved the issue, but it’s good to hear it’s working. <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=9" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>

username: reallyclean-sauce
cooked: <p>I think it may have something to do with the first implementation inheriting the class <code>VisionDataset</code>. While on the second one, the implementation inherits the <code>data.Datasets</code>.</p>