1# Copyright 2015 The TensorFlow Authors. All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# ============================================================================== 15# pylint: disable=invalid-name 16"""VGG19 model for Keras. 17 18Reference: 19 - [Very Deep Convolutional Networks for Large-Scale Image Recognition]( 20 https://arxiv.org/abs/1409.1556) (ICLR 2015) 21""" 22from __future__ import absolute_import 23from __future__ import division 24from __future__ import print_function 25 26import os 27 28from tensorflow.python.keras import backend 29from tensorflow.python.keras import layers 30from tensorflow.python.keras.applications import imagenet_utils 31from tensorflow.python.keras.engine import training 32from tensorflow.python.keras.utils import data_utils 33from tensorflow.python.keras.utils import layer_utils 34from tensorflow.python.util.tf_export import keras_export 35 36 37WEIGHTS_PATH = ('https://storage.googleapis.com/tensorflow/keras-applications/' 38 'vgg19/vgg19_weights_tf_dim_ordering_tf_kernels.h5') 39WEIGHTS_PATH_NO_TOP = ('https://storage.googleapis.com/tensorflow/' 40 'keras-applications/vgg19/' 41 'vgg19_weights_tf_dim_ordering_tf_kernels_notop.h5') 42 43 44@keras_export('keras.applications.vgg19.VGG19', 'keras.applications.VGG19') 45def VGG19(include_top=True, 46 weights='imagenet', 47 input_tensor=None, 48 input_shape=None, 49 pooling=None, 50 classes=1000): 51 """Instantiates the VGG19 architecture. 52 53 By default, it loads weights pre-trained on ImageNet. Check 'weights' for 54 other options. 55 56 This model can be built both with 'channels_first' data format 57 (channels, height, width) or 'channels_last' data format 58 (height, width, channels). 59 60 The default input size for this model is 224x224. 61 62 Arguments: 63 include_top: whether to include the 3 fully-connected 64 layers at the top of the network. 65 weights: one of `None` (random initialization), 66 'imagenet' (pre-training on ImageNet), 67 or the path to the weights file to be loaded. 68 input_tensor: optional Keras tensor 69 (i.e. output of `layers.Input()`) 70 to use as image input for the model. 71 input_shape: optional shape tuple, only to be specified 72 if `include_top` is False (otherwise the input shape 73 has to be `(224, 224, 3)` 74 (with `channels_last` data format) 75 or `(3, 224, 224)` (with `channels_first` data format). 76 It should have exactly 3 inputs channels, 77 and width and height should be no smaller than 32. 78 E.g. `(200, 200, 3)` would be one valid value. 79 pooling: Optional pooling mode for feature extraction 80 when `include_top` is `False`. 81 - `None` means that the output of the model will be 82 the 4D tensor output of the 83 last convolutional block. 84 - `avg` means that global average pooling 85 will be applied to the output of the 86 last convolutional block, and thus 87 the output of the model will be a 2D tensor. 88 - `max` means that global max pooling will 89 be applied. 90 classes: optional number of classes to classify images 91 into, only to be specified if `include_top` is True, and 92 if no `weights` argument is specified. 93 94 Returns: 95 A Keras model instance. 96 97 Raises: 98 ValueError: in case of invalid argument for `weights`, 99 or invalid input shape. 100 """ 101 if not (weights in {'imagenet', None} or os.path.exists(weights)): 102 raise ValueError('The `weights` argument should be either ' 103 '`None` (random initialization), `imagenet` ' 104 '(pre-training on ImageNet), ' 105 'or the path to the weights file to be loaded.') 106 107 if weights == 'imagenet' and include_top and classes != 1000: 108 raise ValueError('If using `weights` as `"imagenet"` with `include_top`' 109 ' as true, `classes` should be 1000') 110 # Determine proper input shape 111 input_shape = imagenet_utils.obtain_input_shape( 112 input_shape, 113 default_size=224, 114 min_size=32, 115 data_format=backend.image_data_format(), 116 require_flatten=include_top, 117 weights=weights) 118 119 if input_tensor is None: 120 img_input = layers.Input(shape=input_shape) 121 else: 122 if not backend.is_keras_tensor(input_tensor): 123 img_input = layers.Input(tensor=input_tensor, shape=input_shape) 124 else: 125 img_input = input_tensor 126 # Block 1 127 x = layers.Conv2D( 128 64, (3, 3), activation='relu', padding='same', name='block1_conv1')( 129 img_input) 130 x = layers.Conv2D( 131 64, (3, 3), activation='relu', padding='same', name='block1_conv2')(x) 132 x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x) 133 134 # Block 2 135 x = layers.Conv2D( 136 128, (3, 3), activation='relu', padding='same', name='block2_conv1')(x) 137 x = layers.Conv2D( 138 128, (3, 3), activation='relu', padding='same', name='block2_conv2')(x) 139 x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x) 140 141 # Block 3 142 x = layers.Conv2D( 143 256, (3, 3), activation='relu', padding='same', name='block3_conv1')(x) 144 x = layers.Conv2D( 145 256, (3, 3), activation='relu', padding='same', name='block3_conv2')(x) 146 x = layers.Conv2D( 147 256, (3, 3), activation='relu', padding='same', name='block3_conv3')(x) 148 x = layers.Conv2D( 149 256, (3, 3), activation='relu', padding='same', name='block3_conv4')(x) 150 x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x) 151 152 # Block 4 153 x = layers.Conv2D( 154 512, (3, 3), activation='relu', padding='same', name='block4_conv1')(x) 155 x = layers.Conv2D( 156 512, (3, 3), activation='relu', padding='same', name='block4_conv2')(x) 157 x = layers.Conv2D( 158 512, (3, 3), activation='relu', padding='same', name='block4_conv3')(x) 159 x = layers.Conv2D( 160 512, (3, 3), activation='relu', padding='same', name='block4_conv4')(x) 161 x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x) 162 163 # Block 5 164 x = layers.Conv2D( 165 512, (3, 3), activation='relu', padding='same', name='block5_conv1')(x) 166 x = layers.Conv2D( 167 512, (3, 3), activation='relu', padding='same', name='block5_conv2')(x) 168 x = layers.Conv2D( 169 512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x) 170 x = layers.Conv2D( 171 512, (3, 3), activation='relu', padding='same', name='block5_conv4')(x) 172 x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x) 173 174 if include_top: 175 # Classification block 176 x = layers.Flatten(name='flatten')(x) 177 x = layers.Dense(4096, activation='relu', name='fc1')(x) 178 x = layers.Dense(4096, activation='relu', name='fc2')(x) 179 x = layers.Dense(classes, activation='softmax', name='predictions')(x) 180 else: 181 if pooling == 'avg': 182 x = layers.GlobalAveragePooling2D()(x) 183 elif pooling == 'max': 184 x = layers.GlobalMaxPooling2D()(x) 185 186 # Ensure that the model takes into account 187 # any potential predecessors of `input_tensor`. 188 if input_tensor is not None: 189 inputs = layer_utils.get_source_inputs(input_tensor) 190 else: 191 inputs = img_input 192 # Create model. 193 model = training.Model(inputs, x, name='vgg19') 194 195 # Load weights. 196 if weights == 'imagenet': 197 if include_top: 198 weights_path = data_utils.get_file( 199 'vgg19_weights_tf_dim_ordering_tf_kernels.h5', 200 WEIGHTS_PATH, 201 cache_subdir='models', 202 file_hash='cbe5617147190e668d6c5d5026f83318') 203 else: 204 weights_path = data_utils.get_file( 205 'vgg19_weights_tf_dim_ordering_tf_kernels_notop.h5', 206 WEIGHTS_PATH_NO_TOP, 207 cache_subdir='models', 208 file_hash='253f8cb515780f3b799900260a226db6') 209 model.load_weights(weights_path) 210 elif weights is not None: 211 model.load_weights(weights) 212 213 return model 214 215 216@keras_export('keras.applications.vgg19.preprocess_input') 217def preprocess_input(x, data_format=None): 218 """Preprocesses the input (encoding a batch of images) to the VGG19 model.""" 219 return imagenet_utils.preprocess_input( 220 x, data_format=data_format, mode='caffe') 221 222 223@keras_export('keras.applications.vgg19.decode_predictions') 224def decode_predictions(preds, top=5): 225 """Decodes the prediction result from the VGG19 model.""" 226 return imagenet_utils.decode_predictions(preds, top=top) 227