MultiOutputEvaluator (TFX Component)
A lightweight and flexible TFX component for evaluating multi-output TensorFlow models. It computes per-output and global metrics and writes a TFMA-compatible JSON artifact for downstream analysis and reporting.
📦 Installation
Install from PyPI:
pip install tfx-moe
⚙️ Features
- ✅ Evaluate multi-output models (e.g., shape
(batch, num_outputs)) - ✅ Computes per-output and global metrics
- ✅ Currently supports MSE and MAE (easy to extend)
- ✅ TFMA-compatible JSON output (
ModelEvaluationartifact) - ✅ Works with TFX Transform artifacts (
TransformGraph) - ✅ Pluggable dataset input function (your data, your logic)
📚 API Reference
MultiOutputEvaluator Component
MultiOutputEvaluator(
model, # Channel[Model]
examples, # Channel[Examples]
transform_graph, # Channel[TransformGraph]
output_names, # list[str]: names of model outputs in order
metrics, # list[str]: e.g., ['mse', 'mae']
input_fn_path, # str: "pkg.mod:func" or "pkg.mod.func"
input_fn_kwargs=None, # dict: extra kwargs for input function
example_split='test' # str: which split to evaluate
)
Parameters
- model:
standard_artifacts.Model– Trained SavedModel (expects predictions of shape(batch, num_outputs)). - examples:
standard_artifacts.Examples– TFRecords location for the chosen split. - transform_graph:
standard_artifacts.TransformGraph– Loaded via tft.TFTransformOutput. - output_names (list[str]): Logical names per output index; order must correspond to your model’s output dimension.
- metrics (list[str]): Currently
['mse', 'mae']supported. - input_fn_path (str): Dotted path to your dataset builder function.
- input_fn_kwargs (dict, optional): Keyword args passed to the dataset function.
- example_split (str, default 'test'): Split folder name under
Examplesartifact (e.g.,'Split-test' if that’s how your pipeline writes splits).
🚀 Quickstart (TFX Usage)
[1] Add Component to your Pipeline and Run
from tfx_moe import MultiOutputEvaluator
# InteractiveContext Pipeline Runner
multi_output_evaluator = MultiOutputEvaluator(
model=trainer.outputs['model'],
examples=transform.outputs["transformed_examples"],
transform_graph=transform.outputs['transform_graph'],
output_names=OUTPUT_KEYS, # e.g., ["y_loc1", "y_loc2", ...]
metrics=['mse', 'mae'],
input_fn_path="my_pkg.mdata:input_fn", # Your dataset builder function
example_split='Split-test' # Match your artifact split naming
)
# Run (InteractiveContext example)
context.run(multi_output_evaluator)
# Access TFMA-like JSON results
evaluation_uri = multi_output_evaluator.outputs['evaluation'].get()[0].uri
print(evaluation_uri)
[2] Parse Results (per-output + global)
import json
import pandas as pd
import tensorflow as tf
with tf.io.gfile.GFile(evaluation_uri, 'r') as f:
data = json.load(f) # TFMA-style dict
output_names = []
mse_values = []
mae_values = []
for key, value in data['metrics'].items():
if key.endswith('>>mse'):
output_name = key.split('>>')[0] # 'per_output>>{name}>>mse' → '{name}'
output_names.append(output_name)
mse_values.append(value)
elif key.endswith('>>mae'):
mae_values.append(value)
df = pd.DataFrame({
'Output Name': output_names,
'MSE': mse_values,
'MAE': mae_values
})
last_row_index = df.index[-1]
global_mse = df["MSE"].iloc[last_row_index]
global_mae = df["MAE"].iloc[last_row_index]
df = df.drop(index=[last_row_index]) # keep per-output rows only
[3] Global Metrics
print(f'Global MSE {global_mse}')
print(f'Global MAE {global_mae}')
[4] Aggregate Across Outputs
global_mse_all_outputs = df["MSE"].mean()
global_mae_all_outputs = df["MAE"].mean()
print(f'Global MSE per All Locations {global_mse_all_outputs}')
print(f'Global MAE per All Locations {global_mae_all_outputs}')
🧠 How It Works
The Executor
- Loads
TransformGraph(tft.TFTransformOutput) and the SavedModel. - Builds an evaluation dataset via your input function (
input_fn_path). - Computes per-output and global metrics across the dataset.
- Writes a TFMA-like JSON to the
ModelEvaluationartifact.
Metrics Supported
mse,mae(easy to extend in code).
Output Format (metrics dictionary keys)
- Per-output:
per_output>>{output_name}>>{metric} - Global:
global>>{metric}
📥 Dataset Function Contract
You supply the dataset function via input_fn_path, e.g. "my_pkg.mdata:input_fn".
Expected Signature
def input_fn(file_pattern: str, tf_transform_output, **kwargs) -> tf.data.Dataset:
# returns a dataset of (features, labels)
Expected Yields:
features: a structure compatible with your model’sSavedModelsignature.labels: a Tensor shaped (batch, 1, num_outputs) so that:labels[:, 0, i]is the true label vector foroutput_names[i].
- Your model’s predictions should have shape (batch, num_outputs) so that:
predictions[:, i]aligns withoutput_names[i].
If your labels are shaped differently, update either your input function or the executor’s slicing logic to align shapes.
📤 Artifact Output
-
Writes a single JSON file under the
ModelEvaluationartifact directory:evaluation.json
-
Example keys:
metrics["per_output>>y_loc3>>mse"] = 0.0123metrics["global>>mae"] = 0.1357
📜 License
This project is licensed under the MIT License.
© 2025 Dr. Ahmed Moussa
🤝 Contributing
Pull requests are welcome.
For major changes, please open an issue first to discuss what you would like to change.
📫 Contact
For feedback, bugs, or collaboration ideas:
- GitHub: @real-ahmed-moussa
⭐️ Show Your Support
If you find this project useful, consider giving it a ⭐️ on GitHub!
Metadata
Release files for tfx-moe 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| tfx_moe-0.1.0.tar.gz | 10.4 kB | Without provenance | Details for tfx_moe-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| tfx_moe-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for tfx_moe-0.1.0-py3-none-any.whl |
Total release size: 18.0 kB
Release files / tfx_moe-0.1.0.tar.gz
| Download URL | tfx_moe-0.1.0.tar.gz |
|---|---|
| Size | 10.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0733166d812af1bad34f610f8e9b430035efef245baf2beba96694afad4520d7
|
|
BLAKE2b-256 checksum How to use checksums |
0c5b6ad8c55e53bad66df427158214f654fc52002057daac0f1826dd2688a17d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.8
|
Release files / tfx_moe-0.1.0-py3-none-any.whl
| Download URL | tfx_moe-0.1.0-py3-none-any.whl |
|---|---|
| Size | 7.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a1344b07792fa0cde5634fc2225492266af1d56f91970a0d53c127a737532526
|
|
BLAKE2b-256 checksum How to use checksums |
8a0a53bdaf5da41619b2d637004fab7a6e5f20489ae30654ae003710c8d48071
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.8
|
Security for tfx-moe 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.