Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/keras/src/applications/resnet.py: 20%

172 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2024-01-03 07:57 +0000

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 

16"""ResNet models for Keras. 

17 

18Reference: 

19 - [Deep Residual Learning for Image Recognition]( 

20 https://arxiv.org/abs/1512.03385) (CVPR 2015) 

21""" 

22 

23import tensorflow.compat.v2 as tf 

24 

25from keras.src import backend 

26from keras.src.applications import imagenet_utils 

27from keras.src.engine import training 

28from keras.src.layers import VersionAwareLayers 

29from keras.src.utils import data_utils 

30from keras.src.utils import layer_utils 

31 

32# isort: off 

33from tensorflow.python.util.tf_export import keras_export 

34 

35BASE_WEIGHTS_PATH = ( 

36 "https://storage.googleapis.com/tensorflow/keras-applications/resnet/" 

37) 

38WEIGHTS_HASHES = { 

39 "resnet50": ( 

40 "2cb95161c43110f7111970584f804107", 

41 "4d473c1dd8becc155b73f8504c6f6626", 

42 ), 

43 "resnet101": ( 

44 "f1aeb4b969a6efcfb50fad2f0c20cfc5", 

45 "88cf7a10940856eca736dc7b7e228a21", 

46 ), 

47 "resnet152": ( 

48 "100835be76be38e30d865e96f2aaae62", 

49 "ee4c566cf9a93f14d82f913c2dc6dd0c", 

50 ), 

51 "resnet50v2": ( 

52 "3ef43a0b657b3be2300d5770ece849e0", 

53 "fac2f116257151a9d068a22e544a4917", 

54 ), 

55 "resnet101v2": ( 

56 "6343647c601c52e1368623803854d971", 

57 "c0ed64b8031c3730f411d2eb4eea35b5", 

58 ), 

59 "resnet152v2": ( 

60 "a49b44d1979771252814e80f8ec446f9", 

61 "ed17cf2e0169df9d443503ef94b23b33", 

62 ), 

63 "resnext50": ( 

64 "67a5b30d522ed92f75a1f16eef299d1a", 

65 "62527c363bdd9ec598bed41947b379fc", 

66 ), 

67 "resnext101": ( 

68 "34fb605428fcc7aa4d62f44404c11509", 

69 "0f678c91647380debd923963594981b3", 

70 ), 

71} 

72 

73layers = None 

74 

75 

76def ResNet( 

77 stack_fn, 

78 preact, 

79 use_bias, 

80 model_name="resnet", 

81 include_top=True, 

82 weights="imagenet", 

83 input_tensor=None, 

84 input_shape=None, 

85 pooling=None, 

86 classes=1000, 

87 classifier_activation="softmax", 

88 **kwargs, 

89): 

90 """Instantiates the ResNet, ResNetV2, and ResNeXt architecture. 

91 

92 Args: 

93 stack_fn: a function that returns output tensor for the 

94 stacked residual blocks. 

95 preact: whether to use pre-activation or not 

96 (True for ResNetV2, False for ResNet and ResNeXt). 

97 use_bias: whether to use biases for convolutional layers or not 

98 (True for ResNet and ResNetV2, False for ResNeXt). 

99 model_name: string, model name. 

100 include_top: whether to include the fully-connected 

101 layer at the top of the network. 

102 weights: one of `None` (random initialization), 

103 'imagenet' (pre-training on ImageNet), 

104 or the path to the weights file to be loaded. 

105 input_tensor: optional Keras tensor 

106 (i.e. output of `layers.Input()`) 

107 to use as image input for the model. 

108 input_shape: optional shape tuple, only to be specified 

109 if `include_top` is False (otherwise the input shape 

110 has to be `(224, 224, 3)` (with `channels_last` data format) 

111 or `(3, 224, 224)` (with `channels_first` data format). 

112 It should have exactly 3 inputs channels. 

113 pooling: optional pooling mode for feature extraction 

114 when `include_top` is `False`. 

115 - `None` means that the output of the model will be 

116 the 4D tensor output of the 

117 last convolutional layer. 

118 - `avg` means that global average pooling 

119 will be applied to the output of the 

120 last convolutional layer, and thus 

121 the output of the model will be a 2D tensor. 

122 - `max` means that global max pooling will 

123 be applied. 

124 classes: optional number of classes to classify images 

125 into, only to be specified if `include_top` is True, and 

126 if no `weights` argument is specified. 

127 classifier_activation: A `str` or callable. The activation function to use 

128 on the "top" layer. Ignored unless `include_top=True`. Set 

129 `classifier_activation=None` to return the logits of the "top" layer. 

130 When loading pretrained weights, `classifier_activation` can only 

131 be `None` or `"softmax"`. 

132 **kwargs: For backwards compatibility only. 

133 

134 Returns: 

135 A `keras.Model` instance. 

136 """ 

