-
Notifications
You must be signed in to change notification settings - Fork 965
Contribution Guideline
Author: namizzz
Two steps are listed below:
- Implement original framework to IR part: get the attribute from the source_node and also add IR properties to IR node in the original framework parser file. more detail
- Implement IR to destination framework part: get IR properties and generate the target code. more detail
When you make some changes:
- Start with 'rename_' to add the new funtion to convert the new type source node to IR node
def rename_Dense(self, source_node):
IR_node = self.IR_graph.node.add()
_copy_and_reop(source_node, IR_node, new_op = None)
convert_inedge(self, source_node, IR_node, start_idx = 0, end_idx = None)
# pseudo code
- Use 'assign_IRnode_values' to save the necessary parameters of the operation (eg. kernel_shape, strides, pads)
def rename_Conv2D(self, source_node):
......
kwargs = {}
kwargs['strides'] = source_node.get_attr('strides')
W = self.tf_graph.get_node(source_node.layer.input[1])
W = self.tf_graph.get_node(W.layer.input[0]).layer
kwargs['kernel_shape'] = self.tensor_shape_to_list(W.attr['shape'])
......
assign_IRnode_values(IR_node, kwargs)
- Use 'set_weight' to save the pretrained parameters of the layer (eg. kernel matrix, mean matrix, bias matrix)
def __init__(self, meta_file, checkpoint_file, frozen_file, dest_nodes = None):
......
if checkpoint_file:
self.ckpt_data = TensorflowParser._load_weights(checkpoint_file)
self.weight_loaded = True
......
def rename_Conv2D(self, source_node):
......
if self.weight_loaded:
self.set_weight(source_node.name, 'weights', self.ckpt_data[W.name])
After you make some changes:
- Run the related test functions to ensure correctness after your changes using
$ python -m pytest -v -s ./test/test_conversion_imagenet.py
When you make some changes:
- Start with 'emit_' to add the new funtion to convert the new type IR node to model code(eg. else) or model components(eg. CoreML)
def emit_Dropout(self, IR_node):
parent = self.IR_graph.get_parent(IR_node.name, [0])
self.add_body(...)
- Follow the order in 'gen_code' function of every emitter file to use 'add_body' to generate the code of the operations or add some model layers to the 'base builder'(eg. self.builder in coreml_emitter)
def add_body(self, indent, codes):
if isinstance(codes, _string_types):
codes = [codes]
for code in codes:
self.body_code += (" " * indent) + code + '\n'
'add_body(1, codes)' means 1 Tab at the start of the line. 'add_body(0, codes)' means 0 Tab at the start of the line.For example, 'self.add_body(0, self.header_code)' in the 'gen_code()' function.
def emit_Dropout(self, IR_node):
parent = self.IR_graph.get_parent(IR_node.name, [0])
self.add_body(1, "{:<15} = Dropout(name = '{}', dropout_rate = {})({})".format(
IR_node.variable_name,
IR_node.name,
1 - IR_node.IR_layer.attr["keep_prob"].f,
parent.real_variable_name))
- [Only Model Code]Use self.used_layers to save some operation types for adding the modified functions to the target model code file.
def emit_BatchNorm(self, IR_node):
self.used_layers.add(IR_node.type)
self.add_body(1, "{:<15} = batch_normalization(...)".format(...))
......
def _layer_BatchNorm(self):
self.add_body(0, """
def batch_normalization(input, name, **kwargs):
mean = tf.Variable(__weights_dict[name]['mean'], name = name + "_mean", trainable = is_train)
variance = tf.Variable(__weights_dict[name]['var'], name = name + "_var", trainable = is_train)
offset = tf.Variable(__weights_dict[name]['bias'], name = name + "_bias", trainable = is_train) if 'bias' in __weights_dict[name] else None
scale = tf.Variable(__weights_dict[name]['scale'], name = name + "_scale", trainable = is_train) if 'scale' in __weights_dict[name] else None
return tf.nn.batch_normalization(input, mean, variance, offset, scale, name = name, **kwargs)
""")
[Note!] You can create and test the layer of new type and the modified function in the code file of target framework. Then put them to the 'target_framework'_emitter
After you make some changes:
- Run the related test functions for you changes using
$ python -m pytest -v -s ./test/test_conversion_imagenet.py
Before you make a PR:
- Explain your idea by making an issue on GitHub issues of each projects, especially when introducing new features.
When you make a PR:
- Reference the issue you made for explaining your idea.
When you leave commit message: The most important thing is simple but needs to contain primary summary what you did. And It is also recommended to start with capitalized verb the subject line. For example:
- Remove deprecated methods Instead of:
- methods are removed
Several major rules are listed below:
- Requires 4 spaces for indentation.
- No trailing whitespace, blank lines should have no whitespace.
- End of Line Sequence is 'LF' instand of 'CRLF'