Concepts / Loading Batches with Data Loaders

Loading Batches with Data Loaders

The same accuracy function is applied to a training, a validation, and a test loader, producing three separate results that should be compared with care.

  • Programming

Why One Accuracy Number Is Not Enough

Before a model can be fine-tuned for classification, you need a reliable way to answer a simple question: how often is the model right? The script examined in this article answers that question for three separate datasets, named here as training, validation, and test. The script is small, but it rewards careful reading, because almost every number it prints is the result of a chain of steps you can follow line by line.

The working approach is to run one accuracy function on three different data loaders and print the three results side by side. Read the script first and predict what each printed line will tell you. Then trace how the values are produced. The most useful debugging skill for this kind of script is knowing exactly where to look when a number seems wrong, and that skill is what this article builds.

Three Loaders, One Function

The source names three data loaders: train_loader, val_loader, and test_loader. Each one supplies batches of examples from a different dataset. Accuracy can be calculated for each of them, and this is the central idea of the section: the same model can be evaluated on training, validation, and test data, producing a separate accuracy for each.

The same function, calc_accuracy_loader, is called three times. Each call receives a different loader, but the same model and the same device. The argument num_batches=10 is passed in every call, so each calculation uses the same batch limit. The loader is therefore the main input that distinguishes the three results. If the model, device, and batch limit are held constant, a difference between the three printed numbers can be traced back to the data each loader supplies.

Definition

A data loader is the object that supplies batches of examples from a dataset to the code that evaluates or trains a model. In this script, each of the three loaders supplies batches from one dataset.

train_loadercalc_accuracy_loadersame model, device,num_batches=10training accuracyval_loadercalc_accuracy_loadersame model, device,num_batches=10validation accuracytest_loadercalc_accuracy_loadersame model, device,num_batches=10test accuracyloaderfractionloaderfractionloaderfraction
How do the three loaders feed the same accuracy function, and how do their three results relate to one another?

How a Data Loader Groups Examples into Batches

A data loader does not hand the evaluation code an entire dataset at once. It supplies the dataset's examples in groups called batches. Each call to the accuracy function consumes batches from the loader it receives, which means the loader determines both which examples are looked at and how many of them are looked at in one pass.

The source does not explain what calc_accuracy_loader does internally, so this article does not describe its internals. What the script makes clear is its interface: the function takes a loader, a model, a device, and a batch count, and it returns a value that the script later multiplies by 100 for display. Everything beyond that interface should be treated as something to verify in the source code rather than assumed.

Reading the Call Line by Line

The three calls share a common shape. The first argument changes from call to call, while the model, the device, and the batch limit stay fixed. The pattern below is an illustrative rewrite of that shape. The variable names on the left are placeholders chosen for this article, because the source identifies only the three loaders and the arguments, not the exact result variable names.

python
Notes on the code
  • The first argument is the only one that differs between the three lines.
  • The model and device are passed unchanged, so all three calls run on the same model and device.
  • num_batches=10 is the same in every call, so every calculation uses the same batch limit.
  • Each assignment stores one returned value. Those three variables are the only things that keep results.
Worked example

Tracing where the test accuracy value comes from

A learner wants to know exactly which inputs produced the variable test_accuracy in the three-call pattern above, and which inputs would have to change to get a different result.

  1. 1
    Find the assignment

    The line that creates test_accuracy is the third call, which passes test_loader as its first argument.

  2. 2
    Confirm the shared arguments

    The same model, device, and num_batches=10 are passed as in the other two calls, so they are not what makes this result different.

  3. 3
    Identify the distinguishing input

    Because the loader is the only argument that changes between calls, the test loader is the main reason test_accuracy differs from train_accuracy and val_accuracy.

  4. 4
    Follow the returned value forward

    The function returns a fraction, and that fraction is what is later multiplied by 100 and formatted for display.

Result

The value stored in test_accuracy comes from the test loader plus the shared model, device, and batch limit. Changing only the loader in that call changes the result, and the printed percentage is derived from the returned fraction.

train_loaderval_loadertest_loadercalc_accuracy_loaderreturned fractionprinted percentagemodeldevicenum_batches=10loaderloaderloadersharedsharedshared limitreturnstimes 100, formatted
Where does each argument originate in the script, and where does it end up inside calc_accuracy_loader?

What num_batches Limits

