Я получаю совершенно разные результаты прогнозирования при сравнении результатов нейронной сети, обученной на GPU на Python (3.5.5) + Keras (версия 2.0.8), с результатами той же нейронной сети на Android (API 24) с использованием DL4J (1.0.0-бета2).
Было бы очень полезно, если бы кто-то мог поделиться своим опытом по решению этой проблемы, спасибо!
Импортмодель в Android
Нейронную сеть преобразовали в формат DL4J, импортировав ее с помощью:
MultiLayerNetwork model = KerasModelImport.importKerasSequentialModelAndWeights(SIMPLE_MLP, false)
и сохранив ее с помощью DL4Js ModelSerializer .
Модель импортируется в приложение Android с использованием метода DL4J restoreMultiLayerNetwork ()
Вывод модели
Нейронная сеть предназначена длясделать прогноз для изображений фиксированной формы ввода: фиксированная высота, ширина, 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, так как вывод модели одинаков для монохроматических изображений.
Кто-нибудь сталкивался с подобной проблемой?Любая помощь очень ценится!