How do I pass single jpg file as an argument to predicting function in pytorch?

Eminem_Kupiec: <p>Hello,<br>
i have started to work with pytorch in order to use it in my AI classes project. I have been following ‘60 minutes blitz’ tutorial and everything went quite smooth. The only difference is that im using ImageFolder - not the CIFAR10 dataset. Training my model went great but i occured a problem trying to modify an existing code. Previously, i used a folder with given classes(‘glass’,‘metal’,‘paper’,‘plastic’). My predicting function though needs to take an image path as an argument(just because i need to predict 1 single jpg)<br>
<img src="https://discuss.pytorch.org/uploads/default/original/3X/0/7/076f4c36b6aa1ff948793181d1d5e610c4004588.png" alt="image" data-base62-sha1="13LNnT19Oo6IvW1Q2OmGHgafVbi" width="652" height="439"><br>
Can you please give me some tips on how do i convert the given code so it makes usage of img_path and returns the single guess?</p>
<p>I would like to add that i have tried to resolve it myself but during the process i have stumbled on such errors as<br>
’ <a href="https://discuss.pytorch.org/t/typeerror-only-integer-tensors-of-a-single-element-can-be-converted-to-an-index/45641">TypeError: only integer tensors of a single element can be converted to an index</a>’,<br>
’ <a href="https://discuss.pytorch.org/t/indexerror-index-3-is-out-of-bounds-for-dimension-0-with-size-3/39333">IndexError: index 3 is out of bounds for dimension 0 with size 3</a>’</p>
<p>I would really appreciate some help, thank you</p>

Eminem_Kupiec: <p>I have tried to convert the image to PIL and then transform it to tensor:</p>
<pre><code class="lang-auto">def predict(img_path):
    PATH = './wytrenowaned.pth'
    img = Image.open(img_path)
    pil_to_tensor = transforms.ToTensor()(img).unsqueeze_(0)
    print(pil_to_tensor)
    classes = ('glass', 'metal', 'paper', 'plastic')
    # testset = torchvision.datasets.ImageFolder(
    #     root='./resources/smieci', transform=transform)
    # testloader = torch.utils.data.DataLoader(
    #     testset, batch_size=4, shuffle=True, num_workers=2)
    # dataiter = iter(testloader)
    # images, labels = dataiter.next()


# print images
# imshow(torchvision.utils.make_grid(images))
    # print('GroundTruth: ', ' '.join('%5s' %
    #                                 classes[labels[j]] for j in range(4)))
    # print('---')
    # print(images)
    # print('---')
    net.load_state_dict(torch.load(PATH))
    outputs = net(pil_to_tensor)
    _, predicted = torch.max(outputs, 0)
</code></pre>
<p>but it gives me an error</p>
<pre><code class="lang-auto">RuntimeError: Given groups=1, weight of size [6, 3, 5, 5], expected input[1, 1, 299, 299] to have 3 channels, but got 1 channels instead
</code></pre>
<p>any ideas?</p>

Isaac_Kargar: <p>do you add 1 for the first dimension to your input tensor? its shape should be [1, c, h, w]. you can easily read the image and convert it to tensor and feed it into the net by the shape I mentioned.</p>

