|
105 | 105 |
|
106 | 106 | LayerType = type('LayerType', (), {t : t for t in LAYER_TYPES})
|
107 | 107 |
|
108 |
| -KernelParameters = namedtuple('KernelParameters', ['k_h', 'k_w', 's_h', 's_w', 'p_h', 'p_w']) |
| 108 | +KernelParameters = namedtuple('KernelParameters', ['global_pooling', 'k_h', 'k_w', 's_h', 's_w', 'p_h', 'p_w']) |
109 | 109 |
|
110 | 110 | class NodeKind(LayerType):
|
111 | 111 |
|
@@ -185,45 +185,50 @@ def get_kernel_value(scalar, repeated, idx, default=None):
|
185 | 185 | def kernel_parameters(self):
|
186 | 186 | assert self.kind in (NodeKind.Convolution, NodeKind.Pooling, NodeKind.Deconvolution)
|
187 | 187 | params = self.parameters
|
188 |
| - k_h = self.get_kernel_value(params.kernel_h, params.kernel_size, 0) |
189 |
| - k_w = self.get_kernel_value(params.kernel_w, params.kernel_size, 1) |
190 |
| - s_h = self.get_kernel_value(params.stride_h, params.stride, 0, default=1) |
191 |
| - s_w = self.get_kernel_value(params.stride_w, params.stride, 1, default=1) |
| 188 | + global_pooling = hasattr(params, 'global_pooling') and params.global_pooling |
| 189 | + if not global_pooling: |
| 190 | + k_h = self.get_kernel_value(params.kernel_h, params.kernel_size, 0) |
| 191 | + k_w = self.get_kernel_value(params.kernel_w, params.kernel_size, 1) |
| 192 | + s_h = self.get_kernel_value(params.stride_h, params.stride, 0, default=1) |
| 193 | + s_w = self.get_kernel_value(params.stride_w, params.stride, 1, default=1) |
| 194 | + else: |
| 195 | + k_h = k_w = 0 |
| 196 | + s_h = s_w = 1 |
192 | 197 | p_h = self.get_kernel_value(params.pad_h, params.pad, 0, default=0)
|
193 | 198 | p_w = self.get_kernel_value(params.pad_h, params.pad, 1, default=0)
|
194 |
| - return KernelParameters(k_h, k_w, s_h, s_w, p_h, p_w) |
| 199 | + return KernelParameters(global_pooling, k_h, k_w, s_h, s_w, p_h, p_w) |
195 | 200 |
|
196 | 201 | def __str__(self):
|
197 | 202 | return '[%s] %s' % (self.kind, self.name)
|
198 |
| - |
| 203 | + |
199 | 204 | def __repr__(self):
|
200 | 205 | return '%s (0x%x)' %(self.name, id(self))
|
201 | 206 |
|
202 | 207 |
|
203 | 208 | class CaffeGraph(object):
|
204 |
| - |
| 209 | + |
205 | 210 | def __init__(self, nodes=None, name=None):
|
206 | 211 | self.nodes = nodes or []
|
207 | 212 | self.node_lut = {node.name: node for node in self.nodes}
|
208 | 213 | self.name = name
|
209 | 214 | self.prototxt = None
|
210 |
| - |
| 215 | + |
211 | 216 | def add_node(self, node):
|
212 | 217 | self.nodes.append(node)
|
213 | 218 | self.node_lut[node.name] = node
|
214 |
| - |
| 219 | + |
215 | 220 | def get_node(self, name):
|
216 | 221 | try:
|
217 | 222 | return self.node_lut[name]
|
218 | 223 | except KeyError:
|
219 | 224 | raise ConversionError('Layer not found: %s' % name)
|
220 |
| - |
| 225 | + |
221 | 226 | def get_input_nodes(self):
|
222 | 227 | return [node for node in self.nodes if len(node.parents) == 0]
|
223 | 228 |
|
224 | 229 | def get_output_nodes(self):
|
225 | 230 | return [node for node in self.nodes if len(node.children) == 0]
|
226 |
| - |
| 231 | + |
227 | 232 | def topologically_sorted(self):
|
228 | 233 | visited = set()
|
229 | 234 | sorted_nodes = []
|
@@ -263,11 +268,11 @@ def compute_output_shapes(self, model):
|
263 | 268 | else:
|
264 | 269 | for node in sorted_nodes:
|
265 | 270 | node.output_shape = TensorShape(*NodeKind.compute_output_shape(node))
|
266 |
| - |
| 271 | + |
267 | 272 | # consider rewrite this function to Network.py
|
268 | 273 | def replaced(self, new_nodes):
|
269 | 274 | return CaffeGraph(nodes=new_nodes, name=self.name)
|
270 |
| - |
| 275 | + |
271 | 276 | def transformed(self, transformers):
|
272 | 277 | graph = self
|
273 | 278 | for transformer in transformers:
|
@@ -316,7 +321,7 @@ def load(self):
|
316 | 321 | text_format.Merge(f.read(), self.model)
|
317 | 322 | if self.is_train_proto:
|
318 | 323 | self.process_train_proto()
|
319 |
| - |
| 324 | + |
320 | 325 | def process_train_proto(self):
|
321 | 326 | layers = self.model.layer or self.model.layers
|
322 | 327 | delete_layer = set()
|
@@ -359,7 +364,7 @@ def process_train_proto(self):
|
359 | 364 | elif kind == NodeKind.SigmoidCrossEntropyLoss:
|
360 | 365 | pred.type = NodeKind.Sigmoid if self.model.layer else 19
|
361 | 366 | layers.remove(last_layer)
|
362 |
| - |
| 367 | + |
363 | 368 | def filter_layers(self, layers):
|
364 | 369 | phase_map = {0: 'train', 1: 'test'}
|
365 | 370 | filtered_layer_names = set()
|
@@ -388,7 +393,7 @@ def filter_layers(self, layers):
|
388 | 393 | return filtered_layers
|
389 | 394 |
|
390 | 395 | def make_node(self, layer):
|
391 |
| - kind = NodeKind.map_raw_kind(layer.type) |
| 396 | + kind = NodeKind.map_raw_kind(layer.type) |
392 | 397 | if kind is None:
|
393 | 398 | # TODO: raise error
|
394 | 399 | pass
|
|
0 commit comments