d2l-ai/d2l-zh · error · AssertionError

test_acc <= 1 and test_acc > 0.7

Error message

test_acc <= 1 and test_acc > 0.7

What it means

An AssertionError in d2l.paddle.train_ch3 requiring final test accuracy in (0.7, 1]. It validates the evaluation path of the PaddlePaddle softmax-regression benchmark: the net must generalize past 70% on the Fashion-MNIST test set and the metric must stay within valid bounds.

Source

Thrown at d2l/paddle.py:352

            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`"""
    metric = d2l.Accumulator(2)  # 损失的总和, 样本数量

View on GitHub (pinned to e6b18ccea7)

Solutions

  1. Evaluate the same net object that went through train_ch3 — do not re-instantiate it afterwards.
  2. Build both iterators from d2l.load_data_fashion_mnist(batch_size, resize=None) so preprocessing matches.
  3. Fix divergence first (lr, updater) — test accuracy tracks the loss asserts above.
  4. Sanity-check with evaluate_accuracy(net, test_iter) before train_ch3: it should print ~0.1 for a fresh net and ~0.83 after training.

Example fix

# before
net = SoftmaxRegression()      # accidentally re-created
train_ch3(net, ...)             # test_acc <= 0.7 -> AssertionError
# after
net = SoftmaxRegression()
train_ch3(net, train_iter, test_iter, loss, 10, updater)  # same object
Defensive patterns

Strategy: validation

Validate before calling

test_acc = evaluate_accuracy(net, test_iter)
if not (0.7 < test_acc <= 1.0):
    raise ValueError(f'test_acc={test_acc:.3f} outside (0.7, 1]; verify the '
                     f'trained net object and matching test preprocessing')

Try / catch

try:
    train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)
except AssertionError as e:
    raise RuntimeError(f'Paddle train_ch3 test-accuracy check failed ({e})') from e

Prevention

When it happens

Trigger: Evaluating an untrained or freshly re-initialized net; passing an empty/mis-built test_iter; test preprocessing differing from train preprocessing; divergence from bad hyperparameters pinning test accuracy near chance (~0.1).

Common situations: Notebook cell order re-creating the net between training and evaluation; using d2l.load_data_fashion_mnist with different resize/normalize for the two splits; Paddle version changes in loss or argmax semantics.

Related errors


AI-assisted analysis of d2l-ai/d2l-zh@e6b18ccea7 (2026-08-14). Data as JSON: /api/errors/b6d9305f2148b1db. Report an issue: GitHub.