mirror of
https://github.com/moses-smt/mosesdecoder.git
synced 2024-09-11 19:27:11 +03:00
Store SHyperedge feature scores as deltas instead of totals
This mirrors the change made for the chart decoder in commit 465b4756...
This commit is contained in:
parent
07001f7645
commit
d317fdc373
@ -393,9 +393,7 @@ template <class Model> FFState *LanguageModelKen<Model>::EvaluateWhenApplied(con
|
||||
// Non-terminal is first so we can copy instead of rescoring.
|
||||
const Syntax::SVertex *pred = hyperedge.tail[nonTermIndexMap[phrasePos]];
|
||||
const lm::ngram::ChartState &prevState = static_cast<const LanguageModelChartStateKenLM*>(pred->states[featureID])->GetChartState();
|
||||
float prob = UntransformLMScore(
|
||||
pred->best->label.scoreBreakdown.GetScoresForProducer(this)[0]);
|
||||
ruleScore.BeginNonTerminal(prevState, prob);
|
||||
ruleScore.BeginNonTerminal(prevState);
|
||||
phrasePos++;
|
||||
}
|
||||
}
|
||||
@ -405,9 +403,7 @@ template <class Model> FFState *LanguageModelKen<Model>::EvaluateWhenApplied(con
|
||||
if (word.IsNonTerminal()) {
|
||||
const Syntax::SVertex *pred = hyperedge.tail[nonTermIndexMap[phrasePos]];
|
||||
const lm::ngram::ChartState &prevState = static_cast<const LanguageModelChartStateKenLM*>(pred->states[featureID])->GetChartState();
|
||||
float prob = UntransformLMScore(
|
||||
pred->best->label.scoreBreakdown.GetScoresForProducer(this)[0]);
|
||||
ruleScore.NonTerminal(prevState, prob);
|
||||
ruleScore.NonTerminal(prevState);
|
||||
} else {
|
||||
ruleScore.Terminal(TranslateID(word));
|
||||
}
|
||||
@ -415,7 +411,16 @@ template <class Model> FFState *LanguageModelKen<Model>::EvaluateWhenApplied(con
|
||||
|
||||
float score = ruleScore.Finish();
|
||||
score = TransformLMScore(score);
|
||||
accumulator->Assign(this, score);
|
||||
score -= target.GetScoreBreakdown().GetScoresForProducer(this)[0];
|
||||
|
||||
if (OOVFeatureEnabled()) {
|
||||
std::vector<float> scores(2);
|
||||
scores[0] = score;
|
||||
scores[1] = 0.0;
|
||||
accumulator->PlusEquals(this, scores);
|
||||
} else {
|
||||
accumulator->PlusEquals(this, score);
|
||||
}
|
||||
return newState;
|
||||
}
|
||||
|
||||
|
@ -101,10 +101,6 @@ SHyperedge *Cube::CreateHyperedge(const std::vector<int> &coordinates)
|
||||
for (std::size_t i = 0; i < coordinates.size()-1; ++i) {
|
||||
boost::shared_ptr<SVertex> pred = (*m_bundle.stacks[i])[coordinates[i]];
|
||||
hyperedge->tail[i] = pred.get();
|
||||
if (pred->best) {
|
||||
hyperedge->label.scoreBreakdown.PlusEquals(
|
||||
pred->best->label.scoreBreakdown);
|
||||
}
|
||||
}
|
||||
|
||||
hyperedge->label.inputWeight = m_bundle.inputWeight;
|
||||
@ -112,8 +108,7 @@ SHyperedge *Cube::CreateHyperedge(const std::vector<int> &coordinates)
|
||||
hyperedge->label.translation =
|
||||
*(m_bundle.translations->begin()+coordinates.back());
|
||||
|
||||
hyperedge->label.scoreBreakdown.PlusEquals(
|
||||
hyperedge->label.translation->GetScoreBreakdown());
|
||||
// Calculate feature deltas.
|
||||
|
||||
const StaticData &staticData = StaticData::Instance();
|
||||
|
||||
@ -123,7 +118,7 @@ SHyperedge *Cube::CreateHyperedge(const std::vector<int> &coordinates)
|
||||
StatelessFeatureFunction::GetStatelessFeatureFunctions();
|
||||
for (unsigned i = 0; i < sfs.size(); ++i) {
|
||||
if (!staticData.IsFeatureFunctionIgnored(*sfs[i])) {
|
||||
sfs[i]->EvaluateWhenApplied(*hyperedge, &hyperedge->label.scoreBreakdown);
|
||||
sfs[i]->EvaluateWhenApplied(*hyperedge, &hyperedge->label.deltas);
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,12 +127,24 @@ SHyperedge *Cube::CreateHyperedge(const std::vector<int> &coordinates)
|
||||
for (unsigned i = 0; i < ffs.size(); ++i) {
|
||||
if (!staticData.IsFeatureFunctionIgnored(*ffs[i])) {
|
||||
head->states[i] =
|
||||
ffs[i]->EvaluateWhenApplied(*hyperedge, i,
|
||||
&hyperedge->label.scoreBreakdown);
|
||||
ffs[i]->EvaluateWhenApplied(*hyperedge, i, &hyperedge->label.deltas);
|
||||
}
|
||||
}
|
||||
|
||||
hyperedge->label.score = hyperedge->label.scoreBreakdown.GetWeightedScore();
|
||||
// Calculate future score.
|
||||
|
||||
hyperedge->label.futureScore =
|
||||
hyperedge->label.translation->GetScoreBreakdown().GetWeightedScore();
|
||||
|
||||
hyperedge->label.futureScore += hyperedge->label.deltas.GetWeightedScore();
|
||||
|
||||
for (std::vector<SVertex*>::const_iterator p = hyperedge->tail.begin();
|
||||
p != hyperedge->tail.end(); ++p) {
|
||||
const SVertex *pred = *p;
|
||||
if (pred->best) {
|
||||
hyperedge->label.futureScore += pred->best->label.futureScore;
|
||||
}
|
||||
}
|
||||
|
||||
return hyperedge;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ private:
|
||||
{
|
||||
public:
|
||||
bool operator()(const QueueItem &p, const QueueItem &q) const {
|
||||
return p.first->label.score < q.first->label.score;
|
||||
return p.first->label.futureScore < q.first->label.futureScore;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -31,7 +31,7 @@ private:
|
||||
{
|
||||
public:
|
||||
bool operator()(const Cube *p, const Cube *q) const {
|
||||
return p->Top()->label.score < q->Top()->label.score;
|
||||
return p->Top()->label.futureScore < q->Top()->label.futureScore;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -304,7 +304,7 @@ void Manager<RuleMatcher>::RecombineAndSort(
|
||||
// Compare the score of h against the score of the best incoming hyperedge
|
||||
// for the stored vertex.
|
||||
SVertex *storedVertex = result.first->second;
|
||||
if (h->label.score > storedVertex->best->label.score) {
|
||||
if (h->label.futureScore > storedVertex->best->label.futureScore) {
|
||||
// h's score is better.
|
||||
storedVertex->recombined.push_back(storedVertex->best);
|
||||
storedVertex->best = h;
|
||||
|
@ -32,24 +32,25 @@ void KBestExtractor::Extract(
|
||||
supremeVertex->best = new SHyperedge();
|
||||
supremeVertex->best->head = supremeVertex.get();
|
||||
supremeVertex->best->tail.push_back(&bestTopLevelVertex);
|
||||
supremeVertex->best->label.score = bestTopLevelVertex.best->label.score;
|
||||
supremeVertex->best->label.scoreBreakdown =
|
||||
bestTopLevelVertex.best->label.scoreBreakdown;
|
||||
supremeVertex->best->label.futureScore =
|
||||
bestTopLevelVertex.best->label.futureScore;
|
||||
supremeVertex->best->label.deltas = bestTopLevelVertex.best->label.deltas;
|
||||
supremeVertex->best->label.translation = 0;
|
||||
|
||||
// For each alternative top-level SVertex, add a new incoming hyperedge to
|
||||
// supremeVertex.
|
||||
for (++p; p != topLevelVertices.end(); ++p) {
|
||||
// Check that the first item in topLevelVertices really was the best.
|
||||
UTIL_THROW_IF2((*p)->best->label.score > bestTopLevelVertex.best->label.score,
|
||||
UTIL_THROW_IF2((*p)->best->label.futureScore >
|
||||
bestTopLevelVertex.best->label.futureScore,
|
||||
"top-level SVertices are not correctly sorted");
|
||||
// Note: there's no need for a smart pointer here: supremeVertex will take
|
||||
// ownership of altEdge.
|
||||
SHyperedge *altEdge = new SHyperedge();
|
||||
altEdge->head = supremeVertex.get();
|
||||
altEdge->tail.push_back((*p).get());
|
||||
altEdge->label.score = (*p)->best->label.score;
|
||||
altEdge->label.scoreBreakdown = (*p)->best->label.scoreBreakdown;
|
||||
altEdge->label.futureScore = (*p)->best->label.futureScore;
|
||||
altEdge->label.deltas = (*p)->best->label.deltas;
|
||||
altEdge->label.translation = 0;
|
||||
supremeVertex->recombined.push_back(altEdge);
|
||||
}
|
||||
@ -282,7 +283,13 @@ void KBestExtractor::LazyNext(KVertex &v, const Derivation &d,
|
||||
KBestExtractor::Derivation::Derivation(const boost::shared_ptr<KHyperedge> &e)
|
||||
{
|
||||
edge = e;
|
||||
std::size_t arity = edge->tail.size();
|
||||
const TargetPhrase *translation = edge->shyperedge.label.translation;
|
||||
// Every hyperedge should have an associated target phrase, except for
|
||||
// incoming hyperedges of the 'supreme' vertex.
|
||||
if (translation) {
|
||||
scoreBreakdown = translation->GetScoreBreakdown();
|
||||
}
|
||||
const std::size_t arity = edge->tail.size();
|
||||
backPointers.resize(arity, 0);
|
||||
subderivations.reserve(arity);
|
||||
for (std::size_t i = 0; i < arity; ++i) {
|
||||
@ -290,9 +297,10 @@ KBestExtractor::Derivation::Derivation(const boost::shared_ptr<KHyperedge> &e)
|
||||
assert(pred.kBestList.size() >= 1);
|
||||
boost::shared_ptr<Derivation> sub(pred.kBestList[0]);
|
||||
subderivations.push_back(sub);
|
||||
scoreBreakdown.PlusEquals(sub->scoreBreakdown);
|
||||
}
|
||||
score = edge->shyperedge.label.score;
|
||||
scoreBreakdown = edge->shyperedge.label.scoreBreakdown;
|
||||
scoreBreakdown.PlusEquals(edge->shyperedge.label.deltas);
|
||||
score = scoreBreakdown.GetWeightedScore();
|
||||
}
|
||||
|
||||
// Construct a Derivation that neighbours an existing Derivation.
|
||||
|
@ -32,7 +32,7 @@ void Manager::OutputBest(OutputCollector *collector) const
|
||||
out << '\n';
|
||||
} else {
|
||||
if (options().output.ReportHypoScore) {
|
||||
out << best->label.score << " ";
|
||||
out << best->label.futureScore << " ";
|
||||
}
|
||||
Phrase yield = GetOneBestTargetYield(*best);
|
||||
// delete 1st & last
|
||||
|
@ -368,7 +368,7 @@ void Manager<Parser>::RecombineAndSort(const std::vector<SHyperedge*> &buffer,
|
||||
// Compare the score of h against the score of the best incoming hyperedge
|
||||
// for the stored vertex.
|
||||
SVertex *storedVertex = result.first->second;
|
||||
if (h->label.score > storedVertex->best->label.score) {
|
||||
if (h->label.futureScore > storedVertex->best->label.futureScore) {
|
||||
// h's score is better.
|
||||
storedVertex->recombined.push_back(storedVertex->best);
|
||||
storedVertex->best = h;
|
||||
|
@ -16,7 +16,7 @@ public:
|
||||
bundle.stacks.begin(); p != bundle.stacks.end(); ++p) {
|
||||
const SVertexStack *stack = *p;
|
||||
if (stack->front()->best) {
|
||||
score += stack->front()->best->label.score;
|
||||
score += stack->front()->best->label.futureScore;
|
||||
}
|
||||
}
|
||||
return score;
|
||||
|
@ -8,11 +8,24 @@ namespace Moses
|
||||
namespace Syntax
|
||||
{
|
||||
|
||||
// A SHyperedge label.
|
||||
//
|
||||
struct SLabel {
|
||||
float inputWeight;
|
||||
float score;
|
||||
ScoreComponentCollection scoreBreakdown;
|
||||
// Deltas for individual feature scores. i.e. this object records the change
|
||||
// in each feature score that results from applying the rule associated with
|
||||
// this hyperedge.
|
||||
ScoreComponentCollection deltas;
|
||||
|
||||
// Total derivation score to be used for comparison in beam search (i.e.
|
||||
// including future cost estimates). This is the sum of the 1-best
|
||||
// subderivations' future scores + deltas.
|
||||
float futureScore;
|
||||
|
||||
// Target-side of the grammar rule.
|
||||
const TargetPhrase *translation;
|
||||
|
||||
// Input weight of this hyperedge (e.g. from weighted input forest).
|
||||
float inputWeight;
|
||||
};
|
||||
|
||||
} // Syntax
|
||||
|
@ -18,7 +18,7 @@ struct SVertexStackContentOrderer {
|
||||
public:
|
||||
bool operator()(const boost::shared_ptr<SVertex> &x,
|
||||
const boost::shared_ptr<SVertex> &y) {
|
||||
return x->best->label.score > y->best->label.score;
|
||||
return x->best->label.futureScore > y->best->label.futureScore;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -264,7 +264,7 @@ void Manager<RuleMatcher>::RecombineAndSort(
|
||||
// Compare the score of h against the score of the best incoming hyperedge
|
||||
// for the stored vertex.
|
||||
SVertex *storedVertex = result.first->second;
|
||||
if (h->label.score > storedVertex->best->label.score) {
|
||||
if (h->label.futureScore > storedVertex->best->label.futureScore) {
|
||||
// h's score is better.
|
||||
storedVertex->recombined.push_back(storedVertex->best);
|
||||
storedVertex->best = h;
|
||||
|
Loading…
Reference in New Issue
Block a user