package joshua.discriminative.semiring_parsing; import joshua.decoder.hypergraph.HGNode; import joshua.decoder.hypergraph.HyperEdge; public class MinRiskDAFuncValSemiringParser extends MinRiskDAAbstractSemiringParser { int numValues = 2;//we want to compute two values: risk and entropy double finalRisk; double finalEntropy; public MinRiskDAFuncValSemiringParser(int semiring, int add_mode, double scale, double temperature_) { super(semiring, add_mode, scale, temperature_); } @Override protected ExpectationSemiringVector createNewSemiringMember() { return new ExpectationSemiringVector(numValues); } @Override protected ExpectationSemiringVector getHyperedgeSemiringWeight(HyperEdge dt, HGNode parentItem, double scale, AtomicSemiring p_atomic_semiring) { ExpectationSemiringVector res = null; if(p_atomic_semiring.ATOMIC_SEMIRING==AtomicSemiring.LOG_SEMIRING){ //double logProb = getlogProb(dt, parentItem, activeFeatures); double logProb = getFeatureForest().getEdgeLogTransitionProb(dt, parentItem); //double realProb = Math.exp(logProb); //factor1 double[] factor1Raw = new double[numValues]; SignedValue[] factor1 = new SignedValue[numValues]; //==risk factor1Raw[0] = computeRiskRawFactor(dt, parentItem); //factor1[0] = realProb*factor1Raw[0]; factor1[0] = SignedValue.multi( logProb, SignedValue.createSignedValue(factor1Raw[0]) ); //==entropy factor1Raw[1] = computeEntropyRawFactor(dt, parentItem, logProb); //factor1[1] = realProb*factor1Raw[1]; factor1[1] = SignedValue.multi( logProb, SignedValue.createSignedValue(factor1Raw[1]) ); res = new ExpectationSemiringVector(logProb, factor1); }else{ System.out.println("un-implemented atomic-semiring"); System.exit(1); } return res; } private double computeRiskRawFactor(HyperEdge dt, HGNode parentItem){ double riskFactor1Raw = 0; if(dt.getRule() != null){//note: hyperedges under goal item does not contribute BLEU //TODO riskFactor1Raw = getFeatureForest().getEdgeRisk( dt); } return riskFactor1Raw; } /**-logP has two parts: logZ(x) - s(x,y) * where s(x,y) is the linear combination of feature scores * We need to consider logZ(x) at the root **/ private double computeEntropyRawFactor(HyperEdge dt, HGNode parentItem, double logTransitionProb){ return - logTransitionProb; } public double computeFunctionVal(){ insideEstimationOverHG(hg); CompositeSemiring goal_semiring = getGoalSemiringMember(hg); goal_semiring.normalizeFactors(); //goal_semiring.printInfor(); //get final gradient double logProb = ((ExpectationSemiringVector)goal_semiring).getLogProb(); SignedValue[] factor1 = ((ExpectationSemiringVector)goal_semiring).getFactor1(); finalRisk = factor1[0].convertRealValue(); finalEntropy = factor1[1].convertRealValue() + logProb;//logProb is the normalization constant double functionValue = finalRisk - temperature*finalEntropy; if(finalEntropy<0){ System.out.println("Entropy is negative, must be wrong; " + finalEntropy); //System.exit(1); } if(Double.isNaN(finalRisk)){System.out.println("risk is NaN"); System.exit(1);} if(Double.isNaN(finalEntropy)){System.out.println("entropy is NaN"); System.exit(1);} if(Double.isNaN(functionValue)){System.out.println("functionValue is NaN"); System.exit(1);} /* System.out.println("Risk is : " + finalRisk); System.out.println("Entropy is : " + finalEntropy); System.out.println("Function value is : " + functionValue); */ return functionValue; } public double getRisk(){ return finalRisk; } public double getEntropy(){ return finalEntropy; } }