| 705 | } |
| 706 | |
| 707 | void compute_logli_gradient(LinCrfLBFGSTransitionState<MutableArrayHandle<double> >& state, |
| 708 | MappedColumnVector& sparse_r, |
| 709 | MappedColumnVector& dense_m, |
| 710 | MappedColumnVector& sparse_m) { |
| 711 | int r_size = static_cast<int>(sparse_r.size()); |
| 712 | int sparse_m_size = static_cast<int>(sparse_m.size()); |
| 713 | int seq_len = static_cast<int>(sparse_r(r_size-2)) + 1; |
| 714 | |
| 715 | Eigen::MatrixXd betas(static_cast<uint32_t>(state.num_labels), seq_len); |
| 716 | Eigen::VectorXd scale(seq_len); |
| 717 | Eigen::MatrixXd Mi(static_cast<uint32_t>(state.num_labels), |
| 718 | static_cast<uint32_t>(state.num_labels)); |
| 719 | Eigen::VectorXd Vi(state.num_labels); |
| 720 | Eigen::VectorXd alpha(state.num_labels); |
| 721 | Eigen::VectorXd next_alpha(state.num_labels); |
| 722 | Eigen::VectorXd temp(state.num_labels); |
| 723 | Eigen::VectorXd ExpF(state.num_features); |
| 724 | betas.fill(0); |
| 725 | scale.fill(0); |
| 726 | alpha.fill(1); |
| 727 | next_alpha.fill(0); |
| 728 | temp.fill(0); |
| 729 | ExpF.fill(0); |
| 730 | |
| 731 | // compute beta values in a backward fashion |
| 732 | // also scale beta-values to 1 to avoid numerical problems |
| 733 | scale(seq_len - 1) = state.num_labels; |
| 734 | betas.col(seq_len - 1).fill(1.0 / scale(seq_len - 1)); |
| 735 | |
| 736 | int index = r_size-1; |
| 737 | for (int i = seq_len - 1; i > 0; i--) { |
| 738 | Mi.fill(0); |
| 739 | Vi.fill(0); |
| 740 | // examine all features at position "pos" |
| 741 | //(prev_labe, curr_label, f_index, start_pos, exist) |
| 742 | while (index-4>=0 && sparse_r(index-1) == i) { |
| 743 | int curr_label = static_cast<int>(sparse_r(index-3)); |
| 744 | validate_label(curr_label, state.num_labels); |
| 745 | int f_index = static_cast<int>(sparse_r(index-2)); |
| 746 | Vi(curr_label) += state.coef(f_index); |
| 747 | index-=5; |
| 748 | } |
| 749 | //(f_index, prev_label, curr_label) |
| 750 | for(int n=0; n+2<sparse_m_size ; n+=3) { |
| 751 | int prev_label = static_cast<int>(sparse_m(n+1)); |
| 752 | int curr_label = static_cast<int>(sparse_m(n+2)); |
| 753 | validate_label(prev_label, state.num_labels); |
| 754 | validate_label(curr_label, state.num_labels); |
| 755 | Mi(prev_label, curr_label) += state.coef(static_cast<int>(sparse_m(n))); |
| 756 | } |
| 757 | |
| 758 | compute_exp_Mi(state.num_labels, Mi, Vi); |
| 759 | |
| 760 | temp=betas.col(i); |
| 761 | temp=temp.cwiseProduct(Vi); |
| 762 | betas.col(i -1) = mult(Mi,temp,false,state.num_labels); |
| 763 | // scale for the next (backward) beta values |
| 764 | scale(i - 1)=betas.col(i-1).sum(); |
no test coverage detected