DHMM_LHS.cpp
上传用户:avbj512
上传日期:2013-09-18
资源大小:6239k
文件大小:23k
源码类别:

DSP编程

开发平台:

Visual C++

  1. // DHMM_LHS.cpp:
  2. // Implementation of the DHMM_LHS Module.
  3. // That is the transform of previous DHMM Code by LiHuSheng.
  4. //
  5. // Created 2001/08, By DongMing, MDSR.
  6. //
  7. //////////////////////////////////////////////////////////////////////
  8. #include "stdafx.h"
  9. #include "DHMM_LHS.h"
  10. #include "DHMM_GL.h"
  11. #include <math.h>
  12. //#define KMEAN_PRECISION (1.0E-3)
  13. //#define Epsilon_B (1.0E-6)
  14. //#define EPSILON_CALC (1.0E-6)
  15. //#define MAX_CALC_NUM 300
  16. //////////////////////////////////////////////////////////////////////
  17. // Private Function Head
  18. void DHMM_VQ(
  19.  int DMNU_Train_num, // 训练集人数
  20.  double **DMNU_Codebook, // VQ码本
  21.  int Codeword_num, // 码字个数
  22.  double K_means_precision, // K平均精度
  23.  int *DMNU_Train_Speaker, // 训练集说话人标号
  24.  int Dimension, // 特征维数
  25.  int DMNU_sex, // 性别标志
  26.  int DMNU_num, // 测试集的组号(num=0~Test_time)
  27.  int DMAD_n_Code_Word_Num,
  28.  DYNA_2DIM_DOUBLE_ARRAY DMAD_d2dda_Code_Word,
  29.  DYNA_2DIM_DOUBLE_ARRAY DMAD_d2dda_Code_Book
  30.  );
  31. void DHMM_train(
  32. int Status_num, // 状态数
  33. int Train_num, // 训练集人数
  34. int *DMNU_Train_Speaker, // 训练集说话人标号
  35. double **DMNU_Codebook, // VQ码本
  36. double *Pi, // 初始概率
  37. double **A, // A矩阵
  38. double **B, // B矩阵
  39. int Output_num, // VQ码本大小(码字个数)
  40. int DMNU_Cepstrum_order, // 特征维数
  41. int DMNU_digit, // 词条标号
  42. FILE *DMNU_Fp1, // 模型文件指针
  43. FILE *DMNU_Fp2, // ???
  44. int DMNU_sex, // sex在该函数中没有引用
  45. int DMNU_Mode, // 程序中出现的Mode参数的取值包括:
  46. // WHOLE_WORD
  47. // WORD_HEAD1
  48. // WORD_HEAD2
  49. // WORD_TAIL
  50. WORD_SAMPLE * DMAD_pu_Word_Sample,
  51. DHMM_MODEL * DMAD_pu_DHMM_Model
  52. );
  53. double DHMM_Calculate(
  54.   double ***Alpha,
  55.   double ***Belta,
  56.   double *Pi,
  57.   double **A,
  58.   double **B,
  59.   int **Out, // 用于训练的各句子的观察序列(输出序列)
  60.   int Sample_num, // 训练集人数
  61.   int Output_num, // VQ码本大小(码字数,即观察值的个数)
  62.   int *T, // 用于训练的各句子的帧数
  63.   int n, // 状态数
  64.   double **P // ???
  65.   );
  66. double DHMM_Priority(double *Pi, double **A, double **B, int *Out, int T, int n);
  67. double Viterbi(
  68.    int *VQ_Out, // VQ后的一个识别样本
  69.    int Frame_num, // 帧数
  70.    double **B, // B矩阵
  71.    double **A, // A矩阵
  72.    int Status_num, // 状态数
  73.    int *Status_sequence // 状态序列
  74.    );
  75. //////////////////////////////////////////////////////////////////////
  76. // API functions
  77. int DHMM_VQ_Train_Code_Book_LHS(DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Word, int n_Code_Word_Num, int n_Code_Word_Dim,
  78. DYNA_2DIM_DOUBLE_ARRAY d2dda_Initial_Code_Book, DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Book, int n_Code_Book_Size)
  79. {
  80. DHMM_VQ(0, NULL, n_Code_Book_Size, KMEAN_PRECISION, 0, n_Code_Word_Dim, 0, 0,
  81. n_Code_Word_Num, d2dda_Code_Word, d2dda_Code_Book);
  82. return 0;
  83. }
  84. int DHMM_Model_Train_DHMM_Model_LHS(WORD_SAMPLE * pu_Word_Sample, int n_Word_Sample_Num,
  85. DHMM_MODEL * pu_DHMM_Model)
  86. {
  87. DHMM_train(pu_DHMM_Model->n_State_Num, n_Word_Sample_Num, NULL, NULL,
  88. pu_DHMM_Model->pdPi, pu_DHMM_Model->d2dda_A, pu_DHMM_Model->d2dda_B, pu_DHMM_Model->n_Code_Book_Size, 0,
  89. 0, NULL, NULL, 0, 0, pu_Word_Sample, pu_DHMM_Model);
  90. return 0;
  91. }
  92. int DHMM_Recog_Viterbi_LHS(DHMM_MODEL * pu_DHMM_Model,
  93.    WORD_SAMPLE * pu_Word_Sample,
  94.    double * pd_Max_Likelihood, int * pn_Status_Sequence)
  95. {
  96. (*pd_Max_Likelihood) = Viterbi(pu_Word_Sample->pn_VQed_Feature_Sequence, pu_Word_Sample->n_Feature_Sequence_Len,
  97. pu_DHMM_Model->d2dda_B, pu_DHMM_Model->d2dda_A, pu_DHMM_Model->n_State_Num,
  98. pn_Status_Sequence);
  99. return 0;
  100. }
  101. //////////////////////////////////////////////////////////////////////
  102. // Original Code
  103. //////////////////////////////////////////////////////////////////////
  104. // DMNU = DongMing doesn't use this when transforming.
  105. // DMAD = DongMing addes this when transforming.
  106. static void DHMM_VQ(
  107.  int DMNU_Train_num, // 训练集人数
  108.  double **DMNU_Codebook, // VQ码本
  109.  int Codeword_num, // 码字个数
  110.  double K_means_precision, // K平均精度
  111.  int *DMNU_Train_Speaker, // 训练集说话人标号
  112.  int Dimension, // 特征维数
  113.  int DMNU_sex, // 性别标志
  114.  int DMNU_num, // 测试集的组号(num=0~Test_time)
  115.  int DMAD_n_Code_Word_Num,
  116.  DYNA_2DIM_DOUBLE_ARRAY DMAD_d2dda_Code_Word,
  117.  DYNA_2DIM_DOUBLE_ARRAY DMAD_d2dda_Code_Book
  118.  )
  119. {
  120. int    i, j, p, /* n, */ m /* q,t,h */;
  121. // int    Seg[3]; // 除了在Read_Feature中初始化,Seg在该函数中并没有被引用
  122. int    Nearer;
  123. int    *Counter; // 长度:Codeword_num
  124. int    Total_num; // 训练样本的帧数总和
  125. // int    Acoustic_Mode;
  126. // char   Feature_file[50]; // 一个训练样本(utterance)的特征数据文件名
  127. double **Codeword; // size: Codeword_num*Dimension
  128. double **Sum; // size: Codeword_num*Dimension
  129. double **s; // size: Total_num*Dimension
  130. // double **Feature; // size: Frame_num*Dimension (一个训练样本(utterance)的特征数据)
  131. double Min_Dist;
  132. double Dist;
  133. double New_D;
  134. double Old_D;
  135. // int    Frame_num; // 一个训练样本(utterance)的帧数
  136. // char   Codefile_name[2][40] = {{"\work\dspv\comp"},{"\work\dspv\comp"}};
  137. // char   Savefile[50];
  138. // FILE * Fp;
  139. // 计算训练样本的帧数总和
  140. /*
  141. Total_num = 0;
  142. for(n=0;n<Train_num;n++)
  143. for(i=0;i<MODEL_NUM;i++)
  144. {
  145. sprintf(Feature_file,"\work\dspv\mm%02d\mm%d.mfc",Train_Speaker[n],i);
  146. // 每个说话人一个目录,每个utterance一个文件
  147. Total_num += Get_Length(Feature_file);
  148. }
  149. */
  150. Total_num = DMAD_n_Code_Word_Num;
  151. /*
  152. if((Codeword = new double *[Codeword_num]) == NULL)
  153. {
  154. printf("Not enough memory for Codeword !n");
  155. exit(-1);
  156. }
  157. */
  158. if((Sum = new double *[Codeword_num]) == NULL)
  159. {
  160. DEBUG_PRINTF("Not enough memory for Sum !n");
  161. ASSERT(0);
  162. }
  163. for(i=0; i<Codeword_num; i++)
  164. {
  165. /*
  166. if((Codeword[i] = new double [Dimension]) == NULL)
  167. {
  168. printf("Not enough memory for Codeword[%d] !n", i);
  169. exit(-1);
  170. }
  171. */
  172. if((Sum[i] = new double [Dimension]) == NULL)
  173. {
  174. DEBUG_PRINTF("Not enough memory for Sum[%d] !n", i);
  175. ASSERT(0);
  176. }
  177. }
  178. Codeword = DMAD_d2dda_Code_Book;
  179. if((Counter  = new int [Codeword_num]) == NULL)
  180. {
  181. DEBUG_PRINTF("Not enough memory for Counter !n");
  182. ASSERT(0);
  183. }
  184. /*
  185. if((s  = new double * [Total_num]) == NULL)
  186. {
  187. printf("Not enough memory for s !n");
  188. exit(-1);
  189. }
  190. for(i=0; i<Total_num; i++)
  191. if((s[i]  = new double [Dimension]) == NULL)
  192. {
  193. printf("Not enough memory for s !n");
  194. exit(-1);
  195. }
  196. */
  197. // 读取所有的训练样本,逐帧写入s中,形成训练向量集
  198. /*
  199. q = 0;
  200. for(i=0;i<Train_num;i++)
  201. for(n=0;n<MODEL_NUM;n++)
  202. {
  203. sprintf(Feature_file,"\work\dspv\mm%02d\mm%d.mfc",Train_Speaker[i],n);
  204. Read_Feature(Feature_file,Dimension,WHOLE_WORD,Frame_num,Feature,Seg,Acoustic_Mode);
  205. for(t=0;t<Frame_num;t++)
  206. for(h=0;h<Dimension;h++)
  207. s[q+t][h] = Feature[t][h];
  208. q += Frame_num;
  209. Free_Feature(Feature,Frame_num);
  210. }
  211. */
  212. s = DMAD_d2dda_Code_Word;
  213. // k-means Clusteration
  214. for(p=0; p<Dimension; p++) Codeword[0][p] = 0;
  215. for(i=0; i<Total_num; i++)
  216. for(p=0; p<Dimension; p++)
  217. Codeword[0][p] += s[i][p];
  218. for(p=0; p<Dimension; p++) Codeword[0][p] /= Total_num;
  219. // printf("  Clustering...n");
  220. for(m=2; m<=Codeword_num; m*=2)
  221. {
  222. DEBUG_PRINTF("tM = %d.n", m);
  223. for(i=m/2-1; i>=0; i--)
  224. for(j=0; j<Dimension; j++)
  225. {
  226. Codeword[i*2+1][j] = Codeword[i][j] * 0.9;
  227. Codeword[i*2][j]   = Codeword[i][j] * 1.1;
  228. }
  229. Old_D = 1.0e20;
  230. New_D = 1.0e15;
  231. while(((Old_D - New_D) / New_D) > K_means_precision)
  232. {
  233. for(j=0; j<m; j++)
  234. {
  235. for(p=0; p<Dimension; p++) Sum[j][p] = 0;
  236. Counter[j] = 0;
  237. }
  238. Old_D = New_D;
  239. New_D = 0;
  240. for(i=0; i<Total_num; i++)
  241. {
  242. Dist = 0;
  243. for(p=0; p<Dimension; p++)
  244. Dist += (Codeword[0][p] - s[i][p]) * (Codeword[0][p] - s[i][p]);
  245. Min_Dist = Dist;
  246. Nearer = 0;
  247. for(j=1; j<m; j++)
  248. {
  249. Dist = 0;
  250. for(p=0; p<Dimension; p++)
  251. Dist += (Codeword[j][p] - s[i][p]) * (Codeword[j][p] - s[i][p]);
  252. if(Dist < Min_Dist)
  253. {
  254. Min_Dist = Dist;
  255. Nearer = j;
  256. }
  257. } // To find out the nearest center to s[i][].
  258. for(p=0; p<Dimension; p++) Sum[Nearer][p] += s[i][p]; // To compute center.
  259. Counter[Nearer] ++; // Class Number.
  260. New_D += Min_Dist;
  261. }
  262. for(j=0; j<m; j++)
  263. {
  264. if(Counter[j] > 0)
  265. for(p=0; p<Dimension; p++)
  266. Codeword[j][p] = Sum[j][p] / Counter[j];
  267. }
  268. }
  269. }
  270. // 训练结束,保存码本到Codebook参数中
  271. /*
  272. for(i=0;i<Codeword_num;i++)
  273. for(j=0;j<Dimension;j++)
  274. Codebook[i][j] = Codeword[i][j];
  275. // 写入到码本文件中
  276. sprintf(Savefile,"%s%d.cod",Codefile_name[sex],num);
  277. Fp = fopen(Savefile, "wb");
  278. if(Fp == NULL)
  279. {
  280. printf("File open error with %s !n", Codefile_name);
  281. exit(-1);
  282. }
  283. fwrite(&Codeword_num, sizeof(int), 1, Fp);
  284. fwrite(&Dimension, sizeof(int), 1, Fp);
  285. for(i=0; i<Codeword_num; i++)
  286. fwrite(Codeword[i], sizeof(double), Dimension, Fp);
  287. fclose(Fp);
  288. */
  289. // 释放内存
  290. for(i=0; i<Codeword_num; i++)
  291. {
  292. // delete Codeword[i];
  293. delete Sum[i];
  294. }
  295. // delete Codeword;
  296. delete Sum;
  297. delete Counter;
  298. // for(i=0; i<Total_num; i++) delete s[i];
  299. // delete s;
  300. }
  301. static void DHMM_train(
  302. int Status_num, // 状态数
  303. int Train_num, // 训练集人数
  304. int *DMNU_Train_Speaker, // 训练集说话人标号
  305. double **DMNU_Codebook, // VQ码本
  306. double *Pi, // 初始概率
  307. double **A, // A矩阵
  308. double **B, // B矩阵
  309. int Output_num, // VQ码本大小(码字个数)
  310. int DMNU_Cepstrum_order, // 特征维数
  311. int DMNU_digit, // 词条标号
  312. FILE *DMNU_Fp1, // 模型文件指针
  313. FILE *DMNU_Fp2, // ???
  314. int DMNU_sex, // sex在该函数中没有引用
  315. int DMNU_Mode, // 程序中出现的Mode参数的取值包括:
  316. // WHOLE_WORD
  317. // WORD_HEAD1
  318. // WORD_HEAD2
  319. // WORD_TAIL
  320. WORD_SAMPLE * DMAD_pu_Word_Sample,
  321. DHMM_MODEL * DMAD_pu_DHMM_Model
  322. )
  323. {
  324. int     i, j, k,m;
  325. // int     Acoustic_Mode;
  326. // int     Seg[3];
  327. int     **Output; // for each word item model being trained, the output sequence (observation sequence) of each utterance of this model. (每个元素保存该帧的码字标号,每一行是一个utterance,且各行不等长)
  328. // 1st dimension: index of the training utterance; 
  329. // 2nd dimension: index of frame
  330. int     *Frame_num; // 各训练句子的帧数
  331. double  ** P; // Status_num*Output_num矩阵(干什么用的???)
  332. double  **Old_A;
  333. double  **Old_B;
  334. double  ***Alpha;
  335. double  ***Belta;
  336. // double  **Feature; // feature data of one utterance
  337. double  w, u;
  338. // char    File_Name[40];
  339. // time_t  t;
  340. // srand((unsigned) time(&t));
  341. // 分配内存
  342. if((Old_A = new double *[Status_num]) == NULL)
  343. {
  344. DEBUG_PRINTF("Not enough memory for Old_A !n");
  345. ASSERT(0);
  346. }
  347. for(i=0; i<Status_num; i++)
  348. {
  349. if((Old_A[i] = new double [Status_num]) == NULL)
  350. {
  351. DEBUG_PRINTF("Not enough memory for Old_A[%d] !n", i);
  352. ASSERT(0);
  353. }
  354. }
  355. if((Old_B = new double *[Status_num]) == NULL)
  356. {
  357. DEBUG_PRINTF("Not enough memory for Old_B !n");
  358. ASSERT(0);
  359. }
  360. for(i=0; i<Status_num; i++)
  361. {
  362. if((Old_B[i] = new double [Output_num]) == NULL)
  363. {
  364. DEBUG_PRINTF("Not enough memory for Old_B[%d] !n", i);
  365. ASSERT(0);
  366. }
  367. }
  368. if((P = new double*[Status_num]) == NULL)
  369. {
  370. DEBUG_PRINTF("Not eoungh memory for P[]n");
  371. ASSERT(0);
  372. }
  373. for(i=0;i<Status_num;i++)
  374. if((P[i] = new double[Output_num]) == NULL)
  375. {
  376. DEBUG_PRINTF("Not enough memory for P[%d]n",i);
  377. ASSERT(0);
  378. }
  379. // Initialize Alpha & Belta
  380. if((Alpha = new double **[Train_num]) == NULL)
  381. {
  382. DEBUG_PRINTF("Not enough memory for Alpha !n");
  383. ASSERT(0);
  384. }
  385. if((Belta = new double **[Train_num]) == NULL)
  386. {
  387. DEBUG_PRINTF("Not enough memory for Belta !n");
  388. ASSERT(0);
  389. }
  390. if((Output = new int *[Train_num]) == NULL)
  391. {
  392. DEBUG_PRINTF("Not enough memory for Output !n");
  393. ASSERT(0);
  394. }
  395. if((Frame_num = new int [Train_num]) == NULL)
  396. {
  397. DEBUG_PRINTF("Not enough memory for Frame_num !n");
  398. ASSERT(0);
  399. }
  400. // 初始化初始概率Pi:状态0概率为1,其余状态概率为0
  401. Pi[0] = 1;
  402. for(i=1; i<Status_num; i++) Pi[i] = 0;
  403. for(i=0; i<Status_num; i++)
  404. {
  405. // 初始化A矩阵
  406. for(j=0; j<Status_num; j++) A[i][j] = 0;
  407. if(i < Status_num-1)
  408. {
  409. A[i][i]   = 0.5;
  410. A[i][i+1] = 0.5;
  411. }
  412. else
  413. {
  414. A[i][i]   = 1.0;
  415. }
  416. // 归一化A矩阵
  417. w = 0;
  418. for(j=0; j<Status_num; j++) w = w + A[i][j];
  419. for(j=0; j<Status_num; j++) A[i][j] = A[i][j] / w;
  420. w = 0;
  421. // 初始化B矩阵
  422. for(j=0; j<Output_num; j++)
  423. {
  424. B[i][j] = 1.0 / Output_num * (0.9 + ((rand()%1000) / 5000.0));
  425. w = w + B[i][j];
  426. }
  427. // 归一化B矩阵
  428. for(j=0; j<Output_num; j++) B[i][j] = B[i][j] / w;
  429. }
  430. k = 0;
  431. for(m=0;m<Train_num;m++)
  432. {
  433. // 初始化第m个训练集说话人的特征数据文件名
  434. // sprintf(File_Name,"\work\dspv\mm%02d\mm%d.mfc",Train_Speaker[m],digit);
  435. // 读取该说话人的该词条的训练数据
  436. // Read_Feature(File_Name,Cepstrum_order,Mode,Frame_num[k],Feature,Seg,Acoustic_Mode);
  437. Frame_num[k] = DMAD_pu_Word_Sample[k].n_Feature_Sequence_Len;
  438. // 根据帧数为Alpha,Belta和Output分配内存
  439. // allocate memory for Alpha
  440. if((Alpha[k] = new double *[Frame_num[k]]) == NULL)
  441. {
  442. DEBUG_PRINTF("Not enough memory for Alpha[%d] !n", k);
  443. ASSERT(0);
  444. }
  445. for(i=0; i<Frame_num[k]; i++)
  446. if((Alpha[k][i] = new double [Status_num]) == NULL)
  447. {
  448. DEBUG_PRINTF("Not enough memory for Alpha[%d][%d] !n", k, i);
  449. ASSERT(0);
  450. }
  451. // allocate memory for Belta
  452. if((Belta[k] = new double *[Frame_num[k]]) == NULL)
  453. {
  454. DEBUG_PRINTF("Not enough memory for Belta[%d] !n", k);
  455. ASSERT(0);
  456. }
  457. for(i=0; i<Frame_num[k]; i++)
  458. if((Belta[k][i] = new double [Status_num]) == NULL)
  459. {
  460. DEBUG_PRINTF("Not enough memory for Belta[%d][%d] !n", k, i);
  461. ASSERT(0);
  462. }
  463. // allocate memory for Output
  464. /*
  465. if((Output[k] = new int [Frame_num[k]]) == NULL)
  466. {
  467. printf("Not enough memory for Output[%d] !n", k);
  468. exit(-1);
  469. }
  470. // VQ
  471. for(i=0; i<Frame_num[k]; i++)
  472. {
  473. Output[k][i] = DHMM_Match(Feature[i], Codebook, Output_num, Cepstrum_order);
  474. }
  475. // 释放Feature的内存
  476. Free_Feature(Feature,Frame_num[k]);
  477. */
  478. Output[k] = DMAD_pu_Word_Sample[k].pn_VQed_Feature_Sequence;
  479. k ++;
  480. }
  481. w = 1;
  482. m = 0;
  483. k = MAX_CALC_NUM; // 最多训练300遍
  484. while(m < k)
  485. {
  486. u = DHMM_Calculate(
  487. Alpha,
  488. Belta,
  489. Pi,
  490. A,
  491. B,
  492. Output,
  493. Train_num,
  494. Output_num,
  495. Frame_num,
  496. Status_num,
  497. P
  498. );
  499. m ++;
  500. if((u > w) && (fabs((u-w)/w) < EPSILON_CALC)) break;
  501. else w = u;
  502. }
  503. DEBUG_PRINTF("tM = %d.n", m);
  504. /*
  505. fwrite(Pi, sizeof(double), Status_num, Fp1);
  506. for(i=0; i<Status_num;i++)
  507. fwrite(A[i], sizeof(double), Status_num, Fp1);
  508. for(i=0; i<Status_num; i++)
  509. fwrite(B[i], sizeof(double), Output_num, Fp1);
  510. if(Mode & WHOLE_WORD)
  511. {
  512. // P的各元素是B的各元素加1,保存这个干什么???
  513. for(i=0; i<Status_num; i++)
  514. fwrite(P[i], sizeof(double), Output_num, Fp2);
  515. }
  516. */
  517. for(k=0; k<Train_num; k++)
  518. {
  519. for(i=0; i<Frame_num[k]; i++)
  520. delete Alpha[k][i];
  521. delete Alpha[k];
  522. for(i=0; i<Frame_num[k]; i++)
  523. delete Belta[k][i];
  524. delete Belta[k];
  525. // delete Output[k];
  526. }
  527. for(i=0; i<Status_num; i++) delete Old_A[i];
  528. delete Old_A;
  529. for(i=0; i<Status_num; i++) delete Old_B[i];
  530. delete Old_B;
  531. for(i=0;i<Status_num;i++)
  532. delete P[i];
  533. delete P;
  534. delete Alpha;
  535. delete Belta;
  536. delete Output;
  537. delete Frame_num;
  538. }
  539. static double DHMM_Calculate(
  540.   double ***Alpha,
  541.   double ***Belta,
  542.   double *Pi,
  543.   double **A,
  544.   double **B,
  545.   int **Out, // 用于训练的各句子的观察序列(输出序列)
  546.   int Sample_num, // 训练集人数
  547.   int Output_num, // VQ码本大小(码字数,即观察值的个数)
  548.   int *T, // 用于训练的各句子的帧数
  549.   int n, // 状态数
  550.   double **P // ???
  551.   )
  552. {
  553. int    i, j, k, m;
  554. double w;
  555. double *R;
  556. double **New_A;
  557. double **New_B;
  558. double **Ct; // to prevent underflow of Alpha and Belta, Ct is the scaling coefficient
  559. double Residue;
  560. // 分配内存
  561. // allocate memory for New_A
  562. if((New_A = new double *[n]) == NULL)
  563. {
  564. DEBUG_PRINTF("Not enough memory for New_A !n");
  565. ASSERT(0);
  566. }
  567. for(i=0; i<n; i++)
  568. {
  569. if((New_A[i] = new double [n]) == NULL)
  570. {
  571. DEBUG_PRINTF("Not enough memory for New_A[%d] !n", i);
  572. ASSERT(0);
  573. }
  574. }
  575. // allocate memory for New_B
  576. if((New_B = new double *[n]) == NULL)
  577. {
  578. DEBUG_PRINTF("Not enough memory for New_B !n");
  579. ASSERT(0);
  580. }
  581. for(i=0; i<n; i++)
  582. {
  583. if((New_B[i] = new double [Output_num]) == NULL)
  584. {
  585. DEBUG_PRINTF("Not enough memory for New_B[%d] !n", i);
  586. ASSERT(0);
  587. }
  588. }
  589. if((R = new double [n]) == NULL)
  590. {
  591. DEBUG_PRINTF("Not enough memory for R !n");
  592. ASSERT(0);
  593. }
  594. if((Ct = new double *[Sample_num]) == NULL)
  595. {
  596. DEBUG_PRINTF("Not enough memory for Ct !n");
  597. ASSERT(0);
  598. }
  599. for(i=0; i<Sample_num; i++)
  600. if((Ct[i] = new double [T[i]]) == NULL)
  601. {
  602. DEBUG_PRINTF("Not enough memory for Ct[%d] !n", i);
  603. ASSERT(0);
  604. }
  605. // Calculate Alpha & Belta.
  606. for(m=0; m<Sample_num; m++)
  607. {
  608. w = 0;
  609. for(i=0; i<n; i++) // n, State Number.
  610. {
  611. Alpha[m][0][i] = Pi[i] * B[i][ Out[m][0] ];
  612. w = w + Alpha[m][0][i];
  613. }
  614. Ct[m][0] = 1.0 / w; // scaling coefficient
  615. for(i=0; i<n; i++)
  616. Alpha[m][0][i] = Alpha[m][0][i] * Ct[m][0]; // scaling
  617. // calculate Alpha
  618. for(k=1; k<T[m]; k++)
  619. {
  620. Ct[m][k] = 0;
  621. for(i=0; i<n; i++)
  622. {
  623. w = 0;
  624. for(j=0; j<n; j++)
  625. w = w + Alpha[m][k-1][j] * A[j][i];
  626. w = w * B[i][ Out[m][k] ];
  627. Alpha[m][k][i] = w;
  628. Ct[m][k] = Ct[m][k] + w;
  629. }
  630. Ct[m][k] = 1.0 / Ct[m][k];
  631. for(i=0; i<n; i++)
  632. Alpha[m][k][i] = Alpha[m][k][i] * Ct[m][k];
  633. }
  634. //在顾良的程序中,通过End_state_mode来区分最后一个状态是否为吸收态(ENDSTATE_ABSORB),现在不再区分了,而是认为不是ENDSTATE_ABSORB.(参见顾良程序R_DHMM.CPP)
  635. for(i=0; i<n; i++) Belta[m][ T[m]-1 ][i] = Ct[m][ T[m]-1 ];
  636. // calculate Belta
  637. for(k=T[m]-2; k>=0; k--)
  638. for(i=0; i<n; i++)
  639. {
  640. w = 0;
  641. for(j=0; j<n; j++)
  642. w = w + A[i][j] * B[j][ Out[m][k+1] ] * Belta[m][k+1][j];
  643. Belta[m][k][i] = w * Ct[m][k];
  644. }
  645. }
  646. // Re-estimate B[i][j], i = 0 to n-1, j = 0 to m-1.
  647. for(i=0; i<n; i++)
  648. for(j=0; j<Output_num; j++)
  649. New_B[i][j] = 0;
  650. for(m=0; m<Sample_num; m++)
  651. {
  652. w = 0;
  653. for(i=0; i<n; i++)
  654. w += Alpha[m][T[m]-1][i]; // w: 观察序列概率,即P(O)
  655. for(k=0; k<T[m]; k++)
  656. for(i=0; i<n; i++) // n, State Number.
  657. {
  658. New_B[i][Out[m][k]] += Alpha[m][k][i] * Belta[m][k][i] /
  659. Ct[m][k] / w;
  660. }
  661. }
  662. // 算这个P干什么用???
  663. for(i=0;i<n;i++)
  664. for(k=0;k<Output_num;k++)
  665. P[i][k] = 1 + New_B[i][k];
  666. for(i=0; i<n; i++)
  667. {
  668. w = 0;
  669. for(j=0; j<Output_num; j++) w += New_B[i][j];
  670. for(j=0; j<Output_num; j++) New_B[i][j] /= w; // 归一化
  671. for(j=0; j<Output_num; j++)
  672. if(New_B[i][j] < Epsilon_B) // Epsilon_B=1.0e-6
  673. New_B[i][j] = Epsilon_B;
  674. w = 0;
  675. for(j=0; j<Output_num; j++) w += New_B[i][j];
  676. for(j=0; j<Output_num; j++) New_B[i][j] /= w; // 归一化
  677. }
  678. for(i=0; i<n; i++) // 更新B矩阵
  679. for(j=0; j<Output_num; j++)
  680. {
  681. B[i][j] = New_B[i][j];
  682. }
  683. Residue = 0;
  684. for(m=0; m<Sample_num; m++)
  685. Residue += DHMM_Priority(Pi, A, B, Out[m], T[m], n);
  686. for(i=0; i<n; i++) delete New_A[i];
  687. delete New_A;
  688. for(i=0; i<n; i++) delete New_B[i];
  689. delete New_B;
  690. delete R;
  691. for(i=0; i<Sample_num; i++) delete Ct[i];
  692. delete Ct;
  693. return Residue;
  694. }
  695. // Calculate P(O|lamuda)
  696. static double DHMM_Priority(double *Pi, double **A, double **B, int *Out, int T, int n)
  697. {
  698. int   i, j, k;
  699. double  w, p;
  700. double  *Alpha1;
  701. double  *Alpha2;
  702. if((Alpha1 = new double [n]) == NULL) { DEBUG_PRINTF("Not enough memory for !n"); ASSERT(0); }
  703. if((Alpha2 = new double [n]) == NULL) { DEBUG_PRINTF("Not enough memory for !n"); ASSERT(0); }
  704. p = 0;
  705. w = 0;
  706. for(i=0; i<n; i++)
  707. {
  708. Alpha1[i] = Pi[i] * B[i][ Out[0] ];
  709. w += Alpha1[i];
  710. }
  711. for(i=0; i<n; i++) Alpha1[i] /= w;
  712. p += log(w);
  713. for(k=1; k<T; k++)
  714. {
  715. for(i=0; i<n; i++)
  716. {
  717. w = 0;
  718. for(j=0; j<n; j++)
  719. w = w + Alpha1[j] * A[j][i];
  720. w = w * B[i][ Out[k] ];
  721. Alpha2[i] = w;
  722. }
  723. if(k < T-1)
  724. {
  725. w = 0;
  726. for(i=0; i<n; i++) w += Alpha2[i];
  727. for(i=0; i<n; i++) Alpha1[i] = Alpha2[i] / w;
  728. p += log(w);
  729. }
  730. }
  731. w = 0;
  732. for(i=0; i<n; i++) w += Alpha2[i];
  733. p += log(w);
  734. delete Alpha1;
  735. delete Alpha2;
  736. return p;
  737. }
  738. static double Viterbi(
  739.    int *VQ_Out, // VQ后的一个识别样本
  740.    int Frame_num, // 帧数
  741.    double **B, // B矩阵
  742.    double **A, // A矩阵
  743.    int Status_num, // 状态数
  744.    int *Status_sequence // 状态序列
  745.    )
  746. {
  747. int **Predecessor; // Status_num*Frame_num矩阵:Predecessor[j][i]中保存第i帧状态为j的情况下,第i-1帧的状态
  748. int  i, j, k;
  749. double  w1, w2,p;
  750. double  **Current_Pr; // Status_num*Frame_num矩阵:即Viterbi搜索中的delta概率
  751. if((Predecessor = new int*[Status_num]) == NULL)
  752. {
  753. printf("Not enough memory for Predecessorn");
  754. exit(0);
  755. }
  756. for(i=0;i<Status_num;i++)
  757. if((Predecessor[i] = new int[Frame_num]) == NULL)
  758. {
  759. printf("Not enough memory for Predecessor[%d]n",i);
  760. exit(0);
  761. }
  762. if((Current_Pr = new double*[Status_num]) == NULL)
  763. {
  764. printf("Not enough memory for Current_Prn");
  765. exit(0);
  766. }
  767. for(i=0;i<Status_num;i++)
  768. if((Current_Pr[i] = new double[Frame_num]) == NULL)
  769. {
  770. printf("Not enough memory for Current_Pr[%d]n",i);
  771. exit(0);
  772. }
  773. /* Viterbi decoding */
  774. /* the first frame */
  775. // 初始化delta[0][0]:第一帧状态0的概率为1,其余状态的概率为0。(这里概率取了对数)
  776. Current_Pr[0][0] = 0;
  777. for(i=1;i<Status_num;i++)
  778. Current_Pr[i][0] = -1e50;
  779. /* forward */
  780. for(i=1;i<Frame_num;i++)
  781. {
  782. Predecessor[0][i] = 0; // 状态0的前一状态只能是状态0
  783. Current_Pr[0][i] = log10(A[0][0] * B[0][VQ_Out[i]]) + Current_Pr[0][i-1]; // 计算delta[i][0]
  784. for(j=1;j<Status_num;j++) // 当前状态是j
  785. {
  786. w1 = log10(A[j-1][j] * B[j][VQ_Out[i]]) + Current_Pr[j-1][i-1]; // 前一状态是j-1
  787. w2 = log10(A[j][j] * B[j][VQ_Out[i]]) + Current_Pr[j][i-1]; // 前一状态是j
  788. // 对于前一状态的两种可能:j-1和j,取delta[i][j]更大的(j为当前状态)
  789. if(w1 >= w2)
  790. {
  791. Predecessor[j][i] = j - 1;
  792. Current_Pr[j][i] = w1;
  793. }
  794. else
  795. {
  796. Predecessor[j][i] = j;
  797. Current_Pr[j][i] = w2;
  798. }
  799. }
  800. }
  801. /* Maximum Likelihood */
  802. // 计算最大输出概率
  803. p = -1e50;
  804. k = -1;
  805. for(i=0;i<Status_num;i++)
  806. {
  807. if(Current_Pr[i][Frame_num-1] > p)
  808. {
  809. p = Current_Pr[i][Frame_num-1];
  810. k = i;
  811. }
  812. }
  813. /*Backward for Status-Sequence */
  814. Status_sequence[Frame_num-1] = Status_num - 1; //k
  815. for(i=Frame_num-2;i>=0;i--)
  816. Status_sequence[i] = Predecessor[Status_sequence[i+1]][i+1];
  817. /* free the memory */
  818. for(i=0;i<Status_num;i++)
  819. {
  820. delete Current_Pr[i];
  821. delete Predecessor[i];
  822. }
  823. delete Current_Pr;
  824. delete Predecessor;
  825. return p;
  826. }