Tensorflow apply op to each element of a 2d tensor
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
TensorFlow operations are element-wise by default for most math functions. To apply an operation to every element of a 2D tensor, use built-in ops like tf.math.square, tf.math.log, or tf.where. For custom element-wise logic, use tf.vectorized_map or tf.map_fn. Avoid Python loops over tensor elements — they bypass TensorFlow's graph execution and run orders of magnitude slower. The key principle is to express operations as vectorized tensor math wherever possible.
Built-in Element-wise Operations
Custom Element-wise with Standard Ops
Using tf.map_fn for Complex Per-Element Logic
Using tf.vectorized_map (Faster)
Applying Custom Python Functions with tf.py_function
Performance Comparison
Common Pitfalls
- Using Python loops to iterate over tensor elements:
for i in range(t.shape[0]): t[i]creates separate TF operations for each element and bypasses batch optimization. Use vectorized TF ops (tf.math.square,tf.where) ortf.map_fnfor operations that must apply per-row or per-element. - Confusing tf.map_fn axis behavior:
tf.map_fnmaps over the first dimension (axis 0) by default. For a 2D tensor of shape(m, n), it applies the function to each row, not each individual element. To map per-element, flatten first withtf.reshape(t, [-1]), apply, then reshape back. - Using tf.py_function in performance-critical code:
tf.py_functiondrops into Python execution, losing all TF graph optimizations, GPU acceleration, and XLA compilation. It also preventstf.functiontracing. Use it only for prototyping or operations that genuinely cannot be expressed in TF ops. - Forgetting that TF ops broadcast automatically:
t + scalarort * vectorautomatically broadcasts across dimensions. Writing explicit loops ortf.map_fnfor operations that are already handled by broadcasting wastes performance. Check NumPy broadcasting rules — TF follows the same conventions. - Shape loss with tf.py_function and tf.map_fn: Both functions may lose static shape information. TF cannot infer output shapes through Python code. Call
result.set_shape(expected_shape)aftertf.py_functionto restore shape metadata, especially if the result feeds into a Keras layer.
Summary
- Most TF math ops (
tf.math.square,tf.where,+,*) are already element-wise — use them directly - Use
tf.map_fnto apply a function per-row of a 2D tensor, or flatten to apply per-element - Prefer
tf.vectorized_mapovertf.map_fnfor better performance (auto-batches operations) - Avoid Python loops over tensor elements — they are 100-1000x slower than vectorized ops
- Use
tf.py_functiononly as a last resort when the operation cannot be expressed in TF ops
Related reading
- TensorFlow argmax -min
- Tensorflow Attempting to use uninitialized value beta1_power
- Tensorflow Attempting to use uninitialized value beta1_power
- Tensorflow, best way to save state in RNNs?
- Tensorflow Assign requires shapes of both tensors to match. lhs shape 20 rhs shape 48
- Tensorflow Attempting to use uninitialized value AUC/AUC/auc/false_positives
- TensorFlow Attempting to use uninitialized value in variable initialization
- TensorFlow Attempting to use uninitialized value in variable initialization
.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.