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
6541b440
Commit
6541b440
authored
2 years ago
by
Yannick DAYER
Browse files
Options
Downloads
Patches
Plain Diff
[refactor] Cleaning reference comments from c++
parent
0e5c7756
No related branches found
No related tags found
1 merge request
!60
Port of I-Vector to python
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
bob/learn/em/ivector.py
+10
-109
10 additions, 109 deletions
bob/learn/em/ivector.py
with
10 additions
and
109 deletions
bob/learn/em/ivector.py
+
10
−
109
View file @
6541b440
...
...
@@ -78,27 +78,6 @@ class IVectorStats:
def
compute_tct_sigmac_inv
(
T
:
np
.
ndarray
,
sigma
:
np
.
ndarray
)
->
np
.
ndarray
:
"""
Computes T_{c}^{T}.sigma_{c}^{-1}
"""
# C++ to port to python:
#
# for (int c=0; c<C; ++c)
# {
# blitz::Array<double,2> Tct_sigmacInv = m_cache_Tct_sigmacInv(c, rall, rall);
# blitz::Array<double,2> Tc = m_T(blitz::Range(c*D,(c+1)*D-1), rall);
# blitz::Array<double,2> Tct = Tc.transpose(1,0);
# blitz::Array<double,1> sigma_c = m_sigma(blitz::Range(c*D,(c+1)*D-1));
# Tct_sigmacInv = Tct(i,j) / sigma_c(j);
# }
# Python version:
# Tct_sigmacInv = np.zeros(shape=(c,d,t))
# for c in range(dim_c):
# Tc = T[c]
# Tct = Tc.transpose(1, 0)
# sigma_c = sigma[c]
# Tct_sigmacInv[c] = T[c].t / sigma[c]
# Vectorized version:
# TT_sigma_inv (c,t,d) = T.T (c,t,d) / sigma (c,1,d)
Tct_sigmacInv
=
T
.
transpose
(
0
,
2
,
1
)
/
sigma
[:,
None
,
:]
...
...
@@ -108,18 +87,8 @@ def compute_tct_sigmac_inv(T: np.ndarray, sigma: np.ndarray) -> np.ndarray:
def
compute_tct_sigmac_inv_tc
(
T
:
np
.
ndarray
,
sigma
:
np
.
ndarray
)
->
np
.
ndarray
:
"""
Computes T_{c}^{T}.sigma_{c}^{-1}.T_{c}
"""
# for (int c=0; c<C; ++c)
# {
# blitz::Array<double,2> Tc = m_T(blitz::Range(c*D,(c+1)*D-1), rall);
# blitz::Array<double,2> Tct_sigmacInv = m_cache_Tct_sigmacInv(c, rall, rall);
# blitz::Array<double,2> Tct_sigmacInv_Tc = m_cache_Tct_sigmacInv_Tc(c, rall, rall);
# bob::math::prod(Tct_sigmacInv, Tc, Tct_sigmacInv_Tc);
# }
Tct_sigmacInv_Tc
=
np
.
zeros
(
shape
=
(
T
.
shape
[
0
],
T
.
shape
[
-
1
],
T
.
shape
[
-
1
]))
# Python version:
tct_sigmac_inv
=
compute_tct_sigmac_inv
(
T
,
sigma
)
for
c
in
range
(
T
.
shape
[
0
]):
# TODO Vectorize
# (c,t,t) = (c,t,d) @ (c,d,t)
...
...
@@ -132,14 +101,6 @@ def compute_tct_sigmac_inv_tc(T: np.ndarray, sigma: np.ndarray) -> np.ndarray:
def
compute_id_tt_sigma_inv_t
(
stats
:
GMMStats
,
T
:
np
.
ndarray
,
sigma
:
np
.
ndarray
)
->
np
.
ndarray
:
# void bob::learn::em::IVectorMachine::computeIdTtSigmaInvT(
# const bob::learn::em::GMMStats& gs, blitz::Array<double,2>& output) const
# {
# blitz::Range rall = blitz::Range::all();
# bob::math::eye(output);
# for (int c=0; c<(int)getNGaussians(); ++c)
# output += gs.n(c) * m_cache_Tct_sigmacInv_Tc(c, rall, rall);
# }
dim_t
=
T
.
shape
[
-
1
]
output
=
np
.
eye
(
dim_t
,
dim_t
)
tct_sigmac_inv_tc
=
compute_tct_sigmac_inv_tc
(
T
,
sigma
)
...
...
@@ -159,22 +120,6 @@ def compute_tt_sigma_inv_fnorm(
Returns an array of shape (t,)
"""
# void bob::learn::em::IVectorMachine::computeTtSigmaInvFnorm(
# const bob::learn::em::GMMStats& gs, blitz::Array<double,1>& output) const
# {
# // Computes \f$T^{T} \Sigma^{-1} \sum_{c=1}^{C} (F_c - N_c ubmmean_{c})\f$
# blitz::Range rall = blitz::Range::all();
# output = 0;
# for (int c=0; c<(int)getNGaussians(); ++c)
# {
# m_tmp_d = gs.sumPx(c,rall) - gs.n(c) * m_ubm->getGaussian(c)->getMean();
# blitz::Array<double,2> Tct_sigmacInv = m_cache_Tct_sigmacInv(c, rall, rall);
# bob::math::prod(Tct_sigmacInv, m_tmp_d, m_tmp_t2);
# output += m_tmp_t2;
# }
# }
output
=
np
.
zeros
(
shape
=
T
.
shape
[
-
1
])
tct_sigmac_inv
=
compute_tct_sigmac_inv
(
T
,
sigma
)
# (c,t,d)
fnorm
=
stats
.
sum_px
-
stats
.
n
[:,
None
]
*
ubm_means
# (c,d)
...
...
@@ -224,9 +169,6 @@ class IVectorMachine(BaseEstimator):
self
.
convergence_threshold
=
convergence_threshold
self
.
max_iterations
=
max_iterations
self
.
update_sigma
=
update_sigma
# TODO: add params
# self.compute_likelihood = compute_likelihood
# self.variance_floor = variance_floor
self
.
dim_c
=
self
.
ubm
.
n_gaussians
self
.
dim_d
=
self
.
ubm
.
means
.
shape
[
-
1
]
self
.
variance_floor
=
variance_floor
...
...
@@ -253,21 +195,6 @@ class IVectorMachine(BaseEstimator):
sample
,
self
.
T
,
self
.
sigma
)
# self.compute_Id_TtSigmaInvT(data[n]), # shape: (t,t)
# Fnorm = np.zeros(
# shape=(
# self.dim_c,
# self.dim_d,
# ),
# dtype=float,
# )
# Snorm = np.zeros(
# shape=(
# self.dim_c,
# self.dim_d,
# ),
# dtype=float,
# )
# Latent variables
I_TtSigmaInvNT_inv
=
np
.
linalg
.
inv
(
I_TtSigmaInvNT
)
# shape: (t,t)
sigma_w_ij
=
np
.
dot
(
...
...
@@ -278,18 +205,6 @@ class IVectorMachine(BaseEstimator):
)
# shape: (t,t)
# Compute normalized statistics
# for c in range(self.dim_c): # TODO Vectorize
# Fc = Fij[c, :]
# Sc = Sij[c, :]
# mc = self.ubm.means[c]
# Fc_mc = Fc * mc
# Nc_mc_mcT = Nij[c] * mc * mc
# Fnorm[c] = Fc - Nij[c] * mc
# Snorm[c] = Sc - (2 * Fc_mc) + Nc_mc_mcT
Fnorm
=
Fij
-
Nij
[:,
None
]
*
self
.
ubm
.
means
Snorm
=
(
Sij
...
...
@@ -304,12 +219,8 @@ class IVectorMachine(BaseEstimator):
stats
.
nij_sigma_wij2
[
c
]
+=
(
Nij
[
c
]
*
sigma_w_ij2
)
# (dim_t, dim_t)
# stats.nij_sigma_wij2 += Nij[:, None] * sigma_w_ij2 # (c, t, t) # TODO Not working
# stats.nij_sigma_wij2 += Nij[:, None] * sigma_w_ij2 # (c, t, t) # TODO
Vectorized v.
Not working
stats
.
nij
+=
Nij
# for c in range(self.dim_c): # TODO Vectorize
# stats.fnorm_sigma_wij[c] += np.outer(
# Fnorm[c], sigma_w_ij # (c,d) x (t,)
# ) # (dim_d, dim_t)
stats
.
fnorm_sigma_wij
+=
np
.
matmul
(
Fnorm
[:,
:,
None
],
sigma_w_ij
[
None
,
:]
)
# (c,d,t)
...
...
@@ -318,16 +229,6 @@ class IVectorMachine(BaseEstimator):
def
m_step
(
self
,
stats
:
IVectorStats
)
->
None
:
"""
Updates the Machine with the maximization step of the e-m algorithm.
"""
A
=
stats
.
nij_sigma_wij2
# self.T = np.zeros(
# shape=(self.dim_c, self.dim_d, self.dim_t),
# dtype=np.float64,
# )
# if self.update_sigma:
# self.sigma = np.zeros(
# shape=stats.snormij.shape, dtype=np.float64
# )
for
c
in
range
(
self
.
dim_c
):
# TODO Vectorize
# T update
A
=
stats
.
nij_sigma_wij2
[
c
].
transpose
()
...
...
@@ -356,7 +257,7 @@ class IVectorMachine(BaseEstimator):
``max_iterations`` is reached.
"""
t_old
=
0
#
t_old = 0
for
step
in
range
(
self
.
max_iterations
):
logger
.
debug
(
f
"
IVector step
{
step
+
1
}
.
"
)
# E-step
...
...
@@ -364,14 +265,14 @@ class IVectorMachine(BaseEstimator):
# M-step
self
.
m_step
(
stats
)
# Convergence
if
step
>
0
:
if
np
.
linalg
.
norm
(
stats
.
t
-
t_old
)
<
self
.
convergence_threshold
:
logger
.
info
(
f
"
Converged after
{
step
+
1
}
steps.
"
)
logger
.
debug
(
f
"
t_diff:
{
stats
.
t
-
t_old
}
(Convergence threshold:
{
self
.
convergence_threshold
}
)
"
)
break
t_old
=
stats
.
t
#
if step > 0:
#
if np.linalg.norm(stats.t - t_old) < self.convergence_threshold:
#
logger.info(f"Converged after {step+1} steps.")
#
logger.debug(
#
f"t_diff: {stats.t - t_old} (Convergence threshold: {self.convergence_threshold})"
#
)
#
break
#
t_old = stats.t
else
:
logger
.
info
(
f
"
Did not converge after
{
step
+
1
}
steps.
"
)
return
self
...
...
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