Add fplearn.sh, because a cumulative measurement is a protocol not three commands
Learning rewrites the template on every matched press, so run two is not a
repeat of run one and an A/B against a moving template is not an A/B. The order
is the measurement:
enrol a fresh template at 20 samples with no position prompts, which is also
the outstanding replication of the best result this lane has seen
base learning off: the clean number for that template, and the only figure
comparable to every rate already recorded
trend learning on, three times: the rate should climb, with the container
size as an independent witness that it is the template moving
A rate that climbs while the body grows is learning. A rate that moves while the
body does not is noise, and the daemon's own learn: lines say which. Run one of
the trend is not evidence that learning helped; it starts on the template the
baseline ended on.
One limit the script states rather than letting someone discover it: learning
only fires on a press that matched, so a template that never matches never
improves. That is why the protocol re-enrols instead of building on a template
already measured at 0 of 10.
This commit is contained in:
parent
21d6aa448c
commit
c5fc3afc77
2 changed files with 123 additions and 0 deletions
25
README.md
25
README.md
|
|
@ -109,6 +109,31 @@ the shipped config sets `max_authentication_rescan_times` to 0, because at the
|
||||||
stock budget a wrong finger never yields a terminal frame and a PAM client
|
stock budget a wrong finger never yields a terminal frame and a PAM client
|
||||||
waits forever for the `verify-no-match` it needs.
|
waits forever for the `verify-no-match` it needs.
|
||||||
|
|
||||||
|
**Template learning.** Stock rewrites the stored template on every successful
|
||||||
|
press — `0x1015 UPDATE_TEMPLATE` while the finger is still down, then a deferred
|
||||||
|
`SAVE_DATA` — and the stored body measurably grows over a template's life
|
||||||
|
(333278 bytes at enrolment to 371734 after one authentication session on the
|
||||||
|
reference device). This daemon does the same as of 0.1.0. It matters more than
|
||||||
|
any tuning knob: before it, every match rate measured against this device was
|
||||||
|
measured against a day-zero template that no stock user lives with.
|
||||||
|
|
||||||
|
The harvest sends no event, so the matcher does not re-run and a verdict cannot
|
||||||
|
be revised by it. A quick tap pays almost nothing, because the finger is gone by
|
||||||
|
the time a verdict lands; a held press contributes the frames it was held for —
|
||||||
|
which means the frames learned from are, by construction, frames from real
|
||||||
|
unlock presses. The save is deferred until after the verdict reaches the client,
|
||||||
|
because ~350 ms of RPMB traffic does not belong on an unlock path; stock defers
|
||||||
|
it the same way. `--learn=0` turns the whole thing off so the comparison can be
|
||||||
|
made on one binary, which is the only way it is single-variable.
|
||||||
|
|
||||||
|
**Reading the trustlet.** There is no `tzdbg` on mainline, but focal64 writes
|
||||||
|
its log into the response buffer, so `--ta-log` surfaces the matcher's own
|
||||||
|
verdicts (`auth success score`, `identify fail! FtVerifyByTemplate() = -2`, the
|
||||||
|
per-frame `image quality / coverage / humidity`). The log ring is ~150 lines per
|
||||||
|
session and is never reset, so the config dump alone can overflow it: the
|
||||||
|
shipped verbose config leaves the framework log off to reserve the ring for the
|
||||||
|
algorithm. Lower levels are more verbose and 6 is off.
|
||||||
|
|
||||||
**Known about the loop, from real use.** A verify frame is four QTEE round
|
**Known about the loop, from real use.** A verify frame is four QTEE round
|
||||||
trips (~200 ms idle); a `REPORT_EVENT` that runs the matcher is ~300 ms, and
|
trips (~200 ms idle); a `REPORT_EVENT` that runs the matcher is ~300 ms, and
|
||||||
the rising edge pays it twice because events 5 and 7 both reach the matcher.
|
the rising edge pays it twice because events 5 and 7 both reach the matcher.
|
||||||
|
|
|
||||||
98
packaging/fplearn.sh
Executable file
98
packaging/fplearn.sh
Executable file
|
|
@ -0,0 +1,98 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# fplearn.sh -- the template-learning measurement, as a protocol rather than a
|
||||||
|
# pile of remembered commands.
|
||||||
|
#
|
||||||
|
# fplearn.sh enrol [finger] re-enrol at the config's sample count
|
||||||
|
# fplearn.sh base [n] [w] trial with learning OFF (the baseline)
|
||||||
|
# fplearn.sh trend [n] [w] three trials with learning ON
|
||||||
|
# fplearn.sh sizes just print the template container sizes
|
||||||
|
#
|
||||||
|
# WHY IT IS SHAPED LIKE THIS. Learning is cumulative: every matched press folds
|
||||||
|
# frames into the stored template, so a second run is not a repeat of the first
|
||||||
|
# and an A/B against a moving template is not an A/B at all. The only honest
|
||||||
|
# comparison is on ONE template lineage, in order:
|
||||||
|
#
|
||||||
|
# 1. enrol a fresh template, 20 samples, no position prompts --
|
||||||
|
# which is also the outstanding replication of the 7/10
|
||||||
|
# result, the one measurement this lane was parked on
|
||||||
|
# 2. base learning off: the clean number for THIS template, and
|
||||||
|
# the only figure comparable to every rate in the journal
|
||||||
|
# 3. trend learning on, three times: the rate should climb, and
|
||||||
|
# the container size is an independent witness that it
|
||||||
|
# is the template moving and not the weather
|
||||||
|
#
|
||||||
|
# Do NOT read run 1 of the trend as "learning made it better". Run 1 starts on
|
||||||
|
# the same template the baseline ended on; it is the first run that can improve
|
||||||
|
# it, not one that has already been improved.
|
||||||
|
set -u
|
||||||
|
|
||||||
|
GROUP=/mnt/persist/data/RIY7A+mQm3EA4FsCUmkJo0b9dFUYP2YZ4P5hmMiZgeA_Alt
|
||||||
|
UNIT=fingerprintd-test
|
||||||
|
BIN=/tmp/fingerprintd
|
||||||
|
COMMON="--daemon --verbose --edge-wake --sfs-root=/var/lib/fingerprintd/sfs --sfs-writable --rpmb-write"
|
||||||
|
|
||||||
|
sizes() {
|
||||||
|
# A template is stored twice, the container and its backup, so the sizes
|
||||||
|
# come in pairs. The BODY is the container minus its 4096-byte header.
|
||||||
|
sudo ls -la "$GROUP" 2>/dev/null | awk '$5 > 200000 { printf " %9d body %9d %s\n", $5, $5-4096, $9 }' | sort -u
|
||||||
|
}
|
||||||
|
|
||||||
|
restart() { # $1 = extra args
|
||||||
|
sudo systemctl stop "$UNIT" 2>/dev/null
|
||||||
|
sleep 2
|
||||||
|
sudo systemd-run --unit="$UNIT" --collect $BIN $COMMON $1 >/dev/null 2>&1
|
||||||
|
printf 'daemon starting'
|
||||||
|
i=0
|
||||||
|
while [ $i -lt 40 ]; do
|
||||||
|
if busctl --system list 2>/dev/null | grep -q net.reactivated.Fprint; then
|
||||||
|
# Owning the name is not the same as being ready: the session comes
|
||||||
|
# up on the worker thread afterwards.
|
||||||
|
sleep 6; printf ' ready\n'; return 0
|
||||||
|
fi
|
||||||
|
printf '.'; sleep 1; i=$((i+1))
|
||||||
|
done
|
||||||
|
printf ' TIMED OUT\n'; return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
case "${1:-}" in
|
||||||
|
sizes)
|
||||||
|
echo "template containers now:"; sizes ;;
|
||||||
|
|
||||||
|
enrol)
|
||||||
|
F=${2:-right-middle-finger}
|
||||||
|
echo "=== enrol $F ==="
|
||||||
|
echo "sizes before:"; sizes
|
||||||
|
restart "--learn=1" || exit 1
|
||||||
|
/tmp/fpenrol.sh "$F"
|
||||||
|
echo; echo "sizes after the enrolment:"; sizes
|
||||||
|
echo; echo "next: fplearn.sh base" ;;
|
||||||
|
|
||||||
|
base)
|
||||||
|
N=${2:-10}; W=${3:-5}
|
||||||
|
echo "=== BASELINE: learning OFF ==="
|
||||||
|
restart "--learn=0" || exit 1
|
||||||
|
echo "sizes before:"; sizes
|
||||||
|
/tmp/fptrial.sh "$N" "$W"
|
||||||
|
echo; echo "sizes after (MUST be unchanged -- learning was off):"; sizes
|
||||||
|
echo; echo "next: fplearn.sh trend" ;;
|
||||||
|
|
||||||
|
trend)
|
||||||
|
N=${2:-10}; W=${3:-5}
|
||||||
|
echo "=== TREND: learning ON, three runs on one template ==="
|
||||||
|
restart "--learn=1" || exit 1
|
||||||
|
echo "sizes at the start:"; sizes
|
||||||
|
r=1
|
||||||
|
while [ $r -le 3 ]; do
|
||||||
|
echo; echo "----- learning run $r of 3 -----"
|
||||||
|
/tmp/fptrial.sh "$N" "$W"
|
||||||
|
echo "sizes after run $r:"; sizes
|
||||||
|
r=$((r+1))
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
echo "Read it as a trend, not three numbers. A rate that climbs while the"
|
||||||
|
echo "container grows is learning; a rate that moves while the container"
|
||||||
|
echo "does not is noise, and the daemon's own 'learn:' lines say which." ;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
sed -n '2,30p' "$0"; exit 1 ;;
|
||||||
|
esac
|
||||||
Loading…
Reference in a new issue