Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Optimize

python ~/tensorflow/tensorflow/python/tools/optimize_for_inference.py \
  --input model.pb \
  --output opt_model.pb \
  --input_names input_1 \
  --output_names output_node0

Text graph

See http://answers.opencv.org/question/183507/opencv-dnn-import-error-for-keras-pretrained-vgg16-model/

Flatten

Remove nodes flatten/Shape, flatten/strided_slice, flatten/Prod, flatten/stack Replace

node {
  name: "flatten/Reshape"
  op: "Reshape"
  input: "block5_pool/MaxPool"
  input: "flatten/stack"
}

to

node {
  name: "flatten/Reshape"
  op: "Flatten"
  input: "block5_pool/MaxPool"
}

Dropout

Remove nodes dropout_1/keras_learning_phase, dropout_1/cond/Switch, dropout_1/cond/mul/Switch, dropout_1/cond/mul, dropout_1/cond/dropout/Shape, dropout_1/cond/dropout/random_uniform/RandomUniform, dropout_1/cond/dropout/random_uniform/sub, dropout_1/cond/dropout/random_uniform/mul, dropout_1/cond/dropout/random_uniform, dropout_1/cond/dropout/add, dropout_1/cond/dropout/Floor, dropout_1/cond/dropout/div, dropout_1/cond/dropout/mul, dropout_1/cond/Switch_1, dropout_1/cond/Merge.

Replace input: "dropout_1/cond/Merge" onto input: "dense_1/Relu".

Test

import tensorflow as tf
import cv2 as cv
import numpy as np

# Read the graph.
with tf.gfile.FastGFile('model.pb') as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())

np.random.seed(223)
inp = np.random.standard_normal([1, 224, 224, 3]).astype(np.float32)

with tf.Session() as sess:
    # Restore session
    sess.graph.as_default()
    tf.import_graph_def(graph_def, name='')

    out = sess.run(sess.graph.get_tensor_by_name('output_node0:0'),
                   feed_dict={'input_1:0': inp})

cvNet = cv.dnn.readNetFromTensorflow('model.pb', 'graph.pbtxt')
cvNet.setInput(inp.transpose(0, 3, 1, 2))
cvOut = cvNet.forward()
print np.max(np.abs(cvOut - out))

Here it's a graph:

