TensorFlow
Mean Absolute Error
MAE
Evaluation
Machine Learning

Tensorflow Mean Absolute Error MAE for evaluation

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Mean Absolute Error, usually shortened to MAE, is one of the simplest evaluation metrics for regression models. In TensorFlow it is easy to compute, but it helps to understand what the metric is measuring, how it aggregates across batches, and when it is more appropriate than metrics such as MSE or RMSE.

What MAE Measures

MAE is the average absolute difference between predicted values and true values. Because the error is not squared, every unit of error counts linearly.

A plain Python version makes the definition clear:

python
1import numpy as np
2
3y_true = np.array([3.0, 5.0, 2.5])
4y_pred = np.array([2.5, 5.5, 4.0])
5
6mae = np.mean(np.abs(y_true - y_pred))
7print(mae)

This metric is easy to interpret. If your model predicts house prices in thousands of dollars and MAE is 12.0, the average absolute error is twelve thousand dollars.

Using MAE in TensorFlow and Keras

In TensorFlow 2, the most common way to evaluate MAE is to include it in model.compile.

python
1import tensorflow as tf
2
3model = tf.keras.Sequential([
4    tf.keras.layers.Dense(16, activation="relu"),
5    tf.keras.layers.Dense(1)
6])
7
8model.compile(
9    optimizer="adam",
10    loss="mse",
11    metrics=[tf.keras.metrics.MeanAbsoluteError()]
12)

Here MAE is a metric, not the training loss. That is a common and useful setup: optimize with one objective and report a metric that is easy for humans to interpret.

Training then reports MAE automatically:

python
1import numpy as np
2
3x = np.random.rand(100, 4).astype("float32")
4y = (x.sum(axis=1) * 2.0).astype("float32")
5
6model.fit(x, y, epochs=3, batch_size=16, verbose=1)

Keras tracks the metric across batches and reports the aggregated result for each epoch.

Computing MAE Manually

Sometimes you want MAE outside of model.fit, for example during a custom evaluation loop.

python
1import tensorflow as tf
2
3y_true = tf.constant([3.0, 5.0, 2.5])
4y_pred = tf.constant([2.5, 5.5, 4.0])
5
6metric = tf.keras.metrics.MeanAbsoluteError()
7metric.update_state(y_true, y_pred)
8print(metric.result().numpy())

The metric object is stateful. Each call to update_state adds more data to the running total, so reset it when you start a fresh evaluation.

python
metric.reset_state()

That detail matters in notebooks and custom loops where the same metric instance may be reused across experiments.

MAE as a Loss vs MAE as a Metric

You can also train directly with MAE:

python
1model.compile(
2    optimizer="adam",
3    loss=tf.keras.losses.MeanAbsoluteError(),
4    metrics=[tf.keras.metrics.MeanAbsoluteError()]
5)

Using MAE as the loss can make sense when you want the optimization objective to match the reporting metric closely. However, MAE has a constant gradient magnitude away from zero, so some practitioners prefer MSE or Huber loss for smoother optimization behavior.

A practical pattern is:

  • use MAE as a metric for interpretability
  • choose the loss based on optimization behavior and robustness needs

Batch Aggregation and Shape Details

TensorFlow expects y_true and y_pred to have compatible shapes. For standard regression, common shapes are (batch_size,) or (batch_size, 1).

python
1y_true = tf.constant([[1.0], [2.0], [3.0]])
2y_pred = tf.constant([[1.5], [1.8], [2.7]])
3
4metric = tf.keras.metrics.MeanAbsoluteError()
5metric.update_state(y_true, y_pred)
6print(metric.result().numpy())

This works because TensorFlow can compare the tensors element by element.

If you use sample weights, TensorFlow can weight the contribution of each example:

python
1weights = tf.constant([1.0, 0.5, 2.0])
2metric = tf.keras.metrics.MeanAbsoluteError()
3metric.update_state(y_true=[1.0, 2.0, 3.0], y_pred=[1.5, 1.8, 2.7], sample_weight=weights)
4print(metric.result().numpy())

Common Pitfalls

A common mistake is treating MAE as a classification metric. It is for regression-style numeric prediction, not class labels.

Another issue is forgetting that metric objects are stateful. If you reuse the same MeanAbsoluteError instance without reset_state, later results include earlier batches.

Developers also sometimes choose MAE because it looks simple, then overlook whether large errors should be penalized more strongly. If outliers matter a lot, MSE or Huber loss may be a better fit.

Finally, keep the scale of the target variable in mind. MAE is reported in the same units as the prediction target, which is a strength, but only if those units are meaningful to you.

Summary

  • MAE measures average absolute prediction error for regression tasks.
  • Use tf.keras.metrics.MeanAbsoluteError() in model.compile for routine reporting.
  • Reset metric state in custom evaluation loops.
  • MAE can be used as a loss, but it is often more useful as an interpretable metric.
  • Choose MAE when linear error magnitude is more meaningful than squared error.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track 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.

Practice ML system design

All Rights Reserved.