Mercurial > hg > aimc
comparison src/Modules/Features/ModuleGaussians.cc @ 162:9fcf55c040fe
- Added property svn:eol-style native to all text files
author | tomwalters |
---|---|
date | Thu, 22 Jul 2010 04:14:20 +0000 |
parents | f03d4455b262 |
children | c155e7fbe76e |
comparison
equal
deleted
inserted
replaced
161:0420c86456c1 | 162:9fcf55c040fe |
---|---|
24 * \date created 2008/06/23 | 24 * \date created 2008/06/23 |
25 * \version \$Id$ | 25 * \version \$Id$ |
26 */ | 26 */ |
27 | 27 |
28 #include <math.h> | 28 #include <math.h> |
29 | |
30 #ifdef _WINDOWS | |
31 #include <float.h> | |
32 #endif | |
33 | 29 |
34 #include "Modules/Features/ModuleGaussians.h" | 30 #include "Modules/Features/ModuleGaussians.h" |
35 #include "Support/Common.h" | 31 #include "Support/Common.h" |
36 | 32 |
37 namespace aimc { | 33 namespace aimc { |
40 module_description_ = "Gaussian Fitting to SSI profile"; | 36 module_description_ = "Gaussian Fitting to SSI profile"; |
41 module_identifier_ = "gaussians"; | 37 module_identifier_ = "gaussians"; |
42 module_type_ = "features"; | 38 module_type_ = "features"; |
43 module_version_ = "$Id$"; | 39 module_version_ = "$Id$"; |
44 | 40 |
45 m_iParamNComp = parameters_->DefaultInt("gaussians.ncomp", 4); | 41 m_iParamNComp = parameters_->DefaultInt("features.gaussians.ncomp", 4); |
46 m_fParamVar = parameters_->DefaultFloat("gaussians.var", 115.0); | 42 m_fParamVar = parameters_->DefaultFloat("features.gaussians.var", 115.0); |
47 m_fParamPosteriorExp = parameters_->DefaultFloat("gaussians.posterior_exp", | 43 m_fParamPosteriorExp = |
48 6.0); | 44 parameters_->DefaultFloat("features.gaussians.posterior_exp", 6.0); |
49 m_iParamMaxIt = parameters_->DefaultInt("gaussians.maxit", 250); | 45 m_iParamMaxIt = parameters_->DefaultInt("features.gaussians.maxit", 250); |
50 | 46 |
51 // The parameters system doesn't support tiny numbers well, to define this | 47 // The parameters system doesn't support tiny numbers well, to define this |
52 // variable as a string, then convert it to a float afterwards | 48 // variable as a string, then convert it to a float afterwards |
53 parameters_->DefaultString("gaussians.priors_converged", "1e-7"); | 49 parameters_->DefaultString("features.gaussians.priors_converged", "1e-7"); |
54 priors_converged_ = parameters_->GetFloat("gaussians.priors_converged"); | 50 m_fParamPriorsConverged = |
55 output_positions_ = parameters_->DefaultBool("gaussians.positions", false); | 51 parameters_->GetFloat("features.gaussians.priors_converged"); |
56 } | 52 } |
57 | 53 |
58 ModuleGaussians::~ModuleGaussians() { | 54 ModuleGaussians::~ModuleGaussians() { |
59 } | 55 } |
60 | 56 |
62 m_pA.resize(m_iParamNComp, 0.0f); | 58 m_pA.resize(m_iParamNComp, 0.0f); |
63 m_pMu.resize(m_iParamNComp, 0.0f); | 59 m_pMu.resize(m_iParamNComp, 0.0f); |
64 | 60 |
65 // Assuming the number of channels is greater than twice the number of | 61 // Assuming the number of channels is greater than twice the number of |
66 // Gaussian components, this is ok | 62 // Gaussian components, this is ok |
67 output_component_count_ = 1; // Energy component | |
68 if (input.channel_count() >= 2 * m_iParamNComp) { | 63 if (input.channel_count() >= 2 * m_iParamNComp) { |
69 output_component_count_ += (m_iParamNComp - 1); | 64 output_.Initialize(m_iParamNComp, 1, input.sample_rate()); |
70 } else { | 65 } else { |
71 LOG_ERROR(_T("Too few channels in filterbank to produce sensible " | 66 LOG_ERROR(_T("Too few channels in filterbank to produce sensible " |
72 "Gaussian features. Either increase the number of filterbank" | 67 "Gaussian features. Either increase the number of filterbank" |
73 " channels, or decrease the number of Gaussian components")); | 68 " channels, or decrease the number of Gaussian components")); |
74 return false; | 69 return false; |
75 } | 70 } |
76 | |
77 if (output_positions_) { | |
78 output_component_count_ += m_iParamNComp; | |
79 } | |
80 | |
81 output_.Initialize(output_component_count_, 1, input.sample_rate()); | |
82 | 71 |
83 m_iNumChannels = input.channel_count(); | 72 m_iNumChannels = input.channel_count(); |
84 m_pSpectralProfile.resize(m_iNumChannels, 0.0f); | 73 m_pSpectralProfile.resize(m_iNumChannels, 0.0f); |
85 | 74 |
86 return true; | 75 return true; |
98 void ModuleGaussians::Process(const SignalBank &input) { | 87 void ModuleGaussians::Process(const SignalBank &input) { |
99 if (!initialized_) { | 88 if (!initialized_) { |
100 LOG_ERROR(_T("Module ModuleGaussians not initialized.")); | 89 LOG_ERROR(_T("Module ModuleGaussians not initialized.")); |
101 return; | 90 return; |
102 } | 91 } |
103 output_.set_start_time(input.start_time()); | |
104 // Calculate spectral profile | 92 // Calculate spectral profile |
105 for (int ch = 0; ch < input.channel_count(); ++ch) { | 93 for (int iChannel = 0; |
106 m_pSpectralProfile[ch] = 0.0f; | 94 iChannel < input.channel_count(); |
107 for (int i = 0; i < input.buffer_length(); ++i) { | 95 ++iChannel) { |
108 m_pSpectralProfile[ch] += input[ch][i]; | 96 m_pSpectralProfile[iChannel] = 0.0f; |
109 } | 97 for (int iSample = 0; |
110 m_pSpectralProfile[ch] /= static_cast<float>(input.buffer_length()); | 98 iSample < input.buffer_length(); |
99 ++iSample) { | |
100 m_pSpectralProfile[iChannel] += input[iChannel][iSample]; | |
101 } | |
102 m_pSpectralProfile[iChannel] /= static_cast<float>(input.buffer_length()); | |
111 } | 103 } |
112 | 104 |
113 float spectral_profile_sum = 0.0f; | 105 float spectral_profile_sum = 0.0f; |
114 for (int i = 0; i < input.channel_count(); ++i) { | 106 for (int i = 0; i < input.channel_count(); ++i) { |
115 spectral_profile_sum += m_pSpectralProfile[i]; | 107 spectral_profile_sum += m_pSpectralProfile[i]; |
116 } | 108 } |
117 | 109 |
118 // Set the last component of the feature vector to be the log energy | |
119 float logsum = log(spectral_profile_sum); | 110 float logsum = log(spectral_profile_sum); |
120 if (!isinf(logsum)) { | 111 if (!isinf(logsum)) { |
121 output_.set_sample(output_component_count_ - 1, 0, logsum); | 112 output_.set_sample(m_iParamNComp - 1, 0, logsum); |
122 } else { | 113 } else { |
123 output_.set_sample(output_component_count_ - 1, 0, -1000.0); | 114 output_.set_sample(m_iParamNComp - 1, 0, -1000.0); |
124 } | 115 } |
125 | 116 |
126 for (int ch = 0; ch < input.channel_count(); ++ch) { | 117 for (int iChannel = 0; |
127 m_pSpectralProfile[ch] = pow(m_pSpectralProfile[ch], 0.8f); | 118 iChannel < input.channel_count(); |
119 ++iChannel) { | |
120 m_pSpectralProfile[iChannel] = pow(m_pSpectralProfile[iChannel], 0.8); | |
128 } | 121 } |
129 | 122 |
130 RubberGMMCore(2, true); | 123 RubberGMMCore(2, true); |
131 | 124 |
132 float mean1 = m_pMu[0]; | 125 float fMean1 = m_pMu[0]; |
133 float mean2 = m_pMu[1]; | 126 float fMean2 = m_pMu[1]; |
134 // LOG_INFO(_T("Orig. mean 0 = %f"), m_pMu[0]); | 127 // LOG_INFO(_T("Orig. mean 0 = %f"), m_pMu[0]); |
135 // LOG_INFO(_T("Orig. mean 1 = %f"), m_pMu[1]); | 128 // LOG_INFO(_T("Orig. mean 1 = %f"), m_pMu[1]); |
136 // LOG_INFO(_T("Orig. prob 0 = %f"), m_pA[0]); | 129 // LOG_INFO(_T("Orig. prob 0 = %f"), m_pA[0]); |
137 // LOG_INFO(_T("Orig. prob 1 = %f"), m_pA[1]); | 130 // LOG_INFO(_T("Orig. prob 1 = %f"), m_pA[1]); |
138 | 131 |
139 float a1 = 0.05 * m_pA[0]; | 132 float fA1 = 0.05 * m_pA[0]; |
140 float a2 = 1.0 - 0.25 * m_pA[1]; | 133 float fA2 = 1.0 - 0.25 * m_pA[1]; |
141 | 134 |
142 // LOG_INFO(_T("fA1 = %f"), fA1); | 135 // LOG_INFO(_T("fA1 = %f"), fA1); |
143 // LOG_INFO(_T("fA2 = %f"), fA2); | 136 // LOG_INFO(_T("fA2 = %f"), fA2); |
144 | 137 |
145 float gradient = (mean2 - mean1) / (a2 - a1); | 138 float fGradient = (fMean2 - fMean1) / (fA2 - fA1); |
146 float intercept = mean2 - gradient * a2; | 139 float fIntercept = fMean2 - fGradient * fA2; |
147 | 140 |
148 // LOG_INFO(_T("fGradient = %f"), fGradient); | 141 // LOG_INFO(_T("fGradient = %f"), fGradient); |
149 // LOG_INFO(_T("fIntercept = %f"), fIntercept); | 142 // LOG_INFO(_T("fIntercept = %f"), fIntercept); |
150 | 143 |
151 for (int i = 0; i < m_iParamNComp; ++i) { | 144 for (int i = 0; i < m_iParamNComp; ++i) { |
152 m_pMu[i] = (static_cast<float>(i) | 145 m_pMu[i] = (static_cast<float>(i) |
153 / (static_cast<float>(m_iParamNComp) - 1.0f)) | 146 / (static_cast<float>(m_iParamNComp) - 1.0f)) |
154 * gradient + intercept; | 147 * fGradient + fIntercept; |
155 // LOG_INFO(_T("mean %d = %f"), i, m_pMu[i]); | 148 // LOG_INFO(_T("mean %d = %f"), i, m_pMu[i]); |
156 } | 149 } |
157 | 150 |
158 for (int i = 0; i < m_iParamNComp; ++i) { | 151 for (int i = 0; i < m_iParamNComp; ++i) { |
159 m_pA[i] = 1.0f / static_cast<float>(m_iParamNComp); | 152 m_pA[i] = 1.0f / static_cast<float>(m_iParamNComp); |
160 } | 153 } |
161 | 154 |
162 RubberGMMCore(m_iParamNComp, false); | 155 RubberGMMCore(m_iParamNComp, false); |
163 | 156 |
164 // Amplitudes first | |
165 for (int i = 0; i < m_iParamNComp - 1; ++i) { | 157 for (int i = 0; i < m_iParamNComp - 1; ++i) { |
166 if (!isnan(m_pA[i])) { | 158 if (!isnan(m_pA[i])) { |
167 output_.set_sample(i, 0, m_pA[i]); | 159 output_.set_sample(i, 0, m_pA[i]); |
168 } else { | 160 } else { |
169 output_.set_sample(i, 0, 0.0f); | 161 output_.set_sample(i, 0, 0.0f); |
170 } | 162 } |
171 } | 163 } |
172 | 164 |
173 // Then means if required | |
174 if (output_positions_) { | |
175 int idx = 0; | |
176 for (int i = m_iParamNComp - 1; i < 2 * m_iParamNComp - 1; ++i) { | |
177 if (!isnan(m_pMu[i])) { | |
178 output_.set_sample(i, 0, m_pMu[idx]); | |
179 } else { | |
180 output_.set_sample(i, 0, 0.0f); | |
181 } | |
182 ++idx; | |
183 } | |
184 } | |
185 | |
186 PushOutput(); | 165 PushOutput(); |
187 } | 166 } |
188 | 167 |
189 bool ModuleGaussians::RubberGMMCore(int iNComponents, bool bDoInit) { | 168 bool ModuleGaussians::RubberGMMCore(int iNComponents, bool bDoInit) { |
190 int iSizeX = m_iNumChannels; | 169 int iSizeX = m_iNumChannels; |
191 | 170 |
192 // Normalise the spectral profile | 171 // Normalise the spectral profile |
193 float SpectralProfileTotal = 0.0f; | 172 float fSpectralProfileTotal = 0.0f; |
194 for (int iCount = 0; iCount < iSizeX; iCount++) { | 173 for (int iCount = 0; iCount < iSizeX; iCount++) { |
195 SpectralProfileTotal += m_pSpectralProfile[iCount]; | 174 fSpectralProfileTotal += m_pSpectralProfile[iCount]; |
196 } | 175 } |
197 for (int iCount = 0; iCount < iSizeX; iCount++) { | 176 for (int iCount = 0; iCount < iSizeX; iCount++) { |
198 m_pSpectralProfile[iCount] /= SpectralProfileTotal; | 177 m_pSpectralProfile[iCount] /= fSpectralProfileTotal; |
199 } | 178 } |
200 | 179 |
201 if (bDoInit) { | 180 if (bDoInit) { |
202 // Uniformly spaced components | 181 // Uniformly spaced components |
203 float dd = (iSizeX - 1.0f) / iNComponents; | 182 float dd = (iSizeX - 1.0f) / iNComponents; |
219 // denominator: the model density at all observation points X | 198 // denominator: the model density at all observation points X |
220 for (int i = 0; i < iSizeX; ++i) { | 199 for (int i = 0; i < iSizeX; ++i) { |
221 pP_mod_X[i] = 0.0f; | 200 pP_mod_X[i] = 0.0f; |
222 } | 201 } |
223 | 202 |
224 for (int c = 0; c < iNComponents; c++) { | 203 for (int i = 0; i < iNComponents; i++) { |
225 for (int iCount = 0; iCount < iSizeX; iCount++) { | 204 for (int iCount = 0; iCount < iSizeX; iCount++) { |
226 pP_mod_X[iCount] += 1.0f / sqrt(2.0f * M_PI * m_fParamVar) | 205 pP_mod_X[iCount] += 1.0f / sqrt(2.0f * M_PI * m_fParamVar) |
227 * exp((-0.5f) | 206 * exp((-0.5f) |
228 * pow(static_cast<float>(iCount+1) - m_pMu[c], 2) | 207 * pow(static_cast<float>(iCount+1) - m_pMu[i], 2) |
229 / m_fParamVar) * m_pA[c]; | 208 / m_fParamVar) * m_pA[i]; |
230 } | 209 } |
231 } | 210 } |
232 | 211 |
233 for (int i = 0; i < iSizeX * iNComponents; ++i) { | 212 for (int i = 0; i < iSizeX * iNComponents; ++i) { |
234 pP_comp[i] = 0.0f; | 213 pP_comp[i] = 0.0f; |
270 for (int i = 0; i < iNComponents; ++i) { | 249 for (int i = 0; i < iNComponents; ++i) { |
271 fPrdist += pow((m_pA[i] - pA_old[i]), 2); | 250 fPrdist += pow((m_pA[i] - pA_old[i]), 2); |
272 } | 251 } |
273 fPrdist /= iNComponents; | 252 fPrdist /= iNComponents; |
274 | 253 |
275 if (fPrdist < priors_converged_) { | 254 if (fPrdist < m_fParamPriorsConverged) { |
276 // LOG_INFO("Converged!"); | 255 // LOG_INFO("Converged!"); |
277 break; | 256 break; |
278 } | 257 } |
279 // LOG_INFO("Didn't converge!"); | 258 // LOG_INFO("Didn't converge!"); |
280 | 259 |