this is actually a little bit wrong. Its probably a upper bound on the true training error at epoch X because its updating the model during the iterations until it reaches a full epoch (i.e. the model is changing). But I guess its faster though that updating the whole model and then checking the whole train error.