A Function specifies a layer, its parameters, and its inputs (which are Tops from other layers).
| 98 | |
| 99 | |
| 100 | class Function(object): |
| 101 | """A Function specifies a layer, its parameters, and its inputs (which |
| 102 | are Tops from other layers).""" |
| 103 | |
| 104 | def __init__(self, type_name, inputs, params): |
| 105 | self.type_name = type_name |
| 106 | for index, input in enumerate(inputs): |
| 107 | if not isinstance(input, Top): |
| 108 | raise TypeError('%s input %d is not a Top (type is %s)' % |
| 109 | (type_name, index, type(input))) |
| 110 | self.inputs = inputs |
| 111 | self.params = params |
| 112 | self.ntop = self.params.get('ntop', 1) |
| 113 | # use del to make sure kwargs are not double-processed as layer params |
| 114 | if 'ntop' in self.params: |
| 115 | del self.params['ntop'] |
| 116 | self.in_place = self.params.get('in_place', False) |
| 117 | if 'in_place' in self.params: |
| 118 | del self.params['in_place'] |
| 119 | self.tops = tuple(Top(self, n) for n in range(self.ntop)) |
| 120 | |
| 121 | def _get_name(self, names, autonames): |
| 122 | if self not in names and self.ntop > 0: |
| 123 | names[self] = self._get_top_name(self.tops[0], names, autonames) |
| 124 | elif self not in names: |
| 125 | autonames[self.type_name] += 1 |
| 126 | names[self] = self.type_name + str(autonames[self.type_name]) |
| 127 | return names[self] |
| 128 | |
| 129 | def _get_top_name(self, top, names, autonames): |
| 130 | if top not in names: |
| 131 | autonames[top.fn.type_name] += 1 |
| 132 | names[top] = top.fn.type_name + str(autonames[top.fn.type_name]) |
| 133 | return names[top] |
| 134 | |
| 135 | def _to_proto(self, layers, names, autonames): |
| 136 | if self in layers: |
| 137 | return |
| 138 | bottom_names = [] |
| 139 | for inp in self.inputs: |
| 140 | inp._to_proto(layers, names, autonames) |
| 141 | bottom_names.append(layers[inp.fn].top[inp.n]) |
| 142 | layer = caffe_pb2.LayerParameter() |
| 143 | layer.type = self.type_name |
| 144 | layer.bottom.extend(bottom_names) |
| 145 | |
| 146 | if self.in_place: |
| 147 | layer.top.extend(layer.bottom) |
| 148 | else: |
| 149 | for top in self.tops: |
| 150 | layer.top.append(self._get_top_name(top, names, autonames)) |
| 151 | layer.name = self._get_name(names, autonames) |
| 152 | |
| 153 | for k, v in six.iteritems(self.params): |
| 154 | # special case to handle generic *params |
| 155 | if k.endswith('param'): |
| 156 | assign_proto(layer, k, v) |
| 157 | else: |