31 vector<vector<StdArc::Label> > *path,
32 vector<StdArc::Weight> *weight,
34 vector<StdArc::Label> cur_path,
36 if (proxy.Final(cur_state) != StdArc::Weight::Zero()) {
38 cur_weight =
Times(proxy.Final(cur_state), cur_weight);
39 path->push_back(cur_path);
40 weight->push_back(cur_weight);
44 for (ArcIterator<StdFst> aiter(proxy, cur_state);
45 !aiter.Done(); aiter.Next()) {
46 const StdArc &arc = aiter.Value();
48 cur_path.push_back(arc.ilabel);
50 arc.nextstate, cur_path, temp_weight);
58 int main(
int argc,
char *argv[]) {
60 using namespace kaldi;
65 typedef kaldi::uint64 uint64;
70 "Convert the keywords into in-vocabulary words using the given phone\n" 71 "level edit distance fst (E.fst). The large lexicon (L2.fst) and\n" 72 "inverted small lexicon (L1'.fst) are also expected to be present. We\n" 73 "actually use the composed FST L2xE.fst to be more efficient. Ideally\n" 74 "we should have used L2xExL1'.fst but this is quite computationally\n" 75 "expensive at command level. Keywords.int is in the transcription\n" 76 "format. If kwlist-wspecifier is given, the program also prints out\n" 77 "the proxy fst in a format where each line is \"kwid weight proxy\".\n" 79 "Usage: generate-proxy-keywords [options] <L2xE.fst> <L1'.fst> \\\n" 80 " <keyword-rspecifier> <proxy-wspecifier> [kwlist-wspecifier] \n" 81 " e.g.: generate-proxy-keywords L2xE.fst L1'.fst ark:keywords.int \\\n" 82 " ark:proxy.fsts [ark,t:proxy.kwlist.txt]\n";
86 int32 max_states = 100000;
87 int32 phone_nbest = 50;
88 int32 proxy_nbest = 100;
89 double phone_beam = 5;
90 double proxy_beam = 5;
91 po.
Register(
"phone-nbest", &phone_nbest,
"Prune KxL2xE transducer to only " 92 "contain top n phone sequences, -1 means all sequences.");
93 po.
Register(
"proxy-nbest", &proxy_nbest,
"Prune KxL2xExL1' transducer to " 94 "only contain top n proxy keywords, -1 means all proxies.");
95 po.
Register(
"phone-beam", &phone_beam,
"Prune KxL2xE transducer to the " 96 "given beam, -1 means no prune.");
97 po.
Register(
"proxy-beam", &proxy_beam,
"Prune KxL2xExL1' transducer to the " 98 "given beam, -1 means no prune.");
99 po.
Register(
"max-states", &max_states,
"Prune kxL2xExL1' transducer to the " 100 "given number of states, 0 means no prune.");
105 if (phone_nbest != -1 && phone_nbest <= 0) {
106 KALDI_ERR <<
"--phone-nbest must either be -1 or positive.";
109 if (proxy_nbest != -1 && proxy_nbest <= 0) {
110 KALDI_ERR <<
"--proxy-nbest must either be -1 or positive.";
113 if (phone_beam != -1 && phone_beam < 0) {
114 KALDI_ERR <<
"--phone-beam must either be -1 or non-negative.";
117 if (proxy_beam != -1 && proxy_beam <=0) {
118 KALDI_ERR <<
"--proxy-beam must either be -1 or non-negative.";
127 std::string L2xE_filename = po.
GetArg(1),
128 L1_filename = po.
GetArg(2),
129 keyword_rspecifier = po.
GetArg(3),
130 proxy_wspecifier = po.
GetArg(4),
141 for (; !keyword_reader.
Done(); keyword_reader.
Next()) {
142 std::string key = keyword_reader.
Key();
143 std::vector<int32> keyword = keyword_reader.
Value();
148 VectorFst<StdArc> proxy;
149 VectorFst<StdArc> tmp_proxy;
154 ArcSort(&proxy, OLabelCompare<StdArc>());
155 Compose(proxy, *L2xE, &tmp_proxy);
158 KALDI_VLOG(1) <<
"Project(KxL2xE, PROJECT_OUTPUT)";
159 Project(&tmp_proxy, PROJECT_OUTPUT);
160 if (phone_beam >= 0) {
161 KALDI_VLOG(1) <<
"Prune(KxL2xE, " << phone_beam <<
")";
162 Prune(&tmp_proxy, phone_beam);
164 if (phone_nbest > 0) {
165 KALDI_VLOG(1) <<
"ShortestPath(KxL2xE, " << phone_nbest <<
")";
166 RmEpsilon(&tmp_proxy);
167 ShortestPath(tmp_proxy, &proxy, phone_nbest,
true,
true);
168 tmp_proxy.DeleteStates();
170 Determinize(proxy, &tmp_proxy);
171 proxy.DeleteStates();
175 tmp_proxy.DeleteStates();
176 ArcSort(&proxy, OLabelCompare<StdArc>());
181 ArcSort(&proxy, OLabelCompare<StdArc>());
182 if (proxy_beam >= 0) {
187 ComposeFst<StdArc> lazy_compose(proxy, *L1);
188 proxy.DeleteStates();
190 KALDI_VLOG(1) <<
"Project(KxL2xExL1', PROJECT_OUTPUT)";
191 ProjectFst<StdArc> lazy_project(lazy_compose, PROJECT_OUTPUT);
195 KALDI_VLOG(1) <<
"Prune(KxL2xExL1', " << proxy_beam <<
")";
196 PruneSpecial(lazy_project, &tmp_proxy, proxy_beam, max_states);
200 Compose(proxy, *L1, &tmp_proxy);
201 proxy.DeleteStates();
203 KALDI_VLOG(1) <<
"Project(KxL2xExL1', PROJECT_OUTPUT)";
204 Project(&tmp_proxy, PROJECT_OUTPUT);
206 if (proxy_nbest > 0) {
207 KALDI_VLOG(1) <<
"ShortestPath(KxL2xExL1', " << proxy_nbest <<
")";
209 tmp_proxy.DeleteStates();
211 ShortestPath(proxy, &tmp_proxy, proxy_nbest,
true,
true);
212 proxy.DeleteStates();
215 RmEpsilon(&tmp_proxy);
217 Determinize(tmp_proxy, &proxy);
218 tmp_proxy.DeleteStates();
219 KALDI_VLOG(1) <<
"ArcSort(KxL2xExL1', OLabel)";
220 ArcSort(&proxy, fst::OLabelCompare<StdArc>());
223 proxy_writer.
Write(key, proxy);
227 if (proxy.Properties(kAcyclic,
true) == 0) {
228 KALDI_WARN <<
"Proxy FST has cycles, skip printing paths for " << key;
230 vector<vector<StdArc::Label> > path;
231 vector<StdArc::Weight> weight;
233 vector<StdArc::Label>(), StdArc::Weight::One());
235 for (int32
i = 0;
i < path.size();
i++) {
236 vector<double> kwlist;
237 kwlist.push_back(static_cast<double>(weight[
i].Value()));
238 for (int32
j = 0;
j < path[
i].size();
j++) {
239 kwlist.push_back(static_cast<double>(path[
i][
j]));
241 kwlist_writer.
Write(key, kwlist);
251 KALDI_LOG <<
"Done " << n_done <<
" keywords";
252 return (n_done != 0 ? 0 : 1);
253 }
catch(
const std::exception &e) {
254 std::cerr << e.what();
fst::StdArc::StateId StateId
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
int main(int argc, char *argv[])
void PruneSpecial(const Fst< Arc > &ifst, VectorFst< Arc > *ofst, typename Arc::Weight beam, size_t max_states)
The function PruneSpecial is like the standard OpenFst function "prune", except it does not expand th...
For an extended explanation of the framework of which grammar-fsts are a part, please see Support for...
void PrintUsage(bool print_command_line=false)
Prints the usage documentation [provided in the constructor].
A templated class for writing objects to an archive or script file; see The Table concept...
void Write(const std::string &key, const T &value) const
void Register(const std::string &name, bool *ptr, const std::string &doc)
void MakeLinearAcceptor(const std::vector< I > &labels, MutableFst< Arc > *ofst)
Creates unweighted linear acceptor from symbol sequence.
LatticeWeightTpl< FloatType > Times(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2)
The class ParseOptions is for parsing command-line options; see Parsing command-line options for more...
bool PrintProxyFstPath(const VectorFst< StdArc > &proxy, vector< vector< StdArc::Label > > *path, vector< StdArc::Weight > *weight, StdArc::StateId cur_state, vector< StdArc::Label > cur_path, StdArc::Weight cur_weight)
A templated class for reading objects sequentially from an archive or script file; see The Table conc...
int Read(int argc, const char *const *argv)
Parses the command line options and fills the ParseOptions-registered variables.
std::string GetArg(int param) const
Returns one of the positional parameters; 1-based indexing for argc/argv compatibility.
fst::StdArc::Weight Weight
int NumArgs() const
Number of positional parameters (c.f. argc-1).
#define KALDI_ASSERT(cond)
void ReadFstKaldi(std::istream &is, bool binary, VectorFst< Arc > *fst)
std::string GetOptArg(int param) const