Reference PyTorch implementation of ECHO (Environment-Calibrated Hydroacoustic Observation) for body-weight-normalized feed-intake estimation from passive acoustic monitoring of Litopenaeus vannamei.
Associated manuscript: Environment-Calibrated Feed Intake Estimation of Litopenaeus vannamei Using Passive Acoustic Monitoring.
The repository implements the pipeline described in the manuscript:
- offline 96-kHz waveform to log-Mel preprocessing;
- condition-level train/validation/test splitting;
- recording-wise normalization and MBConv-SE-SimAM acoustic tokenization;
- state-level context calibration in selective state-space blocks;
- attention pooling and feature-level context calibration;
- Huber-loss regression;
- context-only, acoustic-only, append-only, ablation, FiLM, CNN-BiGRU, and handcrafted XGBoost baselines.
The paper fixes the log-Mel parameters, 200-s input window, latent dimension,
number of state-space blocks, training schedule, and calibration equations.
Some low-level architecture choices are not uniquely specified in the paper,
including individual MBConv channel widths and estimation-head widths. They are
therefore exposed in configs/echo.yaml as reference defaults. Before an
archival release, replace these defaults with the exact settings used for the
reported experiments and publish the exact condition split file.
The private shrimp recordings and labels are not included. The code can be
tested with synthetic tensors and can be trained once a manifest and .npy
log-Mel files are supplied.
Linux/macOS:
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -e .Windows PowerShell:
python -m venv .venv
.venv\Scripts\activate
python -m pip install --upgrade pip
pip install -e .For the official CUDA Mamba implementation on a supported Linux environment:
pip install -e ".[mamba]"Without mamba-ssm, mamba_backend: auto uses a transparent pure-PyTorch
selective-SSM fallback. The fallback is useful for tests and portability but is
slower than the official fused implementation.
For the handcrafted baseline:
pip install -e ".[xgboost]"The following commands exercise the complete data-loading, training, checkpointing, and evaluation path without access to the private recordings:
python scripts/create_synthetic_data.py \
--output-dir data/synthetic \
--frames 1024
python scripts/train.py --config configs/smoke.yaml
python scripts/evaluate.py \
--checkpoint runs/smoke/best.pt \
--manifest data/synthetic/manifest.csv \
--output runs/smoke/evaluated.csvSynthetic data are intended only for software validation and must not be used to assess scientific performance.
See data/manifest.example.csv. Required fields are:
| Field | Meaning |
|---|---|
record_id |
Unique acoustic-context-intake record identifier |
mel_path |
Path to a [64, time] log-Mel .npy tensor |
body_weight |
Nominal body-weight level encoded as 1, 3, 6, or 9 |
ammonia |
Ammonia nitrogen concentration in mg/L |
nitrite |
Nitrite nitrogen concentration in mg/L |
density |
Stocking density in pcs/m^3 |
target |
Body-weight-normalized feed intake in g/g |
split |
train, validation, or test |
The optional handcrafted columns are pulse_count, highest_frequency,
lowest_frequency, and mean_spl.
python scripts/preprocess_audio.py \
--manifest data/manifest.csv \
--output-dir data/melDefaults follow the paper: mono 96 kHz, discard the first 10 s, Hann window,
n_fft=1024, window length 1024, hop length 512, 64 Mel bins, 2-16 kHz, and
log(S + epsilon). Tensors are stored as float16. Standard uncompressed PCM
WAV files can also be read through the built-in fallback when the local
torchaudio installation has no audio backend.
If the manifest does not already contain a split:
python scripts/make_split.py \
--manifest data/manifest.csv \
--output data/manifest.split.csv \
--seed 42All records sharing (body_weight, ammonia, nitrite, density) remain in one
subset. For exact paper reproduction, use the archived official split rather
than regenerating it from a seed alone.
python scripts/train.py --config configs/echo.yaml
python scripts/evaluate.py \
--checkpoint runs/echo/best.pt \
--manifest data/manifest.csv \
--output runs/echo/test_predictions.csvChange model.name to one of:
echo
acoustic_only
context_only
append_only
representation_concat
head_gate
feature_only
state_only
film
cnn_bigru
Run the handcrafted model with the same manifest and split:
python scripts/train_xgboost.py \
--manifest data/manifest.csv \
--output-dir runs/xgboostFor confidence intervals that respect the condition-level sampling unit, merge model predictions into one CSV and run:
python scripts/paired_bootstrap.py \
--predictions runs/combined_predictions.csv \
--manifest data/manifest.csv \
--model-a echo \
--model-b append_only \
--output runs/bootstrap_echo_vs_append.jsonpython -m unittest discover -s tests -vThe tests create short synthetic log-Mel tensors, check condition-level split isolation, execute ECHO forward/backward passes, and run a two-epoch training smoke test.
configs/ Paper-scale and smoke-test configurations
data/ Manifest schema example
scripts/ Preprocessing, training, evaluation, and analysis CLIs
src/echo_pam/ ECHO models and reusable training/data modules
tests/ Unit and end-to-end smoke tests
ECHO is a research implementation, not a closed-loop feeding controller or a validated animal-welfare decision system. Performance outside the biological, water-quality, and farming conditions represented by the training data has not been established. See MODEL_CARD.md for the intended use, known limitations, and reproducibility scope.
Contributions are welcome. Please read CONTRIBUTING.md and the Code of Conduct before opening an issue or pull request. Security-sensitive reports should follow SECURITY.md.
Citation metadata are provided in CITATION.cff. The article citation and DOI will be added after publication.
This project is released under the MIT License.