2017-08-28 4 views
2

私はアンドロイドに推論のための私の入力画像サイズを増やすたびに、いくつかの理由で、私は(画像分類のために)このエラーを取得しています:AndroidでTensorFlowモデルを実行しているときにjava.nio.BufferOverflowExceptionランタイムエラーが発生しましたか?

Process: com.example.android.androidevaluateimagenet, PID: 31064 
java.nio.BufferOverflowException 
    at java.nio.FloatBuffer.put(FloatBuffer.java:444) 
    at org.tensorflow.Tensor.writeTo(Tensor.java:390) 
    at org.tensorflow.contrib.android.TensorFlowInferenceInterface.fetch(TensorFlowInferenceInterface.java:338) 
    at org.tensorflow.contrib.android.TensorFlowInferenceInterface.fetch(TensorFlowInferenceInterface.java:301) 
    at com.example.android.androidevaluateimagenet.TensorFlowImageClassifier.recognizeImage(TensorFlowImageClassifier.java:148) 
    at com.example.android.androidevaluateimagenet.MainActivity.getInferenceTime(MainActivity.java:240) 
    at com.example.android.androidevaluateimagenet.MainActivity$2.onClick(MainActivity.java:318) 
    at android.view.View.performClick(View.java:4763) 
    at android.view.View$PerformClick.run(View.java:19821) 
    at android.os.Handler.handleCallback(Handler.java:739) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:135) 
    at android.app.ActivityThread.main(ActivityThread.java:5272) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)                  at com.example.android.androidevaluateimagenet.MainActivity$2.onClick(MainActivity.java:318) 
                           at android.view.View.performClick(View.java:4763) 
                           at android.view.View$PerformClick.run(View.java:19821) 
                           at android.os.Handler.handleCallback(Handler.java:739) 
                           at android.os.Handler.dispatchMessage(Handler.java:95) 
                           at android.os.Looper.loop(Looper.java:135) 
                           at android.app.ActivityThread.main(ActivityThread.java:5272) 
                           at java.lang.reflect.Method.invoke(Native Method) 
                           at java.lang.reflect.Method.invoke(Method.java:372) 
                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909) 
                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704) 

と私はなぜ本当にわかりません。私が使用したものよりも低い入力画像サイズの場合、モデルは正常に動作します。さらに、この問題は私が使用している1つのモデルにのみ固有です。私は小型モデルと大型モデルの両方を試してみました。私に問題を与えたのはこのモデルだけでしたが、生成されたエラーに基づいてこのモデルで何が間違っているのかを特定することはできません。

特定のエラースタックトレース:

TensorFlowImageClassifier.java:

inferenceInterface.fetch(outputName, outputs); 

TensorFlowInferenceInterace.java:

public void fetch(String var1, float[] var2) { 
    this.fetch(var1, FloatBuffer.wrap(var2)); 
} 

Tensor.java:

public void writeTo(FloatBuffer var1) { 
    if(this.dtype != DataType.FLOAT) { 
     throw incompatibleBuffer(var1, this.dtype); 
    } else { 
     ByteBuffer var2 = this.buffer(); 
     var1.put(var2.asFloatBuffer()); 
    } 
} 

FloatBuffer.java:

public FloatBuffer put(FloatBuffer src) { 
    if (src == this) 
     throw new IllegalArgumentException(); 
    int n = src.remaining(); 
    if (n > remaining()) 
     throw new BufferOverflowException(); 
    for (int i = 0; i < n; i++) 
     put(src.get()); 
    return this; 
} 
+0

ここからのコメント - > https://stackoverflow.com/a/20785579/7230266 –

+0

私はスレッドを見ましたが、それが問題の原因だとは思わないのです。 (バッファーはライブラリー内で内部的に割り振られており、制御することはできません)。さらに、私ははるかに大きなモデルを実行し、サイズは超えていません。 – kwotsin

+0

Runtime.getRuntime()。gc();によってビットマップキャッシュを消去してみます。 System.gc(); –

答えて

1

は、スタックトレースとエラーメッセージをオフに行く、クレームはfetchに提供float[]アレイ出力の大きさよりも長さが小さいことであると思われますモデルによって生成されます。したがって、より適切なサイズの配列をfetchに提供するようにコードを調整する必要があります。

残念ながら、TensorFlowInferenceInterfaceクラスには、フェッチされたテンソルの実際の形状にアクセスするパブリックメソッドがありません。

(バックプロジェクトに良い貢献かもしれません)
public long[] fetchShape(String outputName) { 
    return getTensor(outputName).shape(); 
} 

:あなたはソースからビルドしている場合は、クラスに次のようなものを追加することによって、それを得ることができます。

希望に役立ちます。

+0

残念ながら、私が必要とする容量はかなり固定されており、コード内でどこでメモリ要件をさらに減らすことができるかわかりません。私は問題はモデルの実装と関係していると思います。なぜなら私は3倍以上のメモリを消費するより大きなモデルを使用していますが、モバイル上で実行することには問題はありません。メモリの大部分がモデルから来ている場所を確認する方法はありますか? – kwotsin

関連する問題