Experiment Tracking (MLflow, Weights & Biases)
Experiment Tracking: MLflow and Weights & Biases
Learn how to record, organize, compare, reproduce, and govern Machine Learning experiments using MLflow and Weights & Biases. Track parameters, metrics, code versions, datasets, artifacts, system information, model files, evaluation reports, and conclusions across the complete experimentation lifecycle.
Introduction
Machine Learning development is iterative. A team may test different algorithms, feature sets, data versions, hyperparameters, random seeds, preprocessing strategies, decision thresholds, and runtime environments before selecting a model.
Without experiment tracking, results may be scattered across notebooks, terminal output, spreadsheets, screenshots, and filenames. It becomes difficult to determine which experiment produced a model, why one candidate was selected, or whether a historical result can be reproduced.
Experiment tracking is the systematic recording of the inputs, configuration, execution context, outputs, metrics, artifacts, and conclusions associated with each Machine Learning run.
MLflow and Weights & Biases, commonly abbreviated as W&B, provide experiment-tracking capabilities. Both can organize runs, log parameters and metrics, preserve artifacts, compare results, and improve collaboration, although their interfaces, deployment options, integrations, and broader platform capabilities differ.
Learning Objectives
By the End of This Lesson
- Define Machine Learning experiment tracking
- Explain why manual experiment records are unreliable
- Distinguish experiments, runs, parameters, metrics, tags, and artifacts
- Identify the information required for reproducibility
- Design a consistent experiment-naming strategy
- Track source-code and dataset versions
- Track training configuration and random states
- Log scalar metrics and metric history
- Log model files, reports, plots, and schemas
- Track experiments with MLflow
- Use MLflow manual logging
- Use MLflow autologging
- Track experiments using Weights & Biases
- Use W&B Artifacts for versioned outputs
- Compare multiple experimental runs
- Track cross-validation and threshold-selection results
- Understand hyperparameter sweeps
- Integrate experiment tracking with ML pipelines and CI/CD
- Protect sensitive experiment data
- Create an experiment-tracking readiness checklist
Prerequisites
Recommended Knowledge
- Python programming
- pandas and NumPy
- scikit-learn fundamentals
- Model training and evaluation
- Train-validation-test separation
- Hyperparameters and model parameters
- Git fundamentals
- Saving and loading models
- ML pipelines
- Model version control
Required Packages
- MLflow
- Weights & Biases
- pandas
- NumPy
- scikit-learn
- Matplotlib
- Joblib
python -m pip install mlflow wandb pandas numpy scikit-learn matplotlib joblib
What Is a Machine Learning Experiment?
A Machine Learning experiment is a structured investigation that tests a defined hypothesis by changing one or more controlled inputs and measuring the resulting behavior.
| Experiment Element | Example |
|---|---|
| Question | Does class weighting improve recall without unacceptable precision loss? |
| Controlled Change | Class-weight configuration |
| Fixed Inputs | Dataset version, split, features, and evaluation protocol |
| Measured Outputs | Precision, recall, F1, calibration, and latency |
| Conclusion | Evidence-based decision to accept, reject, or investigate further |
What Is Experiment Tracking?
Experiment tracking creates a searchable history of model-development runs and connects every result to the inputs and artifacts that produced it.
| Tracked Information | Purpose |
|---|---|
| Run Identifier | Uniquely identifies one execution |
| Parameters | Records configuration selected before or during training |
| Metrics | Records measured model and system behavior |
| Tags | Adds searchable descriptive metadata |
| Artifacts | Preserves model files, reports, plots, schemas, and outputs |
| Code Version | Identifies the source revision used by the run |
| Data Version | Identifies the training and evaluation information |
| Environment | Identifies dependencies, runtime, and hardware context |
| Status | Records whether the run completed, failed, or was canceled |
| Conclusion | Explains the interpretation and next decision |
Why Experiment Tracking Matters
Practical Benefits
- Preserves experiment history
- Supports reproducibility
- Enables run comparison
- Prevents repeated failed experiments
- Supports collaboration
- Connects metrics with exact configurations
- Preserves generated artifacts
- Improves model-selection evidence
- Supports audit and governance
- Provides lineage for model registration
- Supports incident investigation
- Improves handover between teams
Core Tracking Concepts
| Concept | Meaning |
|---|---|
| Project or Experiment | A logical collection of related runs |
| Run | One execution of training, evaluation, or analysis code |
| Parameter | A configuration value associated with a run |
| Metric | A measured numerical value |
| Metric Step | The iteration, epoch, or time point associated with a metric |
| Tag | A descriptive searchable value |
| Artifact | A file or directory produced or used by a run |
| Configuration | The complete set of values controlling execution |
| Lineage | The relationship among code, data, runs, metrics, and artifacts |
Parameters vs Metrics
Parameters
- Control experiment execution
- Usually selected before training
- Examples include learning rate and tree depth
- Support filtering and comparison
Metrics
- Measure experiment results
- Calculated from training or evaluation
- Examples include F1 and validation loss
- May be logged once or over multiple steps
| Tracked Value | Classification |
|---|---|
| Learning Rate | Parameter |
| Maximum Tree Depth | Parameter |
| Random State | Parameter |
| Validation F1 | Metric |
| Training Loss by Epoch | Metric History |
| Model Type | Parameter or Tag |
| Source Revision | Tag or System Metadata |
Experiment Artifacts
Useful Artifacts
- Saved model pipeline
- Model metadata
- Input and output schemas
- Data-validation report
- Evaluation report
- Confusion matrix
- ROC and precision-recall plots
- Calibration plot
- Feature-importance report
- Error-analysis table
- Model card
- Dependency manifest
- Representative prediction samples
Reproducibility Record
Record
- Git commit identifier
- Training-data version
- Validation-data version
- Test-data version
- Feature-definition version
- Configuration version
- Dependency versions
- Container-image digest where applicable
- Random seeds
- Hardware or accelerator type where relevant
- Model checksum
Create a Shared Training Function
The following training function is used in the MLflow and W&B examples so that both platforms track equivalent model behavior.
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import StandardScaler
def create_model_pipeline(
numerical_features,
categorical_features,
regularization_strength,
random_state
):
numerical_pipeline = Pipeline(
steps=[
(
"imputer",
SimpleImputer(
strategy="median"
)
),
(
"scaler",
StandardScaler()
)
]
)
categorical_pipeline = Pipeline(
steps=[
(
"imputer",
SimpleImputer(
strategy="most_frequent"
)
),
(
"encoder",
OneHotEncoder(
handle_unknown="ignore"
)
)
]
)
preprocessor = ColumnTransformer(
transformers=[
(
"numerical",
numerical_pipeline,
numerical_features
),
(
"categorical",
categorical_pipeline,
categorical_features
)
]
)
return Pipeline(
steps=[
(
"preprocessor",
preprocessor
),
(
"classifier",
LogisticRegression(
C=regularization_strength,
class_weight="balanced",
max_iter=2000,
random_state=random_state
)
)
]
)
Create an Evaluation Function
from sklearn.metrics import accuracy_score
from sklearn.metrics import average_precision_score
from sklearn.metrics import f1_score
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import roc_auc_score
def calculate_metrics(
true_labels,
probabilities,
decision_threshold
):
predictions = (
probabilities
>=
decision_threshold
).astype(
int
)
return {
"accuracy": float(
accuracy_score(
true_labels,
predictions
)
),
"precision": float(
precision_score(
true_labels,
predictions,
zero_division=0
)
),
"recall": float(
recall_score(
true_labels,
predictions,
zero_division=0
)
),
"f1": float(
f1_score(
true_labels,
predictions,
zero_division=0
)
),
"roc_auc": float(
roc_auc_score(
true_labels,
probabilities
)
),
"average_precision": float(
average_precision_score(
true_labels,
probabilities
)
)
}
MLflow Tracking Concepts
| MLflow Concept | Purpose |
|---|---|
| Tracking URI | Identifies the tracking-server or storage location |
| Experiment | Groups related runs |
| Run | Represents one tracked execution |
| Parameter | Stores a run configuration value |
| Metric | Stores a numerical result, optionally over steps |
| Tag | Stores searchable descriptive metadata |
| Artifact | Stores an output file or directory |
| Logged Model | Represents a tracked trained-model artifact |
| Model Registry | Manages registered model versions and lifecycle metadata |
Configure MLflow Tracking
import mlflow
mlflow.set_tracking_uri(
"http://127.0.0.1:5000"
)
mlflow.set_experiment(
"customer-churn-experiments"
)
Start a Local MLflow Server
mlflow server \
--host 127.0.0.1 \
--port 5000
Track an Experiment with MLflow
import mlflow
import mlflow.sklearn
regularization_strength = 1.0
decision_threshold = 0.60
random_state = 42
with mlflow.start_run(
run_name="logistic-regression-balanced"
) as run:
mlflow.log_params(
{
"algorithm": (
"logistic-regression"
),
"regularization_strength": (
regularization_strength
),
"class_weight": "balanced",
"decision_threshold": (
decision_threshold
),
"random_state": random_state
}
)
mlflow.set_tags(
{
"project": "customer-churn",
"task": "binary-classification",
"code_version": (
"replace-with-source-revision"
),
"training_data_version": (
"replace-with-data-version"
),
"feature_definition_version": (
"1.0.0"
),
"run_purpose": (
"evaluate-class-weighting"
)
}
)
model_pipeline = create_model_pipeline(
numerical_features=(
numerical_features
),
categorical_features=(
categorical_features
),
regularization_strength=(
regularization_strength
),
random_state=random_state
)
model_pipeline.fit(
training_features,
training_labels
)
validation_probabilities = (
model_pipeline.predict_proba(
validation_features
)[:, 1]
)
validation_metrics = (
calculate_metrics(
true_labels=validation_labels,
probabilities=(
validation_probabilities
),
decision_threshold=(
decision_threshold
)
)
)
mlflow.log_metrics(
validation_metrics
)
mlflow.sklearn.log_model(
sk_model=model_pipeline,
name="model"
)
run_id = run.info.run_id
print(
run_id
)
Log Evaluation Artifacts with MLflow
import json
from pathlib import Path
artifact_directory = Path(
"experiment-artifacts"
)
artifact_directory.mkdir(
parents=True,
exist_ok=True
)
metrics_path = (
artifact_directory
/ "validation_metrics.json"
)
with open(
metrics_path,
"w",
encoding="utf-8"
) as metrics_file:
json.dump(
validation_metrics,
metrics_file,
indent=4
)
mlflow.log_artifact(
str(
metrics_path
),
artifact_path="evaluation"
)
evaluation,
schemas, plots, and
model-card so reviewers can find evidence quickly.
Log an Input Example and Signature
from mlflow.models import infer_signature
input_example = (
validation_features.head(
3
)
)
model_signature = infer_signature(
input_example,
model_pipeline.predict_proba(
input_example
)
)
mlflow.sklearn.log_model(
sk_model=model_pipeline,
name="model-with-signature",
signature=model_signature,
input_example=input_example
)
MLflow Autologging
MLflow autologging can automatically capture supported parameters, metrics, models, and related metadata from compatible libraries.
import mlflow
import mlflow.sklearn
mlflow.sklearn.autolog(
log_input_examples=True,
log_model_signatures=True,
log_models=True
)
with mlflow.start_run(
run_name="autologged-logistic-regression"
):
model_pipeline = create_model_pipeline(
numerical_features=(
numerical_features
),
categorical_features=(
categorical_features
),
regularization_strength=1.0,
random_state=42
)
model_pipeline.fit(
training_features,
training_labels
)
Log Metrics Over Time
with mlflow.start_run(
run_name="iterative-training"
):
for epoch in range(
number_of_epochs
):
training_loss = (
calculate_training_loss(
epoch
)
)
validation_loss = (
calculate_validation_loss(
epoch
)
)
mlflow.log_metric(
"training_loss",
float(
training_loss
),
step=epoch
)
mlflow.log_metric(
"validation_loss",
float(
validation_loss
),
step=epoch
)
Search MLflow Runs
experiment = (
mlflow.get_experiment_by_name(
"customer-churn-experiments"
)
)
runs = mlflow.search_runs(
experiment_ids=[
experiment.experiment_id
],
filter_string=(
"tags.task = "
"'binary-classification'"
),
order_by=[
"metrics.f1 DESC"
],
max_results=20
)
print(
runs[
[
"run_id",
"params.algorithm",
"params.regularization_strength",
"metrics.precision",
"metrics.recall",
"metrics.f1"
]
]
)
Load a Model from an MLflow Run
import mlflow.pyfunc
model_uri = (
f"runs:/{run_id}/model"
)
tracked_model = mlflow.pyfunc.load_model(
model_uri
)
predictions = tracked_model.predict(
inference_frame
)
Weights & Biases Tracking Concepts
| W&B Concept | Purpose |
|---|---|
| Entity | Represents a user or team scope |
| Project | Groups related runs |
| Run | Represents one tracked execution |
| Config | Stores hyperparameters and execution settings |
| Summary | Stores final or important result values |
| History | Stores metrics over time |
| Artifact | Versions datasets, models, and other files |
| Table | Stores structured data for analysis and visualization |
| Sweep | Coordinates hyperparameter-search runs |
| Report | Presents analyses and comparisons collaboratively |
Authenticate Weights & Biases
wandb login
Track an Experiment with W&B
import wandb
configuration = {
"algorithm": "logistic-regression",
"regularization_strength": 1.0,
"class_weight": "balanced",
"decision_threshold": 0.60,
"random_state": 42,
"training_data_version": (
"replace-with-data-version"
),
"feature_definition_version": "1.0.0"
}
with wandb.init(
entity="replace-with-approved-entity",
project="customer-churn-experiments",
name="logistic-regression-balanced",
config=configuration,
tags=[
"binary-classification",
"candidate",
"scikit-learn"
],
notes=(
"Evaluate class weighting using "
"the approved validation protocol."
),
job_type="training"
) as run:
model_pipeline = create_model_pipeline(
numerical_features=(
numerical_features
),
categorical_features=(
categorical_features
),
regularization_strength=(
run.config[
"regularization_strength"
]
),
random_state=(
run.config[
"random_state"
]
)
)
model_pipeline.fit(
training_features,
training_labels
)
validation_probabilities = (
model_pipeline.predict_proba(
validation_features
)[:, 1]
)
validation_metrics = (
calculate_metrics(
true_labels=validation_labels,
probabilities=(
validation_probabilities
),
decision_threshold=(
run.config[
"decision_threshold"
]
)
)
)
run.log(
validation_metrics
)
run.summary[
"code_version"
] = "replace-with-source-revision"
run.summary[
"validation_status"
] = "completed"
Log Training History with W&B
with wandb.init(
entity="replace-with-approved-entity",
project="neural-network-experiments",
config={
"epochs": number_of_epochs,
"learning_rate": learning_rate
}
) as run:
for epoch in range(
run.config[
"epochs"
]
):
training_loss = (
calculate_training_loss(
epoch
)
)
validation_loss = (
calculate_validation_loss(
epoch
)
)
run.log(
{
"epoch": epoch,
"training_loss": float(
training_loss
),
"validation_loss": float(
validation_loss
)
}
)
Log a Model as a W&B Artifact
from pathlib import Path
import joblib
import wandb
artifact_directory = Path(
"experiment-artifacts"
)
artifact_directory.mkdir(
parents=True,
exist_ok=True
)
model_path = (
artifact_directory
/ "customer_churn_pipeline.joblib"
)
joblib.dump(
model_pipeline,
model_path
)
model_artifact = wandb.Artifact(
name="customer-churn-classifier",
type="model",
description=(
"Candidate customer-churn "
"classification pipeline"
),
metadata={
"code_version": (
"replace-with-source-revision"
),
"training_data_version": (
"replace-with-data-version"
),
"decision_threshold": 0.60,
"validation_metrics": (
validation_metrics
)
}
)
model_artifact.add_file(
str(
model_path
)
)
run.log_artifact(
model_artifact
)
Track a Dataset as a W&B Artifact
dataset_artifact = wandb.Artifact(
name="customer-churn-training-data",
type="dataset",
description=(
"Approved training-data reference "
"for the churn model"
),
metadata={
"schema_version": "1.0.0",
"data_version": (
"replace-with-data-version"
),
"row_count": int(
training_features.shape[0]
),
"column_count": int(
training_features.shape[1]
)
}
)
dataset_artifact.add_file(
"data/training.parquet"
)
run.log_artifact(
dataset_artifact
)
Log Prediction Samples with a W&B Table
prediction_table = wandb.Table(
columns=[
"record_id",
"true_label",
"probability",
"predicted_label"
]
)
for (
record_id,
true_label,
probability
) in zip(
approved_record_identifiers,
validation_labels,
validation_probabilities
):
predicted_label = int(
probability
>=
decision_threshold
)
prediction_table.add_data(
record_id,
int(
true_label
),
float(
probability
),
predicted_label
)
run.log(
{
"validation_predictions": (
prediction_table
)
}
)
MLflow vs Weights & Biases
| Area | MLflow | Weights & Biases |
|---|---|---|
| Core Tracking Unit | Run grouped within an experiment | Run grouped within a project and entity |
| Configuration | Parameters and tags | Run configuration, tags, notes, and summary |
| Metric History | Metrics logged with steps or timestamps | Run history logged over training steps |
| Artifacts | General artifacts and logged models | Versioned Artifacts with metadata and lineage |
| Model Lifecycle | Model Registry and logged-model capabilities | Model Artifacts and registry-related workflows |
| Autologging | Supported framework integrations | Framework integrations and callbacks |
| Visualization | Tracking interfaces and run comparison | Interactive dashboards, tables, charts, and reports |
| Deployment Choice | Local, self-managed, or managed integrations depending on setup | Available deployment options depend on the selected W&B service configuration |
What Should You Compare Across Runs?
| Comparison Area | Examples |
|---|---|
| Data | Dataset version, date range, sample count, target rate, and schema |
| Features | Feature set, transformations, missing-value logic, and availability |
| Model | Algorithm, architecture, hyperparameters, and initialization |
| Quality | Precision, recall, F1, calibration, loss, and error analysis |
| Groups | Metrics across relevant populations and operating segments |
| Runtime | Duration, CPU, memory, accelerator, and artifact size |
| Serving | Latency, throughput, startup, memory, and schema compatibility |
| Governance | Intended use, limitations, approval status, and owner |
Compare Only Compatible Runs
Confirm Before Ranking Runs
- The target definition is identical
- The evaluation dataset is identical or appropriately comparable
- The split strategy is compatible
- Metric definitions are identical
- The positive class is consistent
- The threshold-selection procedure is consistent
- Preprocessing semantics are compatible
- Label maturity is comparable
- Data leakage has been prevented
- Relevant operating constraints are comparable
Create a Run-Comparison Table
import pandas as pd
def create_run_comparison(
run_records
):
comparison = pd.DataFrame(
run_records
)
required_columns = [
"run_id",
"algorithm",
"data_version",
"precision",
"recall",
"f1",
"roc_auc",
"decision_threshold"
]
missing_columns = (
set(required_columns)
-
set(comparison.columns)
)
if missing_columns:
raise ValueError(
"Missing comparison columns: "
f"{sorted(missing_columns)}"
)
return comparison.sort_values(
by=[
"f1",
"recall"
],
ascending=[
False,
False
]
)
Track a Confusion Matrix
import matplotlib.pyplot as plt
from sklearn.metrics import ConfusionMatrixDisplay
predicted_labels = (
validation_probabilities
>=
decision_threshold
).astype(
int
)
display = (
ConfusionMatrixDisplay
.from_predictions(
validation_labels,
predicted_labels
)
)
figure_path = (
artifact_directory
/ "confusion_matrix.png"
)
plt.savefig(
figure_path,
bbox_inches="tight"
)
plt.close()
mlflow.log_artifact(
str(
figure_path
),
artifact_path="plots"
)
run.log(
{
"confusion_matrix": (
wandb.Image(
str(
figure_path
)
)
)
}
)
Track Threshold Selection
A classification threshold can materially change precision, recall, selection rate, and business impact. Track threshold evaluation separately from model training.
import pandas as pd
threshold_rows = []
for threshold in [
0.30,
0.40,
0.50,
0.60,
0.70
]:
metrics = calculate_metrics(
true_labels=validation_labels,
probabilities=(
validation_probabilities
),
decision_threshold=threshold
)
threshold_rows.append(
{
"threshold": threshold,
**metrics
}
)
threshold_report = pd.DataFrame(
threshold_rows
)
threshold_report.to_csv(
artifact_directory
/ "threshold_analysis.csv",
index=False
)
Track Cross-Validation Results
from sklearn.model_selection import cross_validate
cross_validation_results = cross_validate(
estimator=model_pipeline,
X=training_features,
y=training_labels,
cv=5,
scoring=[
"precision",
"recall",
"f1",
"roc_auc"
],
return_train_score=False
)
cross_validation_summary = {
metric_name: float(
values.mean()
)
for metric_name, values in (
cross_validation_results.items()
)
if metric_name.startswith(
"test_"
)
}
mlflow.log_metrics(
cross_validation_summary
)
run.log(
cross_validation_summary
)
Hyperparameter Sweeps
A hyperparameter sweep coordinates multiple runs over a defined search space. Each trial should use the same approved evaluation protocol.
method: random
metric:
name: validation_f1
goal: maximize
parameters:
regularization_strength:
distribution: log_uniform_values
min: 0.001
max: 10.0
class_weight:
values:
- balanced
- null
decision_threshold:
values:
- 0.4
- 0.5
- 0.6
W&B Sweep Training Function
import wandb
def train_sweep_candidate():
with wandb.init() as run:
model_pipeline = (
create_model_pipeline(
numerical_features=(
numerical_features
),
categorical_features=(
categorical_features
),
regularization_strength=(
run.config[
"regularization_strength"
]
),
random_state=42
)
)
model_pipeline.set_params(
classifier__class_weight=(
run.config[
"class_weight"
]
)
)
model_pipeline.fit(
training_features,
training_labels
)
probabilities = (
model_pipeline.predict_proba(
validation_features
)[:, 1]
)
metrics = calculate_metrics(
true_labels=validation_labels,
probabilities=probabilities,
decision_threshold=(
run.config[
"decision_threshold"
]
)
)
run.log(
{
f"validation_{key}": value
for key, value in metrics.items()
}
)
Automatic Logging vs Explicit Logging
| Area | Automatic Logging | Explicit Logging |
|---|---|---|
| Setup | Requires less logging code | Requires deliberate calls |
| Coverage | Captures supported framework information | Captures project-specific evidence |
| Consistency | Can standardize common framework values | Depends on implementation discipline |
| Control | Limited to integration behavior and options | Provides direct control over names and content |
| Governance Metadata | Usually requires additional explicit tracking | Can record intended use, owner, and approval directly |
Naming and Tagging Strategy
| Field | Example Pattern |
|---|---|
| Experiment or Project | customer-churn-training |
| Run Name | logistic-balanced-c1-threshold06 |
| Task Tag | binary-classification |
| Purpose Tag | threshold-comparison |
| Data Tag | data-version-2026-01 |
| Status Tag | experimental or candidate |
| Owner Tag | Approved team or service identity |
Team Collaboration
Collaboration Practices
- Use shared projects or experiments
- Standardize metric and parameter names
- Assign experiment owners
- Record hypotheses and conclusions
- Link runs to work items or pull requests
- Use tags for task and lifecycle status
- Create reusable comparison reports
- Document failed experiments
- Restrict access according to project sensitivity
- Archive obsolete runs according to policy
Connect Runs to Source Control
git rev-parse HEAD
import subprocess
def get_git_commit():
result = subprocess.run(
[
"git",
"rev-parse",
"HEAD"
],
check=True,
capture_output=True,
text=True
)
return result.stdout.strip()
source_revision = get_git_commit()
mlflow.set_tag(
"code_version",
source_revision
)
run.summary[
"code_version"
] = source_revision
Connect Runs to Data Versions
data_metadata = {
"training_data_version": (
"replace-with-training-version"
),
"validation_data_version": (
"replace-with-validation-version"
),
"test_data_version": (
"replace-with-test-version"
),
"schema_version": "1.0.0",
"feature_definition_version": "1.0.0"
}
mlflow.set_tags(
data_metadata
)
for key, value in data_metadata.items():
run.summary[
key
] = value
Record Experiment Conclusions
{
"hypothesis": "Class weighting may improve recall.",
"controlled_change": "classifier class_weight",
"evaluation_protocol": "approved validation split",
"result_summary": "Populate from calculated experiment evidence.",
"decision": "accept, reject, or investigate",
"limitations": [
"Populate observed limitations",
"Do not infer from unmeasured behavior"
],
"next_action": "Populate the approved next step"
}
Track Model-Selection Evidence
| Selection Area | Evidence to Track |
|---|---|
| Baseline | Metrics and configuration of the meaningful baseline |
| Candidate | Metrics and configuration of the proposed model |
| Error Analysis | Important false positives, false negatives, or residuals |
| Calibration | Probability reliability and Brier score where relevant |
| Group Performance | Approved segment-level metrics with sufficient sample sizes |
| Operational Performance | Latency, memory, throughput, and artifact size |
| Limitations | Known unsupported data and operating conditions |
| Selection Reason | Why the candidate is preferred for the intended use |
Integrate Tracking with an ML Pipeline
Pipeline Integration Requirements
- One traceable run identity
- Pipeline-run identifier
- Component or child-run relationships
- Data and code versions
- Step-specific metrics
- Final model artifact
- Evaluation and quality-gate reports
- Failure status and diagnostics
- Registry relationship
Integrate Tracking with CI/CD
CI/CD Metadata
- Build identifier
- Source revision
- Branch or release reference
- Pipeline definition version
- Runner environment
- Model artifact checksum
- Container-image digest
- Quality-gate result
- Approval status
- Deployment environment
ci_metadata = {
"ci_build_id": (
environment_build_id
),
"source_revision": (
source_revision
),
"pipeline_version": "1.0.0",
"release_status": "candidate"
}
mlflow.set_tags(
ci_metadata
)
Security and Privacy
Required Controls
- Use authenticated access
- Apply project-level authorization
- Use approved storage locations
- Encrypt tracking information
- Keep credentials outside source code
- Do not log access tokens or passwords
- Minimize personal and confidential information
- Review sample predictions before logging them
- Restrict artifact download access
- Define retention and deletion policies
- Audit administrative activity
- Separate experiment and production permissions
Tracking-Server Architecture
| Architecture Area | Responsibility |
|---|---|
| Tracking Client | Logs run metadata, metrics, tags, and artifacts |
| Tracking Service | Receives and presents tracking information |
| Metadata Store | Stores experiments, runs, parameters, metrics, and tags |
| Artifact Store | Stores model files, reports, plots, and larger outputs |
| Identity Layer | Controls who may log, read, modify, or administer records |
| Backup and Recovery | Protects experiment and artifact history |
Retention and Run Hygiene
Run-Hygiene Practices
- Use consistent project and experiment names
- Tag temporary and smoke-test runs
- Mark failed runs clearly
- Record conclusions before closing significant work
- Remove duplicate artifacts according to policy
- Archive obsolete experiments
- Preserve approved and production-related runs
- Apply retention according to legal and privacy requirements
- Do not delete evidence related to active incidents
Responsible Experiment Tracking
Responsible-AI Evidence
- Intended and prohibited uses
- Data authorization and limitations
- Target definition
- Prediction-time assumptions
- Relevant group-level metrics
- Error analysis
- Calibration evidence
- Known model limitations
- Human-oversight requirements
- Approval status
- Model-card artifact
- Fallback and rollback requirements
Common Experiment-Tracking Mistakes
Recommended Experiment-Tracking Workflow
Define the Hypothesis
State the question, controlled change, expected result, and evaluation protocol.
Identify the Inputs
Record code, data, features, configuration, environment, and random-state versions.
Start a Tracked Run
Create a run under the correct project or experiment and assign a meaningful name and purpose.
Log Parameters and Tags
Record model configuration, data references, ownership, lifecycle status, and intended use.
Train the Candidate
Execute the reproducible training workflow and capture runtime information.
Log Measured Metrics
Record validation metrics, metric history, threshold evidence, and relevant group results.
Log Artifacts
Preserve the model, evaluation reports, plots, schemas, metadata, and model card.
Compare Compatible Runs
Review quality, errors, calibration, stability, latency, resources, and limitations.
Record the Conclusion
Document whether the hypothesis was supported and what action should follow.
Register or Reject
Submit a suitable candidate to the controlled model-lifecycle workflow or preserve the reason for rejection.
Hands-On Practice
Create an Experiment Plan
Define a hypothesis, controlled change, fixed inputs, evaluation metrics, and acceptance criteria.
Track a Run with MLflow
Log parameters, calculated validation metrics, tags, model artifact, input example, and model signature.
Use MLflow Autologging
Compare the automatically captured information with your project-specific tracking requirements.
Track the Same Run with W&B
Log equivalent configuration, metrics, tags, notes, and model artifacts.
Create a Run Comparison
Compare compatible models using multiple quality and operational measures.
Track Threshold Analysis
Log validation results for several thresholds without using the final test set.
Track an Artifact
Version a model or approved dataset reference with metadata and lineage.
Audit Reproducibility
Confirm that the selected run identifies its code, data, features, configuration, environment, metrics, and artifacts.
Knowledge Check
What is experiment tracking?
Explain how it records and organizes run inputs, settings, metrics, artifacts, context, and conclusions.
What is the difference between an experiment and a run?
Explain that an experiment or project groups related work, while a run represents one execution.
What is the difference between a parameter and a metric?
Explain configuration inputs compared with measured outputs.
What is an experiment artifact?
Explain saved models, reports, plots, schemas, tables, and other run outputs.
What does MLflow Tracking record?
Explain runs, parameters, code versions, metrics, tags, output files, and logged models.
What does a W&B Run contain?
Explain configuration, metric history, summary values, tags, notes, tables, and artifacts.
Why is autologging not always enough?
Explain project-specific data versions, hypotheses, thresholds, limitations, governance, and conclusions.
Why should only compatible runs be compared?
Explain differences in datasets, targets, metrics, splits, thresholds, and label maturity.
Why track failed experiments?
Explain troubleshooting, prevention of repeated work, and preservation of useful conclusions.
Does the best tracked metric automatically identify the production model?
Explain the need for independent testing, error analysis, calibration, group evaluation, operational checks, security, governance, and approval.
Experiment-Tracking Readiness Checklist
Confirm Before Team Adoption
- Approved tracking infrastructure is selected
- Authentication and authorization are configured
- Project and experiment naming standards are documented
- Run-naming standards are documented
- Metric names and definitions are standardized
- Parameter names are standardized
- Required tags are defined
- Every run receives an immutable identifier
- The source-code revision is recorded
- Training and evaluation data versions are recorded
- Feature-definition versions are recorded
- Random states are recorded where applicable
- Environment versions are recorded
- Decision thresholds are recorded
- Actual evaluation metrics are logged
- Metric history is logged where useful
- Artifacts are organized consistently
- Input examples are reviewed for privacy
- Model signatures or schemas are tracked
- Failed runs preserve useful diagnostics
- Experiment conclusions are documented
- Only compatible runs are compared
- Hyperparameter searches use an approved validation protocol
- The final test set remains independent
- Sensitive data is minimized
- Credentials are kept out of code and logs
- Artifact access is restricted
- Retention and deletion policies are defined
- Tracked candidates flow into a controlled registry process
- Experiment history is backed up where required
Lesson Summary
| Tracking Area | Main Outcome |
|---|---|
| Experiment | Groups related investigations |
| Run | Represents one tracked execution |
| Parameter | Records a configuration value |
| Metric | Records measured model or system behavior |
| Metric History | Tracks behavior over epochs, steps, or time |
| Tag | Adds searchable descriptive context |
| Artifact | Preserves models, reports, plots, schemas, and outputs |
| MLflow Tracking | Logs experiments, runs, parameters, metrics, tags, and artifacts |
| MLflow Autologging | Automatically captures supported framework information |
| W&B Experiments | Tracks configuration, metric history, summaries, and system information |
| W&B Artifacts | Versions datasets, models, and other experiment outputs |
| Run Comparison | Supports evidence-based candidate analysis |
| Source and Data Lineage | Supports reproducibility and investigation |
| Security | Protects credentials, data, artifacts, and project access |
| Governance | Preserves hypotheses, limitations, ownership, conclusions, and approval evidence |
Key Takeaway
Experiment tracking creates an organized and reproducible history of Machine Learning development. Each run should identify the question being tested, the code and data versions, feature definitions, configuration, random state, environment, calculated metrics, generated artifacts, and final conclusion. MLflow provides tracking APIs and interfaces for runs, parameters, metrics, tags, artifacts, logged models, and model lifecycle workflows. Weights & Biases provides run configuration, metric history, dashboards, tables, reports, artifacts, and hyperparameter-sweep workflows. Neither platform replaces sound experiment design. Reliable model selection still requires compatible evaluation conditions, independent testing, error analysis, calibration, relevant group evaluation, operational testing, security review, governance, and controlled approval.
Get Machine Learning updates by email
Short, practical lessons and course updates from Rumman Ansari. No spam.