|
|
|
|
|
|
|
|
|
|
|
|
|
#include <boost/foreach.hpp> |
|
#include <boost/functional/hash.hpp> |
|
#include <boost/unordered_set.hpp> |
|
#include <vector> |
|
#include <sstream> |
|
#include "Manager.h" |
|
#include "TargetPhraseImpl.h" |
|
#include "InputPath.h" |
|
#include "Sentence.h" |
|
|
|
#include "Normal/Search.h" |
|
#include "CubePruningMiniStack/Search.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "../TrellisPaths.h" |
|
#include "../System.h" |
|
#include "../Phrase.h" |
|
#include "../InputPathsBase.h" |
|
#include "../TranslationModel/PhraseTable.h" |
|
#include "../TranslationModel/UnknownWordPenalty.h" |
|
#include "../legacy/Range.h" |
|
#include "../PhraseBased/TargetPhrases.h" |
|
|
|
using namespace std; |
|
|
|
namespace Moses2 |
|
{ |
|
Manager::Manager(System &sys, const TranslationTask &task, |
|
const std::string &inputStr, long translationId) : |
|
ManagerBase(sys, task, inputStr, translationId) |
|
,m_search(NULL) |
|
,m_bitmaps(NULL) |
|
{ |
|
|
|
} |
|
|
|
Manager::~Manager() |
|
{ |
|
|
|
delete m_search; |
|
delete m_bitmaps; |
|
|
|
} |
|
|
|
void Manager::Init() |
|
{ |
|
|
|
InitPools(); |
|
|
|
FactorCollection &vocab = system.GetVocab(); |
|
m_input = Moses2::Sentence::CreateFromString(GetPool(), vocab, system, m_inputStr); |
|
|
|
m_bitmaps = new Bitmaps(GetPool()); |
|
|
|
const PhraseTable &firstPt = *system.featureFunctions.phraseTables[0]; |
|
m_initPhrase = new (GetPool().Allocate<TargetPhraseImpl>()) TargetPhraseImpl( |
|
GetPool(), firstPt, system, 0); |
|
|
|
const Sentence &sentence = static_cast<const Sentence&>(GetInput()); |
|
|
|
|
|
m_inputPaths.Init(sentence, *this); |
|
|
|
|
|
const UnknownWordPenalty *unkWP = system.featureFunctions.GetUnknownWordPenalty(); |
|
UTIL_THROW_IF2(unkWP == NULL, "There must be a UnknownWordPenalty FF"); |
|
unkWP->ProcessXML(*this, GetPool(), sentence, m_inputPaths); |
|
|
|
|
|
const std::vector<const PhraseTable*> &pts = system.mappings; |
|
for (size_t i = 0; i < pts.size(); ++i) { |
|
const PhraseTable &pt = *pts[i]; |
|
|
|
pt.Lookup(*this, m_inputPaths); |
|
} |
|
|
|
CalcFutureScore(); |
|
|
|
m_bitmaps->Init(sentence.GetSize(), vector<bool>(0)); |
|
|
|
switch (system.options.search.algo) { |
|
case Normal: |
|
m_search = new NSNormal::Search(*this); |
|
break; |
|
case NormalBatch: |
|
|
|
UTIL_THROW2("Not implemented"); |
|
break; |
|
case CubePruning: |
|
case CubePruningMiniStack: |
|
m_search = new NSCubePruningMiniStack::Search(*this); |
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default: |
|
UTIL_THROW2("Unknown search algorithm"); |
|
} |
|
} |
|
|
|
void Manager::Decode() |
|
{ |
|
|
|
|
|
Init(); |
|
m_search->Decode(); |
|
|
|
|
|
} |
|
|
|
void Manager::CalcFutureScore() |
|
{ |
|
const Sentence &sentence = static_cast<const Sentence&>(GetInput()); |
|
size_t size = sentence.GetSize(); |
|
m_estimatedScores = |
|
new (GetPool().Allocate<EstimatedScores>()) EstimatedScores(GetPool(), |
|
size); |
|
m_estimatedScores->InitTriangle(-numeric_limits<SCORE>::infinity()); |
|
|
|
|
|
BOOST_FOREACH(const InputPathBase *path, m_inputPaths) { |
|
const Range &range = path->range; |
|
SCORE bestScore = -numeric_limits<SCORE>::infinity(); |
|
|
|
size_t numPt = system.mappings.size(); |
|
for (size_t i = 0; i < numPt; ++i) { |
|
const TargetPhrases *tps = static_cast<const InputPath*>(path)->targetPhrases[i]; |
|
if (tps) { |
|
BOOST_FOREACH(const TargetPhraseImpl *tp, *tps) { |
|
SCORE score = tp->GetFutureScore(); |
|
if (score > bestScore) { |
|
bestScore = score; |
|
} |
|
} |
|
} |
|
} |
|
m_estimatedScores->SetValue(range.GetStartPos(), range.GetEndPos(), bestScore); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t colstart = 1; colstart < size; colstart++) { |
|
for (size_t diagshift = 0; diagshift < size - colstart; diagshift++) { |
|
size_t sPos = diagshift; |
|
size_t ePos = colstart + diagshift; |
|
for (size_t joinAt = sPos; joinAt < ePos; joinAt++) { |
|
float joinedScore = m_estimatedScores->GetValue(sPos, joinAt) |
|
+ m_estimatedScores->GetValue(joinAt + 1, ePos); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (joinedScore > m_estimatedScores->GetValue(sPos, ePos)) m_estimatedScores->SetValue( |
|
sPos, ePos, joinedScore); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
} |
|
|
|
std::string Manager::OutputBest() const |
|
{ |
|
stringstream out; |
|
Moses2::FixPrecision(out); |
|
|
|
const Hypothesis *bestHypo = m_search->GetBestHypo(); |
|
if (bestHypo) { |
|
if (system.options.output.ReportHypoScore) { |
|
out << bestHypo->GetScores().GetTotalScore() << " "; |
|
} |
|
|
|
bestHypo->OutputToStream(out); |
|
|
|
} else { |
|
if (system.options.output.ReportHypoScore) { |
|
out << "0 "; |
|
} |
|
|
|
} |
|
|
|
return out.str(); |
|
|
|
} |
|
|
|
std::string Manager::OutputNBest() |
|
{ |
|
arcLists.Sort(); |
|
|
|
boost::unordered_set<size_t> distinctHypos; |
|
|
|
TrellisPaths<TrellisPath> contenders; |
|
m_search->AddInitialTrellisPaths(contenders); |
|
|
|
long transId = GetTranslationId(); |
|
|
|
|
|
stringstream out; |
|
|
|
|
|
size_t maxIter = system.options.nbest.nbest_size * system.options.nbest.factor; |
|
size_t bestInd = 0; |
|
for (size_t i = 0; i < maxIter; ++i) { |
|
if (bestInd > system.options.nbest.nbest_size || contenders.empty()) { |
|
break; |
|
} |
|
|
|
|
|
TrellisPath *path = contenders.Get(); |
|
|
|
bool ok = false; |
|
if (system.options.nbest.only_distinct) { |
|
string tgtPhrase = path->OutputTargetPhrase(system); |
|
|
|
boost::hash<std::string> string_hash; |
|
size_t hash = string_hash(tgtPhrase); |
|
|
|
if (distinctHypos.insert(hash).second) { |
|
ok = true; |
|
} |
|
} else { |
|
ok = true; |
|
} |
|
|
|
if (ok) { |
|
++bestInd; |
|
out << transId << " ||| "; |
|
path->OutputToStream(out, system); |
|
out << "\n"; |
|
} |
|
|
|
|
|
path->CreateDeviantPaths(contenders, arcLists, GetPool(), system); |
|
|
|
delete path; |
|
} |
|
|
|
return out.str(); |
|
} |
|
|
|
std::string Manager::OutputTransOpt() |
|
{ |
|
return ""; |
|
} |
|
|
|
} |
|
|
|
|