Automatic call detection analysis
Call activity in strawberry poison-dart frogs
Purpose
Train model to automate detection of strawberry poison-dart frog calls
Detect calls in passive acoustic monitoring recordings
Report overview
Load packages
1 Training model
1.1 Prepare data
- Import annotations
Code
all selections are OK
[1] 1545
[1] 6.4834
- Resample sound files
1.2 Find templates
Code
The first 2 principal components explained 0.52 of the variance
Code
checking selections (step 1 of 2):
saving wave objects into extended selection table (step 2 of 2):
Code
corrs <- template_correlator(templates = templates[1:5, ], path = train_path,
wl = 100, ovlp = 70, cores = 10)
opt_oo <- optimize_template_detector(template.correlations = corrs,
reference = ref, threshold = seq(0.1, 0.95, 0.05), cores = 15,
by.sound.file = FALSE)
write.csv(opt_oo, "~/Dropbox/oophaga/optimization_results.csv", row.names = FALSE)
Code
threshold | templates | true.positives | false.positives | false.negatives | recall | precision | |
---|---|---|---|---|---|---|---|
37 | 0.45 | ZOOM0002_Tr1-3.wav-92 | 1957 | 877 | 593 | 0.77 | 0.69 |
45 | 0.50 | ZOOM0002_Tr1-2.wav-256 | 1817 | 1703 | 515 | 0.78 | 0.52 |
48 | 0.55 | ZOOM0002_Tr1-5.wav-238 | 1092 | 667 | 702 | 0.61 | 0.62 |
2 Run model on the entire data set
- Split files into 1 min segments (to improve computation effciency)
Code
split_sound_files("~/Dropbox/oophaga/test/", sgmt.dur = 300)
fix_wavs(samp.rate = 14, path = "~/Dropbox/oophaga/test/1min_clips/")
templates_est <- readRDS("~/Dropbox/oophaga/templates_est.RDS")
corrs <- template_correlator(templates = templates_est[2, ], path = "~/Dropbox/oophaga/test/1min_clips/converted_sound_files/",
wl = 100, ovlp = 70, cores = 1)
full_detec <- template_detector(template.correlations = corrs, threshold = 0.45,
cores = 1)
write.csv(full_detec, "~/Dropbox/oophaga/full_detection.csv", row.names = FALSE)
2.1 Vocal activity through time in open and closed habitat
Code
full_detec <- read.csv("~/Dropbox/oophaga/full_detection.csv")
full_detec$site <- ifelse(grepl("arriera_zompopa", full_detec$sound.files),
"open", "closed")
full_detec$time.block <- as.numeric(gsub(".wav", "", sapply(strsplit(full_detec$sound.files,
"-"), "[", 2)))
full_detec$time <- ((9 * 60) + (full_detec$time.block * 5))/60
full_detec <- full_detec[!is.na(full_detec$start), ]
2.2 Counts per site
Code
call_count <- aggregate(sound.files ~ time + site, full_detec, length)
ggplot(call_count, aes(x = time, y = sound.files, fill = site, color = site)) +
geom_point(size = 4, pch = 21) + geom_smooth(method = "lm") +
scale_fill_viridis_d(alpha = 0.5, begin = 0.2, end = 0.8) + scale_color_viridis_d(alpha = 0.3,
begin = 0.2, end = 0.8) + theme_classic(base_size = 20) + labs(x = "Time (h)",
y = "Call count", color = "Habitat", fill = "Habitat") + theme(legend.position = c(0.9,
0.9))
Takeaways
- Fair performance of automatic detection model
- Prediction on test data shows expected pattern of decrease in activity through time during morning hours
# Example images
3 Spectro + oscillo
Code
wv <- read_sound_file("/home/m/Dropbox/oophaga/example_inaturalist/clip.wav")
anns <- imp_raven(path = "/home/m/Dropbox/oophaga/example_inaturalist/",
warbler.format = TRUE, all.data = FALSE)
spectro(wv, scale = FALSE, wl = 76, collevels = seq(-100, 0, 5), palette = viridis::viridis,
ovlp = 9, grid = FALSE, flim = c(1, 6.5), zp = 1000, osc = TRUE,
heights = c(2, 1))
3.1 Perfect detection
3.2 Precision 1, recall 0.7
3.3 Precision 0.7, recall 1
true.positives | false.positives | false.negatives | recall | precision | f1.score |
---|---|---|---|---|---|
7 | 3 | 0 | 1 | 0.7 | 0.823529 |
Code
Session information
R version 4.1.0 (2021-05-18)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 20.04.2 LTS
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/atlas/libblas.so.3.10.3
LAPACK: /usr/lib/x86_64-linux-gnu/atlas/liblapack.so.3.10.3
locale:
[1] LC_CTYPE=pt_BR.UTF-8 LC_NUMERIC=C
[3] LC_TIME=es_CR.UTF-8 LC_COLLATE=pt_BR.UTF-8
[5] LC_MONETARY=es_CR.UTF-8 LC_MESSAGES=pt_BR.UTF-8
[7] LC_PAPER=es_CR.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=es_CR.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] viridis_0.6.2 viridisLite_0.4.1 dynaSpec_1.0.1 ggplot2_3.4.0
[5] Rraven_1.0.13 ohun_0.1.0 warbleR_1.1.28 NatureSounds_1.0.4
[9] seewave_2.2.0 tuneR_1.4.1 rprojroot_2.0.3 formatR_1.11
[13] knitr_1.42
loaded via a namespace (and not attached):
[1] Rcpp_1.0.9 lattice_0.20-44 fftw_1.0-7
[4] assertthat_0.2.1 digest_0.6.31 packrat_0.9.0
[7] utf8_1.2.2 R6_2.5.1 Sim.DiffProc_4.8
[10] signal_0.7-7 evaluate_0.20 pillar_1.8.1
[13] rlang_1.0.6 rstudioapi_0.14 Matrix_1.5-1
[16] rmarkdown_2.20 labeling_0.4.2 splines_4.1.0
[19] sketchy_1.0.2 xaringanExtra_0.7.0 htmlwidgets_1.5.4
[22] igraph_1.3.5 RCurl_1.98-1.9 munsell_0.5.0
[25] proxy_0.4-27 compiler_4.1.0 Deriv_4.1.3
[28] xfun_0.36 pkgconfig_2.0.3 mgcv_1.8-36
[31] htmltools_0.5.4 tidyselect_1.2.0 tibble_3.1.8
[34] gridExtra_2.3 dtw_1.23-1 fansi_1.0.3
[37] crayon_1.5.2 dplyr_1.0.10 withr_2.5.0
[40] shinyBS_0.61 MASS_7.3-54 bitops_1.0-7
[43] grid_4.1.0 nlme_3.1-152 jsonlite_1.8.4
[46] gtable_0.3.1 lifecycle_1.0.3 DBI_1.1.1
[49] magrittr_2.0.3 scales_1.2.1 cli_3.6.0
[52] stringi_1.7.12 pbapply_1.6-0 farver_2.1.1
[55] remotes_2.4.2 sp_1.5-1 vctrs_0.5.2
[58] generics_0.1.3 rjson_0.2.21 tools_4.1.0
[61] glue_1.6.2 parallel_4.1.0 fastmap_1.1.0
[64] yaml_2.3.7 colorspace_2.0-3 soundgen_2.1.0