137 global layers 

138 if "layers" in kwargs: 

139 layers = kwargs.pop("layers") 

140 else: 

141 layers = VersionAwareLayers() 

142 if kwargs: 

143 raise ValueError(f"Unknown argument(s): {kwargs}") 

144 if not (weights in {"imagenet", None} or tf.io.gfile.exists(weights)): 

145 raise ValueError( 

146 "The `weights` argument should be either " 

147 "`None` (random initialization), `imagenet` " 

148 "(pre-training on ImageNet), " 

149 "or the path to the weights file to be loaded." 

150 ) 

151 

152 if weights == "imagenet" and include_top and classes != 1000: 

153 raise ValueError( 

154 'If using `weights` as `"imagenet"` with `include_top`' 

155 " as true, `classes` should be 1000" 

156 ) 

157 

158 # Determine proper input shape 

159 input_shape = imagenet_utils.obtain_input_shape( 

160 input_shape, 

161 default_size=224, 

162 min_size=32, 

163 data_format=backend.image_data_format(), 

164 require_flatten=include_top, 

165 weights=weights, 

166 ) 

167 

168 if input_tensor is None: 

169 img_input = layers.Input(shape=input_shape) 

170 else: 

171 if not backend.is_keras_tensor(input_tensor): 

172 img_input = layers.Input(tensor=input_tensor, shape=input_shape) 

173 else: 

174 img_input = input_tensor 

175 

176 bn_axis = 3 if backend.image_data_format() == "channels_last" else 1 

177 

178 x = layers.ZeroPadding2D(padding=((3, 3), (3, 3)), name="conv1_pad")( 

179 img_input 

180 ) 

181 x = layers.Conv2D(64, 7, strides=2, use_bias=use_bias, name="conv1_conv")(x) 

182 

183 if not preact: 

184 x = layers.BatchNormalization( 

185 axis=bn_axis, epsilon=1.001e-5, name="conv1_bn" 

186 )(x) 

187 x = layers.Activation("relu", name="conv1_relu")(x) 

188 

189 x = layers.ZeroPadding2D(padding=((1, 1), (1, 1)), name="pool1_pad")(x) 

190 x = layers.MaxPooling2D(3, strides=2, name="pool1_pool")(x) 

191 

192 x = stack_fn(x) 

193 

194 if preact: 

195 x = layers.BatchNormalization( 

196 axis=bn_axis, epsilon=1.001e-5, name="post_bn" 

197 )(x) 

198 x = layers.Activation("relu", name="post_relu")(x) 

199 

200 if include_top: 

201 x = layers.GlobalAveragePooling2D(name="avg_pool")(x) 

202 imagenet_utils.validate_activation(classifier_activation, weights) 

203 x = layers.Dense( 

204 classes, activation=classifier_activation, name="predictions" 

205 )(x) 

206 else: 

207 if pooling == "avg": 

208 x = layers.GlobalAveragePooling2D(name="avg_pool")(x) 

209 elif pooling == "max": 

210 x = layers.GlobalMaxPooling2D(name="max_pool")(x) 

211 

212 # Ensure that the model takes into account 

213 # any potential predecessors of `input_tensor`. 

214 if input_tensor is not None: 

215 inputs = layer_utils.get_source_inputs(input_tensor) 

216 else: 

217 inputs = img_input 

218 

219 # Create model. 

220 model = training.Model(inputs, x, name=model_name) 

221 

222 # Load weights. 

223 if (weights == "imagenet") and (model_name in WEIGHTS_HASHES): 

224 if include_top: 

225 file_name = model_name + "_weights_tf_dim_ordering_tf_kernels.h5" 

226 file_hash = WEIGHTS_HASHES[model_name][0] 

227 else: 

228 file_name = ( 

229 model_name + "_weights_tf_dim_ordering_tf_kernels_notop.h5" 

230 ) 

