📄 dhmm_gl.cpp
字号:
} // end of: for(k=1; k<T[m]; k++)
// 最后一帧状态为吸收态,即只有最后一个状态概率不为0,其余状态概率均为0
if(End_state_mode & ENDSTATE_ABSORB) // End_state_mode是在RECOG.CPP中根据用户输入确定的
{
for(i=0; i<n-1; i++) Alpha[m][ T[m]-1 ][i] = 0;
Belta[m][ T[m]-1 ][n-1] = Ct[m][ T[m]-1 ];
for(i=0; i<n-1; i++) Belta[m][ T[m]-1 ][i] = 0;
}
else
{
for(i=0; i<n; i++) Belta[m][ T[m]-1 ][i] = Ct[m][ T[m]-1 ];
}
// 计算Belta
for(k=T[m]-2; k>=0; k--)
for(i=0; i<n; i++)
{
w = 0;
for(j=0; j<n; j++)
w = w + A[i][j] * B[j][ Out[m][k+1] ] * Belta[m][k+1][j];
Belta[m][k][i] = w * Ct[m][k];
}
}
}
// Re-estimate A[i][j], i = 0 to n-1, j = 0 to n-1.
/* if((mode == REESTIMATE_A) || (mode == REESTIMATE_ALL))
{
for(i=0; i<n; i++)
for(j=0; j<n; j++)
New_A[i][j] = 0;
for(m=0; m<Sample_num; m++)
{
w = 0;
for(i=0; i<n; i++)
w += Alpha[m][T[m]-1][i];
for(k=0; k<T[m]-1; k++)
{
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
w1 = Alpha[m][k][i] * A[i][j] * B[j][ Out[m][k+1] ] * Belta[m][k+1][j];
w1 /= w;
New_A[i][j] += w1;
}
}
}
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
if((j < i) || (j > (i+1)))
New_A[i][j] = 0;
w = 0;
for(j=0; j<n; j++) w += New_A[i][j];
for(j=0; j<n; j++) New_A[i][j] /= w;
for(j=0; j<n; j++)
if((j < i) || (j > (i+1)) && (New_A[i][j] < Epsilon_A))
New_A[i][j] = Epsilon_A;
w = 0;
for(j=0; j<n; j++) w += New_A[i][j];
for(j=0; j<n; j++) New_A[i][j] /= w;
}
for(i=0; i<n; i++)
for(j=0; j<n; j++)
A[i][j] = New_A[i][j];
}*/
// Re-estimate B[i][j], i = 0 to n-1, j = 0 to m-1.
if((mode == REESTIMATE_B) || (mode == REESTIMATE_ALL))
{
// clear new B matrix
for(i=0; i<n; i++)
for(j=0; j<Output_num; j++)
New_B[i][j] = 0;
for(m=1; m<Sample_num; m++)
{
w = 0;
for(i=0; i<n; i++)
if (T[m] > 0) // add by wd @ 030331z
w += Alpha[m][T[m]-1][i]; // w: 观察序列概率,即P(O)
// reestimate matrix B
for(k=0; k<T[m]; k++)
for(i=0; i<n; i++)
{
New_B[i][Out[m][k]] += Alpha[m][k][i] * Belta[m][k][i] /
Ct[m][k] / w;
}
}
for(i=0; i<n; i++)
{
w = 0;
for(j=0; j<Output_num; j++) w += New_B[i][j];
for(j=0; j<Output_num; j++)
{
New_B[i][j] /= w; // 归一化
}
for(j=0; j<Output_num; j++)
if(New_B[i][j] < Epsilon_B) // Epsilon_B=1.0e-6
New_B[i][j] = Epsilon_B;
w = 0;
for(j=0; j<Output_num; j++) w += New_B[i][j];
for(j=0; j<Output_num; j++) New_B[i][j] /= w; // 归一化
}
for(i=0; i<n; i++) // 更新B矩阵
for(j=0; j<Output_num; j++)
B[i][j] = New_B[i][j];
}
Residue = 0;
for(m=0; m<Sample_num; m++)
if(T[m] > 0) // add by wd @ 030331
Residue += DHMM_Priority(Pi, A, B, Out[m], T[m], n, End_state_mode);
/*if (T[m] > 0)
{
Residue += DHMM_Priority(Pi, A, B, Out[m], T[m], n, End_state_mode);
}
else
Residue += -10; */
for(i=0; i<n; i++) delete New_A[i];
delete New_A;
for(i=0; i<n; i++) delete New_B[i];
delete New_B;
for(i=0; i<Sample_num; i++) delete Ct[i];
delete Ct;
return Residue;
}
static double DHMM_Priority(double *Pi, double **A, double **B, int *Out, int T, int n, int mode)
// input:
// Pi 初始概率
// A A矩阵
// B B矩阵
// Out 训练集中第m个说话人的观察序列
// T 训练集中第m个说话人的观察序列帧数
// n 状态数
// mode
// return value:
// logP(o1,o2,...,oT|Pi,A,B)
//caller(r_dhmm.cpp): Residue += DHMM_Priority(Pi, A, B, Out[m], T[m], n, End_state_mode);
{
int i, j, k;
double w, p;
double *Alpha1;
double *Alpha2;
if((Alpha1 = new double [n]) == NULL) { DEBUG_PRINTF("Not enough memory for !\n"); ASSERT(0); }
if((Alpha2 = new double [n]) == NULL) { DEBUG_PRINTF("Not enough memory for !\n"); ASSERT(0); }
p = 0;
w = 0;
for(i=0; i<n; i++)
{
Alpha1[i] = Pi[i] * B[i][ Out[0] ];
w += Alpha1[i];
}
for(i=0; i<n; i++) Alpha1[i] /= w;
p += log(w);
for(k=1; k<T; k++)
{
for(i=0; i<n; i++)
{
w = 0;
for(j=0; j<n; j++)
w = w + Alpha1[j] * A[j][i];
w = w * B[i][ Out[k] ];
Alpha2[i] = w;
}
if(k < T-1)
{
w = 0;
for(i=0; i<n; i++) w += Alpha2[i];
for(i=0; i<n; i++) Alpha1[i] = Alpha2[i] / w;
p += log(w);
}
}
if(mode & ENDSTATE_ABSORB)
{
p += log(Alpha2[n-1]);
}
else
{
w = 0;
for(i=0; i<n; i++) w += Alpha2[i];
p += log(w);
}
delete Alpha1;
delete Alpha2;
return p;
}
static double DHMM_Calculate(double ***Alpha, double ***Belta, double *Pi, double **A,
double **B, int Out[140][150], int Sample_num, int Output_num, int *T,
int n, int mode, int End_state_mode, WORD_SAMPLE * DMAD_pu_Word_Sample)
// 功能:训练某一词条的模型
// input:
// Pi 初始时刻各状态的概率
// Alpha 前向概率
// Belta 后向概率
// A 初始A矩阵
// B 初始B矩阵
// Out 用于训练的各句子的观察序列(输出序列)
// Sample_num 训练集人数
// Output_num VQ码本大小(码字数,即观察值的个数)
// T 用于训练的各句子的帧数
// n 状态数
// mode 训练模式(REESTIMATE_A, REESTIMATE_B, REESTIMATE_ALL)
// End_state_mode 结尾帧状态模式(ENDSTATE_ABSORB = 0x200)
// output:
// A
// B
// caller(r_dhmm.cpp): u = DHMM_Calculate(Alpha, Belta, Pi, A, B, Output, Train_num, Output_num,
// Frame_num, Status_num, REESTIMATE_ALL, mode);
{
int i, j, k, m;
double w;
double **New_A;
double **New_B;
double **Ct; // to prevent underflow of Alpha and Belta, Ct is the scaling coefficient
double Residue;
if((New_A = new double *[n]) == NULL)
{
DEBUG_PRINTF("Not enough memory for New_A !\n");
ASSERT(0);
}
for(i=0; i<n; i++)
{
if((New_A[i] = new double [n]) == NULL)
{
DEBUG_PRINTF("Not enough memory for New_A[%d] !\n", i);
ASSERT(0);
}
}
if((New_B = new double *[n]) == NULL)
{
DEBUG_PRINTF("Not enough memory for New_B !\n");
ASSERT(0);
}
for(i=0; i<n; i++)
{
if((New_B[i] = new double [Output_num]) == NULL)
{
DEBUG_PRINTF("Not enough memory for New_B[%d] !\n", i);
ASSERT(0);
}
}
if((Ct = new double *[Sample_num]) == NULL)
{
DEBUG_PRINTF("Not enough memory for Ct !\n");
ASSERT(0);
}
for(i=0; i<Sample_num; i++)
if((Ct[i] = new double [T[i]]) == NULL)
{
DEBUG_PRINTF("Not enough memory for Ct[%d] !\n", i);
ASSERT(0);
}
// Calculate Alpha & Belta.
for(m=0; m<Sample_num; m++)
{
w = 0;
for(i=0; i<n; i++)
{
Alpha[m][0][i] = Pi[i] * B[i][ DMAD_pu_Word_Sample[m].pn_VQed_Feature_Sequence[i] ];
w = w + Alpha[m][0][i];
}
Ct[m][0] = 1.0 / w; // scaling coefficient
for(i=0; i<n; i++)
Alpha[m][0][i] = Alpha[m][0][i] * Ct[m][0]; // scaling
// 计算Alpha
for(k=1; k<T[m]; k++) // 第m个训练utterance的各帧
{
Ct[m][k] = 0;
for(i=0; i<n; i++)
{
w = 0;
for(j=0; j<n; j++)
w = w + Alpha[m][k-1][j] * A[j][i];
w = w * B[i][ Out[m][k] ];
Alpha[m][k][i] = w;
Ct[m][k] = Ct[m][k] + w;
}
Ct[m][k] = 1.0 / Ct[m][k];
for(i=0; i<n; i++)
Alpha[m][k][i] = Alpha[m][k][i] * Ct[m][k];
} // end of: for(k=1; k<T[m]; k++)
// 最后一帧状态为吸收态,即只有最后一个状态概率不为0,其余状态概率均为0
if(End_state_mode & ENDSTATE_ABSORB) // End_state_mode是在RECOG.CPP中根据用户输入确定的
{
for(i=0; i<n-1; i++) Alpha[m][ T[m]-1 ][i] = 0;
Belta[m][ T[m]-1 ][n-1] = Ct[m][ T[m]-1 ];
for(i=0; i<n-1; i++) Belta[m][ T[m]-1 ][i] = 0;
}
else
{
for(i=0; i<n; i++) Belta[m][ T[m]-1 ][i] = Ct[m][ T[m]-1 ];
}
// 计算Belta
for(k=T[m]-2; k>=0; k--)
for(i=0; i<n; i++)
{
w = 0;
for(j=0; j<n; j++)
w = w + A[i][j] * B[j][ Out[m][k+1] ] * Belta[m][k+1][j];
Belta[m][k][i] = w * Ct[m][k];
}
}
// Re-estimate A[i][j], i = 0 to n-1, j = 0 to n-1.
/* if((mode == REESTIMATE_A) || (mode == REESTIMATE_ALL))
{
for(i=0; i<n; i++)
for(j=0; j<n; j++)
New_A[i][j] = 0;
for(m=0; m<Sample_num; m++)
{
w = 0;
for(i=0; i<n; i++)
w += Alpha[m][T[m]-1][i];
for(k=0; k<T[m]-1; k++)
{
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
w1 = Alpha[m][k][i] * A[i][j] * B[j][ Out[m][k+1] ] * Belta[m][k+1][j];
w1 /= w;
New_A[i][j] += w1;
}
}
}
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
if((j < i) || (j > (i+1)))
New_A[i][j] = 0;
w = 0;
for(j=0; j<n; j++) w += New_A[i][j];
for(j=0; j<n; j++) New_A[i][j] /= w;
for(j=0; j<n; j++)
if((j < i) || (j > (i+1)) && (New_A[i][j] < Epsilon_A))
New_A[i][j] = Epsilon_A;
w = 0;
for(j=0; j<n; j++) w += New_A[i][j];
for(j=0; j<n; j++) New_A[i][j] /= w;
}
for(i=0; i<n; i++)
for(j=0; j<n; j++)
A[i][j] = New_A[i][j];
}*/
// Re-estimate B[i][j], i = 0 to n-1, j = 0 to m-1.
if((mode == REESTIMATE_B) || (mode == REESTIMATE_ALL))
{
// clear new B matrix
for(i=0; i<n; i++)
for(j=0; j<Output_num; j++)
New_B[i][j] = 0;
for(m=1; m<Sample_num; m++)
{
w = 0;
for(i=0; i<n; i++)
w += Alpha[m][T[m]-1][i]; // w: 观察序列概率,即P(O)
// reestimate matrix B
for(k=0; k<T[m]; k++)
for(i=0; i<n; i++)
{
New_B[i][Out[m][k]] += Alpha[m][k][i] * Belta[m][k][i] /
Ct[m][k] / w;
}
}
for(i=0; i<n; i++)
{
w = 0;
for(j=0; j<Output_num; j++) w += New_B[i][j];
for(j=0; j<Output_num; j++)
{
New_B[i][j] /= w; // 归一化
}
for(j=0; j<Output_num; j++)
if(New_B[i][j] < Epsilon_B) // Epsilon_B=1.0e-6
New_B[i][j] = Epsilon_B;
w = 0;
for(j=0; j<Output_num; j++) w += New_B[i][j];
for(j=0; j<Output_num; j++) New_B[i][j] /= w; // 归一化
}
for(i=0; i<n; i++) // 更新B矩阵
for(j=0; j<Output_num; j++)
B[i][j] = New_B[i][j];
}
Residue = 0;
for(m=1; m<Sample_num; m++)
Residue += DHMM_Priority(Pi, A, B, Out[m], T[m], n, End_state_mode);
for(i=0; i<n; i++) delete New_A[i];
delete New_A;
for(i=0; i<n; i++) delete New_B[i];
delete New_B;
for(i=0; i<Sample_num; i++) delete Ct[i];
delete Ct;
return Residue;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -