def create_tflite_graph(): class Model(tf.Module): @tf.function def depthwise_conv2d(self, x): weight_shape = [kernel_shape[0], kernel_shape[1], ifm_shape[3], 1] weight = tf.constant(np.random.uniform(size=weight_shape), dtype=tf.float32) # The input strides to the TensorFlow API needs to be of shape 1x4 tf_strides = [1, strides[0], strides[1], 1] op = tf.nn.depthwise_conv2d( x, weight, strides=tf_strides, padding=padding, dilations=dilation ) if activation: op = tf.nn.relu(op) return op model = Model() concrete_func = model.depthwise_conv2d.get_concrete_function( tf.TensorSpec(ifm_shape, dtype=tf.float32) ) # Convert the model def representative_dataset(): for _ in range(100): data = np.random.rand(*tuple(ifm_shape)) yield [data.astype(np.float32)] converter = tf.lite.TFLiteConverter.from_concrete_functions([concrete_func]) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 tflite_model = converter.convert() return tflite_model
def create_tflite_graph(): class Model(tf.Module): @tf.function def tf_function(self, x): if pooling_type == "MAX": op = tf.nn.max_pool(x, pool_shape, strides, padding) elif pooling_type == "AVG": op = tf.nn.avg_pool(x, pool_shape, strides, padding) if activation_function == "RELU": op = tf.nn.relu(op) return op model = Model() concrete_func = model.tf_function.get_concrete_function( tf.TensorSpec(ifm_shape, dtype=tf.float32) ) # Convert the model def representative_dataset(): for _ in range(100): data = np.random.rand(*tuple(ifm_shape)) yield [data.astype(np.float32)] converter = tf.lite.TFLiteConverter.from_concrete_functions([concrete_func]) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 tflite_model = converter.convert() return tflite_model
def create_mod_from_tflite(): class Model(tf.Module): @tf.function def tf_function(self, x): op = tf.math.reduce_mean(x, axis=axis, keepdims=keep_dims) return op model = Model() concrete_func = model.tf_function.get_concrete_function( tf.TensorSpec(ifm_shape, dtype=tf.float32) ) # Convert the model def representative_dataset(): for _ in range(100): data = np.random.rand(*tuple(ifm_shape)) yield [data.astype(np.float32)] converter = tf.lite.TFLiteConverter.from_concrete_functions([concrete_func]) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 tflite_graph = converter.convert() tflite_model = tflite.Model.Model.GetRootAsModel(tflite_graph, 0) mod, _ = relay.frontend.from_tflite( tflite_model, shape_dict={"ifm": ifm_shape}, dtype_dict={"ifm": dtype}, ) input_data, output_data = infra.generate_ref_data_tflite(tflite_graph) return mod, input_data, output_data
def create_model(): class Model(tf.Module): @tf.function def tf_function(self, x): for _ in range(2): x = tf.nn.max_pool2d(x, (1, 1), (1, 1), "SAME", "NHWC") return x model = Model() concrete_func = model.tf_function.get_concrete_function( tf.TensorSpec(ifm_shape, dtype=tf.float32)) # Convert the model def representative_dataset(): for _ in range(100): data = np.random.rand(*tuple(ifm_shape)) yield [data.astype(np.float32)] converter = tf.lite.TFLiteConverter.from_concrete_functions( [concrete_func]) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [ tf.lite.OpsSet.TFLITE_BUILTINS_INT8 ] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 return converter.convert()
def create_tflite_graph(): class Model(tf.Module): @tf.function def abs_func(self, x): if operator_type == "ABS": op = tf.math.abs(x) return op model = Model() # Save the model concrete_func = model.abs_func.get_concrete_function( tf.TensorSpec(ifm_shape, dtype=tf.float32)) # Convert the model def representative_dataset(): for _ in range(100): data = np.random.rand(*tuple(ifm_shape)) yield [data.astype(np.float32)] converter = tf.lite.TFLiteConverter.from_concrete_functions( [concrete_func]) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [ tf.lite.OpsSet.TFLITE_BUILTINS_INT8 ] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 tflite_model = converter.convert() return tflite_model
def load(self, path, shape_dict=None): # pylint: disable=C0415 import tflite.Model as model with open(path, "rb") as tf_graph: content = tf_graph.read() # tflite.Model.Model is tflite.Model in 1.14 and 2.1.0 try: tflite_model = model.Model.GetRootAsModel(content, 0) except AttributeError: tflite_model = model.GetRootAsModel(content, 0) try: version = tflite_model.Version() logger.debug("tflite version %s", version) except Exception: raise TVMCException("input file not tflite") if version != 3: raise TVMCException("input file not tflite version 3") logger.debug("tflite_input_type") input_shapes, dtype_dict = TFLiteFrontend._input_type(tflite_model) if shape_dict is not None: input_shapes.update(shape_dict) logger.debug( "parse TFLite model and convert into Relay computation graph") mod, params = relay.frontend.from_tflite(tflite_model, shape_dict=input_shapes, dtype_dict=dtype_dict) return mod, params
def create_tflite_graph(): tf.config.run_functions_eagerly(True) class Model(tf.Module): @tf.function def tf_function(self, x): return tf.nn.max_pool(x, [1, 2], [1, 2], "SAME") def representative_dataset(): for _ in range(100): data = np.random.rand(*tuple([1, 3, 4, 3])) yield [data.astype(np.float32)] model = Model() concrete_func = model.tf_function.get_concrete_function( tf.TensorSpec([1, 3, 4, 3], dtype=tf.float32) ) converter = tf.lite.TFLiteConverter.from_concrete_functions([concrete_func]) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 tflite_model = converter.convert() return tflite_model
def create_tflite_graph_two_outs(): """Create a model with 2 output tensors""" class Model(tf.Module): """Simple TFLite test model""" @tf.function def tf_function(self, tf_input_x): """Single TFLite function with two convolutions""" tf_strides = [1, strides[0], strides[1], 1] filter_shape = [kernel_shape[0], kernel_shape[1], 3, 3] filter1 = tf.constant( np.arange(np.prod(filter_shape)).reshape(filter_shape), dtype=tf.float32, ) first_conv2d = tf.nn.conv2d( tf_input_x, filters=filter1, strides=tf_strides, padding=padding, dilations=dilation, ) first_conv2d = tf.nn.relu(first_conv2d) filter2 = tf.constant( 1000 + np.arange(np.prod(filter_shape)).reshape(filter_shape), dtype=tf.float32, ) second_conv2d = tf.nn.conv2d( tf_input_x, filters=filter2, strides=strides, padding=padding, data_format="NHWC", dilations=dilation, ) second_conv2d = tf.nn.relu(second_conv2d) return first_conv2d, second_conv2d model = Model() concrete_func = model.tf_function.get_concrete_function( tf.TensorSpec(ifm_shape, dtype=tf.float32)) # Convert the model def representative_dataset(): for _ in range(100): data = np.random.rand(*tuple(ifm_shape)) yield [data.astype(np.float32)] converter = tf.lite.TFLiteConverter.from_concrete_functions( [concrete_func]) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [ tf.lite.OpsSet.TFLITE_BUILTINS_INT8 ] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 tflite_model = converter.convert() return tflite_model
def create_tflite_graph_two_outs(): """Create a model with 2 output tensors""" class Model(tf.Module): @tf.function def tf_function(self, x): # Use tf.nn API to create the model tf_strides = [1, strides[0], strides[1], 1] op = tf.nn.conv2d( x, filters=tf.constant( np.random.uniform( size=[kernel_shape[0], kernel_shape[1], 3, 3]), dtype=tf.float32, ), strides=tf_strides, padding=padding, dilations=dilation, ) op = tf.nn.relu(op) # Second convolution op2 = tf.nn.conv2d( x, filters=tf.constant( np.random.uniform(size=(kernel_shape[0], kernel_shape[1], 3, 3)), dtype=tf.float32, ), strides=strides, padding=padding, data_format="NHWC", dilations=dilation, ) op2 = tf.nn.relu(op2) return op, op2 model = Model() concrete_func = model.tf_function.get_concrete_function( tf.TensorSpec(ifm_shape, dtype=tf.float32)) # Convert the model def representative_dataset(): for _ in range(100): data = np.random.rand(*tuple(ifm_shape)) yield [data.astype(np.float32)] converter = tf.lite.TFLiteConverter.from_concrete_functions( [concrete_func]) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [ tf.lite.OpsSet.TFLITE_BUILTINS_INT8 ] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 tflite_model = converter.convert() return tflite_model
def create_tflite_graph(): class Model(tf.Module): @tf.function def tf_func(self, x): weight_shape = (3, 3, ifm_shape[3], 4) weight = tf.constant(np.random.uniform(low=0, high=0.3, size=weight_shape), dtype=tf.float32) # The input strides to the TensorFlow API needs to be of shape 1x4 op = tf.nn.conv2d(x, weight, strides=(1, 2, 2, 1), padding="SAME", dilations=(1, 1)) op = tf.nn.tanh(op) op = tf.nn.tanh(op) weight_shape2 = (2, 3, 4, 1) weight2 = tf.constant(np.random.uniform(low=0, high=0.3, size=weight_shape2), dtype=tf.float32) op = tf.nn.depthwise_conv2d(op, weight2, strides=(1, 1, 1, 1), padding="VALID", dilations=(2, 2)) op = tf.nn.sigmoid(op) op = tf.nn.max_pool(op, (1, 1), strides=(1, 1, 1, 1), padding="SAME") op = tf.nn.tanh(op) return op model = Model() concrete_func = model.tf_func.get_concrete_function( tf.TensorSpec(ifm_shape, dtype=tf.float32)) # Convert the model def representative_dataset(): for _ in range(100): data = 0.7 * np.random.rand(*tuple(ifm_shape)) yield [data.astype(np.float32)] converter = tf.lite.TFLiteConverter.from_concrete_functions( [concrete_func]) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [ tf.lite.OpsSet.TFLITE_BUILTINS_INT8 ] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 tflite_model = converter.convert() return tflite_model
def _input_type(model): subgraph_count = model.SubgraphsLength() assert subgraph_count > 0 shape_dict = {} dtype_dict = {} for subgraph_index in range(subgraph_count): subgraph = model.Subgraphs(subgraph_index) inputs_count = subgraph.InputsLength() assert inputs_count >= 1 for input_index in range(inputs_count): input_ = subgraph.Inputs(input_index) assert subgraph.TensorsLength() > input_ tensor = subgraph.Tensors(input_) input_shape = tuple(tensor.ShapeAsNumpy()) tensor_type = tensor.Type() input_name = tensor.Name().decode("utf8") shape_dict[input_name] = input_shape dtype_dict[input_name] = TFLiteFrontend._decode_type( tensor_type) return shape_dict, dtype_dict
def create_conv2d_tflite_model(ifm_shape, kernel_shape, strides, dilation, padding, activation): """ This method prepares TFlite graph with a single Conv2d layer """ import tensorflow as tf class Model(tf.Module): @tf.function def tf_function(self, x): # Use tf.nn API to create the model tf_strides = [1, strides[0], strides[1], 1] op = tf.nn.conv2d( x, filters=tf.constant( np.random.uniform( size=[kernel_shape[0], kernel_shape[1], 3, 3]), dtype=tf.float32, ), strides=tf_strides, padding=padding, dilations=dilation, ) if activation: op = tf.nn.relu(op) return op model = Model() concrete_func = model.tf_function.get_concrete_function( tf.TensorSpec(ifm_shape, dtype=tf.float32)) def representative_dataset(): for _ in range(100): data = np.random.rand(*tuple(ifm_shape)) yield [data.astype(np.float32)] converter = tf.lite.TFLiteConverter.from_concrete_functions( [concrete_func]) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 tflite_model = converter.convert() return tflite_model
def create_tflite_graph(): class Model(tf.Module): @tf.function def tf_function(self, lhs, rhs): if operator_type == "ADD": op = tf.math.add(lhs, rhs) elif operator_type == "SUB": op = tf.math.subtract(lhs, rhs) elif operator_type == "MUL": op = tf.math.multiply(lhs, rhs) elif operator_type == "MIN": op = tf.math.minimum(lhs, rhs) elif operator_type == "MAX": op = tf.math.maximum(lhs, rhs) if activation_function == "RELU": op = tf.nn.relu(op) return op model = Model() concrete_func = model.tf_function.get_concrete_function( tf.TensorSpec(ifm_shape, dtype=tf.float32), tf.TensorSpec(ifm2_shape, dtype=tf.float32)) # Convert the model def representative_dataset(): for _ in range(100): data = np.random.rand(*tuple(ifm_shape)) data2 = np.random.rand(*tuple(ifm2_shape)) * 2 yield [data.astype(np.float32), data2.astype(np.float32)] converter = tf.lite.TFLiteConverter.from_concrete_functions( [concrete_func]) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [ tf.lite.OpsSet.TFLITE_BUILTINS_INT8 ] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 tflite_model = converter.convert() return tflite_model
def create_tflite_graph(): class Model(tf.Module): @tf.function def model_func(self, x): weight_shape = [3, 3, 6, 1] # HWO1 weight = tf.constant(np.random.uniform(size=weight_shape), dtype=tf.float32) op = tf.nn.depthwise_conv2d(x, weight, strides=[1, 1, 1, 1], padding="SAME") op = tf.nn.relu(op) op = tf.reshape(op, [1, 8, 6, 3]) op = tf.nn.pool(op, [2, 2], "MAX") op = tf.strided_slice(op, [0, 2, 3, 1], [1, 6, 5, 2]) return op model = Model() concrete_func = model.model_func.get_concrete_function( tf.TensorSpec(ifm_shape, dtype=tf.float32)) # Convert the model def representative_dataset(): for _ in range(100): data = np.random.rand(*tuple(ifm_shape)) yield [data.astype(np.float32)] converter = tf.lite.TFLiteConverter.from_concrete_functions( [concrete_func]) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [ tf.lite.OpsSet.TFLITE_BUILTINS_INT8 ] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 tflite_model = converter.convert() return tflite_model
def create_model(): class Model(tf.Module): @tf.function def tf_function(self, x): for _ in range(3): x = tf.nn.conv2d( x, filters=tf.constant( np.random.uniform(size=kernel_shape), dtype=tf.float32), strides=(1, 1), padding="SAME", data_format="NHWC", dilations=1, ) return x model = Model() concrete_func = model.tf_function.get_concrete_function( tf.TensorSpec(ifm_shape, dtype=tf.float32)) # Convert the model def representative_dataset(): for _ in range(100): data = np.random.rand(*tuple(ifm_shape)) yield [data.astype(np.float32)] converter = tf.lite.TFLiteConverter.from_concrete_functions( [concrete_func]) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [ tf.lite.OpsSet.TFLITE_BUILTINS_INT8 ] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 return converter.convert()
import tflite from tflite import Model import pdb buf = open('weights/yolov3_quant.tflite', 'rb').read() model = Model.GetRootAsModel(buf, 0) subgraph = model.Subgraphs(0) # print(dir(subgraph)) print('subgraph.OperatorsLength()', subgraph.OperatorsLength()) n_ops = subgraph.OperatorsLength() print('n_ops', n_ops) i_op = 0 # op = subgraph.Operators(i_op) # print("Inputs", op.Inputs(0), op.Inputs(1)) # print(op.BuiltinOptionsType()) # assert(op.BuiltinOptionsType() == tflite.BuiltinOptions.ReshapeOptions) for i_op in range(n_ops): op = subgraph.Operators(i_op) if op.BuiltinOptionsType() == tflite.BuiltinOptions.ReshapeOptions: print(i_op) i_out = op.Outputs(0) out = subgraph.Tensors(i_out) print('out', out.Name()) op_opt = op.BuiltinOptions() opt = tflite.ReshapeOptions() opt.Init(op_opt.Bytes, op_opt.Pos) print(opt.NewShapeAsNumpy()) # print(op.BuiltinOptions())
def device_api_main_func(): # Ideally we should have a sample Target registered here # but we're going to re-use this for now pytest.importorskip("ethosu.vela") import tensorflow as tf import tflite.Model from tests.python.contrib.test_ethosu.infra import create_test_runner, generate_ref_data_tflite from tvm.relay.op.contrib.ethosu import partition_for_ethosu tf.config.run_functions_eagerly(True) class Model(tf.Module): @tf.function def tf_function(self, x): return tf.nn.max_pool(x, [1, 2], [1, 2], "SAME") def representative_dataset(): for _ in range(100): data = np.random.rand(1, 3, 4, 3) yield [data.astype(np.float32)] model = Model() concrete_func = model.tf_function.get_concrete_function( tf.TensorSpec([1, 3, 4, 3], dtype=tf.float32)) converter = tf.lite.TFLiteConverter.from_concrete_functions( [concrete_func]) converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_dataset converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 tflite_graph = converter.convert() tflite_model = tflite.Model.Model.GetRootAsModel(tflite_graph, 0) relay_module, params = relay.frontend.from_tflite( tflite_model, shape_dict={"x": [1, 3, 4, 3]}, dtype_dict={"x": "int8"}, ) mod = partition_for_ethosu(relay_module, params) # Generate reference data input_data, output_data = generate_ref_data_tflite(tflite_graph) def compile_to_main_func(interface_api="c", use_unpacked_api=True): test_runner = create_test_runner() compiled_models = compile_models( models=AOTTestModel( module=mod, inputs=input_data, outputs=output_data, ), interface_api=interface_api, use_unpacked_api=use_unpacked_api, workspace_byte_alignment=16, pass_config=test_runner.pass_config, ) main_ir_module = compiled_models[ 0].executor_factory.lowered_ir_mods.items()[0][1] main_func = main_ir_module["__tvm_main__"] return main_func return compile_to_main_func
from tflite import Model import numpy as np from collections import OrderedDict from facial_lm_model import FacialLM_Model from utils import GetKeysDict import torch data = open("model_weights/face_landmark.tflite", "rb").read() model = Model.GetRootAsModel(data, 0) tflite_graph = model.Subgraphs(0) tflite_graph.Name() # Tensor name to index mapping tflite_tensor_dict = {} for i in range(tflite_graph.TensorsLength()): tflite_tensor_dict[tflite_graph.Tensors(i).Name().decode("utf8")] = i def get_weights(tensor_name): index = tflite_tensor_dict[tensor_name] tensor = tflite_graph.Tensors(index) buffer = tensor.Buffer() shape = [tensor.Shape(i) for i in range(tensor.ShapeLength())] weights = model.Buffers(buffer).DataAsNumpy() weights = weights.view(dtype=np.float32) weights = weights.reshape(shape) return weights
def handle_fc_parsing(op: tflite.Operator, builtin_code: tflite.BuiltinOperator, graph: tflite.SubGraph, model: tflite.Model) -> Tuple[str, Layer]: op_opt = op.BuiltinOptions() opt = tflite.FullyConnectedOptions() opt.Init(op_opt.Bytes, op_opt.Pos) input_ids = op.InputsAsNumpy() output_ids = op.OutputsAsNumpy() assert len(input_ids) == 3 input_tensor_id, weight_tensor_id, bias_tensor_id = list(input_ids) input_tensor = graph.Tensors(input_tensor_id) input_shape = input_tensor.ShapeAsNumpy() assert len(input_shape) == 2 input_batch_size, input_size = list(input_shape) weight_tensor = graph.Tensors(weight_tensor_id) weight_shape = weight_tensor.ShapeAsNumpy() assert len(weight_shape) == 2 weight_width, weight_height = list(weight_shape) weight_quantization = weight_tensor.Quantization() weight_quantization_scales = weight_quantization.ScaleAsNumpy() assert len(weight_quantization_scales) == 1 weight_scale = weight_quantization_scales[0] weight_zero_points = weight_quantization.ZeroPointAsNumpy() assert len(weight_zero_points) == 1 weight_zero_point = weight_zero_points[0] weight_data = clean_data_int_op(model.Buffers(weight_tensor.Buffer()).DataAsNumpy(), is_32=False).reshape(weight_shape) bias_tensor = graph.Tensors(bias_tensor_id) bias_data = clean_data_int_op(model.Buffers(bias_tensor.Buffer()).DataAsNumpy(), is_32=True) assert len(output_ids) == 1 output_id = output_ids[0] output_tensor = graph.Tensors(output_id) output_shape = output_tensor.ShapeAsNumpy() assert len(output_shape) == 2 output_batch_size, output_size = list(output_shape) output_quantization = output_tensor.Quantization() output_quantization_scales = output_quantization.ScaleAsNumpy() assert len(output_quantization_scales) == 1 output_scale = output_quantization_scales[0] output_zero_points = output_quantization.ZeroPointAsNumpy() assert len(output_zero_points) == 1 output_zero_point = output_zero_points[0] activation_type = opt.FusedActivationFunction() followed_by_relu = activation_type == tflite.ActivationFunctionType.RELU input_name = input_tensor.Name() output_name = output_tensor.Name() layer = FC( input=None, output_size=output_size, input_size=input_size, weight_data=weight_data, weight_scale=weight_scale, bias_data=bias_data, output_scale=output_scale, followed_by_relu=followed_by_relu, weight_zero_point=weight_zero_point, output_zero_point=output_zero_point ) return output_name, layer, input_name
def handle_conv2d_parsing(op: tflite.Operator, builtin_code: tflite.BuiltinOperator, graph: tflite.SubGraph, model: tflite.Model) -> Tuple[str, Layer]: op_opt = op.BuiltinOptions() opt = tflite.Conv2DOptions() opt.Init(op_opt.Bytes, op_opt.Pos) stride = opt.StrideW() input_ids = op.InputsAsNumpy() output_ids = op.OutputsAsNumpy() assert len(input_ids) == 3 input_tensor_id, filter_tensor_id, bias_tensor_id = list(input_ids) input_tensor = graph.Tensors(input_tensor_id) input_shape = input_tensor.ShapeAsNumpy() assert len(input_shape) == 4 _, input_width, input_height, input_depth = list(input_shape) filter_tensor = graph.Tensors(filter_tensor_id) filter_shape = filter_tensor.ShapeAsNumpy() assert len(filter_shape) == 4 if builtin_code == tflite.BuiltinOperator.CONV_2D: filter_count, filter_width, filter_height, filter_in_channels = list(filter_shape) else: filter_in_channels, filter_width, filter_height, filter_count = list(filter_shape) filter_quantization = filter_tensor.Quantization() filter_scales = filter_quantization.ScaleAsNumpy() filter_data = clean_data_int_op(model.Buffers(filter_tensor.Buffer()).DataAsNumpy(), is_32=False).reshape(filter_shape) padding = opt.Padding() padding_size = 0 if padding == tflite.Padding.SAME: padding_size = int(filter_width) // 2 else: # PADDING should be valid in this case raise Exception(f"Unexpected padding type: {padding}") bias_tensor = graph.Tensors(bias_tensor_id) bias_data = clean_data_int_op(model.Buffers(bias_tensor.Buffer()).DataAsNumpy(), is_32=True) assert len(output_ids) == 1 output_id = output_ids[0] output_tensor = graph.Tensors(output_id) output_shape = output_tensor.ShapeAsNumpy() output_batch_size, output_width, output_height, output_channels = list(output_shape) assert output_channels == filter_count output_quantization = output_tensor.Quantization().ScaleAsNumpy() assert len(output_quantization) == 1 output_scale = output_quantization[0] activation_type = opt.FusedActivationFunction() followed_by_relu = activation_type == tflite.ActivationFunctionType.RELU output_name = output_tensor.Name() input_name = input_tensor.Name() if builtin_code == tflite.BuiltinOperator.CONV_2D: return output_name, Conv2d( input=None, filter_width=filter_width, filter_height=filter_height, filter_in_channels=filter_in_channels, filter_count=filter_count, filter_data=filter_data, bias_data=bias_data, input_width=input_width, input_height=input_height, stride=stride, padding=padding_size, followed_by_relu=followed_by_relu, output_scale=output_scale, filter_scales=filter_scales, output_width=output_width, output_height=output_height ), input_name else: return output_name, Conv2d_DW( input=None, filter_width=filter_width, filter_height=filter_height, filter_in_channels=filter_in_channels, filter_count=filter_count, filter_data=filter_data, bias_data=bias_data, input_width=input_width, input_height=input_height, stride=stride, padding=padding_size, followed_by_relu=followed_by_relu, output_scale=output_scale, filter_scales=filter_scales, output_width=output_width, output_height=output_height ), input_name