231 file_hash = WEIGHTS_HASHES[model_name][1] 

232 weights_path = data_utils.get_file( 

233 file_name, 

234 BASE_WEIGHTS_PATH + file_name, 

235 cache_subdir="models", 

236 file_hash=file_hash, 

237 ) 

238 model.load_weights(weights_path) 

239 elif weights is not None: 

240 model.load_weights(weights) 

241 

242 return model 

243 

244 

245def block1(x, filters, kernel_size=3, stride=1, conv_shortcut=True, name=None): 

246 """A residual block. 

247 

248 Args: 

249 x: input tensor. 

250 filters: integer, filters of the bottleneck layer. 

251 kernel_size: default 3, kernel size of the bottleneck layer. 

252 stride: default 1, stride of the first layer. 

253 conv_shortcut: default True, use convolution shortcut if True, 

254 otherwise identity shortcut. 

255 name: string, block label. 

256 

257 Returns: 

258 Output tensor for the residual block. 

259 """ 

260 bn_axis = 3 if backend.image_data_format() == "channels_last" else 1 

261 

262 if conv_shortcut: 

263 shortcut = layers.Conv2D( 

264 4 * filters, 1, strides=stride, name=name + "_0_conv" 

265 )(x) 

266 shortcut = layers.BatchNormalization( 

267 axis=bn_axis, epsilon=1.001e-5, name=name + "_0_bn" 

268 )(shortcut) 

269 else: 

270 shortcut = x 

271 

272 x = layers.Conv2D(filters, 1, strides=stride, name=name + "_1_conv")(x) 

273 x = layers.BatchNormalization( 

274 axis=bn_axis, epsilon=1.001e-5, name=name + "_1_bn" 

275 )(x) 

276 x = layers.Activation("relu", name=name + "_1_relu")(x) 

277 

278 x = layers.Conv2D( 

279 filters, kernel_size, padding="SAME", name=name + "_2_conv" 

280 )(x) 

281 x = layers.BatchNormalization( 

282 axis=bn_axis, epsilon=1.001e-5, name=name + "_2_bn" 

283 )(x) 

284 x = layers.Activation("relu", name=name + "_2_relu")(x) 

285 

286 x = layers.Conv2D(4 * filters, 1, name=name + "_3_conv")(x) 

287 x = layers.BatchNormalization( 

288 axis=bn_axis, epsilon=1.001e-5, name=name + "_3_bn" 

289 )(x) 

290 

291 x = layers.Add(name=name + "_add")([shortcut, x]) 

292 x = layers.Activation("relu", name=name + "_out")(x) 

293 return x 

294 

295 

296def stack1(x, filters, blocks, stride1=2, name=None): 

297 """A set of stacked residual blocks. 

298 

299 Args: 

300 x: input tensor. 

301 filters: integer, filters of the bottleneck layer in a block. 

302 blocks: integer, blocks in the stacked blocks. 

303 stride1: default 2, stride of the first layer in the first block. 

304 name: string, stack label. 

305 

306 Returns: 

307 Output tensor for the stacked blocks. 

308 """ 

309 x = block1(x, filters, stride=stride1, name=name + "_block1") 

310 for i in range(2, blocks + 1): 

311 x = block1( 

312 x, filters, conv_shortcut=False, name=name + "_block" + str(i) 

313 ) 

314 return x 

315 

316 

317def block2(x, filters, kernel_size=3, stride=1, conv_shortcut=False, name=None): 

318 """A residual block. 

319 

320 Args: 

321 x: input tensor. 

322 filters: integer, filters of the bottleneck layer. 

323 kernel_size: default 3, kernel size of the bottleneck layer. 

324 stride: default 1, stride of the first layer. 

325 conv_shortcut: default False, use convolution shortcut if True, 

326 otherwise identity shortcut. 

327 name: string, block label. 

328 

329 Returns: 

330 Output tensor for the residual block. 

331 """ 

332 bn_axis = 3 if backend.image_data_format() == "channels_last" else 1 

333 

334 preact = layers.BatchNormalization( 

335 axis=bn_axis, epsilon=1.001e-5, name=name + "_preact_bn" 

336 )(x) 

337 preact = layers.Activation("relu", name=name + "_preact_relu")(preact) 

338 

339 if conv_shortcut: 

