我在Keras Build 一个模型如下:

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)

因此,模型应该接受任意数量的大小为300x1的序列,并返回相同数量的大小为75x64的序列 . 使用 model.predict 时,这适用于keras .

转换为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的数组但确实应该导致错误 . 转换或我对它的理解出了什么问题?