KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pt_sample_scenes.h
Go to the documentation of this file.
1 /* =========================================================================== *
2 |
3 | Copyright (c) 1994-2008 by Kobus Barnard (author).
4 |
5 | Personal and educational use of this code is granted, provided that this
6 | header is kept intact, and that the authorship is not misrepresented, that
7 | its use is acknowledged in publications, and relevant papers are cited.
8 |
9 | For other use contact the author (kobus AT cs DOT arizona DOT edu).
10 |
11 | Please note that the code in this file has not necessarily been adequately
12 | tested. Naturally, there is no guarantee of performance, support, or fitness
13 | for any particular task. Nonetheless, I am interested in hearing about
14 | problems that you encounter.
15 |
16 | Authors:
17 | Ernesto Brau, Jinyan Guan
18 |
19 * =========================================================================== */
20 
21 /* $Id$ */
22 
23 #ifndef PT_SAMPLE_SCENES_H
24 #define PT_SAMPLE_SCENES_H
25 
33 #include <l_cpp/l_exception.h>
34 #include <vector>
35 #include <algorithm>
36 #include <boost/foreach.hpp>
37 #include <boost/optional.hpp>
38 
39 #ifdef KJB_HAVE_ERGO
40 #include <ergo/hmc.h>
41 #include <ergo/mh.h>
42 #include <ergo/record.h>
43 #endif
44 
45 namespace kjb {
46 namespace pt {
47 
53 //struct Control_scene
54 //{
55 // Scene scene;
56 //};
57 
59 bool all_new_targets(const Scene& scene);
60 
66 {
67 public:
69  (
70  double hsdv,
71  double wsdv,
72  double gsdv,
73  bool infer_head = true
74  )
75  : N_height(0.0, hsdv),
76  N_width(0.0, wsdv),
77  N_girth(0.0, gsdv),
78  m_infer_head(infer_head)
79  {}
80 
81 #ifdef KJB_HAVE_ERGO
82  ergo::mh_proposal_result operator()(const Scene& in, Scene& out);
83 #endif
84 
85 private:
86  Normal_distribution N_height;
87  Normal_distribution N_width;
88  Normal_distribution N_girth;
89  bool m_infer_head;
90 };
91 
97 {
98 public:
99  enum Sample_method { HMC, MH };
100  typedef ergo::hmc_step<Scene> Hmc_step;
101  typedef ergo::mh_step<Scene> Mh_step;
102 
103 public:
104  Sample_scenes(const Scene_posterior& posterior, bool infer_head) :
105  posterior_p_(&posterior),
106  sample_method_(HMC),
107  num_iterations_(10),
108  num_leapfrog_steps_(5),
109  pos_opt_step_size_(0.00001),
110  pos_grad_step_size_(0.01),
111  estimate_grad_step_size_(true),
112  height_sdv_(0.02),
113  width_sdv_(0.01),
114  girth_sdv_(0.01),
115  infer_head_(infer_head)
116  {}
117 
118 public:
120  const Scene_posterior& scene_posterior() const { return *posterior_p_; }
121 
124  {
125  posterior_p_ = &post;
126  }
127 
129  void set_sample_method(Sample_method method) { sample_method_ = method; }
130 
135  void set_num_iterations(size_t num_its) { num_iterations_ = num_its; }
136 
138  void set_num_leapfrog_steps(size_t lf_steps)
139  {
140  num_leapfrog_steps_ = lf_steps;
141  }
142 
144  void set_hmc_step_size(double pss) { pos_opt_step_size_ = pss; }
145 
147  void set_gradient_step_size(double pss)
148  {
149  pos_grad_step_size_ = pss;
150  estimate_grad_step_size_ = false;
151  }
152 
154  void set_size_proposal_sigmas(double hsdv, double wsdv, double gsdv)
155  {
156  height_sdv_ = hsdv;
157  width_sdv_ = wsdv;
158  girth_sdv_ = gsdv;
159  }
160 
162  template<
163  class StepIterator,
164  class SampleIterator,
165  class ProposalIterator,
166  class PdIterator>
167  void operator()
168  (
169  const Scene& initial_scene,
170  boost::optional<StepIterator> step_out,
171  boost::optional<SampleIterator> sample_out,
172  boost::optional<ProposalIterator> proposed_out,
173  boost::optional<PdIterator> pd_out
174  ) const;
175 
176 private:
177 #ifdef KJB_HAVE_ERGO
178 
179  Hmc_step make_hmc_traj_step
180  (
181  const Scene_adapter& scene_adapter,
182  Scene& best_scene
183  ) const;
184 
185 // /** @brief Helper function that creates an MH trajectory step. */
186 // Mh_step make_mh_traj_step() const;
187 
189  Mh_step make_mh_size_step(bool infer_head) const;
190 
192  template<class TrajStep, class TRecIter, class SRecIter>
193  void run_steps
194  (
195  Scene& scene,
196  double& lt,
197  //const TrajStep& traj_step,
198  TrajStep& traj_step,
199  TRecIter tfirst,
200  TRecIter tlast,
201  const Mh_step& size_step,
202  SRecIter sfirst,
203  SRecIter slast
204  ) const;
205 #endif
206 
207 private:
208  const Scene_posterior* posterior_p_;
209  Sample_method sample_method_;
210  size_t num_iterations_;
211  size_t num_leapfrog_steps_;
212  double pos_opt_step_size_;
213  double pos_grad_step_size_;
214  bool estimate_grad_step_size_;
215  double height_sdv_;
216  double width_sdv_;
217  double girth_sdv_;
218  bool infer_head_;
219 };
220 
221 /* \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ */
222 
223 template<
224  class StepIterator,
225  class SampleIterator,
226  class ProposalIterator,
227  class PdIterator>
228 void Sample_scenes::operator()
229 (
230  const Scene& initial_scene,
231  boost::optional<StepIterator> step_out,
232  boost::optional<SampleIterator> sample_out,
233  boost::optional<ProposalIterator> proposed_out,
234  boost::optional<PdIterator> pd_out
235 ) const
236 {
237 #ifdef KJB_HAVE_ERGO
238  typedef std::vector<Hmc_step::record_t> Hmc_rec_vector;
239  typedef std::vector<Mh_step::record_t> Mh_rec_vector;
240 
241  if(num_iterations_ == 0) return;
242 
243  // size of scene
244  Scene_adapter scene_adapter(posterior_p_->vis_off(), infer_head_);
245  size_t scene_size = scene_adapter.size(&initial_scene);
246 
247  if(scene_size == 0) return;
248 
249  // make current and best scene and posterior value
250  Scene cur_scene = initial_scene;
251  double cur_lt = (*posterior_p_)(cur_scene);
252  Scene best_scene = initial_scene;
253 
254  // steps
255  Hmc_step traj_step = make_hmc_traj_step(scene_adapter, best_scene);
256  Mh_step size_step = make_mh_size_step(infer_head_);
257 
258  // recorders
259  Hmc_rec_vector hrv;
260  Mh_rec_vector mrv;
261  hrv.reserve(4);
262  mrv.reserve(4);
263 
264  // best scene
265  hrv.push_back(ergo::make_best_sample_recorder(&best_scene).replace());
266  mrv.push_back(ergo::make_best_sample_recorder(&best_scene).replace());
267 
268  // log recorder
269  if(step_out)
270  {
271  hrv.push_back(ergo::make_hmc_detail_recorder(*step_out));
272  mrv.push_back(ergo::make_mh_detail_recorder(*step_out));
273  }
274 
275  // sample recorder
276  if(sample_out)
277  {
278  hrv.push_back(ergo::make_sample_recorder(*sample_out));
279  mrv.push_back(ergo::make_sample_recorder(*sample_out));
280  }
281 
282  // proposal recorder
283  if(proposed_out)
284  {
285  hrv.push_back(ergo::make_proposed_recorder(*proposed_out));
286  mrv.push_back(ergo::make_proposed_recorder(*proposed_out));
287  traj_step.store_proposed();
288  size_step.store_proposed();
289  }
290 
291  // proposal detail recorder
292  if(pd_out)
293  {
294  hrv.push_back(make_pd_recorder(*pd_out, *posterior_p_));
295  mrv.push_back(make_pd_recorder(*pd_out, *posterior_p_));
296  traj_step.store_proposed();
297  size_step.store_proposed();
298  }
299 
300  // run steps
301  run_steps(
302  cur_scene,
303  cur_lt,
304  traj_step,
305  hrv.begin(),
306  hrv.end(),
307  size_step,
308  mrv.begin(),
309  mrv.end());
310 
311  // swap in best trajectories
312  Ascn::const_iterator tg_p = best_scene.association.begin();
313  BOOST_FOREACH(const Target& itarget, initial_scene.association)
314  {
315  const Target& btarget = *tg_p++;
316 
317  using std::swap;
318  swap(btarget.trajectory(), itarget.trajectory());
319  swap(btarget.body_trajectory(), itarget.body_trajectory());
320  swap(btarget.face_trajectory(), itarget.face_trajectory());
321  }
322 
323 #else
324  KJB_THROW_2(Missing_dependency, "libergo");
325 #endif
326 }
327 
328 /* \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ */
329 
330 #ifdef KJB_HAVE_ERGO
331 
332 template<class TrajStep, class TRecIter, class SRecIter>
333 void Sample_scenes::run_steps
334 (
335  Scene& scene,
336  double& lt,
337  //const TrajStep& traj_step,
338  TrajStep& traj_step,
339  TRecIter tfirst,
340  TRecIter tlast,
341  const Mh_step& size_step,
342  SRecIter sfirst,
343  SRecIter slast
344 ) const
345 {
346  bool rss = all_new_targets(scene);
347 
348  int D = dims(scene, true);
349  //size_t num_iterations = std::max(5, D / 20);
350  //size_t num_iterations = std::max(5, D / 5);
351  size_t num_iterations = std::max(5, D / 10);
352  std::cout << "\t\t\t\tscene size: " << std::setw(4) << D << " iters: " << num_iterations << std::endl;
353  double best_lt = lt;
354  double prev_best_lt = lt;
355  for(size_t i = 1; i <= num_iterations; i++)
356  {
357  // run hmc step and record
358  traj_step(scene, lt);
359  /*if(traj_step.acceptance_probability() < -10)
360  {
361  std::vector<double> step_sizes = traj_step.step_sizes();
362  if(step_sizes[0] > 1e-5)
363  {
364  double ratio = std::pow((i+1), 2.0);
365  std::transform(step_sizes.begin(),
366  step_sizes.end(),
367  step_sizes.begin(),
368  std::bind2nd(std::divides<double>(), ratio));
369  traj_step.reset(step_sizes);
370  std::cout << "new step: " << step_sizes[0] << std::endl;
371  }
372  }*/
373  for(TRecIter rec_p = tfirst; rec_p != tlast; ++rec_p)
374  {
375  (*rec_p)(traj_step, scene, lt);
376  }
377 
378  // run mh step and record
379  if(rss)
380  {
381  size_step(scene, lt);
382  for(SRecIter rec_p = sfirst; rec_p != slast; ++rec_p)
383  {
384  (*rec_p)(size_step, scene, lt);
385  }
386  }
387  if(lt > best_lt) best_lt = lt;
388 
389  if((i + 1) % 10 == 0)
390  {
391  if(best_lt > prev_best_lt)
392  prev_best_lt = best_lt;
393  else break;
394  }
395  }
396 }
397 
398 #endif
399 
400 }} // namespace kjb::pt
401 
402 #endif /*PT_SAMPLE_SCENES_H */
403 
Definition: mcmcda_proposer.h:57
void set_gradient_step_size(double pss)
Set the gradient approximation step sizes.
Definition: pt_sample_scenes.h:147
void set_num_leapfrog_steps(size_t lf_steps)
Set the number of leapfrog steps.
Definition: pt_sample_scenes.h:138
Adapts a Scene into a VectorModel for HMC sampling.
Definition: pt_scene_adapter.h:183
Int_matrix::Value_type max(const Int_matrix &mat)
Return the maximum value in this matrix.
Definition: l_int_matrix.h:1397
Definition of various standard probability distributions.
Parent::const_iterator const_iterator
Definition: mcmcda_association.h:122
bool all_new_targets(const Scene &scene)
Helper fcn; returns true if the scene has only new targets.
Definition: pt_sample_scenes.cpp:46
Definition: pt_sample_scenes.h:99
const Scene_posterior & scene_posterior() const
Get posterior distribution.
Definition: pt_sample_scenes.h:120
Trajectory & trajectory() const
Get this target's current 3D positions.
Definition: pt_target.h:85
Class that represents a full scene in the PT universe.
Definition: pt_scene.h:40
void swap(Scene &s1, Scene &s2)
Swap two scenes.
Definition: pt_scene.h:69
Face_2d_trajectory & face_trajectory() const
Get this target's current 2D body trajectory.
Definition: pt_target.h:97
void set_scene_posterior(const Scene_posterior &post)
Set posterior distribution.
Definition: pt_sample_scenes.h:123
Definition: pt_sample_scenes.h:99
void set_hmc_step_size(double pss)
Set the HMC step sizes.
Definition: pt_sample_scenes.h:144
Posterior_detail_recorder< OutputIterator > make_pd_recorder(OutputIterator it, const Scene_posterior &post)
Convenience function to create a Posterior_detail_recorder.
Definition: pt_recorder.h:76
size_t dims(const Scene &scene, bool respect_changed=true, bool infer_head=true)
Computes the number of variables in this scene.
Definition: pt_scene.cpp:106
void set_size_proposal_sigmas(double hsdv, double wsdv, double gsdv)
Set the MH proposal sigmas.
Definition: pt_sample_scenes.h:154
Propose_person_size(double hsdv, double wsdv, double gsdv, bool infer_head=true)
Definition: pt_sample_scenes.h:69
Sample_method
Definition: pt_sample_scenes.h:99
Class that represents a target moving through space.
Definition: pt_target.h:50
void set_num_iterations(size_t num_its)
Set the number of iterations and the fraction of HMC steps (vis-a-vis MH steps).
Definition: pt_sample_scenes.h:135
Use HMC to draw samples from the scene posterior using HMC.
Definition: pt_sample_scenes.h:96
Body_2d_trajectory & body_trajectory() const
Get this target's current 2D body trajectory.
Definition: pt_target.h:91
#define KJB_THROW_2(ex, msg)
Definition: l_exception.h:48
Posterior distribution of a scene.
Definition: pt_scene_posterior.h:53
ergo::mh_step< Scene > Mh_step
Definition: pt_sample_scenes.h:101
void swap(kjb::Gsl_Multimin_fdf &m1, kjb::Gsl_Multimin_fdf &m2)
Swap two wrapped multimin objects.
Definition: gsl_multimin.h:693
boost::math::normal Normal_distribution
Definition: prob_distribution.h:68
size_t size(const Scene *s) const
Get the number of elements in this scene.
Definition: pt_scene_adapter.h:233
void set_sample_method(Sample_method method)
Set the sampling method.
Definition: pt_sample_scenes.h:129
get the indices of edges in each direction for i
Definition: APPgetLargeConnectedEdges.m:48
Sample_scenes(const Scene_posterior &posterior, bool infer_head)
Definition: pt_sample_scenes.h:104
D
Definition: APPgetLargeConnectedEdges.m:106
Support for error handling exception classes in libKJB.
Object thrown when a program lacks required resources or libraries.
Definition: l_exception.h:539
Proposal distribution/mechanism for the size of targets.
Definition: pt_sample_scenes.h:65
ergo::hmc_step< Scene > Hmc_step
Definition: pt_sample_scenes.h:100