This forum is disabled, please visit https://forum.opencv.org

1 | initial version |

Hi, @berak, DNN doesn't support TensorFlow's flatten op because it computes Shape of input in runtime. Then it does a reshape. There are several ways to make it more simple for DNN:

1. Use reshape op instead but computing input's shape out of the graph:

```
total = int(np.prod(inp.shape[1:]))
flattened = tf.reshape(inp, [-1, total])
```

2. More preferable way because it'll solve both flatten and dropout ops import:

2.1. Freeze and optimize graph as you did.

2.2. Call the following script to create a text graph representation:

```
import tensorflow as tf
# Read the graph.
with tf.gfile.FastGFile('face_opt.pb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
# Remove Const nodes.
for i in reversed(range(len(graph_def.node))):
if graph_def.node[i].op == 'Const':
del graph_def.node[i]
for attr in ['T', 'data_format', 'Tshape', 'N', 'Tidx', 'Tdim',
'use_cudnn_on_gpu', 'Index', 'Tperm', 'is_training',
'Tpaddings']:
if attr in graph_def.node[i].attr:
del graph_def.node[i].attr[attr]
# Save as text.
tf.train.write_graph(graph_def, "", "text_graph.pbtxt", as_text=True)
```

2.3.
Replace a subgraph of nodes `ConvNet/Flatten/Shape`

, `ConvNet/Flatten/Slice`

, `ConvNet/Flatten/Slice_1`

, `ConvNet/Flatten/Prod`

, `ConvNet/Flatten/ExpandDim`

, `ConvNet/Flatten/concat`

, `ConvNet/Flatten/Reshape`

onto the following node:

```
node {
name: "ConvNet/Flatten/Reshape"
op: "Flatten"
input: "ConvNet/max_pooling2d_2/MaxPool"
}
```

2.4.
Remove a subgraph from `ConvNet/dropout/dropout/Shape`

to `ConvNet/dropout/dropout/mul`

(inclusive both). Replace `ConvNet/dense_2/MatMul`

's input from `ConvNet/dropout/dropout/mul`

to `ConvNet/dense/BiasAdd`

.

Then use both binary graph and a text one during import: https://docs.opencv.org/master/d6/d0f/group__dnn.html#gad820b280978d06773234ba6841e77e8d .

2 | No.2 Revision |

Hi, @berak, DNN doesn't support TensorFlow's flatten op because it computes Shape of input in runtime. Then it does a reshape. There are several ways to make it more simple for DNN:

1.
Use reshape op instead but ~~computing ~~compute input's shape out of the graph:

```
total = int(np.prod(inp.shape[1:]))
flattened = tf.reshape(inp, [-1, total])
```

2. More preferable way because it'll solve both flatten and dropout ops import:

2.1. Freeze and optimize graph as you did.

2.2. Call the following script to create a text graph representation:

```
import tensorflow as tf
# Read the graph.
with tf.gfile.FastGFile('face_opt.pb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
# Remove Const nodes.
for i in reversed(range(len(graph_def.node))):
if graph_def.node[i].op == 'Const':
del graph_def.node[i]
for attr in ['T', 'data_format', 'Tshape', 'N', 'Tidx', 'Tdim',
'use_cudnn_on_gpu', 'Index', 'Tperm', 'is_training',
'Tpaddings']:
if attr in graph_def.node[i].attr:
del graph_def.node[i].attr[attr]
# Save as text.
tf.train.write_graph(graph_def, "", "text_graph.pbtxt", as_text=True)
```

2.3.
Replace a subgraph of nodes `ConvNet/Flatten/Shape`

, `ConvNet/Flatten/Slice`

, `ConvNet/Flatten/Slice_1`

, `ConvNet/Flatten/Prod`

, `ConvNet/Flatten/ExpandDim`

, `ConvNet/Flatten/concat`

, `ConvNet/Flatten/Reshape`

onto the following node:

```
node {
name: "ConvNet/Flatten/Reshape"
op: "Flatten"
input: "ConvNet/max_pooling2d_2/MaxPool"
}
```

2.4.
Remove a subgraph from `ConvNet/dropout/dropout/Shape`

to `ConvNet/dropout/dropout/mul`

(inclusive both). Replace `ConvNet/dense_2/MatMul`

's input from `ConvNet/dropout/dropout/mul`

to `ConvNet/dense/BiasAdd`

.

Then use both binary graph and a text one during import: https://docs.opencv.org/master/d6/d0f/group__dnn.html#gad820b280978d06773234ba6841e77e8d .

Copyright OpenCV foundation, 2012-2018. Content on this site is licensed under a Creative Commons Attribution Share Alike 3.0 license.