📚 The CoCalc Library - books, templates and other resources
cocalc-examples / data-science-ipython-notebooks / deep-learning / keras-tutorial / deep_learning_models / resnet50.py
132928 viewsLicense: OTHER
# -*- coding: utf-8 -*-1'''ResNet50 model for Keras.23# Reference:45- [Deep Residual Learning for Image Recognition](https://arxiv.org/abs/1512.03385)67Adapted from code contributed by BigMoyan.8'''9from __future__ import print_function1011import numpy as np12import warnings1314from keras.layers import merge, Input15from keras.layers import Dense, Activation, Flatten16from keras.layers import Convolution2D, MaxPooling2D, ZeroPadding2D, AveragePooling2D17from keras.layers import BatchNormalization18from keras.models import Model19from keras.preprocessing import image20import keras.backend as K21from keras.utils.layer_utils import convert_all_kernels_in_model22from keras.utils.data_utils import get_file232425TH_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/resnet50_weights_th_dim_ordering_th_kernels.h5'26TF_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/resnet50_weights_tf_dim_ordering_tf_kernels.h5'27TH_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/resnet50_weights_th_dim_ordering_th_kernels_notop.h5'28TF_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5'293031def identity_block(input_tensor, kernel_size, filters, stage, block):32'''The identity_block is the block that has no conv layer at shortcut3334# Arguments35input_tensor: input tensor36kernel_size: defualt 3, the kernel size of middle conv layer at main path37filters: list of integers, the nb_filters of 3 conv layer at main path38stage: integer, current stage label, used for generating layer names39block: 'a','b'..., current block label, used for generating layer names40'''41nb_filter1, nb_filter2, nb_filter3 = filters42if K.image_dim_ordering() == 'tf':43bn_axis = 344else:45bn_axis = 146conv_name_base = 'res' + str(stage) + block + '_branch'47bn_name_base = 'bn' + str(stage) + block + '_branch'4849x = Convolution2D(nb_filter1, 1, 1, name=conv_name_base + '2a')(input_tensor)50x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)51x = Activation('relu')(x)5253x = Convolution2D(nb_filter2, kernel_size, kernel_size,54border_mode='same', name=conv_name_base + '2b')(x)55x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)56x = Activation('relu')(x)5758x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)59x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)6061x = merge([x, input_tensor], mode='sum')62x = Activation('relu')(x)63return x646566def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2)):67'''conv_block is the block that has a conv layer at shortcut6869# Arguments70input_tensor: input tensor71kernel_size: defualt 3, the kernel size of middle conv layer at main path72filters: list of integers, the nb_filters of 3 conv layer at main path73stage: integer, current stage label, used for generating layer names74block: 'a','b'..., current block label, used for generating layer names7576Note that from stage 3, the first conv layer at main path is with subsample=(2,2)77And the shortcut should have subsample=(2,2) as well78'''79nb_filter1, nb_filter2, nb_filter3 = filters80if K.image_dim_ordering() == 'tf':81bn_axis = 382else:83bn_axis = 184conv_name_base = 'res' + str(stage) + block + '_branch'85bn_name_base = 'bn' + str(stage) + block + '_branch'8687x = Convolution2D(nb_filter1, 1, 1, subsample=strides,88name=conv_name_base + '2a')(input_tensor)89x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)90x = Activation('relu')(x)9192x = Convolution2D(nb_filter2, kernel_size, kernel_size, border_mode='same',93name=conv_name_base + '2b')(x)94x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)95x = Activation('relu')(x)9697x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)98x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)99100shortcut = Convolution2D(nb_filter3, 1, 1, subsample=strides,101name=conv_name_base + '1')(input_tensor)102shortcut = BatchNormalization(axis=bn_axis, name=bn_name_base + '1')(shortcut)103104x = merge([x, shortcut], mode='sum')105x = Activation('relu')(x)106return x107108109def ResNet50(include_top=True, weights='imagenet',110input_tensor=None):111'''Instantiate the ResNet50 architecture,112optionally loading weights pre-trained113on ImageNet. Note that when using TensorFlow,114for best performance you should set115`image_dim_ordering="tf"` in your Keras config116at ~/.keras/keras.json.117118The model and the weights are compatible with both119TensorFlow and Theano. The dimension ordering120convention used by the model is the one121specified in your Keras config file.122123# Arguments124include_top: whether to include the 3 fully-connected125layers at the top of the network.126weights: one of `None` (random initialization)127or "imagenet" (pre-training on ImageNet).128input_tensor: optional Keras tensor (i.e. xput of `layers.Input()`)129to use as image input for the model.130131# Returns132A Keras model instance.133'''134if weights not in {'imagenet', None}:135raise ValueError('The `weights` argument should be either '136'`None` (random initialization) or `imagenet` '137'(pre-training on ImageNet).')138# Determine proper input shape139if K.image_dim_ordering() == 'th':140if include_top:141input_shape = (3, 224, 224)142else:143input_shape = (3, None, None)144else:145if include_top:146input_shape = (224, 224, 3)147else:148input_shape = (None, None, 3)149150if input_tensor is None:151img_input = Input(shape=input_shape)152else:153if not K.is_keras_tensor(input_tensor):154img_input = Input(tensor=input_tensor)155else:156img_input = input_tensor157if K.image_dim_ordering() == 'tf':158bn_axis = 3159else:160bn_axis = 1161162x = ZeroPadding2D((3, 3))(img_input)163x = Convolution2D(64, 7, 7, subsample=(2, 2), name='conv1')(x)164x = BatchNormalization(axis=bn_axis, name='bn_conv1')(x)165x = Activation('relu')(x)166x = MaxPooling2D((3, 3), strides=(2, 2))(x)167168x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1))169x = identity_block(x, 3, [64, 64, 256], stage=2, block='b')170x = identity_block(x, 3, [64, 64, 256], stage=2, block='c')171172x = conv_block(x, 3, [128, 128, 512], stage=3, block='a')173x = identity_block(x, 3, [128, 128, 512], stage=3, block='b')174x = identity_block(x, 3, [128, 128, 512], stage=3, block='c')175x = identity_block(x, 3, [128, 128, 512], stage=3, block='d')176177x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a')178x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b')179x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c')180x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d')181x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e')182x = identity_block(x, 3, [256, 256, 1024], stage=4, block='f')183184x = conv_block(x, 3, [512, 512, 2048], stage=5, block='a')185x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b')186x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c')187188x = AveragePooling2D((7, 7), name='avg_pool')(x)189190if include_top:191x = Flatten()(x)192x = Dense(1000, activation='softmax', name='fc1000')(x)193194model = Model(img_input, x)195196# load weights197if weights == 'imagenet':198print('K.image_dim_ordering:', K.image_dim_ordering())199if K.image_dim_ordering() == 'th':200if include_top:201weights_path = get_file('resnet50_weights_th_dim_ordering_th_kernels.h5',202TH_WEIGHTS_PATH,203cache_subdir='models')204else:205weights_path = get_file('resnet50_weights_th_dim_ordering_th_kernels_notop.h5',206TH_WEIGHTS_PATH_NO_TOP,207cache_subdir='models')208model.load_weights(weights_path)209if K.backend() == 'tensorflow':210warnings.warn('You are using the TensorFlow backend, yet you '211'are using the Theano '212'image dimension ordering convention '213'(`image_dim_ordering="th"`). '214'For best performance, set '215'`image_dim_ordering="tf"` in '216'your Keras config '217'at ~/.keras/keras.json.')218convert_all_kernels_in_model(model)219else:220if include_top:221weights_path = get_file('resnet50_weights_tf_dim_ordering_tf_kernels.h5',222TF_WEIGHTS_PATH,223cache_subdir='models')224else:225weights_path = get_file('resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5',226TF_WEIGHTS_PATH_NO_TOP,227cache_subdir='models')228model.load_weights(weights_path)229if K.backend() == 'theano':230convert_all_kernels_in_model(model)231return model232233234if __name__ == '__main__':235model = ResNet50(include_top=True, weights='imagenet')236237img_path = 'elephant.jpg'238img = image.load_img(img_path, target_size=(224, 224))239x = image.img_to_array(img)240x = np.expand_dims(x, axis=0)241x = preprocess_input(x)242print('Input image shape:', x.shape)243244preds = model.predict(x)245print('Predicted:', decode_predictions(preds))246247248