我在我的 Android 项目中使用 DL4J 来运行 CNN 网络作为分类器。问题是这个 CNN 模型占用的内存超过了我智能手机允许的每个应用程序堆大小,这导致内存不足错误。所以,我想知道是否有一种方法可以显式释放这个本机 DL4J 代码分配的内存。
我的输入总共是 200 个图像补丁。我需要将它们堆叠在一起,以便处理时间更快。我尝试将批量大小设置为 32,因此每个输入 INDARRAY 的大小为 [32、3、44、44]。我也尝试过 16、8 等。但唯一没有出现内存不足错误的情况是我一次输入一个图像补丁。但我不能承受它导致的长处理时间。
我尝试使用 GC 显式释放内存,但它不起作用,这是有道理的,因为内存是由本机代码占用的。
for (int i = 0; i < N / UtilsCustom.NN_batch_size; i++) {
INDArray temp = UtilsCustom.overallArray.get(NDArrayIndex.interval(i * UtilsCustom.NN_batch_size, i * UtilsCustom.NN_batch_size + UtilsCustom.NN_batch_size), NDArrayIndex.all(), NDArrayIndex.all(), NDArrayIndex.all());
NN_classify(temp);
a = i * UtilsCustom.NN_batch_size + UtilsCustom.NN_batch_size;
if (i%2==1){
model = null;
java.lang.System.gc();
Log.d(TAG, "GCGCGC");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
loadNNModel();
}
temp = null;
java.lang.System.gc();
}
private void NN_classify(INDArray imageMat) {
int result;
DataNormalization scaler = new ImagePreProcessingScaler(0, 1);
scaler.transform(imageMat);
INDArray output = model.output(imageMat);
Log.d(LOG_TAG, "output.size(): " + output.size(0) + ", " + output.size(1));
double prob_parasitemic = 0, prob_uninfected = 0;
for (int i = 0; i < output.size(0); i++) {
prob_parasitemic = output.getDouble(i, 0);
prob_uninfected = output.getDouble(i, 1);
Log.d(LOG_TAG, "prob_parasitemic: " + i + " " + output.getDouble(0, 0));
Log.d(LOG_TAG, "prob_uninfected: " + i + " " + output.getDouble(0, 1));
}
if (prob_parasitemic > prob_uninfected) {
result = 2;
} else {
result = 1;
}
Log.e(LOG_TAG, "Result: " + result);
imageMat = null;
output = null;
java.lang.System.gc();
}