Skip to content

Commit

Permalink
Fix level dependency of "hzappp" feature extraction
Browse files Browse the repository at this point in the history
The main reason for this update to the code is an update to the feature
extraction. The originally published implementation divided the log amplitude
values of the log Mel-spectrogram by the (frequency-dependet) values of the
level uncertainty before adding random values drawn from a standard normal
distribution. Although this seemed like an elegant way of removing the
information in frequency regions with high level uncertainty, it resulted
in an undesired level dependency of the effect of the level uncertainty.
This effect was observed in an attempt to simulate the level dependency
of the SRT (Plomp curves).

This release comes with an alternative implementation, where the values
of the log Mel-spectrogram are no longer divided by the values of the
level uncertainty, but the values drawn from the standard normal distribution
are multiplied by the values of the level uncertainty, which ocurrs due to
subsequent across-frequency integration by the Gabor filter banks. This change
avoids the undesired level dependency of the effect of the level uncertainty,
with only very little change to the simulation results of this study.

The main change is (now using singleton dimension expansion):
- log_melspec = bsxfun(@times,log_melspec,1./ul_mel) + randn(size(log_melspec));
+ log_melspec = log_melspec + ul_mel.*randn(size(log_melspec));

The simulation scripts also have been updated to run with Ubuntu 20.10 and
FADE 2.4.0. All simulations were re-run, the simulation results are also
part of this commit (ul2tintable.txt and matrix_simulated_data.txt).
The differences to the published results are minor.

Further changes:
- Use ramdisk (/dev/shm/) to run simulations (needs a size of at least ~24Gb)
- Updated evaluation scripts to run with Ubuntu 20.10
  • Loading branch information
suaefar committed Dec 26, 2020
1 parent d812e44 commit a9925f5
Show file tree
Hide file tree
Showing 9 changed files with 805 additions and 864 deletions.
1,298 changes: 649 additions & 649 deletions evaluation/matrix_simulated_data.txt

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion evaluation/play_evaluate.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/octave-cli
#!/usr/bin/octave
close all
clear
clc
Expand Down
5 changes: 2 additions & 3 deletions evaluation/play_statistics.m
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#!/usr/bin/octave-cli
#!/usr/bin/octave
close all
clear
clc
warning off;
graphics_toolkit qt

subjects = { ...
'listener01-l' ... 1
Expand Down Expand Up @@ -173,7 +172,7 @@
printf('%s & %s & ', names{i}, individualizations{k});
pct = prctile(stats(:,:,i),[5 50 95]);
pctg = prctile(statsg(:,i),[5 95]);
confidence = [pct(1,:)-pct(2,:); pct(3,:)-pct(2,:)];
confidence = [pct(1)-pct(2); pct(3)-pct(2)];
confidenceg = pctg - values(i);
printf('%.2f\\,%s & [%.2f,%.2f]\\,%s & [%.2f,%.2f]\\,%s \\\\',values(i),units{i},confidence,units{i},confidenceg,units{i});
printf('\n');
Expand Down
77 changes: 46 additions & 31 deletions fade/fade_simulate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ DIR=$(cd "$( dirname "$0" )" && pwd)
SCN=$(basename "$0")

if [ $# -lt 7 ]; then
echo "Usage: $0 PROJECTDIR MEASUREMENTSTRING SIMRANGE SIMMODE FEATURES INDIVIDUALIZATION INDIVIDUAL EAR ..."
echo "Usage: $0 PROJECTDIR MEASUREMENTSTRING SIMRANGE SIMMODE FEATURES INDIVIDUALIZATION INDIVIDUAL EAR"
echo ""
exit 1
fi
Expand All @@ -27,7 +27,7 @@ EAR="$8"

case "$SIMMODE" in
coarse)
TRAININGSAMPELSPERMODEL=12
TRAININGSAMPELSPERMODEL=24
RECOGNITIONDECISIONS=100
# [STATES] [SILENCE_STATES] [MIXTURES] [ITERATIONS] [UPDATES] [PRUNINGS] [BINARY]
TRAININGOPTIONS="4 4 1 4 mvwt 0 1"
Expand All @@ -36,7 +36,7 @@ case "$SIMMODE" in
;;
medium)
TRAININGSAMPELSPERMODEL=48
RECOGNITIONDECISIONS=300
RECOGNITIONDECISIONS=200
# [STATES] [SILENCE_STATES] [MIXTURES] [ITERATIONS] [UPDATES] [PRUNINGS] [BINARY]
TRAININGOPTIONS="6 4 1 4 mvwt 0 1"
RECOGNITIONOPTIONS="0 100 1"
Expand Down Expand Up @@ -74,14 +74,18 @@ else
fi
FEATURESDIR="${DIR}/features/${FEATURESMODE}/"