The source describes num_batches as a batch limit that each calculation uses. Read literally, a limit of 10 means each call works with at most ten batches from its loader. A smaller number would mean fewer batches are evaluated, and the reported accuracy would be based on a smaller slice of that loader's data. The loop below shows how a limit of five would progress through a loader, as a reasoning exercise rather than a description of the function's internals.

startbatch 0batch 1batch 2batch 3batch 4stop after 5 batchesnextnextnextnextlimit reached
If num_batches is set to 5 on a loader with 100 batches, which batches are processed, and when does the loop stop?

What do you think happens?

If num_batches changed from 10 to 5 in all three calls, what would change in the script's arguments, and what would stay the same?

Reveal answer
Answer:

Only the value passed as num_batches would change, from 10 to 5. The three loaders, the model, and the device would stay the same, and every call would still receive the same batch limit.

The script passes num_batches=10 in every call, so changing it in the three calls means changing one shared argument. Because each calculation uses the same limit, the three results would all be based on fewer batches, but the loader is still the input that separates them.

Where a Printed Percentage Comes From

The function returns a fraction, not a percentage. The f-strings in the print lines multiply that fraction by 100 and format it to two decimal places before printing. Every printed percentage can therefore be reconstructed by hand from one variable and one format string.

python
Output (expected)
Training accuracy: 87.50%
Notes on the code
  • train_accuracy holds the fraction returned by the function, for example 0.875.
  • *100 scales the fraction up to a percentage.
  • :.2f formats the result to two decimal places.
  • The output 87.50% uses a made-up return value to show the formatting path. It is not a real result for any model.
pass loader intofunctionfunction returnsfractionassign to variablemultiply by 100format to twodecimalsprinted percentagebatches evaluatedfractionvariablepercent valuedisplay
What sequence of steps turns batches of predictions into the final printed percentage, and which step could produce an unexpected value?

Mistakes That Make Accuracy Look Wrong

  • Common mistake

    Assuming a surprising percentage came from the function itself rather than from the loader passed in

    What it looks like

    A test accuracy looks much higher than expected, and the learner starts questioning the internals of calc_accuracy_loader.

    Why it fails

    The source identifies the loader as the main input that distinguishes the three results. Checking the call is faster and does not require knowing the internals.

    Do this instead

    First confirm which loader went into the call that produced the variable.

  • Common mistake

    Reading a printed value as the raw return value

    What it looks like

    A learner expects a line to show 0.875 but sees 87.50%, and concludes the script is broken.

    Why it fails

    The function returns a fraction, and the f-string multiplies it by 100 and formats it to two decimals before printing.

    Do this instead

    Check the multiplication and formatting in the matching print line.

  • Common mistake

    Changing one call's arguments and forgetting the others

    What it looks like

    A learner edits num_batches in only one of the three calls and then compares the three numbers as if they were produced under identical conditions.

    Why it fails

    The source says the same model, device, and num_batches=10 are shared across calls. A mismatched batch limit would make the comparison unfair.

    Do this instead

    Confirm that the arguments held constant across calls are the ones you intended.

  • Common mistake

    Treating the three printed numbers as one combined score

Comparing Training, Validation, and Test Results

Because the three numbers come from three different loaders under shared conditions, they are meant to be compared, but with care. A higher training number than validation number, for example, tells you about the two datasets as evaluated by the same model under the same batch limit. The source treats the three results as separate values to be compared thoughtfully, rather than as a single score that can be read at a glance.

MEDIUM

Suppose you run the three-call script and get a training value that is very different from the validation value. Before drawing any conclusion, list the three things you would check: the loader passed into each call, the arguments held constant across calls, and the formatting in each print line. Which of those could explain the difference without any change to the model?

Hints
  • Start with the only argument that differs between the calls.
  • Ask whether the batch limit was the same in every call.
  • Remember that the printed value is the returned fraction multiplied by 100.

Key Takeaways

  • The same accuracy function is run on a training, a validation, and a test loader, producing three separate results that should be compared with care.
  • The loader is the main input that distinguishes the three calls, because the model, device, and num_batches=10 are passed unchanged to each.
  • The function returns a fraction, which the print lines multiply by 100 and format to two decimal places before showing a percentage.
  • When a printed value looks wrong, check the loader passed in, the arguments held constant across calls, and the multiplication and formatting, in that order.

Related concepts

More concepts starting with L