Description Usage Arguments Details Value Examples
This customized wrapper for optim
attemps to optimize the
parameters of segmentFolder
or analyzeFolder
by
comparing the results with a manually annotated "key". This optimization
function uses a single measurement per audio file (e.g., median pitch or the
number of syllables). For other purposes, you may want to adapt the
optimization function so that the key specifies the exact timing of
syllables, their median length, frame-by-frame pitch values, or any other
characteristic that you want to optimize for. The general idea remains the
same, however: we want to tune function parameters to fit our type of audio
and research priorities. The default settings of segmentFolder
and analyzeFolder
have been optimized for human non-linguistic
vocalizations.
1 2 3 4 5 | optimizePars(myfolder, key, myfun, pars, bounds = NULL, fitnessPar,
fitnessFun = function(x) 1 - cor(x, key, use = "pairwise.complete.obs"),
nIter = 10, init = NULL, initSD = 0.2, control = list(maxit = 50,
reltol = 0.01, trace = 0), otherPars = list(plot = FALSE, verbose = FALSE),
mygrid = NULL, verbose = TRUE)
|
myfolder |
path to where the .wav files live |
key |
a vector containing the "correct" measurement that we are aiming to reproduce |
myfun |
the function being optimized: either 'segmentFolder' or 'analyzeFolder' (in quotes) |
pars |
names of arguments to |
bounds |
a list setting the lower and upper boundaries for possible
values of optimized parameters. For ex., if we optimize |
fitnessPar |
the name of output variable that we are comparing with the key, e.g. 'nBursts' or 'pitch_median' |
fitnessFun |
the function used to evaluate how well the output of
|
nIter |
repeat the optimization several times to check convergence |
init |
initial values of optimized parameters (if NULL, the default
values are taken from the definition of |
initSD |
each optimization begins with a random seed, and
|
control |
a list of control parameters passed on to
|
otherPars |
a list of additional arguments to |
mygrid |
a dataframe with one column per parameter to optimize, with
each row specifying the values to try. If not NULL, |
verbose |
if TRUE, reports the values of parameters evaluated and fitness |
If your sounds are very different from human non-linguistic vocalizations, you may want to change the default values of other arguments to speed up convergence. Adapt the code to enforce suitable constraints, depending on your data.
Returns a matrix with one row per iteration with fitness in the first column and the best values of each of the optimized parameters in the remaining columns.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | ## Not run:
# download 260 sounds from Anikin & Persson (2017)
# http://cogsci.se/personal/results/
# 01_anikin-persson_2016_naturalistics-non-linguistic-vocalizations/260sounds_wav.zip
# unzip them into a folder, say '~/Downloads/temp'
myfolder = '~/Downloads/temp' # 260 .wav files live here
# Optimization of SEGMENTATION
# import manual counts of syllables in 260 sounds from Anikin & Persson (2017) (our "key")
key = segmentManual # a vector of 260 integers
# run optimization loop several times with random initial values to check convergence
# NB: with 260 sounds and default settings, this might take ~20 min per iteration!
res = optimizePars(myfolder = myfolder, myfun = 'segmentFolder', key = key,
pars = c('shortestSyl', 'shortestPause', 'sylThres'),
fitnessPar = 'nBursts',
nIter = 3, control = list(maxit = 50, reltol = .01, trace = 0))
# examine the results
print(res)
for (c in 2:ncol(res)) {
plot(res[, c], res[, 1], main = colnames(res)[c])
}
pars = as.list(res[1, 2:ncol(res)]) # top candidate (best pars)
s = do.call(segmentFolder, c(myfolder, pars)) # segment with best pars
cor(key, as.numeric(s[, fitnessPar]))
boxplot(as.numeric(s[, fitnessPar]) ~ as.integer(key), xlab='key')
abline(a=0, b=1, col='red')
# Try a grid with particular parameter values instead of formal optimization
res = optimizePars(myfolder = myfolder, myfun = 'segmentFolder', key = segment_manual,
pars = c('shortestSyl', 'shortestPause'),
fitnessPar = 'nBursts',
mygrid = expand.grid(shortestSyl = c(30, 40),
shortestPause = c(30, 40, 50)))
1 - res$fit # correlations with key
# Optimization of PITCH TRACKING (takes several hours!)
res = optimizePars(myfolder = myfolder,
myfun = 'analyzeFolder',
key = log(pitchManual), # log-scale better for pitch
pars = c('specThres', 'specSmooth'),
bounds = list(low = c(0, 0), high = c(1, Inf)),
fitnessPar = 'pitch_median',
nIter = 2,
otherPars = list(plot = FALSE, verbose = FALSE, step = 50,
pitchMethods = 'spec'),
fitnessFun = function(x) {
1 - cor(log(x), key, use = 'pairwise.complete.obs') *
(1 - mean(is.na(x) & !is.na(key))) # penalize failing to detect F0
})
## End(Not run) # end of dontrun
|
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.