Keras error You must feed a value for placeholder tensor 'bidirectional_1/keras_learning_phase' with dtype bool
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When using bidirectional LSTMs or other recurrent layers in Keras with a TensorFlow 1.x backend, you may encounter the error: You must feed a value for placeholder tensor 'bidirectional_1/keras_learning_phase' with dtype bool. This error occurs because Keras uses a learning_phase placeholder to distinguish between training and inference modes, and certain operations fail to set this flag automatically.
The Error
The full error message typically looks like:
This happens when:
- Running predictions or evaluations outside Keras's standard
model.predict()ormodel.evaluate() - Using
K.function()or TensorFlow sessions directly - Serving the model through TensorFlow Serving or a custom inference pipeline
- Mixing Keras and raw TensorFlow operations
Why This Happens
Keras layers like Dropout, BatchNormalization, and bidirectional RNNs behave differently during training vs inference. Keras tracks this via K.learning_phase() — a boolean placeholder tensor:
- Training (
learning_phase = True): Dropout is active, BatchNorm uses batch statistics - Inference (
learning_phase = False): Dropout is disabled, BatchNorm uses running statistics
When you call model.predict(), Keras automatically sets learning_phase = False. But if you bypass Keras and use a raw TensorFlow session, this placeholder remains unfed.
Fix 1: Set Learning Phase Explicitly
Feed K.learning_phase() in your session run:
Fix 2: Set Learning Phase Globally
If you only need inference, set the learning phase globally before creating the session:
Warning: Setting K.set_learning_phase(0) before model creation makes the model inference-only. You cannot train it afterward. Set it after training is complete.
Fix 3: Use K.function with Learning Phase
When creating custom prediction functions with K.function:
Or in newer Keras versions:
Fix 4: Upgrade to TensorFlow 2.x
TensorFlow 2.x with eager execution eliminates this issue entirely. The learning phase is handled automatically via the training argument in layer calls:
Fix 5: Freeze the Graph for Serving
If you need to export the model for TensorFlow Serving:
Common Pitfalls
- Setting learning_phase too early: Calling
K.set_learning_phase(0)before building the model makes it permanently inference-only. You cannot callmodel.fit()afterward. Set it after training. - Multiple models: If you have multiple models in the same session,
K.set_learning_phase()affects all of them. Use per-callfeed_dictif you need different modes for different models. - Layer-specific behavior: Not just
Dropout—BatchNormalization,SpatialDropout1D,GaussianNoise, andAlphaDropoutall depend onlearning_phase. Any model using these layers can trigger the error. - Model loading: When loading a saved model in a new session,
learning_phaseresets. Set it again before inference. - TF1 compatibility mode: In TF2 with
tf.compat.v1.disable_eager_execution(), you are back in graph mode and will encounter this error again. Prefer native TF2 eager mode.
Summary
- The error occurs because
learning_phaseis a boolean placeholder that must be fed in TF1 graph mode - Use
model.predict()instead of raw session runs when possible - Feed
K.learning_phase(): Falseinfeed_dictfor custom inference - Set
K.set_learning_phase(0)globally for inference-only pipelines (after training) - Upgrade to TensorFlow 2.x to avoid the issue entirely — eager execution handles it automatically

