title: How do I load up an image and convert it to a proper tensor for PyTorch?
body: <p>I'm trying to custom load some image files (JPG files) with some labels and feed them into a convolutional neural network (CNN) in PyTorch following the example <a href="https://leonardoaraujosantos.gitbooks.io/artificial-inteligence/content/pytorch/dataloader-and-datasets.html" rel="noreferrer">here</a>. However, there still seem to be <a href="https://github.com/pytorch/tutorials/issues/7" rel="noreferrer">no decent end-to-end tutorials</a>. The problem that I am seeing is the following.</p>
  
  <pre class="lang-none prettyprint-override"><code>RuntimeError: thnn_conv2d_forward is not implemented for type
  torch.ByteTensor
  </code></pre>
  
  <p>My <code>Dataset</code> looks like the following.</p>
  
  <pre><code>class ImageData(Dataset):
      def __init__(self, width=256, height=256, transform=None):
          self.width = width
          self.height = height
          self.transform = transform
          y, x = get_images() #y is a list of labels, x is a list of file paths
          self.y = y
          self.x = x
  
      def __getitem__(self, index):
          img = Image.open(self.x[index]) # use pillow to open a file
          img = img.resize((self.width, self.height)) # resize the file to 256x256
          img = img.convert('RGB') #convert image to RGB channel
          if self.transform is not None:
              img = self.transform(img)
  
          img = np.asarray(img).transpose(-1, 0, 1) # we have to change the dimensions from width x height x channel (WHC) to channel x width x height (CWH)
          img = torch.from_numpy(np.asarray(img)) # create the image tensor
          label = torch.from_numpy(np.asarray(self.y[index]).reshape([1, 1])) # create the label tensor
          return img, label
  
      def __len__(self):
          return len(self.x)
  </code></pre>
  
  <p>The CNN is taken from <a href="https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html" rel="noreferrer">here</a> and is modified to handle NCWH (batch x channel x width x height) as follows.</p>
  
  <pre><code>class Net(nn.Module):
      def __init__(self):
          super(Net, self).__init__()
          self.conv1 = nn.Conv2d(3, 256, 256)
          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 = x.view(-1, 16 * 5 * 5)
          x = F.relu(self.fc1(x))
          x = F.relu(self.fc2(x))
          x = self.fc3(x)
          return x
  </code></pre>
  
  <p>The learning loop is also taken from the <a href="https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html" rel="noreferrer">same tutorial</a> and looks like the following.</p>
  
  <pre><code>for epoch in range(2):  # loop over the dataset multiple times
  
      running_loss = 0.0
      for i, data in enumerate(dataloader, 0):
          # get the inputs
          inputs, labels = data
  
          # zero the parameter gradients
          optimizer.zero_grad()
  
          # forward + backward + optimize
          outputs = net(inputs)
          loss = criterion(outputs, labels)
          loss.backward()
          optimizer.step()
  
          # print statistics
          running_loss += loss.item()
          if i % 2000 == 1999:    # print every 2000 mini-batches
              print('[%d, %5d] loss: %.3f' %
                    (epoch + 1, i + 1, running_loss / 2000))
              running_loss = 0.0
  
  print('Finished Training')
  </code></pre>
  
  <p>However, the <code>RuntimeError</code> mentioned above is thrown. Any ideas on what I am doing wrong?</p>
  
  <p>Additionally, I know that without transposing the image data, it is in the shape of WHC, but the NN model requires it as CWH. The problem is this, if we change from WHC to CWH, then we can no longer simply plot the images if we iterate over the <code>DataLoader</code>.</p>
  
  <pre><code>data = ImageData()
  dataloader = DataLoader(data, batch_size=10, shuffle=True, num_workers=1)
  imgs, labels = next(iter(dataloader))
  plt.imshow(imgs.numpy()[0,:,:,:])
  plt.show()
  </code></pre>
  
  <p>Attempting to do will throw the following error.</p>
  
  <pre class="lang-none prettyprint-override"><code>TypeError: Invalid dimensions for image data
  </code></pre>
  
  <p>To me, that Pillow gives you WHC and you can use that to plot, but the PyTorch CNN wants CWH to process, is a nuisance. Any idea on how to consistently or easily not do so many transforms but be able to plot and feed the data into the CNN? Or is this mismatch of WHC vs CWH just something we have to live with?</p>
  
  <p>Without transposing the image, when feeding it to the CNN, the following error is thrown.</p>
  
  <pre class="lang-none prettyprint-override"><code>RuntimeError: Given groups=1, weight[256, 3, 256, 256], so expected
  input[10, 256, 256, 3] to have 3 channels, but got 256 channels
  </code></pre>
  
  <p>instead.</p>