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

Input layer didn't get converted #18

Closed
AIGirl10 opened this issue Jan 12, 2021 · 6 comments
Closed

Input layer didn't get converted #18

AIGirl10 opened this issue Jan 12, 2021 · 6 comments
Labels
enhancement New feature or request

Comments

@AIGirl10
Copy link

AIGirl10 commented Jan 12, 2021

Trying to convert keras model to NCNN.

When tried to convert model, it got converted successfully but convolution layer was the first layer

Convolution              conv2d_3                                0 1  conv2d_3_blob 0=16 1=3 2=1 3=1 4=0 5=1 6=432 9=1 11=3 12=1 13=1 

Not able to understand why input layer (data) couldn't get converted. Any reasons ?

Please help ! thank you.

@MarsTechHAN

@MarsTechHAN
Copy link
Owner

Hi, the input layer should be converted. The converter should find the InputLayer layer and convert that to ncnn Input layer.
Can you attach your keras file and a screenshot of the file opened by Netron.

@AIGirl10
Copy link
Author

@MarsTechHAN

Model link: here

Netron Graph: here

@MarsTechHAN
Copy link
Owner

MarsTechHAN commented Jan 18, 2021

Hi, from the decoded model config string, there is no InputLayer inside your model. Without an input layer, there is no way to know your input shape settings.

However, I am thinking maybe I should add a default input Layer. I will PR that later.

If you want to fix your model. you can edit your model config to:

7767517
12 12
Input                    input_0                                 0 1 input_0_blob
Convolution              conv2d_3                                1 1 input_0_blob conv2d_3_blob 0=16 1=3 2=1 3=1 4=0 5=1 6=432 9=1 11=3 12=1 13=1 
Pooling                  average_pooling2d_3                     1 1 conv2d_3_blob average_pooling2d_3_blob 0=1 1=2 11=2 2=2 12=2 3=0 4=0 5=1 
Convolution              conv2d_4                                1 1 average_pooling2d_3_blob conv2d_4_blob 0=32 1=3 2=1 3=1 4=0 5=1 6=4608 9=1 11=3 12=1 13=1 
Pooling                  average_pooling2d_4                     1 1 conv2d_4_blob average_pooling2d_4_blob 0=1 1=2 11=2 2=2 12=2 3=0 4=0 5=1 
Convolution              conv2d_5                                1 1 average_pooling2d_4_blob conv2d_5_blob 0=64 1=3 2=1 3=1 4=0 5=1 6=18432 9=1 11=3 12=1 13=1 
Pooling                  average_pooling2d_5                     1 1 conv2d_5_blob average_pooling2d_5_blob 0=1 1=2 11=2 2=2 12=2 3=0 4=0 5=1 
Reshape                  flatten_1                               1 1 average_pooling2d_5_blob flatten_1_blob 0=-1 1=-233 2=-233 3=1 
InnerProduct             dense_3                                 1 1 flatten_1_blob dense_3_blob 0=256 1=1 2=589824 9=1 
InnerProduct             dense_4                                 1 1 dense_3_blob dense_4_blob 0=128 1=1 2=32768 9=1 
InnerProduct             dense_5                                 1 1 dense_4_blob dense_5_blob 0=2 1=1 2=256 9=1 
Softmax                  dense_5_Softmax                         1 1 dense_5_blob dense_5_Softmax_blob 0=0 


Here is the decoded config string in your model

