Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for Resizing op #36

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ python3 -m keras2ncnn -i SOME_H5DF_FILE.h5 -o DIR_TO_SAVE_NCNN_PARAM --plot_grap
- Maximum
- TensorFlowOpLayer (Mul with constant)
- Permute (Need more testing)
- Resizing (Requires tensorflow/keras for conversion)

## Ops that will be dropped by converter
- Dropout
Expand Down
46 changes: 38 additions & 8 deletions keras2ncnn/h5df_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@ def __init__(self, h5_file):
self.model_config = json.loads(self.__decode(model_config_raw))
self.keras_version = self.get_keras_version()

try:
import tensorflow.keras as keras
except ModuleNotFoundError:
try:
import keras
except ModuleNotFoundError:
pass

try:
model = keras.models.load_model(h5_file)
self.layer_input_shapes = {layer.name: layer.input_shape for layer in model.layers}
except NameError:
self.layer_input_shapes = None
except Exception as e:
print(f"Exception {e} occurred when attempting to load model in keras. Will attempt conversion without "
f"additional information.")
self.layer_input_shapes = None

if self.keras_version != '1':
weight_layers = self.f['model_weights']
else:
Expand Down Expand Up @@ -124,10 +142,16 @@ def parse_graph(self, graph_helper):
inbound_nodes = graph_helper.get_graph_tail()

graph_helper.node(layer_name, inbound_nodes)
graph_helper.set_node_attr(
layer_name, {
'layer': layers, 'weight': self.find_weights_root(
layer_name)})
if self.layer_input_shapes is None:
graph_helper.set_node_attr(
layer_name, {
'layer': layers, 'weight': self.find_weights_root(
layer_name)})
else:
graph_helper.set_node_attr(
layer_name, {
'layer': layers, 'weight': self.find_weights_root(
layer_name), 'input_shape': self.layer_input_shapes[layer_name]})

def parse_model_graph(self, model_layers, graph_helper):
for layer in model_layers:
Expand All @@ -136,7 +160,13 @@ def parse_model_graph(self, model_layers, graph_helper):
inbound_nodes = graph_helper.get_graph_tail()

graph_helper.node(layer['name'], inbound_nodes)
graph_helper.set_node_attr(
layer['name'], {
'layer': layer, 'weight': self.find_weights_root(
layer['name'])})
if self.layer_input_shapes is None:
graph_helper.set_node_attr(
layer['name'], {
'layer': layer, 'weight': self.find_weights_root(
layer['name'])})
else:
graph_helper.set_node_attr(
layer['name'], {
'layer': layer, 'weight': self.find_weights_root(
layer['name']), 'input_shape': self.layer_input_shapes[layer['name']]})
49 changes: 49 additions & 0 deletions keras2ncnn/keras_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,55 @@ def BatchNormalization_helper(
bn_params['bn_moving_variance'],
bn_params['bn_beta']]})

def Resizing_helper(
self,
layer,
keras_graph_helper,
ncnn_graph_helper,
ncnn_helper):
if "crop_to_aspect_ratio" in layer["layer"]["config"] and \
layer["layer"]["config"]["crop_to_aspect_ratio"]:
print(f'[ERROR] Crop to aspect ratio is currently not supported for Resizing layers.')
frameinfo = inspect.getframeinfo(inspect.currentframe())
print('Failed to convert at %s:%d %s()' %
(frameinfo.filename, frameinfo.lineno, frameinfo.function))
sys.exit(-1)
# Set the interpolation type and make sure it is supported.
if layer["layer"]["config"]["interpolation"].lower() == "bilinear":
resize_type = 2
elif layer["layer"]["config"]["interpolation"].lower() == "nearest":
resize_type = 1
else:
print(f'[ERROR] Activation type {layer.interpolation} is is not supported yet. '
f'Currently, only bilinear and nearest are supported as Resizing layer interpolation types.')
frameinfo = inspect.getframeinfo(inspect.currentframe())
print('Failed to convert at %s:%d %s()' %
(frameinfo.filename, frameinfo.lineno, frameinfo.function))
sys.exit(-1)
if "input_shape" in layer:
height_scale = layer["layer"]["config"]["height"] / layer["input_shape"][1]
width_scale = layer["layer"]["config"]["width"] / layer["input_shape"][2]
output_height = layer["layer"]["config"]["height"]
output_width = layer["layer"]["config"]["width"]
else:
print(f'[ERROR] Could not find input shape for Resizing layer. Please make sure you have either tensorflow '
f'or keras installed.')
frameinfo = inspect.getframeinfo(inspect.currentframe())
print('Failed to convert at %s:%d %s()' %
(frameinfo.filename, frameinfo.lineno, frameinfo.function))
sys.exit(-1)
ncnn_graph_attr = ncnn_helper.dump_args(
'Interp', resize_type=resize_type, height_scale=height_scale, width_scale=width_scale,
output_height=output_height, output_width=output_width
)
ncnn_graph_helper.node(
layer['layer']['name'],
keras_graph_helper.get_node_inbounds(
layer['layer']['name']))
ncnn_graph_helper.set_node_attr(
layer['layer']['name'], {
'type': 'Interp', 'param': ncnn_graph_attr, 'binary': []})

def Add_helper(
self,
layer,
Expand Down