d2l-ai/d2l-zh · error · AssertionError
train_acc <= 1 and train_acc > 0.7
Error message
train_acc <= 1 and train_acc > 0.7
What it means
An AssertionError in d2l.tensorflow.train_ch3 requiring final training accuracy to lie in (0.7, 1]. It is a post-training sanity check that the softmax-regression model actually learned Fashion-MNIST to a reasonable degree. Values <= 0.7 mean the model undertrained or diverged; values > 1 mean the metric computation itself is broken.
Source
Thrown at d2l/tensorflow.py:320
for x, y, fmt in zip(self.X, self.Y, self.fmts):
self.axes[0].plot(x, y, fmt)
self.config_axes()
display.display(self.fig)
display.clear_output(wait=True)
def train_ch3(net, train_iter, test_iter, loss, num_epochs, updater):
"""训练模型(定义见第3章)
Defined in :numref:`sec_softmax_scratch`"""
animator = Animator(xlabel='epoch', xlim=[1, num_epochs], ylim=[0.3, 0.9],
legend=['train loss', 'train acc', 'test acc'])
for epoch in range(num_epochs):
train_metrics = train_epoch_ch3(net, train_iter, loss, updater)
test_acc = evaluate_accuracy(net, test_iter)
animator.add(epoch + 1, train_metrics + (test_acc,))
train_loss, train_acc = train_metrics
assert train_loss < 0.5, train_loss
assert train_acc <= 1 and train_acc > 0.7, train_acc
assert test_acc <= 1 and test_acc > 0.7, test_acc
class Updater():
"""用小批量随机梯度下降法更新参数
Defined in :numref:`sec_softmax_scratch`"""
def __init__(self, params, lr):
self.params = params
self.lr = lr
def __call__(self, batch_size, grads):
d2l.sgd(self.params, grads, self.lr, batch_size)
def predict_ch3(net, test_iter, n=6):
"""预测标签(定义见第3章)
Defined in :numref:`sec_softmax_scratch`"""
for X, y in test_iter:View on GitHub (pinned to e6b18ccea7)
Solutions
- Restore the book's hyperparameters (lr=0.1, batch_size=256, num_epochs=10) and rerun.
- Check train_epoch_ch3's accuracy accumulator: metric.add(y == argmax(y_hat), y.numel()) style bookkeeping must sum counts and divide by totals exactly once.
- Confirm updater.apply_gradients is actually called each batch; a broken update loop yields ~0.1 accuracy (chance level).
- Read the Animator curves: if accuracy is still climbing at the final epoch, increase num_epochs.
Example fix
# before train_ch3(net, train_iter, test_iter, loss, 1, updater) # undertrained -> acc <= 0.7 # after train_ch3(net, train_iter, test_iter, loss, 10, updater)
Defensive patterns
Strategy: validation
Validate before calling
final_loss, final_acc = train_epoch_ch3(net, train_iter, loss, updater)
if not (0.7 < final_acc <= 1.0):
raise ValueError(f'train_acc out of expected (0.7, 1]: {final_acc:.3f}; '
f'check metric accumulator and optimizer wiring') Try / catch
try:
train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)
except AssertionError as e:
raise RuntimeError(f'train_ch3 accuracy check failed ({e}); '
f'likely undertrained or broken updater') from e Prevention
- Train the full 10 epochs before judging accuracy.
- Unit-check your metric Accumulator bookkeeping on one hand-made batch where the answer is known.
- Confirm updater.apply_gradients (TF) actually runs each step; a no-op updater pins accuracy near 0.1.
- Keep accuracy computation as correct_count / total_examples, computed once.
When it happens
Trigger: Same divergence/undertraining causes as the loss assert: too-high lr, wrong updater scaling, too few epochs, untrained net; additionally a custom train_epoch_ch3 whose accuracy accumulation divides by the wrong denominator can push train_acc above 1 and trip the upper bound.
Common situations: Notebook users changing num_epochs from 10 to 1-2; using a custom metric accumulator with a mismatched count; training on a heavily subsampled train_iter; TF2 gradient-tape code that forgets to apply updates.
Related errors
- train_acc <= 1 and train_acc > 0.7
- train_acc <= 1 and train_acc > 0.7
- train_loss < 0.5
- test_acc <= 1 and test_acc > 0.7
- train_acc <= 1 and train_acc > 0.7
AI-assisted analysis of d2l-ai/d2l-zh@e6b18ccea7 (2026-08-14).
Data as JSON: /api/errors/53ba4edc3be185f3.
Report an issue: GitHub.