You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

565 lines
19 KiB

4 years ago
  1. import sys
  2. import os
  3. os.chdir(r'C:\Users\Aki\source\repos\acoustic_model\acoustic_model')
  4. import tempfile
  5. import shutil
  6. import glob
  7. import time
  8. import numpy as np
  9. import pandas as pd
  10. import fame_functions
  11. from phoneset import fame_ipa, fame_asr, fame_phonetics
  12. import defaultfiles as default
  13. sys.path.append(default.toolbox_dir)
  14. import file_handling as fh
  15. from htk import pyhtk
  16. #from scripts import run_command
  17. ## ======================= user define =======================
  18. # procedure
  19. combine_all = 1
  20. make_lexicon = 0
  21. make_label = 0 # it takes roughly 4800 sec on Surface pro 2.
  22. make_mlf = 0
  23. extract_features = 0
  24. flat_start = 1
  25. train_monophone_without_sp = 1
  26. add_sp = 1
  27. train_monophone_with_re_aligned_mlf = 1
  28. increase_mixture = 1
  29. train_triphone = 0
  30. train_triphone_tied = 0
  31. # pre-defined values.
  32. dataset_list = ['devel', 'test', 'train']
  33. feature_size = 30
  34. improvement_threshold = 0.3
  35. lexicon_asr = os.path.join(default.fame_dir, 'lexicon', 'lex.asr')
  36. lexicon_oov = os.path.join(default.fame_dir, 'lexicon', 'lex.oov')
  37. config_dir = os.path.join(default.htk_dir, 'config')
  38. phonelist_full_txt = os.path.join(config_dir, 'phonelist_full.txt')
  39. tree_hed = os.path.join(config_dir, 'tree.hed')
  40. quests_hed = os.path.join(config_dir, 'quests.hed')
  41. model_dir = os.path.join(default.htk_dir, 'model')
  42. model_mono0_dir = os.path.join(model_dir, 'mono0')
  43. model_mono1_dir = os.path.join(model_dir, 'mono1')
  44. model_mono1sp_dir = os.path.join(model_dir, 'mono1sp')
  45. model_mono1sp2_dir = os.path.join(model_dir, 'mono1sp2')
  46. model_tri1_dir = os.path.join(model_dir, 'tri1')
  47. model_tri1tied_dir = os.path.join(model_dir, 'tri1tied')
  48. # directories / files to be made.
  49. lexicon_dir = os.path.join(default.htk_dir, 'lexicon')
  50. lexicon_htk_asr = os.path.join(lexicon_dir, 'lex.htk_asr')
  51. lexicon_htk_oov = os.path.join(lexicon_dir, 'lex.htk_oov')
  52. lexicon_htk = os.path.join(lexicon_dir, 'lex.htk')
  53. lexicon_htk_with_sp = os.path.join(lexicon_dir, 'lex_with_sp.htk')
  54. lexicon_htk_triphone = os.path.join(lexicon_dir, 'lex_triphone.htk')
  55. feature_dir = os.path.join(default.htk_dir, 'mfc')
  56. fh.make_new_directory(feature_dir, existing_dir='leave')
  57. tmp_dir = os.path.join(default.htk_dir, 'tmp')
  58. fh.make_new_directory(tmp_dir, existing_dir='leave')
  59. label_dir = os.path.join(default.htk_dir, 'label')
  60. fh.make_new_directory(label_dir, existing_dir='leave')
  61. ## training
  62. if combine_all:
  63. hcompv_scp_train = os.path.join(tmp_dir, 'all.scp')
  64. mlf_file_train = os.path.join(label_dir, 'all_phone.mlf')
  65. mlf_file_train_word = os.path.join(label_dir, 'all_word.mlf')
  66. mlf_file_train_with_sp = os.path.join(label_dir, 'all_phone_with_sp.mlf')
  67. mlf_file_train_aligned = os.path.join(label_dir, 'all_phone_aligned.mlf')
  68. triphone_mlf = os.path.join(label_dir, 'all_triphone.mlf')
  69. else:
  70. hcompv_scp_train = os.path.join(tmp_dir, 'train.scp')
  71. mlf_file_train = os.path.join(label_dir, 'train_phone.mlf')
  72. mlf_file_train_word = os.path.join(label_dir, 'train_word.mlf')
  73. mlf_file_train_with_sp = os.path.join(label_dir, 'train_phone_with_sp.mlf')
  74. mlf_file_train_aligned = os.path.join(label_dir, 'train_phone_aligned.mlf')
  75. triphone_mlf = os.path.join(label_dir, 'train_triphone.mlf')
  76. hcompv_scp_train_updated = hcompv_scp_train.replace('.scp', '_updated.scp')
  77. ## testing
  78. htk_stimmen_dir = os.path.join(default.htk_dir, 'stimmen')
  79. ## ======================= make lexicon for HTK =======================
  80. if make_lexicon:
  81. timer_start = time.time()
  82. print('==== making lexicon for HTK ====')
  83. # convert each lexicon from fame_asr phoneset to fame_htk phoneset.
  84. print('>>> converting each lexicon from fame_asr phoneset to fame_htk phoneset...')
  85. fame_functions.lexicon_asr2htk(lexicon_asr, lexicon_htk_asr)
  86. fame_functions.lexicon_asr2htk(lexicon_oov, lexicon_htk_oov)
  87. # combine lexicon
  88. print('>>> combining lexicon files into one lexicon...')
  89. # pronunciations which is not found in lex.asr are generated using G2P and listed in lex.oov.
  90. # therefore there is no overlap between lex_asr and lex_oov.
  91. fame_functions.combine_lexicon(lexicon_htk_asr, lexicon_htk_oov, lexicon_htk)
  92. ## fixing the lexicon for HTK.
  93. # (1) Replace all tabs with single space;
  94. # (2) Put a '\' before any dictionary entry beginning with single quote
  95. # http://electroblaze.blogspot.nl/2013/03/understanding-htk-error-messages.html
  96. print('>>> fixing the lexicon...')
  97. fame_functions.fix_lexicon(lexicon_htk)
  98. ## adding sp to the lexicon for HTK.
  99. print('>>> adding sp to the lexicon...')
  100. with open(lexicon_htk) as f:
  101. lines = f.read().split('\n')
  102. with open(lexicon_htk_with_sp, 'wb') as f:
  103. f.write(bytes(' sp\n'.join(lines), 'ascii'))
  104. print("elapsed time: {}".format(time.time() - timer_start))
  105. ## intialize the instance for HTK.
  106. chtk = pyhtk.HTK(config_dir, fame_asr.phoneset_htk, lexicon_htk_with_sp, feature_size)
  107. ## ======================= make label files =======================
  108. if make_label:
  109. for dataset in dataset_list:
  110. timer_start = time.time()
  111. print("==== making label files on dataset {}".format(dataset))
  112. script_list = os.path.join(default.fame_dir, 'data', dataset, 'text')
  113. wav_dir_ = os.path.join(default.fame_dir, 'fame', 'wav', dataset)
  114. label_dir_ = os.path.join(label_dir, dataset)
  115. dictionary_file = os.path.join(label_dir_, 'temp.dic')
  116. fh.make_new_directory(label_dir_, existing_dir='leave')
  117. # list of scripts
  118. with open(script_list, "rt", encoding="utf-8") as fin:
  119. scripts = fin.read().split('\n')
  120. for line in scripts:
  121. # sample line:
  122. # sp0457m_test_1968_plakkenfryslanterhorne_2168 en dan begjinne je natuerlik
  123. filename_ = line.split(' ')[0]
  124. filename = '_'.join(filename_.split('_')[1:])
  125. sentence = ' '.join(line.split(' ')[1:])
  126. sentence_htk = fame_functions.word2htk(sentence)
  127. wav_file = os.path.join(wav_dir_, filename + '.wav')
  128. if os.path.exists(wav_file) and chtk.can_be_ascii(sentence_htk) == 0:
  129. if chtk.get_number_of_missing_words(
  130. sentence_htk, dictionary_file) == 0:
  131. # when the file name is too long, HDMan command does not work.
  132. # therefore first temporary dictionary_file is made, then renamed.
  133. shutil.move(dictionary_file, os.path.join(label_dir_, filename + '.dic'))
  134. label_file = os.path.join(label_dir_, filename + '.lab')
  135. chtk.make_label_file(sentence_htk, label_file)
  136. else:
  137. os.remove(dictionary_file)
  138. print("elapsed time: {}".format(time.time() - timer_start))
  139. ## ======================= make master label files =======================
  140. if make_mlf:
  141. timer_start = time.time()
  142. print("==== making master label files ====")
  143. # train_2002_gongfansaken_10347.lab is empty. should be removed.
  144. empty_lab_file = os.path.join(label_dir, 'train', 'train_2002_gongfansaken_10347.lab')
  145. empty_dic_file = empty_lab_file.replace('.lab', '.dic')
  146. if os.path.exists(empty_lab_file):
  147. os.remove(empty_lab_file)
  148. if os.path.exists(empty_dic_file):
  149. os.remove(empty_dic_file)
  150. for dataset in dataset_list:
  151. feature_dir_ = os.path.join(feature_dir, dataset)
  152. label_dir_ = os.path.join(label_dir, dataset)
  153. mlf_word = os.path.join(label_dir, dataset + '_word.mlf')
  154. mlf_phone = os.path.join(label_dir, dataset + '_phone.mlf')
  155. mlf_phone_with_sp = os.path.join(label_dir, dataset + '_phone_with_sp.mlf')
  156. print(">>> generating a word level mlf file for {}...".format(dataset))
  157. chtk.label2mlf(label_dir_, mlf_word)
  158. print(">>> generating a phone level mlf file for {}...".format(dataset))
  159. chtk.mlf_word2phone(mlf_phone, mlf_word, with_sp=False)
  160. chtk.mlf_word2phone(mlf_phone_with_sp, mlf_word, with_sp=True)
  161. print("elapsed time: {}".format(time.time() - timer_start))
  162. ## ======================= extract features =======================
  163. if extract_features:
  164. for dataset in dataset_list:
  165. timer_start = time.time()
  166. print('==== extract features on dataset {} ===='.format(dataset))
  167. wav_dir_ = os.path.join(default.fame_dir, 'fame', 'wav', dataset)
  168. label_dir_ = os.path.join(label_dir, dataset)
  169. feature_dir_ = os.path.join(feature_dir, dataset)
  170. fh.make_new_directory(feature_dir_, existing_dir='delete')
  171. # a script file for HCopy
  172. print(">>> making a script file for HCopy...")
  173. hcopy_scp = tempfile.NamedTemporaryFile(mode='w', delete=False)
  174. hcopy_scp.close()
  175. # get a list of features (hcopy.scp)
  176. # from the filelist in FAME! corpus.
  177. #fame_functions.make_hcopy_scp_from_filelist_in_fame(default.fame_dir, dataset, feature_dir_, hcopy_scp.name)
  178. # from the list of label files.
  179. lab_list = glob.glob(os.path.join(label_dir_, '*.lab'))
  180. feature_list = [
  181. os.path.join(wav_dir_, os.path.basename(lab_file).replace('.lab', '.wav')) + '\t'
  182. + os.path.join(feature_dir_, os.path.basename(lab_file).replace('.lab', '.mfc'))
  183. for lab_file in lab_list]
  184. #if os.path.exists(empty_mfc_file):
  185. # os.remove(empty_mfc_file)
  186. with open(hcopy_scp.name, 'wb') as f:
  187. f.write(bytes('\n'.join(feature_list), 'ascii'))
  188. # extract features.
  189. print(">>> extracting features on {}...".format(dataset))
  190. chtk.wav2mfc(hcopy_scp.name)
  191. os.remove(hcopy_scp.name)
  192. # make hcompv.scp.
  193. print(">>> making a script file for {}...".format(dataset))
  194. listdir = glob.glob(os.path.join(label_dir_, '*.dic'))
  195. mfc_list = [filename.replace(label_dir_, feature_dir_).replace('.dic', '.mfc') for filename in listdir]
  196. hcompv_scp = os.path.join(tmp_dir, dataset + '.scp')
  197. with open(hcompv_scp, 'wb') as f:
  198. f.write(bytes('\n'.join(mfc_list) + '\n', 'ascii'))
  199. print(">>> extracting features on stimmen...")
  200. chtk.wav2mfc(os.path.join(htk_stimmen_dir, 'hcopy.scp'))
  201. print("elapsed time: {}".format(time.time() - timer_start))
  202. ## ======================= flat start monophones =======================
  203. if combine_all:
  204. # script files.
  205. fh.concatenate(
  206. os.path.join(tmp_dir, 'devel.scp'),
  207. os.path.join(tmp_dir, 'test.scp'),
  208. hcompv_scp_train
  209. )
  210. fh.concatenate(
  211. hcompv_scp_train,
  212. os.path.join(tmp_dir, 'train.scp'),
  213. hcompv_scp_train
  214. )
  215. # phone level mlfs.
  216. fh.concatenate(
  217. os.path.join(label_dir, 'devel_phone.mlf'),
  218. os.path.join(label_dir, 'test_phone.mlf'),
  219. mlf_file_train
  220. )
  221. fh.concatenate(
  222. mlf_file_train,
  223. os.path.join(label_dir, 'train_phone.mlf'),
  224. mlf_file_train
  225. )
  226. # phone level mlfs with sp.
  227. fh.concatenate(
  228. os.path.join(label_dir, 'devel_phone_with_sp.mlf'),
  229. os.path.join(label_dir, 'test_phone_with_sp.mlf'),
  230. mlf_file_train_with_sp
  231. )
  232. fh.concatenate(
  233. mlf_file_train_with_sp,
  234. os.path.join(label_dir, 'train_phone_with_sp.mlf'),
  235. mlf_file_train_with_sp
  236. )
  237. # word level mlfs.
  238. fh.concatenate(
  239. os.path.join(label_dir, 'devel_word.mlf'),
  240. os.path.join(label_dir, 'test_word.mlf'),
  241. mlf_file_train_word
  242. )
  243. fh.concatenate(
  244. mlf_file_train_word,
  245. os.path.join(label_dir, 'train_word.mlf'),
  246. mlf_file_train_word
  247. )
  248. ## ======================= flat start monophones =======================
  249. if flat_start:
  250. timer_start = time.time()
  251. print('==== flat start ====')
  252. fh.make_new_directory(model_mono0_dir, existing_dir='leave')
  253. chtk.flat_start(hcompv_scp_train, model_mono0_dir)
  254. # make macros.
  255. vFloors = os.path.join(model_mono0_dir, 'vFloors')
  256. if os.path.exists(vFloors):
  257. chtk.make_macros(vFloors)
  258. # allocate mean & variance to all phones in the phone list
  259. print('>>> allocating mean & variance to all phones in the phone list...')
  260. chtk.make_hmmdefs(model_mono0_dir)
  261. print("elapsed time: {}".format(time.time() - timer_start))
  262. ## ======================= train model without short pause =======================
  263. if train_monophone_without_sp:
  264. print('==== train monophone without sp ====')
  265. timer_start = time.time()
  266. niter = chtk.re_estimation_until_saturated(
  267. model_mono1_dir,
  268. model_mono0_dir, improvement_threshold, hcompv_scp_train,
  269. os.path.join(htk_stimmen_dir, 'mfc'),
  270. 'mfc',
  271. os.path.join(htk_stimmen_dir, 'word_lattice.ltc'),
  272. mlf_file=mlf_file_train,
  273. lexicon=os.path.join(htk_stimmen_dir, 'lexicon_recognition.dic')
  274. )
  275. print("elapsed time: {}".format(time.time() - timer_start))
  276. ## ======================= adding sp to the model =======================
  277. if add_sp:
  278. print('==== adding sp to the model ====')
  279. # reference:
  280. # http://www.f.waseda.jp/yusukekondo/htk.html#flat_start_estimation
  281. timer_start = time.time()
  282. # make model with sp.
  283. print('>>> adding sp state to the last model in the previous step...')
  284. fh.make_new_directory(model_mono1sp_dir, existing_dir='leave')
  285. niter = chtk.get_niter_max(model_mono1_dir)
  286. modeln_dir_pre = os.path.join(model_mono1_dir, 'iter'+str(niter))
  287. modeln_dir = os.path.join(model_mono1sp_dir, 'iter0')
  288. chtk.add_sp(modeln_dir_pre, modeln_dir)
  289. print('>>> re-estimation...')
  290. niter = chtk.re_estimation_until_saturated(
  291. model_mono1sp_dir, modeln_dir, improvement_threshold, hcompv_scp_train,
  292. os.path.join(htk_stimmen_dir, 'mfc'),
  293. 'mfc',
  294. os.path.join(htk_stimmen_dir, 'word_lattice.ltc'),
  295. mlf_file=mlf_file_train_with_sp,
  296. lexicon=os.path.join(htk_stimmen_dir, 'lexicon_recognition.dic'),
  297. model_type='monophone_with_sp'
  298. )
  299. print("elapsed time: {}".format(time.time() - timer_start))
  300. ## ======================= train model with re-aligned mlf =======================
  301. if train_monophone_with_re_aligned_mlf:
  302. print('==== traina monophone with re-aligned mlf ====')
  303. timer_start = time.time()
  304. print('>>> re-aligning the training data... ')
  305. niter = chtk.get_niter_max(model_mono1sp_dir)
  306. modeln_dir = os.path.join(model_mono1sp_dir, 'iter'+str(niter))
  307. chtk.make_aligned_label(
  308. os.path.join(modeln_dir, 'macros'),
  309. os.path.join(modeln_dir, 'hmmdefs'),
  310. mlf_file_train_aligned,
  311. mlf_file_train_word,
  312. hcompv_scp_train)
  313. chtk.fix_mlf(mlf_file_train_aligned)
  314. print('>>> updating the script file... ')
  315. chtk.update_script_file(
  316. mlf_file_train_aligned,
  317. mlf_file_train_with_sp,
  318. hcompv_scp_train,
  319. hcompv_scp_train_updated)
  320. print('>>> re-estimation... ')
  321. timer_start = time.time()
  322. fh.make_new_directory(model_mono1sp2_dir, existing_dir='leave')
  323. niter = chtk.get_niter_max(model_mono1sp_dir)
  324. niter = chtk.re_estimation_until_saturated(
  325. model_mono1sp2_dir,
  326. os.path.join(model_mono1sp_dir, 'iter'+str(niter)),
  327. improvement_threshold,
  328. hcompv_scp_train_updated,
  329. os.path.join(htk_stimmen_dir, 'mfc'),
  330. 'mfc',
  331. os.path.join(htk_stimmen_dir, 'word_lattice.ltc'),
  332. mlf_file=mlf_file_train_aligned,
  333. lexicon=os.path.join(htk_stimmen_dir, 'lexicon_recognition.dic'),
  334. model_type='monophone_with_sp'
  335. )
  336. print("elapsed time: {}".format(time.time() - timer_start))
  337. ## ======================= increase mixture =======================
  338. if increase_mixture:
  339. print('==== increase mixture ====')
  340. timer_start = time.time()
  341. for nmix in [2, 4, 8, 16]:
  342. if nmix == 2:
  343. modeln_dir_ = model_mono1sp2_dir
  344. else:
  345. modeln_dir_ = os.path.join(model_dir, 'mono'+str(nmix_))
  346. modeln_dir = os.path.join(model_dir, 'mono'+str(nmix))
  347. print('mixture: {}'.format(nmix))
  348. fh.make_new_directory(modeln_dir, existing_dir='delete')
  349. niter = chtk.get_niter_max(modeln_dir_)
  350. chtk.increase_mixture(
  351. os.path.join(modeln_dir_, 'iter'+str(niter), 'hmmdefs'),
  352. nmix,
  353. os.path.join(modeln_dir, 'iter0'),
  354. model_type='monophone_with_sp')
  355. shutil.copy2(os.path.join(modeln_dir_, 'iter'+str(niter), 'macros'),
  356. os.path.join(modeln_dir, 'iter0', 'macros'))
  357. #improvement_threshold = -10
  358. niter = chtk.re_estimation_until_saturated(
  359. modeln_dir,
  360. os.path.join(modeln_dir_, 'iter0'),
  361. improvement_threshold,
  362. hcompv_scp_train_updated,
  363. os.path.join(htk_stimmen_dir, 'mfc'),
  364. 'mfc',
  365. os.path.join(htk_stimmen_dir, 'word_lattice.ltc'),
  366. mlf_file=mlf_file_train_aligned,
  367. lexicon=os.path.join(htk_stimmen_dir, 'lexicon_recognition.dic'),
  368. model_type='monophone_with_sp'
  369. )
  370. nmix_ = nmix
  371. print("elapsed time: {}".format(time.time() - timer_start))
  372. ## ======================= train triphone =======================
  373. print('>>> making triphone list... ')
  374. chtk.make_triphonelist(
  375. mlf_file_train_aligned,
  376. triphone_mlf)
  377. if train_triphone:
  378. print('==== train triphone model ====')
  379. timer_start = time.time()
  380. print('>>> init triphone model... ')
  381. niter = chtk.get_niter_max(model_mono1sp2_dir)
  382. fh.make_new_directory(os.path.join(model_tri1_dir, 'iter0'), existing_dir='leave')
  383. chtk.init_triphone(
  384. os.path.join(model_mono1sp2_dir, 'iter'+str(niter)),
  385. os.path.join(model_tri1_dir, 'iter0')
  386. )
  387. print('>>> re-estimation... ')
  388. ## I wanted to train until satulated:
  389. #niter = chtk.re_estimation_until_saturated(
  390. # model_tri1_dir,
  391. # os.path.join(model_tri1_dir, 'iter0'),
  392. # improvement_threshold,
  393. # hcompv_scp_train_updated,
  394. # os.path.join(htk_stimmen_dir, 'mfc'),
  395. # 'mfc',
  396. # os.path.join(htk_stimmen_dir, 'word_lattice.ltc'),
  397. # mlf_file=triphone_mlf,
  398. # lexicon=os.path.join(htk_stimmen_dir, 'lexicon_recognition.dic'),
  399. # model_type='triphone'
  400. # )
  401. #
  402. # but because the data size is limited, some triphone cannot be trained and received the error:
  403. # ERROR [+8231] GetHCIModel: Cannot find hmm [i:-]r[+???]
  404. # therefore only two times re-estimation is performed.
  405. output_dir = model_tri1_dir
  406. for niter in range(1, 4):
  407. hmm_n = 'iter' + str(niter)
  408. hmm_n_pre = 'iter' + str(niter-1)
  409. _modeln_dir = os.path.join(output_dir, hmm_n)
  410. _modeln_dir_pre = os.path.join(output_dir, hmm_n_pre)
  411. fh.make_new_directory(_modeln_dir, 'leave')
  412. chtk.re_estimation(
  413. os.path.join(_modeln_dir_pre, 'hmmdefs'),
  414. _modeln_dir,
  415. hcompv_scp_train_updated,
  416. mlf_file=triphone_mlf,
  417. macros=os.path.join(_modeln_dir_pre, 'macros'),
  418. model_type='triphone')
  419. print("elapsed time: {}".format(time.time() - timer_start))
  420. ## ======================= train tied-state triphones =======================
  421. if train_triphone_tied:
  422. print('==== train tied-state triphones ====')
  423. timer_start = time.time()
  424. print('>>> making lexicon for triphone... ')
  425. chtk.make_lexicon_triphone(phonelist_full_txt, lexicon_htk_triphone)
  426. chtk.combine_phonelists(phonelist_full_txt)
  427. print('>>> making a tree header... ')
  428. fame_phonetics.make_quests_hed(quests_hed)
  429. stats = os.path.join(r'c:\OneDrive\Research\rug\experiments\acoustic_model\fame\htk\model\tri1\iter3', 'stats')
  430. chtk.make_tree_header(tree_hed, quests_hed, stats, config_dir)
  431. print('>>> init triphone model... ')
  432. niter = chtk.get_niter_max(model_tri1_dir)
  433. fh.make_new_directory(os.path.join(model_tri1tied_dir, 'iter0'), existing_dir='leave')
  434. chtk.init_triphone(
  435. os.path.join(model_tri1_dir, 'iter'+str(niter)),
  436. os.path.join(model_tri1tied_dir, 'iter0'),
  437. tied=True)
  438. # I wanted to train until satulated:
  439. #niter = chtk.re_estimation_until_saturated(
  440. # model_tri1tied_dir,
  441. # os.path.join(model_tri1tied_dir, 'iter0'),
  442. # improvement_threshold,
  443. # hcompv_scp_train_updated,
  444. # os.path.join(htk_stimmen_dir, 'mfc'),
  445. # 'mfc',
  446. # os.path.join(htk_stimmen_dir, 'word_lattice.ltc'),
  447. # mlf_file=triphone_mlf,
  448. # lexicon=os.path.join(htk_stimmen_dir, 'lexicon_recognition.dic'),
  449. # model_type='triphone'
  450. # )
  451. #
  452. # but because the data size is limited, some triphone cannot be trained and received the error:
  453. # ERROR [+8231] GetHCIModel: Cannot find hmm [i:-]r[+???]
  454. # therefore only 3 times re-estimation is performed.
  455. output_dir = model_tri1tied_dir
  456. for niter in range(1, 4):
  457. hmm_n = 'iter' + str(niter)
  458. hmm_n_pre = 'iter' + str(niter-1)
  459. _modeln_dir = os.path.join(output_dir, hmm_n)
  460. _modeln_dir_pre = os.path.join(output_dir, hmm_n_pre)
  461. fh.make_new_directory(_modeln_dir, 'leave')
  462. chtk.re_estimation(
  463. os.path.join(_modeln_dir_pre, 'hmmdefs'),
  464. _modeln_dir,
  465. hcompv_scp_train_updated,
  466. mlf_file=triphone_mlf,
  467. macros=os.path.join(_modeln_dir_pre, 'macros'),
  468. model_type='triphone')
  469. print("elapsed time: {}".format(time.time() - timer_start))