def to_pbuf_message(self, drop_phase=False): r""" Create a plain protobuf message from this object. Since this object is not derived from the protobuf objects, it is necessary to have this converter. Deriving is discouraged by the protobuf documentation and this object offers a lot more functionality. :param drop_phase: Bool. If set to ``True``, phase, level and stage are not serialized. Default: False. """ pblayers = [] for idx, layer in enumerate(self.layers): if idx == 0: pblayers.append(layer.to_pbuf_message(idx, None, self.inputs)) else: pblayers.append( layer.to_pbuf_message(idx, self.layers[idx - 1], self.inputs)) if drop_phase: pbstate = _caffe_pb2.NetState() else: pbstate = _caffe_pb2.NetState(phase=self.phase, level=self.level, stage=self.stages) if _HAS_BLOB_SHAPE: pbinput_shape = [ _caffe_pb2.BlobShape(dim=dims) for dims in self.input_shape ] netmessage = _caffe_pb2.NetParameter( name=self.name, input=self.inputs, input_shape=pbinput_shape, layer=pblayers, force_backward=self.force_backward, # noqa state=pbstate, debug_info=self.debug_info) else: # pragma: no cover shapes_to_use = [] for shape in self.input_shape: if len(shape) != 4: shape += [1] * (4 - len(shape)) shapes_to_use.append(shape) netmessage = _caffe_pb2.NetParameter( name=self.name, input=self.inputs, input_dim=_itertools.chain(*self.input_shape), layer=pblayers, force_backward=self.force_backward, # noqa state=pbstate, debug_info=self.debug_info) assert netmessage.IsInitialized() return netmessage
def TranslateModel(cls, caffe_net, pretrained_net, net_state=caffe_pb2.NetState()): net = caffe2_pb2.NetDef() net.name = caffe_net.name net_params = caffe2_pb2.TensorProtos() if len(caffe_net.layer) == 0: raise ValueError('I think something is wrong. This translation script ' 'only accepts new style layers that are stored in the ' 'layer field.') for layer in caffe_net.layer: if not _ShouldInclude(net_state, layer): print 'Current net state does not need layer', layer.name continue print 'Translate layer', layer.name # Get pretrained one pretrained_layers = ( [l for l in pretrained_net.layer if l.name == layer.name] + [l for l in pretrained_net.layers if l.name == layer.name]) if len(pretrained_layers) > 1: raise ValueError('huh? more than one pretrained layer of one name?') elif len(pretrained_layers) == 1: pretrained_blobs = [utils.CaffeBlobToNumpyArray(blob) for blob in pretrained_layers[0].blobs] else: # No pretrained layer for the given layer name. We'll just pass no # parameter blobs. # print 'No pretrained layer for layer', layer.name pretrained_blobs = [] operators, params = cls.TranslateLayer(layer, pretrained_blobs) net.op.extend(operators) net_params.protos.extend(params) return net, net_params
def TranslateModel( cls, caffe_net, pretrained_net, is_test=False, net_state=None, remove_legacy_pad=False, input_dims=None ): net_state = caffe_pb2.NetState() if net_state is None else net_state net = caffe2_pb2.NetDef() net.name = caffe_net.name net_params = caffe2_pb2.TensorProtos() if len(caffe_net.layers) > 0: raise ValueError( 'I think something is wrong. This translation script ' 'only accepts new style layers that are stored in the ' 'layer field.' ) if not input_dims: input_dims = _GetInputDims(caffe_net) for layer in caffe_net.layer: if not _ShouldInclude(net_state, layer): log.info('Current net state does not need layer {}' .format(layer.name)) continue log.info('Translate layer {}'.format(layer.name)) # Get pretrained one pretrained_layers = ( [l for l in pretrained_net.layer if l.name == layer.name] + [l for l in pretrained_net.layers if l.name == layer.name] ) if len(pretrained_layers) > 1: raise ValueError( 'huh? more than one pretrained layer of one name?') elif len(pretrained_layers) == 1: pretrained_blobs = [ utils.CaffeBlobToNumpyArray(blob) for blob in pretrained_layers[0].blobs ] else: # No pretrained layer for the given layer name. We'll just pass # no parameter blobs. # print 'No pretrained layer for layer', layer.name pretrained_blobs = [] operators, params = cls.TranslateLayer( layer, pretrained_blobs, is_test, net=net, net_params=net_params, input_dims=input_dims) net.op.extend(operators) net_params.protos.extend(params) if remove_legacy_pad: assert input_dims, \ 'Please specify input_dims to remove legacy_pad' net = _RemoveLegacyPad(net, net_params, input_dims) return net, net_params
def TranslateModel( cls, caffe_net, pretrained_net, is_test=False, input_mean=None, net_state=None, ): net_state = caffe_pb2.NetState() if net_state is None else net_state net = caffe2_pb2.NetDef() net.name = caffe_net.name net_params = caffe2_pb2.TensorProtos() if len(caffe_net.layer) == 0: raise ValueError( 'I think something is wrong. This translation script ' 'only accepts new style layers that are stored in the ' 'layer field.') if input_mean: caffenet_mean = caffe_pb2.BlobProto() caffenet_mean.ParseFromString(open(input_mean, 'rb').read()) mean_ = utils.CaffeBlobToNumpyArray(caffenet_mean) mean_tensor = utils.NumpyArrayToCaffe2Tensor(mean_, 'mean_') net_params.protos.extend([mean_tensor]) mean_op = caffe2_pb2.OperatorDef() mean_op.type = 'Sub' mean_op.input.extend(['data_', 'mean_']) # Assume that input blob's name is "data" mean_op.output.extend(['data']) net.op.extend([mean_op]) i = 0 while i < len(caffe_net.layer): if not _ShouldInclude(net_state, caffe_net.layer[i]): log.info('Current net state does not need layer {}'.format( caffe_net.layer[i].name)) continue log.info('Translate layer {}'.format(caffe_net.layer[i].name)) # Get pretrained one pretrained_layers_index = ([ l for l in xrange(len(pretrained_net.layer)) if pretrained_net.layer[l].name == caffe_net.layer[i].name ] + [ l for l in xrange(len(pretrained_net.layers)) if pretrained_net.layers[l].name == caffe_net.layer[i].name ]) is_bn = False if len(pretrained_layers_index) > 1: raise ValueError( 'huh? more than one pretrained layer of one name?') elif len(pretrained_layers_index) == 1: if pretrained_net.layer[ pretrained_layers_index[0]].type == "BatchNorm": # A Scale layer should follow BatchNorm layer # according to paper https://arxiv.org/abs/1502.03167. assert pretrained_net.layer[pretrained_layers_index[0] + 1].type == "Scale" pretrained_blobs = [utils.CaffeBlobToNumpyArray(blob) for blob in pretrained_net.layer[pretrained_layers_index[0]].blobs] + \ [utils.CaffeBlobToNumpyArray(blob) for blob in pretrained_net.layer[pretrained_layers_index[0] + 1].blobs] is_bn = True else: pretrained_blobs = [ utils.CaffeBlobToNumpyArray(blob) for blob in pretrained_net.layer[pretrained_layers_index[0]].blobs ] else: # No pretrained layer for the given layer name. We'll just pass # no parameter blobs. # print 'No pretrained layer for layer', layer.name pretrained_blobs = [] operators, params = cls.TranslateLayer(caffe_net.layer[i], pretrained_blobs, is_test) net.op.extend(operators) net_params.protos.extend(params) if is_bn: i += 2 else: i += 1 return net, net_params
def set_training(self, train_param): ''' required train_param: layer_names batch_size data ''' ''' SET NET PARAMETERS ''' self.solver_def = default_solver() self.train_param = train_param # comput data size self.train_param['data_size'] = data_size(train_param['data']) layer_names = train_param['layer_names'] net_spec = get_net_spec(self.net_file) net_spec.state.stage.append('train') net_spec.layer[0].data_param.batch_size = train_param['batch_size'] net_spec.layer[0].data_param.source = train_param['data'] self.setup_noise_layer(net_spec, train_param) if 'rand_skip' in train_param: net_spec.layer[0].data_param.rand_skip = train_param['rand_skip'] if 'test_param' in train_param: test_param = train_param['test_param'] net_spec.layer[1].data_param.batch_size = test_param['batch_size'] net_spec.layer[1].data_param.source = test_param['data'] test_param['data_size'] = test_param['data_size'] if 'data_size' in test_param \ else data_size(test_param['data']) if 'test_interval' not in test_param: train_param['test_param']['test_interval'] = self.solver_def.test_interval learn_layer(net_spec, layer_names) weights_file = train_param['in_weights'] if 'in_weights' in train_param else \ self.weights_file # scale learning rate according to weight std #scale_lr(self.net, net_spec, 1.0) # write net definition net_file = NamedTemporaryFile(dir = tmpdir, prefix = 'net_', delete = False) net_file.write(text_format.MessageToString(net_spec)) net_file.close() solver_file = NamedTemporaryFile(dir = tmpdir, prefix = 'sol_', delete = False) ''' SET SOLVER PARAMETERS ''' for k, v in train_param.items(): if hasattr(self.solver_def, k): self.solver_def.__setattr__(k, v) self.solver_def.train_net = net_file.name self.solver_def.snapshot_prefix = self.snapshot_dir + train_param['description'] print 'TEST FILE NAME ============= ' + net_file.name if 'test_param' in train_param: # adding test_state to the test net so it load data from LMDB test_state = caffe_pb2.NetState() test_state.stage.append('test') self.solver_def.test_state.extend([test_state]) if 'test_net' in test_param: self.solver_def.test_net.append(test_param['test_net']) else: self.solver_def.test_net.append(net_file.name) if 'data_size' in test_param: # Test on 100 batches each time we test. self.solver_def.test_iter.append(\ test_param['data_size']/test_param['batch_size']) if 'test_interval' in test_param: self.solver_def.test_interval = test_param['test_interval'] else: test_param['test_interval'] = self.solver_def.test_interval solver_file.write(str(self.solver_def)) solver_file.close() self.solver = None self.net = None self.solver = caffe.get_solver(solver_file.name) self.solver.net.copy_from(weights_file) if 'test_param' in train_param: self.solver.test_nets[0].copy_from(weights_file) os.remove(solver_file.name) os.remove(net_file.name) print 'Learning set with weights: ' + weights_file
def TranslateModel(cls, caffe_net, pretrained_net, is_test=False, net_state=None, remove_legacy_pad=False, input_dims=None): net_state = caffe_pb2.NetState() if net_state is None else net_state net = caffe2_pb2.NetDef() net.name = caffe_net.name net_params = caffe2_pb2.TensorProtos() if len(caffe_net.layers) > 0: raise ValueError( 'I think something is wrong. This translation script ' 'only accepts new style layers that are stored in the ' 'layer field.') if not input_dims: input_dims = _GetInputDims(caffe_net) for layer in caffe_net.layer: if not _ShouldInclude(net_state, layer): log.info('Current net state does not need layer {}'.format( layer.name)) continue log.info('Translate layer {}'.format(layer.name)) # Get pretrained one pretrained_layers = ( [l for l in pretrained_net.layer if l.name == layer.name] + [l for l in pretrained_net.layers if l.name == layer.name]) if len(pretrained_layers) > 1: print('>>> huh? more than one pretrained layer of one name?') print( '>>> Assuming these layers have no trainable parameters (e.g relu or pooling)' ) print([(pt.name, pt.type) for pt in pretrained_layers]) pt_types = [pt.type for pt in pretrained_layers] if len(set(pt_types)) == len(pt_types): print( '>>> But, just in case, try to match layer types since types are unique. If not, do not transfer params.' ) for pt in pretrained_layers: if pt.type == layer.type: print ' Found matching type {}'.format(layer.type) print ' Setting pretrained blobs' pretrained_blobs = [ utils.CaffeBlobToNumpyArray(blob) for blob in pt.blobs ] #print pretrained_blobs else: print('>>> Setting pretrained blobs = []') pretrained_blobs = [] #raise ValueError( # 'huh? more than one pretrained layer of one name?') elif len(pretrained_layers) == 1: pretrained_blobs = [ utils.CaffeBlobToNumpyArray(blob) for blob in pretrained_layers[0].blobs ] else: # No pretrained layer for the given layer name. We'll just pass # no parameter blobs. # print 'No pretrained layer for layer', layer.name pretrained_blobs = [] operators, params = cls.TranslateLayer(layer, pretrained_blobs, is_test, net=net, net_params=net_params, input_dims=input_dims) net.op.extend(operators) net_params.protos.extend(params) if remove_legacy_pad: assert input_dims, \ 'Please specify input_dims to remove legacy_pad' net = _RemoveLegacyPad(net, net_params, input_dims) return net, net_params