d2l-ai/d2l-zh · error · AssertionError

f"{name} 不存在于 {DATA_HUB}"

Error message

f"{name} 不存在于 {DATA_HUB}"

What it means

AssertionError from d2l.mxnet.download: the requested dataset name must be a key in the module-level DATA_HUB dict (populated at import with entries like 'kaggle_house_train', 'kaggle_house_test', 'fra_mu', 'time_machine', etc.). The message interpolates the entire DATA_HUB contents so you can see exactly which names are registered. It exists to stop a KeyError/HTTP 404 later when a URL is guessed.

Source

Thrown at d2l/mxnet.py:347

def evaluate_loss(net, data_iter, loss):
    """评估给定数据集上模型的损失

    Defined in :numref:`sec_model_selection`"""
    metric = d2l.Accumulator(2)  # 损失的总和,样本数量
    for X, y in data_iter:
        l = loss(net(X), y)
        metric.add(d2l.reduce_sum(l), d2l.size(l))
    return metric[0] / metric[1]

DATA_HUB = dict()
DATA_URL = 'http://d2l-data.s3-accelerate.amazonaws.com/'

def download(name, cache_dir=os.path.join('..', 'data')):
    """下载一个DATA_HUB中的文件,返回本地文件名

    Defined in :numref:`sec_kaggle_house`"""
    assert name in DATA_HUB, f"{name} 不存在于 {DATA_HUB}"
    url, sha1_hash = DATA_HUB[name]
    os.makedirs(cache_dir, exist_ok=True)
    fname = os.path.join(cache_dir, url.split('/')[-1])
    if os.path.exists(fname):
        sha1 = hashlib.sha1()
        with open(fname, 'rb') as f:
            while True:
                data = f.read(1048576)
                if not data:
                    break
                sha1.update(data)
        if sha1.hexdigest() == sha1_hash:
            return fname  # 命中缓存
    print(f'正在从{url}下载{fname}...')
    r = requests.get(url, stream=True, verify=True)
    with open(fname, 'wb') as f:
        f.write(r.content)
    return fname

View on GitHub (pinned to e6b18ccea7)

Solutions

  1. Inspect the printed DATA_HUB in the error message and use the exact registered key (e.g. 'kaggle_house_train')
  2. Check spelling/case of the dataset name against d2l.mxnet.DATA_HUB keys
  3. If you genuinely need a new file, register it first: DATA_HUB['mydata'] = (DATA_URL + 'mydata.csv', '<sha1>') then call download('mydata')
  4. Upgrade the d2l package to the edition matching your notebook

Example fix

# before
d2l.download('kaggle_house_prediction')  # AssertionError: ... 不存在于 {...}
# after
d2l.download('kaggle_house_train')
# or register your own
DATA_HUB['myset'] = (DATA_URL + 'myset.csv', 'da14dd1caee0dd2d91c3a35a4c7f5f6e')
d2l.download('myset')
Defensive patterns

Strategy: type-guard

Validate before calling

import d2l.mxnet as d2l
name = 'kaggle_house_train'
if name not in d2l.DATA_HUB:
    raise KeyError(f'{name} not registered; available: {sorted(d2l.DATA_HUB)}')
fname = d2l.download(name)

Type guard

def is_registered_dataset(name: str, hub=d2l.DATA_HUB) -> bool:
    return name in hub

Prevention

When it happens

Trigger: Calling d2l.download('kaggle_house_prediction') (unregistered name/typo), calling download on a dataset constant defined in d2l.torch.DATA_HUB but using d2l.mxnet.download (the dicts hold the same keys in this repo, but custom or newer datasets are not present), or calling download before DATA_HUB is extended with your own (url, sha1) tuple.

Common situations: Copy-pasting notebook code from a newer D2L edition whose dataset name differs; users who assume any URL string can be passed (download takes a registry key, not a URL); stale d2l version missing a recently added dataset entry.

Related errors


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