{"action":"created","comment":{"url":"https://api.github.com/repos/uber/pyro/pulls/comments/232105483","pull_request_review_id":173228625,"id":232105483,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzMjEwNTQ4Mw==","diff_hunk":"@@ -227,102 +209,36 @@ def _find_reasonable_step_size(self, z):\n         while direction_new == direction:\n             step_size = step_size_scale * step_size\n             z_new, r_new, z_grads, potential_energy = velocity_verlet(\n-                z, r, self._potential_energy, self._inverse_mass_matrix, step_size)\n+                z, r, self._potential_energy, self.inverse_mass_matrix, step_size)\n             energy_new = potential_energy + self._kinetic_energy(r_new)\n             delta_energy = energy_new - energy_current\n             direction_new = 1 if self._direction_threshold < -delta_energy else -1\n         return step_size\n \n     def _configure_adaptation(self, trace):\n-        self._adapt_phase = True\n-        self._adapt_window = self._adapt_initial_window\n-\n+        initial_step_size = None\n         if self.adapt_step_size:\n             z = {name: node[\"value\"].detach() for name, node in self._iter_latent_nodes(trace)}\n             for name, transform in self.transforms.items():\n                 z[name] = transform(z[name])\n             with pyro.validation_enabled(False):\n-                self.step_size = self._find_reasonable_step_size(z)\n-            self.num_steps = max(1, int(self.trajectory_length / self.step_size))\n-            # make prox-center for Dual Averaging scheme\n-            loc = math.log(10 * self.step_size)\n-            self._step_size_adapt_scheme = DualAveraging(prox_center=loc)\n-\n-        # from Stan, for small warmup_steps\n-        if self._warmup_steps < 20:\n-            self._adapt_window_ending = self._warmup_steps\n-            return\n-\n-        if (self._adapt_start_buffer + self._adapt_end_buffer\n-                + self._adapt_initial_window > self._warmup_steps):\n-            self._adapt_start_buffer = int(0.15 * self._warmup_steps)\n-            self._adapt_end_buffer = int(0.1 * self._warmup_steps)\n-            self._adapt_window = (self._warmup_steps - self._adapt_start_buffer\n-                                  - self._adapt_end_buffer)\n-\n-        # define ending pointer of the current window\n-        self._adapt_window_ending = self._adapt_start_buffer\n-        self._adapt_mass_matrix_phase_ending = self._warmup_steps - self._adapt_end_buffer\n-\n-        if self.adapt_mass_matrix:\n-            is_diag = not self.full_mass\n-            self._mass_matrix_adapt_scheme = WelfordCovariance(diagonal=is_diag)\n-\n-    def _end_warmup(self):\n-        self._adapt_phase = False\n-        if self.adapt_step_size:\n-            _, log_step_size_avg = self._step_size_adapt_scheme.get_state()\n-            self.step_size = math.exp(log_step_size_avg)\n-            self.num_steps = max(1, int(self.trajectory_length / self.step_size))\n-\n-    def _end_adapt_window(self):\n-        if self._adapt_window_ending == self._warmup_steps:\n-            self._end_warmup()\n-            return\n-\n-        if self._adapt_window_ending == self._adapt_start_buffer:\n-            if self.adapt_mass_matrix:\n-                self._adapt_mass_matrix_phase = True\n-        else:\n-            if self.adapt_step_size:\n-                self._step_size_adapt_scheme.prox_center = math.log(10 * self.step_size)\n-                self._step_size_adapt_scheme.reset()\n-\n-            if self.adapt_mass_matrix:\n-                self._inverse_mass_matrix = self._mass_matrix_adapt_scheme.get_covariance()\n-                self._update_r_dist()\n-                self._mass_matrix_adapt_scheme.reset()\n-\n-            self._adapt_window = 2 * self._adapt_window\n-            if self._adapt_window_ending == self._adapt_mass_matrix_phase_ending:\n-                self._adapt_mass_matrix_phase = False\n-                self._adapt_window_ending = self._warmup_steps\n-                return\n+                initial_step_size = self._find_reasonable_step_size(z)\n \n-        self._adapt_window_ending = self._adapt_window_ending + self._adapt_window\n-        # expanding the current window if length of the next one is too large\n-        next_adapt_window_ending = self._adapt_window_ending + 2 * self._adapt_window\n-        if next_adapt_window_ending > self._adapt_mass_matrix_phase_ending:\n-            self._adapt_window_ending = self._adapt_mass_matrix_phase_ending\n-\n-    def _adapt_step_size(self, accept_prob):\n-        # calculate a statistic for Dual Averaging scheme\n-        H = self._target_accept_prob - accept_prob\n-        self._step_size_adapt_scheme.step(H)\n-        log_step_size, _ = self._step_size_adapt_scheme.get_state()\n-        self.step_size = math.exp(log_step_size)\n-        self.num_steps = max(1, int(self.trajectory_length / self.step_size))\n-\n-    def _update_r_dist(self):\n-        loc = self._inverse_mass_matrix.new_zeros(self._inverse_mass_matrix.size(0))\n-        if self.full_mass:\n-            self._r_dist = dist.MultivariateNormal(loc,\n-                                                   precision_matrix=self._inverse_mass_matrix)\n-        else:\n-            self._r_dist = dist.Normal(loc, self._inverse_mass_matrix.rsqrt())\n+        self._adapter.configure(self._warmup_steps,\n+                                self._initial_mass_matrix,\n+                                initial_step_size)\n \n     def _sample_r(self, name):\n-        r_flat = pyro.sample(name, self._r_dist)\n+        r_dist = self._adapter.r_dist\n+        # For finding a reasonable step size before adapter is initialized.\n+        if r_dist is None:\n+            inv_mass_matrix = self._initial_mass_matrix\n+            loc = inv_mass_matrix.new_zeros(inv_mass_matrix.size(0))\n+            if self.full_mass:\n+                r_dist = dist.MultivariateNormal(loc, precision_matrix=inv_mass_matrix)\n+            else:\n+                r_dist = dist.Normal(loc, inv_mass_matrix.rsqrt())","path":"pyro/infer/mcmc/hmc.py","position":223,"original_position":223,"commit_id":"9e9d3b1c29d1b8ac8337f017ef53ed9286a26203","original_commit_id":"9e9d3b1c29d1b8ac8337f017ef53ed9286a26203","user":{"login":"neerajprad","id":1762463,"node_id":"MDQ6VXNlcjE3NjI0NjM=","avatar_url":"https://avatars3.githubusercontent.com/u/1762463?v=4","gravatar_id":"","url":"https://api.github.com/users/neerajprad","html_url":"https://github.com/neerajprad","followers_url":"https://api.github.com/users/neerajprad/followers","following_url":"https://api.github.com/users/neerajprad/following{/other_user}","gists_url":"https://api.github.com/users/neerajprad/gists{/gist_id}","starred_url":"https://api.github.com/users/neerajprad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/neerajprad/subscriptions","organizations_url":"https://api.github.com/users/neerajprad/orgs","repos_url":"https://api.github.com/users/neerajprad/repos","events_url":"https://api.github.com/users/neerajprad/events{/privacy}","received_events_url":"https://api.github.com/users/neerajprad/received_events","type":"User","site_admin":false},"body":"Btw @fehiepsi - Feel free to directly commit to this PR if you notice something off!","created_at":"2018-11-09T00:07:55Z","updated_at":"2018-11-09T00:07:55Z","html_url":"https://github.com/uber/pyro/pull/1522#discussion_r232105483","pull_request_url":"https://api.github.com/repos/uber/pyro/pulls/1522","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/uber/pyro/pulls/comments/232105483"},"html":{"href":"https://github.com/uber/pyro/pull/1522#discussion_r232105483"},"pull_request":{"href":"https://api.github.com/repos/uber/pyro/pulls/1522"}},"in_reply_to_id":232103778},"pull_request":{"url":"https://api.github.com/repos/uber/pyro/pulls/1522","id":229531445,"node_id":"MDExOlB1bGxSZXF1ZXN0MjI5NTMxNDQ1","html_url":"https://github.com/uber/pyro/pull/1522","diff_url":"https://github.com/uber/pyro/pull/1522.diff","patch_url":"https://github.com/uber/pyro/pull/1522.patch","issue_url":"https://api.github.com/repos/uber/pyro/issues/1522","number":1522,"state":"open","locked":false,"title":"Abstract out HMC adaptation into its own class","user":{"login":"neerajprad","id":1762463,"node_id":"MDQ6VXNlcjE3NjI0NjM=","avatar_url":"https://avatars3.githubusercontent.com/u/1762463?v=4","gravatar_id":"","url":"https://api.github.com/users/neerajprad","html_url":"https://github.com/neerajprad","followers_url":"https://api.github.com/users/neerajprad/followers","following_url":"https://api.github.com/users/neerajprad/following{/other_user}","gists_url":"https://api.github.com/users/neerajprad/gists{/gist_id}","starred_url":"https://api.github.com/users/neerajprad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/neerajprad/subscriptions","organizations_url":"https://api.github.com/users/neerajprad/orgs","repos_url":"https://api.github.com/users/neerajprad/repos","events_url":"https://api.github.com/users/neerajprad/events{/privacy}","received_events_url":"https://api.github.com/users/neerajprad/received_events","type":"User","site_admin":false},"body":"Addresses #1520. \r\n\r\nThis refactors the step size and mass matrix adaptation into its own class. The motivation for this is to reduce the complexity in the HMC class that arises out of maintaining many stateful attributes during adaptation. The logic that previously resided here has been refactored to keep mutable attributes to a minimum, and moved to `WarmupAdapter`. \r\n\r\nWe are doing this by constructing an adaptation schedule instead and then moving within this schedule to take appropriate actions as needed. One minor departure from earlier might be that the slow adaptation windows are always monotonically increasing, i.e. the last slow window (before the end buffer) cannot be smaller than the penultimate one. This is to ensure that we are collecting enough number of samples for estimating the covariance.\r\n\r\n### Testing\r\nTest is added to check if the adaptation schedule is built correctly. Remaining tests should pass as is (or with minor changes) since this is a straight up refactor.\r\n\r\n### TODOs:\r\n - [ ] Ensure that there is no perf regression.\r\n - [ ] Understand test failures, if any; ensure that logic is largely the same as earlier. ","created_at":"2018-11-08T22:36:39Z","updated_at":"2018-11-09T00:07:55Z","closed_at":null,"merged_at":null,"merge_commit_sha":"44670035b72e9ada36755f9b6696d211abab4de4","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":704807577,"node_id":"MDU6TGFiZWw3MDQ4MDc1Nzc=","url":"https://api.github.com/repos/uber/pyro/labels/WIP","name":"WIP","color":"fbca04","default":false},{"id":634787400,"node_id":"MDU6TGFiZWw2MzQ3ODc0MDA=","url":"https://api.github.com/repos/uber/pyro/labels/discussion","name":"discussion","color":"fef2c0","default":false},{"id":995725240,"node_id":"MDU6TGFiZWw5OTU3MjUyNDA=","url":"https://api.github.com/repos/uber/pyro/labels/refactor","name":"refactor","color":"ffa0f2","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/uber/pyro/pulls/1522/commits","review_comments_url":"https://api.github.com/repos/uber/pyro/pulls/1522/comments","review_comment_url":"https://api.github.com/repos/uber/pyro/pulls/comments{/number}","comments_url":"https://api.github.com/repos/uber/pyro/issues/1522/comments","statuses_url":"https://api.github.com/repos/uber/pyro/statuses/9e9d3b1c29d1b8ac8337f017ef53ed9286a26203","head":{"label":"uber:hmc-adapt-refactor","ref":"hmc-adapt-refactor","sha":"9e9d3b1c29d1b8ac8337f017ef53ed9286a26203","user":{"login":"uber","id":538264,"node_id":"MDEyOk9yZ2FuaXphdGlvbjUzODI2NA==","avatar_url":"https://avatars3.githubusercontent.com/u/538264?v=4","gravatar_id":"","url":"https://api.github.com/users/uber","html_url":"https://github.com/uber","followers_url":"https://api.github.com/users/uber/followers","following_url":"https://api.github.com/users/uber/following{/other_user}","gists_url":"https://api.github.com/users/uber/gists{/gist_id}","starred_url":"https://api.github.com/users/uber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uber/subscriptions","organizations_url":"https://api.github.com/users/uber/orgs","repos_url":"https://api.github.com/users/uber/repos","events_url":"https://api.github.com/users/uber/events{/privacy}","received_events_url":"https://api.github.com/users/uber/received_events","type":"Organization","site_admin":false},"repo":{"id":94506832,"node_id":"MDEwOlJlcG9zaXRvcnk5NDUwNjgzMg==","name":"pyro","full_name":"uber/pyro","private":false,"owner":{"login":"uber","id":538264,"node_id":"MDEyOk9yZ2FuaXphdGlvbjUzODI2NA==","avatar_url":"https://avatars3.githubusercontent.com/u/538264?v=4","gravatar_id":"","url":"https://api.github.com/users/uber","html_url":"https://github.com/uber","followers_url":"https://api.github.com/users/uber/followers","following_url":"https://api.github.com/users/uber/following{/other_user}","gists_url":"https://api.github.com/users/uber/gists{/gist_id}","starred_url":"https://api.github.com/users/uber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uber/subscriptions","organizations_url":"https://api.github.com/users/uber/orgs","repos_url":"https://api.github.com/users/uber/repos","events_url":"https://api.github.com/users/uber/events{/privacy}","received_events_url":"https://api.github.com/users/uber/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/uber/pyro","description":"Deep universal probabilistic programming with Python and PyTorch","fork":false,"url":"https://api.github.com/repos/uber/pyro","forks_url":"https://api.github.com/repos/uber/pyro/forks","keys_url":"https://api.github.com/repos/uber/pyro/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uber/pyro/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uber/pyro/teams","hooks_url":"https://api.github.com/repos/uber/pyro/hooks","issue_events_url":"https://api.github.com/repos/uber/pyro/issues/events{/number}","events_url":"https://api.github.com/repos/uber/pyro/events","assignees_url":"https://api.github.com/repos/uber/pyro/assignees{/user}","branches_url":"https://api.github.com/repos/uber/pyro/branches{/branch}","tags_url":"https://api.github.com/repos/uber/pyro/tags","blobs_url":"https://api.github.com/repos/uber/pyro/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uber/pyro/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uber/pyro/git/refs{/sha}","trees_url":"https://api.github.com/repos/uber/pyro/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uber/pyro/statuses/{sha}","languages_url":"https://api.github.com/repos/uber/pyro/languages","stargazers_url":"https://api.github.com/repos/uber/pyro/stargazers","contributors_url":"https://api.github.com/repos/uber/pyro/contributors","subscribers_url":"https://api.github.com/repos/uber/pyro/subscribers","subscription_url":"https://api.github.com/repos/uber/pyro/subscription","commits_url":"https://api.github.com/repos/uber/pyro/commits{/sha}","git_commits_url":"https://api.github.com/repos/uber/pyro/git/commits{/sha}","comments_url":"https://api.github.com/repos/uber/pyro/comments{/number}","issue_comment_url":"https://api.github.com/repos/uber/pyro/issues/comments{/number}","contents_url":"https://api.github.com/repos/uber/pyro/contents/{+path}","compare_url":"https://api.github.com/repos/uber/pyro/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uber/pyro/merges","archive_url":"https://api.github.com/repos/uber/pyro/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uber/pyro/downloads","issues_url":"https://api.github.com/repos/uber/pyro/issues{/number}","pulls_url":"https://api.github.com/repos/uber/pyro/pulls{/number}","milestones_url":"https://api.github.com/repos/uber/pyro/milestones{/number}","notifications_url":"https://api.github.com/repos/uber/pyro/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uber/pyro/labels{/name}","releases_url":"https://api.github.com/repos/uber/pyro/releases{/id}","deployments_url":"https://api.github.com/repos/uber/pyro/deployments","created_at":"2017-06-16T05:03:47Z","updated_at":"2018-11-08T23:03:19Z","pushed_at":"2018-11-08T23:56:07Z","git_url":"git://github.com/uber/pyro.git","ssh_url":"git@github.com:uber/pyro.git","clone_url":"https://github.com/uber/pyro.git","svn_url":"https://github.com/uber/pyro","homepage":"http://pyro.ai","size":46100,"stargazers_count":4537,"watchers_count":4537,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":483,"mirror_url":null,"archived":false,"open_issues_count":95,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":483,"open_issues":95,"watchers":4537,"default_branch":"dev"}},"base":{"label":"uber:dev","ref":"dev","sha":"5ad3eacdadcd4d048a2ef07df7cac5cf8d01bf79","user":{"login":"uber","id":538264,"node_id":"MDEyOk9yZ2FuaXphdGlvbjUzODI2NA==","avatar_url":"https://avatars3.githubusercontent.com/u/538264?v=4","gravatar_id":"","url":"https://api.github.com/users/uber","html_url":"https://github.com/uber","followers_url":"https://api.github.com/users/uber/followers","following_url":"https://api.github.com/users/uber/following{/other_user}","gists_url":"https://api.github.com/users/uber/gists{/gist_id}","starred_url":"https://api.github.com/users/uber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uber/subscriptions","organizations_url":"https://api.github.com/users/uber/orgs","repos_url":"https://api.github.com/users/uber/repos","events_url":"https://api.github.com/users/uber/events{/privacy}","received_events_url":"https://api.github.com/users/uber/received_events","type":"Organization","site_admin":false},"repo":{"id":94506832,"node_id":"MDEwOlJlcG9zaXRvcnk5NDUwNjgzMg==","name":"pyro","full_name":"uber/pyro","private":false,"owner":{"login":"uber","id":538264,"node_id":"MDEyOk9yZ2FuaXphdGlvbjUzODI2NA==","avatar_url":"https://avatars3.githubusercontent.com/u/538264?v=4","gravatar_id":"","url":"https://api.github.com/users/uber","html_url":"https://github.com/uber","followers_url":"https://api.github.com/users/uber/followers","following_url":"https://api.github.com/users/uber/following{/other_user}","gists_url":"https://api.github.com/users/uber/gists{/gist_id}","starred_url":"https://api.github.com/users/uber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uber/subscriptions","organizations_url":"https://api.github.com/users/uber/orgs","repos_url":"https://api.github.com/users/uber/repos","events_url":"https://api.github.com/users/uber/events{/privacy}","received_events_url":"https://api.github.com/users/uber/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/uber/pyro","description":"Deep universal probabilistic programming with Python and PyTorch","fork":false,"url":"https://api.github.com/repos/uber/pyro","forks_url":"https://api.github.com/repos/uber/pyro/forks","keys_url":"https://api.github.com/repos/uber/pyro/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uber/pyro/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uber/pyro/teams","hooks_url":"https://api.github.com/repos/uber/pyro/hooks","issue_events_url":"https://api.github.com/repos/uber/pyro/issues/events{/number}","events_url":"https://api.github.com/repos/uber/pyro/events","assignees_url":"https://api.github.com/repos/uber/pyro/assignees{/user}","branches_url":"https://api.github.com/repos/uber/pyro/branches{/branch}","tags_url":"https://api.github.com/repos/uber/pyro/tags","blobs_url":"https://api.github.com/repos/uber/pyro/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uber/pyro/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uber/pyro/git/refs{/sha}","trees_url":"https://api.github.com/repos/uber/pyro/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uber/pyro/statuses/{sha}","languages_url":"https://api.github.com/repos/uber/pyro/languages","stargazers_url":"https://api.github.com/repos/uber/pyro/stargazers","contributors_url":"https://api.github.com/repos/uber/pyro/contributors","subscribers_url":"https://api.github.com/repos/uber/pyro/subscribers","subscription_url":"https://api.github.com/repos/uber/pyro/subscription","commits_url":"https://api.github.com/repos/uber/pyro/commits{/sha}","git_commits_url":"https://api.github.com/repos/uber/pyro/git/commits{/sha}","comments_url":"https://api.github.com/repos/uber/pyro/comments{/number}","issue_comment_url":"https://api.github.com/repos/uber/pyro/issues/comments{/number}","contents_url":"https://api.github.com/repos/uber/pyro/contents/{+path}","compare_url":"https://api.github.com/repos/uber/pyro/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uber/pyro/merges","archive_url":"https://api.github.com/repos/uber/pyro/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uber/pyro/downloads","issues_url":"https://api.github.com/repos/uber/pyro/issues{/number}","pulls_url":"https://api.github.com/repos/uber/pyro/pulls{/number}","milestones_url":"https://api.github.com/repos/uber/pyro/milestones{/number}","notifications_url":"https://api.github.com/repos/uber/pyro/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uber/pyro/labels{/name}","releases_url":"https://api.github.com/repos/uber/pyro/releases{/id}","deployments_url":"https://api.github.com/repos/uber/pyro/deployments","created_at":"2017-06-16T05:03:47Z","updated_at":"2018-11-08T23:03:19Z","pushed_at":"2018-11-08T23:56:07Z","git_url":"git://github.com/uber/pyro.git","ssh_url":"git@github.com:uber/pyro.git","clone_url":"https://github.com/uber/pyro.git","svn_url":"https://github.com/uber/pyro","homepage":"http://pyro.ai","size":46100,"stargazers_count":4537,"watchers_count":4537,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":483,"mirror_url":null,"archived":false,"open_issues_count":95,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":483,"open_issues":95,"watchers":4537,"default_branch":"dev"}},"_links":{"self":{"href":"https://api.github.com/repos/uber/pyro/pulls/1522"},"html":{"href":"https://github.com/uber/pyro/pull/1522"},"issue":{"href":"https://api.github.com/repos/uber/pyro/issues/1522"},"comments":{"href":"https://api.github.com/repos/uber/pyro/issues/1522/comments"},"review_comments":{"href":"https://api.github.com/repos/uber/pyro/pulls/1522/comments"},"review_comment":{"href":"https://api.github.com/repos/uber/pyro/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/uber/pyro/pulls/1522/commits"},"statuses":{"href":"https://api.github.com/repos/uber/pyro/statuses/9e9d3b1c29d1b8ac8337f017ef53ed9286a26203"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"neerajprad"}}