{"action":"created","comment":{"url":"https://api.github.com/repos/pymc-devs/pymc3/pulls/comments/92720405","pull_request_review_id":13241725,"id":92720405,"diff_hunk":"@@ -0,0 +1,264 @@\n+import collections\n+import functools\n+import theano.tensor as tt\n+import theano\n+from ..theanof import tt_rng\n+from ..distributions.dist_math import rho2sd, log_normal3\n+from ..math import flatten\n+import numpy as np\n+\n+\n+def replace_out(func):\n+    @functools.wraps(func)\n+    def wrapped(self, *args, **kwargs):\n+        out = func(self, *args, **kwargs)\n+        return self.apply_replacements(out)\n+    return wrapped\n+\n+\n+class BaseReplacement(object):\n+    def __init__(self, model, population=None, known=None):\n+        if known is None:\n+            known = dict()\n+        if population is None:\n+            population = dict()\n+        self.population = population\n+        self.model = model\n+        self.known = known\n+        s, g, l = self.create_mapping()\n+        self.stochastic_replacements = s\n+        self.global_dict = g\n+        self.local_dict = l\n+\n+    def new_global_dict(self):\n+        \"\"\"\n+        :return: dict\n+        \"\"\"\n+        raise NotImplementedError\n+\n+    def new_local_dict(self):\n+        \"\"\"\n+        :return: dict\n+        \"\"\"\n+        local_dict = dict(\n+            means=collections.OrderedDict(),\n+            rhos=collections.OrderedDict(),\n+            x=list(),\n+            replacement=self.__class__.__name__\n+        )\n+        return local_dict\n+\n+    def new_rep_glob_loc(self):\n+        \"\"\"\n+        :return: empty_replacements, new_global_dict, new_local_dict\n+        \"\"\"\n+        return collections.OrderedDict(), self.new_global_dict(), self.new_local_dict()\n+\n+    @staticmethod\n+    def known_node(local_dict, node, *args):\n+        \"\"\"\n+        :param local_dict: placeholder for local params\n+        :param node: node to be replaced\n+        :param args: mu, rho\n+        :return: replacement for given node\n+        \"\"\"\n+        mu, rho = args\n+        e = tt_rng().normal(rho.shape)\n+        v = mu + rho2sd(rho) * e\n+        local_dict['means'][node.name] = mu\n+        local_dict['rhos'][node.name] = rho\n+        local_dict['x'].append(v)\n+        return v\n+\n+    def create_mapping(self):\n+        \"\"\"Implements creation of new replacements and parameters\n+        Returns\n+        -------\n+        replacements, global_dict, local_dict\n+        \"\"\"\n+        raise NotImplementedError\n+\n+    @property\n+    def deterministic_replacements(self):\n+        \"\"\"\n+        :return: dict\n+        \"\"\"\n+        replacements = collections.OrderedDict()\n+        replacements.update(self.deterministic_replacements_global)\n+        replacements.update(self.deterministic_replacements_local)\n+        return replacements\n+\n+    @property\n+    def deterministic_replacements_local(self):\n+        \"\"\"\n+        :return: dict\n+        \"\"\"\n+        return collections.OrderedDict(\n+            [(self.model[k], v) for k, v in self.local_dict['means'].items()]\n+        )\n+\n+    @property\n+    def deterministic_replacements_global(self):\n+        \"\"\"\n+        :return: dict\n+        \"\"\"\n+        raise NotImplementedError\n+\n+    @property\n+    def params(self):\n+        \"\"\"\n+        :return: list - shared params to fit\n+        \"\"\"\n+        return self.params_local + self.params_global\n+\n+    @property\n+    def params_local(self):\n+        \"\"\"\n+        :return: list - shared params for local replacements\n+        \"\"\"\n+        return []\n+\n+    @property\n+    def params_global(self):\n+        \"\"\"\n+        :return: list - shared params for global replacements\n+        \"\"\"\n+        raise NotImplementedError\n+\n+    @property\n+    @replace_out\n+    def log_q_W_local(self):\n+        x = flatten(self.local_dict['x'])\n+        mu = flatten(self.local_dict['means'].values())\n+        rho = flatten(self.local_dict['rhos'].values())\n+        _log_q_W_local_ = tt.sum(log_normal3(x, mu, rho))\n+        return _log_q_W_local_\n+\n+    @property\n+    def log_q_W_global(self):\n+        raise NotImplementedError\n+\n+    @property\n+    def log_q_W(self):\n+        return self.log_q_W_global + self.log_q_W_local\n+\n+    @property\n+    @replace_out\n+    def log_p_D(self):\n+        _log_p_D_ = tt.add(\n+            *map(self.weighted_likelihood, self.model.observed_RVs)\n+        )\n+        return _log_p_D_\n+\n+    @property\n+    @replace_out\n+    def log_p_W(self):\n+        _log_p_W_ = self.model.varlogpt + tt.sum(self.model.potentials)\n+        return _log_p_W_\n+\n+    def apply_replacements(self, node, deterministic=False):\n+        if deterministic:\n+            return theano.clone(\n+                node, self.deterministic_replacements, strict=False)\n+        else:\n+            return theano.clone(\n+                node, self.stochastic_replacements, strict=False)\n+\n+    def weighted_likelihood(self, var):\n+        tot = self.population.get(\n+            var, self.population.get(var.name))\n+        logpt = tt.sum(var.logpt)\n+        if tot is not None:\n+            tot = tt.as_tensor(tot)\n+            logpt *= tot\n+            logpt /= var.size\n+        return logpt\n+\n+    def sample_elbo(self, samples=1, pi=1):\n+        samples = tt.as_tensor(samples)\n+        pi = tt.as_tensor(pi)\n+        _elbo_ = self.log_p_D + pi * (self.log_p_W - self.log_q_W)\n+        elbos, updates = theano.scan(fn=lambda: _elbo_,","path":"pymc3/variational/replacements.py","position":181,"original_position":181,"commit_id":"5e68b95f0e5dec4f903480ca73e11b165409b3ee","original_commit_id":"5e68b95f0e5dec4f903480ca73e11b165409b3ee","user":{"login":"springcoil","id":983944,"avatar_url":"https://avatars.githubusercontent.com/u/983944?v=3","gravatar_id":"","url":"https://api.github.com/users/springcoil","html_url":"https://github.com/springcoil","followers_url":"https://api.github.com/users/springcoil/followers","following_url":"https://api.github.com/users/springcoil/following{/other_user}","gists_url":"https://api.github.com/users/springcoil/gists{/gist_id}","starred_url":"https://api.github.com/users/springcoil/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/springcoil/subscriptions","organizations_url":"https://api.github.com/users/springcoil/orgs","repos_url":"https://api.github.com/users/springcoil/repos","events_url":"https://api.github.com/users/springcoil/events{/privacy}","received_events_url":"https://api.github.com/users/springcoil/received_events","type":"User","site_admin":false},"body":"Good use of the theano.scan functionality, and hidden well in the API.","created_at":"2016-12-15T23:06:43Z","updated_at":"2016-12-15T23:06:44Z","html_url":"https://github.com/pymc-devs/pymc3/pull/1600#discussion_r92720405","pull_request_url":"https://api.github.com/repos/pymc-devs/pymc3/pulls/1600","_links":{"self":{"href":"https://api.github.com/repos/pymc-devs/pymc3/pulls/comments/92720405"},"html":{"href":"https://github.com/pymc-devs/pymc3/pull/1600#discussion_r92720405"},"pull_request":{"href":"https://api.github.com/repos/pymc-devs/pymc3/pulls/1600"}}},"pull_request":{"url":"https://api.github.com/repos/pymc-devs/pymc3/pulls/1600","id":97789933,"html_url":"https://github.com/pymc-devs/pymc3/pull/1600","diff_url":"https://github.com/pymc-devs/pymc3/pull/1600.diff","patch_url":"https://github.com/pymc-devs/pymc3/pull/1600.patch","issue_url":"https://api.github.com/repos/pymc-devs/pymc3/issues/1600","number":1600,"state":"open","locked":false,"title":"Added base class for variational methods","user":{"login":"ferrine","id":11705326,"avatar_url":"https://avatars.githubusercontent.com/u/11705326?v=3","gravatar_id":"","url":"https://api.github.com/users/ferrine","html_url":"https://github.com/ferrine","followers_url":"https://api.github.com/users/ferrine/followers","following_url":"https://api.github.com/users/ferrine/following{/other_user}","gists_url":"https://api.github.com/users/ferrine/gists{/gist_id}","starred_url":"https://api.github.com/users/ferrine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ferrine/subscriptions","organizations_url":"https://api.github.com/users/ferrine/orgs","repos_url":"https://api.github.com/users/ferrine/repos","events_url":"https://api.github.com/users/ferrine/events{/privacy}","received_events_url":"https://api.github.com/users/ferrine/received_events","type":"User","site_admin":false},"body":"Because of upcomming Normalizing flows and Stain variational gradient descent I propose a unified interface for variational methods","created_at":"2016-12-13T16:48:50Z","updated_at":"2016-12-15T23:06:44Z","closed_at":null,"merged_at":null,"merge_commit_sha":"bd09f39bf4822b4a71dc916e27b4e4973d7435c7","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/pymc-devs/pymc3/pulls/1600/commits","review_comments_url":"https://api.github.com/repos/pymc-devs/pymc3/pulls/1600/comments","review_comment_url":"https://api.github.com/repos/pymc-devs/pymc3/pulls/comments{/number}","comments_url":"https://api.github.com/repos/pymc-devs/pymc3/issues/1600/comments","statuses_url":"https://api.github.com/repos/pymc-devs/pymc3/statuses/5e68b95f0e5dec4f903480ca73e11b165409b3ee","head":{"label":"ferrine:refactor_advi","ref":"refactor_advi","sha":"5e68b95f0e5dec4f903480ca73e11b165409b3ee","user":{"login":"ferrine","id":11705326,"avatar_url":"https://avatars.githubusercontent.com/u/11705326?v=3","gravatar_id":"","url":"https://api.github.com/users/ferrine","html_url":"https://github.com/ferrine","followers_url":"https://api.github.com/users/ferrine/followers","following_url":"https://api.github.com/users/ferrine/following{/other_user}","gists_url":"https://api.github.com/users/ferrine/gists{/gist_id}","starred_url":"https://api.github.com/users/ferrine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ferrine/subscriptions","organizations_url":"https://api.github.com/users/ferrine/orgs","repos_url":"https://api.github.com/users/ferrine/repos","events_url":"https://api.github.com/users/ferrine/events{/privacy}","received_events_url":"https://api.github.com/users/ferrine/received_events","type":"User","site_admin":false},"repo":{"id":65422489,"name":"pymc3","full_name":"ferrine/pymc3","owner":{"login":"ferrine","id":11705326,"avatar_url":"https://avatars.githubusercontent.com/u/11705326?v=3","gravatar_id":"","url":"https://api.github.com/users/ferrine","html_url":"https://github.com/ferrine","followers_url":"https://api.github.com/users/ferrine/followers","following_url":"https://api.github.com/users/ferrine/following{/other_user}","gists_url":"https://api.github.com/users/ferrine/gists{/gist_id}","starred_url":"https://api.github.com/users/ferrine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ferrine/subscriptions","organizations_url":"https://api.github.com/users/ferrine/orgs","repos_url":"https://api.github.com/users/ferrine/repos","events_url":"https://api.github.com/users/ferrine/events{/privacy}","received_events_url":"https://api.github.com/users/ferrine/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ferrine/pymc3","description":"Probabilistic Programming in Python. Uses Theano as a backend, supports NUTS and ADVI.","fork":true,"url":"https://api.github.com/repos/ferrine/pymc3","forks_url":"https://api.github.com/repos/ferrine/pymc3/forks","keys_url":"https://api.github.com/repos/ferrine/pymc3/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ferrine/pymc3/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ferrine/pymc3/teams","hooks_url":"https://api.github.com/repos/ferrine/pymc3/hooks","issue_events_url":"https://api.github.com/repos/ferrine/pymc3/issues/events{/number}","events_url":"https://api.github.com/repos/ferrine/pymc3/events","assignees_url":"https://api.github.com/repos/ferrine/pymc3/assignees{/user}","branches_url":"https://api.github.com/repos/ferrine/pymc3/branches{/branch}","tags_url":"https://api.github.com/repos/ferrine/pymc3/tags","blobs_url":"https://api.github.com/repos/ferrine/pymc3/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ferrine/pymc3/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ferrine/pymc3/git/refs{/sha}","trees_url":"https://api.github.com/repos/ferrine/pymc3/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ferrine/pymc3/statuses/{sha}","languages_url":"https://api.github.com/repos/ferrine/pymc3/languages","stargazers_url":"https://api.github.com/repos/ferrine/pymc3/stargazers","contributors_url":"https://api.github.com/repos/ferrine/pymc3/contributors","subscribers_url":"https://api.github.com/repos/ferrine/pymc3/subscribers","subscription_url":"https://api.github.com/repos/ferrine/pymc3/subscription","commits_url":"https://api.github.com/repos/ferrine/pymc3/commits{/sha}","git_commits_url":"https://api.github.com/repos/ferrine/pymc3/git/commits{/sha}","comments_url":"https://api.github.com/repos/ferrine/pymc3/comments{/number}","issue_comment_url":"https://api.github.com/repos/ferrine/pymc3/issues/comments{/number}","contents_url":"https://api.github.com/repos/ferrine/pymc3/contents/{+path}","compare_url":"https://api.github.com/repos/ferrine/pymc3/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ferrine/pymc3/merges","archive_url":"https://api.github.com/repos/ferrine/pymc3/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ferrine/pymc3/downloads","issues_url":"https://api.github.com/repos/ferrine/pymc3/issues{/number}","pulls_url":"https://api.github.com/repos/ferrine/pymc3/pulls{/number}","milestones_url":"https://api.github.com/repos/ferrine/pymc3/milestones{/number}","notifications_url":"https://api.github.com/repos/ferrine/pymc3/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ferrine/pymc3/labels{/name}","releases_url":"https://api.github.com/repos/ferrine/pymc3/releases{/id}","deployments_url":"https://api.github.com/repos/ferrine/pymc3/deployments","created_at":"2016-08-10T23:13:40Z","updated_at":"2016-08-10T23:13:48Z","pushed_at":"2016-12-15T22:45:01Z","git_url":"git://github.com/ferrine/pymc3.git","ssh_url":"git@github.com:ferrine/pymc3.git","clone_url":"https://github.com/ferrine/pymc3.git","svn_url":"https://github.com/ferrine/pymc3","homepage":"http://pymc-devs.github.io/pymc3/","size":141258,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"pymc-devs:3.1","ref":"3.1","sha":"32a2eb7e3711b2e8de22ad76cc4532b03cd6af55","user":{"login":"pymc-devs","id":81121,"avatar_url":"https://avatars.githubusercontent.com/u/81121?v=3","gravatar_id":"","url":"https://api.github.com/users/pymc-devs","html_url":"https://github.com/pymc-devs","followers_url":"https://api.github.com/users/pymc-devs/followers","following_url":"https://api.github.com/users/pymc-devs/following{/other_user}","gists_url":"https://api.github.com/users/pymc-devs/gists{/gist_id}","starred_url":"https://api.github.com/users/pymc-devs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pymc-devs/subscriptions","organizations_url":"https://api.github.com/users/pymc-devs/orgs","repos_url":"https://api.github.com/users/pymc-devs/repos","events_url":"https://api.github.com/users/pymc-devs/events{/privacy}","received_events_url":"https://api.github.com/users/pymc-devs/received_events","type":"Organization","site_admin":false},"repo":{"id":192904,"name":"pymc3","full_name":"pymc-devs/pymc3","owner":{"login":"pymc-devs","id":81121,"avatar_url":"https://avatars.githubusercontent.com/u/81121?v=3","gravatar_id":"","url":"https://api.github.com/users/pymc-devs","html_url":"https://github.com/pymc-devs","followers_url":"https://api.github.com/users/pymc-devs/followers","following_url":"https://api.github.com/users/pymc-devs/following{/other_user}","gists_url":"https://api.github.com/users/pymc-devs/gists{/gist_id}","starred_url":"https://api.github.com/users/pymc-devs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pymc-devs/subscriptions","organizations_url":"https://api.github.com/users/pymc-devs/orgs","repos_url":"https://api.github.com/users/pymc-devs/repos","events_url":"https://api.github.com/users/pymc-devs/events{/privacy}","received_events_url":"https://api.github.com/users/pymc-devs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/pymc-devs/pymc3","description":"Probabilistic Programming in Python: Bayesian Modeling and Probabilistic Machine Learning with Theano","fork":false,"url":"https://api.github.com/repos/pymc-devs/pymc3","forks_url":"https://api.github.com/repos/pymc-devs/pymc3/forks","keys_url":"https://api.github.com/repos/pymc-devs/pymc3/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pymc-devs/pymc3/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pymc-devs/pymc3/teams","hooks_url":"https://api.github.com/repos/pymc-devs/pymc3/hooks","issue_events_url":"https://api.github.com/repos/pymc-devs/pymc3/issues/events{/number}","events_url":"https://api.github.com/repos/pymc-devs/pymc3/events","assignees_url":"https://api.github.com/repos/pymc-devs/pymc3/assignees{/user}","branches_url":"https://api.github.com/repos/pymc-devs/pymc3/branches{/branch}","tags_url":"https://api.github.com/repos/pymc-devs/pymc3/tags","blobs_url":"https://api.github.com/repos/pymc-devs/pymc3/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pymc-devs/pymc3/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pymc-devs/pymc3/git/refs{/sha}","trees_url":"https://api.github.com/repos/pymc-devs/pymc3/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pymc-devs/pymc3/statuses/{sha}","languages_url":"https://api.github.com/repos/pymc-devs/pymc3/languages","stargazers_url":"https://api.github.com/repos/pymc-devs/pymc3/stargazers","contributors_url":"https://api.github.com/repos/pymc-devs/pymc3/contributors","subscribers_url":"https://api.github.com/repos/pymc-devs/pymc3/subscribers","subscription_url":"https://api.github.com/repos/pymc-devs/pymc3/subscription","commits_url":"https://api.github.com/repos/pymc-devs/pymc3/commits{/sha}","git_commits_url":"https://api.github.com/repos/pymc-devs/pymc3/git/commits{/sha}","comments_url":"https://api.github.com/repos/pymc-devs/pymc3/comments{/number}","issue_comment_url":"https://api.github.com/repos/pymc-devs/pymc3/issues/comments{/number}","contents_url":"https://api.github.com/repos/pymc-devs/pymc3/contents/{+path}","compare_url":"https://api.github.com/repos/pymc-devs/pymc3/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pymc-devs/pymc3/merges","archive_url":"https://api.github.com/repos/pymc-devs/pymc3/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pymc-devs/pymc3/downloads","issues_url":"https://api.github.com/repos/pymc-devs/pymc3/issues{/number}","pulls_url":"https://api.github.com/repos/pymc-devs/pymc3/pulls{/number}","milestones_url":"https://api.github.com/repos/pymc-devs/pymc3/milestones{/number}","notifications_url":"https://api.github.com/repos/pymc-devs/pymc3/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pymc-devs/pymc3/labels{/name}","releases_url":"https://api.github.com/repos/pymc-devs/pymc3/releases{/id}","deployments_url":"https://api.github.com/repos/pymc-devs/pymc3/deployments","created_at":"2009-05-05T09:43:50Z","updated_at":"2016-12-15T18:34:02Z","pushed_at":"2016-12-15T22:45:01Z","git_url":"git://github.com/pymc-devs/pymc3.git","ssh_url":"git@github.com:pymc-devs/pymc3.git","clone_url":"https://github.com/pymc-devs/pymc3.git","svn_url":"https://github.com/pymc-devs/pymc3","homepage":"http://pymc-devs.github.io/pymc3/","size":168030,"stargazers_count":1775,"watchers_count":1775,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":422,"mirror_url":null,"open_issues_count":141,"forks":422,"open_issues":141,"watchers":1775,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/pymc-devs/pymc3/pulls/1600"},"html":{"href":"https://github.com/pymc-devs/pymc3/pull/1600"},"issue":{"href":"https://api.github.com/repos/pymc-devs/pymc3/issues/1600"},"comments":{"href":"https://api.github.com/repos/pymc-devs/pymc3/issues/1600/comments"},"review_comments":{"href":"https://api.github.com/repos/pymc-devs/pymc3/pulls/1600/comments"},"review_comment":{"href":"https://api.github.com/repos/pymc-devs/pymc3/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/pymc-devs/pymc3/pulls/1600/commits"},"statuses":{"href":"https://api.github.com/repos/pymc-devs/pymc3/statuses/5e68b95f0e5dec4f903480ca73e11b165409b3ee"}}}}
{"actor":{"display_login":"springcoil"}}