d2l-ai/d2l-zh · error · NotImplementedError
NotImplementedError
Error message
NotImplementedError
What it means
A NotImplementedError raised by d2l.tensorflow.Encoder.call. Encoder is the abstract interface of the encoder-decoder architecture (sec_encoder-decoder): it is a tf.keras.layers.Layer whose call is intentionally left unimplemented. Subclasses (Seq2SeqEncoder, TransformerEncoder, ...) must override call; instantiating the base class and invoking it as a layer triggers the error.
Source
Thrown at d2l/tensorflow.py:881
text = preprocess_nmt(read_data_nmt())
source, target = tokenize_nmt(text, num_examples)
src_vocab = d2l.Vocab(source, min_freq=2,
reserved_tokens=['<pad>', '<bos>', '<eos>'])
tgt_vocab = d2l.Vocab(target, min_freq=2,
reserved_tokens=['<pad>', '<bos>', '<eos>'])
src_array, src_valid_len = build_array_nmt(source, src_vocab, num_steps)
tgt_array, tgt_valid_len = build_array_nmt(target, tgt_vocab, num_steps)
data_arrays = (src_array, src_valid_len, tgt_array, tgt_valid_len)
data_iter = d2l.load_array(data_arrays, batch_size)
return data_iter, src_vocab, tgt_vocab
class Encoder(tf.keras.layers.Layer):
"""编码器-解码器架构的基本编码器接口"""
def __init__(self, **kwargs):
super(Encoder, self).__init__(**kwargs)
def call(self, X, *args, **kwargs):
raise NotImplementedError
class Decoder(tf.keras.layers.Layer):
"""编码器-解码器架构的基本解码器接口
Defined in :numref:`sec_encoder-decoder`"""
def __init__(self, **kwargs):
super(Decoder, self).__init__(**kwargs)
def init_state(self, enc_outputs, *args):
raise NotImplementedError
def call(self, X, state, **kwargs):
raise NotImplementedError
class EncoderDecoder(tf.keras.Model):
"""编码器-解码器架构的基类
Defined in :numref:`sec_encoder-decoder`"""View on GitHub (pinned to e6b18ccea7)
Solutions
- Subclass and override call: class MyEncoder(d2l.Encoder): def call(self, X, *args, **kwargs): ...
- If porting from the PyTorch edition, rename forward -> call in TensorFlow subclasses.
- Use the provided concrete implementations, e.g. d2l.Seq2SeqEncoder(vocab_size, num_hiddens, num_layers, dropout), instead of the abstract base.
- Check for typos in the method name (call vs calls) and correct signature (self, X, *args, **kwargs).
Example fix
# before
enc = d2l.Encoder()
enc(X) # NotImplementedError
# after
class MyEncoder(d2l.Encoder):
def call(self, X, *args, **kwargs):
return tf.identity(X)
enc = MyEncoder()
enc(X) Defensive patterns
Strategy: type-guard
Type guard
def is_concrete_encoder(enc) -> bool:
return (isinstance(enc, d2l.Encoder)
and type(enc).call is not d2l.Encoder.call) Try / catch
try:
enc(X)
except NotImplementedError:
raise TypeError(f'{type(enc).__name__} must override Encoder.call(X, *args, **kwargs)') from None Prevention
- In TensorFlow subclasses, the method must be named call (not forward).
- Prefer library encoders (d2l.Seq2SeqEncoder) unless writing a custom architecture.
- Add a smoke test that runs one forward pass on a tiny batch right after constructing any new encoder.
When it happens
Trigger: Instantiating d2l.Encoder() directly and calling encoder(X); a custom encoder subclass whose forward method is misspelled (e.g. 'forward' instead of 'call' in the TF API) so the base call runs; type-testing code that calls call on an arbitrary Encoder instance.
Common situations: Porting PyTorch d2l code to TensorFlow: writing def forward(self, X) on a TF subclass silently falls through to the base call; omitting the override entirely while developing a new architecture chapter; IDE auto-generating __init__ but not call.
Related errors
- NotImplementedError
- NotImplementedError
- NotImplementedError
- train_loss < 0.5
- 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/26cf03749cf2c26b.
Report an issue: GitHub.