summaryrefslogtreecommitdiff
path: root/training/risk.cc
diff options
context:
space:
mode:
authorChris Dyer <cdyer@cab.ark.cs.cmu.edu>2012-06-24 15:52:30 -0400
committerChris Dyer <cdyer@cab.ark.cs.cmu.edu>2012-06-24 15:52:30 -0400
commitd19ddda6446d3093de1617027350d34df20a1b50 (patch)
treec7bdde43d2e3ef70b24f2804ea13ce8ffd0123f5 /training/risk.cc
parentd790e7aea5ffdf3c3e15683fe3d8b2b17a92b62f (diff)
compute risk / gradient of risk
Diffstat (limited to 'training/risk.cc')
-rw-r--r--training/risk.cc43
1 files changed, 43 insertions, 0 deletions
diff --git a/training/risk.cc b/training/risk.cc
new file mode 100644
index 00000000..347ed3cb
--- /dev/null
+++ b/training/risk.cc
@@ -0,0 +1,43 @@
+#include "risk.h"
+
+#include "prob.h"
+#include "candidate_set.h"
+#include "ns.h"
+
+using namespace std;
+
+namespace training {
+
+// g = \sum_e p(e|f) * loss(e) * (phi(e,f) - E[phi(e,f)])
+double CandidateSetRisk::operator()(const vector<double>& params,
+ SparseVector<double>* g) const {
+ prob_t z;
+ for (unsigned i = 0; i < cands_.size(); ++i) {
+ const prob_t u(cands_[i].fmap.dot(params), init_lnx());
+ z += u;
+ }
+ const double log_z = log(z);
+
+ SparseVector<double> exp_feats;
+ if (g) {
+ 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);
+ exp_feats += cands_[i].fmap * prob;
+ }
+ }
+
+ double risk = 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 r = prob * metric_.ComputeScore(cands_[i].eval_feats);
+ risk += r;
+ if (g) (*g) += (cands_[i].fmap - exp_feats) * r;
+ }
+ return risk;
+}
+
+}
+
+