"IndexError: too many indices for tensor of dimension 3"

aizyuval: <p>When Loading an RGB image o a custom dataset class:</p>
<p>My problem is that: <code>imag = Image.fromarray(imag)</code> takes an original numpy image,<br>
and drops from it a dimesion AND transposes the H and W.<br>
Iv’e tried writing: <code>        imag = np.transpose(imag, (1,0,2))</code> , and it works just fine,<br>
but it still drops the third dimention of 3 - fro RGB.</p>
<p>Thats my code:</p>
<pre><code class="lang-auto">import pandas as pd
import numpy as np
import os
from skimage import io
from torch.utils.data import Dataset
from PIL import Image

class projectdata(Dataset):

    def __init__(self, csv_file, root_dir, transform=None):
        self.landmarks_frame = pd.read_csv(csv_file)
        self.root_dir = root_dir
        self.transform = transform

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

    def __getitem__(self, idx):
        img_name = os.path.join(self.root_dir, self.landmarks_frame.iloc[idx, 0])
        imag = io.imread(img_name) 
        landmarks = self.landmarks_frame.iloc[idx, 1:]
        landmarks = np.array([landmarks])
        landmarks = landmarks.astype('float').reshape(-1, 2)
        imag = np.transpose(imag, (1,0,2))
        imag = Image.fromarray(imag) 
        sample = {'image': imag, 'landmarks': landmarks}
        
        if self.transform:
            sample = self.transform(sample['image'])
        
        img = sample['image'] 
        label = sample['landmarks']
        return img, label        

</code></pre>
<p>The CNN Net expects tensor of size: [1,3,175,175]<br>
The image itself (before it drops a dimension) is 3 dimensions, and im transforming it to be 4 dimensions.</p>
<pre><code class="lang-auto">from projectd import projectdata #custom dataset class file

transformer = transforms.Compose([
    transforms.Resize(1,3,175,175),
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))

trainset  = projectdata(csv_file = 'face_landmarks.csv', root_dir = 'faces',transform=transformer)
train_loader = DataLoader(trainset, batch_size=batchsize, shuffle=True, num_workers=0)
])

for epochs in range(2):
  running_loss = 0.0
  **for i,data in enumerate(train_loader,0):**
</code></pre>

azhanmohammed: <aside class="quote no-group" data-username="aizyuval" data-post="1" data-topic="159389">
<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/aizyuval/48/53728_2.png" class="avatar"> aizyuval:</div>
<blockquote>
<pre><code class="lang-auto">transformer = transforms.Compose([
    transforms.Resize(1,3,175,175),
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))

trainset  = projectdata(csv_file = 'face_landmarks.csv', root_dir = 'faces',transform=transformer)
train_loader = DataLoader(trainset, batch_size=batchsize, shuffle=True, num_workers=0)
])
</code></pre>
</blockquote>
</aside>
<p>Change your resize transform to:</p>
<pre><code class="lang-auto">transformer = transforms.Compose([
    transforms.Resize(175,175),
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))

trainset  = projectdata(csv_file = 'face_landmarks.csv', root_dir = 'faces',transform=transformer)
train_loader = DataLoader(trainset, batch_size=batchsize, shuffle=True, num_workers=0)
])
</code></pre>
<p>Also why aren’t you using PIL directly to load the image? That should work as well. This way you won’t have to transpose the dimensions of the image. Try changing the <code>__getitem__()</code> function to:</p>
<pre><code class="lang-auto"> def __getitem__(self, idx):
        img_name = os.path.join(self.root_dir, self.landmarks_frame.iloc[idx, 0])
        imag = Image.open(img_name)
        landmarks = self.landmarks_frame.iloc[idx, 1:]
        landmarks = np.array([landmarks])
        landmarks = landmarks.astype('float').reshape(-1, 2)
        sample = {'image': imag, 'landmarks': landmarks}
        
        if self.transform:
            sample = self.transform(sample['image'])
        
        img = sample['image'] 
        label = sample['landmarks']
        return img, label
</code></pre>
<p>The modified <code>__getitem__()</code> function should work with the changed transforms function I have mentioned.</p>