{"action":"created","issue":{"url":"https://api.github.com/repos/BVLC/caffe/issues/1976","labels_url":"https://api.github.com/repos/BVLC/caffe/issues/1976/labels{/name}","comments_url":"https://api.github.com/repos/BVLC/caffe/issues/1976/comments","events_url":"https://api.github.com/repos/BVLC/caffe/issues/1976/events","html_url":"https://github.com/BVLC/caffe/pull/1976","id":58994145,"number":1976,"title":"Crop layer for automatically aligning computations","user":{"login":"shelhamer","id":311113,"avatar_url":"https://avatars.githubusercontent.com/u/311113?v=3","gravatar_id":"","url":"https://api.github.com/users/shelhamer","html_url":"https://github.com/shelhamer","followers_url":"https://api.github.com/users/shelhamer/followers","following_url":"https://api.github.com/users/shelhamer/following{/other_user}","gists_url":"https://api.github.com/users/shelhamer/gists{/gist_id}","starred_url":"https://api.github.com/users/shelhamer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/shelhamer/subscriptions","organizations_url":"https://api.github.com/users/shelhamer/orgs","repos_url":"https://api.github.com/users/shelhamer/repos","events_url":"https://api.github.com/users/shelhamer/events{/privacy}","received_events_url":"https://api.github.com/users/shelhamer/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/BVLC/caffe/labels/focus","name":"focus","color":"006b75"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-02-26T00:21:51Z","updated_at":"2015-09-26T07:33:07Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/BVLC/caffe/pulls/1976","html_url":"https://github.com/BVLC/caffe/pull/1976","diff_url":"https://github.com/BVLC/caffe/pull/1976.diff","patch_url":"https://github.com/BVLC/caffe/pull/1976.patch"},"body":"`master` edition of #1639 -- thanks to a rebase by @philkr. After #1974 and #1975.\r\n\r\nExisting layers shift and warp coordinate space: translation by padding (or lack thereof), contraction by strided convolution or pooling, and expansion by strided deconvolution (#1615). Often one wants to align two blobs, e.g., to establish a correspondence between input and output, or to fuse two different paths of computation. Counting conv/deconv strides to ensure that blob coordinates have the same scale is generally straightforward. Computing the offset between two blobs that results from intermediate padding and kernel sizes is trickier.\r\n\r\nThis layer takes two bottom blobs and produces one top, which is a copy of the first bottom cropped to the size of the second so that coordinates exactly correspond, i.e., it makes sense to fuse or compare the top blob with the second bottom, regardless of whatever padding or other shenanigans took place between their computation.\r\n\r\nThis is done by computing the coordinate mapping between the two bottom blobs, as provided by #1637 and made accessible by #1638. If that mapping is a simple translation, and has the right sign to allow the first blob to be \"cropped to\" the second, the layer simply performs the copy. If the mapping is not an integer translation, or the translation has the wrong sign, an error is thrown, and the net may be rearranged to allow sensible fusion.\r\n\r\nThe implementation of `LayerSetUp` amounts to some simple graph traversal to find the path connecting the two bottoms. Currently `Net` does not provide great facilities for traversing the layer graph, so it's a bit cumbersome; maybe this can be improved in the future.\r\n\r\nThere is a bit of engineering involved in these three PRs, but the result is pretty convenient: what was before a tricky offline calculation becomes a trivial layer specification.\r\n\r\nAnother way to implement this, without #1974, would be to remove the graph traversal from `CropLayer`, giving it a simple parameter instead, and provide some other mechanism for automatically filling in that parameter.\r\n\r\nCurrently CPU and GPU (trivially) are provided, but tests and documentation are not."},"comment":{"url":"https://api.github.com/repos/BVLC/caffe/issues/comments/143406623","html_url":"https://github.com/BVLC/caffe/pull/1976#issuecomment-143406623","issue_url":"https://api.github.com/repos/BVLC/caffe/issues/1976","id":143406623,"user":{"login":"longjon","id":940817,"avatar_url":"https://avatars.githubusercontent.com/u/940817?v=3","gravatar_id":"","url":"https://api.github.com/users/longjon","html_url":"https://github.com/longjon","followers_url":"https://api.github.com/users/longjon/followers","following_url":"https://api.github.com/users/longjon/following{/other_user}","gists_url":"https://api.github.com/users/longjon/gists{/gist_id}","starred_url":"https://api.github.com/users/longjon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/longjon/subscriptions","organizations_url":"https://api.github.com/users/longjon/orgs","repos_url":"https://api.github.com/users/longjon/repos","events_url":"https://api.github.com/users/longjon/events{/privacy}","received_events_url":"https://api.github.com/users/longjon/received_events","type":"User","site_admin":false},"created_at":"2015-09-26T07:33:07Z","updated_at":"2015-09-26T07:33:07Z","body":"For those watching, this is due for an update with a less intrusive version (like the \"another way\" above) that takes advantage of net spec, after which I think it'll be ready for merge.\r\n\r\n@waldol1, yes, that's a good point about the extra allocation. Unfortunately you can't really specify a layer name in a parameter (without some extra mechanism), since that breaks the layer abstraction (a layer has no way to access other layers (without the backpointer to its net, which is present here but removed in the \"less intrusive version\" above) except through its top and bottom links). Let's think more about the right way to address that!"}}