amish1729 commited on
Commit
4d9e196
·
1 Parent(s): f28c826

Upload 4 files

Browse files
keras_vggface/models.py ADDED
@@ -0,0 +1,516 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ '''VGGFace models for Keras.
2
+
3
+ # Notes:
4
+ - Resnet50 and VGG16 are modified architectures from Keras Application folder. [Keras](https://keras.io)
5
+
6
+ - Squeeze and excitation block is taken from [Squeeze and Excitation Networks in
7
+ Keras](https://github.com/titu1994/keras-squeeze-excite-network) and modified.
8
+
9
+ '''
10
+
11
+
12
+ from keras.layers import Flatten, Dense, Input, GlobalAveragePooling2D, \
13
+ GlobalMaxPooling2D, Activation, Conv2D, MaxPooling2D, BatchNormalization, \
14
+ AveragePooling2D, Reshape, Permute, multiply
15
+ from keras_applications.imagenet_utils import _obtain_input_shape
16
+ from keras.utils import layer_utils
17
+ from keras.utils.data_utils import get_file
18
+ from keras import backend as K
19
+ from keras_vggface import utils
20
+ from keras.utils.layer_utils import get_source_inputs
21
+ import warnings
22
+ from keras.models import Model
23
+ from keras import layers
24
+
25
+
26
+ def VGG16(include_top=True, weights='vggface',
27
+ input_tensor=None, input_shape=None,
28
+ pooling=None,
29
+ classes=2622):
30
+ input_shape = _obtain_input_shape(input_shape,
31
+ default_size=224,
32
+ min_size=48,
33
+ data_format=K.image_data_format(),
34
+ require_flatten=include_top)
35
+
36
+ if input_tensor is None:
37
+ img_input = Input(shape=input_shape)
38
+ else:
39
+ if not K.is_keras_tensor(input_tensor):
40
+ img_input = Input(tensor=input_tensor, shape=input_shape)
41
+ else:
42
+ img_input = input_tensor
43
+
44
+ # Block 1
45
+ x = Conv2D(64, (3, 3), activation='relu', padding='same', name='conv1_1')(
46
+ img_input)
47
+ x = Conv2D(64, (3, 3), activation='relu', padding='same', name='conv1_2')(x)
48
+ x = MaxPooling2D((2, 2), strides=(2, 2), name='pool1')(x)
49
+
50
+ # Block 2
51
+ x = Conv2D(128, (3, 3), activation='relu', padding='same', name='conv2_1')(
52
+ x)
53
+ x = Conv2D(128, (3, 3), activation='relu', padding='same', name='conv2_2')(
54
+ x)
55
+ x = MaxPooling2D((2, 2), strides=(2, 2), name='pool2')(x)
56
+
57
+ # Block 3
58
+ x = Conv2D(256, (3, 3), activation='relu', padding='same', name='conv3_1')(
59
+ x)
60
+ x = Conv2D(256, (3, 3), activation='relu', padding='same', name='conv3_2')(
61
+ x)
62
+ x = Conv2D(256, (3, 3), activation='relu', padding='same', name='conv3_3')(
63
+ x)
64
+ x = MaxPooling2D((2, 2), strides=(2, 2), name='pool3')(x)
65
+
66
+ # Block 4
67
+ x = Conv2D(512, (3, 3), activation='relu', padding='same', name='conv4_1')(
68
+ x)
69
+ x = Conv2D(512, (3, 3), activation='relu', padding='same', name='conv4_2')(
70
+ x)
71
+ x = Conv2D(512, (3, 3), activation='relu', padding='same', name='conv4_3')(
72
+ x)
73
+ x = MaxPooling2D((2, 2), strides=(2, 2), name='pool4')(x)
74
+
75
+ # Block 5
76
+ x = Conv2D(512, (3, 3), activation='relu', padding='same', name='conv5_1')(
77
+ x)
78
+ x = Conv2D(512, (3, 3), activation='relu', padding='same', name='conv5_2')(
79
+ x)
80
+ x = Conv2D(512, (3, 3), activation='relu', padding='same', name='conv5_3')(
81
+ x)
82
+ x = MaxPooling2D((2, 2), strides=(2, 2), name='pool5')(x)
83
+
84
+ if include_top:
85
+ # Classification block
86
+ x = Flatten(name='flatten')(x)
87
+ x = Dense(4096, name='fc6')(x)
88
+ x = Activation('relu', name='fc6/relu')(x)
89
+ x = Dense(4096, name='fc7')(x)
90
+ x = Activation('relu', name='fc7/relu')(x)
91
+ x = Dense(classes, name='fc8')(x)
92
+ x = Activation('softmax', name='fc8/softmax')(x)
93
+ else:
94
+ if pooling == 'avg':
95
+ x = GlobalAveragePooling2D()(x)
96
+ elif pooling == 'max':
97
+ x = GlobalMaxPooling2D()(x)
98
+
99
+ # Ensure that the model takes into account
100
+ # any potential predecessors of `input_tensor`.
101
+ if input_tensor is not None:
102
+ inputs = get_source_inputs(input_tensor)
103
+ else:
104
+ inputs = img_input
105
+ # Create model.
106
+ model = Model(inputs, x, name='vggface_vgg16') # load weights
107
+ if weights == 'vggface':
108
+ if include_top:
109
+ weights_path = get_file('rcmalli_vggface_tf_vgg16.h5',
110
+ utils.
111
+ VGG16_WEIGHTS_PATH,
112
+ cache_subdir=utils.VGGFACE_DIR)
113
+ else:
114
+ weights_path = get_file('rcmalli_vggface_tf_notop_vgg16.h5',
115
+ utils.VGG16_WEIGHTS_PATH_NO_TOP,
116
+ cache_subdir=utils.VGGFACE_DIR)
117
+ model.load_weights(weights_path, by_name=True)
118
+ if K.backend() == 'theano':
119
+ layer_utils.convert_all_kernels_in_model(model)
120
+
121
+ if K.image_data_format() == 'channels_first':
122
+ if include_top:
123
+ maxpool = model.get_layer(name='pool5')
124
+ shape = maxpool.output_shape[1:]
125
+ dense = model.get_layer(name='fc6')
126
+ layer_utils.convert_dense_weights_data_format(dense, shape,
127
+ 'channels_first')
128
+
129
+ if K.backend() == 'tensorflow':
130
+ warnings.warn('You are using the TensorFlow backend, yet you '
131
+ 'are using the Theano '
132
+ 'image data format convention '
133
+ '(`image_data_format="channels_first"`). '
134
+ 'For best performance, set '
135
+ '`image_data_format="channels_last"` in '
136
+ 'your Keras config '
137
+ 'at ~/.keras/keras.json.')
138
+ return model
139
+
140
+
141
+ def resnet_identity_block(input_tensor, kernel_size, filters, stage, block,
142
+ bias=False):
143
+ filters1, filters2, filters3 = filters
144
+ if K.image_data_format() == 'channels_last':
145
+ bn_axis = 3
146
+ else:
147
+ bn_axis = 1
148
+ conv1_reduce_name = 'conv' + str(stage) + "_" + str(block) + "_1x1_reduce"
149
+ conv1_increase_name = 'conv' + str(stage) + "_" + str(
150
+ block) + "_1x1_increase"
151
+ conv3_name = 'conv' + str(stage) + "_" + str(block) + "_3x3"
152
+
153
+ x = Conv2D(filters1, (1, 1), use_bias=bias, name=conv1_reduce_name)(
154
+ input_tensor)
155
+ x = BatchNormalization(axis=bn_axis, name=conv1_reduce_name + "/bn")(x)
156
+ x = Activation('relu')(x)
157
+
158
+ x = Conv2D(filters2, kernel_size, use_bias=bias,
159
+ padding='same', name=conv3_name)(x)
160
+ x = BatchNormalization(axis=bn_axis, name=conv3_name + "/bn")(x)
161
+ x = Activation('relu')(x)
162
+
163
+ x = Conv2D(filters3, (1, 1), use_bias=bias, name=conv1_increase_name)(x)
164
+ x = BatchNormalization(axis=bn_axis, name=conv1_increase_name + "/bn")(x)
165
+
166
+ x = layers.add([x, input_tensor])
167
+ x = Activation('relu')(x)
168
+ return x
169
+
170
+
171
+ def resnet_conv_block(input_tensor, kernel_size, filters, stage, block,
172
+ strides=(2, 2), bias=False):
173
+ filters1, filters2, filters3 = filters
174
+ if K.image_data_format() == 'channels_last':
175
+ bn_axis = 3
176
+ else:
177
+ bn_axis = 1
178
+ conv1_reduce_name = 'conv' + str(stage) + "_" + str(block) + "_1x1_reduce"
179
+ conv1_increase_name = 'conv' + str(stage) + "_" + str(
180
+ block) + "_1x1_increase"
181
+ conv1_proj_name = 'conv' + str(stage) + "_" + str(block) + "_1x1_proj"
182
+ conv3_name = 'conv' + str(stage) + "_" + str(block) + "_3x3"
183
+
184
+ x = Conv2D(filters1, (1, 1), strides=strides, use_bias=bias,
185
+ name=conv1_reduce_name)(input_tensor)
186
+ x = BatchNormalization(axis=bn_axis, name=conv1_reduce_name + "/bn")(x)
187
+ x = Activation('relu')(x)
188
+
189
+ x = Conv2D(filters2, kernel_size, padding='same', use_bias=bias,
190
+ name=conv3_name)(x)
191
+ x = BatchNormalization(axis=bn_axis, name=conv3_name + "/bn")(x)
192
+ x = Activation('relu')(x)
193
+
194
+ x = Conv2D(filters3, (1, 1), name=conv1_increase_name, use_bias=bias)(x)
195
+ x = BatchNormalization(axis=bn_axis, name=conv1_increase_name + "/bn")(x)
196
+
197
+ shortcut = Conv2D(filters3, (1, 1), strides=strides, use_bias=bias,
198
+ name=conv1_proj_name)(input_tensor)
199
+ shortcut = BatchNormalization(axis=bn_axis, name=conv1_proj_name + "/bn")(
200
+ shortcut)
201
+
202
+ x = layers.add([x, shortcut])
203
+ x = Activation('relu')(x)
204
+ return x
205
+
206
+
207
+ def RESNET50(include_top=True, weights='vggface',
208
+ input_tensor=None, input_shape=None,
209
+ pooling=None,
210
+ classes=8631):
211
+ input_shape = _obtain_input_shape(input_shape,
212
+ default_size=224,
213
+ min_size=32,
214
+ data_format=K.image_data_format(),
215
+ require_flatten=include_top,
216
+ weights=weights)
217
+
218
+ if input_tensor is None:
219
+ img_input = Input(shape=input_shape)
220
+ else:
221
+ if not K.is_keras_tensor(input_tensor):
222
+ img_input = Input(tensor=input_tensor, shape=input_shape)
223
+ else:
224
+ img_input = input_tensor
225
+ if K.image_data_format() == 'channels_last':
226
+ bn_axis = 3
227
+ else:
228
+ bn_axis = 1
229
+
230
+ x = Conv2D(
231
+ 64, (7, 7), use_bias=False, strides=(2, 2), padding='same',
232
+ name='conv1/7x7_s2')(img_input)
233
+ x = BatchNormalization(axis=bn_axis, name='conv1/7x7_s2/bn')(x)
234
+ x = Activation('relu')(x)
235
+ x = MaxPooling2D((3, 3), strides=(2, 2))(x)
236
+
237
+ x = resnet_conv_block(x, 3, [64, 64, 256], stage=2, block=1, strides=(1, 1))
238
+ x = resnet_identity_block(x, 3, [64, 64, 256], stage=2, block=2)
239
+ x = resnet_identity_block(x, 3, [64, 64, 256], stage=2, block=3)
240
+
241
+ x = resnet_conv_block(x, 3, [128, 128, 512], stage=3, block=1)
242
+ x = resnet_identity_block(x, 3, [128, 128, 512], stage=3, block=2)
243
+ x = resnet_identity_block(x, 3, [128, 128, 512], stage=3, block=3)
244
+ x = resnet_identity_block(x, 3, [128, 128, 512], stage=3, block=4)
245
+
246
+ x = resnet_conv_block(x, 3, [256, 256, 1024], stage=4, block=1)
247
+ x = resnet_identity_block(x, 3, [256, 256, 1024], stage=4, block=2)
248
+ x = resnet_identity_block(x, 3, [256, 256, 1024], stage=4, block=3)
249
+ x = resnet_identity_block(x, 3, [256, 256, 1024], stage=4, block=4)
250
+ x = resnet_identity_block(x, 3, [256, 256, 1024], stage=4, block=5)
251
+ x = resnet_identity_block(x, 3, [256, 256, 1024], stage=4, block=6)
252
+
253
+ x = resnet_conv_block(x, 3, [512, 512, 2048], stage=5, block=1)
254
+ x = resnet_identity_block(x, 3, [512, 512, 2048], stage=5, block=2)
255
+ x = resnet_identity_block(x, 3, [512, 512, 2048], stage=5, block=3)
256
+
257
+ x = AveragePooling2D((7, 7), name='avg_pool')(x)
258
+
259
+ if include_top:
260
+ x = Flatten()(x)
261
+ x = Dense(classes, activation='softmax', name='classifier')(x)
262
+ else:
263
+ if pooling == 'avg':
264
+ x = GlobalAveragePooling2D()(x)
265
+ elif pooling == 'max':
266
+ x = GlobalMaxPooling2D()(x)
267
+
268
+ # Ensure that the model takes into account
269
+ # any potential predecessors of `input_tensor`.
270
+ if input_tensor is not None:
271
+ inputs = get_source_inputs(input_tensor)
272
+ else:
273
+ inputs = img_input
274
+ # Create model.
275
+ model = Model(inputs, x, name='vggface_resnet50')
276
+
277
+ # load weights
278
+ if weights == 'vggface':
279
+ if include_top:
280
+ weights_path = get_file('rcmalli_vggface_tf_resnet50.h5',
281
+ utils.RESNET50_WEIGHTS_PATH,
282
+ cache_subdir=utils.VGGFACE_DIR)
283
+ else:
284
+ weights_path = get_file('rcmalli_vggface_tf_notop_resnet50.h5',
285
+ utils.RESNET50_WEIGHTS_PATH_NO_TOP,
286
+ cache_subdir=utils.VGGFACE_DIR)
287
+ model.load_weights(weights_path)
288
+ if K.backend() == 'theano':
289
+ layer_utils.convert_all_kernels_in_model(model)
290
+ if include_top:
291
+ maxpool = model.get_layer(name='avg_pool')
292
+ shape = maxpool.output_shape[1:]
293
+ dense = model.get_layer(name='classifier')
294
+ layer_utils.convert_dense_weights_data_format(dense, shape,
295
+ 'channels_first')
296
+
297
+ if K.image_data_format() == 'channels_first' and K.backend() == 'tensorflow':
298
+ warnings.warn('You are using the TensorFlow backend, yet you '
299
+ 'are using the Theano '
300
+ 'image data format convention '
301
+ '(`image_data_format="channels_first"`). '
302
+ 'For best performance, set '
303
+ '`image_data_format="channels_last"` in '
304
+ 'your Keras config '
305
+ 'at ~/.keras/keras.json.')
306
+ elif weights is not None:
307
+ model.load_weights(weights)
308
+
309
+ return model
310
+
311
+
312
+ def senet_se_block(input_tensor, stage, block, compress_rate=16, bias=False):
313
+ conv1_down_name = 'conv' + str(stage) + "_" + str(
314
+ block) + "_1x1_down"
315
+ conv1_up_name = 'conv' + str(stage) + "_" + str(
316
+ block) + "_1x1_up"
317
+
318
+ num_channels = int(input_tensor.shape[-1])
319
+ bottle_neck = int(num_channels // compress_rate)
320
+
321
+ se = GlobalAveragePooling2D()(input_tensor)
322
+ se = Reshape((1, 1, num_channels))(se)
323
+ se = Conv2D(bottle_neck, (1, 1), use_bias=bias,
324
+ name=conv1_down_name)(se)
325
+ se = Activation('relu')(se)
326
+ se = Conv2D(num_channels, (1, 1), use_bias=bias,
327
+ name=conv1_up_name)(se)
328
+ se = Activation('sigmoid')(se)
329
+
330
+ x = input_tensor
331
+ x = multiply([x, se])
332
+ return x
333
+
334
+
335
+ def senet_conv_block(input_tensor, kernel_size, filters,
336
+ stage, block, bias=False, strides=(2, 2)):
337
+ filters1, filters2, filters3 = filters
338
+ if K.image_data_format() == 'channels_last':
339
+ bn_axis = 3
340
+ else:
341
+ bn_axis = 1
342
+
343
+ bn_eps = 0.0001
344
+
345
+ conv1_reduce_name = 'conv' + str(stage) + "_" + str(block) + "_1x1_reduce"
346
+ conv1_increase_name = 'conv' + str(stage) + "_" + str(
347
+ block) + "_1x1_increase"
348
+ conv1_proj_name = 'conv' + str(stage) + "_" + str(block) + "_1x1_proj"
349
+ conv3_name = 'conv' + str(stage) + "_" + str(block) + "_3x3"
350
+
351
+ x = Conv2D(filters1, (1, 1), use_bias=bias, strides=strides,
352
+ name=conv1_reduce_name)(input_tensor)
353
+ x = BatchNormalization(axis=bn_axis, name=conv1_reduce_name + "/bn",epsilon=bn_eps)(x)
354
+ x = Activation('relu')(x)
355
+
356
+ x = Conv2D(filters2, kernel_size, padding='same', use_bias=bias,
357
+ name=conv3_name)(x)
358
+ x = BatchNormalization(axis=bn_axis, name=conv3_name + "/bn",epsilon=bn_eps)(x)
359
+ x = Activation('relu')(x)
360
+
361
+ x = Conv2D(filters3, (1, 1), name=conv1_increase_name, use_bias=bias)(x)
362
+ x = BatchNormalization(axis=bn_axis, name=conv1_increase_name + "/bn" ,epsilon=bn_eps)(x)
363
+
364
+ se = senet_se_block(x, stage=stage, block=block, bias=True)
365
+
366
+ shortcut = Conv2D(filters3, (1, 1), use_bias=bias, strides=strides,
367
+ name=conv1_proj_name)(input_tensor)
368
+ shortcut = BatchNormalization(axis=bn_axis,
369
+ name=conv1_proj_name + "/bn",epsilon=bn_eps)(shortcut)
370
+
371
+ m = layers.add([se, shortcut])
372
+ m = Activation('relu')(m)
373
+ return m
374
+
375
+
376
+ def senet_identity_block(input_tensor, kernel_size,
377
+ filters, stage, block, bias=False):
378
+ filters1, filters2, filters3 = filters
379
+ if K.image_data_format() == 'channels_last':
380
+ bn_axis = 3
381
+ else:
382
+ bn_axis = 1
383
+
384
+ bn_eps = 0.0001
385
+
386
+ conv1_reduce_name = 'conv' + str(stage) + "_" + str(block) + "_1x1_reduce"
387
+ conv1_increase_name = 'conv' + str(stage) + "_" + str(
388
+ block) + "_1x1_increase"
389
+ conv3_name = 'conv' + str(stage) + "_" + str(block) + "_3x3"
390
+
391
+ x = Conv2D(filters1, (1, 1), use_bias=bias,
392
+ name=conv1_reduce_name)(input_tensor)
393
+ x = BatchNormalization(axis=bn_axis, name=conv1_reduce_name + "/bn",epsilon=bn_eps)(x)
394
+ x = Activation('relu')(x)
395
+
396
+ x = Conv2D(filters2, kernel_size, padding='same', use_bias=bias,
397
+ name=conv3_name)(x)
398
+ x = BatchNormalization(axis=bn_axis, name=conv3_name + "/bn",epsilon=bn_eps)(x)
399
+ x = Activation('relu')(x)
400
+
401
+ x = Conv2D(filters3, (1, 1), name=conv1_increase_name, use_bias=bias)(x)
402
+ x = BatchNormalization(axis=bn_axis, name=conv1_increase_name + "/bn",epsilon=bn_eps)(x)
403
+
404
+ se = senet_se_block(x, stage=stage, block=block, bias=True)
405
+
406
+ m = layers.add([se, input_tensor])
407
+ m = Activation('relu')(m)
408
+
409
+ return m
410
+
411
+
412
+ def SENET50(include_top=True, weights='vggface',
413
+ input_tensor=None, input_shape=None,
414
+ pooling=None,
415
+ classes=8631):
416
+ input_shape = _obtain_input_shape(input_shape,
417
+ default_size=224,
418
+ min_size=197,
419
+ data_format=K.image_data_format(),
420
+ require_flatten=include_top,
421
+ weights=weights)
422
+
423
+ if input_tensor is None:
424
+ img_input = Input(shape=input_shape)
425
+ else:
426
+ if not K.is_keras_tensor(input_tensor):
427
+ img_input = Input(tensor=input_tensor, shape=input_shape)
428
+ else:
429
+ img_input = input_tensor
430
+ if K.image_data_format() == 'channels_last':
431
+ bn_axis = 3
432
+ else:
433
+ bn_axis = 1
434
+
435
+ bn_eps = 0.0001
436
+
437
+ x = Conv2D(
438
+ 64, (7, 7), use_bias=False, strides=(2, 2), padding='same',
439
+ name='conv1/7x7_s2')(img_input)
440
+ x = BatchNormalization(axis=bn_axis, name='conv1/7x7_s2/bn',epsilon=bn_eps)(x)
441
+ x = Activation('relu')(x)
442
+ x = MaxPooling2D((3, 3), strides=(2, 2))(x)
443
+
444
+ x = senet_conv_block(x, 3, [64, 64, 256], stage=2, block=1, strides=(1, 1))
445
+ x = senet_identity_block(x, 3, [64, 64, 256], stage=2, block=2)
446
+ x = senet_identity_block(x, 3, [64, 64, 256], stage=2, block=3)
447
+
448
+ x = senet_conv_block(x, 3, [128, 128, 512], stage=3, block=1)
449
+ x = senet_identity_block(x, 3, [128, 128, 512], stage=3, block=2)
450
+ x = senet_identity_block(x, 3, [128, 128, 512], stage=3, block=3)
451
+ x = senet_identity_block(x, 3, [128, 128, 512], stage=3, block=4)
452
+
453
+ x = senet_conv_block(x, 3, [256, 256, 1024], stage=4, block=1)
454
+ x = senet_identity_block(x, 3, [256, 256, 1024], stage=4, block=2)
455
+ x = senet_identity_block(x, 3, [256, 256, 1024], stage=4, block=3)
456
+ x = senet_identity_block(x, 3, [256, 256, 1024], stage=4, block=4)
457
+ x = senet_identity_block(x, 3, [256, 256, 1024], stage=4, block=5)
458
+ x = senet_identity_block(x, 3, [256, 256, 1024], stage=4, block=6)
459
+
460
+ x = senet_conv_block(x, 3, [512, 512, 2048], stage=5, block=1)
461
+ x = senet_identity_block(x, 3, [512, 512, 2048], stage=5, block=2)
462
+ x = senet_identity_block(x, 3, [512, 512, 2048], stage=5, block=3)
463
+
464
+ x = AveragePooling2D((7, 7), name='avg_pool')(x)
465
+
466
+ if include_top:
467
+ x = Flatten()(x)
468
+ x = Dense(classes, activation='softmax', name='classifier')(x)
469
+ else:
470
+ if pooling == 'avg':
471
+ x = GlobalAveragePooling2D()(x)
472
+ elif pooling == 'max':
473
+ x = GlobalMaxPooling2D()(x)
474
+
475
+ # Ensure that the model takes into account
476
+ # any potential predecessors of `input_tensor`.
477
+ if input_tensor is not None:
478
+ inputs = get_source_inputs(input_tensor)
479
+ else:
480
+ inputs = img_input
481
+ # Create model.
482
+ model = Model(inputs, x, name='vggface_senet50')
483
+
484
+ # load weights
485
+ if weights == 'vggface':
486
+ if include_top:
487
+ weights_path = get_file('rcmalli_vggface_tf_senet50.h5',
488
+ utils.SENET50_WEIGHTS_PATH,
489
+ cache_subdir=utils.VGGFACE_DIR)
490
+ else:
491
+ weights_path = get_file('rcmalli_vggface_tf_notop_senet50.h5',
492
+ utils.SENET50_WEIGHTS_PATH_NO_TOP,
493
+ cache_subdir=utils.VGGFACE_DIR)
494
+ model.load_weights(weights_path)
495
+ if K.backend() == 'theano':
496
+ layer_utils.convert_all_kernels_in_model(model)
497
+ if include_top:
498
+ maxpool = model.get_layer(name='avg_pool')
499
+ shape = maxpool.output_shape[1:]
500
+ dense = model.get_layer(name='classifier')
501
+ layer_utils.convert_dense_weights_data_format(dense, shape,
502
+ 'channels_first')
503
+
504
+ if K.image_data_format() == 'channels_first' and K.backend() == 'tensorflow':
505
+ warnings.warn('You are using the TensorFlow backend, yet you '
506
+ 'are using the Theano '
507
+ 'image data format convention '
508
+ '(`image_data_format="channels_first"`). '
509
+ 'For best performance, set '
510
+ '`image_data_format="channels_last"` in '
511
+ 'your Keras config '
512
+ 'at ~/.keras/keras.json.')
513
+ elif weights is not None:
514
+ model.load_weights(weights)
515
+
516
+ return model
keras_vggface/utils.py ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ '''VGGFace models for Keras.
2
+
3
+ # Notes:
4
+ - Utility functions are modified versions of Keras functions [Keras](https://keras.io)
5
+
6
+ '''
7
+
8
+
9
+
10
+ import numpy as np
11
+ from keras import backend as K
12
+ from keras.utils.data_utils import get_file
13
+
14
+ V1_LABELS_PATH = 'https://github.com/rcmalli/keras-vggface/releases/download/v2.0/rcmalli_vggface_labels_v1.npy'
15
+ V2_LABELS_PATH = 'https://github.com/rcmalli/keras-vggface/releases/download/v2.0/rcmalli_vggface_labels_v2.npy'
16
+
17
+ VGG16_WEIGHTS_PATH = 'https://github.com/rcmalli/keras-vggface/releases/download/v2.0/rcmalli_vggface_tf_vgg16.h5'
18
+ VGG16_WEIGHTS_PATH_NO_TOP = 'https://github.com/rcmalli/keras-vggface/releases/download/v2.0/rcmalli_vggface_tf_notop_vgg16.h5'
19
+
20
+
21
+ RESNET50_WEIGHTS_PATH = 'https://github.com/rcmalli/keras-vggface/releases/download/v2.0/rcmalli_vggface_tf_resnet50.h5'
22
+ RESNET50_WEIGHTS_PATH_NO_TOP = 'https://github.com/rcmalli/keras-vggface/releases/download/v2.0/rcmalli_vggface_tf_notop_resnet50.h5'
23
+
24
+ SENET50_WEIGHTS_PATH = 'https://github.com/rcmalli/keras-vggface/releases/download/v2.0/rcmalli_vggface_tf_senet50.h5'
25
+ SENET50_WEIGHTS_PATH_NO_TOP = 'https://github.com/rcmalli/keras-vggface/releases/download/v2.0/rcmalli_vggface_tf_notop_senet50.h5'
26
+
27
+
28
+ VGGFACE_DIR = 'models/vggface'
29
+
30
+
31
+ def preprocess_input(x, data_format=None, version=1):
32
+ x_temp = np.copy(x)
33
+ if data_format is None:
34
+ data_format = K.image_data_format()
35
+ assert data_format in {'channels_last', 'channels_first'}
36
+
37
+ if version == 1:
38
+ if data_format == 'channels_first':
39
+ x_temp = x_temp[:, ::-1, ...]
40
+ x_temp[:, 0, :, :] -= 93.5940
41
+ x_temp[:, 1, :, :] -= 104.7624
42
+ x_temp[:, 2, :, :] -= 129.1863
43
+ else:
44
+ x_temp = x_temp[..., ::-1]
45
+ x_temp[..., 0] -= 93.5940
46
+ x_temp[..., 1] -= 104.7624
47
+ x_temp[..., 2] -= 129.1863
48
+
49
+ elif version == 2:
50
+ if data_format == 'channels_first':
51
+ x_temp = x_temp[:, ::-1, ...]
52
+ x_temp[:, 0, :, :] -= 91.4953
53
+ x_temp[:, 1, :, :] -= 103.8827
54
+ x_temp[:, 2, :, :] -= 131.0912
55
+ else:
56
+ x_temp = x_temp[..., ::-1]
57
+ x_temp[..., 0] -= 91.4953
58
+ x_temp[..., 1] -= 103.8827
59
+ x_temp[..., 2] -= 131.0912
60
+ else:
61
+ raise NotImplementedError
62
+
63
+ return x_temp
64
+
65
+
66
+ def decode_predictions(preds, top=5):
67
+ LABELS = None
68
+ if len(preds.shape) == 2:
69
+ if preds.shape[1] == 2622:
70
+ fpath = get_file('rcmalli_vggface_labels_v1.npy',
71
+ V1_LABELS_PATH,
72
+ cache_subdir=VGGFACE_DIR)
73
+ LABELS = np.load(fpath)
74
+ elif preds.shape[1] == 8631:
75
+ fpath = get_file('rcmalli_vggface_labels_v2.npy',
76
+ V2_LABELS_PATH,
77
+ cache_subdir=VGGFACE_DIR)
78
+ LABELS = np.load(fpath)
79
+ else:
80
+ raise ValueError('`decode_predictions` expects '
81
+ 'a batch of predictions '
82
+ '(i.e. a 2D array of shape (samples, 2622)) for V1 or '
83
+ '(samples, 8631) for V2.'
84
+ 'Found array with shape: ' + str(preds.shape))
85
+ else:
86
+ raise ValueError('`decode_predictions` expects '
87
+ 'a batch of predictions '
88
+ '(i.e. a 2D array of shape (samples, 2622)) for V1 or '
89
+ '(samples, 8631) for V2.'
90
+ 'Found array with shape: ' + str(preds.shape))
91
+ results = []
92
+ for pred in preds:
93
+ top_indices = pred.argsort()[-top:][::-1]
94
+ result = [[str(LABELS[i].encode('utf8')), pred[i]] for i in top_indices]
95
+ result.sort(key=lambda x: x[1], reverse=True)
96
+ results.append(result)
97
+ return results
keras_vggface/version.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ __version__ = '0.6'
2
+
3
+ def pretty_versions():
4
+ import keras
5
+ import tensorflow as tf
6
+ k_version = keras.__version__
7
+ t_version = tf.__version__
8
+ return "keras-vggface : {}, keras : {} , tensorflow : {} ".format(__version__,k_version,t_version)
keras_vggface/vggface.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ '''VGGFace models for Keras.
2
+
3
+ # Reference:
4
+ - [Deep Face Recognition](http://www.robots.ox.ac.uk/~vgg/publications/2015/Parkhi15/parkhi15.pdf)
5
+ - [VGGFace2: A dataset for recognising faces across pose and age](http://www.robots.ox.ac.uk/~vgg/data/vgg_face2/vggface2.pdf)
6
+
7
+ '''
8
+ from __future__ import print_function
9
+ from keras_vggface.models import RESNET50, VGG16, SENET50
10
+
11
+
12
+ def VGGFace(include_top=True, model='vgg16', weights='vggface',
13
+ input_tensor=None, input_shape=None,
14
+ pooling=None,
15
+ classes=None):
16
+ """Instantiates the VGGFace architectures.
17
+ Optionally loads weights pre-trained
18
+ on VGGFace datasets. Note that when using TensorFlow,
19
+ for best performance you should set
20
+ `image_data_format="channels_last"` in your Keras config
21
+ at ~/.keras/keras.json.
22
+ The model and the weights are compatible with both
23
+ TensorFlow and Theano. The data format
24
+ convention used by the model is the one
25
+ specified in your Keras config file.
26
+ # Arguments
27
+ include_top: whether to include the 3 fully-connected
28
+ layers at the top of the network.
29
+ weights: one of `None` (random initialization)
30
+ or "vggface" (pre-training on VGGFACE datasets).
31
+ input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)
32
+ to use as image input for the model.
33
+ model: selects the one of the available architectures
34
+ vgg16, resnet50 or senet50 default is vgg16.
35
+ input_shape: optional shape tuple, only to be specified
36
+ if `include_top` is False (otherwise the input shape
37
+ has to be `(224, 224, 3)` (with `channels_last` data format)
38
+ or `(3, 224, 244)` (with `channels_first` data format).
39
+ It should have exactly 3 inputs channels,
40
+ and width and height should be no smaller than 48.
41
+ E.g. `(200, 200, 3)` would be one valid value.
42
+ pooling: Optional pooling mode for feature extraction
43
+ when `include_top` is `False`.
44
+ - `None` means that the output of the model will be
45
+ the 4D tensor output of the
46
+ last convolutional layer.
47
+ - `avg` means that global average pooling
48
+ will be applied to the output of the
49
+ last convolutional layer, and thus
50
+ the output of the model will be a 2D tensor.
51
+ - `max` means that global max pooling will
52
+ be applied.
53
+ classes: optional number of classes to classify images
54
+ into, only to be specified if `include_top` is True, and
55
+ if no `weights` argument is specified.
56
+ # Returns
57
+ A Keras model instance.
58
+ # Raises
59
+ ValueError: in case of invalid argument for `weights`,
60
+ or invalid input shape.
61
+ """
62
+
63
+ if weights not in {'vggface', None}:
64
+ raise ValueError('The `weights` argument should be either '
65
+ '`None` (random initialization) or `vggface`'
66
+ '(pre-training on VGGFace Datasets).')
67
+
68
+ if model == 'vgg16':
69
+
70
+ if classes is None:
71
+ classes = 2622
72
+
73
+ if weights == 'vggface' and include_top and classes != 2622:
74
+ raise ValueError(
75
+ 'If using `weights` as vggface original with `include_top`'
76
+ ' as true, `classes` should be 2622')
77
+
78
+ return VGG16(include_top=include_top, input_tensor=input_tensor,
79
+ input_shape=input_shape, pooling=pooling,
80
+ weights=weights,
81
+ classes=classes)
82
+
83
+
84
+ if model == 'resnet50':
85
+
86
+ if classes is None:
87
+ classes = 8631
88
+
89
+ if weights == 'vggface' and include_top and classes != 8631:
90
+ raise ValueError(
91
+ 'If using `weights` as vggface original with `include_top`'
92
+ ' as true, `classes` should be 8631')
93
+
94
+ return RESNET50(include_top=include_top, input_tensor=input_tensor,
95
+ input_shape=input_shape, pooling=pooling,
96
+ weights=weights,
97
+ classes=classes)
98
+
99
+ if model == 'senet50':
100
+
101
+ if classes is None:
102
+ classes = 8631
103
+
104
+ if weights == 'vggface' and include_top and classes != 8631:
105
+ raise ValueError(
106
+ 'If using `weights` as vggface original with `include_top`'
107
+ ' as true, `classes` should be 8631')
108
+
109
+ return SENET50(include_top=include_top, input_tensor=input_tensor,
110
+ input_shape=input_shape, pooling=pooling,
111
+ weights=weights,
112
+ classes=classes)