DHMM_MODEL_MFC.cpp
资源名称:VQ-DHMM.rar [点击查看]
上传用户:avbj512
上传日期:2013-09-18
资源大小:6239k
文件大小:28k
源码类别:
DSP编程
开发平台:
Visual C++
- // DHMM_MODEL_MFC.cpp:
- // Implementation of the DHMM_MODEL_MFC Module.
- // That is to train DHMM_Model.
- //
- // Created 2001/08, By DongMing, MDSR.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "DHMM_Model_MFC.h"
- #include "kwspot.h"
- #include "DAT_File_Access.h"
- #include "DHMM_VQ_MFC.h"
- #include "DHMM_GL.h"
- #include "DHMM_LHS.h"
- #include "DHMM_HQ.h"
- extern PRO_CONFIG u_Pro_Config;
- //////////////////////////////////////////////////////////////////////
- // API functions
- //////////////////////////////////////////////////////////////////////
- // 函数名称:DHMM_Model
- // 函数功能:DHMM程序进行模型训练模块的入口
- // 函数性质:API
- // 输入参数:
- // 无
- // 输出参数:
- // 无
- // 返回值:
- // 0 表示成功
- // 备注:本模块完成DHMM模型训练,模块的应用接口实际上是基于文件的,
- // 训练的结果将保存在u_Pro_Config.sz_Toload_DHMM_Model_File_Name中
- int DHMM_Model(void)
- {
- int nRetCode;
- DHMM_MODEL * pu_DHMM_Model;
- int n_Model_Index;
- DHMM_MODEL Silence_Model;
- int Total_Model_Num;
- if ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)
- {
- // 为静音模型多准备两个状态
- u_Pro_Config.n_DHMM_Model_State_Num += 2;
- }
- Total_Model_Num =u_Pro_Config.n_DHMM_Model_Num;
- // 为DHMM模型准备内存
- pu_DHMM_Model = new DHMM_MODEL[Total_Model_Num];
- ASSERT(pu_DHMM_Model);
- for (n_Model_Index = 0; n_Model_Index < Total_Model_Num; n_Model_Index++)
- {
- pu_DHMM_Model[n_Model_Index].n_State_Num = u_Pro_Config.n_DHMM_Model_State_Num;
- pu_DHMM_Model[n_Model_Index].n_Code_Book_Size = u_Pro_Config.n_VQ_Code_Book_Size;
- pu_DHMM_Model[n_Model_Index].pdPi = new double[u_Pro_Config.n_DHMM_Model_State_Num];
- pu_DHMM_Model[n_Model_Index].d2dda_A = d2dda_New(u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_DHMM_Model_State_Num);
- pu_DHMM_Model[n_Model_Index].d2dda_B = d2dda_New(u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
- ASSERT((pu_DHMM_Model[n_Model_Index].pdPi != NULL)
- && (pu_DHMM_Model[n_Model_Index].d2dda_A != NULL)
- && (pu_DHMM_Model[n_Model_Index].d2dda_B != NULL));
- }
- Silence_Model.n_State_Num = 1;
- Silence_Model.n_Code_Book_Size = u_Pro_Config.n_VQ_Code_Book_Size;
- Silence_Model.pdPi = new double[u_Pro_Config.n_DHMM_Model_State_Num];
- Silence_Model.d2dda_A = d2dda_New(Silence_Model.n_State_Num, Silence_Model.n_State_Num);
- Silence_Model.d2dda_B = d2dda_New(Silence_Model.n_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
- ASSERT((Silence_Model.pdPi != NULL)
- && (Silence_Model.d2dda_A != NULL)
- && (Silence_Model.d2dda_B != NULL));
- // Load_Only With Silence DHMM_Model
- if ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)
- {
- nRetCode = DHMM_Model_Load_DHMM_Model_File_With_Silence(u_Pro_Config.sz_Toload_DHMM_Model_File_Name, pu_DHMM_Model, Total_Model_Num);
- ASSERT(nRetCode == 0);
- }
- // Train_Only With Silence DHMM_Model
- else if ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == MODEL_CONFIG_TRAIN_WITH_SILENCE_MODEL)
- {
- nRetCode = DHMM_Model_Train_Silence_DHMM_Model(&Silence_Model);
- nRetCode = DHMM_Model_Train_All_DHMM_Model(pu_DHMM_Model, u_Pro_Config.n_DHMM_Model_Num);
- ASSERT(nRetCode == 0);
- nRetCode = DHMM_Model_Save_DHMM_Model_File_With_Silence(u_Pro_Config.sz_Toload_DHMM_Model_File_Name, pu_DHMM_Model, &Silence_Model,Total_Model_Num);
- ASSERT(nRetCode == 0);
- }
- // 释放模型占用内存
- for (n_Model_Index = 0; n_Model_Index < Total_Model_Num; n_Model_Index++)
- {
- delete[] pu_DHMM_Model[n_Model_Index].pdPi;
- d2dda_Free(pu_DHMM_Model[n_Model_Index].d2dda_A, u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_DHMM_Model_State_Num);
- d2dda_Free(pu_DHMM_Model[n_Model_Index].d2dda_B, u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
- }
- delete[] pu_DHMM_Model;
- if ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)
- {
- // 为静音模型多准备两个状态
- u_Pro_Config.n_DHMM_Model_State_Num -= 2;
- }
- delete [] Silence_Model.pdPi;
- d2dda_Free(Silence_Model.d2dda_A, Silence_Model.n_State_Num, Silence_Model.n_State_Num);
- d2dda_Free(Silence_Model.d2dda_B, Silence_Model.n_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
- return 0;
- }
- //////////////////////////////////////////////////////////////////////
- // 函数名称:DHMM_Model_Save_DHMM_Model_File_With_Silence
- // 函数功能:向文件写入DHMM模型
- // 函数性质:API
- // 输入参数:
- // sz_Tosave_DHMM_Model_File_Name,存储模型的文件名
- // n_DHMM_Model_Num,要存储的模型个数
- // 输出参数:
- // pu_DHMM_Model,存放待写入的DHMM模型
- // 返回值:
- // 0 表示成功
- // 备注:关于DHMM_MODEL的定义,参见公共的.H文件
- // 模型存储使用.DAT格式中的模型存储格式,可参见DAT_File_Access模块
- int DHMM_Model_Save_DHMM_Model_File_With_Silence(char * sz_Tosave_DHMM_Model_File_Name,
- DHMM_MODEL * pu_DHMM_Model, DHMM_MODEL * pu_Silence_Model, int n_DHMM_Model_Num)
- {
- FILE * fp_DHMM_Model_File;
- DHMM_MODEL_FILE_HEAD u_DHMM_Model_File_Head;
- long l_Word_Sample_Offset;
- int n_Model_Index, n_State_Index;
- long lTmp;
- CString Silence_File(sz_Tosave_DHMM_Model_File_Name);
- Silence_File.Replace(".DAT", "WS.DAT");
- fp_DHMM_Model_File = fopen(Silence_File, "wb");
- ASSERT(fp_DHMM_Model_File != NULL);
- // 填写模型文件头
- memset(&u_DHMM_Model_File_Head, 0, sizeof(u_DHMM_Model_File_Head));
- u_DHMM_Model_File_Head.lVersion = DAT_FILE_VERSION;
- strcpy(u_DHMM_Model_File_Head.szName, "DHMM_Model");
- u_DHMM_Model_File_Head.sDHMM_Model_Num = u_DHMM_Model_File_Head.sDHMM_Model_Num2 = n_DHMM_Model_Num;
- strcpy(u_DHMM_Model_File_Head.szParameterType, "DHMMModel");
- u_DHMM_Model_File_Head.sSampleType = SAMPLE_DATA_TYPE_DOUBLE;
- u_DHMM_Model_File_Head.sModelStateNum = pu_DHMM_Model[0].n_State_Num + 2;
- u_DHMM_Model_File_Head.sCodeBookSize = pu_DHMM_Model[0].n_Code_Book_Size;
- ASSERT(sizeof(u_DHMM_Model_File_Head) == 200);
- fwrite(&u_DHMM_Model_File_Head, sizeof(u_DHMM_Model_File_Head), 1, fp_DHMM_Model_File);
- // 用空索引表占据空间
- lTmp = 0;
- for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
- {
- fwrite(&lTmp, sizeof(long), 1, fp_DHMM_Model_File);
- fwrite(&lTmp, sizeof(long), 1, fp_DHMM_Model_File);
- }
- // 依次写入每个模型
- for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
- {
- // 得到模型的文件偏移值,写入索引表
- fseek(fp_DHMM_Model_File, 0, SEEK_END);
- l_Word_Sample_Offset = ftell(fp_DHMM_Model_File);
- fseek(fp_DHMM_Model_File, 200 + 4 * 2 * (n_Model_Index), SEEK_SET);
- fwrite(&l_Word_Sample_Offset, sizeof(long), 1, fp_DHMM_Model_File);
- fseek(fp_DHMM_Model_File, l_Word_Sample_Offset, SEEK_SET);
- // Pi
- fwrite(pu_DHMM_Model[n_Model_Index].pdPi, sizeof(double), u_DHMM_Model_File_Head.sModelStateNum - 2, fp_DHMM_Model_File);
- // A
- for (n_State_Index = 0; n_State_Index < u_DHMM_Model_File_Head.sModelStateNum - 2; n_State_Index++)
- {
- fwrite(pu_DHMM_Model[n_Model_Index].d2dda_A[n_State_Index], sizeof(double), u_DHMM_Model_File_Head.sModelStateNum - 2, fp_DHMM_Model_File);
- }
- // B
- fwrite(pu_Silence_Model[0].d2dda_B[0], sizeof(double), u_DHMM_Model_File_Head.sCodeBookSize, fp_DHMM_Model_File);
- for (n_State_Index = 0; n_State_Index < u_DHMM_Model_File_Head.sModelStateNum - 2; n_State_Index++)
- {
- fwrite(pu_DHMM_Model[n_Model_Index].d2dda_B[n_State_Index], sizeof(double), u_DHMM_Model_File_Head.sCodeBookSize, fp_DHMM_Model_File);
- }
- fwrite(pu_Silence_Model[0].d2dda_B[0], sizeof(double), u_DHMM_Model_File_Head.sCodeBookSize, fp_DHMM_Model_File);
- }
- fclose(fp_DHMM_Model_File);
- return 0;
- }
- //////////////////////////////////////////////////////////////////////
- // 函数名称:DHMM_Model_Load_DHMM_Model_File_With_Silence
- // 函数功能:从文件读入带静音的DHMM模型
- // 函数性质:API
- // 输入参数:
- // sz_Toload_DHMM_Model_File_Name,存储模型的文件名
- // n_DHMM_Model_Num,要读取的模型个数
- // 输出参数:
- // pu_DHMM_Model,存放读出的DHMM模型
- // 返回值:
- // 0 表示成功
- // 备注:关于DHMM_MODEL的定义,参见公共的.H文件
- // 模型存储使用.DAT格式中的模型存储格式,可参见DAT_File_Access模块
- int DHMM_Model_Load_DHMM_Model_File_With_Silence(char * sz_Toload_DHMM_Model_File_Name,
- DHMM_MODEL * pu_DHMM_Model, int n_DHMM_Model_Num)
- {
- FILE * fp_DHMM_Model_File;
- DHMM_MODEL_FILE_HEAD u_DHMM_Model_File_Head;
- int * pn_DHMM_Model_Offset;
- int n_Model_Index, n_State_Index;
- long lTmp;
- CString Silence_File(sz_Toload_DHMM_Model_File_Name);
- Silence_File.Replace(".DAT", "WS.DAT");
- fp_DHMM_Model_File = fopen(Silence_File, "rb");
- ASSERT(fp_DHMM_Model_File != NULL);
- fread(&u_DHMM_Model_File_Head, sizeof(u_DHMM_Model_File_Head), 1, fp_DHMM_Model_File);
- ASSERT(u_DHMM_Model_File_Head.lVersion >= DAT_FILE_VERSION);
- // ASSERT(u_DHMM_Model_File_Head.sDHMM_Model_Num == u_Pro_Config.n_DHMM_Model_Num);
- // ASSERT(u_DHMM_Model_File_Head.sModelStateNum == pu_DHMM_Model->n_State_Num);
- pn_DHMM_Model_Offset = new int[n_DHMM_Model_Num];
- ASSERT(pn_DHMM_Model_Offset != NULL);
- // 读入每个模型的文件偏移
- for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
- {
- fread(&pn_DHMM_Model_Offset[n_Model_Index], sizeof(long), 1, fp_DHMM_Model_File);
- fread(&lTmp, sizeof(long), 1, fp_DHMM_Model_File);
- }
- // 依次读入每个模型数据
- for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
- {
- pu_DHMM_Model[n_Model_Index].n_State_Num = u_DHMM_Model_File_Head.sModelStateNum;
- pu_DHMM_Model[n_Model_Index].n_Code_Book_Size = u_DHMM_Model_File_Head.sCodeBookSize;
- fseek(fp_DHMM_Model_File, pn_DHMM_Model_Offset[n_Model_Index], SEEK_SET);
- // Pi
- fread(pu_DHMM_Model[n_Model_Index].pdPi, sizeof(double), u_DHMM_Model_File_Head.sModelStateNum - 2, fp_DHMM_Model_File);
- // A
- for (n_State_Index = 0; n_State_Index < u_DHMM_Model_File_Head.sModelStateNum - 2; n_State_Index++)
- {
- fread(pu_DHMM_Model[n_Model_Index].d2dda_A[n_State_Index], sizeof(double), u_DHMM_Model_File_Head.sModelStateNum - 2, fp_DHMM_Model_File);
- }
- // B
- for (n_State_Index = 0; n_State_Index < u_DHMM_Model_File_Head.sModelStateNum; n_State_Index++)
- {
- fread(pu_DHMM_Model[n_Model_Index].d2dda_B[n_State_Index], sizeof(double), u_DHMM_Model_File_Head.sCodeBookSize, fp_DHMM_Model_File);
- }
- }
- delete[] pn_DHMM_Model_Offset;
- fclose(fp_DHMM_Model_File);
- return 0;
- }
- //////////////////////////////////////////////////////////////////////
- // 函数名称:DHMM_Model_To_519_Model
- // 函数功能:向文件写入可以用于519系统的定点,对数化,DHMM模型。
- // 函数性质:API
- // 备注:关于DHMM_MODEL的定义,参见公共的.H文件
- // 模型存储使用.DAT格式中的模型存储格式,可参见DAT_File_Access模块
- int DHMM_Model_To_519_Model(void)
- {
- DHMM_MODEL * pu_DHMM_Model;
- int n_Model_Index;
- int n_DHMM_Model_Num;
- int nRetCode;
- char ModelFile[256];
- strcpy(ModelFile, u_Pro_Config.sz_Toload_DHMM_Model_File_Name);
- n_DHMM_Model_Num = u_Pro_Config.n_DHMM_Model_Num;
- if (((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == (MODEL_CONFIG_TRAIN_WITH_SILENCE_MODEL))
- | ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == ( MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)))
- {
- u_Pro_Config.n_DHMM_Model_State_Num += 2;
- }
- // 为DHMM模型准备内存
- pu_DHMM_Model = new DHMM_MODEL[n_DHMM_Model_Num];
- ASSERT(pu_DHMM_Model);
- for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
- {
- pu_DHMM_Model[n_Model_Index].n_State_Num = u_Pro_Config.n_DHMM_Model_State_Num;
- pu_DHMM_Model[n_Model_Index].n_Code_Book_Size = u_Pro_Config.n_VQ_Code_Book_Size;
- pu_DHMM_Model[n_Model_Index].pdPi = new double[u_Pro_Config.n_DHMM_Model_State_Num];
- pu_DHMM_Model[n_Model_Index].d2dda_A = d2dda_New(u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_DHMM_Model_State_Num);
- pu_DHMM_Model[n_Model_Index].d2dda_B = d2dda_New(u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
- ASSERT((pu_DHMM_Model[n_Model_Index].pdPi != NULL)
- && (pu_DHMM_Model[n_Model_Index].d2dda_A != NULL)
- && (pu_DHMM_Model[n_Model_Index].d2dda_B != NULL));
- }
- double** d2dda_B;
- double** d2dda_LogB = d2dda_New(u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
- ASSERT((d2dda_LogB != NULL));
- if (((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == (MODEL_CONFIG_TRAIN_WITH_SILENCE_MODEL))
- | ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == ( MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)))
- {
- nRetCode = DHMM_Model_Load_DHMM_Model_File_With_Silence(u_Pro_Config.sz_Toload_DHMM_Model_File_Name, pu_DHMM_Model, n_DHMM_Model_Num);
- }
- ASSERT(nRetCode == 0);
- CString model_519file = u_Pro_Config.sz_Toload_DHMM_Model_File_Name;
- model_519file.Replace(".DAT", "519.dat");
- FILE *fp_DHMM_Model_File, *fp_DHMM_Model_TXT_File, *fp_DHMM_Model_BIN_File;
- fp_DHMM_Model_File = fopen(model_519file, "wb");
- fp_DHMM_Model_TXT_File = fopen("..//..//data//modelTXT.dat","wb+");
- fp_DHMM_Model_BIN_File = fopen("..//..//data//modelBIN.dat","wb+");
- ASSERT(fp_DHMM_Model_File != NULL);
- short data;
- // 依次写入每个模型
- for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
- {
- d2dda_B = pu_DHMM_Model[n_Model_Index].d2dda_B;
- // B
- for (int n_State_Index = 0; n_State_Index < u_Pro_Config.n_DHMM_Model_State_Num; n_State_Index++)
- {
- for(int n_Code_Word_Index = 0; n_Code_Word_Index < pu_DHMM_Model->n_Code_Book_Size; n_Code_Word_Index++)
- {
- if (d2dda_B[n_State_Index][n_Code_Word_Index] < EPSILON_DOUBLE_VALUE)
- d2dda_B[n_State_Index][n_Code_Word_Index] = EPSILON_DOUBLE_VALUE;
- d2dda_LogB[n_State_Index][n_Code_Word_Index]
- = (int)(log10(d2dda_B[n_State_Index][n_Code_Word_Index]) * (65536L / LOG_SCALE) + 32768L/* + 0.5F*/);
- ASSERT((d2dda_LogB[n_State_Index][n_Code_Word_Index] >= short(MIN_SHORT_VALUE)) && (d2dda_LogB[n_State_Index][n_Code_Word_Index] <= MAX_SHORT_VALUE));
- data = (short)d2dda_LogB[n_State_Index][n_Code_Word_Index];
- fwrite(&data,sizeof(short),1,fp_DHMM_Model_File);
- // if ((n_Model_Index < 15) || (n_Model_Index > 15 && n_Model_Index < 20)
- // || (n_Model_Index > 25 && n_Model_Index < 34))
- {
- fwrite(&data,sizeof(short),1,fp_DHMM_Model_BIN_File);
- fprintf(fp_DHMM_Model_TXT_File,"%d,",data);
- }
- }
- }
- fprintf(fp_DHMM_Model_TXT_File,"n");
- }
- fclose(fp_DHMM_Model_File);
- fclose(fp_DHMM_Model_TXT_File);
- fclose(fp_DHMM_Model_BIN_File);
- d2dda_Free(d2dda_LogB, pu_DHMM_Model->n_State_Num, pu_DHMM_Model->n_Code_Book_Size);
- // 释放模型占用内存
- for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
- {
- delete[] pu_DHMM_Model[n_Model_Index].pdPi;
- d2dda_Free(pu_DHMM_Model[n_Model_Index].d2dda_A, u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_DHMM_Model_State_Num);
- d2dda_Free(pu_DHMM_Model[n_Model_Index].d2dda_B, u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
- }
- delete[] pu_DHMM_Model;
- if ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == (MODEL_CONFIG_TRAIN_WITH_SILENCE_MODEL))
- u_Pro_Config.n_DHMM_Model_State_Num -= 2;
- else if((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)
- u_Pro_Config.n_DHMM_Model_State_Num -= 2;
- return 0;
- }
- //////////////////////////////////////////////////////////////////////
- // 函数名称:DHMM_Model_Train_All_DHMM_Model
- // 函数功能:训练所有词的DHMM模型
- // 函数性质:API
- // 输入参数:
- // n_DHMM_Model_Num,要训练的模型个数
- // 输出参数:
- // pu_DHMM_Model,存放训好的DHMM模型
- // 返回值:
- // 0 表示成功
- // 备注:关于训练的细节参数,均在u_Pro_Config中指定,
- // n_Feature_Person_Num,总的语料库人数
- // n_DHMM_Model_Train_Set_Person_Num,训练集的人数
- // n_DHMM_Model_Person_Start_Index,训练集起始人的标号,
- // 训练集将从此人顺序持续指定人数,标号越界自动折返到0
- int DHMM_Model_Train_All_DHMM_Model(DHMM_MODEL * pu_DHMM_Model, int n_DHMM_Model_Num)
- {
- int nRetCode;
- char sz_Feature_File_Name[256];
- DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Book;
- WORD_SAMPLE * pu_Word_Sample;
- int n_Word_Sample_Index, n_Person_Index, n_Train_Set_Person_Index;
- // 读入码书
- d2dda_Code_Book = d2dda_New(u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
- ASSERT(d2dda_Code_Book != NULL);
- nRetCode = DHMM_VQ_Load_Code_Book_File(u_Pro_Config.sz_Toload_Code_Book_File_Name,
- d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
- ASSERT(nRetCode == 0);
- ASSERT((0 <= u_Pro_Config.n_DHMM_Model_Person_Start_Index) && (u_Pro_Config.n_DHMM_Model_Person_Start_Index < u_Pro_Config.n_Feature_Person_Num)
- && (0 <= u_Pro_Config.n_DHMM_Model_Person_End_Index) && (u_Pro_Config.n_DHMM_Model_Person_End_Index < u_Pro_Config.n_Feature_Person_Num));
- // 为训练集的词条准备内存
- pu_Word_Sample = new WORD_SAMPLE[u_Pro_Config.n_DHMM_Model_Train_Set_Person_Num];
- ASSERT(pu_Word_Sample != NULL);
- // 该重循环,训练每一个词条的模型
- for (n_Word_Sample_Index = 0; n_Word_Sample_Index < u_Pro_Config.n_DHMM_Model_Num; n_Word_Sample_Index++)
- {
- int Sen_Index = n_Word_Sample_Index + u_Pro_Config.n_Sentence_Start_Index;
- // 该重循环,对一个词条,用所有训练集进行训练的数据准备
- n_Train_Set_Person_Index = 0;
- for (n_Person_Index = 0; n_Person_Index < u_Pro_Config.n_Feature_Person_Num; n_Person_Index++)
- {
- // 跳过测试集的人
- if (u_Pro_Config.n_DHMM_Model_Person_Start_Index <= u_Pro_Config.n_DHMM_Model_Person_End_Index)
- {
- if ((n_Person_Index < u_Pro_Config.n_DHMM_Model_Person_Start_Index) || (n_Person_Index > u_Pro_Config.n_DHMM_Model_Person_End_Index)) continue;
- }
- else
- {
- if ((n_Person_Index > u_Pro_Config.n_DHMM_Model_Person_End_Index) && (n_Person_Index < u_Pro_Config.n_DHMM_Model_Person_Start_Index)) continue;
- }
- // 准备该词条的内存空间
- sprintf(sz_Feature_File_Name, u_Pro_Config.sz_Feature_Origin_File_Name_Format, n_Person_Index);
- pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len = dfa_Feature_Get_Sentence_Frame_Num(sz_Feature_File_Name, Sen_Index);
- pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Dim = u_Pro_Config.n_Feature_Dim;
- pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence =
- d2dda_New(pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len, pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Dim);
- pu_Word_Sample[n_Train_Set_Person_Index].pn_VQed_Feature_Sequence =
- new int[pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len];
- ASSERT((pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence != NULL)
- && (pu_Word_Sample[n_Train_Set_Person_Index].pn_VQed_Feature_Sequence != NULL));
- // 读入特征参数
- nRetCode = dfa_Feature_Read_A_Sentence(sz_Feature_File_Name, Sen_Index, u_Pro_Config.n_Feature_Dim,
- pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence);
- ASSERT(nRetCode == pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len);
- // VQ特征
- DHMM_VQ_Encode_A_Word_Sample(d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim,
- &pu_Word_Sample[n_Train_Set_Person_Index]);
- // 释放原始的特征参数占用空间
- d2dda_Free(pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence,
- pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len, pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Dim);
- n_Train_Set_Person_Index++;
- }
- ASSERT(n_Train_Set_Person_Index == u_Pro_Config.n_DHMM_Model_Train_Set_Person_Num);
- PRO_LOG("Model:tTraining Model %4d of %4d.n", n_Word_Sample_Index, u_Pro_Config.n_DHMM_Model_Num);
- // 训练一个词条的模型
- DHMM_Model_Train_DHMM_Model(pu_Word_Sample, u_Pro_Config.n_DHMM_Model_Train_Set_Person_Num, &pu_DHMM_Model[n_Word_Sample_Index]);
- // 释放VQ后的特征占用的内存
- for (n_Train_Set_Person_Index = 0; n_Train_Set_Person_Index < u_Pro_Config.n_DHMM_Model_Train_Set_Person_Num; n_Train_Set_Person_Index++)
- {
- delete[] pu_Word_Sample[n_Train_Set_Person_Index].pn_VQed_Feature_Sequence;
- }
- }
- // 释放所有训练集的词条所占内存,释放码书内存
- delete[] pu_Word_Sample;
- d2dda_Free(d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
- return 0;
- }
- //////////////////////////////////////////////////////////////////////
- // 函数名称:DHMM_Model_Train_Silence_DHMM_Model
- // 函数功能:训练静音的单状态DHMM模型
- // 函数性质:API
- // 输入参数:
- // n_DHMM_Model_Num,要训练的模型个数
- // 输出参数:
- // pu_DHMM_Model,存放训好的DHMM模型
- // 返回值:
- // 0 表示成功
- // 备注:关于训练的细节参数,均在u_Pro_Config中指定,
- // n_Feature_Person_Num,总的语料库人数
- // n_DHMM_Model_Train_Set_Person_Num,训练集的人数
- // n_DHMM_Model_Person_Start_Index,训练集起始人的标号,
- // 训练集将从此人顺序持续指定人数,标号越界自动折返到0
- int DHMM_Model_Train_Silence_DHMM_Model(DHMM_MODEL * pu_DHMM_Model)
- {
- int nRetCode;
- char sz_Feature_File_Name[256];
- char sz_Silence_File_Name[256];
- DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Book;
- WORD_SAMPLE * pu_Word_Sample;
- int n_Word_Sample_Index, n_Person_Index, n_Train_Set_Person_Index;
- int n_DHMM_Model_Train_Set_Person_Num;
- int i, j/*, k, n, m*/;
- int Status_num = 1;
- int Output_num = u_Pro_Config.n_VQ_Code_Book_Size; // VQ码本大小(码字个数)
- double *Pi; // 初始概率
- double **A; // A矩阵:Status_num*Status_num
- double **B; // B矩阵:Status_num*Output_num
- double w;
- // Generate (A, B, Pi)
- Pi = pu_DHMM_Model->pdPi; // The above block transform to this line. #DongMing#
- // allocate memory for A matrix
- A = pu_DHMM_Model->d2dda_A; // The above block transform to this line. #DongMing#
- // allocate memory for B matrix
- B = pu_DHMM_Model->d2dda_B; // The above block transform to this line. #DongMing#
- // 初始化初始概率Pi:状态0概率为1,其余状态概率为0
- Pi[0] = 1;
- for(i=1; i<Status_num; i++) Pi[i] = 0;
- for(i=0; i<Status_num; i++)
- {
- // 初始化A矩阵
- for(j=0; j<Status_num; j++) A[i][j] = 0;
- if(i < Status_num-1)
- {
- A[i][i] = 0.5;
- A[i][i+1] = 0.5;
- }
- else
- {
- A[i][i] = 1.0;
- }
- // 归一化A矩阵
- w = 0;
- for(j=0; j<Status_num; j++) w = w + A[i][j];
- for(j=0; j<Status_num; j++) A[i][j] = A[i][j] / w;
- w = 0;
- // 初始化B矩阵
- for(j=0; j<Output_num; j++)
- {
- B[i][j] = 1.0 / Output_num * (0.9 + ((rand()%1000) / 5000.0));
- w = w + B[i][j];
- }
- // 归一化B矩阵
- for(j=0; j<Output_num; j++) B[i][j] = 0; //B[i][j] / w;
- }
- // 读入码书
- d2dda_Code_Book = d2dda_New(u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
- ASSERT(d2dda_Code_Book != NULL);
- nRetCode = DHMM_VQ_Load_Code_Book_File(u_Pro_Config.sz_Toload_Code_Book_File_Name,
- d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
- ASSERT(nRetCode == 0);
- ASSERT((0 <= u_Pro_Config.n_DHMM_Model_Person_Start_Index) && (u_Pro_Config.n_DHMM_Model_Person_Start_Index < u_Pro_Config.n_Feature_Person_Num)
- && (0 <= u_Pro_Config.n_DHMM_Model_Person_End_Index) && (u_Pro_Config.n_DHMM_Model_Person_End_Index < u_Pro_Config.n_Feature_Person_Num));
- // 为训练集的词条准备内存
- pu_Word_Sample = new WORD_SAMPLE[u_Pro_Config.n_DHMM_Model_Train_Set_Person_Num * u_Pro_Config.n_DHMM_Model_Num];
- ASSERT(pu_Word_Sample != NULL);
- n_Train_Set_Person_Index = 0;
- // 该重循环,加载每一个词条的静音数据
- for (n_Word_Sample_Index = 0; n_Word_Sample_Index < u_Pro_Config.n_DHMM_Model_Num; n_Word_Sample_Index++)
- {
- int Sen_Index = n_Word_Sample_Index + u_Pro_Config.n_Sentence_Start_Index;
- // 该重循环,对一个词条,用所有训练集进行训练的数据准备
- for (n_Person_Index = 0; n_Person_Index < u_Pro_Config.n_Feature_Person_Num; n_Person_Index++)
- {
- // 跳过测试集的人
- if (u_Pro_Config.n_DHMM_Model_Person_Start_Index <= u_Pro_Config.n_DHMM_Model_Person_End_Index)
- {
- if ((n_Person_Index < u_Pro_Config.n_DHMM_Model_Person_Start_Index) || (n_Person_Index > u_Pro_Config.n_DHMM_Model_Person_End_Index)) continue;
- }
- else
- {
- if ((n_Person_Index > u_Pro_Config.n_DHMM_Model_Person_End_Index) && (n_Person_Index < u_Pro_Config.n_DHMM_Model_Person_Start_Index)) continue;
- }
- // 修改文件名
- sprintf(sz_Feature_File_Name, u_Pro_Config.sz_Feature_Origin_File_Name_Format, n_Person_Index);
- strcpy(sz_Silence_File_Name, sz_Feature_File_Name);
- int j = strlen(sz_Silence_File_Name) - 4;
- sz_Silence_File_Name[j] = ' ';
- strcat(sz_Silence_File_Name,"_sl.dat");
- // 准备该词条的内存空间
- pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len = dfa_Feature_Get_Silence_Frame_Num(sz_Silence_File_Name, Sen_Index);
- //pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len = 2 * RELAX_FRAME;
- pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Dim = u_Pro_Config.n_Feature_Dim;
- pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence =
- d2dda_New(pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len, pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Dim);
- pu_Word_Sample[n_Train_Set_Person_Index].pn_VQed_Feature_Sequence =
- new int[pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len];
- ASSERT((pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence != NULL)
- && (pu_Word_Sample[n_Train_Set_Person_Index].pn_VQed_Feature_Sequence != NULL));
- // 读入特征参数
- nRetCode = dfa_Feature_Read_A_Silence(sz_Silence_File_Name, Sen_Index, u_Pro_Config.n_Feature_Dim,
- pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence);
- ASSERT(nRetCode == pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len);
- // VQ特征
- DHMM_VQ_Encode_A_Word_Sample(d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim,
- &pu_Word_Sample[n_Train_Set_Person_Index]);
- // 释放原始的特征参数占用空间
- d2dda_Free(pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence,
- pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len, pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Dim);
- n_Train_Set_Person_Index++;
- }
- }
- PRO_LOG("Model:tTraining Silence Model...n");
- n_DHMM_Model_Train_Set_Person_Num = n_Train_Set_Person_Index;
- int fr_num;
- for(i = 0; i < n_DHMM_Model_Train_Set_Person_Num; i++)
- {
- fr_num = pu_Word_Sample[i].n_Feature_Sequence_Len;
- for(j = 0; j < fr_num; j++)
- B[0][pu_Word_Sample[i].pn_VQed_Feature_Sequence[j]]++;
- }
- // 释放VQ后的特征占用的内存
- for (n_Train_Set_Person_Index = 0; n_Train_Set_Person_Index < n_DHMM_Model_Train_Set_Person_Num; n_Train_Set_Person_Index++)
- {
- delete[] pu_Word_Sample[n_Train_Set_Person_Index].pn_VQed_Feature_Sequence;
- }
- for(i = 0; i < Output_num; i++)
- {
- B[0][i] /= (fr_num * n_DHMM_Model_Train_Set_Person_Num);
- if (B[0][i] < Epsilon_B)
- B[0][i] = Epsilon_B;
- }
- for(j=0; j<Output_num; j++)
- w = w + B[0][j];
- // 归一化B矩阵
- for(j=0; j<Output_num; j++) B[0][j] = B[0][j] / w;
- // 释放所有训练集的词条所占内存,释放码书内存
- delete[] pu_Word_Sample;
- d2dda_Free(d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
- return 0;
- }
- //////////////////////////////////////////////////////////////////////
- // 函数名称:DHMM_Model_Train_DHMM_Model
- // 函数功能:训练一个词的DHMM模型
- // 函数性质:API
- // 输入参数:
- // pu_Word_Sample,存放该词训练集的数据
- // n_Word_Sample_Num,训练集的词数
- // 输出参数:
- // pu_DHMM_Model,存放训好的DHMM模型
- // 返回值:
- // 0 表示成功
- // 备注:WORD_SAMPLE的定义,参见公共的.H文件
- // 该函数是一个分发函数,按照u_Pro_Config.l_DHMM_Model_Config配置的信息
- // 将具体调用不同的函数体
- int DHMM_Model_Train_DHMM_Model(WORD_SAMPLE * pu_Word_Sample, int n_Word_Sample_Num,
- DHMM_MODEL * pu_DHMM_Model)
- {
- switch (u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_TRAIN_PROCEDURE_MASK)
- {
- case MODEL_CONFIG_TRAIN_PROCEDURE_STD:
- ASSERT(0);
- break;
- case MODEL_CONFIG_TRAIN_PROCEDURE_GL:
- return DHMM_Model_Train_DHMM_Model_GL(pu_Word_Sample, n_Word_Sample_Num, pu_DHMM_Model);
- break;
- case MODEL_CONFIG_TRAIN_PROCEDURE_LHS:
- ASSERT(0); //LHS的训练过程,与GL的完全相同,故略去
- break;
- case MODEL_CONFIG_TRAIN_PROCEDURE_HQ:
- return DHMM_Model_Train_DHMM_Model_HQ(pu_Word_Sample, n_Word_Sample_Num, pu_DHMM_Model);
- break;
- case MODEL_CONFIG_TRAIN_PROCEDURE_WP:
- ASSERT(0);
- break;
- default:
- ASSERT(0);
- break;
- }
- return 0;
- }