Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
bob
bob.pad.base
Commits
f276f395
Commit
f276f395
authored
May 04, 2018
by
Theophile GENTILHOMME
Browse files
Add legend options, small changes utils function and doc
parent
a2640f7d
Changes
5
Hide whitespace changes
Inline
Side-by-side
bob/pad/base/script/det.py
View file @
f276f395
...
...
@@ -10,6 +10,8 @@ from . import figure
@
common_options
.
scores_argument
(
min_arg
=
2
,
force_eval
=
True
,
nargs
=-
1
)
@
common_options
.
output_plot_file_option
(
default_out
=
'det.pdf'
)
@
common_options
.
legends_option
()
@
common_options
.
no_legend_option
()
@
common_options
.
legend_loc_option
(
dflt
=
'upper-right'
)
@
common_options
.
title_option
()
@
common_options
.
const_layout_option
()
@
common_options
.
style_option
()
...
...
@@ -18,7 +20,7 @@ from . import figure
'no-spoof'
,
'ns'
,
''
,
False
)
@
verbosity_option
()
@
common_options
.
axes_val_option
(
dflt
=
[
0.01
,
95
,
0.01
,
95
]
)
@
common_options
.
axes_val_option
(
dflt
=
'
0.01,95,0.01,95
'
)
@
common_options
.
x_rotation_option
(
dflt
=
45
)
@
common_options
.
x_label_option
()
@
common_options
.
y_label_option
()
...
...
bob/pad/base/script/epc.py
View file @
f276f395
...
...
@@ -10,6 +10,8 @@ from . import figure
@
common_options
.
scores_argument
(
min_arg
=
2
,
force_eval
=
True
,
nargs
=-
1
)
@
common_options
.
output_plot_file_option
(
default_out
=
'epc.pdf'
)
@
common_options
.
legends_option
()
@
common_options
.
no_legend_option
()
@
common_options
.
legend_loc_option
()
@
common_options
.
title_option
()
@
common_options
.
const_layout_option
()
@
common_options
.
x_label_option
()
...
...
@@ -51,6 +53,8 @@ def epc(ctx, scores, **kwargs):
@
common_options
.
scores_argument
(
min_arg
=
2
,
force_eval
=
True
,
nargs
=-
1
)
@
common_options
.
output_plot_file_option
(
default_out
=
'epsc.pdf'
)
@
common_options
.
legends_option
()
@
common_options
.
no_legend_option
()
@
common_options
.
legend_loc_option
()
@
common_options
.
const_layout_option
()
@
common_options
.
x_label_option
()
@
common_options
.
y_label_option
()
...
...
bob/pad/base/script/error_utils.py
View file @
f276f395
...
...
@@ -13,12 +13,20 @@ import argparse
def
calc_pass_rate
(
threshold
,
attacks
):
"""Calculates the rate of successful spoofing attacks
Keyword parameters:
Parameters
----------
threshold :
the threshold used for classification
scores :
numpy with the scores of the spoofing attacks
Returns
-------
float
rate of successful spoofing attacks
"""
return
(
attacks
>=
threshold
).
mean
()
- threshold - the threshold used for classification
- attack: numpy with the scores of the spoofing attacks
"""
return
sum
(
1
for
i
in
attacks
if
i
>=
threshold
)
/
float
(
attacks
.
size
)
def
weighted_neg_error_rate_criteria
(
data
,
weight
,
...
...
@@ -298,30 +306,32 @@ def epsc_error_rates(licit_neg, licit_pos, spoof_neg, spoof_pos, thresholds,
(omega and beta) and thresholds (the thresholds need to be computed first
using the method: epsc_thresholds() before passing to this method)
Keyword arguments:
- licit_neg - numpy.array of scores for the negatives (licit scenario)
- licit_pos - numpy.array of scores for the positives (licit scenario)
- spoof_neg - numpy.array of scores for the negatives (spoof scenario)
- spoof_pos - numpy.array of scores for the positives (spoof scenario)
- thresholds - numpy.ndarray with threshold values
- omega - numpy.array of the omega parameter balancing between impostors
and spoofing attacks
- beta - numpy.array of the beta parameter balancing between real accesses
and all negatives (impostors and spoofing attacks)
"""
if
not
isinstance
(
omega
,
list
)
and
not
isinstance
(
omega
,
tuple
)
and
not
isinstance
(
omega
,
numpy
.
ndarray
):
omega
=
numpy
.
array
([
omega
])
else
:
omega
=
numpy
.
array
(
omega
)
if
not
isinstance
(
beta
,
list
)
and
not
isinstance
(
beta
,
tuple
)
and
not
isinstance
(
beta
,
numpy
.
ndarray
):
beta
=
numpy
.
array
([
beta
])
else
:
beta
=
numpy
.
array
(
beta
)
Parameters
----------
licit_neg : array_like
array of scores for the negatives (licit scenario)
licit_pos : array_like
array of scores for the positives (licit scenario)
spoof_neg : array_like
array of scores for the negatives (spoof scenario)
spoof_pos : array_like
array of scores for the positives (spoof scenario)
thresholds : array_like
ndarray with threshold values
omega : array_like
array of the omega parameter balancing between impostors
and spoofing attacks
beta : array_like
array of the beta parameter balancing between real accesses
and all negatives (impostors and spoofing attacks)
Returns
-------
far_w_errors: array_like
FAR_w
wer_wb_errors: array_like
WER_wb
"""
far_w_errors
=
numpy
.
ndarray
((
beta
.
size
,
omega
.
size
),
'float64'
)
wer_wb_errors
=
numpy
.
ndarray
((
beta
.
size
,
omega
.
size
),
'float64'
)
...
...
@@ -340,34 +350,36 @@ def epsc_error_rates(licit_neg, licit_pos, spoof_neg, spoof_pos, thresholds,
def
all_error_rates
(
licit_neg
,
licit_pos
,
spoof_neg
,
spoof_pos
,
thresholds
,
omega
,
beta
):
"""Calculates several error rates: FAR_w and
HT
ER_w for the given weights
(omega and beta) and thresholds (the thresholds need to be computed first
"""Calculates several error rates: FAR_w and
W
ER_w
b
for the given weights
(omega and beta) and thresholds (the thresholds need to be computed first
using the method: epsc_thresholds() before passing to this method)
Keyword arguments:
- licit_neg - numpy.array of scores for the negatives (licit scenario)
- licit_pos - numpy.array of scores for the positives (licit scenario)
- spoof_neg - numpy.array of scores for the negatives (spoof scenario)
- spoof_pos - numpy.array of scores for the positives (spoof scenario)
- thresholds - numpy.array with threshold values
- omega - numpy.array of the omega parameter balancing between impostors
and spoofing attacks
- beta - numpy.array of the beta parameter balancing between real accesses
and all negatives (impostors and spoofing attacks)
"""
if
not
isinstance
(
omega
,
list
)
and
not
isinstance
(
omega
,
tuple
)
and
not
isinstance
(
omega
,
numpy
.
ndarray
):
omega
=
numpy
.
array
([
omega
])
else
:
omega
=
numpy
.
array
(
omega
)
if
not
isinstance
(
beta
,
list
)
and
not
isinstance
(
beta
,
tuple
)
and
not
isinstance
(
beta
,
numpy
.
ndarray
):
beta
=
numpy
.
array
([
beta
])
else
:
beta
=
numpy
.
array
(
beta
)
Parameters
----------
licit_neg : array_like
array of scores for the negatives (licit scenario)
licit_pos : array_like
array of scores for the positives (licit scenario)
spoof_neg : array_like
array of scores for the negatives (spoof scenario)
spoof_pos : array_like
array of scores for the positives (spoof scenario)
thresholds : array_like
ndarray with threshold values
omega : array_like
array of the omega parameter balancing between impostors
and spoofing attacks
beta : array_like
array of the beta parameter balancing between real accesses
and all negatives (impostors and spoofing attacks)
Returns
-------
far_w_errors: array_like
FAR_w
wer_wb_errors: array_like
WER_wb
"""
frr_errors
=
numpy
.
ndarray
((
beta
.
size
,
omega
.
size
),
'float64'
)
far_errors
=
numpy
.
ndarray
((
beta
.
size
,
omega
.
size
),
'float64'
)
...
...
bob/pad/base/script/figure.py
View file @
f276f395
...
...
@@ -17,6 +17,7 @@ from . import error_utils
ALL_CRITERIA
=
(
'bpcer20'
,
'eer'
,
'min-hter'
)
def
calc_threshold
(
method
,
neg
,
pos
):
"""Calculates the threshold based on the given method.
The scores should be sorted!
...
...
@@ -52,6 +53,7 @@ def calc_threshold(method, neg, pos):
return
threshold
class
Metrics
(
measure_figure
.
Metrics
):
def
__init__
(
self
,
ctx
,
scores
,
evaluation
,
func_load
):
super
(
Metrics
,
self
).
__init__
(
ctx
,
scores
,
evaluation
,
func_load
)
...
...
@@ -90,6 +92,7 @@ class Metrics(measure_figure.Metrics):
file
=
self
.
log_file
)
class
HistPad
(
measure_figure
.
Hist
):
''' Histograms for PAD '''
...
...
@@ -103,8 +106,6 @@ class HistPad(measure_figure.Hist):
hatch
=
'
\\\\
'
)
def
_calc_pass_rate
(
threshold
,
scores
):
return
(
scores
>=
threshold
).
mean
()
def
_iapmr_dot
(
threshold
,
iapmr
,
real_data
,
**
kwargs
):
# plot a dot on threshold versus IAPMR line and show IAPMR as a number
...
...
@@ -127,20 +128,23 @@ def _iapmr_dot(threshold, iapmr, real_data, **kwargs):
mpl
.
text
(
threshold
+
(
threshold
-
axlim
[
0
])
/
12
,
100.
*
iapmr
,
'%.1f%%'
%
(
100.
*
iapmr
,),
color
=
'C3'
)
def
_iapmr_line_plot
(
scores
,
n_points
=
100
,
**
kwargs
):
axlim
=
mpl
.
axis
()
step
=
(
axlim
[
1
]
-
axlim
[
0
])
/
float
(
n_points
)
thres
=
[(
k
*
step
)
+
axlim
[
0
]
for
k
in
range
(
2
,
n_points
-
1
)]
mix_prob_y
=
[]
for
k
in
thres
:
mix_prob_y
.
append
(
100.
*
_
calc_pass_rate
(
k
,
scores
))
mix_prob_y
.
append
(
100.
*
error_utils
.
calc_pass_rate
(
k
,
scores
))
mpl
.
plot
(
thres
,
mix_prob_y
,
label
=
'IAPMR'
,
color
=
'C3'
,
**
kwargs
)
def
_iapmr_plot
(
scores
,
threshold
,
iapmr
,
real_data
,
**
kwargs
):
_iapmr_dot
(
threshold
,
iapmr
,
real_data
,
**
kwargs
)
_iapmr_line_plot
(
scores
,
n_points
=
100
,
**
kwargs
)
class
HistVuln
(
measure_figure
.
Hist
):
''' Histograms for vulnerability '''
...
...
@@ -169,15 +173,7 @@ class HistVuln(measure_figure.Hist):
ax2
.
grid
(
False
)
real_data
=
True
if
'real_data'
not
in
self
.
_ctx
.
meta
else
\
self
.
_ctx
.
meta
[
'real_data'
]
far
,
frr
=
farfrr
(
neg
[
0
],
pos
[
0
],
threshold
)
_iapmr_plot
(
neg
[
1
],
threshold
,
iapmr
,
real_data
=
real_data
)
click
.
echo
(
'%s (t=%.2g) = %.2f%%; IAPMR = %.2f%%'
%
(
self
.
_criterion
.
upper
(),
threshold
,
50
*
(
far
+
frr
),
100
*
iapmr
)
)
n
=
idx
%
self
.
_step_print
col
=
n
%
self
.
_ncols
rest_print
=
self
.
n_systems
-
int
(
idx
/
self
.
_step_print
)
*
self
.
_step_print
...
...
@@ -187,6 +183,7 @@ class HistVuln(measure_figure.Hist):
ax2
.
yaxis
.
label
.
set_color
(
'red'
)
ax2
.
spines
[
'right'
].
set_color
(
'red'
)
class
PadPlot
(
measure_figure
.
PlotBase
):
'''Base class for PAD plots'''
def
__init__
(
self
,
ctx
,
scores
,
evaluation
,
func_load
):
...
...
@@ -208,7 +205,10 @@ class PadPlot(measure_figure.PlotBase):
li
,
la
=
ax
.
get_legend_handles_labels
()
lines
+=
li
labels
+=
la
mpl
.
gca
().
legend
(
lines
,
labels
,
loc
=
0
,
fancybox
=
True
,
framealpha
=
0.5
)
if
self
.
_disp_legend
:
mpl
.
gca
().
legend
(
lines
,
labels
,
loc
=
self
.
_legend_loc
,
fancybox
=
True
,
framealpha
=
0.5
)
class
Epc
(
PadPlot
):
''' Handles the plotting of EPC '''
...
...
@@ -277,12 +277,14 @@ class Epc(PadPlot):
prob_ax
.
yaxis
.
set_ticklabels
([
"%.0f"
%
val
for
val
in
ylabels
])
prob_ax
.
set_axisbelow
(
True
)
title
=
self
.
_legends
[
idx
]
if
self
.
_legends
is
not
None
else
self
.
_title
mpl
.
title
(
title
)
if
title
.
replace
(
' '
,
''
):
mpl
.
title
(
title
)
#legends for all axes
self
.
_plot_legends
()
mpl
.
xticks
(
rotation
=
self
.
_x_rotation
)
self
.
_pdf_page
.
savefig
(
mpl
.
gcf
())
class
Epsc
(
PadPlot
):
''' Handles the plotting of EPSC '''
def
__init__
(
self
,
ctx
,
scores
,
evaluation
,
func_load
,
...
...
@@ -397,11 +399,13 @@ class Epsc(PadPlot):
axis
.
spines
[
'right'
].
set_color
(
'red'
)
if
self
.
_var_param
==
'omega'
:
mpl
.
title
(
title
or
(
r
"EPSC with $\beta$ = %.2f"
%
\
self
.
_fixed_param
))
if
title
.
replace
(
' '
,
''
):
mpl
.
title
(
title
or
(
r
"EPSC with $\beta$ = %.2f"
%
\
self
.
_fixed_param
))
else
:
mpl
.
title
(
title
or
(
r
"EPSC with $\omega$ = %.2f"
%
\
self
.
_fixed_param
))
if
title
.
replace
(
' '
,
''
):
mpl
.
title
(
title
or
(
r
"EPSC with $\omega$ = %.2f"
%
\
self
.
_fixed_param
))
mpl
.
grid
()
self
.
_plot_legends
()
...
...
@@ -410,6 +414,7 @@ class Epsc(PadPlot):
mpl
.
xticks
(
rotation
=
self
.
_x_rotation
)
self
.
_pdf_page
.
savefig
()
class
Epsc3D
(
Epsc
):
''' 3D EPSC plots for PAD'''
def
compute
(
self
,
idx
,
input_scores
,
input_names
):
...
...
@@ -469,7 +474,8 @@ class Epsc3D(Epsc):
r
"WER$_{\omega,\beta}$ (%)"
if
self
.
_wer
else
"IAPMR (%)"
)
mpl
.
title
(
title
or
"3D EPSC"
)
if
title
.
replace
(
' '
,
''
):
mpl
.
title
(
title
or
"3D EPSC"
)
ax1
.
set_xticklabels
(
ax1
.
get_xticks
())
ax1
.
set_yticklabels
(
ax1
.
get_yticks
())
...
...
@@ -477,6 +483,7 @@ class Epsc3D(Epsc):
self
.
_pdf_page
.
savefig
()
class
Det
(
PadPlot
):
'''DET for PAD'''
def
__init__
(
self
,
ctx
,
scores
,
evaluation
,
func_load
,
criteria
,
real_data
):
...
...
@@ -617,11 +624,13 @@ class Det(PadPlot):
add
=
" and overlaid SPOOF scenario"
title
=
self
.
_title
if
self
.
_title
is
not
None
else
\
(
'DET: LICIT'
+
add
)
mpl
.
title
(
title
)
if
title
.
replace
(
' '
,
''
):
mpl
.
title
(
title
)
mpl
.
xlabel
(
self
.
_x_label
or
"False Acceptance Rate (%)"
)
mpl
.
ylabel
(
self
.
_y_label
or
"False Rejection Rate (%)"
)
mpl
.
grid
(
True
,
color
=
self
.
_grid_color
)
mpl
.
legend
(
loc
=
'best'
)
if
self
.
_disp_legend
:
mpl
.
legend
(
loc
=
self
.
_legend_loc
)
self
.
_set_axis
()
fig
=
mpl
.
gcf
()
mpl
.
xticks
(
rotation
=
self
.
_x_rotation
)
...
...
@@ -644,6 +653,7 @@ class Det(PadPlot):
else
:
det_axis
([
0.01
,
99
,
0.01
,
99
])
class
FmrIapmr
(
PadPlot
):
'''FMR vs IAPMR'''
def
__init__
(
self
,
ctx
,
scores
,
evaluation
,
func_load
):
...
...
@@ -682,11 +692,13 @@ class FmrIapmr(PadPlot):
close pdf is needed '''
#only for plots
title
=
self
.
_title
if
self
.
_title
is
not
None
else
"FMR vs IAPMR"
mpl
.
title
(
title
)
if
title
.
replace
(
' '
,
''
):
mpl
.
title
(
title
)
mpl
.
xlabel
(
self
.
_x_label
or
"False Match Rate (%)"
)
mpl
.
ylabel
(
self
.
_y_label
or
"IAPMR (%)"
)
mpl
.
grid
(
True
,
color
=
self
.
_grid_color
)
mpl
.
legend
(
loc
=
'best'
)
if
self
.
_disp_legend
:
mpl
.
legend
(
loc
=
self
.
_legend_loc
)
self
.
_set_axis
()
fig
=
mpl
.
gcf
()
mpl
.
xticks
(
rotation
=
self
.
_x_rotation
)
...
...
bob/pad/base/script/fmr_iapmr.py
View file @
f276f395
...
...
@@ -10,6 +10,8 @@ from . import figure
@
common_options
.
scores_argument
(
min_arg
=
2
,
force_eval
=
True
,
nargs
=-
1
)
@
common_options
.
output_plot_file_option
(
default_out
=
'fmr_iapmr.pdf'
)
@
common_options
.
legends_option
()
@
common_options
.
no_legend_option
()
@
common_options
.
legend_loc_option
()
@
common_options
.
title_option
()
@
common_options
.
const_layout_option
()
@
common_options
.
style_option
()
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment