canapy 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- canapy-0.1.0/LICENSE +29 -0
- canapy-0.1.0/PKG-INFO +213 -0
- canapy-0.1.0/README.md +166 -0
- canapy-0.1.0/canapy/__init__.py +15 -0
- canapy-0.1.0/canapy/annotator/__init__.py +63 -0
- canapy-0.1.0/canapy/annotator/base.py +243 -0
- canapy-0.1.0/canapy/annotator/commons/__init__.py +3 -0
- canapy-0.1.0/canapy/annotator/commons/compat.py +28 -0
- canapy-0.1.0/canapy/annotator/commons/esn.py +102 -0
- canapy-0.1.0/canapy/annotator/commons/mfccs.py +144 -0
- canapy-0.1.0/canapy/annotator/commons/postprocess.py +177 -0
- canapy-0.1.0/canapy/annotator/ensemble.py +359 -0
- canapy-0.1.0/canapy/annotator/nsynannotator.py +268 -0
- canapy-0.1.0/canapy/annotator/synannotator.py +242 -0
- canapy-0.1.0/canapy/corpus.py +558 -0
- canapy-0.1.0/canapy/correction/__init__.py +4 -0
- canapy-0.1.0/canapy/correction/base.py +106 -0
- canapy-0.1.0/canapy/formats/__init__.py +6 -0
- canapy-0.1.0/canapy/formats/marron1csv.py +193 -0
- canapy-0.1.0/canapy/log.py +21 -0
- canapy-0.1.0/canapy/metrics/__init__.py +4 -0
- canapy-0.1.0/canapy/metrics/base.py +115 -0
- canapy-0.1.0/canapy/metrics/utils.py +71 -0
- canapy-0.1.0/canapy/optimization.py +906 -0
- canapy-0.1.0/canapy/plots/__init__.py +4 -0
- canapy-0.1.0/canapy/plots/base.py +272 -0
- canapy-0.1.0/canapy/timings/__init__.py +4 -0
- canapy-0.1.0/canapy/timings/base.py +78 -0
- canapy-0.1.0/canapy/transforms/__init__.py +5 -0
- canapy-0.1.0/canapy/transforms/base.py +96 -0
- canapy-0.1.0/canapy/transforms/commons/__init__.py +3 -0
- canapy-0.1.0/canapy/transforms/commons/annots.py +99 -0
- canapy-0.1.0/canapy/transforms/commons/audio.py +225 -0
- canapy-0.1.0/canapy/transforms/commons/training.py +193 -0
- canapy-0.1.0/canapy/transforms/nsynesn.py +193 -0
- canapy-0.1.0/canapy/transforms/synesn.py +15 -0
- canapy-0.1.0/canapy/utils/__init__.py +11 -0
- canapy-0.1.0/canapy/utils/arrays.py +70 -0
- canapy-0.1.0/canapy/utils/exceptions.py +13 -0
- canapy-0.1.0/canapy/utils/tempstorage.py +20 -0
- canapy-0.1.0/config/__init__.py +27 -0
- canapy-0.1.0/config/config.py +151 -0
- canapy-0.1.0/config/default/default.config.toml +62 -0
- canapy-0.1.0/config/presets/bengalese_finch.toml +64 -0
- canapy-0.1.0/config/presets/canary.toml +62 -0
- canapy-0.1.0/config/presets/infant_marmoset.toml +64 -0
- canapy-0.1.0/config/presets/mouse_binary_classification.toml +64 -0
- canapy-0.1.0/config/presets/zebra_finch.toml +64 -0
- canapy-0.1.0/config/store/default.config.toml +62 -0
- canapy-0.1.0/config/store/default.config.yml +404 -0
- canapy-0.1.0/config/template/default.config.toml +61 -0
- canapy-0.1.0/dashboard/__init__.py +6 -0
- canapy-0.1.0/dashboard/__main__.py +299 -0
- canapy-0.1.0/dashboard/app.py +105 -0
- canapy-0.1.0/dashboard/controler/__init__.py +4 -0
- canapy-0.1.0/dashboard/controler/base.py +1153 -0
- canapy-0.1.0/dashboard/controler/corpusutils.py +30 -0
- canapy-0.1.0/dashboard/controler/segments.py +89 -0
- canapy-0.1.0/dashboard/view/__init__.py +3 -0
- canapy-0.1.0/dashboard/view/annotate/__init__py +0 -0
- canapy-0.1.0/dashboard/view/annotate/annotate_dash.py +472 -0
- canapy-0.1.0/dashboard/view/eval/__init__.py +3 -0
- canapy-0.1.0/dashboard/view/eval/classmerge.py +499 -0
- canapy-0.1.0/dashboard/view/eval/eval_dash.py +239 -0
- canapy-0.1.0/dashboard/view/eval/samplecorrection.py +377 -0
- canapy-0.1.0/dashboard/view/export/__init__.py +3 -0
- canapy-0.1.0/dashboard/view/export/export_dash.py +333 -0
- canapy-0.1.0/dashboard/view/helpers.py +600 -0
- canapy-0.1.0/dashboard/view/home/__init__.py +3 -0
- canapy-0.1.0/dashboard/view/home/home_dash.py +172 -0
- canapy-0.1.0/dashboard/view/loaddata/__init__.py +3 -0
- canapy-0.1.0/dashboard/view/loaddata/load_data_dash.py +617 -0
- canapy-0.1.0/dashboard/view/preprocess/__init__.py +3 -0
- canapy-0.1.0/dashboard/view/preprocess/preprocess_dash.py +1601 -0
- canapy-0.1.0/dashboard/view/settings/__init__.py +3 -0
- canapy-0.1.0/dashboard/view/settings/settings_dash.py +1077 -0
- canapy-0.1.0/dashboard/view/train/__init__.py +3 -0
- canapy-0.1.0/dashboard/view/train/train_dash.py +449 -0
- canapy-0.1.0/pyproject.toml +69 -0
canapy-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024, neuronalX
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its contributors
|
|
17
|
+
may be used to endorse or promote products derived from this software
|
|
18
|
+
without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
canapy-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: canapy
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: canapy is a user friendly auto annotator for animal vocalizations using reservoir computing
|
|
5
|
+
License: BSD-3-Clause
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Author: Axel Arnaud
|
|
8
|
+
Author-email: axel.arnaud@inria.fr
|
|
9
|
+
Requires-Python: >=3.11,<3.12
|
|
10
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Requires-Dist: Levenshtein (==0.21.1)
|
|
14
|
+
Requires-Dist: PyYAML (==6.0.3)
|
|
15
|
+
Requires-Dist: attrs (==23.2.0)
|
|
16
|
+
Requires-Dist: audioread (==3.1.0)
|
|
17
|
+
Requires-Dist: bokeh (==3.2.2)
|
|
18
|
+
Requires-Dist: click (==8.3.1)
|
|
19
|
+
Requires-Dist: crowsetta (==5.1.0)
|
|
20
|
+
Requires-Dist: hyperopt (==0.2.7)
|
|
21
|
+
Requires-Dist: ipykernel (==6.29.4)
|
|
22
|
+
Requires-Dist: joblib (==1.5.2)
|
|
23
|
+
Requires-Dist: jupyter (==1.1.1)
|
|
24
|
+
Requires-Dist: librosa (==0.10.2.post1)
|
|
25
|
+
Requires-Dist: matplotlib (==3.10.7)
|
|
26
|
+
Requires-Dist: multimethod (<2.0)
|
|
27
|
+
Requires-Dist: numba (>=0.58,<0.59)
|
|
28
|
+
Requires-Dist: numpy (==1.26)
|
|
29
|
+
Requires-Dist: pandas (==2.3.3)
|
|
30
|
+
Requires-Dist: pandera (==0.15.2)
|
|
31
|
+
Requires-Dist: panel (==1.2.3)
|
|
32
|
+
Requires-Dist: param (==1.13.0)
|
|
33
|
+
Requires-Dist: pillow (==12.0.0)
|
|
34
|
+
Requires-Dist: py4j (==0.10.9.9)
|
|
35
|
+
Requires-Dist: pydantic (==1.10.24)
|
|
36
|
+
Requires-Dist: pydub (==0.25.1)
|
|
37
|
+
Requires-Dist: requests (==2.32.5)
|
|
38
|
+
Requires-Dist: reservoirpy (>=0.4.0,<0.5.0)
|
|
39
|
+
Requires-Dist: scikit-learn (==1.7.2)
|
|
40
|
+
Requires-Dist: scipy (==1.15.3)
|
|
41
|
+
Requires-Dist: setuptools (==68.2.2)
|
|
42
|
+
Requires-Dist: soundfile (==0.13.1)
|
|
43
|
+
Requires-Dist: toml (==0.10.2)
|
|
44
|
+
Requires-Dist: tqdm (==4.67.1)
|
|
45
|
+
Description-Content-Type: text/markdown
|
|
46
|
+
|
|
47
|
+
# Canapy
|
|
48
|
+
|
|
49
|
+
**Automatic audio annotation tools for animal vocalizations**
|
|
50
|
+
|
|
51
|
+
--------
|
|
52
|
+
|
|
53
|
+
Canapy trains automatic annotators for animal vocalizations using [Reservoir Computing](https://reservoirpy.readthedocs.io/) (Echo State Networks). It comes with an interactive dashboard to guide you through the full pipeline: dataset preparation, model training, evaluation, and annotation.
|
|
54
|
+
|
|
55
|
+
> For the full reference documentation, see [README_extended.md](README_extended.md).
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
git clone git@github.com:birds-canopy/canapy.git
|
|
61
|
+
pip install -e canapy/.
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Quick start
|
|
65
|
+
|
|
66
|
+
### 1. Prepare your dataset
|
|
67
|
+
|
|
68
|
+
You need hand-labeled audio recordings. Annotations should be `.csv` files in **marron1csv** format (columns: `wave`, `start`, `end`, `syll`). Audio must be mono WAV files.
|
|
69
|
+
|
|
70
|
+
Recommended structure:
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
song_dataset/
|
|
74
|
+
├── annotations/
|
|
75
|
+
│ ├── song1.csv
|
|
76
|
+
│ └── song2.csv
|
|
77
|
+
└── audio/
|
|
78
|
+
├── song1.wav
|
|
79
|
+
└── song2.wav
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
or
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
song_dataset/
|
|
86
|
+
├── song1.wav
|
|
87
|
+
├── song1.csv
|
|
88
|
+
├── song2.wav
|
|
89
|
+
└── song2.csv
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Aim for 30 min–1 hour of annotated data (10 min can already give good results on canary songs).
|
|
93
|
+
|
|
94
|
+
### 2. Launch the dashboard
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
canapy dash
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The dashboard opens automatically at [localhost:9321](http://localhost:9321).
|
|
101
|
+
|
|
102
|
+
You can also pass paths directly as arguments:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
canapy dash -a song_dataset/annotations -s song_dataset/audio -o output
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Using the dashboard
|
|
111
|
+
|
|
112
|
+
The dashboard is organized around a sidebar giving access to all pages. The typical workflow for training a new annotator is:
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
Load data → Preprocess → Train → Eval → (iterate) → Export → Annotate
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Home
|
|
119
|
+
|
|
120
|
+
The **Home** page gives an overview of Canapy and its pipelines, with a FAQ section and links to the GitHub repository and the Mnemosyne INRIA team.
|
|
121
|
+
|
|
122
|
+
### Load data
|
|
123
|
+
|
|
124
|
+
On the **Load data** page, specify where your data lives:
|
|
125
|
+
|
|
126
|
+
- **Source selection**: choose *combined folders* if audio and annotations are in the same directory, or *separate folders* otherwise.
|
|
127
|
+
- **Model directory**: if you want to annotate unlabeled data, point to a folder containing already-trained models (exported after using the training pipeline).
|
|
128
|
+
- **Output directory**: where models and annotations will be saved (defaults to `output/`).
|
|
129
|
+
- **Annotation format** and **audio extension**: set these to match your files.
|
|
130
|
+
- The **sampling rate** is auto-detected from your audio files. Enable *Downsample* if you want audio resampled to that rate at load time.
|
|
131
|
+
|
|
132
|
+
### Preprocess (Edit dataset)
|
|
133
|
+
|
|
134
|
+
Use this page to clean your dataset before training. It has two sections:
|
|
135
|
+
|
|
136
|
+
Two collapsible modules are always accessible at the top of the page, regardless of the active section:
|
|
137
|
+
|
|
138
|
+
- **Class spectrograms** — displays one representative mel spectrogram per class (the sample closest to the median duration). Useful for quickly spotting acoustically similar classes before merging.
|
|
139
|
+
- **Trim silences** *(Preprocess only)* — balances the proportion of silence in the dataset. Set the target silence ratio (e.g. 20%) and Canapy center-crops silence segments that exceed it. Trimmed files are saved to `output/audio_trimmed/` and `output/annots_trimmed/`.
|
|
140
|
+
|
|
141
|
+
**Class merge** — listen to each annotation class, compare them side by side, and rename or merge classes that are acoustically too similar. Type the new label in the text field and click *Apply*.
|
|
142
|
+
|
|
143
|
+
**Sample correction** — review individual samples per class. Select a class to listen to its samples one by one, view their spectrogram, and correct any mislabeled ones via the text input. Click *Save all* when done.
|
|
144
|
+
|
|
145
|
+
You can export corrected annotations at any time using the *Export Annotations* button at the top of the page.
|
|
146
|
+
|
|
147
|
+
### Train
|
|
148
|
+
|
|
149
|
+
**Hyperparameter search (optional):** Before training, you can run an automatic HP search to find better ESN parameters for your dataset. It uses TPE (sequential) or parallel random search. Key settings (on the **Settings** page): `opt_max_evals`, `opt_n_jobs`, `opt_max_percentage`. Optimized parameters are preserved across training iterations — no need to re-run the search each time.
|
|
150
|
+
|
|
151
|
+
Click *Start Training*. Three ESN-based models are trained:
|
|
152
|
+
|
|
153
|
+
| Model | Description |
|
|
154
|
+
|-------|-------------|
|
|
155
|
+
| `syn` | Trained on complete songs in order — uses sequential/syntactic context |
|
|
156
|
+
| `nsyn` | Trained on randomly shuffled, class-balanced samples — context-free |
|
|
157
|
+
| `ensemble` | Combines `syn` and `nsyn` by majority vote |
|
|
158
|
+
|
|
159
|
+
### Eval
|
|
160
|
+
|
|
161
|
+
After training, the **Eval** page shows:
|
|
162
|
+
|
|
163
|
+
- **Confusion matrix** — which classes are being confused with each other.
|
|
164
|
+
- **Per-class metrics table** — precision, recall, F1-score for each class (1.0 = perfect).
|
|
165
|
+
- **Class merge / sample correction** — same tools as Preprocessing, but focused on misclassified samples from the model's output.
|
|
166
|
+
|
|
167
|
+
If results are not satisfying, correct samples or merge classes, then retrain. **3–4 iterations** of train → eval is typically enough to converge. All corrections are preserved across iterations.
|
|
168
|
+
|
|
169
|
+
### Export
|
|
170
|
+
|
|
171
|
+
When you are satisfied with the model's performance, go to the **Export** page to save the trained models to the output folder. These exported models are then used in the **Annotate** pipeline. You can also export the current configuration (ESN and species parameters) from this page — or from the **Settings** page — to reuse it as a personal preset in future sessions.
|
|
172
|
+
|
|
173
|
+
### Annotate unlabeled data
|
|
174
|
+
|
|
175
|
+
Load your unlabeled audio and trained models via the **Load data** page, or pass them directly at launch:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
canapy dash -d song_dataset/audio -c output/model -o output/annotations
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Select which model(s) to use (*Syn-ESN*, *NSyn-ESN*, *Ensemble*), click *Start annotation*, then *Export annotation* when done. The export folder is named with a timestamp (`YYYY-MM-DD_HHhMMminSS`).
|
|
182
|
+
|
|
183
|
+
> If you trained with multiple iterations, you can pick a specific one: load `output/model/3` instead of `output/model`.
|
|
184
|
+
|
|
185
|
+
### Settings
|
|
186
|
+
|
|
187
|
+
The **Settings** page lets you configure the parameters used by Canapy:
|
|
188
|
+
|
|
189
|
+
- **Species parameters**: `fmin`, `fmax` (frequency range), `win_length`, `hop_length`, `n_fft` (spectrogram).
|
|
190
|
+
- **ESN parameters**: `sr` (spectral radius), `leak` (leak rate), `iss`, `isd`, `isd2` (input scalings), `ridge` (regularization).
|
|
191
|
+
- **HP search parameters**: `opt_max_evals`, `opt_n_jobs`, `opt_max_percentage`.
|
|
192
|
+
|
|
193
|
+
Click *Validate* to apply changes to the current session.
|
|
194
|
+
|
|
195
|
+
**Presets** — the Settings page provides pre-configured profiles for specific species (canary, Bengalese finch, zebra finch, mouse, infant marmoset). The canary preset is loaded by default. You can also load your own configuration file via *Load config*. If you have tuned Canapy for a new species, feel free to send us your configuration so we can add it to the preset library.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Quick commands (no dashboard)
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# Train once and export models
|
|
203
|
+
canapy train -d song_dataset/data -o output
|
|
204
|
+
|
|
205
|
+
# Annotate unlabeled audio with trained models
|
|
206
|
+
canapy annotate -d song_dataset/audio -c models_folder -o output
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Support
|
|
210
|
+
|
|
211
|
+
Contact Axel Arnaud or Xavier Hinaut at Inria Mnemosyne:
|
|
212
|
+
<axel.arnaud@inria.fr> — <xavier.hinaut@inria.fr>
|
|
213
|
+
|
canapy-0.1.0/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Canapy
|
|
2
|
+
|
|
3
|
+
**Automatic audio annotation tools for animal vocalizations**
|
|
4
|
+
|
|
5
|
+
--------
|
|
6
|
+
|
|
7
|
+
Canapy trains automatic annotators for animal vocalizations using [Reservoir Computing](https://reservoirpy.readthedocs.io/) (Echo State Networks). It comes with an interactive dashboard to guide you through the full pipeline: dataset preparation, model training, evaluation, and annotation.
|
|
8
|
+
|
|
9
|
+
> For the full reference documentation, see [README_extended.md](README_extended.md).
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
git clone git@github.com:birds-canopy/canapy.git
|
|
15
|
+
pip install -e canapy/.
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
### 1. Prepare your dataset
|
|
21
|
+
|
|
22
|
+
You need hand-labeled audio recordings. Annotations should be `.csv` files in **marron1csv** format (columns: `wave`, `start`, `end`, `syll`). Audio must be mono WAV files.
|
|
23
|
+
|
|
24
|
+
Recommended structure:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
song_dataset/
|
|
28
|
+
├── annotations/
|
|
29
|
+
│ ├── song1.csv
|
|
30
|
+
│ └── song2.csv
|
|
31
|
+
└── audio/
|
|
32
|
+
├── song1.wav
|
|
33
|
+
└── song2.wav
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
or
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
song_dataset/
|
|
40
|
+
├── song1.wav
|
|
41
|
+
├── song1.csv
|
|
42
|
+
├── song2.wav
|
|
43
|
+
└── song2.csv
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Aim for 30 min–1 hour of annotated data (10 min can already give good results on canary songs).
|
|
47
|
+
|
|
48
|
+
### 2. Launch the dashboard
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
canapy dash
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The dashboard opens automatically at [localhost:9321](http://localhost:9321).
|
|
55
|
+
|
|
56
|
+
You can also pass paths directly as arguments:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
canapy dash -a song_dataset/annotations -s song_dataset/audio -o output
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Using the dashboard
|
|
65
|
+
|
|
66
|
+
The dashboard is organized around a sidebar giving access to all pages. The typical workflow for training a new annotator is:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
Load data → Preprocess → Train → Eval → (iterate) → Export → Annotate
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Home
|
|
73
|
+
|
|
74
|
+
The **Home** page gives an overview of Canapy and its pipelines, with a FAQ section and links to the GitHub repository and the Mnemosyne INRIA team.
|
|
75
|
+
|
|
76
|
+
### Load data
|
|
77
|
+
|
|
78
|
+
On the **Load data** page, specify where your data lives:
|
|
79
|
+
|
|
80
|
+
- **Source selection**: choose *combined folders* if audio and annotations are in the same directory, or *separate folders* otherwise.
|
|
81
|
+
- **Model directory**: if you want to annotate unlabeled data, point to a folder containing already-trained models (exported after using the training pipeline).
|
|
82
|
+
- **Output directory**: where models and annotations will be saved (defaults to `output/`).
|
|
83
|
+
- **Annotation format** and **audio extension**: set these to match your files.
|
|
84
|
+
- The **sampling rate** is auto-detected from your audio files. Enable *Downsample* if you want audio resampled to that rate at load time.
|
|
85
|
+
|
|
86
|
+
### Preprocess (Edit dataset)
|
|
87
|
+
|
|
88
|
+
Use this page to clean your dataset before training. It has two sections:
|
|
89
|
+
|
|
90
|
+
Two collapsible modules are always accessible at the top of the page, regardless of the active section:
|
|
91
|
+
|
|
92
|
+
- **Class spectrograms** — displays one representative mel spectrogram per class (the sample closest to the median duration). Useful for quickly spotting acoustically similar classes before merging.
|
|
93
|
+
- **Trim silences** *(Preprocess only)* — balances the proportion of silence in the dataset. Set the target silence ratio (e.g. 20%) and Canapy center-crops silence segments that exceed it. Trimmed files are saved to `output/audio_trimmed/` and `output/annots_trimmed/`.
|
|
94
|
+
|
|
95
|
+
**Class merge** — listen to each annotation class, compare them side by side, and rename or merge classes that are acoustically too similar. Type the new label in the text field and click *Apply*.
|
|
96
|
+
|
|
97
|
+
**Sample correction** — review individual samples per class. Select a class to listen to its samples one by one, view their spectrogram, and correct any mislabeled ones via the text input. Click *Save all* when done.
|
|
98
|
+
|
|
99
|
+
You can export corrected annotations at any time using the *Export Annotations* button at the top of the page.
|
|
100
|
+
|
|
101
|
+
### Train
|
|
102
|
+
|
|
103
|
+
**Hyperparameter search (optional):** Before training, you can run an automatic HP search to find better ESN parameters for your dataset. It uses TPE (sequential) or parallel random search. Key settings (on the **Settings** page): `opt_max_evals`, `opt_n_jobs`, `opt_max_percentage`. Optimized parameters are preserved across training iterations — no need to re-run the search each time.
|
|
104
|
+
|
|
105
|
+
Click *Start Training*. Three ESN-based models are trained:
|
|
106
|
+
|
|
107
|
+
| Model | Description |
|
|
108
|
+
|-------|-------------|
|
|
109
|
+
| `syn` | Trained on complete songs in order — uses sequential/syntactic context |
|
|
110
|
+
| `nsyn` | Trained on randomly shuffled, class-balanced samples — context-free |
|
|
111
|
+
| `ensemble` | Combines `syn` and `nsyn` by majority vote |
|
|
112
|
+
|
|
113
|
+
### Eval
|
|
114
|
+
|
|
115
|
+
After training, the **Eval** page shows:
|
|
116
|
+
|
|
117
|
+
- **Confusion matrix** — which classes are being confused with each other.
|
|
118
|
+
- **Per-class metrics table** — precision, recall, F1-score for each class (1.0 = perfect).
|
|
119
|
+
- **Class merge / sample correction** — same tools as Preprocessing, but focused on misclassified samples from the model's output.
|
|
120
|
+
|
|
121
|
+
If results are not satisfying, correct samples or merge classes, then retrain. **3–4 iterations** of train → eval is typically enough to converge. All corrections are preserved across iterations.
|
|
122
|
+
|
|
123
|
+
### Export
|
|
124
|
+
|
|
125
|
+
When you are satisfied with the model's performance, go to the **Export** page to save the trained models to the output folder. These exported models are then used in the **Annotate** pipeline. You can also export the current configuration (ESN and species parameters) from this page — or from the **Settings** page — to reuse it as a personal preset in future sessions.
|
|
126
|
+
|
|
127
|
+
### Annotate unlabeled data
|
|
128
|
+
|
|
129
|
+
Load your unlabeled audio and trained models via the **Load data** page, or pass them directly at launch:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
canapy dash -d song_dataset/audio -c output/model -o output/annotations
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Select which model(s) to use (*Syn-ESN*, *NSyn-ESN*, *Ensemble*), click *Start annotation*, then *Export annotation* when done. The export folder is named with a timestamp (`YYYY-MM-DD_HHhMMminSS`).
|
|
136
|
+
|
|
137
|
+
> If you trained with multiple iterations, you can pick a specific one: load `output/model/3` instead of `output/model`.
|
|
138
|
+
|
|
139
|
+
### Settings
|
|
140
|
+
|
|
141
|
+
The **Settings** page lets you configure the parameters used by Canapy:
|
|
142
|
+
|
|
143
|
+
- **Species parameters**: `fmin`, `fmax` (frequency range), `win_length`, `hop_length`, `n_fft` (spectrogram).
|
|
144
|
+
- **ESN parameters**: `sr` (spectral radius), `leak` (leak rate), `iss`, `isd`, `isd2` (input scalings), `ridge` (regularization).
|
|
145
|
+
- **HP search parameters**: `opt_max_evals`, `opt_n_jobs`, `opt_max_percentage`.
|
|
146
|
+
|
|
147
|
+
Click *Validate* to apply changes to the current session.
|
|
148
|
+
|
|
149
|
+
**Presets** — the Settings page provides pre-configured profiles for specific species (canary, Bengalese finch, zebra finch, mouse, infant marmoset). The canary preset is loaded by default. You can also load your own configuration file via *Load config*. If you have tuned Canapy for a new species, feel free to send us your configuration so we can add it to the preset library.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Quick commands (no dashboard)
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Train once and export models
|
|
157
|
+
canapy train -d song_dataset/data -o output
|
|
158
|
+
|
|
159
|
+
# Annotate unlabeled audio with trained models
|
|
160
|
+
canapy annotate -d song_dataset/audio -c models_folder -o output
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Support
|
|
164
|
+
|
|
165
|
+
Contact Axel Arnaud or Xavier Hinaut at Inria Mnemosyne:
|
|
166
|
+
<axel.arnaud@inria.fr> — <xavier.hinaut@inria.fr>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Author: Axel Arnaud
|
|
2
|
+
# Licence: BSD-3-Clause
|
|
3
|
+
# Copyright: Axel Arnaud
|
|
4
|
+
import logging
|
|
5
|
+
|
|
6
|
+
import crowsetta
|
|
7
|
+
|
|
8
|
+
from . import log
|
|
9
|
+
from .corpus import Corpus
|
|
10
|
+
from config import Config
|
|
11
|
+
from .formats.marron1csv import Marron1CSV
|
|
12
|
+
|
|
13
|
+
crowsetta.register_format(Marron1CSV)
|
|
14
|
+
|
|
15
|
+
logging.basicConfig(level=logging.INFO)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Author: Axel Arnaud
|
|
2
|
+
# Licence: BSD-3-Clause
|
|
3
|
+
# Copyright: Axel Arnaud
|
|
4
|
+
"""
|
|
5
|
+
This module provides annotator classes and a registry for audio classification in Canapy.
|
|
6
|
+
|
|
7
|
+
Classes
|
|
8
|
+
-------
|
|
9
|
+
Annotator
|
|
10
|
+
Base class for annotators.
|
|
11
|
+
SynAnnotator
|
|
12
|
+
An annotator that uses a Syntaxic approach with an Echo State Network (ESN).
|
|
13
|
+
NSynAnnotator
|
|
14
|
+
An annotator that uses a non-Syntaxic approach with an Echo State Network (ESN).
|
|
15
|
+
Ensemble
|
|
16
|
+
An ensemble annotator that combines the predictions of other annotators.
|
|
17
|
+
|
|
18
|
+
Functions
|
|
19
|
+
---------
|
|
20
|
+
get_annotator
|
|
21
|
+
Retrieves an annotator object by name from the registry.
|
|
22
|
+
get_annotator_names
|
|
23
|
+
Retrieves a list of available annotator names.
|
|
24
|
+
|
|
25
|
+
"""
|
|
26
|
+
import logging
|
|
27
|
+
|
|
28
|
+
from .base import Annotator
|
|
29
|
+
from .synannotator import SynAnnotator
|
|
30
|
+
from .nsynannotator import NSynAnnotator
|
|
31
|
+
from .ensemble import Ensemble
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
logger = logging.getLogger("canapy")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class _Registry:
|
|
38
|
+
def __init__(self):
|
|
39
|
+
self._registry = {
|
|
40
|
+
"syn-esn": SynAnnotator,
|
|
41
|
+
"nsyn-esn": NSynAnnotator,
|
|
42
|
+
"ensemble": Ensemble,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
def __getitem__(self, item):
|
|
46
|
+
return self._registry[item]
|
|
47
|
+
|
|
48
|
+
def register_annotator(self, name, cls):
|
|
49
|
+
if name in self._registry:
|
|
50
|
+
logger.warning(f"'{name}' is already registered. Skipping.")
|
|
51
|
+
return
|
|
52
|
+
self._registry[name] = cls
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
registry = _Registry()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def get_annotator(name):
|
|
59
|
+
return registry[name]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_annotator_names():
|
|
63
|
+
return sorted(registry._registry.keys())
|