{"action":"created","issue":{"url":"https://api.github.com/repos/BVLC/caffe/issues/2842","labels_url":"https://api.github.com/repos/BVLC/caffe/issues/2842/labels{/name}","comments_url":"https://api.github.com/repos/BVLC/caffe/issues/2842/comments","events_url":"https://api.github.com/repos/BVLC/caffe/issues/2842/events","html_url":"https://github.com/BVLC/caffe/pull/2842","id":98464261,"number":2842,"title":"add functionality to name tops in python-net spec","user":{"login":"jmerkow","id":5933681,"avatar_url":"https://avatars.githubusercontent.com/u/5933681?v=3","gravatar_id":"","url":"https://api.github.com/users/jmerkow","html_url":"https://github.com/jmerkow","followers_url":"https://api.github.com/users/jmerkow/followers","following_url":"https://api.github.com/users/jmerkow/following{/other_user}","gists_url":"https://api.github.com/users/jmerkow/gists{/gist_id}","starred_url":"https://api.github.com/users/jmerkow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jmerkow/subscriptions","organizations_url":"https://api.github.com/users/jmerkow/orgs","repos_url":"https://api.github.com/users/jmerkow/repos","events_url":"https://api.github.com/users/jmerkow/events{/privacy}","received_events_url":"https://api.github.com/users/jmerkow/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-07-31T20:18:50Z","updated_at":"2015-07-31T22:42:31Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/BVLC/caffe/pulls/2842","html_url":"https://github.com/BVLC/caffe/pull/2842","diff_url":"https://github.com/BVLC/caffe/pull/2842.diff","patch_url":"https://github.com/BVLC/caffe/pull/2842.patch"},"body":"This PR allows you to name tops, explicitly.  You can name all, none or some of the tops.  It will default to autonames for unnamed tops.\r\nIf you do not specify ntops, it will infer from the number of top names given.\r\nTwo examples:\r\n```python\r\nimport caffe\r\nfrom caffe import layers as L, params as P, to_proto\r\nfrom caffe.proto import caffe_pb2\r\nfrom __future__ import print_function\r\ndef caffenet_name_all():\r\n    data,label  = L.DummyData(name=\"data\",top=[\"data\",\"label\"],\r\n                              dummy_data_param=dict(shape=[dict(dim=[1,2,3])]))\r\n    loss = L.SigmoidCrossEntropyLoss(data, label,name=\"loss\",top=[\"SCEloss\"])\r\n    return to_proto(loss)\r\ndef caffenet_name_few():\r\n    data,label  = L.DummyData(name=\"data\",ntop=2,top=[\"data\"],\r\n                              dummy_data_param=dict(shape=[dict(dim=[1,2,3])]))\r\n    loss = L.SigmoidCrossEntropyLoss(data, label,name=\"loss\",top=[\"SCEloss\"])\r\n    return to_proto(loss)\r\n\r\ndef make_net():\r\n    with open('train-all.prototxt', 'w') as f:\r\n        print(caffenet_name_all(), file=f)\r\n    with open('train-few.prototxt', 'w') as f:\r\n        print(caffenet_name_few(), file=f)\r\n```\r\n\r\nproduces: \r\ntrain-all.prototxt\r\n\r\n```\r\nlayer {\r\n  name: \"data\"\r\n  type: \"DummyData\"\r\n  top: \"data\"\r\n  top: \"label\"\r\n  dummy_data_param {\r\n    shape {\r\n      dim: 1\r\n      dim: 2\r\n      dim: 3\r\n    }\r\n  }\r\n}\r\nlayer {\r\n  name: \"loss\"\r\n  type: \"SigmoidCrossEntropyLoss\"\r\n  bottom: \"data\"\r\n  bottom: \"label\"\r\n  top: \"SCEloss\"\r\n}\r\n```\r\ntrain-few.prototxt\r\n```\r\nlayer {\r\n  name: \"data\"\r\n  type: \"DummyData\"\r\n  top: \"data\"\r\n  top: \"DummyData1\"\r\n  dummy_data_param {\r\n    shape {\r\n      dim: 1\r\n      dim: 2\r\n      dim: 3\r\n    }\r\n  }\r\n}\r\nlayer {\r\n  name: \"loss\"\r\n  type: \"SigmoidCrossEntropyLoss\"\r\n  bottom: \"data\"\r\n  bottom: \"DummyData1\"\r\n  top: \"SCEloss\"\r\n}\r\n```\r\n\r\nThanks!\r\n--Jameson\r\n\r\nP.S. Thanks to @BlGene for help figuring out why dummy data wasn't working. You gave be the one thing I didn't try!\r\n\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/BVLC/caffe/issues/comments/126829240","html_url":"https://github.com/BVLC/caffe/pull/2842#issuecomment-126829240","issue_url":"https://api.github.com/repos/BVLC/caffe/issues/2842","id":126829240,"user":{"login":"jmerkow","id":5933681,"avatar_url":"https://avatars.githubusercontent.com/u/5933681?v=3","gravatar_id":"","url":"https://api.github.com/users/jmerkow","html_url":"https://github.com/jmerkow","followers_url":"https://api.github.com/users/jmerkow/followers","following_url":"https://api.github.com/users/jmerkow/following{/other_user}","gists_url":"https://api.github.com/users/jmerkow/gists{/gist_id}","starred_url":"https://api.github.com/users/jmerkow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jmerkow/subscriptions","organizations_url":"https://api.github.com/users/jmerkow/orgs","repos_url":"https://api.github.com/users/jmerkow/repos","events_url":"https://api.github.com/users/jmerkow/events{/privacy}","received_events_url":"https://api.github.com/users/jmerkow/received_events","type":"User","site_admin":false},"created_at":"2015-07-31T22:42:31Z","updated_at":"2015-07-31T22:42:31Z","body":"I did not see that in the tests.\r\nYes, this allows you too do it without netspec for one. I ran that test, and they don't seem to interfere.\r\n\r\nSecondly, you can use this PR to dynamically name units without dealing with setattr after the fact since this could would be cumbersome. \r\nSay for example, you want 'groups' (or units) that are very similar in structure.\r\nYou can create a function that reads in the group name/id and then leaves the internal naming to the def.\r\n\r\ni.e. Something like this:\r\n\r\n```python\r\ndef GenGroup(bottom,grpname):\r\n    conv1 = L.Convolution(bottom, kernel_size=3, num_output=64,\r\n        weight_filler=dict(type='xavier'),top=[grpname+\"_conv\"])\r\n    relu1 = L.ReLU(conv1, in_place=True)\r\n    return L.Pooling(relu1, kernel_size=2, stride=2, pool=P.Pooling.MAX,top=[grpname+\"_pool\"])\r\nn = caffe.NetSpec()\r\nn.data, n.label = L.DummyData(shape=[dict(dim=[1, 1, 32, 32]),\r\n                                     dict(dim=[1, 1, 32, 32])],\r\n                          transform_param=dict(scale=1./255), ntop=2)\r\nunit = []\r\nunit.append(n.data)\r\nfor i in range(0,3):\r\n    unit.append(GenGroup(unit[-1],\"unit\"+str(i)))\r\nn.loss = L.SoftmaxWithLoss(unit[-1], n.label)\r\nprint(n.to_proto())\r\n```\r\nproduces:\r\n```\r\nlayer {\r\n  name: \"data\"\r\n  type: \"DummyData\"\r\n  top: \"data\"\r\n  top: \"label\"\r\n  transform_param {\r\n    scale: 0.00392156862745\r\n  }\r\n  dummy_data_param {\r\n    shape {\r\n      dim: 1\r\n      dim: 1\r\n      dim: 32\r\n      dim: 32\r\n    }\r\n    shape {\r\n      dim: 1\r\n      dim: 1\r\n      dim: 32\r\n      dim: 32\r\n    }\r\n  }\r\n}\r\nlayer {\r\n  name: \"unit0_conv\"\r\n  type: \"Convolution\"\r\n  bottom: \"data\"\r\n  top: \"unit0_conv\"\r\n  convolution_param {\r\n    num_output: 64\r\n    kernel_size: 3\r\n    weight_filler {\r\n      type: \"xavier\"\r\n    }\r\n  }\r\n}\r\nlayer {\r\n  name: \"ReLU1\"\r\n  type: \"ReLU\"\r\n  bottom: \"unit0_conv\"\r\n  top: \"unit0_conv\"\r\n}\r\nlayer {\r\n  name: \"unit0_pool\"\r\n  type: \"Pooling\"\r\n  bottom: \"unit0_conv\"\r\n  top: \"unit0_pool\"\r\n  pooling_param {\r\n    pool: MAX\r\n    kernel_size: 2\r\n    stride: 2\r\n  }\r\n}\r\nlayer {\r\n  name: \"unit1_conv\"\r\n  type: \"Convolution\"\r\n  bottom: \"unit0_pool\"\r\n  top: \"unit1_conv\"\r\n  convolution_param {\r\n    num_output: 64\r\n    kernel_size: 3\r\n    weight_filler {\r\n      type: \"xavier\"\r\n    }\r\n  }\r\n}\r\nlayer {\r\n  name: \"ReLU2\"\r\n  type: \"ReLU\"\r\n  bottom: \"unit1_conv\"\r\n  top: \"unit1_conv\"\r\n}\r\nlayer {\r\n  name: \"unit1_pool\"\r\n  type: \"Pooling\"\r\n  bottom: \"unit1_conv\"\r\n  top: \"unit1_pool\"\r\n  pooling_param {\r\n    pool: MAX\r\n    kernel_size: 2\r\n    stride: 2\r\n  }\r\n}\r\nlayer {\r\n  name: \"unit2_conv\"\r\n  type: \"Convolution\"\r\n  bottom: \"unit1_pool\"\r\n  top: \"unit2_conv\"\r\n  convolution_param {\r\n    num_output: 64\r\n    kernel_size: 3\r\n    weight_filler {\r\n      type: \"xavier\"\r\n    }\r\n  }\r\n}\r\nlayer {\r\n  name: \"ReLU3\"\r\n  type: \"ReLU\"\r\n  bottom: \"unit2_conv\"\r\n  top: \"unit2_conv\"\r\n}\r\nlayer {\r\n  name: \"unit2_pool\"\r\n  type: \"Pooling\"\r\n  bottom: \"unit2_conv\"\r\n  top: \"unit2_pool\"\r\n  pooling_param {\r\n    pool: MAX\r\n    kernel_size: 2\r\n    stride: 2\r\n  }\r\n}\r\nlayer {\r\n  name: \"loss\"\r\n  type: \"SoftmaxWithLoss\"\r\n  bottom: \"unit2_pool\"\r\n  bottom: \"label\"\r\n  top: \"loss\"\r\n```\r\n\r\nYou don't need to know the current net, all you need it a top to link to.\r\n--Jameson\r\n"}}