{"action":"created","comment":{"url":"https://api.github.com/repos/Theano/Theano/pulls/comments/135626687","pull_request_review_id":59059602,"id":135626687,"diff_hunk":"@@ -0,0 +1,413 @@\n+\"\"\"\n+Concrete spatial transformer implementation\n+\"\"\"\n+from __future__ import absolute_import, print_function, division\n+\n+import theano\n+from theano.gof.op import Op\n+from theano.scalar import as_scalar\n+from theano.tensor import as_tensor_variable\n+from theano.tensor.extra_ops import cpu_contiguous\n+from theano.gof import Apply\n+from theano.gradient import grad_not_implemented\n+import numpy as np\n+\n+\n+def sampling_grid(height, width):\n+    # Create sampling grid\n+    x_t, y_t = np.meshgrid(np.linspace(-1, 1, width),\n+                           np.linspace(-1, 1, height))\n+    ones = np.ones(np.prod(x_t.shape))\n+    grid = np.vstack([x_t.flatten(), y_t.flatten(), ones])\n+    return grid\n+\n+\n+class TransformerGrid(Op):\n+    def make_node(self, theta, out_dims):\n+        _theta = cpu_contiguous(as_tensor_variable(theta))\n+\n+        if _theta.ndim != 3:\n+            raise TypeError('SpatialTransformerGrid (make_node) requires theta to '\n+                            'be a 3D tensor; received \"%s\" (%i dims)' %\n+                            (theta, _theta.ndim))\n+\n+        assert _theta.type.dtype in ('float16', 'float32', 'float64')\n+\n+        _out_dims = cpu_contiguous(as_tensor_variable(out_dims))\n+        _out_dims = theano.tensor.basic.cast(out_dims, 'int64')\n+\n+        _grid = theano.tensor.tensor(dtype=_theta.type.dtype,\n+                                     broadcastable=len(out_dims) * (False,))\n+\n+        return Apply(self, [_theta, _out_dims], [_grid])\n+\n+    def perform(self, node, inputs, output_storage):\n+        theta, out_dims = inputs\n+\n+        assert len(out_dims) == 4\n+        # Theta should be in the format (batch_size, 2, 3)\n+        assert len(theta.shape) == 3\n+        assert (theta.shape[1] == 2) and (theta.shape[2] == 3)\n+        # Check if theta has the same batch size as out_dims\n+        assert theta.shape[0] == out_dims[0]\n+\n+        num_batch = theta.shape[0]\n+        grid_out = output_storage[0]\n+\n+        out_height, out_width = out_dims[2:]\n+        grid = sampling_grid(out_height, out_width)\n+        # Generate transformed grid with shape (num_batch, 2, out_height * out_width)\n+        transformed_grid = np.dot(theta, grid)\n+        # Dimshuffle grid into (2, num_batch, out_height * out_width)\n+        transposed_grid = np.transpose(transformed_grid, axes=(1, 0, 2))\n+        # Reshape into (2, num_batch, out_height, out_width)\n+        grid_out[0] = np.reshape(transposed_grid, (2, num_batch, out_height, out_width)).astype(theta.dtype)","path":"theano/tensor/nnet/spatialtf.py","position":64,"original_position":64,"commit_id":"9d2fdcbf3c5eeb866b4c5932188fdbe09b0096ca","original_commit_id":"9d2fdcbf3c5eeb866b4c5932188fdbe09b0096ca","user":{"login":"joaovictortr","id":17904001,"avatar_url":"https://avatars0.githubusercontent.com/u/17904001?v=4","gravatar_id":"","url":"https://api.github.com/users/joaovictortr","html_url":"https://github.com/joaovictortr","followers_url":"https://api.github.com/users/joaovictortr/followers","following_url":"https://api.github.com/users/joaovictortr/following{/other_user}","gists_url":"https://api.github.com/users/joaovictortr/gists{/gist_id}","starred_url":"https://api.github.com/users/joaovictortr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joaovictortr/subscriptions","organizations_url":"https://api.github.com/users/joaovictortr/orgs","repos_url":"https://api.github.com/users/joaovictortr/repos","events_url":"https://api.github.com/users/joaovictortr/events{/privacy}","received_events_url":"https://api.github.com/users/joaovictortr/received_events","type":"User","site_admin":false},"body":"It eases the CPU computations and (I assumed it) makes the grid data contiguous, but it can easily reverted to the same format as in the GPU. Otherwise, a dimshuffle is required when lifting to the GPU, as you've stated. I'll change it to use same format as the GPU.","created_at":"2017-08-28T20:33:09Z","updated_at":"2017-08-28T20:33:09Z","html_url":"https://github.com/Theano/Theano/pull/6298#discussion_r135626687","pull_request_url":"https://api.github.com/repos/Theano/Theano/pulls/6298","_links":{"self":{"href":"https://api.github.com/repos/Theano/Theano/pulls/comments/135626687"},"html":{"href":"https://github.com/Theano/Theano/pull/6298#discussion_r135626687"},"pull_request":{"href":"https://api.github.com/repos/Theano/Theano/pulls/6298"}},"in_reply_to_id":135617261},"pull_request":{"url":"https://api.github.com/repos/Theano/Theano/pulls/6298","id":135260265,"html_url":"https://github.com/Theano/Theano/pull/6298","diff_url":"https://github.com/Theano/Theano/pull/6298.diff","patch_url":"https://github.com/Theano/Theano/pull/6298.patch","issue_url":"https://api.github.com/repos/Theano/Theano/issues/6298","number":6298,"state":"open","locked":false,"title":"[WIP] CPU Spatial Transformer","user":{"login":"joaovictortr","id":17904001,"avatar_url":"https://avatars0.githubusercontent.com/u/17904001?v=4","gravatar_id":"","url":"https://api.github.com/users/joaovictortr","html_url":"https://github.com/joaovictortr","followers_url":"https://api.github.com/users/joaovictortr/followers","following_url":"https://api.github.com/users/joaovictortr/following{/other_user}","gists_url":"https://api.github.com/users/joaovictortr/gists{/gist_id}","starred_url":"https://api.github.com/users/joaovictortr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joaovictortr/subscriptions","organizations_url":"https://api.github.com/users/joaovictortr/orgs","repos_url":"https://api.github.com/users/joaovictortr/repos","events_url":"https://api.github.com/users/joaovictortr/events{/privacy}","received_events_url":"https://api.github.com/users/joaovictortr/received_events","type":"User","site_admin":false},"body":"Tasks:\r\n* [x] Abstract spatial transformer Op\r\n* [x] Optimization to lift spatial transformer Op to CPU implementation\r\n* [x] Optimization to lift spatial transformer Op to GPU implementation\r\n* [x] Unit test the spatial transformer Op\r\n* [x] Compute gradients of inputs in the CPU\r\n* [ ] Compute gradients of affine transformation in the CPU\r\n* [ ] Unit test the gradient implementations","created_at":"2017-08-11T03:06:22Z","updated_at":"2017-08-28T20:33:09Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9a18ce59be4192563c3f5f690929d6896637baa2","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/Theano/Theano/pulls/6298/commits","review_comments_url":"https://api.github.com/repos/Theano/Theano/pulls/6298/comments","review_comment_url":"https://api.github.com/repos/Theano/Theano/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Theano/Theano/issues/6298/comments","statuses_url":"https://api.github.com/repos/Theano/Theano/statuses/9d2fdcbf3c5eeb866b4c5932188fdbe09b0096ca","head":{"label":"joaovictortr:spatialtf_cpu","ref":"spatialtf_cpu","sha":"9d2fdcbf3c5eeb866b4c5932188fdbe09b0096ca","user":{"login":"joaovictortr","id":17904001,"avatar_url":"https://avatars0.githubusercontent.com/u/17904001?v=4","gravatar_id":"","url":"https://api.github.com/users/joaovictortr","html_url":"https://github.com/joaovictortr","followers_url":"https://api.github.com/users/joaovictortr/followers","following_url":"https://api.github.com/users/joaovictortr/following{/other_user}","gists_url":"https://api.github.com/users/joaovictortr/gists{/gist_id}","starred_url":"https://api.github.com/users/joaovictortr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joaovictortr/subscriptions","organizations_url":"https://api.github.com/users/joaovictortr/orgs","repos_url":"https://api.github.com/users/joaovictortr/repos","events_url":"https://api.github.com/users/joaovictortr/events{/privacy}","received_events_url":"https://api.github.com/users/joaovictortr/received_events","type":"User","site_admin":false},"repo":{"id":81968810,"name":"Theano","full_name":"joaovictortr/Theano","owner":{"login":"joaovictortr","id":17904001,"avatar_url":"https://avatars0.githubusercontent.com/u/17904001?v=4","gravatar_id":"","url":"https://api.github.com/users/joaovictortr","html_url":"https://github.com/joaovictortr","followers_url":"https://api.github.com/users/joaovictortr/followers","following_url":"https://api.github.com/users/joaovictortr/following{/other_user}","gists_url":"https://api.github.com/users/joaovictortr/gists{/gist_id}","starred_url":"https://api.github.com/users/joaovictortr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joaovictortr/subscriptions","organizations_url":"https://api.github.com/users/joaovictortr/orgs","repos_url":"https://api.github.com/users/joaovictortr/repos","events_url":"https://api.github.com/users/joaovictortr/events{/privacy}","received_events_url":"https://api.github.com/users/joaovictortr/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/joaovictortr/Theano","description":"Theano is a Python library that allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. It can use GPUs and perform efficient symbolic differentiation.","fork":true,"url":"https://api.github.com/repos/joaovictortr/Theano","forks_url":"https://api.github.com/repos/joaovictortr/Theano/forks","keys_url":"https://api.github.com/repos/joaovictortr/Theano/keys{/key_id}","collaborators_url":"https://api.github.com/repos/joaovictortr/Theano/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/joaovictortr/Theano/teams","hooks_url":"https://api.github.com/repos/joaovictortr/Theano/hooks","issue_events_url":"https://api.github.com/repos/joaovictortr/Theano/issues/events{/number}","events_url":"https://api.github.com/repos/joaovictortr/Theano/events","assignees_url":"https://api.github.com/repos/joaovictortr/Theano/assignees{/user}","branches_url":"https://api.github.com/repos/joaovictortr/Theano/branches{/branch}","tags_url":"https://api.github.com/repos/joaovictortr/Theano/tags","blobs_url":"https://api.github.com/repos/joaovictortr/Theano/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/joaovictortr/Theano/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/joaovictortr/Theano/git/refs{/sha}","trees_url":"https://api.github.com/repos/joaovictortr/Theano/git/trees{/sha}","statuses_url":"https://api.github.com/repos/joaovictortr/Theano/statuses/{sha}","languages_url":"https://api.github.com/repos/joaovictortr/Theano/languages","stargazers_url":"https://api.github.com/repos/joaovictortr/Theano/stargazers","contributors_url":"https://api.github.com/repos/joaovictortr/Theano/contributors","subscribers_url":"https://api.github.com/repos/joaovictortr/Theano/subscribers","subscription_url":"https://api.github.com/repos/joaovictortr/Theano/subscription","commits_url":"https://api.github.com/repos/joaovictortr/Theano/commits{/sha}","git_commits_url":"https://api.github.com/repos/joaovictortr/Theano/git/commits{/sha}","comments_url":"https://api.github.com/repos/joaovictortr/Theano/comments{/number}","issue_comment_url":"https://api.github.com/repos/joaovictortr/Theano/issues/comments{/number}","contents_url":"https://api.github.com/repos/joaovictortr/Theano/contents/{+path}","compare_url":"https://api.github.com/repos/joaovictortr/Theano/compare/{base}...{head}","merges_url":"https://api.github.com/repos/joaovictortr/Theano/merges","archive_url":"https://api.github.com/repos/joaovictortr/Theano/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/joaovictortr/Theano/downloads","issues_url":"https://api.github.com/repos/joaovictortr/Theano/issues{/number}","pulls_url":"https://api.github.com/repos/joaovictortr/Theano/pulls{/number}","milestones_url":"https://api.github.com/repos/joaovictortr/Theano/milestones{/number}","notifications_url":"https://api.github.com/repos/joaovictortr/Theano/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/joaovictortr/Theano/labels{/name}","releases_url":"https://api.github.com/repos/joaovictortr/Theano/releases{/id}","deployments_url":"https://api.github.com/repos/joaovictortr/Theano/deployments","created_at":"2017-02-14T17:05:19Z","updated_at":"2017-06-30T21:37:52Z","pushed_at":"2017-08-28T19:26:45Z","git_url":"git://github.com/joaovictortr/Theano.git","ssh_url":"git@github.com:joaovictortr/Theano.git","clone_url":"https://github.com/joaovictortr/Theano.git","svn_url":"https://github.com/joaovictortr/Theano","homepage":"http://www.deeplearning.net/software/theano","size":64671,"stargazers_count":1,"watchers_count":1,"language":"Python","has_issues":false,"has_projects":true,"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":1,"default_branch":"master"}},"base":{"label":"Theano:master","ref":"master","sha":"9592125cdad4cd94605c3844a7f3d6541aa2098e","user":{"login":"Theano","id":970517,"avatar_url":"https://avatars2.githubusercontent.com/u/970517?v=4","gravatar_id":"","url":"https://api.github.com/users/Theano","html_url":"https://github.com/Theano","followers_url":"https://api.github.com/users/Theano/followers","following_url":"https://api.github.com/users/Theano/following{/other_user}","gists_url":"https://api.github.com/users/Theano/gists{/gist_id}","starred_url":"https://api.github.com/users/Theano/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Theano/subscriptions","organizations_url":"https://api.github.com/users/Theano/orgs","repos_url":"https://api.github.com/users/Theano/repos","events_url":"https://api.github.com/users/Theano/events{/privacy}","received_events_url":"https://api.github.com/users/Theano/received_events","type":"Organization","site_admin":false},"repo":{"id":2183193,"name":"Theano","full_name":"Theano/Theano","owner":{"login":"Theano","id":970517,"avatar_url":"https://avatars2.githubusercontent.com/u/970517?v=4","gravatar_id":"","url":"https://api.github.com/users/Theano","html_url":"https://github.com/Theano","followers_url":"https://api.github.com/users/Theano/followers","following_url":"https://api.github.com/users/Theano/following{/other_user}","gists_url":"https://api.github.com/users/Theano/gists{/gist_id}","starred_url":"https://api.github.com/users/Theano/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Theano/subscriptions","organizations_url":"https://api.github.com/users/Theano/orgs","repos_url":"https://api.github.com/users/Theano/repos","events_url":"https://api.github.com/users/Theano/events{/privacy}","received_events_url":"https://api.github.com/users/Theano/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Theano/Theano","description":"Theano is a Python library that allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. It can use GPUs and perform efficient symbolic differentiation.","fork":false,"url":"https://api.github.com/repos/Theano/Theano","forks_url":"https://api.github.com/repos/Theano/Theano/forks","keys_url":"https://api.github.com/repos/Theano/Theano/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Theano/Theano/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Theano/Theano/teams","hooks_url":"https://api.github.com/repos/Theano/Theano/hooks","issue_events_url":"https://api.github.com/repos/Theano/Theano/issues/events{/number}","events_url":"https://api.github.com/repos/Theano/Theano/events","assignees_url":"https://api.github.com/repos/Theano/Theano/assignees{/user}","branches_url":"https://api.github.com/repos/Theano/Theano/branches{/branch}","tags_url":"https://api.github.com/repos/Theano/Theano/tags","blobs_url":"https://api.github.com/repos/Theano/Theano/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Theano/Theano/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Theano/Theano/git/refs{/sha}","trees_url":"https://api.github.com/repos/Theano/Theano/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Theano/Theano/statuses/{sha}","languages_url":"https://api.github.com/repos/Theano/Theano/languages","stargazers_url":"https://api.github.com/repos/Theano/Theano/stargazers","contributors_url":"https://api.github.com/repos/Theano/Theano/contributors","subscribers_url":"https://api.github.com/repos/Theano/Theano/subscribers","subscription_url":"https://api.github.com/repos/Theano/Theano/subscription","commits_url":"https://api.github.com/repos/Theano/Theano/commits{/sha}","git_commits_url":"https://api.github.com/repos/Theano/Theano/git/commits{/sha}","comments_url":"https://api.github.com/repos/Theano/Theano/comments{/number}","issue_comment_url":"https://api.github.com/repos/Theano/Theano/issues/comments{/number}","contents_url":"https://api.github.com/repos/Theano/Theano/contents/{+path}","compare_url":"https://api.github.com/repos/Theano/Theano/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Theano/Theano/merges","archive_url":"https://api.github.com/repos/Theano/Theano/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Theano/Theano/downloads","issues_url":"https://api.github.com/repos/Theano/Theano/issues{/number}","pulls_url":"https://api.github.com/repos/Theano/Theano/pulls{/number}","milestones_url":"https://api.github.com/repos/Theano/Theano/milestones{/number}","notifications_url":"https://api.github.com/repos/Theano/Theano/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Theano/Theano/labels{/name}","releases_url":"https://api.github.com/repos/Theano/Theano/releases{/id}","deployments_url":"https://api.github.com/repos/Theano/Theano/deployments","created_at":"2011-08-10T03:48:06Z","updated_at":"2017-08-28T17:38:50Z","pushed_at":"2017-08-28T19:26:46Z","git_url":"git://github.com/Theano/Theano.git","ssh_url":"git@github.com:Theano/Theano.git","clone_url":"https://github.com/Theano/Theano.git","svn_url":"https://github.com/Theano/Theano","homepage":"http://www.deeplearning.net/software/theano","size":64697,"stargazers_count":6833,"watchers_count":6833,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2265,"mirror_url":null,"open_issues_count":689,"forks":2265,"open_issues":689,"watchers":6833,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Theano/Theano/pulls/6298"},"html":{"href":"https://github.com/Theano/Theano/pull/6298"},"issue":{"href":"https://api.github.com/repos/Theano/Theano/issues/6298"},"comments":{"href":"https://api.github.com/repos/Theano/Theano/issues/6298/comments"},"review_comments":{"href":"https://api.github.com/repos/Theano/Theano/pulls/6298/comments"},"review_comment":{"href":"https://api.github.com/repos/Theano/Theano/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Theano/Theano/pulls/6298/commits"},"statuses":{"href":"https://api.github.com/repos/Theano/Theano/statuses/9d2fdcbf3c5eeb866b4c5932188fdbe09b0096ca"}}}}
{"actor":{"display_login":"joaovictortr"}}