Gradient computations
| 331 | |
| 332 | // Gradient computations |
| 333 | double DenseCRF::gradient( int n_iterations, const ObjectiveFunction & objective, VectorXf * unary_grad, VectorXf * lbl_cmp_grad, VectorXf * kernel_grad) const { |
| 334 | // Run inference |
| 335 | std::vector< MatrixXf > Q(n_iterations+1); |
| 336 | MatrixXf tmp1, unary( M_, N_ ), tmp2; |
| 337 | unary.fill(0); |
| 338 | if( unary_ ) |
| 339 | unary = unary_->get(); |
| 340 | expAndNormalize( Q[0], -unary ); |
| 341 | for( int it=0; it<n_iterations; it++ ) { |
| 342 | tmp1 = -unary; |
| 343 | for( unsigned int k=0; k<pairwise_.size(); k++ ) { |
| 344 | pairwise_[k]->apply( tmp2, Q[it] ); |
| 345 | tmp1 -= tmp2; |
| 346 | } |
| 347 | expAndNormalize( Q[it+1], tmp1 ); |
| 348 | } |
| 349 | |
| 350 | // Compute the objective value |
| 351 | MatrixXf b( M_, N_ ); |
| 352 | double r = objective.evaluate( b, Q[n_iterations] ); |
| 353 | sumAndNormalize( b, b, Q[n_iterations] ); |
| 354 | |
| 355 | // Compute the gradient |
| 356 | if(unary_grad && unary_) |
| 357 | *unary_grad = unary_->gradient( b ); |
| 358 | if( lbl_cmp_grad ) |
| 359 | *lbl_cmp_grad = 0*labelCompatibilityParameters(); |
| 360 | if( kernel_grad ) |
| 361 | *kernel_grad = 0*kernelParameters(); |
| 362 | |
| 363 | for( int it=n_iterations-1; it>=0; it-- ) { |
| 364 | // Do the inverse message passing |
| 365 | tmp1.fill(0); |
| 366 | int ip = 0, ik = 0; |
| 367 | // Add up all pairwise potentials |
| 368 | for( unsigned int k=0; k<pairwise_.size(); k++ ) { |
| 369 | // Compute the pairwise gradient expression |
| 370 | if( lbl_cmp_grad ) { |
| 371 | VectorXf pg = pairwise_[k]->gradient( b, Q[it] ); |
| 372 | lbl_cmp_grad->segment( ip, pg.rows() ) += pg; |
| 373 | ip += pg.rows(); |
| 374 | } |
| 375 | // Compute the kernel gradient expression |
| 376 | if( kernel_grad ) { |
| 377 | VectorXf pg = pairwise_[k]->kernelGradient( b, Q[it] ); |
| 378 | kernel_grad->segment( ik, pg.rows() ) += pg; |
| 379 | ik += pg.rows(); |
| 380 | } |
| 381 | // Compute the new b |
| 382 | pairwise_[k]->applyTranspose( tmp2, b ); |
| 383 | tmp1 += tmp2; |
| 384 | } |
| 385 | sumAndNormalize( b, tmp1.array()*Q[it].array(), Q[it] ); |
| 386 | |
| 387 | // Add the gradient |
| 388 | if(unary_grad && unary_) |
| 389 | *unary_grad += unary_->gradient( b ); |
| 390 | } |
nothing calls this directly
no test coverage detected