/** Flag = 0: marginloss, no label loss. The label loss will always be zero 1: marginloss, and label loss. */ void CSMMMulticlassLoss::ComputeLoss(vector<unsigned int> y, vector<unsigned int> ylabel, vector<unsigned int> ybar, vector<unsigned int> ybarlabel, const CSeqMulticlassFeature::seqfeature_struct &x, const TheMatrix &w, double & marginloss, double & labelloss, int flag) { unsigned int i; double w_dot_phi1 = 0; double w_dot_phi2 = 0; marginloss = 0; unsigned int start; if(is_first_phi1_used) start = 0; else start = 1; for(i=start; i < ybar.size(); i++) { _data->TensorPhi1(x.phi_1[ybar[i]],ybarlabel[i],0,tphi_1); //tphi_1->Print(); w.Dot(*(tphi_1), w_dot_phi1); marginloss += w_dot_phi1; //printf("%d(%d):%2.4f\t",ybar[i],ybarlabel[i],marginloss); } for(i=1;i<ybar.size();i++) { int vb = 0; _data->TensorPhi2(x.phi_2[ybar[i-1]][ybar[i]-ybar[i-1]-1], ybarlabel[i-1], ybarlabel[i], 0,vb,tphi_2); w.Dot(*(tphi_2), w_dot_phi2); marginloss += w_dot_phi2; } if(ybar.size() > 0) { //grad.Add(*(X[i].phi_2[ybar[ybar.size()-1]][X[i].len-1 - ybar[ybar.size()-1]-1]));//// _data->TensorPhi2(x.phi_2[ybar[ybar.size()-1]][x.len - ybar[ybar.size()-1]-1 ], ybarlabel[ybar.size()-1], 0, 0,0,tphi_2); w.Dot(*(tphi_2), w_dot_phi2); marginloss += w_dot_phi2; } //vector <unsigned int> yss = Boundry2StatSequence(y,ylabel,x.len); //vector <unsigned int> ybarss = Boundry2StatSequence(ybar,ybarlabel,x.len); //labelloss = Labelloss(yss,ybarss); labelloss = AllDelta(ybar,y,ybarlabel,ylabel,x.len); }
/** find best label (without label loss): g(w) := max_y' <w,\phi(x,y')> * * @param x [read] sequence * @param w [read] weight vector * @param ybar [write] found best label * @param marginloss [write] margin loss <w,\Phi(x,y')> w.r.t to best y' */ void CSMMMulticlassLoss::find_best_label_grammer(const CSeqMulticlassFeature::seqfeature_struct &x, const TheMatrix &w, vector<unsigned int> &ybar, vector<unsigned int> &ybarlabel, double &marginloss, unsigned int personid, unsigned int classNum) { using namespace std; // reset return values marginloss = 0; ybar.clear(); ybarlabel.clear(); /** The margin value vector used in dynamic programming */ vector< vector<double> > M (x.len+1,vector<double> (classNum,0)); /** The back pointers vector used in dynamic programming to retrieve the optimal path */ // The positions vector< vector<int> > A (x.len+1,vector<int> (classNum,-1)); // The class labels vector< vector<int> > C (x.len+1,vector<int> (classNum,0)); double maxval = -SML::INFTY; double w_dot_phi1 = 0; double w_dot_phi2 = 0; double marginval = 0; unsigned int right = 0; unsigned int left = 0; unsigned int start = 0; unsigned int end = 0; unsigned int classID = 0; unsigned int classIDPrev = 0; double sum = 0; // compute DP statistics for positions 1 to len-1 for(classID=0;classID<classNum;classID++) { A[1][classID] = 0; //C[1][classID] = 0; } if(is_first_phi1_used) { right =0; for(classID=0;classID<classNum;classID++) { maxval = -SML::INFTY; w_dot_phi1 = 0.0; _data->TensorPhi1(x.phi_1[right],classID,0,tphi_1); //tphi_1->Print(); w.Dot(*(tphi_1), w_dot_phi1); marginval = w_dot_phi1; sum = marginval; if(sum > maxval) { M[right][classID] = marginval; maxval = sum; } } } for(right=1; right < x.len+1; right++) { for(classID=0;classID<classNum;classID++) { // \Phi = (phi1, phi2[left,right]) // <w, \Phi> = <w,phi1> + <w,phi[left,right]> maxval = -SML::INFTY; w_dot_phi1 = 0.0; if(right<x.len) { _data->TensorPhi1(x.phi_1[right],classID,0,tphi_1); w.Dot(*(tphi_1), w_dot_phi1); } start = max(0,int(right-maxDuration)); //end = right;//-minDuration+1; if(lastDuration>0) { unsigned int lastpos = x.len-lastDuration+1 ; end = MIN(right,lastpos); } else end = right; for(left=start; left < end; left++) { classIDPrev = classID; int vb = 0; _data->TensorPhi2(x.phi_2[left][right-left-1], classIDPrev, classID, 0,vb,tphi_2); w.Dot(*(tphi_2), w_dot_phi2); marginval = w_dot_phi1 + w_dot_phi2; sum = M[left][classIDPrev]+marginval; if(sum > maxval) { A[right][classID] = left; C[right][classID] = classIDPrev; M[right][classID] = M[left][classIDPrev] + marginval; maxval = sum; } } } } // get optimal path (i.e. segmentation) unsigned int pos,prepos,classid,preclassid; int maxclassid = 0; maxval = -SML::INFTY; for(unsigned int i=0;i<classNum;i++) { sum = M[x.len][i]; if(sum>maxval) { maxval = sum; maxclassid = i; } } pos = A[x.len][maxclassid]; classid = C[x.len][maxclassid]; if(lastDuration>0) { pos = x.len-lastDuration; classid = 0; } ybar.push_back(pos); ybarlabel.push_back(classid); prepos = pos; preclassid = classid; while(A[pos][classid] >= 0) { pos = A[prepos][preclassid]; classid = C[prepos][preclassid]; ybar.push_back(pos);//positions ybarlabel.push_back(classid);//class labels prepos = pos; preclassid = classid; } marginloss = M[x.len][maxclassid]; reverse(ybar.begin(), ybar.end()); reverse(ybarlabel.begin(), ybarlabel.end()); }
/** find best label with a grammer(with label loss): g(w) := max_y' <w,\phi(x,y')> + Delta(y', y) * * @param x [read] sequence * @param y [read] actual label for x * @param w [read] weight vector * @param ybar [write] found best label * @param marginloss [write] margin loss <w,\Phi(x,y')> w.r.t to best y' * @param labelloss [write] label loss \Delta(y',y) w.r.t. to best y' * */ void CSMMMulticlassLoss::find_best_label_grammer(const vector<unsigned int> &y,const vector<unsigned int> &ylabel, const CSeqMulticlassFeature::seqfeature_struct &x, const TheMatrix &w, vector<unsigned int> &ybar,vector<unsigned int> &ybarlabel, double &marginloss, double &labelloss, unsigned int personid, unsigned int classNum) { // reset return values marginloss = 0; labelloss = 0; ybar.clear(); ybarlabel.clear(); /** The margin value vector used in dynamic programming */ vector< vector<double> > M (x.len+1,vector<double> (classNum,0)); /** The label loss value vector used in dynamic programming */ vector< vector<double> > L (x.len+1,vector<double> (classNum,0)); /** The back pointers vector used in dynamic programming to retrieve the optimal path */ // The positions vector< vector<int> > A (x.len+1,vector<int> (classNum,-1)); // The class labels vector< vector<int> > C (x.len+1,vector<int> (classNum,0)); double maxval = -SML::INFTY; double w_dot_phi1 = 0; double w_dot_phi2 = 0; double marginval = 0; double labelval = 0; unsigned int right = 0; unsigned int left = 0; unsigned int start = 0; unsigned int end = 0; unsigned int classID = 0; unsigned int classIDPrev = 0; double sum = 0; // compute DP statistics for positions 1 to len-1 // L[0] += y.size()-2; // A[1] = 0; for(classID=0;classID<classNum;classID++) { A[1][classID] = 0; //C[1][classID] = 0; } //debug //printf("x.len:%d",x.len); if(is_first_phi1_used) { right =0; for(classID=0;classID<classNum;classID++) { maxval = -SML::INFTY; w_dot_phi1 = 0.0; _data->TensorPhi1(x.phi_1[right],classID,0,tphi_1); //tphi_1->Print(); w.Dot(*(tphi_1), w_dot_phi1); marginval = w_dot_phi1; sum = marginval; if(sum > maxval) { M[right][classID] = marginval; maxval = sum; } } } for(right=1; right < x.len+1; right++) { for(classID=0;classID<classNum;classID++) { // \Phi = (phi1, phi2[left,right]) // <w, \Phi> = <w,phi1> + <w,phi[left,right]> maxval = -SML::INFTY; w_dot_phi1 = 0.0; //w.Dot(*(x.phi_1[right]), w_dot_phi1); //printf("pos:%d,classid:%d ",right,classID);fflush(stdout); //x.phi_1[right]->Print(); if(right<x.len) { _data->TensorPhi1(x.phi_1[right],classID,0,tphi_1); //tphi_1->Print(); w.Dot(*(tphi_1), w_dot_phi1); } start = max(0,int(right-maxDuration)); //end = right;//-minDuration+1; if(lastDuration>0) { unsigned int lastpos = x.len-lastDuration+1 ; end = MIN(right,lastpos); } else end = right; for(left=start; left < end; left++) { classIDPrev = classID; labelval = PartialDelta(left,right,y,ylabel,classIDPrev,x.len); assert( (labelval<=x.len) && (labelval>=0) ); int vb = 0; _data->TensorPhi2(x.phi_2[left][right-left-1], classIDPrev, classID, 0,vb,tphi_2); w.Dot(*(tphi_2), w_dot_phi2); marginval = w_dot_phi1 + w_dot_phi2; sum = M[left][classIDPrev]+marginval + L[left][classIDPrev]+labelval; if(sum > maxval) { A[right][classID] = left; C[right][classID] = classIDPrev; M[right][classID] = M[left][classIDPrev] + marginval; L[right][classID] = L[left][classIDPrev] + labelval; maxval = sum; } } } } // get optimal path (i.e. segmentation) unsigned int pos,prepos,classid,preclassid; int maxclassid = 0; maxval = -SML::INFTY; for(unsigned int i=0;i<classNum;i++) { sum = M[x.len][i] + L[x.len][i]; if(sum>maxval) { maxval = sum; maxclassid = i; } } pos = A[x.len][maxclassid]; classid = C[x.len][maxclassid]; if(lastDuration>0) { pos = x.len-lastDuration; classid = 0; } ybar.push_back(pos); ybarlabel.push_back(classid); prepos = pos; preclassid = classid; while(A[pos][classid] >= 0) { pos = A[prepos][preclassid]; classid = C[prepos][preclassid]; ybar.push_back(pos);//positions ybarlabel.push_back(classid);//class labels //printf("%d(%d):%2.4f ",pos,classid,L[pos][classid]);fflush(stdout); prepos = pos; preclassid = classid; } marginloss = M[x.len][maxclassid]; labelloss = L[x.len][maxclassid]; //printf("finished back track\n labelloss:%3.4f,marginloss:%3.4f\n",labelloss,marginloss);fflush(stdout); reverse(ybar.begin(), ybar.end()); reverse(ybarlabel.begin(), ybarlabel.end()); //printf("reversed\n");fflush(stdout); unsigned int i; if(verbosity>=2) { printf("y: "); for(i=0;i<y.size();i++) { printf("%d(%d) ",y[i],ylabel[i]); } fflush(stdout); printf("\nybar:"); for(i=0;i<ybar.size();i++) { printf("%d(%d) ",ybar[i],ybarlabel[i]); } fflush(stdout); printf("\nmargin:%f, loss:%f, totalloss:%f\n",marginloss,labelloss,marginloss+labelloss); } }