Contents

Introduction

If you use this software for your experiment and found that it is useful, please cite the following paper:

@Inproceedings{poh10:_gFnorm,
   author =  {N. Poh and A. Rattani and M. Tistarelli and J. Kittler},
   title ={Group-specific Score Normalization for Biometric Systems},
   booktitle = {IEEE Computer Society Workshop on Biometrics, CVPR2010},
   year = 2010
}

% First, download this file
% http://info.ee.surrey.ac.uk/Personal/Norman.Poh/web/gFnorm/gFnorm.zip
% and unzip all the contents to a directory.
% Then, go to that directory and execute the following codes.

addpath lib

Load the data sets

The training and test data sets are two different partitions of users (hence non-overlapping). These two sets are called dev and eva here. For each data set (dev or eva), we have also enrolment and query sessions which are named ses1 and ses2 in our case.

p=1; %training data set
d=1; [dat{p}.dset{d,1}, dat{p}.dset{d,2}, dat{p}.label{d,1}, dat{p}.label{d,2}, dat{p}.impostor_id{d}] = load_raw_scores_labels('cost_dev_ses1.scores'); %enrolment
d=2; [dat{p}.dset{d,1}, dat{p}.dset{d,2}, dat{p}.label{d,1}, dat{p}.label{d,2}, dat{p}.impostor_id{d}] = load_raw_scores_labels('cost_dev_ses2.scores'); %query
p=2; %testing data set
d=1; [dat{p}.dset{d,1}, dat{p}.dset{d,2}, dat{p}.label{d,1}, dat{p}.label{d,2}, dat{p}.impostor_id{d}] = load_raw_scores_labels('cost_eva_ses1.scores'); %enrolment
d=2; [dat{p}.dset{d,1}, dat{p}.dset{d,2}, dat{p}.label{d,1}, dat{p}.label{d,2}, dat{p}.impostor_id{d}] = load_raw_scores_labels('cost_eva_ses2.scores'); %query

% The dev set is used to derive the mean scores which are used to partition
% the users into four groups.

% If you do not have the two data sets, you could partition them yourself
% or else use the same data set for both, e.g.:
% dat{2} = dat{1}
The following columns are used:
working_col =

1

21063 samples loaded
The following columns are used:
working_col =

1

21114 samples loaded
The following columns are used:
working_col =

1

129524 samples loaded
The following columns are used:
working_col =

1

77234 samples loaded

Check that the claimed client IDs are consistent:

for p=1:2,
fprintf(1, 'The claimed client IDs are listing below for data set %d :\n',p);
[unique(dat{p}.label{1,1}) unique(dat{p}.label{1,2}) unique(dat{p}.label{2,1}) unique(dat{p}.label{2,2})]
end;
The claimed client IDs are listing below for data set 1 :

ans =

4006 4006 4006 4006
4007 4007 4007 4007
4008 4008 4008 4008
4012 4012 4012 4012
4014 4014 4014 4014
4015 4015 4015 4015
4016 4016 4016 4016
4017 4017 4017 4017
4018 4018 4018 4018
4020 4020 4020 4020
4021 4021 4021 4021
4023 4023 4023 4023
4024 4024 4024 4024
4027 4027 4027 4027
4028 4028 4028 4028
4030 4030 4030 4030
4032 4032 4032 4032
4035 4035 4035 4035
4036 4036 4036 4036
8000 8000 8000 8000
8001 8001 8001 8001
8004 8004 8004 8004
8007 8007 8007 8007
8008 8008 8008 8008
8009 8009 8009 8009
8010 8010 8010 8010
8011 8011 8011 8011
8013 8013 8013 8013
8015 8015 8015 8015
8016 8016 8016 8016
8017 8017 8017 8017
8018 8018 8018 8018
8019 8019 8019 8019
8020 8020 8020 8020
8022 8022 8022 8022
8023 8023 8023 8023
8025 8025 8025 8025
8026 8026 8026 8026
8027 8027 8027 8027
8028 8028 8028 8028
11001 11001 11001 11001
11004 11004 11004 11004
11005 11005 11005 11005
11006 11006 11006 11006
11007 11007 11007 11007
11008 11008 11008 11008
11009 11009 11009 11009
11010 11010 11010 11010
11011 11011 11011 11011
11014 11014 11014 11014
11015 11015 11015 11015

The claimed client IDs are listing below for data set 2 :

ans =

