(author: John Salatas)
Foreword
This article, the second in a series regarding, porting openFST to java, briefly presents some additional base classes and raise some issues regarding the java fst architecture in general and its compatibility with the original openFST binary format for saving models.
1. FST java library base architecture
The first article in the series [1] introduced the Weight
Furthermore revision 11363 includes the edu.cmu.sphinx.fst.state.State
2. Architecture design issues
2.1. Java generics support
As described in the first part [1], the edu.cmu.sphinx.fst.weight.Weight
As an example the Arc class definition would be simplified to
public class Arc implements Serializable{
private static final long serialVersionUID = -7996802366816336109L;
// Arc's weight
protected Weight weight;
// Rest of the code.....
}
instead of its current definition
public class Arc
private static final long serialVersionUID = -7996802366816336109L;
// Arc's weight
protected W weight;
// Rest of the code.....
}
The proposed modification can be applied also to State and Fst classes and provide an easier to use api. In that case the construction of a basic FST in the class edu.cmu.sphinx.fst.demos.basic.FstTest would be simplified as follows
// ...
Fst fst = new Fst();
// State 0
State s = new State();
s.AddArc(new Arc(new Weight(0.5), 1, 1, 1));
s.AddArc(new Arc(new Weight(1.5), 2, 2, 1));
fst.AddState(s);
// State 1
s = new State();
s.AddArc(new Arc(new Weight(2.5), 3, 3, 2));
fst.AddState(s);
// State 2 (final)
s = new State(new Weight(3.5));
fst.AddState(s);
// ...
The code could be further simplified by completely dropping generics support in State, Arc and Fst classes by just providing solid implementations based on Weight weights.
2.2. Compatibility with the original openFST binary format
A second issue is the compatibility of the serialized binary format with the original openFST format. A compatible java library that is able to load/save openFST models, would provide us the ability to share trained models between various applications. As an example, in the case of ASR appliactions, trained models could be easily shared between between sphinx4 and kaldi [3] which is written in C++ and already uses the openFST library.
2.3. Logarithmic Semiring implementation issues
A final issue has to do with a possible inconsistency of the plus operation definition between Allauzen's et. Al paper [4] and the actual openFST code (version 1.3.1.): The plus operation ( $latex \oplus_{\log} $ ) is defined in [4] as $latex x \oplus_{\log} y = -\log(e^{-x} +e^{-y}) $, however in code it is implemented as follows
template
inline T LogExp(T x) { return log(1.0F + exp(-x)); }
template
inline LogWeightTpl Plus(const LogWeightTpl &w1,
const LogWeightTpl &w2) {
T f1 = w1.Value(), f2 = w2.Value();
if (f1 == FloatLimits::kPosInfinity)
return w2;
else if (f2 == FloatLimits::kPosInfinity)
return w1;
else if (f1 > f2)
return LogWeightTpl(f2 - LogExp(f1 - f2));
else
return LogWeightTpl(f1 - LogExp(f2 - f1));
}
References
[1] “Porting openFST to java: Part 1”, last accessed: 18/05/2012.
[2] CMUSphinx g2p SVN repository
[3] Kaldi Speech recognition research toolkit , last accessed: 18/05/2012.
[4] C. Allauzen, M. Riley, J. Schalkwyk, W. Skut, M. Mohri, “OpenFst: a general and efficient weighted finite-state transducer library”, Proceedings of the 12th International Conference on Implementation and Application of Automata (CIAA 2007), pp. 11–23, Prague, Czech Republic, July 2007.