Mini-batches in a given order

Easy10 min9 hidden tests

A house price model trains on mini-batches: small groups of rows, with one gradient step per group. The data loader has already shuffled the row numbers into order. Write make_batches(X, y, order, batch_size) that walks through order and cuts the rows into batches of batch_size. When the rows do not divide evenly, the last batch is shorter, and no row is dropped.

Change the batch size or the order

batches of batch_size rows, in `order`

order

row 3row 0row 4row 1row 2

batches

batch 0
X [[4, 40], [1, 10]]
y [400, 100]

row 3row 0

batch 1
X [[5, 50], [2, 20]]
y [500, 200]

row 4row 1

batch 2, the rest
X [[3, 30]]
y [300]

row 2

order = [3, 0, 4, 1, 2] in batches of 2: [3, 0], [4, 1], [2]. The last batch holds the 1 row left over, so no row is dropped. Each row’s features and target travel together, at the same position.

3 batches.

Examples

Five rows in batches of 2: the last batch holds one row

make_batches([[1.0, 10.0], [2.0, 20.0], [3.0, 30.0], [4.0, 40.0], [5.0, 50.0]], [100.0, 200.0, 300.0, 400.0, 500.0], [3, 0, 4, 1, 2], 2)

returns [([[4, 40], [1, 10]], [400, 100]), ([[5, 50], [2, 20]], [500, 200]), ([[3, 30]], [300])]

One full batch, in the shuffled order

make_batches([[0.5], [1.5], [2.5]], [1.0, 2.0, 3.0], [2, 1, 0], 3)

returns [([[2.5], [1.5], [0.5]], [3, 2, 1])]

Requirements

  • X is an (n, d) array or list of lists, y holds n targets, order lists every row number from 0 to n - 1 once, and batch_size is 1 or more.
  • Return a list of tuples (X_batch, y_batch) in the order the rows appear in order. X_batch is a 2-D array of shape (b, d), and y_batch is a 1-D array of shape (b,).
  • Every batch has batch_size rows except possibly the last one, which holds the rest. Never return an empty batch.
  • Keep each row's features and its target in the same batch, at the same position.
The idea behind it

Gradient descent on the whole dataset takes one step per pass over the data. Mini-batch gradient descent splits the data into small groups, called mini-batches, and takes one step per group, so the model learns many times per pass. Each full pass is an epoch. Before an epoch, the loader shuffles the row numbers, so batches mix different examples and the gradients do not follow the file's order. Two details trip people up. First, the features and the targets must be indexed with the same row numbers, or the model learns from mismatched labels and the loss stays high for no clear reason. Second, when n is not a multiple of the batch size, the leftover rows form a short last batch. PyTorch's DataLoader keeps it by default and drops it only when you pass drop_last=True.

pythonCtrl+Enter runs
import numpy as np

def make_batches(X, y, order, batch_size):
"""Cut the rows into mini-batches, following a shuffled order.

X: (n, d) array or list of lists of features
y: n targets
order: list of the n row numbers, already shuffled
batch_size: rows per batch, 1 or more
Returns a list of (X_batch, y_batch) tuples, with X_batch of shape
(b, d) and y_batch of shape (b,). Only the last batch may be shorter.
"""
raise NotImplementedError

Stuck? Reveal one rung at a time

Worked solution

Pro includes the solution and walkthrough for every problem, plus the hands-on labs. The first problem of each topic is free.