keras-team / keras-applications

Reference implementations of popular deep learning models.
Other
2k stars 907 forks source link

Loading VGG16/19 with pooling=None still has pooling #48

Closed weiji14 closed 6 years ago

weiji14 commented 6 years ago

Loading a VGG19 layer with include_top=False and pooling=None should return an output that is the 4D tensor of the last convolutional layer according to the docstring.

        pooling: Optional pooling mode for feature extraction
            when `include_top` is `False`.
            - `None` means that the output of the model will be
                the 4D tensor output of the
                last convolutional layer.

However, we get a MaxPooling layer at the very end rather than a Conv2D layer.

   >>> vgg19 = keras.applications.VGG19(weights='imagenet', include_top=False, pooling=None)
   >>> vgg19.layers
        [<keras.engine.input_layer.InputLayer at 0x7ef7b7f5e710>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb67ddd8>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb2d72b0>,
         <keras.layers.pooling.MaxPooling2D at 0x7ef7bb2ef2b0>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb2ef908>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb28f7f0>,
         <keras.layers.pooling.MaxPooling2D at 0x7ef7bb2ad160>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb2adc50>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb2631d0>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb202160>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb2205c0>,
         <keras.layers.pooling.MaxPooling2D at 0x7ef7bb23b208>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb23bd68>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb1e7208>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb182048>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb19c128>,
         <keras.layers.pooling.MaxPooling2D at 0x7ef7bb1ba4a8>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb1bad30>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb1762e8>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb114390>,
         <keras.layers.convolutional.Conv2D at 0x7ef7bb12d208>,
         <keras.layers.pooling.MaxPooling2D at 0x7ef7bb0cb588>]

I've traced it back via this git blame to this commit which was a part of https://github.com/farizrahman4u/keras/pull/9

Depending on what is the intended behaviour, we'll need to either change the docstring to clarify that it is the MaxPooling2D layer that is the output, or modify the VGG scripts so that the output is a Conv2D layer.

Some steps involved for the latter (more involved) fix:

I can create a pull request to help out with the first two once we clarify the intended behaviour. Changing the weight files will require a bit of help.

taehoonlee commented 6 years ago

Thank you for reporting the issue, @weiji14. There is no problem in the current implementations, but the docstrings need to be revised, as you pointed out. The include_top=False, pooling=None arguments should return the last convolutional "block" rather than "layer". The "block" means generally a set of layers, and the "convolutional block" in the ImageNet models typically consists of several convolutional layers followed by (or following) a 2x down-sampling layer.

Thus, it is true that the last output in VGG(include_top=False, pooling=None) is MaxPooling2D (block5_pool). I will revise the docstrings. Thank you!

weiji14 commented 6 years ago

Thanks for the quick fix. I'll close the issue now :smile: