Coremltools: Keras model get incorrect input shape

Created on 6 Apr 2018  路  5Comments  路  Source: apple/coremltools

env:
keras = 2.1.5
tensorflow = 1.7.0

Use this example:
https://github.com/keras-team/keras/blob/master/examples/imdb_fasttext.py

keras model.input_shape: (None, 400)
coreml model input1: MultiArray (Double 1)

I also tried in
keras = 2.1.3
tensorflow = 1.5.0
Get same incorrect result.
How to fix this? thanks.

question

Most helpful comment

You should create an MLMultiArray of shape [Seq, 1, 1] (i.e. [Seq, Batch, C]) and pass that as an input to the mlmodel in your app in Xcode.
Is that not working ?

All 5 comments

This is not a bug.

Keras model input shape (None, 400) represents (Batch=None, Seq=400), i.e. the model takes in a sequence scalars of length 400
The CoreML model is not bound to a particular sequence length. It can take any seq. length input. The sequence must of multi arrays which are of size (Double 1), i.e. scalars.

The following code should clarify this:

import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Embedding, GlobalAveragePooling1D
import coremltools

embedding_dims = 50
max_len = 300

model = Sequential()
model.add(Embedding(2000,
                    embedding_dims,
                    input_length=max_len))
model.add(GlobalAveragePooling1D())
model.add(Dense(1, activation='sigmoid'))
print(model.summary())
print('keras input shape: ', model.input_shape)
print('keras output_shape: ', model.output_shape)

X = np.random.randint(low=0, high=embedding_dims, size=(1,max_len))
keras_out = model.predict(X)

coreml_model = coremltools.converters.keras.convert(model)
input_dict = {}
input_dict['input1'] = np.reshape(X.flatten(), (max_len, 1, 1)).astype(np.float64) #input: [Seq,Batch,Channel]

print('keras out: ', keras_out)
print('coreml out with input seq. 300: ', coreml_model.predict(input_dict)['output1'])
input_dict['input1'] = input_dict['input1'][:5, :, :]
print('coreml out with input seq. 5: ', coreml_model.predict(input_dict)['output1']) 

Thank you for your reply.
11c1a25a-3771-4adb-a1b4-e85fb1de09f4

However, the model class generated in xcode can't take a sequence as input.It can only predict one MultiArray with size (Double 1) at a time. If I try to predict the sequence value one by one, the result is independent.This is different from the purpose of the model.

You should create an MLMultiArray of shape [Seq, 1, 1] (i.e. [Seq, Batch, C]) and pass that as an input to the mlmodel in your app in Xcode.
Is that not working ?

oh! That works! I misunderstood the input shape of MLMultiArray. Thanks a lot!

I have a similar problem and appreciate some assistance:

I'm trying to convert the following Keras model to an mlmodel:

    input_layer = Input(shape=(100,3))
    model = BatchNormalization(input_layer)(model)
    model = Conv1D(10, kernel_size=(3), padding='same')(model)
    model = Dropout(dropout_rate)(model)
    model = Conv1D(20, kernel_size=(2), padding='same')(model)
    model = Dropout(dropout_rate)(model)
    model = LSTM(128, return_sequences=True, input_shape=(100,3), batch_size=1)(model)
    model = Dropout(dropout_rate)(model)
    model = LSTM(128, batch_size=1)(model)
    model = Dense(output_size, activation='softmax')(model)
    model = Model(inputs=inputlayer, outputs=model)

But the conversion translates the input shape incorrectly as described in this thread, so I changed the model such that I flatten the input and then run a Reshape as follows:

I have the following model:

    input_layer = Input(shape=(300,))
    model = Reshape((100,3))(input_layer)
    model = BatchNormalization()(model)
    model = Conv1D(10, kernel_size=(3), padding='same')(model)
    model = Dropout(dropout_rate)(model)
    model = Conv1D(20, kernel_size=(2), padding='same')(model)
    model = Dropout(dropout_rate)(model)
    model = LSTM(128, return_sequences=True, input_shape=(100,3), batch_size=1)(model)
    model = Dropout(dropout_rate)(model)
    model = LSTM(128, batch_size=1)(model)
    model = Dense(output_size, activation='softmax')(model)
    model = Model(inputs=inputlayer, outputs=model)

The Keras model input shape is (?, 300)
I'm passing in an ndarray of shape (300,1,1) (sequence, batch, features) as follows:
x = np.reshape(X[0].flatten(), (300, 1, 1)).astype(np.float64)
and then I'm calling the predict:
coremlpred = coremlmodel.predict({'input':x})['output1']

I'm getting the following error:
NSLocalizedDescription = "Shape (1) was not in enumerated set of allowed shapes

Any ideas?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mushipand picture mushipand  路  5Comments

zaccharieramzi picture zaccharieramzi  路  5Comments

ghop02 picture ghop02  路  6Comments

zantism picture zantism  路  5Comments

xternalz picture xternalz  路  3Comments