Модель CoreML дает разные результаты между coremltools и Xcode - PullRequest
1 голос
/ 01 мая 2019

Я создал файл .mlmodel на основе пользовательской модели PyTorch CNN, преобразовав сначала модель PyTorch в ONNX, а затем в CoreML с помощью onnx_coreml. Используя фиктивные данные (массив 3 x 224 x 224, где каждое отдельное значение равно 1,0), я убедился, что модель PyTorch, модель ONNX (выполняется с использованием бэкэнда Caffe) и модель CoreML (с использованием coremltools) дают одинаковые результаты. ,

Однако, когда я импортирую ту же модель в Xcode и запускаю ее на телефоне, даже используя фиктивные данные, выходные данные модели не совпадают.

Устройство, которое я использую, похоже, не имеет значения (я пробовал на iPhone от XS Max до SE). Все работают под управлением iOS 12.2 и используют Xcode 10.2.1

Вот код (в Swift), который я использую для создания фиктивных данных и получения прогноза из моей модели:

let pixelsWide = Int(newImg.size.width)
let pixelsHigh = Int(newImg.size.height)
var pixelMLArray = try MLMultiArray(shape: [1, 1, 3, 224, 224], dataType: .float32)
for y in 0 ..< pixelsHigh {
    for x in 0 ..< pixelsWide {
        pixelMLArray[[0,0,0,x,y] as [NSNumber]] = 1.0
        pixelMLArray[[0,0,1,x,y] as [NSNumber]] = 1.0
        pixelMLArray[[0,0,2,x,y] as [NSNumber]] = 1.0
    }
}

do {
    let convModel = CNNModel()
    var thisConvOutput = try convModel.prediction(_0: pixelMLArray)._1161
} catch { print("Error") }

Я проверил правильность тегов ввода и вывода и т. Д. И т. Д. Это работает гладко, но первые три значения thisConvOutput: [0,000139, 0,000219, 0,003607]

Для сравнения, первые три значения, использующие модель PyTorch: [0,0002148, 0,00032246 и 0,0035419]

И точно такая же .ml-модель с использованием coremltools: [0,00021577, 0,00031877, 0,0035404]

Короче говоря, не имея опыта работы со Swift, мне интересно, что я делаю что-то глупое в инициализации / заполнении моего "pixelMLArray", чтобы запустить его через модель в Xcode на моем устройстве, так как .mlmodel получается из coremltools очень близки к результатам, которые я получаю с помощью PyTorch. Кто-нибудь может помочь?

1 Ответ

0 голосов
/ 01 мая 2019

Выход Core ML на устройстве: [0,000139, 0,000219, 0,003607]

Ваш вывод из coremltools: [0.00021577, 0.00031877, 0.0035404]

Обратите внимание, что это очень маленькие цифры. Когда Core ML запускает вашу модель на графическом процессоре (и, возможно, на Neural Engine, не уверен), он использует 16-битную плавающую точку. Они имеют гораздо меньшую точность, чем 32-разрядные с плавающей точкой.

Обратите внимание, что 0,000139 и 0,00021577 - это не одно и то же число, но оба они равны 1e-4. Это ниже предела точности 16-битных операций с плавающей запятой. Но 0,003607 и 0,0035404 - это почти одинаковые числа, потому что они примерно в 10 раз больше и поэтому не теряют столько точности.

Попробуйте запустить модель Core ML на устройстве с использованием процессора (вы можете передать опцию для этого при создании экземпляра вашей модели). Вы, вероятно, увидите, что теперь вы получаете результаты, которые намного ближе (и, вероятно, идентичны) к версии coremltools, потому что Core ML на процессоре использует 32-разрядные числа с плавающей запятой.

Вывод: из того, что вы показали до сих пор, похоже, что ваша модель работает должным образом, учитывая, что вы потеряете точность из-за вычислений с 16-разрядными числами с плавающей запятой.

...