4037 4037 4037 4037
4038 4038 4038 4038
4039 4039 4039 4039
4040 4040 4040 4040
4041 4041 4041 4041
4042 4042 4042 4042
4044 4044 4044 4044
4045 4045 4045 4045
4046 4046 4046 4046
4048 4048 4048 4048
4049 4049 4049 4049
4050 4050 4050 4050
4052 4052 4052 4052
4053 4053 4053 4053
4054 4054 4054 4054
4056 4056 4056 4056
4058 4058 4058 4058
4059 4059 4059 4059
4060 4060 4060 4060
4061 4061 4061 4061
4062 4062 4062 4062
4063 4063 4063 4063
4064 4064 4064 4064
4065 4065 4065 4065
4067 4067 4067 4067
4070 4070 4070 4070
4071 4071 4071 4071
4073 4073 4073 4073
4074 4074 4074 4074
4075 4075 4075 4075
4076 4076 4076 4076
4077 4077 4077 4077
4079 4079 4079 4079
4081 4081 4081 4081
4082 4082 4082 4082
4083 4083 4083 4083
4084 4084 4084 4084
4085 4085 4085 4085
4086 4086 4086 4086
4087 4087 4087 4087
4088 4088 4088 4088
4091 4091 4091 4091
4093 4093 4093 4093
4094 4094 4094 4094
4096 4096 4096 4096
4097 4097 4097 4097
4098 4098 4098 4098
4099 4099 4099 4099
4101 4101 4101 4101
4102 4102 4102 4102
4104 4104 4104 4104
4108 4108 4108 4108
4109 4109 4109 4109
4110 4110 4110 4110
4114 4114 4114 4114
4115 4115 4115 4115
4118 4118 4118 4118
4119 4119 4119 4119
4121 4121 4121 4121
8029 8029 8029 8029
8031 8031 8031 8031
8032 8032 8032 8032
8033 8033 8033 8033
8034 8034 8034 8034
8035 8035 8035 8035
8037 8037 8037 8037
8038 8038 8038 8038
8039 8039 8039 8039
8040 8040 8040 8040
8041 8041 8041 8041
8042 8042 8042 8042
8043 8043 8043 8043
8044 8044 8044 8044
8045 8045 8045 8045
8046 8046 8046 8046
8047 8047 8047 8047
8048 8048 8048 8048
8049 8049 8049 8049
8050 8050 8050 8050
8051 8051 8051 8051
8052 8052 8052 8052
8053 8053 8053 8053
8054 8054 8054 8054
8056 8056 8056 8056
8057 8057 8057 8057
8058 8058 8058 8058
8059 8059 8059 8059
8060 8060 8060 8060
8061 8061 8061 8061
8062 8062 8062 8062
8064 8064 8064 8064
8065 8065 8065 8065
8066 8066 8066 8066
8067 8067 8067 8067
8069 8069 8069 8069
8070 8070 8070 8070
8071 8071 8071 8071
8073 8073 8073 8073
8074 8074 8074 8074
8075 8075 8075 8075
8076 8076 8076 8076
8077 8077 8077 8077
8078 8078 8078 8078
8079 8079 8079 8079
8080 8080 8080 8080
8081 8081 8081 8081
8083 8083 8083 8083
8084 8084 8084 8084
8085 8085 8085 8085
8086 8086 8086 8086
8087 8087 8087 8087
8088 8088 8088 8088
8089 8089 8089 8089
8090 8090 8090 8090
8093 8093 8093 8093
8095 8095 8095 8095
8096 8096 8096 8096
8097 8097 8097 8097
8098 8098 8098 8098
8101 8101 8101 8101
8102 8102 8102 8102
8103 8103 8103 8103
8104 8104 8104 8104
11017 11017 11017 11017
11018 11018 11018 11018
11019 11019 11019 11019
11020 11020 11020 11020
11021 11021 11021 11021
11022 11022 11022 11022
11025 11025 11025 11025
11026 11026 11026 11026
11027 11027 11027 11027
11028 11028 11028 11028
11029 11029 11029 11029
11030 11030 11030 11030
11031 11031 11031 11031
11033 11033 11033 11033
11034 11034 11034 11034
11035 11035 11035 11035
11036 11036 11036 11036
11037 11037 11037 11037
11038 11038 11038 11038
11039 11039 11039 11039
11041 11041 11041 11041
11042 11042 11042 11042
11043 11043 11043 11043
11044 11044 11044 11044
11045 11045 11045 11045
11046 11046 11046 11046
11047 11047 11047 11047
11048 11048 11048 11048
11050 11050 11050 11050
11051 11051 11051 11051
11052 11052 11052 11052
11053 11053 11053 11053
11054 11054 11054 11054

perform group-specific Fnorm

adapt_prm = 1;
client_spec = 0;
debug = 1;
gnorm = gFnorm(dat, adapt_prm,client_spec, debug);

plot the DET curve

for p=1:2,
figure(p);
eer_{p}(1) = wer(gnorm{p}.dset{2,1},gnorm{p}.dset{2,2},[],2,[],1);
eer_{p}(2) = wer(dat{p}.dset{2,1},dat{p}.dset{2,2},[],2,[],2);
legend('gFnorm','orig');
end;

perform client-specific Fnorm

adapt_prm = 0.5; %the *recommended* parameter
client_spec = 1;
Fnorm = gFnorm(dat, adapt_prm,client_spec);

plot the DET curve

for p=1:2,
figure(p);
eer_{p}(1) = wer(Fnorm{p}.dset{2,1},Fnorm{p}.dset{2,2},[],2,[],1);
eer_{p}(2) = wer(dat{p}.dset{2,1},dat{p}.dset{2,2},[],2,[],2);
legend('Fnorm','orig');
end;