in example/ssd/tools/caffe_converter/convert_symbol.py [0:0]
def proto2script(proto_file):
proto = read_proto_solver_file(proto_file)
connection = dict()
symbols = dict()
top = dict()
flatten_count = 0
symbol_string = ""
layer = ''
if len(proto.layer):
layer = proto.layer
elif len(proto.layers):
layer = proto.layers
else:
raise Exception('Invalid proto file.')
# Get input size to network
input_dim = [1, 3, 224, 224] # default
if len(proto.input_dim) > 0:
input_dim = proto.input_dim
elif len(proto.input_shape) > 0:
input_dim = proto.input_shape[0].dim
elif layer[0].type == "Input":
input_dim = layer[0].input_param.shape._values[0].dim
layer.pop(0)
else:
raise Exception('Invalid proto file.')
# We assume the first bottom blob of first layer is the output from data layer
input_name = layer[0].bottom[0]
output_name = ""
mapping = {input_name: 'data'}
need_flatten = {input_name: False}
for i in range(len(layer)):
type_string = ''
param_string = ''
name = re.sub('[-/]', '_', layer[i].name)
from_name = 'data='
bottom_order = []
if layer[i].type == 'Convolution' or layer[i].type == 4:
type_string = 'mx.symbol.Convolution'
param_string = conv_param_to_string(layer[i].convolution_param)
need_flatten[name] = True
if layer[i].type == 'Deconvolution' or layer[i].type == 39:
type_string = 'mx.symbol.Deconvolution'
param_string = conv_param_to_string(layer[i].convolution_param)
need_flatten[name] = True
if layer[i].type == 'Pooling' or layer[i].type == 17:
type_string = 'mx.symbol.Pooling'
param = layer[i].pooling_param
param_string = ''
param_string += "pooling_convention='full', "
if param.global_pooling:
# there must be a param `kernel` in a pooling layer
param_string += "global_pool=True, kernel=(1,1)"
else:
param_string += "pad=(%d,%d), kernel=(%d,%d), stride=(%d,%d)" % \
(param.pad, param.pad, param.kernel_size, param.kernel_size, param.stride, param.stride)
if param.pool == 0:
param_string += ", pool_type='max'"
elif param.pool == 1:
param_string += ", pool_type='avg'"
else:
raise Exception("Unknown Pooling Method!")
need_flatten[name] = True
if layer[i].type == 'ReLU' or layer[i].type == 18:
type_string = 'mx.symbol.Activation'
param_string = "act_type='relu'"
need_flatten[name] = need_flatten[mapping[layer[i].bottom[0]]]
if layer[i].type == 'TanH' or layer[i].type == 23:
type_string = 'mx.symbol.Activation'
param_string = "act_type='tanh'"
need_flatten[name] = need_flatten[mapping[layer[i].bottom[0]]]
if layer[i].type == 'Sigmoid' or layer[i].type == 19:
type_string = 'mx.symbol.Activation'
param_string = "act_type='sigmoid'"
need_flatten[name] = need_flatten[mapping[layer[i].bottom[0]]]
if layer[i].type == 'LRN' or layer[i].type == 15:
type_string = 'mx.symbol.LRN'
param = layer[i].lrn_param
param_string = "alpha=%f, beta=%f, knorm=%f, nsize=%d" % \
(param.alpha, param.beta, param.k, param.local_size)
need_flatten[name] = True
if layer[i].type == 'InnerProduct' or layer[i].type == 14:
type_string = 'mx.symbol.FullyConnected'
param = layer[i].inner_product_param
param_string = "num_hidden=%d, no_bias=%s" % (param.num_output, not param.bias_term)
need_flatten[name] = False
if layer[i].type == 'Dropout' or layer[i].type == 6:
type_string = 'mx.symbol.Dropout'
param = layer[i].dropout_param
param_string = "p=%f" % param.dropout_ratio
need_flatten[name] = need_flatten[mapping[layer[i].bottom[0]]]
if layer[i].type == 'Softmax' or layer[i].type == 20:
if layer[i].softmax_param.axis == 2:
symbol_string += "%s = mx.symbol.transpose(%s, axes=(0,2,1))\n" %\
(mapping[layer[i].bottom[0]], mapping[layer[i].bottom[0]])
type_string = 'mx.symbol.SoftmaxActivation'
param_string = "mode='channel'"
need_flatten[name] = False
else:
type_string = 'mx.symbol.SoftmaxOutput'
if layer[i].type == 'Flatten' or layer[i].type == 8:
if 'softmax' in layer[i].bottom[0]:
type_string = 'identical'
else:
type_string = 'mx.symbol.Flatten'
need_flatten[name] = False
if layer[i].type == 'Split' or layer[i].type == 22:
type_string = 'split'
if layer[i].type == 'Concat' or layer[i].type == 3:
type_string = 'mx.symbol.Concat'
need_flatten[name] = True
if layer[i].type == 'Crop':
type_string = 'mx.symbol.Crop'
need_flatten[name] = True
param_string = 'center_crop=True'
if layer[i].type == 'BatchNorm':
type_string = 'mx.symbol.BatchNorm'
param = layer[i].batch_norm_param
param_string = 'use_global_stats=%s' % param.use_global_stats
if layer[i].type == 'PReLU':
type_string = 'mx.symbol.LeakyReLU'
param = layer[i].prelu_param
param_string = "act_type='prelu', slope=%f" % param.filler.value
need_flatten[name] = need_flatten[mapping[layer[i].bottom[0]]]
if layer[i].type == 'Normalize':
bottom = re.sub('[-/]', '_', layer[i].bottom[0])
conv_layer = find_layer(layer, bottom)
assert conv_layer is not None
param = layer[i].norm_param
assert not param.across_spatial and not param.channel_shared
assert param.scale_filler.type == 'constant'
if conv_layer.type == 'Convolution':
scale_name = "%s_scale" % name
symbol_string += "%s=mx.sym.Variable(name='%s', shape=(1, %d, 1, 1), init=mx.init.Constant(%f))\n" % \
(scale_name, scale_name, conv_layer.convolution_param.num_output,
param.scale_filler.value)
symbol_string += "%s=mx.symbol.L2Normalization(name='%s', data=%s, mode='channel')\n" %\
(name, name, mapping[layer[i].bottom[0]])
symbol_string += "%s=mx.symbol.broadcast_mul(lhs=%s, rhs=%s)\n" %\
(name, scale_name, name)
type_string = 'split'
need_flatten[name] = True
else:
raise ValueError('Unknown/Invalid normalize layer!')
if layer[i].type == 'Permute':
type_string = 'mx.symbol.transpose'
param_string = "axes=(%s)" % (','.join([str(x) for x in layer[i].permute_param.order]))
need_flatten[name] = True
from_name = ''
if layer[i].type == 'PriorBox':
param = layer[i].prior_box_param
if layer[i].bottom[0] == 'data':
bottom_order = [1]
else:
bottom_order = [0]
try:
min_size = param.min_size[0] / input_dim[2]
max_size = math.sqrt(param.min_size[0] * param.max_size[0]) / input_dim[2]
sizes = '(%f, %f)' %(min_size, max_size)
except AttributeError:
min_size = param.min_size[0] / input_dim[2]
sizes = '(%f)' %(min_size)
ars = list(param.aspect_ratio)
ratios = [1.]
for ar in ars:
ratios.append(ar)
if param.flip:
ratios.append(1. / ar)
ratios_string = '(' + ','.join(str(x) for x in ratios) + ')'
clip = param.clip
if (param.step_h > 0 or param.step_w > 0):
step_h = param.step_h
step_w = param.step_w
elif param.step > 0:
step_h = param.step
step_w = param.step
else:
step_h = -1
step_w = -1
finput_dim = float(input_dim[2])
step = '(%f, %f)' % (step_h / finput_dim, step_w / finput_dim)
assert param.offset == 0.5, "currently only support offset = 0.5"
symbol_string += '%s = mx.contrib.symbol.MultiBoxPrior(%s, sizes=%s, ratios=%s, clip=%s, steps=%s, name="%s")\n' % \
(name, mapping[layer[i].bottom[0]], sizes, ratios_string, clip, step, name)
symbol_string += '%s = mx.symbol.Flatten(data=%s)\n' % (name, name)
type_string = 'split'
need_flatten[name] = False
if layer[i].type == 'Reshape':
type_string = 'mx.symbol.Reshape'
param = layer[i].reshape_param
param_string = 'shape=(' + ','.join([str(x) for x in list(param.shape.dim)]) + ')'
need_flatten[name] = True
if layer[i].type == 'DetectionOutput':
bottom_order = [1, 0, 2]
param = layer[i].detection_output_param
assert param.share_location == True
assert param.background_label_id == 0
nms_param = param.nms_param
type_string = 'mx.contrib.symbol.MultiBoxDetection'
param_string = "nms_threshold=%f, nms_topk=%d" % \
(nms_param.nms_threshold, nms_param.top_k)
if type_string == '':
raise Exception('Unknown Layer %s!' % layer[i].type)
if type_string == 'identical':
bottom = layer[i].bottom
symbol_string += "%s = %s\n" % (name, mapping[bottom[0]])
elif type_string != 'split':
bottom = layer[i].bottom
if param_string != "":
param_string = ", " + param_string
if len(bottom) == 1:
if need_flatten[mapping[bottom[0]]] and type_string == 'mx.symbol.FullyConnected':
flatten_name = "flatten_%d" % flatten_count
symbol_string += "%s=mx.symbol.Flatten(name='%s', data=%s)\n" % \
(flatten_name, flatten_name, mapping[bottom[0]])
flatten_count += 1
need_flatten[flatten_name] = False
bottom[0] = flatten_name
mapping[bottom[0]] = bottom[0]
symbol_string += "%s = %s(%s%s %s, name='%s')\n" % \
(name, type_string, from_name, mapping[bottom[0]], param_string, name)
else:
if not bottom_order:
bottom_order = range(len(bottom))
symbol_string += "%s = %s(name='%s', *[%s] %s)\n" % \
(name, type_string, name, ','.join([mapping[bottom[x]] for x in bottom_order]), param_string)
if layer[i].type == 'Concat' and layer[i].concat_param.axis == 2:
symbol_string += "%s = mx.symbol.Reshape(data=%s, shape=(0, -1, 4), name='%s')\n" %\
(name, name, name)
for j in range(len(layer[i].top)):
mapping[layer[i].top[j]] = name
output_name = name
return symbol_string, output_name, input_dim