diff options
author | Michael Denkowski <michael.j.denkowski@gmail.com> | 2012-12-22 16:01:23 -0500 |
---|---|---|
committer | Michael Denkowski <michael.j.denkowski@gmail.com> | 2012-12-22 16:01:23 -0500 |
commit | 778a4cec55f82bcc66b3f52de7cc871e8daaeb92 (patch) | |
tree | 2a5bccaa85965855104c4e8ac3738b2e1c77f164 /training/utils/entropy.cc | |
parent | 57fff9eea5ba0e71fb958fdb4f32d17f2fe31108 (diff) | |
parent | d21491daa5e50b4456c7c5f9c2e51d25afd2a757 (diff) |
Merge branch 'master' of git://github.com/redpony/cdec
Diffstat (limited to 'training/utils/entropy.cc')
-rw-r--r-- | training/utils/entropy.cc | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/training/utils/entropy.cc b/training/utils/entropy.cc new file mode 100644 index 00000000..4fdbe2be --- /dev/null +++ b/training/utils/entropy.cc @@ -0,0 +1,41 @@ +#include "entropy.h" + +#include "prob.h" +#include "candidate_set.h" + +using namespace std; + +namespace training { + +// see Mann and McCallum "Efficient Computation of Entropy Gradient ..." for +// a mostly clear derivation of: +// g = E[ F(x,y) * log p(y|x) ] + H(y | x) * E[ F(x,y) ] +double CandidateSetEntropy::operator()(const vector<double>& params, + SparseVector<double>* g) const { + prob_t z; + vector<double> dps(cands_.size()); + for (unsigned i = 0; i < cands_.size(); ++i) { + dps[i] = cands_[i].fmap.dot(params); + const prob_t u(dps[i], init_lnx()); + z += u; + } + const double log_z = log(z); + + SparseVector<double> exp_feats; + double entropy = 0; + for (unsigned i = 0; i < cands_.size(); ++i) { + const double log_prob = cands_[i].fmap.dot(params) - log_z; + const double prob = exp(log_prob); + const double e_logprob = prob * log_prob; + entropy -= e_logprob; + if (g) { + (*g) += cands_[i].fmap * e_logprob; + exp_feats += cands_[i].fmap * prob; + } + } + if (g) (*g) += exp_feats * entropy; + return entropy; +} + +} + |