Keras Tokenizer num_words doesn't seem to work
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.
Introduction
The num_words argument in Keras Tokenizer often looks broken because it does not shrink word_index after fit_on_texts. That is expected behavior: the tokenizer still records the full vocabulary, and the num_words limit is applied later when texts are converted into sequences or matrices.
What num_words Actually Does
When you call fit_on_texts, Keras counts all observed tokens and assigns indices based on frequency. The internal word_index therefore contains every token the tokenizer saw.
The num_words limit is then used as a cutoff during downstream transformations. In other words:
- vocabulary statistics are full
- generated sequences are truncated to the most common tokens
That is why inspecting word_index alone makes it seem like num_words had no effect.
Demonstration
You will usually see a word_index with more than three entries, but the sequence output keeps only indices below num_words. Less frequent words are skipped unless you define an out-of-vocabulary token.
Why The Sequence Looks Shorter
Suppose the most frequent tokens receive these indices:
- '
bluebecomes1' - '
yellowbecomes2' - '
redbecomes3' - '
greenbecomes4'
With num_words=3, only indices strictly less than 3 are kept during texts_to_sequences. That means tokens at index 3 and above are not included. This catches many people because they expect the top three indexed words to survive, but in practice the cutoff is based on index comparison, not on dictionary length.
Use oov_token When You Need Stable Output
If you want unseen or filtered words to map to a known placeholder instead of disappearing entirely, set oov_token.
Now filtered or unknown tokens map to the out-of-vocabulary index rather than vanishing. That is often better for model stability.
Match Your Embedding Layer To The Limit
If you use an embedding layer, its input_dim should usually reflect the effective vocabulary limit rather than the raw word_index size.
If your tokenizer uses num_words=5000, your embedding layer should normally expect that same maximum indexed range, adjusted for padding and any out-of-vocabulary token strategy.
Practical Debugging Checklist
When num_words seems ineffective, check these things in order:
- did you inspect
word_indexinstead of the generated sequences - did you forget that the cutoff is applied during transformation
- are you using
oov_tokenor silently dropping filtered tokens - does your embedding layer match the intended vocabulary limit
Most confusion comes from mixing up tokenizer statistics with tokenizer output.
Common Pitfalls
The most common mistake is expecting fit_on_texts to cap word_index. It does not. It records the whole corpus vocabulary.
Another mistake is setting num_words=n and expecting indices up to and including n to remain. The effective sequence filter is based on the tokenizer’s index rules, so borderline indices often surprise people.
A third issue is forgetting oov_token. Without it, rare or filtered words disappear from sequences, which can make debugging harder.
Summary
- '
num_wordsdoes not shrinkword_indexafter fitting.' - The limit is applied when converting texts to sequences or matrices.
- Inspect sequence output, not just the vocabulary dictionary.
- Use
oov_tokenif you want filtered words to map to a known placeholder. - Keep your embedding layer dimensions aligned with the tokenizer limit.
Related reading
- Keras TypeError can't pickle _thread.lock objects with KerasClassifier
- Keras TypeError run got an unexpected keyword argument 'kernel_regularizer
- Keras unable to calculate number of parameters in a Keras Custom Layer
- Keras UnboundLocalError local variable 'logs' referenced before assignment
- Keras Use the same layer in different models share weights
- Keras utilises less CPU when number of workers grows and numpy generates a large array
- Keras ValueError Failed to convert a NumPy array to a Tensor Unsupported object type float
- Keras ValueError Input 0 is incompatible with layer conv2d_1 expected ndim4, found ndim5
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.