Gradient computations
| 236 | |
| 237 | // Gradient computations |
| 238 | double DenseCRF::gradient( int n_iterations, const ObjectiveFunction & objective, VectorXf * unary_grad, VectorXf * lbl_cmp_grad, VectorXf * kernel_grad) const { |
| 239 | // Run inference |
| 240 | std::vector< MatrixXf > Q(n_iterations+1); |
| 241 | MatrixXf tmp1, unary( M_, N_ ), tmp2; |
| 242 | unary.fill(0); |
| 243 | if( unary_ ) |
| 244 | unary = unary_->get(); |
| 245 | expAndNormalize( Q[0], -unary ); |
| 246 | for( int it=0; it<n_iterations; it++ ) { |
| 247 | tmp1 = -unary; |
| 248 | for( unsigned int k=0; k<pairwise_.size(); k++ ) { |
| 249 | pairwise_[k]->apply( tmp2, Q[it] ); |
| 250 | tmp1 -= tmp2; |
| 251 | } |
| 252 | expAndNormalize( Q[it+1], tmp1 ); |
| 253 | } |
| 254 | |
| 255 | // Compute the objective value |
| 256 | MatrixXf b( M_, N_ ); |
| 257 | double r = objective.evaluate( b, Q[n_iterations] ); |
| 258 | sumAndNormalize( b, b, Q[n_iterations] ); |
| 259 | |
| 260 | // Compute the gradient |
| 261 | if(unary_grad && unary_) |
| 262 | *unary_grad = unary_->gradient( b ); |
| 263 | if( lbl_cmp_grad ) |
| 264 | *lbl_cmp_grad = 0*labelCompatibilityParameters(); |
| 265 | if( kernel_grad ) |
| 266 | *kernel_grad = 0*kernelParameters(); |
| 267 | |
| 268 | for( int it=n_iterations-1; it>=0; it-- ) { |
| 269 | // Do the inverse message passing |
| 270 | tmp1.fill(0); |
| 271 | int ip = 0, ik = 0; |
| 272 | // Add up all pairwise potentials |
| 273 | for( unsigned int k=0; k<pairwise_.size(); k++ ) { |
| 274 | // Compute the pairwise gradient expression |
| 275 | if( lbl_cmp_grad ) { |
| 276 | VectorXf pg = pairwise_[k]->gradient( b, Q[it] ); |
| 277 | lbl_cmp_grad->segment( ip, pg.rows() ) += pg; |
| 278 | ip += pg.rows(); |
| 279 | } |
| 280 | // Compute the kernel gradient expression |
| 281 | if( kernel_grad ) { |
| 282 | VectorXf pg = pairwise_[k]->kernelGradient( b, Q[it] ); |
| 283 | kernel_grad->segment( ik, pg.rows() ) += pg; |
| 284 | ik += pg.rows(); |
| 285 | } |
| 286 | // Compute the new b |
| 287 | pairwise_[k]->applyTranspose( tmp2, b ); |
| 288 | tmp1 += tmp2; |
| 289 | } |
| 290 | sumAndNormalize( b, tmp1.array()*Q[it].array(), Q[it] ); |
| 291 | |
| 292 | // Add the gradient |
| 293 | if(unary_grad && unary_) |
| 294 | *unary_grad += unary_->gradient( b ); |
| 295 | } |
nothing calls this directly
no test coverage detected