{
    "class_name": "Sequential",
    "config": {
        "layers": [
            {
                "class_name": "Conv2D",
                "config": {
                    "activation": "relu",
                    "activity_regularizer": null,
                    "batch_input_shape": [
                        null,
                        64,
                        64,
                        3
                    ],
                    "bias_constraint": null,
                    "bias_initializer": {
                        "class_name": "Zeros",
                        "config": {
                            "dtype": "float32"
                        }
                    },
                    "bias_regularizer": null,
                    "data_format": "channels_last",
                    "dilation_rate": [
                        1,
                        1
                    ],
                    "dtype": "float32",
                    "filters": 16,
                    "kernel_constraint": null,
                    "kernel_initializer": {
                        "class_name": "GlorotUniform",
                        "config": {
                            "dtype": "float32",
                            "seed": null
                        }
                    },
                    "kernel_regularizer": null,
                    "kernel_size": [
                        3,
                        3
                    ],
                    "name": "conv2d_3",
                    "padding": "valid",
                    "strides": [
                        1,
                        1
                    ],
                    "trainable": true,
                    "use_bias": true
                }
            },
            {
                "class_name": "AveragePooling2D",
                "config": {
                    "data_format": "channels_last",
                    "dtype": "float32",
                    "name": "average_pooling2d_3",
                    "padding": "valid",
                    "pool_size": [
                        2,
                        2
                    ],
                    "strides": [
                        2,
                        2
                    ],
                    "trainable": true
                }
            },
            {
                "class_name": "Dropout",
                "config": {
                    "dtype": "float32",
                    "name": "dropout_5",
                    "noise_shape": null,
                    "rate": 0.5,
                    "seed": null,
                    "trainable": true
                }
            },
            {
                "class_name": "Conv2D",
                "config": {
                    "activation": "relu",
                    "activity_regularizer": null,
                    "bias_constraint": null,
                    "bias_initializer": {
                        "class_name": "Zeros",
                        "config": {
                            "dtype": "float32"
                        }
                    },
                    "bias_regularizer": null,
                    "data_format": "channels_last",
                    "dilation_rate": [
                        1,
                        1
                    ],
                    "dtype": "float32",
                    "filters": 32,
                    "kernel_constraint": null,
                    "kernel_initializer": {
                        "class_name": "GlorotUniform",
                        "config": {
                            "dtype": "float32",
                            "seed": null
                        }
                    },
                    "kernel_regularizer": null,
                    "kernel_size": [
                        3,
                        3
                    ],
                    "name": "conv2d_4",
                    "padding": "valid",
                    "strides": [
                        1,
                        1
                    ],
                    "trainable": true,
                    "use_bias": true
                }
            },
            {
                "class_name": "AveragePooling2D",
                "config": {
                    "data_format": "channels_last",
                    "dtype": "float32",
                    "name": "average_pooling2d_4",
                    "padding": "valid",
                    "pool_size": [
                        2,
                        2
                    ],
                    "strides": [
                        2,
                        2
                    ],
                    "trainable": true
                }
            },
            {
                "class_name": "Dropout",
                "config": {
                    "dtype": "float32",
                    "name": "dropout_6",
                    "noise_shape": null,
                    "rate": 0.5,
                    "seed": null,
                    "trainable": true
                }
            },
            {
                "class_name": "Conv2D",
                "config": {
                    "activation": "relu",
                    "activity_regularizer": null,
                    "bias_constraint": null,
                    "bias_initializer": {
                        "class_name": "Zeros",
                        "config": {
                            "dtype": "float32"
                        }
                    },
                    "bias_regularizer": null,
                    "data_format": "channels_last",
                    "dilation_rate": [
                        1,
                        1
                    ],
                    "dtype": "float32",
                    "filters": 64,
                    "kernel_constraint": null,
                    "kernel_initializer": {
                        "class_name": "GlorotUniform",
                        "config": {
                            "dtype": "float32",
                            "seed": null
                        }
                    },
                    "kernel_regularizer": null,
                    "kernel_size": [
                        3,
                        3
                    ],
                    "name": "conv2d_5",
                    "padding": "valid",
                    "strides": [
                        1,
                        1
                    ],
                    "trainable": true,
                    "use_bias": true
                }
            },
            {
                "class_name": "AveragePooling2D",
                "config": {
                    "data_format": "channels_last",
                    "dtype": "float32",
                    "name": "average_pooling2d_5",
                    "padding": "valid",
                    "pool_size": [
                        2,
                        2
                    ],
                    "strides": [
                        2,
                        2
                    ],
                    "trainable": true
                }
            },
            {
                "class_name": "Dropout",
                "config": {
                    "dtype": "float32",
                    "name": "dropout_7",
                    "noise_shape": null,
                    "rate": 0.5,
                    "seed": null,
                    "trainable": true
                }
            },
            {
                "class_name": "Flatten",
                "config": {
                    "data_format": "channels_last",
                    "dtype": "float32",
                    "name": "flatten_1",
                    "trainable": true
                }
            },
            {
                "class_name": "Dense",
                "config": {
                    "activation": "relu",
                    "activity_regularizer": null,
                    "bias_constraint": null,
                    "bias_initializer": {
                        "class_name": "Zeros",
                        "config": {
                            "dtype": "float32"
                        }
                    },
                    "bias_regularizer": null,
                    "dtype": "float32",
                    "kernel_constraint": null,
                    "kernel_initializer": {
                        "class_name": "GlorotUniform",
                        "config": {
                            "dtype": "float32",
                            "seed": null
                        }
                    },
                    "kernel_regularizer": null,
                    "name": "dense_3",
                    "trainable": true,
                    "units": 256,
                    "use_bias": true
                }
            },
            {
                "class_name": "Dropout",
                "config": {
                    "dtype": "float32",
                    "name": "dropout_8",
                    "noise_shape": null,
                    "rate": 0.2,
                    "seed": null,
                    "trainable": true
                }
            },
            {
                "class_name": "Dense",
                "config": {
                    "activation": "relu",
                    "activity_regularizer": null,
                    "bias_constraint": null,
                    "bias_initializer": {
                        "class_name": "Zeros",
                        "config": {
                            "dtype": "float32"
                        }
                    },
                    "bias_regularizer": null,
                    "dtype": "float32",
                    "kernel_constraint": null,
                    "kernel_initializer": {
                        "class_name": "GlorotUniform",
                        "config": {
                            "dtype": "float32",
                            "seed": null
                        }
                    },
                    "kernel_regularizer": null,
                    "name": "dense_4",
                    "trainable": true,
                    "units": 128,
                    "use_bias": true
                }
            },
            {
                "class_name": "Dense",
                "config": {
                    "activation": "softmax",
                    "activity_regularizer": null,
                    "bias_constraint": null,
                    "bias_initializer": {
                        "class_name": "Zeros",
                        "config": {
                            "dtype": "float32"
                        }
                    },
                    "bias_regularizer": null,
                    "dtype": "float32",
                    "kernel_constraint": null,
                    "kernel_initializer": {
                        "class_name": "GlorotUniform",
                        "config": {
                            "dtype": "float32",
                            "seed": null
                        }
                    },
                    "kernel_regularizer": null,
                    "name": "dense_5",
                    "trainable": true,
                    "units": 2,
                    "use_bias": true
                }
            }
        ],
        "name": "sequential_1"
    }
}

