2017-08-28 43 views
2

出於某種原因,我得到這個錯誤,每當我在Android中增加我的輸入圖像大小推斷(圖像分類):在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) 

,我真的不知道爲什麼。對於我使用的輸入圖像尺寸,模型運行良好。而且,這個問題只對我使用的一個模型是唯一的。我已經嘗試了更小和更大(2倍大)的模型,並且它們工作得很好。只有這個模型給了我這個問題,但是我根據產生的錯誤無法確定這個模型究竟有什麼問題。

特定錯誤堆棧跟蹤:

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

變成爲關狀態的棧跟蹤和錯誤信息,似乎該抱怨是,提供給fetchfloat[]陣列在長度上比輸出的尺寸小由您的模型生成。所以,你需要調整你的代碼以提供一個更合適的大小的數組到fetch

不幸的是,TensorFlowInferenceInterface類沒有公開的方法來訪問獲取的張量的實際形狀。如果你是從源代碼構建,你可以得到通過添加類似以下的類:

public long[] fetchShape(String outputName) { 
    return getTensor(outputName).shape(); 
} 

(這可能是一個很好的貢獻回到項目)。

希望有所幫助。

+0

不幸的是,我需要的容量是相當固定的,我不太清楚在代碼中我可以進一步減少內存需求。我認爲這些問題與模型實現有關,因爲我已經使用了一個更大的模型,它消耗了大約3倍的內存,但在移動設備上運行它沒有問題。有沒有辦法來檢查大部分內存來自模型? – kwotsin

相關問題