node {
  name: "input_1"
  op: "Placeholder"
  attr {
    key: "dtype"
    value {
      type: DT_FLOAT
    }
  }
}
node {
  name: "block1_conv1/convolution"
  op: "Conv2D"
  input: "input_1"
  input: "block1_conv1/kernel"
  attr {
    key: "padding"
    value {
      s: "SAME"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 1
        i: 1
        i: 1
      }
    }
  }
}
node {
  name: "block1_conv1/BiasAdd"
  op: "BiasAdd"
  input: "block1_conv1/convolution"
  input: "block1_conv1/bias"
}
node {
  name: "block1_conv1/Relu"
  op: "Relu"
  input: "block1_conv1/BiasAdd"
}
node {
  name: "block1_conv2/convolution"
  op: "Conv2D"
  input: "block1_conv1/Relu"
  input: "block1_conv2/kernel"
  attr {
    key: "padding"
    value {
      s: "SAME"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 1
        i: 1
        i: 1
      }
    }
  }
}
node {
  name: "block1_conv2/BiasAdd"
  op: "BiasAdd"
  input: "block1_conv2/convolution"
  input: "block1_conv2/bias"
}
node {
  name: "block1_conv2/Relu"
  op: "Relu"
  input: "block1_conv2/BiasAdd"
}
node {
  name: "block1_pool/MaxPool"
  op: "MaxPool"
  input: "block1_conv2/Relu"
  attr {
    key: "ksize"
    value {
      list {
        i: 1
        i: 2
        i: 2
        i: 1
      }
    }
  }
  attr {
    key: "padding"
    value {
      s: "VALID"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 2
        i: 2
        i: 1
      }
    }
  }
}
node {
  name: "block2_conv1/convolution"
  op: "Conv2D"
  input: "block1_pool/MaxPool"
  input: "block2_conv1/kernel"
  attr {
    key: "padding"
    value {
      s: "SAME"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 1
        i: 1
        i: 1
      }
    }
  }
}
node {
  name: "block2_conv1/BiasAdd"
  op: "BiasAdd"
  input: "block2_conv1/convolution"
  input: "block2_conv1/bias"
}
node {
  name: "block2_conv1/Relu"
  op: "Relu"
  input: "block2_conv1/BiasAdd"
}
node {
  name: "block2_conv2/convolution"
  op: "Conv2D"
  input: "block2_conv1/Relu"
  input: "block2_conv2/kernel"
  attr {
    key: "padding"
    value {
      s: "SAME"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 1
        i: 1
        i: 1
      }
    }
  }
}
node {
  name: "block2_conv2/BiasAdd"
  op: "BiasAdd"
  input: "block2_conv2/convolution"
  input: "block2_conv2/bias"
}
node {
  name: "block2_conv2/Relu"
  op: "Relu"
  input: "block2_conv2/BiasAdd"
}
node {
  name: "block2_pool/MaxPool"
  op: "MaxPool"
  input: "block2_conv2/Relu"
  attr {
    key: "ksize"
    value {
      list {
        i: 1
        i: 2
        i: 2
        i: 1
      }
    }
  }
  attr {
    key: "padding"
    value {
      s: "VALID"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 2
        i: 2
        i: 1
      }
    }
  }
}
node {
  name: "block3_conv1/convolution"
  op: "Conv2D"
  input: "block2_pool/MaxPool"
  input: "block3_conv1/kernel"
  attr {
    key: "padding"
    value {
      s: "SAME"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 1
        i: 1
        i: 1
      }
    }
  }
}
node {
  name: "block3_conv1/BiasAdd"
  op: "BiasAdd"
  input: "block3_conv1/convolution"
  input: "block3_conv1/bias"
}
node {
  name: "block3_conv1/Relu"
  op: "Relu"
  input: "block3_conv1/BiasAdd"
}
node {
  name: "block3_conv2/convolution"
  op: "Conv2D"
  input: "block3_conv1/Relu"
  input: "block3_conv2/kernel"
  attr {
    key: "padding"
    value {
      s: "SAME"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 1
        i: 1
        i: 1
      }
    }
  }
}
node {
  name: "block3_conv2/BiasAdd"
  op: "BiasAdd"
  input: "block3_conv2/convolution"
  input: "block3_conv2/bias"
}
node {
  name: "block3_conv2/Relu"
  op: "Relu"
  input: "block3_conv2/BiasAdd"
}
node {
  name: "block3_conv3/convolution"
  op: "Conv2D"
  input: "block3_conv2/Relu"
  input: "block3_conv3/kernel"
  attr {
    key: "padding"
    value {
      s: "SAME"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 1
        i: 1
        i: 1
      }
    }
  }
}
node {
  name: "block3_conv3/BiasAdd"
  op: "BiasAdd"
  input: "block3_conv3/convolution"
  input: "block3_conv3/bias"
}
node {
  name: "block3_conv3/Relu"
  op: "Relu"
  input: "block3_conv3/BiasAdd"
}
node {
  name: "block3_pool/MaxPool"
  op: "MaxPool"
  input: "block3_conv3/Relu"
  attr {
    key: "ksize"
    value {
      list {
        i: 1
        i: 2
        i: 2
        i: 1
      }
    }
  }
  attr {
    key: "padding"
    value {
      s: "VALID"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 2
        i: 2
        i: 1
      }
    }
  }
}
node {
  name: "block4_conv1/convolution"
  op: "Conv2D"
  input: "block3_pool/MaxPool"
  input: "block4_conv1/kernel"
  attr {
    key: "padding"
    value {
      s: "SAME"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 1
        i: 1
        i: 1
      }
    }
  }
}
node {
  name: "block4_conv1/BiasAdd"
  op: "BiasAdd"
  input: "block4_conv1/convolution"
  input: "block4_conv1/bias"
}
node {
  name: "block4_conv1/Relu"
  op: "Relu"
  input: "block4_conv1/BiasAdd"
}
node {
  name: "block4_conv2/convolution"
  op: "Conv2D"
  input: "block4_conv1/Relu"
  input: "block4_conv2/kernel"
  attr {
    key: "padding"
    value {
      s: "SAME"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 1
        i: 1
        i: 1
      }
    }
  }
}
node {
  name: "block4_conv2/BiasAdd"
  op: "BiasAdd"
  input: "block4_conv2/convolution"
  input: "block4_conv2/bias"
}
node {
  name: "block4_conv2/Relu"
  op: "Relu"
  input: "block4_conv2/BiasAdd"
}
node {
  name: "block4_conv3/convolution"
  op: "Conv2D"
  input: "block4_conv2/Relu"
  input: "block4_conv3/kernel"
  attr {
    key: "padding"
    value {
      s: "SAME"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 1
        i: 1
        i: 1
      }
    }
  }
}
node {
  name: "block4_conv3/BiasAdd"
  op: "BiasAdd"
  input: "block4_conv3/convolution"
  input: "block4_conv3/bias"
}
node {
  name: "block4_conv3/Relu"
  op: "Relu"
  input: "block4_conv3/BiasAdd"
}
node {
  name: "block4_pool/MaxPool"
  op: "MaxPool"
  input: "block4_conv3/Relu"
  attr {
    key: "ksize"
    value {
      list {
        i: 1
        i: 2
        i: 2
        i: 1
      }
    }
  }
  attr {
    key: "padding"
    value {
      s: "VALID"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 2
        i: 2
        i: 1
      }
    }
  }
}
node {
  name: "block5_conv1/convolution"
  op: "Conv2D"
  input: "block4_pool/MaxPool"
  input: "block5_conv1/kernel"
  attr {
    key: "padding"
    value {
      s: "SAME"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 1
        i: 1
        i: 1
      }
    }
  }
}
node {
  name: "block5_conv1/BiasAdd"
  op: "BiasAdd"
  input: "block5_conv1/convolution"
  input: "block5_conv1/bias"
}
node {
  name: "block5_conv1/Relu"
  op: "Relu"
  input: "block5_conv1/BiasAdd"
}
node {
  name: "block5_conv2/convolution"
  op: "Conv2D"
  input: "block5_conv1/Relu"
  input: "block5_conv2/kernel"
  attr {
    key: "padding"
    value {
      s: "SAME"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 1
        i: 1
        i: 1
      }
    }
  }
}
node {
  name: "block5_conv2/BiasAdd"
  op: "BiasAdd"
  input: "block5_conv2/convolution"
  input: "block5_conv2/bias"
}
node {
  name: "block5_conv2/Relu"
  op: "Relu"
  input: "block5_conv2/BiasAdd"
}
node {
  name: "block5_conv3/convolution"
  op: "Conv2D"
  input: "block5_conv2/Relu"
  input: "block5_conv3/kernel"
  attr {
    key: "padding"
    value {
      s: "SAME"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 1
        i: 1
        i: 1
      }
    }
  }
}
node {
  name: "block5_conv3/BiasAdd"
  op: "BiasAdd"
  input: "block5_conv3/convolution"
  input: "block5_conv3/bias"
}
node {
  name: "block5_conv3/Relu"
  op: "Relu"
  input: "block5_conv3/BiasAdd"
}
node {
  name: "block5_pool/MaxPool"
  op: "MaxPool"
  input: "block5_conv3/Relu"
  attr {
    key: "ksize"
    value {
      list {
        i: 1
        i: 2
        i: 2
        i: 1
      }
    }
  }
  attr {
    key: "padding"
    value {
      s: "VALID"
    }
  }
  attr {
    key: "strides"
    value {
      list {
        i: 1
        i: 2
        i: 2
        i: 1
      }
    }
  }
}
node {
  name: "flatten/Reshape"
  op: "Flatten"
  input: "block5_pool/MaxPool"
}
node {
  name: "dense_1/MatMul"
  op: "MatMul"
  input: "flatten/Reshape"
  input: "dense_1/kernel"
  attr {
    key: "transpose_a"
    value {
      b: false
    }
  }
  attr {
    key: "transpose_b"
    value {
      b: false
    }
  }
}
node {
  name: "dense_1/BiasAdd"
  op: "BiasAdd"
  input: "dense_1/MatMul"
  input: "dense_1/bias"
}
node {
  name: "dense_1/Relu"
  op: "Relu"
  input: "dense_1/BiasAdd"
}
node {
  name: "dense_2/MatMul"
  op: "MatMul"
  input: "dense_1/Relu"
  input: "dense_2/kernel"
  attr {
    key: "transpose_a"
    value {
      b: false
    }
  }
  attr {
    key: "transpose_b"
    value {
      b: false
    }
  }
}
node {
  name: "dense_2/BiasAdd"
  op: "BiasAdd"
  input: "dense_2/MatMul"
  input: "dense_2/bias"
}
node {
  name: "dense_2/Softmax"
  op: "Softmax"
  input: "dense_2/BiasAdd"
}
node {
  name: "output_node0"
  op: "Identity"
  input: "dense_2/Softmax"
}