@MarsTechHAN MarsTechHAN added enhancement New feature or request and removed Not able to reproduce labels Jan 18, 2021
@AIGirl10
Copy link
Author

@MarsTechHAN

Ohh okk Thanks. Since netron showed input layer I thought it's there.

About input size model needs 64×64 . Also adding input in Param file doesn't it affect the number of parameters (first line in .param file)

So maybe correct .Param can be something like this

Input                    input_0                                 0 1 input_0_blob 0=1 1=3 2=64 3=64

Right ?

Again Thanks for your help.

@MarsTechHAN
Copy link
Owner

MarsTechHAN commented Jan 18, 2021

You can check the code, the first line is just a constant magic, but the second line is the layer count and blob count which should be increment. ncnn uses dynamic shapes alone for all executions, so you don't need to give a constant input shape here.

def emit_param(self, file_name, seq):
ncnn_param_file = open(file_name, 'w+')
ncnn_param_file.write('%d\n' % self.MAGGGGGIC)
param_contect = ''
blob_count = 0
for layer_name in seq:
layer_type = self.ncnn_graph.get_node_attr(layer_name)['type']
input_count = len(self.ncnn_graph.get_node_inbounds(layer_name))
output_count = len(self.ncnn_graph.get_node_outbounds(layer_name))
output_count = 1 if output_count == 0 else output_count
input_blobs = []
inbound_nodes = self.ncnn_graph.get_node_inbounds(layer_name)
for in_node in inbound_nodes:
if len(self.ncnn_graph.get_node_outbounds(in_node)) > 1:
input_blobs.append(
'%s_blob_idx_%d' %
(in_node, self.ncnn_graph.get_node_outbounds(in_node).index(layer_name)))
else:
input_blobs.append('%s_blob' % in_node)
output_blobs = []
if output_count > 1:
for i in range(output_count):
output_blobs.append('%s_blob_idx_%d' % (layer_name, i))
else:
output_blobs.append('%s_blob' % layer_name)
blob_count += len(output_blobs)
param_contect += (
('%s' + (
25 - len(layer_type)) * ' ' + '%s' + (
40 - len(layer_name)) * ' ' + '%d %d %s %s %s\n') % (layer_type,
layer_name,
input_count,
output_count,
' '.join(input_blobs),
' '.join(output_blobs),
self.ncnn_graph.get_node_attr(layer_name)['param']))
layer_count = len(self.ncnn_graph.get_graph())
ncnn_param_file.write('%d %d\n' % (layer_count, blob_count))
ncnn_param_file.write(param_contect)
ncnn_param_file.close()

@MarsTechHAN
Copy link
Owner

Fix in 9841e26, I will close this issue since the issue has been resolved and no other issue raised.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants