def getHListData(self): #For Finding Additional Options hList = self.getHierarchyList() returnList = [] if (len(hList) == 0): return [] if (len(hList) >= 1): handle = caffe_pb2.LayerParameter() bracketedData = self.getBracketedData()[1:-1] lst = bracketedData.splitlines() if (self.getCurrentLine() in lst): lst.remove(self.getCurrentLine()) bracketedData = '\n'.join(lst) text_format.Merge(bracketedData, handle) print 'HList: Message Type : ', handle if (len(hList) == 1): return [elem.name for elem in handle.DESCRIPTOR.fields] descriptor = caffe_pb2.LayerParameter().DESCRIPTOR if (len(hList) > 1): #Elements Except for layers for elem in hList[1:]: print 'extra', elem for e in descriptor.fields: if (e.name == elem): descriptor = e.message_type for elem in descriptor.fields: print elem.name, '$$$$$$' return [elem.name for elem in descriptor.fields] if (len(hList) > 1): print 'Size more than 1' pass
def batchnorm(pytorch_layer): layer_bn = pb2.LayerParameter() layer_bn.type = "BatchNorm" layer_bn.batch_norm_param.use_global_stats = 1 layer_bn.batch_norm_param.eps = pytorch_layer.eps layer_bn.blobs.extend([ as_blob(pytorch_layer.running_mean.numpy()), as_blob(pytorch_layer.running_var.numpy()), as_blob(np.array([1.])) ]) layer_scale = pb2.LayerParameter() layer_scale.type = "Scale" blobs_weight = pytorch_layer.next_functions[1][0].variable.data.numpy() if pytorch_layer.next_functions[2][0]: layer_scale.scale_param.bias_term = True bias = pytorch_layer.next_functions[2][0].variable.data.numpy() layer_scale.blobs.extend([as_blob(blobs_weight), as_blob(bias)]) else: layer_scale.scale_param.bias_term = False layer_scale.blobs.extend([as_blob(blobs_weight)]) return [layer_bn, layer_scale]
def batchnorm(self,pytorch_layer): layer_bn = pb2.LayerParameter() layer_bn.type = "BatchNorm" bnmodule = self._bn_module_dict[self._bnindex] layer_bn.batch_norm_param.use_global_stats = 1 layer_bn.batch_norm_param.eps = bnmodule.eps #pytorch_layer.eps print(type(bnmodule.eps)) layer_bn.blobs.extend([ self.as_blob(bnmodule.running_mean.cpu().numpy()), self.as_blob(bnmodule.running_var.cpu().numpy()), self.as_blob(np.array([1.])) ]) layer_bn.blobs.extend([ self.as_blob(bnmodule.weight.data.cpu().numpy()), self.as_blob(bnmodule.weight.data.cpu().numpy()), self.as_blob(np.array([1.])) ]) layer_scale = pb2.LayerParameter() layer_scale.type = "Scale" blobs_weight = bnmodule.weight.data.cpu().numpy() if bnmodule.bias is not None: layer_scale.scale_param.bias_term = True bias = bnmodule.bias.data.cpu().numpy() layer_scale.blobs.extend([self.as_blob(blobs_weight), self.as_blob(bias)]) else: layer_scale.scale_param.bias_term = False layer_scale.blobs.extend([self.as_blob(blobs_weight)]) self._bnindex += 1 return [layer_bn, layer_scale]
def _to_proto(self, layers, names, autonames): if self in layers: return bottom_names = [] for inp in self.inputs: inp._to_proto(layers, names, autonames) bottom_names.append(layers[inp.fn].top[inp.n]) layer = caffe_pb2.LayerParameter() layer.type = self.type_name layer.bottom.extend(bottom_names) if self.in_place: layer.top.extend(layer.bottom) else: for top in self.tops: layer.top.append(self._get_top_name(top, names, autonames)) layer.name = self._get_name(names, autonames) for k, v in six.iteritems(self.params): # special case to handle generic *params if k.endswith('param'): assign_proto(layer, k, v) else: try: assign_proto( getattr(layer, _param_names[self.type_name] + '_param'), k, v) except (AttributeError, KeyError): assign_proto(layer, k, v) layers[self] = layer
def __init__(self, kwargs): name = kwargs['name'] bottoms = kwargs.get('bottoms', []) tops = kwargs.get('tops', [name]) param_names = kwargs.get('param_names', []) param_lr_mults = kwargs.get('param_lr_mults', []) param_decay_mults = kwargs.get('param_decay_mults', []) assert type(tops) != str and type(bottoms) != str and type( param_names) != str self.p = caffe_pb2.LayerParameter() self.r = caffe_pb2.RuntimeParameter() self.p.name = name for blob_name in tops: self.p.top.append(blob_name) for blob_name in bottoms: self.p.bottom.append(blob_name) for i in range( max(len(param_names), len(param_lr_mults), len(param_decay_mults))): param = self.p.param.add() if param_names: param.name = param_names[i] if param_lr_mults: param.lr_mult = param_lr_mults[i] if param_decay_mults: param.decay_mult = param_decay_mults[i] if 'phase' in kwargs: if kwargs['phase'] == 'TRAIN': self.p.phase = caffe_pb2.TRAIN elif kwargs['phase'] == 'TEST': self.p.phase = caffe_pb2.TEST else: raise ValueError('Unknown phase')
def extra_input_layer(config): if config.input: top_names = [] top_shapes = [] for input_idx in range(len(config.input)): in_name = config.input[input_idx] if config.input_shape: in_shape = config.input_shape elif config.input_dim: in_shape = caffe.BlobShape(dim=config.input_dim) else: raise ValueError("if input: occurs at top-level of network " "spec, it must be matched by input_shape or " "input_dim") top_names.append(in_name) top_shapes.append(in_shape) input_param = caffe.InputParameter(shape=top_shapes) return caffe.LayerParameter( name='dummy_input', top=top_names, type='Input', input_param=input_param) return None
def MulConst(pytorch_layer): layer = pb2.LayerParameter() layer.type = "Power" layer.power_param.power = 1 layer.power_param.scale = float(pytorch_layer.constant) layer.power_param.shift = 0 return layer
def operate(bottomDict, layerParameter): print layerParameter layerHandler = caffe_pb2.LayerParameter() text_format.Merge(layerParameter, layerHandler) conv_param = layerHandler.convolution_param paramdict = {} # First handle the optional fields: if (conv_param.HasField("num_output")): paramdict["num_output"] = conv_param.num_output if (conv_param.HasField("group")): paramdict["group"] = conv_param.group # The following are specified as "repeated" in caffe.proto # TODO: What is the best way to handle the multi-domensionality if conv_param.stride: paramdict["stride"] = conv_param.stride[0] if conv_param.pad: paramdict["pad"] = conv_param.pad[0] if conv_param.kernel_size: paramdict["size"] = conv_param.kernel_size[0] return getDim(bottomDict[bottomDict.keys()[0]]["dim"], **paramdict)
def UpsampleBilinear(pytorch_layer): layer = pb2.LayerParameter() layer.type = "Deconvolution" assert pytorch_layer.scale_factor[0] == pytorch_layer.scale_factor[1] factor = int(pytorch_layer.scale_factor[0]) c = int(pytorch_layer.input_size[1]) k = 2 * factor - factor % 2 layer.convolution_param.num_output = c layer.convolution_param.kernel_size.extend([k]) layer.convolution_param.stride.extend([factor]) layer.convolution_param.pad.extend([int(math.ceil((factor - 1) / 2.))]) layer.convolution_param.group = c layer.convolution_param.weight_filler.type = 'bilinear' layer.convolution_param.bias_term = False learning_param = pb2.ParamSpec() learning_param.lr_mult = 0 learning_param.decay_mult = 0 layer.param.extend([learning_param]) """ Init weight blob of filter kernel """ blobs_weight = FillBilinear(c, k) layer.blobs.extend([as_blob(blobs_weight)]) return layer
def data(inputs): layer = pb2.LayerParameter() layer.type = 'Input' input_shape = pb2.BlobShape() input_shape.dim.extend(inputs.data.numpy().shape) layer.input_param.shape.extend([input_shape]) return layer
def Slice(pytorch_layer): layer = pb2.LayerParameter() layer.type = "Slice" layer.slice_param.axis = pytorch_layer.axis layer.slice_param.slice_point.extend(pytorch_layer.slice_point) return layer
def AddConst(pytorch_layer): layer = pb2.LayerParameter() layer.type = "Power" layer.power_param.power = 1 layer.power_param.scale = 1 """ Constant to add should be filled by hand, since not visible in autograd """ layer.power_param.shift = float('inf') return layer
def dropout(pytorch_layer): layer = pb2.LayerParameter() layer.type = "Dropout" layer.dropout_param.dropout_ratio = float(pytorch_layer.p) train_only = pb2.NetStateRule() train_only.phase = pb2.TEST layer.exclude.extend([train_only]) return layer
def PReLU(pytorch_layer): layer = pb2.LayerParameter() layer.type = "PReLU" num_parameters = int(pytorch_layer.num_parameters) layer.prelu_param.channel_shared = True if num_parameters == 1 else False blobs_weight = pytorch_layer.next_functions[1][0].variable.data.numpy() layer.blobs.extend([as_blob(blobs_weight)]) return layer
def operate(bottomDict, layerParameter): layerHandler = caffe_pb2.LayerParameter() text_format.Merge(layerParameter, layerHandler) inner_product_param = layerHandler.inner_product_param paramdict = {} if (inner_product_param.HasField("num_output")): paramdict["num_output"] = inner_product_param.num_output return getDim(bottomDict[bottomDict.keys()[0]]["dim"], **paramdict)
def operate(bottomDict, layerParameter): layerHandler = caffe_pb2.LayerParameter() text_format.Merge(layerParameter, layerHandler) paramdict = {} print bottomDict print '*******************' dimArray = [bottomDict[k]["dim"] for k in bottomDict.keys()] print dimArray return getDim(dimArray, **paramdict)
def __init__(self, name='', type='', top=(), bottom=()): self.param = pb.LayerParameter() self.name = self.param.name = name self.type = self.param.type = type self.top = self.param.top self.top.extend(top) self.bottom = self.param.bottom self.bottom.extend(bottom)
def create_euclidean_loss_layer(self, each_net_last_layer_name): euclidean_loss_layer= caffe_pb2.LayerParameter( name = "euclidean_loss", type = "EuclideanLoss", bottom = each_net_last_layer_name ) net_proto = caffe_pb2.NetParameter() net_proto.layer.extend([euclidean_loss_layer]) return net_proto
def flatten(self,pytorch_layer): """ Only support flatten view """ total = 1 old_size = [2048,1,1] #pytorch_layer.old_size for dim in old_size: total *= dim #assert ((pytorch_layer.new_sizes[1] == total) or (pytorch_layer.new_sizes[1] == -1)) layer = pb2.LayerParameter() layer.type = "Flatten" return layer
def flatten(pytorch_layer): """ Only support flatten view """ total = 1 for dim in pytorch_layer.old_size: total *= dim assert ((pytorch_layer.new_sizes[1] == total) or (pytorch_layer.new_sizes[1] == -1)) layer = pb2.LayerParameter() layer.type = "Flatten" return layer
def Mean(pytorch_layer): layer = pb2.LayerParameter() layer.type = "Reduction" layer.reduction_param.operation = 4 try: layer.reduction_param.axis = pytorch_layer.dim except: print(dir(pytorch_layer)) exit(0) return layer
def spatial_convolution(self, pytorch_layer): layer = pb2.LayerParameter() convmodel = self._conv_module_dict[self._convindex] blobs_weight = convmodel.weight.data.cpu().numpy() #blobs_weight = pytorch_layer.next_functions[1][0].variable.data.numpy() #blobs_weight = convmodel. assert len(blobs_weight.shape) == 4, blobs_weight.shape (nOutputPlane, nInputPlane, kH, kW) = blobs_weight.shape padH = convmodel.padding[0] #pytorch_layer.padding[0] padW = convmodel.padding[1] #pytorch_layer.padding[1] dH = convmodel.stride[0] #pytorch_layer.stride[0] dW = convmodel.stride[1] #pytorch_layer.stride[1] dilation = convmodel.dilation[0] #pytorch_layer.dilation[0] transposed = convmodel.transposed #pytorch_layer.transposed groups = convmodel.groups #pytorch_layer.groups #print(blobs_weight) #print(convmodel.weight.data) if transposed: layer.type = "Deconvolution" layer.convolution_param.num_output = nInputPlane else: layer.type = "Convolution" layer.convolution_param.num_output = nOutputPlane if kH == kW: layer.convolution_param.kernel_size.extend([kH]) else: layer.convolution_param.kernel_h = kH layer.convolution_param.kernel_w = kW if dH == dW: layer.convolution_param.stride.extend([dH]) else: layer.convolution_param.stride_h = dH layer.convolution_param.stride_w = dW if padH == padW: layer.convolution_param.pad.extend([padH]) else: layer.convolution_param.pad_h = padH layer.convolution_param.pad_w = padW layer.convolution_param.dilation.extend([dilation]) layer.convolution_param.group = groups if convmodel.bias: layer.convolution_param.bias_term = True bias = convmodel.bias.data layer.blobs.extend( [self.as_blob(blobs_weight), self.as_blob(bias)]) else: layer.convolution_param.bias_term = False layer.blobs.extend([self.as_blob(blobs_weight)]) print('convindex:', self._convindex) self._convindex += 1 return layer
class GeneralLayer(object): type = LayerType.none in_channel = 0 out_channel = 0 out_size = 0 name = '' bottom = '' top = '' layer_param = caffe_pb2.LayerParameter() param_dict = {} param_txt = ''
def operate(bottomDict,layerParameter): layerHandler=caffe_pb2.LayerParameter() text_format.Merge(layerParameter,layerHandler) conv_param= layerHandler.pooling_param paramdict={} if(conv_param.HasField("stride")):paramdict["stride"]=conv_param.stride if(conv_param.HasField("pad")):paramdict["pad"]=conv_param.pad if(conv_param.HasField("kernel_size")):paramdict["size"]=conv_param.kernel_size print 'POOLING BOTTOM DICT',bottomDict return getDim(bottomDict[bottomDict.keys()[0]]["dim"],**paramdict)
def ConvertModel_caffe(pytorch_net, InputShape, softmax=False): """ Pytorch to Caffe, only support single tensor input """ import os import caffe_pb2 as pb2 from ConvertLayer_caffe import convert_caffe """ Need forward once """ pytorch_net.eval() global inputs n, c, h, w = InputShape inputs = Variable(torch.rand(n, c, h, w), requires_grad=True) outputs = pytorch_net(inputs) if softmax: import torch.nn as nn regularize = nn.Softmax() outputs = regularize(outputs) """ Travel computational graph in backward order """ global caffe_net, visited, tops_dict, layer_type_count, dst global slice_point, slice_tops global convert, link convert = convert_caffe link = link_caffe caffe_net = [] dst = 'caffe' visited = set() tops_dict = dict() layer_type_count = dict() slice_point = dict() slice_tops = dict() for out in outputs: DFS(out.grad_fn) """ Caffe input """ text_net = pb2.NetParameter() if os.environ.get("T2C_DEBUG"): text_net.debug_info = True """ Caffe layer parameters """ binary_weights = pb2.NetParameter() binary_weights.CopyFrom(text_net) for layer in caffe_net: binary_weights.layer.extend([layer]) layer_proto = pb2.LayerParameter() layer_proto.CopyFrom(layer) del layer_proto.blobs[:] text_net.layer.extend([layer_proto]) return text_net, binary_weights
def create_softmax_layer(self, add_net_layer_name): add_softamx_layers = [] for elem in add_net_layer_name: softmax_layer= caffe_pb2.LayerParameter( name = "{}-softmax".format(elem), type = "Softmax", bottom = elem ) add_softamx_layers.append(softmax_layer) net_proto = caffe_pb2.NetParameter() for elem in add_softamx_layers: net_proto.layer.extend([elem]) return net_proto
def operate(bottomDict, layerParameter): layerHandler = caffe_pb2.LayerParameter() text_format.Merge(layerParameter, layerHandler) conv_param = layerHandler.convolution_param paramdict = {} if (conv_param.HasField("stride")): paramdict["stride"] = conv_param.stride if (conv_param.HasField("num_output")): paramdict["num_output"] = conv_param.num_output if (conv_param.HasField("pad")): paramdict["pad"] = conv_param.pad if (conv_param.HasField("group")): paramdict["group"] = conv_param.group if (conv_param.HasField("kernel_size")): paramdict["size"] = conv_param.kernel_size return getDim(bottomDict[bottomDict.keys()[0]]["dim"], **paramdict)
def param_name_dict(): """Find out the correspondence between layer names and parameter names.""" layer = caffe_pb2.LayerParameter() # get all parameter names (typically underscore case) and corresponding # type names (typically camel case), which contain the layer names # (note that not all parameters correspond to layers, but we'll ignore that) param_names = [ f.name for f in layer.DESCRIPTOR.fields if f.name.endswith('_param') ] param_type_names = [type(getattr(layer, s)).__name__ for s in param_names] # strip the final '_param' or 'Parameter' param_names = [s[:-len('_param')] for s in param_names] param_type_names = [s[:-len('Parameter')] for s in param_type_names] return dict(zip(param_type_names, param_names))
def insertLayer(self, handle, pos, data): #Step 1: Assign Net Parameter c = caffe_pb2.NetParameter() text_format.Merge(data, c) for idx in range(len(c.layer)): handle.layer.add() #Step 2: length = len(handle.layer) for idx in range(length - 1, pos - 1, -1): h = caffe_pb2.LayerParameter() text_format.Merge(handle.layer[idx - len(c.layer)].__str__(), h) handle.layer[idx].CopyFrom(h) for idx in range(pos, pos + len(c.layer)): handle.layer[idx].CopyFrom(c.layer[idx - pos])
def spatial_convolution(pytorch_layer): layer = pb2.LayerParameter() blobs_weight = pytorch_layer.next_functions[1][0].variable.data.numpy() assert len(blobs_weight.shape) == 4, blobs_weight.shape (nOutputPlane, nInputPlane, kH, kW) = blobs_weight.shape padH = pytorch_layer.padding[0] padW = pytorch_layer.padding[1] dH = pytorch_layer.stride[0] dW = pytorch_layer.stride[1] dilation = pytorch_layer.dilation[0] if pytorch_layer.transposed: layer.type = "Deconvolution" layer.convolution_param.num_output = nInputPlane else: layer.type = "Convolution" layer.convolution_param.num_output = nOutputPlane if kH == kW: layer.convolution_param.kernel_size.extend([kH]) else: layer.convolution_param.kernel_h = kH layer.convolution_param.kernel_w = kW if dH == dW: layer.convolution_param.stride.extend([dH]) else: layer.convolution_param.stride_h = dH layer.convolution_param.stride_w = dW if padH == padW: layer.convolution_param.pad.extend([padH]) else: layer.convolution_param.pad_h = padH layer.convolution_param.pad_w = padW layer.convolution_param.dilation.extend([dilation]) layer.convolution_param.group = pytorch_layer.groups if pytorch_layer.next_functions[2][0]: layer.convolution_param.bias_term = True bias = pytorch_layer.next_functions[2][0].variable.data.numpy() layer.blobs.extend([as_blob(blobs_weight), as_blob(bias)]) else: layer.convolution_param.bias_term = False layer.blobs.extend([as_blob(blobs_weight)]) return layer