I am working with YOLO26.pt to segment images. I would like to know how YOLO choses the best epoch to save the trained model best.pt.
I looked for some information, seems it choses the best model based on the metric mAp50 - 95 of Box and Mask. Is it true?
If it is true, as I am working with image segmentation, would make sense to use only metrics of mask to chose the best model? If yes, how would I do this?
Thanks in advance.
Toxite
August 20, 2026, 3:52pm
2
It chooses by taking sum of box and mask mAP50-95.
If you want to update it to only use segmentation metrics, you would have to change the code and remove the detection metrics part.
Doesn’t necessarily make it better. Accurate masks also require accurate boxes.
return DetMetrics.class_result(self, i) + self.seg.class_result(i)
@property
def maps(self) -> np.ndarray:
"""Return mAP scores for object detection and segmentation models."""
return DetMetrics.maps.fget(self) + self.seg.maps
@property
def fitness(self) -> float:
"""Return the fitness score for both segmentation and bounding box models."""
return self.seg.fitness() + DetMetrics.fitness.fget(self)
@property
def curves(self) -> list[str]:
"""Return a list of curves for accessing specific metrics curves."""
return [
*DetMetrics.curves.fget(self),
"Precision-Recall(M)",
"F1-Confidence(M)",
"Precision-Confidence(M)",
"Recall-Confidence(M)",
Thank you Toxite,
Is there a way to analyse the file results.cvs and find the epoch that YOLO used to saved the best.pt?
Toxite
August 20, 2026, 4:02pm
4
Yes, you can use some code to get it. I got this from the Ask AI bot. You can also use that. It’s in our docs page and can generate custom code like these.
import pandas as pd
csv_path = "runs/segment/train/results.csv"
df = pd.read_csv(csv_path)
df.columns = df.columns.str.strip()
df["fitness"] = (
df["metrics/mAP50-95(B)"].fillna(0)
+ df["metrics/mAP50-95(M)"].fillna(0)
)
best_fitness = df["fitness"].max()
# Select the last matching epoch, consistent with best.pt on equal fitness
best_row = df[df["fitness"] == best_fitness].iloc[-1]
print(f"Best epoch: {int(best_row['epoch'])}")
print(f"Best fitness: {best_row['fitness']:.6f}")
print(f"Box mAP50-95: {best_row['metrics/mAP50-95(B)']:.6f}")
print(f"Mask mAP50-95: {best_row['metrics/mAP50-95(M)']:.6f}")
You’re welcome! Selecting the last maximum-fitness row also matches how best.pt is overwritten if multiple epochs have equal fitness.
Thank you for this information!
You’re welcome! Glad the explanation helped clarify how best.pt corresponds to the best fitness epoch.