340 shortcut = layers.Conv2D( 

341 4 * filters, 1, strides=stride, name=name + "_0_conv" 

342 )(preact) 

343 else: 

344 shortcut = ( 

345 layers.MaxPooling2D(1, strides=stride)(x) if stride > 1 else x 

346 ) 

347 

348 x = layers.Conv2D( 

349 filters, 1, strides=1, use_bias=False, name=name + "_1_conv" 

350 )(preact) 

351 x = layers.BatchNormalization( 

352 axis=bn_axis, epsilon=1.001e-5, name=name + "_1_bn" 

353 )(x) 

354 x = layers.Activation("relu", name=name + "_1_relu")(x) 

355 

356 x = layers.ZeroPadding2D(padding=((1, 1), (1, 1)), name=name + "_2_pad")(x) 

357 x = layers.Conv2D( 

358 filters, 

359 kernel_size, 

360 strides=stride, 

361 use_bias=False, 

362 name=name + "_2_conv", 

363 )(x) 

364 x = layers.BatchNormalization( 

365 axis=bn_axis, epsilon=1.001e-5, name=name + "_2_bn" 

366 )(x) 

367 x = layers.Activation("relu", name=name + "_2_relu")(x) 

368 

369 x = layers.Conv2D(4 * filters, 1, name=name + "_3_conv")(x) 

370 x = layers.Add(name=name + "_out")([shortcut, x]) 

371 return x 

372 

373 

374def stack2(x, filters, blocks, stride1=2, name=None): 

375 """A set of stacked residual blocks. 

376 

377 Args: 

378 x: input tensor. 

379 filters: integer, filters of the bottleneck layer in a block. 

380 blocks: integer, blocks in the stacked blocks. 

381 stride1: default 2, stride of the first layer in the first block. 

382 name: string, stack label. 

383 

384 Returns: 

385 Output tensor for the stacked blocks. 

386 """ 

387 x = block2(x, filters, conv_shortcut=True, name=name + "_block1") 

388 for i in range(2, blocks): 

389 x = block2(x, filters, name=name + "_block" + str(i)) 

390 x = block2(x, filters, stride=stride1, name=name + "_block" + str(blocks)) 

391 return x 

392 

393 

394def block3( 

395 x, 

396 filters, 

397 kernel_size=3, 

398 stride=1, 

399 groups=32, 

400 conv_shortcut=True, 

401 name=None, 

402): 

403 """A residual block. 

404 

405 Args: 

406 x: input tensor. 

407 filters: integer, filters of the bottleneck layer. 

408 kernel_size: default 3, kernel size of the bottleneck layer. 

409 stride: default 1, stride of the first layer. 

410 groups: default 32, group size for grouped convolution. 

411 conv_shortcut: default True, use convolution shortcut if True, 

412 otherwise identity shortcut. 

413 name: string, block label. 

414 

415 Returns: 

416 Output tensor for the residual block. 

417 """ 

418 bn_axis = 3 if backend.image_data_format() == "channels_last" else 1 

419 

420 if conv_shortcut: 

