Error showing - pic should be 2/3 dimensional. Got 1 dimensions

shravan: <p>Hi All,</p>
<p>I am trying to solve a binary image classification problem. I am trying to implement feed forward neural network use.</p>
<p>I am getting a problem - like this.</p>
<p>File “/opt/conda/lib/python3.7/site-packages/torchvision/transforms/functional.py”, line 104, in to_pil_image<br>
raise ValueError(‘pic should be 2/3 dimensional. Got {} dimensions.’.format(pic.ndimension()))<br>
ValueError: pic should be 2/3 dimensional. Got 1 dimensions.</p>
<p>Here is my code.</p>
<p>Please let me know where is the problem . <a href="https://github.com/shravankoninti/AV/blob/master/AV_Janata_Hack_ComputerVision/Pytorch_use_AV_Hack.ipynb" rel="nofollow noopener">CODE HERE</a></p>
<p>It would be great if someone points the problem at my code location.</p>
<p>I have just joined this forum. Pardon me if this is not the right place to ask these questions.(I’m Beginner in Pytorch use)</p>
<p>Regards<br>
Shravan</p>

ptrblck: <p>In your datasets you are flattening the tensors via:</p>
<pre><code class="lang-python">data = data.view(1, -1)
</code></pre>
<p>which seems wrong, as the expected shape of a color image tensor would be <code>[3, height, width]</code>.<br>
Could you check the shape of <code>X_train</code> etc. before passing them to the dataset and make sure the image shape is correct?</p>

shravan: <p>Thanks very much for the reply.</p>
<p>the input size of each image is (224, 224, 3).</p>
<p>I tried changing the code to----  data = data.view(-1, 224, 224, 3)</p>
<p>I get the following error.</p>
<p>RuntimeError: size mismatch, m1: [32 x 2016], m2: [150528 x 1536] at /opt/conda/conda-bld/pytorch_1587428398394/work/aten/src/THC/generic/THCTensorMathBlas.cu:283</p>
<p>Initially it was giving me this error . Hence to abovid the above error  i changed the line – data = data.view(1, -1).<br>
But then it gives other error.</p>
<p>You think we can resolve this?</p>
<p>Thanks &amp; Regards<br>
Shravan</p>

harsha_g: <p>Apply <code>transform</code> first and then flatten it using <code>view</code>.</p>

shravan: <p>I already did this like</p>
<p>transform = transforms.Compose(<br>
[transforms.ToPILImage(), transforms.ToTensor()])</p>
<p>and  did this</p>
<p>class DatasetProcessing(Dataset):</p>
<pre><code>#initialise the class variables - transform, data, target
def __init__(self, data, target, transform=None): 
    self.transform = transform     
    data = data.view(1, -1)

    self.data =  data
    # converting target to torch.LongTensor dtype
    self.target = target 

#retrieve the X and y index value and return it
def __getitem__(self, index):   
    return (self.transform(self.data[index]), self.target[index])

#returns the length of the data
def __len__(self): 
    return len(list(self.data))</code></pre>

harsha_g: <p>Try this. Please note that, in your code, you are applying <code>transform</code> after <code>view</code>.</p>
<pre><code class="lang-auto">#initialise the class variables - transform, data, target
def __init__(self, data, target, transform=None): 
    data = transform(data)
    self.data =  data.view(1, -1)
    # converting target to torch.LongTensor dtype
    self.target = target 

#retrieve the X and y index value and return it
def __getitem__(self, index):   
    return (self.data[index], self.target[index])

#returns the length of the data
def __len__(self): 
    return len(list(self.data))
</code></pre>

harsha_g: <p><code>transform</code> is only instantiated and is not applied until you explicitly apply it to an image, which you are in the <code>__getitem__</code> method. But note that you are flattening your data/image in the <code>__init__</code> method prior to applying your transform. I hope this clarifies my earlier comment on- <code>transform</code> after <code>view</code>.</p>

shravan: <p>Thanks for the reply and clear explanation.<br>
I just got this error again<br>
" [ValueError: pic should be 2/3 dimensional. Got 4 dimensions]".</p>
<p>I believe i am missing a small trick to convert image shape to the right format.  Any idea?</p>

harsha_g: <p>From what I understand, <code>torchvision.transforms</code> only work with one image at a time and not a batch of images. I guess this should do.</p>
<pre><code class="lang-auto">#initialise the class variables - transform, data, target
def __init__(self, data, target, transform=None): 
    self.transform = transform     
    self.data =  data
    # converting target to torch.LongTensor dtype
    self.target = target 

#retrieve the X and y index value and return it
def __getitem__(self, index):   
    return (self.transform(self.data[index]).view(1, -1), self.target[index])

#returns the length of the data
def __len__(self): 
    return len(list(self.data))
</code></pre>

shravan: <p>No it is not working with the above code.</p>
<p>RuntimeError: size mismatch, m1: [32 x 2016], m2: [150528 x 1536] at /opt/conda/conda-bld/pytorch_1587428190859/work/aten/src/TH/generic/THTensorMath.cpp:41</p>

shravan: <p><a class="mention" href="/u/harsha_g">@harsha_g</a></p>
<p>I changed class like this to pass image into a transform function.</p>
<p>class DatasetProcessing(Dataset):</p>
<pre><code>#initialise the class variables - transform, data, target
def __init__(self, data, target, transform=None): 
     #self.transform = transform 
    print("Before transformation")
    print(data.size())

    print(data[0].size())

    outputs = []
    datalen = data.size()[0]
    for i in range(datalen):          
        tensor = transform(data[i,:,:,:])   #transform 
        outputs.append(tensor)
    result = torch.cat(outputs, dim=1)  #shape (64, 32*in_channels, 224, 224)        

    print("After transformation")
    print(result.size())
    data = result
    self.data =  data.view(1, -1)
    # converting target to torch.LongTensor dtype
    self.target = target 

#retrieve the X and y index value and return it
def __getitem__(self, index):        
    return (self.data[index], self.target[index])
    
     return (self.transform(self.data[index]), self.target[index])

#returns the length of the data
def __len__(self): 
    return len(list(self.data))
</code></pre>
<ul>
<li>OUTPUT from prints.</li>
</ul>
<p>Before transformation<br>
torch.Size([1316, 224, 224, 3])<br>
torch.Size([224, 224, 3])<br>
After transformation<br>
torch.Size([3, 294784, 3])</p>
<p>Errror Message:</p>
<p>RuntimeError: size mismatch, m1: [3 x 221760], m2: [150528 x 1536] at /opt/conda/conda-bld/pytorch_1587428190859/work/aten/src/TH/generic/THTensorMath.cpp:41</p>
<p>Output from validation output: (Actually the output has to be showing 32 batches with 32 labels but am not sure why is it throwing belwo output<br>
**<strong><strong><strong><strong><strong>IMAGES</strong></strong></strong></strong></strong><br>
torch.Size([3, 73920, 3])<br>
**<strong><strong><strong><strong><strong>LABEL</strong></strong></strong></strong></strong><br>
tensor([0., 0., 0.])</p>

harsha_g: <p>Hi, it was really difficult to figure out the issue without the full stack trace. However, I just took a look at your code and it’s failing in the <code>evaluate</code> function all the way at the bottom. The size of your labels look fine after passing through the <code>DataLoader</code>. It’s failing at <code>self(images)</code>. You might want to revisit your <code>EmergencyVehicleDetectionModel</code> class and ensure the size of the inputs and targets match as intended.</p>

shravan: <p>THanks for the reply. So do you think whatever the code I wrote earlier was good (as you said my github code looks fine only place I need to see is <strong>evaluate</strong>).<br>
So what about the modified code I wrote above ? To which code I need to stick and debug?The above modified code or my github code!</p>

harsha_g: <p><a class="mention" href="/u/shravan">@shravan</a> I took another pass at your code and figured out some errors but trying to correct one led to another and so on and I couldn’t take it further in the interest of time (sorry about that). But, I’ll try to help you start so you know what exactly is the issue. One, the input image which is <code>224x224x3</code> is transformed using <code>ToPILImage</code> and further flattened using <code>view</code>. Try to understand the shape of the output (<code>3x224x3 = 2016</code>). Later on, when you define your <code>EmergencyVehicleDetectionModel</code> class you hard-coded an input of size <code>224x224x3 = 150528</code>. I hope you can see what’s happening here. You are feeding a tensor of shape <code>2016</code> to a network expecting a tensor of shape <code>150528</code>. I hope this will help you understand where to look in your code and how to go about it. The other follow-up issues are not really difficult to address and some intuitive understanding of how various NN layers and also loss functions work and what shapes are expected will come in very handy. I urge you to spend more time going through <code>PyTorch</code> documentation for every function you use. I wish you the best.</p>

shravan: <p>Thanks . This is really great and so kind of you for all the follow up answers.</p>