0

I am using keras 2.02 and tensorflow 1.3 to build a convolution net with multiple sizes of filters. The code is shown below.

flts=100
kernel_sizes=[2,3,4]
submodels = []
for kw in kernel_sizes:    # kernel sizes
    submodel = Sequential()
    submodel.add(embedding_layer)
    submodel.add(Dropout(0.2))
    submodel.add(Conv1D(filters=flts,
                        kernel_size=kw,
                        padding='same',
                        activation='relu'))
    submodel.add(MaxPooling1D(pool_size=kw))
    submodels.append(submodel)

big_model = Sequential()
#concat = Concatenate(axis=1)     #line B
#big_model.add(concat(submodels)) #line C
big_model.add(Merge(submodels, mode="concat", concat_axis=1))  #line A
big_model.add(LSTM(units=100, return_sequences=True))
big_model.add(GlobalMaxPooling1D())
#big_model.add(Dropout(0.2))
big_model.add(Dense(2, activation='softmax'))
big_model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

When using the deprecated code as on line A, it works ok. But when this is replaced by lines B,C, an error is generated as below:

--> 141     big_model.add(concat(submodels))
        big_model.add = <bound method Sequential.add of <keras.models.Sequential object>>
        concat = <keras.layers.merge.Concatenate object>
        submodels = [<keras.models.Sequential object>, <keras.models.Sequential object>, <keras.models.Sequential object>]
    142     big_model.add(LSTM(units=100, return_sequences=True))
    143     big_model.add(GlobalMaxPooling1D())
    144     #big_model.add(Dropout(0.2))
    145     big_model.add(Dense(2, activation='softmax'))


........

/home/zqz/Programs/anaconda3/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py in int_shape(x=<keras.models.Sequential object>)
    404         (2, 2)
    405     ```
    406     """
    407     if hasattr(x, '_keras_shape'):
    408         return x._keras_shape
--> 409     shape = x.get_shape()
        shape = undefined
        x.get_shape = undefined
    410     try:
    411         return tuple([i.__int__() for i in shape])
    412     except ValueError:
    413         return None

AttributeError: 'Sequential' object has no attribute 'get_shape'
___________________________________________________________________

I don't know what I should do to fix this?

Thanks in advance

1 Answer 1

3

I'll suggest using the functional API when your model contains branches. The Concatenate layer takes a list of tensors as its input. In this case, the list should contain the output tensors of the submodels.

submodel_outputs = [model.output for model in submodels]
x = Concatenate(axis=1)(submodel_outputs)

x = LSTM(units=100, return_sequences=True)(x)
x = GlobalMaxPooling1D()(x)
x = Dropout(0.2)(x)
x = Dense(2, activation='softmax')(x)

big_model = Model(inputs=embedding_layer.input, outputs=x)
big_model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
big_model.summary()

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to
==================================================================================================
embedding_1_input (InputLayer)  (None, None)         0
__________________________________________________________________________________________________
embedding_1 (Embedding)         (None, None, 64)     64000       embedding_1_input[0][0]
__________________________________________________________________________________________________
dropout_3 (Dropout)             (None, None, 64)     0           embedding_1[0][0]
__________________________________________________________________________________________________
dropout_4 (Dropout)             (None, None, 64)     0           embedding_1[0][0]
__________________________________________________________________________________________________
dropout_5 (Dropout)             (None, None, 64)     0           embedding_1[0][0]
__________________________________________________________________________________________________
conv1d_4 (Conv1D)               (None, None, 100)    12900       dropout_3[0][0]
__________________________________________________________________________________________________
conv1d_5 (Conv1D)               (None, None, 100)    19300       dropout_4[0][0]
__________________________________________________________________________________________________
conv1d_6 (Conv1D)               (None, None, 100)    25700       dropout_5[0][0]
__________________________________________________________________________________________________
max_pooling1d_4 (MaxPooling1D)  (None, None, 100)    0           conv1d_4[0][0]
__________________________________________________________________________________________________
max_pooling1d_5 (MaxPooling1D)  (None, None, 100)    0           conv1d_5[0][0]
__________________________________________________________________________________________________
max_pooling1d_6 (MaxPooling1D)  (None, None, 100)    0           conv1d_6[0][0]
__________________________________________________________________________________________________
concatenate_7 (Concatenate)     (None, None, 100)    0           max_pooling1d_4[0][0]
                                                                 max_pooling1d_5[0][0]
                                                                 max_pooling1d_6[0][0]
__________________________________________________________________________________________________
lstm_4 (LSTM)                   (None, None, 100)    80400       concatenate_7[0][0]
__________________________________________________________________________________________________
global_max_pooling1d_4 (GlobalM (None, 100)          0           lstm_4[0][0]
__________________________________________________________________________________________________
dropout_7 (Dropout)             (None, 100)          0           global_max_pooling1d_4[0][0]
__________________________________________________________________________________________________
dense_4 (Dense)                 (None, 2)            202         dropout_7[0][0]
==================================================================================================
Total params: 202,502
Trainable params: 202,502
Non-trainable params: 0
__________________________________________________________________________________________________

For using Model with the Scikit-Learn API:

class MyKerasClassifier(KerasClassifier):
    def predict(self, x, **kwargs):
        kwargs = self.filter_sk_params(self.model.predict, kwargs)
        proba = self.model.predict(x, **kwargs)
        if proba.shape[-1] > 1:
            classes = proba.argmax(axis=-1)
        else:
            classes = (proba > 0.5).astype('int32')
        return self.classes_[classes]

Originally in KerasClassifier.predict(), the function predict_classes() is called to obtain the predicted classes. You can override this function and compute the classes from the probabilities to avoid the need of predict_classes().

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, the model builds fine but is there no way I can use with the sequential model? the reason is that the Sequential model seems to be the only one that implements 'predict_classes'. I need to wrap the model in a GridSearchCV object and call 'cross_val_predict' which then will call the 'predict_classes' attribute of the classifier. I can update the code with details if needed. Any suggestions please?
@Ziqi The documentation states that the sklearn wrappers are to be used with "Sequential Keras models (single-input only)". So I think you may need to modify the wrapper a bit for your purpose. See my edit for a possible workaround.
thank you it seems to be working technically as the code is running. but results i got are only predicting one out of two classes - every instance belong to that class. but I wonder if that's the semantics of the network for my specific problem. thanks again

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.