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, но на самом деле должен вызвать ошибку. Что не так с преобразованием или моим пониманием этого?