Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

📚 The CoCalc Library - books, templates and other resources

132928 views
License: OTHER
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
25
26
TH_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/resnet50_weights_th_dim_ordering_th_kernels.h5'
27
TF_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/resnet50_weights_tf_dim_ordering_tf_kernels.h5'
28
TH_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/resnet50_weights_th_dim_ordering_th_kernels_notop.h5'
29
TF_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5'
30
31
32
def identity_block(input_tensor, kernel_size, filters, stage, block):
33
'''The identity_block is the block that has no conv layer at shortcut
34
35
# Arguments
36
input_tensor: input tensor
37
kernel_size: defualt 3, the kernel size of middle conv layer at main path
38
filters: list of integers, the nb_filters of 3 conv layer at main path
39
stage: integer, current stage label, used for generating layer names
40
block: 'a','b'..., current block label, used for generating layer names
41
'''
42
nb_filter1, nb_filter2, nb_filter3 = filters
43
if K.image_dim_ordering() == 'tf':
44
bn_axis = 3
45
else:
46
bn_axis = 1
47
conv_name_base = 'res' + str(stage) + block + '_branch'
48
bn_name_base = 'bn' + str(stage) + block + '_branch'
49
50
x = Convolution2D(nb_filter1, 1, 1, name=conv_name_base + '2a')(input_tensor)
51
x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)
52
x = Activation('relu')(x)
53
54
x = Convolution2D(nb_filter2, kernel_size, kernel_size,
55
border_mode='same', name=conv_name_base + '2b')(x)
56
x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)
57
x = Activation('relu')(x)
58
59
x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)
60
x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)
61
62
x = merge([x, input_tensor], mode='sum')
63
x = Activation('relu')(x)
64
return x
65
66
67
def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2)):
68
'''conv_block is the block that has a conv layer at shortcut
69
70
# Arguments
71
input_tensor: input tensor
72
kernel_size: defualt 3, the kernel size of middle conv layer at main path
73
filters: list of integers, the nb_filters of 3 conv layer at main path
74
stage: integer, current stage label, used for generating layer names
75
block: 'a','b'..., current block label, used for generating layer names
76
77
Note that from stage 3, the first conv layer at main path is with subsample=(2,2)
78
And the shortcut should have subsample=(2,2) as well
79
'''
80
nb_filter1, nb_filter2, nb_filter3 = filters
81
if K.image_dim_ordering() == 'tf':
82
bn_axis = 3
83
else:
84
bn_axis = 1
85
conv_name_base = 'res' + str(stage) + block + '_branch'
86
bn_name_base = 'bn' + str(stage) + block + '_branch'
87
88
x = Convolution2D(nb_filter1, 1, 1, subsample=strides,
89
name=conv_name_base + '2a')(input_tensor)
90
x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)
91
x = Activation('relu')(x)
92
93
x = Convolution2D(nb_filter2, kernel_size, kernel_size, border_mode='same',
94
name=conv_name_base + '2b')(x)
95
x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)
96
x = Activation('relu')(x)
97
98
x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)
99
x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)
100
101
shortcut = Convolution2D(nb_filter3, 1, 1, subsample=strides,
102
name=conv_name_base + '1')(input_tensor)
103
shortcut = BatchNormalization(axis=bn_axis, name=bn_name_base + '1')(shortcut)
104
105
x = merge([x, shortcut], mode='sum')
106
x = Activation('relu')(x)
107
return x
108
109
110
def ResNet50(include_top=True, weights='imagenet',
111
input_tensor=None):
112
'''Instantiate the ResNet50 architecture,
113
optionally loading weights pre-trained
114
on ImageNet. Note that when using TensorFlow,
115
for best performance you should set
116
`image_dim_ordering="tf"` in your Keras config
117
at ~/.keras/keras.json.
118
119
The model and the weights are compatible with both
120
TensorFlow and Theano. The dimension ordering
121
convention used by the model is the one
122
specified in your Keras config file.
123
124
# Arguments
125
include_top: whether to include the 3 fully-connected
126
layers at the top of the network.
127
weights: one of `None` (random initialization)
128
or "imagenet" (pre-training on ImageNet).
129
input_tensor: optional Keras tensor (i.e. xput of `layers.Input()`)
130
to use as image input for the model.
131
132
# Returns
133
A Keras model instance.
134
'''
135
if weights not in {'imagenet', None}:
136
raise ValueError('The `weights` argument should be either '
137
'`None` (random initialization) or `imagenet` '
138
'(pre-training on ImageNet).')
139
# Determine proper input shape
140
if K.image_dim_ordering() == 'th':
141
if include_top:
142
input_shape = (3, 224, 224)
143
else:
144
input_shape = (3, None, None)
145
else:
146
if include_top:
147
input_shape = (224, 224, 3)
148
else:
149
input_shape = (None, None, 3)
150
151
if input_tensor is None:
152
img_input = Input(shape=input_shape)
153
else:
154
if not K.is_keras_tensor(input_tensor):
155
img_input = Input(tensor=input_tensor)
156
else:
157
img_input = input_tensor
158
if K.image_dim_ordering() == 'tf':
159
bn_axis = 3
160
else:
161
bn_axis = 1
162
163
x = ZeroPadding2D((3, 3))(img_input)
164
x = Convolution2D(64, 7, 7, subsample=(2, 2), name='conv1')(x)
165
x = BatchNormalization(axis=bn_axis, name='bn_conv1')(x)
166
x = Activation('relu')(x)
167
x = MaxPooling2D((3, 3), strides=(2, 2))(x)
168
169
x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1))
170
x = identity_block(x, 3, [64, 64, 256], stage=2, block='b')
171
x = identity_block(x, 3, [64, 64, 256], stage=2, block='c')
172
173
x = conv_block(x, 3, [128, 128, 512], stage=3, block='a')
174
x = identity_block(x, 3, [128, 128, 512], stage=3, block='b')
175
x = identity_block(x, 3, [128, 128, 512], stage=3, block='c')
176
x = identity_block(x, 3, [128, 128, 512], stage=3, block='d')
177
178
x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a')
179
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b')
180
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c')
181
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d')
182
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e')
183
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='f')
184
185
x = conv_block(x, 3, [512, 512, 2048], stage=5, block='a')
186
x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b')
187
x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c')
188
189
x = AveragePooling2D((7, 7), name='avg_pool')(x)
190
191
if include_top:
192
x = Flatten()(x)
193
x = Dense(1000, activation='softmax', name='fc1000')(x)
194
195
model = Model(img_input, x)
196
197
# load weights
198
if weights == 'imagenet':
199
print('K.image_dim_ordering:', K.image_dim_ordering())
200
if K.image_dim_ordering() == 'th':
201
if include_top:
202
weights_path = get_file('resnet50_weights_th_dim_ordering_th_kernels.h5',
203
TH_WEIGHTS_PATH,
204
cache_subdir='models')
205
else:
206
weights_path = get_file('resnet50_weights_th_dim_ordering_th_kernels_notop.h5',
207
TH_WEIGHTS_PATH_NO_TOP,
208
cache_subdir='models')
209
model.load_weights(weights_path)
210
if K.backend() == 'tensorflow':
211
warnings.warn('You are using the TensorFlow backend, yet you '
212
'are using the Theano '
213
'image dimension ordering convention '
214
'(`image_dim_ordering="th"`). '
215
'For best performance, set '
216
'`image_dim_ordering="tf"` in '
217
'your Keras config '
218
'at ~/.keras/keras.json.')
219
convert_all_kernels_in_model(model)
220
else:
221
if include_top:
222
weights_path = get_file('resnet50_weights_tf_dim_ordering_tf_kernels.h5',
223
TF_WEIGHTS_PATH,
224
cache_subdir='models')
225
else:
226
weights_path = get_file('resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5',
227
TF_WEIGHTS_PATH_NO_TOP,
228
cache_subdir='models')
229
model.load_weights(weights_path)
230
if K.backend() == 'theano':
231
convert_all_kernels_in_model(model)
232
return model
233
234
235
if __name__ == '__main__':
236
model = ResNet50(include_top=True, weights='imagenet')
237
238
img_path = 'elephant.jpg'
239
img = image.load_img(img_path, target_size=(224, 224))
240
x = image.img_to_array(img)
241
x = np.expand_dims(x, axis=0)
242
x = preprocess_input(x)
243
print('Input image shape:', x.shape)
244
245
preds = model.predict(x)
246
print('Predicted:', decode_predictions(preds))
247
248