1

在比较使用 Python(3.5.5)+ Keras(版本 2.0.8)在 GPU 上训练的神经网络的输出与使用 DL4J 在 Android(API 24)上的相同神经网络的输出时,我遇到了截然不同的预测结果(1.0.0-beta2)。

这将非常有帮助,如果有人可以分享他们如何解决这个问题的经验,谢谢!

将模型导入 Android

通过使用以下命令导入神经网络,将其转换为 DL4J 格式:

MultiLayerNetwork model = KerasModelImport.importKerasSequentialModelAndWeights(SIMPLE_MLP, false)

并使用 DL4Js ModelSerializer存储它。

使用 DL4J 方法restoreMultiLayerNetwork()将模型导入 Android 应用程序

模型输出

神经网络旨在对具有固定输入形状的图像进行预测:固定高度、宽度、3 个通道。

Android中的图像预处理管道:

图像作为输入流从设备加载并将其存储在 INDarray 中:

AndroidNativeImageLoader loader = new AndroidNativeImageLoader(100, 100, 3);

InputStream  inputStream_bitmap = getContentResolver().openInputStream(uri);
INDArray indarray1 = loader.asMatrix(inputStream_bitmap);

AndroidNativeImageLoader()加载并重新缩放图像。

INDarray 'indarray1' 被重新缩放以包含范围 [0,1] 中的值:

indarray1 = indarray1.divi(255);

INDarray 通过网络传递以计算输出:

INDArray output = model.output(indarray1);

Python中的图像预处理管道:

from keras.preprocessing import image
from keras.utils import np_utils
import numpy as np

img = image.load_img(img_path, target_size=(100, 100))
img = image.img_to_array(img)
img = np.expand_dims(img, axis=0)
img = img.astype('float32')/255

output = model.predict(img)

问题:

使用 Python 和 Keras 的预测与 Android 中使用 DL4J 的预测有很大不同。输出是一个包含 2 个值的数组,每个值都是 [0,1] 中的浮点数。相机拍摄的普通 .bmp 图片的预测差异高达该输出数组的每个元素 0.99。

到目前为止完成的测试:

当使用单色 .bmp 图像(仅红色或仅蓝色或仅绿色或完全白色)时,两种环境的预测结果几乎相同。它们仅相差 10e-3,这可以通过在 GPU 上训练和在 CPU 上应用来解释。

结论: 到目前为止,我认为 Android 上的图像预处理与 Python 中的图像预处理方式不同,因为单色图片的模型输出是相同的。

有人遇到过类似的问题吗?任何帮助深表感谢!

4

1 回答 1

1

DL4J 和 Android 使用 BGR 而不是 RGB。因此必须执行颜色格式转换。

从这个 Github 帖子中向@saudet 致敬:

https://github.com/deeplearning4j/deeplearning4j/issues/6495

NativeImageLoader 需要加载这个转换:

loader = new NativeImageLoader(100, 100, 3, new ColorConversionTransform(COLOR_BGR2RGB));
于 2018-09-28T13:24:13.017 回答