├── LICENSE ├── imagenet_utils.py ├── README.md ├── vgg16.py ├── vgg19.py ├── resnet50.py └── inception_v3.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 François Chollet 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /imagenet_utils.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import json 3 | 4 | from keras.utils.data_utils import get_file 5 | from keras import backend as K 6 | 7 | CLASS_INDEX = None 8 | CLASS_INDEX_PATH = 'https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json' 9 | 10 | 11 | def preprocess_input(x, dim_ordering='default'): 12 | if dim_ordering == 'default': 13 | dim_ordering = K.image_dim_ordering() 14 | assert dim_ordering in {'tf', 'th'} 15 | 16 | if dim_ordering == 'th': 17 | x[:, 0, :, :] -= 103.939 18 | x[:, 1, :, :] -= 116.779 19 | x[:, 2, :, :] -= 123.68 20 | # 'RGB'->'BGR' 21 | x = x[:, ::-1, :, :] 22 | else: 23 | x[:, :, :, 0] -= 103.939 24 | x[:, :, :, 1] -= 116.779 25 | x[:, :, :, 2] -= 123.68 26 | # 'RGB'->'BGR' 27 | x = x[:, :, :, ::-1] 28 | return x 29 | 30 | 31 | def decode_predictions(preds): 32 | global CLASS_INDEX 33 | assert len(preds.shape) == 2 and preds.shape[1] == 1000 34 | if CLASS_INDEX is None: 35 | fpath = get_file('imagenet_class_index.json', 36 | CLASS_INDEX_PATH, 37 | cache_subdir='models') 38 | CLASS_INDEX = json.load(open(fpath)) 39 | indices = np.argmax(preds, axis=-1) 40 | results = [] 41 | for i in indices: 42 | results.append(CLASS_INDEX[str(i)]) 43 | return results 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Trained image classification models for Keras 2 | 3 | This repository contains code for the following Keras models: 4 | 5 | - VGG16 6 | - VGG19 7 | - ResNet50 8 | - Inception v3 9 | 10 | All architectures are compatible with both TensorFlow and Theano, and upon instantiation the models will be built according to the image dimension ordering set in your Keras configuration file at `~/.keras/keras.json`. For instance, if you have set `image_dim_ordering=tf`, then any model loaded from this repository will get built according to the TensorFlow dimension ordering convention, "Width-Height-Depth". 11 | 12 | Weights can be automatically loaded upon instantiation (`weights='imagenet'` argument in model constructor). Weights are automatically downloaded if necessary, and cached locally in `~/.keras/models/`. 13 | 14 | **Note that using these models requires the latest version of Keras (from the Github repo, not PyPI).** 15 | 16 | ## Examples 17 | 18 | ### Classify images 19 | 20 | ```python 21 | from resnet50 import ResNet50 22 | from keras.preprocessing import image 23 | from imagenet_utils import preprocess_input, decode_predictions 24 | 25 | model = ResNet50(weights='imagenet') 26 | 27 | img_path = 'elephant.jpg' 28 | img = image.load_img(img_path, target_size=(224, 224)) 29 | x = image.img_to_array(img) 30 | x = np.expand_dims(x, axis=0) 31 | x = preprocess_input(x) 32 | 33 | preds = model.predict(x) 34 | print('Predicted:', decode_predictions(preds)) 35 | # print: [[u'n02504458', u'African_elephant']] 36 | ``` 37 | 38 | ### Extract features from images 39 | 40 | ```python 41 | from vgg16 import VGG16 42 | from keras.preprocessing import image 43 | from imagenet_utils import preprocess_input 44 | 45 | model = VGG16(weights='imagenet', include_top=False) 46 | 47 | img_path = 'elephant.jpg' 48 | img = image.load_img(img_path, target_size=(224, 224)) 49 | x = image.img_to_array(img) 50 | x = np.expand_dims(x, axis=0) 51 | x = preprocess_input(x) 52 | 53 | features = model.predict(x) 54 | ``` 55 | 56 | ### Extract features from an arbitrary intermediate layer 57 | 58 | ```python 59 | from vgg19 import VGG19 60 | from keras.preprocessing import image 61 | from imagenet_utils import preprocess_input 62 | from keras.models import Model 63 | 64 | base_model = VGG19(weights='imagenet') 65 | model = Model(input=base_model.input, output=base_model.get_layer('block4_pool').output) 66 | 67 | img_path = 'elephant.jpg' 68 | img = image.load_img(img_path, target_size=(224, 224)) 69 | x = image.img_to_array(img) 70 | x = np.expand_dims(x, axis=0) 71 | x = preprocess_input(x) 72 | 73 | block4_pool_features = model.predict(x) 74 | ``` 75 | 76 | ## References 77 | 78 | - [Very Deep Convolutional Networks for Large-Scale Image Recognition](https://arxiv.org/abs/1409.1556) - please cite this paper if you use the VGG models in your work. 79 | - [Deep Residual Learning for Image Recognition](https://arxiv.org/abs/1512.03385) - please cite this paper if you use the ResNet model in your work. 80 | - [Rethinking the Inception Architecture for Computer Vision](http://arxiv.org/abs/1512.00567) - please cite this paper if you use the Inception v3 model in your work. 81 | 82 | Additionally, don't forget to [cite Keras](https://keras.io/getting-started/faq/#how-should-i-cite-keras) if you use these models. 83 | 84 | 85 | ## License 86 | 87 | - All code in this repository is under the MIT license as specified by the LICENSE file. 88 | - The ResNet50 weights are ported from the ones [released by Kaiming He](https://github.com/KaimingHe/deep-residual-networks) under the [MIT license](https://github.com/KaimingHe/deep-residual-networks/blob/master/LICENSE). 89 | - The VGG16 and VGG19 weights are ported from the ones [released by VGG at Oxford](http://www.robots.ox.ac.uk/~vgg/research/very_deep/) under the [Creative Commons Attribution License](https://creativecommons.org/licenses/by/4.0/). 90 | - The Inception v3 weights are trained by ourselves and are released under the MIT license. 91 | -------------------------------------------------------------------------------- /vgg16.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | '''VGG16 model for Keras. 3 | 4 | # Reference: 5 | 6 | - [Very Deep Convolutional Networks for Large-Scale Image Recognition](https://arxiv.org/abs/1409.1556) 7 | 8 | ''' 9 | from __future__ import print_function 10 | 11 | import numpy as np 12 | import warnings 13 | 14 | from keras.models import Model 15 | from keras.layers import Flatten, Dense, Input 16 | from keras.layers import Convolution2D, MaxPooling2D 17 | from keras.preprocessing import image 18 | from keras.utils.layer_utils import convert_all_kernels_in_model 19 | from keras.utils.data_utils import get_file 20 | from keras import backend as K 21 | from imagenet_utils import decode_predictions, preprocess_input 22 | 23 | 24 | TH_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_th_dim_ordering_th_kernels.h5' 25 | TF_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels.h5' 26 | TH_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_th_dim_ordering_th_kernels_notop.h5' 27 | TF_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5' 28 | 29 | 30 | def VGG16(include_top=True, weights='imagenet', 31 | input_tensor=None): 32 | '''Instantiate the VGG16 architecture, 33 | optionally loading weights pre-trained 34 | on ImageNet. Note that when using TensorFlow, 35 | for best performance you should set 36 | `image_dim_ordering="tf"` in your Keras config 37 | at ~/.keras/keras.json. 38 | 39 | The model and the weights are compatible with both 40 | TensorFlow and Theano. The dimension ordering 41 | convention used by the model is the one 42 | specified in your Keras config file. 43 | 44 | # Arguments 45 | include_top: whether to include the 3 fully-connected 46 | layers at the top of the network. 47 | weights: one of `None` (random initialization) 48 | or "imagenet" (pre-training on ImageNet). 49 | input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) 50 | to use as image input for the model. 51 | 52 | # Returns 53 | A Keras model instance. 54 | ''' 55 | if weights not in {'imagenet', None}: 56 | raise ValueError('The `weights` argument should be either ' 57 | '`None` (random initialization) or `imagenet` ' 58 | '(pre-training on ImageNet).') 59 | # Determine proper input shape 60 | if K.image_dim_ordering() == 'th': 61 | if include_top: 62 | input_shape = (3, 224, 224) 63 | else: 64 | input_shape = (3, None, None) 65 | else: 66 | if include_top: 67 | input_shape = (224, 224, 3) 68 | else: 69 | input_shape = (None, None, 3) 70 | 71 | if input_tensor is None: 72 | img_input = Input(shape=input_shape) 73 | else: 74 | if not K.is_keras_tensor(input_tensor): 75 | img_input = Input(tensor=input_tensor) 76 | else: 77 | img_input = input_tensor 78 | # Block 1 79 | x = Convolution2D(64, 3, 3, activation='relu', border_mode='same', name='block1_conv1')(img_input) 80 | x = Convolution2D(64, 3, 3, activation='relu', border_mode='same', name='block1_conv2')(x) 81 | x = MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x) 82 | 83 | # Block 2 84 | x = Convolution2D(128, 3, 3, activation='relu', border_mode='same', name='block2_conv1')(x) 85 | x = Convolution2D(128, 3, 3, activation='relu', border_mode='same', name='block2_conv2')(x) 86 | x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x) 87 | 88 | # Block 3 89 | x = Convolution2D(256, 3, 3, activation='relu', border_mode='same', name='block3_conv1')(x) 90 | x = Convolution2D(256, 3, 3, activation='relu', border_mode='same', name='block3_conv2')(x) 91 | x = Convolution2D(256, 3, 3, activation='relu', border_mode='same', name='block3_conv3')(x) 92 | x = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x) 93 | 94 | # Block 4 95 | x = Convolution2D(512, 3, 3, activation='relu', border_mode='same', name='block4_conv1')(x) 96 | x = Convolution2D(512, 3, 3, activation='relu', border_mode='same', name='block4_conv2')(x) 97 | x = Convolution2D(512, 3, 3, activation='relu', border_mode='same', name='block4_conv3')(x) 98 | x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x) 99 | 100 | # Block 5 101 | x = Convolution2D(512, 3, 3, activation='relu', border_mode='same', name='block5_conv1')(x) 102 | x = Convolution2D(512, 3, 3, activation='relu', border_mode='same', name='block5_conv2')(x) 103 | x = Convolution2D(512, 3, 3, activation='relu', border_mode='same', name='block5_conv3')(x) 104 | x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x) 105 | 106 | if include_top: 107 | # Classification block 108 | x = Flatten(name='flatten')(x) 109 | x = Dense(4096, activation='relu', name='fc1')(x) 110 | x = Dense(4096, activation='relu', name='fc2')(x) 111 | x = Dense(1000, activation='softmax', name='predictions')(x) 112 | 113 | # Create model 114 | model = Model(img_input, x) 115 | 116 | # load weights 117 | if weights == 'imagenet': 118 | print('K.image_dim_ordering:', K.image_dim_ordering()) 119 | if K.image_dim_ordering() == 'th': 120 | if include_top: 121 | weights_path = get_file('vgg16_weights_th_dim_ordering_th_kernels.h5', 122 | TH_WEIGHTS_PATH, 123 | cache_subdir='models') 124 | else: 125 | weights_path = get_file('vgg16_weights_th_dim_ordering_th_kernels_notop.h5', 126 | TH_WEIGHTS_PATH_NO_TOP, 127 | cache_subdir='models') 128 | model.load_weights(weights_path) 129 | if K.backend() == 'tensorflow': 130 | warnings.warn('You are using the TensorFlow backend, yet you ' 131 | 'are using the Theano ' 132 | 'image dimension ordering convention ' 133 | '(`image_dim_ordering="th"`). ' 134 | 'For best performance, set ' 135 | '`image_dim_ordering="tf"` in ' 136 | 'your Keras config ' 137 | 'at ~/.keras/keras.json.') 138 | convert_all_kernels_in_model(model) 139 | else: 140 | if include_top: 141 | weights_path = get_file('vgg16_weights_tf_dim_ordering_tf_kernels.h5', 142 | TF_WEIGHTS_PATH, 143 | cache_subdir='models') 144 | else: 145 | weights_path = get_file('vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5', 146 | TF_WEIGHTS_PATH_NO_TOP, 147 | cache_subdir='models') 148 | model.load_weights(weights_path) 149 | if K.backend() == 'theano': 150 | convert_all_kernels_in_model(model) 151 | return model 152 | 153 | 154 | if __name__ == '__main__': 155 | model = VGG16(include_top=True, weights='imagenet') 156 | 157 | img_path = 'elephant.jpg' 158 | img = image.load_img(img_path, target_size=(224, 224)) 159 | x = image.img_to_array(img) 160 | x = np.expand_dims(x, axis=0) 161 | x = preprocess_input(x) 162 | print('Input image shape:', x.shape) 163 | 164 | preds = model.predict(x) 165 | print('Predicted:', decode_predictions(preds)) 166 | -------------------------------------------------------------------------------- /vgg19.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | '''VGG19 model for Keras. 3 | 4 | # Reference: 5 | 6 | - [Very Deep Convolutional Networks for Large-Scale Image Recognition](https://arxiv.org/abs/1409.1556) 7 | 8 | ''' 9 | from __future__ import print_function 10 | 11 | import numpy as np 12 | import warnings 13 | 14 | from keras.models import Model 15 | from keras.layers import Flatten, Dense, Input 16 | from keras.layers import Convolution2D, MaxPooling2D 17 | from keras.preprocessing import image 18 | from keras.utils.layer_utils import convert_all_kernels_in_model 19 | from keras.utils.data_utils import get_file 20 | from keras import backend as K 21 | from imagenet_utils import decode_predictions, preprocess_input 22 | 23 | 24 | TH_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg19_weights_th_dim_ordering_th_kernels.h5' 25 | TF_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg19_weights_tf_dim_ordering_tf_kernels.h5' 26 | TH_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg19_weights_th_dim_ordering_th_kernels_notop.h5' 27 | TF_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg19_weights_tf_dim_ordering_tf_kernels_notop.h5' 28 | 29 | 30 | def VGG19(include_top=True, weights='imagenet', 31 | input_tensor=None): 32 | '''Instantiate the VGG19 architecture, 33 | optionally loading weights pre-trained 34 | on ImageNet. Note that when using TensorFlow, 35 | for best performance you should set 36 | `image_dim_ordering="tf"` in your Keras config 37 | at ~/.keras/keras.json. 38 | 39 | The model and the weights are compatible with both 40 | TensorFlow and Theano. The dimension ordering 41 | convention used by the model is the one 42 | specified in your Keras config file. 43 | 44 | # Arguments 45 | include_top: whether to include the 3 fully-connected 46 | layers at the top of the network. 47 | weights: one of `None` (random initialization) 48 | or "imagenet" (pre-training on ImageNet). 49 | input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) 50 | to use as image input for the model. 51 | 52 | # Returns 53 | A Keras model instance. 54 | ''' 55 | if weights not in {'imagenet', None}: 56 | raise ValueError('The `weights` argument should be either ' 57 | '`None` (random initialization) or `imagenet` ' 58 | '(pre-training on ImageNet).') 59 | # Determine proper input shape 60 | if K.image_dim_ordering() == 'th': 61 | if include_top: 62 | input_shape = (3, 224, 224) 63 | else: 64 | input_shape = (3, None, None) 65 | else: 66 | if include_top: 67 | input_shape = (224, 224, 3) 68 | else: 69 | input_shape = (None, None, 3) 70 | 71 | if input_tensor is None: 72 | img_input = Input(shape=input_shape) 73 | else: 74 | if not K.is_keras_tensor(input_tensor): 75 | img_input = Input(tensor=input_tensor) 76 | else: 77 | img_input = input_tensor 78 | # Block 1 79 | x = Convolution2D(64, 3, 3, activation='relu', border_mode='same', name='block1_conv1')(img_input) 80 | x = Convolution2D(64, 3, 3, activation='relu', border_mode='same', name='block1_conv2')(x) 81 | x = MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x) 82 | 83 | # Block 2 84 | x = Convolution2D(128, 3, 3, activation='relu', border_mode='same', name='block2_conv1')(x) 85 | x = Convolution2D(128, 3, 3, activation='relu', border_mode='same', name='block2_conv2')(x) 86 | x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x) 87 | 88 | # Block 3 89 | x = Convolution2D(256, 3, 3, activation='relu', border_mode='same', name='block3_conv1')(x) 90 | x = Convolution2D(256, 3, 3, activation='relu', border_mode='same', name='block3_conv2')(x) 91 | x = Convolution2D(256, 3, 3, activation='relu', border_mode='same', name='block3_conv3')(x) 92 | x = Convolution2D(256, 3, 3, activation='relu', border_mode='same', name='block3_conv4')(x) 93 | x = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x) 94 | 95 | # Block 4 96 | x = Convolution2D(512, 3, 3, activation='relu', border_mode='same', name='block4_conv1')(x) 97 | x = Convolution2D(512, 3, 3, activation='relu', border_mode='same', name='block4_conv2')(x) 98 | x = Convolution2D(512, 3, 3, activation='relu', border_mode='same', name='block4_conv3')(x) 99 | x = Convolution2D(512, 3, 3, activation='relu', border_mode='same', name='block4_conv4')(x) 100 | x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x) 101 | 102 | # Block 5 103 | x = Convolution2D(512, 3, 3, activation='relu', border_mode='same', name='block5_conv1')(x) 104 | x = Convolution2D(512, 3, 3, activation='relu', border_mode='same', name='block5_conv2')(x) 105 | x = Convolution2D(512, 3, 3, activation='relu', border_mode='same', name='block5_conv3')(x) 106 | x = Convolution2D(512, 3, 3, activation='relu', border_mode='same', name='block5_conv4')(x) 107 | x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x) 108 | 109 | if include_top: 110 | # Classification block 111 | x = Flatten(name='flatten')(x) 112 | x = Dense(4096, activation='relu', name='fc1')(x) 113 | x = Dense(4096, activation='relu', name='fc2')(x) 114 | x = Dense(1000, activation='softmax', name='predictions')(x) 115 | 116 | # Create model 117 | model = Model(img_input, x) 118 | 119 | # load weights 120 | if weights == 'imagenet': 121 | print('K.image_dim_ordering:', K.image_dim_ordering()) 122 | if K.image_dim_ordering() == 'th': 123 | if include_top: 124 | weights_path = get_file('vgg19_weights_th_dim_ordering_th_kernels.h5', 125 | TH_WEIGHTS_PATH, 126 | cache_subdir='models') 127 | else: 128 | weights_path = get_file('vgg19_weights_th_dim_ordering_th_kernels_notop.h5', 129 | TH_WEIGHTS_PATH_NO_TOP, 130 | cache_subdir='models') 131 | model.load_weights(weights_path) 132 | if K.backend() == 'tensorflow': 133 | warnings.warn('You are using the TensorFlow backend, yet you ' 134 | 'are using the Theano ' 135 | 'image dimension ordering convention ' 136 | '(`image_dim_ordering="th"`). ' 137 | 'For best performance, set ' 138 | '`image_dim_ordering="tf"` in ' 139 | 'your Keras config ' 140 | 'at ~/.keras/keras.json.') 141 | convert_all_kernels_in_model(model) 142 | else: 143 | if include_top: 144 | weights_path = get_file('vgg19_weights_tf_dim_ordering_tf_kernels.h5', 145 | TF_WEIGHTS_PATH, 146 | cache_subdir='models') 147 | else: 148 | weights_path = get_file('vgg19_weights_tf_dim_ordering_tf_kernels_notop.h5', 149 | TF_WEIGHTS_PATH_NO_TOP, 150 | cache_subdir='models') 151 | model.load_weights(weights_path) 152 | if K.backend() == 'theano': 153 | convert_all_kernels_in_model(model) 154 | return model 155 | 156 | 157 | if __name__ == '__main__': 158 | model = VGG19(include_top=True, weights='imagenet') 159 | 160 | img_path = 'cat.jpg' 161 | img = image.load_img(img_path, target_size=(224, 224)) 162 | x = image.img_to_array(img) 163 | x = np.expand_dims(x, axis=0) 164 | x = preprocess_input(x) 165 | print('Input image shape:', x.shape) 166 | 167 | preds = model.predict(x) 168 | print('Predicted:', decode_predictions(preds)) 169 | -------------------------------------------------------------------------------- /resnet50.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | '''ResNet50 model for Keras. 3 | 4 | # Reference: 5 | 6 | - [Deep Residual Learning for Image Recognition](https://arxiv.org/abs/1512.03385) 7 | 8 | Adapted from code contributed by BigMoyan. 9 | ''' 10 | from __future__ import print_function 11 | 12 | import numpy as np 13 | import warnings 14 | 15 | from keras.layers import merge, Input 16 | from keras.layers import Dense, Activation, Flatten 17 | from keras.layers import Convolution2D, MaxPooling2D, ZeroPadding2D, AveragePooling2D 18 | from keras.layers import BatchNormalization 19 | from keras.models import Model 20 | from keras.preprocessing import image 21 | import keras.backend as K 22 | from keras.utils.layer_utils import convert_all_kernels_in_model 23 | from keras.utils.data_utils import get_file 24 | from imagenet_utils import decode_predictions, preprocess_input 25 | 26 | 27 | TH_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.2/resnet50_weights_th_dim_ordering_th_kernels.h5' 28 | TF_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.2/resnet50_weights_tf_dim_ordering_tf_kernels.h5' 29 | TH_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.2/resnet50_weights_th_dim_ordering_th_kernels_notop.h5' 30 | TF_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.2/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5' 31 | 32 | 33 | def identity_block(input_tensor, kernel_size, filters, stage, block): 34 | '''The identity_block is the block that has no conv layer at shortcut 35 | 36 | # Arguments 37 | input_tensor: input tensor 38 | kernel_size: defualt 3, the kernel size of middle conv layer at main path 39 | filters: list of integers, the nb_filters of 3 conv layer at main path 40 | stage: integer, current stage label, used for generating layer names 41 | block: 'a','b'..., current block label, used for generating layer names 42 | ''' 43 | nb_filter1, nb_filter2, nb_filter3 = filters 44 | if K.image_dim_ordering() == 'tf': 45 | bn_axis = 3 46 | else: 47 | bn_axis = 1 48 | conv_name_base = 'res' + str(stage) + block + '_branch' 49 | bn_name_base = 'bn' + str(stage) + block + '_branch' 50 | 51 | x = Convolution2D(nb_filter1, 1, 1, name=conv_name_base + '2a')(input_tensor) 52 | x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x) 53 | x = Activation('relu')(x) 54 | 55 | x = Convolution2D(nb_filter2, kernel_size, kernel_size, 56 | border_mode='same', name=conv_name_base + '2b')(x) 57 | x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x) 58 | x = Activation('relu')(x) 59 | 60 | x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x) 61 | x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x) 62 | 63 | x = merge([x, input_tensor], mode='sum') 64 | x = Activation('relu')(x) 65 | return x 66 | 67 | 68 | def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2)): 69 | '''conv_block is the block that has a conv layer at shortcut 70 | 71 | # Arguments 72 | input_tensor: input tensor 73 | kernel_size: defualt 3, the kernel size of middle conv layer at main path 74 | filters: list of integers, the nb_filters of 3 conv layer at main path 75 | stage: integer, current stage label, used for generating layer names 76 | block: 'a','b'..., current block label, used for generating layer names 77 | 78 | Note that from stage 3, the first conv layer at main path is with subsample=(2,2) 79 | And the shortcut should have subsample=(2,2) as well 80 | ''' 81 | nb_filter1, nb_filter2, nb_filter3 = filters 82 | if K.image_dim_ordering() == 'tf': 83 | bn_axis = 3 84 | else: 85 | bn_axis = 1 86 | conv_name_base = 'res' + str(stage) + block + '_branch' 87 | bn_name_base = 'bn' + str(stage) + block + '_branch' 88 | 89 | x = Convolution2D(nb_filter1, 1, 1, subsample=strides, 90 | name=conv_name_base + '2a')(input_tensor) 91 | x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x) 92 | x = Activation('relu')(x) 93 | 94 | x = Convolution2D(nb_filter2, kernel_size, kernel_size, border_mode='same', 95 | name=conv_name_base + '2b')(x) 96 | x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x) 97 | x = Activation('relu')(x) 98 | 99 | x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x) 100 | x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x) 101 | 102 | shortcut = Convolution2D(nb_filter3, 1, 1, subsample=strides, 103 | name=conv_name_base + '1')(input_tensor) 104 | shortcut = BatchNormalization(axis=bn_axis, name=bn_name_base + '1')(shortcut) 105 | 106 | x = merge([x, shortcut], mode='sum') 107 | x = Activation('relu')(x) 108 | return x 109 | 110 | 111 | def ResNet50(include_top=True, weights='imagenet', 112 | input_tensor=None): 113 | '''Instantiate the ResNet50 architecture, 114 | optionally loading weights pre-trained 115 | on ImageNet. Note that when using TensorFlow, 116 | for best performance you should set 117 | `image_dim_ordering="tf"` in your Keras config 118 | at ~/.keras/keras.json. 119 | 120 | The model and the weights are compatible with both 121 | TensorFlow and Theano. The dimension ordering 122 | convention used by the model is the one 123 | specified in your Keras config file. 124 | 125 | # Arguments 126 | include_top: whether to include the 3 fully-connected 127 | layers at the top of the network. 128 | weights: one of `None` (random initialization) 129 | or "imagenet" (pre-training on ImageNet). 130 | input_tensor: optional Keras tensor (i.e. xput of `layers.Input()`) 131 | to use as image input for the model. 132 | 133 | # Returns 134 | A Keras model instance. 135 | ''' 136 | if weights not in {'imagenet', None}: 137 | raise ValueError('The `weights` argument should be either ' 138 | '`None` (random initialization) or `imagenet` ' 139 | '(pre-training on ImageNet).') 140 | # Determine proper input shape 141 | if K.image_dim_ordering() == 'th': 142 | if include_top: 143 | input_shape = (3, 224, 224) 144 | else: 145 | input_shape = (3, None, None) 146 | else: 147 | if include_top: 148 | input_shape = (224, 224, 3) 149 | else: 150 | input_shape = (None, None, 3) 151 | 152 | if input_tensor is None: 153 | img_input = Input(shape=input_shape) 154 | else: 155 | if not K.is_keras_tensor(input_tensor): 156 | img_input = Input(tensor=input_tensor) 157 | else: 158 | img_input = input_tensor 159 | if K.image_dim_ordering() == 'tf': 160 | bn_axis = 3 161 | else: 162 | bn_axis = 1 163 | 164 | x = ZeroPadding2D((3, 3))(img_input) 165 | x = Convolution2D(64, 7, 7, subsample=(2, 2), name='conv1')(x) 166 | x = BatchNormalization(axis=bn_axis, name='bn_conv1')(x) 167 | x = Activation('relu')(x) 168 | x = MaxPooling2D((3, 3), strides=(2, 2))(x) 169 | 170 | x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1)) 171 | x = identity_block(x, 3, [64, 64, 256], stage=2, block='b') 172 | x = identity_block(x, 3, [64, 64, 256], stage=2, block='c') 173 | 174 | x = conv_block(x, 3, [128, 128, 512], stage=3, block='a') 175 | x = identity_block(x, 3, [128, 128, 512], stage=3, block='b') 176 | x = identity_block(x, 3, [128, 128, 512], stage=3, block='c') 177 | x = identity_block(x, 3, [128, 128, 512], stage=3, block='d') 178 | 179 | x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a') 180 | x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b') 181 | x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c') 182 | x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d') 183 | x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e') 184 | x = identity_block(x, 3, [256, 256, 1024], stage=4, block='f') 185 | 186 | x = conv_block(x, 3, [512, 512, 2048], stage=5, block='a') 187 | x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b') 188 | x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c') 189 | 190 | x = AveragePooling2D((7, 7), name='avg_pool')(x) 191 | 192 | if include_top: 193 | x = Flatten()(x) 194 | x = Dense(1000, activation='softmax', name='fc1000')(x) 195 | 196 | model = Model(img_input, x) 197 | 198 | # load weights 199 | if weights == 'imagenet': 200 | print('K.image_dim_ordering:', K.image_dim_ordering()) 201 | if K.image_dim_ordering() == 'th': 202 | if include_top: 203 | weights_path = get_file('resnet50_weights_th_dim_ordering_th_kernels.h5', 204 | TH_WEIGHTS_PATH, 205 | cache_subdir='models', 206 | md5_hash='1c1f8f5b0c8ee28fe9d950625a230e1c') 207 | else: 208 | weights_path = get_file('resnet50_weights_th_dim_ordering_th_kernels_notop.h5', 209 | TH_WEIGHTS_PATH_NO_TOP, 210 | cache_subdir='models', 211 | md5_hash='f64f049c92468c9affcd44b0976cdafe') 212 | model.load_weights(weights_path) 213 | if K.backend() == 'tensorflow': 214 | warnings.warn('You are using the TensorFlow backend, yet you ' 215 | 'are using the Theano ' 216 | 'image dimension ordering convention ' 217 | '(`image_dim_ordering="th"`). ' 218 | 'For best performance, set ' 219 | '`image_dim_ordering="tf"` in ' 220 | 'your Keras config ' 221 | 'at ~/.keras/keras.json.') 222 | convert_all_kernels_in_model(model) 223 | else: 224 | if include_top: 225 | weights_path = get_file('resnet50_weights_tf_dim_ordering_tf_kernels.h5', 226 | TF_WEIGHTS_PATH, 227 | cache_subdir='models', 228 | md5_hash='a7b3fe01876f51b976af0dea6bc144eb') 229 | else: 230 | weights_path = get_file('resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5', 231 | TF_WEIGHTS_PATH_NO_TOP, 232 | cache_subdir='models', 233 | md5_hash='a268eb855778b3df3c7506639542a6af') 234 | model.load_weights(weights_path) 235 | if K.backend() == 'theano': 236 | convert_all_kernels_in_model(model) 237 | return model 238 | 239 | 240 | if __name__ == '__main__': 241 | model = ResNet50(include_top=True, weights='imagenet') 242 | 243 | img_path = 'elephant.jpg' 244 | img = image.load_img(img_path, target_size=(224, 224)) 245 | x = image.img_to_array(img) 246 | x = np.expand_dims(x, axis=0) 247 | x = preprocess_input(x) 248 | print('Input image shape:', x.shape) 249 | 250 | preds = model.predict(x) 251 | print('Predicted:', decode_predictions(preds)) 252 | -------------------------------------------------------------------------------- /inception_v3.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | '''Inception V3 model for Keras. 3 | 4 | Note that the ImageNet weights provided are from a model that had not fully converged. 5 | Inception v3 should be able to reach 6.9% top-5 error, but our model 6 | only gets to 7.8% (same as a fully-converged ResNet 50). 7 | For comparison, VGG16 only gets to 9.9%, quite a bit worse. 8 | 9 | Also, do note that the input image format for this model is different than for 10 | other models (299x299 instead of 224x224), and that the input preprocessing function 11 | is also different. 12 | 13 | # Reference: 14 | 15 | - [Rethinking the Inception Architecture for Computer Vision](http://arxiv.org/abs/1512.00567) 16 | 17 | ''' 18 | from __future__ import print_function 19 | 20 | import numpy as np 21 | import warnings 22 | 23 | from keras.models import Model 24 | from keras.layers import Flatten, Dense, Input, BatchNormalization, merge 25 | from keras.layers import Convolution2D, MaxPooling2D, AveragePooling2D 26 | from keras.preprocessing import image 27 | from keras.utils.layer_utils import convert_all_kernels_in_model 28 | from keras.utils.data_utils import get_file 29 | from keras import backend as K 30 | from imagenet_utils import decode_predictions 31 | 32 | 33 | TH_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.2/inception_v3_weights_th_dim_ordering_th_kernels.h5' 34 | TF_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.2/inception_v3_weights_tf_dim_ordering_tf_kernels.h5' 35 | TH_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.2/inception_v3_weights_th_dim_ordering_th_kernels_notop.h5' 36 | TF_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.2/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5' 37 | 38 | 39 | def conv2d_bn(x, nb_filter, nb_row, nb_col, 40 | border_mode='same', subsample=(1, 1), 41 | name=None): 42 | '''Utility function to apply conv + BN. 43 | ''' 44 | if name is not None: 45 | bn_name = name + '_bn' 46 | conv_name = name + '_conv' 47 | else: 48 | bn_name = None 49 | conv_name = None 50 | if K.image_dim_ordering() == 'th': 51 | bn_axis = 1 52 | else: 53 | bn_axis = 3 54 | x = Convolution2D(nb_filter, nb_row, nb_col, 55 | subsample=subsample, 56 | activation='relu', 57 | border_mode=border_mode, 58 | name=conv_name)(x) 59 | x = BatchNormalization(axis=bn_axis, name=bn_name)(x) 60 | return x 61 | 62 | 63 | def InceptionV3(include_top=True, weights='imagenet', 64 | input_tensor=None): 65 | '''Instantiate the Inception v3 architecture, 66 | optionally loading weights pre-trained 67 | on ImageNet. Note that when using TensorFlow, 68 | for best performance you should set 69 | `image_dim_ordering="tf"` in your Keras config 70 | at ~/.keras/keras.json. 71 | 72 | The model and the weights are compatible with both 73 | TensorFlow and Theano. The dimension ordering 74 | convention used by the model is the one 75 | specified in your Keras config file. 76 | 77 | Note that the default input image size for this model is 299x299. 78 | 79 | # Arguments 80 | include_top: whether to include the 3 fully-connected 81 | layers at the top of the network. 82 | weights: one of `None` (random initialization) 83 | or "imagenet" (pre-training on ImageNet). 84 | input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) 85 | to use as image input for the model. 86 | 87 | # Returns 88 | A Keras model instance. 89 | ''' 90 | if weights not in {'imagenet', None}: 91 | raise ValueError('The `weights` argument should be either ' 92 | '`None` (random initialization) or `imagenet` ' 93 | '(pre-training on ImageNet).') 94 | # Determine proper input shape 95 | if K.image_dim_ordering() == 'th': 96 | if include_top: 97 | input_shape = (3, 299, 299) 98 | else: 99 | input_shape = (3, None, None) 100 | else: 101 | if include_top: 102 | input_shape = (299, 299, 3) 103 | else: 104 | input_shape = (None, None, 3) 105 | 106 | if input_tensor is None: 107 | img_input = Input(shape=input_shape) 108 | else: 109 | if not K.is_keras_tensor(input_tensor): 110 | img_input = Input(tensor=input_tensor) 111 | else: 112 | img_input = input_tensor 113 | 114 | if K.image_dim_ordering() == 'th': 115 | channel_axis = 1 116 | else: 117 | channel_axis = 3 118 | 119 | x = conv2d_bn(img_input, 32, 3, 3, subsample=(2, 2), border_mode='valid') 120 | x = conv2d_bn(x, 32, 3, 3, border_mode='valid') 121 | x = conv2d_bn(x, 64, 3, 3) 122 | x = MaxPooling2D((3, 3), strides=(2, 2))(x) 123 | 124 | x = conv2d_bn(x, 80, 1, 1, border_mode='valid') 125 | x = conv2d_bn(x, 192, 3, 3, border_mode='valid') 126 | x = MaxPooling2D((3, 3), strides=(2, 2))(x) 127 | 128 | # mixed 0, 1, 2: 35 x 35 x 256 129 | for i in range(3): 130 | branch1x1 = conv2d_bn(x, 64, 1, 1) 131 | 132 | branch5x5 = conv2d_bn(x, 48, 1, 1) 133 | branch5x5 = conv2d_bn(branch5x5, 64, 5, 5) 134 | 135 | branch3x3dbl = conv2d_bn(x, 64, 1, 1) 136 | branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3) 137 | branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3) 138 | 139 | branch_pool = AveragePooling2D( 140 | (3, 3), strides=(1, 1), border_mode='same')(x) 141 | branch_pool = conv2d_bn(branch_pool, 32, 1, 1) 142 | x = merge([branch1x1, branch5x5, branch3x3dbl, branch_pool], 143 | mode='concat', concat_axis=channel_axis, 144 | name='mixed' + str(i)) 145 | 146 | # mixed 3: 17 x 17 x 768 147 | branch3x3 = conv2d_bn(x, 384, 3, 3, subsample=(2, 2), border_mode='valid') 148 | 149 | branch3x3dbl = conv2d_bn(x, 64, 1, 1) 150 | branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3) 151 | branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3, 152 | subsample=(2, 2), border_mode='valid') 153 | 154 | branch_pool = MaxPooling2D((3, 3), strides=(2, 2))(x) 155 | x = merge([branch3x3, branch3x3dbl, branch_pool], 156 | mode='concat', concat_axis=channel_axis, 157 | name='mixed3') 158 | 159 | # mixed 4: 17 x 17 x 768 160 | branch1x1 = conv2d_bn(x, 192, 1, 1) 161 | 162 | branch7x7 = conv2d_bn(x, 128, 1, 1) 163 | branch7x7 = conv2d_bn(branch7x7, 128, 1, 7) 164 | branch7x7 = conv2d_bn(branch7x7, 192, 7, 1) 165 | 166 | branch7x7dbl = conv2d_bn(x, 128, 1, 1) 167 | branch7x7dbl = conv2d_bn(branch7x7dbl, 128, 7, 1) 168 | branch7x7dbl = conv2d_bn(branch7x7dbl, 128, 1, 7) 169 | branch7x7dbl = conv2d_bn(branch7x7dbl, 128, 7, 1) 170 | branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7) 171 | 172 | branch_pool = AveragePooling2D((3, 3), strides=(1, 1), border_mode='same')(x) 173 | branch_pool = conv2d_bn(branch_pool, 192, 1, 1) 174 | x = merge([branch1x1, branch7x7, branch7x7dbl, branch_pool], 175 | mode='concat', concat_axis=channel_axis, 176 | name='mixed4') 177 | 178 | # mixed 5, 6: 17 x 17 x 768 179 | for i in range(2): 180 | branch1x1 = conv2d_bn(x, 192, 1, 1) 181 | 182 | branch7x7 = conv2d_bn(x, 160, 1, 1) 183 | branch7x7 = conv2d_bn(branch7x7, 160, 1, 7) 184 | branch7x7 = conv2d_bn(branch7x7, 192, 7, 1) 185 | 186 | branch7x7dbl = conv2d_bn(x, 160, 1, 1) 187 | branch7x7dbl = conv2d_bn(branch7x7dbl, 160, 7, 1) 188 | branch7x7dbl = conv2d_bn(branch7x7dbl, 160, 1, 7) 189 | branch7x7dbl = conv2d_bn(branch7x7dbl, 160, 7, 1) 190 | branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7) 191 | 192 | branch_pool = AveragePooling2D( 193 | (3, 3), strides=(1, 1), border_mode='same')(x) 194 | branch_pool = conv2d_bn(branch_pool, 192, 1, 1) 195 | x = merge([branch1x1, branch7x7, branch7x7dbl, branch_pool], 196 | mode='concat', concat_axis=channel_axis, 197 | name='mixed' + str(5 + i)) 198 | 199 | # mixed 7: 17 x 17 x 768 200 | branch1x1 = conv2d_bn(x, 192, 1, 1) 201 | 202 | branch7x7 = conv2d_bn(x, 192, 1, 1) 203 | branch7x7 = conv2d_bn(branch7x7, 192, 1, 7) 204 | branch7x7 = conv2d_bn(branch7x7, 192, 7, 1) 205 | 206 | branch7x7dbl = conv2d_bn(x, 160, 1, 1) 207 | branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 7, 1) 208 | branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7) 209 | branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 7, 1) 210 | branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7) 211 | 212 | branch_pool = AveragePooling2D((3, 3), strides=(1, 1), border_mode='same')(x) 213 | branch_pool = conv2d_bn(branch_pool, 192, 1, 1) 214 | x = merge([branch1x1, branch7x7, branch7x7dbl, branch_pool], 215 | mode='concat', concat_axis=channel_axis, 216 | name='mixed7') 217 | 218 | # mixed 8: 8 x 8 x 1280 219 | branch3x3 = conv2d_bn(x, 192, 1, 1) 220 | branch3x3 = conv2d_bn(branch3x3, 320, 3, 3, 221 | subsample=(2, 2), border_mode='valid') 222 | 223 | branch7x7x3 = conv2d_bn(x, 192, 1, 1) 224 | branch7x7x3 = conv2d_bn(branch7x7x3, 192, 1, 7) 225 | branch7x7x3 = conv2d_bn(branch7x7x3, 192, 7, 1) 226 | branch7x7x3 = conv2d_bn(branch7x7x3, 192, 3, 3, 227 | subsample=(2, 2), border_mode='valid') 228 | 229 | branch_pool = AveragePooling2D((3, 3), strides=(2, 2))(x) 230 | x = merge([branch3x3, branch7x7x3, branch_pool], 231 | mode='concat', concat_axis=channel_axis, 232 | name='mixed8') 233 | 234 | # mixed 9: 8 x 8 x 2048 235 | for i in range(2): 236 | branch1x1 = conv2d_bn(x, 320, 1, 1) 237 | 238 | branch3x3 = conv2d_bn(x, 384, 1, 1) 239 | branch3x3_1 = conv2d_bn(branch3x3, 384, 1, 3) 240 | branch3x3_2 = conv2d_bn(branch3x3, 384, 3, 1) 241 | branch3x3 = merge([branch3x3_1, branch3x3_2], 242 | mode='concat', concat_axis=channel_axis, 243 | name='mixed9_' + str(i)) 244 | 245 | branch3x3dbl = conv2d_bn(x, 448, 1, 1) 246 | branch3x3dbl = conv2d_bn(branch3x3dbl, 384, 3, 3) 247 | branch3x3dbl_1 = conv2d_bn(branch3x3dbl, 384, 1, 3) 248 | branch3x3dbl_2 = conv2d_bn(branch3x3dbl, 384, 3, 1) 249 | branch3x3dbl = merge([branch3x3dbl_1, branch3x3dbl_2], 250 | mode='concat', concat_axis=channel_axis) 251 | 252 | branch_pool = AveragePooling2D( 253 | (3, 3), strides=(1, 1), border_mode='same')(x) 254 | branch_pool = conv2d_bn(branch_pool, 192, 1, 1) 255 | x = merge([branch1x1, branch3x3, branch3x3dbl, branch_pool], 256 | mode='concat', concat_axis=channel_axis, 257 | name='mixed' + str(9 + i)) 258 | 259 | if include_top: 260 | # Classification block 261 | x = AveragePooling2D((8, 8), strides=(8, 8), name='avg_pool')(x) 262 | x = Flatten(name='flatten')(x) 263 | x = Dense(1000, activation='softmax', name='predictions')(x) 264 | 265 | # Create model 266 | model = Model(img_input, x) 267 | 268 | # load weights 269 | if weights == 'imagenet': 270 | if K.image_dim_ordering() == 'th': 271 | if include_top: 272 | weights_path = get_file('inception_v3_weights_th_dim_ordering_th_kernels.h5', 273 | TH_WEIGHTS_PATH, 274 | cache_subdir='models', 275 | md5_hash='b3baf3070cc4bf476d43a2ea61b0ca5f') 276 | else: 277 | weights_path = get_file('inception_v3_weights_th_dim_ordering_th_kernels_notop.h5', 278 | TH_WEIGHTS_PATH_NO_TOP, 279 | cache_subdir='models', 280 | md5_hash='79aaa90ab4372b4593ba3df64e142f05') 281 | model.load_weights(weights_path) 282 | if K.backend() == 'tensorflow': 283 | warnings.warn('You are using the TensorFlow backend, yet you ' 284 | 'are using the Theano ' 285 | 'image dimension ordering convention ' 286 | '(`image_dim_ordering="th"`). ' 287 | 'For best performance, set ' 288 | '`image_dim_ordering="tf"` in ' 289 | 'your Keras config ' 290 | 'at ~/.keras/keras.json.') 291 | convert_all_kernels_in_model(model) 292 | else: 293 | if include_top: 294 | weights_path = get_file('inception_v3_weights_tf_dim_ordering_tf_kernels.h5', 295 | TF_WEIGHTS_PATH, 296 | cache_subdir='models', 297 | md5_hash='fe114b3ff2ea4bf891e9353d1bbfb32f') 298 | else: 299 | weights_path = get_file('inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5', 300 | TF_WEIGHTS_PATH_NO_TOP, 301 | cache_subdir='models', 302 | md5_hash='2f3609166de1d967d1a481094754f691') 303 | model.load_weights(weights_path) 304 | if K.backend() == 'theano': 305 | convert_all_kernels_in_model(model) 306 | return model 307 | 308 | 309 | def preprocess_input(x): 310 | x /= 255. 311 | x -= 0.5 312 | x *= 2. 313 | return x 314 | 315 | 316 | if __name__ == '__main__': 317 | model = InceptionV3(include_top=True, weights='imagenet') 318 | 319 | img_path = 'elephant.jpg' 320 | img = image.load_img(img_path, target_size=(299, 299)) 321 | x = image.img_to_array(img) 322 | x = np.expand_dims(x, axis=0) 323 | 324 | x = preprocess_input(x) 325 | 326 | preds = model.predict(x) 327 | print('Predicted:', decode_predictions(preds)) 328 | --------------------------------------------------------------------------------