Iter(testloader).next() samples 3 images instead of one

danielmanu93: <p>Hi All I have a function which get the value from a scale and feeds a randomly sampled image using <code>iter(testloader).next()</code> to a network to perform testing. For the testing results, I print the testing time. Even though the <code>iter(testloader).next()</code> command is known to sample one image at random, the results after testing shows three testing times instead of just one as can be seen below. I am really lost as to why that’s happening, and can’t tell if three images are sampled which makes the code prints 3 results instead of 1 after testing. Below is my sample code for review:</p>
<h2>
<a name="testing-time-report-after-testing-1" class="anchor" href="#testing-time-report-after-testing-1"></a>Testing time report after testing</h2>
<pre><code class="lang-auto">Testing complete in  0m 2s
Testing complete in  0m 3s
Testing complete in  0m 3s
</code></pre>
<h2>
<a name="below-is-my-sample-code-2" class="anchor" href="#below-is-my-sample-code-2"></a>Below is my sample code</h2>
<pre><code class="lang-auto">test= data_utils.TensorDataset(torch.from_numpy(test_set),torch.from_numpy(label_set))
test_loader = data_utils.DataLoader(test,batch_size=TestBatchSize,shuffle=True)

def noise_scale(scale_value=0):
    since = time.time()
    images, labels = iter(test_loader).next()
    images = images.view(1, 10, 200, 301)
    labels = labels.view(1, 1, 201, 301) 
    if (scale.get()) == 0:
        for i in range(1):
            net.eval()
            outputs  = net(images,labels)
            for k in range(1):
                Img = images.view(10, 200, 301)
                Img = Img[1,:,:].numpy()

     elif (scale.get()) == 10:
        for i in range(1):
            net.eval()
            outputs  = net(images,labels)
            for k in range(1):
                Img = images.view(10, 200, 301)
                Img = Img[1,:,:].numpy()

     elif (scale.get()) == 20:
        for i in range(1):
            net.eval()
            outputs  = net(images,labels)
            for k in range(1):
                Img = images.view(10, 200, 301)
                Img = Img[1,:,:].numpy()
 
    time_elapsed = time.time() - since  
    print('Testing complete in  {:.0f}m {:.0f}s' .format(time_elapsed // 60, time_elapsed % 60))  
## This above line prints three times as shown above instead of just one.

## Scale ##
var3 = StringVar()
scale = tk.Scale(root, variable=var3, orient='horizontal', bg = "gray80", bd=1, from_=0, to=20, tickinterval=10, resolution=10, length=200, command=noise_scale)
</code></pre>

ptrblck: <aside class="quote no-group" data-username="danielmanu93" data-post="1" data-topic="152635">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/d/a88e4f/48.png" class="avatar"> danielmanu93:</div>
<blockquote>
<p>Even though the <code>iter(testloader).next()</code> command is known to sample one image at random</p>
</blockquote>
</aside>
<p>This code snippet would return one batch of samples, so depending on the used <code>batch_size</code> it could return more than a single sample.</p>

danielmanu93: <p><a class="mention" href="/u/ptrblck">@ptrblck</a> , the test batch size is just one, so it should have return only however getting results for three.</p>

ptrblck: <p>I don’t know what might be causing it and cannot reproduce the issue:</p>
<pre><code class="lang-python">dataset = TensorDataset(torch.randn(10, 10), torch.randn(10))

loader = DataLoader(dataset, batch_size=1)
a, b = iter(loader).next()
print(a.shape, b.shape)
# torch.Size([1, 10]) torch.Size([1])

loader = DataLoader(dataset, batch_size=3)
a, b = iter(loader).next()
print(a.shape, b.shape)
# torch.Size([3, 10]) torch.Size([3])

loader = DataLoader(dataset, batch_size=5)
a, b = iter(loader).next()
print(a.shape, b.shape)
# torch.Size([5, 10]) torch.Size([5])
</code></pre>

danielmanu93: <p>Is there  way to select only the first image and label after using the <code>iter(loader).next</code>? I have used <code>iter(leader).next()[0][0]</code> but getting <code>too many values to unpack (expected 2)</code> error.</p>

ptrblck: <p>I would recommend to check why 3 values are returned when the <code>batch_size</code> is set to <code>1</code> as this seems to be an error.<br>
Once this is done, check how many values are returned and which shape they have to index them if needed (which should not be needed after fixing the first issue).</p>

danielmanu93: <p><a class="mention" href="/u/ptrblck">@ptrblck</a> , can you have a look at the extended code in my post to see if I am missing something. The scale levels are three (0,10, 20) and I am using the <code>if</code> and <code>elif</code> conditional statements to get the state of the scale and execute the code under. I am unsure if the <code>if</code> and <code>elif</code> statements are causing this issue.</p>

ptrblck: <p>I don’t fully understand the code as I don’t know how <code>noise_scale</code> is executed in <code>tk.Scale</code>.<br>
The conditions also seem to be irrelevant as the <code>images, labels = iter(test_loader).next()</code> line is executed before and should already yield the single sample given the <code>batch_size</code> is set to 1.</p>

danielmanu93: <p>Okay, so the <code>noise_scale</code> is the function command that controls the scale. There are 3 levels in the scale (0, 10, 20). If current scale value is set to 0, the first <code>if</code> statement is executed, if the current scale value is set to 10 then the middle <code>elif</code> is executed and finally if the scale is set to the 20, then the last <code>elif</code> is  executed. Do you get it now?</p>

ptrblck: <p>I understand the code logic of the if conditions but don’t see how they can influence the return values of the <code>DataLoader</code> in any way.<br>
Rip out all unneeded code and make sure that <code>iter(loader).next()</code> returns the expected shape first.</p>