Model Card for aquaculture_oysters
Model Details
A fine-tuned YOLO11 model for sizing aquaculture oyster sample populations
Model Description
This model detects two object classes: triploid Crassostrea virginica oysters from various stages of aquaculture production and round sizing standards. Size standards should be flat disk-like objects. It was fine-tuned from the Ultralytics YOLO11n pretrained object detection model by using custom images of various sampled oyster populations and various different size standards.
- Developed by: Craig S. Echt
- Model type: Object Detection
- Language(s) (NLP): American English
- License: gpl-3.0
- Finetuned from model: yolo11n
Model Sources
Uses
Its intended use is calculation of oyster population size metrics from filtered bounding box coordinates in images of dozens to hundreds of oysters that include one or a few disks of known diameter. It may be helpful to oyster farmers and researchers as an alternative to rough size estimates from tumblers or manual sizing of individual oysters.
Direct Use
A full GUI application is available at https://github.com/csecht/oyster-sizer.
An abbreviated demo Python script is below.
Bias, Risks, and Limitations
The model is not trained to distinguish between oysters and other bivalve species, e.g. scallops. Its intended use is with samples of aquaculture oyster populations at a particular stage of growth. That is, populations that are not mixed with other shell types. It may be possible, however, to use to size sample populations of bivalves.
How to Get Started with the Model
Download these files into a local folder: aquaculture_oysters.pt, oyster_sample.jpg, oysters.py. The python script in oysters.py is printed below.
From within the local folder, create a new venv virtual environment (using whatever venv folder name you like; here oyster_venv is used):
python3 -m venv oyster_venv
Activate this new virtual environment:
source oyster_venv/bin/activate
(Linux and macOS)
oyster_venv\Scripts\activate
(Windows)
Update the PIP installer and install the most recent Ultralytics package in the active virtual environment.
python3 -m pip install --upgrade pip
python3 -m pip install ultralytics
Run oysters.py:
python3 -m oysters
oysters.py code:
"""
Python3 script for YOLO prediction and sizing of oyster objects.
"""
from ultralytics import YOLO
# Locally written directories
results_dir = 'oyster_yolo_results'
predict_name = 'example_oyster_results'
# Files from this aquaculture_oysters HF repository
model = YOLO('aquaculture_oysters.pt')
oyster_img = 'oyster_sample.jpg'
# The size standard disk diameter. In this case, as millimeters,
# using a cutout from a 3 inch hockey puck.
std_mm = 76.2
# Run inference with these arguments
prediction_kwargs = dict(
save=True, # saves image to project/name
save_txt=True, # saves relative bounding box coordinates
save_conf=True, # includes conf scores
augment=False,
show_labels=True,
line_width=2,
project=results_dir,
name=predict_name,
exist_ok=False,
)
results = model.predict(
source=oyster_img,
half=False,
imgsz=960,
conf=0.7,
device='cpu',
iou=0.7,
max_det=400,
classes=[0,1], # 0 is 'disk', 1 is 'oyster'.
**prediction_kwargs
)
# Display detection bounding boxes with class names and confidence values.
results[0].show(line_width=2)
# Calculate and print size metrics, Are based on longest bounding box dimension.
# Sizes do not account for longer lengths of oysters oriented on the diagonal.
# An empirically determined correction factor is recommended for better accuracy.
# A good correction function is used in the companion GitHub repository.
boxes_tensor = results[0].boxes.xywh
boxes_numpy = boxes_tensor.cpu().numpy().astype(int)
w_h = boxes_numpy[:, 2:4]
px_lengths = w_h.max(axis=1)
classes = results[0].boxes.cls
class_distribution = classes.cpu().numpy().astype(int)
num_disks = len(class_distribution[class_distribution == 0])
num_oysters = len(class_distribution[class_distribution == 1])
oyster_px_sizes = px_lengths[class_distribution == 1]
disk_px_sizes = px_lengths[class_distribution == 0]
px2mm_factor = std_mm / disk_px_sizes.mean()
oyster_mean_mm = round(oyster_px_sizes.mean() * px2mm_factor, 2)
smallest = round(oyster_px_sizes.min() * px2mm_factor, 2)
largest = round(oyster_px_sizes.max() * px2mm_factor, 2)
print(f'Mean oyster size, mm: {oyster_mean_mm}')
print(f'Oyster size range, mm: [{smallest} -- {largest}]')
Training Details
Training Data
The images and yolo-formatted labels used for training and validation (testing) are in those respective folders under Files and versions of this repository. Images are also in the aquaculture-oysters Dataset. These data have just two classes, disk and oyster.
Training Procedure
Versions and resources: Ultralytics 8.3.38 Python-3.12.3 torch-2.5.1+cu124 CUDA:0 (NVIDIA GeForce RTX 4070, 12002MiB)
Initial PyTorch training with yolo11n.pt weights was for 125 epochs, an image size of 960, batch size of 20, and the AdamW optimizer.
The resulting best.pt model was then tuned for 50 epochs over 300 iterations.
Hyperparameters from that best tune iteration, #233, were used to fine-tune the initial oyster model:
hyperparam_args233 = {
'lr0': 0.00242,
'lrf': 0.01009,
'momentum': 0.92746,
'weight_decay': 0.00038,
'warmup_epochs': 1.94011,
'warmup_momentum': 0.47865,
'box': 5.89996,
'cls': 0.27165,
'dfl': 1.23119,
'hsv_h': 0.01303,
'hsv_s': 0.32101,
'hsv_v': 0.40969,
'degrees': 0.0,
'translate': 0.15574,
'scale': 0.75304,
'shear': 0.0,
'perspective': 0.0,
'flipud': 0.0,
'fliplr': 0.58715,
'bgr': 0.0,
'mosaic': 1.0,
'mixup': 0.0,
'copy_paste': 0.0,
}
Weights of the resulting best.pt (renamed here as aquaculture_oysters.pt) gave a mAP50-95(B) of 0.93349.
Results
Using the oyster_sample.jpg image with the oyster.py script, expected Terminal output and sizing results:
image 1/1 /home/craig/Desktop/oyster_sample.jpg: 960x768 3 disks, 105 oysters, 2903.9ms
Speed: 13.3ms preprocess, 2903.9ms inference, 28.1ms postprocess per image at shape (1, 3, 960, 768)
Results saved to oyster_yolo_results/example_oyster_results
1 label saved to oyster_yolo_results/example_oyster_results/labels
Mean oyster size, mm: 58.71
Oyster size range, mm: [47.22 -- 69.1]
Resulting image (2928 x 3761), saved to the oyster_yolo_results folder: