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
Python AssertionError from d2l.mxnet.train_ch3's post-training sanity check: after the final epoch, training accuracy must lie in (0.7, 1]. It guards the book's promise that softmax regression on Fashion-MNIST reaches ~0.8+ train accuracy; a value outside that band means the model underfit, diverged, or the metric computation is off.
Source
Thrown at d2l/mxnet.py:315
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
def predict_ch3(net, test_iter, n=6):
"""预测标签(定义见第3章)
Defined in :numref:`sec_softmax_scratch`"""
for X, y in test_iter:
break
trues = d2l.get_fashion_mnist_labels(y)
preds = d2l.get_fashion_mnist_labels(d2l.argmax(net(X), axis=1))
titles = [true +'\n' + pred for true, pred in zip(trues, preds)]
d2l.show_images(
d2l.reshape(X[0:n], (n, 28, 28)), 1, n, titles=titles[0:n])
def evaluate_loss(net, data_iter, loss):
"""评估给定数据集上模型的损失
Defined in :numref:`sec_model_selection`"""View on GitHub (pinned to e6b18ccea7)
Solutions
- Confirm cross-entropy (d2l.cross_entropy or gluon.loss.SoftmaxCrossEntropyLoss) is the loss, not L2 loss, and labels are int32/float as the framework expects
- Restore num_epochs=10 and lr=0.1 from the book before trusting the assert
- Ensure net.initialize() ran and the params list handed to d2l.sgd is non-empty
- Print per-epoch metrics from the Animator to see whether accuracy rises at all; flat ~0.1 accuracy means the updater is a no-op or outputs are shuffled
Example fix
// before loss = gluon.loss.L2Loss() train_ch3(net, train_iter, test_iter, loss, 10, updater) # train_acc ~0.1 -> AssertionError // after loss = gluon.loss.SoftmaxCrossEntropyLoss() train_ch3(net, train_iter, test_iter, loss, 10, updater) # train_acc ~0.85
Defensive patterns
Strategy: validation
Validate before calling
# verify the metric pipeline before training
X, y = next(iter(train_iter))
y_hat = net(X)
assert y_hat.shape[1] == 10, f'expected 10 logits, got {y_hat.shape}'
assert float(loss(y_hat, y)) > 0, 'loss must be positive'
assert updater is not None and callable(updater) Type guard
def valid_train_setup(net, loss, updater, n_classes=10) -> bool:
return (callable(updater)
and 'SoftmaxCrossEntropy' in type(loss).__name__
and getattr(net, 'output_dim', n_classes) == n_classes) Try / catch
try:
train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)
except AssertionError as e:
value = e.args[0]
if value <= 0.7:
print('underfit: check lr, epochs, and that updater updates params')
raise Prevention
- Confirm cross-entropy loss and int/float label dtype match mxnet expectations
- Pass net.collect_params().values() (non-empty) to d2l.sgd
- Check the Animator each epoch: flat 0.1 accuracy means the updater is a no-op
- Re-initialize the net between experiment runs
When it happens
Trigger: Final train_acc <= 0.7 because of a diverging lr, too few epochs, an updater that never updates (empty params list passed to d2l.sgd), or labels/loss mismatch (e.g. using squared loss on integer labels instead of cross_entropy). train_acc > 1 is essentially impossible unless a custom accuracy accumulator double-counts.
Common situations: Users shorten num_epochs in slow CPU/GPU environments; users pass net.collect_params() before initialize() so weights stay random; users swap in a custom net with a wrong output shape; mixing torch dataloaders with the mxnet training loop so y is a torch tensor and argmax comparisons silently misbehave.
Related errors
- train_loss < 0.5
- train_acc <= 1 and train_acc > 0.7
- train_loss < 0.5
- train_acc <= 1 and train_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/e07d08b25eeadc3c.
Report an issue: GitHub.