16

I am adding a dense layer before InceptionResNetV2 model(pre-trained) This is InceptionResNetV2 output

model_base = InceptionResNetV2(include_top=True, weights='imagenet')
x = model_base.get_layer('avg_pool').output
x = Dense(3, activation='softmax')(x)

This is the layer will be added

input1 = Input(shape=input_shape1)
pre1 = Conv2D(filters=3, kernel_size=(5, 5), padding='SAME', 
input_shape=input_shape1, name='first_dense')(input1)
pre = Model(inputs=input1, outputs=pre1)

This is combining two models

 after = Model(inputs=pre.output, outputs=x)

 model = Model(inputs=input1, outputs=after.output)

 model.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['accuracy'])

use

pre.output

as

after.input

But it doesn't works . How can I resolve it?

cwzat cwzat
  • 193
  • 1
  • 1
  • 6

1 Answers1

23

First let's create a new model from model_base, because you want to get an earlier output.

Your code:

model_base = InceptionResNetV2(include_top=True, weights='imagenet')
x = model_base.get_layer('avg_pool').output
x = Dense(3, activation='softmax')(x)

New model_base:

model_base = Model(model_base.input, x)

Now, it's important to pass the output pre1 to this model:

base_out = model_base(pre1)     

That's it:

model = Model(input1, base_out)
Daniel Möller
  • 84,878
  • 18
  • 192
  • 214
  • I have another question. If I want to use my own layer 'pre1' replacing the model_base first layer, how can I solve it ?Thank you ! – cwzat cwzat Dec 09 '17 at 19:14
  • The first part of my answer becomes `short_base = Model(base_model.get_layer('theFirstYouWantToKeep').input, base_model.get_layer('avg_pool'))` --- The rest is the same. – Daniel Möller Dec 09 '17 at 19:37
  • 1
    I tried, but i get the error:TypeError: Input layers to a `Model` must be `InputLayer` objects. Received inputs: Tensor("conv2d_1/convolution:0", shape=(?, ?, ?, 32), dtype=float32). – cwzat cwzat Dec 10 '17 at 02:46
  • 1
    I think you'll have to call layer by layer then....something like `out = base_model.layers[2](pre1)`. Then a loop from layers 3 to end: `out = model.layers[i](out)`. Then make a model from your first input to this `out`. – Daniel Möller Dec 10 '17 at 04:09
  • I think is may not bacause i use resnet, it has short cut, so the layer is not stacked one by one, if so, i get the dimension error. Is there another methods? – cwzat cwzat Dec 10 '17 at 04:34
  • You can try to copy the resnet code and change it...: https://github.com/fchollet/keras/blob/master/keras/applications/inception_resnet_v2.py – Daniel Möller Dec 10 '17 at 04:52
  • @DanielMöller In case the output layer of network A is merged layer. How can we pass first ncolumns of the merged layer as input to network B? – shaifali Gupta Dec 18 '18 at 17:55
  • @DanielMöller Sorry to bring up an old thread question, but I have a question about this line: `base_out = model_base(pre1)` Here we are treating model_base as a regular model, and just getting the output `base_out`? We don't need to use `.output` in this case, if we want to feed the output to other models? Thanks. – Moondra Jun 11 '19 at 19:38
  • 1
    @Moondra, we are "calling" `model_base` when we use `(pre1)` in front of it. This means we are getting an "output" `base_out` given an "input" `pre1`. – Daniel Möller Jun 12 '19 at 20:08
  • Thanks. Yeah it seems we can use models as layers. – Moondra Jun 13 '19 at 20:55
  • Quick question, if I wanted to add the new trainable layer after (instead of before like in this post) what would be some key points to keep track of? (I'm trying but its bugging up) – ABIM Apr 07 '20 at 16:57
  • `inputs = Input(...)`, `outputs = YourLayer(...)(inputs)`, `outputs = model_base(outputs)`, `outputs = MoreLayers(...)(outputs)`, `model = Model(inputs, outputs)`. – Daniel Möller Apr 07 '20 at 17:32