Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
bob.learn.em
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
bob
bob.learn.em
Commits
44c8b41e
Commit
44c8b41e
authored
2 years ago
by
Yannick DAYER
Browse files
Options
Downloads
Patches
Plain Diff
Adding IVector high level methods
parent
a736f9db
No related branches found
No related tags found
1 merge request
!60
Port of I-Vector to python
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
bob/learn/em/ivector.py
+56
-5
56 additions, 5 deletions
bob/learn/em/ivector.py
bob/learn/em/test/test_ivector.py
+85
-12
85 additions, 12 deletions
bob/learn/em/test/test_ivector.py
with
141 additions
and
17 deletions
bob/learn/em/ivector.py
+
56
−
5
View file @
44c8b41e
...
...
@@ -2,15 +2,16 @@
# @author: Yannick Dayer <yannick.dayer@idiap.ch>
# @date: Fri 06 May 2022 14:18:25 UTC+02
import
copy
import
logging
from
typing
import
List
,
Tuple
from
typing
import
Any
,
Dict
,
List
,
Tuple
import
numpy
as
np
from
sklearn.base
import
BaseEstimator
from
bob.learn.em
import
GMMMachine
,
GMMStats
from
bob.learn.em
import
GMMMachine
,
GMMStats
,
linear_scoring
logger
=
logging
.
getLogger
(
"
__name__
"
)
...
...
@@ -93,7 +94,7 @@ def compute_tct_sigmac_inv(T: np.ndarray, sigma: np.ndarray) -> np.ndarray:
# Vectorized version:
# T.T (c,t,d) / sigma (c,1,d)
#
TT_sigma_inv (c,t,d) =
T.T (c,t,d) / sigma (c,1,d)
Tct_sigmacInv
=
T
.
transpose
(
0
,
2
,
1
)
/
sigma
[:,
None
,
:]
# Tt_sigma_inv (c,t,d)
...
...
@@ -244,8 +245,10 @@ class IVectorMachine(BaseEstimator):
self
.
dim_c
=
self
.
ubm
.
n_gaussians
self
.
dim_d
=
self
.
ubm
.
means
.
shape
[
-
1
]
self
.
T
=
np
.
zeros
(
shape
=
(
self
.
dim_c
,
self
.
dim_d
,
self
.
dim_t
))
self
.
sigma
=
np
.
zeros
(
shape
=
(
self
.
dim_c
,
self
.
dim_d
))
self
.
T
=
np
.
zeros
(
shape
=
(
self
.
dim_c
,
self
.
dim_d
,
self
.
dim_t
)
)
# TODO random ?
self
.
sigma
=
copy
.
deepcopy
(
self
.
ubm
.
variances
)
def
e_step
(
self
,
data
:
List
[
GMMStats
])
->
IVectorStats
:
"""
Computes the expectation step of the e-m algorithm.
"""
...
...
@@ -391,4 +394,52 @@ class IVectorMachine(BaseEstimator):
return
self
def
project
(
self
,
stats
:
GMMStats
)
->
IVectorStats
:
if
not
isinstance
(
stats
,
GMMStats
):
return
[
self
.
project
(
s
)
for
s
in
stats
]
# TODO yes?
return
forward
(
self
.
ubm
.
means
,
stats
,
self
.
T
,
self
.
sigma
)
def
transform
(
self
,
data
:
np
.
ndarray
)
->
List
[
IVectorStats
]:
"""
Transforms the data using the trained IVectorMachine.
Parameters
----------
data : np.ndarray
The data to transform.
Returns
-------
np.ndarray
The transformed data.
"""
stats
=
self
.
project
(
self
.
ubm
.
acc_stats
(
data
))
return
stats
.
t
def
enroll
(
self
,
stats
:
List
[
GMMStats
])
->
IVectorStats
:
"""
Enrolls a new speaker.
Parameters
----------
stats : List[GMMStats]
The GMM statistics of the speaker to enroll.
Returns
-------
IVectorStats
The IVector statistics of the speaker.
"""
return
self
.
project
(
stats
)
def
score
(
self
,
model
:
IVectorStats
,
probes
:
List
[
GMMStats
])
->
List
[
float
]:
return
linear_scoring
(
model
,
ubm
=
self
.
ubm
,
test_stats
=
probes
,
test_channel_offsets
=
0
,
frame_length_normalization
=
True
,
)
def
_more_tags
(
self
)
->
Dict
[
str
,
Any
]:
return
{
"
requires_fit
"
:
True
,
"
bob_fit_supports_dask_arrays
"
:
True
,
}
This diff is collapsed.
Click to expand it.
bob/learn/em/test/test_ivector.py
+
85
−
12
View file @
44c8b41e
...
...
@@ -7,12 +7,27 @@ import numpy as np
from
bob.learn.em
import
GMMMachine
,
GMMStats
,
IVectorMachine
def
test_ivector_machine_base
():
dim_c
,
dim_d
,
dim_t
=
2
,
3
,
4
# Create the UBM and set its values manually
ubm
=
GMMMachine
(
n_gaussians
=
dim_c
)
ubm
.
weights
=
np
.
array
([
0.4
,
0.6
],
dtype
=
float
)
ubm
.
means
=
np
.
array
([[
1
,
7
,
4
],
[
4
,
5
,
3
]],
dtype
=
float
)
ubm
.
variances
=
np
.
array
([[
0.5
,
1.0
,
1.5
],
[
1.0
,
1.5
,
2.0
]],
dtype
=
float
)
machine
=
IVectorMachine
(
ubm
=
ubm
,
dim_t
=
dim_t
)
assert
hasattr
(
machine
,
"
ubm
"
)
assert
hasattr
(
machine
,
"
T
"
)
assert
hasattr
(
machine
,
"
sigma
"
)
assert
machine
.
T
.
shape
==
(
dim_c
,
dim_d
,
dim_t
),
machine
.
T
.
shape
assert
machine
.
sigma
.
shape
==
(
dim_c
,
dim_d
),
machine
.
sigma
.
shape
np
.
testing
.
assert_equal
(
machine
.
sigma
,
ubm
.
variances
)
def
test_ivector_machine_projection
():
# Preset IVector Machine parameters
t
=
np
.
array
(
[[
1
,
2
],
[
4
,
1
],
[
0
,
3
],
[
5
,
8
],
[
7
,
10
],
[
11
,
1
]],
dtype
=
float
)
sigma
=
np
.
array
([
1
,
2
,
1
,
3
,
2
,
4
],
dtype
=
float
)
# Create the UBM and set its values manually
ubm
=
GMMMachine
(
n_gaussians
=
2
)
...
...
@@ -20,24 +35,82 @@ def test_ivector_machine_projection():
ubm
.
means
=
np
.
array
([[
1
,
7
,
4
],
[
4
,
5
,
3
]],
dtype
=
float
)
ubm
.
variances
=
np
.
array
([[
0.5
,
1.0
,
1.5
],
[
1.0
,
1.5
,
2.0
]],
dtype
=
float
)
# Manually create a feature projected on the UBM
machine
=
IVectorMachine
(
ubm
=
ubm
,
dim_t
=
2
)
machine
.
T
=
np
.
array
(
[[[
1
,
2
],
[
4
,
1
],
[
0
,
3
]],
[[
5
,
8
],
[
7
,
10
],
[
11
,
1
]]],
dtype
=
float
)
machine
.
sigma
=
np
.
array
([[
1
,
2
,
1
],
[
3
,
2
,
4
]],
dtype
=
float
)
# Manually create a feature (usually projected with the UBM)
gmm_projection
=
GMMStats
(
ubm
.
n_gaussians
,
ubm
.
means
.
shape
[
-
1
])
gmm_projection
.
t
=
1
gmm_projection
.
n
=
np
.
array
([
0.4
,
0.6
],
dtype
=
float
)
gmm_projection
.
sum_px
=
np
.
array
([[
1
,
2
,
3
],
[
2
,
4
,
3
]],
dtype
=
float
)
gmm_projection
.
sum_pxx
=
np
.
array
([[
10
,
20
,
30
],
[
40
,
50
,
60
]],
dtype
=
float
)
machine
=
IVectorMachine
(
ubm
=
ubm
,
dim_t
=
2
)
machine
.
t
=
t
machine
.
sigma
=
sigma
# Reference from C++ implementation
ivector_projection_ref
=
np
.
array
([
-
0.04213415
,
0.21463343
])
ivector_projection
=
machine
.
project
(
gmm_projection
)
np
.
testing
.
assert_almost_equal
(
ivector_projection_ref
,
ivector_projection
,
decimal
=
5
ivector_projection_ref
,
ivector_projection
,
decimal
=
7
)
def
test_ivector_machine_transformer
():
ubm
=
GMMMachine
(
n_gaussians
=
2
)
ubm
.
means
=
np
.
array
([[
1
,
7
,
4
],
[
4
,
5
,
3
]],
dtype
=
float
)
ubm
.
variances
=
np
.
array
([[
0.5
,
1.0
,
1.5
],
[
1.0
,
1.5
,
2.0
]],
dtype
=
float
)
machine
=
IVectorMachine
(
ubm
=
ubm
,
dim_t
=
2
)
assert
hasattr
(
machine
,
"
fit
"
)
assert
hasattr
(
machine
,
"
transform
"
)
assert
hasattr
(
machine
,
"
enroll
"
)
assert
hasattr
(
machine
,
"
score
"
)
transformed
=
machine
.
transform
([
np
.
ndarray
([
1
,
2
,
3
])])[
0
]
assert
isinstance
(
transformed
,
IVectorMachine
)
nij_sigma_wij2_ref
=
np
.
array
([[
0.5
,
1.0
,
1.5
],
[
1.0
,
1.5
,
2.0
]])
# TODO
nij_ref
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]])
fnorm_sigma_wij_ref
=
np
.
array
([[
0.5
,
1.0
,
1.5
],
[
1.0
,
1.5
,
2.0
]])
# TODO
snormij_ref
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]])
np
.
testing
.
assert_almost_equal
(
transformed
.
acc_nij_sigma_wij2
,
nij_sigma_wij2_ref
)
np
.
testing
.
assert_almost_equal
(
transformed
.
acc_nij
,
nij_ref
)
np
.
testing
.
assert_almost_equal
(
transformed
.
acc_fnorm_sigma_wij
,
fnorm_sigma_wij_ref
)
np
.
testing
.
assert_almost_equal
(
transformed
.
acc_snormij
,
snormij_ref
)
def
test_ivector_machine_training
():
assert
False
,
"
Not implemented
"
# Define GMMStats
gs1
=
GMMStats
(
n_gaussians
=
2
,
n_features
=
3
)
gs1
.
log_likelihood
=
-
3
gs1
.
t
=
1
gs1
.
n
=
np
.
array
([
0.4
,
0.6
],
dtype
=
float
)
gs1
.
sum_px
=
np
.
array
([[
1.0
,
2.0
,
3.0
],
[
2.0
,
4.0
,
3.0
]],
dtype
=
float
)
gs1
.
sum_pxx
=
np
.
array
(
[[
10.0
,
20.0
,
30.0
],
[
40.0
,
50.0
,
60.0
]],
dtype
=
float
)
gs2
=
GMMStats
(
n_gaussians
=
2
,
n_features
=
3
)
gs2
.
log_likelihood
=
-
4
gs2
.
t
=
1
gs2
.
n
=
np
.
array
([
0.2
,
0.8
],
dtype
=
float
)
gs2
.
sum_px
=
np
.
array
([[
2.0
,
1.0
,
3.0
],
[
3.0
,
4.1
,
3.2
]],
dtype
=
float
)
gs2
.
sum_pxx
=
np
.
array
(
[[
12.0
,
15.0
,
25.0
],
[
39.0
,
51.0
,
62.0
]],
dtype
=
float
)
data
=
[
gs1
,
gs2
]
# Define the ubm
ubm
=
GMMMachine
(
n_gaussians
=
3
)
ubm
.
means
=
np
.
array
([[
1
,
2
,
3
],
[
6
,
7
,
8
],
[
10
,
11
,
12
]])
ubm
.
variances
=
np
.
ones
((
3
,
3
))
machine
=
IVectorMachine
(
ubm
=
ubm
,
dim_t
=
2
)
machine
.
fit
(
data
)
assert
False
,
"
TODO: add tests (with projection)
"
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
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!
Save comment
Cancel
Please
register
or
sign in
to comment