# Temporary project dir in ramdisk
WORKDIR=$(mktemp -d -p /dev/shm/) || error "folder in ramdisk"
PROJECT="${WORKDIR}/simulation"

# Set up experiment
case "$MEASUREMENT" in
sweep)
QSIM_THRESHOLD=0.875
fade "$PROJECTDIR" corpus-stimulus "$[${TRAININGSAMPELSPERMODEL}*1]" "$[${RECOGNITIONDECISIONS}/2]" || error "creating project"
fade "${PROJECT}" corpus-stimulus "$[${TRAININGSAMPELSPERMODEL}*1]" "$[${RECOGNITIONDECISIONS}/2]" || error "creating project"
FREQUENCY=${PARAMETERS[0]}
cp -L "${DIR}/stimulus/"* "${PROJECTDIR}/config/corpus/matlab" || error "copying stimulus generation files"
cp -L "${DIR}/stimulus/control_"* "${PROJECTDIR}/config/figures/matlab" || error "copying stimulus control files"
cp -L "${DIR}/stimulus/"* "${PROJECT}/config/corpus/matlab" || error "copying stimulus generation files"
cp -L "${DIR}/stimulus/control_"* "${PROJECT}/config/figures/matlab" || error "copying stimulus control files"
echo "function generate(target_dir, samples, seed, verbose)
mkdir(target_dir);
classes = {0 1};
Expand All @@ -90,14 +94,14 @@ case "$MEASUREMENT" in
values = ${SIMRANGE};
generate_conditions(target_dir, funname, classes, ...
num2cell(values), samples, {'${FREQUENCY}'}, seed, verbose);
" > "${PROJECTDIR}/config/corpus/matlab/generate.m"
" > "${PROJECT}/config/corpus/matlab/generate.m"
;;
sweepinnoise)
QSIM_THRESHOLD=0.875
fade "$PROJECTDIR" corpus-stimulus "$[${TRAININGSAMPELSPERMODEL}*1]" "$[${RECOGNITIONDECISIONS}/2]" || error "creating project"
fade "${PROJECT}" corpus-stimulus "$[${TRAININGSAMPELSPERMODEL}*1]" "$[${RECOGNITIONDECISIONS}/2]" || error "creating project"
FREQUENCY=${PARAMETERS[0]}
cp -L "${DIR}/stimulus/"* "${PROJECTDIR}/config/corpus/matlab" || error "copying stimulus generation files"
cp -L "${DIR}/stimulus/control_"* "${PROJECTDIR}/config/figures/matlab" || error "copying stimulus control files"
cp -L "${DIR}/stimulus/"* "${PROJECT}/config/corpus/matlab" || error "copying stimulus generation files"
cp -L "${DIR}/stimulus/control_"* "${PROJECT}/config/figures/matlab" || error "copying stimulus control files"
echo "function generate(target_dir, samples, seed, verbose)
mkdir(target_dir);
classes = {0 1};
Expand All @@ -106,25 +110,25 @@ case "$MEASUREMENT" in
values = ${SIMRANGE};
generate_conditions(target_dir, funname, classes, ...
num2cell(values), samples, {'${FREQUENCY}'}, seed, verbose);
" > "${PROJECTDIR}/config/corpus/matlab/generate.m"
" > "${PROJECT}/config/corpus/matlab/generate.m"
;;
matrix)
QSIM_THRESHOLD=0.5
TALKER="${PARAMETERS[0]}"
NOISEMASKER="${PARAMETERS[1]}"
NOISELEVEL="${PARAMETERS[2]}"
fade "$PROJECTDIR" corpus-matrix "$[${TRAININGSAMPELSPERMODEL}*10]" "$[${RECOGNITIONDECISIONS}/5]" || error "creating project"
cp -L "${DIR}/matrix/speech/${TALKER}/"*".wav" "${PROJECTDIR}/source/speech/" || error "copying speech files"
cp -L "${DIR}/matrix/maskers/${NOISEMASKER}.wav" "${PROJECTDIR}/source/noise/" || error "copying masker file"
(cd "${PROJECTDIR}/source" && find -iname '*.wav') > "${PROJECTDIR}/config/sourcelist.txt"
fade "${PROJECT}" corpus-matrix "$[${TRAININGSAMPELSPERMODEL}*10]" "$[${RECOGNITIONDECISIONS}/5]" "${SIMRANGE}" || error "creating project"
cp -L "${DIR}/matrix/speech/${TALKER}/"*".wav" "${PROJECT}/source/speech/" || error "copying speech files"
cp -L "${DIR}/matrix/maskers/${NOISEMASKER}.wav" "${PROJECT}/source/noise/" || error "copying masker file"
(cd "${PROJECT}/source" && find -iname '*.wav') > "${PROJECT}/config/sourcelist.txt"
# Adjust level and resample to 44100Hz
echo "Adjust levels and resample"
octave-cli --quiet --eval "
filelist = strsplit(fileread('${PROJECTDIR}/config/sourcelist.txt'),'\n');
filelist = strsplit(fileread('${PROJECT}/config/sourcelist.txt'),'\n');
numfiles = length(filelist);
for i=1:numfiles
if ~isempty(filelist{i})
filename = ['${PROJECTDIR}/source/' filelist{i}];
filename = ['${PROJECT}/source/' filelist{i}];
[signal, fs] = audioread(filename);
signal = signal.*10.^((${NOISELEVEL}-65)./20);
if fs ~= 44100
Expand All @@ -135,25 +139,30 @@ case "$MEASUREMENT" in
end
end
printf('\nfinished\n');" || error "adjusting levels"
sed -i "s/^SNRS=.*/SNRS=${SIMRANGE}/g" "${PROJECTDIR}/config/corpus/generate.cfg"
;;
esac

# Parallel compuations
fade "$PROJECTDIR" parallel
fade "${PROJECT}" parallel

# Generate corpus
fade "$PROJECTDIR" corpus-generate || error "generating corpus"
fade "${PROJECT}" corpus-generate || error "generating corpus"

# Perform signal processing
if [ ! "$PROCESSING" == "none" ]; then
echo "Apply signal processing"
[ -e "$PROCESSINGDIR" ] || error "processingdir not found"
fade "$PROJECTDIR" processing "$PROCESSINGDIR" || error "processing"
[ -e "${PROCESSINGDIR}" ] || error "processingdir not found"
fade "${PROJECT}" processing "${PROCESSINGDIR}" || error "processing"
# And remove corpus files
[ -e "${PROJECT}/corpus" ] && rm -r "${PROJECT}/corpus"
fi

# Extract features
fade "$PROJECTDIR" features "$FEATURESDIR" "$INDIVIDUALIZATION" "$INDIVIDUAL" "$EAR" || error "extracting features"
fade "${PROJECT}" features "$FEATURESDIR" "$INDIVIDUALIZATION" "$INDIVIDUAL" "$EAR" || error "extracting features"

# Remove corpus/processing
[ -e "${PROJECT}/corpus" ] && rm -r "${PROJECT}/corpus"
[ -e "${PROJECT}/processing" ] && rm -r "${PROJECT}/processing"

