use of gnu.trove.iterator.TIntDoubleIterator in project ProPPR by TeamCohen.
the class LightweightStateGraph method serialize.
public String serialize(boolean featureIndex) {
StringBuilder ret = //numNodes
new StringBuilder().append(this.nodeSize()).append("\t").append(this.edgeCount).append(// waiting for label dependency size
"\t");
int labelDependencies = 0;
StringBuilder sb = new StringBuilder();
boolean first = true;
if (featureIndex) {
sb.append("\t");
for (int fi = 1; fi <= this.featureTab.size(); fi++) {
if (!first)
sb.append(LearningGraphBuilder.FEATURE_INDEX_DELIM);
else
first = false;
Feature f = this.featureTab.getSymbol(fi);
sb.append(f);
}
}
// foreach src node
for (TIntObjectIterator<TIntArrayList> it = this.near.iterator(); it.hasNext(); ) {
it.advance();
int ui = it.key();
TIntArrayList nearu = it.value();
HashSet<Integer> outgoingFeatures = new HashSet<Integer>();
//foreach dst from src
for (TIntIterator vit = nearu.iterator(); vit.hasNext(); ) {
int vi = vit.next();
sb.append("\t");
sb.append(ui).append(LearningGraphBuilder.SRC_DST_DELIM).append(vi);
sb.append(LearningGraphBuilder.EDGE_DELIM);
//foreach feature on src,dst
for (TIntDoubleIterator fit = edgeFeatureDict.get(ui).get(vi).iterator(); fit.hasNext(); ) {
fit.advance();
int fi = fit.key();
double wi = fit.value();
outgoingFeatures.add(fi);
sb.append(fi).append(LearningGraphBuilder.FEATURE_WEIGHT_DELIM).append(wi).append(LearningGraphBuilder.EDGE_FEATURE_DELIM);
}
// drop last ','
sb.deleteCharAt(sb.length() - 1);
}
labelDependencies += outgoingFeatures.size() * nearu.size();
}
ret.append(labelDependencies).append(sb);
return ret.toString();
}
use of gnu.trove.iterator.TIntDoubleIterator in project ProPPR by TeamCohen.
the class AdaGradSRW method agd.
/**
* AdaGrad Descent Algo
*
* edits params using totSqGrad as well
*
* @author rosecatherinek
*/
protected void agd(ParamVector<String, ?> params, PosNegRWExample ex) {
TIntDoubleMap gradient = gradient(params, ex);
// apply gradient to param vector
for (TIntDoubleIterator grad = gradient.iterator(); grad.hasNext(); ) {
grad.advance();
// avoid underflow since we're summing the square
if (Math.abs(grad.value()) < MIN_GRADIENT)
continue;
String feature = ex.getGraph().featureLibrary.getSymbol(grad.key());
if (trainable(feature)) {
Double g = grad.value();
//first update the running total of the square of the gradient
totSqGrad.adjustValue(feature, g * g);
//now get the running total
// Double rt = totSqGrad.get(feature);
//w_{t+1, i} = w_{t, i} - \eta * g_{t,i} / \sqrt{ G,i }
// Double descentVal = - c.eta * g / Math.sqrt(rt);
params.adjustValue(feature, -learningRate(feature) * g);
if (params.get(feature).isInfinite()) {
log.warn("Infinity at " + feature + "; gradient " + grad.value() + "; rt " + totSqGrad.get(feature));
}
}
}
}
use of gnu.trove.iterator.TIntDoubleIterator in project ProPPR by TeamCohen.
the class PosNegLoss method computeLossGradient.
@Override
public int computeLossGradient(ParamVector params, PosNegRWExample example, TIntDoubleMap gradient, LossData lossdata, SRWOptions c) {
PosNegRWExample ex = (PosNegRWExample) example;
int nonzero = 0;
// add empirical loss gradient term
// positive examples
double pmax = 0;
for (int a : ex.getPosList()) {
double pa = clip(ex.p[a]);
if (pa > pmax)
pmax = pa;
for (TIntDoubleIterator da = ex.dp[a].iterator(); da.hasNext(); ) {
da.advance();
if (da.value() == 0)
continue;
nonzero++;
double aterm = -da.value() / pa;
gradient.adjustOrPutValue(da.key(), aterm, aterm);
}
if (log.isDebugEnabled())
log.debug("+p=" + pa);
lossdata.add(LOSS.LOG, -Math.log(pa));
}
//negative instance booster
double h = pmax + c.delta;
double beta = 1;
if (c.delta < 0.5)
beta = (Math.log(1 / h)) / (Math.log(1 / (1 - h)));
// negative examples
for (int b : ex.getNegList()) {
double pb = clip(ex.p[b]);
for (TIntDoubleIterator db = ex.dp[b].iterator(); db.hasNext(); ) {
db.advance();
if (db.value() == 0)
continue;
nonzero++;
double bterm = beta * db.value() / (1 - pb);
gradient.adjustOrPutValue(db.key(), bterm, bterm);
}
if (log.isDebugEnabled())
log.debug("-p=" + pb);
lossdata.add(LOSS.LOG, -Math.log(1.0 - pb));
}
return nonzero;
}
use of gnu.trove.iterator.TIntDoubleIterator in project ProPPR by TeamCohen.
the class SRW method load.
/** fills M, dM in ex **/
protected void load(ParamVector<String, ?> params, PosNegRWExample example) {
PprExample ex = (PprExample) example;
int dM_cursor = 0;
for (int uid = 0; uid < ex.getGraph().node_hi; uid++) {
// (a); (b): initialization
double tu = 0;
TIntDoubleMap dtu = new TIntDoubleHashMap();
int udeg = ex.getGraph().node_near_hi[uid] - ex.getGraph().node_near_lo[uid];
double[] suv = new double[udeg];
double[][] dfu = new double[udeg][];
// begin (c): for each neighbor v of u,
for (int eid = ex.getGraph().node_near_lo[uid], xvi = 0; eid < ex.getGraph().node_near_hi[uid]; eid++, xvi++) {
int vid = ex.getGraph().edge_dest[eid];
// i. s_{uv} = w * phi_{uv}, a scalar:
suv[xvi] = 0;
for (int lid = ex.getGraph().edge_labels_lo[eid]; lid < ex.getGraph().edge_labels_hi[eid]; lid++) {
suv[xvi] += params.get(ex.getGraph().featureLibrary.getSymbol(ex.getGraph().label_feature_id[lid])) * ex.getGraph().label_feature_weight[lid];
}
// ii. t_u += f(s_{uv}), a scalar:
tu += c.squashingFunction.edgeWeight(suv[xvi]);
// iii. df_{uv} = f'(s_{uv})* phi_{uv}, a vector, as sparse as phi_{uv}
// by looping over features i in phi_{uv}
double[] dfuv = new double[ex.getGraph().edge_labels_hi[eid] - ex.getGraph().edge_labels_lo[eid]];
double cee = c.squashingFunction.computeDerivative(suv[xvi]);
for (int lid = ex.getGraph().edge_labels_lo[eid], dfuvi = 0; lid < ex.getGraph().edge_labels_hi[eid]; lid++, dfuvi++) {
// iii. again
dfuv[dfuvi] = cee * ex.getGraph().label_feature_weight[lid];
// iv. dt_u += df_{uv}, a vector, as sparse as sum_{v'} phi_{uv'}
// by looping over features i in df_{uv}
// (identical to features i in phi_{uv}, so we use the same loop)
dtu.adjustOrPutValue(ex.getGraph().label_feature_id[lid], dfuv[dfuvi], dfuv[dfuvi]);
}
dfu[xvi] = dfuv;
}
// end (c)
// begin (d): for each neighbor v of u,
double scale = (1 / (tu * tu));
for (int eid = ex.getGraph().node_near_lo[uid], xvi = 0; eid < ex.getGraph().node_near_hi[uid]; eid++, xvi++) {
int vid = ex.getGraph().edge_dest[eid];
//dM_features.size();
ex.dM_lo[uid][xvi] = dM_cursor;
// create the vector dM_{uv} = (1/t^2_u) * (t_u * df_{uv} - f(s_{uv}) * dt_u)
// by looping over features i in dt_u
// getting the df offset for features in dt_u is awkward, so we'll first iterate over features in df_uv,
// then fill in the rest
int[] seenFeatures = new int[ex.getGraph().edge_labels_hi[eid] - ex.getGraph().edge_labels_lo[eid]];
for (int lid = ex.getGraph().edge_labels_lo[eid], dfuvi = 0; lid < ex.getGraph().edge_labels_hi[eid]; lid++, dfuvi++) {
int fid = ex.getGraph().label_feature_id[lid];
//dM_features.add(fid);
ex.dM_feature_id[dM_cursor] = fid;
double dMuvi = (tu * dfu[xvi][dfuvi] - c.squashingFunction.edgeWeight(suv[xvi]) * dtu.get(fid));
if (tu == 0) {
if (dMuvi != 0)
throw new IllegalStateException("tu=0 at u=" + uid + "; example " + ex.toString());
} else
dMuvi *= scale;
//dM_values.add(dMuvi);
ex.dM_value[dM_cursor] = dMuvi;
dM_cursor++;
//save this feature so we can skip it later
seenFeatures[dfuvi] = fid;
}
Arrays.sort(seenFeatures);
// we've hit all the features in df_uv, now we do the remaining features in dt_u:
for (TIntDoubleIterator it = dtu.iterator(); it.hasNext(); ) {
it.advance();
// skip features we already added in the df_uv loop
if (Arrays.binarySearch(seenFeatures, it.key()) >= 0)
continue;
//dM_features.add(it.key());
ex.dM_feature_id[dM_cursor] = it.key();
// zero the first term, since df_uv doesn't cover this feature
double dMuvi = scale * (-c.squashingFunction.edgeWeight(suv[xvi]) * it.value());
//dM_values.add(dMuvi);
ex.dM_value[dM_cursor] = dMuvi;
dM_cursor++;
}
//dM_features.size();
ex.dM_hi[uid][xvi] = dM_cursor;
// also create the scalar M_{uv} = f(s_{uv}) / t_u
ex.M[uid][xvi] = c.squashingFunction.edgeWeight(suv[xvi]);
if (tu == 0) {
if (ex.M[uid][xvi] != 0)
throw new IllegalStateException("tu=0 at u=" + uid + "; example " + ex.toString());
} else
ex.M[uid][xvi] /= tu;
}
}
}
use of gnu.trove.iterator.TIntDoubleIterator in project ProPPR by TeamCohen.
the class SRW method accumulateGradient.
public void accumulateGradient(ParamVector<String, ?> params, PosNegRWExample example, ParamVector<String, ?> accumulator, StatusLogger status) {
log.debug("Gradient calculating on " + example);
initializeFeatures(params, example.getGraph());
ParamVector<String, Double> prepare = new SimpleParamVector<String>();
regularizer.prepareForExample(params, example.getGraph(), prepare);
load(params, example);
inference(params, example, status);
TIntDoubleMap gradient = gradient(params, example);
for (Map.Entry<String, Double> e : prepare.entrySet()) {
if (trainable(e.getKey()))
accumulator.adjustValue(e.getKey(), -e.getValue() / example.length());
}
for (TIntDoubleIterator it = gradient.iterator(); it.hasNext(); ) {
it.advance();
String feature = example.getGraph().featureLibrary.getSymbol(it.key());
if (trainable(feature))
accumulator.adjustValue(example.getGraph().featureLibrary.getSymbol(it.key()), it.value() / example.length());
}
}
Aggregations