Workflow for: Using transfer and active learning to improve BirdNET detection of nocturnal birds from PAM in a Neotropical forest
Abstract
Retraining BirdNET with an Active Learning Approach Overview BirdNET is a convolutional neural network (CNN) trained to recognize the sounds of over 6,500 birds, other animals, and some environmental sounds. Developed by the team at the K. Lisa Yang Center for Conservation Bioacoustics (Kahl et al. 2021), this tool is a powerful resource for automating species detection in large-scale acoustic datasets. However, BirdNET may underperform when applied to low-quality Passive Acoustic Monitoring (PAM) recordings (e.g., AudioMoth), especially in underrepresented regions like the Neotropics, due to biases in its training data and environmental mismatch. Project Goals This project aims to improve BirdNET’s performance for detecting rare nocturnal birds (e.g., owls, caprimulgids) in the Atlantic Forest of Argentina using 7,000 hours of low-cost PAM data. Our goals were to: - Improve BirdNET detection and classification of the target classes in PAM recordings from AudioMoth. - Enable adaptation with minimal computational resources. - Provide a replicable, low-barrier workflow for researchers with limited coding/ML experience. We share the description of our workflow and a set of Jupyter Notebooks (.ipynb) that were used to implement our workflow. The notebooks are intended to be adapted and reused by anyone who finds them useful. Notebooks are also provided in `.html` format for easy viewing. Workflow Preprocessing: Preparing the Initial Training Set For the first retraining of BirdNET, we used 100 3-second clips per class, organized in folders named after each target species, following this example structure: training-set/├── Rusty-barred Owl_Strix hylophila/│ ├── LOC001_REC01_20220103_221500_Strix-hylophila.wav│ ├── LOC001_REC01_20220103_221803_Strix-hylophila_1.wav│ └── ...├── Mottled Owl_Strix virgata/│ ├── LOC002_REC03_20211215_200512_Strix-virgata.wav│ ├── LOC002_REC03_20211215_200815_Strix-virgata_1.wav│ └── ... ├── Spectacled Owl_Pulsatrix perspicillata/│ └── ...└── Background/ └── ... Each .wav file is 3 seconds long. If longer, BirdNET will trim the file (e.g., using the first or center 3 seconds, depending on parameters). Filenames follow this structure: LOCATION_RECORDERID_DATE_TIME_Species.wav.Be cautious: several notebooks use core_name logic that splits the filename using _, so changes in naming conventions might require modifications. Folder names follow the BirdNET class naming format: Common Name_Scientific name. However, any consistent format is valid as long as each class has a unique label. However, for some rare species with insufficient field recordings, we augmented the training data using library clips overlaid with PAM background noise to better match real-world acoustic conditions. See the notebook: Noise-overlay.ipynb 🔁 Active Learning Loop This section outlines how to identify informative clips for human validation, in order to iteratively enrich the training set with PAM (Passive Acoustic Monitoring) recordings—helping BirdNET adapt to a new acoustic domain. Why Work on a Subset? The active learning loop is implemented using BirdNET’s train.py script. This script re-analyzes the audio files from scratch in each iteration, even though the acoustic features (embeddings) remain the same and only the classification head is updated. ⚠️ Sound analysis is the most computationally intensive step, and re-processing thousands of hours of raw PAM audio at each iteration can be infeasible on an ordinary computer. To reduce the computational load, we ran BirdNET (both the original and custom classification head versions) on a stratified 20% subset of our full PAM dataset. Stratification ensured the subset preserved the structure of our field soundscape (e.g., time-of-day, habitat types). We included 20% more clips from forest sites compared to other environments. This was based on two reasons: Acoustic complexity is greater in forests (denser species community, sound overlap). Sound propagation is lower in forests, so more clips were needed to capture equivalent information. This allowed us to prioritize model improvement for forest-dwelling species while keeping the subset manageable for local processing. In the uncertainty sampling and random sampling notebooks, you'll find a variable named: audio_files_dir = '/directory/where/unlabeled/PAM-recordings/is/' This can refer to: Your entire PAM dataset, or A stratified subset, such as the one we used, which is ideal for use in limited-resource environments. 0. Create a Stratified Subset of Unlabeled PAM Recordings Notebook: Stratified-subset_unlabeledPAM.ipynb This notebook helps create a representative subset of your field recordings, optionally excluding files already used in previous iterations (if a .txt file listing them is provided).You can adjust the number of clips per habitat type, time period (e.g., Dawn, Dusk), or site as needed.If you want balanced sampling across environments (rather than prioritizing one), you can modify the logic accordingly. After Audio Analysis (on Full Dataset or Subset) Once you've analyzed your selected audio with BirdNET (or a custom head), proceed with: 1. Track Training Set Composition 📄 Training-set-tracker.ipynb Re-run after each update to the training set. 2. Uncertainty Sampling – Iteration 1 📄 Uncertainty-Sampling.ipynb Select clips for human validation. 3. Manual Validation: - Validate clips using Raven Pro or another tool. - Rename files to include confirmed class. - Move validated files to class folders. 4. After validating your top-scoring clips per class, compute precision. You can use the notebook Precision.ipynb. Create a DataFrame with columns class and precision. Save this DataFrame as a .csv file in a specified directory. This precision file will be used by the uncertainty sampling notebook from iteration 2 onwards to adapt the sampling per class according to their precision. 5. Update Training Set TrackerRe-run the Training-set-tracker.ipynb Notebook and update the iteration parameter in the code: current_iteration = 1 *Update this for each new iteration 6. Perform Random Sampling: Run Random-sampling.ipynb 7. Repeat Steps: 3, then proceed to step 5. **Additional Notes - From Iteration 2 onward, include your `precision.csv` in the uncertainty sampling notebook. - Helper classes (e.g., frogs, non-target birds) can be included in the model but excluded from random sampling. Model training After updating the training set using uncertainty and random sampling. We trained a new model using this new updated training set. 📊 Model Evaluation After completing the training of a new customized model (i.e. after each active learning iteration), we evaluated the model using a test set. The test set consisted of fully annotated recordings containing all the classes included in the model classification head. With these annotated recordings we build an annotated dataframe matching each recording and indicating whether in each of the 3 s segments of each recording a specific class was present (1) or absent (0), known as one-hot-encoded dataframe. With that dataframe and with the BirdNET predictions outputted as continuous scores ranging 0–1 we computed classification metrics. Test Set Preparation📄 One-hot-label_testset.ipynb ; Model-predictions-evalset.ipynbThese notebooks create: A one-hot-encoded test set (binary labels) A continuous score dataframe with BirdNET’s (or a customized BirdNET’s) prediction scores [0, 1] on 3 s segments. Multiclass performance metric: macro mAP📄 Model-evaluation_macro mAP.ipynbComputes Mean Average Precision (mAP) across all classes. Per-class performance metric across Active Learning iterations📄 Model-evaluation_per-class-AP-across-iterations.ipynbComputes and visualizes per-class Average Precision (AP) for each model version (off-the-shelf BirdNET and all customized models trained across active learning rounds). This notebook is useful to track the effect of each iteration on each species' detection performance. --- Requirements These notebooks are written in Python using Jupyter Lab and rely on packages such as numpy, pandas, opensoundscape, pydub, matplotlib, and scikit-learn. Dependencies were managed using Anaconda 3.
Fields of Study & Subjects
Music and Audio Processing
Animal Vocal Communication and Behavior
Speech Recognition and Synthesis
Publication details
- Journal / source
- Zenodo (CERN European Organization for Nuclear Research)
- Publication date
- 9 February 2026
- Language
- EN