Keras Conv1D в CoreML не работает должным образом

Я строю модель в Керасе следующим образом:

sequence_length = 300
num_cats = 64

model = Sequential()

model.add(Conv1D(filters=4,
                 kernel_size=4,
                 strides=4, 
                 padding='same', 
                 activation='relu',
                 input_shape=(sequence_length, 1),
                 name='input'))
model.add(Dense(32, activation='relu'))
model.add(Dense(num_cats, activation='softmax'))

for (i, layer) in enumerate(model.layers):
    print(i, type(layer), layer.input_shape, layer.output_shape)

model.compile(loss=keras.losses.sparse_categorical_crossentropy,
              optimizer=keras.optimizers.Adam(lr=0.002, decay=1e-6),#0.004
              metrics=['accuracy']) 

Форма слоев этой модели выглядит следующим образом:

0 <class 'keras.layers.convolutional.Conv1D'> (None, 300, 1) (None, 75, 4)
1 <class 'keras.layers.core.Dense'> (None, 75, 4) (None, 75, 32)
2 <class 'keras.layers.core.Dense'> (None, 75, 32) (None, 75, 64)

Таким образом, модель должна принимать произвольное количество последовательностей размером 300х1 и возвращать одинаковое количество последовательностей размером 75х64. Это хорошо работает с керасом при использовании model.predict,

Преобразование в CoreML, кажется, работает:

>>> coreml_model = coremltools.converters.keras.convert(model_name,
                                                        input_names=['input1'])

0 : input_input, <keras.engine.topology.InputLayer object at 0x11d1aae48>
1 : input_input_permute_input, <keras.layers.core.Permute object at 0x11d08f668>
2 : input, <keras.layers.convolutional.Conv1D object at 0x11d1aab38>
3 : input__activation__, <keras.layers.core.Activation object at 0x11d08fef0>
4 : input_permute_dense_3, <keras.layers.core.Permute object at 0x11cdf8748>
5 : dense_3, <keras.layers.core.Dense object at 0x11d1aae80>
6 : dense_3__activation__, <keras.layers.core.Activation object at 0x11cd33320>
7 : dense_4, <keras.layers.core.Dense object at 0x11d1c82e8>
8 : dense_4__activation__, <keras.layers.core.Activation object at 0x11cd33198>

Однако что-то идет не так при попытке выполнить прогноз:

>>> coreml_model.predict({'input1': [0.0 for _ in range(300)]})

RuntimeError                              Traceback (most recent call last)
<ipython-input-25-fa8bb7c37555> in <module>()
      1 inputX = X[0:3]#.reshape(-1,1,1000)
      2 print(inputX.shape)
----> 3 coreml_model.predict({'input1': [0.0 for _ in range(300)]})

~/dev/coreml_experiments/.venv/lib/python3.6/site-packages/coremltools/models/model.py in predict(self, data, useCPUOnly, **kwargs)
    262 
    263         if self.__proxy__:
--> 264             return self.__proxy__.predict(data,useCPUOnly)
    265         else:
    266             if _macos_version() < (10, 13):

RuntimeError: {
    NSLocalizedDescription = "Input feature input1 was presented as a vector of length 300, but the model expects an input of length 1.";
}

Действительно, единственное, что работает, - это массив длиной 1:

coreml_model.predict({'input1': [0.0]})

Который возвращает массив длиной 64, но на самом деле должен вызвать ошибку. Что не так с преобразованием или моим пониманием этого?

0 ответов

Другие вопросы по тегам