421 shortcut = layers.Conv2D( 

422 (64 // groups) * filters, 

423 1, 

424 strides=stride, 

425 use_bias=False, 

426 name=name + "_0_conv", 

427 )(x) 

428 shortcut = layers.BatchNormalization( 

429 axis=bn_axis, epsilon=1.001e-5, name=name + "_0_bn" 

430 )(shortcut) 

431 else: 

432 shortcut = x 

433 

434 x = layers.Conv2D(filters, 1, use_bias=False, name=name + "_1_conv")(x) 

435 x = layers.BatchNormalization( 

436 axis=bn_axis, epsilon=1.001e-5, name=name + "_1_bn" 

437 )(x) 

438 x = layers.Activation("relu", name=name + "_1_relu")(x) 

439 

440 c = filters // groups 

441 x = layers.ZeroPadding2D(padding=((1, 1), (1, 1)), name=name + "_2_pad")(x) 

442 x = layers.DepthwiseConv2D( 

443 kernel_size, 

444 strides=stride, 

445 depth_multiplier=c, 

446 use_bias=False, 

447 name=name + "_2_conv", 

448 )(x) 

449 x_shape = backend.shape(x)[:-1] 

450 x = backend.reshape(x, backend.concatenate([x_shape, (groups, c, c)])) 

451 x = layers.Lambda( 

452 lambda x: sum(x[:, :, :, :, i] for i in range(c)), 

453 name=name + "_2_reduce", 

454 )(x) 

455 x = backend.reshape(x, backend.concatenate([x_shape, (filters,)])) 

456 x = layers.BatchNormalization( 

457 axis=bn_axis, epsilon=1.001e-5, name=name + "_2_bn" 

458 )(x) 

459 x = layers.Activation("relu", name=name + "_2_relu")(x) 

460 

461 x = layers.Conv2D( 

462 (64 // groups) * filters, 1, use_bias=False, name=name + "_3_conv" 

463 )(x) 

464 x = layers.BatchNormalization( 

465 axis=bn_axis, epsilon=1.001e-5, name=name + "_3_bn" 

466 )(x) 

467 

468 x = layers.Add(name=name + "_add")([shortcut, x]) 

469 x = layers.Activation("relu", name=name + "_out")(x) 

470 return x 

471 

472 

473def stack3(x, filters, blocks, stride1=2, groups=32, name=None): 

474 """A set of stacked residual blocks. 

475 

476 Args: 

477 x: input tensor. 

478 filters: integer, filters of the bottleneck layer in a block. 

479 blocks: integer, blocks in the stacked blocks. 

480 stride1: default 2, stride of the first layer in the first block. 

481 groups: default 32, group size for grouped convolution. 

482 name: string, stack label. 

483 

484 Returns: 

485 Output tensor for the stacked blocks. 

486 """ 

487 x = block3(x, filters, stride=stride1, groups=groups, name=name + "_block1") 

488 for i in range(2, blocks + 1): 

489 x = block3( 

490 x, 

491 filters, 

492 groups=groups, 

493 conv_shortcut=False, 

494 name=name + "_block" + str(i), 

495 ) 

496 return x 

497 

498 

499@keras_export( 

500 "keras.applications.resnet50.ResNet50", 

501 "keras.applications.resnet.ResNet50", 

502 "keras.applications.ResNet50", 

503) 

504def ResNet50( 

505 include_top=True, 

506 weights="imagenet", 

507 input_tensor=None, 

508 input_shape=None, 

509 pooling=None, 

510 classes=1000, 

511 **kwargs, 

512): 

513 """Instantiates the ResNet50 architecture.""" 

514 

515 def stack_fn(x): 

516 x = stack1(x, 64, 3, stride1=1, name="conv2") 

517 x = stack1(x, 128, 4, name="conv3") 

518 x = stack1(x, 256, 6, name="conv4") 

519 return stack1(x, 512, 3, name="conv5") 

520 

521 return ResNet( 

522 stack_fn, 

523 False, 

524 True, 

525 "resnet50", 

526 include_top, 

527 weights, 

528 input_tensor, 

529 input_shape, 

530 pooling, 

531 classes, 

532 **kwargs, 

533 ) 

534 

535 

536@keras_export( 

537 "keras.applications.resnet.ResNet101", "keras.applications.ResNet101" 

538) 

539def ResNet101( 

540 include_top=True, 

541 weights="imagenet", 

542 input_tensor=None, 

543 input_shape=None, 

544 pooling=None, 

545 classes=1000, 

546 **kwargs, 

547): 

548 """Instantiates the ResNet101 architecture.""" 

549 

550 def stack_fn(x): 

551 x = stack1(x, 64, 3, stride1=1, name="conv2") 

552 x = stack1(x, 128, 4, name="conv3") 

553 x = stack1(x, 256, 23, name="conv4") 

554 return stack1(x, 512, 3, name="conv5") 

555 

556 return ResNet( 

557 stack_fn, 

558 False, 

559 True, 

560 "resnet101", 

561 include_top, 

562 weights, 

563 input_tensor, 

564 input_shape, 

565 pooling, 

566 classes, 

567 **kwargs, 

568 ) 

569 

570 

571@keras_export( 

572 "keras.applications.resnet.ResNet152", "keras.applications.ResNet152" 

573) 

574def ResNet152( 

575 include_top=True, 

576 weights="imagenet", 

577 input_tensor=None, 

578 input_shape=None, 

579 pooling=None, 

580 classes=1000, 

581 **kwargs, 

582): 

583 """Instantiates the ResNet152 architecture.""" 

584 

585 def stack_fn(x): 

586 x = stack1(x, 64, 3, stride1=1, name="conv2") 

587 x = stack1(x, 128, 8, name="conv3") 

588 x = stack1(x, 256, 36, name="conv4") 

589 return stack1(x, 512, 3, name="conv5") 

590 

591 return ResNet( 

592 stack_fn, 

593 False, 

594 True, 

595 "resnet152", 

596 include_top, 

597 weights, 

598 input_tensor, 

599 input_shape, 

600 pooling, 

601 classes, 

602 **kwargs, 

603 ) 

604 

605 

606@keras_export( 

607 "keras.applications.resnet50.preprocess_input", 

608 "keras.applications.resnet.preprocess_input", 

609) 

610def preprocess_input(x, data_format=None): 

611 return imagenet_utils.preprocess_input( 

612 x, data_format=data_format, mode="caffe" 

613 ) 

614 

615 

616@keras_export( 

617 "keras.applications.resnet50.decode_predictions", 

618 "keras.applications.resnet.decode_predictions", 

619) 

620def decode_predictions(preds, top=5): 

621 return imagenet_utils.decode_predictions(preds, top=top) 

622 

623 

624preprocess_input.__doc__ = imagenet_utils.PREPROCESS_INPUT_DOC.format( 

625 mode="", 

626 ret=imagenet_utils.PREPROCESS_INPUT_RET_DOC_CAFFE, 

627 error=imagenet_utils.PREPROCESS_INPUT_ERROR_DOC, 

628) 

629decode_predictions.__doc__ = imagenet_utils.decode_predictions.__doc__ 

630 

631DOC = """ 

632 

633 Reference: 

634 - [Deep Residual Learning for Image Recognition]( 

635 https://arxiv.org/abs/1512.03385) (CVPR 2015) 

636 

637 For image classification use cases, see 

638 [this page for detailed examples]( 

639 https://keras.io/api/applications/#usage-examples-for-image-classification-models). 

640 

641 For transfer learning use cases, make sure to read the 

642 [guide to transfer learning & fine-tuning]( 

643 https://keras.io/guides/transfer_learning/). 

644 

645 Note: each Keras Application expects a specific kind of input preprocessing. 

646 For ResNet, call `tf.keras.applications.resnet.preprocess_input` on your 

647 inputs before passing them to the model. 

648 `resnet.preprocess_input` will convert the input images from RGB to BGR, 

649 then will zero-center each color channel with respect to the ImageNet dataset, 

650 without scaling. 

651 

652 Args: 

653 include_top: whether to include the fully-connected 

654 layer at the top of the network. 

655 weights: one of `None` (random initialization), 

656 'imagenet' (pre-training on ImageNet), 

657 or the path to the weights file to be loaded. 

658 input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) 

659 to use as image input for the model. 

660 input_shape: optional shape tuple, only to be specified 

661 if `include_top` is False (otherwise the input shape 

662 has to be `(224, 224, 3)` (with `'channels_last'` data format) 

663 or `(3, 224, 224)` (with `'channels_first'` data format). 

664 It should have exactly 3 inputs channels, 

665 and width and height should be no smaller than 32. 

666 E.g. `(200, 200, 3)` would be one valid value. 

667 pooling: Optional pooling mode for feature extraction 

668 when `include_top` is `False`. 

669 - `None` means that the output of the model will be 

670 the 4D tensor output of the 

671 last convolutional block. 

672 - `avg` means that global average pooling 

673 will be applied to the output of the 

674 last convolutional block, and thus 

675 the output of the model will be a 2D tensor. 

676 - `max` means that global max pooling will 

677 be applied. 

678 classes: optional number of classes to classify images 

679 into, only to be specified if `include_top` is True, and 

680 if no `weights` argument is specified. 

681 classifier_activation: A `str` or callable. The activation function to use 

682 on the "top" layer. Ignored unless `include_top=True`. Set 

683 `classifier_activation=None` to return the logits of the "top" layer. 

684 When loading pretrained weights, `classifier_activation` can only 

685 be `None` or `"softmax"`. 

686 

687 Returns: 

688 A Keras model instance. 

689""" 

690 

691setattr(ResNet50, "__doc__", ResNet50.__doc__ + DOC) 

692setattr(ResNet101, "__doc__", ResNet101.__doc__ + DOC) 

693setattr(ResNet152, "__doc__", ResNet152.__doc__ + DOC) 

694