# Format corpus (determine training/testing combinations)
if [ "$SIMMODE" == "coarse" ] || [ "$SIMMODE" == "medium" ] ; then
Expand All @@ -168,24 +177,27 @@ if [ "$SIMMODE" == "coarse" ] || [ "$SIMMODE" == "medium" ] ; then
CONDITION_CODE='o o'
;;
esac
sed -i "s/^CONDITION_CODE=.*$/CONDITION_CODE='${CONDITION_CODE}'/g" "${PROJECTDIR}/config/corpus/format.cfg"
sed -i "s/^CONDITION_CODE=.*$/CONDITION_CODE='${CONDITION_CODE}'/g" "${PROJECT}/config/corpus/format.cfg"
fi
fade "$PROJECTDIR" corpus-format || error "formatting corpus"
fade "${PROJECT}" corpus-format || error "formatting corpus"

# Training
fade "$PROJECTDIR" training $TRAININGOPTIONS || error "training"
fade "${PROJECT}" training $TRAININGOPTIONS || error "training"

# Recognition
fade "$PROJECTDIR" recognition $RECOGNITIONOPTIONS || error "recognition"
fade "${PROJECT}" recognition $RECOGNITIONOPTIONS || error "recognition"

# Delete features
[ -e "${PROJECT}/features" ] && rm -r "${PROJECT}/features"

# Evaluation
fade "$PROJECTDIR" evaluation || error "evaluating results"
fade "${PROJECT}" evaluation || error "evaluating results"

case "$SIMMODE" in
coarse|medium)
# Evaluate quick simulation to find point of interest

POI=$(cat "${PROJECTDIR}/evaluation/summary" | \
POI=$(cat "${PROJECT}/evaluation/summary" | \
sed -E 's/.*_([^_]*)$/\1/g' | sed -E 's/^(snr)?\+?//g' | \
cut -d' ' -f1,2,3 | sort -n | \
awk -F' ' -vt="${QSIM_THRESHOLD}" '{x1=$1;y1=$3/$2;if (y1>t) {if (NR>1) {printf "%.0f",x2+(x2-x1)/(y2-y1)*(t-y2)} exit} x2=x1;y2=y1}')
Expand All @@ -195,10 +207,13 @@ case "$SIMMODE" in
exit 1
fi
echo -e "\nPOI found: ${POI}\n"
echo "${POI}" > "${PROJECTDIR}/poi"
echo "${POI}" > "${PROJECT}/poi"
;;
precise)
fade "$PROJECTDIR" figures
fade "${PROJECT}" figures || error "figures"
;;
esac

mv "${PROJECT}" "${PROJECTDIR}" || error "move project"

[ -e "${WORKDIR}" ] && rm -rf "${WORKDIR}"
4 changes: 2 additions & 2 deletions fade/features/hzappp-full/feature_extraction.m
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@

% Apply absolute hearing threshold
ht_mel = interp1(f(:), ht(:), melspec_freqs(:), 'linear', 'extrap');
log_melspec = max(bsxfun(@minus, log_melspec, ht_mel), randn(size(log_melspec)));
log_melspec = max(log_melspec-ht_mel, 0.5.*randn(size(log_melspec)));

% Apply frequency-dependent level-uncertainty
ul_mel = interp1(f(:), ul(:), melspec_freqs(:), 'linear', 'extrap');
ul_mel(isnan(ul_mel)) = 0.1;
log_melspec = bsxfun(@times,log_melspec,1./ul_mel) + randn(size(log_melspec));
log_melspec = log_melspec + ul_mel.*randn(size(log_melspec));

% SGBFB feature extraction and mean-and-variance normalization
features = mvn(sgbfb(log_melspec));
Expand Down
Loading

0 comments on commit a9925f5

Please sign in to comment.