{"record":{"id":"4247601219bee41a","repo":"d2l-ai/d2l-zh","slug":"test-acc-1-and-test-acc-0-7","errorCode":null,"errorMessage":"test_acc <= 1 and test_acc > 0.7","messagePattern":"test_acc <= 1 and test_acc > 0\\.7","errorType":"validation","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"d2l/mxnet.py","lineNumber":316,"sourceCode":"            self.axes[0].plot(x, y, fmt)\n        self.config_axes()\n        display.display(self.fig)\n        display.clear_output(wait=True)\n\ndef train_ch3(net, train_iter, test_iter, loss, num_epochs, updater):\n    \"\"\"训练模型（定义见第3章）\n\n    Defined in :numref:`sec_softmax_scratch`\"\"\"\n    animator = Animator(xlabel='epoch', xlim=[1, num_epochs], ylim=[0.3, 0.9],\n                        legend=['train loss', 'train acc', 'test acc'])\n    for epoch in range(num_epochs):\n        train_metrics = train_epoch_ch3(net, train_iter, loss, updater)\n        test_acc = evaluate_accuracy(net, test_iter)\n        animator.add(epoch + 1, train_metrics + (test_acc,))\n    train_loss, train_acc = train_metrics\n    assert train_loss < 0.5, train_loss\n    assert train_acc <= 1 and train_acc > 0.7, train_acc\n    assert test_acc <= 1 and test_acc > 0.7, test_acc\n\ndef predict_ch3(net, test_iter, n=6):\n    \"\"\"预测标签（定义见第3章）\n\n    Defined in :numref:`sec_softmax_scratch`\"\"\"\n    for X, y in test_iter:\n        break\n    trues = d2l.get_fashion_mnist_labels(y)\n    preds = d2l.get_fashion_mnist_labels(d2l.argmax(net(X), axis=1))\n    titles = [true +'\\n' + pred for true, pred in zip(trues, preds)]\n    d2l.show_images(\n        d2l.reshape(X[0:n], (n, 28, 28)), 1, n, titles=titles[0:n])\n\ndef evaluate_loss(net, data_iter, loss):\n    \"\"\"评估给定数据集上模型的损失\n\n    Defined in :numref:`sec_model_selection`\"\"\"\n    metric = d2l.Accumulator(2)  # 损失的总和,样本数量","sourceCodeStart":298,"sourceCodeEnd":334,"githubUrl":"https://github.com/d2l-ai/d2l-zh/blob/e6b18ccea71451a55fcd861d7b96fddf2587b09a/d2l/mxnet.py#L298-L334","documentation":"Python AssertionError from d2l.mxnet.train_ch3's final sanity check: test accuracy must be in (0.7, 1] after training on Fashion-MNIST. It verifies the trained model generalizes as the book claims (~0.83 test acc); failure means underfitting, divergence, or an evaluation-path bug rather than a library defect.","triggerScenarios":"Calling train_ch3 then having evaluate_accuracy(net, test_iter) return <= 0.7: too few epochs, diverged lr, net evaluated before parameters were initialized, or test_iter built with a different normalization than train_iter (e.g. transform applied to only one of the two).","commonSituations":"CPU-only environments where users trim num_epochs; reusing a net across notebook runs without re-initialization so it was already overfit/corrupted; batch_size or shuffle differences between train_iter and test_iter; using the mxnet loop on data already consumed as a torch DataLoader (empty iterator -> accuracy 0).","solutions":["Rerun with the book's hyperparameters: num_epochs=10, lr=0.1, batch_size=256, and a freshly initialized net","Verify net.initialize(mx.init.Xavier()) executed before training/eval","Rebuild test_iter with the same transforms as train_iter (only shuffle differs)","If the animator shows good train acc but ~0.1 test acc, check that evaluate_accuracy uses the same net instance and that test labels are not one-hot when argmax comparison expects an index"],"exampleFix":"// before\nnet = d2l.Sequential()  # never initialized, random weights\ntrain_ch3(net, train_iter, test_iter, loss, 10, updater)  # test_acc ~0.1 -> AssertionError\n// after\nnet.initialize()\ntrain_ch3(net, train_iter, test_iter, loss, 10, updater)  # test_acc ~0.83","handlingStrategy":"validation","validationCode":"# pre-check evaluation path and data consistency\nassert evaluate_accuracy(net, train_iter) is not None\nassert same_transforms(train_iter, test_iter), 'train/test transforms differ'\nnet.initialize()  # ensure parameters exist before eval\nacc0 = evaluate_accuracy(net, test_iter)\nassert 0 <= acc0 <= 1, 'sanity: random-init accuracy should be ~0.1'","typeGuard":"def evaluation_ready(net, test_iter) -> bool:\n    return any(True for _ in iter(test_iter)) and net.collect_params() is not None","tryCatchPattern":"try:\n    train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)\nexcept AssertionError as e:\n    print(f'test_acc out of (0.7, 1]: {e.args[0]}')\n    raise\nfinally:\n    print('animator history saved for inspection')","preventionTips":["Build train_iter and test_iter with identical transforms","Always call net.initialize() before training/eval","Keep num_epochs at 10 for the Fashion-MNIST chapter runs","Watch test_acc per epoch; if it tracks train_acc but stays low, suspect undertraining, not the assert"],"tags":["d2l","mxnet","assertion","evaluation","generalization","fashion-mnist"],"backgroundTag":null,"analyzedSha":"e6b18ccea71451a55fcd861d7b96fddf2587b09a","analyzedAt":"2026-08-14T20:05:26.414Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}