У меня есть сеть PyTorch, и я хочу развернуть ее на iOS устройствах. Короче говоря, я не могу добавить гибкость к форме входного тензора в CoreML.
Сеть представляет собой con vnet, который принимает изображение RGB (сохраненное как тензор) в качестве входных данных и возвращает изображение RGB с такой же размер. Используя PyTorch, я могу вводить изображения любого размера, который мне нужен, например тензор размера (1, 3, 300, 300) для изображения 300x300.
Чтобы преобразовать модель PyTorch в модель CoreML, я сначала конвертируйте его в модель ONNX, используя torch.onnx.export
. Эта функция требует передачи фиктивного ввода, чтобы он мог выполнить график. Поэтому я использовал:
input = torch.rand(1, 3, 300, 300)
Я предполагаю, что модель ONNX принимает только изображения / тензоры размера (1, 3, 300, 300). Теперь я могу использовать функцию onnx_coreml.convert
для преобразования модели ONNX в модель CoreML. Распечатав описание модели CoreML spe c с использованием Python, я получаю что-то вроде:
input {
name: "my_image"
type {
multiArrayType {
shape: 1
shape: 3
shape: 300
shape: 300
dataType: FLOAT32
}
}
}
output {
name: "my_output"
type {
multiArrayType {
shape: 1
shape: 3
shape: 300
shape: 300
dataType: FLOAT32
}
}
}
metadata {
userDefined {
key: "coremltoolsVersion"
value: "3.1"
}
}
Ввод модели должен иметь размер multiArrayType
(1, 3, 300, 300). Копируя эту модель в XCode, я вижу при проверке модели, что my_name
указано в разделе «Входы» и ожидается, что оно будет MultiArray (Float32 1 x 3 x 300 x 300)
. Пока что все согласованно.
Моя задача - придать гибкость форме ввода. Я попытался использовать coremltools без удачи. Это моя проблема. Вот мой код:
import coremltools
from coremltools.models.neural_network import flexible_shape_utils
spec = coremltools.utils.load_spec('my_model.mlmodel')
shape_range = flexible_shape_utils.NeuralNetworkMultiArrayShapeRange()
shape_range.add_channel_range((3,3))
shape_range.add_height_range((64, 5000))
shape_range.add_width_range((64, 5000))
flexible_shape_utils.update_multiarray_shape_range(spec, feature_name='my_image', shape_range=shape_range)
coremltools.models.utils.save_spec(spec, 'my_flexible_model.mlmodel')
Я получаю следующее описание spe c, используя Python:
input {
name: "my_image"
type {
multiArrayType {
shape: 1
shape: 3
shape: 300
shape: 300
dataType: FLOAT32
shapeRange {
sizeRanges {
lowerBound: 3
upperBound: 3
}
sizeRanges {
lowerBound: 64
upperBound: 5000
}
sizeRanges {
lowerBound: 64
upperBound: 5000
}
}
}
}
}
Только 3 диапазона, как указано, что имеет смысл, так как я только определил диапазон для канала, высоты и ширины, но не для размера партии. В XCode я получаю следующую ошибку при проверке гибкой модели CoreML:
There was a problem decoding this CoreML document
validator error: Description of multiarray feature 'my_image' has a default 4-d shape but a 3-d shape range
Я почти уверен, что она работала над другим проектом, когда я работал в MacOS X Mojave, но на данный момент я ничего не знаю.
Я использую:
- macOS X Catalina
- conda 4.7.12
- python 3.7.5
- pytorch 1.3.1
- onnx 1.6.0
- onnx-coreml 1.1
- coremltools 3.1
Спасибо за помощь