Eminem_Kupiec: <p>Thanks for the reply!</p>
<p>i made it print out the shape of created tensors everytime function executes in my program and it goes like this:</p>
<pre><code class="lang-auto">torch.Size([1, 3, 299, 299])
torch.Size([1, 3, 299, 299])
torch.Size([1, 3, 299, 299])
torch.Size([1, 3, 299, 299])
torch.Size([1, 3, 299, 299])
torch.Size([1, 1, 299, 299])
Traceback (most recent call last):
  File "main.py", line 11, in &lt;module&gt;
    main()
  File "main.py", line 7, in main
    game.game()
  File "/home/adasko147/Desktop/VSCode/SZISMIECIARKA/game.py", line 111, in game
    adamB.predict(smiec)
  File "/home/adasko147/Desktop/VSCode/SZISMIECIARKA/uczenie_adamB.py", line 117, in predict
    outputs = net(pil_to_tensor)
  File "/home/adasko147/Desktop/VSCode/SZISMIECIARKA/venv/lib/python3.6/site-packages/torch/nn/modules/module.py", line 550, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/adasko147/Desktop/VSCode/SZISMIECIARKA/uczenie_adamB.py", line 44, in forward
    x = self.pool(F.relu(self.conv1(x)))
  File "/home/adasko147/Desktop/VSCode/SZISMIECIARKA/venv/lib/python3.6/site-packages/torch/nn/modules/module.py", line 550, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/adasko147/Desktop/VSCode/SZISMIECIARKA/venv/lib/python3.6/site-packages/torch/nn/modules/conv.py", line 349, in forward
    return self._conv_forward(input, self.weight)
  File "/home/adasko147/Desktop/VSCode/SZISMIECIARKA/venv/lib/python3.6/site-packages/torch/nn/modules/conv.py", line 346, in _conv_forward
    self.padding, self.dilation, self.groups)
RuntimeError: Given groups=1, weight of size [6, 3, 5, 5], expected input[1, 1, 299, 299] to have 3 channels, but got 1 channels instead
</code></pre>
<p>It looks like it has 1 for the first dim and 3 channels too. At some point channel changes from 3 to 1. Maybe it is something with provided images. Im not really sure what to do now</p>

Isaac_Kargar: <p>your input shape is [1, 1, 299, 299]? If so, it should be [1, 3, 299, 299]. You can first test your network with a random tensor to become sure if it works and then use the image with exact shape.</p>

Isaac_Kargar: <p>I’m not sure what are this printed shapes. Can you explain more?</p>

Eminem_Kupiec: <p>Sure,<br>
heres the code of printed tensors</p>
<pre><code class="lang-auto">def predict(img_path):
    PATH = './wytrenowaned.pth'
    img = Image.open(img_path)
    pil_to_tensor = transforms.ToTensor()(img).unsqueeze_(0)
    print(pil_to_tensor.shape)
</code></pre>
<p>And my Net code goes as follows:</p>
<pre><code class="lang-auto">class Net(nn.Module):
    def __init__(self):
        super(Net, self).__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 * 71 * 71, 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(x.size(0), 16 * 71 * 71)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x
</code></pre>
<p>i would like to point out that everything went smoothly while i was training and testing it on datasets created from my ImageFolder</p>

Isaac_Kargar: <p>It seems your model expect an image to have 3 channels but you are feeding an image with one channel. The printed shapes are different. 5 of them have 3 channel and one has 1 channel. So the network should work for first 5 images and not for the 6th image, right?</p>

Eminem_Kupiec: <p>Yes and i think this is the case. Is it caused by some of the images though?It looks like guesses on those 3 channel tensors are just fine until the error with ‘1 channel one’ occures<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/a/6/a6798b050c8efb763a5755f735901ebc1db74ecf.png" data-download-href="https://discuss.pytorch.org/uploads/default/a6798b050c8efb763a5755f735901ebc1db74ecf" title="image"><img src="https://discuss.pytorch.org/uploads/default/original/3X/a/6/a6798b050c8efb763a5755f735901ebc1db74ecf.png" alt="image" data-base62-sha1="nKHFdKWo6ibla2eG6VBl76UC3gj" width="575" height="500" data-dominant-color="091D2D"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">667×579 49.4 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>

Isaac_Kargar: <p>yes. your image is gray. Maybe you can stack your image three times and feed it into your net.</p>

Eminem_Kupiec: <p>Thats exactly what i thought! I will find the path to the gray img since my dataset is rather small and give you some feedback! Thanks Isaac</p>

Eminem_Kupiec: <p>I made it work, the whole project is done. Thanks again!</p>