Androidデバイス(CPU Snapdragon 820)で推論を実行しているダークフローからのテンソルフローグラフがあります。このグラフ変換ツールを見つけて、展開用にモデルを最適化しました。そのため、以前よりも高速になると予想されるグラフを最適化しましたが、約 10% 遅くなりました。
その原因は何ですか?私は何を間違っていますか?
詳細は次のとおりです。
- darkflowのtiny-yolo-vocモデルを変更せずに使用します。次のような tf モデルを作成しました。
$ ./flow --model cfg/tiny-yolo-voc.cfg --load bin/tiny-yolo-voc.weights --savepb --verbalise
- 次のコマンドでグラフを最適化しました。
$ bazel-bin/tensorflow/tools/graph_transforms/transform_graph /
--in_graph=../darkflow/darkflow/built_graph/tiny-yolo-voc.pb /
--out_graph=../darkflow/darkflow/built_graph/optimized-tiny -yolo-voc.pb /
--inputs='input' --outputs='output' /
--transforms='strip_unused_nodes(type=float, shape="1,299,299,3") fold_constants(ignore_errors=true) fold_batch_norms fold_old_batch_norms'
- 私のコード:
InfrerenceRunner.java:
public class InferenceRunner {
private static final String INPUT_NODE = "input";
private static final String OUTPUT_NODE = "output";
protected final TensorFlowInferenceInterface mInferenceInterface;
private final int mGridSize;
private final int mNumOfLabels;
private int mInputSize;
public InferenceRunner(Context context, String modelFile, int inputSize, int gridSize, int numOfLabels) {
this.mInputSize = inputSize;
this.mGridSize = gridSize;
this.mNumOfLabels = numOfLabels;
mInferenceInterface = new TensorFlowInferenceInterface(context.getAssets(), modelFile);
}
public synchronized void runInference(Bitmap image) {
Trace.beginSection("imageTransform");
Bitmap bitmap = Bitmap.createScaledBitmap(image, mInputSize, mInputSize, false);
int[] intValues = new int[mInputSize * mInputSize];
float[] floatValues = new float[mInputSize * mInputSize * 3];
bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
for (int i = 0; i < intValues.length; ++i) {
floatValues[i * 3 + 0] = ((intValues[i] >> 16) & 0xFF) / 255.0f;
floatValues[i * 3 + 1] = ((intValues[i] >> 8) & 0xFF) / 255.0f;
floatValues[i * 3 + 2] = (intValues[i] & 0xFF) / 255.0f;
}
Trace.endSection();
Trace.beginSection("inferenceFeed");
mInferenceInterface.feed(INPUT_NODE, floatValues, 1, mInputSize, mInputSize, 3);
Trace.endSection();
Trace.beginSection("inferenceRun");
mInferenceInterface.run(new String[]{OUTPUT_NODE});
Trace.endSection();
final float[] resu =
new float[mGridSize * mGridSize * (mNumOfLabels + 5) * 5];
Trace.beginSection("inferenceFetch");
mInferenceInterface.fetch(OUTPUT_NODE, resu);
Trace.endSection();
}
}
MainActivity:onCreate():
...
tinyYolo = new InferenceRunner(getApplicationContext(), TINY_YOLO_MODEL_FILE, TINY_YOLO_INPUT_SIZE, 13, 20);
optimizedTinyYolo = new InferenceRunner(getApplicationContext(), OPTIMIZED_TINY_YOLO_MODEL_FILE, TINY_YOLO_INPUT_SIZE, 13, 20);
...
MainActivity:onResume():
...
mHandler.post(new Runnable() {
@Override
public void run() {
Trace.beginSection("TinyYoloModel");
for (int i = 0; i < 5; i++) {
tinyYolo.runInference(b);
}
Trace.endSection();
Log.d(TAG, "run: optimized");
Trace.beginSection("OptimizedModel");
for (int i = 0; i < 5; i++) {
optimizedTinyYolo.runInference(b);
}
Trace.endSection();
}
});
...
TinyYoloModel の壁の持続時間は 5,525 ミリ秒です
OptimizedModel の持続時間は 6,043
ミリ秒です TinyYoloModel の推論実行の平均: 1051
ミリ秒
最適化されたモデルの速度が遅い理由がわかりましたか?
さらに情報が必要な場合は、お気軽にコメントしてください。ご協力いただきありがとうございます。