Хорошо, кажется, я нашел способ go. Я создал виртуальную среду с отдельной копией coremltools и отредактировал метод _convert()
в _keras2_converter.py
, добавив следующий код:
for iter, layer in enumerate(graph.layer_list):
keras_layer = graph.keras_layer_map[layer]
print("%d : %s, %s" % (iter, layer, keras_layer))
if isinstance(keras_layer, _keras.layers.wrappers.TimeDistributed):
keras_layer = keras_layer.layer
converter_func = _get_layer_converter_fn(keras_layer, add_custom_layers)
input_names, output_names = graph.get_layer_blobs(layer)
# this may be none if we're using custom layers
if converter_func:
converter_func(builder, layer, input_names, output_names,
keras_layer, respect_trainable)
else:
if _is_activation_layer(keras_layer):
import six
if six.PY2:
layer_name = keras_layer.activation.func_name
else:
layer_name = keras_layer.activation.__name__
else:
layer_name = type(keras_layer).__name__
if layer_name in custom_conversion_functions:
custom_spec = custom_conversion_functions[layer_name](keras_layer)
else:
custom_spec = None
if layer.find('tf_up') != -1:
print('TF_UPSCALE found')
builder.add_reorganize_data(layer, input_names[0], output_names[0], mode='DEPTH_TO_SPACE', block_size=4)
elif layer.find('mulfunc') != -1:
print('SCALE found')
builder.add_scale(layer, W=0.2, b=0, has_bias=False, input_name=input_names[0], output_name=output_names[0])
else:
builder.add_custom(layer, input_names, output_names, custom_spec)
Триггер - имя слоя. В керасе я использую model.load_weights(by_name=True)
и следующую маркировку моих лямбд:
x = Lambda(mulfunc, name=scope+'mulfunc')(x)
x = Lambda(tf_upsampler,name='tf_up')(x)
Теперь у модели по крайней мере есть нужные мне слои:
[Id: 417], Name: tf_up (Type: reorganizeData)
Updatable: False
Input blobs: ['up1_output']
Output blobs: ['tf_up_output']
Теперь пришло время проверить мои VBox MacOS, опубликует то, что у меня есть.
ОБНОВЛЕНИЕ:
Я не вижу ошибок, связанных с моими замененными лямбда-слоями, но есть еще один, который не позволяет мне прогнозировать:
Layer 'concatenate_1' type 320 has 1 inputs but expects at least 2
Я думаю, это связано с тем, что Keras получает один вход для сцепленного слоя, который представляет собой список входов. Посмотрим, как это исправить
ОБНОВЛЕНИЕ 2:
Попытка исправить это с помощью функции построителя add_concat_nd(self, name, input_names, output_name, axis)
для моих слоев сцепления: во время вывода получена ошибка, что данный тип слоя поддерживается (?! ):
if converter_func:
if layer.find('concatenate') != -1:
print('CONCATENATE FOUND')
builder.add_concat_nd(layer, input_names, output_names[0], axis=3)
else:
converter_func(builder, layer, input_names, output_names,
keras_layer, respect_trainable)
Unsupported layer type (CoreML.Specification.NeuralNetworkLayer)
ОБНОВЛЕНИЕ 4:
Найдены исправления для этого и изменен способ инициализации компоновщика:
builder = _NeuralNetworkBuilder(input_features, output_features, mode = mode,
use_float_arraytype=use_float_arraytype, disable_rank5_shape_mapping=True)
Теперь сообщение об ошибке исчезло, но у меня проблемы с версией XCode: модель имеет версию 4, а мой Xcode поддерживает 3. Будет пытаться обновить мою ВМ.
«Руководство по выживанию CoreML» в этом случае предлагает pdf:
pip install -U git+https://github.com/apple/coremltools.git
Например, если при загрузке модели с помощью coremltools выдается ошибка, такая как показано ниже, попробуйте установить последнюю версию coremltools непосредственно из репозиторий GitHub.
Error compiling model: "Error reading protobuf spec. validator error:
The .mlmodel supplied is of version 3, intended for a newer version of
Xcode. This version of Xcode supports model version 2 or earlier.
ОБНОВЛЕНИЕ:
Обновлено с git. Ошибка:
Нет модуля с именем 'coremltools.libcoreml python'
Похоже, что последний git не работает: (
Черт, кажется, я нужны macos 10.15 и xcode 11
ОБНОВЛЕНИЕ 5:
Все еще борется с ошибкой в 10.15. Обнаружено, что
- coremltools каким-то образом дедуплицирует входные данные для уровня Concatenate, так что если в вашем коде keras есть что-то вроде
Concatenate()([x,x])
, у вас будет слой сцепления с 1 входом в coreml и ошибкой. Чтобы исправить это, я попытаюсь изменить код, приведенный выше:
if layer.find('concatenate') != -1:
print('CONCATENATE FOUND', len(input_names))
if len(input_names) == 1:
input_names = [input_names[0],input_names[0]]
builder.add_concat_nd(layer, input_names, output_names[0], axis=3)
[Я сталкивался с этой ошибкой:
input layer 'conv_in' of type 'Convolution' has input rank 3 but expects rank at least 4
] (
coremltools: как правильно использовать NeuralNetworkMultiArrayShapeRange? , которая, кажется, вызвана тем, что coreml делает ввод 3-мерным CHW, в то время как оно должно быть 4 NWH C (?). В настоящее время играет со следующими
Получение неправильной формы капли из внутренних элементов модели