Add transform_graph script into tflkit (#3545)
author윤지영/동작제어Lab(SR)/Engineer/삼성전자 <jy910.yun@samsung.com>
Thu, 15 Nov 2018 07:27:31 +0000 (16:27 +0900)
committer오형석/동작제어Lab(SR)/Staff Engineer/삼성전자 <hseok82.oh@samsung.com>
Thu, 15 Nov 2018 07:27:31 +0000 (16:27 +0900)
* Add transform_graph script into tflkit

transform_graph tool will transform a TensorFlow GraphDef applying some transformations.

Signed-off-by: Jiyoung Yun <jy910.yun@samsung.com>
* Update detailed usage to README.md

Signed-off-by: Jiyoung Yun <jy910.yun@samsung.com>
tools/tflkit/README.md
tools/tflkit/info/transform.template [new file with mode: 0644]
tools/tflkit/transform_graph.sh [new file with mode: 0755]

index c1202bd..1136a22 100644 (file)
@@ -198,3 +198,43 @@ $ ./optimize_for_inference.sh --info=./optimize.info
 $ ls *.pb
 inception_v3.optimize.pb  inception_v3.pb
 ```
+
+## Transform a TensorFlow graph
+
+### TensorFlow
+
+The trained TensorFlow model can be trasformed by some variants to deploy it in production. This [Graph Transform Tool](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/graph_transforms#graph-transform-tool) provides to support this behavior. There are so many transform options in this tool. For more information on transform options, please see [this page](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/graph_transforms#transform-reference). The input and output file of this tool is a TensorFlow GraphDef file.
+
+### with tflkit
+
+The [transform_graph.sh](transform_graph.sh) file supports to transform a TensorFlow GraphDef using various transform options. This tool requires a transform information file as a parameter and the transform options are described in the information file. There is an [example file](info/transform.template) for this tool. The information file needs `INPUT` and `OUTPUT` array names. The [summarize_pb.sh](summarize_pb.sh) file will help you to define the `INPUT` and `OUTPUT` array names. The `--tensorflow_path` can change the TensorFlow location. By default, it uses `externals/tensorflow` directory.
+
+Transform information:
+  * GRAPHDEF_PATH : Full filepath of file containing frozen TensorFlow GraphDef.
+  * TRANSFORM_PATH : Full filepath of the output TensorFlow GraphDef.
+  * INPUT : Names of the input arrays, comma-separated.
+  * OUTPUT : Names of the output arrays, comma-seperated.
+  * TRANSFORM_OPTIONS : Names of transform option, space-separated.
+                        By default, it includes the following options.
+    * strip_unused_nodes : Removes all nodes not used in calculated the layer given in `OUTPUT` array, fed by `INPUT` array.
+    * remove_nodes : Removes the given name nodes from the graph.
+      * `Identity` is not necessary in inference graph. But if it needs in inference graph, this tool does not remove this node.
+      * `CheckNumerics` is useful during training but it is not necessary in inference graph.
+    * fold_constants : Replaces the sub-graps that always evaluate to constant expressions with those constants. This optimization is always executed at run-time after the graph is loaded, so it does'nt help latency, but it can simplify the graph and so make futher processing easier.
+    * fold_batch_norms : Scans the graph for any channel-wise multiplies immediately after convolutions, and multiplies the convolution's weights with the Mul instead so this can be omitted at inference time. It should be run after `fold_constants`.
+
+Usage (for example, [InceptionV3](https://storage.googleapis.com/download.tensorflow.org/models/tflite/model_zoo/upload_20180427/inception_v3_2018_04_27.tgz)):
+```
+$ wget https://storage.googleapis.com/download.tensorflow.org/models/tflite/model_zoo/upload_20180427/inception_v3_2018_04_27.tgz
+$ tar xzvf inception_v3_2018_04_27.tgz ./inception_v3.pb
+$ cat > transform.info << END
+GRAPHDEF_PATH="${PWD}/inception_v3.pb"
+TRANSFORM_PATH="${PWD}/inception_v3.transform.pb"
+INPUT="input"
+OUTPUT="InceptionV3/Predictions/Reshape_1"
+TRANSFORM_OPTIONS="strip_unused_nodes(type=float, shape=\"1,299,299,3\") remove_nodes(op=Identity, op=CheckNumerics) fold_constants(ignore_errors=true) fold_batch_norms"
+END
+$ ./transform_graph.sh --info=./transform.info
+$ ls *.pb
+inception_v3.pb  inception_v3.transform.pb
+```
diff --git a/tools/tflkit/info/transform.template b/tools/tflkit/info/transform.template
new file mode 100644 (file)
index 0000000..8a97f3d
--- /dev/null
@@ -0,0 +1,5 @@
+GRAPHDEF_PATH=
+TRANSFORM_PATH=
+INPUT=
+OUTPUT=
+TRANSFORM_OPTIONS="strip_unused_nodes remove_nodes(op=Identity, op=CheckNumerics) fold_constants(ignore_errors=true) fold_batch_norms"
diff --git a/tools/tflkit/transform_graph.sh b/tools/tflkit/transform_graph.sh
new file mode 100755 (executable)
index 0000000..828a363
--- /dev/null
@@ -0,0 +1,94 @@
+#!/bin/bash
+
+usage()
+{
+  echo "usage : $0"
+  echo "       --info=Information file"
+  echo "       --tensorflow_path=TensorFlow path (Use externals/tensorflow by default)"
+}
+
+SCRIPT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+
+TF_DIR="${SCRIPT_PATH}/../../externals/tensorflow"
+
+for i in "$@"
+do
+  case $i in
+    --info=*)
+      INFO=${i#*=}
+      ;;
+    --tensorflow_path=*)
+      TF_DIR=${i#*=}
+      ;;
+    -h|--help)
+      usage
+      exit 0
+      ;;
+    *)
+      usage
+      exit 1
+      ;;
+  esac
+  shift
+done
+
+if [ -z "$INFO" ]; then
+  echo "INFO is unset or set to the empty string"
+  usage
+  exit 1
+fi
+if [ -z "$TF_DIR" ]; then
+  echo "tensorflow_path is unset or set to the empty string"
+  usage
+  exit 1
+fi
+
+if [ ! -x "$(command -v bazel)" ]; then
+  echo "Cannot find bazel. Please install bazel."
+  exit 1
+fi
+
+source $INFO
+
+if [ -z "$GRAPHDEF_PATH" ]; then
+  echo "GRAPHDEF_PATH is unset or set to the empty string"
+  echo "Update the $INFO file"
+  exit 1
+fi
+if [ -z "$TRANSFORM_PATH" ]; then
+  echo "TRANSFORM_PATH is unset or set to the empty string"
+  echo "Update the $INFO file"
+  exit 1
+fi
+if [ -z "$INPUT" ]; then
+  echo "INPUT is unset or set to the empty string"
+  echo "Update the $INFO file"
+  exit 1
+fi
+if [ -z "$OUTPUT" ]; then
+  echo "OUTPUT is unset or set to the empty string"
+  echo "Update the $INFO file"
+  exit 1
+fi
+if [ -z "$TRANSFORM_OPTIONS" ]; then
+  echo "TRANSFORM_OPTIONS is unset or set to the empty string"
+  echo "Update the $INFO file"
+  exit 1
+fi
+
+CUR_DIR=$(pwd)
+{
+  echo "Enter $TF_DIR"
+  pushd $TF_DIR > /dev/null
+
+  bazel run tensorflow/tools/graph_transforms/transform_graph -- \
+  --in_graph="$GRAPHDEF_PATH" \
+  --out_graph="$TRANSFORM_PATH" \
+  --inputs="$INPUT" \
+  --outputs="$OUTPUT" \
+  --transforms="$TRANSFORM_OPTIONS"
+
+  popd
+
+  echo "OUTPUT FILE : $TRANSFORM_PATH"
+}