From 3a98e184fea13fd784fdf56a689926d833ea3b70 Mon Sep 17 00:00:00 2001 From: yemaozi88 <428968@gmail.com> Date: Sun, 2 Sep 2018 12:16:37 +0200 Subject: [PATCH] with bug-fixed xsampa->ipa conversion, FA is performed. --- .vs/acoustic_model/v15/.suo | Bin 60416 -> 67072 bytes acoustic_model.sln | 6 +- .../acoustic_model_functions.cpython-36.pyc | Bin 3362 -> 4615 bytes .../convert_xsampa2ipa.cpython-36.pyc | Bin 2324 -> 3195 bytes .../__pycache__/defaultfiles.cpython-36.pyc | Bin 0 -> 612 bytes acoustic_model/acoustic_model.pyproj | 9 +- acoustic_model/acoustic_model_functions.py | 67 ++++- acoustic_model/convert_xsampa2ipa.py | 235 ++++++++------- acoustic_model/defaultfiles.py | 35 +++ acoustic_model/fa_test.py | 16 + acoustic_model/performance_check.py | 282 +++++++----------- acoustic_model/phone_conversion_check.py | 54 ---- 12 files changed, 352 insertions(+), 352 deletions(-) create mode 100644 acoustic_model/__pycache__/defaultfiles.cpython-36.pyc create mode 100644 acoustic_model/defaultfiles.py create mode 100644 acoustic_model/fa_test.py delete mode 100644 acoustic_model/phone_conversion_check.py diff --git a/.vs/acoustic_model/v15/.suo b/.vs/acoustic_model/v15/.suo index 08f86848888a22747bde3877c133438504588205..d7f39204db0df761287424f7fe769c9c8ce6ea6d 100644 GIT binary patch literal 67072 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 delta 7066 zcmeHM3sjV48vegw1_o3FL2ix+sE7zSGZ=!R4uXiHTof(`0%lAXg-s%u z*DbTNCR%hib@tY7*_dRencX(cc3a!iX=^)O^uRgc*_?gepMMZkTsyUUI-S0Ao_R0d z``y3)ec%5ddz0FJ#;YYET1b+l0^|}PNm?*0Uvj(Mtn)fh_?&39svW9Qf73UIeg8G} zT@eetE0yY0b>bh?rONXaanNW0YHo164RSjSWn3YvIH>+~O_>cLT2iEN=yE02&qfUeIj{&-KmVcL6OxE8qZL zr#XJfS-ZhK4(tK;0!M+zfOddeJ^}h9@D%Vg@C@)Qun%|+H~^5#FRY%8{|MoE;7`Dx zffs-mfkVJcfD1SbyaF5nIsk5WLZQsR2L8Arp8`DzyrIZ%g1!ZuR^)d<{{p-xNk+M& zGZ5Yf&H^6*e+B*qd`y$W7R;F08Z>k2^H&p@r{Bfg=3atUHRrpPyw*#Aj zI}{z;I>vNRhrgaW$JjM*L$9UUu?+`9^gsG}>oPTReBg5+o320`fY~Pka=dB-^Cflb z=K4y3U`Hr=Q9;!s5!M0iujaj zW(|5HY!G%2f%btclahzPt_558sW_~n4z#!S419V>I|AKP`ysIBaYw5 z{PX3;@~r8Izk&2Bwa`)bxcUL-Fi4&Q#y}zW!Y)xvT}Aa`6;&_V=7_M}z{DCHMIG9S zXztHlVD0_7NVkc_RGp4Z)S}wQW3q_4((~mVLuF9v$(B<@$NUqhGbi6y+ypI0cJ5E}4wz#k zF62_jWA~_|dmFUp`%3I#CU`WR?FHKL5GHvPw#W1Nv-Ajb`<>@&oSarypFZ3lf4xmW=b^?B`L~m|LnGUm3$AA#!0_0L%t(=rD*b8Nv76D+#arcAShyFRm$LqNgH&@GT6+1P(6+R)iuZDS*QrkmH;X-ZFTB%$r zlcJLD8xpN2iVg906o638rE01ag(EBS%{ZnMzNH9BNuO ziCWeVfkir<`%*`5BzO<8!b6uM)08`+jOiO`ozag9&PLFM7Z-)6NqTtYBqU)LczBCs z#^4tA)g-Jl_S(x-dtF-v*{$}yrbgkYFp>RNCNfp*p_ryfTGcX%_MgwA*v0_IRy*zg zN=^E3GtSBxo z+hD1zT3cR5ZIuSGhf3d@MqBKm1#7M5#F{GedUIlriOo{E47wGp16gmjCatR~FT4Hr zO=zV|-mmRX8XGr{>ducs>2l4nv`C>Wm-&^sCOOLtiAfiI-5@}^rC;C9_*KiIk3mg>b<`~f#%}!>MGmX z;uY)5S6fOk&Kx@MPPW>^5U-Wj*HbcGoDH(a&gy^jC-`aQhXCzz$WU+c?I$S@Nb|{} zJu6kT?fq)!kh|_x1vV?aGT8x)qJY_YGRnEQWSNZw5eT@xl$H^0y8l(v(xZF`V8x1_*(o?cKqKt+_^z8-9op?>3 zBDGUS!hO`77!epXb?NdQ!?v#cx_G?Ndisk732(At&mwHR0pm7I!iH{UAoExPiu_1N zrs*zn<;BsSFT%ty5>54DH;Kp@zdI=61(kmN1ihV{L~k}Mrc37|H7}!=-&1YIc#4UR z=EOjA44S8U0(E#g1zbRm0BSV1JKI-n(Ec2@_>6u;VJo6HY+cXOTqg)z4gf!NOp{#? z-M=yYdjzlRE$Zj+)h9ja4N!7?3cn&g^{>5V^x|mHQ*?HW=VA!iA#i#`{=nbIqlz*K%g4_45cVC(?T>zz4Jbrx4Gy zbW3AQz=zMr&D@v$?#sQAxux;9BXXo7eDzJji$EOj1?3dF341Ub z&yWN33CN%0nffK#-|XLGcPl8{(c)jn&yXbkg0&_T-??E@2Ab1n%LdY;Nl&2z?!#m^ pejL~kvu#-HQ?)N0df?LD{b%m}Mn1OXrci1zMpNaNrk~JK{sV{%A$b4* diff --git a/acoustic_model.sln b/acoustic_model.sln index 1eca07a..ecdeaf9 100644 --- a/acoustic_model.sln +++ b/acoustic_model.sln @@ -9,14 +9,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject ..\forced_alignment\forced_alignment\__init__.py = ..\forced_alignment\forced_alignment\__init__.py ..\forced_alignment\forced_alignment\convert_phone_set.py = ..\forced_alignment\forced_alignment\convert_phone_set.py - ..\ipa-xsama-converter\converter.py = ..\ipa-xsama-converter\converter.py - ..\forced_alignment\forced_alignment\defaultfiles.py = ..\forced_alignment\forced_alignment\defaultfiles.py + ..\toolbox\evaluation.py = ..\toolbox\evaluation.py ..\forced_alignment\forced_alignment\forced_alignment.pyproj = ..\forced_alignment\forced_alignment\forced_alignment.pyproj - ..\forced_alignment\forced_alignment\htk_dict.py = ..\forced_alignment\forced_alignment\htk_dict.py ..\forced_alignment\forced_alignment\lexicon.py = ..\forced_alignment\forced_alignment\lexicon.py ..\forced_alignment\forced_alignment\mlf.py = ..\forced_alignment\forced_alignment\mlf.py - ..\accent_classification\accent_classification\output_confusion_matrix.py = ..\accent_classification\accent_classification\output_confusion_matrix.py ..\forced_alignment\forced_alignment\pronunciations.py = ..\forced_alignment\forced_alignment\pronunciations.py + ..\toolbox\pyHTK.py = ..\toolbox\pyHTK.py ..\forced_alignment\forced_alignment\pyhtk.py = ..\forced_alignment\forced_alignment\pyhtk.py ..\forced_alignment\forced_alignment\scripts.py = ..\forced_alignment\forced_alignment\scripts.py ..\forced_alignment\forced_alignment\tempfilename.py = ..\forced_alignment\forced_alignment\tempfilename.py diff --git a/acoustic_model/__pycache__/acoustic_model_functions.cpython-36.pyc b/acoustic_model/__pycache__/acoustic_model_functions.cpython-36.pyc index 99ef1fa1494729ba8ab09edd98170be0e7edef36..3ff968422062f223c00c69ce5bffdb0b149c2db2 100644 GIT binary patch delta 2465 zcmZ`*&5s<#74Pcr?&euJSTXS>%=jHwP*H$#`KibTr!}#a$7JmT2G)7V_oN5vhnCq$DH$sC<*UZqW zZS2sgwHtbz^!#3fd%a*nYAYk1>(7VtFgBTWUkewQ&2Bm{SY$5qKrb<$H9#-3fX#tE z#^%`q=oPlemOwwnmf11T#~FEBYpy(m#I##YqMU2_Fq2&TdW!UKQNDc+Z)v)?nzj$1E-6Z8%)aM=LJ{qd(MdOcTzWST-=VvW&E?g959mZ68 zUMMF`3JFexk2?$1XXbhP7!IGR{uLan{%g*UDNGCeP}6-qAU+Y#z&J)P_{_mO5AQX2 zi&dg&rPk9X+Q=*oM)q`ZTaun$k_j1E(kOMNPxRlfkL>-^rFC8V@c76n?Vibuo>iKq zGtm*-k1lL$+kom@+HLKN$ukOT zNtDSAn(epf`RzAvU#FMk<2Fs2u}FyMVAdZdc0C!#ZJH0|U??%&I@?*J=~hP`40xM9 z-|i06^a9;%7ZPF@GKq@|wAJnk{?U+U@d16Q^(^I?6bT$T5}XR&&+l@!LATm6AJDB0 zTAx+`Oq#%wJsi6qKR@z5-W>V2gaZo?84BD#T$%2)H(Fh=Xu-QR@*iTOHyg?t4hCE( zJsT){m?aSZsK#Mi*#K@ok^*g&Q4IUaz8j@OUZ_StFJvdq`~5sqRwDVhUo_{GiO4JW z5yZ-wf)lI83;@bRaFugprARk42Y|jJvGQatqqLJjC}WQwD65XAe8@2dK%yNkPCznK zv5INASRx&^mBdY$7V981&(&Qr?ZUG#3gFKrD`Zt)CIQS>VdfHXxpJ+4KZgw}JQQmn zZZ)mx`5U+rfPiyzDdwvsdnH)Hxs@gvAW&`EFO!>9Za+h=RKKUi@j3 zh@as1HHCcV{CmCyGJ>)rxPpu|9r0rAf3TZpTwpBG1_6}1FGUnf&csV-U?Ol&!r)hb zcYN}G^$%x_T&=!!zPcn35AiYx;7SWAub7s~V>y09sIW0gb<$hEg!HD2!(Po+JpuDJnn`cS3bE8JGX+phajPEOZmq(0?8fv_yLDPNW?!*mnBwhod z>^RTjNLHUTuAM<>L%Y7l%_H3k&6MwN*0L2=dT@^1tDXzi#&3gdjBSJu0)>T9lXw>f z5@?(epz75TDM^n2q3fmIL;5Bo9mv_J$ywXcM#la|sRN6y1Ld1N9W0UPfrFX3XNp#7 z^vu#?)=6M(p!ODgYXhB*jS2qfIfv=A;o-zo?jj)+!*oiDH18q-A`!;Ghf$jBWPRwB zDgDUZq@Z13xtinhEImL%+(Rbi8BH=IEU^$^r@*9Eh`MVh{XsSr=)&~ino+8;nByZMGcKSIRruDxOYH?<_-mJSsoPprT+ny&ukq4 delta 1229 zcmZ`&&2QX96rb_e+FtKRwrxVHmLz2p;95^D4!~r<<02gkY`o;+eQenxz_c8OHpMSrZXWcJP z?_X*({A;W-gG(W>(~Ix>MV6 zIYIO)^mT@jMRGv7ePA3=N{;q8+Gn>3v(x${hyn~8R{NAh4dyZrZIk(|j<&@D)moy#?7n!j|2zNzpR6l%zb1Cw!pXzuidwWPDCLa$CAJ1nuQcU**80^` z+MU<1@DIF!o@z|uT|UswbyXKr!bKp4Zv@n*a8|zS{`!G#4?6#nBHRt_!`{A5*AbM7 ze*h>h2^|%rd@mX1S=ALz=w&-iGA<%H_O35&VnUomAZDAo_znH~G@xxdPhm~I@LupY zadl=-%hBeQkirs1hksbj0LvJ^HbV7v<-|q7GZxn19Bzv2Vw`8ZngQOzg!1@a3GuMx z47&1nzq@h`vqBR?3_Z^7H!*y8pji9d^Jfr0@cohoPa2Po63-7DMDH$sXUT_{3vl zCmG{=${F*Rai|E_k`|$ROlY`>jbIBwIVkZkF6EESn=4x6$f-o$I;CTepTXvKuh;oz z@Z|H+F(H4FgBF1OF1(clkR&0JN>`kp1s_dMag50X%^S!)(44j8L&)|PzBwv^(& zpy%!;3g zJ=y&c{yX+R_-6Eaj0U#dG&=92@i!H=1zv4?_gnPA z*-K~+5W4=T>g%d*RZc2v?KPMgb?psYy@?=p!}#sN%Sdd^v&BM5dxG;GUfDg4&o{SW zoHGDycuolKd+=5kU_#dH(WxUVvZe2nFK({6qbt4zeJ%pqU$Gg(5hV}$_mLX_m(PL~ zU9l|#{`GaZ3V=gq;R>Ecs|R=Q6A3!5f-PO&3xE(wE`u#wgAEFW%TFjF&*e*uZ8;Z@ zs%*Z!4LK`J6t#(csq0N5ftm8d=Tsn0i#dv9Q2Quw7 zN5zCJRV7U6#ARtO#N||(|D?O+3q+g6(g|I`VH+UHCPIwjmgjqt4?~;0SW56W93GN} z&z=rNW~3NSptru{Dh=8ysK8QurG(VuF$|5{$894}$+iKODB`oHHJyy&I@lDtay2iM zv9BV710;j_vT!=hrk2&gTTkSP*ol6NA?O5{N2!T5<}c&Dz&wk2m29T*q$O_h5IuOB5XbYSg7N7 c=A~Q~>MmZif*%wKXp9ew>3|;b_``VgFVO%fEC2ui delta 372 zcmew@F-0iCn3tE!;P1~UM;-=-#|%h-3CMN;;$j0Jk-`wgkiwY4l*1Us2&S2$n7}l1 z6mtr53QG$^6iW(g3LB7SO<@XV&}5(3Gjp>KV=@zCz~l|gB8;4qPcU1tbKYXkEJ%#n z%)`RT#0#?E7IRr*&Ps+N#mP!+^B9#UA7tAn(apt~oS#>gT2!2wpQp#g=~$FrY{kXN zIe9U=0TYnA&F;v}`HNAZh#6==5!+-f4p%)%5K|OHaDYuMt}MRAR$P*jT2xdd2o%xe zE)oODih~H*$#XfZC1iliD7M_hf`ZhPB1Momm{6Mhfx|IUAIR5ayTu+KpOT*(A73N{ ulGg+g+#o_3M1a&FX@uwoirwO{$<0qG%}KRm1@elyfCLL82MDrrcmn|Rq)wOs diff --git a/acoustic_model/__pycache__/defaultfiles.cpython-36.pyc b/acoustic_model/__pycache__/defaultfiles.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5dbcde73aa1d335c81a17b3bf8821acb23eb041b GIT binary patch literal 612 zcmZ9J&u`N(6vv&^ZIf;-MZg5&I4(Oh7k(TNLZETrFfoY6LoaUsZDp>M+w)Oo!zmNTVJRbd8{kVQKMCcYBjDcIfbJI{4IO1M`2;x5R z0L}e*4?N!Ec+(@8_epE0TDrI26qwQ8E=-eZ0-l$FIUd{lrxp`f)!lM ztghsOLS|^nTtnt1O_VMxQ$I@%^q;{1(@9Qsl~Guipha8MkRa6pj9`*X{^h7o%3Mh( zgt75oO=Q>h?5OdTA*1a(#9ZhGm(1o3o+}~Ajyld)j+z85VXGmJ9c0`>y0oY4+)w`} zZQrpfptA)nRJXc!&~@hv_x=4uI&}Zjg+KQr${}S{VN+3niOQQMc(bke)^jQ|bs@mG OH+_h`i8t}Fhy6PP55{f) literal 0 HcmV?d00001 diff --git a/acoustic_model/acoustic_model.pyproj b/acoustic_model/acoustic_model.pyproj index 74793ee..7a2f4b5 100644 --- a/acoustic_model/acoustic_model.pyproj +++ b/acoustic_model/acoustic_model.pyproj @@ -4,7 +4,7 @@ 2.0 4d8c8573-32f0-4a62-9e62-3ce5cc680390 . - phone_conversion_check.py + performance_check.py . @@ -28,10 +28,13 @@ Code - + Code - + + Code + + Code diff --git a/acoustic_model/acoustic_model_functions.py b/acoustic_model/acoustic_model_functions.py index 04e19c3..bde97be 100644 --- a/acoustic_model/acoustic_model_functions.py +++ b/acoustic_model/acoustic_model_functions.py @@ -1,17 +1,13 @@ import os import sys +from collections import Counter +import numpy as np import pandas as pd +import defaultfiles as default -## ======================= user define ======================= -repo_dir = 'C:\\Users\\Aki\\source\\repos\\acoustic_model' -curr_dir = repo_dir + '\\acoustic_model' -forced_alignment_module = 'C:\\Users\\Aki\\source\\repos\\forced_alignment' - - -sys.path.append(os.path.join(os.path.dirname(sys.path[0]), curr_dir)) -sys.path.append(forced_alignment_module) +sys.path.append(default.forced_alignment_module_dir) from forced_alignment import convert_phone_set @@ -42,6 +38,41 @@ def make_filelist(input_dir, output_txt): fout.write(input_dir + '\\' + filename + '\n') +def make_dic(word, pronvar_, fileDic, output_type): + """ + make dict files which can be used for HTK. + param word: target word. + param pronvar_: pronunciation variant. nx2 (WORD /t pronunciation) ndarray. + param fileDic: output dic file. + param output_type: 0:full, 1:statistics, 2:frequency <2% entries are removed. 3:top 3. + """ + #assert(output_type < 4 and output_type >= 0, 'output_type should be an integer between 0 and 3.') + WORD = word.upper() + + if output_type == 0: # full + pronvar = np.unique(pronvar_) + + with open(fileDic, 'w') as f: + for pvar in pronvar: + f.write('{0}\t{1}\n'.format(WORD, pvar)) + else: + c = Counter(pronvar_) + total_num = sum(c.values()) + with open(fileDic, 'w') as f: + if output_type == 3: + for key, value in c.most_common(3): + f.write('{0}\t{1}\n'.format(WORD, key)) + else: + for key, value in c.items(): + percentage = value/total_num*100 + + if output_type == 1: # all + f.write('{0}\t{1:.2f}\t{2}\t{3}\n'.format(value, percentage, WORD, key)) + elif output_type == 2: # less than 2 percent + if percentage < 2: + f.write('{0}\t{1}\n'.format(WORD, key)) + + def get_phonelist(lexicon_file): """ Make a list of phones which appears in the lexicon. """ @@ -99,4 +130,22 @@ def combine_lexicon(lexicon_file1, lexicon_file2, lexicon_out): lex2 = pd.read_table(lexicon_file2, names=['word', 'pronunciation']) lex = pd.concat([lex1, lex2]) lex = lex.sort_values(by='word', ascending=True) - lex.to_csv(lexicon_out, index=False, header=False, encoding="utf-8", sep='\t') \ No newline at end of file + lex.to_csv(lexicon_out, index=False, header=False, encoding="utf-8", sep='\t') + + +def read_fileFA(fileFA): + """ + read the result file of HTK forced alignment. + this function only works when input is one word. + """ + with open(fileFA, 'r') as f: + lines = f.read() + lines = lines.split('\n') + + phones = [] + for line in lines: + line_split = line.split() + if len(line_split) > 1: + phones.append(line_split[2]) + + return ' '.join(phones) diff --git a/acoustic_model/convert_xsampa2ipa.py b/acoustic_model/convert_xsampa2ipa.py index 933b960..f1ca96a 100644 --- a/acoustic_model/convert_xsampa2ipa.py +++ b/acoustic_model/convert_xsampa2ipa.py @@ -7,122 +7,155 @@ import json import sys import os - -#sys.path.append(ipa_xsampa_converter_dir) -#import converter +import defaultfiles as default +sys.path.append(os.path.join(default.repo_dir, 'forced_alignment')) +from forced_alignment import convert_phone_set def load_converter(source, sink, ipa_xsampa_converter_dir): - """load the converter. - source and sink are either of "ipa", "xsampa" or "sassc". - """ - choices = ["ipa", "xsampa", "sassc"] + """load the converter. + source and sink are either of "ipa", "xsampa" or "sassc". + """ + choices = ["ipa", "xsampa", "sassc"] - # Validate params - try: - choice1 = choices.index(source) - choice2 = choices.index(sink) - if choice1 == choice2: - print("source and destination format are the same.") - except ValueError: - print("source and destination should be one of [ipa xsampa sassc].") - exit(1) - - # Mappings from disk - # some may not be used if source or sink is already IPA - source_to_ipa = {} - ipa_to_sink = {} + # Validate params + try: + choice1 = choices.index(source) + choice2 = choices.index(sink) + if choice1 == choice2: + print("source and destination format are the same.") + except ValueError: + print("source and destination should be one of [ipa xsampa sassc].") + exit(1) + + # Mappings from disk + # some may not be used if source or sink is already IPA + source_to_ipa = {} + ipa_to_sink = {} - ipa_xsampa = [] - sassc_ipa = [] + ipa_xsampa = [] + sassc_ipa = [] - # The IPAs that actually occur within SASSC - sassc_active_ipa = {} + # The IPAs that actually occur within SASSC + sassc_active_ipa = {} - script_dir = os.path.dirname(os.path.realpath(__file__)) + script_dir = os.path.dirname(os.path.realpath(__file__)) - with open(os.path.join(ipa_xsampa_converter_dir, "ipa_xsampa_map.json"), encoding="utf-8") as f: - ipa_xsampa = json.load(f) + with open(os.path.join(ipa_xsampa_converter_dir, "ipa_xsampa_map.json"), encoding="utf-8") as f: + ipa_xsampa = json.load(f) - sassc_active = source == "sassc" or sink == "sassc" - if sassc_active: - with open(os.path.join(script_dir, "./sassc_ipa.json")) as f: - sassc_ipa = json.load(f) - for pair in sassc_ipa: - for char in pair[1]: - sassc_active_ipa[char] = 1 + sassc_active = source == "sassc" or sink == "sassc" + if sassc_active: + with open(os.path.join(script_dir, "./sassc_ipa.json")) as f: + sassc_ipa = json.load(f) + for pair in sassc_ipa: + for char in pair[1]: + sassc_active_ipa[char] = 1 - if source == "xsampa": - for pair in ipa_xsampa: - source_to_ipa[pair[1]] = pair[0] - elif source == "sassc": - for pair in sassc_ipa: - source_to_ipa[pair[0]] = pair[1] + if source == "xsampa": + for pair in ipa_xsampa: + source_to_ipa[pair[1]] = pair[0] + elif source == "sassc": + for pair in sassc_ipa: + source_to_ipa[pair[0]] = pair[1] - if sink == "xsampa": - for pair in ipa_xsampa: - ipa_to_sink[pair[0]] = pair[1] - elif sink == "sassc": - for pair in sassc_ipa: - ipa_to_sink[pair[1]] = pair[0] + if sink == "xsampa": + for pair in ipa_xsampa: + ipa_to_sink[pair[0]] = pair[1] + elif sink == "sassc": + for pair in sassc_ipa: + ipa_to_sink[pair[1]] = pair[0] - # Combine them into a single mapping - mapping = {} - if source == "ipa": - mapping = ipa_to_sink - elif sink == "ipa": - mapping = source_to_ipa - else: - for k, ipas in source_to_ipa.iteritems(): - map_out = "" - failed = False - for ipa in ipas: - val = ipa_to_sink.get(ipa) - if not val: - failed = True - break - map_out += val - mapping[k] = map_out if not failed else None + # Combine them into a single mapping + mapping = {} + if source == "ipa": + mapping = ipa_to_sink + elif sink == "ipa": + mapping = source_to_ipa + else: + for k, ipas in source_to_ipa.iteritems(): + map_out = "" + failed = False + for ipa in ipas: + val = ipa_to_sink.get(ipa) + if not val: + failed = True + break + map_out += val + mapping[k] = map_out if not failed else None - return mapping + return mapping def conversion(source, sink, mapping, line): - """ - conversion. - Args: - mapping: can be obtained with load_converter(). - line: must be seperated, by default the seperator is whitespace. - """ + """ + conversion. + Args: + mapping: can be obtained with load_converter(). + line: must be seperated, by default the seperator is whitespace. + """ - # Edit this to change the seperator - SEPERATOR = " " + # Edit this to change the seperator + SEPERATOR = " " - line = line.strip() - output = [] - #if sassc_active: - # tokens = line.split(SEPERATOR) - #else: - tokens = line - for token in tokens: - if token.isspace(): - output.append(token) - continue - # Remove extraneous chars that IPA does not accept - if sink == "sassc": - cleaned_token = u"" - for char in token: - if sassc_active_ipa.get(char): - cleaned_token += char - token = cleaned_token - mapped = mapping.get(token) - if not mapped: - print("WARNING: could not map token ", token, file=sys.stderr) - else: - output.append(mapped) - #if sassc_active: - # output = SEPERATOR.join(output) - #else: - output = "".join(output) - - return output \ No newline at end of file + line = line.strip() + output = [] + #if sassc_active: + # tokens = line.split(SEPERATOR) + #else: + tokens = line + for token in tokens: + if token.isspace(): + output.append(token) + continue + # Remove extraneous chars that IPA does not accept + if sink == "sassc": + cleaned_token = u"" + for char in token: + if sassc_active_ipa.get(char): + cleaned_token += char + token = cleaned_token + mapped = mapping.get(token) + if not mapped: + print("WARNING: could not map token ", token, file=sys.stderr) + else: + output.append(mapped) + #if sassc_active: + # output = SEPERATOR.join(output) + #else: + output = "".join(output) + + return output + + +def xsampa2ipa(mapping, xsampa): + """ + conversion from xsampa to ipa. + + Args: + mapping: can be obtained with load_converter(). + xsampa: a line written in xsampa. + + Notes: + function conversion does not work when: + - the input is a word. + - when the line includes '\'. + - 'ɡ' and 'g' are considered to be different. + + """ + # make a multi_character_list to split 'xsampa'. + multi_character_list = [] + for i in list(mapping): + if len(i) > 1: + multi_character_list.append(i) + + # conversion + ipa = [] + for phone in convert_phone_set.multi_character_tokenize(xsampa, multi_character_list): + ipa.append(mapping.get(phone, phone)) + ipa = ''.join(ipa) + + # strange conversion. + ipa = ipa.replace('ɡ', 'g') + + return ipa \ No newline at end of file diff --git a/acoustic_model/defaultfiles.py b/acoustic_model/defaultfiles.py new file mode 100644 index 0000000..7437cd9 --- /dev/null +++ b/acoustic_model/defaultfiles.py @@ -0,0 +1,35 @@ +import os + +#default_hvite_config = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data', 'htk', 'config.HVite') + +cygwin_dir = r'C:\cygwin64\home\Aki\acoustic_model' +#config_hcopy = os.path.join(cygwin_dir, 'config', 'config.HCopy') +#config_train = os.path.join(cygwin_dir, 'config', 'config.train') +config_hvite = os.path.join(cygwin_dir, 'config', 'config.HVite') +#mkhmmdefs_pl = os.path.join(cygwin_dir, 'src', 'acoustic_model', 'mkhmmdefs.pl') + +#dbLexicon = C:\\Users\\Aki\\source\\repos\\rug_VS\\forced_alignment\\config\\lexicon.accdb +#scriptBarbara = C:\\Users\\Aki\\source\\repos\\rug_VS\\forced_alignment\\config\\pronvars_barbara.perl +#exeG2P = C:\\Users\\Aki\\source\\repos\\rug_VS\\forced_alignment\\config\\string2phon.exe + +#[pyHTK] +#configHVite = C:\\Users\\Aki\\source\\repos\\rug_VS\\forced_alignment\\config\\config.HVite +#filePhoneList = C:\\Users\\Aki\\source\\repos\\rug_VS\\forced_alignment\\config\\phonelist_barbara.txt +#AcousticModel = C:\\Users\\Aki\\source\\repos\\rug_VS\\forced_alignment\\config\\hmmdefs_16-2_barbara.compo + +#dbLexicon = config['cLexicon']['dbLexicon'] +#scriptBarbara = config['cLexicon']['scriptBarbara'] +#exeG2P = config['cLexicon']['exeG2P'] + +#configHVite = config['pyHTK']['configHVite'] +#filePhoneList = config['pyHTK']['filePhoneList'] +#AcousticModel = config['pyHTK']['AcousticModel'] + +repo_dir = r'C:\Users\Aki\source\repos' +ipa_xsampa_converter_dir = os.path.join(repo_dir, 'ipa-xsama-converter') +forced_alignment_module_dir = os.path.join(repo_dir, 'forced_alignment') + +fame_dir = r'C:\OneDrive\WSL\kaldi-trunk\egs\fame\s5\corpus' +experiments_dir = r'c:\OneDrive\Research\rug\experiments' + +phonelist = os.path.join(experiments_dir, 'friesian', 'acoustic_model', 'config', 'phonelist_friesian.txt') \ No newline at end of file diff --git a/acoustic_model/fa_test.py b/acoustic_model/fa_test.py new file mode 100644 index 0000000..3a1bb08 --- /dev/null +++ b/acoustic_model/fa_test.py @@ -0,0 +1,16 @@ +import os +import sys +os.chdir(r'C:\Users\Aki\source\repos\acoustic_model\acoustic_model') + +import defaultfiles as default + +sys.path.append(os.path.join(default.repo_dir, 'forced_alignment')) +from forced_alignment import forced_alignment + +wav_file = r'C:\Users\Aki\source\repos\forced_alignment\notebooks\sample\10147-1464186409-1917281.wav' +forced_alignment( + wav_file, + #'Australië' + 'BUFFETCOUPON COULISSEN DOUANE' + ) + diff --git a/acoustic_model/performance_check.py b/acoustic_model/performance_check.py index 0738ab9..e3d9820 100644 --- a/acoustic_model/performance_check.py +++ b/acoustic_model/performance_check.py @@ -1,255 +1,176 @@ import os +os.chdir(r'C:\Users\Aki\source\repos\acoustic_model\acoustic_model') + import sys import csv import subprocess -import configparser from collections import Counter import re import numpy as np import pandas as pd import matplotlib.pyplot as plt -from sklearn.metrics import confusion_matrix +#from sklearn.metrics import confusion_matrix - -## ======================= functions ======================= - -def read_fileFA(fileFA): - """ - read the result file of HTK forced alignment. - this function only works when input is one word. - """ - with open(fileFA, 'r') as f: - lines = f.read() - lines = lines.split('\n') - - phones = [] - for line in lines: - line_split = line.split() - if len(line_split) > 1: - phones.append(line_split[2]) - - return ' '.join(phones) - - -def make_dic(word, pronvar_, fileDic, output_type): - """ - make dict files which can be used for HTK. - param word: target word. - param pronvar_: pronunciation variant. nx2 (WORD /t pronunciation) ndarray. - param fileDic: output dic file. - param output_type: 0:full, 1:statistics, 2:frequency <2% entries are removed. 3:top 3. - """ - #assert(output_type < 4 and output_type >= 0, 'output_type should be an integer between 0 and 3.') - - if output_type == 0: # full - pronvar = np.unique(pronvar_) - - with open(fileDic, 'w') as f: - for pvar in pronvar: - f.write('{0}\t{1}\n'.format(WORD, pvar)) - else: - c = Counter(pronvar_) - total_num = sum(c.values()) - with open(fileDic, 'w') as f: - if output_type == 3: - for key, value in c.most_common(3): - f.write('{0}\t{1}\n'.format(WORD, key)) - else: - for key, value in c.items(): - percentage = value/total_num*100 - - if output_type == 1: # all - f.write('{0}\t{1:.2f}\t{2}\t{3}\n'.format(value, percentage, WORD, key)) - elif output_type == 2: # less than 2 percent - if percentage < 2: - f.write('{0}\t{1}\n'.format(WORD, key)) +import acoustic_model_functions as am_func +import convert_xsampa2ipa +import defaultfiles as default ## ======================= user define ======================= -curr_dir = r'C:\Users\Aki\source\repos\acoustic_model\acoustic_model' -config_ini = curr_dir + '\\config.ini' -forced_alignment_module = r'C:\Users\Aki\source\repos\forced_alignment' -forced_alignment_module_old = r'C:\OneDrive\Research\rug\code\forced_alignment\forced_alignment' -ipa_xsampa_converter_dir = r'C:\Users\Aki\source\repos\ipa-xsama-converter' -accent_classification_dir = r'C:\Users\Aki\source\repos\accent_classification\accent_classification' +#curr_dir = r'C:\Users\Aki\source\repos\acoustic_model\acoustic_model' +#config_ini = 'config.ini' +#repo_dir = r'C:\Users\Aki\source\repos' +#forced_alignment_module = repo_dir + '\\forced_alignment' +#forced_alignment_module_old = repo_dir + '\\aki_tools' +#ipa_xsampa_converter_dir = repo_dir + '\\ipa-xsama-converter' +#accent_classification_dir = repo_dir + '\\accent_classification\accent_classification' +excel_file = os.path.join(default.experiments_dir, 'stimmen', 'data', 'Frisian Variants Picture Task Stimmen.xlsx') -experiments_dir = r'C:\OneDrive\Research\rug\experiments' -data_dir = experiments_dir + '\\stimmen\\data' -csvfile = data_dir + '\\Frisian Variants Picture Task Stimmen.csv' +#experiments_dir = r'C:\OneDrive\Research\rug\experiments' +data_dir = os.path.join(default.experiments_dir, 'stimmen', 'data') +#csvfile = data_dir + '\\Frisian Variants Picture Task Stimmen.csv' +wav_dir = os.path.join(default.experiments_dir, 'stimmen', 'wav') +acoustic_model_dir = os.path.join(default.experiments_dir, 'friesian', 'acoustic_model', 'model') +htk_dict_dir = os.path.join(default.experiments_dir, 'stimmen', 'dic_short') +fa_dir = os.path.join(default.experiments_dir, 'stimmen', 'FA') + +#cygwin_dir = r'C:\cygwin64\home\Aki\acoustic_model' +#lex_asr = os.path.join(default.fame_dir, 'lexicon', 'lex.asr') +#lex_asr_htk = os.path.join(default.fame_dir, 'lexicon', 'lex.asr_htk') -cygwin_dir = r'C:\cygwin64\home\Aki\acoustic_model' # procedure -convert_phones = 0 make_dic_files = 0 -make_dic_files_short = 0 -do_forced_alignment_htk = 0 +do_forced_alignment_htk = 1 make_kaldi_data_files = 0 make_kaldi_lexicon_txt = 0 -load_forced_alignment_kaldi = 1 +load_forced_alignment_kaldi = 0 eval_forced_alignment = 0 ## ======================= add paths ======================= -sys.path.append(forced_alignment_module) +sys.path.append(os.path.join(default.repo_dir, 'forced_alignment')) from forced_alignment import convert_phone_set +from forced_alignment import pyhtk -# for interactive window -sys.path.append(curr_dir) -import convert_xsampa2ipa -import acoustic_model_functions as am_func - -# for forced-alignment -sys.path.append(forced_alignment_module_old) -import pyHTK - -# to output confusion matrix -sys.path.append(accent_classification_dir) -from output_confusion_matrix import plot_confusion_matrix - - -## ======================= load variables ======================= -config = configparser.ConfigParser() -config.sections() -config.read(config_ini) - -FAME_dir = config['Settings']['FAME_dir'] - -lex_asr = FAME_dir + '\\lexicon\\lex.asr' -lex_asr_htk = FAME_dir + '\\lexicon\\lex.asr_htk' +sys.path.append(os.path.join(default.repo_dir, 'toolbox')) +#import pyHTK +from evaluation import plot_confusion_matrix ## ======================= convert phones ====================== -if convert_phones: - mapping = convert_xsampa2ipa.load_converter('xsampa', 'ipa', ipa_xsampa_converter_dir) - ## check phones included in FAME! - # the phones used in the lexicon. - #phonelist = am_func.get_phonelist(lex_htk) +mapping = convert_xsampa2ipa.load_converter('xsampa', 'ipa', default.ipa_xsampa_converter_dir) - # the lines which include a specific phone. - #lines = am_func.find_phone(lex_asr, 'x') +xls = pd.ExcelFile(excel_file) - with open(csvfile, encoding="utf-8") as fin: - lines = csv.reader(fin, delimiter=';', lineterminator="\n", skipinitialspace=True) - next(lines, None) # skip the headers +## check conversion +#df = pd.read_excel(xls, 'frequency') +#for xsampa, ipa in zip(df['X-SAMPA'], df['IPA']): +# #ipa_converted = convert_xsampa2ipa.conversion('xsampa', 'ipa', mapping, xsampa_) +# ipa_converted = convert_xsampa2ipa.xsampa2ipa(mapping, xsampa) +# if not ipa_converted == ipa: +# print('{0}: {1} - {2}'.format(xsampa, ipa_converted, ipa)) - filenames = [] - words = [] - pronunciations = [] - for line in lines: - if line[1] is not '' and len(line) > 5: - filenames.append(line[0]) - words.append(line[1]) - pron_xsampa = line[3] - pron_ipa = convert_xsampa2ipa.conversion('xsampa', 'ipa', mapping, pron_xsampa) - pron_ipa = pron_ipa.replace('ː', ':') - pron_famehtk = convert_phone_set.ipa2famehtk(pron_ipa) - - # adjust to phones used in the acoustic model. - pron_famehtk = pron_famehtk.replace('sp', 'sil') - pron_famehtk = pron_famehtk.replace('ce :', 'ce') # because ceh is ignored. - pron_famehtk = pron_famehtk.replace('w :', 'wh') - pron_famehtk = pron_famehtk.replace('e :', 'eh') - pron_famehtk = pron_famehtk.replace('eh :', 'eh') - pron_famehtk = pron_famehtk.replace('ih :', 'ih') - #translation_key = {'sp': 'sil', 'ce :': 'ceh', 'w :': 'wh'} - #pron = [] - #for phoneme in pron_famehtk.split(' '): - # pron.append(translation_key.get(phoneme, phoneme)) - #pronunciations.append(' '.join(pron_famehtk)) - pronunciations.append(pron_famehtk) +## check phones included in FAME! +# the phones used in the lexicon. +#phonelist = am_func.get_phonelist(lex_asr) - # check if all phones are in the phonelist of the acoustic model. - #phonelist = ' '.join(pronunciations) - #np.unique(phonelist.split(' ')) - #phonelist.find(':') +# the lines which include a specific phone. +#lines = am_func.find_phone(lex_asr, 'x') - filenames = np.array(filenames) - words = np.array(words) - pronunciations = np.array(pronunciations) - del line, lines - del pron_xsampa, pron_ipa, pron_famehtk - - np.save(data_dir + '\\filenames.npy', filenames) - np.save(data_dir + '\\words.npy', words) - np.save(data_dir + '\\pronunciations.npy', pronunciations) -else: - filenames = np.load(data_dir + '\\filenames.npy') - words = np.load(data_dir + '\\words.npy') +# Filename, Word, Self Xsampa +df = pd.read_excel(xls, 'original') - pronunciations = np.load(data_dir + '\\pronunciations.npy') -word_list = np.unique(words) +ipas = [] +famehtks = [] +for xsampa in df['Self Xsampa']: + if not isinstance(xsampa, float): # 'NaN' + # typo? + xsampa = xsampa.replace('r2:z@rA:\\t', 'r2:z@rA:t') + xsampa = xsampa.replace(';', ':') + + ipa = convert_xsampa2ipa.xsampa2ipa(mapping, xsampa) + ipa = ipa.replace('ː', ':') + ipa = ipa.replace(' ', '') + ipas.append(ipa) + famehtk = convert_phone_set.ipa2famehtk(ipa) + famehtks.append(famehtk) + else: + ipas.append('') + famehtks.append('') + +# extract interesting cols. +df = pd.DataFrame({'filename': df['Filename'], + 'word': df['Word'], + 'xsampa': df['Self Xsampa'], + 'ipa': pd.Series(ipas), + 'famehtk': pd.Series(famehtks)}) +# cleansing. +df = df[~df['famehtk'].isin(['/', ''])] ## ======================= make dict files used for HTK. ====================== if make_dic_files: - output_type = 2 - output_dir = experiments_dir + r'\stimmen\dic_short' + word_list = np.unique(df['word']) + + output_type = 3 for word in word_list: - WORD = word.upper() - fileDic = output_dir + '\\' + word + '.dic' + htk_dict_file = htk_dict_dir + '\\' + word + '.dic' # pronunciation variant of the target word. - pronvar_ = pronunciations[words == word] - # remove '' - pronvar_ = np.delete(pronvar_, np.where(pronvar_=='')) + pronvar_ = df['famehtk'][df['word'].str.match(word)] # make dic file. - make_dic(word, pronvar_, fileDic, output_type) + am_func.make_dic(word, pronvar_, htk_dict_file, output_type) ## ======================= forced alignment using HTK ======================= if do_forced_alignment_htk: - configHVite = cygwin_dir + r'\config\config.HVite' - filePhoneList = experiments_dir + r'\friesian\acoustic_model\config\phonelist_friesian.txt' - wav_dir = experiments_dir + r'\stimmen\wav' - #hmm_num = 128 - for hmm_num in [1, 2, 4, 8, 16, 32, 64, 128, 256]: + #hmm_num = 2 + for hmm_num in [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]: + hmm_num_str = str(hmm_num) - AcousticModel = experiments_dir + r'\friesian\acoustic_model\model\hmm' + hmm_num_str + r'-2\hmmdefs' + acoustic_model = os.path.join(acoustic_model_dir, 'hmm' + hmm_num_str + r'-2\hmmdefs') predictions = [] - file_num_max = len(filenames) - for i in range(0, file_num_max): - #for i in range(500, 502): - print('=== {0}/{1} ==='.format(i, file_num_max)) - filename = filenames[i] - fileWav = wav_dir + '\\' + filename + for i, filename in enumerate(df['filename']): + print('=== {0}/{1} ==='.format(i, len(df))) + wav_file = os.path.join(wav_dir, filename) - if os.path.exists(fileWav): - word = words[i] + if os.path.exists(wav_file) and i in df['filename'].keys(): + word = df['word'][i] WORD = word.upper() # make label file. - fileLab = wav_dir + '\\' + filename.replace('.wav', '.lab') - with open(fileLab, 'w') as f: + label_file = os.path.join(wav_dir, filename.replace('.wav', '.lab')) + with open(label_file, 'w') as f: lines = f.write(WORD) - fileDic = experiments_dir + r'\stimmen\dic_top3' + '\\' + word + '.dic' - fileFA = experiments_dir + r'\stimmen\FA' + '\\' + filename.replace('.wav', '.txt') + hmm_num_str + htk_dict_file = os.path.join(htk_dict_dir, word + '.dic') + fa_file = os.path.join(fa_dir, filename.replace('.wav', '.txt') + hmm_num_str) + pyhtk.doHVite(wav_file, label_file, htk_dict_file, fa_file, default.config_hvite, default.phonelist, acoustic_model) - pyHTK.doHVite(fileWav, fileLab, fileDic, fileFA, configHVite, filePhoneList, AcousticModel) - prediction = read_fileFA(fileFA) + prediction = am_func.read_fileFA(fa_file) predictions.append(prediction) - os.remove(fileLab) - print('{0}: {1} -> {2}'.format(WORD, pronunciations[i], prediction)) + os.remove(label_file) + print('{0}: {1} -> {2}'.format(WORD, df['famehtk'][i], prediction)) else: predictions.append('') print('!!!!! file not found.') predictions = np.array(predictions) - match = np.c_[words[predictions != ''], pronunciations[predictions != ''], predictions[predictions != '']] - np.save(data_dir + '\\match_hmm' + hmm_num_str + '.npy', match) + #match = np.c_[words[predictions != ''], pronunciations[predictions != ''], predictions[predictions != '']] + np.save(os.path.join(data_dir, 'predictions_hmm' + hmm_num_str + '.npy'), predictions) ## ======================= make files which is used for forced alignment by Kaldi ======================= @@ -392,7 +313,7 @@ if make_kaldi_lexicon_txt: pronvar_list = np.unique(pronvar_list_) for pronvar_ in pronvar_list: - split_ipa = convert_phone_set.split_ipa_fame(pronvar_) + split_ipa = convert_phone_set.split_fame_ipa(pronvar_) pronvar_out = ' '.join(split_ipa) pronvar_list_all.append([word, pronvar_out]) @@ -456,13 +377,12 @@ if load_forced_alignment_kaldi: filename_ = filename # correct or not. - for filename, fa_pronunciation in zip(fa_filenames, fa_pronunciations): + #for filename, fa_pronunciation in zip(fa_filenames, fa_pronunciations): ## ======================= evaluate the result of forced alignment ======================= if eval_forced_alignment: - match_num = [] for hmm_num in [1, 2, 4, 8, 16, 32, 64, 128, 256]: #hmm_num = 256 diff --git a/acoustic_model/phone_conversion_check.py b/acoustic_model/phone_conversion_check.py deleted file mode 100644 index 743cdd0..0000000 --- a/acoustic_model/phone_conversion_check.py +++ /dev/null @@ -1,54 +0,0 @@ -import os -os.chdir(r'C:\Users\Aki\source\repos\acoustic_model\acoustic_model') - -import sys - -import pandas as pd - - -## ======================= user define ======================= - -forced_alignment_module = r'C:\Users\Aki\source\repos\forced_alignment' -ipa_xsampa_converter_dir = r'C:\Users\Aki\source\repos\ipa-xsama-converter' - -experiments_dir = r'c:\OneDrive\Research\rug\experiments' -excel_file = experiments_dir + '\\stimmen\\data\\Frisian Variants Picture Task Stimmen.xlsx' - - -## ======================= add paths ======================= - -sys.path.append(forced_alignment_module) -from forced_alignment import convert_phone_set - -import convert_xsampa2ipa - - -xls = pd.ExcelFile(excel_file) -df = pd.read_excel(xls, 'frequency') - -mapping = convert_xsampa2ipa.load_converter('xsampa', 'ipa', ipa_xsampa_converter_dir) - -def xsampa2ipa(mapping, xsampa): - # make a multi_character_list to split 'xsampa'. - multi_character_list = [] - for i in list(mapping): - if len(i) > 1: - multi_character_list.append(i) - - # conversion - ipa = [] - for phone in convert_phone_set.multi_character_tokenize(xsampa, multi_character_list): - ipa.append(mapping.get(phone, phone)) - ipa = ''.join(ipa) - - # strange conversion. - ipa = ipa.replace('ɡ', 'g') - - return ipa - - -for xsampa, ipa in zip(df['X-SAMPA'], df['IPA']): - #ipa_converted = convert_xsampa2ipa.conversion('xsampa', 'ipa', mapping, xsampa_) - ipa_converted = xsampa2ipa(mapping, xsampa) - if not ipa_converted == ipa: - print('{0}: {1} - {2}'.format(xsampa_, ipa_converted, ipa)) \ No newline at end of file