From 9f5d8874f23d6ac036b4614ca092fc6fe21af285 Mon Sep 17 00:00:00 2001 From: Naveen M Date: Mon, 9 Dec 2019 00:57:14 -0600 Subject: [PATCH 1/6] Deeplabv3 code with LMS --- .../deeplabv3/tensorflow-models/AUTHORS | 10 + .../deeplabv3/tensorflow-models/CODEOWNERS | 67 + .../tensorflow-models/CONTRIBUTING.md | 23 + .../tensorflow-models/ISSUE_TEMPLATE.md | 37 + .../deeplabv3/tensorflow-models/LICENSE | 203 + .../deeplabv3/tensorflow-models/README.md | 25 + .../deeplabv3/tensorflow-models/WORKSPACE | 0 .../research/deeplab/README.md | 235 + .../research/deeplab/__init__.py | 0 .../research/deeplab/common.py | 173 + .../research/deeplab/common_test.py | 52 + .../research/deeplab/core/__init__.py | 0 .../deeplab/core/dense_prediction_cell.py | 288 + ...ediction_cell_branch5_top1_cityscapes.json | 1 + .../core/dense_prediction_cell_test.py | 135 + .../deeplab/core/feature_extractor.py | 330 + .../research/deeplab/core/preprocess_utils.py | 445 + .../deeplab/core/preprocess_utils_test.py | 432 + .../research/deeplab/core/resnet_v1_beta.py | 517 + .../deeplab/core/resnet_v1_beta_test.py | 274 + .../research/deeplab/core/utils.py | 84 + .../research/deeplab/core/utils_test.py | 32 + .../research/deeplab/core/xception.py | 761 + .../research/deeplab/core/xception_test.py | 467 + .../research/deeplab/datasets/__init__.py | 0 .../deeplab/datasets/build_ade20k_data.py | 118 + .../deeplab/datasets/build_cityscapes_data.py | 183 + .../research/deeplab/datasets/build_data.py | 161 + .../deeplab/datasets/build_voc2012_data.py | 141 + .../deeplab/datasets/convert_cityscapes.sh | 58 + .../datasets/download_and_convert_ade20k.sh | 80 + .../datasets/download_and_convert_voc2012.sh | 90 + .../deeplab/datasets/remove_gt_colormap.py | 83 + .../deeplab/datasets/segmentation_dataset.py | 198 + .../research/deeplab/deeplab_demo.ipynb | 348 + .../research/deeplab/eval.py | 176 + .../research/deeplab/export_model.py | 166 + .../research/deeplab/g3doc/ade20k.md | 108 + .../research/deeplab/g3doc/cityscapes.md | 160 + .../research/deeplab/g3doc/export_model.md | 23 + .../research/deeplab/g3doc/faq.md | 82 + .../research/deeplab/g3doc/img/image1.jpg | Bin 0 -> 151959 bytes .../research/deeplab/g3doc/img/image2.jpg | Bin 0 -> 106187 bytes .../research/deeplab/g3doc/img/image3.jpg | Bin 0 -> 108846 bytes .../research/deeplab/g3doc/img/image_info.txt | 13 + .../research/deeplab/g3doc/img/vis1.png | Bin 0 -> 421699 bytes .../research/deeplab/g3doc/img/vis2.png | Bin 0 -> 361149 bytes .../research/deeplab/g3doc/img/vis3.png | Bin 0 -> 430175 bytes .../research/deeplab/g3doc/installation.md | 66 + .../research/deeplab/g3doc/model_zoo.md | 185 + .../research/deeplab/g3doc/pascal.md | 164 + .../research/deeplab/input_preprocess.py | 138 + .../research/deeplab/learning.py.patch | 22 + .../research/deeplab/local_test.sh | 150 + .../deeplab/local_test_mobilenetv2.sh | 132 + .../research/deeplab/model.py | 709 + .../research/deeplab/model_test.py | 146 + .../research/deeplab/train.py | 470 + .../research/deeplab/utils/__init__.py | 0 .../deeplab/utils/get_dataset_colormap.py | 405 + .../utils/get_dataset_colormap_test.py | 96 + .../research/deeplab/utils/input_generator.py | 168 + .../research/deeplab/utils/save_annotation.py | 52 + .../research/deeplab/utils/train_utils.py | 211 + .../tensorflow-models/research/deeplab/vis.py | 320 + .../tensorflow-models/research/slim/BUILD | 820 + .../tensorflow-models/research/slim/README.md | 530 + .../tensorflow-models/research/slim/WORKSPACE | 0 .../research/slim/__init__.py | 0 .../research/slim/datasets/__init__.py | 1 + .../slim/datasets/build_imagenet_data.py | 704 + .../research/slim/datasets/cifar10.py | 98 + .../research/slim/datasets/dataset_factory.py | 57 + .../research/slim/datasets/dataset_utils.py | 150 + .../datasets/download_and_convert_cifar10.py | 198 + .../datasets/download_and_convert_flowers.py | 211 + .../datasets/download_and_convert_imagenet.sh | 103 + .../datasets/download_and_convert_mnist.py | 221 + .../slim/datasets/download_imagenet.sh | 99 + .../research/slim/datasets/flowers.py | 98 + .../research/slim/datasets/imagenet.py | 198 + ...imagenet_2012_validation_synset_labels.txt | 50000 ++++++++++++++++ .../datasets/imagenet_lsvrc_2015_synsets.txt | 1000 + .../slim/datasets/imagenet_metadata.txt | 21842 +++++++ .../research/slim/datasets/mnist.py | 98 + .../preprocess_imagenet_validation_data.py | 83 + .../slim/datasets/process_bounding_boxes.py | 253 + .../research/slim/deployment/__init__.py | 1 + .../research/slim/deployment/model_deploy.py | 682 + .../slim/deployment/model_deploy_test.py | 572 + .../slim/download_and_convert_data.py | 73 + .../research/slim/eval_image_classifier.py | 197 + .../research/slim/export_inference_graph.py | 156 + .../slim/export_inference_graph_test.py | 44 + .../research/slim/nets/__init__.py | 1 + .../research/slim/nets/alexnet.py | 138 + .../research/slim/nets/alexnet_test.py | 180 + .../research/slim/nets/cifarnet.py | 117 + .../research/slim/nets/cyclegan.py | 278 + .../research/slim/nets/cyclegan_test.py | 112 + .../research/slim/nets/dcgan.py | 202 + .../research/slim/nets/dcgan_test.py | 120 + .../research/slim/nets/i3d.py | 177 + .../research/slim/nets/i3d_test.py | 149 + .../research/slim/nets/i3d_utils.py | 287 + .../research/slim/nets/inception.py | 37 + .../research/slim/nets/inception_resnet_v2.py | 406 + .../slim/nets/inception_resnet_v2_test.py | 334 + .../research/slim/nets/inception_utils.py | 82 + .../research/slim/nets/inception_v1.py | 329 + .../research/slim/nets/inception_v1_test.py | 265 + .../research/slim/nets/inception_v2.py | 572 + .../research/slim/nets/inception_v2_test.py | 379 + .../research/slim/nets/inception_v3.py | 579 + .../research/slim/nets/inception_v3_test.py | 346 + .../research/slim/nets/inception_v4.py | 337 + .../research/slim/nets/inception_v4_test.py | 283 + .../research/slim/nets/lenet.py | 97 + .../research/slim/nets/mobilenet/README.md | 73 + .../research/slim/nets/mobilenet/__init__.py | 0 .../slim/nets/mobilenet/conv_blocks.py | 358 + .../nets/mobilenet/madds_top1_accuracy.png | Bin 0 -> 102412 bytes .../mnet_v1_vs_v2_pixel1_latency.png | Bin 0 -> 63145 bytes .../research/slim/nets/mobilenet/mobilenet.py | 467 + .../nets/mobilenet/mobilenet_example.ipynb | 445 + .../slim/nets/mobilenet/mobilenet_v2.py | 216 + .../slim/nets/mobilenet/mobilenet_v2_test.py | 189 + .../research/slim/nets/mobilenet_v1.md | 136 + .../research/slim/nets/mobilenet_v1.png | Bin 0 -> 100916 bytes .../research/slim/nets/mobilenet_v1.py | 476 + .../research/slim/nets/mobilenet_v1_eval.py | 152 + .../research/slim/nets/mobilenet_v1_test.py | 534 + .../research/slim/nets/mobilenet_v1_train.py | 212 + .../research/slim/nets/nasnet/README.md | 64 + .../research/slim/nets/nasnet/__init__.py | 1 + .../research/slim/nets/nasnet/nasnet.py | 547 + .../research/slim/nets/nasnet/nasnet_test.py | 410 + .../research/slim/nets/nasnet/nasnet_utils.py | 524 + .../slim/nets/nasnet/nasnet_utils_test.py | 62 + .../research/slim/nets/nasnet/pnasnet.py | 280 + .../research/slim/nets/nasnet/pnasnet_test.py | 256 + .../research/slim/nets/nets_factory.py | 159 + .../research/slim/nets/nets_factory_test.py | 81 + .../research/slim/nets/overfeat.py | 131 + .../research/slim/nets/overfeat_test.py | 178 + .../research/slim/nets/pix2pix.py | 295 + .../research/slim/nets/pix2pix_test.py | 156 + .../research/slim/nets/resnet_utils.py | 275 + .../research/slim/nets/resnet_v1.py | 375 + .../research/slim/nets/resnet_v1_test.py | 555 + .../research/slim/nets/resnet_v2.py | 337 + .../research/slim/nets/resnet_v2_test.py | 475 + .../research/slim/nets/s3dg.py | 599 + .../research/slim/nets/s3dg_test.py | 150 + .../research/slim/nets/vgg.py | 302 + .../research/slim/nets/vgg_test.py | 583 + .../research/slim/preprocessing/__init__.py | 1 + .../preprocessing/cifarnet_preprocessing.py | 128 + .../preprocessing/inception_preprocessing.py | 318 + .../slim/preprocessing/lenet_preprocessing.py | 44 + .../preprocessing/preprocessing_factory.py | 85 + .../slim/preprocessing/vgg_preprocessing.py | 365 + .../research/slim/scripts/export_mobilenet.sh | 132 + ...finetune_inception_resnet_v2_on_flowers.sh | 109 + .../finetune_inception_v1_on_flowers.sh | 104 + .../finetune_inception_v3_on_flowers.sh | 106 + .../finetune_resnet_v1_50_on_flowers.sh | 104 + .../slim/scripts/train_cifarnet_on_cifar10.sh | 64 + .../slim/scripts/train_lenet_on_mnist.sh | 63 + .../tensorflow-models/research/slim/setup.py | 27 + .../research/slim/slim_walkthrough.ipynb | 1141 + .../research/slim/train_image_classifier.py | 590 + 172 files changed, 107943 insertions(+) create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/AUTHORS create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/CODEOWNERS create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/CONTRIBUTING.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/ISSUE_TEMPLATE.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/LICENSE create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/README.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/WORKSPACE create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/README.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/__init__.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/common.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/common_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/__init__.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/dense_prediction_cell.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/dense_prediction_cell_branch5_top1_cityscapes.json create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/dense_prediction_cell_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/feature_extractor.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/preprocess_utils.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/preprocess_utils_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/resnet_v1_beta.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/resnet_v1_beta_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/utils.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/utils_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/xception.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/xception_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/__init__.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_ade20k_data.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_cityscapes_data.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_data.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_voc2012_data.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/convert_cityscapes.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/download_and_convert_ade20k.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/download_and_convert_voc2012.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/remove_gt_colormap.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/segmentation_dataset.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/deeplab_demo.ipynb create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/eval.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/export_model.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/ade20k.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/cityscapes.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/export_model.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/faq.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/image1.jpg create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/image2.jpg create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/image3.jpg create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/image_info.txt create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/vis1.png create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/vis2.png create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/vis3.png create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/installation.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/model_zoo.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/pascal.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/input_preprocess.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/learning.py.patch create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/local_test.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/local_test_mobilenetv2.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/model.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/model_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/train.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/__init__.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/get_dataset_colormap.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/get_dataset_colormap_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/input_generator.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/save_annotation.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/train_utils.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/vis.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/BUILD create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/README.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/WORKSPACE create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/__init__.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/__init__.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/build_imagenet_data.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/cifar10.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/dataset_factory.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/dataset_utils.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_cifar10.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_flowers.py create mode 100755 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_imagenet.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_mnist.py create mode 100755 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_imagenet.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/flowers.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/imagenet.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/imagenet_2012_validation_synset_labels.txt create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/imagenet_lsvrc_2015_synsets.txt create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/imagenet_metadata.txt create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/mnist.py create mode 100755 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/preprocess_imagenet_validation_data.py create mode 100755 examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/process_bounding_boxes.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/deployment/__init__.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/deployment/model_deploy.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/deployment/model_deploy_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/download_and_convert_data.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/eval_image_classifier.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/export_inference_graph.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/export_inference_graph_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/__init__.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/alexnet.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/alexnet_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/cifarnet.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/cyclegan.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/cyclegan_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/dcgan.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/dcgan_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/i3d.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/i3d_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/i3d_utils.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_resnet_v2.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_resnet_v2_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_utils.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v1.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v1_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v2.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v2_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v3.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v3_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v4.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v4_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/lenet.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/README.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/__init__.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/conv_blocks.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/madds_top1_accuracy.png create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mnet_v1_vs_v2_pixel1_latency.png create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet_example.ipynb create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet_v2.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet_v2_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1.png create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1_eval.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1_train.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/README.md create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/__init__.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet_utils.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet_utils_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/pnasnet.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/pnasnet_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nets_factory.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nets_factory_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/overfeat.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/overfeat_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/pix2pix.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/pix2pix_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_utils.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v1.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v1_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v2.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v2_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/s3dg.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/s3dg_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/vgg.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/vgg_test.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/__init__.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/cifarnet_preprocessing.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/inception_preprocessing.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/lenet_preprocessing.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/preprocessing_factory.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/vgg_preprocessing.py create mode 100755 examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/export_mobilenet.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_inception_resnet_v2_on_flowers.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_inception_v1_on_flowers.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_inception_v3_on_flowers.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_resnet_v1_50_on_flowers.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/train_cifarnet_on_cifar10.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/train_lenet_on_mnist.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/setup.py create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/slim_walkthrough.ipynb create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/slim/train_image_classifier.py diff --git a/examples/performance_models/deeplabv3/tensorflow-models/AUTHORS b/examples/performance_models/deeplabv3/tensorflow-models/AUTHORS new file mode 100644 index 0000000..0fa85c9 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/AUTHORS @@ -0,0 +1,10 @@ +# This is the official list of authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS files. +# See the latter for an explanation. + +# Names should be added to this file as: +# Name or Organization +# The email address is not required for organizations. + +Google Inc. +David Dao diff --git a/examples/performance_models/deeplabv3/tensorflow-models/CODEOWNERS b/examples/performance_models/deeplabv3/tensorflow-models/CODEOWNERS new file mode 100644 index 0000000..0867156 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/CODEOWNERS @@ -0,0 +1,67 @@ +* @tensorflow/tf-garden-team +/official/ @tensorflow/tf-garden-team @karmel +/research/adversarial_crypto/ @dave-andersen +/research/adversarial_logit_pairing/ @AlexeyKurakin +/research/adversarial_text/ @rsepassi @a-dai +/research/adv_imagenet_models/ @AlexeyKurakin +/research/attention_ocr/ @alexgorban +/research/audioset/ @plakal @dpwe +/research/autoaugment/* @barretzoph +/research/autoencoders/ @snurkabill +/research/brain_coder/ @danabo +/research/cognitive_mapping_and_planning/ @s-gupta +/research/compression/ @nmjohn +/research/cvt_text/ @clarkkev @lmthang +/research/deep_contextual_bandits/ @rikel +/research/deeplab/ @aquariusjay @yknzhu @gpapan +/research/delf/ @andrefaraujo +/research/differential_privacy/ @ilyamironov @ananthr +/research/domain_adaptation/ @bousmalis @dmrd +/research/efficient-hrl/ @ofirnachum +/research/gan/ @joel-shor +/research/global_objectives/ @mackeya-google +/research/im2txt/ @cshallue +/research/inception/ @shlens @vincentvanhoucke +/research/keypointnet/ @mnorouzi +/research/learned_optimizer/ @olganw @nirum +/research/learning_to_remember_rare_events/ @lukaszkaiser @ofirnachum +/research/learning_unsupervised_learning/ @lukemetz @nirum +/research/lexnet_nc/ @vered1986 @waterson +/research/lfads/ @jazcollins @susillo +/research/lm_1b/ @oriolvinyals @panyx0718 +/research/lm_commonsense/ @thtrieu +/research/lstm_object_detection/ @dreamdragon @masonliuw @yinxiaoli +/research/marco/ @vincentvanhoucke +/research/maskgan/ @a-dai +/research/morph_net/ @gariel-google +/research/namignizer/ @knathanieltucker +/research/neural_gpu/ @lukaszkaiser +/research/neural_programmer/ @arvind2505 +/research/next_frame_prediction/ @panyx0718 +/research/object_detection/ @jch1 @tombstone @derekjchow @jesu9 @dreamdragon @pkulzc +/research/pcl_rl/ @ofirnachum +/research/ptn/ @xcyan @arkanath @hellojas @honglaklee +/research/real_nvp/ @laurent-dinh +/research/rebar/ @gjtucker +/research/resnet/ @panyx0718 +/research/seq2species/ @apbusia @depristo +/research/skip_thoughts/ @cshallue +/research/slim/ @sguada @nathansilberman +/research/steve/ @buckman-google +/research/street/ @theraysmith +/research/struct2depth/ @aneliaangelova +/research/swivel/ @waterson +/research/syntaxnet/ @calberti @andorardo @bogatyy @markomernick +/research/tcn/ @coreylynch @sermanet +/research/tensorrt/ @karmel +/research/textsum/ @panyx0718 @peterjliu +/research/transformer/ @daviddao +/research/vid2depth/ @rezama +/research/video_prediction/ @cbfinn +/research/fivo/ @dieterichlawson +/samples/ @MarkDaoust @lamberta +/samples/languages/java/ @asimshankar +/tutorials/embedding/ @zffchen78 @a-dai +/tutorials/image/ @sherrym @shlens +/tutorials/image/cifar10_estimator/ @tfboyd @protoget +/tutorials/rnn/ @lukaszkaiser @ebrevdo diff --git a/examples/performance_models/deeplabv3/tensorflow-models/CONTRIBUTING.md b/examples/performance_models/deeplabv3/tensorflow-models/CONTRIBUTING.md new file mode 100644 index 0000000..6053119 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/CONTRIBUTING.md @@ -0,0 +1,23 @@ +# Contributing guidelines + +If you have created a model and would like to publish it here, please send us a +pull request. For those just getting started with pull requests, GitHub has a +[howto](https://help.github.com/articles/using-pull-requests/). + +The code for any model in this repository is licensed under the Apache License +2.0. + +In order to accept our code, we have to make sure that we can publish your code: +You have to sign a Contributor License Agreement (CLA). + +### Contributor License Agreements + +Please fill out either the individual or corporate Contributor License Agreement (CLA). + + * If you are an individual writing original source code and you're sure you own the intellectual property, then you'll need to sign an [individual CLA](http://code.google.com/legal/individual-cla-v1.0.html). + * If you work for a company that wants to allow you to contribute your work, then you'll need to sign a [corporate CLA](http://code.google.com/legal/corporate-cla-v1.0.html). + +Follow either of the two links above to access the appropriate CLA and instructions for how to sign and return it. Once we receive it, we'll be able to accept your pull requests. + +***NOTE***: Only original source code from you and other people that have signed the CLA can be accepted into the repository. + diff --git a/examples/performance_models/deeplabv3/tensorflow-models/ISSUE_TEMPLATE.md b/examples/performance_models/deeplabv3/tensorflow-models/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..021d5aa --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/ISSUE_TEMPLATE.md @@ -0,0 +1,37 @@ +Please go to Stack Overflow for help and support: + +http://stackoverflow.com/questions/tagged/tensorflow + +Also, please understand that many of the models included in this repository are experimental and research-style code. If you open a GitHub issue, here is our policy: + +1. It must be a bug, a feature request, or a significant problem with documentation (for small docs fixes please send a PR instead). +2. The form below must be filled out. + +**Here's why we have that policy**: TensorFlow developers respond to issues. We want to focus on work that benefits the whole community, e.g., fixing bugs and adding features. Support only helps individuals. GitHub also notifies thousands of people when issues are filed. We want them to see you communicating an interesting problem, rather than being redirected to Stack Overflow. + +------------------------ + +### System information +- **What is the top-level directory of the model you are using**: +- **Have I written custom code (as opposed to using a stock example script provided in TensorFlow)**: +- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: +- **TensorFlow installed from (source or binary)**: +- **TensorFlow version (use command below)**: +- **Bazel version (if compiling from source)**: +- **CUDA/cuDNN version**: +- **GPU model and memory**: +- **Exact command to reproduce**: + +You can collect some of this information using our environment capture script: + +https://github.com/tensorflow/tensorflow/tree/master/tools/tf_env_collect.sh + +You can obtain the TensorFlow version with + +python -c "import tensorflow as tf; print(tf.GIT_VERSION, tf.VERSION)" + +### Describe the problem +Describe the problem clearly here. Be sure to convey here why it's a bug in TensorFlow or a feature request. + +### Source code / logs +Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached. Try to provide a reproducible test case that is the bare minimum necessary to generate the problem. diff --git a/examples/performance_models/deeplabv3/tensorflow-models/LICENSE b/examples/performance_models/deeplabv3/tensorflow-models/LICENSE new file mode 100644 index 0000000..43fcf7b --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/LICENSE @@ -0,0 +1,203 @@ +Copyright 2016 The TensorFlow Authors. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016, The Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/examples/performance_models/deeplabv3/tensorflow-models/README.md b/examples/performance_models/deeplabv3/tensorflow-models/README.md new file mode 100644 index 0000000..9168ffd --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/README.md @@ -0,0 +1,25 @@ +The repository code in the powerai-1.6.0 branch +came from https://github.com/tensorflow/models at commit `078575a121c79f1f1594b03f5bc70bbf0b3fb744`. + +It contains the DeepLabV3+ model that was used for the TensorFlow Large Model +Support performance investigation on top of PowerAI 1.6.0. + +# TensorFlow Models + +This repository contains a number of different models implemented in [TensorFlow](https://www.tensorflow.org): + +The [official models](official) are a collection of example models that use TensorFlow's high-level APIs. They are intended to be well-maintained, tested, and kept up to date with the latest stable TensorFlow API. They should also be reasonably optimized for fast performance while still being easy to read. We especially recommend newer TensorFlow users to start here. + +The [research models](https://github.com/tensorflow/models/tree/master/research) are a large collection of models implemented in TensorFlow by researchers. They are not officially supported or available in release branches; it is up to the individual researchers to maintain the models and/or provide support on issues and pull requests. + +The [samples folder](samples) contains code snippets and smaller models that demonstrate features of TensorFlow, including code presented in various blog posts. + +The [tutorials folder](tutorials) is a collection of models described in the [TensorFlow tutorials](https://www.tensorflow.org/tutorials/). + +## Contribution guidelines + +If you want to contribute to models, be sure to review the [contribution guidelines](CONTRIBUTING.md). + +## License + +[Apache License 2.0](LICENSE) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/WORKSPACE b/examples/performance_models/deeplabv3/tensorflow-models/WORKSPACE new file mode 100644 index 0000000..e69de29 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/README.md b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/README.md new file mode 100644 index 0000000..6d02465 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/README.md @@ -0,0 +1,235 @@ +# DeepLab: Deep Labelling for Semantic Image Segmentation + +DeepLab is a state-of-art deep learning model for semantic image segmentation, +where the goal is to assign semantic labels (e.g., person, dog, cat and so on) +to every pixel in the input image. Current implementation includes the following +features: + +1. DeepLabv1 [1]: We use *atrous convolution* to explicitly control the + resolution at which feature responses are computed within Deep Convolutional + Neural Networks. + +2. DeepLabv2 [2]: We use *atrous spatial pyramid pooling* (ASPP) to robustly + segment objects at multiple scales with filters at multiple sampling rates + and effective fields-of-views. + +3. DeepLabv3 [3]: We augment the ASPP module with *image-level feature* [5, 6] + to capture longer range information. We also include *batch normalization* + [7] parameters to facilitate the training. In particular, we applying atrous + convolution to extract output features at different output strides during + training and evaluation, which efficiently enables training BN at output + stride = 16 and attains a high performance at output stride = 8 during + evaluation. + +4. DeepLabv3+ [4]: We extend DeepLabv3 to include a simple yet effective + decoder module to refine the segmentation results especially along object + boundaries. Furthermore, in this encoder-decoder structure one can + arbitrarily control the resolution of extracted encoder features by atrous + convolution to trade-off precision and runtime. + +If you find the code useful for your research, please consider citing our latest +works: + +* DeepLabv3+: + +``` +@inproceedings{deeplabv3plus2018, + title={Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation}, + author={Liang-Chieh Chen and Yukun Zhu and George Papandreou and Florian Schroff and Hartwig Adam}, + booktitle={ECCV}, + year={2018} +} +``` + +* MobileNetv2: + +``` +@inproceedings{mobilenetv22018, + title={MobileNetV2: Inverted Residuals and Linear Bottlenecks}, + author={Mark Sandler and Andrew Howard and Menglong Zhu and Andrey Zhmoginov and Liang-Chieh Chen}, + booktitle={CVPR}, + year={2018} +} +``` + +* Architecture search for dense prediction cell: + +``` +@inproceedings{dpc2018, + title={Searching for Efficient Multi-Scale Architectures for Dense Image Prediction}, + author={Liang-Chieh Chen and Maxwell D. Collins and Yukun Zhu and George Papandreou and Barret Zoph and Florian Schroff and Hartwig Adam and Jonathon Shlens}, + booktitle={NIPS}, + year={2018} +} + +``` + +In the current implementation, we support adopting the following network +backbones: + +1. MobileNetv2 [8]: A fast network structure designed for mobile devices. + +2. Xception [9, 10]: A powerful network structure intended for server-side + deployment. + +This directory contains our TensorFlow [11] implementation. We provide codes +allowing users to train the model, evaluate results in terms of mIOU (mean +intersection-over-union), and visualize segmentation results. We use PASCAL VOC +2012 [12] and Cityscapes [13] semantic segmentation benchmarks as an example in +the code. + +Some segmentation results on Flickr images: +

+
+
+
+

+ +## Contacts (Maintainers) + +* Liang-Chieh Chen, github: [aquariusjay](https://github.com/aquariusjay) +* YuKun Zhu, github: [yknzhu](https://github.com/YknZhu) +* George Papandreou, github: [gpapan](https://github.com/gpapan) +* Hui Hui, github: [huihui-personal](https://github.com/huihui-personal) + +## Tables of Contents + +Demo: + +* Colab notebook for off-the-shelf inference.
+ +Running: + +* Installation.
+* Running DeepLab on PASCAL VOC 2012 semantic segmentation dataset.
+* Running DeepLab on Cityscapes semantic segmentation dataset.
+* Running DeepLab on ADE20K semantic segmentation dataset.
+ +Models: + +* Checkpoints and frozen inference graphs.
+ +Misc: + +* Please check FAQ if you have some questions before reporting the issues.
+ +## TensorFlow Large Model Support + +This version of deeplab has been enabled to run with TensorFlow Large Model +Support. This requires a corresponding change to the +tensorflow/contrib/slim/python/slim/learning.py to allow the LMS instance +to run on the model after SLIM has finished building it up in the +slim.learning.train method. The changes to learning.py can be found in +learning.py.patch. These changes can be applied to learning.py with the +following command: +``` +patch -p1 learning.py < learning.py.patch +``` + + +## Getting Help + +To get help with issues you may encounter while using the DeepLab Tensorflow +implementation, create a new question on +[StackOverflow](https://stackoverflow.com/) with the tag "tensorflow". + +Please report bugs (i.e., broken code, not usage questions) to the +tensorflow/models GitHub [issue +tracker](https://github.com/tensorflow/models/issues), prefixing the issue name +with "deeplab". + +## Change Logs + +### October 1, 2018 + +Released MobileNet-v2 depth-multiplier = 0.5 COCO-pretrained checkpoints on +PASCAL VOC 2012, and Xception-65 COCO pretrained checkpoint (i.e., no PASCAL +pretrained). + + +### September 5, 2018 + +Released Cityscapes pretrained checkpoints with found best dense prediction cell. + + +### May 26, 2018 + +Updated ADE20K pretrained checkpoint. + + +### May 18, 2018 +1. Added builders for ResNet-v1 and Xception model variants. +1. Added ADE20K support, including colormap and pretrained Xception_65 checkpoint. +1. Fixed a bug on using non-default depth_multiplier for MobileNet-v2. + + +### March 22, 2018 + +Released checkpoints using MobileNet-V2 as network backbone and pretrained on +PASCAL VOC 2012 and Cityscapes. + + +### March 5, 2018 + +First release of DeepLab in TensorFlow including deeper Xception network +backbone. Included chekcpoints that have been pretrained on PASCAL VOC 2012 +and Cityscapes. + +## References + +1. **Semantic Image Segmentation with Deep Convolutional Nets and Fully Connected CRFs**
+ Liang-Chieh Chen+, George Papandreou+, Iasonas Kokkinos, Kevin Murphy, Alan L. Yuille (+ equal + contribution).
+ [[link]](https://arxiv.org/abs/1412.7062). In ICLR, 2015. + +2. **DeepLab: Semantic Image Segmentation with Deep Convolutional Nets,** + **Atrous Convolution, and Fully Connected CRFs**
+ Liang-Chieh Chen+, George Papandreou+, Iasonas Kokkinos, Kevin Murphy, and Alan L Yuille (+ equal + contribution).
+ [[link]](http://arxiv.org/abs/1606.00915). TPAMI 2017. + +3. **Rethinking Atrous Convolution for Semantic Image Segmentation**
+ Liang-Chieh Chen, George Papandreou, Florian Schroff, Hartwig Adam.
+ [[link]](http://arxiv.org/abs/1706.05587). arXiv: 1706.05587, 2017. + +4. **Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation**
+ Liang-Chieh Chen, Yukun Zhu, George Papandreou, Florian Schroff, Hartwig Adam.
+ [[link]](https://arxiv.org/abs/1802.02611). In ECCV, 2018. + +5. **ParseNet: Looking Wider to See Better**
+ Wei Liu, Andrew Rabinovich, Alexander C Berg
+ [[link]](https://arxiv.org/abs/1506.04579). arXiv:1506.04579, 2015. + +6. **Pyramid Scene Parsing Network**
+ Hengshuang Zhao, Jianping Shi, Xiaojuan Qi, Xiaogang Wang, Jiaya Jia
+ [[link]](https://arxiv.org/abs/1612.01105). In CVPR, 2017. + +7. **Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate shift**
+ Sergey Ioffe, Christian Szegedy
+ [[link]](https://arxiv.org/abs/1502.03167). In ICML, 2015. + +8. **MobileNetV2: Inverted Residuals and Linear Bottlenecks**
+ Mark Sandler, Andrew Howard, Menglong Zhu, Andrey Zhmoginov, Liang-Chieh Chen
+ [[link]](https://arxiv.org/abs/1801.04381). In CVPR, 2018. + +9. **Xception: Deep Learning with Depthwise Separable Convolutions**
+ François Chollet
+ [[link]](https://arxiv.org/abs/1610.02357). In CVPR, 2017. + +10. **Deformable Convolutional Networks -- COCO Detection and Segmentation Challenge 2017 Entry**
+ Haozhi Qi, Zheng Zhang, Bin Xiao, Han Hu, Bowen Cheng, Yichen Wei, Jifeng Dai
+ [[link]](http://presentations.cocodataset.org/COCO17-Detect-MSRA.pdf). ICCV COCO Challenge + Workshop, 2017. + +11. **Tensorflow: Large-Scale Machine Learning on Heterogeneous Distributed Systems**
+ M. Abadi, A. Agarwal, et al.
+ [[link]](https://arxiv.org/abs/1603.04467). arXiv:1603.04467, 2016. + +12. **The Pascal Visual Object Classes Challenge – A Retrospective,**
+ Mark Everingham, S. M. Ali Eslami, Luc Van Gool, Christopher K. I. Williams, John + Winn, and Andrew Zisserma.
+ [[link]](http://host.robots.ox.ac.uk/pascal/VOC/voc2012/). IJCV, 2014. + +13. **The Cityscapes Dataset for Semantic Urban Scene Understanding**
+ Cordts, Marius, Mohamed Omran, Sebastian Ramos, Timo Rehfeld, Markus Enzweiler, Rodrigo Benenson, Uwe Franke, Stefan Roth, Bernt Schiele.
+ [[link]](https://www.cityscapes-dataset.com/). In CVPR, 2016. diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/__init__.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/common.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/common.py new file mode 100644 index 0000000..83b73f0 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/common.py @@ -0,0 +1,173 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Provides flags that are common to scripts. + +Common flags from train/eval/vis/export_model.py are collected in this script. +""" +import collections +import copy +import json + +import tensorflow as tf + +flags = tf.app.flags + +# Flags for input preprocessing. + +flags.DEFINE_integer('min_resize_value', None, + 'Desired size of the smaller image side.') + +flags.DEFINE_integer('max_resize_value', None, + 'Maximum allowed size of the larger image side.') + +flags.DEFINE_integer('resize_factor', None, + 'Resized dimensions are multiple of factor plus one.') + +# Model dependent flags. + +flags.DEFINE_integer('logits_kernel_size', 1, + 'The kernel size for the convolutional kernel that ' + 'generates logits.') + +# When using 'mobilent_v2', we set atrous_rates = decoder_output_stride = None. +# When using 'xception_65' or 'resnet_v1' model variants, we set +# atrous_rates = [6, 12, 18] (output stride 16) and decoder_output_stride = 4. +# See core/feature_extractor.py for supported model variants. +flags.DEFINE_string('model_variant', 'mobilenet_v2', 'DeepLab model variant.') + +flags.DEFINE_multi_float('image_pyramid', None, + 'Input scales for multi-scale feature extraction.') + +flags.DEFINE_boolean('add_image_level_feature', True, + 'Add image level feature.') + +flags.DEFINE_multi_integer( + 'image_pooling_crop_size', None, + 'Image pooling crop size [height, width] used in the ASPP module. When ' + 'value is None, the model performs image pooling with "crop_size". This' + 'flag is useful when one likes to use different image pooling sizes.') + +flags.DEFINE_boolean('aspp_with_batch_norm', True, + 'Use batch norm parameters for ASPP or not.') + +flags.DEFINE_boolean('aspp_with_separable_conv', True, + 'Use separable convolution for ASPP or not.') + +# Defaults to None. Set multi_grid = [1, 2, 4] when using provided +# 'resnet_v1_{50,101}_beta' checkpoints. +flags.DEFINE_multi_integer('multi_grid', None, + 'Employ a hierarchy of atrous rates for ResNet.') + +flags.DEFINE_float('depth_multiplier', 1.0, + 'Multiplier for the depth (number of channels) for all ' + 'convolution ops used in MobileNet.') + +# For `xception_65`, use decoder_output_stride = 4. For `mobilenet_v2`, use +# decoder_output_stride = None. +flags.DEFINE_integer('decoder_output_stride', None, + 'The ratio of input to output spatial resolution when ' + 'employing decoder to refine segmentation results.') + +flags.DEFINE_boolean('decoder_use_separable_conv', True, + 'Employ separable convolution for decoder or not.') + +flags.DEFINE_enum('merge_method', 'max', ['max', 'avg'], + 'Scheme to merge multi scale features.') + +flags.DEFINE_string( + 'dense_prediction_cell_json', + '', + 'A JSON file that specifies the dense prediction cell.') + +FLAGS = flags.FLAGS + +# Constants + +# Perform semantic segmentation predictions. +OUTPUT_TYPE = 'semantic' + +# Semantic segmentation item names. +LABELS_CLASS = 'labels_class' +IMAGE = 'image' +HEIGHT = 'height' +WIDTH = 'width' +IMAGE_NAME = 'image_name' +LABEL = 'label' +ORIGINAL_IMAGE = 'original_image' + +# Test set name. +TEST_SET = 'test' + + +class ModelOptions( + collections.namedtuple('ModelOptions', [ + 'outputs_to_num_classes', + 'crop_size', + 'atrous_rates', + 'output_stride', + 'merge_method', + 'add_image_level_feature', + 'image_pooling_crop_size', + 'aspp_with_batch_norm', + 'aspp_with_separable_conv', + 'multi_grid', + 'decoder_output_stride', + 'decoder_use_separable_conv', + 'logits_kernel_size', + 'model_variant', + 'depth_multiplier', + 'dense_prediction_cell_config', + ])): + """Immutable class to hold model options.""" + + __slots__ = () + + def __new__(cls, + outputs_to_num_classes, + crop_size=None, + atrous_rates=None, + output_stride=8): + """Constructor to set default values. + + Args: + outputs_to_num_classes: A dictionary from output type to the number of + classes. For example, for the task of semantic segmentation with 21 + semantic classes, we would have outputs_to_num_classes['semantic'] = 21. + crop_size: A tuple [crop_height, crop_width]. + atrous_rates: A list of atrous convolution rates for ASPP. + output_stride: The ratio of input to output spatial resolution. + + Returns: + A new ModelOptions instance. + """ + dense_prediction_cell_config = None + if FLAGS.dense_prediction_cell_json: + with tf.gfile.Open(FLAGS.dense_prediction_cell_json, 'r') as f: + dense_prediction_cell_config = json.load(f) + + return super(ModelOptions, cls).__new__( + cls, outputs_to_num_classes, crop_size, atrous_rates, output_stride, + FLAGS.merge_method, FLAGS.add_image_level_feature, + FLAGS.image_pooling_crop_size, FLAGS.aspp_with_batch_norm, + FLAGS.aspp_with_separable_conv, FLAGS.multi_grid, + FLAGS.decoder_output_stride, FLAGS.decoder_use_separable_conv, + FLAGS.logits_kernel_size, FLAGS.model_variant, FLAGS.depth_multiplier, + dense_prediction_cell_config) + + def __deepcopy__(self, memo): + return ModelOptions(copy.deepcopy(self.outputs_to_num_classes), + self.crop_size, + self.atrous_rates, + self.output_stride) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/common_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/common_test.py new file mode 100644 index 0000000..45b64e5 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/common_test.py @@ -0,0 +1,52 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Tests for common.py.""" +import copy + +import tensorflow as tf + +from deeplab import common + + +class CommonTest(tf.test.TestCase): + + def testOutputsToNumClasses(self): + num_classes = 21 + model_options = common.ModelOptions( + outputs_to_num_classes={common.OUTPUT_TYPE: num_classes}) + self.assertEqual(model_options.outputs_to_num_classes[common.OUTPUT_TYPE], + num_classes) + + def testDeepcopy(self): + num_classes = 21 + model_options = common.ModelOptions( + outputs_to_num_classes={common.OUTPUT_TYPE: num_classes}) + model_options_new = copy.deepcopy(model_options) + self.assertEqual((model_options_new. + outputs_to_num_classes[common.OUTPUT_TYPE]), + num_classes) + + num_classes_new = 22 + model_options_new.outputs_to_num_classes[common.OUTPUT_TYPE] = ( + num_classes_new) + self.assertEqual(model_options.outputs_to_num_classes[common.OUTPUT_TYPE], + num_classes) + self.assertEqual((model_options_new. + outputs_to_num_classes[common.OUTPUT_TYPE]), + num_classes_new) + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/__init__.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/dense_prediction_cell.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/dense_prediction_cell.py new file mode 100644 index 0000000..c149858 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/dense_prediction_cell.py @@ -0,0 +1,288 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Dense Prediction Cell class that can be evolved in semantic segmentation. + +DensePredictionCell is used as a `layer` in semantic segmentation whose +architecture is determined by the `config`, a dictionary specifying +the architecture. +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from deeplab.core import utils + +slim = tf.contrib.slim + +# Local constants. +_META_ARCHITECTURE_SCOPE = 'meta_architecture' +_CONCAT_PROJECTION_SCOPE = 'concat_projection' +_OP = 'op' +_CONV = 'conv' +_PYRAMID_POOLING = 'pyramid_pooling' +_KERNEL = 'kernel' +_RATE = 'rate' +_GRID_SIZE = 'grid_size' +_TARGET_SIZE = 'target_size' +_INPUT = 'input' + + +def dense_prediction_cell_hparams(): + """DensePredictionCell HParams. + + Returns: + A dictionary of hyper-parameters used for dense prediction cell with keys: + - reduction_size: Integer, the number of output filters for each operation + inside the cell. + - dropout_on_concat_features: Boolean, apply dropout on the concatenated + features or not. + - dropout_on_projection_features: Boolean, apply dropout on the projection + features or not. + - dropout_keep_prob: Float, when `dropout_on_concat_features' or + `dropout_on_projection_features' is True, the `keep_prob` value used + in the dropout operation. + - concat_channels: Integer, the concatenated features will be + channel-reduced to `concat_channels` channels. + - conv_rate_multiplier: Integer, used to multiply the convolution rates. + This is useful in the case when the output_stride is changed from 16 + to 8, we need to double the convolution rates correspondingly. + """ + return { + 'reduction_size': 256, + 'dropout_on_concat_features': True, + 'dropout_on_projection_features': False, + 'dropout_keep_prob': 0.9, + 'concat_channels': 256, + 'conv_rate_multiplier': 1, + } + + +class DensePredictionCell(object): + """DensePredictionCell class used as a 'layer' in semantic segmentation.""" + + def __init__(self, config, hparams=None): + """Initializes the dense prediction cell. + + Args: + config: A dictionary storing the architecture of a dense prediction cell. + hparams: A dictionary of hyper-parameters, provided by users. This + dictionary will be used to update the default dictionary returned by + dense_prediction_cell_hparams(). + + Raises: + ValueError: If `conv_rate_multiplier` has value < 1. + """ + self.hparams = dense_prediction_cell_hparams() + if hparams is not None: + self.hparams.update(hparams) + self.config = config + + # Check values in hparams are valid or not. + if self.hparams['conv_rate_multiplier'] < 1: + raise ValueError('conv_rate_multiplier cannot have value < 1.') + + def _get_pyramid_pooling_arguments( + self, crop_size, output_stride, image_grid, image_pooling_crop_size=None): + """Gets arguments for pyramid pooling. + + Args: + crop_size: A list of two integers, [crop_height, crop_width] specifying + whole patch crop size. + output_stride: Integer, output stride value for extracted features. + image_grid: A list of two integers, [image_grid_height, image_grid_width], + specifying the grid size of how the pyramid pooling will be performed. + image_pooling_crop_size: A list of two integers, [crop_height, crop_width] + specifying the crop size for image pooling operations. Note that we + decouple whole patch crop_size and image_pooling_crop_size as one could + perform the image_pooling with different crop sizes. + + Returns: + A list of (resize_value, pooled_kernel) + """ + resize_height = utils.scale_dimension(crop_size[0], 1. / output_stride) + resize_width = utils.scale_dimension(crop_size[1], 1. / output_stride) + # If image_pooling_crop_size is not specified, use crop_size. + if image_pooling_crop_size is None: + image_pooling_crop_size = crop_size + pooled_height = utils.scale_dimension( + image_pooling_crop_size[0], 1. / (output_stride * image_grid[0])) + pooled_width = utils.scale_dimension( + image_pooling_crop_size[1], 1. / (output_stride * image_grid[1])) + return ([resize_height, resize_width], [pooled_height, pooled_width]) + + def _parse_operation(self, config, crop_size, output_stride, + image_pooling_crop_size=None): + """Parses one operation. + + When 'operation' is 'pyramid_pooling', we compute the required + hyper-parameters and save in config. + + Args: + config: A dictionary storing required hyper-parameters for one + operation. + crop_size: A list of two integers, [crop_height, crop_width] specifying + whole patch crop size. + output_stride: Integer, output stride value for extracted features. + image_pooling_crop_size: A list of two integers, [crop_height, crop_width] + specifying the crop size for image pooling operations. Note that we + decouple whole patch crop_size and image_pooling_crop_size as one could + perform the image_pooling with different crop sizes. + + Returns: + A dictionary stores the related information for the operation. + """ + if config[_OP] == _PYRAMID_POOLING: + (config[_TARGET_SIZE], + config[_KERNEL]) = self._get_pyramid_pooling_arguments( + crop_size=crop_size, + output_stride=output_stride, + image_grid=config[_GRID_SIZE], + image_pooling_crop_size=image_pooling_crop_size) + + return config + + def build_cell(self, + features, + output_stride=16, + crop_size=None, + image_pooling_crop_size=None, + weight_decay=0.00004, + reuse=None, + is_training=False, + fine_tune_batch_norm=False, + scope=None): + """Builds the dense prediction cell based on the config. + + Args: + features: Input feature map of size [batch, height, width, channels]. + output_stride: Int, output stride at which the features were extracted. + crop_size: A list [crop_height, crop_width], determining the input + features resolution. + image_pooling_crop_size: A list of two integers, [crop_height, crop_width] + specifying the crop size for image pooling operations. Note that we + decouple whole patch crop_size and image_pooling_crop_size as one could + perform the image_pooling with different crop sizes. + weight_decay: Float, the weight decay for model variables. + reuse: Reuse the model variables or not. + is_training: Boolean, is training or not. + fine_tune_batch_norm: Boolean, fine-tuning batch norm parameters or not. + scope: Optional string, specifying the variable scope. + + Returns: + Features after passing through the constructed dense prediction cell with + shape = [batch, height, width, channels] where channels are determined + by `reduction_size` returned by dense_prediction_cell_hparams(). + + Raises: + ValueError: Use Convolution with kernel size not equal to 1x1 or 3x3 or + the operation is not recognized. + """ + batch_norm_params = { + 'is_training': is_training and fine_tune_batch_norm, + 'decay': 0.9997, + 'epsilon': 1e-5, + 'scale': True, + } + hparams = self.hparams + with slim.arg_scope( + [slim.conv2d, slim.separable_conv2d], + weights_regularizer=slim.l2_regularizer(weight_decay), + activation_fn=tf.nn.relu, + normalizer_fn=slim.batch_norm, + padding='SAME', + stride=1, + reuse=reuse): + with slim.arg_scope([slim.batch_norm], **batch_norm_params): + with tf.variable_scope(scope, _META_ARCHITECTURE_SCOPE, [features]): + depth = hparams['reduction_size'] + branch_logits = [] + for i, current_config in enumerate(self.config): + scope = 'branch%d' % i + current_config = self._parse_operation( + config=current_config, + crop_size=crop_size, + output_stride=output_stride, + image_pooling_crop_size=image_pooling_crop_size) + tf.logging.info(current_config) + if current_config[_INPUT] < 0: + operation_input = features + else: + operation_input = branch_logits[current_config[_INPUT]] + if current_config[_OP] == _CONV: + if current_config[_KERNEL] == [1, 1] or current_config[ + _KERNEL] == 1: + branch_logits.append( + slim.conv2d(operation_input, depth, 1, scope=scope)) + else: + conv_rate = [r * hparams['conv_rate_multiplier'] + for r in current_config[_RATE]] + branch_logits.append( + utils.split_separable_conv2d( + operation_input, + filters=depth, + kernel_size=current_config[_KERNEL], + rate=conv_rate, + weight_decay=weight_decay, + scope=scope)) + elif current_config[_OP] == _PYRAMID_POOLING: + pooled_features = slim.avg_pool2d( + operation_input, + kernel_size=current_config[_KERNEL], + stride=[1, 1], + padding='VALID') + pooled_features = slim.conv2d( + pooled_features, + depth, + 1, + scope=scope) + pooled_features = tf.image.resize_bilinear( + pooled_features, + current_config[_TARGET_SIZE], + align_corners=True) + # Set shape for resize_height/resize_width if they are not Tensor. + resize_height = current_config[_TARGET_SIZE][0] + resize_width = current_config[_TARGET_SIZE][1] + if isinstance(resize_height, tf.Tensor): + resize_height = None + if isinstance(resize_width, tf.Tensor): + resize_width = None + pooled_features.set_shape( + [None, resize_height, resize_width, depth]) + branch_logits.append(pooled_features) + else: + raise ValueError('Unrecognized operation.') + # Merge branch logits. + concat_logits = tf.concat(branch_logits, 3) + if self.hparams['dropout_on_concat_features']: + concat_logits = slim.dropout( + concat_logits, + keep_prob=self.hparams['dropout_keep_prob'], + is_training=is_training, + scope=_CONCAT_PROJECTION_SCOPE + '_dropout') + concat_logits = slim.conv2d(concat_logits, + self.hparams['concat_channels'], + 1, + scope=_CONCAT_PROJECTION_SCOPE) + if self.hparams['dropout_on_projection_features']: + concat_logits = slim.dropout( + concat_logits, + keep_prob=self.hparams['dropout_keep_prob'], + is_training=is_training, + scope=_CONCAT_PROJECTION_SCOPE + '_dropout') + return concat_logits \ No newline at end of file diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/dense_prediction_cell_branch5_top1_cityscapes.json b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/dense_prediction_cell_branch5_top1_cityscapes.json new file mode 100644 index 0000000..12b093d --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/dense_prediction_cell_branch5_top1_cityscapes.json @@ -0,0 +1 @@ +[{"kernel": 3, "rate": [1, 6], "op": "conv", "input": -1}, {"kernel": 3, "rate": [18, 15], "op": "conv", "input": 0}, {"kernel": 3, "rate": [6, 3], "op": "conv", "input": 1}, {"kernel": 3, "rate": [1, 1], "op": "conv", "input": 0}, {"kernel": 3, "rate": [6, 21], "op": "conv", "input": 0}] \ No newline at end of file diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/dense_prediction_cell_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/dense_prediction_cell_test.py new file mode 100644 index 0000000..9ae84ae --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/dense_prediction_cell_test.py @@ -0,0 +1,135 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Tests for dense_prediction_cell.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from deeplab.core import dense_prediction_cell + + +class DensePredictionCellTest(tf.test.TestCase): + + def setUp(self): + self.segmentation_layer = dense_prediction_cell.DensePredictionCell( + config=[ + { + dense_prediction_cell._INPUT: -1, + dense_prediction_cell._OP: dense_prediction_cell._CONV, + dense_prediction_cell._KERNEL: 1, + }, + { + dense_prediction_cell._INPUT: 0, + dense_prediction_cell._OP: dense_prediction_cell._CONV, + dense_prediction_cell._KERNEL: 3, + dense_prediction_cell._RATE: [1, 3], + }, + { + dense_prediction_cell._INPUT: 1, + dense_prediction_cell._OP: ( + dense_prediction_cell._PYRAMID_POOLING), + dense_prediction_cell._GRID_SIZE: [1, 2], + }, + ], + hparams={'conv_rate_multiplier': 2}) + + def testPyramidPoolingArguments(self): + features_size, pooled_kernel = ( + self.segmentation_layer._get_pyramid_pooling_arguments( + crop_size=[513, 513], + output_stride=16, + image_grid=[4, 4])) + self.assertListEqual(features_size, [33, 33]) + self.assertListEqual(pooled_kernel, [9, 9]) + + def testPyramidPoolingArgumentsWithImageGrid1x1(self): + features_size, pooled_kernel = ( + self.segmentation_layer._get_pyramid_pooling_arguments( + crop_size=[257, 257], + output_stride=16, + image_grid=[1, 1])) + self.assertListEqual(features_size, [17, 17]) + self.assertListEqual(pooled_kernel, [17, 17]) + + def testParseOperationStringWithConv1x1(self): + operation = self.segmentation_layer._parse_operation( + config={ + dense_prediction_cell._OP: dense_prediction_cell._CONV, + dense_prediction_cell._KERNEL: [1, 1], + }, + crop_size=[513, 513], output_stride=16) + self.assertEqual(operation[dense_prediction_cell._OP], + dense_prediction_cell._CONV) + self.assertListEqual(operation[dense_prediction_cell._KERNEL], [1, 1]) + + def testParseOperationStringWithConv3x3(self): + operation = self.segmentation_layer._parse_operation( + config={ + dense_prediction_cell._OP: dense_prediction_cell._CONV, + dense_prediction_cell._KERNEL: [3, 3], + dense_prediction_cell._RATE: [9, 6], + }, + crop_size=[513, 513], output_stride=16) + self.assertEqual(operation[dense_prediction_cell._OP], + dense_prediction_cell._CONV) + self.assertListEqual(operation[dense_prediction_cell._KERNEL], [3, 3]) + self.assertEqual(operation[dense_prediction_cell._RATE], [9, 6]) + + def testParseOperationStringWithPyramidPooling2x2(self): + operation = self.segmentation_layer._parse_operation( + config={ + dense_prediction_cell._OP: dense_prediction_cell._PYRAMID_POOLING, + dense_prediction_cell._GRID_SIZE: [2, 2], + }, + crop_size=[513, 513], + output_stride=16) + self.assertEqual(operation[dense_prediction_cell._OP], + dense_prediction_cell._PYRAMID_POOLING) + # The feature maps of size [33, 33] should be covered by 2x2 kernels with + # size [17, 17]. + self.assertListEqual( + operation[dense_prediction_cell._TARGET_SIZE], [33, 33]) + self.assertListEqual(operation[dense_prediction_cell._KERNEL], [17, 17]) + + def testBuildCell(self): + with self.test_session(graph=tf.Graph()) as sess: + features = tf.random_normal([2, 33, 33, 5]) + concat_logits = self.segmentation_layer.build_cell( + features, + output_stride=8, + crop_size=[257, 257]) + sess.run(tf.global_variables_initializer()) + concat_logits = sess.run(concat_logits) + self.assertTrue(concat_logits.any()) + + def testBuildCellWithImagePoolingCropSize(self): + with self.test_session(graph=tf.Graph()) as sess: + features = tf.random_normal([2, 33, 33, 5]) + concat_logits = self.segmentation_layer.build_cell( + features, + output_stride=8, + crop_size=[257, 257], + image_pooling_crop_size=[129, 129]) + sess.run(tf.global_variables_initializer()) + concat_logits = sess.run(concat_logits) + self.assertTrue(concat_logits.any()) + + +if __name__ == '__main__': + tf.test.main() \ No newline at end of file diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/feature_extractor.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/feature_extractor.py new file mode 100644 index 0000000..da89dfe --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/feature_extractor.py @@ -0,0 +1,330 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Extracts features for different models.""" +import functools +import tensorflow as tf + +from deeplab.core import resnet_v1_beta +from deeplab.core import xception +from tensorflow.contrib.slim.nets import resnet_utils +from nets.mobilenet import mobilenet_v2 + + +slim = tf.contrib.slim + +# Default end point for MobileNetv2. +_MOBILENET_V2_FINAL_ENDPOINT = 'layer_18' + + +def _mobilenet_v2(net, + depth_multiplier, + output_stride, + reuse=None, + scope=None, + final_endpoint=None): + """Auxiliary function to add support for 'reuse' to mobilenet_v2. + + Args: + net: Input tensor of shape [batch_size, height, width, channels]. + depth_multiplier: Float multiplier for the depth (number of channels) + for all convolution ops. The value must be greater than zero. Typical + usage will be to set this value in (0, 1) to reduce the number of + parameters or computation cost of the model. + output_stride: An integer that specifies the requested ratio of input to + output spatial resolution. If not None, then we invoke atrous convolution + if necessary to prevent the network from reducing the spatial resolution + of the activation maps. Allowed values are 8 (accurate fully convolutional + mode), 16 (fast fully convolutional mode), 32 (classification mode). + reuse: Reuse model variables. + scope: Optional variable scope. + final_endpoint: The endpoint to construct the network up to. + + Returns: + Features extracted by MobileNetv2. + """ + with tf.variable_scope( + scope, 'MobilenetV2', [net], reuse=reuse) as scope: + return mobilenet_v2.mobilenet_base( + net, + conv_defs=mobilenet_v2.V2_DEF, + depth_multiplier=depth_multiplier, + min_depth=8 if depth_multiplier == 1.0 else 1, + divisible_by=8 if depth_multiplier == 1.0 else 1, + final_endpoint=final_endpoint or _MOBILENET_V2_FINAL_ENDPOINT, + output_stride=output_stride, + scope=scope) + + +# A map from network name to network function. +networks_map = { + 'mobilenet_v2': _mobilenet_v2, + 'resnet_v1_50': resnet_v1_beta.resnet_v1_50, + 'resnet_v1_50_beta': resnet_v1_beta.resnet_v1_50_beta, + 'resnet_v1_101': resnet_v1_beta.resnet_v1_101, + 'resnet_v1_101_beta': resnet_v1_beta.resnet_v1_101_beta, + 'xception_41': xception.xception_41, + 'xception_65': xception.xception_65, + 'xception_71': xception.xception_71, +} + +# A map from network name to network arg scope. +arg_scopes_map = { + 'mobilenet_v2': mobilenet_v2.training_scope, + 'resnet_v1_50': resnet_utils.resnet_arg_scope, + 'resnet_v1_50_beta': resnet_utils.resnet_arg_scope, + 'resnet_v1_101': resnet_utils.resnet_arg_scope, + 'resnet_v1_101_beta': resnet_utils.resnet_arg_scope, + 'xception_41': xception.xception_arg_scope, + 'xception_65': xception.xception_arg_scope, + 'xception_71': xception.xception_arg_scope, +} + +# Names for end point features. +DECODER_END_POINTS = 'decoder_end_points' + +# A dictionary from network name to a map of end point features. +networks_to_feature_maps = { + 'mobilenet_v2': { + DECODER_END_POINTS: ['layer_4/depthwise_output'], + }, + 'resnet_v1_50': { + DECODER_END_POINTS: ['block1/unit_2/bottleneck_v1/conv3'], + }, + 'resnet_v1_50_beta': { + DECODER_END_POINTS: ['block1/unit_2/bottleneck_v1/conv3'], + }, + 'resnet_v1_101': { + DECODER_END_POINTS: ['block1/unit_2/bottleneck_v1/conv3'], + }, + 'resnet_v1_101_beta': { + DECODER_END_POINTS: ['block1/unit_2/bottleneck_v1/conv3'], + }, + 'xception_41': { + DECODER_END_POINTS: [ + 'entry_flow/block2/unit_1/xception_module/' + 'separable_conv2_pointwise', + ], + }, + 'xception_65': { + DECODER_END_POINTS: [ + 'entry_flow/block2/unit_1/xception_module/' + 'separable_conv2_pointwise', + ], + }, + 'xception_71': { + DECODER_END_POINTS: [ + 'entry_flow/block3/unit_1/xception_module/' + 'separable_conv2_pointwise', + ], + }, +} + +# A map from feature extractor name to the network name scope used in the +# ImageNet pretrained versions of these models. +name_scope = { + 'mobilenet_v2': 'MobilenetV2', + 'resnet_v1_50': 'resnet_v1_50', + 'resnet_v1_50_beta': 'resnet_v1_50', + 'resnet_v1_101': 'resnet_v1_101', + 'resnet_v1_101_beta': 'resnet_v1_101', + 'xception_41': 'xception_41', + 'xception_65': 'xception_65', + 'xception_71': 'xception_71', +} + +# Mean pixel value. +_MEAN_RGB = [123.15, 115.90, 103.06] + + +def _preprocess_subtract_imagenet_mean(inputs): + """Subtract Imagenet mean RGB value.""" + mean_rgb = tf.reshape(_MEAN_RGB, [1, 1, 1, 3]) + return inputs - mean_rgb + + +def _preprocess_zero_mean_unit_range(inputs): + """Map image values from [0, 255] to [-1, 1].""" + return (2.0 / 255.0) * tf.to_float(inputs) - 1.0 + + +_PREPROCESS_FN = { + 'mobilenet_v2': _preprocess_zero_mean_unit_range, + 'resnet_v1_50': _preprocess_subtract_imagenet_mean, + 'resnet_v1_50_beta': _preprocess_zero_mean_unit_range, + 'resnet_v1_101': _preprocess_subtract_imagenet_mean, + 'resnet_v1_101_beta': _preprocess_zero_mean_unit_range, + 'xception_41': _preprocess_zero_mean_unit_range, + 'xception_65': _preprocess_zero_mean_unit_range, + 'xception_71': _preprocess_zero_mean_unit_range, +} + + +def mean_pixel(model_variant=None): + """Gets mean pixel value. + + This function returns different mean pixel value, depending on the input + model_variant which adopts different preprocessing functions. We currently + handle the following preprocessing functions: + (1) _preprocess_subtract_imagenet_mean. We simply return mean pixel value. + (2) _preprocess_zero_mean_unit_range. We return [127.5, 127.5, 127.5]. + The return values are used in a way that the padded regions after + pre-processing will contain value 0. + + Args: + model_variant: Model variant (string) for feature extraction. For + backwards compatibility, model_variant=None returns _MEAN_RGB. + + Returns: + Mean pixel value. + """ + if model_variant in ['resnet_v1_50', + 'resnet_v1_101'] or model_variant is None: + return _MEAN_RGB + else: + return [127.5, 127.5, 127.5] + + +def extract_features(images, + output_stride=8, + multi_grid=None, + depth_multiplier=1.0, + final_endpoint=None, + model_variant=None, + weight_decay=0.0001, + reuse=None, + is_training=False, + fine_tune_batch_norm=False, + regularize_depthwise=False, + preprocess_images=True, + num_classes=None, + global_pool=False): + """Extracts features by the particular model_variant. + + Args: + images: A tensor of size [batch, height, width, channels]. + output_stride: The ratio of input to output spatial resolution. + multi_grid: Employ a hierarchy of different atrous rates within network. + depth_multiplier: Float multiplier for the depth (number of channels) + for all convolution ops used in MobileNet. + final_endpoint: The MobileNet endpoint to construct the network up to. + model_variant: Model variant for feature extraction. + weight_decay: The weight decay for model variables. + reuse: Reuse the model variables or not. + is_training: Is training or not. + fine_tune_batch_norm: Fine-tune the batch norm parameters or not. + regularize_depthwise: Whether or not apply L2-norm regularization on the + depthwise convolution weights. + preprocess_images: Performs preprocessing on images or not. Defaults to + True. Set to False if preprocessing will be done by other functions. We + supprot two types of preprocessing: (1) Mean pixel substraction and (2) + Pixel values normalization to be [-1, 1]. + num_classes: Number of classes for image classification task. Defaults + to None for dense prediction tasks. + global_pool: Global pooling for image classification task. Defaults to + False, since dense prediction tasks do not use this. + + Returns: + features: A tensor of size [batch, feature_height, feature_width, + feature_channels], where feature_height/feature_width are determined + by the images height/width and output_stride. + end_points: A dictionary from components of the network to the corresponding + activation. + + Raises: + ValueError: Unrecognized model variant. + """ + if 'resnet' in model_variant: + arg_scope = arg_scopes_map[model_variant]( + weight_decay=weight_decay, + batch_norm_decay=0.95, + batch_norm_epsilon=1e-5, + batch_norm_scale=True) + features, end_points = get_network( + model_variant, preprocess_images, arg_scope)( + inputs=images, + num_classes=num_classes, + is_training=(is_training and fine_tune_batch_norm), + global_pool=global_pool, + output_stride=output_stride, + multi_grid=multi_grid, + reuse=reuse, + scope=name_scope[model_variant]) + elif 'xception' in model_variant: + arg_scope = arg_scopes_map[model_variant]( + weight_decay=weight_decay, + batch_norm_decay=0.9997, + batch_norm_epsilon=1e-3, + batch_norm_scale=True, + regularize_depthwise=regularize_depthwise) + features, end_points = get_network( + model_variant, preprocess_images, arg_scope)( + inputs=images, + num_classes=num_classes, + is_training=(is_training and fine_tune_batch_norm), + global_pool=global_pool, + output_stride=output_stride, + regularize_depthwise=regularize_depthwise, + multi_grid=multi_grid, + reuse=reuse, + scope=name_scope[model_variant]) + elif 'mobilenet' in model_variant: + arg_scope = arg_scopes_map[model_variant]( + is_training=(is_training and fine_tune_batch_norm), + weight_decay=weight_decay) + features, end_points = get_network( + model_variant, preprocess_images, arg_scope)( + inputs=images, + depth_multiplier=depth_multiplier, + output_stride=output_stride, + reuse=reuse, + scope=name_scope[model_variant], + final_endpoint=final_endpoint) + else: + raise ValueError('Unknown model variant %s.' % model_variant) + + return features, end_points + + +def get_network(network_name, preprocess_images, arg_scope=None): + """Gets the network. + + Args: + network_name: Network name. + preprocess_images: Preprocesses the images or not. + arg_scope: Optional, arg_scope to build the network. If not provided the + default arg_scope of the network would be used. + + Returns: + A network function that is used to extract features. + + Raises: + ValueError: network is not supported. + """ + if network_name not in networks_map: + raise ValueError('Unsupported network %s.' % network_name) + arg_scope = arg_scope or arg_scopes_map[network_name]() + def _identity_function(inputs): + return inputs + if preprocess_images: + preprocess_function = _PREPROCESS_FN[network_name] + else: + preprocess_function = _identity_function + func = networks_map[network_name] + @functools.wraps(func) + def network_fn(inputs, *args, **kwargs): + with slim.arg_scope(arg_scope): + return func(preprocess_function(inputs), *args, **kwargs) + return network_fn diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/preprocess_utils.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/preprocess_utils.py new file mode 100644 index 0000000..f602650 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/preprocess_utils.py @@ -0,0 +1,445 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Utility functions related to preprocessing inputs.""" +import tensorflow as tf + + +def flip_dim(tensor_list, prob=0.5, dim=1): + """Randomly flips a dimension of the given tensor. + + The decision to randomly flip the `Tensors` is made together. In other words, + all or none of the images pass in are flipped. + + Note that tf.random_flip_left_right and tf.random_flip_up_down isn't used so + that we can control for the probability as well as ensure the same decision + is applied across the images. + + Args: + tensor_list: A list of `Tensors` with the same number of dimensions. + prob: The probability of a left-right flip. + dim: The dimension to flip, 0, 1, .. + + Returns: + outputs: A list of the possibly flipped `Tensors` as well as an indicator + `Tensor` at the end whose value is `True` if the inputs were flipped and + `False` otherwise. + + Raises: + ValueError: If dim is negative or greater than the dimension of a `Tensor`. + """ + random_value = tf.random_uniform([]) + + def flip(): + flipped = [] + for tensor in tensor_list: + if dim < 0 or dim >= len(tensor.get_shape().as_list()): + raise ValueError('dim must represent a valid dimension.') + flipped.append(tf.reverse_v2(tensor, [dim])) + return flipped + + is_flipped = tf.less_equal(random_value, prob) + outputs = tf.cond(is_flipped, flip, lambda: tensor_list) + if not isinstance(outputs, (list, tuple)): + outputs = [outputs] + outputs.append(is_flipped) + + return outputs + + +def pad_to_bounding_box(image, offset_height, offset_width, target_height, + target_width, pad_value): + """Pads the given image with the given pad_value. + + Works like tf.image.pad_to_bounding_box, except it can pad the image + with any given arbitrary pad value and also handle images whose sizes are not + known during graph construction. + + Args: + image: 3-D tensor with shape [height, width, channels] + offset_height: Number of rows of zeros to add on top. + offset_width: Number of columns of zeros to add on the left. + target_height: Height of output image. + target_width: Width of output image. + pad_value: Value to pad the image tensor with. + + Returns: + 3-D tensor of shape [target_height, target_width, channels]. + + Raises: + ValueError: If the shape of image is incompatible with the offset_* or + target_* arguments. + """ + image_rank = tf.rank(image) + image_rank_assert = tf.Assert( + tf.equal(image_rank, 3), + ['Wrong image tensor rank [Expected] [Actual]', + 3, image_rank]) + with tf.control_dependencies([image_rank_assert]): + image -= pad_value + image_shape = tf.shape(image) + height, width = image_shape[0], image_shape[1] + target_width_assert = tf.Assert( + tf.greater_equal( + target_width, width), + ['target_width must be >= width']) + target_height_assert = tf.Assert( + tf.greater_equal(target_height, height), + ['target_height must be >= height']) + with tf.control_dependencies([target_width_assert]): + after_padding_width = target_width - offset_width - width + with tf.control_dependencies([target_height_assert]): + after_padding_height = target_height - offset_height - height + offset_assert = tf.Assert( + tf.logical_and( + tf.greater_equal(after_padding_width, 0), + tf.greater_equal(after_padding_height, 0)), + ['target size not possible with the given target offsets']) + + height_params = tf.stack([offset_height, after_padding_height]) + width_params = tf.stack([offset_width, after_padding_width]) + channel_params = tf.stack([0, 0]) + with tf.control_dependencies([offset_assert]): + paddings = tf.stack([height_params, width_params, channel_params]) + padded = tf.pad(image, paddings) + return padded + pad_value + + +def _crop(image, offset_height, offset_width, crop_height, crop_width): + """Crops the given image using the provided offsets and sizes. + + Note that the method doesn't assume we know the input image size but it does + assume we know the input image rank. + + Args: + image: an image of shape [height, width, channels]. + offset_height: a scalar tensor indicating the height offset. + offset_width: a scalar tensor indicating the width offset. + crop_height: the height of the cropped image. + crop_width: the width of the cropped image. + + Returns: + The cropped (and resized) image. + + Raises: + ValueError: if `image` doesn't have rank of 3. + InvalidArgumentError: if the rank is not 3 or if the image dimensions are + less than the crop size. + """ + original_shape = tf.shape(image) + + if len(image.get_shape().as_list()) != 3: + raise ValueError('input must have rank of 3') + original_channels = image.get_shape().as_list()[2] + + rank_assertion = tf.Assert( + tf.equal(tf.rank(image), 3), + ['Rank of image must be equal to 3.']) + with tf.control_dependencies([rank_assertion]): + cropped_shape = tf.stack([crop_height, crop_width, original_shape[2]]) + + size_assertion = tf.Assert( + tf.logical_and( + tf.greater_equal(original_shape[0], crop_height), + tf.greater_equal(original_shape[1], crop_width)), + ['Crop size greater than the image size.']) + + offsets = tf.to_int32(tf.stack([offset_height, offset_width, 0])) + + # Use tf.slice instead of crop_to_bounding box as it accepts tensors to + # define the crop size. + with tf.control_dependencies([size_assertion]): + image = tf.slice(image, offsets, cropped_shape) + image = tf.reshape(image, cropped_shape) + image.set_shape([crop_height, crop_width, original_channels]) + return image + + +def random_crop(image_list, crop_height, crop_width): + """Crops the given list of images. + + The function applies the same crop to each image in the list. This can be + effectively applied when there are multiple image inputs of the same + dimension such as: + + image, depths, normals = random_crop([image, depths, normals], 120, 150) + + Args: + image_list: a list of image tensors of the same dimension but possibly + varying channel. + crop_height: the new height. + crop_width: the new width. + + Returns: + the image_list with cropped images. + + Raises: + ValueError: if there are multiple image inputs provided with different size + or the images are smaller than the crop dimensions. + """ + if not image_list: + raise ValueError('Empty image_list.') + + # Compute the rank assertions. + rank_assertions = [] + for i in range(len(image_list)): + image_rank = tf.rank(image_list[i]) + rank_assert = tf.Assert( + tf.equal(image_rank, 3), + ['Wrong rank for tensor %s [expected] [actual]', + image_list[i].name, 3, image_rank]) + rank_assertions.append(rank_assert) + + with tf.control_dependencies([rank_assertions[0]]): + image_shape = tf.shape(image_list[0]) + image_height = image_shape[0] + image_width = image_shape[1] + crop_size_assert = tf.Assert( + tf.logical_and( + tf.greater_equal(image_height, crop_height), + tf.greater_equal(image_width, crop_width)), + ['Crop size greater than the image size.']) + + asserts = [rank_assertions[0], crop_size_assert] + + for i in range(1, len(image_list)): + image = image_list[i] + asserts.append(rank_assertions[i]) + with tf.control_dependencies([rank_assertions[i]]): + shape = tf.shape(image) + height = shape[0] + width = shape[1] + + height_assert = tf.Assert( + tf.equal(height, image_height), + ['Wrong height for tensor %s [expected][actual]', + image.name, height, image_height]) + width_assert = tf.Assert( + tf.equal(width, image_width), + ['Wrong width for tensor %s [expected][actual]', + image.name, width, image_width]) + asserts.extend([height_assert, width_assert]) + + # Create a random bounding box. + # + # Use tf.random_uniform and not numpy.random.rand as doing the former would + # generate random numbers at graph eval time, unlike the latter which + # generates random numbers at graph definition time. + with tf.control_dependencies(asserts): + max_offset_height = tf.reshape(image_height - crop_height + 1, []) + max_offset_width = tf.reshape(image_width - crop_width + 1, []) + offset_height = tf.random_uniform( + [], maxval=max_offset_height, dtype=tf.int32) + offset_width = tf.random_uniform( + [], maxval=max_offset_width, dtype=tf.int32) + + return [_crop(image, offset_height, offset_width, + crop_height, crop_width) for image in image_list] + + +def get_random_scale(min_scale_factor, max_scale_factor, step_size): + """Gets a random scale value. + + Args: + min_scale_factor: Minimum scale value. + max_scale_factor: Maximum scale value. + step_size: The step size from minimum to maximum value. + + Returns: + A random scale value selected between minimum and maximum value. + + Raises: + ValueError: min_scale_factor has unexpected value. + """ + if min_scale_factor < 0 or min_scale_factor > max_scale_factor: + raise ValueError('Unexpected value of min_scale_factor.') + + if min_scale_factor == max_scale_factor: + return tf.to_float(min_scale_factor) + + # When step_size = 0, we sample the value uniformly from [min, max). + if step_size == 0: + return tf.random_uniform([1], + minval=min_scale_factor, + maxval=max_scale_factor) + + # When step_size != 0, we randomly select one discrete value from [min, max]. + num_steps = int((max_scale_factor - min_scale_factor) / step_size + 1) + scale_factors = tf.lin_space(min_scale_factor, max_scale_factor, num_steps) + shuffled_scale_factors = tf.random_shuffle(scale_factors) + return shuffled_scale_factors[0] + + +def randomly_scale_image_and_label(image, label=None, scale=1.0): + """Randomly scales image and label. + + Args: + image: Image with shape [height, width, 3]. + label: Label with shape [height, width, 1]. + scale: The value to scale image and label. + + Returns: + Scaled image and label. + """ + # No random scaling if scale == 1. + if scale == 1.0: + return image, label + image_shape = tf.shape(image) + new_dim = tf.to_int32(tf.to_float([image_shape[0], image_shape[1]]) * scale) + + # Need squeeze and expand_dims because image interpolation takes + # 4D tensors as input. + image = tf.squeeze(tf.image.resize_bilinear( + tf.expand_dims(image, 0), + new_dim, + align_corners=True), [0]) + if label is not None: + label = tf.squeeze(tf.image.resize_nearest_neighbor( + tf.expand_dims(label, 0), + new_dim, + align_corners=True), [0]) + + return image, label + + +def resolve_shape(tensor, rank=None, scope=None): + """Fully resolves the shape of a Tensor. + + Use as much as possible the shape components already known during graph + creation and resolve the remaining ones during runtime. + + Args: + tensor: Input tensor whose shape we query. + rank: The rank of the tensor, provided that we know it. + scope: Optional name scope. + + Returns: + shape: The full shape of the tensor. + """ + with tf.name_scope(scope, 'resolve_shape', [tensor]): + if rank is not None: + shape = tensor.get_shape().with_rank(rank).as_list() + else: + shape = tensor.get_shape().as_list() + + if None in shape: + shape_dynamic = tf.shape(tensor) + for i in range(len(shape)): + if shape[i] is None: + shape[i] = shape_dynamic[i] + + return shape + + +def resize_to_range(image, + label=None, + min_size=None, + max_size=None, + factor=None, + align_corners=True, + label_layout_is_chw=False, + scope=None, + method=tf.image.ResizeMethod.BILINEAR): + """Resizes image or label so their sides are within the provided range. + + The output size can be described by two cases: + 1. If the image can be rescaled so its minimum size is equal to min_size + without the other side exceeding max_size, then do so. + 2. Otherwise, resize so the largest side is equal to max_size. + + An integer in `range(factor)` is added to the computed sides so that the + final dimensions are multiples of `factor` plus one. + + Args: + image: A 3D tensor of shape [height, width, channels]. + label: (optional) A 3D tensor of shape [height, width, channels] (default) + or [channels, height, width] when label_layout_is_chw = True. + min_size: (scalar) desired size of the smaller image side. + max_size: (scalar) maximum allowed size of the larger image side. Note + that the output dimension is no larger than max_size and may be slightly + smaller than min_size when factor is not None. + factor: Make output size multiple of factor plus one. + align_corners: If True, exactly align all 4 corners of input and output. + label_layout_is_chw: If true, the label has shape [channel, height, width]. + We support this case because for some instance segmentation dataset, the + instance segmentation is saved as [num_instances, height, width]. + scope: Optional name scope. + method: Image resize method. Defaults to tf.image.ResizeMethod.BILINEAR. + + Returns: + A 3-D tensor of shape [new_height, new_width, channels], where the image + has been resized (with the specified method) so that + min(new_height, new_width) == ceil(min_size) or + max(new_height, new_width) == ceil(max_size). + + Raises: + ValueError: If the image is not a 3D tensor. + """ + with tf.name_scope(scope, 'resize_to_range', [image]): + new_tensor_list = [] + min_size = tf.to_float(min_size) + if max_size is not None: + max_size = tf.to_float(max_size) + # Modify the max_size to be a multiple of factor plus 1 and make sure the + # max dimension after resizing is no larger than max_size. + if factor is not None: + max_size = (max_size + (factor - (max_size - 1) % factor) % factor + - factor) + + [orig_height, orig_width, _] = resolve_shape(image, rank=3) + orig_height = tf.to_float(orig_height) + orig_width = tf.to_float(orig_width) + orig_min_size = tf.minimum(orig_height, orig_width) + + # Calculate the larger of the possible sizes + large_scale_factor = min_size / orig_min_size + large_height = tf.to_int32(tf.ceil(orig_height * large_scale_factor)) + large_width = tf.to_int32(tf.ceil(orig_width * large_scale_factor)) + large_size = tf.stack([large_height, large_width]) + + new_size = large_size + if max_size is not None: + # Calculate the smaller of the possible sizes, use that if the larger + # is too big. + orig_max_size = tf.maximum(orig_height, orig_width) + small_scale_factor = max_size / orig_max_size + small_height = tf.to_int32(tf.ceil(orig_height * small_scale_factor)) + small_width = tf.to_int32(tf.ceil(orig_width * small_scale_factor)) + small_size = tf.stack([small_height, small_width]) + new_size = tf.cond( + tf.to_float(tf.reduce_max(large_size)) > max_size, + lambda: small_size, + lambda: large_size) + # Ensure that both output sides are multiples of factor plus one. + if factor is not None: + new_size += (factor - (new_size - 1) % factor) % factor + new_tensor_list.append(tf.image.resize_images( + image, new_size, method=method, align_corners=align_corners)) + if label is not None: + if label_layout_is_chw: + # Input label has shape [channel, height, width]. + resized_label = tf.expand_dims(label, 3) + resized_label = tf.image.resize_nearest_neighbor( + resized_label, new_size, align_corners=align_corners) + resized_label = tf.squeeze(resized_label, 3) + else: + # Input label has shape [height, width, channel]. + resized_label = tf.image.resize_images( + label, new_size, method=tf.image.ResizeMethod.NEAREST_NEIGHBOR, + align_corners=align_corners) + new_tensor_list.append(resized_label) + else: + new_tensor_list.append(None) + return new_tensor_list diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/preprocess_utils_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/preprocess_utils_test.py new file mode 100644 index 0000000..bca14d4 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/preprocess_utils_test.py @@ -0,0 +1,432 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Tests for preprocess_utils.""" +import numpy as np +import tensorflow as tf + +from tensorflow.python.framework import errors +from deeplab.core import preprocess_utils + + +class PreprocessUtilsTest(tf.test.TestCase): + + def testNoFlipWhenProbIsZero(self): + numpy_image = np.dstack([[[5., 6.], + [9., 0.]], + [[4., 3.], + [3., 5.]]]) + image = tf.convert_to_tensor(numpy_image) + + with self.test_session(): + actual, is_flipped = preprocess_utils.flip_dim([image], prob=0, dim=0) + self.assertAllEqual(numpy_image, actual.eval()) + self.assertAllEqual(False, is_flipped.eval()) + actual, is_flipped = preprocess_utils.flip_dim([image], prob=0, dim=1) + self.assertAllEqual(numpy_image, actual.eval()) + self.assertAllEqual(False, is_flipped.eval()) + actual, is_flipped = preprocess_utils.flip_dim([image], prob=0, dim=2) + self.assertAllEqual(numpy_image, actual.eval()) + self.assertAllEqual(False, is_flipped.eval()) + + def testFlipWhenProbIsOne(self): + numpy_image = np.dstack([[[5., 6.], + [9., 0.]], + [[4., 3.], + [3., 5.]]]) + dim0_flipped = np.dstack([[[9., 0.], + [5., 6.]], + [[3., 5.], + [4., 3.]]]) + dim1_flipped = np.dstack([[[6., 5.], + [0., 9.]], + [[3., 4.], + [5., 3.]]]) + dim2_flipped = np.dstack([[[4., 3.], + [3., 5.]], + [[5., 6.], + [9., 0.]]]) + image = tf.convert_to_tensor(numpy_image) + + with self.test_session(): + actual, is_flipped = preprocess_utils.flip_dim([image], prob=1, dim=0) + self.assertAllEqual(dim0_flipped, actual.eval()) + self.assertAllEqual(True, is_flipped.eval()) + actual, is_flipped = preprocess_utils.flip_dim([image], prob=1, dim=1) + self.assertAllEqual(dim1_flipped, actual.eval()) + self.assertAllEqual(True, is_flipped.eval()) + actual, is_flipped = preprocess_utils.flip_dim([image], prob=1, dim=2) + self.assertAllEqual(dim2_flipped, actual.eval()) + self.assertAllEqual(True, is_flipped.eval()) + + def testFlipMultipleImagesConsistentlyWhenProbIsOne(self): + numpy_image = np.dstack([[[5., 6.], + [9., 0.]], + [[4., 3.], + [3., 5.]]]) + numpy_label = np.dstack([[[0., 1.], + [2., 3.]]]) + image_dim1_flipped = np.dstack([[[6., 5.], + [0., 9.]], + [[3., 4.], + [5., 3.]]]) + label_dim1_flipped = np.dstack([[[1., 0.], + [3., 2.]]]) + image = tf.convert_to_tensor(numpy_image) + label = tf.convert_to_tensor(numpy_label) + + with self.test_session() as sess: + image, label, is_flipped = preprocess_utils.flip_dim( + [image, label], prob=1, dim=1) + actual_image, actual_label = sess.run([image, label]) + self.assertAllEqual(image_dim1_flipped, actual_image) + self.assertAllEqual(label_dim1_flipped, actual_label) + self.assertEqual(True, is_flipped.eval()) + + def testReturnRandomFlipsOnMultipleEvals(self): + numpy_image = np.dstack([[[5., 6.], + [9., 0.]], + [[4., 3.], + [3., 5.]]]) + dim1_flipped = np.dstack([[[6., 5.], + [0., 9.]], + [[3., 4.], + [5., 3.]]]) + image = tf.convert_to_tensor(numpy_image) + tf.set_random_seed(53) + + with self.test_session() as sess: + actual, is_flipped = preprocess_utils.flip_dim( + [image], prob=0.5, dim=1) + actual_image, actual_is_flipped = sess.run([actual, is_flipped]) + self.assertAllEqual(numpy_image, actual_image) + self.assertEqual(False, actual_is_flipped) + actual_image, actual_is_flipped = sess.run([actual, is_flipped]) + self.assertAllEqual(dim1_flipped, actual_image) + self.assertEqual(True, actual_is_flipped) + + def testReturnCorrectCropOfSingleImage(self): + np.random.seed(0) + + height, width = 10, 20 + image = np.random.randint(0, 256, size=(height, width, 3)) + + crop_height, crop_width = 2, 4 + + image_placeholder = tf.placeholder(tf.int32, shape=(None, None, 3)) + [cropped] = preprocess_utils.random_crop([image_placeholder], + crop_height, + crop_width) + + with self.test_session(): + cropped_image = cropped.eval(feed_dict={image_placeholder: image}) + + # Ensure we can find the cropped image in the original: + is_found = False + for x in range(0, width - crop_width + 1): + for y in range(0, height - crop_height + 1): + if np.isclose(image[y:y+crop_height, x:x+crop_width, :], + cropped_image).all(): + is_found = True + break + + self.assertTrue(is_found) + + def testRandomCropMaintainsNumberOfChannels(self): + np.random.seed(0) + + crop_height, crop_width = 10, 20 + image = np.random.randint(0, 256, size=(100, 200, 3)) + + tf.set_random_seed(37) + image_placeholder = tf.placeholder(tf.int32, shape=(None, None, 3)) + [cropped] = preprocess_utils.random_crop( + [image_placeholder], crop_height, crop_width) + + with self.test_session(): + cropped_image = cropped.eval(feed_dict={image_placeholder: image}) + self.assertTupleEqual(cropped_image.shape, (crop_height, crop_width, 3)) + + def testReturnDifferentCropAreasOnTwoEvals(self): + tf.set_random_seed(0) + + crop_height, crop_width = 2, 3 + image = np.random.randint(0, 256, size=(100, 200, 3)) + image_placeholder = tf.placeholder(tf.int32, shape=(None, None, 3)) + [cropped] = preprocess_utils.random_crop( + [image_placeholder], crop_height, crop_width) + + with self.test_session(): + crop0 = cropped.eval(feed_dict={image_placeholder: image}) + crop1 = cropped.eval(feed_dict={image_placeholder: image}) + self.assertFalse(np.isclose(crop0, crop1).all()) + + def testReturnConsistenCropsOfImagesInTheList(self): + tf.set_random_seed(0) + + height, width = 10, 20 + crop_height, crop_width = 2, 3 + labels = np.linspace(0, height * width-1, height * width) + labels = labels.reshape((height, width, 1)) + image = np.tile(labels, (1, 1, 3)) + + image_placeholder = tf.placeholder(tf.int32, shape=(None, None, 3)) + label_placeholder = tf.placeholder(tf.int32, shape=(None, None, 1)) + [cropped_image, cropped_label] = preprocess_utils.random_crop( + [image_placeholder, label_placeholder], crop_height, crop_width) + + with self.test_session() as sess: + cropped_image, cropped_labels = sess.run([cropped_image, cropped_label], + feed_dict={ + image_placeholder: image, + label_placeholder: labels}) + for i in range(3): + self.assertAllEqual(cropped_image[:, :, i], cropped_labels.squeeze()) + + def testDieOnRandomCropWhenImagesWithDifferentWidth(self): + crop_height, crop_width = 2, 3 + image1 = tf.placeholder(tf.float32, name='image1', shape=(None, None, 3)) + image2 = tf.placeholder(tf.float32, name='image2', shape=(None, None, 1)) + cropped = preprocess_utils.random_crop( + [image1, image2], crop_height, crop_width) + + with self.test_session() as sess: + with self.assertRaises(errors.InvalidArgumentError): + sess.run(cropped, feed_dict={image1: np.random.rand(4, 5, 3), + image2: np.random.rand(4, 6, 1)}) + + def testDieOnRandomCropWhenImagesWithDifferentHeight(self): + crop_height, crop_width = 2, 3 + image1 = tf.placeholder(tf.float32, name='image1', shape=(None, None, 3)) + image2 = tf.placeholder(tf.float32, name='image2', shape=(None, None, 1)) + cropped = preprocess_utils.random_crop( + [image1, image2], crop_height, crop_width) + + with self.test_session() as sess: + with self.assertRaisesWithPredicateMatch( + errors.InvalidArgumentError, + 'Wrong height for tensor'): + sess.run(cropped, feed_dict={image1: np.random.rand(4, 5, 3), + image2: np.random.rand(3, 5, 1)}) + + def testDieOnRandomCropWhenCropSizeIsGreaterThanImage(self): + crop_height, crop_width = 5, 9 + image1 = tf.placeholder(tf.float32, name='image1', shape=(None, None, 3)) + image2 = tf.placeholder(tf.float32, name='image2', shape=(None, None, 1)) + cropped = preprocess_utils.random_crop( + [image1, image2], crop_height, crop_width) + + with self.test_session() as sess: + with self.assertRaisesWithPredicateMatch( + errors.InvalidArgumentError, + 'Crop size greater than the image size.'): + sess.run(cropped, feed_dict={image1: np.random.rand(4, 5, 3), + image2: np.random.rand(4, 5, 1)}) + + def testReturnPaddedImageWithNonZeroPadValue(self): + for dtype in [np.int32, np.int64, np.float32, np.float64]: + image = np.dstack([[[5, 6], + [9, 0]], + [[4, 3], + [3, 5]]]).astype(dtype) + expected_image = np.dstack([[[255, 255, 255, 255, 255], + [255, 255, 255, 255, 255], + [255, 5, 6, 255, 255], + [255, 9, 0, 255, 255], + [255, 255, 255, 255, 255]], + [[255, 255, 255, 255, 255], + [255, 255, 255, 255, 255], + [255, 4, 3, 255, 255], + [255, 3, 5, 255, 255], + [255, 255, 255, 255, 255]]]).astype(dtype) + + with self.test_session(): + image_placeholder = tf.placeholder(tf.float32) + padded_image = preprocess_utils.pad_to_bounding_box( + image_placeholder, 2, 1, 5, 5, 255) + self.assertAllClose(padded_image.eval( + feed_dict={image_placeholder: image}), expected_image) + + def testReturnOriginalImageWhenTargetSizeIsEqualToImageSize(self): + image = np.dstack([[[5, 6], + [9, 0]], + [[4, 3], + [3, 5]]]) + + with self.test_session(): + image_placeholder = tf.placeholder(tf.float32) + padded_image = preprocess_utils.pad_to_bounding_box( + image_placeholder, 0, 0, 2, 2, 255) + self.assertAllClose(padded_image.eval( + feed_dict={image_placeholder: image}), image) + + def testDieOnTargetSizeGreaterThanImageSize(self): + image = np.dstack([[[5, 6], + [9, 0]], + [[4, 3], + [3, 5]]]) + with self.test_session(): + image_placeholder = tf.placeholder(tf.float32) + padded_image = preprocess_utils.pad_to_bounding_box( + image_placeholder, 0, 0, 2, 1, 255) + with self.assertRaisesWithPredicateMatch( + errors.InvalidArgumentError, + 'target_width must be >= width'): + padded_image.eval(feed_dict={image_placeholder: image}) + padded_image = preprocess_utils.pad_to_bounding_box( + image_placeholder, 0, 0, 1, 2, 255) + with self.assertRaisesWithPredicateMatch( + errors.InvalidArgumentError, + 'target_height must be >= height'): + padded_image.eval(feed_dict={image_placeholder: image}) + + def testDieIfTargetSizeNotPossibleWithGivenOffset(self): + image = np.dstack([[[5, 6], + [9, 0]], + [[4, 3], + [3, 5]]]) + with self.test_session(): + image_placeholder = tf.placeholder(tf.float32) + padded_image = preprocess_utils.pad_to_bounding_box( + image_placeholder, 3, 0, 4, 4, 255) + with self.assertRaisesWithPredicateMatch( + errors.InvalidArgumentError, + 'target size not possible with the given target offsets'): + padded_image.eval(feed_dict={image_placeholder: image}) + + def testDieIfImageTensorRankIsNotThree(self): + image = np.vstack([[5, 6], + [9, 0]]) + with self.test_session(): + image_placeholder = tf.placeholder(tf.float32) + padded_image = preprocess_utils.pad_to_bounding_box( + image_placeholder, 0, 0, 2, 2, 255) + with self.assertRaisesWithPredicateMatch( + errors.InvalidArgumentError, + 'Wrong image tensor rank'): + padded_image.eval(feed_dict={image_placeholder: image}) + + def testResizeTensorsToRange(self): + test_shapes = [[60, 40], + [15, 30], + [15, 50]] + min_size = 50 + max_size = 100 + factor = None + expected_shape_list = [(75, 50, 3), + (50, 100, 3), + (30, 100, 3)] + for i, test_shape in enumerate(test_shapes): + image = tf.random_normal([test_shape[0], test_shape[1], 3]) + new_tensor_list = preprocess_utils.resize_to_range( + image=image, + label=None, + min_size=min_size, + max_size=max_size, + factor=factor, + align_corners=True) + with self.test_session() as session: + resized_image = session.run(new_tensor_list[0]) + self.assertEqual(resized_image.shape, expected_shape_list[i]) + + def testResizeTensorsToRangeWithFactor(self): + test_shapes = [[60, 40], + [15, 30], + [15, 50]] + min_size = 50 + max_size = 98 + factor = 8 + expected_image_shape_list = [(81, 57, 3), + (49, 97, 3), + (33, 97, 3)] + expected_label_shape_list = [(81, 57, 1), + (49, 97, 1), + (33, 97, 1)] + for i, test_shape in enumerate(test_shapes): + image = tf.random_normal([test_shape[0], test_shape[1], 3]) + label = tf.random_normal([test_shape[0], test_shape[1], 1]) + new_tensor_list = preprocess_utils.resize_to_range( + image=image, + label=label, + min_size=min_size, + max_size=max_size, + factor=factor, + align_corners=True) + with self.test_session() as session: + new_tensor_list = session.run(new_tensor_list) + self.assertEqual(new_tensor_list[0].shape, expected_image_shape_list[i]) + self.assertEqual(new_tensor_list[1].shape, expected_label_shape_list[i]) + + def testResizeTensorsToRangeWithFactorAndLabelShapeCHW(self): + test_shapes = [[60, 40], + [15, 30], + [15, 50]] + min_size = 50 + max_size = 98 + factor = 8 + expected_image_shape_list = [(81, 57, 3), + (49, 97, 3), + (33, 97, 3)] + expected_label_shape_list = [(5, 81, 57), + (5, 49, 97), + (5, 33, 97)] + for i, test_shape in enumerate(test_shapes): + image = tf.random_normal([test_shape[0], test_shape[1], 3]) + label = tf.random_normal([5, test_shape[0], test_shape[1]]) + new_tensor_list = preprocess_utils.resize_to_range( + image=image, + label=label, + min_size=min_size, + max_size=max_size, + factor=factor, + align_corners=True, + label_layout_is_chw=True) + with self.test_session() as session: + new_tensor_list = session.run(new_tensor_list) + self.assertEqual(new_tensor_list[0].shape, expected_image_shape_list[i]) + self.assertEqual(new_tensor_list[1].shape, expected_label_shape_list[i]) + + def testResizeTensorsToRangeWithSimilarMinMaxSizes(self): + test_shapes = [[60, 40], + [15, 30], + [15, 50]] + # Values set so that one of the side = 97. + min_size = 96 + max_size = 98 + factor = 8 + expected_image_shape_list = [(97, 65, 3), + (49, 97, 3), + (33, 97, 3)] + expected_label_shape_list = [(97, 65, 1), + (49, 97, 1), + (33, 97, 1)] + for i, test_shape in enumerate(test_shapes): + image = tf.random_normal([test_shape[0], test_shape[1], 3]) + label = tf.random_normal([test_shape[0], test_shape[1], 1]) + new_tensor_list = preprocess_utils.resize_to_range( + image=image, + label=label, + min_size=min_size, + max_size=max_size, + factor=factor, + align_corners=True) + with self.test_session() as session: + new_tensor_list = session.run(new_tensor_list) + self.assertEqual(new_tensor_list[0].shape, expected_image_shape_list[i]) + self.assertEqual(new_tensor_list[1].shape, expected_label_shape_list[i]) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/resnet_v1_beta.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/resnet_v1_beta.py new file mode 100644 index 0000000..91b72e4 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/resnet_v1_beta.py @@ -0,0 +1,517 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Resnet v1 model variants. + +Code branched out from slim/nets/resnet_v1.py, and please refer to it for +more details. + +The original version ResNets-v1 were proposed by: +[1] Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun + Deep Residual Learning for Image Recognition. arXiv:1512.03385 +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import functools +import tensorflow as tf + +from tensorflow.contrib.slim.nets import resnet_utils + +slim = tf.contrib.slim + +_DEFAULT_MULTI_GRID = [1, 1, 1] + + +@slim.add_arg_scope +def bottleneck(inputs, + depth, + depth_bottleneck, + stride, + unit_rate=1, + rate=1, + outputs_collections=None, + scope=None): + """Bottleneck residual unit variant with BN after convolutions. + + This is the original residual unit proposed in [1]. See Fig. 1(a) of [2] for + its definition. Note that we use here the bottleneck variant which has an + extra bottleneck layer. + + When putting together two consecutive ResNet blocks that use this unit, one + should use stride = 2 in the last unit of the first block. + + Args: + inputs: A tensor of size [batch, height, width, channels]. + depth: The depth of the ResNet unit output. + depth_bottleneck: The depth of the bottleneck layers. + stride: The ResNet unit's stride. Determines the amount of downsampling of + the units output compared to its input. + unit_rate: An integer, unit rate for atrous convolution. + rate: An integer, rate for atrous convolution. + outputs_collections: Collection to add the ResNet unit output. + scope: Optional variable_scope. + + Returns: + The ResNet unit's output. + """ + with tf.variable_scope(scope, 'bottleneck_v1', [inputs]) as sc: + depth_in = slim.utils.last_dimension(inputs.get_shape(), min_rank=4) + if depth == depth_in: + shortcut = resnet_utils.subsample(inputs, stride, 'shortcut') + else: + shortcut = slim.conv2d( + inputs, + depth, + [1, 1], + stride=stride, + activation_fn=None, + scope='shortcut') + + residual = slim.conv2d(inputs, depth_bottleneck, [1, 1], stride=1, + scope='conv1') + residual = resnet_utils.conv2d_same(residual, depth_bottleneck, 3, stride, + rate=rate*unit_rate, scope='conv2') + residual = slim.conv2d(residual, depth, [1, 1], stride=1, + activation_fn=None, scope='conv3') + output = tf.nn.relu(shortcut + residual) + + return slim.utils.collect_named_outputs(outputs_collections, + sc.name, + output) + + +def root_block_fn_for_beta_variant(net): + """Gets root_block_fn for beta variant. + + ResNet-v1 beta variant modifies the first original 7x7 convolution to three + 3x3 convolutions. + + Args: + net: A tensor of size [batch, height, width, channels], input to the model. + + Returns: + A tensor after three 3x3 convolutions. + """ + net = resnet_utils.conv2d_same(net, 64, 3, stride=2, scope='conv1_1') + net = resnet_utils.conv2d_same(net, 64, 3, stride=1, scope='conv1_2') + net = resnet_utils.conv2d_same(net, 128, 3, stride=1, scope='conv1_3') + + return net + + +def resnet_v1_beta(inputs, + blocks, + num_classes=None, + is_training=None, + global_pool=True, + output_stride=None, + root_block_fn=None, + reuse=None, + scope=None): + """Generator for v1 ResNet models (beta variant). + + This function generates a family of modified ResNet v1 models. In particular, + the first original 7x7 convolution is replaced with three 3x3 convolutions. + See the resnet_v1_*() methods for specific model instantiations, obtained by + selecting different block instantiations that produce ResNets of various + depths. + + The code is modified from slim/nets/resnet_v1.py, and please refer to it for + more details. + + Args: + inputs: A tensor of size [batch, height_in, width_in, channels]. + blocks: A list of length equal to the number of ResNet blocks. Each element + is a resnet_utils.Block object describing the units in the block. + num_classes: Number of predicted classes for classification tasks. If None + we return the features before the logit layer. + is_training: Enable/disable is_training for batch normalization. + global_pool: If True, we perform global average pooling before computing the + logits. Set to True for image classification, False for dense prediction. + output_stride: If None, then the output will be computed at the nominal + network stride. If output_stride is not None, it specifies the requested + ratio of input to output spatial resolution. + root_block_fn: The function consisting of convolution operations applied to + the root input. If root_block_fn is None, use the original setting of + RseNet-v1, which is simply one convolution with 7x7 kernel and stride=2. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + + Returns: + net: A rank-4 tensor of size [batch, height_out, width_out, channels_out]. + If global_pool is False, then height_out and width_out are reduced by a + factor of output_stride compared to the respective height_in and width_in, + else both height_out and width_out equal one. If num_classes is None, then + net is the output of the last ResNet block, potentially after global + average pooling. If num_classes is not None, net contains the pre-softmax + activations. + end_points: A dictionary from components of the network to the corresponding + activation. + + Raises: + ValueError: If the target output_stride is not valid. + """ + if root_block_fn is None: + root_block_fn = functools.partial(resnet_utils.conv2d_same, + num_outputs=64, + kernel_size=7, + stride=2, + scope='conv1') + with tf.variable_scope(scope, 'resnet_v1', [inputs], reuse=reuse) as sc: + end_points_collection = sc.original_name_scope + '_end_points' + with slim.arg_scope([slim.conv2d, bottleneck, + resnet_utils.stack_blocks_dense], + outputs_collections=end_points_collection): + if is_training is not None: + arg_scope = slim.arg_scope([slim.batch_norm], is_training=is_training) + else: + arg_scope = slim.arg_scope([]) + with arg_scope: + net = inputs + if output_stride is not None: + if output_stride % 4 != 0: + raise ValueError('The output_stride needs to be a multiple of 4.') + output_stride /= 4 + net = root_block_fn(net) + net = slim.max_pool2d(net, 3, stride=2, padding='SAME', scope='pool1') + net = resnet_utils.stack_blocks_dense(net, blocks, output_stride) + + if global_pool: + # Global average pooling. + net = tf.reduce_mean(net, [1, 2], name='pool5', keepdims=True) + if num_classes is not None: + net = slim.conv2d(net, num_classes, [1, 1], activation_fn=None, + normalizer_fn=None, scope='logits') + # Convert end_points_collection into a dictionary of end_points. + end_points = slim.utils.convert_collection_to_dict( + end_points_collection) + if num_classes is not None: + end_points['predictions'] = slim.softmax(net, scope='predictions') + return net, end_points + + +def resnet_v1_beta_block(scope, base_depth, num_units, stride): + """Helper function for creating a resnet_v1 beta variant bottleneck block. + + Args: + scope: The scope of the block. + base_depth: The depth of the bottleneck layer for each unit. + num_units: The number of units in the block. + stride: The stride of the block, implemented as a stride in the last unit. + All other units have stride=1. + + Returns: + A resnet_v1 bottleneck block. + """ + return resnet_utils.Block(scope, bottleneck, [{ + 'depth': base_depth * 4, + 'depth_bottleneck': base_depth, + 'stride': 1, + 'unit_rate': 1 + }] * (num_units - 1) + [{ + 'depth': base_depth * 4, + 'depth_bottleneck': base_depth, + 'stride': stride, + 'unit_rate': 1 + }]) + + +def resnet_v1_50(inputs, + num_classes=None, + is_training=None, + global_pool=False, + output_stride=None, + multi_grid=None, + reuse=None, + scope='resnet_v1_50'): + """Resnet v1 50. + + Args: + inputs: A tensor of size [batch, height_in, width_in, channels]. + num_classes: Number of predicted classes for classification tasks. If None + we return the features before the logit layer. + is_training: Enable/disable is_training for batch normalization. + global_pool: If True, we perform global average pooling before computing the + logits. Set to True for image classification, False for dense prediction. + output_stride: If None, then the output will be computed at the nominal + network stride. If output_stride is not None, it specifies the requested + ratio of input to output spatial resolution. + multi_grid: Employ a hierarchy of different atrous rates within network. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + + Returns: + net: A rank-4 tensor of size [batch, height_out, width_out, channels_out]. + If global_pool is False, then height_out and width_out are reduced by a + factor of output_stride compared to the respective height_in and width_in, + else both height_out and width_out equal one. If num_classes is None, then + net is the output of the last ResNet block, potentially after global + average pooling. If num_classes is not None, net contains the pre-softmax + activations. + end_points: A dictionary from components of the network to the corresponding + activation. + + Raises: + ValueError: if multi_grid is not None and does not have length = 3. + """ + if multi_grid is None: + multi_grid = _DEFAULT_MULTI_GRID + else: + if len(multi_grid) != 3: + raise ValueError('Expect multi_grid to have length 3.') + + blocks = [ + resnet_v1_beta_block( + 'block1', base_depth=64, num_units=3, stride=2), + resnet_v1_beta_block( + 'block2', base_depth=128, num_units=4, stride=2), + resnet_v1_beta_block( + 'block3', base_depth=256, num_units=6, stride=2), + resnet_utils.Block('block4', bottleneck, [ + {'depth': 2048, + 'depth_bottleneck': 512, + 'stride': 1, + 'unit_rate': rate} for rate in multi_grid]), + ] + return resnet_v1_beta( + inputs, + blocks=blocks, + num_classes=num_classes, + is_training=is_training, + global_pool=global_pool, + output_stride=output_stride, + reuse=reuse, + scope=scope) + + +def resnet_v1_50_beta(inputs, + num_classes=None, + is_training=None, + global_pool=False, + output_stride=None, + multi_grid=None, + reuse=None, + scope='resnet_v1_50'): + """Resnet v1 50 beta variant. + + This variant modifies the first convolution layer of ResNet-v1-50. In + particular, it changes the original one 7x7 convolution to three 3x3 + convolutions. + + Args: + inputs: A tensor of size [batch, height_in, width_in, channels]. + num_classes: Number of predicted classes for classification tasks. If None + we return the features before the logit layer. + is_training: Enable/disable is_training for batch normalization. + global_pool: If True, we perform global average pooling before computing the + logits. Set to True for image classification, False for dense prediction. + output_stride: If None, then the output will be computed at the nominal + network stride. If output_stride is not None, it specifies the requested + ratio of input to output spatial resolution. + multi_grid: Employ a hierarchy of different atrous rates within network. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + + Returns: + net: A rank-4 tensor of size [batch, height_out, width_out, channels_out]. + If global_pool is False, then height_out and width_out are reduced by a + factor of output_stride compared to the respective height_in and width_in, + else both height_out and width_out equal one. If num_classes is None, then + net is the output of the last ResNet block, potentially after global + average pooling. If num_classes is not None, net contains the pre-softmax + activations. + end_points: A dictionary from components of the network to the corresponding + activation. + + Raises: + ValueError: if multi_grid is not None and does not have length = 3. + """ + if multi_grid is None: + multi_grid = _DEFAULT_MULTI_GRID + else: + if len(multi_grid) != 3: + raise ValueError('Expect multi_grid to have length 3.') + + blocks = [ + resnet_v1_beta_block( + 'block1', base_depth=64, num_units=3, stride=2), + resnet_v1_beta_block( + 'block2', base_depth=128, num_units=4, stride=2), + resnet_v1_beta_block( + 'block3', base_depth=256, num_units=6, stride=2), + resnet_utils.Block('block4', bottleneck, [ + {'depth': 2048, + 'depth_bottleneck': 512, + 'stride': 1, + 'unit_rate': rate} for rate in multi_grid]), + ] + return resnet_v1_beta( + inputs, + blocks=blocks, + num_classes=num_classes, + is_training=is_training, + global_pool=global_pool, + output_stride=output_stride, + root_block_fn=functools.partial(root_block_fn_for_beta_variant), + reuse=reuse, + scope=scope) + + +def resnet_v1_101(inputs, + num_classes=None, + is_training=None, + global_pool=False, + output_stride=None, + multi_grid=None, + reuse=None, + scope='resnet_v1_101'): + """Resnet v1 101. + + Args: + inputs: A tensor of size [batch, height_in, width_in, channels]. + num_classes: Number of predicted classes for classification tasks. If None + we return the features before the logit layer. + is_training: Enable/disable is_training for batch normalization. + global_pool: If True, we perform global average pooling before computing the + logits. Set to True for image classification, False for dense prediction. + output_stride: If None, then the output will be computed at the nominal + network stride. If output_stride is not None, it specifies the requested + ratio of input to output spatial resolution. + multi_grid: Employ a hierarchy of different atrous rates within network. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + + Returns: + net: A rank-4 tensor of size [batch, height_out, width_out, channels_out]. + If global_pool is False, then height_out and width_out are reduced by a + factor of output_stride compared to the respective height_in and width_in, + else both height_out and width_out equal one. If num_classes is None, then + net is the output of the last ResNet block, potentially after global + average pooling. If num_classes is not None, net contains the pre-softmax + activations. + end_points: A dictionary from components of the network to the corresponding + activation. + + Raises: + ValueError: if multi_grid is not None and does not have length = 3. + """ + if multi_grid is None: + multi_grid = _DEFAULT_MULTI_GRID + else: + if len(multi_grid) != 3: + raise ValueError('Expect multi_grid to have length 3.') + + blocks = [ + resnet_v1_beta_block( + 'block1', base_depth=64, num_units=3, stride=2), + resnet_v1_beta_block( + 'block2', base_depth=128, num_units=4, stride=2), + resnet_v1_beta_block( + 'block3', base_depth=256, num_units=23, stride=2), + resnet_utils.Block('block4', bottleneck, [ + {'depth': 2048, + 'depth_bottleneck': 512, + 'stride': 1, + 'unit_rate': rate} for rate in multi_grid]), + ] + return resnet_v1_beta( + inputs, + blocks=blocks, + num_classes=num_classes, + is_training=is_training, + global_pool=global_pool, + output_stride=output_stride, + reuse=reuse, + scope=scope) + + +def resnet_v1_101_beta(inputs, + num_classes=None, + is_training=None, + global_pool=False, + output_stride=None, + multi_grid=None, + reuse=None, + scope='resnet_v1_101'): + """Resnet v1 101 beta variant. + + This variant modifies the first convolution layer of ResNet-v1-101. In + particular, it changes the original one 7x7 convolution to three 3x3 + convolutions. + + Args: + inputs: A tensor of size [batch, height_in, width_in, channels]. + num_classes: Number of predicted classes for classification tasks. If None + we return the features before the logit layer. + is_training: Enable/disable is_training for batch normalization. + global_pool: If True, we perform global average pooling before computing the + logits. Set to True for image classification, False for dense prediction. + output_stride: If None, then the output will be computed at the nominal + network stride. If output_stride is not None, it specifies the requested + ratio of input to output spatial resolution. + multi_grid: Employ a hierarchy of different atrous rates within network. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + + Returns: + net: A rank-4 tensor of size [batch, height_out, width_out, channels_out]. + If global_pool is False, then height_out and width_out are reduced by a + factor of output_stride compared to the respective height_in and width_in, + else both height_out and width_out equal one. If num_classes is None, then + net is the output of the last ResNet block, potentially after global + average pooling. If num_classes is not None, net contains the pre-softmax + activations. + end_points: A dictionary from components of the network to the corresponding + activation. + + Raises: + ValueError: if multi_grid is not None and does not have length = 3. + """ + if multi_grid is None: + multi_grid = _DEFAULT_MULTI_GRID + else: + if len(multi_grid) != 3: + raise ValueError('Expect multi_grid to have length 3.') + + blocks = [ + resnet_v1_beta_block( + 'block1', base_depth=64, num_units=3, stride=2), + resnet_v1_beta_block( + 'block2', base_depth=128, num_units=4, stride=2), + resnet_v1_beta_block( + 'block3', base_depth=256, num_units=23, stride=2), + resnet_utils.Block('block4', bottleneck, [ + {'depth': 2048, + 'depth_bottleneck': 512, + 'stride': 1, + 'unit_rate': rate} for rate in multi_grid]), + ] + return resnet_v1_beta( + inputs, + blocks=blocks, + num_classes=num_classes, + is_training=is_training, + global_pool=global_pool, + output_stride=output_stride, + root_block_fn=functools.partial(root_block_fn_for_beta_variant), + reuse=reuse, + scope=scope) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/resnet_v1_beta_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/resnet_v1_beta_test.py new file mode 100644 index 0000000..49ea3ee --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/resnet_v1_beta_test.py @@ -0,0 +1,274 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Tests for resnet_v1_beta module.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import functools + +import numpy as np +import tensorflow as tf + +from deeplab.core import resnet_v1_beta +from tensorflow.contrib.slim.nets import resnet_utils + +slim = tf.contrib.slim + + +def create_test_input(batch, height, width, channels): + """Create test input tensor.""" + if None in [batch, height, width, channels]: + return tf.placeholder(tf.float32, (batch, height, width, channels)) + else: + return tf.to_float( + np.tile( + np.reshape( + np.reshape(np.arange(height), [height, 1]) + + np.reshape(np.arange(width), [1, width]), + [1, height, width, 1]), + [batch, 1, 1, channels])) + + +class ResnetCompleteNetworkTest(tf.test.TestCase): + """Tests with complete small ResNet v1 networks.""" + + def _resnet_small(self, + inputs, + num_classes=None, + is_training=True, + global_pool=True, + output_stride=None, + multi_grid=None, + reuse=None, + scope='resnet_v1_small'): + """A shallow and thin ResNet v1 for faster tests.""" + if multi_grid is None: + multi_grid = [1, 1, 1] + else: + if len(multi_grid) != 3: + raise ValueError('Expect multi_grid to have length 3.') + + block = resnet_v1_beta.resnet_v1_beta_block + blocks = [ + block('block1', base_depth=1, num_units=3, stride=2), + block('block2', base_depth=2, num_units=3, stride=2), + block('block3', base_depth=4, num_units=3, stride=2), + resnet_utils.Block('block4', resnet_v1_beta.bottleneck, [ + {'depth': 32, + 'depth_bottleneck': 8, + 'stride': 1, + 'unit_rate': rate} for rate in multi_grid])] + + return resnet_v1_beta.resnet_v1_beta( + inputs, + blocks, + num_classes=num_classes, + is_training=is_training, + global_pool=global_pool, + output_stride=output_stride, + root_block_fn=functools.partial( + resnet_v1_beta.root_block_fn_for_beta_variant), + reuse=reuse, + scope=scope) + + def testClassificationEndPoints(self): + global_pool = True + num_classes = 10 + inputs = create_test_input(2, 224, 224, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + logits, end_points = self._resnet_small(inputs, + num_classes, + global_pool=global_pool, + scope='resnet') + + self.assertTrue(logits.op.name.startswith('resnet/logits')) + self.assertListEqual(logits.get_shape().as_list(), [2, 1, 1, num_classes]) + self.assertTrue('predictions' in end_points) + self.assertListEqual(end_points['predictions'].get_shape().as_list(), + [2, 1, 1, num_classes]) + + def testClassificationEndPointsWithMultigrid(self): + global_pool = True + num_classes = 10 + inputs = create_test_input(2, 224, 224, 3) + multi_grid = [1, 2, 4] + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + logits, end_points = self._resnet_small(inputs, + num_classes, + global_pool=global_pool, + multi_grid=multi_grid, + scope='resnet') + + self.assertTrue(logits.op.name.startswith('resnet/logits')) + self.assertListEqual(logits.get_shape().as_list(), [2, 1, 1, num_classes]) + self.assertTrue('predictions' in end_points) + self.assertListEqual(end_points['predictions'].get_shape().as_list(), + [2, 1, 1, num_classes]) + + def testClassificationShapes(self): + global_pool = True + num_classes = 10 + inputs = create_test_input(2, 224, 224, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_small(inputs, + num_classes, + global_pool=global_pool, + scope='resnet') + endpoint_to_shape = { + 'resnet/conv1_1': [2, 112, 112, 64], + 'resnet/conv1_2': [2, 112, 112, 64], + 'resnet/conv1_3': [2, 112, 112, 128], + 'resnet/block1': [2, 28, 28, 4], + 'resnet/block2': [2, 14, 14, 8], + 'resnet/block3': [2, 7, 7, 16], + 'resnet/block4': [2, 7, 7, 32]} + for endpoint, shape in endpoint_to_shape.iteritems(): + self.assertListEqual(end_points[endpoint].get_shape().as_list(), shape) + + def testFullyConvolutionalEndpointShapes(self): + global_pool = False + num_classes = 10 + inputs = create_test_input(2, 321, 321, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_small(inputs, + num_classes, + global_pool=global_pool, + scope='resnet') + endpoint_to_shape = { + 'resnet/conv1_1': [2, 161, 161, 64], + 'resnet/conv1_2': [2, 161, 161, 64], + 'resnet/conv1_3': [2, 161, 161, 128], + 'resnet/block1': [2, 41, 41, 4], + 'resnet/block2': [2, 21, 21, 8], + 'resnet/block3': [2, 11, 11, 16], + 'resnet/block4': [2, 11, 11, 32]} + for endpoint, shape in endpoint_to_shape.iteritems(): + self.assertListEqual(end_points[endpoint].get_shape().as_list(), shape) + + def testAtrousFullyConvolutionalEndpointShapes(self): + global_pool = False + num_classes = 10 + output_stride = 8 + inputs = create_test_input(2, 321, 321, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_small(inputs, + num_classes, + global_pool=global_pool, + output_stride=output_stride, + scope='resnet') + endpoint_to_shape = { + 'resnet/conv1_1': [2, 161, 161, 64], + 'resnet/conv1_2': [2, 161, 161, 64], + 'resnet/conv1_3': [2, 161, 161, 128], + 'resnet/block1': [2, 41, 41, 4], + 'resnet/block2': [2, 41, 41, 8], + 'resnet/block3': [2, 41, 41, 16], + 'resnet/block4': [2, 41, 41, 32]} + for endpoint, shape in endpoint_to_shape.iteritems(): + self.assertListEqual(end_points[endpoint].get_shape().as_list(), shape) + + def testAtrousFullyConvolutionalValues(self): + """Verify dense feature extraction with atrous convolution.""" + nominal_stride = 32 + for output_stride in [4, 8, 16, 32, None]: + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + with tf.Graph().as_default(): + with self.test_session() as sess: + tf.set_random_seed(0) + inputs = create_test_input(2, 81, 81, 3) + # Dense feature extraction followed by subsampling. + output, _ = self._resnet_small(inputs, + None, + is_training=False, + global_pool=False, + output_stride=output_stride) + if output_stride is None: + factor = 1 + else: + factor = nominal_stride // output_stride + output = resnet_utils.subsample(output, factor) + # Make the two networks use the same weights. + tf.get_variable_scope().reuse_variables() + # Feature extraction at the nominal network rate. + expected, _ = self._resnet_small(inputs, + None, + is_training=False, + global_pool=False) + sess.run(tf.global_variables_initializer()) + self.assertAllClose(output.eval(), expected.eval(), + atol=1e-4, rtol=1e-4) + + def testUnknownBatchSize(self): + batch = 2 + height, width = 65, 65 + global_pool = True + num_classes = 10 + inputs = create_test_input(None, height, width, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + logits, _ = self._resnet_small(inputs, + num_classes, + global_pool=global_pool, + scope='resnet') + self.assertTrue(logits.op.name.startswith('resnet/logits')) + self.assertListEqual(logits.get_shape().as_list(), + [None, 1, 1, num_classes]) + images = create_test_input(batch, height, width, 3) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(logits, {inputs: images.eval()}) + self.assertEquals(output.shape, (batch, 1, 1, num_classes)) + + def testFullyConvolutionalUnknownHeightWidth(self): + batch = 2 + height, width = 65, 65 + global_pool = False + inputs = create_test_input(batch, None, None, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + output, _ = self._resnet_small(inputs, + None, + global_pool=global_pool) + self.assertListEqual(output.get_shape().as_list(), + [batch, None, None, 32]) + images = create_test_input(batch, height, width, 3) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(output, {inputs: images.eval()}) + self.assertEquals(output.shape, (batch, 3, 3, 32)) + + def testAtrousFullyConvolutionalUnknownHeightWidth(self): + batch = 2 + height, width = 65, 65 + global_pool = False + output_stride = 8 + inputs = create_test_input(batch, None, None, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + output, _ = self._resnet_small(inputs, + None, + global_pool=global_pool, + output_stride=output_stride) + self.assertListEqual(output.get_shape().as_list(), + [batch, None, None, 32]) + images = create_test_input(batch, height, width, 3) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(output, {inputs: images.eval()}) + self.assertEquals(output.shape, (batch, 9, 9, 32)) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/utils.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/utils.py new file mode 100644 index 0000000..60a8743 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/utils.py @@ -0,0 +1,84 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""This script contains utility functions.""" +import tensorflow as tf + +slim = tf.contrib.slim + + +def scale_dimension(dim, scale): + """Scales the input dimension. + + Args: + dim: Input dimension (a scalar or a scalar Tensor). + scale: The amount of scaling applied to the input. + + Returns: + Scaled dimension. + """ + if isinstance(dim, tf.Tensor): + return tf.cast((tf.to_float(dim) - 1.0) * scale + 1.0, dtype=tf.int32) + else: + return int((float(dim) - 1.0) * scale + 1.0) + + +def split_separable_conv2d(inputs, + filters, + kernel_size=3, + rate=1, + weight_decay=0.00004, + depthwise_weights_initializer_stddev=0.33, + pointwise_weights_initializer_stddev=0.06, + scope=None): + """Splits a separable conv2d into depthwise and pointwise conv2d. + + This operation differs from `tf.layers.separable_conv2d` as this operation + applies activation function between depthwise and pointwise conv2d. + + Args: + inputs: Input tensor with shape [batch, height, width, channels]. + filters: Number of filters in the 1x1 pointwise convolution. + kernel_size: A list of length 2: [kernel_height, kernel_width] of + of the filters. Can be an int if both values are the same. + rate: Atrous convolution rate for the depthwise convolution. + weight_decay: The weight decay to use for regularizing the model. + depthwise_weights_initializer_stddev: The standard deviation of the + truncated normal weight initializer for depthwise convolution. + pointwise_weights_initializer_stddev: The standard deviation of the + truncated normal weight initializer for pointwise convolution. + scope: Optional scope for the operation. + + Returns: + Computed features after split separable conv2d. + """ + outputs = slim.separable_conv2d( + inputs, + None, + kernel_size=kernel_size, + depth_multiplier=1, + rate=rate, + weights_initializer=tf.truncated_normal_initializer( + stddev=depthwise_weights_initializer_stddev), + weights_regularizer=None, + scope=scope + '_depthwise') + return slim.conv2d( + outputs, + filters, + 1, + weights_initializer=tf.truncated_normal_initializer( + stddev=pointwise_weights_initializer_stddev), + weights_regularizer=slim.l2_regularizer(weight_decay), + scope=scope + '_pointwise') \ No newline at end of file diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/utils_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/utils_test.py new file mode 100644 index 0000000..8384328 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/utils_test.py @@ -0,0 +1,32 @@ + +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for utils.py.""" + +import tensorflow as tf + +from deeplab.core import utils + + +class UtilsTest(tf.test.TestCase): + + def testScaleDimensionOutput(self): + self.assertEqual(161, utils.scale_dimension(321, 0.5)) + self.assertEqual(193, utils.scale_dimension(321, 0.6)) + self.assertEqual(241, utils.scale_dimension(321, 0.75)) + + +if __name__ == '__main__': + tf.test.main() \ No newline at end of file diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/xception.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/xception.py new file mode 100644 index 0000000..6fd306c --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/xception.py @@ -0,0 +1,761 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +r"""Xception model. + +"Xception: Deep Learning with Depthwise Separable Convolutions" +Fran{\c{c}}ois Chollet +https://arxiv.org/abs/1610.02357 + +We implement the modified version by Jifeng Dai et al. for their COCO 2017 +detection challenge submission, where the model is made deeper and has aligned +features for dense prediction tasks. See their slides for details: + +"Deformable Convolutional Networks -- COCO Detection and Segmentation Challenge +2017 Entry" +Haozhi Qi, Zheng Zhang, Bin Xiao, Han Hu, Bowen Cheng, Yichen Wei and Jifeng Dai +ICCV 2017 COCO Challenge workshop +http://presentations.cocodataset.org/COCO17-Detect-MSRA.pdf + +We made a few more changes on top of MSRA's modifications: +1. Fully convolutional: All the max-pooling layers are replaced with separable + conv2d with stride = 2. This allows us to use atrous convolution to extract + feature maps at any resolution. + +2. We support adding ReLU and BatchNorm after depthwise convolution, motivated + by the design of MobileNetv1. + +"MobileNets: Efficient Convolutional Neural Networks for Mobile Vision +Applications" +Andrew G. Howard, Menglong Zhu, Bo Chen, Dmitry Kalenichenko, Weijun Wang, +Tobias Weyand, Marco Andreetto, Hartwig Adam +https://arxiv.org/abs/1704.04861 +""" +import collections +import tensorflow as tf + +from tensorflow.contrib.slim.nets import resnet_utils + +slim = tf.contrib.slim + + +_DEFAULT_MULTI_GRID = [1, 1, 1] + + +class Block(collections.namedtuple('Block', ['scope', 'unit_fn', 'args'])): + """A named tuple describing an Xception block. + + Its parts are: + scope: The scope of the block. + unit_fn: The Xception unit function which takes as input a tensor and + returns another tensor with the output of the Xception unit. + args: A list of length equal to the number of units in the block. The list + contains one dictionary for each unit in the block to serve as argument to + unit_fn. + """ + + +def fixed_padding(inputs, kernel_size, rate=1): + """Pads the input along the spatial dimensions independently of input size. + + Args: + inputs: A tensor of size [batch, height_in, width_in, channels]. + kernel_size: The kernel to be used in the conv2d or max_pool2d operation. + Should be a positive integer. + rate: An integer, rate for atrous convolution. + + Returns: + output: A tensor of size [batch, height_out, width_out, channels] with the + input, either intact (if kernel_size == 1) or padded (if kernel_size > 1). + """ + kernel_size_effective = kernel_size + (kernel_size - 1) * (rate - 1) + pad_total = kernel_size_effective - 1 + pad_beg = pad_total // 2 + pad_end = pad_total - pad_beg + padded_inputs = tf.pad(inputs, [[0, 0], [pad_beg, pad_end], + [pad_beg, pad_end], [0, 0]]) + return padded_inputs + + +@slim.add_arg_scope +def separable_conv2d_same(inputs, + num_outputs, + kernel_size, + depth_multiplier, + stride, + rate=1, + use_explicit_padding=True, + regularize_depthwise=False, + scope=None, + **kwargs): + """Strided 2-D separable convolution with 'SAME' padding. + + If stride > 1 and use_explicit_padding is True, then we do explicit zero- + padding, followed by conv2d with 'VALID' padding. + + Note that + + net = separable_conv2d_same(inputs, num_outputs, 3, + depth_multiplier=1, stride=stride) + + is equivalent to + + net = slim.separable_conv2d(inputs, num_outputs, 3, + depth_multiplier=1, stride=1, padding='SAME') + net = resnet_utils.subsample(net, factor=stride) + + whereas + + net = slim.separable_conv2d(inputs, num_outputs, 3, stride=stride, + depth_multiplier=1, padding='SAME') + + is different when the input's height or width is even, which is why we add the + current function. + + Consequently, if the input feature map has even height or width, setting + `use_explicit_padding=False` will result in feature misalignment by one pixel + along the corresponding dimension. + + Args: + inputs: A 4-D tensor of size [batch, height_in, width_in, channels]. + num_outputs: An integer, the number of output filters. + kernel_size: An int with the kernel_size of the filters. + depth_multiplier: The number of depthwise convolution output channels for + each input channel. The total number of depthwise convolution output + channels will be equal to `num_filters_in * depth_multiplier`. + stride: An integer, the output stride. + rate: An integer, rate for atrous convolution. + use_explicit_padding: If True, use explicit padding to make the model fully + compatible with the open source version, otherwise use the native + Tensorflow 'SAME' padding. + regularize_depthwise: Whether or not apply L2-norm regularization on the + depthwise convolution weights. + scope: Scope. + **kwargs: additional keyword arguments to pass to slim.conv2d + + Returns: + output: A 4-D tensor of size [batch, height_out, width_out, channels] with + the convolution output. + """ + def _separable_conv2d(padding): + """Wrapper for separable conv2d.""" + return slim.separable_conv2d(inputs, + num_outputs, + kernel_size, + depth_multiplier=depth_multiplier, + stride=stride, + rate=rate, + padding=padding, + scope=scope, + **kwargs) + def _split_separable_conv2d(padding): + """Splits separable conv2d into depthwise and pointwise conv2d.""" + outputs = slim.separable_conv2d(inputs, + None, + kernel_size, + depth_multiplier=depth_multiplier, + stride=stride, + rate=rate, + padding=padding, + scope=scope + '_depthwise', + **kwargs) + return slim.conv2d(outputs, + num_outputs, + 1, + scope=scope + '_pointwise', + **kwargs) + if stride == 1 or not use_explicit_padding: + if regularize_depthwise: + outputs = _separable_conv2d(padding='SAME') + else: + outputs = _split_separable_conv2d(padding='SAME') + else: + inputs = fixed_padding(inputs, kernel_size, rate) + if regularize_depthwise: + outputs = _separable_conv2d(padding='VALID') + else: + outputs = _split_separable_conv2d(padding='VALID') + return outputs + + +@slim.add_arg_scope +def xception_module(inputs, + depth_list, + skip_connection_type, + stride, + unit_rate_list=None, + rate=1, + activation_fn_in_separable_conv=False, + regularize_depthwise=False, + outputs_collections=None, + scope=None): + """An Xception module. + + The output of one Xception module is equal to the sum of `residual` and + `shortcut`, where `residual` is the feature computed by three separable + convolution. The `shortcut` is the feature computed by 1x1 convolution with + or without striding. In some cases, the `shortcut` path could be a simple + identity function or none (i.e, no shortcut). + + Note that we replace the max pooling operations in the Xception module with + another separable convolution with striding, since atrous rate is not properly + supported in current TensorFlow max pooling implementation. + + Args: + inputs: A tensor of size [batch, height, width, channels]. + depth_list: A list of three integers specifying the depth values of one + Xception module. + skip_connection_type: Skip connection type for the residual path. Only + supports 'conv', 'sum', or 'none'. + stride: The block unit's stride. Determines the amount of downsampling of + the units output compared to its input. + unit_rate_list: A list of three integers, determining the unit rate for + each separable convolution in the xception module. + rate: An integer, rate for atrous convolution. + activation_fn_in_separable_conv: Includes activation function in the + separable convolution or not. + regularize_depthwise: Whether or not apply L2-norm regularization on the + depthwise convolution weights. + outputs_collections: Collection to add the Xception unit output. + scope: Optional variable_scope. + + Returns: + The Xception module's output. + + Raises: + ValueError: If depth_list and unit_rate_list do not contain three elements, + or if stride != 1 for the third separable convolution operation in the + residual path, or unsupported skip connection type. + """ + if len(depth_list) != 3: + raise ValueError('Expect three elements in depth_list.') + if unit_rate_list: + if len(unit_rate_list) != 3: + raise ValueError('Expect three elements in unit_rate_list.') + + with tf.variable_scope(scope, 'xception_module', [inputs]) as sc: + residual = inputs + + def _separable_conv(features, depth, kernel_size, depth_multiplier, + regularize_depthwise, rate, stride, scope): + if activation_fn_in_separable_conv: + activation_fn = tf.nn.relu + else: + activation_fn = None + features = tf.nn.relu(features) + return separable_conv2d_same(features, + depth, + kernel_size, + depth_multiplier=depth_multiplier, + stride=stride, + rate=rate, + activation_fn=activation_fn, + regularize_depthwise=regularize_depthwise, + scope=scope) + for i in range(3): + residual = _separable_conv(residual, + depth_list[i], + kernel_size=3, + depth_multiplier=1, + regularize_depthwise=regularize_depthwise, + rate=rate*unit_rate_list[i], + stride=stride if i == 2 else 1, + scope='separable_conv' + str(i+1)) + if skip_connection_type == 'conv': + shortcut = slim.conv2d(inputs, + depth_list[-1], + [1, 1], + stride=stride, + activation_fn=None, + scope='shortcut') + outputs = residual + shortcut + elif skip_connection_type == 'sum': + outputs = residual + inputs + elif skip_connection_type == 'none': + outputs = residual + else: + raise ValueError('Unsupported skip connection type.') + + return slim.utils.collect_named_outputs(outputs_collections, + sc.name, + outputs) + + +@slim.add_arg_scope +def stack_blocks_dense(net, + blocks, + output_stride=None, + outputs_collections=None): + """Stacks Xception blocks and controls output feature density. + + First, this function creates scopes for the Xception in the form of + 'block_name/unit_1', 'block_name/unit_2', etc. + + Second, this function allows the user to explicitly control the output + stride, which is the ratio of the input to output spatial resolution. This + is useful for dense prediction tasks such as semantic segmentation or + object detection. + + Control of the output feature density is implemented by atrous convolution. + + Args: + net: A tensor of size [batch, height, width, channels]. + blocks: A list of length equal to the number of Xception blocks. Each + element is an Xception Block object describing the units in the block. + output_stride: If None, then the output will be computed at the nominal + network stride. If output_stride is not None, it specifies the requested + ratio of input to output spatial resolution, which needs to be equal to + the product of unit strides from the start up to some level of Xception. + For example, if the Xception employs units with strides 1, 2, 1, 3, 4, 1, + then valid values for the output_stride are 1, 2, 6, 24 or None (which + is equivalent to output_stride=24). + outputs_collections: Collection to add the Xception block outputs. + + Returns: + net: Output tensor with stride equal to the specified output_stride. + + Raises: + ValueError: If the target output_stride is not valid. + """ + # The current_stride variable keeps track of the effective stride of the + # activations. This allows us to invoke atrous convolution whenever applying + # the next residual unit would result in the activations having stride larger + # than the target output_stride. + current_stride = 1 + + # The atrous convolution rate parameter. + rate = 1 + + for block in blocks: + with tf.variable_scope(block.scope, 'block', [net]) as sc: + for i, unit in enumerate(block.args): + if output_stride is not None and current_stride > output_stride: + raise ValueError('The target output_stride cannot be reached.') + with tf.variable_scope('unit_%d' % (i + 1), values=[net]): + # If we have reached the target output_stride, then we need to employ + # atrous convolution with stride=1 and multiply the atrous rate by the + # current unit's stride for use in subsequent layers. + if output_stride is not None and current_stride == output_stride: + net = block.unit_fn(net, rate=rate, **dict(unit, stride=1)) + rate *= unit.get('stride', 1) + else: + net = block.unit_fn(net, rate=1, **unit) + current_stride *= unit.get('stride', 1) + + # Collect activations at the block's end before performing subsampling. + net = slim.utils.collect_named_outputs(outputs_collections, sc.name, net) + + if output_stride is not None and current_stride != output_stride: + raise ValueError('The target output_stride cannot be reached.') + + return net + + +def xception(inputs, + blocks, + num_classes=None, + is_training=True, + global_pool=True, + keep_prob=0.5, + output_stride=None, + reuse=None, + scope=None): + """Generator for Xception models. + + This function generates a family of Xception models. See the xception_*() + methods for specific model instantiations, obtained by selecting different + block instantiations that produce Xception of various depths. + + Args: + inputs: A tensor of size [batch, height_in, width_in, channels]. Must be + floating point. If a pretrained checkpoint is used, pixel values should be + the same as during training (see go/slim-classification-models for + specifics). + blocks: A list of length equal to the number of Xception blocks. Each + element is an Xception Block object describing the units in the block. + num_classes: Number of predicted classes for classification tasks. + If 0 or None, we return the features before the logit layer. + is_training: whether batch_norm layers are in training mode. + global_pool: If True, we perform global average pooling before computing the + logits. Set to True for image classification, False for dense prediction. + keep_prob: Keep probability used in the pre-logits dropout layer. + output_stride: If None, then the output will be computed at the nominal + network stride. If output_stride is not None, it specifies the requested + ratio of input to output spatial resolution. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + + Returns: + net: A rank-4 tensor of size [batch, height_out, width_out, channels_out]. + If global_pool is False, then height_out and width_out are reduced by a + factor of output_stride compared to the respective height_in and width_in, + else both height_out and width_out equal one. If num_classes is 0 or None, + then net is the output of the last Xception block, potentially after + global average pooling. If num_classes is a non-zero integer, net contains + the pre-softmax activations. + end_points: A dictionary from components of the network to the corresponding + activation. + + Raises: + ValueError: If the target output_stride is not valid. + """ + with tf.variable_scope( + scope, 'xception', [inputs], reuse=reuse) as sc: + end_points_collection = sc.original_name_scope + 'end_points' + with slim.arg_scope([slim.conv2d, + slim.separable_conv2d, + xception_module, + stack_blocks_dense], + outputs_collections=end_points_collection): + with slim.arg_scope([slim.batch_norm], is_training=is_training): + net = inputs + if output_stride is not None: + if output_stride % 2 != 0: + raise ValueError('The output_stride needs to be a multiple of 2.') + output_stride /= 2 + # Root block function operated on inputs. + net = resnet_utils.conv2d_same(net, 32, 3, stride=2, + scope='entry_flow/conv1_1') + net = resnet_utils.conv2d_same(net, 64, 3, stride=1, + scope='entry_flow/conv1_2') + + # Extract features for entry_flow, middle_flow, and exit_flow. + net = stack_blocks_dense(net, blocks, output_stride) + + # Convert end_points_collection into a dictionary of end_points. + end_points = slim.utils.convert_collection_to_dict( + end_points_collection, clear_collection=True) + + if global_pool: + # Global average pooling. + net = tf.reduce_mean(net, [1, 2], name='global_pool', keepdims=True) + end_points['global_pool'] = net + if num_classes: + net = slim.dropout(net, keep_prob=keep_prob, is_training=is_training, + scope='prelogits_dropout') + net = slim.conv2d(net, num_classes, [1, 1], activation_fn=None, + normalizer_fn=None, scope='logits') + end_points[sc.name + '/logits'] = net + end_points['predictions'] = slim.softmax(net, scope='predictions') + return net, end_points + + +def xception_block(scope, + depth_list, + skip_connection_type, + activation_fn_in_separable_conv, + regularize_depthwise, + num_units, + stride, + unit_rate_list=None): + """Helper function for creating a Xception block. + + Args: + scope: The scope of the block. + depth_list: The depth of the bottleneck layer for each unit. + skip_connection_type: Skip connection type for the residual path. Only + supports 'conv', 'sum', or 'none'. + activation_fn_in_separable_conv: Includes activation function in the + separable convolution or not. + regularize_depthwise: Whether or not apply L2-norm regularization on the + depthwise convolution weights. + num_units: The number of units in the block. + stride: The stride of the block, implemented as a stride in the last unit. + All other units have stride=1. + unit_rate_list: A list of three integers, determining the unit rate in the + corresponding xception block. + + Returns: + An Xception block. + """ + if unit_rate_list is None: + unit_rate_list = _DEFAULT_MULTI_GRID + return Block(scope, xception_module, [{ + 'depth_list': depth_list, + 'skip_connection_type': skip_connection_type, + 'activation_fn_in_separable_conv': activation_fn_in_separable_conv, + 'regularize_depthwise': regularize_depthwise, + 'stride': stride, + 'unit_rate_list': unit_rate_list, + }] * num_units) + + +def xception_41(inputs, + num_classes=None, + is_training=True, + global_pool=True, + keep_prob=0.5, + output_stride=None, + regularize_depthwise=False, + multi_grid=None, + reuse=None, + scope='xception_41'): + """Xception-41 model.""" + blocks = [ + xception_block('entry_flow/block1', + depth_list=[128, 128, 128], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + xception_block('entry_flow/block2', + depth_list=[256, 256, 256], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + xception_block('entry_flow/block3', + depth_list=[728, 728, 728], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + xception_block('middle_flow/block1', + depth_list=[728, 728, 728], + skip_connection_type='sum', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=8, + stride=1), + xception_block('exit_flow/block1', + depth_list=[728, 1024, 1024], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + xception_block('exit_flow/block2', + depth_list=[1536, 1536, 2048], + skip_connection_type='none', + activation_fn_in_separable_conv=True, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=1, + unit_rate_list=multi_grid), + ] + return xception(inputs, + blocks=blocks, + num_classes=num_classes, + is_training=is_training, + global_pool=global_pool, + keep_prob=keep_prob, + output_stride=output_stride, + reuse=reuse, + scope=scope) + + +def xception_65(inputs, + num_classes=None, + is_training=True, + global_pool=True, + keep_prob=0.5, + output_stride=None, + regularize_depthwise=False, + multi_grid=None, + reuse=None, + scope='xception_65'): + """Xception-65 model.""" + blocks = [ + xception_block('entry_flow/block1', + depth_list=[128, 128, 128], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + xception_block('entry_flow/block2', + depth_list=[256, 256, 256], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + xception_block('entry_flow/block3', + depth_list=[728, 728, 728], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + xception_block('middle_flow/block1', + depth_list=[728, 728, 728], + skip_connection_type='sum', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=16, + stride=1), + xception_block('exit_flow/block1', + depth_list=[728, 1024, 1024], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + xception_block('exit_flow/block2', + depth_list=[1536, 1536, 2048], + skip_connection_type='none', + activation_fn_in_separable_conv=True, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=1, + unit_rate_list=multi_grid), + ] + return xception(inputs, + blocks=blocks, + num_classes=num_classes, + is_training=is_training, + global_pool=global_pool, + keep_prob=keep_prob, + output_stride=output_stride, + reuse=reuse, + scope=scope) + + +def xception_71(inputs, + num_classes=None, + is_training=True, + global_pool=True, + keep_prob=0.5, + output_stride=None, + regularize_depthwise=False, + multi_grid=None, + reuse=None, + scope='xception_71'): + """Xception-71 model.""" + blocks = [ + xception_block('entry_flow/block1', + depth_list=[128, 128, 128], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + xception_block('entry_flow/block2', + depth_list=[256, 256, 256], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=1), + xception_block('entry_flow/block3', + depth_list=[256, 256, 256], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + xception_block('entry_flow/block4', + depth_list=[728, 728, 728], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=1), + xception_block('entry_flow/block5', + depth_list=[728, 728, 728], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + xception_block('middle_flow/block1', + depth_list=[728, 728, 728], + skip_connection_type='sum', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=16, + stride=1), + xception_block('exit_flow/block1', + depth_list=[728, 1024, 1024], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + xception_block('exit_flow/block2', + depth_list=[1536, 1536, 2048], + skip_connection_type='none', + activation_fn_in_separable_conv=True, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=1, + unit_rate_list=multi_grid), + ] + return xception(inputs, + blocks=blocks, + num_classes=num_classes, + is_training=is_training, + global_pool=global_pool, + keep_prob=keep_prob, + output_stride=output_stride, + reuse=reuse, + scope=scope) + + +def xception_arg_scope(weight_decay=0.00004, + batch_norm_decay=0.9997, + batch_norm_epsilon=0.001, + batch_norm_scale=True, + weights_initializer_stddev=0.09, + activation_fn=tf.nn.relu, + regularize_depthwise=False, + use_batch_norm=True): + """Defines the default Xception arg scope. + + Args: + weight_decay: The weight decay to use for regularizing the model. + batch_norm_decay: The moving average decay when estimating layer activation + statistics in batch normalization. + batch_norm_epsilon: Small constant to prevent division by zero when + normalizing activations by their variance in batch normalization. + batch_norm_scale: If True, uses an explicit `gamma` multiplier to scale the + activations in the batch normalization layer. + weights_initializer_stddev: The standard deviation of the trunctated normal + weight initializer. + activation_fn: The activation function in Xception. + regularize_depthwise: Whether or not apply L2-norm regularization on the + depthwise convolution weights. + use_batch_norm: Whether or not to use batch normalization. + + Returns: + An `arg_scope` to use for the Xception models. + """ + batch_norm_params = { + 'decay': batch_norm_decay, + 'epsilon': batch_norm_epsilon, + 'scale': batch_norm_scale, + } + if regularize_depthwise: + depthwise_regularizer = slim.l2_regularizer(weight_decay) + else: + depthwise_regularizer = None + with slim.arg_scope( + [slim.conv2d, slim.separable_conv2d], + weights_initializer=tf.truncated_normal_initializer( + stddev=weights_initializer_stddev), + activation_fn=activation_fn, + normalizer_fn=slim.batch_norm if use_batch_norm else None): + with slim.arg_scope([slim.batch_norm], **batch_norm_params): + with slim.arg_scope( + [slim.conv2d], + weights_regularizer=slim.l2_regularizer(weight_decay)): + with slim.arg_scope( + [slim.separable_conv2d], + weights_regularizer=depthwise_regularizer) as arg_sc: + return arg_sc diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/xception_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/xception_test.py new file mode 100644 index 0000000..4ef25ba --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/core/xception_test.py @@ -0,0 +1,467 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Tests for xception.py.""" +import numpy as np +import six +import tensorflow as tf + +from deeplab.core import xception +from tensorflow.contrib.slim.nets import resnet_utils + +slim = tf.contrib.slim + + +def create_test_input(batch, height, width, channels): + """Create test input tensor.""" + if None in [batch, height, width, channels]: + return tf.placeholder(tf.float32, (batch, height, width, channels)) + else: + return tf.to_float( + np.tile( + np.reshape( + np.reshape(np.arange(height), [height, 1]) + + np.reshape(np.arange(width), [1, width]), + [1, height, width, 1]), + [batch, 1, 1, channels])) + + +class UtilityFunctionTest(tf.test.TestCase): + + def testSeparableConv2DSameWithInputEvenSize(self): + n, n2 = 4, 2 + + # Input image. + x = create_test_input(1, n, n, 1) + + # Convolution kernel. + dw = create_test_input(1, 3, 3, 1) + dw = tf.reshape(dw, [3, 3, 1, 1]) + + tf.get_variable('Conv/depthwise_weights', initializer=dw) + tf.get_variable('Conv/pointwise_weights', + initializer=tf.ones([1, 1, 1, 1])) + tf.get_variable('Conv/biases', initializer=tf.zeros([1])) + tf.get_variable_scope().reuse_variables() + + y1 = slim.separable_conv2d(x, 1, [3, 3], depth_multiplier=1, + stride=1, scope='Conv') + y1_expected = tf.to_float([[14, 28, 43, 26], + [28, 48, 66, 37], + [43, 66, 84, 46], + [26, 37, 46, 22]]) + y1_expected = tf.reshape(y1_expected, [1, n, n, 1]) + + y2 = resnet_utils.subsample(y1, 2) + y2_expected = tf.to_float([[14, 43], + [43, 84]]) + y2_expected = tf.reshape(y2_expected, [1, n2, n2, 1]) + + y3 = xception.separable_conv2d_same(x, 1, 3, depth_multiplier=1, + regularize_depthwise=True, + stride=2, scope='Conv') + y3_expected = y2_expected + + y4 = slim.separable_conv2d(x, 1, [3, 3], depth_multiplier=1, + stride=2, scope='Conv') + y4_expected = tf.to_float([[48, 37], + [37, 22]]) + y4_expected = tf.reshape(y4_expected, [1, n2, n2, 1]) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + self.assertAllClose(y1.eval(), y1_expected.eval()) + self.assertAllClose(y2.eval(), y2_expected.eval()) + self.assertAllClose(y3.eval(), y3_expected.eval()) + self.assertAllClose(y4.eval(), y4_expected.eval()) + + def testSeparableConv2DSameWithInputOddSize(self): + n, n2 = 5, 3 + + # Input image. + x = create_test_input(1, n, n, 1) + + # Convolution kernel. + dw = create_test_input(1, 3, 3, 1) + dw = tf.reshape(dw, [3, 3, 1, 1]) + + tf.get_variable('Conv/depthwise_weights', initializer=dw) + tf.get_variable('Conv/pointwise_weights', + initializer=tf.ones([1, 1, 1, 1])) + tf.get_variable('Conv/biases', initializer=tf.zeros([1])) + tf.get_variable_scope().reuse_variables() + + y1 = slim.separable_conv2d(x, 1, [3, 3], depth_multiplier=1, + stride=1, scope='Conv') + y1_expected = tf.to_float([[14, 28, 43, 58, 34], + [28, 48, 66, 84, 46], + [43, 66, 84, 102, 55], + [58, 84, 102, 120, 64], + [34, 46, 55, 64, 30]]) + y1_expected = tf.reshape(y1_expected, [1, n, n, 1]) + + y2 = resnet_utils.subsample(y1, 2) + y2_expected = tf.to_float([[14, 43, 34], + [43, 84, 55], + [34, 55, 30]]) + y2_expected = tf.reshape(y2_expected, [1, n2, n2, 1]) + + y3 = xception.separable_conv2d_same(x, 1, 3, depth_multiplier=1, + regularize_depthwise=True, + stride=2, scope='Conv') + y3_expected = y2_expected + + y4 = slim.separable_conv2d(x, 1, [3, 3], depth_multiplier=1, + stride=2, scope='Conv') + y4_expected = y2_expected + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + self.assertAllClose(y1.eval(), y1_expected.eval()) + self.assertAllClose(y2.eval(), y2_expected.eval()) + self.assertAllClose(y3.eval(), y3_expected.eval()) + self.assertAllClose(y4.eval(), y4_expected.eval()) + + +class XceptionNetworkTest(tf.test.TestCase): + """Tests with small Xception network.""" + + def _xception_small(self, + inputs, + num_classes=None, + is_training=True, + global_pool=True, + output_stride=None, + regularize_depthwise=True, + reuse=None, + scope='xception_small'): + """A shallow and thin Xception for faster tests.""" + block = xception.xception_block + blocks = [ + block('entry_flow/block1', + depth_list=[1, 1, 1], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + block('entry_flow/block2', + depth_list=[2, 2, 2], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + block('entry_flow/block3', + depth_list=[4, 4, 4], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=1), + block('entry_flow/block4', + depth_list=[4, 4, 4], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + block('middle_flow/block1', + depth_list=[4, 4, 4], + skip_connection_type='sum', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=2, + stride=1), + block('exit_flow/block1', + depth_list=[8, 8, 8], + skip_connection_type='conv', + activation_fn_in_separable_conv=False, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=2), + block('exit_flow/block2', + depth_list=[16, 16, 16], + skip_connection_type='none', + activation_fn_in_separable_conv=True, + regularize_depthwise=regularize_depthwise, + num_units=1, + stride=1), + ] + return xception.xception(inputs, + blocks=blocks, + num_classes=num_classes, + is_training=is_training, + global_pool=global_pool, + output_stride=output_stride, + reuse=reuse, + scope=scope) + + def testClassificationEndPoints(self): + global_pool = True + num_classes = 10 + inputs = create_test_input(2, 224, 224, 3) + with slim.arg_scope(xception.xception_arg_scope()): + logits, end_points = self._xception_small( + inputs, + num_classes=num_classes, + global_pool=global_pool, + scope='xception') + self.assertTrue( + logits.op.name.startswith('xception/logits')) + self.assertListEqual(logits.get_shape().as_list(), [2, 1, 1, num_classes]) + self.assertTrue('predictions' in end_points) + self.assertListEqual(end_points['predictions'].get_shape().as_list(), + [2, 1, 1, num_classes]) + self.assertTrue('global_pool' in end_points) + self.assertListEqual(end_points['global_pool'].get_shape().as_list(), + [2, 1, 1, 16]) + + def testEndpointNames(self): + global_pool = True + num_classes = 10 + inputs = create_test_input(2, 224, 224, 3) + with slim.arg_scope(xception.xception_arg_scope()): + _, end_points = self._xception_small( + inputs, + num_classes=num_classes, + global_pool=global_pool, + scope='xception') + expected = [ + 'xception/entry_flow/conv1_1', + 'xception/entry_flow/conv1_2', + 'xception/entry_flow/block1/unit_1/xception_module/separable_conv1', + 'xception/entry_flow/block1/unit_1/xception_module/separable_conv2', + 'xception/entry_flow/block1/unit_1/xception_module/separable_conv3', + 'xception/entry_flow/block1/unit_1/xception_module/shortcut', + 'xception/entry_flow/block1/unit_1/xception_module', + 'xception/entry_flow/block1', + 'xception/entry_flow/block2/unit_1/xception_module/separable_conv1', + 'xception/entry_flow/block2/unit_1/xception_module/separable_conv2', + 'xception/entry_flow/block2/unit_1/xception_module/separable_conv3', + 'xception/entry_flow/block2/unit_1/xception_module/shortcut', + 'xception/entry_flow/block2/unit_1/xception_module', + 'xception/entry_flow/block2', + 'xception/entry_flow/block3/unit_1/xception_module/separable_conv1', + 'xception/entry_flow/block3/unit_1/xception_module/separable_conv2', + 'xception/entry_flow/block3/unit_1/xception_module/separable_conv3', + 'xception/entry_flow/block3/unit_1/xception_module/shortcut', + 'xception/entry_flow/block3/unit_1/xception_module', + 'xception/entry_flow/block3', + 'xception/entry_flow/block4/unit_1/xception_module/separable_conv1', + 'xception/entry_flow/block4/unit_1/xception_module/separable_conv2', + 'xception/entry_flow/block4/unit_1/xception_module/separable_conv3', + 'xception/entry_flow/block4/unit_1/xception_module/shortcut', + 'xception/entry_flow/block4/unit_1/xception_module', + 'xception/entry_flow/block4', + 'xception/middle_flow/block1/unit_1/xception_module/separable_conv1', + 'xception/middle_flow/block1/unit_1/xception_module/separable_conv2', + 'xception/middle_flow/block1/unit_1/xception_module/separable_conv3', + 'xception/middle_flow/block1/unit_1/xception_module', + 'xception/middle_flow/block1/unit_2/xception_module/separable_conv1', + 'xception/middle_flow/block1/unit_2/xception_module/separable_conv2', + 'xception/middle_flow/block1/unit_2/xception_module/separable_conv3', + 'xception/middle_flow/block1/unit_2/xception_module', + 'xception/middle_flow/block1', + 'xception/exit_flow/block1/unit_1/xception_module/separable_conv1', + 'xception/exit_flow/block1/unit_1/xception_module/separable_conv2', + 'xception/exit_flow/block1/unit_1/xception_module/separable_conv3', + 'xception/exit_flow/block1/unit_1/xception_module/shortcut', + 'xception/exit_flow/block1/unit_1/xception_module', + 'xception/exit_flow/block1', + 'xception/exit_flow/block2/unit_1/xception_module/separable_conv1', + 'xception/exit_flow/block2/unit_1/xception_module/separable_conv2', + 'xception/exit_flow/block2/unit_1/xception_module/separable_conv3', + 'xception/exit_flow/block2/unit_1/xception_module', + 'xception/exit_flow/block2', + 'global_pool', + 'xception/logits', + 'predictions', + ] + self.assertItemsEqual(end_points.keys(), expected) + + def testClassificationShapes(self): + global_pool = True + num_classes = 10 + inputs = create_test_input(2, 224, 224, 3) + with slim.arg_scope(xception.xception_arg_scope()): + _, end_points = self._xception_small( + inputs, + num_classes, + global_pool=global_pool, + scope='xception') + endpoint_to_shape = { + 'xception/entry_flow/conv1_1': [2, 112, 112, 32], + 'xception/entry_flow/block1': [2, 56, 56, 1], + 'xception/entry_flow/block2': [2, 28, 28, 2], + 'xception/entry_flow/block4': [2, 14, 14, 4], + 'xception/middle_flow/block1': [2, 14, 14, 4], + 'xception/exit_flow/block1': [2, 7, 7, 8], + 'xception/exit_flow/block2': [2, 7, 7, 16]} + for endpoint, shape in six.iteritems(endpoint_to_shape): + self.assertListEqual(end_points[endpoint].get_shape().as_list(), shape) + + def testFullyConvolutionalEndpointShapes(self): + global_pool = False + num_classes = 10 + inputs = create_test_input(2, 321, 321, 3) + with slim.arg_scope(xception.xception_arg_scope()): + _, end_points = self._xception_small( + inputs, + num_classes, + global_pool=global_pool, + scope='xception') + endpoint_to_shape = { + 'xception/entry_flow/conv1_1': [2, 161, 161, 32], + 'xception/entry_flow/block1': [2, 81, 81, 1], + 'xception/entry_flow/block2': [2, 41, 41, 2], + 'xception/entry_flow/block4': [2, 21, 21, 4], + 'xception/middle_flow/block1': [2, 21, 21, 4], + 'xception/exit_flow/block1': [2, 11, 11, 8], + 'xception/exit_flow/block2': [2, 11, 11, 16]} + for endpoint, shape in six.iteritems(endpoint_to_shape): + self.assertListEqual(end_points[endpoint].get_shape().as_list(), shape) + + def testAtrousFullyConvolutionalEndpointShapes(self): + global_pool = False + num_classes = 10 + output_stride = 8 + inputs = create_test_input(2, 321, 321, 3) + with slim.arg_scope(xception.xception_arg_scope()): + _, end_points = self._xception_small( + inputs, + num_classes, + global_pool=global_pool, + output_stride=output_stride, + scope='xception') + endpoint_to_shape = { + 'xception/entry_flow/block1': [2, 81, 81, 1], + 'xception/entry_flow/block2': [2, 41, 41, 2], + 'xception/entry_flow/block4': [2, 41, 41, 4], + 'xception/middle_flow/block1': [2, 41, 41, 4], + 'xception/exit_flow/block1': [2, 41, 41, 8], + 'xception/exit_flow/block2': [2, 41, 41, 16]} + for endpoint, shape in six.iteritems(endpoint_to_shape): + self.assertListEqual(end_points[endpoint].get_shape().as_list(), shape) + + def testAtrousFullyConvolutionalValues(self): + """Verify dense feature extraction with atrous convolution.""" + nominal_stride = 32 + for output_stride in [4, 8, 16, 32, None]: + with slim.arg_scope(xception.xception_arg_scope()): + with tf.Graph().as_default(): + with self.test_session() as sess: + tf.set_random_seed(0) + inputs = create_test_input(2, 96, 97, 3) + # Dense feature extraction followed by subsampling. + output, _ = self._xception_small( + inputs, + None, + is_training=False, + global_pool=False, + output_stride=output_stride) + if output_stride is None: + factor = 1 + else: + factor = nominal_stride // output_stride + output = resnet_utils.subsample(output, factor) + # Make the two networks use the same weights. + tf.get_variable_scope().reuse_variables() + # Feature extraction at the nominal network rate. + expected, _ = self._xception_small( + inputs, + None, + is_training=False, + global_pool=False) + sess.run(tf.global_variables_initializer()) + self.assertAllClose(output.eval(), expected.eval(), + atol=1e-5, rtol=1e-5) + + def testUnknownBatchSize(self): + batch = 2 + height, width = 65, 65 + global_pool = True + num_classes = 10 + inputs = create_test_input(None, height, width, 3) + with slim.arg_scope(xception.xception_arg_scope()): + logits, _ = self._xception_small( + inputs, + num_classes, + global_pool=global_pool, + scope='xception') + self.assertTrue(logits.op.name.startswith('xception/logits')) + self.assertListEqual(logits.get_shape().as_list(), + [None, 1, 1, num_classes]) + images = create_test_input(batch, height, width, 3) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(logits, {inputs: images.eval()}) + self.assertEquals(output.shape, (batch, 1, 1, num_classes)) + + def testFullyConvolutionalUnknownHeightWidth(self): + batch = 2 + height, width = 65, 65 + global_pool = False + inputs = create_test_input(batch, None, None, 3) + with slim.arg_scope(xception.xception_arg_scope()): + output, _ = self._xception_small( + inputs, + None, + global_pool=global_pool) + self.assertListEqual(output.get_shape().as_list(), + [batch, None, None, 16]) + images = create_test_input(batch, height, width, 3) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(output, {inputs: images.eval()}) + self.assertEquals(output.shape, (batch, 3, 3, 16)) + + def testAtrousFullyConvolutionalUnknownHeightWidth(self): + batch = 2 + height, width = 65, 65 + global_pool = False + output_stride = 8 + inputs = create_test_input(batch, None, None, 3) + with slim.arg_scope(xception.xception_arg_scope()): + output, _ = self._xception_small( + inputs, + None, + global_pool=global_pool, + output_stride=output_stride) + self.assertListEqual(output.get_shape().as_list(), + [batch, None, None, 16]) + images = create_test_input(batch, height, width, 3) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(output, {inputs: images.eval()}) + self.assertEquals(output.shape, (batch, 9, 9, 16)) + + def testEndpointsReuse(self): + inputs = create_test_input(2, 32, 32, 3) + with slim.arg_scope(xception.xception_arg_scope()): + _, end_points0 = xception.xception_65( + inputs, + num_classes=10, + reuse=False) + with slim.arg_scope(xception.xception_arg_scope()): + _, end_points1 = xception.xception_65( + inputs, + num_classes=10, + reuse=True) + self.assertItemsEqual(end_points0.keys(), end_points1.keys()) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/__init__.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_ade20k_data.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_ade20k_data.py new file mode 100644 index 0000000..b637fb4 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_ade20k_data.py @@ -0,0 +1,118 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Converts ADE20K data to TFRecord file format with Example protos.""" + +import math +import os +import random +import sys +import build_data +import tensorflow as tf + +FLAGS = tf.app.flags.FLAGS + +tf.app.flags.DEFINE_string( + 'train_image_folder', + './ADE20K/ADEChallengeData2016/images/training', + 'Folder containing trainng images') +tf.app.flags.DEFINE_string( + 'train_image_label_folder', + './ADE20K/ADEChallengeData2016/annotations/training', + 'Folder containing annotations for trainng images') + +tf.app.flags.DEFINE_string( + 'val_image_folder', + './ADE20K/ADEChallengeData2016/images/validation', + 'Folder containing validation images') + +tf.app.flags.DEFINE_string( + 'val_image_label_folder', + './ADE20K/ADEChallengeData2016/annotations/validation', + 'Folder containing annotations for validation') + +tf.app.flags.DEFINE_string( + 'output_dir', './ADE20K/tfrecord', + 'Path to save converted tfrecord of Tensorflow example') + +_NUM_SHARDS = 4 + + +def _convert_dataset(dataset_split, dataset_dir, dataset_label_dir): + """Converts the ADE20k dataset into into tfrecord format. + + Args: + dataset_split: Dataset split (e.g., train, val). + dataset_dir: Dir in which the dataset locates. + dataset_label_dir: Dir in which the annotations locates. + + Raises: + RuntimeError: If loaded image and label have different shape. + """ + + img_names = tf.gfile.Glob(os.path.join(dataset_dir, '*.jpg')) + random.shuffle(img_names) + seg_names = [] + for f in img_names: + # get the filename without the extension + basename = os.path.basename(f).split('.')[0] + # cover its corresponding *_seg.png + seg = os.path.join(dataset_label_dir, basename+'.png') + seg_names.append(seg) + + num_images = len(img_names) + num_per_shard = int(math.ceil(num_images / float(_NUM_SHARDS))) + + image_reader = build_data.ImageReader('jpeg', channels=3) + label_reader = build_data.ImageReader('png', channels=1) + + for shard_id in range(_NUM_SHARDS): + output_filename = os.path.join( + FLAGS.output_dir, + '%s-%05d-of-%05d.tfrecord' % (dataset_split, shard_id, _NUM_SHARDS)) + with tf.python_io.TFRecordWriter(output_filename) as tfrecord_writer: + start_idx = shard_id * num_per_shard + end_idx = min((shard_id + 1) * num_per_shard, num_images) + for i in range(start_idx, end_idx): + sys.stdout.write('\r>> Converting image %d/%d shard %d' % ( + i + 1, num_images, shard_id)) + sys.stdout.flush() + # Read the image. + image_filename = img_names[i] + image_data = tf.gfile.FastGFile(image_filename, 'r').read() + height, width = image_reader.read_image_dims(image_data) + # Read the semantic segmentation annotation. + seg_filename = seg_names[i] + seg_data = tf.gfile.FastGFile(seg_filename, 'r').read() + seg_height, seg_width = label_reader.read_image_dims(seg_data) + if height != seg_height or width != seg_width: + raise RuntimeError('Shape mismatched between image and label.') + # Convert to tf example. + example = build_data.image_seg_to_tfexample( + image_data, img_names[i], height, width, seg_data) + tfrecord_writer.write(example.SerializeToString()) + sys.stdout.write('\n') + sys.stdout.flush() + + +def main(unused_argv): + tf.gfile.MakeDirs(FLAGS.output_dir) + _convert_dataset( + 'train', FLAGS.train_image_folder, FLAGS.train_image_label_folder) + _convert_dataset('val', FLAGS.val_image_folder, FLAGS.val_image_label_folder) + + +if __name__ == '__main__': + tf.app.run() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_cityscapes_data.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_cityscapes_data.py new file mode 100644 index 0000000..df7fec6 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_cityscapes_data.py @@ -0,0 +1,183 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Converts Cityscapes data to TFRecord file format with Example protos. + +The Cityscapes dataset is expected to have the following directory structure: + + + cityscapes + - build_cityscapes_data.py (current working directiory). + - build_data.py + + cityscapesscripts + + annotation + + evaluation + + helpers + + preparation + + viewer + + gtFine + + train + + val + + test + + leftImg8bit + + train + + val + + test + + tfrecord + +This script converts data into sharded data files and save at tfrecord folder. + +Note that before running this script, the users should (1) register the +Cityscapes dataset website at https://www.cityscapes-dataset.com to +download the dataset, and (2) run the script provided by Cityscapes +`preparation/createTrainIdLabelImgs.py` to generate the training groundtruth. + +Also note that the tensorflow model will be trained with `TrainId' instead +of `EvalId' used on the evaluation server. Thus, the users need to convert +the predicted labels to `EvalId` for evaluation on the server. See the +vis.py for more details. + +The Example proto contains the following fields: + + image/encoded: encoded image content. + image/filename: image filename. + image/format: image file format. + image/height: image height. + image/width: image width. + image/channels: image channels. + image/segmentation/class/encoded: encoded semantic segmentation content. + image/segmentation/class/format: semantic segmentation file format. +""" +import glob +import math +import os.path +import re +import sys +import build_data +import tensorflow as tf + +FLAGS = tf.app.flags.FLAGS + +tf.app.flags.DEFINE_string('cityscapes_root', + './cityscapes', + 'Cityscapes dataset root folder.') + +tf.app.flags.DEFINE_string( + 'output_dir', + './tfrecord', + 'Path to save converted SSTable of TensorFlow examples.') + + +_NUM_SHARDS = 10 + +# A map from data type to folder name that saves the data. +_FOLDERS_MAP = { + 'image': 'leftImg8bit', + 'label': 'gtFine', +} + +# A map from data type to filename postfix. +_POSTFIX_MAP = { + 'image': '_leftImg8bit', + 'label': '_gtFine_labelTrainIds', +} + +# A map from data type to data format. +_DATA_FORMAT_MAP = { + 'image': 'png', + 'label': 'png', +} + +# Image file pattern. +_IMAGE_FILENAME_RE = re.compile('(.+)' + _POSTFIX_MAP['image']) + + +def _get_files(data, dataset_split): + """Gets files for the specified data type and dataset split. + + Args: + data: String, desired data ('image' or 'label'). + dataset_split: String, dataset split ('train', 'val', 'test') + + Returns: + A list of sorted file names or None when getting label for + test set. + """ + if data == 'label' and dataset_split == 'test': + return None + pattern = '*%s.%s' % (_POSTFIX_MAP[data], _DATA_FORMAT_MAP[data]) + search_files = os.path.join( + FLAGS.cityscapes_root, _FOLDERS_MAP[data], dataset_split, '*', pattern) + filenames = glob.glob(search_files) + return sorted(filenames) + + +def _convert_dataset(dataset_split): + """Converts the specified dataset split to TFRecord format. + + Args: + dataset_split: The dataset split (e.g., train, val). + + Raises: + RuntimeError: If loaded image and label have different shape, or if the + image file with specified postfix could not be found. + """ + image_files = _get_files('image', dataset_split) + label_files = _get_files('label', dataset_split) + + num_images = len(image_files) + num_per_shard = int(math.ceil(num_images / float(_NUM_SHARDS))) + + image_reader = build_data.ImageReader('png', channels=3) + label_reader = build_data.ImageReader('png', channels=1) + + for shard_id in range(_NUM_SHARDS): + shard_filename = '%s-%05d-of-%05d.tfrecord' % ( + dataset_split, shard_id, _NUM_SHARDS) + output_filename = os.path.join(FLAGS.output_dir, shard_filename) + with tf.python_io.TFRecordWriter(output_filename) as tfrecord_writer: + start_idx = shard_id * num_per_shard + end_idx = min((shard_id + 1) * num_per_shard, num_images) + for i in range(start_idx, end_idx): + sys.stdout.write('\r>> Converting image %d/%d shard %d' % ( + i + 1, num_images, shard_id)) + sys.stdout.flush() + # Read the image. + image_data = tf.gfile.FastGFile(image_files[i], 'rb').read() + height, width = image_reader.read_image_dims(image_data) + # Read the semantic segmentation annotation. + seg_data = tf.gfile.FastGFile(label_files[i], 'rb').read() + seg_height, seg_width = label_reader.read_image_dims(seg_data) + if height != seg_height or width != seg_width: + raise RuntimeError('Shape mismatched between image and label.') + # Convert to tf example. + re_match = _IMAGE_FILENAME_RE.search(image_files[i]) + if re_match is None: + raise RuntimeError('Invalid image filename: ' + image_files[i]) + filename = os.path.basename(re_match.group(1)) + example = build_data.image_seg_to_tfexample( + image_data, filename, height, width, seg_data) + tfrecord_writer.write(example.SerializeToString()) + sys.stdout.write('\n') + sys.stdout.flush() + + +def main(unused_argv): + # Only support converting 'train' and 'val' sets for now. + for dataset_split in ['train', 'val']: + _convert_dataset(dataset_split) + + +if __name__ == '__main__': + tf.app.run() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_data.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_data.py new file mode 100644 index 0000000..4562867 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_data.py @@ -0,0 +1,161 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Contains common utility functions and classes for building dataset. + +This script contains utility functions and classes to converts dataset to +TFRecord file format with Example protos. + +The Example proto contains the following fields: + + image/encoded: encoded image content. + image/filename: image filename. + image/format: image file format. + image/height: image height. + image/width: image width. + image/channels: image channels. + image/segmentation/class/encoded: encoded semantic segmentation content. + image/segmentation/class/format: semantic segmentation file format. +""" +import collections +import six +import tensorflow as tf + +FLAGS = tf.app.flags.FLAGS + +tf.app.flags.DEFINE_enum('image_format', 'png', ['jpg', 'jpeg', 'png'], + 'Image format.') + +tf.app.flags.DEFINE_enum('label_format', 'png', ['png'], + 'Segmentation label format.') + +# A map from image format to expected data format. +_IMAGE_FORMAT_MAP = { + 'jpg': 'jpeg', + 'jpeg': 'jpeg', + 'png': 'png', +} + + +class ImageReader(object): + """Helper class that provides TensorFlow image coding utilities.""" + + def __init__(self, image_format='jpeg', channels=3): + """Class constructor. + + Args: + image_format: Image format. Only 'jpeg', 'jpg', or 'png' are supported. + channels: Image channels. + """ + with tf.Graph().as_default(): + self._decode_data = tf.placeholder(dtype=tf.string) + self._image_format = image_format + self._session = tf.Session() + if self._image_format in ('jpeg', 'jpg'): + self._decode = tf.image.decode_jpeg(self._decode_data, + channels=channels) + elif self._image_format == 'png': + self._decode = tf.image.decode_png(self._decode_data, + channels=channels) + + def read_image_dims(self, image_data): + """Reads the image dimensions. + + Args: + image_data: string of image data. + + Returns: + image_height and image_width. + """ + image = self.decode_image(image_data) + return image.shape[:2] + + def decode_image(self, image_data): + """Decodes the image data string. + + Args: + image_data: string of image data. + + Returns: + Decoded image data. + + Raises: + ValueError: Value of image channels not supported. + """ + image = self._session.run(self._decode, + feed_dict={self._decode_data: image_data}) + if len(image.shape) != 3 or image.shape[2] not in (1, 3): + raise ValueError('The image channels not supported.') + + return image + + +def _int64_list_feature(values): + """Returns a TF-Feature of int64_list. + + Args: + values: A scalar or list of values. + + Returns: + A TF-Feature. + """ + if not isinstance(values, collections.Iterable): + values = [values] + + return tf.train.Feature(int64_list=tf.train.Int64List(value=values)) + + +def _bytes_list_feature(values): + """Returns a TF-Feature of bytes. + + Args: + values: A string. + + Returns: + A TF-Feature. + """ + def norm2bytes(value): + return value.encode() if isinstance(value, str) and six.PY3 else value + + return tf.train.Feature( + bytes_list=tf.train.BytesList(value=[norm2bytes(values)])) + + +def image_seg_to_tfexample(image_data, filename, height, width, seg_data): + """Converts one image/segmentation pair to tf example. + + Args: + image_data: string of image data. + filename: image filename. + height: image height. + width: image width. + seg_data: string of semantic segmentation data. + + Returns: + tf example of one image/segmentation pair. + """ + return tf.train.Example(features=tf.train.Features(feature={ + 'image/encoded': _bytes_list_feature(image_data), + 'image/filename': _bytes_list_feature(filename), + 'image/format': _bytes_list_feature( + _IMAGE_FORMAT_MAP[FLAGS.image_format]), + 'image/height': _int64_list_feature(height), + 'image/width': _int64_list_feature(width), + 'image/channels': _int64_list_feature(3), + 'image/segmentation/class/encoded': ( + _bytes_list_feature(seg_data)), + 'image/segmentation/class/format': _bytes_list_feature( + FLAGS.label_format), + })) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_voc2012_data.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_voc2012_data.py new file mode 100644 index 0000000..94ad319 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/build_voc2012_data.py @@ -0,0 +1,141 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Converts PASCAL VOC 2012 data to TFRecord file format with Example protos. + +PASCAL VOC 2012 dataset is expected to have the following directory structure: + + + pascal_voc_seg + - build_data.py + - build_voc2012_data.py (current working directory). + + VOCdevkit + + VOC2012 + + JPEGImages + + SegmentationClass + + ImageSets + + Segmentation + + tfrecord + +Image folder: + ./VOCdevkit/VOC2012/JPEGImages + +Semantic segmentation annotations: + ./VOCdevkit/VOC2012/SegmentationClass + +list folder: + ./VOCdevkit/VOC2012/ImageSets/Segmentation + +This script converts data into sharded data files and save at tfrecord folder. + +The Example proto contains the following fields: + + image/encoded: encoded image content. + image/filename: image filename. + image/format: image file format. + image/height: image height. + image/width: image width. + image/channels: image channels. + image/segmentation/class/encoded: encoded semantic segmentation content. + image/segmentation/class/format: semantic segmentation file format. +""" +import math +import os.path +import sys +import build_data +import tensorflow as tf + +FLAGS = tf.app.flags.FLAGS + +tf.app.flags.DEFINE_string('image_folder', + './VOCdevkit/VOC2012/JPEGImages', + 'Folder containing images.') + +tf.app.flags.DEFINE_string( + 'semantic_segmentation_folder', + './VOCdevkit/VOC2012/SegmentationClassRaw', + 'Folder containing semantic segmentation annotations.') + +tf.app.flags.DEFINE_string( + 'list_folder', + './VOCdevkit/VOC2012/ImageSets/Segmentation', + 'Folder containing lists for training and validation') + +tf.app.flags.DEFINE_string( + 'output_dir', + './tfrecord', + 'Path to save converted SSTable of TensorFlow examples.') + + +_NUM_SHARDS = 4 + + +def _convert_dataset(dataset_split): + """Converts the specified dataset split to TFRecord format. + + Args: + dataset_split: The dataset split (e.g., train, test). + + Raises: + RuntimeError: If loaded image and label have different shape. + """ + dataset = os.path.basename(dataset_split)[:-4] + sys.stdout.write('Processing ' + dataset) + filenames = [x.strip('\n') for x in open(dataset_split, 'r')] + num_images = len(filenames) + num_per_shard = int(math.ceil(num_images / float(_NUM_SHARDS))) + + image_reader = build_data.ImageReader('jpeg', channels=3) + label_reader = build_data.ImageReader('png', channels=1) + + for shard_id in range(_NUM_SHARDS): + output_filename = os.path.join( + FLAGS.output_dir, + '%s-%05d-of-%05d.tfrecord' % (dataset, shard_id, _NUM_SHARDS)) + with tf.python_io.TFRecordWriter(output_filename) as tfrecord_writer: + start_idx = shard_id * num_per_shard + end_idx = min((shard_id + 1) * num_per_shard, num_images) + for i in range(start_idx, end_idx): + sys.stdout.write('\r>> Converting image %d/%d shard %d' % ( + i + 1, len(filenames), shard_id)) + sys.stdout.flush() + # Read the image. + image_filename = os.path.join( + FLAGS.image_folder, filenames[i] + '.' + FLAGS.image_format) + image_data = tf.gfile.FastGFile(image_filename, 'rb').read() + height, width = image_reader.read_image_dims(image_data) + # Read the semantic segmentation annotation. + seg_filename = os.path.join( + FLAGS.semantic_segmentation_folder, + filenames[i] + '.' + FLAGS.label_format) + seg_data = tf.gfile.FastGFile(seg_filename, 'rb').read() + seg_height, seg_width = label_reader.read_image_dims(seg_data) + if height != seg_height or width != seg_width: + raise RuntimeError('Shape mismatched between image and label.') + # Convert to tf example. + example = build_data.image_seg_to_tfexample( + image_data, filenames[i], height, width, seg_data) + tfrecord_writer.write(example.SerializeToString()) + sys.stdout.write('\n') + sys.stdout.flush() + + +def main(unused_argv): + dataset_splits = tf.gfile.Glob(os.path.join(FLAGS.list_folder, '*.txt')) + for dataset_split in dataset_splits: + _convert_dataset(dataset_split) + + +if __name__ == '__main__': + tf.app.run() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/convert_cityscapes.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/convert_cityscapes.sh new file mode 100644 index 0000000..9945e12 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/convert_cityscapes.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +# +# Script to preprocess the Cityscapes dataset. Note (1) the users should +# register the Cityscapes dataset website at +# https://www.cityscapes-dataset.com/downloads/ to download the dataset, +# and (2) the users should download the utility scripts provided by +# Cityscapes at https://github.com/mcordts/cityscapesScripts. +# +# Usage: +# bash ./preprocess_cityscapes.sh +# +# The folder structure is assumed to be: +# + datasets +# - build_cityscapes_data.py +# - convert_cityscapes.sh +# + cityscapes +# + cityscapesscripts (downloaded scripts) +# + gtFine +# + leftImg8bit +# + +# Exit immediately if a command exits with a non-zero status. +set -e + +CURRENT_DIR=$(pwd) +WORK_DIR="." + +# Root path for Cityscapes dataset. +CITYSCAPES_ROOT="${WORK_DIR}/cityscapes" + +# Create training labels. +python "${CITYSCAPES_ROOT}/cityscapesscripts/preparation/createTrainIdLabelImgs.py" + +# Build TFRecords of the dataset. +# First, create output directory for storing TFRecords. +OUTPUT_DIR="${CITYSCAPES_ROOT}/tfrecord" +mkdir -p "${OUTPUT_DIR}" + +BUILD_SCRIPT="${CURRENT_DIR}/build_cityscapes_data.py" + +echo "Converting Cityscapes dataset..." +python "${BUILD_SCRIPT}" \ + --cityscapes_root="${CITYSCAPES_ROOT}" \ + --output_dir="${OUTPUT_DIR}" \ diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/download_and_convert_ade20k.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/download_and_convert_ade20k.sh new file mode 100644 index 0000000..aa684b4 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/download_and_convert_ade20k.sh @@ -0,0 +1,80 @@ +#!/bin/bash +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +# +# Script to download and preprocess the PASCAL VOC 2012 dataset. +# +# Usage: +# bash ./download_and_convert_ade20k.sh +# +# The folder structure is assumed to be: +# + datasets +# - build_data.py +# - build_ade20k_data.py +# - download_and_convert_ade20k.sh +# + ADE20K +# + tfrecord +# + ADEChallengeData2016 +# + annotations +# + training +# + validation +# + images +# + training +# + validation + +# Exit immediately if a command exits with a non-zero status. +set -e + +CURRENT_DIR=$(pwd) +WORK_DIR="./ADE20K" +mkdir -p "${WORK_DIR}" +cd "${WORK_DIR}" + +# Helper function to download and unpack ADE20K dataset. +download_and_uncompress() { + local BASE_URL=${1} + local FILENAME=${2} + + if [ ! -f "${FILENAME}" ]; then + echo "Downloading ${FILENAME} to ${WORK_DIR}" + wget -nd -c "${BASE_URL}/${FILENAME}" + fi + echo "Uncompressing ${FILENAME}" + unzip "${FILENAME}" +} + +# Download the images. +BASE_URL="http://data.csail.mit.edu/places/ADEchallenge" +FILENAME="ADEChallengeData2016.zip" + +download_and_uncompress "${BASE_URL}" "${FILENAME}" + +cd "${CURRENT_DIR}" + +# Root path for ADE20K dataset. +ADE20K_ROOT="${WORK_DIR}/ADEChallengeData2016" + +# Build TFRecords of the dataset. +# First, create output directory for storing TFRecords. +OUTPUT_DIR="${WORK_DIR}/tfrecord" +mkdir -p "${OUTPUT_DIR}" + +echo "Converting ADE20K dataset..." +python ./build_ade20k_data.py \ + --train_image_folder="${ADE20K_ROOT}/images/training/" \ + --train_image_label_folder="${ADE20K_ROOT}/annotations/training/" \ + --val_image_folder="${ADE20K_ROOT}/images/validation/" \ + --val_image_label_folder="${ADE20K_ROOT}/annotations/validation/" \ + --output_dir="${OUTPUT_DIR}" diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/download_and_convert_voc2012.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/download_and_convert_voc2012.sh new file mode 100644 index 0000000..30eec7f --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/download_and_convert_voc2012.sh @@ -0,0 +1,90 @@ +#!/bin/bash +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +# +# Script to download and preprocess the PASCAL VOC 2012 dataset. +# +# Usage: +# bash ./download_and_convert_voc2012.sh +# +# The folder structure is assumed to be: +# + datasets +# - build_data.py +# - build_voc2012_data.py +# - download_and_convert_voc2012.sh +# - remove_gt_colormap.py +# + pascal_voc_seg +# + VOCdevkit +# + VOC2012 +# + JPEGImages +# + SegmentationClass +# + +# Exit immediately if a command exits with a non-zero status. +set -e + +CURRENT_DIR=$(pwd) +WORK_DIR="./pascal_voc_seg" +mkdir -p "${WORK_DIR}" +cd "${WORK_DIR}" + +# Helper function to download and unpack VOC 2012 dataset. +download_and_uncompress() { + local BASE_URL=${1} + local FILENAME=${2} + + if [ ! -f "${FILENAME}" ]; then + echo "Downloading ${FILENAME} to ${WORK_DIR}" + wget -nd -c "${BASE_URL}/${FILENAME}" + fi + echo "Uncompressing ${FILENAME}" + tar -xf "${FILENAME}" +} + +# Download the images. +BASE_URL="http://host.robots.ox.ac.uk/pascal/VOC/voc2012/" +FILENAME="VOCtrainval_11-May-2012.tar" + +download_and_uncompress "${BASE_URL}" "${FILENAME}" + +cd "${CURRENT_DIR}" + +# Root path for PASCAL VOC 2012 dataset. +PASCAL_ROOT="${WORK_DIR}/VOCdevkit/VOC2012" + +# Remove the colormap in the ground truth annotations. +SEG_FOLDER="${PASCAL_ROOT}/SegmentationClass" +SEMANTIC_SEG_FOLDER="${PASCAL_ROOT}/SegmentationClassRaw" + +echo "Removing the color map in ground truth annotations..." +python ./remove_gt_colormap.py \ + --original_gt_folder="${SEG_FOLDER}" \ + --output_dir="${SEMANTIC_SEG_FOLDER}" + +# Build TFRecords of the dataset. +# First, create output directory for storing TFRecords. +OUTPUT_DIR="${WORK_DIR}/tfrecord" +mkdir -p "${OUTPUT_DIR}" + +IMAGE_FOLDER="${PASCAL_ROOT}/JPEGImages" +LIST_FOLDER="${PASCAL_ROOT}/ImageSets/Segmentation" + +echo "Converting PASCAL VOC 2012 dataset..." +python ./build_voc2012_data.py \ + --image_folder="${IMAGE_FOLDER}" \ + --semantic_segmentation_folder="${SEMANTIC_SEG_FOLDER}" \ + --list_folder="${LIST_FOLDER}" \ + --image_format="jpg" \ + --output_dir="${OUTPUT_DIR}" diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/remove_gt_colormap.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/remove_gt_colormap.py new file mode 100644 index 0000000..7bd68b0 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/remove_gt_colormap.py @@ -0,0 +1,83 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Removes the color map from segmentation annotations. + +Removes the color map from the ground truth segmentation annotations and save +the results to output_dir. +""" +import glob +import os.path +import numpy as np + +from PIL import Image + +import tensorflow as tf + +FLAGS = tf.app.flags.FLAGS + +tf.app.flags.DEFINE_string('original_gt_folder', + './VOCdevkit/VOC2012/SegmentationClass', + 'Original ground truth annotations.') + +tf.app.flags.DEFINE_string('segmentation_format', 'png', 'Segmentation format.') + +tf.app.flags.DEFINE_string('output_dir', + './VOCdevkit/VOC2012/SegmentationClassRaw', + 'folder to save modified ground truth annotations.') + + +def _remove_colormap(filename): + """Removes the color map from the annotation. + + Args: + filename: Ground truth annotation filename. + + Returns: + Annotation without color map. + """ + return np.array(Image.open(filename)) + + +def _save_annotation(annotation, filename): + """Saves the annotation as png file. + + Args: + annotation: Segmentation annotation. + filename: Output filename. + """ + pil_image = Image.fromarray(annotation.astype(dtype=np.uint8)) + with tf.gfile.Open(filename, mode='w') as f: + pil_image.save(f, 'PNG') + + +def main(unused_argv): + # Create the output directory if not exists. + if not tf.gfile.IsDirectory(FLAGS.output_dir): + tf.gfile.MakeDirs(FLAGS.output_dir) + + annotations = glob.glob(os.path.join(FLAGS.original_gt_folder, + '*.' + FLAGS.segmentation_format)) + for annotation in annotations: + raw_annotation = _remove_colormap(annotation) + filename = os.path.splitext(os.path.basename(annotation))[0] + _save_annotation(raw_annotation, + os.path.join( + FLAGS.output_dir, + filename + '.' + FLAGS.segmentation_format)) + + +if __name__ == '__main__': + tf.app.run() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/segmentation_dataset.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/segmentation_dataset.py new file mode 100644 index 0000000..65c0604 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/segmentation_dataset.py @@ -0,0 +1,198 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Provides data from semantic segmentation datasets. + +The SegmentationDataset class provides both images and annotations (semantic +segmentation and/or instance segmentation) for TensorFlow. Currently, we +support the following datasets: + +1. PASCAL VOC 2012 (http://host.robots.ox.ac.uk/pascal/VOC/voc2012/). + +PASCAL VOC 2012 semantic segmentation dataset annotates 20 foreground objects +(e.g., bike, person, and so on) and leaves all the other semantic classes as +one background class. The dataset contains 1464, 1449, and 1456 annotated +images for the training, validation and test respectively. + +2. Cityscapes dataset (https://www.cityscapes-dataset.com) + +The Cityscapes dataset contains 19 semantic labels (such as road, person, car, +and so on) for urban street scenes. + +3. ADE20K dataset (http://groups.csail.mit.edu/vision/datasets/ADE20K) + +The ADE20K dataset contains 150 semantic labels both urban street scenes and +indoor scenes. + +References: + M. Everingham, S. M. A. Eslami, L. V. Gool, C. K. I. Williams, J. Winn, + and A. Zisserman, The pascal visual object classes challenge a retrospective. + IJCV, 2014. + + M. Cordts, M. Omran, S. Ramos, T. Rehfeld, M. Enzweiler, R. Benenson, + U. Franke, S. Roth, and B. Schiele, "The cityscapes dataset for semantic urban + scene understanding," In Proc. of CVPR, 2016. + + B. Zhou, H. Zhao, X. Puig, S. Fidler, A. Barriuso, A. Torralba, "Scene Parsing + through ADE20K dataset", In Proc. of CVPR, 2017. +""" +import collections +import os.path +import tensorflow as tf + +slim = tf.contrib.slim + +dataset = slim.dataset + +tfexample_decoder = slim.tfexample_decoder + + +_ITEMS_TO_DESCRIPTIONS = { + 'image': 'A color image of varying height and width.', + 'labels_class': ('A semantic segmentation label whose size matches image.' + 'Its values range from 0 (background) to num_classes.'), +} + +# Named tuple to describe the dataset properties. +DatasetDescriptor = collections.namedtuple( + 'DatasetDescriptor', + ['splits_to_sizes', # Splits of the dataset into training, val, and test. + 'num_classes', # Number of semantic classes, including the background + # class (if exists). For example, there are 20 + # foreground classes + 1 background class in the PASCAL + # VOC 2012 dataset. Thus, we set num_classes=21. + 'ignore_label', # Ignore label value. + ] +) + +_CITYSCAPES_INFORMATION = DatasetDescriptor( + splits_to_sizes={ + 'train': 2975, + 'val': 500, + }, + num_classes=19, + ignore_label=255, +) + +_PASCAL_VOC_SEG_INFORMATION = DatasetDescriptor( + splits_to_sizes={ + 'train': 1464, + 'train_aug': 10582, + 'trainval': 2913, + 'val': 1449, + }, + num_classes=21, + ignore_label=255, +) + +# These number (i.e., 'train'/'test') seems to have to be hard coded +# You are required to figure it out for your training/testing example. +_ADE20K_INFORMATION = DatasetDescriptor( + splits_to_sizes={ + 'train': 20210, # num of samples in images/training + 'val': 2000, # num of samples in images/validation + }, + num_classes=151, + ignore_label=0, +) + + +_DATASETS_INFORMATION = { + 'cityscapes': _CITYSCAPES_INFORMATION, + 'pascal_voc_seg': _PASCAL_VOC_SEG_INFORMATION, + 'ade20k': _ADE20K_INFORMATION, +} + +# Default file pattern of TFRecord of TensorFlow Example. +_FILE_PATTERN = '%s-*' + + +def get_cityscapes_dataset_name(): + return 'cityscapes' + + +def get_dataset(dataset_name, split_name, dataset_dir): + """Gets an instance of slim Dataset. + + Args: + dataset_name: Dataset name. + split_name: A train/val Split name. + dataset_dir: The directory of the dataset sources. + + Returns: + An instance of slim Dataset. + + Raises: + ValueError: if the dataset_name or split_name is not recognized. + """ + if dataset_name not in _DATASETS_INFORMATION: + raise ValueError('The specified dataset is not supported yet.') + + splits_to_sizes = _DATASETS_INFORMATION[dataset_name].splits_to_sizes + + if split_name not in splits_to_sizes: + raise ValueError('data split name %s not recognized' % split_name) + + # Prepare the variables for different datasets. + num_classes = _DATASETS_INFORMATION[dataset_name].num_classes + ignore_label = _DATASETS_INFORMATION[dataset_name].ignore_label + + file_pattern = _FILE_PATTERN + file_pattern = os.path.join(dataset_dir, file_pattern % split_name) + + # Specify how the TF-Examples are decoded. + keys_to_features = { + 'image/encoded': tf.FixedLenFeature( + (), tf.string, default_value=''), + 'image/filename': tf.FixedLenFeature( + (), tf.string, default_value=''), + 'image/format': tf.FixedLenFeature( + (), tf.string, default_value='jpeg'), + 'image/height': tf.FixedLenFeature( + (), tf.int64, default_value=0), + 'image/width': tf.FixedLenFeature( + (), tf.int64, default_value=0), + 'image/segmentation/class/encoded': tf.FixedLenFeature( + (), tf.string, default_value=''), + 'image/segmentation/class/format': tf.FixedLenFeature( + (), tf.string, default_value='png'), + } + items_to_handlers = { + 'image': tfexample_decoder.Image( + image_key='image/encoded', + format_key='image/format', + channels=3), + 'image_name': tfexample_decoder.Tensor('image/filename'), + 'height': tfexample_decoder.Tensor('image/height'), + 'width': tfexample_decoder.Tensor('image/width'), + 'labels_class': tfexample_decoder.Image( + image_key='image/segmentation/class/encoded', + format_key='image/segmentation/class/format', + channels=1), + } + + decoder = tfexample_decoder.TFExampleDecoder( + keys_to_features, items_to_handlers) + + return dataset.Dataset( + data_sources=file_pattern, + reader=tf.TFRecordReader, + decoder=decoder, + num_samples=splits_to_sizes[split_name], + items_to_descriptions=_ITEMS_TO_DESCRIPTIONS, + ignore_label=ignore_label, + num_classes=num_classes, + name=dataset_name, + multi_label=True) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/deeplab_demo.ipynb b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/deeplab_demo.ipynb new file mode 100644 index 0000000..84728fe --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/deeplab_demo.ipynb @@ -0,0 +1,348 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "KFPcBuVFw61h" + }, + "source": [ + "# DeepLab Demo\n", + "\n", + "This demo will demostrate the steps to run deeplab semantic segmentation model on sample input images." + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "cellView": "code", + "colab": { + "autoexec": { + "startup": false, + "wait_interval": 0 + } + }, + "colab_type": "code", + "id": "kAbdmRmvq0Je" + }, + "outputs": [], + "source": [ + "#@title Imports\n", + "\n", + "import os\n", + "from io import BytesIO\n", + "import tarfile\n", + "import tempfile\n", + "from six.moves import urllib\n", + "\n", + "from matplotlib import gridspec\n", + "from matplotlib import pyplot as plt\n", + "import numpy as np\n", + "from PIL import Image\n", + "\n", + "import tensorflow as tf" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "cellView": "code", + "colab": { + "autoexec": { + "startup": false, + "wait_interval": 0 + } + }, + "colab_type": "code", + "id": "vN0kU6NJ1Ye5" + }, + "outputs": [], + "source": [ + "#@title Helper methods\n", + "\n", + "\n", + "class DeepLabModel(object):\n", + " \"\"\"Class to load deeplab model and run inference.\"\"\"\n", + "\n", + " INPUT_TENSOR_NAME = 'ImageTensor:0'\n", + " OUTPUT_TENSOR_NAME = 'SemanticPredictions:0'\n", + " INPUT_SIZE = 513\n", + " FROZEN_GRAPH_NAME = 'frozen_inference_graph'\n", + "\n", + " def __init__(self, tarball_path):\n", + " \"\"\"Creates and loads pretrained deeplab model.\"\"\"\n", + " self.graph = tf.Graph()\n", + "\n", + " graph_def = None\n", + " # Extract frozen graph from tar archive.\n", + " tar_file = tarfile.open(tarball_path)\n", + " for tar_info in tar_file.getmembers():\n", + " if self.FROZEN_GRAPH_NAME in os.path.basename(tar_info.name):\n", + " file_handle = tar_file.extractfile(tar_info)\n", + " graph_def = tf.GraphDef.FromString(file_handle.read())\n", + " break\n", + "\n", + " tar_file.close()\n", + "\n", + " if graph_def is None:\n", + " raise RuntimeError('Cannot find inference graph in tar archive.')\n", + "\n", + " with self.graph.as_default():\n", + " tf.import_graph_def(graph_def, name='')\n", + "\n", + " self.sess = tf.Session(graph=self.graph)\n", + "\n", + " def run(self, image):\n", + " \"\"\"Runs inference on a single image.\n", + "\n", + " Args:\n", + " image: A PIL.Image object, raw input image.\n", + "\n", + " Returns:\n", + " resized_image: RGB image resized from original input image.\n", + " seg_map: Segmentation map of `resized_image`.\n", + " \"\"\"\n", + " width, height = image.size\n", + " resize_ratio = 1.0 * self.INPUT_SIZE / max(width, height)\n", + " target_size = (int(resize_ratio * width), int(resize_ratio * height))\n", + " resized_image = image.convert('RGB').resize(target_size, Image.ANTIALIAS)\n", + " batch_seg_map = self.sess.run(\n", + " self.OUTPUT_TENSOR_NAME,\n", + " feed_dict={self.INPUT_TENSOR_NAME: [np.asarray(resized_image)]})\n", + " seg_map = batch_seg_map[0]\n", + " return resized_image, seg_map\n", + "\n", + "\n", + "def create_pascal_label_colormap():\n", + " \"\"\"Creates a label colormap used in PASCAL VOC segmentation benchmark.\n", + "\n", + " Returns:\n", + " A Colormap for visualizing segmentation results.\n", + " \"\"\"\n", + " colormap = np.zeros((256, 3), dtype=int)\n", + " ind = np.arange(256, dtype=int)\n", + "\n", + " for shift in reversed(range(8)):\n", + " for channel in range(3):\n", + " colormap[:, channel] |= ((ind \u003e\u003e channel) \u0026 1) \u003c\u003c shift\n", + " ind \u003e\u003e= 3\n", + "\n", + " return colormap\n", + "\n", + "\n", + "def label_to_color_image(label):\n", + " \"\"\"Adds color defined by the dataset colormap to the label.\n", + "\n", + " Args:\n", + " label: A 2D array with integer type, storing the segmentation label.\n", + "\n", + " Returns:\n", + " result: A 2D array with floating type. The element of the array\n", + " is the color indexed by the corresponding element in the input label\n", + " to the PASCAL color map.\n", + "\n", + " Raises:\n", + " ValueError: If label is not of rank 2 or its value is larger than color\n", + " map maximum entry.\n", + " \"\"\"\n", + " if label.ndim != 2:\n", + " raise ValueError('Expect 2-D input label')\n", + "\n", + " colormap = create_pascal_label_colormap()\n", + "\n", + " if np.max(label) \u003e= len(colormap):\n", + " raise ValueError('label value too large.')\n", + "\n", + " return colormap[label]\n", + "\n", + "\n", + "def vis_segmentation(image, seg_map):\n", + " \"\"\"Visualizes input image, segmentation map and overlay view.\"\"\"\n", + " plt.figure(figsize=(15, 5))\n", + " grid_spec = gridspec.GridSpec(1, 4, width_ratios=[6, 6, 6, 1])\n", + "\n", + " plt.subplot(grid_spec[0])\n", + " plt.imshow(image)\n", + " plt.axis('off')\n", + " plt.title('input image')\n", + "\n", + " plt.subplot(grid_spec[1])\n", + " seg_image = label_to_color_image(seg_map).astype(np.uint8)\n", + " plt.imshow(seg_image)\n", + " plt.axis('off')\n", + " plt.title('segmentation map')\n", + "\n", + " plt.subplot(grid_spec[2])\n", + " plt.imshow(image)\n", + " plt.imshow(seg_image, alpha=0.7)\n", + " plt.axis('off')\n", + " plt.title('segmentation overlay')\n", + "\n", + " unique_labels = np.unique(seg_map)\n", + " ax = plt.subplot(grid_spec[3])\n", + " plt.imshow(\n", + " FULL_COLOR_MAP[unique_labels].astype(np.uint8), interpolation='nearest')\n", + " ax.yaxis.tick_right()\n", + " plt.yticks(range(len(unique_labels)), LABEL_NAMES[unique_labels])\n", + " plt.xticks([], [])\n", + " ax.tick_params(width=0.0)\n", + " plt.grid('off')\n", + " plt.show()\n", + "\n", + "\n", + "LABEL_NAMES = np.asarray([\n", + " 'background', 'aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus',\n", + " 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike',\n", + " 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tv'\n", + "])\n", + "\n", + "FULL_LABEL_MAP = np.arange(len(LABEL_NAMES)).reshape(len(LABEL_NAMES), 1)\n", + "FULL_COLOR_MAP = label_to_color_image(FULL_LABEL_MAP)" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab": { + "autoexec": { + "startup": false, + "wait_interval": 0 + } + }, + "colab_type": "code", + "id": "c4oXKmnjw6i_" + }, + "outputs": [], + "source": [ + "#@title Select and download models {display-mode: \"form\"}\n", + "\n", + "MODEL_NAME = 'mobilenetv2_coco_voctrainaug' # @param ['mobilenetv2_coco_voctrainaug', 'mobilenetv2_coco_voctrainval', 'xception_coco_voctrainaug', 'xception_coco_voctrainval']\n", + "\n", + "_DOWNLOAD_URL_PREFIX = 'http://download.tensorflow.org/models/'\n", + "_MODEL_URLS = {\n", + " 'mobilenetv2_coco_voctrainaug':\n", + " 'deeplabv3_mnv2_pascal_train_aug_2018_01_29.tar.gz',\n", + " 'mobilenetv2_coco_voctrainval':\n", + " 'deeplabv3_mnv2_pascal_trainval_2018_01_29.tar.gz',\n", + " 'xception_coco_voctrainaug':\n", + " 'deeplabv3_pascal_train_aug_2018_01_04.tar.gz',\n", + " 'xception_coco_voctrainval':\n", + " 'deeplabv3_pascal_trainval_2018_01_04.tar.gz',\n", + "}\n", + "_TARBALL_NAME = 'deeplab_model.tar.gz'\n", + "\n", + "model_dir = tempfile.mkdtemp()\n", + "tf.gfile.MakeDirs(model_dir)\n", + "\n", + "download_path = os.path.join(model_dir, _TARBALL_NAME)\n", + "print('downloading model, this might take a while...')\n", + "urllib.request.urlretrieve(_DOWNLOAD_URL_PREFIX + _MODEL_URLS[MODEL_NAME],\n", + " download_path)\n", + "print('download completed! loading DeepLab model...')\n", + "\n", + "MODEL = DeepLabModel(download_path)\n", + "print('model loaded successfully!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "SZst78N-4OKO" + }, + "source": [ + "## Run on sample images\n", + "\n", + "Select one of sample images (leave `IMAGE_URL` empty) or feed any internet image\n", + "url for inference.\n", + "\n", + "Note that we are using single scale inference in the demo for fast computation,\n", + "so the results may slightly differ from the visualizations in\n", + "[README](https://github.com/tensorflow/models/blob/master/research/deeplab/README.md),\n", + "which uses multi-scale and left-right flipped inputs." + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab": { + "autoexec": { + "startup": false, + "wait_interval": 0 + } + }, + "colab_type": "code", + "id": "edGukUHXyymr" + }, + "outputs": [], + "source": [ + "#@title Run on sample images {display-mode: \"form\"}\n", + "\n", + "SAMPLE_IMAGE = 'image1' # @param ['image1', 'image2', 'image3']\n", + "IMAGE_URL = '' #@param {type:\"string\"}\n", + "\n", + "_SAMPLE_URL = ('https://github.com/tensorflow/models/blob/master/research/'\n", + " 'deeplab/g3doc/img/%s.jpg?raw=true')\n", + "\n", + "\n", + "def run_visualization(url):\n", + " \"\"\"Inferences DeepLab model and visualizes result.\"\"\"\n", + " try:\n", + " f = urllib.request.urlopen(url)\n", + " jpeg_str = f.read()\n", + " original_im = Image.open(BytesIO(jpeg_str))\n", + " except IOError:\n", + " print('Cannot retrieve image. Please check url: ' + url)\n", + " return\n", + "\n", + " print('running deeplab on image %s...' % url)\n", + " resized_im, seg_map = MODEL.run(original_im)\n", + "\n", + " vis_segmentation(resized_im, seg_map)\n", + "\n", + "\n", + "image_url = IMAGE_URL or _SAMPLE_URL % SAMPLE_IMAGE\n", + "run_visualization(image_url)" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab": { + "autoexec": { + "startup": false, + "wait_interval": 0 + } + }, + "colab_type": "code", + "id": "7XrFNGsxzSIB" + }, + "outputs": [], + "source": [ + "" + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "default_view": {}, + "name": "DeepLab Demo.ipynb", + "provenance": [], + "version": "0.3.2", + "views": {} + }, + "kernelspec": { + "display_name": "Python 2", + "name": "python2" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} + diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/eval.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/eval.py new file mode 100644 index 0000000..600bb5f --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/eval.py @@ -0,0 +1,176 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Evaluation script for the DeepLab model. + +See model.py for more details and usage. +""" + +import math +import six +import tensorflow as tf +from deeplab import common +from deeplab import model +from deeplab.datasets import segmentation_dataset +from deeplab.utils import input_generator + +slim = tf.contrib.slim + +flags = tf.app.flags + +FLAGS = flags.FLAGS + +flags.DEFINE_string('master', '', 'BNS name of the tensorflow server') + +# Settings for log directories. + +flags.DEFINE_string('eval_logdir', None, 'Where to write the event logs.') + +flags.DEFINE_string('checkpoint_dir', None, 'Directory of model checkpoints.') + +# Settings for evaluating the model. + +flags.DEFINE_integer('eval_batch_size', 1, + 'The number of images in each batch during evaluation.') + +flags.DEFINE_multi_integer('eval_crop_size', [513, 513], + 'Image crop size [height, width] for evaluation.') + +flags.DEFINE_integer('eval_interval_secs', 60 * 5, + 'How often (in seconds) to run evaluation.') + +# For `xception_65`, use atrous_rates = [12, 24, 36] if output_stride = 8, or +# rates = [6, 12, 18] if output_stride = 16. For `mobilenet_v2`, use None. Note +# one could use different atrous_rates/output_stride during training/evaluation. +flags.DEFINE_multi_integer('atrous_rates', None, + 'Atrous rates for atrous spatial pyramid pooling.') + +flags.DEFINE_integer('output_stride', 16, + 'The ratio of input to output spatial resolution.') + +# Change to [0.5, 0.75, 1.0, 1.25, 1.5, 1.75] for multi-scale test. +flags.DEFINE_multi_float('eval_scales', [1.0], + 'The scales to resize images for evaluation.') + +# Change to True for adding flipped images during test. +flags.DEFINE_bool('add_flipped_images', False, + 'Add flipped images for evaluation or not.') + +# Dataset settings. + +flags.DEFINE_string('dataset', 'pascal_voc_seg', + 'Name of the segmentation dataset.') + +flags.DEFINE_string('eval_split', 'val', + 'Which split of the dataset used for evaluation') + +flags.DEFINE_string('dataset_dir', None, 'Where the dataset reside.') + +flags.DEFINE_integer('max_number_of_evaluations', 0, + 'Maximum number of eval iterations. Will loop ' + 'indefinitely upon nonpositive values.') + + +def main(unused_argv): + tf.logging.set_verbosity(tf.logging.INFO) + # Get dataset-dependent information. + dataset = segmentation_dataset.get_dataset( + FLAGS.dataset, FLAGS.eval_split, dataset_dir=FLAGS.dataset_dir) + + tf.gfile.MakeDirs(FLAGS.eval_logdir) + tf.logging.info('Evaluating on %s set', FLAGS.eval_split) + + with tf.Graph().as_default(): + samples = input_generator.get( + dataset, + FLAGS.eval_crop_size, + FLAGS.eval_batch_size, + min_resize_value=FLAGS.min_resize_value, + max_resize_value=FLAGS.max_resize_value, + resize_factor=FLAGS.resize_factor, + dataset_split=FLAGS.eval_split, + is_training=False, + model_variant=FLAGS.model_variant) + + model_options = common.ModelOptions( + outputs_to_num_classes={common.OUTPUT_TYPE: dataset.num_classes}, + crop_size=FLAGS.eval_crop_size, + atrous_rates=FLAGS.atrous_rates, + output_stride=FLAGS.output_stride) + + if tuple(FLAGS.eval_scales) == (1.0,): + tf.logging.info('Performing single-scale test.') + predictions = model.predict_labels(samples[common.IMAGE], model_options, + image_pyramid=FLAGS.image_pyramid) + else: + tf.logging.info('Performing multi-scale test.') + predictions = model.predict_labels_multi_scale( + samples[common.IMAGE], + model_options=model_options, + eval_scales=FLAGS.eval_scales, + add_flipped_images=FLAGS.add_flipped_images) + predictions = predictions[common.OUTPUT_TYPE] + predictions = tf.reshape(predictions, shape=[-1]) + labels = tf.reshape(samples[common.LABEL], shape=[-1]) + weights = tf.to_float(tf.not_equal(labels, dataset.ignore_label)) + + # Set ignore_label regions to label 0, because metrics.mean_iou requires + # range of labels = [0, dataset.num_classes). Note the ignore_label regions + # are not evaluated since the corresponding regions contain weights = 0. + labels = tf.where( + tf.equal(labels, dataset.ignore_label), tf.zeros_like(labels), labels) + + predictions_tag = 'miou' + for eval_scale in FLAGS.eval_scales: + predictions_tag += '_' + str(eval_scale) + if FLAGS.add_flipped_images: + predictions_tag += '_flipped' + + # Define the evaluation metric. + metric_map = {} + metric_map[predictions_tag] = tf.metrics.mean_iou( + predictions, labels, dataset.num_classes, weights=weights) + + metrics_to_values, metrics_to_updates = ( + tf.contrib.metrics.aggregate_metric_map(metric_map)) + + for metric_name, metric_value in six.iteritems(metrics_to_values): + slim.summaries.add_scalar_summary( + metric_value, metric_name, print_summary=True) + + num_batches = int( + math.ceil(dataset.num_samples / float(FLAGS.eval_batch_size))) + + tf.logging.info('Eval num images %d', dataset.num_samples) + tf.logging.info('Eval batch size %d and num batch %d', + FLAGS.eval_batch_size, num_batches) + + num_eval_iters = None + if FLAGS.max_number_of_evaluations > 0: + num_eval_iters = FLAGS.max_number_of_evaluations + slim.evaluation.evaluation_loop( + master=FLAGS.master, + checkpoint_dir=FLAGS.checkpoint_dir, + logdir=FLAGS.eval_logdir, + num_evals=num_batches, + eval_op=list(metrics_to_updates.values()), + max_number_of_evaluations=num_eval_iters, + eval_interval_secs=FLAGS.eval_interval_secs) + + +if __name__ == '__main__': + flags.mark_flag_as_required('checkpoint_dir') + flags.mark_flag_as_required('eval_logdir') + flags.mark_flag_as_required('dataset_dir') + tf.app.run() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/export_model.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/export_model.py new file mode 100644 index 0000000..c2ad6a6 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/export_model.py @@ -0,0 +1,166 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Exports trained model to TensorFlow frozen graph.""" + +import os +import tensorflow as tf + +from tensorflow.python.tools import freeze_graph +from deeplab import common +from deeplab import input_preprocess +from deeplab import model + +slim = tf.contrib.slim +flags = tf.app.flags + +FLAGS = flags.FLAGS + +flags.DEFINE_string('checkpoint_path', None, 'Checkpoint path') + +flags.DEFINE_string('export_path', None, + 'Path to output Tensorflow frozen graph.') + +flags.DEFINE_integer('num_classes', 21, 'Number of classes.') + +flags.DEFINE_multi_integer('crop_size', [513, 513], + 'Crop size [height, width].') + +# For `xception_65`, use atrous_rates = [12, 24, 36] if output_stride = 8, or +# rates = [6, 12, 18] if output_stride = 16. For `mobilenet_v2`, use None. Note +# one could use different atrous_rates/output_stride during training/evaluation. +flags.DEFINE_multi_integer('atrous_rates', None, + 'Atrous rates for atrous spatial pyramid pooling.') + +flags.DEFINE_integer('output_stride', 8, + 'The ratio of input to output spatial resolution.') + +# Change to [0.5, 0.75, 1.0, 1.25, 1.5, 1.75] for multi-scale inference. +flags.DEFINE_multi_float('inference_scales', [1.0], + 'The scales to resize images for inference.') + +flags.DEFINE_bool('add_flipped_images', False, + 'Add flipped images during inference or not.') + +# Input name of the exported model. +_INPUT_NAME = 'ImageTensor' + +# Output name of the exported model. +_OUTPUT_NAME = 'SemanticPredictions' + + +def _create_input_tensors(): + """Creates and prepares input tensors for DeepLab model. + + This method creates a 4-D uint8 image tensor 'ImageTensor' with shape + [1, None, None, 3]. The actual input tensor name to use during inference is + 'ImageTensor:0'. + + Returns: + image: Preprocessed 4-D float32 tensor with shape [1, crop_height, + crop_width, 3]. + original_image_size: Original image shape tensor [height, width]. + resized_image_size: Resized image shape tensor [height, width]. + """ + # input_preprocess takes 4-D image tensor as input. + input_image = tf.placeholder(tf.uint8, [1, None, None, 3], name=_INPUT_NAME) + original_image_size = tf.shape(input_image)[1:3] + + # Squeeze the dimension in axis=0 since `preprocess_image_and_label` assumes + # image to be 3-D. + image = tf.squeeze(input_image, axis=0) + resized_image, image, _ = input_preprocess.preprocess_image_and_label( + image, + label=None, + crop_height=FLAGS.crop_size[0], + crop_width=FLAGS.crop_size[1], + min_resize_value=FLAGS.min_resize_value, + max_resize_value=FLAGS.max_resize_value, + resize_factor=FLAGS.resize_factor, + is_training=False, + model_variant=FLAGS.model_variant) + resized_image_size = tf.shape(resized_image)[:2] + + # Expand the dimension in axis=0, since the following operations assume the + # image to be 4-D. + image = tf.expand_dims(image, 0) + + return image, original_image_size, resized_image_size + + +def main(unused_argv): + tf.logging.set_verbosity(tf.logging.INFO) + tf.logging.info('Prepare to export model to: %s', FLAGS.export_path) + + with tf.Graph().as_default(): + image, image_size, resized_image_size = _create_input_tensors() + + model_options = common.ModelOptions( + outputs_to_num_classes={common.OUTPUT_TYPE: FLAGS.num_classes}, + crop_size=FLAGS.crop_size, + atrous_rates=FLAGS.atrous_rates, + output_stride=FLAGS.output_stride) + + if tuple(FLAGS.inference_scales) == (1.0,): + tf.logging.info('Exported model performs single-scale inference.') + predictions = model.predict_labels( + image, + model_options=model_options, + image_pyramid=FLAGS.image_pyramid) + else: + tf.logging.info('Exported model performs multi-scale inference.') + predictions = model.predict_labels_multi_scale( + image, + model_options=model_options, + eval_scales=FLAGS.inference_scales, + add_flipped_images=FLAGS.add_flipped_images) + + predictions = tf.cast(predictions[common.OUTPUT_TYPE], tf.float32) + # Crop the valid regions from the predictions. + semantic_predictions = tf.slice( + predictions, + [0, 0, 0], + [1, resized_image_size[0], resized_image_size[1]]) + # Resize back the prediction to the original image size. + def _resize_label(label, label_size): + # Expand dimension of label to [1, height, width, 1] for resize operation. + label = tf.expand_dims(label, 3) + resized_label = tf.image.resize_images( + label, + label_size, + method=tf.image.ResizeMethod.NEAREST_NEIGHBOR, + align_corners=True) + return tf.cast(tf.squeeze(resized_label, 3), tf.int32) + semantic_predictions = _resize_label(semantic_predictions, image_size) + semantic_predictions = tf.identity(semantic_predictions, name=_OUTPUT_NAME) + + saver = tf.train.Saver(tf.model_variables()) + + tf.gfile.MakeDirs(os.path.dirname(FLAGS.export_path)) + freeze_graph.freeze_graph_with_def_protos( + tf.get_default_graph().as_graph_def(add_shapes=True), + saver.as_saver_def(), + FLAGS.checkpoint_path, + _OUTPUT_NAME, + restore_op_name=None, + filename_tensor_name=None, + output_graph=FLAGS.export_path, + clear_devices=True, + initializer_nodes=None) + + +if __name__ == '__main__': + flags.mark_flag_as_required('checkpoint_path') + flags.mark_flag_as_required('export_path') + tf.app.run() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/ade20k.md b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/ade20k.md new file mode 100644 index 0000000..d7d8a38 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/ade20k.md @@ -0,0 +1,108 @@ +# Running DeepLab on ADE20K Semantic Segmentation Dataset + +This page walks through the steps required to run DeepLab on ADE20K dataset on a +local machine. + +## Download dataset and convert to TFRecord + +We have prepared the script (under the folder `datasets`) to download and +convert ADE20K semantic segmentation dataset to TFRecord. + +```bash +# From the tensorflow/models/research/deeplab/datasets directory. +bash download_and_convert_ade20k.sh +``` + +The converted dataset will be saved at ./deeplab/datasets/ADE20K/tfrecord + +## Recommended Directory Structure for Training and Evaluation + +``` ++ datasets + - build_data.py + - build_ade20k_data.py + - download_and_convert_ade20k.sh + + ADE20K + + tfrecord + + exp + + train_on_train_set + + train + + eval + + vis + + ADEChallengeData2016 + + annotations + + training + + validation + + images + + training + + validation +``` + +where the folder `train_on_train_set` stores the train/eval/vis events and +results (when training DeepLab on the ADE20K train set). + +## Running the train/eval/vis jobs + +A local training job using `xception_65` can be run with the following command: + +```bash +# From tensorflow/models/research/ +python deeplab/train.py \ + --logtostderr \ + --training_number_of_steps=150000 \ + --train_split="train" \ + --model_variant="xception_65" \ + --atrous_rates=6 \ + --atrous_rates=12 \ + --atrous_rates=18 \ + --output_stride=16 \ + --decoder_output_stride=4 \ + --train_crop_size=513 \ + --train_crop_size=513 \ + --train_batch_size=4 \ + --min_resize_value=513 \ + --max_resize_value=513 \ + --resize_factor=16 \ + --dataset="ade20k" \ + --tf_initial_checkpoint=${PATH_TO_INITIAL_CHECKPOINT} \ + --train_logdir=${PATH_TO_TRAIN_DIR}\ + --dataset_dir=${PATH_TO_DATASET} +``` + +where ${PATH\_TO\_INITIAL\_CHECKPOINT} is the path to the initial checkpoint. +${PATH\_TO\_TRAIN\_DIR} is the directory in which training checkpoints and +events will be written to (it is recommended to set it to the +`train_on_train_set/train` above), and ${PATH\_TO\_DATASET} is the directory in +which the ADE20K dataset resides (the `tfrecord` above) + +**Note that for train.py:** + +1. In order to fine tune the BN layers, one needs to use large batch size (> + 12), and set fine_tune_batch_norm = True. Here, we simply use small batch + size during training for the purpose of demonstration. If the users have + limited GPU memory at hand, please fine-tune from our provided checkpoints + whose batch norm parameters have been trained, and use smaller learning rate + with fine_tune_batch_norm = False. + +2. User should fine tune the `min_resize_value` and `max_resize_value` to get + better result. Note that `resize_factor` has to be equal to `output_stride`. + +3. The users should change atrous_rates from [6, 12, 18] to [12, 24, 36] if + setting output_stride=8. + +4. The users could skip the flag, `decoder_output_stride`, if you do not want + to use the decoder structure. + +## Running Tensorboard + +Progress for training and evaluation jobs can be inspected using Tensorboard. If +using the recommended directory structure, Tensorboard can be run using the +following command: + +```bash +tensorboard --logdir=${PATH_TO_LOG_DIRECTORY} +``` + +where `${PATH_TO_LOG_DIRECTORY}` points to the directory that contains the train +directorie (e.g., the folder `train_on_train_set` in the above example). Please +note it may take Tensorboard a couple minutes to populate with data. diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/cityscapes.md b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/cityscapes.md new file mode 100644 index 0000000..8e89703 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/cityscapes.md @@ -0,0 +1,160 @@ +# Running DeepLab on Cityscapes Semantic Segmentation Dataset + +This page walks through the steps required to run DeepLab on Cityscapes on a +local machine. + +## Download dataset and convert to TFRecord + +We have prepared the script (under the folder `datasets`) to convert Cityscapes +dataset to TFRecord. The users are required to download the dataset beforehand +by registering the [website](https://www.cityscapes-dataset.com/). + +```bash +# From the tensorflow/models/research/deeplab/datasets directory. +sh convert_cityscapes.sh +``` + +The converted dataset will be saved at ./deeplab/datasets/cityscapes/tfrecord. + +## Recommended Directory Structure for Training and Evaluation + +``` ++ datasets + + cityscapes + + leftImg8bit + + gtFine + + tfrecord + + exp + + train_on_train_set + + train + + eval + + vis +``` + +where the folder `train_on_train_set` stores the train/eval/vis events and +results (when training DeepLab on the Cityscapes train set). + +## Running the train/eval/vis jobs + +A local training job using `xception_65` can be run with the following command: + +```bash +# From tensorflow/models/research/ +python deeplab/train.py \ + --logtostderr \ + --training_number_of_steps=90000 \ + --train_split="train" \ + --model_variant="xception_65" \ + --atrous_rates=6 \ + --atrous_rates=12 \ + --atrous_rates=18 \ + --output_stride=16 \ + --decoder_output_stride=4 \ + --train_crop_size=769 \ + --train_crop_size=769 \ + --train_batch_size=1 \ + --dataset="cityscapes" \ + --tf_initial_checkpoint=${PATH_TO_INITIAL_CHECKPOINT} \ + --train_logdir=${PATH_TO_TRAIN_DIR} \ + --dataset_dir=${PATH_TO_DATASET} +``` + +where ${PATH_TO_INITIAL_CHECKPOINT} is the path to the initial checkpoint +(usually an ImageNet pretrained checkpoint), ${PATH_TO_TRAIN_DIR} is the +directory in which training checkpoints and events will be written to, and +${PATH_TO_DATASET} is the directory in which the Cityscapes dataset resides. + +**Note that for {train,eval,vis}.py**: + +1. In order to reproduce our results, one needs to use large batch size (> 8), + and set fine_tune_batch_norm = True. Here, we simply use small batch size + during training for the purpose of demonstration. If the users have limited + GPU memory at hand, please fine-tune from our provided checkpoints whose + batch norm parameters have been trained, and use smaller learning rate with + fine_tune_batch_norm = False. + +2. The users should change atrous_rates from [6, 12, 18] to [12, 24, 36] if + setting output_stride=8. + +3. The users could skip the flag, `decoder_output_stride`, if you do not want + to use the decoder structure. + +4. Change and add the following flags in order to use the provided dense prediction cell. + +```bash +--model_variant="xception_71" +--dense_prediction_cell_json="deeplab/core/dense_prediction_cell_branch5_top1_cityscapes.json" + +``` + +A local evaluation job using `xception_65` can be run with the following +command: + +```bash +# From tensorflow/models/research/ +python deeplab/eval.py \ + --logtostderr \ + --eval_split="val" \ + --model_variant="xception_65" \ + --atrous_rates=6 \ + --atrous_rates=12 \ + --atrous_rates=18 \ + --output_stride=16 \ + --decoder_output_stride=4 \ + --eval_crop_size=1025 \ + --eval_crop_size=2049 \ + --dataset="cityscapes" \ + --checkpoint_dir=${PATH_TO_CHECKPOINT} \ + --eval_logdir=${PATH_TO_EVAL_DIR} \ + --dataset_dir=${PATH_TO_DATASET} +``` + +where ${PATH_TO_CHECKPOINT} is the path to the trained checkpoint (i.e., the +path to train_logdir), ${PATH_TO_EVAL_DIR} is the directory in which evaluation +events will be written to, and ${PATH_TO_DATASET} is the directory in which the +Cityscapes dataset resides. + +A local visualization job using `xception_65` can be run with the following +command: + +```bash +# From tensorflow/models/research/ +python deeplab/vis.py \ + --logtostderr \ + --vis_split="val" \ + --model_variant="xception_65" \ + --atrous_rates=6 \ + --atrous_rates=12 \ + --atrous_rates=18 \ + --output_stride=16 \ + --decoder_output_stride=4 \ + --vis_crop_size=1025 \ + --vis_crop_size=2049 \ + --dataset="cityscapes" \ + --colormap_type="cityscapes" \ + --checkpoint_dir=${PATH_TO_CHECKPOINT} \ + --vis_logdir=${PATH_TO_VIS_DIR} \ + --dataset_dir=${PATH_TO_DATASET} +``` + +where ${PATH_TO_CHECKPOINT} is the path to the trained checkpoint (i.e., the +path to train_logdir), ${PATH_TO_VIS_DIR} is the directory in which evaluation +events will be written to, and ${PATH_TO_DATASET} is the directory in which the +Cityscapes dataset resides. Note that if the users would like to save the +segmentation results for evaluation server, set also_save_raw_predictions = +True. + +## Running Tensorboard + +Progress for training and evaluation jobs can be inspected using Tensorboard. If +using the recommended directory structure, Tensorboard can be run using the +following command: + +```bash +tensorboard --logdir=${PATH_TO_LOG_DIRECTORY} +``` + +where `${PATH_TO_LOG_DIRECTORY}` points to the directory that contains the +train, eval, and vis directories (e.g., the folder `train_on_train_set` in the +above example). Please note it may take Tensorboard a couple minutes to populate +with data. diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/export_model.md b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/export_model.md new file mode 100644 index 0000000..c41649e --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/export_model.md @@ -0,0 +1,23 @@ +# Export trained deeplab model to frozen inference graph + +After model training finishes, you could export it to a frozen TensorFlow +inference graph proto. Your trained model checkpoint usually includes the +following files: + +* model.ckpt-${CHECKPOINT_NUMBER}.data-00000-of-00001, +* model.ckpt-${CHECKPOINT_NUMBER}.index +* model.ckpt-${CHECKPOINT_NUMBER}.meta + +After you have identified a candidate checkpoint to export, you can run the +following commandline to export to a frozen graph: + +```bash +# From tensorflow/models/research/ +# Assume all checkpoint files share the same path prefix `${CHECKPOINT_PATH}`. +python deeplab/export_model.py \ + --checkpoint_path=${CHECKPOINT_PATH} \ + --export_path=${OUTPUT_DIR}/frozen_inference_graph.pb +``` + +Please also add other model specific flags as you use for training, such as +`model_variant`, `add_image_level_feature`, etc. diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/faq.md b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/faq.md new file mode 100644 index 0000000..c816249 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/faq.md @@ -0,0 +1,82 @@ +# FAQ +___ +Q1: What if I want to use other network backbones, such as ResNet [1], instead of only those provided ones (e.g., Xception)? + +A: The users could modify the provided core/feature_extractor.py to support more network backbones. +___ +Q2: What if I want to train the model on other datasets? + +A: The users could modify the provided dataset/build_{cityscapes,voc2012}_data.py and dataset/segmentation_dataset.py to build their own dataset. +___ +Q3: Where can I download the PASCAL VOC augmented training set? + +A: The PASCAL VOC augmented training set is provided by Bharath Hariharan et al. [2] Please refer to their [website](http://home.bharathh.info/pubs/codes/SBD/download.html) for details and consider citing their paper if using the dataset. +___ +Q4: Why the implementation does not include DenseCRF [3]? + +A: We have not tried this. The interested users could take a look at Philipp Krähenbühl's [website](http://graphics.stanford.edu/projects/densecrf/) and [paper](https://arxiv.org/abs/1210.5644) for details. +___ +Q5: What if I want to train the model and fine-tune the batch normalization parameters? + +A: If given the limited resource at hand, we would suggest you simply fine-tune +from our provided checkpoint whose batch-norm parameters have been trained (i.e., +train with a smaller learning rate, set `fine_tune_batch_norm = false`, and +employ longer training iterations since the learning rate is small). If +you really would like to train by yourself, we would suggest + +1. Set `output_stride = 16` or maybe even `32` (remember to change the flag +`atrous_rates` accordingly, e.g., `atrous_rates = [3, 6, 9]` for +`output_stride = 32`). + +2. Use as many GPUs as possible (change the flag `num_clones` in train.py) and +set `train_batch_size` as large as possible. + +3. Adjust the `train_crop_size` in train.py. Maybe set it to be smaller, e.g., +513x513 (or even 321x321), so that you could use a larger batch size. + +4. Use a smaller network backbone, such as MobileNet-v2. + +___ +Q6: How can I train the model asynchronously? + +A: In the train.py, the users could set `num_replicas` (number of machines for training) and `num_ps_tasks` (we usually set `num_ps_tasks` = `num_replicas` / 2). See slim.deployment.model_deploy for more details. +___ +Q7: I could not reproduce the performance even with the provided checkpoints. + +A: Please try running + +```bash +# Run the simple test with Xception_65 as network backbone. +sh local_test.sh +``` + +or + +```bash +# Run the simple test with MobileNet-v2 as network backbone. +sh local_test_mobilenetv2.sh +``` + +First, make sure you could reproduce the results with our provided setting. +After that, you could start to make a new change one at a time to help debug. +___ +Q8: What value of `eval_crop_size` should I use? + +A: Our model uses whole-image inference, meaning that we need to set `eval_crop_size` equal to `output_stride` * k + 1, where k is an integer and set k so that the resulting `eval_crop_size` is slightly larger the largest +image dimension in the dataset. For example, we have `eval_crop_size` = 513x513 for PASCAL dataset whose largest image dimension is 512. Similarly, we set `eval_crop_size` = 1025x2049 for Cityscapes images whose +image dimension is all equal to 1024x2048. +___ + +## References + +1. **Deep Residual Learning for Image Recognition**
+ Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun
+ [[link]](https://arxiv.org/abs/1512.03385), In CVPR, 2016. + +2. **Semantic Contours from Inverse Detectors**
+ Bharath Hariharan, Pablo Arbelaez, Lubomir Bourdev, Subhransu Maji, Jitendra Malik
+ [[link]](http://home.bharathh.info/pubs/codes/SBD/download.html), In ICCV, 2011. + +3. **Efficient Inference in Fully Connected CRFs with Gaussian Edge Potentials**
+ Philipp Krähenbühl, Vladlen Koltun
+ [[link]](http://graphics.stanford.edu/projects/densecrf/), In NIPS, 2011. diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/image1.jpg b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/image1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..939b6f9cef3da337e1279246090f20bd78920bc8 GIT binary patch literal 151959 zcmb??WmFwa6XwO;U4zTTU4uJZ+}+*bVu29c-7fC#F2UVNa0>(v5P}n&<^A5>^X@OB_&N%)m3EVm89P* z003xqaVZIDXiNaW$=TCgT~>lZS5Kb;VGaNffC2m`nOS(aimR$B{Znvuakl!G`oHIQ z%Yb)D0KfvvKeGP!n*R%oY~kwe`Of$Jesfw{c~}4dQ0(v6!Q0dIoeq`rj&aQ${(~F- z!S0&slJE54cZ_cHFJAlyoBxaV|H1C>5An`(^AEqxe=s!SKiK?VO!^P@wDS2!FF?}8 z)z{t5#@3U9LqI@)Lfq2D+=@cO*Td7w$%8`P*}}!$)y3V+)5`Ll_uu~g(+Ys~FXKNW z#_-;dpYcD`|Bu-}^YE{@YqkH3FBJate`)_!WC3>f`ky5zXf6QY|5X03j2uD$K&2D_ zfPMZijXMqiC}0KvFw*`@qvHSoFxdcr-ki5r0I7wOD;FyVJL`L<9u^uJ4lxcM z0RbT)AqF-H83`d7{yY3f2-JI1csO_zcz6^-3^a^)>i=VU>jz*VLRCY5fq}vTKx09{ zU_reN1IXT&JIwpr@XxycH^ITfA|S#*LjjQ9t938|P%zN2urP3Nun2JQFfeG)P%yA? zSO9ozN(3A#4qQ%gL~02&Gdy*3w;(R}q(Xce$>7F;3nYT%?>n^I8Wu&DgiV8VQko(2 zS48w4Da}06p2fTGf=QtM)%(A+{?iQr)cfEdyjM!Tcko>;3_KhR>^}e&0SX!bgGGtW z0V}QsheKuNb`g|R*f_xXeFq+w`cgvO9goXAxJWX&X%L@=Tf<|1_iY`33iGZ43kC}y z3K;paM4OM!wGp5;xTwr6fAHM6(yi9VSl*L+pPzd5qOPo!1OZiCg@1n*cMNm6y?O%( zTh%Ki`P78?&_~@?eCwcxILStdj>v0oWY3&BCiy9Psz2BCCI3`&77Nbg;>wQiq}i8q z-So_Gck_$-?6c-9VGHfk_LTzuIHpgJ5|MQ}hHwK~W&^B-qT>jIsRS(^!HBVVHS2BN zqv#_nB_RQ=De(qa2;*3aMBvZ==8U}(xRsB1oH_Xw-@={Zb)4r@6O*1i7K`WelLa*^ z1js{rmCkHW^l_Ldvxo?L9Gq&`C>p*>GKehCOf^E!awI2kqU=~JgrT0%9f7MTj!+2p z*KKkGFrj9uJn1elW+t%jKcL;TT<=ftGX@|QWhhBG@H`iWB+JT6>2z?=(V2WMR!siR z2^5soT2lLb?8SCD1ZU<`Xu!)^FpcY7xi&zJWv}(VTWWOFkWavN=BvGzzSBh=&aI=>yb`v%w`gbI>F;uAU)ZL(svH>hdk zlVvCMXn%YIv-T?w?NbY7pl2bavhd1TC?bp)edB(1~Q#|Tm@Y$axr%I$Ua zq+xvudfY%+J?0$J)u(=v-hXaS3rPJr8-+Dm75Zepu(A2-m(kj?jjBb6ndX_qWj5_| z_+^4#y7dFgD>HUQxOMwa9TJ~UsT~G)o)z=QS86Tvipgd0+E2%)4?B*Yhx17{M5Ua? zsB;rd&6<%#i&+`HQf`7_UpAbu#3i8cm|_C``YfGoNt2mY>~|jFTpY8sjVSCqMiaHL>ke_E#TAM_+2&x0_o#$L3Nv&0=UY$6ZLJ+6q9ygC zmZt>`?YA==&8s4`Ak#~@+nkBhnLnAh6R;?9eFxqE!$!I^1uhJX(U?pWY3)`-i z{J|I9Wri5Z1;l36C8AExL;2Acg{OGzad=d07J7EQGt2Z;hqGm;9q#Gt7Vn6hYDqQi-8--;pC0Y@`)h zJ-nMnOoBB!ywv3P{D4l;AsFwXZ1 zB-}6|%z30wqKCwPRJ_Wb698MgEWPtd1kVlMK%lmGK*MnJ$`@B^*DgfqoQ-&st)%DI z{2fOPHD)%(O7rWU4@~MlZX%WWptJd>|JFE-%6TjZa18>VAwaz2LAO={P5=op7 ztz#02dsSHPauAk2@2DhCthA^8bNaEq3C055Q45@U*ggYda=FoUXLpP=^+>x3e4Tp| z);`7)Y;jF4`pJWcyt&3TQ7*r}m-A>R%+WNxo{i zS=%WDxmXXp4CiZ8Z{~6w`x}8joKxH5iHY&(4bWV9i|)Y+pUf`B7V{E_3efme`Gw7Q z&;+M>*<@$aKO_A_9zB~yK#Xd&vZ})PO2KhSL+P)wLFVV9WdYy0GigBjSbNq#D=HRQI9T^mnKP_ zg+LJuA^uXcQ&P=Ey&RqlH%4y$W+uxec2Q@0=;C}FY8IbcWr#u#Jiwi_Q z%r@`-coH5d-p7WCae4zVi)7iYW8z1vy1%H`>$@9aMMPB`S4;~b@0_V=>J{PxbZ2-V zK029K5l!60bL(*vTmbr;I(vz=x?|5Hgk+ z-i}E`U~Bz3!u&pS&9Gj}TAoo=GY@pk=g`?QIEe4k)DKagu?iwgphV^gj0jPh&}5Wy z+c;G8k(4XL2F07hokJQ?sBGku3@fFkQb}#-&QOH<6u3%PSO$j_jw(NJXt(mkEoOjry9d(o>$G@MT-3={brz*vb(8>L#i&e3O{1s zCoDw#d+AoHnBmJc2Ghx<|KP%pGBuIoxY%cp} ztsB_A0Z`4WN?Jq3(fk!fzZlQsDb0;|GYG^Mqu4BC3uhQSI7Qn_%SL0Gr|365VIQw& zbAX#w_Ci;q3fRp!Wn1n{Dy@DWE7vr#ER=K~=BX63c}sklVa+dNcCnbH0U+s#gKFgK z29i{RR1@pDd&H#YeTwj?JdXt;ml*2joQA-8YUOGIakyDySXEAFu2Gu>qyb=$CJ%~K z4@}o~T#w5Dp)w-FT&nLw4j`sfpErQiWT!j1@zkO(9bP2a z3Nmf=$aA&Y-0LWtc47V+7(eS0mC+CAQquA#pIJTL8d%Y0jURq19vym&7g}(0ckQZ7Pq=1aP!i zX*pw!(!Ik-b!lQtv5l97x@LSdxZg%)#UCEiq=r>O0tRV3@zhBgE&w{qr;fv!;Q5nk z>GlP7bocPcqv!-MMLEhgvDQ3K&Z0E+Kt*eAzAu1XGV6AkpCyEvKJNH{u>FsuJWQZy z|F4f`EU|L?VGZFv0g!^DKAWA?#AmF?V=A`%Ie#hB)$j<_m{j4}TWHT!=j^6cgqgM< zqCBno%cJ_v>X*O+H>699h=Z)A6!ejV7qk8OI^f-hI`mdDFKQn!WBPbzlTNdMj(V%zVXU&Ity=>o>n}9xrNpX~!;}@@cT&Spo^BE?mDvYU>e_4<@%f8}V|JgI|5auyoB zgBQu381vAu*{L}f1Mv^*OtC$w3U-=O@$g)e&x+M*{^zGLfBw)yMcKHHHj3pAM`8oj zuuLwgr>K-uUtE*9GsSdga+NZO(=rA*WW_C1&fs{J9N-u1TSF(i)pr+gMO`9U4v_yQ zlyZ`;U99{4&R)5)f7p1~fs(}5u?^qGqUUuR1UsxVpW^=VqrQS?M@r794?KziDw|>| zD>c|0eQ5PjM2D7jBzJXICidHdETNc=qz~60e(Tg)v250IwM0IhUo+b+V}|`Q*7qcl zFf^Vh6`sI(o=O%rYOJJ*ENI!cO2RFoA&3$YrFAdG;Yk*sE#Ljialp65P z$0Wb9Rly4k#67+l#QT)PQk^9Wy2bWZa^}Hbj$4YN3c%r14!O%xvLuG+XPfnX@!Wpq zP?E4lZoo-5jxd_aqm)lCp?o>mz8(Y$_7n)9wd~@V1x8tChNN$P!cS@+@h1;*sL28~ z(#d|#q~?)jotj z-Icw!qVUZ_8Q{2-F(U@=O8d)qZF(fiRP^!)3g4fK} zv$uH6C1X>f2Y2ike0~EcL01YyYqCJ-xxX{$$*u)Uomd$g0*_c6Y29?9?+c1^!oj@n*#i0cr6cHEO3V)0`>6svxhNVI*4XCZ8+Tw$B8&5epBD}7W9JfW4CNPACN`P_x zbq@aowu!EAN`RhjDIhwl>Js@tcuWI!$8P@z4>a1>0GF##_kL(gWEO}4#YLV{&YD0p znWsd$(#<3Z)`@}VD+JF-7Mn#VGxwSezBy)VS&O+gy>d=#Qh*UB_P1al7VFArY6bL> zFW`WMG$`>@kD6Lka$5ECbcIOhVT7ap*u@56NA{v^RVJsl^&AuA-r@zuxnu#bihXTjIG^D7t##S0mIWC;I>w+&`$9bThUv<5T=Fg$kn*6iM%zcstx}Z)V zz_ef#3G0?`0_reoA2ZDs%tu^-jF*K0pZ^}jj=+h3cC)6v?`&$ut%vnW9V+=KR7k}N zC<=nW8u*SqD(a%Hy#ef~BTD^4zWhmyRcttb)8VhaQ#STaow^ZYHenDw}g)4su7BpK|ypYQl!aZ?$xh&)jgk&PV^(mbT~BN8j!*2}vr zYbV&dF#ZO3p1aH;yF0mID!UOM>rJe~8-|fxh4(2m~edaxa+IvcLBxQF^mQA`FhI~NU>2FD;3bhw#u(c+A0G0e2oAh|y-)`Mx^ zw`^MaK}w1|v0tyfk*YX)vTYxVV*QV6-8cP7q!vomPoGv*Ey~r77(yH%$bCuH+Wfx6 z-3PW>htfzSRJRY$?`ss8s|s%#Ql@pOb>I0nSI1IA!VU^+VIdB#6$6!N)BMBa+Mni( zYr`XkCK9KJ2>JFB#i#A=e9<}FNpI}&7THX-(wADEKjpOJoLnZuJs15oPRuZP%3$%| z{b-!Xu%hTZu&QiCC9?X`=7=0Sz)OPMjj7l)Mr`LsB@D*3XfpIl6Lw7x<%4p}MesVv zQi0<}E4?Z=hU`0^v2LApclvo_s=cK>b*%Maf`pQ#*Z0pSeQZNvX@d2*xF=VUG6fBI zvwj}+OTn>J0nT{h&n+535eocy@up?#jXv0QY_|Gnf--IRi1(TFKdSErSFgT|iXfnS zfayH>jt1t@pN7oRPSqX^P&i}?__6mVyV0iBcB$1%2sN@?!7w!XXrC3WPE@`t0zgGW zyerY9=0C%&c9xBwWb?_LFk>V{f=bq<&#Hd#tM^5ZvXib(8mImmm@eWN2N(W8eghoE zu_SpAdhpi6_+$wDz8Vp9GF8r6AmDaQDQIgyj-?#A#;h$FAfL}HUGE8q_Vml~K2`?X zk(Vy!b*12af+(!#WM(lmY}>a3xowb)`V`PJ4)r#4hpRN9Wj){W{;>`Xe?cXO>w``OmlCR>Y0V*r^HScIQ2+xdiOTpMc1uE=8}@~{*8MWT^0V%n z1g~c9#@v;y!zv4esn7I{LQQ@TP&(uJQA})=j{54!Qx+g^2_AG z)W@$-4j$8AA7Q)`TF75kutzp;O7fhDQi}xdynUsO%p_WsJIX}^A4m0om31alBP642 zdpqh_-L{bbWhQ@m1EzN2>Qs6yQl=i~4FzEnCht5V(}RT~%g74WZ&nV53E$-u zg-TG_qJdi!g~R;Wh};`M^w!@JqoZZY*L**ZR-x8vHRsr^B`$eO{gu#3@CX2T1j`RM zb_b{jSn5Bqv{Uj6^;ADM7ONdcKBXUEbp#F7w5skXB?AM)dHZ{wsIAC)A!PuRkseBi zX_v9?=pTZOiphAR^bO1#sk}Ijtu6--8yMvpn7GGjMG>5qKFsoRZjpSne;i`quLh2g zE|vqR^3UXzlvbuQr0jM2J_u60oca|3w^6F#>L@Xhx9oa3t(Y6$&(Ukz?x8_WMyec$ zN8bY4RUXXXQhma|E6MCy<_yT^%T0q~%Z&c^m3;s$jSSN?#y?ZfVE=mdu!=4b@x)fv zdmbRzBW0~iBMvQB<>DU0^VuMd`F)4`+#p^hDcpxCA3&fICK9+4hMZMX-9oK?k3%e< zesySqxffD7yclxuXh7^4qpv?Y-7200EZCUisQ{bwa%u-qp-DQ*w(qM%LDYIRBFak} zdO3jbSQJQ)MecOg6kaIyL*;*_72D7p*{u*aq$bwdN|W>ApXM~Pol3RS#=2u}hM?0a zD#Cid8?ab9Qy(d%k?RCGO*#@e+ePnXX~trxWVCxSyTC%(ntEpKQQ08tKZ(GAT@kUV z=_9;^_Da5lIGCq>A&Qe#ZQ~-h7IX=|+pLz1d>EUmQ{YihkzQ z_69R85WI-sOiVlL!Ip3YFpI&@GYq-bq8!wG1lA+us3yZK&okPch)Gs2+Sj}7AwbJb zic_p=8E#&3?VOU;^u%CR3dKg5XRdw3q=`uWyAef+CQ-ITay8aH^P2hFhdS3mi^cWG z`yF~X>eFxfYVU@CMgAUq4smnI8|FRPDIS92!bV(hGj;W!hm=!CF4#e6?F-wvscFkq zVgmM?ZDO*UNa;qln*3CvDI!-AcU@Z0Y~fN{(s?W%69NAh{ebD#Wrpkc6pgB{bXh{~ z(q4{d2O|_Tj$pHTAgtXb4QoIocz!el(ioPo0~^BF79ZN_{o6?h-}6_V*v6 zQ&iWjYKU}3KPe56fAzr}k)tk&UI+aoeadxz1K`-i$|4N5W7WBf$Q5O8yOf{C*erWQ z@&N6*L?jC1j6Zoks&Ei9QcN}9u(6bwXg!!&B|H~w)Y!~rQst7w-sDtE)rQoiFr4m7 zFH#@BoR<;8#nYYa~oVMSJ{+ zax;{i7EZGOv(U_41(uMO;EL;b8t(o5^=DSvNC~5WKo;3M0BSSN4Syt)WfhM3DQDGF-Ua20gZqkZBZoAa1;{-&J z*_C!ijR6-$ZJ~q=EiSJSQ!{UtZM9Z&>(|oIB zVF6b)A$ClmR66rhtNylRiBZuj>sZYCI!|OuLVM+M{Aikpzoj49jKd+qf@-NKDC?x_ zphhyqgtdsG8~wrGrF&i~6Y0*v10}Uiz=f9~*a}Bf^uvhc<#&tDsXpVR#mJ5Zrzo*2 z&OdkFlUyF#*jW*}Vx&D-no&hqf5ZE3SF^rwc%|FmbAGD7 z2#?F+OtmW)p$rKg=Ax7h`?M)*H8`Z#OgIUEl_XLT_|6}eZe=;Wro_($mrIN8ofD>U zPjDPIrX8UYooP{TouU9&@tImmbb(26&Kk$gVZk9r zJ(DV!^OKpMxNg&MWQ?v?G1o_iuj~i9iHUbty93D7m_aSn&>pUxS41cx zA?2XPyn?0fb|)E>3e9Y9mJaoGgvgkKUc%II{v;VU6ia)J)>rEJ9rblF$lfkX!U~*P zBz~+7Z_9#jFpCRC!``iYon}eLa-k#1@xuDv8-SpGitvs`22;!33Z%WGY%`tqm}eIw z@0%Vz7wb(R(bxJ2_BIq?0>%*KbF73da2^Kk!itbB9@ojn7S3>hxsmK1{a9Yfp3K>g zh#qUGMKPP8U9(DgHgkUS9?$Qs?(u(2e*?Tb6ueFEx{0GKIKmWghK!S~XH#4!Mw< z>}cJBpNmoUCrX@>ilowaYQJdXT7ds+3+0k2s}5Y6WKy?lqUByM%8;+mT3x(ZYDNsA zUG%s~Ds1S-rfjMV5b0>$3EC3NHB%#lXUJof#%u5V;rs*g!`Cu6|fR`L+=TOrPh z<{Xgumqoimz#}14!+3cpH28yJz()vYUbRK!5nG^W9(jYw~jra57e47?i^j2bXu71)%;z3YhK zL2WU!$`Ur#m{P})QSV=_%fEMvJ8h06=+>TF`^=*ptA!w6a`6;}y|c-bb`fPS7sMI3 zmayb+5gYjhJ&eipK6q$|d15UXGBNhqt1PbI{?i-aEK0sphRXbsDga12Sb$<*Lt$q3nVMSP;J?)+Wz5Jr7Q~@MuA@ z1W%^ti;;?n778b3Rsx;;sr)-M&?x4C$X?MA*Dh=IdHDRUvpZ$+;ru>x$wK0!8vpR1 zcYQ{o2xO(~A^y+9WO?NChx#L>Z(F8QN93sYN;uLg>BI(UKl~>SjPCk3_@EKIJ$y1o zY9_Sm0-Ga#PfrbbGhXr9=<&m1<)DDkzIwg5*{(s$3WrW%!?bM|K}?e9pb%oJ*l{|`?vBbBmp4zuux1KQX#<-yS+0TcSy_#usE4X58Le{gBW#} z`C9u;e?BH(q`9t~YEW$H(2d*b7*D5k#U}1mRT-m9zR)B&6j!=mnC$eXO&WFhjE_Q% zxoi2=gs!F*8{0W6L4W~LZrohBR;L7-B(Iya9he^ItOl=u`p39V_k`_?;Kg{AS5SH% z$3WGGU`VN4BC)~tOlUU=X@&G}>GN}68B&JM315~_>k*?e>w#4Q#H4yY*J<6-D-o%fU{X?V3FvO~vo; z%OF9EVffu1%t?7lLZ6xpNowhHL(Ho!5n@FE&A#o~+r2g~~gg>(^yHUrYh zt*D_%DIlz!R?5*V_aVjIsQv9K30l!q_Aam3^ts3zU^R6Wm0iEnb}yzxGK>4^dIVUJQKv^1?*wK85r{#dZQibvDDN;`()P?tGQ&I-<@zc9g{ z$j+1kM{$)Zx);LK zmV>F4WgS1BoPkGhmoly7!wa=^lTi0k(Cjr&MDs9zx%j|}O_2pp!_#yHKhcqS*t)fc z-$0UH3JWypL10LY971Po@(BssU~f#=Vg>i=6f@m)c5X+2R^g1z8R6AowzlJnL&lJK zYYNe);a&^kuCxWhrUl7tej#)sQ2b9u_k9|!HQ58_-JS;XS-#X>4$7W^och#``8(TE zjR%TTV7Tz$vB+cCXFNka5Pe0sT~ManWj5PXjg^A2Z4zXJaZ4y|f?5Ma`z=fH=7dy> z33b@;9QWr1FLR^@P+1ckjovoqa3{SGc)`rB**RT3SHEvqt#T)JsBt1IQWn4YU{y;H znCvTidflJmL0b>4_7haYMa&jyPD9mfx$6o3{2m#j57~m!ec_|GHYRWl)^g_Rvm5gv z(2Ib4t`fz3UU+xt>cT4EYm6Axbv?H2Dc4SbYZosISd)k=`CFg7>|ROHj?hr-Xt>w6I&PLryRBhvV}bj8D=XTcpG@nZhABLA6y-XSlqME`oh|0A%y^33 z)YTH)KKHm;-Hb&KxSF#O(0#iP!O4|O2g5{uXKY(qWc!uRw1cP6xQJ?GjqXerPyV^7tLwo#`j$g+~Yr?LwdQ8pMNjVYMcA?+zW6sWbPR~)7rfoM2M(6PTLa+ku zuPWbdSvC{AgsgdEH=6T7?ZJ!|DGdU?X9K;vhcEz8VYkVTrb~$UoV9G^h&HWN%FMl% zbZU|c-8yf82#f-Sd*uZX0$)oflgF+G=dn_9RhGz!OB_L)(&9eq^!GCtjZBAl%1bEYjG&bT_W0J-2&)P(>{4B5+9lm@OFWb*XDymBTnXeO%qpRU@wLyYz zU1pHe?=M+yjqz7Xt%Ap`{1=(RVVo3nzBlyG4HEIHvSsYT8Q;6y)R+8%11}&p>62=w zG;^KN^HKFV+x?CKYg#0WS&5{-&K@lW?I+GSd_(%#LRQ9BjEqIWBuudVd0WZAW>N{F z^PX~M9A|*JqcYWOzILTz^i7c3UsfRF=R4MheiZBta}zy>NTN?vPjr)07nMP@6YHBt zj2miMdYUh8In9_lHPLsllC9{X%_x-a$AD|~uxwr$!5V|-S0mnmaA(yp$%e>=t6twZ z^69I1TD!#Zj_BQnziRy2S|=~A4rUbC^)s!<%HIp66BlTnIkZ>OMe&mO-X{bf|4=h& zkp4YNt1lg03+geY35~>&5F~wV5LmY|ve=)l^g{p?E$rWX*HW$@LCjB)<6Q$inxFe* zo*_5Ei#0BDDB}^?>EBaIp?-`_EgwapljZbB@P#Eb>%ae8+XG-_G!mtE#X>s87J?q@dT7`7r}V4EM>EwNQl+IB_e|E>oZub}?lk4s zhTXEZ0p^TR=igiV(+A2I5IE?hRAI0fxLeW<<7;T*v?B$!k|NO0T7LAIm%FUCrEDS& z>T4mybY1AX`yM6(^n}vEgz<~+ly)QCrRA{y{DFR$vF>?H=**wBZL87Q4Chh%%$03+)fvXF~?;Dzc#(51?^CsCjeeH$%7 z_yb=+)L*~!%@H%w@O0N!qeG^@s*pv@-~UoqBQA0)T_%lT-}F%PzXaQ!5T;KcN`wJh zjTf-F!c{uHkO>)Suj*04`-*p9?UoLpZb(d<`T0kOepcZbwCY=9Wvq@7KNrWefojUr zoh6??Ri63q*ELo-+61&hytyi)O@k`Q;UjJ`=MS33;*3qskSqbw6~*kAh#D~kVU!s5 zub8!2m;c;GJ=!-Wya#rSdd^k-%uZN13SIm(V#n-kRjCp}PFlpIEc0|^XZC3-Zl4Q!>(>YX9|UA5nez( z{pc#HE*U$GQ707t9`z)kxohpXznQ)(>lx;J-1JrG^V1ukWFWjH8WH=_Bg&sV>381D z#}fo#DLHTYZme@2P_jBK+8eD6B`) zunL?)D+0dfOZfC%N5+dASTI=Qx*aQ04ygcHOO!0_t;?t;Ptwm3I?l+$hKKD-o^8K< z_^3>Tetg?sN>}DDBw40FWObPl!y`O4K>k_G)k;I(U@B+)l&p4MRK>_di6mFHAg)ri zVR)uxWmE(8K8gmdIxAH95&XP@0zHN!vH-f+>!0VB-D!r^@Lh@d(G^t5?L`9gbu$h6 zG+IEq7d(Ie`J8Y^tgJ-Z_fRos!#2<8>l@%>!xEz_teJE#E!!FOP?d=Gj;DUOw)a5s zT(OHR%wPMM-Vzn*Uc`H43c+Iz7&e>OizCmu}ZIPD4xKNQ(x?HT`m;d~3V>7+1G>517|S2xUM#&n$ZZ%FvqnYoNKU6t<|IIE1roaHD~cT&kVORC?p~K5nIMZLvWN1E%OWv z1RO9tHo~Pi3^NwYIL36Gm|c$X6YX;=N3pG9REvk+W=)gT6i1sq%DbdlrFKQWP)*q1 za!p0+GdVnue^DX(fTodho66K@^sZzB214wItH2aCRLrql;< zQE4~#s=HNEQ;8=sax0Y&J^Xx1EZfzpala|doFSm|88itu7(&z70SmBlL?h-E?AvTpS zFKM+oc3DQAeAbodQ`alfl)!uma2x0mYP zt}DIT_FvNO6h;&_@hxkBN@aP_-sqYqf#xrpUeM0sX%;xw}lhqQ1xrzYs+UBXi zyaX2;oGCwlJ(-nC(6llC!f(J!1GI93G+EmgxiOe89XB6mb?see8nM2f&%xJlAA)$d z3^JL*8uw?*rl)TcWAK%84SRDHw=*ifn!$}02oT}1d9b(~vuf{TSEuf%BTI`ojnf3* zAXm9mze22j%VFQz4bPJ5Wv3fOQL!477T9N08e<$iYq@&(+rO&fM5at{kIPHC1SQ|k?MQx7iVvo7R2?LWjrk5l@epB#&pdWL9%;n9?*vsXY<(t%w5{^R3#D$ zJz?y&1K!bwq@%1Kp12Oym#xcWa(6px+UFn>mGJe687~}}K4p~}Vxcv<>jt;VP-+Yh zpPWSCYO~{wRbMt0s-||~4d$sieZ*LYGoS!{WI|a zy}3+#lKn(a-C8@q18V#`Ik2&IOtArd!+TIq<%C_1o=e7xuc}-GUBC8wFl2ue@wO|Z zZ|CLw!IV{;+&%ShH1K1`CkW#MTg;rMebS_oMf4tHaToUEUe%atmaaYak2|kj$y9~0 z8{dY5W>!0aK+e^7Q+gi$UQ%=wA|H;0OvO;fNBsl_Qdjj8hOayL!NeEYj0@m?hkqY>`0xkynvZueu|fPaYYd6cF{tIr zyN8I1E)*#B%_L`7F!Xr-?_q)WX2;#+`+v!EBzCaKr{y`j`iWRdi#CuB1`6%eJHFEW6!J?Gx5*2Vz+-o&W#3%fTyJgr>thIKXn`1G2p{Ylk!IB>YDo~q2|dQi}cX* z*%o3|0~KCPedtVJgHApbpY&fQltV#&Pa`=|OHl@C+uC?-M*C_0a%qLu$<)!MdP$$-Oz^TH!cFFP8`Lt23gq#WalZtz^l^s;knaugNR*b<&K zEW9vu{?{m%XttaC+eR|!zNSIqpR!HI-;pLoyF4SYigh`WW;H?Ye*{RRL7KUoPsnXp z`E3_Yzt{&HqGBmEc5*FCPqMpb5Yw+z)qAXWjhX$;P)7`0fswNl$WXH5W2YzVaMhcO zX*g+-*&yJqostOUh#~_$iY1~AzDP_umraLJ)1s5Ec(ZsKyq8AA&`MvjvTAGc zdQ67!L-j`i(1w}NjnWqUuv=8J_W7!b>s+XYS_g>wC!%1q0M|GLk`X9{ZO-C7ZsBf` zMUS$B6z4y7ht#|Wnf2g}Hbkt3br}8oXf(O1 z2L=K`#iKc!b-oU=($4&xGV_L#sQsC`u{V#IhGBxzZb(}FVXnLhh97e^C-o}r6F-<{ zfZ{?Fqs(}K??$b=Y@rBG;yAz9S-0tiZk*ZH7j5G7B1eKfwqcVAcF($3>XrbSjz#mu ztTYeiC&QVf9sL8jCQg=@8Qsap<0TeM-Qq2;-8R2ZFKe=Kc*)Mjg|4AJ9Q;*X{gU0l zB~})o-|*em&-IB2*s9wJu_7!zkh06wQ|0Z5>qI#R3SP>n=1bh`(6m6LnHCWktS%=Y zgU_12C_EgQkIxqdPm~7sVE?Ev8LvU))IdcG=Z1$8_^`X2*367ptXQm4bI7VigRYeL z1Ary313$Vkm{TNW_OWnB)d4jHn???w^w7&iy~uBBYGfkf9^0b$TzmE%W* z&8w)DWL>sSUe4Yl0D_s`O;QXMLeq8M3!o`Gx&k!FsOW-ebCa4|sbZDHzD?`M&t?Th zrYG!$CHhXEE9FehF^1EjNCO$%@(?ne#p(+Gm<7B6=1|ck z#-N>i-lLI_rT$QIpFuT6$F@+2iB#V_njx}HBBM71pqFAXCX`%w*5OOPZ$kq~Wes<+ zFonCc#7LbL(Yn$2{j#Zh`tk^gyg1KoAGjFCDzvj_u&KKm?46+4XmB4e?r6HawAxli z^}#ps=a9JfAY#_W_uyKnZp7yPFT&elu1lY+zw6%&FkAhqTOR+B8c*fhvJ+<*6vVK| zIWnFq+$cGT2h3IWh||tr)b)?tL$(Y>T;I5Q^@43!aBjB4emY7!uj(Xy7c&J(9^Uri?Kj! zx|oyKp=w2R9k8+r(6oj_-EKM|gSkk&GlbE=@8eGuVT!6?Sc}%OS;zRja_l4*LsrW= z2@RqMIJ_Y>Ieol9r#-^QCzFCGRlF0BQyS$CK_zxe)O;eaBL~SCQo*q$M*J znHtdWsA^H$hTrk`34KNAU!aB`DD$?s!)jGpS9vm(8?-T7fnek;r zox;j+NMbINfc@L)BD`IrKxjN{skplIeeLlLGozzyG>a~KV_L7-4hu0Gm9ip#Q+)o5 z>0YmXXH=i`Q~7r{vzap=nww-sL$tEPUV*V{&Hn*?K!U$d!z+yggxqD*V)+qz{(q($ za&gvJTjDzLau#3VkFjUjR2LeG^p{7L$oC?;85O^~fn^J2>n+qMu$fG=M-e!O$7+2l zl~kKG=*BKG$2Z*~qW#|3cvVHb0sxy&G*xpY4~JBl8CE1(mSA&3PSc!sl8OqQYk!8= z62~27lWR=<$DFL@W6reb)V#Lib<^vY;l&AeUyJ9udf?HtjKK!RP2slzc#D#Ks;M>T zwH7&Y7;qm{^D;Voq@NZ40Lu}c;?{&NW2JtxpDSETXCb#wrn4rAEKS+&UEz_?x-^d3 zbs=wjEU_4t-6Cfkskw)Tv9A4 zt^E7qsnzbqw}noom9&kQbAJ)50pOTrh_NJVbRE&uBYxLhE|pr1fhk?i1b1tNlqqz$ zm1*Ml+6@M~^Gi;zsQTkjrZh7OEOjd$2WeP-3Rf_NQ3X5#$EqD`oIYY7Q_^tK8 z5?2IbLQ3JI9eT4islj-eqbfsbbT%>?2X@vPf8~N^C3P%gv9_g|SBe}!o0xOMZ`9h1 zBHr3r4L4tw_)c8h?=zFA+{((aGAz89>QmcsnJzo0lnv^?$$wlu5RK#2PMBjXaF;g6 zr@2|2)3opbTe9NlaL4?yRjOkVEYj@ZE=tN&dL36cW(`rI)17Txl^~Y-eFO0k7h(17 zg&^;+V<-(qFY&jEho7qq94x^OB_5idA&78XE_xc>wKp6Q)FtrrCr#G<@zF&cCeRJ? zB{3eanO883BarQWnK``xwGLdDboS_b2Y)-c`N@DVBw4 zSWV9~*{sK?Qru`C)1%6P%Ov!-m4AX^f|&-!Luk28;?wku$Wf})*lz@NLTx1}G(b1D zwj>VW_12p&eX#RHk%+RQYfcqsss?k(5?m=SxYNPnjASO2<|m(5q7v!r^i@PO{iYN~ zEZnAgiENk`i%d|fyeVfhMw29%k0pl%mXoEx<_@FN`E_G8LKtdOG1RfhihNPc*=PDG z0yR3A5XI{H)M#*|L71%yA{XA$chB$HgH z<(Xwqht&I`W2ligT?5>#m}-&E7#!s3yr~>ChZqo<7F*u`02VS4XCy^iFkLc@P@gJa z*(`Gk5Q~lx-%=%)Z}Y=Kk|oL2Ov4saP(I9o$>{gGgW~!w1g|3?o+V6Fj@lb~-P3$f zOGg2SDIR6;K5#r9tEDh{PbjiX;Wjfy&Z=~sVjW5=-w{c@nnf9&;CP8_-Y+v`>l{Y1 z?=IHfHRSpkP2zlKntPVhCI;s-%XC}mTxY7{)-V{&fE-np`whp72mzpO=IR~M3j{c} z*bSq9xHhnrg;R@dvz_M@qiN?=dR!v6Z}R$K9qYBsRiMvx}VErgVU}r1lmR*3rNR;6qIHtWe zRrSKFu^E;(gR?GJs%GzOa+KM$QeAOK_tGGV>xNUV3IPbVoJ}jh+66-|R%KMPB|Vtp z-I`#AR3!3(S>ra+lvFuezZ)GBsfuH|=DQxCT2PGvz`bMFw} zt5W@YVS!8DFG)MhnV=u8gJ4=wOC4dhW{rgS;tEvUZ&ygJB!V+#e9X$X&^6E9lPOG8p6T@lY2uPN8r6j zF3cJEY9&gg1yyxPZ26sE!)5yV<1^Jaw4h9;B~|MZrKK_F=95g4p+|F8vH7LE-=-R> z0K71xc+*YEVK0a8W`&C;3rvODaKS|lZRz*FmIbPR!dVxO8B>E4e8<4=wkp-n3s{sS z>kT7_DfwwFi}Qr_h)4G4KP1n<={UyDv>X^w*j;zbm9sQs9Q%0=t1IEs(bBNj}8f;HfV!HgME8Kfo zez;XZt;raUQQ@?ueWUnqFChCzgr*I{q)S^1-fcT3#9w=L#<~q~RPPkaXt9;@-8QR0 zeoHN_gj3!ZWh^SaR#R!6n8{^T8YXCrrx}S$9MJg$N!Fh%QVl}#FIZBkkmd0|Jya*r z1SqVx99$;d1YTi$*316@5q`LB8letj6p2nniBW|(wKQOYe6rG)OXFLzu)HH_s{NXB zreL2AY?*Kzb1dsrbWHXqJM@R}zB%<J^7pi~ngtHKDm@*oC{g@DplZ{& z^ z>Y3AAC*w?t=Q*~EP${78`uE04;4W933j=T^MZ)a)L&*NnBJ+W)WHODepD^#=^2DSX z`lfnsrLQ!t4~ld;?qN2SZcl4->g2aUBW{XSo= z6Isr~XsWL$8Io(S=Z7a$MIHxM!^v$%>GHyhYQ#erdnV)z{P(tGD7q(7>2ugONyhw& zf}TSB?}sQB1Ds_wH?-AsE*`O$xl#sWhhWfp{_Y&9ZgWseN{+9UsFh!7Y|zDWqOwj4 zt;mYmA6rbg+Ies3trr;_>0)mKKx>ImWL^7+de%$P89i4{pV664GDOu)|#sslchVKiQF8s~J_dkX$vmMAf?jZ#2~**}MJ zAp2TW<>m_W($oS57biIU^M4RkS)$)zqKU-tnagpI!u~_b0IfS5wSO< ztUz}9V2LV0CJ;JJ%+D0+m_6+1-3o0=V~j>EOt3y*_4L9WuG2k6xrR7@oo8iA;ZY&8 z7`#z)F6W;A0OyEU>9~V=aAmF=hZ1U!)t#w16_(t)qKzW!B;-LC#4{X?q+9$}!5X7hVRyNf6LohU(Ii2k zg1)Qf!-2keM(R8Ak?OH$&929hPN)MY1+0LBR;2lTF&GoEl)#gTnK=H&Xv}`lwAyWK z1u2ov@dh9ftEx%oFPF<1>Ny17W~fc`3T5hl8Y_G!a-U17Q{qwLk14n01)g_L!>8%@ zm*s&#>?{r>P{d*|y~8ZG#4ZL>+knGu%SQpZGRLU2A$!ro6at{G@Pc1yN%7Z))ZQ5J zrjz|0Y31=vBh0mRH5Wk8cK#!Vn}cZI(lnU%-2%H&;Gf%huB34t@aduu^r-aS%Wmt8 z%(uyz3Y%QYD~LQvZ!fsbCQVkR>k(daMKUIan>Uil%y5?KMgIWGg=F7RV^hiXtGQcbBT6v*M+&4`a&l$To%ar znhZ21r1i%-zZ9neYDyht`I~73#|+zQ8WVCGi_39h7J|0_0GHmzHK~|Fo#r{tHJXNA z%#O7t1E$$6xuQfj{p@xq0Z?LQsG4G}KQqCRRn`e1hY2+F7Oh__Xlg_VpwXf|R+T01 zv*(j9=|$AriE9tVtM2sb_3ea}BO+Kai-dJ~*(Z;TGaZtbPij{vT5!~ru_a57N~P{S zy*KT?%i=8SbHBf43njr5NaxD_W2bOBMrMTcKj{4Q5n`O+Cbj`X&8a(*`M#TD1F2zQ zv7Dy|X->;#G#H>WAjhEPs)lQjNs1%tMn!7O} z%rUcpr&4;_>x!ni1ehuytnHR(WX?C#qU9;gN`oo_bID0H0`7}){IRRNRXT4BkPW42 zQjr%iP$2;^9-jObl?WPNI^Zg~eK*8&9;*n_YI$at!^u$O zz!oHudG^LbsGQ8i-*_?`jMOWM5{&USuKbs(*sTYg0}L@ytYtb>$mcM%xQaSnw%;u` z!$OWyz?E%4r%22QT+%l6?qs@`3;H+3tcqY+8p=FE9>%Vl{2JG3c#_IXvTkPp&m^ zcU$U&hpbwmQKT`P))U$o_kxO7-@Y`}dx%8G%;~C&UWZYFPB!l^srJiC-x)Y|)panc z3z<7C@n1GQnHXKC$Brt5-!jHTzZR=`zdUIa$Tz$KEzW4Z5N4JlAnp`i80ii4dsoUv)l?7v-FzKxF#&JPX7Q5SvZesg4mdoG-gs{)0*8?UWFOwm9*4cww28(^IQuM z24Imb&Ie|i4J(Zfu3{4*m82LXxPY&%*VFUHdaGfGw^KJ14kzTP^z_K>niK9vQDn$D zjJdYrC)roDhat+Yd(YfM5m_ zVAJ?}7PahY8iOs!#Ou(}#~aWjDr$(UaQR->w|r%CZ*dp~CTg!{YL;2{^q^3kru~f6 zQRKfI-4^U7R@8(kVifKxz6}sE7BDT=0^+qIfhXH~o&6Dz&1K2%02?ekE(1=HqFYex zH{EplVCX-9^n^E>uBF48Jzs}3jFnpkn5@3muN>F~_DdI;dhCRWZ_61q6+H}S9HQ2J z%X~=TL>fCeTQXA;nhVHiT#Tq%Ez~48(x{#ABmi#z07(cV0L5-D)FtP?_DLOgp3{<| z2y4~~20+`s@dsD;f8oP8a#g@PUJH(MC((0#PMu5|V3M}Ohjr4ranPy5t9YW#JDZqR zqgduvN^5%{qFp|?Qq#5|X|^L)R?d!8;kgz@qrXQ_nG^KFD^V*2lF{Aj9B8>$krpEo z1@5scCZu22Wx`USCeT%(eh_;=$>HXAla*@J=HH{pbxa9>_lzp-<@l54m~o`Q>JjR6 z!WqjfN#Y;0oT`k7awyT{=?Z&K4uW)0cQ0Sg*raVYyj8AY3SSO$R7~vEDn4G2UK~YS zam5~?`G?-ddWu-UC}VdEcyi@u+a7&ZTbza|U6Au`(ugi53qI9Vl@TmPu0jQ%;}t+Y91Gnr6ZpfEY}T zz#OW^XZEkE#Hk}q9AwtswCeMDFl1Z+CVd*Q9XQcn%vpbqF!JtR%8}n?rn;xLI9QfWF$CT@IxZTKbs(RcZ%?Kg4ly%;Pbsak^)Rxh30ow2 z`CuV+6JD$^4I=YG4GVa+o}}iAlm`C9rIR8)@SJdyNhjU4{cx(f*x*2@%yx=7Z;FjW z<1BYGZ8gXqA&(2r(W$OrAKv@F;e{=H-K8a5=6Uw3n8|w^KuGG@b0@Z_qF$V{TsE$B z!>n;LT*@?8J({9OriUcnO-?>ZrwA-VW@S6(Ri_rC13pEbkMq^DxREc@8q}_s#qyW! zXWCXCOZIc5<-Dm#(L9(zdG~Fk7Rhzna=QBBQ>Iv0VlZCT5>$_9Iy8S{_NWxJnALUQ z_oC=(Y!A7vzRH*FfeB$~B;wH%CUI_CzS5xXYH(vywfi6Hsz( zWkOHHx^0W70~~JxpclmceCFzd)t)gnvJ8pWUOsb++|1o2RsR6hjJ-rR^d4Gu48AVQ%Lr6^Yu(=qg|<(E~@)XRh}~QG!8UMr-r6U zvhq3AZ`U4+hpVjtoVux@ttC;je2A^F8cZ5|q6O%Ez;_6wO>VO}*MbDs&fb!?rTLfU%4c^5bS_itn;CI#`QP-&rlGMDiWiuKE*X z@BFcnpOod*7HdlGsPv!rPfemzVhG*7Xt>bz7y7;dY))ojyz!CdHybF-@p5!YZ1jBa z98%<3Q;2t;InGrb*Qzp)p2XH^x2UV!Yszr(Tua7aD`xc*QoH8D!}i8j3~EGS{tF zRw<6Xf71&LRNUl3)D|!CBRJ3}=1B4>Z5cS; zu|8)=-&Vpn1LMe$x#bWh!JS*J^WS7y5e!&xBE_d%p-O!CmkJYlnUv&_ZKL@vE~a*t zMkUL{Y=~KRA++UH_TMM`t_RJC#o4rG zP?EC^Ik_=get^@FX0z4K```1#qfo9IQny+AEYid&PP<(Na#Oz1zMpe!y`9H z)tEBmeBr`SeWVC7V1=I}FWY>T2h$nSp{CKL^$$r#5lP9Jw8>=qzlC{=V*db#9b`S_ ztsokuo5Bt(&825KHC*FJol>QU`;uqO1O4wZe)bBbF^fyEQ!S78=fK?0O{r@K+nFK0 zSVEH+wVvIRO~o)eEt0T}x=KHVTsoCiw{3OLjO(i$)6=JPL6E%7yJOCE3( zf^!OSn<~(2e%TpzotAl2+4E(9D~z|~-}Z`w+hki7t?(&j2c(C5OS3X?n1A?depN!b zHf>rPYV=9ZnCooEaktZKDe2j799I{a>xrCT$ecyWbn0aI`HCaZZjT`#3byBzhs?LK zr*y!SebhxYK*A(uIjvNEl>W)5)tzc9OV0NZ`RQlj+_^6U&!N{3=fl?`1d)n7B#jH~ukZ(WB@$8PK+v-~ZeK)?WN@QsV zm7-Zf9L+mh3MO9R^VN9N!H^5qe56fF^}~n?FKKOM7nq&c@H0=fEoNLN+lk@i6wr_G zkf~nEpD&tWL0VCAxThMLUH4VKkHrot9H@0S)b~%guN#aip zX_J&2ofcJIJDp9kt9I2r9506pcT=>dW#uZI#htQ05V#<5o}kqJ(Rn$**vBGiPzidq zZRvy-3i^z#R~X(wrF%5X&O8XARC$9*hGq^)h@iaJ8@hV`0IvAZuE)fpSXLrvC#V!W zyO`+EX;fC28h9Y|wbBjt*=^tX;t&G?Y|9`n(!gqT251WGcD3!;2M)N53@wNzQ?+{j zT?XmAxPz)oe1YT{#fnXpa_<%|D0DQK}QhTMepmhu0WtR(3ZNHO#8>W?r98sy$I@kSKiK zfz{g^=vED2cZRLXF~!Qo#IIuYb}cS3W(>O^8xszdkqOVe^C2Yv09V2Hz1!OOGf43+ zIYd?(jI|<(C6pZ-B9Pf{hJ(@|nDtEH7Iv@jQZ{6vcsG_)$}GnxbhzMoe=h$3Uf7zW z05*>k=$YSzKFh6T9Lbji3v1^PT}T!(+To>T{L@B_225ug zrn7cMw%5#}J-_u1Gpk*~9ih>=8QK!eTtSnOIHdI$T$SN;x5?)UotNdS*BXoIBneFA z4TQ2Nx$cutfWv+nU#M;F`-6U~_6~=O>RpLQ}<1{UT&)YG+oPk>VU}xWyS%$xBuL06+O)(f0ydQYr%(lK8EY z-pYR4@-q7`w($72U5?{-(xCAnihi1{{oHpbIBHk&n^4}yYDRd=lyYOy=xjGA^sg-> zNha7wZL*RH7OZdw3hXrr*fj>t9%knnjP4rv`XqfKL#voWwlaDi_12rO(&X9m~#rx=Y80IclsK1|@2* zGH=-uB?UZ~34ixz97RwU0aD^7f?7#EQs199h^h%8HxpQ-$^mY3MCW{{XTb%dL3&+E zo-A~UO7LZ^Z_;{vz@LXr@yj(8TTq<(_4zRR%GV*}iuEdjziY^j{{Tjj1pdh|JVz9* z`e!-X`$KCJB+#fb7L3#^pBX@u)~kS`b9&uza@Vl;N!DBw2{3^h1na(9zSo|viq zw@-b_NwT9HJ?eQD+wJwkJA*7Kh}HU0$8Vhvmn7XCVxM;mrsHE8hpbthDt=y~0!`Eg z_flCcuNuWITSfpIXfh>i=4ZBDb@katQ2A~2!J0q`VFb`QMwON8dB~ct$T;jX7VSFU zP0fCG`eU1_$Hjp&HV$G2W2VEWLQ`SqO_t3~5WLDa!zf+%h6Tiu&3UEEEgNT~jjcLd z^}w2BG!VJ89K@I9=IEf*sSQYMklJv2fqeG*;lV|rm4<4WzcA0vocz;UmsjMEDUo^I zXwrQJHo!6lz=F$ou~E#fN}fR4A`@$EIJBdtK(?M3n!jUNRlQ~0)V#Q|w=x;+hx}zf z!ZRtYO183KO4~Awn$;Rm<xu+645E2S5c7ojlljjuEufB)L{Ig60iYLY zGzc28Q>d|<+VGQ2-eLI%(+@=iW)i53Ig({gceAxZp%$=C%w+*w4O&lcqG1%3MNk-G zU4`=~cy(!2T;|Bt2J#sT_J!#K+K^A)EcSAr!o?Vxi-`Tew6(&YEJI$_X)Hcwn{0opr*v1cNqz|u@HtL zR~0>=^E4l3r$x4-BXTaw5+gaNzrA~JgQrN;HYO2r!qX=JO|435VYEy&CEWnw7wt;^ zpFC<{6A*NBkC5x|vR@F~W^wF@w7`7U0;x7&(cVt5#;>W2sA~ z=n^92wX0^w8+c)%a$zBk+y}~;Do+w>%;&*jtu5$po?-}!o3Bx9EA_)GR6hxB(gtd0 zD7D85qzu1N@pSRj*uG8~2^Y|p%%95uq}t{Hy|WdmKWWh<%KI{?Y_|Qti%zSj<@3Ro z20}!am#e9iDO2LaiyC~XAF_Sz^cTXv=cnn5CsZqHn&*Q&N2*QA&?aZd&B1n;%vTAf z)wa>K6!(^2^2a)%0N7^ zEk0F_NQ14K2fWdy#jDYOmMWSWYj7?gR3sflN&H85in&LJ66#@?&Q%&~%1I5OQt)71 zkPwko6Aemv%vN?XjmcU1Bsf#56B>?=@=3JSs_TDLU-HI>TVfeWr}$;X9EFuVog+xA zW=p#3T7kZ&Z?|nCHx=~X8MSFL(Sq+iR_I(h&s-s$U6j*-K1R7hKwPJJdbTf~n_&Tg zy^V~73tYwy6!75ktqu)m!^x16!%I-#cbcrWzh24n#VWPK5xgW`b3r!C2bXzj-y+_h zb#br`QQ%^Fj_i3+h*v?l+UYOP7k*N}pBb4>Dv?HQ#`%HVF6!Z@L+2)s>Ud7QK5N^ICbT8*7O%jQ3xIn)kwGoy8i(`q!h@S!^q z$4%lL8f>=1iZekw$PZIWeO$tG99H&6JHaRVJVfmL+0>6ZAZRLC4- zhZy99*ez=2L=#?=F65t!4x(6%QmMHaj#-yCmlk8xqtsAFmrc_AU@vxj?F-buQ4NcEg>x&G~L5h;A`L?H-BT?P0Iuzn9Ew`&mX~P9NY71L4YU*XuV?_*R#p3)rGpJG} zBbwtl;_DO?{P3o>lF@ZZTo^yvPK5hEW#;oC)3W7Zh)DFb->r>9YRZErWvy5Jgsetl<^<5ZWxnfE8= zoX1+?MM0^8Y&H(4I0m1y-?!Rhf#G{Wcb@rPAtHW}-!*hBErfn3{_*%AmwF}+iK&^3NM$o60GH|1z6rI zH{%Ag9%NXg=(~R9wlv&Y#y0n!YEwK#K0{Gh7Nj?AOKpc1iJO@K=3t0)G;=Q;g?rxW z>cbiHAvv67Q0KPNi!#N{USY+DS!U2wNv~0A{LAWeO3SOZ7*|+=MdN7a2{LIMhT)E( zPp4KgiU1fIBzX0Kk4GSSD65YzqTfy}lKGTZq?=8rNUYVIVjD!s5N_w)z_mbv=1bag zqtok@YV62SU^ydL5Rn&bN{*}p6C)6FD$2OXqvm;POtjn1mZAc`MmscEI*UiCxPv22 z{@cZvx;{-lm@>Sf5jFn+vd2eKSi%GcOuLN?PIs6&+F-hskyfB1Kj3+Ia!q3#9acH$4IFYNd!*< z>PBqzfa+fAxUw}%wEFc_U!$aRYj4lCC?$>WCYc3Y5gRw#>w~nrb)QB;rPE4piD@*+ zF?Y;$E}b%4q{JSUfuJp$50K#^t(MY@n@<&4P-whfh;U=MJ`-!y+iRtMzH8!? zY6q00Jj`j$*>aCuHuDz><~bH}Mi*sMNL2|JPgbAAo~hdk;p-GSD(%)EgzYKz-k8p9 zbZ3b>EX%A{t66`ZI!pzwC6SCvqab7~urZ&Xp6gL!zS~OY+2Z1Rw6)P(Uc>vi#%dS+ zJ4Lv(U0Aeb;seZ6+BYF2mC>kwv%h=}qin^JWz{EyoE6M5n@U@+q~vHw`EI%>i??+0 z-_43%BTgZyJfS#Ql8sLGd#L5sxl@83h|Y_OE*_tU^R_cPlE8A8tHNh2rN{YMT5CC5 zNfkA&memU83G)8{ONJd|D*;`AocPPc+1bm1#SWWTR@rpX9gbRh)6j3<^ueXr_@$OC za}c;Oo1{=U;Vu?xvqQ?%!`^Ez`nC$P1sa5e4d#TbR4bXYflk&+cs~*-E2Ql`?okp3 z`+U1@n8eIqHri-bDVyRc(l~dJ^M@9mm73-Ow>k*Ogz=ciGWbk(+gMn8eDK~Lt_Z!O z9O@T`s+?WnpAWsCoyyVWw^5YexCrLfiP4ha!?J1V|#*nJyktkD2ohXkr>D zR0b3Em|)M4`DdxdwEaO=-%-OVRy6cqZKa~>y#2$RjhXYiq}?h@Z9-_ob;v!ySLK7N zq#d&sz)e+EjJXPnLV@KKMw8l+kcY56=d zV=%#OQ=?ZXmdfz|0FvU>uD4lA*t`p#II))UhXkZeoScfxg0nDOu)Ib80OqHA;0;Vz z49aH!N|JvPvhNUMvr1|C^qRE82Hc&fS`Ztq+Vy@c0nXwiwyAk#*UF6zyr|OitkZg& z@~xF^f6olQp9qaZZwzOwHrZr{{_;E?5ZAK!-SCHN3s;7|%LOa<@ey*KVHI-wJWF$fWALa^mJq zk6EZvrwMXuQQLFgw!5loxZmf6r9(*Dtg6RpL&AZ}_KO;AVhhCU=7`9M`^QV+(w?~J z2D)599Rx8GGG!<{K&nTpLX?h2GH8DAns-k9?~2i=UQr!op-Y)ctMF;5PevNCh-hw9 zX(Z8dJ!842eJS@#80xVNr)bNYb(LTAcQ$3eXs2tG#CDe7H&jhTyXyD_Np*Vdd~R0- zY#5g zhG`B@)P5c-qofsk`XX(o1WLj&NCq;_rU8g%>Xu@D^+-MnQo8`3-8PKK+oRWf5|O-{F4o)8llpoF-1GDYB8`9 zy9}#QT50937gQnT*_R@jncHJ{&0k<0N#?go515cr>IsiQONFIOYps*e{w4~%L)0Dt zbvqDw@1C|Eg8gkT`V>#GG88zn>o3%tj@mR*<|};J3ZEGW2#&AG6BXnqJ%PC-boPDx zC+XR4pH$&Q+GQvH$#j=k8zZDzaZ_Rx?1}j&>4mjBV`!)G>~AqXUdxq?r%TRM%*juZ z%}$*$#gOBH(sx~YwR}QIsJfHyV?Pm0HKr}Qf&tW8HI-40?-?M3E!>s8-1^I7` z^c2+>GJw8ksx@Mu^9|-W6fl}_9tX8(xY$Id1x9K6} zS!q(rP~x)b^I3EF;k6dTlL!qx0Cy#@W$6XfKEIYX@a`%M zOIExY7F)?oPH;L6y1fEExM5gUl3f=|AuUsyjHLJW3x}_PLDpM*srP)#%w=l~1 z?r^B8wi8V;X$~bF9?Ih>r!Ib>gL<}W8D+C+a&Uh%zmzzI4_mIa&waHbV7$rlQTVZg zh$h6WQz$#lTgGlLGeO{uK5kq(c}+Vg3&(9iZ@QcR030o9ha$#DH?W`0mK!o@bhoPB zsgB7rK{9`Y{;kb?7fRuJxd<0B1h)Ayk$Ea0U9angDY%BRI)}K_g?wG5-h4$--xn@O zO?>wGiK9^63j+j*QCfr%K-+(rFW%mFaFM8g!~_PRsgY^lPf)(pxRm zMwpcvmS*C0E!LoTa3=+MH%qVYSuu{Kkx0B!+fWi@N=Q?qk-U1{IVEqxI8kj!;S|Ol zhV$8bHHC97R+xo4J@s?Ej*9neujsf{i+ET;Mj+4AVNgG(RURTS8Pgk!&Fq}N5M$IS z_)&1hcOX(TLLPFWio>!v$gkAi<%zhil8Jfu{{YpFlaRFRvYg`*%SqJphsun|hSo=M z&CuNDY{J%EqGwsTX~+3mUx~urzkHaE=*Q>YE0Wh zr?s^TY@_h%Ol4}N7%|#ELNJ;C06pbw&BM(77-y);ZRXILkOQ`>T)}VZnB7LARTzTQ z?FdSVMSFoDl{Tb~Xcs_)SI|nzi}`6>5Mg{k$c>phEck9OE19#)8b3T*dgyB3_wCd5 z!8(F1A(u>A18ne4rCj0lNy70liSwd5i0eA^T?dq~csY1#!YFA#5MAO}VSkA4a{A1h;T2PYmGg+Rb66)F3I7%h4n-E-e zi~Nzn{{Y(^CE^Nfu?m(O%SS3?s+L;gWICNcC_5T-QE7+It>_bDxv?0MZVExa(Rb`6c+)| zV4S$fRZDe!JvP}e;+`9hQDKQQ#&hEJec$$hNuyEZa%saDVY=IAs5K7iTYXhi3wnpU zH944dn~(r>Y-lT`Q=N_j~%ul3d9Jx!P4Kp=U>hVp)x7swh39C=cnm+#krY@y7 zIi`Maw5Y+F`kR>G<*qMfh|Fu2b%+SmSDj57`FanlN&}`>C~u>*5S15q#|qHw5W^mFKw_@NDE;!Q7e22M!%ML zah@uC+@UILTHC;G{g&f=?qPSil6gNhTs$>I!wgC&t(7)0vw&GPuS4Q>Qlpp|dK?(8 zi*n$&OVVgMfXIDE>x!#VnPn$7f~aqpTQ;o|J^N-p=RH}YG(gjiG+JD9LU#WEixz5& z+=!}#7L|@{%FyZl($xyQDUO_U5g6p>Ue@3F{P5MPEnx&UEFj9g0)0w_8n)Euh6^qT zxcg_!a1&A?sE>6-z6lu11|4@MO>-(wt7UrZcj>O6gqf0VF>!y~(=RYxxCnY%LJ@;g7%9(;P9T3pzSuc5den21 zL#QC{s@-iD%+t;F(~Ryl4R*-fPS<7C?p)Ho8za}J$MHK(%enpB?@+5|e8E7h!j#yI zNOC02h9FnzLPoU;kNVpVN2EX*2jFLFmw9riK=??pcxNuZTzYj+Jk-J;G>NJmB%O@~ zuaIkS$=6Xnw!uAgRkEnRSst4U2W$FA8jfX+mvUo;F~DtE6}b}pv563|u#N<7Wp$f) z!%xZ_CkFxK#49BWSqDX3~JmkK}v~wQr*-6r?doRgK!*7HG8fvq17MK`OK(=jXdkc;C z^*96KW#Ge%JxS&dCrRvtNxlAm>(?2>1Do7_A|9KkfC35Jbv->G>IFsFx%zQ3Xsoc> zM{I<;U3U75{{WWXo$zj&R10~^cUQY==e4bm_sT5secA0h!#$ZZ>1Bw}k!@Ob-`I z>8Ns=Y2l@nSm596pBRX9&Mf8L6=poaz*(8Hn<=J-Iv=^!ax_l;INYnNF<{zGXEfIG z=L6f9J})hUOAExCUl<;ORC_6w%c#nSG&@tP*V?aC9PtR@bZxQ@Iy3^HD6o}nff=&p zIm(ZPcuk>EBtRESwh>YEoiS`}F4~_5NB;nYmus_Xkz?s=nxxp-F?8uL@e?QlJW_<5 z)K_Q$6^1pr_w?ZM3^UeC%SRrYQ7Kjecy~_SI9*YwS^@D(11#o1ujX;*&G4q#Adrc5 z8eu{9=e6Ja=4#pbkJt3jm>p=NrA6c;^I>@Cpw`PCS(`k z3TbZ%R4goI0enN%nw3Jak)XdK3X6@ma(qjr#=ZBn4rD=A?+^ZTupMdt$r3lETOpI){&v*$aHOz;uY<)ij7eNLR4!gCqmbJJisXKZnWK3a46ls!9@E)LC z%VRL*x?LA1QfVO&TV;S(5w}+82Irqj{oPyRnNF*_7A8@sb`z0QnaUKVB*~!om)>_n zPF%EdwC+Qvz6et_2>{|sV>zBG^76$`E|YnFwGpbDb|uul;EV2~p1u3vf;~1Gh9$Kz zE2y%jOXB3(eEwdRnkQUr+|(zdt8bn*GOE)Kuu1_eZXi#fSNJ_ojh6zZ>~<{hK|xkQ zlu+tjJKr3}REdDh{Gtbkzl~C=PPL$`nUG-!&qiR($+C z=S92f)QNwpVjt*t)v+XKzvmRj>)QOD>$9dO9qG*(rEvIj;*zRsg8FNq@7%&64oHajIk#o=Zu0m1=61U z*zP*?T8r%I7VMuE{{Y>#E!FA&0Fp%khM2oqph+$^zT*_|VzV1Szsw}+J0_L4WKAeL zVX0Uui|rKcV`D1{+}hq@_O5O<%HzzkugAMk9YcIGB39radeBUizxWP~cQVcq6n9&%s9e#YuU0RVA1x7Op;~_Ic zoY#`*no`|u5-rs+jIWC7W~S#eZx$;RoSmI1**NM_SXgW)i)D~l@zl(<*bsY$`08-f zwSq{Q`C2^imQyuZk)_pZGvB2_Ul813<_I*Y+y>?U0H?MQ#j2p&cskEHq4Py@8gNcP z^BNd)T1f#OP;%UGRBvypuAF40P!%-ftF^~DS<;=#dAl#Ymtv!l1C$2fA}I6z?xpyJ zFXhBlRX01#+Oc7YUcjRrAKQ|Y*vd9(l<_H&9C5f}^)9_W0Ion$zndwVCSoZR<|dcy-E}rpzsyYs_%F*Hn)WI{-E%b+#pDKRpKDQy zEcVnTN9kQ&ZM)&60_1FCNDVgiQllCb3nM)$uTQ5mv70-}0y8t^g^&}suJ^|;id%u{ z6-j`>l*bk;k%x~a6q!%+;TeBexY&zUuA6rh`LCN5Kr=1O3YNYgnx=hwHs)sP6$os$ z<832jqU4T$ujPj_^@gNrH=NeHO@AsBX>pkpY_XrZVAl}@W-iv}!3??fY&fXYlrCVO z-^R*f<1yT$R#T+Z>HIAuan`|JyPT%`s^bR`Lp~y0=0DQvuwTj3T9q%uyUJz4FS&43 zz|*?47#<>)W8v*W9WJcoKa1 zwc)vC(wi;_R3zpCK4Ya!s8eb6hGW;JJ5uE%a~hAo!>9(|-t@+5s;J<{kQf_pC|cfn z;q4j)J|Rcw;O^gC9 z9&$@TNU6O#L=pyDZphM~K^EOs`TcQXp$1yDr7f98ttT^2avg8OuXre@+peB#sACafT zAKp!uYk6PEnJLdt`C=5saw!=N&&CUltvp*%1ub31i)c?R9o(;a>al8aw>itNM?f&hW1H~Vs(W!4+;G}I|3 zwn0U4Ez4~!w}0d~?l>BB+k8%aH)JKlfnZ1nH}dl**qT!&)yk8@N;AwzklPgpq{uH0 zR&USC4N37YyZ(4lvwnkqUY>J3N-mciLg~%+u_pwr#@IW2<&QeIZXdea45+dsOdE#( z0EYk_BBY8*r%#&NN4lnzz#(0V>l^44CLwT$X=H*LSD5F9 zPFe$sx3~|covr-vx{s-~MT@P553|2hoAs08PIg<)K&Z4W)MFOr9#=(tt`FfaU%I#Y zU`Xb>7ze|KBbWM_yN_Pa!%@yMc!iXN+9wyp)gZJ!f4?EG#p+?}=TC_+s)H916=~Y! zO#c9y^6erw1wPn|IGlDPwva{D%qKj*rZCc|?D|OFDQrc=PHEbeN0yA9v=zRQ#)1`h zlEM+HQEPOXG$*PpI&|lp>EyZ0MEU7Yg>iK1D`FO#<~*~*h}nmOlIt8f%zinB`X^H6 z$0)LaJxB)qcuB5Ntm4p(A#16;ZOYsiq2!5lJlO4WHC>s-%H=wZg0ObjguY|zd}^pm zELzkgS{~vL6l!xa}g+KTj(HuU-u3azn8R5FINCIA~i zm9kjWUVM2XNu$au@nMK{8yP_IfHG`~iLteBic3S?l9 zrRf5X8|m)D(^-72i*6R_sLNC_vUX&NU7t~5`t2Rih8sNDD5JieKRh5&WVQ}vGD`K# z$n2TI0D6PAoNfNz!!iVh>NPZSd|86p`_==e)8x2CI(E2%7DAazlTgS~YVmE!XwkC~ zUBy=ht`)SIU~`M#Wk_kGQ`STA4m1Y`Xh4Z%(4o`oTquD@rPYEnL}TM4$pjT;-TKGx z3Z^jCx;~;KFMLWNE#_Y7j^T$T)EbU)f^-`rN6_PT@*n)LwPUe{WG7jW!wnOy8(`>j z8&XY-erbyY8Af!83S{S;2yvc}O}0*&G#a#mcP08_5*Kr6Cx+01K&a{yMY{{TDUrQUH@Tv0?LRZLu~Nl@Q#T_g?B6U&G|FiOi0EY>K$?^jr` z+$e9h#-`FolcvR|SAF-!3iOz!d0qjhs#ttak(u)TRHDO+TY(-B#xN;lLTKUoCaW)T z?TlO)rtH9rm|fki6L@!<g%(jgCOL|*ZgnaucEcNoP0X^Rd1Pih*_<;)0yON@ zZn-2y1S0^bG^zKr_QnRbs{@FWz9pl=%(;^(j!|n;<(XzD9ohhr4xgRI+aq zq06bynW$Zf$xfGB)3WPMdIH7wOb4Fk6C|@nVL7TN#p{h!X}B5kK>8+=4oG;c2)gwEk`!K zBwgl%;l6c?nmBNiB!K<1N`;}BE|8L=3LvC*x0Nn8{oHY?sZwnmk8v}X6Y`{qe$#n` zvv(4x16XO%CfJq-{+P+e)Gd>=g$CwXnf4s&mS~MY`wB;biaQ?U0;Ox|HTY9d<1Hg*gH+sF z+d$#N_9^pc)GGDX;EsU?TWm;;-kWy$ZQli37@72rX3_-(C~;hs_OU$lcQmn}7TUVS zahqeyMT1VANNLLKCaLZaFmE^KR>V^6 zmiP5V!Lk};6+6ux=wWL_9Eq3m#LsQl<<|^bq@6j;#msYLR=Hfuf5x`O)U4uw18{8= zjBn*NE^}z7aPKJ9AVO+FzQ-YmMWj+ny4dIqKAYR=jP>uO0qHC)>|(A+%ydr?SPHIK zf?r|EIBoLS^OS{Hxl7FOQ%L=l=~?r3davPl6vXs z{vGhjbpg1Mln94H%Mo80a;s9wr%<_#1@^_%shcbhN#aC^vZTDcrisSxjW{>eZr1r? z#l)JWi|qdZohhNmCo+vvoY5TiNv34HzZj;iAKp!0s$l!D4f@CwZy(1Z%8Q$3%YqRm z>5buvIj^6V>h*2-R~Z7GR_J2N$&sI@QF#q>&6l5!VifHHOf;JOlj%U~Qisj1#2fSSuLGnW(CsVaH$1ej7zI=M5&G(n_) z$v>VEWI>(fq5>vasOGG%PWFQ-bf^U;kn@DxeqnAPzn}Tt)8I}_8B?B$9C)y56 z@_B0)m@hQV?Wu3668I|BY?fHYsbv673&mGs%HT{{^XSqe8>A8CgogDPm98tPJm0;J zZ3ZCdfmB}2DOt`Z^j)Y?ToQ-NPcZqH8WlWRj7Wf~RO-bCF-NOYr6NSB47xPFSG*lo2L%Vdv?ags$1;sl2t(;K)#3Fi zsE~x*qUQ!ZgDX?a(x;jyf;RN2&YP_o_jyC*>*eGiqG{x9w zCfL}IdqNa^x>SxBvjw-ga_1K~-FXytMY!ANa^JQ$l5b#ab`t_=J~pSR7R9-B7Qas^ zb<|mn3)yEcN{-xQl+jo;j-7XKm!y7oO|Y~cBBK}b0FSh) zJZi@ng;lK-$|)9&eTnrgWJ~#;rT*yQWP}9T#L8!=$duK?gJW)%zy$dZl(S*Ec!uLz zgmwH$y87Sw;VpkzlFB#7=ibw*$86`e^Q`G1zLNDz_r(*`%U}K@-@l~r%#m_ykzO4p z(O8E2m)#-6Almkj*-j12%e-9S*AMAZWKE^T1&vmiQPdOmQ6=doRR{k7EVPw@Jf*AB z*2Tr6ulW{dsY^(`x0D4YeJ+Juc$|bG%<2Uc*)R?n*4LRxCNpK~vstG&y_V$2X}A>z zNtVRhA9C-U3~lwoT@5j;ZX*z%(--oVWq&4nN0mOc8Gk+(q0Is7lv`L=Wbd z8K?mrN({8*Y95hn(|x}*z;PSnV>MCUEpajVQN60`RR{{Y$JG}$YyEWE;0`r%b64O)bSd5Qa4 zwaVmm0+z*q0{hA)^X!IaH7uGC=4)G~pPnpfFhS`UbB$tkZ-(%y(dn}Sq2c^H!rN=1 zu3xDx0)-V;Do!EWQM|A6wLY&^&K??Uk`@!brN*uy(wf~yWitRVC06QjsMVQJ>C-yT zrOYmsBUA=q1OjqroV{6;S)vq=A5EpT{{VD#wi-fp)`@zIgs|$!0+DOR7O;SGaMBNn zbqN%iEdY3qSVw8H4M3kC>xb~=w1C18H_Q(R9x9>(UVJsk0_IUM?=wLAD50Ts2F=nEfN>QWsMG^K zBeG*Q?BObCzEkcE%cx z#nlWVK-y5Q7$E5!cJB-cDm0e<#PE)TY6NIXUa4=E1dQBEj2UQRRALrauC`6WGbf|U zWu9x%9$(A2F4~9n#(MW(@+SQ{%D*UcBaKfi@d~XuDDquup3{-15I3ukg|?y{j0n7dyzT zXI73>8r%ud2JbWg=&qefd-~$Az=I$&PiFef6E*ugQK+-oyK?A_Oz}*!(E#=7PRZpJ z_`MSx1r183wcH<^gvw_iz^cv7X%(Es8WeWT#nSV=I)N2Xkv_KD9X>6WP3@UXWBz}5 zqI*qI;y7&^V#5ep2Tz=RanGQ-sIiJ+5$?qYHlh@MVypbSiD@wEw@x)?s(c{=NRsme zqb%y^$qy3DmdBT=ZbGTkvifeA4jgzrB`L%=?Fhld;>{j&0eFJV6j?RRk`y)#{kZRE;^199TMY>wg+y)N;cJp*RCnsp_Hl!ys$D3X&jA^ zD4Ci0E(5V9KTUowCto~BEN!`eDk6TpIOo<<)mc}V1}HX{G7lbUw6Fdn;Z8Yx`eevJ z{8H|z@TlLtlEY+P*qjAd&{cUE9mqJ1yd|TxOv*IcfHv{d-ZgSTHX2R08eLqnPg{>r z;e2IHZD=Ha%3D%6hQSHeovB@8=y9lAy&mPn)A=85?~KWHIfB)7WEoXwD(!A&d6QBY zQh~01o>*T&C#ID7VTocQiMfSFeK4|WF<;jO@O%Xu@~E0``gg*L65brh24!KGD~(6? zimJ8Af05!G9+AJr-y5jY)ks3qi6*}`EWQbew&=(BTXjD7%LhW0pT!6v-U#8gXQ$*p zX}TQQeEO7!Tvpr`oYE~ucio<}_`9iT{5aEAnW&_U0UVYYmdnzWFu1sn_tV*xm0Sagl#nrNx0K8!}f!|`u;Ah z`{HnZE29jLw7)Sfe6vVvK6?_=8;tyRr?hRitE}!Qy=|j}h#G)*zIOD-K@InWzHy>~{_G(8DN^N47UpJQk?%xHQX$| zbc^MN(_{&$@L^v55iU+0)Tm5x0=brWgF}x_kb~6{4Ze77N`P;OqQ(r(xpI$P_LO>|2A3u+G1deajtQk) z{D0y6F_`ff@X9Y?9q93jR|4wURG+EIp;O_6qysjdTZJ6! z4rW&0km1Z>uX4Y$6GZ)>jjn{L-v0nBE3>JMcRZ(2#^iI9&lOp#XKpK3vaL2#i%X}% zU|VD?h;=s<+!Zpl)C6?u^i5i^+Eok%x&5Z4VMoN^+;6tve z-qbF@De}OE;^`M04tA$DHPy1)ef0VdoBp_2w2W9<%txKXTbe8D1 zE)Os|MpH$tzm>IaAK$|24)F*);MC8Aa=)HA4?)Ue+4**#m+H z?T&YN&MYT1l1v#vpGRYjEWXkBd8pu&e|e*;_polRQqX{IQ`Z>Sj$Ctgy&fPGT8j@B!1)U`H12GNP8w8UgepMurldw>Ul++NxMvejO5XW` z#=^!~`4kEN0Bb4UC7@~J4H_Hms4I`KGP;qXmay_Xlu>h{vv~7@*cj>-595Pu0 zdCRCgQml*0>OwBROmtisAr@xx!$>X^Qv1Ox4@anv^k{j`Z;b4j#93U=l}Dw$Sc4Le zIF0IiA(?sIF^f;V?O35;qcWcEVu$p%J+{)m#m*lSxD{kTuvI0X4GTbpq1Mh zj(j?a6m#iZYi=D_W+B%EG-x^(g|l)g~rf`PeBPTGw~pTr)7m`yt1cw1;9qS|)L6f&8aMX6@gS6ftcxr?zPFKi8Z zpbTV72Kz#p+@?vHR;D)4Hq&!O(G)Fqxc%>3XW=xdS3M;XHC_SB?Ns1r_z#n-?w%6= z0H!t7Wn~~k)GvtR#Eib|4k*i=Pl_QG@E639erdil@by7ZtYl%Br9qKUa+^L2a$OkD zh2)6&bc){ibzlXIsa~&_8_16mR7qTd(7M10dWpXO0K*hTstil@XEWU$lX z1c6sEU56mdSiPaQ=brGj*CgE6+FDRaq2cilPJ{#jBZ9ImcoRFI+tY?x-Jh7s5s{=F`6E{)psrM1-hL! zzZdM~qJ=e>LfE_Ff$=S5N$4Ug>2kQ*|~$viMlD^0If9?bFKKTUi=ws~CDT^6#JR-{kKFreCLg&icd z#II>_W6SpIdV?|}Qlh;3kqLaj2Ijzb`D*pV1pfeR7;hO#MWE@_^^2Aq7ln5p@Gp(&|zA8H4OaI}%=KwtH~9l)}yIKMc=U~na3 zfP&)Kd;b6|buSL_iiemcW%m%ErjtK1<2_m;rtwU=x0fDF;w-p)E_KC{ElO8*F!Lw= z+vAhOQnP906h)-W}=)C5eDykCnr`0gJDq83{Lna2{+qLS~9BXwdVvO3Xx@?3o=W^Z? z(u5AP=%=S^dZ1#f)D+YM)>1LrOW^faFht_*Mv`!HRse5*`&$SD}uab#(6vLXfYl8v|Z(}ZwN-Tp@- z2B8|RB2^}iJV4>a3Z+ndJ{Ihy1H z&MunV6K$v3RZ62$%wa5>LZwsr%OtxlruS_>GDRE)kfPko6TO_LahD^H?A%3B zR>@c5MZ>se9oQVlN}f8eH0yQiD>Kz(%MdqhR@bcIhDc;k-+L1FqsyFtwzA z_iLG8Q)X4poa}(6hca%F{fMtXk$$)##Upq@fG?jZp}0RgE5DhdW!di4rafAK)mu#F zL>mX;X%1p46~xm@bo_-eg1a1^TYU30aO?|OOyjj1?SEn_4O%p-vlXM0&C~luB(SH` zRq>^265ft9m#$`xK@?o_ASji6;|797{Urk7&B=(x{a8lvj71YizjfyJ&I zXL|ntv^+YFQ=zR+05aT(N6%|tISCPZNp&dlz!MUKC{hg7R+BNhh>0hLG}`|FwI*iE zs&CP%Iu=YAFNZ_DI?XozU#=fcq0l09+>y>1$$rdlQ~0vfil$*=RAgXWbeSC{(kXV| z&H3X))z#tJ2tw0BQ8J!ar0}YB4v{Cs$4749>qit1V)Xt$t}@o9t$fESfTRgQPNB1u za&~5>IYg>4A@{;S%W~YKjejT4&4FSG9U?-7Q`So3)hd%4JX3R2hsF8T<{4;V3ThzG z-<*AI{{TD{E9u@B6uv8ta;E-_&WFHC-Clfh5QQ)$1ak9}XwvFb{IJbhsta=;n59iy zMm`i~V9m6dajG#RjXR!=g;nPOd@)+$B!&En>EC=6T55+$+{h{7Xu2;Ba^cY&3d3G3 zU6M0nHre!=3S10yt}}OFDJOnjakS|Ua+Rn_%TIBtyPTxa>T#>|Hf7vrD~+eR4|3uU zVIB6uJ0DwHn^3s@nP9MB$%xt8_=+(*9 z&t;lkVuHi*WHV4W{uM(}uA$pcuXOEK%3Q*$RMiY+vr z1a-z0KWU|Z7piu`oGr1me-BGZ)OVTozr)g}`*LO)WXg+eQ&Il_79=lodYnyU8onzp zf6p6*fAE3^c7s~VWuwCi##g8DotVWT9Ap_d@lD~>*NNK0`^$`#6^PVeP`10Y(D_PL zYHbkStkRvOnmY1wwR0RmMd|YGxcXpdhE}+p6>Hk!RW#R_sa0zek-}H!O@2e#gtk-n zW758wY@bay^aZnVwmtr1g6IG+7aXmAWc}@To`0z1x|+uu14| z?$LAF7mQ5s&w~!rX%kx<<4_(|Iw07bV*Y7n9|($HPOmX(?`6Os2Qa8pEWjHPZ)4Z@ znEHcX;*CFuE@p~VcCyV~&)UuzL~lBs^th#cY4}R%foiFH6FWW7Wzt3_l;B6SzGcmv zdym7eA=BfO`5@xOt4D8;s^AW-4>jfA(8k-@6nDM}kTU8Mm&9EgU^Zuzn>g-G0*LqK9wK%zrzV?g=&gNVj=19UNP|v>Tmm< z%kMAtprPVD4ZB@GR9mJMKsR_mi*7_pW-U@Q4E|BumW?u{j-yg6m$qS*)Gsuj2AOiN zpTjWo5z%?RQ-$($I#>9PmB%Ki(lm69qAV>l_Y=kDeYY#oJit%9-Tt~49bO*BfNxK{ zl?ORjGEbYf8?HJg(iw4Z8z9oSgY9DvEY{`|5gcXN4+~|X$8;x<7yWIHcN zfq2cv4i~q>A82N&j3K?3YACM3lJROiyzP?w)BG@w9=WQwJBXT!L5r>M@(gUl_LOR` ziGDpf+KaJ~q7iRvHah)PNpNS1C3M?!XxeG2S5xW%R;PzYHp8wK zkR3{x>ywF~u%3!6fQD}AxCe3)?SZ(Lcy5`Sa~&d($iSBCQII(#8dE`~@1=2CK`=^= za?^vHvkiCIT4S`@l-QFg$~>fH!4Y+`UbIqMcI}R1P^Oi}p>SrB#MAVNF6Ft;*P_&m z!znsy+v3y1?$+LIy%zY?^*{w?KPmG(QY#Jdwri|X4VaC%0MRq$(t?}+0GpNb@t167tx2*51*8q6%O@;kOrx8s+0M4i zOt!?>?rUMVPdMXE9)c?ndj6N+9Qxc%N+O!(#v8Cxw5W5|O_xRC#$I}%PbyrIVH_=8 z-DOMmx_vkF^v3QJiCT`~4aNSj5Cd{2H#1dEu^yDmZ#w3xZN1{zHMVxY(*(3a7WIPC z?BLAGo_5X^%(p#=jd-R5mQA*zA|1=sZddij9xM_T$1*4c5g97{G~x9Yft+BuMSeuq zno{viYY}bL9fc28rpY=~zIVhm$g;~^N_IT~m>$%WcVv6BZMd@epjvK-7yke(QdiYQ zfa*uq0b-^N&d@@g$K2mbrHQt32xqp>n#7tAVTi+8BjFarpl6nq9!_*gkxSzr^cI@UTRXs zQXtaPatQ}feKlbfs%e93^ONftO0kvlqp|8tq)CWE@;I*S>ucyAJS0_0j4iaMTN@b3 z#i}h{K1riyQX=qjjbowP;^hH%{{V?GkF#A%GIN1QMx3{mSk4~I*+<3Z2=JVcQlUl@ zJzZdmVm87nR5WWngt1Jv(XyKBQMg}2;&lhZL$A?fwMM8$Z~Iq;SCr+yh%fJBBaKAS zZH`0|PW;3poU>GV0R>x-a;3hUUIz~gZ_ z@E*Shh&&_A)GYf@tkvFRhJQL^psbR&`!N!>u4<~1U)K0%Xwwv33V3gMPo(~-Y-PDQ zE@uFquI0)VN}3|#Nmg7z*Q`1MfoNLs$RzV5wA@Y5+TE* zptm*?QBWx{9OOKc0+CGN6%#R=yyqh_ z>~FL@gA^sRtx-PptUs<5Q&H7!uxKbzsK;vTmZ-kXlnQoWhIx*j>tj!-Ijc*K4wMaO zKNj|1Ol_#akr+lO@S8E_NRmaFuu7{Sr#k-tLC56@Fe2Lj0BgAa0P4aN znxR+HQqr)z%$!W4Nnzp+wG}P>F@Y+v@SXkrV-23fL@Ew-sBq)jqE1+p z%XMI@RHO^A*U;2J}MSP?~ry4k&S63$T*EpBY4@$E^_C}=0omXm)5LE@4HEB9LH%*Q`m+^MCFx0WC zNQA0k4A#ij{fTpI`r!-pXw<0`^ODLbb6ZvEJPI-I2dIr!vbFk5>BF8M)YCLp>&`GE zB7;u~uYq_Jjzb!(L?604G6%-!m*LuZSSFqn zwx&z(W14PW-6JWcp@`*|GJCY_`6{Vdfesws4BTdFAvM~R*BBn97mdLXZp&{a?|%4s zrHdB+Ci+xbRUAyMdp^}*)rP$eZ9<~Nha!~fTjmp-nenzKvt^+)>bfgos6Ket!=sx8 z9v?VdPYp_t@qVN4F$3BC<|$l%{*Qxla~%e;CC6#()ZS&6B0SI|is?7hBv!I&0iv@`Oh$AY7Y`;R6*LTF?iMDW|^S9@2ZHJ^!jwB-Trvr!|`B%tTvri;TuiC zzpeh`^Km;%%<(F`FcPMjJqmLmaa5C*Vh8uM`AGH1FNj*K>T8j98isMC zWG#nZ#IeIKOpzUheo{u{xDKX-)>@FS>$l4Yek=pw7x%x)B`H}gatYtlrM!*)5n49| zcy&vZ{Lr8`Hl+Um{o<=sbmq%_erEHks=vz^YSwq$&6G}$(kB;kR#}SnmZ|Jt?&(Zp zB;R?oRW_7A8FI9okHi{YZOTlDPL@u>X%VG&NswORDcycvm&aqW*s~QU0wS}AQV6`! z6!WIm^W6G`hl$C$)0@s^5e>u?8-06!JZ;sR4TkfU)QuWy_7{Aq2ILPgA^K`L1`EGt zn1-$SUYp+l#2k^6xIH9baZC_G;4tP*tPkc@9DL!WYl(i(lPYw#WW~(%SnoX=FpjaB z%5|J|`=`>R1@kL>TTKhBUo#ui4QA)l(|?@DJT-o6{5!4Xs-e%15>Pczj4sC_Y1aX7 zzsmSW8mp;lF5?gw=@YBDovM$s-0X=}Ge5H>u>4n??AEf-=jpm&JCd~)vg~gH*%Gg; z(PUCMnJSwsg-NqrE)SK#`@@cz-!QMFOB>6U z7l1*Q4+~zCLiU!S*HxL#M{Y*$MSsJSiP=Y)`tS6{J}S>ltTmTMw03K5znL=bP5UMk zNdo@>i76g0#W)SG;uPsjVc`=%YMg|QFNkk2 z`~Zv9gj1@|QBO$V1vQzGIBiv-`&|}EoK3kWm8r7Qws{G?NvHG2Vy6}!k9sD0s8s2S zGV;XgeDm=m;lK=lfcvGFwlpUatTC9r@ElGa7MSOGx;;DKwYcRVX6Zao-1|R^(OzMu zr0932nYw;>y51^A_=Zk1EDV*!%A77BN~h+J>-4&VB?y}oK;){gNe{}{#l&z5R5d&i zAOd-xm@BkQu=9gglK4Y=kSwz$Nryo@VkIP~ZEIc-7>#e$DOskk{cbBUs|O4TkzjAG z;ESZO&lH-FxZ3eGR~LbDhEi`lds5VN|(xzN|B~VM7 z7{#8l6g-E;e9M+H&)P)v59>U(#avGgX>`^3U{v`mkF0>QfJhiIIQx^ zeK#}x-<}^;h#^-oL`2-c%Tcq$f{1ou)#eIz@7+I*@zJ15AincUfvRv}sWj}?tw>~$ zkbUTB)ppfC<$@$S+!!QUON|{^@eQLZEub+a5;YJY`I2B+uVb_j*^LPbG)#`#ejmK? zUeG|Wh4Wt!=GCcEXAFj+!*fbUQxQE)=|I(`Q~v-?_>@(a$pj!d=RMMRO;pW~wO6E1 zZOt+Px6K7coO9KlJ(auwEOG$cE!bnC|I^~y8Ybd)?zrdr$)%rs~e zDyws3zQe3Rb(W+sN(FsM_3yqp{A#uRV5rHwf6BCGX`anlh3buAxv?seRh21SWa=e` z{rX(G?~L{8YIPuO9upay^3M*_FmQ@Q%Aj(kL#3=}#=)mCw~@m^RrK=PYzV8RoDHve zLXMzJUaZn-(m&cN{QCVWGpMaYVdl{FsW)I{<53?knHLYKREi)2iy-m;2e^eUBXY(PI5p@3z$-e!@h96ZG1Pe;-XIHFCG zcDB}BcZ!Aph$KtK23E==kg~3QmZLK+RDh#OEeUut$Ga|Wo&FWaFTQT^sU64KE~PR6 zU}siyMo`V!rgsl25rCkJf>gQgA6o@~CI0X0fT>04j`d+F)V64QKSY?vvP1c1B)L*z zPBvwIo)8Vi5otPK6HkKe*;g5OM*jdHeq!-J6~wQiu~L888Z`P6D7iwd$CUAlMg3G9 z>~1g18w)6^MNjzy@r+Ch&38%Q&PR7H)h58EJyr_q@#aoxC6h>nu?e;tSQU4_*Bpby zGim3i6H`+{FKC~gxC=}kG}LoWT3$q%k&PXoqrUKwIt-&b^YZjA7`##L#WTuhYCsDJ zJK57J)7#;GWs&w1vwS0q8pd`uQ%W^5A0aS1gDsP%li{{TEKTfwwCRW&YUe@e-Rlz7WfgzY`EYD7P@sqZ`IjzQg` z`l6C=hPJ}6WvWkB9*9M_(N0h28 zZY9T6%18eI!{t*eL4Zxik!cMu+a!FF*SH}3x7!LDfUyzomRk;RMtW{eU*R@TdRr1? zwNFVaIXOy7x?(xzMEpXS(&|6ARp)r71TgfBIYDXpui3%Ys}LndXrZhJqE1eY2HJHE z@3o6>TVZs-0{5B__-16|&PvYNzuGbuQgTF3v)H2)oVOl3e6%2rp7pi=0L(E&TXxuS zvxKa)Ky$t9eGbrS24?_7h`DlIPyL@1T%}Wp^a+gBYH$^)NTTFJ55ucbhw7M> zYl?hXs<{>i;jxISbdfIq0A_C&S^ofKjb4{Vl(dS(DKeor;;w}PvKScMKNYn7FdSVw zS1b+g0gt9ek_7nQ3^Kla_K|*-GOr}1$K}fzabD|pMUl|I%vCM=rV^E%aJxXztVlb{ zHa140WUc~Kp;2c|awO^NQ6Z3hO`0fOFWr2exW`_pW(NMmr>CMx;v{CLaDnQT7JXR= z(I3@9jn9!Odx&ZDTidJA5pdfpFe4zwR2r8CC-5r2F26>rLX@t}rk&DAzAEVpgg0H+ z=c>hqy6HBy3|9?vaAOA)Y7r?O$TjLcGM?-v&Go0oWtPMQl)~bz0(?DKiT?n(Xmvay z(vi&E7p&#}98hx|HR7m~oai&%htx{>wdT|5xZ$F?V8yn+BAE({iFIWvB{MegqL~t} zPkYAEW3$d`Lw5%W#=aphKYV9UNhC%h+yl}uj5}A-&rH&&@jlFn3N1aEl}G$DLCg-?ghbMuZ z{J(Q6gP_jjD7>=i^=9%{fTPr5Whdf`4#|Zgh>|(1i)x5uV)B4#FW9&;SK=Zj0t4^ZYti z-SM}Cqux2!u;nyVsA!;ib|jtsI!u?DGo)(XYKM||Wez^1X9Mm|S?iYs?R1=9^Kf#_Q zXB@(>$fUPPj!XMWqsZ6)0P7t`{IJwgqcOEOs$&4&TUkGY6x_YSnDmxIDPcGQj+s+X$&#vGE(h zr$hdtFI4l4c)(uqF_o&GQ(|!4Vtqr1sFx6P0jZ37(E=~Io&njtZwmfPf(T&{2GU#g zT25il8DX-e{ix)3COX&wsGCl5kVVk+CD@04*S~vXtH1&SVsrS4WDfASRUaQaTb<(| z)mVv2i0mw){{ShDUnSy|WgofeZIk(9Yw6QsZogZ^QWajiFz{7wRsn2AZ@{|piN2J^TCYu4#xs9rWNKxNgcDQY*9d8u?p9EHJxZ$Qs;KyB0ZU-KB{4-s zNXuTIGV);Ks+GJ(4Y+FclNW&`F5WVEX0WWEKH+PLKra6+~3q!ONw^CQEFeV zAK8@%VmiiD07kE4nmey>mQ1ZCEu)L9zYZ&oH>+q%`ej4LOs=f^NkVEJavYj~)#OBS zJ3EUajw6kUpKW$8E-!?v0yrZU{vum*Y2!X+dSqS{(X%x=Ajb(j*mBt)>}9k{h5rB& zVsN#K5{>Ljb9Dqsd^Ckq&9uo`4l7!vKmBr>eSjn;#Drf6kpBRNF1ZxQcr@?&MDap) zUS0N?@$b={NR--{-!KU+fi%`p;T$ZB?I$XxBmrSTsBUK?7Fe1t$uDKkU`fq;w{JwbK z!PI5CnYy6W;*#Z6pFCF(a(WZ>l!oH`;6lla z&EoYcn)B>64xtyB&5ER8o}fCudtu+)fQ5$R*^5-Mv5s}Dt3W53i3&70{Dy_{g&R>T zz`Z>_y045wh-2cv#t|JM%0CM!)U4l7tkvrQC(^r?b`C_Q?S{OegyaYl4yotc9=TV_l zCdbrs893Vh&x~C~ppyRpktXYWFSO`}v0Qoj!V9fWUQo3^Hq|Iz*s)u3w+@?1n!|M? z`#)QN`$p+onW(yt(SL`g7U(L_y}UyoNu65j9XQ1jZfd8}8-mNVNdqOSC2kHH5sPvc((O z`<~8cgG|$Qn3%!y&9c6g0S}1!Y`VQM&#`96ywHD6Oof&ktVC>N%A`!FOn;l;-E7r_ zK(cj^c3oe~0!pc{fB{qI1=Y?!{{S15+N5?$1my>*Zx1aC#PsV&)V?JX>HM)Of_QQ{ z3mCer8zXtjh2!YC_O#VTd`k33B!xw~bj$w$QUVoHEnh-Qpy9OKJteTQwY_8bdY7;= ztbrOGGls0yqtThDJzTGojxbUA{P<^bArbGk>$l4tBT$i~n`s|d9p)kGCk`_OHz4Qy zh2Ywgl`3(Hqe~+_BoYIyqXhZeWlzI_ZY5mPt^WWag9%9>iBRM^btC$I(MeX0OG+;C zTmm5TaNtp`+EMk^Owm}u#F9H zXI!b2vPEl$Rpx0fx8duN{o!)?Ed%{#`1xInXDw9N#wKpa|-{lcmn> zkgodhI(41m>|br5#&VT52Nfz66U^}9(i zd=*y>;3F^`jf^hVUCLRDEW&H-_9Qh#mJdaZZ2=kdMfiUJw?Ih0z1!=DQUaozLI5z# zw_4=;wb}E2R*G4B`v3DRqjzrm=SafH6}#) ze)9V%UfM|$SJw+hE-h+m{{abq2;dHXNp3Z>c~JWmQh&>3mrP8xbwM zLo%w#{3|T0DjMbwvk~aC9&wp3^|o!Tz2&=I68`|I;jLEY`$Q!>n@iusy;Gq?Vks!H z^N1ZpK;SdKSI<_-{BdNLP$t4Lh#NCZW`&Vr)Q_Fv;E^^* zqS-j<2Acu4(4Jd3vg7@=Dm$Y&!A@)JkUBu_$l?l*WF$nv1{b-8NZwA(?Xwdi8%?$? ztbcmTBk>N}zcscO#2^OST2)5Gn+2CA(s{_*NM(9-UzEF#)4m->?llaEYC#ZfJM0Xb zl0M5|0wfJ?$mTK~BdD&owhTS6WWtE8o2e{To1kWzg+)NAavZ7*b~HM!=x3#}^!Z%B zEG3+)d68(Ew!@xMeK#zWA7{Fy0%bx*y773JZmDTdaO`Q*@Q~kodSc6ITOM|_vrfu< z;2&rDm;V5>3eHlm)LN04DV0fWzYW16d6v1I9ZI{0-CSy5x4^*y1tLJwcM;;K<8v|` zxiA?cCJhLdO6$<6(x^JN+ZhSfaydgS;Wm`d5HqtJGWJQIQl_vK8ShUv+Hiq6QRX_A z0Cg71rY$$qYwFS5QwcqUc+Mdm&wvcue@~BIo^yW%#*P|;B7U-FNvCHF;g~qmb&s`c zkG$NLWlWz9702T=4h2E))y)Y7d-H3iAsnP&Sy zWP0vv<6`FuUTT|Mr|Ed(vpB~~ENMedSpfWBRKJ%Q_&y~mf~0TnGquI=rlPAWY&PZa zw^*M+;O$Y$ly<7^M)FTNrvZGWF`=$GFZ_>Mj5E}evG@GDQmGG@7tRf5eOIWjtQ`Yo`LR9kqHMTy9e zrRF&7vbqdY3u@gXSBL8qD%sRT$Xj@SjuOsH)RX|;BvkWsmtMC%>GB*6qkscwt2(J7 zP1J5*t{AC#Ww}7lMwcT>i=nB{E|Wt40NWdB@O20V*qPgjrU_EkBi+4xr%HVin$=Oi zw56Pmq`PgJ0NeMmwKzZx$+(!`iDnu=D#qLGZl*lbr^ky>W5CL3qG|AUFp44ati6Wc zKg~TC8tJZ;(wm+}BA{B$uDbXTSh5S;^0_^JlIEtq#Kw%uJ58%Ap!Y!%9^!xNy^U(gKPTrfDkW=GSu^RJBa?;adK8z%+!g|T0?fEXB1v~IX7ic66{`Y$X5hu zvaYtic7#r&VJs|~l=^00mqez%I$^lr731h6xnHXTOp}ug4pTIgK&tyqXXwWcGqI}B zj!RBDJuJxv%u&Jld&UR&;DhNXFVuc!Vfu)b^+PFUe9OY=#g~|=$%#5?y}2hK-a!&^ z2l4OaPnI=NuT2Qo$Vj)-d2@R|WNG<2xZPajL#w+}WLYVY;b8`{D>N`;h-+H|G?x}2uNQlDMCzur$pz*5q{f^BW0>n@{l5_5MA zDU4(p9I8t#OOa7-p3`PpO<5sLC?WgUlz4|3CMl`e0UO?1RSbzkrhl_o=nxtxGO2LX zn2;Md5)hEB_0(H^a4A<)7dx4;6qRGH5**>gafEdtSg z5%Yh08~ZuKF$CdunFyAL1nU0)(7pxMYfr^}(U~YAI)u7Gpa%TGZSkJD)W8mtPY+uhH%%Sb0f6-`5L5O@=qA!XeE097gV3WHHW;}Va{)e=vl zYxTy?JqrP0n?=&FztC--pzSd|Gs+lT?v8h{WSC z=2N3;)Y`9eLL^a5kyGW0;;Irwg^UEYt4F-G_LSVNJjszJ)8ap2a#ABtxE~sx%b@R! zRqPGM35G65l;u>+)%>xVsTBl*)jgur%O+m-?CSF_-oHFjQ&& z664`&%A1=e)L)O{Va7LNM|0zBwn7Vh_FQwgi~y^?<~EbI!db%+x42fYjFFZpktvgBMKXlj(w!%fupfP`Hn^|LZrG=&bmYOO;S!hPT*y?+ z#Rd$TWAVadonqXS(n#Q~l~F@vCB5vu@wq|CGG zis{USZsv$TV#Vn`94++P3R5$C6=4W072@;}-INCUb zy_e3$uhaZ7u8$CFQPOu1 zs~}T}Veq>&oH{*1B~htAW;nq<5=u#m4u`hVDeGm&JBUCIH;bm>Z+UmAQz;o)%HHi7}8J1XqRjK z-$nZ1nGH57V51w}I@U7Wd0aMbgkm>&6k0Fr%EN6td|wt3RF$!pRSm2rdZX8~22}R5 zmma;BimLpm50dj0OT-fmDF`;Z>_{q~!y6e@=!P9c%#2qjGXAG=0-s+AaNx9XYEat} zb`*frhpDkUTjgT@DU7ds2AU0BLmR-^&9%b``v(intY9dQ-Uxj~; zDvPi>$5~B$-<)X5BSRh+&?w0vxlB^oWLR~Z0-3ftJv(;Qwi{8wH-1@-HpD#6V5Y!y zqPXb+J11NG!c9zoiuIq!bcQDm;4P#=0I-EB6W~hA?Xe-oTNweZwQ$f1*1i6on0q*T zspl9oiA&~;=^7umJtHVrDIDJ%4ZM|ec^YOrO}MTgud9ScDbPPmFNQ{HOw4wQ4R*6~ zms6sT<;Z4U_fqKQxIK0y^~IJYK{1xhM=JFd+}hm)+eg94B@w9Zx2QqiJ7RzMep`zA z;0oMD=#8}os*tmgRpZ&np%oi8OUw=_rOWD?a8+58#5qSZ5F{=mqV z`MH7s!3J3pqLo60E;L|rBd?=P6RoNVi+`V{*wv(vLgQ%p0fU`RYD={afMm;&r1jV} zSuTm*>5Q&knz3#9L1I)J%J+tOWwM}VT8xFNl$xC4dY}_t<_Jnlp%W|j6*SpC921Rb z3i1LfkOglEP$5-m8L85Oaa?Xg+~(Q_wA->88vO0s0HWX#ys)-662z9{gG*Wx7G8^R4^Jc5DA83+R7YC42(iA{kQ84-v<60Xb@$}>Cw&UG=T zIV_y#858ZVS+tsYXg-=W;O(&M0->-opg$J7>}^h}Q5<4)O6xG<0};eQwr{)0Kf>GN zHAE`+K9MyBpgK!hlF+%6W5%A-DsAX7vv%e5{{S!38!3QSNsoY;q);flZYrd5VY-D$ zljpzWStY40`K^-zwo(P;7Q9-jjM&g?G#CIfd}OYAGDW9CIBEX?)R@L3L9ccyz$9Uj5 z&zU}V3bMos#N3-L_lgWp5jL9azw1il09uK$b$tCtu$c)C>AGW|+MEquHCO(_Zk98l z!11GpW2j*K^M>L)X@6eJQ0r zB)`RgzHKts;?|MUGG}S$ItLN*%{HGi?PxWMfzzI-Fz$qiU<7_%tzJU)Oh5&XU*=?P z(jb5r>-S`bXKD&|fbSl{s z%|85A$VJCplv^*$(+sU!yEnc$#lL7)>u-dMA1Ts@i80xa0yC|)?VJN0NMfMp&i%B3 zZ}a-&&~UV<)TSLp?moRC)Z(f-7Z|@TgOLZ!+(EgWmgU!FLxoR{#71}4(y1^;~hIAl=^cFw^lawij!y1DvF<{`qH?tPU9r?-q2aqS(SyAf9sVjHYWJYVUdz+ z^nAeON|QQ6&)FB1s7IRW75ujDSfa{Bxei@^FsV6WrN9izPL;fPQL4_Mon(5EALu#ek6Mb@RG8(+AQM8+ zyQj~#7E=VSL`_OnD6%C?6OoZ`;xX1DMW}GfWMFJ039wxTyA_jA{{S(<_DC52Bb%;MYVUqwMQvy+(84RHI;JH)LgSts7R{~Maqk&{{V<>6i2V&8>+4b zlj|4Q3_??JGj2e2@BT6CREee~AIHvuoX@&Sj|cPD{Bc}$mqU&4e-jfw`6bPivhH4i z!;0Qcf(F!y4=qMHNgkG@D?*x?`RUuY&k9E_zA33}R>Ba;l$aTNi;}6$!lXu(Rb-re zY2b*Cx*lgw)eC$yvA{XyEe9#rHe^_N(}z-=cDGiCDm1Mz(i`g9kO6r~Jy5VT>JSSF z3fx*mjT11|D$ptf^ln@WJWaVDQ;v5<>cZ*NChB0)EO*)(&E7Ug1j?aCE_;oMF5#&c zZu)(6_xjrm7P#pi7+PokJytUld<~-&70F=pnpmp3G!ls8@l=sIoZLiiHze75lN&fS zLdRD_@6KhZeZ->KcQarvOIV*J;9Z&gZa9rwfq48p=(d{)X7 z+MORI=Aq{|R(*(+&j#{}17g#6UAv~`j&%ynO<6f)$8l|d-w7&>94lVR)oi5(of<7l zogCGQp=nZe&xt;IaSQ2i=V_f=7?qz4cs)>;lZ!IvSC$nGT`p7|e501?cKn9;-No^W zTSYDU#;qMosGA9*I7G4`aQ=fu7TI9|UR8uHbFP|~;vbjS9D1hp7(t?J+GUrX8NC7| zhywXMPqxn~4K#P}fvBR_6Gc&Rc|_(qNpTbXp@79EIkf#II)sT%CqWl$CK!#Tg^&EE zH(v3qC7VFX^lEl{{d?U?m8r;)Pa zXk`I91NVpF$E961(nMhgc(Y+;sET^yHx%n|vII7`jX6dO zl$meAcA^qu)IIBBN!AzmKRjlv;g;Y_Q{l`tSfb9TXD1$Y=NxG?gHhdg+@Nyz>HO0R zN`Y3;isJGuGc3?ydojG*+M>D>TQ|8UVjG^xzkCzcV%W?BZ8~FQJdDg<5J#k@H7<*pV8waWrxeKXoFzuxb5n~S@ct{@v7psfI5t0+4M?_N zYQ9p1ABoi5*FT)|OHlC7qs^}Cd!di=!;^_DhLAj0`d+x5j$tVM$ku`0(_ zWBfuFLDGMtSl9?tWclGt+M3*iaXE;2`z%rF8CQ`q44F-Y_|h7Zpsp)jORmN9^uwrD zWMicAGdmM}Lzx;xZbep;1x2>w$Ws=}QEAqRb>Hjq#a6ggCNu)7A!qAuE@zoak`5CM zGo{BGPO&R`eA5)5ixDi6F$ZMFC%2YmNq>^usHozy;Q|^oA2eUn4tk(AA=9V{aH?&prjTrW;5Ba*#Lql7h4yA*hbo&-7>$g= zNABOedBZ!1qJ7+UIGTm7x4aE!RfN%*(vWXn+aCx-_NnewN2HJ0_)&HSz{FQTxf>bHDFqh4nHzpFvle4o z$o1Sjo_l&O8LLu*B7#YfGA>_@miYHFJR@z`2fdQfT-m`QgIYk#E2ohpGcYQ5&b0+cprJT)#2wBg5_;}DeJfJ#HCf31mz;N z+6m(AK2y9FHmOM+C9@=CMsHS@J#%*CD&B?!L@eW+aRkoYE;`=}TBu%|KO?#py_)P_C5MZii=1wXDm29a@ zj`Pk!dY>V(A}1BzYamPR%~#ES-=;N;ovdM=u{Vm@3MOEo1h!k0GHJ4gOAf?ec+i3B z+x{!!s5zv}2kFd(H7+HEmgd%4;SC@9MCUf3;37Ogo00k{TejG$EX9exhmeI#n`SOg zfliI>Zw9o~BJmXgSWmsD{{Rhnt*LxBPOU5TTrjaB+=OEuvGNsJYEfi8%O=IQj5N5K zRFGEMlLx4{HojEbSaYuk9TFPYAY!w}~%+hHC&Ntbh! z0d+S>Z?9GDWlR+^6zDL<1%w>6Vv)r9Oh%ZB%|1G~vLAW$5_4rvfKL0{z9Vr6wg+Jr zYFOGx%v2eZ^IayRNvz0=;fd!tf*mgbHmRVK860Rjlf)Y!`}sw%H@K2%FT5GXREab7 zw#z^u+he6J;$MHR*nbQ{=KP`2JKhCm3|h>(^Hog07CT-g#u+%P{{VPkfK^Sw?X7yh zhBOxjJXx0_8IUyC+&_~Vt1cPA5Y&=9Hz~N_Hq-ci90_GOV}CnE+g2kDE~+ybb<2C! zdJJ?cDgOWp{5aE2sLxR#Fk}Y^PiW@ovYN?CK;b0l?y2ri-?w&HK$o6$4Y7WswOq?otzC{@^bV0!>z*9 zL9LX4Pd}g9WS$G;aN-xW^cqx(i&UtrHuJtI#829bWMiaP%t@zKpTm52INIWkEA@k6 z{{Ste&d;-d5TdnB%5o@eOrgh>;$zA2qCPSG?&y&kD1wTp=uz!|i+pq6v;$-dG4h(| zr3E^e{U(7-r=Dfg<22+7WHDqBoh23ApDG-j5w&;A5}?!ru3VA_W?~ zOjj6ImDeq(ZOdDx6vT_2q3O`U2@D2sZZr0R>RA|Fl5dCry4rL(Z|AlQ)XmQ?I5gWr zXkDLtWC765lwqvU>nPOp*BNcAbs8C{m=Bh*CfmqaYJ#Jc8O zZ^W%K44qKhFtX`BzGpMz>eu|S=4#bZRH5Y(7z>FywO^N8t4+#OsRYcXVS}zZtK@9U zPx08XLZdQ{kc0GuqQsRFhIGf82F0L7WB~P9zQd~rPL_a4=OPifl)Ox-B7yCcGb%?+ zY1+i0l>vZXcwD}hbqf6p2&u%Y(+oBo=2!i2TlA{CU+q$)$YM=m94L_P^oKg*Top%_ zntNZ?_;n(y!;#MM)aiJ#W%Wy?1T5bsTZ9DakvJ}L(E3k%YVU+8(%Fp4neGKXD|xO= zw**z!+~;!$tXkDAdty-miDSI9Th#GGU+y4$9G2m0K0&w>Z3bFmK@@55UG>uygh(1YcdjqOpwiOvFCHFx`S8A zK6r}uTtTWXpa_TT^~2bdYL!znr5;-+IGk!9+5(!8ReqS&#n*QM4)7_412NoqMMInI z8Wr5hRjbWN@zoiPr&DNmRVCRs{c)dLcYWI*k2pr*+{QO|A3<18W7*sPyw1?T5i~h|Fw zg+az)a{FogSbNt00FTl=s^>|IFfyvp_=i%e)2eR2GIA?NvS}3}`@c*tza)g|0Y;XP ztI#WXdbdexh2ZK9vviW<=kI=qgZblCLW+jwI;+`cK!rh@5|rvx0AxpK+(pxWcm$W! zKR?SI^H?$P;!+c_j+sTLvfLLb%PeHa(ni~wdPNK5xXoPmo-1Y^K$A+W>`L<$IHJ*_ z$QGPro6<^~Y14n#39u?@n5|YCOm}UDzop8_uPrPGuU?_m^ZIR!s!g*R4N}(jegq?SLe%WibHUz>@O~N$E2o3oFWw27xiqxpRKt{VnleYJe0syG2%O z3&0stuO+{h^u=_Ak3@<4s2J zW;xi{2yyyDQbSyG7O0sXxORMPaK< zC3}etj|Ec9u1|v{%>qOcn{ZTBH6nEn;YHgO#4eynU(Kak_HvB|(bvdK9r#D;u2KX9m&GCR5 zb(pQf%`v%eJn0gR^_QKr!|K&lr~%ylqiQfxAv&Y3L8EgblSo1T0FAxx{{X%T>Iyk0 z0!68(GnX+Ld51*{K_|OA_AOY>gj1`mU=fd7$XiL(%6fJ?6Jxy3FWtGIwSwu=NL|w! z)q&e%3i+L1Mx(=4TXX^UTV7a-_qyK()=_Kb6}d<<;yG2wP#uFU{Xpv^=9SWpp2scDYeOqRfgMT<77vKL^kF!tIQssr&b?Es@mtIQgacX z!$>^D#)xi{Gdc;u=@zVu{FejVmLtQ1@P==DK!0aE_I|5!-zG@hVX+}A7LhMc(`+d! z1*k_!bpHTR5FZdGE>z+bE@N@!N{uL<_i3mYYfD|shqdvrsNC&|ZrVsPY)(#N;Y>Ga z?M90dVbTy+gGz|Cd&AEk zX$yGCkhp+xQ-+mkGMkh3Y#8MtPaw$&LHUx9*bap6JK7uUEy7OH0DVt!{&B{C#Jj z?XDWNagaZ%hh}r63Wea>Hh$y zI}?U99eAoiiynJ{YsP=KpDJUy6=JM#lr!wmj+HyRHRhHi{(aQ#ml^Ye(MuHX} zra2sSK&-6UGtK`1Q}$O2+2s!oP1u`__UHJQthr3FE-Ma+6H-Ce)JT4q!CAuFp`J~M zzF;~eLd#hJiZtnmBp5;te(R()Y7YMZBThtfo$Tz(v#wU?m;9YEQkt&kjZJD3YT282iE(0}wq~BE7|C zAj*zNfSm0v2fN?bS8cGWg=$yO!vn9J27eulnADDDTy_hMYcmxPl-eqwC!!zI4n|U? zE$Cpq&BPNI%Vks)=GQ82Hh(6zmUoN*g zQ4`bseKBoN*z>=`5|*7Z%V1MT+<30Tq%RXHpz@5KaJ2M-H+?9Z;(^m(xC4}`l^U+I zR07OyPciWPeB{{qMifcoAVu=KhWM&5835DO7vO|kXBgaTnBdKxxd^|3jT+8=!#LAeI?Kq5WVWQ+9yf}tmAI+52NvP<1I^Q&~`hBii@ZS zdSq6{3$$_8GA+#U+IQwE;WR4csgbrL17N9#Y3VAK>a$Xk)AEp1iN@R0bp6~)m3xYW zG@;<$bUzC=bHd{%%jF4dy;t87g;ZcgzjfX z$i(bSWu?=~E?WmV0}az%YC2O%t{B9!hBz|Y#4jVWMCRpL@oN0BjN^p&hijz^3_)}^ z#A1L~Fmukf?+yHY5Q&)Vp?j9w)Fg@d<1K20E!HBV^AM~G&>mJ9S`(TfrAWG0wl0Sj z3Tkb{Vz?`Kt6ru^t5e>GQ3emhYvuCG;Qs*M1nh361yg;ZCRWMuvi|_IT-j9!BIKzC zE~C;{QHto%eeqmJ7{T-%tvU`p6jRJ7mJ9mo#wrym2D6MvmsYux z;|zIj+@dt5PFOx7LB2Etsr-y`ShVpj0mjU7Ba6UX;zdgi1VK><;QBB zO>wns6v-}!Z%j6@x{(Q!=`mEQn@r|YWgc;{WsB-f?|(n~`eV>jTZ_p}u1xb8_fIB4 zr5oI%e@{^SXodVcV#n$&EnMGBHB$%v!#4rL@oMl`)e^vnUG3?NpxvUJ-J#%wafUT@ znFtLyzznuE`P|i~SpF@rqTU@a%XmaT3|NOoY9g+^QUM6H^(D)?VNK$2OoZxSOq)?^ zsS`bT8}p;9F)FY?kz&*6w@_|?x;;eCkYS?pgATujFROT>r?Jp zwoF>Ru1s<&JiIJUyKnpz9qp?X?l6b3VcXs0$f=l(_-+3n|%KO z78gtmf_8vLourtrc&by^e^|I>?*$X5)ARJgm4WdIRQ7_TQk-Ln<5K17Vc10!j^0&L z^C#C0H7bNc9$_!6m#W{E1H1t&4Mp5ByB<>~<99G{fqTcwho@+HSY_zPKj}LALVP z3mNqC^m#P~rM)~vq{ropP7gw8?7!oQU{o8$1OyA28ELQ6T4AOdWS@%ph&UdAVRZdA z#j_9uVQn~!aO865MU>-0hC`*~Z?>zh_QrarO9uniEH#V=L~)4{s!>~cz?3yJM+ltN zX4I2m`3=1=P2;C-c=<~~sZM#rG5{Tf>#suhY{<5-3n}Ujv|qj1FhFWSakn{d%6w(F zyj#47QOBD=)1frociR8~4}$;`e9tV&59wpEP*sPYa8N||_;qc9Evn+yxe>aABMX)_ z0Cb%u$CB==`B!BAeeoy|qkC`mfTu81uSAucjsS#_HrYunzTpomseFRH?wWA=l{j{y z9A96;(e*U4iyssux*v%gUUS8WpepkIYuSI6FqKNIy1YXZJ+5qXCe4YiQ>}8%=EFyr zx)bO6<7W`3Rjqq|W1N$NJ{c5vq>Q#*B#Eg$UGSq@xm$op@{l%@Cq`y8nc&QjHB}uN z{+QXrvN_WG^@a#L&k$lpi&}9J!ff0!E=d=duf7VMC09AgMsbaS`9mh+)0?L2P@j2%Q|0NiLO;iUTvJpiHI0WMD^{2_gQ&epwdrpjAEkTyfJ4DN4{q0}!#Zi4AD~U>Nyz4fdOL7!PTxi>M zw|VWJty}*9rN)x9RRr!z`uqe_%Q=*n?*E%gobecvtyjX=mMB5$1U=p-PFiQ_cWo~_X1(~<5>HFOpA zD=pDCx6^zbwXiqZ6E2}?&NUOmRN%t|T`~20mb|_1(}q<`kem5RDhI+BjS?BfD9;a? z{U!aGt`3qdL8Z6*NVdJq`&6gEnZl@z;Q*t{d~oD#KH{{W58$2Rz9={08!@?>m}!3CyEm=8%Q11?;RC_3NMZ994=m-yqF zYYMk7fDhVy-?aNlyF#(5*aHL8`G)HCaT!gQsMWtJKA#Bl>DLIcRAC9LSl+$({gx-gD`@e_xw#TI4 zlCl73fEUbIe5XY!vfD}b`1P6p04eapja2N(J?WLIHeP6pqAUs5(YD%w5Wv6b^If}) z>6@LVvdeYQE*kc|nDmaZ+u}_VHuGwnT*~pn z1l(uswoH6)iZo`Wa-6HudY5Avtyxp=3ToTS{uls+i|kLSg4FZ>0A*2gus1%oCdLqp zpCC&2V>&Z|%hY8Q#l-H2zv5rR5U(w*oAQ;RkBvsF+yyr*J|6EoHN<*5bvD|ZPHH03 z+lav!pVRna6)Zh=mb5~((2`VLxe>7EzIV6gJ5#07s`S;90njnhiYnS!a10qu;#7+T zJ#r+M85VuuH0IwGw#8mc>ffKd%G)u_cm43oge|%PD$x_0d6a+Uk0aU%ZY}M(KY=nk zX3zyoEFAtXJ0(g#B5y6Pb|@~1Ag=n8&3~>IE_9DMUEhc|SmNwf;AEEDbk9^!u<7;N z4{}v4(r9+F=0a(R^J^gDCaDan8)#oYOd!4RqU1oC{II zE#l=VSQ2N-!(z+LzDb}>QNCF(nSOWxG!O`!3VEb|Sevw+^9zjRz-rBp7_ zNY;aVV{YeGMrXNbOhGxGzg%XlR<%SGO_Xx?yjxVe3&uy}c*+42#mi-~)`xpt6CJv& zSv2yRvP4&{R4G0#l|ZZ3-ia=IrjW(7B_~KzQi&IBHu>SaCkz{hV^**h<+=FBB`s9V z*b98;s*@`YToi|>S`a;LGQB6a#5m_vs#jxwNrA3$BS$fQr7Yutwgk`xocdv6s=e8E zgr|O!jZ#yvN#-MtBrSuf)+@hFyv6dydTpkqxfv-jEn^G4;UUrE%48lCzTJCa z=SZ^%=OHsZ)~1U*xhMUmodzATRrrCd6Dp-qa9}2;ROiWZEBxXY4O3G34X|DAtBdaf zokB^x#^%~cs5;^7Mj8-Hf1W)sI%6+wq~N49xhG5I?+_D1f?h*Ky~pYF!q&0YZ7EJk zjUdC%Wv3#%jiQr6LSJ-rs^cRzm$-{Bn9Bi%o^m4)+-26AJH7W>+g|?wE%2vuGGu1j z(4|^CEaezP5_x9fDJb%_^&uT!=Qwo<&hbrTI-k@_=$p=oYU68li3LYd}^7_To0gc4^%^9XA6sGhGu1H5vho^e_c^LI+R; zK-IR4Gkke$Af$$qUoeK{-xk)^E%A$}Y+=}qqqC#Oc~a)zl)kB|_Wn3JY71D#F5p42 zV!D3PX-{kgwl(g8J=+A`f1hks3RhQ#rdml2*mxQMZvU4I3vfgiH#@=xSrCrQ--EV*dQ>X|y9b!?e zaS68jQYmPR$+04?w#hyo*kwA({uFG3pGeR}uxB`j;WIHABIxb^09+L|?%w>Ms}R%M zRS6*@-Z|8wK)pD$;uswHi3^@`GBwMoqPejW5)b8sXwpD#cazqAc6l;>0!sy`I~a#e z{)>gRa)-I7AQ!N)onee$=-)N*(&CSlQr9dW4c+KE_m&8>gECUFn4yNJ5-A#>@A~5( z5p}4xHbM22&DMI5Z5!Scm`4Fg9CK~IEL}6DwDmWas(UBMIVq_{)VZM|;q@w&3VDeM zoZlXF5plyYBQ#Ayz125N8#4eL$_>s3uGFd!=*~7!TAx#t_%Te5YosJda{2)O008MH z47~xfTn}c^t;F#xoKoFa#eXBq%${FaU~0jUr?B=`;B%fPP|b2XZn#dKktrsuq z39w@q6jr0$o03V1clnvwDl!(j)2@Jsx`=_R;xrF6u-^Kny-l`0+rnCg6naBxS#Ms4 zBpZD(jXi%B8CCpN0`7Jnzeq)e?stM+b(75A8Z@}Eq&y_=g=wMc6x#TzbsRRpc>(#0 z*PKr>7;aur7iENZDolm>jJRIuZ_}iI#@Kaml{{p4ho0Vp_L2Nz=XvukWz50$96Huw zq{ygA(16T;4`9{z$UBDGeAw&ucLAsd;zh#b1N%ns^hp4={{T-@ELQULi4nP#d20EV z{HD4Deww|1mOG}Q2NP?RBFZccujdC!;l@^&>z*!}QULz|`@8QMwf_JO(*FRh@Urcv zNQ7#(qWs9Q!1wWji-eg4uC{U>QE-R<02YqIl7D$ca18ZMbwSmOPS0f;0LBQ#m*GPd zun9+uAPM>+X#OdMYIVsbF={fgU~*+@d_TyUt0Fh{rb?#8s2X!$X_k2|Gxv$JZ%O|E z1-}0PmN(Jjd&__`()-4DjI50Bu(j>5y@bU^1XCkYctcG2#d>lJBCJf z`@V1W`eAh~YYcUR-gl={g2k|>BE)jY&9>h7mXF%4y)eMN@CjK9PRZ&i+vSY@{{U#B zxE8&w`LRDerGJ}NPy5H75QQ6g9TT~ETpn6<{{Rel{?rv4iG3J9i%w?{&8XXX@*oV1 z^2E_*Olh2kMoTv6w{%e~CX<%3kZ;fUG76WpFxyY~!6JRx4fB^tIkmoHhou*%ajRBw z{Kl&iC)x6tZh4aNVQ1x(wE|C{Nra@0gCyX z>g|kmdxF8KT(3T($^(TPNYm?iS`_g6ZTR6cQZpD#y1KR$`r~^g3Z6Dwuo&_Z%Axgw zYQ6@emK`|`xh6U>A{&v=tc81DP~$aTA*oUgBRL8!Co?LAQ{nUqy)+w=jkep--XXaU z!+rZ<>NFAv%ob~JxSbd&GObW>J=&QzBjqB-Zxb=8DNKg+=A|65r?6V$JS{jRJ0U7! zR8ydkA+fsnV0_&zmTIlFA$4d(9lm|=wg8X`h^%b{MVBI0TnepK(ePkM4WoVjgQpJ! zvgF9FS#D=|^BHcM>czh`_ZL;S>iJprG4x3OiJ6X)zmlkvB!f=`GUM#jETs zv~g`qesWBS(V6AJkN~Kpf%DZ8QqBB&}V_Y}g3#+bm^omp{Sp%BMy#+_@L z;u$L277dtr!DjH=oMVwvk^K~k$+^sKOIp{N_tM?4EaYlKw6l9juD9ZI1PO#{YL1DM zWFAq|{P2k^{{VO=L@b z8^WtA{{XX$GOqQi>HP5pK;S9f7;>W1%WSK$d_%6Nqg^65^~KXy$tN8ksMR=DNn}rG zq-$zEp0Cq=bQWHY+z+h+P z5c2;35BcGOrjQRZWI`?vSvpdive=&u%NR03L|sBl^!+b^av83>^O4C7dBUC$N!PqF z9)W082k#ek#R>|^b>#w>z3o0qdDdVXe8Xhyh}(i!qI!M6h(&`M3~iYlbWN%A|6{>2*=S&PRsnUqNq0(jPD2|q#azJE$rIM zEk!M0>r1R$^ERb!-=-CEKrI(owet-(J>Y$btuiIZ^8y~}VP5|LF8FZ`NrSM5sg}gf zZaXR5;Uc2J7&I|ap>b2Wp5?NC3@2Fxu-@NzUE$t#=6E`M2HFxJb%$K)?ww!t#WB!` zM?3xE?`sJ?9(Af=w)>WC*ZHDDvX9Rib(I!viH%0II_2aZ8(xCei`{G zrP8qyU*sJ(#NmQ!xZIriV)E33J_SkF-}jB`V?i#F`_{T|`e2^1Y_P}X64XBl-R9kW z$a15&T%8(C2|HnLO`A)p#J44gBWdFA4rw4W{i*HvSN{NP2xjjBlbg!`-V_#<`lF4L zW?(u=be4@5%POg<7OJ5nOR`0lnTG;3h?*O&Q zyo*qe{{Uz-FChrC=w771^u~TVh}0DF`qxD)wCE)wA*6f%a|?-b!lC8{{W^K{3^KAu0bCDQBaI|e5%7d_gd28ks=!DvZ7;9 ztEts@CzqUJ8yv+NeA%_$B7aN8g7B}hQD|5G&M}fBl63v&)JEU=Lf_vkYV8{4f({;@ z<8$ZyZR;)A?Gw0{nVBqz-4>fsiy_w6nD7UZsiT?npan0j{ z)Z&$nQF?XF?>yi2cN+X(XxJOAJbZU!^T)ziktIf*NpytDJ8v40q>kjDPo^`YC1pSH z2dwjJXCAOkUG~++A+yUgA9kh}(xddpGmax)biBF1t6+4A%7oN5279is+Biiwwih$4CDjb{!|ps@;t{Vd-6OY3FXCSK3Iuo8Ctk6WzPsTDCc<2MvcN!LeDG*{IV zy5mm^z*no{Y!1J~i$R*lq_L?0w?Ih0nQD5G0A5X4`eX#@eRXR*`$GAjM7Mg?^1U z?8jqMlqE+cL*+YdZI{r!eQoNP(NBpWX>x7Xq%^1&psA!14sWseM7n9!4Zkh%WzP%)A-(tbN7PV&5MxU#bx-N1P-mc(S*?I&f0(1ot!Cq=eTsn? z;H$Cg3VlH&OJPCu#_DZD`&%-TQ?3615}Ua+4i3Jz#G3N3)>De(;OIMX2iel8)u+BV z%zQR!iy#7G-A-iXt5oCDNTW!M*$a9$<@8)nCYU3 z@Vv))hop$q6LL&2BCSnlY@0_HyIw_Q9G9CNn@p61!6&?Eduu{XI6~Cc4Z6z)=HTLY zokw!5T#(&CNw|(UL#xZb;rv)(Ul=d6jHUOB(P?z3`I1pbC!C0dp&Qh;)%xPiMb+g2 z0)q=yCI0~0VH1|v40iP=C@sD*uM+hbsT)aAuG5RHwJMT`1FcJz@DFlC#)Lf9FlBKi z%8u#F7d$647tQ!pFlnmyHL=Xn;V#>Z8Id(9hBULn{?Mma|=lq z%vS03$Em0WNRAB%QU%!gF~@z|LfLYNMbCJJW&T(i>K`{P{$<&6+?a1Yrs(dNyjE*#cd1RYfM+?AyIyoR!P2v$FEwt!g z`C-nWB&6O+p;SJ`&XA>5j$JZCy1+~w=+UQ8>0gms6-;=%Fqe5gM0TIbWKrZ1a&(_K zSGKPA`YrG*ZBkPV!@}co@{&en5T9>Zi$UfUAXL-*QwyjHo1ES-omaFt*v1-cXp-GS zc~E`Omy*G~*9%~_@kTASGlEWaytZ$?$0y&YbnS7qll&7E-UYcLQ8>IMA?N00CS)u8 zf)NE)ORoN#t{1GfWOgJ22Ea0>aQT);NJ+YrZrfJAtOJV+jo=Ro`NME(<0hc4gUI0wXIN0}7k*28J&xp`n(vF!cK4 zdorS5nS`V+V29_|3NFSMMA;A6kC(Ej+XU4GQKXEHlFJH-k@AM(w*|-A zblfmuv0FwFu=euX{IJ?$nQtTR(3eR!oNECPOBxqmJ5lhpaQoW zOQ`t@F$2^}REfNj&BgF+Q4Wyc!c%hRRaGf^^_5+&mnkJzI@~_u&{utXMwJ{ZO~e7pQgo$!~tL^4}R}0fCkGa8L`yP+6zFHzsnTN ztaJ^r44zZd4|1TyX{O8#E+?qBMDFy!k zBJT+8aVE9Nb1kYqV4_Ws^`3#fzJEMxZ8a9>nCI{1G!v^aA`6k(g+1q8H_%>fruC|l zD&JPG-5XTsc>zATp)65hDJb%9++2{i52Iq~e6g#C4Z|aG zBxGSnpEK|uSYVYGFh3diiCf8>9cHmZgAw?`%c&)o#B>Wu%0TE+1?B2A4|ZsGQA9#Z z*`0;M4kL(nsxNC>%YUpoBr(j&d5eg#vsVzGI?NvjHDq&6b8kM=(aA*y+U>7M?kUU? zRQuTWYfPxN;%r;123!%$P2rU0xE{<@YLqo*rgG`53$g}JI8&oXn{7p^>D%Xz67)Z} zH5o<8C*gC9OwXtS+mrc(UXdldy!VS3nwi?or;%-IV+B&*rR}`VZU$huv05rCPP;qb zmhFnS&{q6d%=A{_i&?$%fVU#%bb(8eP^md5NSKDFH@c>!^~B++RH{kjCF#^|V@6xb z)q0I6osh^uVaEAf=Yy@$`^X>QtB$`3*_9n{`a$x^_}KcvgN5iS)_OH+=Lt`y4L z;Q}Wiu2iBo%9H^iuakqT1Ku+4m|8*FephJnpXRqJp-6puoOf43{{VGyE{8c18~V?| zmtHpY$E*~f{Lyhcl5!2;m-3w5%F|xh#9vRkc(Fx+xRRGF)03#xErZ%1(nLqw8b%RfN#{2J# zC<%V-K~Z6Tv)oF>P91hlHe@#BMr8#+b$NqM`}!6&(PKpxlZ*9_r&_=x3yI=;&C)*3 zhOnhQ7n(*c0dLFui|eRY4hOpdd3(pgQ&}v#h^tj9z*1k2QLRan%$Rana>8KSWL+Wo zqF}hrA*!Dg4lb)bfu82hq>Q2-Lvx)0K_F64QvUbT8C_Ra2Gb!T{bx$GVVZ%!gB*zk zz)>UR*>!w}>42?MyjV`bfC78V^^;<*l-44Xy()vs9gofb0OsPTsrW)iwgh35E=VkgQ_ArjwDqJEfLo8ZB`U}m6NiI{5Xf;NbvBB;Oq zj@ZnO7~%q(!&2%DN0R#w^E^Tb3JR)xTdJ?~#(I?X5+rjW$e9*Sd#7BCJUWosdwF}V zBNLD|#1LT$s(6Y_*5owXppbd34e!|fKD|qdrEtRCW02-{Vff5sIB?vS)2Yj`>FMl9 zsH=fKCM^`^<{xgkOLN4`Q+_`szC(?2ZO~h4)%mJmEsGdo#`C2%tUqrIPI$QEO*wEe z(`~!z^}^L|Bu31T)R&Kk&}2N}x($Y*5-t1pRQ1AZ5SeKh;6vw`BUWP+m_Q8-b>wpN zTT+Up@ZS355G@$a7+g;z@>F7Toj(o=hixO$(II!hRX^lCB@u88`%X}so=t`w<>_aA zOR;qNeK4D91w^1O)`sLuR`_(+GU3T*Ub6oH56>1qP!Z+49+G?+BIOabU+Hyv%t1S^ zrT+j-KA{YBjf5Ro0(h5IW{Z+s`$3~}D<)))Hay2I@D87r_|d|IKjVLW1S(d(mYiw_ z7N<;dQ||PO0_KwLZtj8kcfhc>h)Qq`+D`_CB|V2Ak~s3T*gD$uYPZFFDvMC0x#8)c{73+O@)ebN5_JT;m1c)s$k!LI~9LpCg`i-LUEre|-$ohFw2lM$4- zB*n9qH$10AlX{?g_W4f4WgB#lr?QQ|TP6as>S1n!>4`zJ1yd$E8Qh4Vw;>Thtt7pz z>wlk{0NxNTF9m1G;~uqxxRA21C8$DqBzo%6^@6p$|4If{rtxNE6f*bpHSpwgrcX7!GH5 z>T*J*6i9RvtPS>EE)$y}ZSf_$VeUfQfuCaViyTJ~iy9vaNbfdBu`-1g`UuZCd+a!%MxFQ zPyKL3d%GK09i-c7Dy1|2(q=nP-Y|kPP5p4%m90 zdUT-SbUZ-291H&d5|DF+DR8CLYKJKsb*S$&*b{<12H{qd@eC#*b<{;|}Mws}b= zCxWZOayfX2ugKJdjxRxX z(yNN%sDyMYl_viH#G)+1NtXNTN#`_ZqzI%+<9+`C*Ut>DS(GBZYFn90=YyCWjsP(9gw4ArewjdrgP?w)I?eKlHvFZVC9!V}?s+ zOm8ja)YQvxl+lv03y&FZZ_f_?&WHVerV{YzIZh`;p~al8#HPfI`XOn2N2o5JdkZuv zDe$NVta?&KI)KcrGh|l-IZuyGq_D)c`DpaG;v(dYB9>PR<4r4MzhqlukH&^$-7v!W z&VLukD z0B*-8u6Ftlyed@LM~YMQ9K8oGae9F(h_K3aHe9ihP>Lc>C<)*8jt#ogrAPpjlI49Q ziYeKuS&;We$CPPfYcBJ6P@zWtibbDDel<=gsy5V^4y2YFZ9iw$3aPSf)sGU~1#TRc za7n)V&TAv7xrC}IdOM9Pz=ZK#5k4jL#wy?wtDLOb(i%L}T)f)>&TT~0wV3RvzamT} z)f&L>ydZ2X8!{Ckx!Im&N@?jUY=xeuxi->T!O*&H&|cdFY1f#>{3&`n0? zX=u1ka~FGkap?@(BE0LNA6u<9`)T)krUaQM0De2JX^Bu!bN>Jg&uk8%$jh|nA=jJf zeW#Q0dVj;~iX`)rKz>1!RuvL&?&<#k3<+s1As7K}B$xge86+osTTk;@bhRhM8!iBY z$`G{f&S{Xvny9hP55Mb+70AO$qWei+E`?NUNW9n)dKTC%Nb;;igCj3Fs?EM?A1nc- z(pY#c+9b%&>t=J&OYaF_JF*V)_0LSZSZ&2_bjbA>_SB+W!BiCPyKVe-!LF^2V3IjX zr#W%AC06g2vUN@=uu|J*T+8WZPLu0plK95@ZhlqMq*Z(2^|(V;nN6=V*HX)*Mrm9z zt3{zss6m}ho_aNmdzWNI+evI#<3D1su?!8l9A0D`IZ_*YL79kIGpE#Bi1e45j6(FQ zD6~W(Js_VImiXj93r!8}W1sXrB5M#^Rj1~g7!?s^>1YB>r!%bsm$&Ty0O$E)@+nwJ zb88vxiJ~!Bk*svEDh7hR@7wufmROPxFl7d|XPGl}P$jx4)Ge;9Ta~-7^21e`us1NS zPSf;hqV!mmC~{hHrsH^yaHp7b^r~T$wIkWL5;eikDHa@-TjKG*Fv!f24Ur}O(#73= z6#oF*4x!?5Th?753mfk|R4P>{mFj#Lpxf`ebmcklDJ}m1Od6ILUEu0_g%gcn;<=II zc*yQICQGFp85Z?}4r=oeC(i_{;J-WVDgOXYcY$4m+{UKIZHJqBIrF2q3DoA2-v|sC zn5$nBG^jNxS<0Ri;V}rzEAQ$Zl@&HYz*D41)Oy1-{2+rnWnZ`2tQ7Vf2F;aZWHR_) z-H@)dAH}{MNP%^2#JWdK?+;5-ksDKFp7oU%8ueYa#wyn~@|MFFk|8o-DH+qtY_w@F zyJW%XDgy}-ahN`!@=D?oMbp>UKZyjE$1;> z5S0iVV@mWOaX-sBSuq45TY4TI;5N1j=rM8hDM;Co%{4IsL++tCNmA96N_(GWvnDQSfpdM)$ z+pAdLq&M}(dUV2@m=?BV_TQx@TnC+h#W|o*W3uL(5_2a?@?dSJgj_u&OJ9(X6_03pXjx=|o822KqSRvY&^2zf5Op zLZPvPc*&PtZUqeEmnGvzj0kjD6xXW6pXY#g(s3FNA-2X0tgk6)@`fAiCa(s4R_p6T zUsS;=BWhrC(o5ZM_xAnFNExb@zlCzLMJ&MIDEk0&|CtUG+YP)DYi|K=;%S{-z()AnSam=+?vGSWT zB)o0K2l-M63uiQkA=wRrpooGh0N71?`F`z zwO6JdUXdD}W_1ReCY)nR^bqv={O}AA5L5Mj-@F%aa5tZ#NQno8%Ne~zFpokLy%#Tw z04b`j-Y&8)gVWmS&g<}-jzi}(6_zuo}uO;4Bm2OsI)A# zN1W9`#+<05(Or&3(rSh7h*RNR)fef9tu-T8Gk6vOaT=;r$T6l<4YNNGUST4>plnpu z*i~9;g5#WJuV^xfJf`J{sm#zSMy~z~>0SQ4@DFnV8&HL6ZnXCj7^Z0@VG-R5J(p`G z*XE19G&2TZIYzk}tvuAHKMbI2JAlOL)V@Kw^?h%)8q7j`BG{Zs?^RG47at){cg)rz zr*u;Ewla#PO`)?3+{s4sF2ZiC#J1%&*dxVnGG5;b?}xhT8t-^SjpTZ~=*(tRO&_#z z3`^U0D)slQ@QeyOed6cBUI?GMdh;GPE2rW zhvqt<)#9`dGIJAhHAa;0HHW?t+eOhfAz#ZFo}j5oshmu#Re@7FxiS9$_g>v4_-+t9 zDD+7K*!y=+__}b~g`0=&Pdu-m`sOBrf5)W!Cz?G&{@r-iBW~D81*dwD^rhDsDAqLI z;9eq=*xo(SGo2E)#7K=8LXf+JR}}|ZCGDf<`FF>n;rm9FUwgpl4#aXV(bR)(;a~+|uwhfPA z=oat!Z{^3(I95ldDj>lF-_~?W6*^AxK3wBYd7bWj`Kz$BX6 z-+qEk*7##m8|?s~GWy^yY|7dDkLOJLE}@cVvl!;MbUKGIsTLp-MwI^mth7n5Rgu#j zDdol4ihrTUUHtzKHE8ZkioN-Mpk8!=za-d$G`77N^ANCHqzj0 zx9Y%vO7fZGKl?=SQ;E?|n_jK>3KQFv9+*6q9Uqgc=6CWnx6>UeTq0A><_t5!x~&5& z&_AVBG->LaE^^@vuCQnS05C`IeODJzNj4ErbAc{M-qj~eVq-LT@#o6>?EEh`wk( zsr)gTr7Ld$DG|>p=Bk!%_HL$T5*Opkl;g(?91RLUH@OesQtk8~t~_UJQ`5v78~e}m zF>xLiw>Z$`#N<+nN=fcUr~@;v(R6c_~Q;V*c{4QdXpzI47jqXoI3>ybBQrV+ro^aJ`O)b#=@SCl&%+9t2hgxGur8-ou6d9f;K*&T!};sO%Q6PrP;;Cis05R!f1Vve$aj%gt6~eT zxN!KA%%|eckO3oDcrn&)*mWS`{53R6zvVdl^oKw%dw1Fum6{_@%@8E99n@*|xsDEw zq$OVKx7QA;X?L2b0tcRBE4@8_0f7ZEf2@OGtsPQU}xT9 zsJTOtcm`HyfmNv0TW%DHZ$l;L=-3?ZZ_{j3GT1e(cn;v3&v{BoIZUbh&|XO=b-uoz zix~Kp(NtTUs%HjCeCjXq38;GZ(t3Jrs}{72%K@KZBxYDn<*bbGM{s3M7CE5SuG{_W zIL!BMDzAv+ z$r&huYEBnGsUmzS>X<5sEG-0x!AhFQ<)>shQeY*Rks%Le$vttOK~hAbv*jVjsx`@s ziJOlroYE(kt^Fyv{+KGX>@^8sTX<5BSe-JT&vl@Xak-6?!diQJ>Hb&7ZX%M}3kwMn zm@?`-Rhv*~#jrNROGEWh*l<+73^0!FU12#I+;sUr#W9 zEmmLC0a}RBsC1D|ZwY10$jE2fl}<$AW*jz6r{Rlf%yq&mA`SllbyopF00fQUBlwAi zBUUF<^KqjF7zkdySoU5Gaj^_4iCsFG>1_`@XJnP&};6XDEnVI|zYskSeN16V%%J|0=SkPz|0fo#b0eQi>k}TLSxm%FD@ofa-Cowd* zH}{%L>3vrEE)-De3&_Njxw(_F&R~!;{?k1TH1{u>WPh@AV7Ra4)rxQy%OdzpKOOJ? z0BsOskvMT5)(5NmCDC!e&immkx2Alf*4l(htY&(16?p7Vb3#m9?uLfh zbX;x5*2?RbG}1%y2AnliT;FIk@rZf)nMuuz%4`WEMtI|pkzEbaR8Rh;!RZ$b360I- zo@C6wZ1K8#Aj7d+rMfJ%*1m#hEQq#F`&oZH9Yxfa8$f%rc}7aDK&DX1`g2RlWwdQv zOD=&0P3`)x@Wx`fw6-_QnI-3GoI5I$>7g1Oeg6QnEx+OTu=n zweTGmxQ61nBklOEly!>Y4wo7#fDzPJV zYIN0o0?L|x=o;Ure^w~>Tsf&w{*j;C@jA%m7VR1(W@>E8LvB;$0f}2kc?ad2W*W2!-8HH;Zr%AyJ4I#;2s>>yuXire(q>AE})$28B zA$m|)@y!)4Zd59$tvbkY^FS_&uvKKoWX5Wmr&^&is`zh z9ogJRXR3EppGnRe8~rCu`&GD#ebW(Z-(W6AGI#i1(A%EZ^CZ@SHf4!VCr%uQzA}v4 zpx`Txh-!7G6dz}n$vvc7bhR1kzBE_t>a{HD!L-|OIS!+lHs}E5DHscZi_J;F4DXk- z&j_m-pDm7vuU90pt&nLU2EnjnS4u6(k!ZTET}p~uU?@_lNkUcM_sRO+T|t>?I^1~? z*O*E_TsVMWNak^2LmqLvBk{N$usB`i&g@Kz?!zU!FTk7s04!Kwb~1>I75bK2i#9)r zeBt<$Higk1ks5TOaJsw@{8kN4fAIbsO476Iij}v%zQ2~q z0ozolzMAP^c5Tnc_?ZtD801(?pO|ufV9FJ-infs;Kzf5}C98D_1 z^jJ5farc(rAwi zPG2|0N-<@wUF~pE-2VW&i;NscXz=_wwMNfDll**QUb0i%%d;T+J;c` zAidxtHmyT(#Pc%Yt(-F3%VAHRJl7ZfK-CFKE2qrw@V4H$nQC#ZViOZYxk8DUvSlWq zoYo_=97IRTvFs^fK~F9?g^3!D!t*grU>PjrH&3pHsUY)$n=0F=f5yZ7*BOeC*SwE%zY`f$uPm&7`qovhfHp^E8^)@ zYD{dzdPzx|nL11y^tn;$OpM@HWyyl^o3`n_%~$d)D_PWUn~&ZklYH+7#*z%T%hZ7E zn9UxdUY|@aP#zPxgR7MJd2qAqRX8T=Z$;^hB8jB6`McvvA`xci4P2{gUBsHzN^!9H z6D{%`Q5MKkPJ`2O!hcA>#JyzPm>L#vYBZ<(F}`T}38;wkL{HZi#kU;b>$k>uiBE}9 zp~;UPe1JEdJuW=ev~PPa`r80NEDuRay0(BR@~e^f;Zk-Ccc9W=icwiN8`QkvFFlvj z8aRPT)EoGLzrsP`zgWwbB~>HLXTy`uiAE(QHA|bA%~HEkTdA}vY|FIi_Wa7OTXbi} zW2Fm9`Aq)+31U~SYFL;pS*jlt7gVXlZ!U~=YeSO6kO9A+`Cut4GZs9gBp9s$m~rz| zNv=Nl>vbIWRxc+)CO4{vQmun7h+FuldZcMo-15V)q`**rQoX&9p+6Iy7FapdT6K4~$#LvWLJgQr zM9*OHeUad%%QjmZ=<3)P>-qlx%NM!SqE9gmQ6{A>oXW*`8*q7my;^xLClZ7$b`Rrerd$7wokBw6uJy?-MA z0O5X}{{TE^Dhq4#vE-i ztfPYpdu1t~mz91m!neLTRp}dfh^t&$Mp~@eMOu{ky&2P-&})UMNJKSQ6pzzYu;EQe zBHKXIacD+^m|dvxu1zX@XpxzJQyv|F(mGddzH5CezBAXO;0_GF>;Z^VF;)x>#A-VY zD`+h_%yXp-S5E%`Oe2S*;<=L7ooSV7lzimnaGHM4Fb+1Y7OuP5K!0CM3vl46P> zcCqU@%&E!BJViML7@R4E%yEp{O=dYAnvld}8?0c>fmp8OR~ zjFlv(@e*_MNsxR5>)H2^PL>5(9pG}-yBh}qM!}wtZbqza3*z90w zQQVV8tBlf*sctU=aZaCBr)QdtR#7rTs7vA2iqy>O8zR% zk;Y1V84BZa=0!$L%^f7*iue1a(}s%*M&oD-FFmtXdIWh9Bts;0!f6?>snV^=AJZ4z z20Dk7vO32#%uPQSD2{}aeWrk%)Mz4Qr>qr!RQ`BNs}pm#zoepZY29-LK3F*-BvuFo z)|=7^xOCfl{9Pir7eY=YlRq_><(~rUB@jGIj;V`Lm$B|4pugk(cse6VFo7fy5~kMz zceQBHMXeB^L?$Cg6zMT+hfycyx|a=W+gB+}Im>e@R>XL{CXlTg@#*RWQWN_}6qE~Z zmzVfpQS^XXXjV7OXO3qYkEc^ooo+z@8XsiUt8eb#_+TAPFiOXU(hLt#tOI;%r@$>H z%g#6;cIp$cuACr0cvP94-0B0AD*|jvoG9&R*6c%MNxxP6OZC#X!L~r^EgGj-^q+F% zT5DWGW(4W6bQH94txB4Co9;hzS7P+}VE9y~)zCSxzt8r(8fc-wCREuBYWds!soC3# zwb%}^0k)f><=%UpK*0(*tV8j)WAtBqxa{_~6-@BTiIQ7!dt4h^&(q^IR&i@cJYlSb zS1nWccLlw3GbKnV&%RwL9wTeakOAwdTLcm``}%Ru?4%U+aST5|zsF!cd6<>5U!-NP zw+aWd>#(N2wECBXGiXWfVn!6-LZ7IJ>?FQb#!5=n+Z*2zYA;}Sn14HFYMy4!vnq=) zjvqYX!4>%}iPImJs|v60jy{RQP+BzBkmM&)n&}pivW9V=lyfw$TzK_bH1-A^T8S|i z!_JP2vKF1h$IK27SQk+GqPdq>tTH9Xmh&9kwOVI8WEmx0qf8);E(FI@n;||3vb6an zk5aQBQ{L~VuTy7^y%egZm0=b@BTGwiocs#DRgakR4Pg?UQ+)zaz9J6AbpcDlIs@6= zT}$wgrPFTSH;mwq2IXptj#HghiKcyHw8kovsL*LNH^~j11vJn#29n)HSL^ajb18wU z=cEv%*a`bGaL0x<{u#=o)amruQ=4ePsZyiez%>=Ifew=`H}Z~gZXNNw|m3li;SKrNQax&`1G7N9Nbtg!qZm_ z^;)0#joYXe`b&)5cft`jzMnY!zPQkD%4m_=sK|)&tcXMmm#an0Mf}ll0j;=~J9tWM zPu@azlJDIfmHrsAirYzZEB-BInPtIAd6ANadYo6eLS?XuuAxtc z%eQ3JqDZ}oK3kaDbqbpaOjEt1>Um12bj?Y zK%Dnckb??JU1g|~PuB`ybcQAwBr(j(JZH`gXMbr*OKe4N?3zqxB)a5_Xm~}=q7m}x zGmZ_7)d=-`DUW&BoD1-@OF!y+e7yYgHqb(#lg?7iWz5%Eqa}T;w>9|lB|6x=%w^^C zwOqh$^46PUwA@V;Zta``JmZU~!81bepN8==w*><*=E@9LDl(@K0LqFlD=i~k4cyYg zq8MKIEOHQ8K=p}RbNA&6Qy!sI_!EYCb!Y1chLE zMk;HLQnHj9gC`uFcy&DmI<&N?o2g&uTYWKUqzm6U$G)+OECG>f6IzqRr=M-(ai_nw z0_Jk>@DThf`C)ICK5cYfSyEGy zbipL#pgrmGwk?zqDM=DRRNbl8f#0-SAqdhD=7Y*=fws%ox5CA_o>7OzkYJbh=uJ* zsBgOIwj0CIZ6!pCr&Re{Vx;vyFF8YNM0pWh(Hw2&Bf4SKbe%=T>|+OqCU~v5-9CoX zgy_8FR)x3qr?}tGr9PiLGL;~FF@;l3BD7kECKHoeHuOjYeWGvqVU?-tU=Jt`Z;3}y zmXFpCE@Z0SdB!FY6;2=mdS{olKc z`cz{3d>~rVeIjF2SL8yOOIIFvP{F1i<#l}1%qxMbYJho2%v#cLF&43$Be@Ev;W^3F z%z;4`mfw4~)8@F&K|n>X1fH|f)aW!?(KQ+eiJ0gA0D7DS$^-l?U-R6T^u>yAP+s`= z&R&@rip_RbU7aZ^&b(2OqRx0!4>Wsd#wL%c>C^hlQ;# z7cfan_}jiCsf#btK->DpYy7mMgI}J|D9t#X5g^K3Ii3BpgBu zVVQ8`3Km`(ME)XYSTY==IQTOfp4%#~)MRM7v$w!2Wm3mA!2}>XUN({_9pz8bKCm|s zxT8NXbi&H)(dgi0T`h}dXKNu9lVU{L*wI6W7qB_O zBvs!NyA?dQKPsWir@a3FgpteC5XQpyx{fSJZ zKNg_;w~9)8#c9O=>>?-TOk!Xuhu65r#Ko01GwEgg-BR|7Syif3>Qmg`6!NPpqB|k$ zw#(>=^T91dN_M^EI2MluU71>-I`uV|1{;hFSkP~zn=>zXW%DIZUrXB<>Zl8HelT>F zAVtwQw1~k^t;UfeJCY4!_-DXc+UL}E^K|yciYOg*2yIM*Y1XOXVo;*y3N&+Jw6k&q zi*acERX@!(TtrPRp|T)_%odeA!t*YDy;av3mz5eCi0hi`N}7qV`UaKP<-}eRjTXH% zvF3eYv+5R>FhzLsbmrs<6rMFP|**h8`{cN~W+UyR*UJ_WFM_j8LE`Ls_(B`Erik%RR z#gDAyI4x^Z4MpW`ETd#y(NhXw*48#ZQ#FMRrqaLS1zrRBoN7kmDH0U({l_upR|oUDU%LFA*ZzKZV2fW4P|{_cfGL3pi-0S-%Z1}XE!2C=KL9@4yr;r`H}Q$Voj~K$U~_< z?jcoWZ>Q}bu@{{=6nb`kas@%B-D!}J`&Ad7AT31dFYJ*lV{{_<*m0mJBOX$lFkHB` zT)XV^BB>C(Rc?9{k=%@2#P@`&%^&V*{#aYOH9)U{=OTg56U$TBu5hMhX&)MU(j%XX zY#UM*W&$TMP<|i2pS_7$G`EzNPEzmkeRDON1 zraE2_0#`Xwm7DVqv_pA`3XNCste&S>oCM1F;gNAJyt75C zLaes`0D@!06WUxB%`Twe^?L8WRx&CO_mNSjxbxkoRi(pv2ZWGw2sA%_YN~22UsNkD z>GQ=^x~|y}gIEzEP)-z#!BCktIX3v!45E^!st(pK?-lT^7Ex}JkPMSPXo;eX`1#|sYvF?_fqvoS5e&xqJ;Y^-%Yf01w_Ry*K1=>3&y=W(*0|_i2U;U z#`nyk!y*9tPby~$9ToXsV#Tjh+!pE*BFiV1BZMR)7~M9+n^zGNaNb}dzmb7=t3p`0K*XN+aAu9dTcP?Ind)f8;Ri;ykV(7>@q)b@ttPyo*(;%rcZ@b z3PxiXz*4Doc_I!v<-D3L?#X<@h47Hx*T*$`Sc>ee;!EIx?*4yC!2ay5LamjG8Dgzl z%6w3Ed`JYO*z&5B*(2^G$L0>U-@i%%s)}kaDyWvrY<3A(TZ3^mkO;i~fej*wU(NBV zygY}OC{tudCTi`7l$w0rP1M+Mn`~9UXzW6172{I8Ep zLVg*v62j}X`Cq53Ia!^`iAL08N}yJ>YN$nbQ^4bjpa^{(7gX4-zvquR$8cwZZLYn4 ze|hzs`nOU5*zm<9-}Xh>U-s*m_%(RNK$Z9zq_Ch9fCLO>R@b_bk~R7?C_ ziG6X`xdv#Hn*E}x#v3n~g}?K`2`9pY!Mm&hM824sM3dX@zRq8D1Qt_*1VYgb`M-e^ z?=NgvCzO-Q?X1YTQo?hb)@d3%!W8=b0GT8-QStwFe>q*nK6dmh!4m zA-j=jlB@M++I6`pn6m_y=QjpBglKILr!1F9Ha=zZK7@TBaq=&_9s#dlDjJ zpG&g%fmJEG9#`qUa~3HuY>ATdUxkGdQ*`$HGZUq(aBZhKjFdQ2ohYTW&SZ9cB6dYmKCKZLjG@uYkEfZdR{Do^=|RUcw0Jr^VvzRo zBG>pI!NeMrlAyWy%L1vyjwR3Gzx}Plrox*3m$?#<+D7;7tD@KX*>}eZmuK)a&XHV_ zJ~Iz@Pi=5xb&TU$%B-};SffCXua?LCq9LH$B`a?I{w~YiFlL_xMUJOt=eJ*kwn|7c zOkis_X9|XKkC&>HY@$xdake>))Etd-_;njXcEnnI11_};V1=SatirXbo_eL#oSL*; zkqNg%VKk*Sr6s~!F0rx`V!lh>$z&^f<0Uri{G!uhM*03>4&vDd-^LcA*0UQ_w$^ zd-8&=x58uJlGYOZbvolmqd{Tj2}1o|>3x1nhPP^!!Xo`+9oc_Mc`DEL* zB?7 z@7)H;+XMEIYt&<;eWIR4iw8Yrr>eE8=3rr&6J#|VhH4IgwgRc3Zc0j9F8kwmXmPdp zN`jJD*b9@HqOD?$rEGo@bs^l2Q|dH2MJei#zI z3y*#zaMaz+nD1Lklb zEe+a8?>nTAYxMl^&LWVdR9g3iQ3WzBCBO<(w21WC(io?EwK&qXE1-q<91-%5_+VH$ zC6_&5o8*Z=H!>ueyTAZ#DKug_SGUMV9>k*s1kR3=X(*~L9bd)7bUBB! zefO(w9+6IKwp7&Z)h)lxaHLdMwJhK1)(W5o>lWOcG9bzZ^)T8xWZ1Y#)AG9fTVtSU z>0oz{BH50~K0N%LPkwVOj3?UjHXUeUyMCWsa{?M}R2+$%sRtX$c{&KxIJGK;Eyf@$ zsBaWV%<9#sLtjqTBeE75#1JV8gEl#g&{%kKWr;|t#o_+|`!XEPlxD>1GUb&DmpV|O zxe=`@+eqITJA+!g2gTs3lX7{%4`!OoOp!}(Ey=0BO_inp02dTo=Es@b(7s{v z75wmppp02+TH}$nNAD|7oU-zKhqG|KGdIwZ8b^j^7lgZJ{*ukuCmSxaZeZ zq%jTa6yIm&xxM^hem`O#o3*1SUw6R-Y}Ad*gK;E|~>e z4YV@BPG?xr^8RqjZH{7!=31_xIzdf_&nO*^rELx+x@~XxyJ9=(CrP;c#XEROkf*a$ zrSVW?#CBaPm@R};CV;dy(EiK{%kZY1yvn!30|J@l5QkZ@+8i2`{v+oXgTPD>sv8db zx|@-bG;(OQb3DK(-zbqteLp-216B@1c7c8JCpwi2x zY19`RiKQH>+umpF>o$e|0K_g?W!gd%8SX0}(!936H_BG}s`kO~L75z>+9mG9u%4+; z4JN7j+t)I-Vn>RmT4PS`@zVvNha&>5^EhH3FNUKT@$+es#UUa}29ZLcB= zOxa1rPlQyBZ;PU#Sd)MTelS#CJQOje`y$lepwDKrSc^;)nNlrHj+RQ{%5Tg_h)xc_ zTPM#Mg_-Q)z?ov!w1t>OoWvByCA#cNui09(G18086y~C*qlgHoKbqntLrsr0C;dPz zZK7RgK3AK{tjVEMZroH~4IV{}w_3H7H2xhajcdcDQ);HtD83Bs!#vSeo5m@WTEqy< zjb)!4*)ld3NKsKm6Yh}S_?7r{N@GFW5uM&Hvd4j!0-s5l9-QGlO^p!Y^NcJ_Nb{MJ z`dnB408TI#HoI<5)1(bJx!PB`9E$XVB%>WQ73O5fLD1xpXq6jqi9FrBrHxh4 z8g9o27U>yaPIs35BE0;*8PZ#V^9;HM-!+#%!$1{X>mdcY0zqD`~!HrS2j8}>kK-nuh!Ppq_6V7O5*5Ht4^r?-HvgQZ{BAd zBk=94S%*2C8=Sef+xszAE72#>X%I$JGwKn#9AT4AOCupUWG)Myb!|X^T4BG$OX$ne zt4J#wsoT%Ybk5xG4d{&}7=9(=!MEv0?7{soZc~*O=0jJ3=>j^Doo*vcDyGW3v1kar zbYU+|Db#jRy{|icoxwJR3xiR<*azXCj%6(x9a}Z=@bgw)pt&jPOrp|ki5R1Yvq1YT`g^>!SdxVa5ST&%)ay&CJGu+G zBIBD+h$^*BQVIqkfx#d6fqWhFzVcL}wLk!J`TF_6nKr*i&s=wzSj*XheqOIKYI7)3 zNe#!y_SA$OFSW9-F*->syJIIE*`XH$QXP*ldU+pN#Hm4%t~tw(B0kh!J1k+0%WEnV zppLcWG6EMDQhn?PW1~~8VsJtH88}mFgi9er3K@%*xcV+VC#>jBaZg*9=a?w`BC1#w zk`f0@kKSo7s&~UAol!N}K{v(8GXDSqqvS3l@cL^KDe~TNnw3gJ=-bGA)%bc{-Qz`FYJ@i0 z``{OXqgJ`%X}(AT-iPNlaC~v$?6wxUITzep(*9&0NH(SI51ncr$8`=K)tI4Hp-XwU zQOPm%y14rGQVo0=cq*JoBSB}w@r)pD}rCpGP38v1`W076K0$p-7mZuCu ztU$=DcE(O2YIh75au3c4EEMV9Y3W&tp6RtFVK)0xM5Hr1`tIJ8JwR#jZi}~kcq&{m zL7|1Mi%vNo@ggNuGX`Ev*iCp=BB-CeaR`N{({C{+Z`CoaDKHp>h+)j>l^lcY=Nf$; z4VrPolm>(b4x)6OzG?C-E|a%-HS@>H65V&_D{3Se)AH*=!wfr^NV z57Sk#s;3D~m;|Op6O%{PAvM zKMB?0_!ZE=FH2(C@`YZ`Fe2>jNtVBOg}?q{Oc(yE{{TQwqWs_Pg^_^8RFA4x1kf51;WpNT^Y&Y}%nng)lqa=;D9mSRege8xDiz z{^h@AD{r5#?G>y1HQ}yneml}>&q0$I(Z-&F@{W~H!?>z_Er-+MxMD1zt@?ZX3C^w9 zfac$cLverEt2fyj>)M-wQpf6Ov6Bzk$6VTI+S_QXTSqlp(&0_#`~M|boyOviTYsDqj7vu3^K=V zfO7dxK@4j6g^7T&L{S{85}#75RB8?KNa&|9KkiIx=D64m*4)D1<@|BGwm5>!LJtVv z%vrHMwD$CqW4#~#rLs`gyF4ESUbd}F>A$&pY)Wer&Q-V z%8&aSyQMAnPziCin^M1adBa^7(_VmOs@onJ9#)XzmU~ zpq4shO8m(Q#7An48?OHVSmxMMxi7_sQAITL9*~d&gDe&(&Q&-j`M`|y$!@Sf!E<~& zOp=#TI7izY#i&xPjs^W=DAO!#q9H-cb%D%oN2k9}nsJ>TZ-tgFfUoake-p*hTX&Zi z7{r`SshctRPt{2*LUGnxk*ZrKzJt~pzKWQ>8&yCUj2MIkhGjmX=-4PJ#21qMXQbz}^dUKJ~4q_i(pWVPVP%w<#^S4M3^Li!|*c`1sMBnH~cg+n724q^gRy`4VTwMdPvnd1fqw`Lq*!BUZkj+O!0b6dek4F+FO#wwL>U~3Yp8z_HeLS! zG20DguVZ($_QWeSh%wG7RF5rX>ZFQO(dkY;>^RQ2h)ud$P?0ruMNRfBbB!O?3thK} zdTgTR7aA=5u~cTU9)#_8?6*bqailFVTKb=5QQzmbB0qcz6Kjv3`;|_ny^W!)$;LS$ z>|sfzvV%sL-BMrLPE+ExAOPTof*o47TN19=T5tjC1s*G8UjAJpZL1KLOk$Nu;mnNH znkw~N)y|8q7EzNcNgQ=645?QxkiOsp)~UMfiBSfv8bCMPNUPLl1l_N!W*}}Iy=_v*+Y9o!w(!8BA0D6_5!r}Fo%HLcdR4G$WO}#k}e4)7))G;c` zC3aONr%x%fL7xvT#E#h_1C27;a)6YR%sQ7F>e5yhQF&o>wzb|zC2D6E9fIV>V}(Rq zk1LYjO4#)ClHVA+WnY>e6JjXqwpPS`-x2njE*UOyXwb|PsBwCW2CC$FZZjrRaOEzc zCSMa50Th3GYcHbXJrSTeOk4|yh870X^cE;C@p_)wQzXVZiAkW#kqT1jVcmZ1!fjIb z@)hs4oNOh#vtzZ4fr%N870kIuu2d?ts<6h3J|i5MvL9dAys2{=j^ZWL{pG*U7^zn) zZjb@6v4XQw$jV#`ftTqIzapkl73X|V_>ZT+jQ#>I5BXo9gJ(bo6r^+AV7fO23BPVs2W2PNnf~ zp5qjVY&=Bthk0g1NTS<_sDi(V2{8A&f(bH}NX_GAJ{=w0mq|#aP@qYJC}uOyVY#h1 zU0&>*5=|(GU5eUqwx4I#sd7b!pS%4d5}RB1hnTOmOrx?*(jpUrE_5LBK*7Z$GPr9U z3%dQ{`EQ0(>{kB(l~1SS+Bs>;yEt*LFw!f|%FFpnFFZgv^ zxP;oFKDIxI-6*X(8-w(ksrH3*-o$*r zG0eErmUGs0p;l@6>4D1h;*lnGG3LpMCoe#Ye6V*%F#!u&f+_BIx5}td;^^?t!L>gT zxCa)^`QLtakEq9|?HD+1I*&7hl?>}K#@>FaPF0_6wb1V=dKnEp)j4PZ z_j<9_SjDfD z&_f?~)}r}-5o~}*(FH#CJD?r6p5wDPULLh-btn%CuRe+`^|&PSCwxNuEXwulyTDm- zCP;*BN(1GwA&mmjIsvUzwQ5q-h?@F*yL|D-ui9;^Qm85~zn?#}`Tqd*Cuo0n#Z`Ax zlY`2`1Lu?M!j8>mhm;YqdQ*lZ+b_vtKfF-YYoadp9_n4!zBrVLYMMdB@`}N6Ds0aI zxgO9}x2uI4Mo`~{{S~qUc=HhLb_Qu{PEPNrkdLK5F88mU^$#Jg`6@3T(wYc z9C;MD{MnU&f?U*ellEvrzWD@DM?znz6;pgSgY6?p^{KEYZ!WOt@g|wD+nlX(Hhj$- z0pq-CU3F(am;6I+%8J5kHzOet-YJ!|wq~eC8*8oz7Cga(={nrR2v^XvOI>} zJjCtLu9|frxaK-bH!?+}*7!A-GmOmTK6emmro+^_^*&jXY#XMa)JQFsk$r)1w7%8R z#iG7QDovMW|LU?i}m@=T}~L#s0!`&_x|Rlcm!r# z!>7uqnClq%;b}1(Bq0%b7qS^I`C_yQCw2a+)|SkP6SIGJ7qpY>Ys@aazbrwSB}c`Y zN&f)7=#vG$dr!kbL0_9@U;c7qHxM!meItuR9(`IqYGzDrY>1))a)*0R{(Qve)c%6aR({CExN59pvx4fak^ZVt)dgg1dFK*6r0ki_`Xg8fcO^Crsro1Xyw0J39? z#CDy2E%b2W-+%uAIzIhdhvc@ zpXZHTo!E6NHNxsY{iD?LfyH*3Cxv(N-}WCFnR9=(j&!ZjiY7?Q3{a5D!74$df)V-+ zt$(gPWe@4a{{Zoy9R@!0j{JR6d^q}_e+gAqIJ3rF$L}gR)}Yb}bc}Cwi}lAwk796C zwoCfvV|tHM^|?P2_SyrNS0bQnawgQA~{{UD8FH+FuoKNnaIQ&QS zl{U>L`Qz#_^qXmRj~Phe^$v_bBF0`EF7}gwp5BxW(Pl?DZjk=~Rdpnpwx8Pgf7^im zNO<7!{fS$HbUN-WeB5WH_CGn)r`w!A=&m%A&zH~moVdGPrg5u{xg&%$N$gZ$N_lHF ziLr?Yqd{wKQXg<4>gm~aD|=(B+109W)E|qgE=Pqy-sgPuw@8jIojTQ3Df-+%8TZ-l zw?pDPRg9NZZbn~ag(q8*OX6wGkKq*e;ctvOlj0v-X$?-j7Ie;XInEauz`X)N%%<}$ zS4xIvW~oY=+`4g^iB9r1Ub??`{#aiN#VV<$cO0e^eZ-!Svh6#DLk3*uGaQLdUAlZ0 z71AHvUih?ksZ+o-krq*z{5XqkRAo0`uf(LmN@Hxmyk;L_=5CP=l~q62535Ljh`GJn zK9-HpR@%3dUgAAQl}U_~VpC0_WECCcBfN(#+kW^8eVnexNjLdRS}GdjCP{IN;GH5!LPXm6+VcX)ZBOr%rDxOK7Q}Bt_xRORgQe zpRK>c8wf99TxZW~OA1M~P3IV=PJV#YxX7H($>SJ}h$b{pDKo zw0e^vn;DZBUwOvX{Mk-vPu|iW;d~2H@DP5I$N)m-Co7RE3<_IPQM2a>An9>F_g3Ve zOlJ%h>crcW9bAm$k3IG(_=&KCoWAg*vDCjMMY3uC01OcV_y^+zpDE%sXi}go6o=YP zT1d&X{&=>aZF@*o7H7mWnu=&t6kArv4VM5*tK=)|gb<~4+v64p+R#IF(Wl7d3lYE^ z*<1!25=-`6IMDAi452xb9H_k#RCoM44*;h92;Q&waG^*zA^^-QL#tA2d`^oPn+QPR z@`}<37x?zS-CxrQt;4-4WbYwOBQj`6m=(~aPGWI61r9dq4hJbW4MJn}TYh*33RhUR zV7mY>2s9M=bZIp9<&<~jHh_hrNH134RxY7mmJmy+4Y(4ncab6R?nO(8Y{Q3Fill~( zw=IBmTxs1_0U@>iTjN0EbgjtvMuZ;5O1~H$}fQswrf-ZF?n`1l2`FEB^o%$Q@5e zy;sL0E@v|g`t4?=P|YzJ3UkmMNOHVKy>dDZr3G)X5bjE7iH<8#(nBH7NT+>3b&9px zCQbV`omCM7j4_p;>pa4L*-r6~Oo40MNb>8H=(!RcCgir2CS)t)p|WAC>e|Jmm2Gs@ruuDiQA~As zKFNB5@8Mspi%S`m-CsLpie*wn=9>?+4LK%ElWqcvUj0fdzNJN=S5J3ou(PxooDwH@XU5`cnJZEsYvF#)@$|rNp_igiv0i_Y?-%+m$BT@{GUgRKMsas+ZwR2L+dRHugh_gx>CD-@YG_vI>De$Vo=ons+Y zW7hK&sWcc|h?K@d;79idj4ORO z_*=#C*+-j8K5cqFd-koQQ&^|Tn@6Xb%jAZhbe39CyNV>KsEW;P_jTiy$5rlVGhWxn z&-k9Zw5u;-a1Bza@x6vQ6MKQ=Gc>FPqEAtf{~Nr7qA@pRdK700Hl-FBY}>wOGHa4%t-dT;pYJ5;LVI3Ee4 zTj9=K&Xww%J|OWDWq&cj<&_`oxF2V|N;3mC#w#r?0=NK@}< zAw@UA&aCcE{)5&tj1NwycEl6*@|ssER);nFJyNT_A~c6(#}awSr>r^S(CQ_=P6?&G zJ7ZfZ*y14hLIo_@gQQq>=M%eNdOw2TOG!L4Ew}0%x6RluC-zT|fA4zY2EO=`PHl&q zbqTWvNB6KmNfY>)DX3HmOs7Oe;*jG4C)lnUt$*%e97(c*VIu%@7GX}LOZQ|T4tnaw zU_p+tg$|caT5h&sFi&Yw0@2w%m^~ucgL4wItwLT$_EoG@9C4s?l8~S{OVrcO^bh8M zn%uXiEpYB0mb!ouDx>1!e?0R%!<57*v6(((!dj;%xoI@zL~HbDQGfidJL-31GoYW+ zZW85~yfgMn%b85xWFLbFMoJaJ@(`1(1v8Bdg9E?%^wHIyaH&l~BiH61Z=~Jfp6~@z@24q|IIZnznKL}+veybh`UMW;+0{rtuFTuG{{Y~R%j5cwY<&Z>Kc}hCLEn#u z{{ZZHpDn#-p5nOos!o%SeV zUNlDbf8#8@&nS2={{YUYMPvM2zB!dYsXIQO{{V}BKu_XpUd`egWHZy=&b(u7vLT{V z9sCT{qLF|6#J~^gj?OsNenuJWt|SbkUaRoSig|LJZ`HCbeU=3-Pcs|DHlN;SSmSjL z*Wjz0Q>vu;+wWOwvdKqrTZHr;FwO4!AI9CW!}W-BEFFkYyH$S=PNTU|}M z*(jT2o7_n|Vwpn?EG`VA(m3UAEmr89ZK-COtwOHtR-%mu^nte#*MwW?((^0s-)OXr z$IZ|xD~>;Dc0l53Ei|^3{{V@{$nFT`%dBk*^*DCdOXW5P3O%4``MOjZ9%Cr5sDE( z*Wdb+IH|(e2bE@LJe^7>-)#-q*={LvTb!Px&A(>n%tz1g*t?wp!&R!UQ0dNX^zai;`YrzcJh0B>DL&5;rGc0A^kbWm;BIeeA)X;v;MbxcI|p&z3gt^}Z9rc9mCPX|3lpRAo5cRusAn zTHa7dlqYHvV6@}F^T8KLGTL?`BP$L%bt<(gg{oK_bDA0S{;lVDlVMG=Ia6>17z3O@!60FU%x!PyDevwAhJ3L?F#l44A6q zxLm53^)~jdgZdTwrW9#1;2W%ja-JQO`*p^z?$Hj&O$Shq-qZ5M3S!0xP&S?FjWEo< zV{AtQBu{?Quf6))(*aDD!9NK=MoLN6b0%MtDhs79qQL5s9~+}@KK}qrWvZ0uuvQjR zv<5{6#(9MnXy;g!BBq3-C0>`4tL~}^0^4+3rX#xOC=b7kH6qp#>W1EB%baA1Oos#s zny!ONgZ}%Lz+af!7s6TCFCa?|iQ1rW}mq zcL=N`T0+b5X)saz$bNWTB37_acE0^a{{T$I74ZWn!K4OV%Krdrl|p&BEm6@~ESQe8 zOKY+!{$0D^YFBE`7Q+#B7{7+n;)>l4B$`umYAv+>k&gDJv>BAB%BUhM=3hT=x%uNE zC6xQxQXp7^QQecK)RoYj$9V=^=Dv$!75q5dwQY;yXj)CC z;7@R2W;#6yDOH*iFkOA#Tsafae`*@6X?5mmLO~znjI7GXP%$M=@TNt|w29m(m7+vK zpQ+K09vqVQu9!F^3C;NIMe$ncimg@6Ks`5vTS87)O%nWuBA$V zTo69-?3Z0aexPLR!$Ev9)oMWlZWya?Tf_hof-7p+{n9N+x3&(i5l!-=GMo!!M^E>6 znA*)jG4YEkJDPv1zQUZL^!=ca{{R9^WqP58kTV3PouORAk}_McX>V7VnDs&n(Oqr0 zf7qWj3^i)H5bGV&eU!0$Jw~KiLErX|P;G+*!r|UhpmE}&#W3BGSE@;Vus2fWHhPrB zy+d?Mr#AYwR1wCim1=p&{uM@P^Z}H7T~^$EaJ-KX&9-RQtQ&nCc~mIJO0i=enD@ zh%=imHws(P7#9RwC;5&8gMC83FEFP5ZCFzcp7327`iCjvCSS`ribR-GVaR#}=fY5^ zv_e$*T5K-1UY`;#?^_10)XqIW+=*+E)<&mftjm{j#I}K&aD_Dq45tb@vZJ5DEM_V{`Fdcz5Aw}3M*5ZQ@GHHkf;r!02ZCfjh@C)Ik+!aLb*qR8SBY^C>0 z((qlHDcR}|7fwU@_vbVV%0D!57Hs(D!x9{38kNPhbx&IM9ZT_8Y(9hZ$6O0WszBLW zDrdeU<^pRgQQVTiA1(Q>mnu7J_etNq_yXnlaf^)Y9v_1jtkx%Cxjuqxqr*K@WEYp- zS@ubzQ=v6Ch*^R}qh6wAw^E-OKAMW}AL*kUO8u?JR2QR2Q(yZzx6}ADZ9X1=!F^59 zMgF@>CXJA|H<$8K)H41_U zt5qo*AXWbW$m%~OyyH8G`6`8#h51xzFeBeXejM9HBl!rbbz>!77KLl~TEXk8{{Vm9 z4L;UIHgcqY;AG~iSwlBuM(4=M#QaTY+lN<=7o%m}MaKNSE7Xhn;OTJmxOTHtaBrN8 zeYS;Pv{i{79Aosb`pTKSm%&`m?IBpJQJ$kvzMu?mwrl9%MMb_gAJ^g?5j`9y2K>49Y#r} z*O2NXlAQeoTWLO*$3Cm~wF^(Q{{T*QU-n!rG-03AeR&U^&%jCxG1n?Jel!HyT|z`B z>F#QZ^mi4rXuj~0c3gER@aQRNad3Li0sU#(BZ}iq1wI;h_?`Y+O&`G?JpHSjnalZw z8KvgO$r@&0^h2&1k|mxF&AIr8`@XH0mF;fD{@pvy9d4aDug`Js%y|ADyYO#x{XEC# z-^OZcJ#w9xavSE$VEk7JW6gy1iRN)wn)b2g==x3%;M~N7&sVPdjvcR$s*J;gdxvR`1b?8e)S z-D))@xeUx`Qwr>oiQyhgh{$v3g(>E-Uzw7g9k)J2lc1%-|e zQhDE`(%c`3O3NG^jg+8Q7GzgL$5Q~ELI&fQ0V^@pL`hf;NTaIcB5A2{p{kQqqi<{T z+idyYq(bda>IH8- z(kYJwLVim_rXKorpb2fWvwOlruY9vR#)_0s@+ibAPk0rGwvL^hX zOm5>}yQQRVW9Y7PG+ui4sHexvPd`@8tA~x?3t9jo@g#3*Ny-55BWJOU;SJ zk7k(pbL|%?bt-(H7&JtGl?FkoSc#!tkoll5?27jHXYRf7@aaykdQ@t)ug={kmM+RP z-@_AGVX9-k445{Z6Cg2gbdVA*;-bB*zL?NYIX91a2ZVXciEa4Gc!e^DuR&HPYULHX zi$a}GpYH6R5e_)rrQ2LT04-46x()t4Cf*l;tHd7w$60;S_*=oA7E*#$ZKms0F|l*1 z?f9n^fAZmlz&HEIU%ihRU$*;4v`Jb6O8H~v)3$gn3xZu-Q;Yfj2Idva9AA+Ohp{J7 zvhvKQKXG8(eKaM5SL|Ez{6nX@C>Ap(Vl#NF)Xn|m%=N#hs8Ju_r+=sJXCdMo{{ZMb zdc?Ws6^8&wqC=;)ZzcZ#e5^mO@WC%;Q4OOc`u@|J{{Yn-N&P6J=6^6lyicyPm^pK2 zjXpG@QifAuH0c9Lr}nxKS5~F?dt*~}O#*J|N^^aXw=3>mTE6bKkP5k#%GD{ifPK)i=djUnBT1T-iJ=;(kYBc4y1%n^JWQ zYK1|LNgq;=x|rVnn`$loTj9c=X?9!MlbmM2-{zWJmvO}02p`lhDPJ^KQf}pu=*&MEPT} z+BGRweI(ow%5ymCs(U((EkO9(`HU^T8_RMmD0$~Alg>R9BnS|V9j6_1wYHvPw_&$z zaMU*pG_HL7jNo@x7aPU8K6Z*6E-D=>EKtIpCTz%q;mD2enQp)1jWuYntPMstJmTF* zJ}9kQtT{I|M1e@BF$QxXc`W#FM$x@pC9PBC>5Wtd*ytAA07Lin1=V=7aZ6}18 zhBZnFMX4djb}WEF5hh58RKaxh3hllhrD{~B$b31tngu)NARqOyb?7PK-MW*iCBOdw zqmH=n+g4-92YDu*0L?`O_l-c%Nw5?`Bl-KXwxs-*_~2h7-`+sCpDMIyZl5+J=)m5U zG3S>rs{4-ViltbL5g=$W#F*tTmh+L^VV3m|EjuOAHEsFf;4SgFgQQ;Kb9s_`H8%53 z7$WI1B(M^X-b=0`n=Onrz|1%_)_i+XJbMlyrnXFd%jik!iklLCdt*7OZEJo+n(QH{ z`C5wo6(`H7KN-_);zmS-oK-|E8)@7LM&6ox<2mA(9Uxp{32}QsNkf{&VxCc&W~eU3 z31lsbmm^Y=S;QY+o8wo0q#K)N(i341M#+^bhJ_2^w#vV%<0TFv&Pxni`GSqs zcF4JMz8rg$^EB5X!i+K-mhl?$m9$kt>G}|QZ`&8f)uw0*o19y$x3-%d<*@!vhc7?7 zSyPTt)u<;6OC2g^CaTyL+xwzRFMM*x6QxM?fCaM~o}xv1l_s1q<3Wp4M`bfm66STJ0G9?sN`5rNo)Dk?XL{|KSm)CCC3XY}q zYzzk%HiI*^R+{B*9F|#=QDU9~(N5M40qVZC%sXv=GGVl;1iN1cl)mf;%awl4qf@5W zA9ZHWR@sj1nNM?u$fihxe%4nDta_}t4)o`wIz?9G!c~{2R&qkrAl2r^s^}*WiN!T- zFV)M~x^TLDNn@Pa32?(#IIiYjuhn?K#9+{DIxIYIy=f8KaPO~CC&sB|)V;9PaisOU z4FvO%^L9azPT^BympNl99QUdO+ahi@YC=Lxnm&(LQ|?K%Q5+;t!4e+t`Sw08JzlvDw#LhGenE8I|#W9CMdp*jONPZ z&oEHN`fbz9x-aizI@HjhsfK9gG*&3{7_Eg#v4tE_!hEzvX$aB80W#HXT8Bw5%&mi` zQU3t;?Hcs?#fg+M&Jk;MPq!)nu5(o4MP6I6n^dz!ru+1^H(UJh)T~d6*UX@o1)&Br>l&NIXi7i`f z90XNx+f7EgQr=~`C*+sEYzU?TgM0h;=^htK<^U|Gmzm>4I;k>Iq&E;FLnhN>2K8yu zskoYI-{*V>_XQV8+CbJ8jc(E3dYI?+#-+H@wIBf7K_VNdyQ}jR+TV8&3#&27-|;M_ zCm5M}3vya!W4>~*xyx39_r1&ew!{Gg4pN9&8gw}kp_NMt^{m^`YM z#gH`WCM|)q@hV(avXwX`a~g1UD}vINlpXw*OD^9I6;*(++Cne^l^+zil*4cinG&fe z;x^WUkPY1`2dix)T7BP}NeVAeYc9Zr>3buy1tH&5{YUBi{f0Wj32B-$Hf)tuuRAhh z+Re+C)BS&sb;o!MVmVgQ;^61AjO@_>b8irtb~Pyjp4BnOJUKiTzPSgtDZ6$JjFWZH zK5sYL9j{gO(%=Qk{-!q4zE?QE(sd|ssJdFYusZ>gegl-!kf%jwF142OoOUU3S!Fa! zZG~hxTD0hj0*TU_YAw9Nwp~}p2ZF5pJu_4tPEDE4NWUS@-e+^l7av-XIyVFUAmDki z9Q=pQLz_dD4=Bt!vu0)FZcw^J@pXJA9Zixgt)}1OfG=DVQm=^L2d}K;RN`utDt}Kw zf$|@iQj1D*HcA>)`A$ua(5gOMq;Ia~e9I@7%&4fAO+$ULpj9<#>*OzgmOpQVO^-M> zUSFa3Vysdqlzww=mxX>~9Nh*>?-xq;RkE${D);ia0%y~6i3YWoCD&+h^1x4eGy`QS zE%RJJ6m_%!zzvGy18IhA!|*>5RVc%IE_c4nzEQ?$QOixx9t z$*PxLhnJ{9bnf2!?uwY-!}i@Csp%) zzWPA(8*X$xU0RcC<{HK=eNR{`1oDRFjIOp}j%(?1+<9r<5p7Oio%5k%Z!i z?=%I*()~zFtLgI{y)mYz58rrD`}gvm8nqXu+FNnFrDxVsrcvnB%%@k)l>TG0oscgt zhLf*#MdYtVyr?9osedjy^!Pf81L_J#D`(%FTGDJ^63)q)0i3y>PCi?qBx*~|>YW0p zBPF)nQ58)DzqCN=OX>Pwd|gVc-XpwVq;D(i@0T-I5v#BGx@5R<5#13W>WYn!T!Tq! zbGcY{O~+Obg{qWWQg8A4N>V|(?K7% z$zo5R&un^H98DfPcWi&ixg5N%KO%3XRFR*I{)lkzKIP6Sdppy!R$r6MjWNC2HTR4< zo_1XPV!M9@?5T*$Vo|q;2~;R1ZtHEwTVKJ1JuYGpGAmH)(FfeheMk4d%LAdt#$CiC z4a&lM*-w~&{ozb8HSSCkX^nWZ!umsA-t}hcjMX7h>d%C>ABRup3KN#qr0=8zTvro* z*TzmFqfD5)RGO47yzeQH=7Khf?z9PucNHN~F%(}m zJr`q97YtaIRke-=NjLcU=N@x?L8V1C0@uIN(=EK)kIx9;g{IxUAI~0vZTgH`bcHDt z8F`C8K%mo!`BfRO1bEHeEJjOY@9_P8SHi3DD@L1DsBEe(WzwUmf}qKt(q0;5x@Ql4 zpDDR|lsv(T8UgJ+QXgO1zQ0v2-`!7#9~|R&`kYl};_7ZrJipg3JkM!IhFUbm72BV` zc$ov*XNu0}zC9jFp-H}7qP(KxjqWpMj>LEM0Ne-r!}JbKbW8JwG5Tbw(qWlYJ(8be$|q`x9eeF)=7 zO4pBTPrFAGx#{V)>8v_6TSBKdk4nu!{{XaL8<($7Bj?sKj)bTUQQ_w{Eou7X%!5dG zD-?LNsg8tDlE5IFOczUJ$ZQ}QlSR9y$alxixPHqei}82W)6dWL@}0grwgolrcuaZz z-@E~va%CnRYsNqJg)zomX^53Lnq-`YlzTg?eG0m@dfji1lDJjw`F$srth&i+gpzrj z-g=~PqCQ>A6)5KW^C>f?voWT1h#MCJZ1?`~es;#1wL8jQEycegPUgbLXwx4hQ(?iA zPp2>`8c6dPdr}d!Y4@(1ez?csVkG|DFN8!|Ck&{Y~X04 zR5dDol*#-ERH^u~C7ndd(eif;0HZ)$ziE_6^99IIX$cYL-O?>M9vpd&Ie+gL(-`>5 z=A~U{^&5Rh^BT%;c}#HnIn1c$elgPEuZHK9HjhYF4c=@KR7Dob`hmhx6it*>dA*Tu zjeVoTiqzAy?~&qT=hXRqcAaj|RZf-Q@Li?Fb}dm(pw&$B>*l_GUp}+ZaXb|c(5K$f{a*K(R;vRs zWR5S$qShn5PpQN%qyz3Mn;01RfRnK&bp9CnM-9Z$<0%TXjnw=3&m&fo(sHaUM1xzO z_KskaQhFE-Fup~o>j9|OgAtKG4)4UfOC z&RAKWE(IgnT9yr@7id+Wak#!I%__^tI=LZq>-)kt^6LATq)}3ts+qUv9{#g~#&E`s zLZoBuJ;2GCV=d)&!Z0@uRH;57-;N8U&wC+h_-a{tnDnU0lwT3Op7R-TT&vkq zsSO;ND5MK*x#7$&)ypgQ`hIxo(CtcSfohA3MKv?eAkTSUgHpV6va^j|L;R9nbVj6s z0y*&N_`Q2!Re0neibBv5h$kY_z|A}?dZEGurGz-9>rmQiGmZ)$BvAD$OY=-~(};R? zHH*y)!<{4vj;OIY8M(ItIXo?g^^vmav66J5eecU2#;ctf_(cPJ7{JC|54F-v_~bq0tZZykBXv3j(x3% zn?H!}6vpP$r9Upx8^}^z8P2S)`@e+bh2*heT`Bm4yZ(4n@eW%2zR_fz;cv0&l?>$~ znM98IupOI??u-Nyz#>RVa#bZI`CADU9ehpofvVayn0~fQZX2iX*A{{S0z5n71h3$?V%S0#4#%lwNO^V zOq-c$uF=_@;hmC?3b<|?$lGowZz}qAZ~5af1qo5SS*UH98m18EN&7;Q$0?T@QI}6> zgn2=uq{LM$NQx*wJTyJ`g2P$3`A^hZ%vt;{rb&-6w_iih4*>h_Uqb3c`S0uU!nF5n z%5ifAPlio&njGZ(?-We2t-uad%p?jAN;rwwx=e1H+t&lEY(%?&ZVYHOg>XlU6ZFcoNYeqRt&KKIa$4~wZJ`%s=_OSB z(Gf9qiB-772XIXBmnAUHb*N01q^NRZ%x&fYId1Ag9<4n)YW_*`#CqCR&7a~GCj$43 z2~sMqY8Y}k3dKB}s65#YrRM6pc3+U{5?n;6#jJgO{NpuhHu%Y5N`^Vr`ivH#IXXml zbSbx^TKfM0cc~WNo-`5%>CWcfaivYMJ26p*48ew8L((MB3tps4ty6B^RJIh=*7!b9 zONr6B=J~8y5!_heYY6nVrD9DbZ{zx6mbq|44ZiZVYQg0sLD20!G^dGLafkF65NZ<= z)uiul!}{L@jx+{4f<8EeHj?5?koLI_${7d`5iXYWmnB!r^;G%&F?8y)oj~pOGS=kg zLY*OM8NMiLZP~G!CqYNEf&0Hbt%|8sy9L~V^MpuarhI-(Qf-pt#wHzTTz8mSgw1xc zkM62|cr#G|2G<+K{+U_vV>Q$A#{^1>{{Sg>xX$w)W^BPCqf$^O4aUOa*sAuw)3RT^lW$Jg_2Ut!vgY=3 z;LBCIlwKj{CWGwpK4msDKY+{{WHc{{Y2&x{ML*G*Yo*f zZh&pfeSJP1d5p(eL4usD#`iEB1bnQ!N>VvC`}J_zT~Kh``_d8 z!6U6zAOc3#``h1GA(h4?GdT3DqJ+`9{Bh?th5=#$znMQ({ZSJX#VMzBnYHuh%>F(e zaM4DaN=uA+zsA+srblx_Y_>YDwU*y6PoMl4>UMPjw5q4bEWWr`Xz`_AxdQ{ApYc40 z^=EFk5yt-jZ%FuQ@8;b7K-%4J4dx7&LvMqx8N`u zFUd(TTqhRXQ3M-SU5{R%`G2vHXPZi@%2`K;nCNS|+VMC&~z>)vDQFif}Vc0nuio z1^#nJy^m`vW%q!^R7pNWxP5vlUYk;>vG??dpU^%SX4*AhhP0Zs6bL98fr4^0d+!oh zC%=#T-6Vg!(~I%r=G~)7xO&biWQ-p$ZDKy3N!skX+JT@>Mn}J=p^nliu%4_8ha)m% z;oR=nuBS90YTxD>aH@4hgA>2s`4&GppS5^>EGiFAe^K&~8lyyKC^E{**`Ba$!$W9@ zN=SAdoA3JD4SJp69xVKAZokJl#dC|^ON|GY39km+c+iQGkJ&(%ZM*KjOggITr*J^` z?$GJju4FRE`EAEte5uhSmo0TQ%FqRW=c}bR!)d5oskyiB@sLtn;&)m=RWjVFB}$&e z+H|PghvCg=UFV5;fbZ$jKl8%q)~T-PgO6BBvYz2*vvo@&dvVRp8DlxsY56@PljBKd zQH!S~ZUWQk<#mwU^{(sEE9$H1_-@hu`i0ndhd9MI%+b`!#$br(wNOaa2!H+|zJ~!m z@{eNvSYo>k;hS=Y9-S~=XuttkbFpdY{{V{ySl(5qH&#rUC?L`myXn2LE=;LU`$h3C zlfqAAp{uyl6&kd;fgYa;_Xt7ax)Z9pH&758uhl~n`ys^m3Adbt%$ZvDwXNpP4A(O2 zxk{5uW>iDxOp7hzFmF)m0TWN{Je~eE!SMZvv}%f)$<6Iy@6IiU)@JwRxg(XUQ4@OC z^L4`1R!`xM*$~uErr{K?c(&=&p!yd;_6_l5^n#0|dgtdfU$S0CDf~vM=jwwZrxd== zf~1~TjD6v!?zX5u{!<<+`pb{gNjNHJEtBXDK4(7(-Rw#lsx@}ma6L}{07-oD{{VUNJ1Xi+47 zrkEm~99gB@Z>QnM*2$hc%WHw$CJgt*=c?7%+|0X7Am_E|G4%lfIo=QGXbGv9q))9uI?BC-pyw{sgM8r!(KQU3KWZABmG_ zh~L|}vPe^-pZ*&iDDi&pkQeAh^22yEQ^Y-bpQe^is2Cra1LEd4P^no?iNm-VQar&p zl=j+y-yl>CTn*6oP0Wi?>h;vP=2zmo+J(ur&HVm7e$zcpAwyU|)k+&Le_qOk8a-N? z(Hm1Va>7`tYFN&X#sr;<;4jx0>M}DFt8#~bBh`OAjN94$s@yGIY5IA@oc)q%d}sD_ z2{2gjIf@Rjh);AI4g#cV>qCB8nWjIN>3+!^B-6*e=~Dxo@s#E6v| zRL5dVj_^GeODojdsJ9g#*ZpsV@pKloGOjKT@%%kft&C6T23q1{TvqmfrBI_~s*CxB z<7P|kvc3_TG}hMq!jMVs^=?2SgnAqb;M;uvT<4a*ND`;%Y|?RnVZ9eB!j zrne)0gVg>9l!r&mOjfdkZ9dD9B}bC%BWgmET3r)S(%}6Z6(3anG0N=<9o{HsI>iA=Cc=(zuG)vv0~BDw>zYKQ}I%&pge) zex$9o<1TJv-`DBe1}Z9G#+C?k&P=4c2;bJ*ogsZqk#$?TZS%z?PaXL}N}elB1p}0j zBsdPb$v74TQ{PpsrAcw_YB9JIHQ}fg#?L#EOpqomnxk#Fq&u&474%;A`r|86A#4O& zGhYy(n=|8~xa_)>HRH1mHjNnthQp)pBK-T`3seljUjXxj32P~l;-k}Oej(_r zoC7m$;uX0vqA0x07xMM#QB=B)DZsS02G=vQlqqsEGp(~E;shw5thT`s=xuG-lchyS zMMqZnqHH`_CwV|~=NqZfDWg}7Ekrbnk`hCJ$~J5&$4<3G{iTdWO%mRVg%(gX6OVtq zdKGQwnvG4DcuLa|p+{LxsW9=d*$O)1md=KsCzkvA`eOCk-DOn5+S!BaRkCH6Fy)BJ zm`pbvtw*HY0@7;RcS|0X9lLIp*>C`}xl^#|wY=tca!rhinUJP&8Ro;pG}yQfH6UZ^ z=|m)6XXd@q+bz8}!MG%TB-P@FW3egRrsSrHibpvRRksenl94p%)3)lX-7V(8=+$z& zLp~e>yd@FwsZ?gQ9#gE#hD=3QThn)U8m*dAoNDWDyYRXQq|WE2n+BeRf<*ucoc->~Ac& z)pI#Y%+qPGwZ9Q#$88MXK4Kz|WfIb#m&?}ps+DRW+Z*HI${&7EXKD6}m>^4|HC19$ zs@ueEx)16RD|G78zDwKkTuN06wtge?@t04C3^O^t{CGLu2u(Ur~}0sRBgl6XUh+^*9f?7dx*`jcYU_p$G|4iIp(7Kr7)so&p7 z)LyVZ2=W8GOZKIUMsQyHF`w&I2OINp5UrqB@3=%DpS-K^<1cLXkM=w{sJUZ>9%uHQ z9uJ4_>ILP`(rvoL`cyodBAcctQlhb>{ci$c`Q(hOqa{IA7 z+i<>%x$4{PHF3S6-P6{%z4Q)>Fk98O9R=qin+2yBl1&7oi(+t}?u`Ns-e?BNeJ9m# zFPpNhm~BwCMHwHcd36J)QOM_M=Su>0PRz}Y%+Ze+(Wh9Hth(Bky=J4Y^ji)wvfK2H zzPS8A3>4xVW#juCL1Z=}BCVKf(55{)bp3GpPoWC7+Z^sNMZCw;=QX2-7BVGC$&FGN zeC4?$i9<%Q(aUpEd67F3_P^!x#H&W7HVhw7JAF6vvZ}N#+Dm+V%e$4S-s==XfDc2;*8AQMoexvF>))Er^KbAFc+&6kc zord}4(t021&dF}m;?jW1jIr|me%G18nND+vzS7TcZ#QLxGS8Xq4@O|Ac)NrHo@Z9<0Ury9kCR&R1Fxm)kq>ClYV(H3J zK?H95iX!ywWkgiRjHARAW=z{QBz#T1XTlJYZ_n=yRvTG)R!o+;fNZG}GU8ZO)NF36 z^AC8JUfyI|_Fjt8(!#aMft+t}IeF*dx#cy{s%fx1xsIcl`2PShlH*25jhZ+|BAZX9 zxD`q~XDYOwSnC2|5PVb-KI*Gtd7<^ux0zEOkA&j`72?JNVaG$sz8_=dHw98OgK@f_ zE}p!-M9Ef1Vk=~5X{O&rMfJz06DgO6vp#Q>FV=W+a*=~|e%zy7Hc4#TTX)+^7M96v z=p>%2k1_pC!mgF#fBH|M+w1s+PN}0+Dvn3#&TOdl7N_LK=S0-3$Y3QhH?rANQYYtP zQOAH+DXN=h-;ZQZS;f%);)w%u?0rCh*r>*-1cQtdIcDex5v_m@-GLBxEAG9~Zn)D- ztz-ZKJ$X+8POO0mM5!y4m*dNd!90Sl5d(=}CA!&nTNS%@+w;NEs!2MOUdK20nANHj z__v{P1-uJ;7mMMZSN;hQ4h+Qm*wf zYM1C;ipGkHx-seh0HO&}EOSRS3#Zd@EmfY5MB_AiM`WpNZz3F_Ts8lSzE&b-)uN^6V(p(~_!;emdpIwL# zmn52LsSLQ;TH4$l7i@nQZPOXQwy&^L8r2ap#1C2GwZ!@i+?Oxx`4TJc#JiEIq>n{u zlJq2XP!IkU(qBFCX~6LZ1y9@S6njU5T(xEN1T!BXqU8LhbK`nfGu0KQt2H<3m6}^9 z5u`b%uR?pqhfR=_mg+{ksfeOBmqxy;edMJ*`8H@cOszn&|cE>qFSHmTvDiL?P*=_Ts= z;#xpw^gDqWT{54sT?U%qAV?_wE=T_WzI)yu@I^uX?mji!ykGYmeOiNHY&`}&`pXNz*D2k0T`BOQ{JCk5nsAgVcK06j39^j(4U~KHo~FBh z>HHRjHfHDN%=|v_D7~(-bzUL0QOh;zPO?iQ1k|uW(`6qpE|T?2Z}rD{{{W`=s%@%; zKo7)z^T#zK%2ZrIsc?>?o?WcuIWJRX858kJ6D1SFx{GuNm_D8U7g!|I@itxY-|XYY zcY1iBE;)mH{>Q9hYPFhOTnOWX8H*~GPt1;TY9p-l2Wd;APO(nNyLAe7^CsG@gSPu9 z)?V_K;`r%LLQ!>?R47RNskf2ITgh-%#cT@A}74P zgjIn|@w_=^Q68s8G;UjC*p)|n{{S3&E+dO-4Mvz3)nI;~yjGjs`bK(cMsq2gYYSq} zFcJ35fWTD@4#bPM=id0E!%=$G8OGX2zyM-X?ThBR zmB*6mL`qt&r`>n@?S*!q4@RvsUGj0U-!}C3i7HiMwlbKaR8u^AbY`9-)!ZlPR5f!i zQY z&RICnkrmrtH~Q_5I+W_($hSXPl}Ww?i&4y3c86Pn?q{wUR5fzrL57PaT$cV35N`a% z?wtr-_qH{!1ocpt&AJc(^<&{5Q{@_z^&6A#?GxeDYqY*P%db?Zvgy!g8%<7&G4Lr} zYNFHT%V?s~C4?=kiG6h8d}>hQsdscp)PUH4ZH>jrxjgS+I!{ymJ=#K@U+tS_+uznx z9?=vWvn!2-o2Yd_d`n9eqJqgt0F~LVcs}o#Vv33?U)k#TvFU%MYjG6l4j+jcd8P13 z=Z)++8(T5GwN8^&H7J|)w!r%Bb18MHxgH^Xl+S}-{Cn$=ss8})J`czce_VRqJ!cMF ze$Ko{Jdf=!3}(DhsP&Zy(mAQ50qs_4{{Yan0WaM$`D4ic08sEPR*|VsFHa+_wpw2sYGev;~qP{+%N^t08yns@ZD%#c}58sIHe&W52-v z05gT#Tq&hnTAUxa{l%b|xx6X7G61Nw^h44Hk22WxGU|Qh^uK$2@hVaz1zpASIQL}( ztmN)vlJo7!ZY%Ca6ef+aTdI;;$Unor5-Ap65zHp82+W3c)Sy&k%XUQBKA>nH%q9hUsrGOMNRST$TZsLA~aka$U@sJ zMJYs19;HH7oNCLh6>s!izPKX9oibd)RLYd4<~)RqXa!Xv1seibk#4DN)O-Cq;Z-S& zN@*Y_lbM+t8Ba9wf=E)j4))chJv_ZOR8(7E3nNPHjiAY~rV*Ef7_20jtST$ariU~d zBBI$W9-fGox2_iGe^u~3`pP%ja0VqnZHY-TV-PCLOcMmgev@7`g$1WH&21fd z=}w?Hge0h@E)T?-ZMq^7F8E_B(``-4LT#Rq%2#SxM=nUHO9+wy-7OrM0d-bYEMi6q zqF1+`*Gu-o=~7y)Wfng6flo^{z>_M~s0_xX%8OBXrsP6xhTnLVqc&8PMY13*%zUf9 z_C@Sg!V1(3Lap9& z5JFellL1{)8tQ;lbCtdW=f{WW;43EVBv$N zD2i@q)1*~4`TX&Ks188E7xawpLmek+4C2%dVMa~p%QJSSG}>7 zlp)jB8i24>IhjJ(L}*Exe3Fn&JWMD!;Go?BJvEBz9{&KA1g=fshAeG)4RXy^UUjX~ z&TCD}s!Q<%=4Nl$xh+DJ225_OOWR= z#^p8|8Ri0=gIS>Oq=-{kk7Y~u!B8OYx%cc!Ww5x1^4yAC&t$43_6A&OZk+ak=Ug8V zsjKJ%)!j(O$e#l3f~`dW7O*+~At(xiu4F1jVc8kv-dLd5zGQW_(lnA;aZ_O=+UR27 zmA+p*VRX{rxgK8nz(aPq=MPh5!j(lAVH5AmbqJ4`LasNVwQ)p}_Sq1Jd-g@X`!T8b zE}Q<|`N{-tyTDT`e`?D=v)XXUu_IP&p8cIVxqzd!_quKA>*y|_u1@i6{nVI>o0{UCd0qIi@^oXd@}t60%NPo@Y!u;_`Ce@z*JdY+jP8v$ia$S zU9UAu_G+jj6&DfuiHt!410hs!dd}VL%MwkO&o)y+#&YfanGX(s66WK(9iG zZp&oak#@#&qIUs|N}5aJTW$TzZ+sDEL#a)Vzx8O1L@)vnd6(L+NUl;^g{|gWS&D ze&zLc`CABbZgH@@jK=uo7{aD8GiU^V7BR>HmYZ<(k1#&r7sj7n>9z@Yf{o$*2G;5g zw*>S1j6xMosXgf~R9zI2J>zi?mM$P&5w~nQ2|n(mAKllD%4#(-j&G4~Fn<>#()rlN zmLwfrXO|cl?3`n0{4zD9PLputs%nw22B)MUjC8p|>?12J&hZ{LitbFnzHB|#m%HE19H~I4HyWbry%BU8h zqTi*iE%y0~iMxbj-I`~0$n@vnvBI@9`;r~>i4`YHf`GmRH9=JKzU+Qms^#BV{r9q|U7M%=O|D*ANYET}u)%eB_{@7L@e z5~78+ljVH+{`9m{6&?KsyqpQ?M%%~Kp|0Od`C6XH0&VQYH*6^ zn+U4i69>ca6}Wc+65nr$ooak{1yYF=$RnWM{)eBgJnbkr(=we$F3YFMahiOm8g-{2 zRN59~marsjNu{|uq?Sao=_ORPl@wFIvDBZYdGoE8O+a9FNTD7Q9i+5#{9mH&CV37G+m2voK#b6x=gX z1^t?`;avz9Nf3JB=}^DwGds{xO~n-o#Bu<76#CT))Eq&%X%LQCs})Top|?+wZ6^*)}&8cANYMoJ5(NUe@x{9d@ytO&530Av+rK+}A2v}qiVm(2KedZsK9w1yDN z)WxmwvW-O^uNgUr>u-@bD8I`1M;BYUp!H86Psm2lPV%CsQYZA@oPymIhJb7YXbEpb zy^|jXsKk=o=g`3AKc0E2u_H8lUuK-b>0icF2n?XdixjAw0e9p@3CY`FZHQ6^c*v!MdhxPeY-)nD0FAW4UR?})nC z{-yje>C4n#)U%IqIVTTmQh-vH{SvOLxQ#Zg71RF!gP1OV>BRowdCIil?o!S9Zg^B( zqgN?!Mbh&!d>f&q!7h?RwTI__`QW?6Y)NTyWh~6O!!w0ga|LfK=W0vsNT@-8Mlq_5 zv|_F}Oo3`c(mi4bSNnywGCd_ySO9O%&@2YxLCl<2<5vv$sVXbA2-B#n&v+^FXF+B| zCLrSJPH3Vov_Ty}N`^lWrV{)Q55zJ%ex=Cw(g~ucGV;k;?>3+NIO}=GG*hX}Rihd5 zV6=)i{gHw?B&VRsUh=PDAln%#@XF0mRQ|t@D{b)D#Wf%fks#&{B1@`&vKmf)j}6EY z>JZG^Ys7O^l6Gh_eqy3u)o=B{P~fzn;p(=l9Fxw*{{X}hPsgOmSyE0s# zYNI7%i@_F@-#F$xX{^jN+@2LuR80w^N+-Nba5#l-GPBog*!8l2F=E7gzy#hUyi7^{ zK5&%!hH|XSe-H{h;N1;}* zPA0ug3$>eX{*@d2G3OMzj$Gs3!g%{GvzeTjd7m&gZ4-b}Y4rC(Z5sw( z0@TZbgSE9F75!5jdX?XR?FHhAxwvcZaCgt8=hW#cal8(c76fC+@|a~?b(x05fL5Js zv>R*i7iCZJ$JdpEE!Sf_8v+fCw>VgIivIw!_F&36iGY-moC!4EpL-mhT?e5315k#c zR8i`_JlAb&;j5<;OPI0qwnxU-nX1>RL4(uhf;kytWeWXa{t`Wqb30GhAXA=MG>L9W z5|ISb;!Q5C&7%?|MeZc2vZt4e#M7qEE1}X`ame$(k?YIztBCC+;y7OJrWj;?*Zuyu zhiQ{&?|VNZxr&)9odq;F`NV-W7g;vXq@0SRM;O#jjusO*RW%KCpro)`$ zQH{Q@4;c?jiTlgb`RT9n za$a#_G1COernwF}=SnLjWbBLcM76Kq)7LhD5VijR*p{Jmp0mRd7;`V0&y>q-M(#kUSKDH;`t;h@#S(Q{Mect4z%83X<0>q?vSkt0xyhs4$m$?9R8u;V7tK!Eu-|fm#Wxc1D>eA^s zYGim*fZ-vs^Gz_q9fZ(;^eNlo5xNpsyDj@->C#heLpk^IkO6BE9e&cHOyTVzfTq%^ zG7-RXG|-IG$l0P<9ngSCo>dhDMAE31QQH_rxQZ-VZ+qCD@ zJQTK^be#!pT=_%}*z~F@>D^F;2{v3#F0i<8b7Suqjti+xr1c zXk?6@Hc1dfZMvYMeEh5VCK{-8-MyJeNE)NuD)f4v18Eh5amjD^XzEHYa>;ZamA~IB zS$D*Hi>0QeI+pW=LafBz5-U;y6Rbylc?!^oJSiQ-Qw1L>-%jJFd-ld=Hn1RmVwr}U z7zOF$Ov@4JEmi*46>!P7G$U$$XIMYpwSc~N-+Vf&-L-OvsMaJ-RC@9h2BEwytfEHb z#&PA;+k~Qs>qMU=GA^%~VFg;{j=;s5n6zXjBy?{bzgAzd3=_SBt}l|66uQt-eHRPlaYEd_wThE0Vc zbUHXRa-9-!InE2Kt5PACEmW0yg%@r9m=;1V4#v=~b0fvf@#RO6Q;*G!ErCKL)zo_J z-8<nNL>jpWI-=b6Zk%W;Uq3TbJO)5fGAprN(A)?LTwnsCs<#0`(& z!wzh3D84!74-rbCQLaw-X5W0gMwMOkgJd_{xu-pTl0wtc=#|ia>X;B-gWlEzTRRcVTwsImGS|bNauY!;8?Q~KxUVrK z_FmBc07)?7HiG1LNqtYwDoLP+)Kpak^@0RifZ*f!KJqgdNYYQgNLEa^zAlh2J1QBh zWp|XT(aZ~y{dFLb+t9S8FjiG4H0Hwp0I?pB7^$>mqs?dRrPI%Osam6tDO8t6=x!~( zT9H5f9CW)WO3?zP{93KO^MZW<`ktaOUf>Py^OZh&;>_!MX6-YsNOV1c5OT8 zFR$`XpQm4j;WPn!kUiRchx%LkSax!bBaO{VZP4_$mp)|l8^_@$R7leq&UKgLB}$_m zP6SsROR*Hz$l{Ifsn3_7Tkm0gqfqEH(SY?M-Zu5Q^}a2 zUG0?`H1`Ws2OfC=)kTiBQdLAp3j6k3ApA(TU6n6|#R>!b?g=8}1pIwGx%y8ELaSMb zycL>j^hkYGs@*o3qoiM%HZx?~sH;<>xMX`L}~>?4C7HZ8Ml?~ z<|fV%sHy?bI^sfaehxnzx4hK+F;SonZrc zXEWyMb7DkzW;GT(D5IgIXvH2a0$?N>P|!(A%Bri6oc7-VK=B2hs?z|GY_Z<^3+Fi( z7M_E#YdX?ubkg=dKxe5jQ$A-Y^qReLn`pF(yxH)oQ|WQu@dDs@O(Nkv%MEv30-%Xx zR#dLH+tBt68ZS*M(z#UyK|B7e^&+&-J=~ zUC&iYOc-X&aHavTFP!Nhx64!1tf3(x^jk_TleQUBr*>_>?Y-eq6!?@CSu9TDY>W_X zy@(?)r7D?Bb0RM-jH}CGk|Gh%vl?NtAn_*JHZCZtffB23tAd-ZrMh6(gm+D9Z{^S5 ztj%AxX;9(^4^%STfEbSnJpuB)y<+}#gHam%7FczbQR!(BB$kqp#Dle)a#ALz8c|(s zxv?rPl2uz_G=Ot%zbVnHR8pqZ8)XFiyrEjJ4f5?XfDcPbbPA*;8_Jm_^9k~A-PRiv zQB6I>4*HYx!-r__i%?P1aj|dP%5z6!_T6e{jWzqW-Dz6l-}Q6U^XcWVRY#i49?oyW zku)XDkI$y8q$~3uU^T{i{{S*=bpHShDc3{Td-uHQ(y6Uhp#^RMvD{yg^BYYklK6qc z+@b74LVz_WjJh<2jUcOnCPqx6==AuO*y8bZ4O+&-%jJpO;CMFS_+VR|*!q%B>?R|q z>;dCEiaXT%y9Cntf)E85U%r^$aK@swGKBr4c zg%|BN+A!3tfHq{wf8m#2yQb;o^u8IbxyV>^hw=tlItR7>UaePP&xcKmAssmnvU)F^ zxY(~i=^K%1(l$(dt$P=YH3Bsz7bBJc>v`;3kKyzdR|g$u^Qx8(MyCssK$<09rFAs# z>-_QdVn-?AT^WB+wAKE}@fvF{W{T6AT-PEbJwmsz0Go!N`iCDp{F4)#`c)L1s8va=paLre>X6%kMotTk{F8wPdj4nvF`{@;;wbPWbk`BRvX9MNrv5 z9J+eXH(H^oQJnK83#H{+EqQ}-l>Izs^EqtNV^q}SNcoT^gWJEarZyUcL|lVtHhxEx zp9T zw<@mll8ePU?=nieA8~V0xzy(?)mP_j(J{WQS>7h4^@~rOM>+*7{huCOqm?;b>dC@wPlfW7Sms+u$Z$N;b*&%0tVUD>c#cgy>R+ zE?1>Cf*L`-aU0@$I1LW=FkdsIB)^Le;;DiKP9WWnsW$ZGW9TBS40GJ0C+m!Y2jCv4$w*1a761S#ijx3=GjM(i;EQ)`h7A$uR{?d3 zmn@fBFUtP_o;*!Dq=1dI=KyCoFkscGk|MqhqmB_U?0!{&hj-PbJj#TfUa98Z%ZXGn zm1=v!RMmxn5YmS&u2hK4%vIOPj2ZyN0TZZq^CkY6HYTF#v>hOe&lP{OWK+ecvehCu z9P$@eL2J=t2FraWD}DWODR^2!G?|x{Yc0zM;mPMM&|PgoMFz`ZR8{$>(&=n_^Gw>! zI;@t3757@9nKTZsJg!11WVdw{`LFn6HjrC9qWR7Yzt5;gY($xi;H!5ALB8@4KCGE^`hb|pQZ`WvswS_h=J4OU+>gYB5wz_{nN3Q4HuWXfb-EI+rB%0U_e*0d zgwPc4YkXjV4a#j8VvOxBsN=Juw&9B=CX32a)F9cV>_S9Ht7|Bo*JVp3SQTL79dQh< zk#J||@+p!seD~$Tl^(t>f;1$p@(rc3k6%)i$TqUsHr-bML0c{EzWHM|F;)OxdCIwk zw`i-XJA~wyv^wOr+Xl`1XkB7DL}gSSqe{{U%r9HBhDnIT54 zBzem+V-d>F!<62W(5cj|T~vipckk+>^2S=U8-Bdy=o>U{nL~pvim%CXBlWosFpWC+ z^4@(k3TSn7plc+(ir(;aqM|P8l+`E# zD;D-!kfxg|>{h>Y#%2w!!)*QGR9=0D`fN)3{I`#5I`EUc(@fw6e-HG7;;2M zInop%ni!FDM375zO?C~%ex2~qNH*9w9{ixPfP650LZH)}YKdEmOqlFP`GjW_!tFR0 zLc3kG*wf0Xu_tB0B{FHUk_YYU>mvS`WsJ=cz8A%kPn<{zQzZ9dLaj5+3yAO85Z7^4 z-G59iXt1b8=HH0G#4$ZYBy#0T;u?c9nIb>&sHzskJErQ|qADley_Xo;f~dJ0 zMU^bNx=$d@YE3o;CNqo^v1hdwUoZ-xQsLlMb_Jz%iDAnIIM zW1E&Nn6emkhg^#?DRiGH34Q2m*=$5B_^vjx;Ft?o(d=69isg z!i%eNMBBdBRI$`;CgVS!Vn*LEJKQ#zSgj<;?-b*4;SETLs!+6ZP~G0$F1BN>6@2KM zE+0pT2)Y2s&&U0JqftRi4a9lNT*tDv*(gy7$VOu0Zj$MAZl>3t$V!TrR8>t$jIJ(2 z4WKIDX(KT)6}qe$QR(q1a$JwfbDpcplt{WAMYaAC`e{<_fKic*OCu|bLb+w#PP;{# z1vZf)6Xr4iRmEvqve<}z@*;=+_Qg{yH3QO0cOdA2Hr)vqz0-fs9^0`fihL*l-sGI`%l4c2RkBW88;&&}Z+xD?qFE|UI=Z`iySe`W z(TnZ9LxHLnax6Vb1M@n(6}#mpVV{;}wSF6Wu{WyU2k%i!dDmg&yexjIyJA@y5ywU)|! z4-LVnWlCfQ++O47ojpcPqtL14@9{f74=RRb3jCN2&v0WnEJ}|fn#nYw*U}<`ucycz zw%ri1qL&B5twBrzb?uNwIqkUUFDpvk-Czk(GroD@WVo4H0G~i$zlRnD7+yGkYDsxZ zLug%KC+0HLq$FYqx}VD(u!5S3RPa6j0J-eHrk}I;2mbesB$fRt1~;d&u6NC` zD9`9)a{ZzTk1^L@r&Hf2CloX>ZbWvEON0WWse3A268d#7VY&f2RmeMY8~i-_4zu6( z?`_hf*^9>5rCNi+w*=gc&;B5T@d8~Hdh_%O+pN{|ObSD4Jh;uVO=j>BPTI*y=Kzfb zM#H55Q*za(N^+NmrF+w+?A;B>9#&8@&z^V8_>mwS0#DEF66KypcRZ{0Z1p!bQWyVy9LR8;enj_7o&K!hozWCR`p|BuD7#wr+aAk-;@PUwQ)?6_1EF8s z&b3NF3WuXx?=zaP(=i3{04Ei0q*qn%>b>#az40>5rR?t}JO2Re@1QQdZ%2gecTrce z47c=u^IP=C%fG5k_~#bbkE)5^{+)5Es&mKYFy@T0morxm=F#hMS^=qOL6p%8PXo=a zfjw*YM3hqdScwqh>lJ*kjERn+?H2F}1)5i=~GL2FNHwVyxdEn!0^X0rncZgLP5gUq3Hi;d!OiEmZb#B6YvlLw;sS?)NZ)8hh zqL46{Y03BRtoIX%nf9@n#x$JoJ*M|gV#_Am3nKg=srPXghNKOw2f|9u$c2;^Bb19u zuhmYl^ruEK-26+V_JHd|+=%*h7W#YLR}iSSAvgf~$2un#t27*#0su-;>^0d`n0N%y2vn6rg_~#MfiRc>RTo> zQlt@WYf0-BA<3vmswCJ7@Hj=F2pZR^e(z;V{V>CAjEBx0Z#d_emDOY_lH$ohS2<+M zY?ZsN$_aqdmV=~CO~F5Fe5;i`ktx}CI@PlR)g#K1>&~$coGuBwtQS%edM|ILF;$@Y z&Yhuh#4!)r_ky5NJVss3ZVX~oX&;Kq!WShqTXTI>m-%61gLT+WrEb^aYX%Pg0IPg- z79SxF(EXwPo(hIiBhhmtW|}5Y&DtA|w4AXmD15c~IJdukpO!M#;c1c3 zr^VC+i)U5rEta*;2KW}~n{NS1u6q+^sZj;#R9NL7-Twewr^$)T3w%YPI=yfFaipbX zvAKyHY8`s0p})f3fLk8Ko0m9i?84S~i(JTDOr=rk@pP1V(K8n;#m^~ww@FgOi`(x~&+TZ!6`9YR=rWkWf8+1+o;j30b)r zlrxdMffL!&B-1kx)F~NO0}_c)(4bc@)SZt>x~Z$Fcekqi@I=&MYu*;OfF}DXWG}W| ztkg1YU@=`zJf~DA8(+j)Znph!UG-HKm)<`}#gq6ulxlv?RZbOC$VmYU$-svANWc_iDzZIdwo^a`*bErUkUE#GqDgOYo`0_00W-Lf)3?scEJWHyVnkbnnO*7iool#uJB1@FHOgOZd3<=JN z*&gWQU|go!(!09Z80jP}JyyfG*IJx2qYMy!-+6UF&_vPMdpa>y%}T^5Cla1WaYk60 za}?6zB2M=dRnybax6d9Zw{!-9ru_N*{{U-FVv~5iSFA}|do=lnF@~xU&8FXR(Y!eg z^?_=))a|R)JuiVvuq+M0wZ~t4;Ay^0U|5jKV+~5HLz+^9#73$<*v61RT6FW<^I3GF zYwzXhTrKR&)9rCJ>D6Q$=gh55ZjYRyK?y8LR@yK}m_pECs%n}^d)vyth<_|(?NVBn zzd7sw0HqC{s(OBAc=nr!EcbWrs#k4ragc3WkTEu2a_MLKbc?DNvDbj zs*lK(?nr≻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 b0IFhxP{l}7d?na`ZB#Fx)1IM4P{04#vHJW< literal 0 HcmV?d00001 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/image3.jpg b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/image3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d788e3dc68d684ca6e282bdff66a32abc767214a GIT binary patch literal 108846 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

bVYQDkI>c&u#V3`=V0S4T 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 literal 0 HcmV?d00001 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/image_info.txt b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/image_info.txt new file mode 100644 index 0000000..583d113 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/image_info.txt @@ -0,0 +1,13 @@ +Image provenance: + +image1.jpg: Philippe Put, + https://www.flickr.com/photos/34547181@N00/14499172124 + +image2.jpg: Peretz Partensky + https://www.flickr.com/photos/ifl/3926001309 + +image3.jpg: Peter Harrison + https://www.flickr.com/photos/devcentre/392585679 + + +vis[1-3].png: Showing original image together with DeepLab segmentation map. diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/vis1.png b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/img/vis1.png new file mode 100644 index 0000000000000000000000000000000000000000..41b8ecd89590dcf6b635e32c3af4d4b18fbafede GIT binary patch literal 421699 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%0Aq0k&rPWJr-u8l7@h2fS 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 z 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 #}j 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 z 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 wJkXYT(_E>lQ(?*7=|J9iT)I>-; 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

Txojd(tL! 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 Depth-Multiplier = 0.5 | MS-COCO
VOC 2012 train_aug set| N/A | N/A +mobilenetv2_dm05_coco_voc_trainval | MobileNet-v2
Depth-Multiplier = 0.5 | MS-COCO
VOC 2012 train_aug + trainval sets | N/A | N/A +mobilenetv2_coco_voc_trainaug | MobileNet-v2 | MS-COCO
VOC 2012 train_aug set| N/A | N/A +mobilenetv2_coco_voc_trainval | MobileNet-v2 | MS-COCO
VOC 2012 train_aug + trainval sets | N/A | N/A +xception65_coco_voc_trainaug | Xception_65 | MS-COCO
VOC 2012 train_aug set| [6,12,18] for OS=16
[12,24,36] for OS=8 | OS = 4 +xception65_coco_voc_trainval | Xception_65 | MS-COCO
VOC 2012 train_aug + trainval sets | [6,12,18] for OS=16
[12,24,36] for OS=8 | OS = 4 + +In the table, **OS** denotes output stride. + +Checkpoint name | Eval OS | Eval scales | Left-right Flip | Multiply-Adds | Runtime (sec) | PASCAL mIOU | File Size +------------------------------------------------------------------------------------------------------------------------ | :-------: | :------------------------: | :-------------: | :------------------: | :------------: | :----------------------------: | :-------: +[mobilenetv2_dm05_coco_voc_trainaug](http://download.tensorflow.org/models/deeplabv3_mnv2_dm05_pascal_trainaug_2018_10_01.tar.gz) | 16 | [1.0] | No | 0.88B | - | 70.19% (val) | 7.6MB +[mobilenetv2_dm05_coco_voc_trainval](http://download.tensorflow.org/models/deeplabv3_mnv2_dm05_pascal_trainval_2018_10_01.tar.gz) | 8 | [1.0] | No | 2.84B | - | 71.83% (test) | 7.6MB +[mobilenetv2_coco_voc_trainaug](http://download.tensorflow.org/models/deeplabv3_mnv2_pascal_train_aug_2018_01_29.tar.gz) | 16
8 | [1.0]
[0.5:0.25:1.75] | No
Yes | 2.75B
152.59B | 0.1
26.9 | 75.32% (val)
77.33 (val) | 23MB +[mobilenetv2_coco_voc_trainval](http://download.tensorflow.org/models/deeplabv3_mnv2_pascal_trainval_2018_01_29.tar.gz) | 8 | [0.5:0.25:1.75] | Yes | 152.59B | 26.9 | 80.25% (**test**) | 23MB +[xception65_coco_voc_trainaug](http://download.tensorflow.org/models/deeplabv3_pascal_train_aug_2018_01_04.tar.gz) | 16
8 | [1.0]
[0.5:0.25:1.75] | No
Yes | 54.17B
3055.35B | 0.7
223.2 | 82.20% (val)
83.58% (val) | 439MB +[xception65_coco_voc_trainval](http://download.tensorflow.org/models/deeplabv3_pascal_trainval_2018_01_04.tar.gz) | 8 | [0.5:0.25:1.75] | Yes | 3055.35B | 223.2 | 87.80% (**test**) | 439MB + +In the table, we report both computation complexity (in terms of Multiply-Adds +and CPU Runtime) and segmentation performance (in terms of mIOU) on the PASCAL +VOC val or test set. The reported runtime is calculated by tfprof on a +workstation with CPU E5-1650 v3 @ 3.50GHz and 32GB memory. Note that applying +multi-scale inputs and left-right flips increases the segmentation performance +but also significantly increases the computation and thus may not be suitable +for real-time applications. + +## DeepLab models trained on Cityscapes + +### Model details + +We provide several checkpoints that have been pretrained on Cityscapes +train_fine set. Note *MobileNet-v2* based model has been pretrained on MS-COCO +dataset and does not employ ASPP and decoder modules for fast computation. + +Checkpoint name | Network backbone | Pretrained dataset | ASPP | Decoder +------------------------------------- | :--------------: | :-------------------------------------: | :----------------------------------------------: | :-----: +mobilenetv2_coco_cityscapes_trainfine | MobileNet-v2 | MS-COCO
Cityscapes train_fine set | N/A | N/A +xception65_cityscapes_trainfine | Xception_65 | ImageNet
Cityscapes train_fine set | [6, 12, 18] for OS=16
[12, 24, 36] for OS=8 | OS = 4 +xception71_dpc_cityscapes_trainfine | Xception_71 | ImageNet
MS-COCO
Cityscapes train_fine set | Dense Prediction Cell | OS = 4 +xception71_dpc_cityscapes_trainval | Xception_71 | ImageNet
MS-COCO
Cityscapes trainval_fine and coarse set | Dense Prediction Cell | OS = 4 + +In the table, **OS** denotes output stride. + +Checkpoint name | Eval OS | Eval scales | Left-right Flip | Multiply-Adds | Runtime (sec) | Cityscapes mIOU | File Size +-------------------------------------------------------------------------------------------------------------------------------- | :-------: | :-------------------------: | :-------------: | :-------------------: | :------------: | :----------------------------: | :-------: +[mobilenetv2_coco_cityscapes_trainfine](http://download.tensorflow.org/models/deeplabv3_mnv2_cityscapes_train_2018_02_05.tar.gz) | 16
8 | [1.0]
[0.75:0.25:1.25] | No
Yes | 21.27B
433.24B | 0.8
51.12 | 70.71% (val)
73.57% (val) | 23MB +[xception65_cityscapes_trainfine](http://download.tensorflow.org/models/deeplabv3_cityscapes_train_2018_02_06.tar.gz) | 16
8 | [1.0]
[0.75:0.25:1.25] | No
Yes | 418.64B
8677.92B | 5.0
422.8 | 78.79% (val)
80.42% (val) | 439MB +[xception71_dpc_cityscapes_trainfine](http://download.tensorflow.org/models/deeplab_cityscapes_xception71_trainfine_2018_09_08.tar.gz) | 16 | [1.0] | No | 502.07B | - | 80.31% (val) | 445MB +[xception71_dpc_cityscapes_trainval](http://download.tensorflow.org/models/deeplab_cityscapes_xception71_trainvalfine_2018_09_08.tar.gz) | 8 | [0.75:0.25:2] | Yes | - | - | 82.66% (**test**) | 446MB + + + +## DeepLab models trained on ADE20K + +### Model details + +We provide some checkpoints that have been pretrained on ADE20K training set. +Note that the model has only been pretrained on ImageNet, following the +dataset rule. + +Checkpoint name | Network backbone | Pretrained dataset | ASPP | Decoder +------------------------------------- | :--------------: | :-------------------------------------: | :----------------------------------------------: | :-----: +xception65_ade20k_train | Xception_65 | ImageNet
ADE20K training set | [6, 12, 18] for OS=16
[12, 24, 36] for OS=8 | OS = 4 + +Checkpoint name | Eval OS | Eval scales | Left-right Flip | mIOU | Pixel-wise Accuracy | File Size +------------------------------------- | :-------: | :-------------------------: | :-------------: | :-------------------: | :-------------------: | :-------: +[xception65_ade20k_train](http://download.tensorflow.org/models/deeplabv3_xception_ade20k_train_2018_05_29.tar.gz) | 8 | [0.5:0.25:1.75] | Yes | 45.65% (val) | 82.52% (val) | 439MB + +## Checkpoints pretrained on ImageNet + +Un-tar'ed directory includes: + +* model checkpoint (`model.ckpt.data-00000-of-00001`, `model.ckpt.index`). + +### Model details + +We also provide some checkpoints that are pretrained on ImageNet and/or COCO (as +post-fixed in the model name) so that one could use this for training your own +models. + +* mobilenet_v2: We refer the interested users to the TensorFlow open source + [MobileNet-V2](https://github.com/tensorflow/models/tree/master/research/slim/nets/mobilenet) + for details. + +* xception_{41,65,71}: We adapt the original Xception model to the task of + semantic segmentation with the following changes: (1) more layers, (2) all + max pooling operations are replaced by strided (atrous) separable + convolutions, and (3) extra batch-norm and ReLU after each 3x3 depthwise + convolution are added. We provide three Xception model variants with + different network depths. + +* resnet_v1_{50,101}_beta: We modify the original ResNet-101 [10], similar to + PSPNet [11] by replacing the first 7x7 convolution with three 3x3 + convolutions. See resnet_v1_beta.py for more details. + +Model name | File Size +-------------------------------------------------------------------------------------- | :-------: +[xception_41_imagenet](http://download.tensorflow.org/models/xception_41_2018_05_09.tar.gz ) | 288MB +[xception_65_imagenet](http://download.tensorflow.org/models/deeplabv3_xception_2018_01_04.tar.gz) | 447MB +[xception_65_imagenet_coco](http://download.tensorflow.org/models/xception_65_coco_pretrained_2018_10_02.tar.gz) | 292MB +[xception_71_imagenet](http://download.tensorflow.org/models/xception_71_2018_05_09.tar.gz ) | 474MB +[resnet_v1_50_beta_imagenet](http://download.tensorflow.org/models/resnet_v1_50_2018_05_04.tar.gz) | 274MB +[resnet_v1_101_beta_imagenet](http://download.tensorflow.org/models/resnet_v1_101_2018_05_04.tar.gz) | 477MB + +## References + +1. **Mobilenets: Efficient convolutional neural networks for mobile vision applications**
+ Andrew G. Howard, Menglong Zhu, Bo Chen, Dmitry Kalenichenko, Weijun Wang, Tobias Weyand, Marco Andreetto, Hartwig Adam
+ [[link]](https://arxiv.org/abs/1704.04861). arXiv:1704.04861, 2017. + +2. **Inverted Residuals and Linear Bottlenecks: Mobile Networks for Classification, Detection and Segmentation**
+ Mark Sandler, Andrew Howard, Menglong Zhu, Andrey Zhmoginov, Liang-Chieh Chen
+ [[link]](https://arxiv.org/abs/1801.04381). arXiv:1801.04381, 2018. + +3. **Xception: Deep Learning with Depthwise Separable Convolutions**
+ François Chollet
+ [[link]](https://arxiv.org/abs/1610.02357). In the Proc. of CVPR, 2017. + +4. **Deformable Convolutional Networks -- COCO Detection and Segmentation Challenge 2017 Entry**
+ Haozhi Qi, Zheng Zhang, Bin Xiao, Han Hu, Bowen Cheng, Yichen Wei, Jifeng Dai
+ [[link]](http://presentations.cocodataset.org/COCO17-Detect-MSRA.pdf). ICCV COCO Challenge + Workshop, 2017. + +5. **The Pascal Visual Object Classes Challenge: A Retrospective**
+ Mark Everingham, S. M. Ali Eslami, Luc Van Gool, Christopher K. I. Williams, John M. Winn, Andrew Zisserman
+ [[link]](http://host.robots.ox.ac.uk/pascal/VOC/voc2012/). IJCV, 2014. + +6. **Semantic Contours from Inverse Detectors**
+ Bharath Hariharan, Pablo Arbelaez, Lubomir Bourdev, Subhransu Maji, Jitendra Malik
+ [[link]](http://home.bharathh.info/pubs/codes/SBD/download.html). In the Proc. of ICCV, 2011. + +7. **The Cityscapes Dataset for Semantic Urban Scene Understanding**
+ Cordts, Marius, Mohamed Omran, Sebastian Ramos, Timo Rehfeld, Markus Enzweiler, Rodrigo Benenson, Uwe Franke, Stefan Roth, Bernt Schiele.
+ [[link]](https://www.cityscapes-dataset.com/). In the Proc. of CVPR, 2016. + +8. **Microsoft COCO: Common Objects in Context**
+ Tsung-Yi Lin, Michael Maire, Serge Belongie, Lubomir Bourdev, Ross Girshick, James Hays, Pietro Perona, Deva Ramanan, C. Lawrence Zitnick, Piotr Dollar
+ [[link]](http://cocodataset.org/). In the Proc. of ECCV, 2014. + +9. **ImageNet Large Scale Visual Recognition Challenge**
+ Olga Russakovsky, Jia Deng, Hao Su, Jonathan Krause, Sanjeev Satheesh, Sean Ma, Zhiheng Huang, Andrej Karpathy, Aditya Khosla, Michael Bernstein, Alexander C. Berg, Li Fei-Fei
+ [[link]](http://www.image-net.org/). IJCV, 2015. + +10. **Deep Residual Learning for Image Recognition**
+ Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun
+ [[link]](https://arxiv.org/abs/1512.03385). CVPR, 2016. + +11. **Pyramid Scene Parsing Network**
+ Hengshuang Zhao, Jianping Shi, Xiaojuan Qi, Xiaogang Wang, Jiaya Jia
+ [[link]](https://arxiv.org/abs/1612.01105). In CVPR, 2017. + +12. **Scene Parsing through ADE20K Dataset**
+ Bolei Zhou, Hang Zhao, Xavier Puig, Sanja Fidler, Adela Barriuso, Antonio Torralba
+ [[link]](http://groups.csail.mit.edu/vision/datasets/ADE20K/). In CVPR, + 2017. diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/pascal.md b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/pascal.md new file mode 100644 index 0000000..de62718 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/g3doc/pascal.md @@ -0,0 +1,164 @@ +# Running DeepLab on PASCAL VOC 2012 Semantic Segmentation Dataset + +This page walks through the steps required to run DeepLab on PASCAL VOC 2012 on +a local machine. + +## Download dataset and convert to TFRecord + +We have prepared the script (under the folder `datasets`) to download and +convert PASCAL VOC 2012 semantic segmentation dataset to TFRecord. + +```bash +# From the tensorflow/models/research/deeplab/datasets directory. +sh download_and_convert_voc2012.sh +``` + +The converted dataset will be saved at +./deeplab/datasets/pascal_voc_seg/tfrecord + +## Recommended Directory Structure for Training and Evaluation + +``` ++ datasets + + pascal_voc_seg + + VOCdevkit + + VOC2012 + + JPEGImages + + SegmentationClass + + tfrecord + + exp + + train_on_train_set + + train + + eval + + vis +``` + +where the folder `train_on_train_set` stores the train/eval/vis events and +results (when training DeepLab on the PASCAL VOC 2012 train set). + +## Running the train/eval/vis jobs + +A local training job using `xception_65` can be run with the following command: + +```bash +# From tensorflow/models/research/ +python deeplab/train.py \ + --logtostderr \ + --training_number_of_steps=30000 \ + --train_split="train" \ + --model_variant="xception_65" \ + --atrous_rates=6 \ + --atrous_rates=12 \ + --atrous_rates=18 \ + --output_stride=16 \ + --decoder_output_stride=4 \ + --train_crop_size=513 \ + --train_crop_size=513 \ + --train_batch_size=1 \ + --dataset="pascal_voc_seg" \ + --tf_initial_checkpoint=${PATH_TO_INITIAL_CHECKPOINT} \ + --train_logdir=${PATH_TO_TRAIN_DIR} \ + --dataset_dir=${PATH_TO_DATASET} +``` + +where ${PATH_TO_INITIAL_CHECKPOINT} is the path to the initial checkpoint +(usually an ImageNet pretrained checkpoint), ${PATH_TO_TRAIN_DIR} is the +directory in which training checkpoints and events will be written to, and +${PATH_TO_DATASET} is the directory in which the PASCAL VOC 2012 dataset +resides. + +**Note that for {train,eval,vis}.py:** + +1. In order to reproduce our results, one needs to use large batch size (> 12), + and set fine_tune_batch_norm = True. Here, we simply use small batch size + during training for the purpose of demonstration. If the users have limited + GPU memory at hand, please fine-tune from our provided checkpoints whose + batch norm parameters have been trained, and use smaller learning rate with + fine_tune_batch_norm = False. + +2. The users should change atrous_rates from [6, 12, 18] to [12, 24, 36] if + setting output_stride=8. + +3. The users could skip the flag, `decoder_output_stride`, if you do not want + to use the decoder structure. + +A local evaluation job using `xception_65` can be run with the following +command: + +```bash +# From tensorflow/models/research/ +python deeplab/eval.py \ + --logtostderr \ + --eval_split="val" \ + --model_variant="xception_65" \ + --atrous_rates=6 \ + --atrous_rates=12 \ + --atrous_rates=18 \ + --output_stride=16 \ + --decoder_output_stride=4 \ + --eval_crop_size=513 \ + --eval_crop_size=513 \ + --dataset="pascal_voc_seg" \ + --checkpoint_dir=${PATH_TO_CHECKPOINT} \ + --eval_logdir=${PATH_TO_EVAL_DIR} \ + --dataset_dir=${PATH_TO_DATASET} +``` + +where ${PATH_TO_CHECKPOINT} is the path to the trained checkpoint (i.e., the +path to train_logdir), ${PATH_TO_EVAL_DIR} is the directory in which evaluation +events will be written to, and ${PATH_TO_DATASET} is the directory in which the +PASCAL VOC 2012 dataset resides. + +A local visualization job using `xception_65` can be run with the following +command: + +```bash +# From tensorflow/models/research/ +python deeplab/vis.py \ + --logtostderr \ + --vis_split="val" \ + --model_variant="xception_65" \ + --atrous_rates=6 \ + --atrous_rates=12 \ + --atrous_rates=18 \ + --output_stride=16 \ + --decoder_output_stride=4 \ + --vis_crop_size=513 \ + --vis_crop_size=513 \ + --dataset="pascal_voc_seg" \ + --checkpoint_dir=${PATH_TO_CHECKPOINT} \ + --vis_logdir=${PATH_TO_VIS_DIR} \ + --dataset_dir=${PATH_TO_DATASET} +``` + +where ${PATH_TO_CHECKPOINT} is the path to the trained checkpoint (i.e., the +path to train_logdir), ${PATH_TO_VIS_DIR} is the directory in which evaluation +events will be written to, and ${PATH_TO_DATASET} is the directory in which the +PASCAL VOC 2012 dataset resides. Note that if the users would like to save the +segmentation results for evaluation server, set also_save_raw_predictions = +True. + +## Running Tensorboard + +Progress for training and evaluation jobs can be inspected using Tensorboard. If +using the recommended directory structure, Tensorboard can be run using the +following command: + +```bash +tensorboard --logdir=${PATH_TO_LOG_DIRECTORY} +``` + +where `${PATH_TO_LOG_DIRECTORY}` points to the directory that contains the +train, eval, and vis directories (e.g., the folder `train_on_train_set` in the +above example). Please note it may take Tensorboard a couple minutes to populate +with data. + +## Example + +We provide a script to run the {train,eval,vis,export_model}.py on the PASCAL VOC +2012 dataset as an example. See the code in local_test.sh for details. + +```bash +# From tensorflow/models/research/deeplab +sh local_test.sh +``` diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/input_preprocess.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/input_preprocess.py new file mode 100644 index 0000000..135e24c --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/input_preprocess.py @@ -0,0 +1,138 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Prepares the data used for DeepLab training/evaluation.""" +import tensorflow as tf +from deeplab.core import feature_extractor +from deeplab.core import preprocess_utils + + +# The probability of flipping the images and labels +# left-right during training +_PROB_OF_FLIP = 0.5 + + +def preprocess_image_and_label(image, + label, + crop_height, + crop_width, + min_resize_value=None, + max_resize_value=None, + resize_factor=None, + min_scale_factor=1., + max_scale_factor=1., + scale_factor_step_size=0, + ignore_label=255, + is_training=True, + model_variant=None): + """Preprocesses the image and label. + + Args: + image: Input image. + label: Ground truth annotation label. + crop_height: The height value used to crop the image and label. + crop_width: The width value used to crop the image and label. + min_resize_value: Desired size of the smaller image side. + max_resize_value: Maximum allowed size of the larger image side. + resize_factor: Resized dimensions are multiple of factor plus one. + min_scale_factor: Minimum scale factor value. + max_scale_factor: Maximum scale factor value. + scale_factor_step_size: The step size from min scale factor to max scale + factor. The input is randomly scaled based on the value of + (min_scale_factor, max_scale_factor, scale_factor_step_size). + ignore_label: The label value which will be ignored for training and + evaluation. + is_training: If the preprocessing is used for training or not. + model_variant: Model variant (string) for choosing how to mean-subtract the + images. See feature_extractor.network_map for supported model variants. + + Returns: + original_image: Original image (could be resized). + processed_image: Preprocessed image. + label: Preprocessed ground truth segmentation label. + + Raises: + ValueError: Ground truth label not provided during training. + """ + if is_training and label is None: + raise ValueError('During training, label must be provided.') + if model_variant is None: + tf.logging.warning('Default mean-subtraction is performed. Please specify ' + 'a model_variant. See feature_extractor.network_map for ' + 'supported model variants.') + + # Keep reference to original image. + original_image = image + + processed_image = tf.cast(image, tf.float32) + + if label is not None: + label = tf.cast(label, tf.int32) + + # Resize image and label to the desired range. + if min_resize_value is not None or max_resize_value is not None: + [processed_image, label] = ( + preprocess_utils.resize_to_range( + image=processed_image, + label=label, + min_size=min_resize_value, + max_size=max_resize_value, + factor=resize_factor, + align_corners=True)) + # The `original_image` becomes the resized image. + original_image = tf.identity(processed_image) + + # Data augmentation by randomly scaling the inputs. + if is_training: + scale = preprocess_utils.get_random_scale( + min_scale_factor, max_scale_factor, scale_factor_step_size) + processed_image, label = preprocess_utils.randomly_scale_image_and_label( + processed_image, label, scale) + processed_image.set_shape([None, None, 3]) + + # Pad image and label to have dimensions >= [crop_height, crop_width] + image_shape = tf.shape(processed_image) + image_height = image_shape[0] + image_width = image_shape[1] + + target_height = image_height + tf.maximum(crop_height - image_height, 0) + target_width = image_width + tf.maximum(crop_width - image_width, 0) + + # Pad image with mean pixel value. + mean_pixel = tf.reshape( + feature_extractor.mean_pixel(model_variant), [1, 1, 3]) + processed_image = preprocess_utils.pad_to_bounding_box( + processed_image, 0, 0, target_height, target_width, mean_pixel) + + if label is not None: + label = preprocess_utils.pad_to_bounding_box( + label, 0, 0, target_height, target_width, ignore_label) + + # Randomly crop the image and label. + if is_training and label is not None: + processed_image, label = preprocess_utils.random_crop( + [processed_image, label], crop_height, crop_width) + + processed_image.set_shape([crop_height, crop_width, 3]) + + if label is not None: + label.set_shape([crop_height, crop_width, 1]) + + if is_training: + # Randomly left-right flip the image and label. + processed_image, label, _ = preprocess_utils.flip_dim( + [processed_image, label], _PROB_OF_FLIP, dim=1) + + return original_image, processed_image, label diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/learning.py.patch b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/learning.py.patch new file mode 100644 index 0000000..adeda79 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/learning.py.patch @@ -0,0 +1,22 @@ +--- learning.py 2018-07-26 06:18:30.000000000 -0500 ++++ /mod/learning.py 2019-02-18 15:28:18.000000000 -0600 +@@ -553,7 +553,8 @@ + session_config=None, + session_wrapper=None, + trace_every_n_steps=None, +- ignore_live_threads=False): ++ ignore_live_threads=False, ++ lms=None): + """Runs a training loop using a TensorFlow supervisor. + + When the sync_optimizer is supplied, gradient updates are applied +@@ -718,7 +719,8 @@ + train_step_kwargs['should_trace'] = math_ops.equal( + math_ops.mod(global_step, trace_every_n_steps), 0) + train_step_kwargs['logdir'] = logdir +- ++ if lms: ++ lms.run(graph) + sv = supervisor.Supervisor( + graph=graph, + is_chief=is_chief, diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/local_test.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/local_test.sh new file mode 100644 index 0000000..65c827a --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/local_test.sh @@ -0,0 +1,150 @@ +#!/bin/bash +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +# +# This script is used to run local test on PASCAL VOC 2012. Users could also +# modify from this script for their use case. +# +# Usage: +# # From the tensorflow/models/research/deeplab directory. +# sh ./local_test.sh +# +# + +# Exit immediately if a command exits with a non-zero status. +set -e + +# Move one-level up to tensorflow/models/research directory. +cd .. + +# Update PYTHONPATH. +export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim + +# Set up the working environment. +CURRENT_DIR=$(pwd) +WORK_DIR="${CURRENT_DIR}/deeplab" + +# Run model_test first to make sure the PYTHONPATH is correctly set. +python "${WORK_DIR}"/model_test.py -v + +# Go to datasets folder and download PASCAL VOC 2012 segmentation dataset. +DATASET_DIR="datasets" +cd "${WORK_DIR}/${DATASET_DIR}" +sh download_and_convert_voc2012.sh + +# Go back to original directory. +cd "${CURRENT_DIR}" + +# Set up the working directories. +PASCAL_FOLDER="pascal_voc_seg" +EXP_FOLDER="exp/train_on_trainval_set" +INIT_FOLDER="${WORK_DIR}/${DATASET_DIR}/${PASCAL_FOLDER}/init_models" +TRAIN_LOGDIR="${WORK_DIR}/${DATASET_DIR}/${PASCAL_FOLDER}/${EXP_FOLDER}/train" +EVAL_LOGDIR="${WORK_DIR}/${DATASET_DIR}/${PASCAL_FOLDER}/${EXP_FOLDER}/eval" +VIS_LOGDIR="${WORK_DIR}/${DATASET_DIR}/${PASCAL_FOLDER}/${EXP_FOLDER}/vis" +EXPORT_DIR="${WORK_DIR}/${DATASET_DIR}/${PASCAL_FOLDER}/${EXP_FOLDER}/export" +mkdir -p "${INIT_FOLDER}" +mkdir -p "${TRAIN_LOGDIR}" +mkdir -p "${EVAL_LOGDIR}" +mkdir -p "${VIS_LOGDIR}" +mkdir -p "${EXPORT_DIR}" + +# Copy locally the trained checkpoint as the initial checkpoint. +TF_INIT_ROOT="http://download.tensorflow.org/models" +TF_INIT_CKPT="deeplabv3_pascal_train_aug_2018_01_04.tar.gz" +cd "${INIT_FOLDER}" +wget -nd -c "${TF_INIT_ROOT}/${TF_INIT_CKPT}" +tar -xf "${TF_INIT_CKPT}" +cd "${CURRENT_DIR}" + +PASCAL_DATASET="${WORK_DIR}/${DATASET_DIR}/${PASCAL_FOLDER}/tfrecord" + +# Train 10 iterations. +NUM_ITERATIONS=10 +python "${WORK_DIR}"/train.py \ + --logtostderr \ + --train_split="trainval" \ + --model_variant="xception_65" \ + --atrous_rates=6 \ + --atrous_rates=12 \ + --atrous_rates=18 \ + --output_stride=16 \ + --decoder_output_stride=4 \ + --train_crop_size=513 \ + --train_crop_size=513 \ + --train_batch_size=4 \ + --training_number_of_steps="${NUM_ITERATIONS}" \ + --fine_tune_batch_norm=true \ + --tf_initial_checkpoint="${INIT_FOLDER}/deeplabv3_pascal_train_aug/model.ckpt" \ + --train_logdir="${TRAIN_LOGDIR}" \ + --dataset_dir="${PASCAL_DATASET}" + +# Run evaluation. This performs eval over the full val split (1449 images) and +# will take a while. +# Using the provided checkpoint, one should expect mIOU=82.20%. +python "${WORK_DIR}"/eval.py \ + --logtostderr \ + --eval_split="val" \ + --model_variant="xception_65" \ + --atrous_rates=6 \ + --atrous_rates=12 \ + --atrous_rates=18 \ + --output_stride=16 \ + --decoder_output_stride=4 \ + --eval_crop_size=513 \ + --eval_crop_size=513 \ + --checkpoint_dir="${TRAIN_LOGDIR}" \ + --eval_logdir="${EVAL_LOGDIR}" \ + --dataset_dir="${PASCAL_DATASET}" \ + --max_number_of_evaluations=1 + +# Visualize the results. +python "${WORK_DIR}"/vis.py \ + --logtostderr \ + --vis_split="val" \ + --model_variant="xception_65" \ + --atrous_rates=6 \ + --atrous_rates=12 \ + --atrous_rates=18 \ + --output_stride=16 \ + --decoder_output_stride=4 \ + --vis_crop_size=513 \ + --vis_crop_size=513 \ + --checkpoint_dir="${TRAIN_LOGDIR}" \ + --vis_logdir="${VIS_LOGDIR}" \ + --dataset_dir="${PASCAL_DATASET}" \ + --max_number_of_iterations=1 + +# Export the trained checkpoint. +CKPT_PATH="${TRAIN_LOGDIR}/model.ckpt-${NUM_ITERATIONS}" +EXPORT_PATH="${EXPORT_DIR}/frozen_inference_graph.pb" + +python "${WORK_DIR}"/export_model.py \ + --logtostderr \ + --checkpoint_path="${CKPT_PATH}" \ + --export_path="${EXPORT_PATH}" \ + --model_variant="xception_65" \ + --atrous_rates=6 \ + --atrous_rates=12 \ + --atrous_rates=18 \ + --output_stride=16 \ + --decoder_output_stride=4 \ + --num_classes=21 \ + --crop_size=513 \ + --crop_size=513 \ + --inference_scales=1.0 + +# Run inference with the exported checkpoint. +# Please refer to the provided deeplab_demo.ipynb for an example. diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/local_test_mobilenetv2.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/local_test_mobilenetv2.sh new file mode 100644 index 0000000..1f0bc84 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/local_test_mobilenetv2.sh @@ -0,0 +1,132 @@ +#!/bin/bash +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +# +# This script is used to run local test on PASCAL VOC 2012 using MobileNet-v2. +# Users could also modify from this script for their use case. +# +# Usage: +# # From the tensorflow/models/research/deeplab directory. +# sh ./local_test_mobilenetv2.sh +# +# + +# Exit immediately if a command exits with a non-zero status. +set -e + +# Move one-level up to tensorflow/models/research directory. +cd .. + +# Update PYTHONPATH. +export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim + +# Set up the working environment. +CURRENT_DIR=$(pwd) +WORK_DIR="${CURRENT_DIR}/deeplab" + +# Run model_test first to make sure the PYTHONPATH is correctly set. +python "${WORK_DIR}"/model_test.py -v + +# Go to datasets folder and download PASCAL VOC 2012 segmentation dataset. +DATASET_DIR="datasets" +cd "${WORK_DIR}/${DATASET_DIR}" +sh download_and_convert_voc2012.sh + +# Go back to original directory. +cd "${CURRENT_DIR}" + +# Set up the working directories. +PASCAL_FOLDER="pascal_voc_seg" +EXP_FOLDER="exp/train_on_trainval_set_mobilenetv2" +INIT_FOLDER="${WORK_DIR}/${DATASET_DIR}/${PASCAL_FOLDER}/init_models" +TRAIN_LOGDIR="${WORK_DIR}/${DATASET_DIR}/${PASCAL_FOLDER}/${EXP_FOLDER}/train" +EVAL_LOGDIR="${WORK_DIR}/${DATASET_DIR}/${PASCAL_FOLDER}/${EXP_FOLDER}/eval" +VIS_LOGDIR="${WORK_DIR}/${DATASET_DIR}/${PASCAL_FOLDER}/${EXP_FOLDER}/vis" +EXPORT_DIR="${WORK_DIR}/${DATASET_DIR}/${PASCAL_FOLDER}/${EXP_FOLDER}/export" +mkdir -p "${INIT_FOLDER}" +mkdir -p "${TRAIN_LOGDIR}" +mkdir -p "${EVAL_LOGDIR}" +mkdir -p "${VIS_LOGDIR}" +mkdir -p "${EXPORT_DIR}" + +# Copy locally the trained checkpoint as the initial checkpoint. +TF_INIT_ROOT="http://download.tensorflow.org/models" +CKPT_NAME="deeplabv3_mnv2_pascal_train_aug" +TF_INIT_CKPT="${CKPT_NAME}_2018_01_29.tar.gz" +cd "${INIT_FOLDER}" +wget -nd -c "${TF_INIT_ROOT}/${TF_INIT_CKPT}" +tar -xf "${TF_INIT_CKPT}" +cd "${CURRENT_DIR}" + +PASCAL_DATASET="${WORK_DIR}/${DATASET_DIR}/${PASCAL_FOLDER}/tfrecord" + +# Train 10 iterations. +NUM_ITERATIONS=10 +python "${WORK_DIR}"/train.py \ + --logtostderr \ + --train_split="trainval" \ + --model_variant="mobilenet_v2" \ + --output_stride=16 \ + --train_crop_size=513 \ + --train_crop_size=513 \ + --train_batch_size=4 \ + --training_number_of_steps="${NUM_ITERATIONS}" \ + --fine_tune_batch_norm=true \ + --tf_initial_checkpoint="${INIT_FOLDER}/${CKPT_NAME}/model.ckpt-30000" \ + --train_logdir="${TRAIN_LOGDIR}" \ + --dataset_dir="${PASCAL_DATASET}" + +# Run evaluation. This performs eval over the full val split (1449 images) and +# will take a while. +# Using the provided checkpoint, one should expect mIOU=75.34%. +python "${WORK_DIR}"/eval.py \ + --logtostderr \ + --eval_split="val" \ + --model_variant="mobilenet_v2" \ + --eval_crop_size=513 \ + --eval_crop_size=513 \ + --checkpoint_dir="${TRAIN_LOGDIR}" \ + --eval_logdir="${EVAL_LOGDIR}" \ + --dataset_dir="${PASCAL_DATASET}" \ + --max_number_of_evaluations=1 + +# Visualize the results. +python "${WORK_DIR}"/vis.py \ + --logtostderr \ + --vis_split="val" \ + --model_variant="mobilenet_v2" \ + --vis_crop_size=513 \ + --vis_crop_size=513 \ + --checkpoint_dir="${TRAIN_LOGDIR}" \ + --vis_logdir="${VIS_LOGDIR}" \ + --dataset_dir="${PASCAL_DATASET}" \ + --max_number_of_iterations=1 + +# Export the trained checkpoint. +CKPT_PATH="${TRAIN_LOGDIR}/model.ckpt-${NUM_ITERATIONS}" +EXPORT_PATH="${EXPORT_DIR}/frozen_inference_graph.pb" + +python "${WORK_DIR}"/export_model.py \ + --logtostderr \ + --checkpoint_path="${CKPT_PATH}" \ + --export_path="${EXPORT_PATH}" \ + --model_variant="mobilenet_v2" \ + --num_classes=21 \ + --crop_size=513 \ + --crop_size=513 \ + --inference_scales=1.0 + +# Run inference with the exported checkpoint. +# Please refer to the provided deeplab_demo.ipynb for an example. diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/model.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/model.py new file mode 100644 index 0000000..8a68739 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/model.py @@ -0,0 +1,709 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +r"""Provides DeepLab model definition and helper functions. + +DeepLab is a deep learning system for semantic image segmentation with +the following features: + +(1) Atrous convolution to explicitly control the resolution at which +feature responses are computed within Deep Convolutional Neural Networks. + +(2) Atrous spatial pyramid pooling (ASPP) to robustly segment objects at +multiple scales with filters at multiple sampling rates and effective +fields-of-views. + +(3) ASPP module augmented with image-level feature and batch normalization. + +(4) A simple yet effective decoder module to recover the object boundaries. + +See the following papers for more details: + +"Encoder-Decoder with Atrous Separable Convolution for Semantic Image +Segmentation" +Liang-Chieh Chen, Yukun Zhu, George Papandreou, Florian Schroff, Hartwig Adam. +(https://arxiv.org/abs/1802.02611) + +"Rethinking Atrous Convolution for Semantic Image Segmentation," +Liang-Chieh Chen, George Papandreou, Florian Schroff, Hartwig Adam +(https://arxiv.org/abs/1706.05587) + +"DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, +Atrous Convolution, and Fully Connected CRFs", +Liang-Chieh Chen*, George Papandreou*, Iasonas Kokkinos, Kevin Murphy, +Alan L Yuille (* equal contribution) +(https://arxiv.org/abs/1606.00915) + +"Semantic Image Segmentation with Deep Convolutional Nets and Fully Connected +CRFs" +Liang-Chieh Chen*, George Papandreou*, Iasonas Kokkinos, Kevin Murphy, +Alan L. Yuille (* equal contribution) +(https://arxiv.org/abs/1412.7062) +""" +import tensorflow as tf +from deeplab.core import dense_prediction_cell +from deeplab.core import feature_extractor +from deeplab.core import utils + + +slim = tf.contrib.slim + +LOGITS_SCOPE_NAME = 'logits' +MERGED_LOGITS_SCOPE = 'merged_logits' +IMAGE_POOLING_SCOPE = 'image_pooling' +ASPP_SCOPE = 'aspp' +CONCAT_PROJECTION_SCOPE = 'concat_projection' +DECODER_SCOPE = 'decoder' +META_ARCHITECTURE_SCOPE = 'meta_architecture' + +scale_dimension = utils.scale_dimension +split_separable_conv2d = utils.split_separable_conv2d + +def get_extra_layer_scopes(last_layers_contain_logits_only=False): + """Gets the scopes for extra layers. + + Args: + last_layers_contain_logits_only: Boolean, True if only consider logits as + the last layer (i.e., exclude ASPP module, decoder module and so on) + + Returns: + A list of scopes for extra layers. + """ + if last_layers_contain_logits_only: + return [LOGITS_SCOPE_NAME] + else: + return [ + LOGITS_SCOPE_NAME, + IMAGE_POOLING_SCOPE, + ASPP_SCOPE, + CONCAT_PROJECTION_SCOPE, + DECODER_SCOPE, + META_ARCHITECTURE_SCOPE, + ] + + +def predict_labels_multi_scale(images, + model_options, + eval_scales=(1.0,), + add_flipped_images=False): + """Predicts segmentation labels. + + Args: + images: A tensor of size [batch, height, width, channels]. + model_options: A ModelOptions instance to configure models. + eval_scales: The scales to resize images for evaluation. + add_flipped_images: Add flipped images for evaluation or not. + + Returns: + A dictionary with keys specifying the output_type (e.g., semantic + prediction) and values storing Tensors representing predictions (argmax + over channels). Each prediction has size [batch, height, width]. + """ + outputs_to_predictions = { + output: [] + for output in model_options.outputs_to_num_classes + } + + for i, image_scale in enumerate(eval_scales): + with tf.variable_scope(tf.get_variable_scope(), reuse=True if i else None): + outputs_to_scales_to_logits = multi_scale_logits( + images, + model_options=model_options, + image_pyramid=[image_scale], + is_training=False, + fine_tune_batch_norm=False) + + if add_flipped_images: + with tf.variable_scope(tf.get_variable_scope(), reuse=True): + outputs_to_scales_to_logits_reversed = multi_scale_logits( + tf.reverse_v2(images, [2]), + model_options=model_options, + image_pyramid=[image_scale], + is_training=False, + fine_tune_batch_norm=False) + + for output in sorted(outputs_to_scales_to_logits): + scales_to_logits = outputs_to_scales_to_logits[output] + logits = tf.image.resize_bilinear( + scales_to_logits[MERGED_LOGITS_SCOPE], + tf.shape(images)[1:3], + align_corners=True) + outputs_to_predictions[output].append( + tf.expand_dims(tf.nn.softmax(logits), 4)) + + if add_flipped_images: + scales_to_logits_reversed = ( + outputs_to_scales_to_logits_reversed[output]) + logits_reversed = tf.image.resize_bilinear( + tf.reverse_v2(scales_to_logits_reversed[MERGED_LOGITS_SCOPE], [2]), + tf.shape(images)[1:3], + align_corners=True) + outputs_to_predictions[output].append( + tf.expand_dims(tf.nn.softmax(logits_reversed), 4)) + + for output in sorted(outputs_to_predictions): + predictions = outputs_to_predictions[output] + # Compute average prediction across different scales and flipped images. + predictions = tf.reduce_mean(tf.concat(predictions, 4), axis=4) + outputs_to_predictions[output] = tf.argmax(predictions, 3) + + return outputs_to_predictions + + +def predict_labels(images, model_options, image_pyramid=None): + """Predicts segmentation labels. + + Args: + images: A tensor of size [batch, height, width, channels]. + model_options: A ModelOptions instance to configure models. + image_pyramid: Input image scales for multi-scale feature extraction. + + Returns: + A dictionary with keys specifying the output_type (e.g., semantic + prediction) and values storing Tensors representing predictions (argmax + over channels). Each prediction has size [batch, height, width]. + """ + outputs_to_scales_to_logits = multi_scale_logits( + images, + model_options=model_options, + image_pyramid=image_pyramid, + is_training=False, + fine_tune_batch_norm=False) + + predictions = {} + for output in sorted(outputs_to_scales_to_logits): + scales_to_logits = outputs_to_scales_to_logits[output] + logits = tf.image.resize_bilinear( + scales_to_logits[MERGED_LOGITS_SCOPE], + tf.shape(images)[1:3], + align_corners=True) + predictions[output] = tf.argmax(logits, 3) + + return predictions + + +def _resize_bilinear(images, size, output_dtype=tf.float32): + """Returns resized images as output_type. + + Args: + images: A tensor of size [batch, height_in, width_in, channels]. + size: A 1-D int32 Tensor of 2 elements: new_height, new_width. The new size + for the images. + output_dtype: The destination type. + Returns: + A tensor of size [batch, height_out, width_out, channels] as a dtype of + output_dtype. + """ + images = tf.image.resize_bilinear(images, size, align_corners=True) + return tf.cast(images, dtype=output_dtype) + + +def multi_scale_logits(images, + model_options, + image_pyramid, + weight_decay=0.0001, + is_training=False, + fine_tune_batch_norm=False): + """Gets the logits for multi-scale inputs. + + The returned logits are all downsampled (due to max-pooling layers) + for both training and evaluation. + + Args: + images: A tensor of size [batch, height, width, channels]. + model_options: A ModelOptions instance to configure models. + image_pyramid: Input image scales for multi-scale feature extraction. + weight_decay: The weight decay for model variables. + is_training: Is training or not. + fine_tune_batch_norm: Fine-tune the batch norm parameters or not. + + Returns: + outputs_to_scales_to_logits: A map of maps from output_type (e.g., + semantic prediction) to a dictionary of multi-scale logits names to + logits. For each output_type, the dictionary has keys which + correspond to the scales and values which correspond to the logits. + For example, if `scales` equals [1.0, 1.5], then the keys would + include 'merged_logits', 'logits_1.00' and 'logits_1.50'. + + Raises: + ValueError: If model_options doesn't specify crop_size and its + add_image_level_feature = True, since add_image_level_feature requires + crop_size information. + """ + # Setup default values. + if not image_pyramid: + image_pyramid = [1.0] + crop_height = ( + model_options.crop_size[0] + if model_options.crop_size else tf.shape(images)[1]) + crop_width = ( + model_options.crop_size[1] + if model_options.crop_size else tf.shape(images)[2]) + + # Compute the height, width for the output logits. + logits_output_stride = ( + model_options.decoder_output_stride or model_options.output_stride) + + logits_height = scale_dimension( + crop_height, + max(1.0, max(image_pyramid)) / logits_output_stride) + logits_width = scale_dimension( + crop_width, + max(1.0, max(image_pyramid)) / logits_output_stride) + + # Compute the logits for each scale in the image pyramid. + outputs_to_scales_to_logits = { + k: {} + for k in model_options.outputs_to_num_classes + } + + for image_scale in image_pyramid: + if image_scale != 1.0: + scaled_height = scale_dimension(crop_height, image_scale) + scaled_width = scale_dimension(crop_width, image_scale) + scaled_crop_size = [scaled_height, scaled_width] + scaled_images = tf.image.resize_bilinear( + images, scaled_crop_size, align_corners=True) + if model_options.crop_size: + scaled_images.set_shape([None, scaled_height, scaled_width, 3]) + else: + scaled_crop_size = model_options.crop_size + scaled_images = images + + updated_options = model_options._replace(crop_size=scaled_crop_size) + outputs_to_logits = _get_logits( + scaled_images, + updated_options, + weight_decay=weight_decay, + reuse=tf.AUTO_REUSE, + is_training=is_training, + fine_tune_batch_norm=fine_tune_batch_norm) + + # Resize the logits to have the same dimension before merging. + for output in sorted(outputs_to_logits): + outputs_to_logits[output] = tf.image.resize_bilinear( + outputs_to_logits[output], [logits_height, logits_width], + align_corners=True) + + # Return when only one input scale. + if len(image_pyramid) == 1: + for output in sorted(model_options.outputs_to_num_classes): + outputs_to_scales_to_logits[output][ + MERGED_LOGITS_SCOPE] = outputs_to_logits[output] + return outputs_to_scales_to_logits + + # Save logits to the output map. + for output in sorted(model_options.outputs_to_num_classes): + outputs_to_scales_to_logits[output][ + 'logits_%.2f' % image_scale] = outputs_to_logits[output] + + # Merge the logits from all the multi-scale inputs. + for output in sorted(model_options.outputs_to_num_classes): + # Concatenate the multi-scale logits for each output type. + all_logits = [ + tf.expand_dims(logits, axis=4) + for logits in outputs_to_scales_to_logits[output].values() + ] + all_logits = tf.concat(all_logits, 4) + merge_fn = ( + tf.reduce_max + if model_options.merge_method == 'max' else tf.reduce_mean) + outputs_to_scales_to_logits[output][MERGED_LOGITS_SCOPE] = merge_fn( + all_logits, axis=4) + + return outputs_to_scales_to_logits + + +def extract_features(images, + model_options, + weight_decay=0.0001, + reuse=None, + is_training=False, + fine_tune_batch_norm=False): + """Extracts features by the particular model_variant. + + Args: + images: A tensor of size [batch, height, width, channels]. + model_options: A ModelOptions instance to configure models. + weight_decay: The weight decay for model variables. + reuse: Reuse the model variables or not. + is_training: Is training or not. + fine_tune_batch_norm: Fine-tune the batch norm parameters or not. + + Returns: + concat_logits: A tensor of size [batch, feature_height, feature_width, + feature_channels], where feature_height/feature_width are determined by + the images height/width and output_stride. + end_points: A dictionary from components of the network to the corresponding + activation. + """ + features, end_points = feature_extractor.extract_features( + images, + output_stride=model_options.output_stride, + multi_grid=model_options.multi_grid, + model_variant=model_options.model_variant, + depth_multiplier=model_options.depth_multiplier, + weight_decay=weight_decay, + reuse=reuse, + is_training=is_training, + fine_tune_batch_norm=fine_tune_batch_norm) + + if not model_options.aspp_with_batch_norm: + return features, end_points + else: + if model_options.dense_prediction_cell_config is not None: + tf.logging.info('Using dense prediction cell config.') + dense_prediction_layer = dense_prediction_cell.DensePredictionCell( + config=model_options.dense_prediction_cell_config, + hparams={ + 'conv_rate_multiplier': 16 // model_options.output_stride, + }) + concat_logits = dense_prediction_layer.build_cell( + features, + output_stride=model_options.output_stride, + crop_size=model_options.crop_size, + image_pooling_crop_size=model_options.image_pooling_crop_size, + weight_decay=weight_decay, + reuse=reuse, + is_training=is_training, + fine_tune_batch_norm=fine_tune_batch_norm) + return concat_logits, end_points + else: + # The following codes employ the DeepLabv3 ASPP module. Note that We + # could express the ASPP module as one particular dense prediction + # cell architecture. We do not do so but leave the following codes in + # order for backward compatibility. + batch_norm_params = { + 'is_training': is_training and fine_tune_batch_norm, + 'decay': 0.9997, + 'epsilon': 1e-5, + 'scale': True, + } + + with slim.arg_scope( + [slim.conv2d, slim.separable_conv2d], + weights_regularizer=slim.l2_regularizer(weight_decay), + activation_fn=tf.nn.relu, + normalizer_fn=slim.batch_norm, + padding='SAME', + stride=1, + reuse=reuse): + with slim.arg_scope([slim.batch_norm], **batch_norm_params): + depth = 256 + branch_logits = [] + + if model_options.add_image_level_feature: + if model_options.crop_size is not None: + image_pooling_crop_size = model_options.image_pooling_crop_size + # If image_pooling_crop_size is not specified, use crop_size. + if image_pooling_crop_size is None: + image_pooling_crop_size = model_options.crop_size + pool_height = scale_dimension( + image_pooling_crop_size[0], + 1. / model_options.output_stride) + pool_width = scale_dimension( + image_pooling_crop_size[1], + 1. / model_options.output_stride) + image_feature = slim.avg_pool2d( + features, [pool_height, pool_width], [1, 1], padding='VALID') + resize_height = scale_dimension( + model_options.crop_size[0], + 1. / model_options.output_stride) + resize_width = scale_dimension( + model_options.crop_size[1], + 1. / model_options.output_stride) + else: + # If crop_size is None, we simply do global pooling. + pool_height = tf.shape(features)[1] + pool_width = tf.shape(features)[2] + image_feature = tf.reduce_mean( + features, axis=[1, 2], keepdims=True) + resize_height = pool_height + resize_width = pool_width + image_feature = slim.conv2d( + image_feature, depth, 1, scope=IMAGE_POOLING_SCOPE) + image_feature = _resize_bilinear( + image_feature, + [resize_height, resize_width], + image_feature.dtype) + # Set shape for resize_height/resize_width if they are not Tensor. + if isinstance(resize_height, tf.Tensor): + resize_height = None + if isinstance(resize_width, tf.Tensor): + resize_width = None + image_feature.set_shape([None, resize_height, resize_width, depth]) + branch_logits.append(image_feature) + + # Employ a 1x1 convolution. + branch_logits.append(slim.conv2d(features, depth, 1, + scope=ASPP_SCOPE + str(0))) + + if model_options.atrous_rates: + # Employ 3x3 convolutions with different atrous rates. + for i, rate in enumerate(model_options.atrous_rates, 1): + scope = ASPP_SCOPE + str(i) + if model_options.aspp_with_separable_conv: + aspp_features = split_separable_conv2d( + features, + filters=depth, + rate=rate, + weight_decay=weight_decay, + scope=scope) + else: + aspp_features = slim.conv2d( + features, depth, 3, rate=rate, scope=scope) + branch_logits.append(aspp_features) + + # Merge branch logits. + concat_logits = tf.concat(branch_logits, 3) + concat_logits = slim.conv2d( + concat_logits, depth, 1, scope=CONCAT_PROJECTION_SCOPE) + concat_logits = slim.dropout( + concat_logits, + keep_prob=0.9, + is_training=is_training, + scope=CONCAT_PROJECTION_SCOPE + '_dropout') + + return concat_logits, end_points + + +def _get_logits(images, + model_options, + weight_decay=0.0001, + reuse=None, + is_training=False, + fine_tune_batch_norm=False): + """Gets the logits by atrous/image spatial pyramid pooling. + + Args: + images: A tensor of size [batch, height, width, channels]. + model_options: A ModelOptions instance to configure models. + weight_decay: The weight decay for model variables. + reuse: Reuse the model variables or not. + is_training: Is training or not. + fine_tune_batch_norm: Fine-tune the batch norm parameters or not. + + Returns: + outputs_to_logits: A map from output_type to logits. + """ + features, end_points = extract_features( + images, + model_options, + weight_decay=weight_decay, + reuse=reuse, + is_training=is_training, + fine_tune_batch_norm=fine_tune_batch_norm) + + if model_options.decoder_output_stride is not None: + if model_options.crop_size is None: + height = tf.shape(images)[1] + width = tf.shape(images)[2] + else: + height, width = model_options.crop_size + decoder_height = scale_dimension(height, + 1.0 / model_options.decoder_output_stride) + decoder_width = scale_dimension(width, + 1.0 / model_options.decoder_output_stride) + features = refine_by_decoder( + features, + end_points, + decoder_height=decoder_height, + decoder_width=decoder_width, + decoder_use_separable_conv=model_options.decoder_use_separable_conv, + model_variant=model_options.model_variant, + weight_decay=weight_decay, + reuse=reuse, + is_training=is_training, + fine_tune_batch_norm=fine_tune_batch_norm) + + outputs_to_logits = {} + for output in sorted(model_options.outputs_to_num_classes): + outputs_to_logits[output] = get_branch_logits( + features, + model_options.outputs_to_num_classes[output], + model_options.atrous_rates, + aspp_with_batch_norm=model_options.aspp_with_batch_norm, + kernel_size=model_options.logits_kernel_size, + weight_decay=weight_decay, + reuse=reuse, + scope_suffix=output) + + return outputs_to_logits + + +def refine_by_decoder(features, + end_points, + decoder_height, + decoder_width, + decoder_use_separable_conv=False, + model_variant=None, + weight_decay=0.0001, + reuse=None, + is_training=False, + fine_tune_batch_norm=False): + """Adds the decoder to obtain sharper segmentation results. + + Args: + features: A tensor of size [batch, features_height, features_width, + features_channels]. + end_points: A dictionary from components of the network to the corresponding + activation. + decoder_height: The height of decoder feature maps. + decoder_width: The width of decoder feature maps. + decoder_use_separable_conv: Employ separable convolution for decoder or not. + model_variant: Model variant for feature extraction. + weight_decay: The weight decay for model variables. + reuse: Reuse the model variables or not. + is_training: Is training or not. + fine_tune_batch_norm: Fine-tune the batch norm parameters or not. + + Returns: + Decoder output with size [batch, decoder_height, decoder_width, + decoder_channels]. + """ + batch_norm_params = { + 'is_training': is_training and fine_tune_batch_norm, + 'decay': 0.9997, + 'epsilon': 1e-5, + 'scale': True, + } + + with slim.arg_scope( + [slim.conv2d, slim.separable_conv2d], + weights_regularizer=slim.l2_regularizer(weight_decay), + activation_fn=tf.nn.relu, + normalizer_fn=slim.batch_norm, + padding='SAME', + stride=1, + reuse=reuse): + with slim.arg_scope([slim.batch_norm], **batch_norm_params): + with tf.variable_scope(DECODER_SCOPE, DECODER_SCOPE, [features]): + feature_list = feature_extractor.networks_to_feature_maps[ + model_variant][feature_extractor.DECODER_END_POINTS] + if feature_list is None: + tf.logging.info('Not found any decoder end points.') + return features + else: + decoder_features = features + for i, name in enumerate(feature_list): + decoder_features_list = [decoder_features] + + # MobileNet variants use different naming convention. + if 'mobilenet' in model_variant: + feature_name = name + else: + feature_name = '{}/{}'.format( + feature_extractor.name_scope[model_variant], name) + decoder_features_list.append( + slim.conv2d( + end_points[feature_name], + 48, + 1, + scope='feature_projection' + str(i))) + # Resize to decoder_height/decoder_width. + for j, feature in enumerate(decoder_features_list): + decoder_features_list[j] = tf.image.resize_bilinear( + feature, [decoder_height, decoder_width], align_corners=True) + h = (None if isinstance(decoder_height, tf.Tensor) + else decoder_height) + w = (None if isinstance(decoder_width, tf.Tensor) + else decoder_width) + decoder_features_list[j].set_shape([None, h, w, None]) + decoder_depth = 256 + if decoder_use_separable_conv: + decoder_features = split_separable_conv2d( + tf.concat(decoder_features_list, 3), + filters=decoder_depth, + rate=1, + weight_decay=weight_decay, + scope='decoder_conv0') + decoder_features = split_separable_conv2d( + decoder_features, + filters=decoder_depth, + rate=1, + weight_decay=weight_decay, + scope='decoder_conv1') + else: + num_convs = 2 + decoder_features = slim.repeat( + tf.concat(decoder_features_list, 3), + num_convs, + slim.conv2d, + decoder_depth, + 3, + scope='decoder_conv' + str(i)) + return decoder_features + + +def get_branch_logits(features, + num_classes, + atrous_rates=None, + aspp_with_batch_norm=False, + kernel_size=1, + weight_decay=0.0001, + reuse=None, + scope_suffix=''): + """Gets the logits from each model's branch. + + The underlying model is branched out in the last layer when atrous + spatial pyramid pooling is employed, and all branches are sum-merged + to form the final logits. + + Args: + features: A float tensor of shape [batch, height, width, channels]. + num_classes: Number of classes to predict. + atrous_rates: A list of atrous convolution rates for last layer. + aspp_with_batch_norm: Use batch normalization layers for ASPP. + kernel_size: Kernel size for convolution. + weight_decay: Weight decay for the model variables. + reuse: Reuse model variables or not. + scope_suffix: Scope suffix for the model variables. + + Returns: + Merged logits with shape [batch, height, width, num_classes]. + + Raises: + ValueError: Upon invalid input kernel_size value. + """ + # When using batch normalization with ASPP, ASPP has been applied before + # in extract_features, and thus we simply apply 1x1 convolution here. + if aspp_with_batch_norm or atrous_rates is None: + if kernel_size != 1: + raise ValueError('Kernel size must be 1 when atrous_rates is None or ' + 'using aspp_with_batch_norm. Gets %d.' % kernel_size) + atrous_rates = [1] + + with slim.arg_scope( + [slim.conv2d], + weights_regularizer=slim.l2_regularizer(weight_decay), + weights_initializer=tf.truncated_normal_initializer(stddev=0.01), + reuse=reuse): + with tf.variable_scope(LOGITS_SCOPE_NAME, LOGITS_SCOPE_NAME, [features]): + branch_logits = [] + for i, rate in enumerate(atrous_rates): + scope = scope_suffix + if i: + scope += '_%d' % i + + branch_logits.append( + slim.conv2d( + features, + num_classes, + kernel_size=kernel_size, + rate=rate, + activation_fn=None, + normalizer_fn=None, + scope=scope)) + + return tf.add_n(branch_logits) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/model_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/model_test.py new file mode 100644 index 0000000..50471c2 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/model_test.py @@ -0,0 +1,146 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Tests for DeepLab model and some helper functions.""" + +import tensorflow as tf + +from deeplab import common +from deeplab import model + + +class DeeplabModelTest(tf.test.TestCase): + + def testWrongDeepLabVariant(self): + model_options = common.ModelOptions([])._replace( + model_variant='no_such_variant') + with self.assertRaises(ValueError): + model._get_logits(images=[], model_options=model_options) + + def testBuildDeepLabv2(self): + batch_size = 2 + crop_size = [41, 41] + + # Test with two image_pyramids. + image_pyramids = [[1], [0.5, 1]] + + # Test two model variants. + model_variants = ['xception_65', 'mobilenet_v2'] + + # Test with two output_types. + outputs_to_num_classes = {'semantic': 3, + 'direction': 2} + + expected_endpoints = [['merged_logits'], + ['merged_logits', + 'logits_0.50', + 'logits_1.00']] + expected_num_logits = [1, 3] + + for model_variant in model_variants: + model_options = common.ModelOptions(outputs_to_num_classes)._replace( + add_image_level_feature=False, + aspp_with_batch_norm=False, + aspp_with_separable_conv=False, + model_variant=model_variant) + + for i, image_pyramid in enumerate(image_pyramids): + g = tf.Graph() + with g.as_default(): + with self.test_session(graph=g): + inputs = tf.random_uniform( + (batch_size, crop_size[0], crop_size[1], 3)) + outputs_to_scales_to_logits = model.multi_scale_logits( + inputs, model_options, image_pyramid=image_pyramid) + + # Check computed results for each output type. + for output in outputs_to_num_classes: + scales_to_logits = outputs_to_scales_to_logits[output] + self.assertListEqual(sorted(scales_to_logits.keys()), + sorted(expected_endpoints[i])) + + # Expected number of logits = len(image_pyramid) + 1, since the + # last logits is merged from all the scales. + self.assertEqual(len(scales_to_logits), expected_num_logits[i]) + + def testForwardpassDeepLabv3plus(self): + crop_size = [33, 33] + outputs_to_num_classes = {'semantic': 3} + + model_options = common.ModelOptions( + outputs_to_num_classes, + crop_size, + output_stride=16 + )._replace( + add_image_level_feature=True, + aspp_with_batch_norm=True, + logits_kernel_size=1, + model_variant='mobilenet_v2') # Employ MobileNetv2 for fast test. + + g = tf.Graph() + with g.as_default(): + with self.test_session(graph=g) as sess: + inputs = tf.random_uniform( + (1, crop_size[0], crop_size[1], 3)) + outputs_to_scales_to_logits = model.multi_scale_logits( + inputs, + model_options, + image_pyramid=[1.0]) + + sess.run(tf.global_variables_initializer()) + outputs_to_scales_to_logits = sess.run(outputs_to_scales_to_logits) + + # Check computed results for each output type. + for output in outputs_to_num_classes: + scales_to_logits = outputs_to_scales_to_logits[output] + # Expect only one output. + self.assertEqual(len(scales_to_logits), 1) + for logits in scales_to_logits.values(): + self.assertTrue(logits.any()) + + def testBuildDeepLabWithDensePredictionCell(self): + batch_size = 1 + crop_size = [33, 33] + outputs_to_num_classes = {'semantic': 2} + expected_endpoints = ['merged_logits'] + dense_prediction_cell_config = [ + {'kernel': 3, 'rate': [1, 6], 'op': 'conv', 'input': -1}, + {'kernel': 3, 'rate': [18, 15], 'op': 'conv', 'input': 0}, + ] + model_options = common.ModelOptions( + outputs_to_num_classes, + crop_size, + output_stride=16)._replace( + aspp_with_batch_norm=True, + model_variant='mobilenet_v2', + dense_prediction_cell_config=dense_prediction_cell_config) + g = tf.Graph() + with g.as_default(): + with self.test_session(graph=g): + inputs = tf.random_uniform( + (batch_size, crop_size[0], crop_size[1], 3)) + outputs_to_scales_to_model_results = model.multi_scale_logits( + inputs, + model_options, + image_pyramid=[1.0]) + for output in outputs_to_num_classes: + scales_to_model_results = outputs_to_scales_to_model_results[output] + self.assertListEqual(scales_to_model_results.keys(), + expected_endpoints) + self.assertEqual(len(scales_to_model_results), 1) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/train.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/train.py new file mode 100644 index 0000000..4975ef4 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/train.py @@ -0,0 +1,470 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Training script for the DeepLab model. + +See model.py for more details and usage. +""" + +import six +import tensorflow as tf +from tensorflow.core.protobuf import rewriter_config_pb2 +from deeplab import common +from deeplab import model +from deeplab.datasets import segmentation_dataset +from deeplab.utils import input_generator +from deeplab.utils import train_utils +from deployment import model_deploy +import os +distribution_mod = None +if "DDL_OPTIONS" in os.environ: + import ddl + distribution_mod = ddl + +slim = tf.contrib.slim + +prefetch_queue = slim.prefetch_queue + +flags = tf.app.flags + +FLAGS = flags.FLAGS + +# Settings for multi-GPUs/multi-replicas training. + +flags.DEFINE_integer('num_clones', 1, 'Number of clones to deploy.') + +flags.DEFINE_boolean('clone_on_cpu', False, 'Use CPUs to deploy clones.') + +flags.DEFINE_integer('num_replicas', 1, 'Number of worker replicas.') + +flags.DEFINE_integer('startup_delay_steps', 15, + 'Number of training steps between replicas startup.') + +flags.DEFINE_integer('num_ps_tasks', 0, + 'The number of parameter servers. If the value is 0, then ' + 'the parameters are handled locally by the worker.') + +flags.DEFINE_string('master', '', 'BNS name of the tensorflow server') + +flags.DEFINE_integer('task', 0, 'The task ID.') + +# Settings for logging. + +flags.DEFINE_string('train_logdir', None, + 'Where the checkpoint and logs are stored.') + +flags.DEFINE_integer('log_steps', 10, + 'Display logging information at every log_steps.') + +flags.DEFINE_integer('save_interval_secs', 1200, + 'How often, in seconds, we save the model to disk.') + +flags.DEFINE_integer('save_summaries_secs', 600, + 'How often, in seconds, we compute the summaries.') + +flags.DEFINE_boolean('save_summaries_images', False, + 'Save sample inputs, labels, and semantic predictions as ' + 'images to summary.') + +# Settings for training strategy. + +flags.DEFINE_enum('learning_policy', 'poly', ['poly', 'step'], + 'Learning rate policy for training.') + +# Use 0.007 when training on PASCAL augmented training set, train_aug. When +# fine-tuning on PASCAL trainval set, use learning rate=0.0001. +flags.DEFINE_float('base_learning_rate', .0001, + 'The base learning rate for model training.') + +flags.DEFINE_float('learning_rate_decay_factor', 0.1, + 'The rate to decay the base learning rate.') + +flags.DEFINE_integer('learning_rate_decay_step', 2000, + 'Decay the base learning rate at a fixed step.') + +flags.DEFINE_float('learning_power', 0.9, + 'The power value used in the poly learning policy.') + +flags.DEFINE_integer('training_number_of_steps', 30000, + 'The number of steps used for training') + +flags.DEFINE_float('momentum', 0.9, 'The momentum value to use') + +# When fine_tune_batch_norm=True, use at least batch size larger than 12 +# (batch size more than 16 is better). Otherwise, one could use smaller batch +# size and set fine_tune_batch_norm=False. +flags.DEFINE_integer('train_batch_size', 8, + 'The number of images in each batch during training.') + +# For weight_decay, use 0.00004 for MobileNet-V2 or Xcpetion model variants. +# Use 0.0001 for ResNet model variants. +flags.DEFINE_float('weight_decay', 0.00004, + 'The value of the weight decay for training.') + +flags.DEFINE_multi_integer('train_crop_size', [513, 513], + 'Image crop size [height, width] during training.') + +flags.DEFINE_float('last_layer_gradient_multiplier', 1.0, + 'The gradient multiplier for last layers, which is used to ' + 'boost the gradient of last layers if the value > 1.') + +flags.DEFINE_boolean('upsample_logits', True, + 'Upsample logits during training.') + +# Settings for fine-tuning the network. + +flags.DEFINE_string('tf_initial_checkpoint', None, + 'The initial checkpoint in tensorflow format.') + +# Set to False if one does not want to re-use the trained classifier weights. +flags.DEFINE_boolean('initialize_last_layer', True, + 'Initialize the last layer.') + +flags.DEFINE_boolean('last_layers_contain_logits_only', False, + 'Only consider logits as last layers or not.') + +flags.DEFINE_integer('slow_start_step', 0, + 'Training model with small learning rate for few steps.') + +flags.DEFINE_float('slow_start_learning_rate', 1e-4, + 'Learning rate employed during slow start.') + +# Set to True if one wants to fine-tune the batch norm parameters in DeepLabv3. +# Set to False and use small batch size to save GPU memory. +flags.DEFINE_boolean('fine_tune_batch_norm', True, + 'Fine tune the batch norm parameters or not.') + +flags.DEFINE_float('min_scale_factor', 0.5, + 'Mininum scale factor for data augmentation.') + +flags.DEFINE_float('max_scale_factor', 2., + 'Maximum scale factor for data augmentation.') + +flags.DEFINE_float('scale_factor_step_size', 0.25, + 'Scale factor step size for data augmentation.') + +# For `xception_65`, use atrous_rates = [12, 24, 36] if output_stride = 8, or +# rates = [6, 12, 18] if output_stride = 16. For `mobilenet_v2`, use None. Note +# one could use different atrous_rates/output_stride during training/evaluation. +flags.DEFINE_multi_integer('atrous_rates', None, + 'Atrous rates for atrous spatial pyramid pooling.') + +flags.DEFINE_integer('output_stride', 16, + 'The ratio of input to output spatial resolution.') + +# Dataset settings. +flags.DEFINE_string('dataset', 'pascal_voc_seg', + 'Name of the segmentation dataset.') + +flags.DEFINE_string('train_split', 'train', + 'Which split of the dataset to be used for training') + +flags.DEFINE_string('dataset_dir', None, 'Where the dataset reside.') + +flags.DEFINE_integer('swapout_threshold', -1, + 'swapout_threshold') +flags.DEFINE_integer('swapin_ahead', -1, + 'swapin_ahead') +flags.DEFINE_integer('swapin_groupby', -1, + 'swapin_groupby') +flags.DEFINE_integer('sync_mode', 0, + 'sync_mode') +flags.DEFINE_boolean('use_tflms', False, 'Use TFLMS') + +flags.DEFINE_boolean('disable_layout_optimizer', False, + 'Disable layout optimizer. (On by default)') + + +def _build_deeplab(inputs_queue, outputs_to_num_classes, ignore_label): + """Builds a clone of DeepLab. + + Args: + inputs_queue: A prefetch queue for images and labels. + outputs_to_num_classes: A map from output type to the number of classes. + For example, for the task of semantic segmentation with 21 semantic + classes, we would have outputs_to_num_classes['semantic'] = 21. + ignore_label: Ignore label. + + Returns: + A map of maps from output_type (e.g., semantic prediction) to a + dictionary of multi-scale logits names to logits. For each output_type, + the dictionary has keys which correspond to the scales and values which + correspond to the logits. For example, if `scales` equals [1.0, 1.5], + then the keys would include 'merged_logits', 'logits_1.00' and + 'logits_1.50'. + """ + samples = inputs_queue.dequeue() + + # Add name to input and label nodes so we can add to summary. + samples[common.IMAGE] = tf.identity( + samples[common.IMAGE], name=common.IMAGE) + samples[common.LABEL] = tf.identity( + samples[common.LABEL], name=common.LABEL) + + model_options = common.ModelOptions( + outputs_to_num_classes=outputs_to_num_classes, + crop_size=FLAGS.train_crop_size, + atrous_rates=FLAGS.atrous_rates, + output_stride=FLAGS.output_stride) + outputs_to_scales_to_logits = model.multi_scale_logits( + samples[common.IMAGE], + model_options=model_options, + image_pyramid=FLAGS.image_pyramid, + weight_decay=FLAGS.weight_decay, + is_training=True, + fine_tune_batch_norm=FLAGS.fine_tune_batch_norm) + + # Add name to graph node so we can add to summary. + output_type_dict = outputs_to_scales_to_logits[common.OUTPUT_TYPE] + output_type_dict[model.MERGED_LOGITS_SCOPE] = tf.identity( + output_type_dict[model.MERGED_LOGITS_SCOPE], + name=common.OUTPUT_TYPE) + + for output, num_classes in six.iteritems(outputs_to_num_classes): + train_utils.add_softmax_cross_entropy_loss_for_each_scale( + outputs_to_scales_to_logits[output], + samples[common.LABEL], + num_classes, + ignore_label, + loss_weight=1.0, + upsample_logits=FLAGS.upsample_logits, + scope=output) + + return outputs_to_scales_to_logits + + +def main(unused_argv): + tf.logging.set_verbosity(tf.logging.INFO) + # Set up deployment (i.e., multi-GPUs and/or multi-replicas). + config = model_deploy.DeploymentConfig( + num_clones=FLAGS.num_clones, + clone_on_cpu=FLAGS.clone_on_cpu, + replica_id=FLAGS.task, + num_replicas=FLAGS.num_replicas, + num_ps_tasks=FLAGS.num_ps_tasks) + + # Split the batch across GPUs. + assert FLAGS.train_batch_size % config.num_clones == 0, ( + 'Training batch size not divisble by number of clones (GPUs).') + + clone_batch_size = FLAGS.train_batch_size // config.num_clones + + # Get dataset-dependent information. + dataset = segmentation_dataset.get_dataset( + FLAGS.dataset, FLAGS.train_split, dataset_dir=FLAGS.dataset_dir) + + tf.gfile.MakeDirs(FLAGS.train_logdir) + tf.logging.info('Training on %s set', FLAGS.train_split) + + with tf.Graph().as_default() as graph: + with tf.device(config.inputs_device()): + samples = input_generator.get( + dataset, + FLAGS.train_crop_size, + clone_batch_size, + min_resize_value=FLAGS.min_resize_value, + max_resize_value=FLAGS.max_resize_value, + resize_factor=FLAGS.resize_factor, + min_scale_factor=FLAGS.min_scale_factor, + max_scale_factor=FLAGS.max_scale_factor, + scale_factor_step_size=FLAGS.scale_factor_step_size, + dataset_split=FLAGS.train_split, + is_training=True, + model_variant=FLAGS.model_variant) + inputs_queue = prefetch_queue.prefetch_queue( + samples, capacity=128 * config.num_clones) + + # Create the global step on the device storing the variables. + with tf.device(config.variables_device()): + global_step = tf.train.get_or_create_global_step() + + # Define the model and create clones. + model_fn = _build_deeplab + model_args = (inputs_queue, { + common.OUTPUT_TYPE: dataset.num_classes + }, dataset.ignore_label) + clones = model_deploy.create_clones(config, model_fn, args=model_args) + + # Gather update_ops from the first clone. These contain, for example, + # the updates for the batch_norm variables created by model_fn. + first_clone_scope = config.clone_scope(0) + update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS, first_clone_scope) + + # Gather initial summaries. + summaries = set(tf.get_collection(tf.GraphKeys.SUMMARIES)) + + # Add summaries for model variables. + for model_var in slim.get_model_variables(): + summaries.add(tf.summary.histogram(model_var.op.name, model_var)) + + # Add summaries for images, labels, semantic predictions + if FLAGS.save_summaries_images: + summary_image = graph.get_tensor_by_name( + ('%s/%s:0' % (first_clone_scope, common.IMAGE)).strip('/')) + summaries.add( + tf.summary.image('samples/%s' % common.IMAGE, summary_image)) + + first_clone_label = graph.get_tensor_by_name( + ('%s/%s:0' % (first_clone_scope, common.LABEL)).strip('/')) + # Scale up summary image pixel values for better visualization. + pixel_scaling = max(1, 255 // dataset.num_classes) + summary_label = tf.cast(first_clone_label * pixel_scaling, tf.uint8) + summaries.add( + tf.summary.image('samples/%s' % common.LABEL, summary_label)) + + first_clone_output = graph.get_tensor_by_name( + ('%s/%s:0' % (first_clone_scope, common.OUTPUT_TYPE)).strip('/')) + predictions = tf.expand_dims(tf.argmax(first_clone_output, 3), -1) + + summary_predictions = tf.cast(predictions * pixel_scaling, tf.uint8) + summaries.add( + tf.summary.image( + 'samples/%s' % common.OUTPUT_TYPE, summary_predictions)) + + # Add summaries for losses. + for loss in tf.get_collection(tf.GraphKeys.LOSSES, first_clone_scope): + summaries.add(tf.summary.scalar('losses/%s' % loss.op.name, loss)) + + # Build the optimizer based on the device specification. + with tf.device(config.optimizer_device()): + learning_rate = train_utils.get_model_learning_rate( + FLAGS.learning_policy, FLAGS.base_learning_rate, + FLAGS.learning_rate_decay_step, FLAGS.learning_rate_decay_factor, + FLAGS.training_number_of_steps, FLAGS.learning_power, + FLAGS.slow_start_step, FLAGS.slow_start_learning_rate) + optimizer = tf.train.MomentumOptimizer(learning_rate, FLAGS.momentum) + summaries.add(tf.summary.scalar('learning_rate', learning_rate)) + + startup_delay_steps = FLAGS.task * FLAGS.startup_delay_steps + for variable in slim.get_model_variables(): + summaries.add(tf.summary.histogram(variable.op.name, variable)) + + with tf.device(config.variables_device(distribution_mod=distribution_mod)): + total_loss, grads_and_vars = model_deploy.optimize_clones( + clones, optimizer) + total_loss = tf.check_numerics(total_loss, 'Loss is inf or nan.') + summaries.add(tf.summary.scalar('total_loss', total_loss)) + + # Modify the gradients for biases and last layer variables. + last_layers = model.get_extra_layer_scopes( + FLAGS.last_layers_contain_logits_only) + grad_mult = train_utils.get_model_gradient_multipliers( + last_layers, FLAGS.last_layer_gradient_multiplier) + if grad_mult: + grads_and_vars = slim.learning.multiply_gradients( + grads_and_vars, grad_mult) + + # Create gradient update op. + grad_updates = optimizer.apply_gradients( + grads_and_vars, global_step=global_step) + update_ops.append(grad_updates) + update_op = tf.group(*update_ops) + with tf.control_dependencies([update_op]): + train_tensor = tf.identity(total_loss, name='train_op') + + # Add the summaries from the first clone. These contain the summaries + # created by model_fn and either optimize_clones() or _gather_clone_loss(). + summaries |= set( + tf.get_collection(tf.GraphKeys.SUMMARIES, first_clone_scope)) + + # Merge all summaries together. + summary_op = tf.summary.merge(list(summaries)) + + if FLAGS.disable_layout_optimizer: + rewrite_options = rewriter_config_pb2.RewriterConfig( + layout_optimizer=rewriter_config_pb2.RewriterConfig.OFF) + graph_options = tf.GraphOptions( + rewrite_options=rewrite_options, infer_shapes=True) + session_config = tf.ConfigProto( + allow_soft_placement=True, log_device_placement=False, + graph_options=graph_options) + else: + # Soft placement allows placing on CPU ops without GPU implementation. + session_config = tf.ConfigProto( + allow_soft_placement=True, log_device_placement=False) + + lms = None + if FLAGS.use_tflms: + from tensorflow_large_model_support import LMS + lms = LMS(swapout_threshold=FLAGS.swapout_threshold, swapin_ahead=FLAGS.swapin_ahead, swapin_groupby=FLAGS.swapin_groupby, sync_mode=FLAGS.sync_mode) + + # Start the training. + number_of_steps = FLAGS.training_number_of_steps + + # Adjust the number of steps based on the number of nodes in the + # distrubted training. + if distribution_mod: + number_of_steps = number_of_steps // distribution_mod.size() + + global_step = None + train_step_kwargs = slim.learning._USE_DEFAULT + trace_every_n_steps = None + + log_every_n_steps=FLAGS.log_steps + + # If a distribution mechanism is used, set up the logging and tracing + # to only occur on the rank == 0 node. This section was copied out + # of slim.train.learning and adjusted to change behavior for + # distribution. + if distribution_mod: + from tensorflow.python.training import training_util + from tensorflow.python.ops import math_ops + from tensorflow.python.framework import ops + with graph.as_default(): + global_step = training_util.get_or_create_global_step() + + with ops.name_scope('train_step'): + train_step_kwargs = {} + + if number_of_steps: + should_stop_op = math_ops.greater_equal(global_step, number_of_steps) + else: + should_stop_op = constant_op.constant(False) + train_step_kwargs['should_stop'] = should_stop_op + if (log_every_n_steps > 0 and not distribution_mod) or distribution_mod.rank() == 0: + train_step_kwargs['should_log'] = math_ops.equal( + math_ops.mod(global_step, log_every_n_steps), 0) + if distribution_mod and distribution_mod.rank() == 0 and trace_every_n_steps is not None: + train_step_kwargs['should_trace'] = math_ops.equal( + math_ops.mod(global_step, trace_every_n_steps), 0) + train_step_kwargs['logdir'] = FLAGS.train_logdir + + slim.learning.train( + train_tensor, + train_step_kwargs=train_step_kwargs, + global_step=global_step, + logdir=FLAGS.train_logdir, + log_every_n_steps=log_every_n_steps, + master=FLAGS.master, + number_of_steps=number_of_steps, + is_chief=(FLAGS.task == 0), + session_config=session_config, + startup_delay_steps=startup_delay_steps, + init_fn=train_utils.get_model_init_fn( + FLAGS.train_logdir, + FLAGS.tf_initial_checkpoint, + FLAGS.initialize_last_layer, + last_layers, + ignore_missing_vars=True), + summary_op=summary_op, + save_summaries_secs=FLAGS.save_summaries_secs, + save_interval_secs=FLAGS.save_interval_secs, + lms=lms) + + +if __name__ == '__main__': + flags.mark_flag_as_required('train_logdir') + flags.mark_flag_as_required('tf_initial_checkpoint') + flags.mark_flag_as_required('dataset_dir') + tf.app.run() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/__init__.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/get_dataset_colormap.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/get_dataset_colormap.py new file mode 100644 index 0000000..eff9b19 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/get_dataset_colormap.py @@ -0,0 +1,405 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Visualizes the segmentation results via specified color map. + +Visualizes the semantic segmentation results by the color map +defined by the different datasets. Supported colormaps are: + +* ADE20K (http://groups.csail.mit.edu/vision/datasets/ADE20K/). + +* Cityscapes dataset (https://www.cityscapes-dataset.com). + +* Mapillary Vistas (https://research.mapillary.com). + +* PASCAL VOC 2012 (http://host.robots.ox.ac.uk/pascal/VOC/). +""" + +import numpy as np + +# Dataset names. +_ADE20K = 'ade20k' +_CITYSCAPES = 'cityscapes' +_MAPILLARY_VISTAS = 'mapillary_vistas' +_PASCAL = 'pascal' + +# Max number of entries in the colormap for each dataset. +_DATASET_MAX_ENTRIES = { + _ADE20K: 151, + _CITYSCAPES: 19, + _MAPILLARY_VISTAS: 66, + _PASCAL: 256, +} + + +def create_ade20k_label_colormap(): + """Creates a label colormap used in ADE20K segmentation benchmark. + + Returns: + A colormap for visualizing segmentation results. + """ + return np.asarray([ + [0, 0, 0], + [120, 120, 120], + [180, 120, 120], + [6, 230, 230], + [80, 50, 50], + [4, 200, 3], + [120, 120, 80], + [140, 140, 140], + [204, 5, 255], + [230, 230, 230], + [4, 250, 7], + [224, 5, 255], + [235, 255, 7], + [150, 5, 61], + [120, 120, 70], + [8, 255, 51], + [255, 6, 82], + [143, 255, 140], + [204, 255, 4], + [255, 51, 7], + [204, 70, 3], + [0, 102, 200], + [61, 230, 250], + [255, 6, 51], + [11, 102, 255], + [255, 7, 71], + [255, 9, 224], + [9, 7, 230], + [220, 220, 220], + [255, 9, 92], + [112, 9, 255], + [8, 255, 214], + [7, 255, 224], + [255, 184, 6], + [10, 255, 71], + [255, 41, 10], + [7, 255, 255], + [224, 255, 8], + [102, 8, 255], + [255, 61, 6], + [255, 194, 7], + [255, 122, 8], + [0, 255, 20], + [255, 8, 41], + [255, 5, 153], + [6, 51, 255], + [235, 12, 255], + [160, 150, 20], + [0, 163, 255], + [140, 140, 140], + [250, 10, 15], + [20, 255, 0], + [31, 255, 0], + [255, 31, 0], + [255, 224, 0], + [153, 255, 0], + [0, 0, 255], + [255, 71, 0], + [0, 235, 255], + [0, 173, 255], + [31, 0, 255], + [11, 200, 200], + [255, 82, 0], + [0, 255, 245], + [0, 61, 255], + [0, 255, 112], + [0, 255, 133], + [255, 0, 0], + [255, 163, 0], + [255, 102, 0], + [194, 255, 0], + [0, 143, 255], + [51, 255, 0], + [0, 82, 255], + [0, 255, 41], + [0, 255, 173], + [10, 0, 255], + [173, 255, 0], + [0, 255, 153], + [255, 92, 0], + [255, 0, 255], + [255, 0, 245], + [255, 0, 102], + [255, 173, 0], + [255, 0, 20], + [255, 184, 184], + [0, 31, 255], + [0, 255, 61], + [0, 71, 255], + [255, 0, 204], + [0, 255, 194], + [0, 255, 82], + [0, 10, 255], + [0, 112, 255], + [51, 0, 255], + [0, 194, 255], + [0, 122, 255], + [0, 255, 163], + [255, 153, 0], + [0, 255, 10], + [255, 112, 0], + [143, 255, 0], + [82, 0, 255], + [163, 255, 0], + [255, 235, 0], + [8, 184, 170], + [133, 0, 255], + [0, 255, 92], + [184, 0, 255], + [255, 0, 31], + [0, 184, 255], + [0, 214, 255], + [255, 0, 112], + [92, 255, 0], + [0, 224, 255], + [112, 224, 255], + [70, 184, 160], + [163, 0, 255], + [153, 0, 255], + [71, 255, 0], + [255, 0, 163], + [255, 204, 0], + [255, 0, 143], + [0, 255, 235], + [133, 255, 0], + [255, 0, 235], + [245, 0, 255], + [255, 0, 122], + [255, 245, 0], + [10, 190, 212], + [214, 255, 0], + [0, 204, 255], + [20, 0, 255], + [255, 255, 0], + [0, 153, 255], + [0, 41, 255], + [0, 255, 204], + [41, 0, 255], + [41, 255, 0], + [173, 0, 255], + [0, 245, 255], + [71, 0, 255], + [122, 0, 255], + [0, 255, 184], + [0, 92, 255], + [184, 255, 0], + [0, 133, 255], + [255, 214, 0], + [25, 194, 194], + [102, 255, 0], + [92, 0, 255], + ]) + + +def create_cityscapes_label_colormap(): + """Creates a label colormap used in CITYSCAPES segmentation benchmark. + + Returns: + A colormap for visualizing segmentation results. + """ + return np.asarray([ + [128, 64, 128], + [244, 35, 232], + [70, 70, 70], + [102, 102, 156], + [190, 153, 153], + [153, 153, 153], + [250, 170, 30], + [220, 220, 0], + [107, 142, 35], + [152, 251, 152], + [70, 130, 180], + [220, 20, 60], + [255, 0, 0], + [0, 0, 142], + [0, 0, 70], + [0, 60, 100], + [0, 80, 100], + [0, 0, 230], + [119, 11, 32], + ]) + + +def create_mapillary_vistas_label_colormap(): + """Creates a label colormap used in Mapillary Vistas segmentation benchmark. + + Returns: + A colormap for visualizing segmentation results. + """ + return np.asarray([ + [165, 42, 42], + [0, 192, 0], + [196, 196, 196], + [190, 153, 153], + [180, 165, 180], + [102, 102, 156], + [102, 102, 156], + [128, 64, 255], + [140, 140, 200], + [170, 170, 170], + [250, 170, 160], + [96, 96, 96], + [230, 150, 140], + [128, 64, 128], + [110, 110, 110], + [244, 35, 232], + [150, 100, 100], + [70, 70, 70], + [150, 120, 90], + [220, 20, 60], + [255, 0, 0], + [255, 0, 0], + [255, 0, 0], + [200, 128, 128], + [255, 255, 255], + [64, 170, 64], + [128, 64, 64], + [70, 130, 180], + [255, 255, 255], + [152, 251, 152], + [107, 142, 35], + [0, 170, 30], + [255, 255, 128], + [250, 0, 30], + [0, 0, 0], + [220, 220, 220], + [170, 170, 170], + [222, 40, 40], + [100, 170, 30], + [40, 40, 40], + [33, 33, 33], + [170, 170, 170], + [0, 0, 142], + [170, 170, 170], + [210, 170, 100], + [153, 153, 153], + [128, 128, 128], + [0, 0, 142], + [250, 170, 30], + [192, 192, 192], + [220, 220, 0], + [180, 165, 180], + [119, 11, 32], + [0, 0, 142], + [0, 60, 100], + [0, 0, 142], + [0, 0, 90], + [0, 0, 230], + [0, 80, 100], + [128, 64, 64], + [0, 0, 110], + [0, 0, 70], + [0, 0, 192], + [32, 32, 32], + [0, 0, 0], + [0, 0, 0], + ]) + + +def create_pascal_label_colormap(): + """Creates a label colormap used in PASCAL VOC segmentation benchmark. + + Returns: + A colormap for visualizing segmentation results. + """ + colormap = np.zeros((_DATASET_MAX_ENTRIES[_PASCAL], 3), dtype=int) + ind = np.arange(_DATASET_MAX_ENTRIES[_PASCAL], dtype=int) + + for shift in reversed(range(8)): + for channel in range(3): + colormap[:, channel] |= bit_get(ind, channel) << shift + ind >>= 3 + + return colormap + + +def get_ade20k_name(): + return _ADE20K + + +def get_cityscapes_name(): + return _CITYSCAPES + + +def get_mapillary_vistas_name(): + return _MAPILLARY_VISTAS + + +def get_pascal_name(): + return _PASCAL + + +def bit_get(val, idx): + """Gets the bit value. + + Args: + val: Input value, int or numpy int array. + idx: Which bit of the input val. + + Returns: + The "idx"-th bit of input val. + """ + return (val >> idx) & 1 + + +def create_label_colormap(dataset=_PASCAL): + """Creates a label colormap for the specified dataset. + + Args: + dataset: The colormap used in the dataset. + + Returns: + A numpy array of the dataset colormap. + + Raises: + ValueError: If the dataset is not supported. + """ + if dataset == _ADE20K: + return create_ade20k_label_colormap() + elif dataset == _CITYSCAPES: + return create_cityscapes_label_colormap() + elif dataset == _MAPILLARY_VISTAS: + return create_mapillary_vistas_label_colormap() + elif dataset == _PASCAL: + return create_pascal_label_colormap() + else: + raise ValueError('Unsupported dataset.') + + +def label_to_color_image(label, dataset=_PASCAL): + """Adds color defined by the dataset colormap to the label. + + Args: + label: A 2D array with integer type, storing the segmentation label. + dataset: The colormap used in the dataset. + + Returns: + result: A 2D array with floating type. The element of the array + is the color indexed by the corresponding element in the input label + to the dataset color map. + + Raises: + ValueError: If label is not of rank 2 or its value is larger than color + map maximum entry. + """ + if label.ndim != 2: + raise ValueError('Expect 2-D input label') + + if np.max(label) >= _DATASET_MAX_ENTRIES[dataset]: + raise ValueError('label value too large.') + + colormap = create_label_colormap(dataset) + return colormap[label] diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/get_dataset_colormap_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/get_dataset_colormap_test.py new file mode 100644 index 0000000..676beb1 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/get_dataset_colormap_test.py @@ -0,0 +1,96 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Tests for get_dataset_colormap.py.""" + +import numpy as np +import tensorflow as tf + +from deeplab.utils import get_dataset_colormap + + +class VisualizationUtilTest(tf.test.TestCase): + + def testBitGet(self): + """Test that if the returned bit value is correct.""" + self.assertEqual(1, get_dataset_colormap.bit_get(9, 0)) + self.assertEqual(0, get_dataset_colormap.bit_get(9, 1)) + self.assertEqual(0, get_dataset_colormap.bit_get(9, 2)) + self.assertEqual(1, get_dataset_colormap.bit_get(9, 3)) + + def testPASCALLabelColorMapValue(self): + """Test the getd color map value.""" + colormap = get_dataset_colormap.create_pascal_label_colormap() + + # Only test a few sampled entries in the color map. + self.assertTrue(np.array_equal([128., 0., 128.], colormap[5, :])) + self.assertTrue(np.array_equal([128., 192., 128.], colormap[23, :])) + self.assertTrue(np.array_equal([128., 0., 192.], colormap[37, :])) + self.assertTrue(np.array_equal([224., 192., 192.], colormap[127, :])) + self.assertTrue(np.array_equal([192., 160., 192.], colormap[175, :])) + + def testLabelToPASCALColorImage(self): + """Test the value of the converted label value.""" + label = np.array([[0, 16, 16], [52, 7, 52]]) + expected_result = np.array([ + [[0, 0, 0], [0, 64, 0], [0, 64, 0]], + [[0, 64, 192], [128, 128, 128], [0, 64, 192]] + ]) + colored_label = get_dataset_colormap.label_to_color_image( + label, get_dataset_colormap.get_pascal_name()) + self.assertTrue(np.array_equal(expected_result, colored_label)) + + def testUnExpectedLabelValueForLabelToPASCALColorImage(self): + """Raise ValueError when input value exceeds range.""" + label = np.array([[120], [300]]) + with self.assertRaises(ValueError): + get_dataset_colormap.label_to_color_image( + label, get_dataset_colormap.get_pascal_name()) + + def testUnExpectedLabelDimensionForLabelToPASCALColorImage(self): + """Raise ValueError if input dimension is not correct.""" + label = np.array([120]) + with self.assertRaises(ValueError): + get_dataset_colormap.label_to_color_image( + label, get_dataset_colormap.get_pascal_name()) + + def testGetColormapForUnsupportedDataset(self): + with self.assertRaises(ValueError): + get_dataset_colormap.create_label_colormap('unsupported_dataset') + + def testUnExpectedLabelDimensionForLabelToADE20KColorImage(self): + label = np.array([250]) + with self.assertRaises(ValueError): + get_dataset_colormap.label_to_color_image( + label, get_dataset_colormap.get_ade20k_name()) + + def testFirstColorInADE20KColorMap(self): + label = np.array([[1, 3], [10, 20]]) + expected_result = np.array([ + [[120, 120, 120], [6, 230, 230]], + [[4, 250, 7], [204, 70, 3]] + ]) + colored_label = get_dataset_colormap.label_to_color_image( + label, get_dataset_colormap.get_ade20k_name()) + self.assertTrue(np.array_equal(colored_label, expected_result)) + + def testMapillaryVistasColorMapValue(self): + colormap = get_dataset_colormap.create_mapillary_vistas_label_colormap() + self.assertTrue(np.array_equal([190, 153, 153], colormap[3, :])) + self.assertTrue(np.array_equal([102, 102, 156], colormap[6, :])) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/input_generator.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/input_generator.py new file mode 100644 index 0000000..4d4d09a --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/input_generator.py @@ -0,0 +1,168 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Wrapper for providing semantic segmentation data.""" + +import tensorflow as tf +from deeplab import common +from deeplab import input_preprocess + +slim = tf.contrib.slim + +dataset_data_provider = slim.dataset_data_provider + + +def _get_data(data_provider, dataset_split): + """Gets data from data provider. + + Args: + data_provider: An object of slim.data_provider. + dataset_split: Dataset split. + + Returns: + image: Image Tensor. + label: Label Tensor storing segmentation annotations. + image_name: Image name. + height: Image height. + width: Image width. + + Raises: + ValueError: Failed to find label. + """ + if common.LABELS_CLASS not in data_provider.list_items(): + raise ValueError('Failed to find labels.') + + image, height, width = data_provider.get( + [common.IMAGE, common.HEIGHT, common.WIDTH]) + + # Some datasets do not contain image_name. + if common.IMAGE_NAME in data_provider.list_items(): + image_name, = data_provider.get([common.IMAGE_NAME]) + else: + image_name = tf.constant('') + + label = None + if dataset_split != common.TEST_SET: + label, = data_provider.get([common.LABELS_CLASS]) + + return image, label, image_name, height, width + + +def get(dataset, + crop_size, + batch_size, + min_resize_value=None, + max_resize_value=None, + resize_factor=None, + min_scale_factor=1., + max_scale_factor=1., + scale_factor_step_size=0, + num_readers=1, + num_threads=1, + dataset_split=None, + is_training=True, + model_variant=None): + """Gets the dataset split for semantic segmentation. + + This functions gets the dataset split for semantic segmentation. In + particular, it is a wrapper of (1) dataset_data_provider which returns the raw + dataset split, (2) input_preprcess which preprocess the raw data, and (3) the + Tensorflow operation of batching the preprocessed data. Then, the output could + be directly used by training, evaluation or visualization. + + Args: + dataset: An instance of slim Dataset. + crop_size: Image crop size [height, width]. + batch_size: Batch size. + min_resize_value: Desired size of the smaller image side. + max_resize_value: Maximum allowed size of the larger image side. + resize_factor: Resized dimensions are multiple of factor plus one. + min_scale_factor: Minimum scale factor value. + max_scale_factor: Maximum scale factor value. + scale_factor_step_size: The step size from min scale factor to max scale + factor. The input is randomly scaled based on the value of + (min_scale_factor, max_scale_factor, scale_factor_step_size). + num_readers: Number of readers for data provider. + num_threads: Number of threads for batching data. + dataset_split: Dataset split. + is_training: Is training or not. + model_variant: Model variant (string) for choosing how to mean-subtract the + images. See feature_extractor.network_map for supported model variants. + + Returns: + A dictionary of batched Tensors for semantic segmentation. + + Raises: + ValueError: dataset_split is None, failed to find labels, or label shape + is not valid. + """ + if dataset_split is None: + raise ValueError('Unknown dataset split.') + if model_variant is None: + tf.logging.warning('Please specify a model_variant. See ' + 'feature_extractor.network_map for supported model ' + 'variants.') + + data_provider = dataset_data_provider.DatasetDataProvider( + dataset, + num_readers=num_readers, + num_epochs=None if is_training else 1, + shuffle=is_training) + image, label, image_name, height, width = _get_data(data_provider, + dataset_split) + if label is not None: + if label.shape.ndims == 2: + label = tf.expand_dims(label, 2) + elif label.shape.ndims == 3 and label.shape.dims[2] == 1: + pass + else: + raise ValueError('Input label shape must be [height, width], or ' + '[height, width, 1].') + + label.set_shape([None, None, 1]) + original_image, image, label = input_preprocess.preprocess_image_and_label( + image, + label, + crop_height=crop_size[0], + crop_width=crop_size[1], + min_resize_value=min_resize_value, + max_resize_value=max_resize_value, + resize_factor=resize_factor, + min_scale_factor=min_scale_factor, + max_scale_factor=max_scale_factor, + scale_factor_step_size=scale_factor_step_size, + ignore_label=dataset.ignore_label, + is_training=is_training, + model_variant=model_variant) + sample = { + common.IMAGE: image, + common.IMAGE_NAME: image_name, + common.HEIGHT: height, + common.WIDTH: width + } + if label is not None: + sample[common.LABEL] = label + + if not is_training: + # Original image is only used during visualization. + sample[common.ORIGINAL_IMAGE] = original_image, + num_threads = 1 + + return tf.train.batch( + sample, + batch_size=batch_size, + num_threads=num_threads, + capacity=32 * batch_size, + allow_smaller_final_batch=not is_training, + dynamic_pad=True) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/save_annotation.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/save_annotation.py new file mode 100644 index 0000000..9f3c7e7 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/save_annotation.py @@ -0,0 +1,52 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Saves an annotation as one png image. + +This script saves an annotation as one png image, and has the option to add +colormap to the png image for better visualization. +""" + +import numpy as np +import PIL.Image as img +import tensorflow as tf + +from deeplab.utils import get_dataset_colormap + + +def save_annotation(label, + save_dir, + filename, + add_colormap=True, + colormap_type=get_dataset_colormap.get_pascal_name()): + """Saves the given label to image on disk. + + Args: + label: The numpy array to be saved. The data will be converted + to uint8 and saved as png image. + save_dir: The directory to which the results will be saved. + filename: The image filename. + add_colormap: Add color map to the label or not. + colormap_type: Colormap type for visualization. + """ + # Add colormap for visualizing the prediction. + if add_colormap: + colored_label = get_dataset_colormap.label_to_color_image( + label, colormap_type) + else: + colored_label = label + + pil_image = img.fromarray(colored_label.astype(dtype=np.uint8)) + with tf.gfile.Open('%s/%s.png' % (save_dir, filename), mode='w') as f: + pil_image.save(f, 'PNG') diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/train_utils.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/train_utils.py new file mode 100644 index 0000000..4eeffb1 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/utils/train_utils.py @@ -0,0 +1,211 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Utility functions for training.""" + +import six + +import tensorflow as tf +from deeplab.core import preprocess_utils + +slim = tf.contrib.slim + + +def add_softmax_cross_entropy_loss_for_each_scale(scales_to_logits, + labels, + num_classes, + ignore_label, + loss_weight=1.0, + upsample_logits=True, + scope=None): + """Adds softmax cross entropy loss for logits of each scale. + + Args: + scales_to_logits: A map from logits names for different scales to logits. + The logits have shape [batch, logits_height, logits_width, num_classes]. + labels: Groundtruth labels with shape [batch, image_height, image_width, 1]. + num_classes: Integer, number of target classes. + ignore_label: Integer, label to ignore. + loss_weight: Float, loss weight. + upsample_logits: Boolean, upsample logits or not. + scope: String, the scope for the loss. + + Raises: + ValueError: Label or logits is None. + """ + if labels is None: + raise ValueError('No label for softmax cross entropy loss.') + + for scale, logits in six.iteritems(scales_to_logits): + loss_scope = None + if scope: + loss_scope = '%s_%s' % (scope, scale) + + if upsample_logits: + # Label is not downsampled, and instead we upsample logits. + logits = tf.image.resize_bilinear( + logits, + preprocess_utils.resolve_shape(labels, 4)[1:3], + align_corners=True) + scaled_labels = labels + else: + # Label is downsampled to the same size as logits. + scaled_labels = tf.image.resize_nearest_neighbor( + labels, + preprocess_utils.resolve_shape(logits, 4)[1:3], + align_corners=True) + + scaled_labels = tf.reshape(scaled_labels, shape=[-1]) + not_ignore_mask = tf.to_float(tf.not_equal(scaled_labels, + ignore_label)) * loss_weight + one_hot_labels = slim.one_hot_encoding( + scaled_labels, num_classes, on_value=1.0, off_value=0.0) + tf.losses.softmax_cross_entropy( + one_hot_labels, + tf.reshape(logits, shape=[-1, num_classes]), + weights=not_ignore_mask, + scope=loss_scope) + + +def get_model_init_fn(train_logdir, + tf_initial_checkpoint, + initialize_last_layer, + last_layers, + ignore_missing_vars=False): + """Gets the function initializing model variables from a checkpoint. + + Args: + train_logdir: Log directory for training. + tf_initial_checkpoint: TensorFlow checkpoint for initialization. + initialize_last_layer: Initialize last layer or not. + last_layers: Last layers of the model. + ignore_missing_vars: Ignore missing variables in the checkpoint. + + Returns: + Initialization function. + """ + if tf_initial_checkpoint is None: + tf.logging.info('Not initializing the model from a checkpoint.') + return None + + if tf.train.latest_checkpoint(train_logdir): + tf.logging.info('Ignoring initialization; other checkpoint exists') + return None + + tf.logging.info('Initializing model from path: %s', tf_initial_checkpoint) + + # Variables that will not be restored. + exclude_list = ['global_step'] + if not initialize_last_layer: + exclude_list.extend(last_layers) + + variables_to_restore = slim.get_variables_to_restore(exclude=exclude_list) + + if variables_to_restore: + return slim.assign_from_checkpoint_fn( + tf_initial_checkpoint, + variables_to_restore, + ignore_missing_vars=ignore_missing_vars) + return None + + +def get_model_gradient_multipliers(last_layers, last_layer_gradient_multiplier): + """Gets the gradient multipliers. + + The gradient multipliers will adjust the learning rates for model + variables. For the task of semantic segmentation, the models are + usually fine-tuned from the models trained on the task of image + classification. To fine-tune the models, we usually set larger (e.g., + 10 times larger) learning rate for the parameters of last layer. + + Args: + last_layers: Scopes of last layers. + last_layer_gradient_multiplier: The gradient multiplier for last layers. + + Returns: + The gradient multiplier map with variables as key, and multipliers as value. + """ + gradient_multipliers = {} + + for var in slim.get_model_variables(): + # Double the learning rate for biases. + if 'biases' in var.op.name: + gradient_multipliers[var.op.name] = 2. + + # Use larger learning rate for last layer variables. + for layer in last_layers: + if layer in var.op.name and 'biases' in var.op.name: + gradient_multipliers[var.op.name] = 2 * last_layer_gradient_multiplier + break + elif layer in var.op.name: + gradient_multipliers[var.op.name] = last_layer_gradient_multiplier + break + + return gradient_multipliers + + +def get_model_learning_rate( + learning_policy, base_learning_rate, learning_rate_decay_step, + learning_rate_decay_factor, training_number_of_steps, learning_power, + slow_start_step, slow_start_learning_rate): + """Gets model's learning rate. + + Computes the model's learning rate for different learning policy. + Right now, only "step" and "poly" are supported. + (1) The learning policy for "step" is computed as follows: + current_learning_rate = base_learning_rate * + learning_rate_decay_factor ^ (global_step / learning_rate_decay_step) + See tf.train.exponential_decay for details. + (2) The learning policy for "poly" is computed as follows: + current_learning_rate = base_learning_rate * + (1 - global_step / training_number_of_steps) ^ learning_power + + Args: + learning_policy: Learning rate policy for training. + base_learning_rate: The base learning rate for model training. + learning_rate_decay_step: Decay the base learning rate at a fixed step. + learning_rate_decay_factor: The rate to decay the base learning rate. + training_number_of_steps: Number of steps for training. + learning_power: Power used for 'poly' learning policy. + slow_start_step: Training model with small learning rate for the first + few steps. + slow_start_learning_rate: The learning rate employed during slow start. + + Returns: + Learning rate for the specified learning policy. + + Raises: + ValueError: If learning policy is not recognized. + """ + global_step = tf.train.get_or_create_global_step() + if learning_policy == 'step': + learning_rate = tf.train.exponential_decay( + base_learning_rate, + global_step, + learning_rate_decay_step, + learning_rate_decay_factor, + staircase=True) + elif learning_policy == 'poly': + learning_rate = tf.train.polynomial_decay( + base_learning_rate, + global_step, + training_number_of_steps, + end_learning_rate=0, + power=learning_power) + else: + raise ValueError('Unknown learning policy.') + + # Employ small learning rate at the first few steps for warm start. + return tf.where(global_step < slow_start_step, slow_start_learning_rate, + learning_rate) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/vis.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/vis.py new file mode 100644 index 0000000..9f75d10 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/vis.py @@ -0,0 +1,320 @@ +# Copyright 2018 The TensorFlow Authors All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Segmentation results visualization on a given set of images. + +See model.py for more details and usage. +""" +import math +import os.path +import time +import numpy as np +import tensorflow as tf +from deeplab import common +from deeplab import model +from deeplab.datasets import segmentation_dataset +from deeplab.utils import input_generator +from deeplab.utils import save_annotation + +slim = tf.contrib.slim + +flags = tf.app.flags + +FLAGS = flags.FLAGS + +flags.DEFINE_string('master', '', 'BNS name of the tensorflow server') + +# Settings for log directories. + +flags.DEFINE_string('vis_logdir', None, 'Where to write the event logs.') + +flags.DEFINE_string('checkpoint_dir', None, 'Directory of model checkpoints.') + +# Settings for visualizing the model. + +flags.DEFINE_integer('vis_batch_size', 1, + 'The number of images in each batch during evaluation.') + +flags.DEFINE_multi_integer('vis_crop_size', [513, 513], + 'Crop size [height, width] for visualization.') + +flags.DEFINE_integer('eval_interval_secs', 60 * 5, + 'How often (in seconds) to run evaluation.') + +# For `xception_65`, use atrous_rates = [12, 24, 36] if output_stride = 8, or +# rates = [6, 12, 18] if output_stride = 16. For `mobilenet_v2`, use None. Note +# one could use different atrous_rates/output_stride during training/evaluation. +flags.DEFINE_multi_integer('atrous_rates', None, + 'Atrous rates for atrous spatial pyramid pooling.') + +flags.DEFINE_integer('output_stride', 16, + 'The ratio of input to output spatial resolution.') + +# Change to [0.5, 0.75, 1.0, 1.25, 1.5, 1.75] for multi-scale test. +flags.DEFINE_multi_float('eval_scales', [1.0], + 'The scales to resize images for evaluation.') + +# Change to True for adding flipped images during test. +flags.DEFINE_bool('add_flipped_images', False, + 'Add flipped images for evaluation or not.') + +# Dataset settings. + +flags.DEFINE_string('dataset', 'pascal_voc_seg', + 'Name of the segmentation dataset.') + +flags.DEFINE_string('vis_split', 'val', + 'Which split of the dataset used for visualizing results') + +flags.DEFINE_string('dataset_dir', None, 'Where the dataset reside.') + +flags.DEFINE_enum('colormap_type', 'pascal', ['pascal', 'cityscapes'], + 'Visualization colormap type.') + +flags.DEFINE_boolean('also_save_raw_predictions', False, + 'Also save raw predictions.') + +flags.DEFINE_integer('max_number_of_iterations', 0, + 'Maximum number of visualization iterations. Will loop ' + 'indefinitely upon nonpositive values.') + +# The folder where semantic segmentation predictions are saved. +_SEMANTIC_PREDICTION_SAVE_FOLDER = 'segmentation_results' + +# The folder where raw semantic segmentation predictions are saved. +_RAW_SEMANTIC_PREDICTION_SAVE_FOLDER = 'raw_segmentation_results' + +# The format to save image. +_IMAGE_FORMAT = '%06d_image' + +# The format to save prediction +_PREDICTION_FORMAT = '%06d_prediction' + +# To evaluate Cityscapes results on the evaluation server, the labels used +# during training should be mapped to the labels for evaluation. +_CITYSCAPES_TRAIN_ID_TO_EVAL_ID = [7, 8, 11, 12, 13, 17, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 31, 32, 33] + + +def _convert_train_id_to_eval_id(prediction, train_id_to_eval_id): + """Converts the predicted label for evaluation. + + There are cases where the training labels are not equal to the evaluation + labels. This function is used to perform the conversion so that we could + evaluate the results on the evaluation server. + + Args: + prediction: Semantic segmentation prediction. + train_id_to_eval_id: A list mapping from train id to evaluation id. + + Returns: + Semantic segmentation prediction whose labels have been changed. + """ + converted_prediction = prediction.copy() + for train_id, eval_id in enumerate(train_id_to_eval_id): + converted_prediction[prediction == train_id] = eval_id + + return converted_prediction + + +def _process_batch(sess, original_images, semantic_predictions, image_names, + image_heights, image_widths, image_id_offset, save_dir, + raw_save_dir, train_id_to_eval_id=None): + """Evaluates one single batch qualitatively. + + Args: + sess: TensorFlow session. + original_images: One batch of original images. + semantic_predictions: One batch of semantic segmentation predictions. + image_names: Image names. + image_heights: Image heights. + image_widths: Image widths. + image_id_offset: Image id offset for indexing images. + save_dir: The directory where the predictions will be saved. + raw_save_dir: The directory where the raw predictions will be saved. + train_id_to_eval_id: A list mapping from train id to eval id. + """ + (original_images, + semantic_predictions, + image_names, + image_heights, + image_widths) = sess.run([original_images, semantic_predictions, + image_names, image_heights, image_widths]) + + num_image = semantic_predictions.shape[0] + for i in range(num_image): + image_height = np.squeeze(image_heights[i]) + image_width = np.squeeze(image_widths[i]) + original_image = np.squeeze(original_images[i]) + semantic_prediction = np.squeeze(semantic_predictions[i]) + crop_semantic_prediction = semantic_prediction[:image_height, :image_width] + + # Save image. + save_annotation.save_annotation( + original_image, save_dir, _IMAGE_FORMAT % (image_id_offset + i), + add_colormap=False) + + # Save prediction. + save_annotation.save_annotation( + crop_semantic_prediction, save_dir, + _PREDICTION_FORMAT % (image_id_offset + i), add_colormap=True, + colormap_type=FLAGS.colormap_type) + + if FLAGS.also_save_raw_predictions: + image_filename = os.path.basename(image_names[i]) + + if train_id_to_eval_id is not None: + crop_semantic_prediction = _convert_train_id_to_eval_id( + crop_semantic_prediction, + train_id_to_eval_id) + save_annotation.save_annotation( + crop_semantic_prediction, raw_save_dir, image_filename, + add_colormap=False) + + +def main(unused_argv): + tf.logging.set_verbosity(tf.logging.INFO) + # Get dataset-dependent information. + dataset = segmentation_dataset.get_dataset( + FLAGS.dataset, FLAGS.vis_split, dataset_dir=FLAGS.dataset_dir) + train_id_to_eval_id = None + if dataset.name == segmentation_dataset.get_cityscapes_dataset_name(): + tf.logging.info('Cityscapes requires converting train_id to eval_id.') + train_id_to_eval_id = _CITYSCAPES_TRAIN_ID_TO_EVAL_ID + + # Prepare for visualization. + tf.gfile.MakeDirs(FLAGS.vis_logdir) + save_dir = os.path.join(FLAGS.vis_logdir, _SEMANTIC_PREDICTION_SAVE_FOLDER) + tf.gfile.MakeDirs(save_dir) + raw_save_dir = os.path.join( + FLAGS.vis_logdir, _RAW_SEMANTIC_PREDICTION_SAVE_FOLDER) + tf.gfile.MakeDirs(raw_save_dir) + + tf.logging.info('Visualizing on %s set', FLAGS.vis_split) + + g = tf.Graph() + with g.as_default(): + samples = input_generator.get(dataset, + FLAGS.vis_crop_size, + FLAGS.vis_batch_size, + min_resize_value=FLAGS.min_resize_value, + max_resize_value=FLAGS.max_resize_value, + resize_factor=FLAGS.resize_factor, + dataset_split=FLAGS.vis_split, + is_training=False, + model_variant=FLAGS.model_variant) + + model_options = common.ModelOptions( + outputs_to_num_classes={common.OUTPUT_TYPE: dataset.num_classes}, + crop_size=FLAGS.vis_crop_size, + atrous_rates=FLAGS.atrous_rates, + output_stride=FLAGS.output_stride) + + if tuple(FLAGS.eval_scales) == (1.0,): + tf.logging.info('Performing single-scale test.') + predictions = model.predict_labels( + samples[common.IMAGE], + model_options=model_options, + image_pyramid=FLAGS.image_pyramid) + else: + tf.logging.info('Performing multi-scale test.') + predictions = model.predict_labels_multi_scale( + samples[common.IMAGE], + model_options=model_options, + eval_scales=FLAGS.eval_scales, + add_flipped_images=FLAGS.add_flipped_images) + predictions = predictions[common.OUTPUT_TYPE] + + if FLAGS.min_resize_value and FLAGS.max_resize_value: + # Only support batch_size = 1, since we assume the dimensions of original + # image after tf.squeeze is [height, width, 3]. + assert FLAGS.vis_batch_size == 1 + + # Reverse the resizing and padding operations performed in preprocessing. + # First, we slice the valid regions (i.e., remove padded region) and then + # we reisze the predictions back. + original_image = tf.squeeze(samples[common.ORIGINAL_IMAGE]) + original_image_shape = tf.shape(original_image) + predictions = tf.slice( + predictions, + [0, 0, 0], + [1, original_image_shape[0], original_image_shape[1]]) + resized_shape = tf.to_int32([tf.squeeze(samples[common.HEIGHT]), + tf.squeeze(samples[common.WIDTH])]) + predictions = tf.squeeze( + tf.image.resize_images(tf.expand_dims(predictions, 3), + resized_shape, + method=tf.image.ResizeMethod.NEAREST_NEIGHBOR, + align_corners=True), 3) + + tf.train.get_or_create_global_step() + saver = tf.train.Saver(slim.get_variables_to_restore()) + sv = tf.train.Supervisor(graph=g, + logdir=FLAGS.vis_logdir, + init_op=tf.global_variables_initializer(), + summary_op=None, + summary_writer=None, + global_step=None, + saver=saver) + num_batches = int(math.ceil( + dataset.num_samples / float(FLAGS.vis_batch_size))) + last_checkpoint = None + + # Loop to visualize the results when new checkpoint is created. + num_iters = 0 + while (FLAGS.max_number_of_iterations <= 0 or + num_iters < FLAGS.max_number_of_iterations): + num_iters += 1 + last_checkpoint = slim.evaluation.wait_for_new_checkpoint( + FLAGS.checkpoint_dir, last_checkpoint) + start = time.time() + tf.logging.info( + 'Starting visualization at ' + time.strftime('%Y-%m-%d-%H:%M:%S', + time.gmtime())) + tf.logging.info('Visualizing with model %s', last_checkpoint) + + with sv.managed_session(FLAGS.master, + start_standard_services=False) as sess: + sv.start_queue_runners(sess) + sv.saver.restore(sess, last_checkpoint) + + image_id_offset = 0 + for batch in range(num_batches): + tf.logging.info('Visualizing batch %d / %d', batch + 1, num_batches) + _process_batch(sess=sess, + original_images=samples[common.ORIGINAL_IMAGE], + semantic_predictions=predictions, + image_names=samples[common.IMAGE_NAME], + image_heights=samples[common.HEIGHT], + image_widths=samples[common.WIDTH], + image_id_offset=image_id_offset, + save_dir=save_dir, + raw_save_dir=raw_save_dir, + train_id_to_eval_id=train_id_to_eval_id) + image_id_offset += FLAGS.vis_batch_size + + tf.logging.info( + 'Finished visualization at ' + time.strftime('%Y-%m-%d-%H:%M:%S', + time.gmtime())) + time_to_next_eval = start + FLAGS.eval_interval_secs - time.time() + if time_to_next_eval > 0: + time.sleep(time_to_next_eval) + + +if __name__ == '__main__': + flags.mark_flag_as_required('checkpoint_dir') + flags.mark_flag_as_required('vis_logdir') + flags.mark_flag_as_required('dataset_dir') + tf.app.run() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/BUILD b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/BUILD new file mode 100644 index 0000000..df22311 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/BUILD @@ -0,0 +1,820 @@ +# Description: +# Contains files for loading, training and evaluating TF-Slim-based models. + +package( + default_visibility = ["//visibility:public"], +) + +licenses(["notice"]) # Apache 2.0 + +exports_files(["LICENSE"]) + +py_library( + name = "dataset_utils", + srcs = ["datasets/dataset_utils.py"], + deps = [ + # "//tensorflow", + ], +) + +sh_binary( + name = "download_and_convert_imagenet", + srcs = ["datasets/download_and_convert_imagenet.sh"], + data = [ + "datasets/download_imagenet.sh", + "datasets/imagenet_2012_validation_synset_labels.txt", + "datasets/imagenet_lsvrc_2015_synsets.txt", + "datasets/imagenet_metadata.txt", + "datasets/preprocess_imagenet_validation_data.py", + "datasets/process_bounding_boxes.py", + ":build_imagenet_data", + ], +) + +py_binary( + name = "build_imagenet_data", + srcs = ["datasets/build_imagenet_data.py"], + deps = [ + # "//numpy", + # "//tensorflow", + ], +) + +py_library( + name = "download_and_convert_cifar10", + srcs = ["datasets/download_and_convert_cifar10.py"], + deps = [ + ":dataset_utils", + # "//numpy", + # "//tensorflow", + ], +) + +py_library( + name = "download_and_convert_flowers", + srcs = ["datasets/download_and_convert_flowers.py"], + deps = [ + ":dataset_utils", + # "//tensorflow", + ], +) + +py_library( + name = "download_and_convert_mnist", + srcs = ["datasets/download_and_convert_mnist.py"], + deps = [ + ":dataset_utils", + # "//numpy", + # "//tensorflow", + ], +) + +py_binary( + name = "download_and_convert_data", + srcs = ["download_and_convert_data.py"], + deps = [ + ":download_and_convert_cifar10", + ":download_and_convert_flowers", + ":download_and_convert_mnist", + # "//tensorflow", + ], +) + +py_library( + name = "cifar10", + srcs = ["datasets/cifar10.py"], + deps = [ + ":dataset_utils", + # "//tensorflow", + ], +) + +py_library( + name = "flowers", + srcs = ["datasets/flowers.py"], + deps = [ + ":dataset_utils", + # "//tensorflow", + ], +) + +py_library( + name = "imagenet", + srcs = ["datasets/imagenet.py"], + deps = [ + ":dataset_utils", + # "//tensorflow", + ], +) + +py_library( + name = "mnist", + srcs = ["datasets/mnist.py"], + deps = [ + ":dataset_utils", + # "//tensorflow", + ], +) + +py_library( + name = "dataset_factory", + srcs = ["datasets/dataset_factory.py"], + deps = [ + ":cifar10", + ":flowers", + ":imagenet", + ":mnist", + ], +) + +py_library( + name = "model_deploy", + srcs = ["deployment/model_deploy.py"], + deps = [ + # "//tensorflow", + ], +) + +py_test( + name = "model_deploy_test", + srcs = ["deployment/model_deploy_test.py"], + srcs_version = "PY2AND3", + deps = [ + ":model_deploy", + # "//numpy", + # "//tensorflow", + ], +) + +py_library( + name = "cifarnet_preprocessing", + srcs = ["preprocessing/cifarnet_preprocessing.py"], + deps = [ + # "//tensorflow", + ], +) + +py_library( + name = "inception_preprocessing", + srcs = ["preprocessing/inception_preprocessing.py"], + deps = [ + # "//tensorflow", + # "//tensorflow/python:control_flow_ops", + ], +) + +py_library( + name = "lenet_preprocessing", + srcs = ["preprocessing/lenet_preprocessing.py"], + deps = [ + # "//tensorflow", + ], +) + +py_library( + name = "vgg_preprocessing", + srcs = ["preprocessing/vgg_preprocessing.py"], + deps = [ + # "//tensorflow", + ], +) + +py_library( + name = "preprocessing_factory", + srcs = ["preprocessing/preprocessing_factory.py"], + deps = [ + ":cifarnet_preprocessing", + ":inception_preprocessing", + ":lenet_preprocessing", + ":vgg_preprocessing", + # "//tensorflow", + ], +) + +# Typical networks definitions. + +py_library( + name = "nets", + deps = [ + ":alexnet", + ":cifarnet", + ":cyclegan", + ":i3d", + ":inception", + ":lenet", + ":mobilenet", + ":nasnet", + ":overfeat", + ":pix2pix", + ":pnasnet", + ":resnet_v1", + ":resnet_v2", + ":s3dg", + ":vgg", + ], +) + +py_library( + name = "alexnet", + srcs = ["nets/alexnet.py"], + srcs_version = "PY2AND3", + deps = [ + # "//tensorflow", + ], +) + +py_test( + name = "alexnet_test", + size = "medium", + srcs = ["nets/alexnet_test.py"], + srcs_version = "PY2AND3", + deps = [ + ":alexnet", + # "//tensorflow", + ], +) + +py_library( + name = "cifarnet", + srcs = ["nets/cifarnet.py"], + deps = [ + # "//tensorflow", + ], +) + +py_library( + name = "cyclegan", + srcs = ["nets/cyclegan.py"], + deps = [ + # "//numpy", + # "//tensorflow", + ], +) + +py_test( + name = "cyclegan_test", + srcs = ["nets/cyclegan_test.py"], + shard_count = 3, + srcs_version = "PY2AND3", + deps = [ + ":cyclegan", + # "//tensorflow", + ], +) + +py_library( + name = "dcgan", + srcs = ["nets/dcgan.py"], + deps = [ + # "//tensorflow", + ], +) + +py_test( + name = "dcgan_test", + srcs = ["nets/dcgan_test.py"], + shard_count = 3, + srcs_version = "PY2AND3", + deps = [ + ":dcgan", + # "//tensorflow", + ], +) + +py_library( + name = "i3d", + srcs = ["nets/i3d.py"], + srcs_version = "PY2AND3", + deps = [ + ":i3d_utils", + ":s3dg", + # "//tensorflow", + ], +) + +py_test( + name = "i3d_test", + size = "large", + srcs = ["nets/i3d_test.py"], + shard_count = 3, + srcs_version = "PY2AND3", + deps = [ + ":i3d", + # "//tensorflow", + ], +) + +py_library( + name = "i3d_utils", + srcs = ["nets/i3d_utils.py"], + srcs_version = "PY2AND3", + deps = [ + # "//tensorflow", + ], +) + +py_library( + name = "inception", + srcs = ["nets/inception.py"], + srcs_version = "PY2AND3", + deps = [ + ":inception_resnet_v2", + ":inception_v1", + ":inception_v2", + ":inception_v3", + ":inception_v4", + ], +) + +py_library( + name = "inception_utils", + srcs = ["nets/inception_utils.py"], + srcs_version = "PY2AND3", + deps = [ + # "//tensorflow", + ], +) + +py_library( + name = "inception_v1", + srcs = ["nets/inception_v1.py"], + srcs_version = "PY2AND3", + deps = [ + ":inception_utils", + # "//tensorflow", + ], +) + +py_library( + name = "inception_v2", + srcs = ["nets/inception_v2.py"], + srcs_version = "PY2AND3", + deps = [ + ":inception_utils", + # "//tensorflow", + ], +) + +py_library( + name = "inception_v3", + srcs = ["nets/inception_v3.py"], + srcs_version = "PY2AND3", + deps = [ + ":inception_utils", + # "//tensorflow", + ], +) + +py_library( + name = "inception_v4", + srcs = ["nets/inception_v4.py"], + srcs_version = "PY2AND3", + deps = [ + ":inception_utils", + # "//tensorflow", + ], +) + +py_library( + name = "inception_resnet_v2", + srcs = ["nets/inception_resnet_v2.py"], + srcs_version = "PY2AND3", + deps = [ + # "//tensorflow", + ], +) + +py_test( + name = "inception_v1_test", + size = "large", + srcs = ["nets/inception_v1_test.py"], + shard_count = 3, + srcs_version = "PY2AND3", + deps = [ + ":inception", + # "//numpy", + # "//tensorflow", + ], +) + +py_test( + name = "inception_v2_test", + size = "large", + srcs = ["nets/inception_v2_test.py"], + shard_count = 3, + srcs_version = "PY2AND3", + deps = [ + ":inception", + # "//numpy", + # "//tensorflow", + ], +) + +py_test( + name = "inception_v3_test", + size = "large", + srcs = ["nets/inception_v3_test.py"], + shard_count = 3, + srcs_version = "PY2AND3", + deps = [ + ":inception", + # "//numpy", + # "//tensorflow", + ], +) + +py_test( + name = "inception_v4_test", + size = "large", + srcs = ["nets/inception_v4_test.py"], + shard_count = 3, + srcs_version = "PY2AND3", + deps = [ + ":inception", + # "//tensorflow", + ], +) + +py_test( + name = "inception_resnet_v2_test", + size = "large", + srcs = ["nets/inception_resnet_v2_test.py"], + shard_count = 3, + srcs_version = "PY2AND3", + deps = [ + ":inception", + # "//tensorflow", + ], +) + +py_library( + name = "lenet", + srcs = ["nets/lenet.py"], + deps = [ + # "//tensorflow", + ], +) + +py_library( + name = "mobilenet_v1", + srcs = ["nets/mobilenet_v1.py"], + srcs_version = "PY2AND3", + deps = [ + # "//tensorflow", + ], +) + +py_library( + name = "mobilenet_v2", + srcs = glob(["nets/mobilenet/*.py"]), + srcs_version = "PY2AND3", + deps = [ + # "//tensorflow", + ], +) + +py_test( + name = "mobilenet_v2_test", + srcs = ["nets/mobilenet/mobilenet_v2_test.py"], + srcs_version = "PY2AND3", + deps = [ + ":mobilenet", + # "//tensorflow", + ], +) + +py_library( + name = "mobilenet", + deps = [ + ":mobilenet_v1", + ":mobilenet_v2", + ], +) + +py_test( + name = "mobilenet_v1_test", + size = "large", + srcs = ["nets/mobilenet_v1_test.py"], + shard_count = 3, + srcs_version = "PY2AND3", + deps = [ + ":mobilenet_v1", + # "//numpy", + # "//tensorflow", + ], +) + +py_binary( + name = "mobilenet_v1_train", + srcs = ["nets/mobilenet_v1_train.py"], + deps = [ + ":dataset_factory", + ":mobilenet_v1", + ":preprocessing_factory", + # "//tensorflow", + ], +) + +py_binary( + name = "mobilenet_v1_eval", + srcs = ["nets/mobilenet_v1_eval.py"], + deps = [ + ":dataset_factory", + ":mobilenet_v1", + ":preprocessing_factory", + # "//tensorflow", + ], +) + +py_library( + name = "nasnet_utils", + srcs = ["nets/nasnet/nasnet_utils.py"], + srcs_version = "PY2AND3", + deps = [ + # "//tensorflow", + ], +) + +py_library( + name = "nasnet", + srcs = ["nets/nasnet/nasnet.py"], + srcs_version = "PY2AND3", + deps = [ + ":nasnet_utils", + # "//tensorflow", + ], +) + +py_test( + name = "nasnet_utils_test", + size = "medium", + srcs = ["nets/nasnet/nasnet_utils_test.py"], + srcs_version = "PY2AND3", + deps = [ + ":nasnet_utils", + # "//tensorflow", + ], +) + +py_test( + name = "nasnet_test", + size = "large", + srcs = ["nets/nasnet/nasnet_test.py"], + shard_count = 10, + srcs_version = "PY2AND3", + deps = [ + ":nasnet", + # "//tensorflow", + ], +) + +py_library( + name = "pnasnet", + srcs = ["nets/nasnet/pnasnet.py"], + srcs_version = "PY2AND3", + deps = [ + ":nasnet", + ":nasnet_utils", + # "//tensorflow", + ], +) + +py_test( + name = "pnasnet_test", + size = "large", + srcs = ["nets/nasnet/pnasnet_test.py"], + shard_count = 4, + srcs_version = "PY2AND3", + deps = [ + ":pnasnet", + # "//tensorflow", + ], +) + +py_library( + name = "overfeat", + srcs = ["nets/overfeat.py"], + srcs_version = "PY2AND3", + deps = [ + # "//tensorflow", + ], +) + +py_test( + name = "overfeat_test", + size = "medium", + srcs = ["nets/overfeat_test.py"], + srcs_version = "PY2AND3", + deps = [ + ":overfeat", + # "//tensorflow", + ], +) + +py_library( + name = "pix2pix", + srcs = ["nets/pix2pix.py"], + srcs_version = "PY2AND3", + deps = [ + # "//tensorflow", + ], +) + +py_test( + name = "pix2pix_test", + srcs = ["nets/pix2pix_test.py"], + srcs_version = "PY2AND3", + deps = [ + ":pix2pix", + # "//tensorflow", + ], +) + +py_library( + name = "resnet_utils", + srcs = ["nets/resnet_utils.py"], + srcs_version = "PY2AND3", + deps = [ + # "//tensorflow", + ], +) + +py_library( + name = "resnet_v1", + srcs = ["nets/resnet_v1.py"], + srcs_version = "PY2AND3", + deps = [ + ":resnet_utils", + # "//tensorflow", + ], +) + +py_test( + name = "resnet_v1_test", + size = "medium", + srcs = ["nets/resnet_v1_test.py"], + shard_count = 2, + srcs_version = "PY2AND3", + deps = [ + ":resnet_utils", + ":resnet_v1", + # "//numpy", + # "//tensorflow", + ], +) + +py_library( + name = "resnet_v2", + srcs = ["nets/resnet_v2.py"], + srcs_version = "PY2AND3", + deps = [ + ":resnet_utils", + # "//tensorflow", + ], +) + +py_test( + name = "resnet_v2_test", + size = "medium", + srcs = ["nets/resnet_v2_test.py"], + shard_count = 2, + srcs_version = "PY2AND3", + deps = [ + ":resnet_utils", + ":resnet_v2", + # "//numpy", + # "//tensorflow", + ], +) + +py_library( + name = "s3dg", + srcs = ["nets/s3dg.py"], + srcs_version = "PY2AND3", + deps = [ + ":i3d_utils", + # "//tensorflow", + ], +) + +py_test( + name = "s3dg_test", + size = "large", + srcs = ["nets/s3dg_test.py"], + shard_count = 3, + srcs_version = "PY2AND3", + deps = [ + ":s3dg", + # "//tensorflow", + ], +) + +py_library( + name = "vgg", + srcs = ["nets/vgg.py"], + srcs_version = "PY2AND3", + deps = [ + # "//tensorflow", + ], +) + +py_test( + name = "vgg_test", + size = "medium", + srcs = ["nets/vgg_test.py"], + srcs_version = "PY2AND3", + deps = [ + ":vgg", + # "//tensorflow", + ], +) + +py_library( + name = "nets_factory", + srcs = ["nets/nets_factory.py"], + deps = [ + ":nets", + # "//tensorflow", + ], +) + +py_test( + name = "nets_factory_test", + size = "large", + srcs = ["nets/nets_factory_test.py"], + shard_count = 3, + srcs_version = "PY2AND3", + deps = [ + ":nets_factory", + # "//tensorflow", + ], +) + +py_library( + name = "train_image_classifier_lib", + srcs = ["train_image_classifier.py"], + deps = [ + ":dataset_factory", + ":model_deploy", + ":nets_factory", + ":preprocessing_factory", + # "//tensorflow", + ], +) + +py_binary( + name = "train_image_classifier", + srcs = ["train_image_classifier.py"], + # WARNING: not supported in bazel; will be commented out by copybara. + # paropts = ["--compress"], + deps = [ + ":train_image_classifier_lib", + ], +) + +py_library( + name = "eval_image_classifier_lib", + srcs = ["eval_image_classifier.py"], + deps = [ + ":dataset_factory", + ":nets_factory", + ":preprocessing_factory", + # "//tensorflow", + ], +) + +py_binary( + name = "eval_image_classifier", + srcs = ["eval_image_classifier.py"], + deps = [ + ":eval_image_classifier_lib", + ], +) + +py_binary( + name = "export_inference_graph", + srcs = ["export_inference_graph.py"], + # WARNING: not supported in bazel; will be commented out by copybara. + # paropts = ["--compress"], + deps = [ + ":dataset_factory", + ":nets_factory", + # "//tensorflow", + # "//tensorflow/python:platform", + ], +) + +py_test( + name = "export_inference_graph_test", + size = "medium", + srcs = ["export_inference_graph_test.py"], + srcs_version = "PY2AND3", + tags = [ + "manual", + ], + deps = [ + ":export_inference_graph", + # "//tensorflow", + # "//tensorflow/python:platform", + ], +) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/README.md b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/README.md new file mode 100644 index 0000000..08bc48b --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/README.md @@ -0,0 +1,530 @@ +# TensorFlow-Slim image classification model library + +[TF-slim](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/slim) +is a new lightweight high-level API of TensorFlow (`tensorflow.contrib.slim`) +for defining, training and evaluating complex +models. This directory contains +code for training and evaluating several widely used Convolutional Neural +Network (CNN) image classification models using TF-slim. +It contains scripts that will allow +you to train models from scratch or fine-tune them from pre-trained network +weights. It also contains code for downloading standard image datasets, +converting them +to TensorFlow's native TFRecord format and reading them in using TF-Slim's +data reading and queueing utilities. You can easily train any model on any of +these datasets, as we demonstrate below. We've also included a +[jupyter notebook](https://github.com/tensorflow/models/blob/master/research/slim/slim_walkthrough.ipynb), +which provides working examples of how to use TF-Slim for image classification. +For developing or modifying your own models, see also the [main TF-Slim page](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/slim). + +## Contacts + +Maintainers of TF-slim: + +* Nathan Silberman, + github: [nathansilberman](https://github.com/nathansilberman) +* Sergio Guadarrama, github: [sguada](https://github.com/sguada) + +## Citation +"TensorFlow-Slim image classification model library" +N. Silberman and S. Guadarrama, 2016. +https://github.com/tensorflow/models/tree/master/research/slim + +## Table of contents + +
Installation and setup
+Preparing the datasets
+Using pre-trained models
+Training from scratch
+Fine tuning to a new task
+Evaluating performance
+Exporting Inference Graph
+Troubleshooting
+ +# Installation + + +In this section, we describe the steps required to install the appropriate +prerequisite packages. + +## Installing latest version of TF-slim + +TF-Slim is available as `tf.contrib.slim` via TensorFlow 1.0. To test that your +installation is working, execute the following command; it should run without +raising any errors. + +``` +python -c "import tensorflow.contrib.slim as slim; eval = slim.evaluation.evaluate_once" +``` + +## Installing the TF-slim image models library + +To use TF-Slim for image classification, you also have to install +the [TF-Slim image models library](https://github.com/tensorflow/models/tree/master/research/slim), +which is not part of the core TF library. +To do this, check out the +[tensorflow/models](https://github.com/tensorflow/models/) repository as follows: + +```bash +cd $HOME/workspace +git clone https://github.com/tensorflow/models/ +``` + +This will put the TF-Slim image models library in `$HOME/workspace/models/research/slim`. +(It will also create a directory called +[models/inception](https://github.com/tensorflow/models/tree/master/research/inception), +which contains an older version of slim; you can safely ignore this.) + +To verify that this has worked, execute the following commands; it should run +without raising any errors. + +``` +cd $HOME/workspace/models/research/slim +python -c "from nets import cifarnet; mynet = cifarnet.cifarnet" +``` + + +# Preparing the datasets + + +As part of this library, we've included scripts to download several popular +image datasets (listed below) and convert them to slim format. + +Dataset | Training Set Size | Testing Set Size | Number of Classes | Comments +:------:|:---------------:|:---------------------:|:-----------:|:-----------: +Flowers|2500 | 2500 | 5 | Various sizes (source: Flickr) +[Cifar10](https://www.cs.toronto.edu/~kriz/cifar.html) | 60k| 10k | 10 |32x32 color +[MNIST](http://yann.lecun.com/exdb/mnist/)| 60k | 10k | 10 | 28x28 gray +[ImageNet](http://www.image-net.org/challenges/LSVRC/2012/)|1.2M| 50k | 1000 | Various sizes + +## Downloading and converting to TFRecord format + +For each dataset, we'll need to download the raw data and convert it to +TensorFlow's native +[TFRecord](https://www.tensorflow.org/versions/r0.10/api_docs/python/python_io.html#tfrecords-format-details) +format. Each TFRecord contains a +[TF-Example](https://github.com/tensorflow/tensorflow/blob/r0.10/tensorflow/core/example/example.proto) +protocol buffer. Below we demonstrate how to do this for the Flowers dataset. + +```shell +$ DATA_DIR=/tmp/data/flowers +$ python download_and_convert_data.py \ + --dataset_name=flowers \ + --dataset_dir="${DATA_DIR}" +``` + +When the script finishes you will find several TFRecord files created: + +```shell +$ ls ${DATA_DIR} +flowers_train-00000-of-00005.tfrecord +... +flowers_train-00004-of-00005.tfrecord +flowers_validation-00000-of-00005.tfrecord +... +flowers_validation-00004-of-00005.tfrecord +labels.txt +``` + +These represent the training and validation data, sharded over 5 files each. +You will also find the `$DATA_DIR/labels.txt` file which contains the mapping +from integer labels to class names. + +You can use the same script to create the mnist and cifar10 datasets. +However, for ImageNet, you have to follow the instructions +[here](https://github.com/tensorflow/models/blob/master/research/inception/README.md#getting-started). +Note that you first have to sign up for an account at image-net.org. +Also, the download can take several hours, and could use up to 500GB. + + +## Creating a TF-Slim Dataset Descriptor. + +Once the TFRecord files have been created, you can easily define a Slim +[Dataset](https://github.com/tensorflow/tensorflow/blob/r0.10/tensorflow/contrib/slim/python/slim/data/dataset.py), +which stores pointers to the data file, as well as various other pieces of +metadata, such as the class labels, the train/test split, and how to parse the +TFExample protos. We have included the TF-Slim Dataset descriptors +for +[Cifar10](https://github.com/tensorflow/models/blob/master/research/slim/datasets/cifar10.py), +[ImageNet](https://github.com/tensorflow/models/blob/master/research/slim/datasets/imagenet.py), +[Flowers](https://github.com/tensorflow/models/blob/master/research/slim/datasets/flowers.py), +and +[MNIST](https://github.com/tensorflow/models/blob/master/research/slim/datasets/mnist.py). +An example of how to load data using a TF-Slim dataset descriptor using a +TF-Slim +[DatasetDataProvider](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/slim/python/slim/data/dataset_data_provider.py) +is found below: + +```python +import tensorflow as tf +from datasets import flowers + +slim = tf.contrib.slim + +# Selects the 'validation' dataset. +dataset = flowers.get_split('validation', DATA_DIR) + +# Creates a TF-Slim DataProvider which reads the dataset in the background +# during both training and testing. +provider = slim.dataset_data_provider.DatasetDataProvider(dataset) +[image, label] = provider.get(['image', 'label']) +``` +## An automated script for processing ImageNet data. + +Training a model with the ImageNet dataset is a common request. To facilitate +working with the ImageNet dataset, we provide an automated script for +downloading and processing the ImageNet dataset into the native TFRecord +format. + +The TFRecord format consists of a set of sharded files where each entry is a serialized `tf.Example` proto. Each `tf.Example` proto contains the ImageNet image (JPEG encoded) as well as metadata such as label and bounding box information. + +We provide a single [script](datasets/download_and_preprocess_imagenet.sh) for +downloading and converting ImageNet data to TFRecord format. Downloading and +preprocessing the data may take several hours (up to half a day) depending on +your network and computer speed. Please be patient. + +To begin, you will need to sign up for an account with [ImageNet] +(http://image-net.org) to gain access to the data. Look for the sign up page, +create an account and request an access key to download the data. + +After you have `USERNAME` and `PASSWORD`, you are ready to run our script. Make +sure that your hard disk has at least 500 GB of free space for downloading and +storing the data. Here we select `DATA_DIR=$HOME/imagenet-data` as such a +location but feel free to edit accordingly. + +When you run the below script, please enter *USERNAME* and *PASSWORD* when +prompted. This will occur at the very beginning. Once these values are entered, +you will not need to interact with the script again. + +```shell +# location of where to place the ImageNet data +DATA_DIR=$HOME/imagenet-data + +# build the preprocessing script. +bazel build slim/download_and_preprocess_imagenet + +# run it +bazel-bin/slim/download_and_preprocess_imagenet "${DATA_DIR}" +``` + +The final line of the output script should read: + +```shell +2016-02-17 14:30:17.287989: Finished writing all 1281167 images in data set. +``` + +When the script finishes you will find 1024 and 128 training and validation +files in the `DATA_DIR`. The files will match the patterns `train-????-of-1024` +and `validation-?????-of-00128`, respectively. + +[Congratulations!](https://www.youtube.com/watch?v=9bZkp7q19f0) You are now +ready to train or evaluate with the ImageNet data set. + +# Pre-trained Models + + +Neural nets work best when they have many parameters, making them powerful +function approximators. +However, this means they must be trained on very large datasets. Because +training models from scratch can be a very computationally intensive process +requiring days or even weeks, we provide various pre-trained models, +as listed below. These CNNs have been trained on the +[ILSVRC-2012-CLS](http://www.image-net.org/challenges/LSVRC/2012/) +image classification dataset. + +In the table below, we list each model, the corresponding +TensorFlow model file, the link to the model checkpoint, and the top 1 and top 5 +accuracy (on the imagenet test set). +Note that the VGG and ResNet V1 parameters have been converted from their original +caffe formats +([here](https://github.com/BVLC/caffe/wiki/Model-Zoo#models-used-by-the-vgg-team-in-ilsvrc-2014) +and +[here](https://github.com/KaimingHe/deep-residual-networks)), +whereas the Inception and ResNet V2 parameters have been trained internally at +Google. Also be aware that these accuracies were computed by evaluating using a +single image crop. Some academic papers report higher accuracy by using multiple +crops at multiple scales. + +Model | TF-Slim File | Checkpoint | Top-1 Accuracy| Top-5 Accuracy | +:----:|:------------:|:----------:|:-------:|:--------:| +[Inception V1](http://arxiv.org/abs/1409.4842v1)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/inception_v1.py)|[inception_v1_2016_08_28.tar.gz](http://download.tensorflow.org/models/inception_v1_2016_08_28.tar.gz)|69.8|89.6| +[Inception V2](http://arxiv.org/abs/1502.03167)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/inception_v2.py)|[inception_v2_2016_08_28.tar.gz](http://download.tensorflow.org/models/inception_v2_2016_08_28.tar.gz)|73.9|91.8| +[Inception V3](http://arxiv.org/abs/1512.00567)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/inception_v3.py)|[inception_v3_2016_08_28.tar.gz](http://download.tensorflow.org/models/inception_v3_2016_08_28.tar.gz)|78.0|93.9| +[Inception V4](http://arxiv.org/abs/1602.07261)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/inception_v4.py)|[inception_v4_2016_09_09.tar.gz](http://download.tensorflow.org/models/inception_v4_2016_09_09.tar.gz)|80.2|95.2| +[Inception-ResNet-v2](http://arxiv.org/abs/1602.07261)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/inception_resnet_v2.py)|[inception_resnet_v2_2016_08_30.tar.gz](http://download.tensorflow.org/models/inception_resnet_v2_2016_08_30.tar.gz)|80.4|95.3| +[ResNet V1 50](https://arxiv.org/abs/1512.03385)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v1.py)|[resnet_v1_50_2016_08_28.tar.gz](http://download.tensorflow.org/models/resnet_v1_50_2016_08_28.tar.gz)|75.2|92.2| +[ResNet V1 101](https://arxiv.org/abs/1512.03385)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v1.py)|[resnet_v1_101_2016_08_28.tar.gz](http://download.tensorflow.org/models/resnet_v1_101_2016_08_28.tar.gz)|76.4|92.9| +[ResNet V1 152](https://arxiv.org/abs/1512.03385)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v1.py)|[resnet_v1_152_2016_08_28.tar.gz](http://download.tensorflow.org/models/resnet_v1_152_2016_08_28.tar.gz)|76.8|93.2| +[ResNet V2 50](https://arxiv.org/abs/1603.05027)^|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v2.py)|[resnet_v2_50_2017_04_14.tar.gz](http://download.tensorflow.org/models/resnet_v2_50_2017_04_14.tar.gz)|75.6|92.8| +[ResNet V2 101](https://arxiv.org/abs/1603.05027)^|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v2.py)|[resnet_v2_101_2017_04_14.tar.gz](http://download.tensorflow.org/models/resnet_v2_101_2017_04_14.tar.gz)|77.0|93.7| +[ResNet V2 152](https://arxiv.org/abs/1603.05027)^|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v2.py)|[resnet_v2_152_2017_04_14.tar.gz](http://download.tensorflow.org/models/resnet_v2_152_2017_04_14.tar.gz)|77.8|94.1| +[ResNet V2 200](https://arxiv.org/abs/1603.05027)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v2.py)|[TBA]()|79.9\*|95.2\*| +[VGG 16](http://arxiv.org/abs/1409.1556.pdf)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/vgg.py)|[vgg_16_2016_08_28.tar.gz](http://download.tensorflow.org/models/vgg_16_2016_08_28.tar.gz)|71.5|89.8| +[VGG 19](http://arxiv.org/abs/1409.1556.pdf)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/vgg.py)|[vgg_19_2016_08_28.tar.gz](http://download.tensorflow.org/models/vgg_19_2016_08_28.tar.gz)|71.1|89.8| +[MobileNet_v1_1.0_224](https://arxiv.org/pdf/1704.04861.pdf)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet_v1.py)|[mobilenet_v1_1.0_224.tgz](http://download.tensorflow.org/models/mobilenet_v1_2018_02_22/mobilenet_v1_1.0_224.tgz)|70.9|89.9| +[MobileNet_v1_0.50_160](https://arxiv.org/pdf/1704.04861.pdf)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet_v1.py)|[mobilenet_v1_0.50_160.tgz](http://download.tensorflow.org/models/mobilenet_v1_2018_02_22/mobilenet_v1_0.5_160.tgz)|59.1|81.9| +[MobileNet_v1_0.25_128](https://arxiv.org/pdf/1704.04861.pdf)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet_v1.py)|[mobilenet_v1_0.25_128.tgz](http://download.tensorflow.org/models/mobilenet_v1_2018_02_22/mobilenet_v1_0.25_128.tgz)|41.5|66.3| +[MobileNet_v2_1.4_224^*](https://arxiv.org/abs/1801.04381)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet_v2.py)| [mobilenet_v2_1.4_224.tgz](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_1.4_224.tgz) | 74.9 | 92.5| +[MobileNet_v2_1.0_224^*](https://arxiv.org/abs/1801.04381)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet_v2.py)| [mobilenet_v2_1.0_224.tgz](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_1.0_224.tgz) | 71.9 | 91.0 +[NASNet-A_Mobile_224](https://arxiv.org/abs/1707.07012)#|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/nasnet/nasnet.py)|[nasnet-a_mobile_04_10_2017.tar.gz](https://storage.googleapis.com/download.tensorflow.org/models/nasnet-a_mobile_04_10_2017.tar.gz)|74.0|91.6| +[NASNet-A_Large_331](https://arxiv.org/abs/1707.07012)#|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/nasnet/nasnet.py)|[nasnet-a_large_04_10_2017.tar.gz](https://storage.googleapis.com/download.tensorflow.org/models/nasnet-a_large_04_10_2017.tar.gz)|82.7|96.2| +[PNASNet-5_Large_331](https://arxiv.org/abs/1712.00559)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/nasnet/pnasnet.py)|[pnasnet-5_large_2017_12_13.tar.gz](https://storage.googleapis.com/download.tensorflow.org/models/pnasnet-5_large_2017_12_13.tar.gz)|82.9|96.2| +[PNASNet-5_Mobile_224](https://arxiv.org/abs/1712.00559)|[Code](https://github.com/tensorflow/models/blob/master/research/slim/nets/nasnet/pnasnet.py)|[pnasnet-5_mobile_2017_12_13.tar.gz](https://storage.googleapis.com/download.tensorflow.org/models/pnasnet-5_mobile_2017_12_13.tar.gz)|74.2|91.9| + +^ ResNet V2 models use Inception pre-processing and input image size of 299 (use +`--preprocessing_name inception --eval_image_size 299` when using +`eval_image_classifier.py`). Performance numbers for ResNet V2 models are +reported on the ImageNet validation set. + +(#) More information and details about the NASNet architectures are available at this [README](nets/nasnet/README.md) + +All 16 float MobileNet V1 models reported in the [MobileNet Paper](https://arxiv.org/abs/1704.04861) and all +16 quantized [TensorFlow Lite](https://www.tensorflow.org/mobile/tflite/) compatible MobileNet V1 models can be found +[here](https://github.com/tensorflow/models/tree/master/research/slim/nets/mobilenet_v1.md). + +(^#) More details on MobileNetV2 models can be found [here](nets/mobilenet/README.md). + +(\*): Results quoted from the [paper](https://arxiv.org/abs/1603.05027). + +Here is an example of how to download the Inception V3 checkpoint: + +```shell +$ CHECKPOINT_DIR=/tmp/checkpoints +$ mkdir ${CHECKPOINT_DIR} +$ wget http://download.tensorflow.org/models/inception_v3_2016_08_28.tar.gz +$ tar -xvf inception_v3_2016_08_28.tar.gz +$ mv inception_v3.ckpt ${CHECKPOINT_DIR} +$ rm inception_v3_2016_08_28.tar.gz +``` + + + +# Training a model from scratch. + + +We provide an easy way to train a model from scratch using any TF-Slim dataset. +The following example demonstrates how to train Inception V3 using the default +parameters on the ImageNet dataset. + +```shell +DATASET_DIR=/tmp/imagenet +TRAIN_DIR=/tmp/train_logs +python train_image_classifier.py \ + --train_dir=${TRAIN_DIR} \ + --dataset_name=imagenet \ + --dataset_split_name=train \ + --dataset_dir=${DATASET_DIR} \ + --model_name=inception_v3 +``` + +This process may take several days, depending on your hardware setup. +For convenience, we provide a way to train a model on multiple GPUs, +and/or multiple CPUs, either synchrononously or asynchronously. +See [model_deploy](https://github.com/tensorflow/models/blob/master/research/slim/deployment/model_deploy.py) +for details. + +### TensorBoard + +To visualize the losses and other metrics during training, you can use +[TensorBoard](https://github.com/tensorflow/tensorboard) +by running the command below. + +```shell +tensorboard --logdir=${TRAIN_DIR} +``` + +Once TensorBoard is running, navigate your web browser to http://localhost:6006. + +# Fine-tuning a model from an existing checkpoint + + +Rather than training from scratch, we'll often want to start from a pre-trained +model and fine-tune it. +To indicate a checkpoint from which to fine-tune, we'll call training with +the `--checkpoint_path` flag and assign it an absolute path to a checkpoint +file. + +When fine-tuning a model, we need to be careful about restoring checkpoint +weights. In particular, when we fine-tune a model on a new task with a different +number of output labels, we wont be able restore the final logits (classifier) +layer. For this, we'll use the `--checkpoint_exclude_scopes` flag. This flag +hinders certain variables from being loaded. When fine-tuning on a +classification task using a different number of classes than the trained model, +the new model will have a final 'logits' layer whose dimensions differ from the +pre-trained model. For example, if fine-tuning an ImageNet-trained model on +Flowers, the pre-trained logits layer will have dimensions `[2048 x 1001]` but +our new logits layer will have dimensions `[2048 x 5]`. Consequently, this +flag indicates to TF-Slim to avoid loading these weights from the checkpoint. + +Keep in mind that warm-starting from a checkpoint affects the model's weights +only during the initialization of the model. Once a model has started training, +a new checkpoint will be created in `${TRAIN_DIR}`. If the fine-tuning +training is stopped and restarted, this new checkpoint will be the one from +which weights are restored and not the `${checkpoint_path}$`. Consequently, +the flags `--checkpoint_path` and `--checkpoint_exclude_scopes` are only used +during the `0-`th global step (model initialization). Typically for fine-tuning +one only want train a sub-set of layers, so the flag `--trainable_scopes` allows +to specify which subsets of layers should trained, the rest would remain frozen. + +Below we give an example of +[fine-tuning inception-v3 on flowers](https://github.com/tensorflow/models/blob/master/research/slim/scripts/finetune_inception_v3_on_flowers.sh), +inception_v3 was trained on ImageNet with 1000 class labels, but the flowers +dataset only have 5 classes. Since the dataset is quite small we will only train +the new layers. + + +```shell +$ DATASET_DIR=/tmp/flowers +$ TRAIN_DIR=/tmp/flowers-models/inception_v3 +$ CHECKPOINT_PATH=/tmp/my_checkpoints/inception_v3.ckpt +$ python train_image_classifier.py \ + --train_dir=${TRAIN_DIR} \ + --dataset_dir=${DATASET_DIR} \ + --dataset_name=flowers \ + --dataset_split_name=train \ + --model_name=inception_v3 \ + --checkpoint_path=${CHECKPOINT_PATH} \ + --checkpoint_exclude_scopes=InceptionV3/Logits,InceptionV3/AuxLogits \ + --trainable_scopes=InceptionV3/Logits,InceptionV3/AuxLogits +``` + + + +# Evaluating performance of a model + + +To evaluate the performance of a model (whether pretrained or your own), +you can use the eval_image_classifier.py script, as shown below. + +Below we give an example of downloading the pretrained inception model and +evaluating it on the imagenet dataset. + +```shell +CHECKPOINT_FILE = ${CHECKPOINT_DIR}/inception_v3.ckpt # Example +$ python eval_image_classifier.py \ + --alsologtostderr \ + --checkpoint_path=${CHECKPOINT_FILE} \ + --dataset_dir=${DATASET_DIR} \ + --dataset_name=imagenet \ + --dataset_split_name=validation \ + --model_name=inception_v3 +``` + +See the [evaluation module example](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/slim#evaluation-loop) +for an example of how to evaluate a model at multiple checkpoints during or after the training. + +# Exporting the Inference Graph + + +Saves out a GraphDef containing the architecture of the model. + +To use it with a model name defined by slim, run: + +```shell +$ python export_inference_graph.py \ + --alsologtostderr \ + --model_name=inception_v3 \ + --output_file=/tmp/inception_v3_inf_graph.pb + +$ python export_inference_graph.py \ + --alsologtostderr \ + --model_name=mobilenet_v1 \ + --image_size=224 \ + --output_file=/tmp/mobilenet_v1_224.pb +``` + +## Freezing the exported Graph +If you then want to use the resulting model with your own or pretrained +checkpoints as part of a mobile model, you can run freeze_graph to get a graph +def with the variables inlined as constants using: + +```shell +bazel build tensorflow/python/tools:freeze_graph + +bazel-bin/tensorflow/python/tools/freeze_graph \ + --input_graph=/tmp/inception_v3_inf_graph.pb \ + --input_checkpoint=/tmp/checkpoints/inception_v3.ckpt \ + --input_binary=true --output_graph=/tmp/frozen_inception_v3.pb \ + --output_node_names=InceptionV3/Predictions/Reshape_1 +``` + +The output node names will vary depending on the model, but you can inspect and +estimate them using the summarize_graph tool: + +```shell +bazel build tensorflow/tools/graph_transforms:summarize_graph + +bazel-bin/tensorflow/tools/graph_transforms/summarize_graph \ + --in_graph=/tmp/inception_v3_inf_graph.pb +``` + +## Run label image in C++ + +To run the resulting graph in C++, you can look at the label_image sample code: + +```shell +bazel build tensorflow/examples/label_image:label_image + +bazel-bin/tensorflow/examples/label_image/label_image \ + --image=${HOME}/Pictures/flowers.jpg \ + --input_layer=input \ + --output_layer=InceptionV3/Predictions/Reshape_1 \ + --graph=/tmp/frozen_inception_v3.pb \ + --labels=/tmp/imagenet_slim_labels.txt \ + --input_mean=0 \ + --input_std=255 +``` + + +# Troubleshooting + + +#### The model runs out of CPU memory. + +See +[Model Runs out of CPU memory](https://github.com/tensorflow/models/tree/master/research/inception#the-model-runs-out-of-cpu-memory). + +#### The model runs out of GPU memory. + +See +[Adjusting Memory Demands](https://github.com/tensorflow/models/tree/master/research/inception#adjusting-memory-demands). + +#### The model training results in NaN's. + +See +[Model Resulting in NaNs](https://github.com/tensorflow/models/tree/master/research/inception#the-model-training-results-in-nans). + +#### The ResNet and VGG Models have 1000 classes but the ImageNet dataset has 1001 + +The ImageNet dataset provided has an empty background class which can be used +to fine-tune the model to other tasks. If you try training or fine-tuning the +VGG or ResNet models using the ImageNet dataset, you might encounter the +following error: + +```bash +InvalidArgumentError: Assign requires shapes of both tensors to match. lhs shape= [1001] rhs shape= [1000] +``` +This is due to the fact that the VGG and ResNet V1 final layers have only 1000 +outputs rather than 1001. + +To fix this issue, you can set the `--labels_offset=1` flag. This results in +the ImageNet labels being shifted down by one: + + +#### I wish to train a model with a different image size. + +The preprocessing functions all take `height` and `width` as parameters. You +can change the default values using the following snippet: + +```python +image_preprocessing_fn = preprocessing_factory.get_preprocessing( + preprocessing_name, + height=MY_NEW_HEIGHT, + width=MY_NEW_WIDTH, + is_training=True) +``` + +#### What hardware specification are these hyper-parameters targeted for? + +See +[Hardware Specifications](https://github.com/tensorflow/models/tree/master/research/inception#what-hardware-specification-are-these-hyper-parameters-targeted-for). diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/WORKSPACE b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/WORKSPACE new file mode 100644 index 0000000..e69de29 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/__init__.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/__init__.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/__init__.py @@ -0,0 +1 @@ + diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/build_imagenet_data.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/build_imagenet_data.py new file mode 100644 index 0000000..d021806 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/build_imagenet_data.py @@ -0,0 +1,704 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Converts ImageNet data to TFRecords file format with Example protos. + +The raw ImageNet data set is expected to reside in JPEG files located in the +following directory structure. + + data_dir/n01440764/ILSVRC2012_val_00000293.JPEG + data_dir/n01440764/ILSVRC2012_val_00000543.JPEG + ... + +where 'n01440764' is the unique synset label associated with +these images. + +The training data set consists of 1000 sub-directories (i.e. labels) +each containing 1200 JPEG images for a total of 1.2M JPEG images. + +The evaluation data set consists of 1000 sub-directories (i.e. labels) +each containing 50 JPEG images for a total of 50K JPEG images. + +This TensorFlow script converts the training and evaluation data into +a sharded data set consisting of 1024 and 128 TFRecord files, respectively. + + train_directory/train-00000-of-01024 + train_directory/train-00001-of-01024 + ... + train_directory/train-00127-of-01024 + +and + + validation_directory/validation-00000-of-00128 + validation_directory/validation-00001-of-00128 + ... + validation_directory/validation-00127-of-00128 + +Each validation TFRecord file contains ~390 records. Each training TFREcord +file contains ~1250 records. Each record within the TFRecord file is a +serialized Example proto. The Example proto contains the following fields: + + image/encoded: string containing JPEG encoded image in RGB colorspace + image/height: integer, image height in pixels + image/width: integer, image width in pixels + image/colorspace: string, specifying the colorspace, always 'RGB' + image/channels: integer, specifying the number of channels, always 3 + image/format: string, specifying the format, always'JPEG' + + image/filename: string containing the basename of the image file + e.g. 'n01440764_10026.JPEG' or 'ILSVRC2012_val_00000293.JPEG' + image/class/label: integer specifying the index in a classification layer. + The label ranges from [1, 1000] where 0 is not used. + image/class/synset: string specifying the unique ID of the label, + e.g. 'n01440764' + image/class/text: string specifying the human-readable version of the label + e.g. 'red fox, Vulpes vulpes' + + image/object/bbox/xmin: list of integers specifying the 0+ human annotated + bounding boxes + image/object/bbox/xmax: list of integers specifying the 0+ human annotated + bounding boxes + image/object/bbox/ymin: list of integers specifying the 0+ human annotated + bounding boxes + image/object/bbox/ymax: list of integers specifying the 0+ human annotated + bounding boxes + image/object/bbox/label: integer specifying the index in a classification + layer. The label ranges from [1, 1000] where 0 is not used. Note this is + always identical to the image label. + +Note that the length of xmin is identical to the length of xmax, ymin and ymax +for each example. + +Running this script using 16 threads may take around ~2.5 hours on a HP Z420. +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from datetime import datetime +import os +import random +import sys +import threading + +import numpy as np +from six.moves import xrange # pylint: disable=redefined-builtin +import tensorflow as tf + + +tf.app.flags.DEFINE_string('train_directory', '/tmp/', + 'Training data directory') +tf.app.flags.DEFINE_string('validation_directory', '/tmp/', + 'Validation data directory') +tf.app.flags.DEFINE_string('output_directory', '/tmp/', + 'Output data directory') + +tf.app.flags.DEFINE_integer('train_shards', 1024, + 'Number of shards in training TFRecord files.') +tf.app.flags.DEFINE_integer('validation_shards', 128, + 'Number of shards in validation TFRecord files.') + +tf.app.flags.DEFINE_integer('num_threads', 8, + 'Number of threads to preprocess the images.') + +# The labels file contains a list of valid labels are held in this file. +# Assumes that the file contains entries as such: +# n01440764 +# n01443537 +# n01484850 +# where each line corresponds to a label expressed as a synset. We map +# each synset contained in the file to an integer (based on the alphabetical +# ordering). See below for details. +tf.app.flags.DEFINE_string('labels_file', + 'imagenet_lsvrc_2015_synsets.txt', + 'Labels file') + +# This file containing mapping from synset to human-readable label. +# Assumes each line of the file looks like: +# +# n02119247 black fox +# n02119359 silver fox +# n02119477 red fox, Vulpes fulva +# +# where each line corresponds to a unique mapping. Note that each line is +# formatted as \t. +tf.app.flags.DEFINE_string('imagenet_metadata_file', + 'imagenet_metadata.txt', + 'ImageNet metadata file') + +# This file is the output of process_bounding_box.py +# Assumes each line of the file looks like: +# +# n00007846_64193.JPEG,0.0060,0.2620,0.7545,0.9940 +# +# where each line corresponds to one bounding box annotation associated +# with an image. Each line can be parsed as: +# +# , , , , +# +# Note that there might exist mulitple bounding box annotations associated +# with an image file. +tf.app.flags.DEFINE_string('bounding_box_file', + './imagenet_2012_bounding_boxes.csv', + 'Bounding box file') + +FLAGS = tf.app.flags.FLAGS + + +def _int64_feature(value): + """Wrapper for inserting int64 features into Example proto.""" + if not isinstance(value, list): + value = [value] + return tf.train.Feature(int64_list=tf.train.Int64List(value=value)) + + +def _float_feature(value): + """Wrapper for inserting float features into Example proto.""" + if not isinstance(value, list): + value = [value] + return tf.train.Feature(float_list=tf.train.FloatList(value=value)) + + +def _bytes_feature(value): + """Wrapper for inserting bytes features into Example proto.""" + return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value])) + + +def _convert_to_example(filename, image_buffer, label, synset, human, bbox, + height, width): + """Build an Example proto for an example. + + Args: + filename: string, path to an image file, e.g., '/path/to/example.JPG' + image_buffer: string, JPEG encoding of RGB image + label: integer, identifier for the ground truth for the network + synset: string, unique WordNet ID specifying the label, e.g., 'n02323233' + human: string, human-readable label, e.g., 'red fox, Vulpes vulpes' + bbox: list of bounding boxes; each box is a list of integers + specifying [xmin, ymin, xmax, ymax]. All boxes are assumed to belong to + the same label as the image label. + height: integer, image height in pixels + width: integer, image width in pixels + Returns: + Example proto + """ + xmin = [] + ymin = [] + xmax = [] + ymax = [] + for b in bbox: + assert len(b) == 4 + # pylint: disable=expression-not-assigned + [l.append(point) for l, point in zip([xmin, ymin, xmax, ymax], b)] + # pylint: enable=expression-not-assigned + + colorspace = 'RGB' + channels = 3 + image_format = 'JPEG' + + example = tf.train.Example(features=tf.train.Features(feature={ + 'image/height': _int64_feature(height), + 'image/width': _int64_feature(width), + 'image/colorspace': _bytes_feature(colorspace), + 'image/channels': _int64_feature(channels), + 'image/class/label': _int64_feature(label), + 'image/class/synset': _bytes_feature(synset), + 'image/class/text': _bytes_feature(human), + 'image/object/bbox/xmin': _float_feature(xmin), + 'image/object/bbox/xmax': _float_feature(xmax), + 'image/object/bbox/ymin': _float_feature(ymin), + 'image/object/bbox/ymax': _float_feature(ymax), + 'image/object/bbox/label': _int64_feature([label] * len(xmin)), + 'image/format': _bytes_feature(image_format), + 'image/filename': _bytes_feature(os.path.basename(filename)), + 'image/encoded': _bytes_feature(image_buffer)})) + return example + + +class ImageCoder(object): + """Helper class that provides TensorFlow image coding utilities.""" + + def __init__(self): + # Create a single Session to run all image coding calls. + self._sess = tf.Session() + + # Initializes function that converts PNG to JPEG data. + self._png_data = tf.placeholder(dtype=tf.string) + image = tf.image.decode_png(self._png_data, channels=3) + self._png_to_jpeg = tf.image.encode_jpeg(image, format='rgb', quality=100) + + # Initializes function that converts CMYK JPEG data to RGB JPEG data. + self._cmyk_data = tf.placeholder(dtype=tf.string) + image = tf.image.decode_jpeg(self._cmyk_data, channels=0) + self._cmyk_to_rgb = tf.image.encode_jpeg(image, format='rgb', quality=100) + + # Initializes function that decodes RGB JPEG data. + self._decode_jpeg_data = tf.placeholder(dtype=tf.string) + self._decode_jpeg = tf.image.decode_jpeg(self._decode_jpeg_data, channels=3) + + def png_to_jpeg(self, image_data): + return self._sess.run(self._png_to_jpeg, + feed_dict={self._png_data: image_data}) + + def cmyk_to_rgb(self, image_data): + return self._sess.run(self._cmyk_to_rgb, + feed_dict={self._cmyk_data: image_data}) + + def decode_jpeg(self, image_data): + image = self._sess.run(self._decode_jpeg, + feed_dict={self._decode_jpeg_data: image_data}) + assert len(image.shape) == 3 + assert image.shape[2] == 3 + return image + + +def _is_png(filename): + """Determine if a file contains a PNG format image. + + Args: + filename: string, path of the image file. + + Returns: + boolean indicating if the image is a PNG. + """ + # File list from: + # https://groups.google.com/forum/embed/?place=forum/torch7#!topic/torch7/fOSTXHIESSU + return 'n02105855_2933.JPEG' in filename + + +def _is_cmyk(filename): + """Determine if file contains a CMYK JPEG format image. + + Args: + filename: string, path of the image file. + + Returns: + boolean indicating if the image is a JPEG encoded with CMYK color space. + """ + # File list from: + # https://github.com/cytsai/ilsvrc-cmyk-image-list + blacklist = ['n01739381_1309.JPEG', 'n02077923_14822.JPEG', + 'n02447366_23489.JPEG', 'n02492035_15739.JPEG', + 'n02747177_10752.JPEG', 'n03018349_4028.JPEG', + 'n03062245_4620.JPEG', 'n03347037_9675.JPEG', + 'n03467068_12171.JPEG', 'n03529860_11437.JPEG', + 'n03544143_17228.JPEG', 'n03633091_5218.JPEG', + 'n03710637_5125.JPEG', 'n03961711_5286.JPEG', + 'n04033995_2932.JPEG', 'n04258138_17003.JPEG', + 'n04264628_27969.JPEG', 'n04336792_7448.JPEG', + 'n04371774_5854.JPEG', 'n04596742_4225.JPEG', + 'n07583066_647.JPEG', 'n13037406_4650.JPEG'] + return filename.split('/')[-1] in blacklist + + +def _process_image(filename, coder): + """Process a single image file. + + Args: + filename: string, path to an image file e.g., '/path/to/example.JPG'. + coder: instance of ImageCoder to provide TensorFlow image coding utils. + Returns: + image_buffer: string, JPEG encoding of RGB image. + height: integer, image height in pixels. + width: integer, image width in pixels. + """ + # Read the image file. + image_data = tf.gfile.FastGFile(filename, 'r').read() + + # Clean the dirty data. + if _is_png(filename): + # 1 image is a PNG. + print('Converting PNG to JPEG for %s' % filename) + image_data = coder.png_to_jpeg(image_data) + elif _is_cmyk(filename): + # 22 JPEG images are in CMYK colorspace. + print('Converting CMYK to RGB for %s' % filename) + image_data = coder.cmyk_to_rgb(image_data) + + # Decode the RGB JPEG. + image = coder.decode_jpeg(image_data) + + # Check that image converted to RGB + assert len(image.shape) == 3 + height = image.shape[0] + width = image.shape[1] + assert image.shape[2] == 3 + + return image_data, height, width + + +def _process_image_files_batch(coder, thread_index, ranges, name, filenames, + synsets, labels, humans, bboxes, num_shards): + """Processes and saves list of images as TFRecord in 1 thread. + + Args: + coder: instance of ImageCoder to provide TensorFlow image coding utils. + thread_index: integer, unique batch to run index is within [0, len(ranges)). + ranges: list of pairs of integers specifying ranges of each batches to + analyze in parallel. + name: string, unique identifier specifying the data set + filenames: list of strings; each string is a path to an image file + synsets: list of strings; each string is a unique WordNet ID + labels: list of integer; each integer identifies the ground truth + humans: list of strings; each string is a human-readable label + bboxes: list of bounding boxes for each image. Note that each entry in this + list might contain from 0+ entries corresponding to the number of bounding + box annotations for the image. + num_shards: integer number of shards for this data set. + """ + # Each thread produces N shards where N = int(num_shards / num_threads). + # For instance, if num_shards = 128, and the num_threads = 2, then the first + # thread would produce shards [0, 64). + num_threads = len(ranges) + assert not num_shards % num_threads + num_shards_per_batch = int(num_shards / num_threads) + + shard_ranges = np.linspace(ranges[thread_index][0], + ranges[thread_index][1], + num_shards_per_batch + 1).astype(int) + num_files_in_thread = ranges[thread_index][1] - ranges[thread_index][0] + + counter = 0 + for s in xrange(num_shards_per_batch): + # Generate a sharded version of the file name, e.g. 'train-00002-of-00010' + shard = thread_index * num_shards_per_batch + s + output_filename = '%s-%.5d-of-%.5d' % (name, shard, num_shards) + output_file = os.path.join(FLAGS.output_directory, output_filename) + writer = tf.python_io.TFRecordWriter(output_file) + + shard_counter = 0 + files_in_shard = np.arange(shard_ranges[s], shard_ranges[s + 1], dtype=int) + for i in files_in_shard: + filename = filenames[i] + label = labels[i] + synset = synsets[i] + human = humans[i] + bbox = bboxes[i] + + image_buffer, height, width = _process_image(filename, coder) + + example = _convert_to_example(filename, image_buffer, label, + synset, human, bbox, + height, width) + writer.write(example.SerializeToString()) + shard_counter += 1 + counter += 1 + + if not counter % 1000: + print('%s [thread %d]: Processed %d of %d images in thread batch.' % + (datetime.now(), thread_index, counter, num_files_in_thread)) + sys.stdout.flush() + + writer.close() + print('%s [thread %d]: Wrote %d images to %s' % + (datetime.now(), thread_index, shard_counter, output_file)) + sys.stdout.flush() + shard_counter = 0 + print('%s [thread %d]: Wrote %d images to %d shards.' % + (datetime.now(), thread_index, counter, num_files_in_thread)) + sys.stdout.flush() + + +def _process_image_files(name, filenames, synsets, labels, humans, + bboxes, num_shards): + """Process and save list of images as TFRecord of Example protos. + + Args: + name: string, unique identifier specifying the data set + filenames: list of strings; each string is a path to an image file + synsets: list of strings; each string is a unique WordNet ID + labels: list of integer; each integer identifies the ground truth + humans: list of strings; each string is a human-readable label + bboxes: list of bounding boxes for each image. Note that each entry in this + list might contain from 0+ entries corresponding to the number of bounding + box annotations for the image. + num_shards: integer number of shards for this data set. + """ + assert len(filenames) == len(synsets) + assert len(filenames) == len(labels) + assert len(filenames) == len(humans) + assert len(filenames) == len(bboxes) + + # Break all images into batches with a [ranges[i][0], ranges[i][1]]. + spacing = np.linspace(0, len(filenames), FLAGS.num_threads + 1).astype(np.int) + ranges = [] + threads = [] + for i in xrange(len(spacing) - 1): + ranges.append([spacing[i], spacing[i+1]]) + + # Launch a thread for each batch. + print('Launching %d threads for spacings: %s' % (FLAGS.num_threads, ranges)) + sys.stdout.flush() + + # Create a mechanism for monitoring when all threads are finished. + coord = tf.train.Coordinator() + + # Create a generic TensorFlow-based utility for converting all image codings. + coder = ImageCoder() + + threads = [] + for thread_index in xrange(len(ranges)): + args = (coder, thread_index, ranges, name, filenames, + synsets, labels, humans, bboxes, num_shards) + t = threading.Thread(target=_process_image_files_batch, args=args) + t.start() + threads.append(t) + + # Wait for all the threads to terminate. + coord.join(threads) + print('%s: Finished writing all %d images in data set.' % + (datetime.now(), len(filenames))) + sys.stdout.flush() + + +def _find_image_files(data_dir, labels_file): + """Build a list of all images files and labels in the data set. + + Args: + data_dir: string, path to the root directory of images. + + Assumes that the ImageNet data set resides in JPEG files located in + the following directory structure. + + data_dir/n01440764/ILSVRC2012_val_00000293.JPEG + data_dir/n01440764/ILSVRC2012_val_00000543.JPEG + + where 'n01440764' is the unique synset label associated with these images. + + labels_file: string, path to the labels file. + + The list of valid labels are held in this file. Assumes that the file + contains entries as such: + n01440764 + n01443537 + n01484850 + where each line corresponds to a label expressed as a synset. We map + each synset contained in the file to an integer (based on the alphabetical + ordering) starting with the integer 1 corresponding to the synset + contained in the first line. + + The reason we start the integer labels at 1 is to reserve label 0 as an + unused background class. + + Returns: + filenames: list of strings; each string is a path to an image file. + synsets: list of strings; each string is a unique WordNet ID. + labels: list of integer; each integer identifies the ground truth. + """ + print('Determining list of input files and labels from %s.' % data_dir) + challenge_synsets = [l.strip() for l in + tf.gfile.FastGFile(labels_file, 'r').readlines()] + + labels = [] + filenames = [] + synsets = [] + + # Leave label index 0 empty as a background class. + label_index = 1 + + # Construct the list of JPEG files and labels. + for synset in challenge_synsets: + jpeg_file_path = '%s/%s/*.JPEG' % (data_dir, synset) + matching_files = tf.gfile.Glob(jpeg_file_path) + + labels.extend([label_index] * len(matching_files)) + synsets.extend([synset] * len(matching_files)) + filenames.extend(matching_files) + + if not label_index % 100: + print('Finished finding files in %d of %d classes.' % ( + label_index, len(challenge_synsets))) + label_index += 1 + + # Shuffle the ordering of all image files in order to guarantee + # random ordering of the images with respect to label in the + # saved TFRecord files. Make the randomization repeatable. + shuffled_index = range(len(filenames)) + random.seed(12345) + random.shuffle(shuffled_index) + + filenames = [filenames[i] for i in shuffled_index] + synsets = [synsets[i] for i in shuffled_index] + labels = [labels[i] for i in shuffled_index] + + print('Found %d JPEG files across %d labels inside %s.' % + (len(filenames), len(challenge_synsets), data_dir)) + return filenames, synsets, labels + + +def _find_human_readable_labels(synsets, synset_to_human): + """Build a list of human-readable labels. + + Args: + synsets: list of strings; each string is a unique WordNet ID. + synset_to_human: dict of synset to human labels, e.g., + 'n02119022' --> 'red fox, Vulpes vulpes' + + Returns: + List of human-readable strings corresponding to each synset. + """ + humans = [] + for s in synsets: + assert s in synset_to_human, ('Failed to find: %s' % s) + humans.append(synset_to_human[s]) + return humans + + +def _find_image_bounding_boxes(filenames, image_to_bboxes): + """Find the bounding boxes for a given image file. + + Args: + filenames: list of strings; each string is a path to an image file. + image_to_bboxes: dictionary mapping image file names to a list of + bounding boxes. This list contains 0+ bounding boxes. + Returns: + List of bounding boxes for each image. Note that each entry in this + list might contain from 0+ entries corresponding to the number of bounding + box annotations for the image. + """ + num_image_bbox = 0 + bboxes = [] + for f in filenames: + basename = os.path.basename(f) + if basename in image_to_bboxes: + bboxes.append(image_to_bboxes[basename]) + num_image_bbox += 1 + else: + bboxes.append([]) + print('Found %d images with bboxes out of %d images' % ( + num_image_bbox, len(filenames))) + return bboxes + + +def _process_dataset(name, directory, num_shards, synset_to_human, + image_to_bboxes): + """Process a complete data set and save it as a TFRecord. + + Args: + name: string, unique identifier specifying the data set. + directory: string, root path to the data set. + num_shards: integer number of shards for this data set. + synset_to_human: dict of synset to human labels, e.g., + 'n02119022' --> 'red fox, Vulpes vulpes' + image_to_bboxes: dictionary mapping image file names to a list of + bounding boxes. This list contains 0+ bounding boxes. + """ + filenames, synsets, labels = _find_image_files(directory, FLAGS.labels_file) + humans = _find_human_readable_labels(synsets, synset_to_human) + bboxes = _find_image_bounding_boxes(filenames, image_to_bboxes) + _process_image_files(name, filenames, synsets, labels, + humans, bboxes, num_shards) + + +def _build_synset_lookup(imagenet_metadata_file): + """Build lookup for synset to human-readable label. + + Args: + imagenet_metadata_file: string, path to file containing mapping from + synset to human-readable label. + + Assumes each line of the file looks like: + + n02119247 black fox + n02119359 silver fox + n02119477 red fox, Vulpes fulva + + where each line corresponds to a unique mapping. Note that each line is + formatted as \t. + + Returns: + Dictionary of synset to human labels, such as: + 'n02119022' --> 'red fox, Vulpes vulpes' + """ + lines = tf.gfile.FastGFile(imagenet_metadata_file, 'r').readlines() + synset_to_human = {} + for l in lines: + if l: + parts = l.strip().split('\t') + assert len(parts) == 2 + synset = parts[0] + human = parts[1] + synset_to_human[synset] = human + return synset_to_human + + +def _build_bounding_box_lookup(bounding_box_file): + """Build a lookup from image file to bounding boxes. + + Args: + bounding_box_file: string, path to file with bounding boxes annotations. + + Assumes each line of the file looks like: + + n00007846_64193.JPEG,0.0060,0.2620,0.7545,0.9940 + + where each line corresponds to one bounding box annotation associated + with an image. Each line can be parsed as: + + , , , , + + Note that there might exist mulitple bounding box annotations associated + with an image file. This file is the output of process_bounding_boxes.py. + + Returns: + Dictionary mapping image file names to a list of bounding boxes. This list + contains 0+ bounding boxes. + """ + lines = tf.gfile.FastGFile(bounding_box_file, 'r').readlines() + images_to_bboxes = {} + num_bbox = 0 + num_image = 0 + for l in lines: + if l: + parts = l.split(',') + assert len(parts) == 5, ('Failed to parse: %s' % l) + filename = parts[0] + xmin = float(parts[1]) + ymin = float(parts[2]) + xmax = float(parts[3]) + ymax = float(parts[4]) + box = [xmin, ymin, xmax, ymax] + + if filename not in images_to_bboxes: + images_to_bboxes[filename] = [] + num_image += 1 + images_to_bboxes[filename].append(box) + num_bbox += 1 + + print('Successfully read %d bounding boxes ' + 'across %d images.' % (num_bbox, num_image)) + return images_to_bboxes + + +def main(unused_argv): + assert not FLAGS.train_shards % FLAGS.num_threads, ( + 'Please make the FLAGS.num_threads commensurate with FLAGS.train_shards') + assert not FLAGS.validation_shards % FLAGS.num_threads, ( + 'Please make the FLAGS.num_threads commensurate with ' + 'FLAGS.validation_shards') + print('Saving results to %s' % FLAGS.output_directory) + + # Build a map from synset to human-readable label. + synset_to_human = _build_synset_lookup(FLAGS.imagenet_metadata_file) + image_to_bboxes = _build_bounding_box_lookup(FLAGS.bounding_box_file) + + # Run it! + _process_dataset('validation', FLAGS.validation_directory, + FLAGS.validation_shards, synset_to_human, image_to_bboxes) + _process_dataset('train', FLAGS.train_directory, FLAGS.train_shards, + synset_to_human, image_to_bboxes) + + +if __name__ == '__main__': + tf.app.run() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/cifar10.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/cifar10.py new file mode 100644 index 0000000..e0d2968 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/cifar10.py @@ -0,0 +1,98 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Provides data for the Cifar10 dataset. + +The dataset scripts used to create the dataset can be found at: +tensorflow/models/research/slim/datasets/download_and_convert_cifar10.py +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import os +import tensorflow as tf + +from datasets import dataset_utils + +slim = tf.contrib.slim + +_FILE_PATTERN = 'cifar10_%s.tfrecord' + +SPLITS_TO_SIZES = {'train': 50000, 'test': 10000} + +_NUM_CLASSES = 10 + +_ITEMS_TO_DESCRIPTIONS = { + 'image': 'A [32 x 32 x 3] color image.', + 'label': 'A single integer between 0 and 9', +} + + +def get_split(split_name, dataset_dir, file_pattern=None, reader=None): + """Gets a dataset tuple with instructions for reading cifar10. + + Args: + split_name: A train/test split name. + dataset_dir: The base directory of the dataset sources. + file_pattern: The file pattern to use when matching the dataset sources. + It is assumed that the pattern contains a '%s' string so that the split + name can be inserted. + reader: The TensorFlow reader type. + + Returns: + A `Dataset` namedtuple. + + Raises: + ValueError: if `split_name` is not a valid train/test split. + """ + if split_name not in SPLITS_TO_SIZES: + raise ValueError('split name %s was not recognized.' % split_name) + + if not file_pattern: + file_pattern = _FILE_PATTERN + file_pattern = os.path.join(dataset_dir, file_pattern % split_name) + + # Allowing None in the signature so that dataset_factory can use the default. + if not reader: + reader = tf.TFRecordReader + + keys_to_features = { + 'image/encoded': tf.FixedLenFeature((), tf.string, default_value=''), + 'image/format': tf.FixedLenFeature((), tf.string, default_value='png'), + 'image/class/label': tf.FixedLenFeature( + [], tf.int64, default_value=tf.zeros([], dtype=tf.int64)), + } + + items_to_handlers = { + 'image': slim.tfexample_decoder.Image(shape=[32, 32, 3]), + 'label': slim.tfexample_decoder.Tensor('image/class/label'), + } + + decoder = slim.tfexample_decoder.TFExampleDecoder( + keys_to_features, items_to_handlers) + + labels_to_names = None + if dataset_utils.has_labels(dataset_dir): + labels_to_names = dataset_utils.read_label_file(dataset_dir) + + return slim.dataset.Dataset( + data_sources=file_pattern, + reader=reader, + decoder=decoder, + num_samples=SPLITS_TO_SIZES[split_name], + items_to_descriptions=_ITEMS_TO_DESCRIPTIONS, + num_classes=_NUM_CLASSES, + labels_to_names=labels_to_names) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/dataset_factory.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/dataset_factory.py new file mode 100644 index 0000000..141079a --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/dataset_factory.py @@ -0,0 +1,57 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""A factory-pattern class which returns classification image/label pairs.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from datasets import cifar10 +from datasets import flowers +from datasets import imagenet +from datasets import mnist + +datasets_map = { + 'cifar10': cifar10, + 'flowers': flowers, + 'imagenet': imagenet, + 'mnist': mnist, +} + + +def get_dataset(name, split_name, dataset_dir, file_pattern=None, reader=None): + """Given a dataset name and a split_name returns a Dataset. + + Args: + name: String, the name of the dataset. + split_name: A train/test split name. + dataset_dir: The directory where the dataset files are stored. + file_pattern: The file pattern to use for matching the dataset source files. + reader: The subclass of tf.ReaderBase. If left as `None`, then the default + reader defined by each dataset is used. + + Returns: + A `Dataset` class. + + Raises: + ValueError: If the dataset `name` is unknown. + """ + if name not in datasets_map: + raise ValueError('Name of dataset unknown %s' % name) + return datasets_map[name].get_split( + split_name, + dataset_dir, + file_pattern, + reader) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/dataset_utils.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/dataset_utils.py new file mode 100644 index 0000000..fdaefca --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/dataset_utils.py @@ -0,0 +1,150 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains utilities for downloading and converting datasets.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import os +import sys +import tarfile + +from six.moves import urllib +import tensorflow as tf + +LABELS_FILENAME = 'labels.txt' + + +def int64_feature(values): + """Returns a TF-Feature of int64s. + + Args: + values: A scalar or list of values. + + Returns: + A TF-Feature. + """ + if not isinstance(values, (tuple, list)): + values = [values] + return tf.train.Feature(int64_list=tf.train.Int64List(value=values)) + + +def bytes_feature(values): + """Returns a TF-Feature of bytes. + + Args: + values: A string. + + Returns: + A TF-Feature. + """ + return tf.train.Feature(bytes_list=tf.train.BytesList(value=[values])) + + +def float_feature(values): + """Returns a TF-Feature of floats. + + Args: + values: A scalar of list of values. + + Returns: + A TF-Feature. + """ + if not isinstance(values, (tuple, list)): + values = [values] + return tf.train.Feature(float_list=tf.train.FloatList(value=values)) + + +def image_to_tfexample(image_data, image_format, height, width, class_id): + return tf.train.Example(features=tf.train.Features(feature={ + 'image/encoded': bytes_feature(image_data), + 'image/format': bytes_feature(image_format), + 'image/class/label': int64_feature(class_id), + 'image/height': int64_feature(height), + 'image/width': int64_feature(width), + })) + + +def download_and_uncompress_tarball(tarball_url, dataset_dir): + """Downloads the `tarball_url` and uncompresses it locally. + + Args: + tarball_url: The URL of a tarball file. + dataset_dir: The directory where the temporary files are stored. + """ + filename = tarball_url.split('/')[-1] + filepath = os.path.join(dataset_dir, filename) + + def _progress(count, block_size, total_size): + sys.stdout.write('\r>> Downloading %s %.1f%%' % ( + filename, float(count * block_size) / float(total_size) * 100.0)) + sys.stdout.flush() + filepath, _ = urllib.request.urlretrieve(tarball_url, filepath, _progress) + print() + statinfo = os.stat(filepath) + print('Successfully downloaded', filename, statinfo.st_size, 'bytes.') + tarfile.open(filepath, 'r:gz').extractall(dataset_dir) + + +def write_label_file(labels_to_class_names, dataset_dir, + filename=LABELS_FILENAME): + """Writes a file with the list of class names. + + Args: + labels_to_class_names: A map of (integer) labels to class names. + dataset_dir: The directory in which the labels file should be written. + filename: The filename where the class names are written. + """ + labels_filename = os.path.join(dataset_dir, filename) + with tf.gfile.Open(labels_filename, 'w') as f: + for label in labels_to_class_names: + class_name = labels_to_class_names[label] + f.write('%d:%s\n' % (label, class_name)) + + +def has_labels(dataset_dir, filename=LABELS_FILENAME): + """Specifies whether or not the dataset directory contains a label map file. + + Args: + dataset_dir: The directory in which the labels file is found. + filename: The filename where the class names are written. + + Returns: + `True` if the labels file exists and `False` otherwise. + """ + return tf.gfile.Exists(os.path.join(dataset_dir, filename)) + + +def read_label_file(dataset_dir, filename=LABELS_FILENAME): + """Reads the labels file and returns a mapping from ID to class name. + + Args: + dataset_dir: The directory in which the labels file is found. + filename: The filename where the class names are written. + + Returns: + A map from a label (integer) to class name. + """ + labels_filename = os.path.join(dataset_dir, filename) + with tf.gfile.Open(labels_filename, 'rb') as f: + lines = f.read().decode() + lines = lines.split('\n') + lines = filter(None, lines) + + labels_to_class_names = {} + for line in lines: + index = line.index(':') + labels_to_class_names[int(line[:index])] = line[index+1:] + return labels_to_class_names diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_cifar10.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_cifar10.py new file mode 100644 index 0000000..f23618e --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_cifar10.py @@ -0,0 +1,198 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +r"""Downloads and converts cifar10 data to TFRecords of TF-Example protos. + +This module downloads the cifar10 data, uncompresses it, reads the files +that make up the cifar10 data and creates two TFRecord datasets: one for train +and one for test. Each TFRecord dataset is comprised of a set of TF-Example +protocol buffers, each of which contain a single image and label. + +The script should take several minutes to run. + +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import os +import sys +import tarfile + +import numpy as np +from six.moves import cPickle +from six.moves import urllib +import tensorflow as tf + +from datasets import dataset_utils + +# The URL where the CIFAR data can be downloaded. +_DATA_URL = 'https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz' + +# The number of training files. +_NUM_TRAIN_FILES = 5 + +# The height and width of each image. +_IMAGE_SIZE = 32 + +# The names of the classes. +_CLASS_NAMES = [ + 'airplane', + 'automobile', + 'bird', + 'cat', + 'deer', + 'dog', + 'frog', + 'horse', + 'ship', + 'truck', +] + + +def _add_to_tfrecord(filename, tfrecord_writer, offset=0): + """Loads data from the cifar10 pickle files and writes files to a TFRecord. + + Args: + filename: The filename of the cifar10 pickle file. + tfrecord_writer: The TFRecord writer to use for writing. + offset: An offset into the absolute number of images previously written. + + Returns: + The new offset. + """ + with tf.gfile.Open(filename, 'rb') as f: + if sys.version_info < (3,): + data = cPickle.load(f) + else: + data = cPickle.load(f, encoding='bytes') + + images = data[b'data'] + num_images = images.shape[0] + + images = images.reshape((num_images, 3, 32, 32)) + labels = data[b'labels'] + + with tf.Graph().as_default(): + image_placeholder = tf.placeholder(dtype=tf.uint8) + encoded_image = tf.image.encode_png(image_placeholder) + + with tf.Session('') as sess: + + for j in range(num_images): + sys.stdout.write('\r>> Reading file [%s] image %d/%d' % ( + filename, offset + j + 1, offset + num_images)) + sys.stdout.flush() + + image = np.squeeze(images[j]).transpose((1, 2, 0)) + label = labels[j] + + png_string = sess.run(encoded_image, + feed_dict={image_placeholder: image}) + + example = dataset_utils.image_to_tfexample( + png_string, b'png', _IMAGE_SIZE, _IMAGE_SIZE, label) + tfrecord_writer.write(example.SerializeToString()) + + return offset + num_images + + +def _get_output_filename(dataset_dir, split_name): + """Creates the output filename. + + Args: + dataset_dir: The dataset directory where the dataset is stored. + split_name: The name of the train/test split. + + Returns: + An absolute file path. + """ + return '%s/cifar10_%s.tfrecord' % (dataset_dir, split_name) + + +def _download_and_uncompress_dataset(dataset_dir): + """Downloads cifar10 and uncompresses it locally. + + Args: + dataset_dir: The directory where the temporary files are stored. + """ + filename = _DATA_URL.split('/')[-1] + filepath = os.path.join(dataset_dir, filename) + + if not os.path.exists(filepath): + def _progress(count, block_size, total_size): + sys.stdout.write('\r>> Downloading %s %.1f%%' % ( + filename, float(count * block_size) / float(total_size) * 100.0)) + sys.stdout.flush() + filepath, _ = urllib.request.urlretrieve(_DATA_URL, filepath, _progress) + print() + statinfo = os.stat(filepath) + print('Successfully downloaded', filename, statinfo.st_size, 'bytes.') + tarfile.open(filepath, 'r:gz').extractall(dataset_dir) + + +def _clean_up_temporary_files(dataset_dir): + """Removes temporary files used to create the dataset. + + Args: + dataset_dir: The directory where the temporary files are stored. + """ + filename = _DATA_URL.split('/')[-1] + filepath = os.path.join(dataset_dir, filename) + tf.gfile.Remove(filepath) + + tmp_dir = os.path.join(dataset_dir, 'cifar-10-batches-py') + tf.gfile.DeleteRecursively(tmp_dir) + + +def run(dataset_dir): + """Runs the download and conversion operation. + + Args: + dataset_dir: The dataset directory where the dataset is stored. + """ + if not tf.gfile.Exists(dataset_dir): + tf.gfile.MakeDirs(dataset_dir) + + training_filename = _get_output_filename(dataset_dir, 'train') + testing_filename = _get_output_filename(dataset_dir, 'test') + + if tf.gfile.Exists(training_filename) and tf.gfile.Exists(testing_filename): + print('Dataset files already exist. Exiting without re-creating them.') + return + + dataset_utils.download_and_uncompress_tarball(_DATA_URL, dataset_dir) + + # First, process the training data: + with tf.python_io.TFRecordWriter(training_filename) as tfrecord_writer: + offset = 0 + for i in range(_NUM_TRAIN_FILES): + filename = os.path.join(dataset_dir, + 'cifar-10-batches-py', + 'data_batch_%d' % (i + 1)) # 1-indexed. + offset = _add_to_tfrecord(filename, tfrecord_writer, offset) + + # Next, process the testing data: + with tf.python_io.TFRecordWriter(testing_filename) as tfrecord_writer: + filename = os.path.join(dataset_dir, + 'cifar-10-batches-py', + 'test_batch') + _add_to_tfrecord(filename, tfrecord_writer) + + # Finally, write the labels file: + labels_to_class_names = dict(zip(range(len(_CLASS_NAMES)), _CLASS_NAMES)) + dataset_utils.write_label_file(labels_to_class_names, dataset_dir) + + _clean_up_temporary_files(dataset_dir) + print('\nFinished converting the Cifar10 dataset!') diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_flowers.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_flowers.py new file mode 100644 index 0000000..93e5c41 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_flowers.py @@ -0,0 +1,211 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +r"""Downloads and converts Flowers data to TFRecords of TF-Example protos. + +This module downloads the Flowers data, uncompresses it, reads the files +that make up the Flowers data and creates two TFRecord datasets: one for train +and one for test. Each TFRecord dataset is comprised of a set of TF-Example +protocol buffers, each of which contain a single image and label. + +The script should take about a minute to run. + +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import math +import os +import random +import sys + +import tensorflow as tf + +from datasets import dataset_utils + +# The URL where the Flowers data can be downloaded. +_DATA_URL = 'http://download.tensorflow.org/example_images/flower_photos.tgz' + +# The number of images in the validation set. +_NUM_VALIDATION = 350 + +# Seed for repeatability. +_RANDOM_SEED = 0 + +# The number of shards per dataset split. +_NUM_SHARDS = 5 + + +class ImageReader(object): + """Helper class that provides TensorFlow image coding utilities.""" + + def __init__(self): + # Initializes function that decodes RGB JPEG data. + self._decode_jpeg_data = tf.placeholder(dtype=tf.string) + self._decode_jpeg = tf.image.decode_jpeg(self._decode_jpeg_data, channels=3) + + def read_image_dims(self, sess, image_data): + image = self.decode_jpeg(sess, image_data) + return image.shape[0], image.shape[1] + + def decode_jpeg(self, sess, image_data): + image = sess.run(self._decode_jpeg, + feed_dict={self._decode_jpeg_data: image_data}) + assert len(image.shape) == 3 + assert image.shape[2] == 3 + return image + + +def _get_filenames_and_classes(dataset_dir): + """Returns a list of filenames and inferred class names. + + Args: + dataset_dir: A directory containing a set of subdirectories representing + class names. Each subdirectory should contain PNG or JPG encoded images. + + Returns: + A list of image file paths, relative to `dataset_dir` and the list of + subdirectories, representing class names. + """ + flower_root = os.path.join(dataset_dir, 'flower_photos') + directories = [] + class_names = [] + for filename in os.listdir(flower_root): + path = os.path.join(flower_root, filename) + if os.path.isdir(path): + directories.append(path) + class_names.append(filename) + + photo_filenames = [] + for directory in directories: + for filename in os.listdir(directory): + path = os.path.join(directory, filename) + photo_filenames.append(path) + + return photo_filenames, sorted(class_names) + + +def _get_dataset_filename(dataset_dir, split_name, shard_id): + output_filename = 'flowers_%s_%05d-of-%05d.tfrecord' % ( + split_name, shard_id, _NUM_SHARDS) + return os.path.join(dataset_dir, output_filename) + + +def _convert_dataset(split_name, filenames, class_names_to_ids, dataset_dir): + """Converts the given filenames to a TFRecord dataset. + + Args: + split_name: The name of the dataset, either 'train' or 'validation'. + filenames: A list of absolute paths to png or jpg images. + class_names_to_ids: A dictionary from class names (strings) to ids + (integers). + dataset_dir: The directory where the converted datasets are stored. + """ + assert split_name in ['train', 'validation'] + + num_per_shard = int(math.ceil(len(filenames) / float(_NUM_SHARDS))) + + with tf.Graph().as_default(): + image_reader = ImageReader() + + with tf.Session('') as sess: + + for shard_id in range(_NUM_SHARDS): + output_filename = _get_dataset_filename( + dataset_dir, split_name, shard_id) + + with tf.python_io.TFRecordWriter(output_filename) as tfrecord_writer: + start_ndx = shard_id * num_per_shard + end_ndx = min((shard_id+1) * num_per_shard, len(filenames)) + for i in range(start_ndx, end_ndx): + sys.stdout.write('\r>> Converting image %d/%d shard %d' % ( + i+1, len(filenames), shard_id)) + sys.stdout.flush() + + # Read the filename: + image_data = tf.gfile.FastGFile(filenames[i], 'rb').read() + height, width = image_reader.read_image_dims(sess, image_data) + + class_name = os.path.basename(os.path.dirname(filenames[i])) + class_id = class_names_to_ids[class_name] + + example = dataset_utils.image_to_tfexample( + image_data, b'jpg', height, width, class_id) + tfrecord_writer.write(example.SerializeToString()) + + sys.stdout.write('\n') + sys.stdout.flush() + + +def _clean_up_temporary_files(dataset_dir): + """Removes temporary files used to create the dataset. + + Args: + dataset_dir: The directory where the temporary files are stored. + """ + filename = _DATA_URL.split('/')[-1] + filepath = os.path.join(dataset_dir, filename) + tf.gfile.Remove(filepath) + + tmp_dir = os.path.join(dataset_dir, 'flower_photos') + tf.gfile.DeleteRecursively(tmp_dir) + + +def _dataset_exists(dataset_dir): + for split_name in ['train', 'validation']: + for shard_id in range(_NUM_SHARDS): + output_filename = _get_dataset_filename( + dataset_dir, split_name, shard_id) + if not tf.gfile.Exists(output_filename): + return False + return True + + +def run(dataset_dir): + """Runs the download and conversion operation. + + Args: + dataset_dir: The dataset directory where the dataset is stored. + """ + if not tf.gfile.Exists(dataset_dir): + tf.gfile.MakeDirs(dataset_dir) + + if _dataset_exists(dataset_dir): + print('Dataset files already exist. Exiting without re-creating them.') + return + + dataset_utils.download_and_uncompress_tarball(_DATA_URL, dataset_dir) + photo_filenames, class_names = _get_filenames_and_classes(dataset_dir) + class_names_to_ids = dict(zip(class_names, range(len(class_names)))) + + # Divide into train and test: + random.seed(_RANDOM_SEED) + random.shuffle(photo_filenames) + training_filenames = photo_filenames[_NUM_VALIDATION:] + validation_filenames = photo_filenames[:_NUM_VALIDATION] + + # First, convert the training and validation sets. + _convert_dataset('train', training_filenames, class_names_to_ids, + dataset_dir) + _convert_dataset('validation', validation_filenames, class_names_to_ids, + dataset_dir) + + # Finally, write the labels file: + labels_to_class_names = dict(zip(range(len(class_names)), class_names)) + dataset_utils.write_label_file(labels_to_class_names, dataset_dir) + + _clean_up_temporary_files(dataset_dir) + print('\nFinished converting the Flowers dataset!') diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_imagenet.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_imagenet.sh new file mode 100755 index 0000000..b4b3866 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_imagenet.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +# Script to download and preprocess ImageNet Challenge 2012 +# training and validation data set. +# +# The final output of this script are sharded TFRecord files containing +# serialized Example protocol buffers. See build_imagenet_data.py for +# details of how the Example protocol buffers contain the ImageNet data. +# +# The final output of this script appears as such: +# +# data_dir/train-00000-of-01024 +# data_dir/train-00001-of-01024 +# ... +# data_dir/train-00127-of-01024 +# +# and +# +# data_dir/validation-00000-of-00128 +# data_dir/validation-00001-of-00128 +# ... +# data_dir/validation-00127-of-00128 +# +# Note that this script may take several hours to run to completion. The +# conversion of the ImageNet data to TFRecords alone takes 2-3 hours depending +# on the speed of your machine. Please be patient. +# +# **IMPORTANT** +# To download the raw images, the user must create an account with image-net.org +# and generate a username and access_key. The latter two are required for +# downloading the raw images. +# +# usage: +# cd research/slim +# bazel build :download_and_convert_imagenet +# ./bazel-bin/download_and_convert_imagenet.sh [data-dir] +set -e + +if [ -z "$1" ]; then + echo "usage download_and_convert_imagenet.sh [data dir]" + exit +fi + +# Create the output and temporary directories. +DATA_DIR="${1%/}" +SCRATCH_DIR="${DATA_DIR}/raw-data/" +mkdir -p "${DATA_DIR}" +mkdir -p "${SCRATCH_DIR}" +WORK_DIR="$0.runfiles/__main__" + +# Download the ImageNet data. +LABELS_FILE="${WORK_DIR}/datasets/imagenet_lsvrc_2015_synsets.txt" +DOWNLOAD_SCRIPT="${WORK_DIR}/datasets/download_imagenet.sh" +"${DOWNLOAD_SCRIPT}" "${SCRATCH_DIR}" "${LABELS_FILE}" + +# Note the locations of the train and validation data. +TRAIN_DIRECTORY="${SCRATCH_DIR}train/" +VALIDATION_DIRECTORY="${SCRATCH_DIR}validation/" + +# Preprocess the validation data by moving the images into the appropriate +# sub-directory based on the label (synset) of the image. +echo "Organizing the validation data into sub-directories." +PREPROCESS_VAL_SCRIPT="${WORK_DIR}/datasets/preprocess_imagenet_validation_data.py" +VAL_LABELS_FILE="${WORK_DIR}/datasets/imagenet_2012_validation_synset_labels.txt" + +"${PREPROCESS_VAL_SCRIPT}" "${VALIDATION_DIRECTORY}" "${VAL_LABELS_FILE}" + +# Convert the XML files for bounding box annotations into a single CSV. +echo "Extracting bounding box information from XML." +BOUNDING_BOX_SCRIPT="${WORK_DIR}/datasets/process_bounding_boxes.py" +BOUNDING_BOX_FILE="${SCRATCH_DIR}/imagenet_2012_bounding_boxes.csv" +BOUNDING_BOX_DIR="${SCRATCH_DIR}bounding_boxes/" + +"${BOUNDING_BOX_SCRIPT}" "${BOUNDING_BOX_DIR}" "${LABELS_FILE}" \ + | sort >"${BOUNDING_BOX_FILE}" +echo "Finished downloading and preprocessing the ImageNet data." + +# Build the TFRecords version of the ImageNet data. +BUILD_SCRIPT="${WORK_DIR}/build_imagenet_data" +OUTPUT_DIRECTORY="${DATA_DIR}" +IMAGENET_METADATA_FILE="${WORK_DIR}/datasets/imagenet_metadata.txt" + +"${BUILD_SCRIPT}" \ + --train_directory="${TRAIN_DIRECTORY}" \ + --validation_directory="${VALIDATION_DIRECTORY}" \ + --output_directory="${OUTPUT_DIRECTORY}" \ + --imagenet_metadata_file="${IMAGENET_METADATA_FILE}" \ + --labels_file="${LABELS_FILE}" \ + --bounding_box_file="${BOUNDING_BOX_FILE}" diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_mnist.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_mnist.py new file mode 100644 index 0000000..d6ae874 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_and_convert_mnist.py @@ -0,0 +1,221 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +r"""Downloads and converts MNIST data to TFRecords of TF-Example protos. + +This module downloads the MNIST data, uncompresses it, reads the files +that make up the MNIST data and creates two TFRecord datasets: one for train +and one for test. Each TFRecord dataset is comprised of a set of TF-Example +protocol buffers, each of which contain a single image and label. + +The script should take about a minute to run. + +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import gzip +import os +import sys + +import numpy as np +from six.moves import urllib +import tensorflow as tf + +from datasets import dataset_utils + +# The URLs where the MNIST data can be downloaded. +_DATA_URL = 'http://yann.lecun.com/exdb/mnist/' +_TRAIN_DATA_FILENAME = 'train-images-idx3-ubyte.gz' +_TRAIN_LABELS_FILENAME = 'train-labels-idx1-ubyte.gz' +_TEST_DATA_FILENAME = 't10k-images-idx3-ubyte.gz' +_TEST_LABELS_FILENAME = 't10k-labels-idx1-ubyte.gz' + +_IMAGE_SIZE = 28 +_NUM_CHANNELS = 1 + +# The names of the classes. +_CLASS_NAMES = [ + 'zero', + 'one', + 'two', + 'three', + 'four', + 'five', + 'size', + 'seven', + 'eight', + 'nine', +] + + +def _extract_images(filename, num_images): + """Extract the images into a numpy array. + + Args: + filename: The path to an MNIST images file. + num_images: The number of images in the file. + + Returns: + A numpy array of shape [number_of_images, height, width, channels]. + """ + print('Extracting images from: ', filename) + with gzip.open(filename) as bytestream: + bytestream.read(16) + buf = bytestream.read( + _IMAGE_SIZE * _IMAGE_SIZE * num_images * _NUM_CHANNELS) + data = np.frombuffer(buf, dtype=np.uint8) + data = data.reshape(num_images, _IMAGE_SIZE, _IMAGE_SIZE, _NUM_CHANNELS) + return data + + +def _extract_labels(filename, num_labels): + """Extract the labels into a vector of int64 label IDs. + + Args: + filename: The path to an MNIST labels file. + num_labels: The number of labels in the file. + + Returns: + A numpy array of shape [number_of_labels] + """ + print('Extracting labels from: ', filename) + with gzip.open(filename) as bytestream: + bytestream.read(8) + buf = bytestream.read(1 * num_labels) + labels = np.frombuffer(buf, dtype=np.uint8).astype(np.int64) + return labels + + +def _add_to_tfrecord(data_filename, labels_filename, num_images, + tfrecord_writer): + """Loads data from the binary MNIST files and writes files to a TFRecord. + + Args: + data_filename: The filename of the MNIST images. + labels_filename: The filename of the MNIST labels. + num_images: The number of images in the dataset. + tfrecord_writer: The TFRecord writer to use for writing. + """ + images = _extract_images(data_filename, num_images) + labels = _extract_labels(labels_filename, num_images) + + shape = (_IMAGE_SIZE, _IMAGE_SIZE, _NUM_CHANNELS) + with tf.Graph().as_default(): + image = tf.placeholder(dtype=tf.uint8, shape=shape) + encoded_png = tf.image.encode_png(image) + + with tf.Session('') as sess: + for j in range(num_images): + sys.stdout.write('\r>> Converting image %d/%d' % (j + 1, num_images)) + sys.stdout.flush() + + png_string = sess.run(encoded_png, feed_dict={image: images[j]}) + + example = dataset_utils.image_to_tfexample( + png_string, 'png'.encode(), _IMAGE_SIZE, _IMAGE_SIZE, labels[j]) + tfrecord_writer.write(example.SerializeToString()) + + +def _get_output_filename(dataset_dir, split_name): + """Creates the output filename. + + Args: + dataset_dir: The directory where the temporary files are stored. + split_name: The name of the train/test split. + + Returns: + An absolute file path. + """ + return '%s/mnist_%s.tfrecord' % (dataset_dir, split_name) + + +def _download_dataset(dataset_dir): + """Downloads MNIST locally. + + Args: + dataset_dir: The directory where the temporary files are stored. + """ + for filename in [_TRAIN_DATA_FILENAME, + _TRAIN_LABELS_FILENAME, + _TEST_DATA_FILENAME, + _TEST_LABELS_FILENAME]: + filepath = os.path.join(dataset_dir, filename) + + if not os.path.exists(filepath): + print('Downloading file %s...' % filename) + def _progress(count, block_size, total_size): + sys.stdout.write('\r>> Downloading %.1f%%' % ( + float(count * block_size) / float(total_size) * 100.0)) + sys.stdout.flush() + filepath, _ = urllib.request.urlretrieve(_DATA_URL + filename, + filepath, + _progress) + print() + with tf.gfile.GFile(filepath) as f: + size = f.size() + print('Successfully downloaded', filename, size, 'bytes.') + + +def _clean_up_temporary_files(dataset_dir): + """Removes temporary files used to create the dataset. + + Args: + dataset_dir: The directory where the temporary files are stored. + """ + for filename in [_TRAIN_DATA_FILENAME, + _TRAIN_LABELS_FILENAME, + _TEST_DATA_FILENAME, + _TEST_LABELS_FILENAME]: + filepath = os.path.join(dataset_dir, filename) + tf.gfile.Remove(filepath) + + +def run(dataset_dir): + """Runs the download and conversion operation. + + Args: + dataset_dir: The dataset directory where the dataset is stored. + """ + if not tf.gfile.Exists(dataset_dir): + tf.gfile.MakeDirs(dataset_dir) + + training_filename = _get_output_filename(dataset_dir, 'train') + testing_filename = _get_output_filename(dataset_dir, 'test') + + if tf.gfile.Exists(training_filename) and tf.gfile.Exists(testing_filename): + print('Dataset files already exist. Exiting without re-creating them.') + return + + _download_dataset(dataset_dir) + + # First, process the training data: + with tf.python_io.TFRecordWriter(training_filename) as tfrecord_writer: + data_filename = os.path.join(dataset_dir, _TRAIN_DATA_FILENAME) + labels_filename = os.path.join(dataset_dir, _TRAIN_LABELS_FILENAME) + _add_to_tfrecord(data_filename, labels_filename, 60000, tfrecord_writer) + + # Next, process the testing data: + with tf.python_io.TFRecordWriter(testing_filename) as tfrecord_writer: + data_filename = os.path.join(dataset_dir, _TEST_DATA_FILENAME) + labels_filename = os.path.join(dataset_dir, _TEST_LABELS_FILENAME) + _add_to_tfrecord(data_filename, labels_filename, 10000, tfrecord_writer) + + # Finally, write the labels file: + labels_to_class_names = dict(zip(range(len(_CLASS_NAMES)), _CLASS_NAMES)) + dataset_utils.write_label_file(labels_to_class_names, dataset_dir) + + _clean_up_temporary_files(dataset_dir) + print('\nFinished converting the MNIST dataset!') diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_imagenet.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_imagenet.sh new file mode 100755 index 0000000..c780e17 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/download_imagenet.sh @@ -0,0 +1,99 @@ +#!/bin/bash +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +# Script to download ImageNet Challenge 2012 training and validation data set. +# +# Downloads and decompresses raw images and bounding boxes. +# +# **IMPORTANT** +# To download the raw images, the user must create an account with image-net.org +# and generate a username and access_key. The latter two are required for +# downloading the raw images. +# +# usage: +# ./download_imagenet.sh [dirname] +set -e + +if [ "x$IMAGENET_ACCESS_KEY" == x -o "x$IMAGENET_USERNAME" == x ]; then + cat < ') + sys.exit(-1) + data_dir = sys.argv[1] + validation_labels_file = sys.argv[2] + + # Read in the 50000 synsets associated with the validation data set. + labels = [l.strip() for l in open(validation_labels_file).readlines()] + unique_labels = set(labels) + + # Make all sub-directories in the validation data dir. + for label in unique_labels: + labeled_data_dir = os.path.join(data_dir, label) + os.makedirs(labeled_data_dir) + + # Move all of the image to the appropriate sub-directory. + for i in xrange(len(labels)): + basename = 'ILSVRC2012_val_000%.5d.JPEG' % (i + 1) + original_filename = os.path.join(data_dir, basename) + if not os.path.exists(original_filename): + print('Failed to find: ', original_filename) + sys.exit(-1) + new_filename = os.path.join(data_dir, labels[i], basename) + os.rename(original_filename, new_filename) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/process_bounding_boxes.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/process_bounding_boxes.py new file mode 100755 index 0000000..78c899e --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/datasets/process_bounding_boxes.py @@ -0,0 +1,253 @@ +#!/usr/bin/python +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Process the ImageNet Challenge bounding boxes for TensorFlow model training. + +This script is called as + +process_bounding_boxes.py

[synsets-file] + +Where is a directory containing the downloaded and unpacked bounding box +data. If [synsets-file] is supplied, then only the bounding boxes whose +synstes are contained within this file are returned. Note that the +[synsets-file] file contains synset ids, one per line. + +The script dumps out a CSV text file in which each line contains an entry. + n00007846_64193.JPEG,0.0060,0.2620,0.7545,0.9940 + +The entry can be read as: + , , , , + +The bounding box for contains two points (xmin, ymin) and +(xmax, ymax) specifying the lower-left corner and upper-right corner of a +bounding box in *relative* coordinates. + +The user supplies a directory where the XML files reside. The directory +structure in the directory is assumed to look like this: + +/nXXXXXXXX/nXXXXXXXX_YYYY.xml + +Each XML file contains a bounding box annotation. The script: + + (1) Parses the XML file and extracts the filename, label and bounding box info. + + (2) The bounding box is specified in the XML files as integer (xmin, ymin) and + (xmax, ymax) *relative* to image size displayed to the human annotator. The + size of the image displayed to the human annotator is stored in the XML file + as integer (height, width). + + Note that the displayed size will differ from the actual size of the image + downloaded from image-net.org. To make the bounding box annotation useable, + we convert bounding box to floating point numbers relative to displayed + height and width of the image. + + Note that each XML file might contain N bounding box annotations. + + Note that the points are all clamped at a range of [0.0, 1.0] because some + human annotations extend outside the range of the supplied image. + + See details here: http://image-net.org/download-bboxes + +(3) By default, the script outputs all valid bounding boxes. If a + [synsets-file] is supplied, only the subset of bounding boxes associated + with those synsets are outputted. Importantly, one can supply a list of + synsets in the ImageNet Challenge and output the list of bounding boxes + associated with the training images of the ILSVRC. + + We use these bounding boxes to inform the random distortion of images + supplied to the network. + +If you run this script successfully, you will see the following output +to stderr: +> Finished processing 544546 XML files. +> Skipped 0 XML files not in ImageNet Challenge. +> Skipped 0 bounding boxes not in ImageNet Challenge. +> Wrote 615299 bounding boxes from 544546 annotated images. +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import glob +import os.path +import sys +import xml.etree.ElementTree as ET +from six.moves import xrange # pylint: disable=redefined-builtin + + +class BoundingBox(object): + pass + + +def GetItem(name, root, index=0): + count = 0 + for item in root.iter(name): + if count == index: + return item.text + count += 1 + # Failed to find "index" occurrence of item. + return -1 + + +def GetInt(name, root, index=0): + return int(GetItem(name, root, index)) + + +def FindNumberBoundingBoxes(root): + index = 0 + while True: + if GetInt('xmin', root, index) == -1: + break + index += 1 + return index + + +def ProcessXMLAnnotation(xml_file): + """Process a single XML file containing a bounding box.""" + # pylint: disable=broad-except + try: + tree = ET.parse(xml_file) + except Exception: + print('Failed to parse: ' + xml_file, file=sys.stderr) + return None + # pylint: enable=broad-except + root = tree.getroot() + + num_boxes = FindNumberBoundingBoxes(root) + boxes = [] + + for index in xrange(num_boxes): + box = BoundingBox() + # Grab the 'index' annotation. + box.xmin = GetInt('xmin', root, index) + box.ymin = GetInt('ymin', root, index) + box.xmax = GetInt('xmax', root, index) + box.ymax = GetInt('ymax', root, index) + + box.width = GetInt('width', root) + box.height = GetInt('height', root) + box.filename = GetItem('filename', root) + '.JPEG' + box.label = GetItem('name', root) + + xmin = float(box.xmin) / float(box.width) + xmax = float(box.xmax) / float(box.width) + ymin = float(box.ymin) / float(box.height) + ymax = float(box.ymax) / float(box.height) + + # Some images contain bounding box annotations that + # extend outside of the supplied image. See, e.g. + # n03127925/n03127925_147.xml + # Additionally, for some bounding boxes, the min > max + # or the box is entirely outside of the image. + min_x = min(xmin, xmax) + max_x = max(xmin, xmax) + box.xmin_scaled = min(max(min_x, 0.0), 1.0) + box.xmax_scaled = min(max(max_x, 0.0), 1.0) + + min_y = min(ymin, ymax) + max_y = max(ymin, ymax) + box.ymin_scaled = min(max(min_y, 0.0), 1.0) + box.ymax_scaled = min(max(max_y, 0.0), 1.0) + + boxes.append(box) + + return boxes + +if __name__ == '__main__': + if len(sys.argv) < 2 or len(sys.argv) > 3: + print('Invalid usage\n' + 'usage: process_bounding_boxes.py [synsets-file]', + file=sys.stderr) + sys.exit(-1) + + xml_files = glob.glob(sys.argv[1] + '/*/*.xml') + print('Identified %d XML files in %s' % (len(xml_files), sys.argv[1]), + file=sys.stderr) + + if len(sys.argv) == 3: + labels = set([l.strip() for l in open(sys.argv[2]).readlines()]) + print('Identified %d synset IDs in %s' % (len(labels), sys.argv[2]), + file=sys.stderr) + else: + labels = None + + skipped_boxes = 0 + skipped_files = 0 + saved_boxes = 0 + saved_files = 0 + for file_index, one_file in enumerate(xml_files): + # Example: <...>/n06470073/n00141669_6790.xml + label = os.path.basename(os.path.dirname(one_file)) + + # Determine if the annotation is from an ImageNet Challenge label. + if labels is not None and label not in labels: + skipped_files += 1 + continue + + bboxes = ProcessXMLAnnotation(one_file) + assert bboxes is not None, 'No bounding boxes found in ' + one_file + + found_box = False + for bbox in bboxes: + if labels is not None: + if bbox.label != label: + # Note: There is a slight bug in the bounding box annotation data. + # Many of the dog labels have the human label 'Scottish_deerhound' + # instead of the synset ID 'n02092002' in the bbox.label field. As a + # simple hack to overcome this issue, we only exclude bbox labels + # *which are synset ID's* that do not match original synset label for + # the XML file. + if bbox.label in labels: + skipped_boxes += 1 + continue + + # Guard against improperly specified boxes. + if (bbox.xmin_scaled >= bbox.xmax_scaled or + bbox.ymin_scaled >= bbox.ymax_scaled): + skipped_boxes += 1 + continue + + # Note bbox.filename occasionally contains '%s' in the name. This is + # data set noise that is fixed by just using the basename of the XML file. + image_filename = os.path.splitext(os.path.basename(one_file))[0] + print('%s.JPEG,%.4f,%.4f,%.4f,%.4f' % + (image_filename, + bbox.xmin_scaled, bbox.ymin_scaled, + bbox.xmax_scaled, bbox.ymax_scaled)) + + saved_boxes += 1 + found_box = True + if found_box: + saved_files += 1 + else: + skipped_files += 1 + + if not file_index % 5000: + print('--> processed %d of %d XML files.' % + (file_index + 1, len(xml_files)), + file=sys.stderr) + print('--> skipped %d boxes and %d XML files.' % + (skipped_boxes, skipped_files), file=sys.stderr) + + print('Finished processing %d XML files.' % len(xml_files), file=sys.stderr) + print('Skipped %d XML files not in ImageNet Challenge.' % skipped_files, + file=sys.stderr) + print('Skipped %d bounding boxes not in ImageNet Challenge.' % skipped_boxes, + file=sys.stderr) + print('Wrote %d bounding boxes from %d annotated images.' % + (saved_boxes, saved_files), + file=sys.stderr) + print('Finished.', file=sys.stderr) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/deployment/__init__.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/deployment/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/deployment/__init__.py @@ -0,0 +1 @@ + diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/deployment/model_deploy.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/deployment/model_deploy.py new file mode 100644 index 0000000..00b28ea --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/deployment/model_deploy.py @@ -0,0 +1,682 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Deploy Slim models across multiple clones and replicas. + +# TODO(sguada) docstring paragraph by (a) motivating the need for the file and +# (b) defining clones. + +# TODO(sguada) describe the high-level components of model deployment. +# E.g. "each model deployment is composed of several parts: a DeploymentConfig, +# which captures A, B and C, an input_fn which loads data.. etc + +To easily train a model on multiple GPUs or across multiple machines this +module provides a set of helper functions: `create_clones`, +`optimize_clones` and `deploy`. + +Usage: + + g = tf.Graph() + + # Set up DeploymentConfig + config = model_deploy.DeploymentConfig(num_clones=2, clone_on_cpu=True) + + # Create the global step on the device storing the variables. + with tf.device(config.variables_device()): + global_step = slim.create_global_step() + + # Define the inputs + with tf.device(config.inputs_device()): + images, labels = LoadData(...) + inputs_queue = slim.data.prefetch_queue((images, labels)) + + # Define the optimizer. + with tf.device(config.optimizer_device()): + optimizer = tf.train.MomentumOptimizer(FLAGS.learning_rate, FLAGS.momentum) + + # Define the model including the loss. + def model_fn(inputs_queue): + images, labels = inputs_queue.dequeue() + predictions = CreateNetwork(images) + slim.losses.log_loss(predictions, labels) + + model_dp = model_deploy.deploy(config, model_fn, [inputs_queue], + optimizer=optimizer) + + # Run training. + slim.learning.train(model_dp.train_op, my_log_dir, + summary_op=model_dp.summary_op) + +The Clone namedtuple holds together the values associated with each call to +model_fn: + * outputs: The return values of the calls to `model_fn()`. + * scope: The scope used to create the clone. + * device: The device used to create the clone. + +DeployedModel namedtuple, holds together the values needed to train multiple +clones: + * train_op: An operation that run the optimizer training op and include + all the update ops created by `model_fn`. Present only if an optimizer + was specified. + * summary_op: An operation that run the summaries created by `model_fn` + and process_gradients. + * total_loss: A `Tensor` that contains the sum of all losses created by + `model_fn` plus the regularization losses. + * clones: List of `Clone` tuples returned by `create_clones()`. + +DeploymentConfig parameters: + * num_clones: Number of model clones to deploy in each replica. + * clone_on_cpu: True if clones should be placed on CPU. + * replica_id: Integer. Index of the replica for which the model is + deployed. Usually 0 for the chief replica. + * num_replicas: Number of replicas to use. + * num_ps_tasks: Number of tasks for the `ps` job. 0 to not use replicas. + * worker_job_name: A name for the worker job. + * ps_job_name: A name for the parameter server job. + +TODO(sguada): + - describe side effect to the graph. + - what happens to summaries and update_ops. + - which graph collections are altered. + - write a tutorial on how to use this. + - analyze the possibility of calling deploy more than once. + + +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import collections + +import tensorflow as tf + +slim = tf.contrib.slim + + +__all__ = ['create_clones', + 'deploy', + 'optimize_clones', + 'DeployedModel', + 'DeploymentConfig', + 'Clone', + ] + + +# Namedtuple used to represent a clone during deployment. +Clone = collections.namedtuple('Clone', + ['outputs', # Whatever model_fn() returned. + 'scope', # The scope used to create it. + 'device', # The device used to create. + ]) + +# Namedtuple used to represent a DeployedModel, returned by deploy(). +DeployedModel = collections.namedtuple('DeployedModel', + ['train_op', # The `train_op` + 'summary_op', # The `summary_op` + 'total_loss', # The loss `Tensor` + 'clones', # A list of `Clones` tuples. + ]) + +# Default parameters for DeploymentConfig +_deployment_params = {'num_clones': 1, + 'clone_on_cpu': False, + 'replica_id': 0, + 'num_replicas': 1, + 'num_ps_tasks': 0, + 'worker_job_name': 'worker', + 'ps_job_name': 'ps'} + + +def create_clones(config, model_fn, args=None, kwargs=None): + """Creates multiple clones according to config using a `model_fn`. + + The returned values of `model_fn(*args, **kwargs)` are collected along with + the scope and device used to created it in a namedtuple + `Clone(outputs, scope, device)` + + Note: it is assumed that any loss created by `model_fn` is collected at + the tf.GraphKeys.LOSSES collection. + + To recover the losses, summaries or update_ops created by the clone use: + ```python + losses = tf.get_collection(tf.GraphKeys.LOSSES, clone.scope) + summaries = tf.get_collection(tf.GraphKeys.SUMMARIES, clone.scope) + update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS, clone.scope) + ``` + + The deployment options are specified by the config object and support + deploying one or several clones on different GPUs and one or several replicas + of such clones. + + The argument `model_fn` is called `config.num_clones` times to create the + model clones as `model_fn(*args, **kwargs)`. + + If `config` specifies deployment on multiple replicas then the default + tensorflow device is set appropriatly for each call to `model_fn` and for the + slim variable creation functions: model and global variables will be created + on the `ps` device, the clone operations will be on the `worker` device. + + Args: + config: A DeploymentConfig object. + model_fn: A callable. Called as `model_fn(*args, **kwargs)` + args: Optional list of arguments to pass to `model_fn`. + kwargs: Optional list of keyword arguments to pass to `model_fn`. + + Returns: + A list of namedtuples `Clone`. + """ + clones = [] + args = args or [] + kwargs = kwargs or {} + with slim.arg_scope([slim.model_variable, slim.variable], + device=config.variables_device()): + # Create clones. + for i in range(0, config.num_clones): + with tf.name_scope(config.clone_scope(i)) as clone_scope: + clone_device = config.clone_device(i) + with tf.device(clone_device): + with tf.variable_scope(tf.get_variable_scope(), + reuse=True if i > 0 else None): + outputs = model_fn(*args, **kwargs) + clones.append(Clone(outputs, clone_scope, clone_device)) + return clones + + +def _gather_clone_loss(clone, num_clones, regularization_losses): + """Gather the loss for a single clone. + + Args: + clone: A Clone namedtuple. + num_clones: The number of clones being deployed. + regularization_losses: Possibly empty list of regularization_losses + to add to the clone losses. + + Returns: + A tensor for the total loss for the clone. Can be None. + """ + # The return value. + sum_loss = None + # Individual components of the loss that will need summaries. + clone_loss = None + regularization_loss = None + # Compute and aggregate losses on the clone device. + with tf.device(clone.device): + all_losses = [] + clone_losses = tf.get_collection(tf.GraphKeys.LOSSES, clone.scope) + if clone_losses: + clone_loss = tf.add_n(clone_losses, name='clone_loss') + if num_clones > 1: + clone_loss = tf.div(clone_loss, 1.0 * num_clones, + name='scaled_clone_loss') + all_losses.append(clone_loss) + if regularization_losses: + regularization_loss = tf.add_n(regularization_losses, + name='regularization_loss') + all_losses.append(regularization_loss) + if all_losses: + sum_loss = tf.add_n(all_losses) + # Add the summaries out of the clone device block. + if clone_loss is not None: + tf.summary.scalar('/'.join(filter(None, + ['Losses', clone.scope, 'clone_loss'])), + clone_loss) + if regularization_loss is not None: + tf.summary.scalar('Losses/regularization_loss', regularization_loss) + return sum_loss + + +def _optimize_clone(optimizer, clone, num_clones, regularization_losses, + **kwargs): + """Compute losses and gradients for a single clone. + + Args: + optimizer: A tf.Optimizer object. + clone: A Clone namedtuple. + num_clones: The number of clones being deployed. + regularization_losses: Possibly empty list of regularization_losses + to add to the clone losses. + **kwargs: Dict of kwarg to pass to compute_gradients(). + + Returns: + A tuple (clone_loss, clone_grads_and_vars). + - clone_loss: A tensor for the total loss for the clone. Can be None. + - clone_grads_and_vars: List of (gradient, variable) for the clone. + Can be empty. + """ + sum_loss = _gather_clone_loss(clone, num_clones, regularization_losses) + clone_grad = None + if sum_loss is not None: + with tf.device(clone.device): + clone_grad = optimizer.compute_gradients(sum_loss, **kwargs) + return sum_loss, clone_grad + + +def optimize_clones(clones, optimizer, + regularization_losses=None, + **kwargs): + """Compute clone losses and gradients for the given list of `Clones`. + + Note: The regularization_losses are added to the first clone losses. + + Args: + clones: List of `Clones` created by `create_clones()`. + optimizer: An `Optimizer` object. + regularization_losses: Optional list of regularization losses. If None it + will gather them from tf.GraphKeys.REGULARIZATION_LOSSES. Pass `[]` to + exclude them. + **kwargs: Optional list of keyword arguments to pass to `compute_gradients`. + + Returns: + A tuple (total_loss, grads_and_vars). + - total_loss: A Tensor containing the average of the clone losses including + the regularization loss. + - grads_and_vars: A List of tuples (gradient, variable) containing the sum + of the gradients for each variable. + + """ + grads_and_vars = [] + clones_losses = [] + num_clones = len(clones) + if regularization_losses is None: + regularization_losses = tf.get_collection( + tf.GraphKeys.REGULARIZATION_LOSSES) + for clone in clones: + with tf.name_scope(clone.scope): + clone_loss, clone_grad = _optimize_clone( + optimizer, clone, num_clones, regularization_losses, **kwargs) + if clone_loss is not None: + clones_losses.append(clone_loss) + grads_and_vars.append(clone_grad) + # Only use regularization_losses for the first clone + regularization_losses = None + # Compute the total_loss summing all the clones_losses. + total_loss = tf.add_n(clones_losses, name='total_loss') + # Sum the gradients across clones. + grads_and_vars = _sum_clones_gradients(grads_and_vars) + return total_loss, grads_and_vars + + +def deploy(config, + model_fn, + args=None, + kwargs=None, + optimizer=None, + summarize_gradients=False): + """Deploys a Slim-constructed model across multiple clones. + + The deployment options are specified by the config object and support + deploying one or several clones on different GPUs and one or several replicas + of such clones. + + The argument `model_fn` is called `config.num_clones` times to create the + model clones as `model_fn(*args, **kwargs)`. + + The optional argument `optimizer` is an `Optimizer` object. If not `None`, + the deployed model is configured for training with that optimizer. + + If `config` specifies deployment on multiple replicas then the default + tensorflow device is set appropriatly for each call to `model_fn` and for the + slim variable creation functions: model and global variables will be created + on the `ps` device, the clone operations will be on the `worker` device. + + Args: + config: A `DeploymentConfig` object. + model_fn: A callable. Called as `model_fn(*args, **kwargs)` + args: Optional list of arguments to pass to `model_fn`. + kwargs: Optional list of keyword arguments to pass to `model_fn`. + optimizer: Optional `Optimizer` object. If passed the model is deployed + for training with that optimizer. + summarize_gradients: Whether or not add summaries to the gradients. + + Returns: + A `DeployedModel` namedtuple. + + """ + # Gather initial summaries. + summaries = set(tf.get_collection(tf.GraphKeys.SUMMARIES)) + + # Create Clones. + clones = create_clones(config, model_fn, args, kwargs) + first_clone = clones[0] + + # Gather update_ops from the first clone. These contain, for example, + # the updates for the batch_norm variables created by model_fn. + update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS, first_clone.scope) + + train_op = None + total_loss = None + with tf.device(config.optimizer_device()): + if optimizer: + # Place the global step on the device storing the variables. + with tf.device(config.variables_device()): + global_step = slim.get_or_create_global_step() + + # Compute the gradients for the clones. + total_loss, clones_gradients = optimize_clones(clones, optimizer) + + if clones_gradients: + if summarize_gradients: + # Add summaries to the gradients. + summaries |= set(_add_gradients_summaries(clones_gradients)) + + # Create gradient updates. + grad_updates = optimizer.apply_gradients(clones_gradients, + global_step=global_step) + update_ops.append(grad_updates) + + update_op = tf.group(*update_ops) + with tf.control_dependencies([update_op]): + train_op = tf.identity(total_loss, name='train_op') + else: + clones_losses = [] + regularization_losses = tf.get_collection( + tf.GraphKeys.REGULARIZATION_LOSSES) + for clone in clones: + with tf.name_scope(clone.scope): + clone_loss = _gather_clone_loss(clone, len(clones), + regularization_losses) + if clone_loss is not None: + clones_losses.append(clone_loss) + # Only use regularization_losses for the first clone + regularization_losses = None + if clones_losses: + total_loss = tf.add_n(clones_losses, name='total_loss') + + # Add the summaries from the first clone. These contain the summaries + # created by model_fn and either optimize_clones() or _gather_clone_loss(). + summaries |= set(tf.get_collection(tf.GraphKeys.SUMMARIES, + first_clone.scope)) + + if total_loss is not None: + # Add total_loss to summary. + summaries.add(tf.summary.scalar('total_loss', total_loss)) + + if summaries: + # Merge all summaries together. + summary_op = tf.summary.merge(list(summaries), name='summary_op') + else: + summary_op = None + + return DeployedModel(train_op, summary_op, total_loss, clones) + + +def _sum_clones_gradients(clone_grads): + """Calculate the sum gradient for each shared variable across all clones. + + This function assumes that the clone_grads has been scaled appropriately by + 1 / num_clones. + + Args: + clone_grads: A List of List of tuples (gradient, variable), one list per + `Clone`. + + Returns: + List of tuples of (gradient, variable) where the gradient has been summed + across all clones. + """ + sum_grads = [] + for grad_and_vars in zip(*clone_grads): + # Note that each grad_and_vars looks like the following: + # ((grad_var0_clone0, var0), ... (grad_varN_cloneN, varN)) + grads = [] + var = grad_and_vars[0][1] + for g, v in grad_and_vars: + assert v == var + if g is not None: + grads.append(g) + if grads: + if len(grads) > 1: + sum_grad = tf.add_n(grads, name=var.op.name + '/sum_grads') + else: + sum_grad = grads[0] + sum_grads.append((sum_grad, var)) + return sum_grads + + +def _add_gradients_summaries(grads_and_vars): + """Add histogram summaries to gradients. + + Note: The summaries are also added to the SUMMARIES collection. + + Args: + grads_and_vars: A list of gradient to variable pairs (tuples). + + Returns: + The _list_ of the added summaries for grads_and_vars. + """ + summaries = [] + for grad, var in grads_and_vars: + if grad is not None: + if isinstance(grad, tf.IndexedSlices): + grad_values = grad.values + else: + grad_values = grad + summaries.append(tf.summary.histogram(var.op.name + ':gradient', + grad_values)) + summaries.append(tf.summary.histogram(var.op.name + ':gradient_norm', + tf.global_norm([grad_values]))) + else: + tf.logging.info('Var %s has no gradient', var.op.name) + return summaries + + +class DeploymentConfig(object): + """Configuration for deploying a model with `deploy()`. + + You can pass an instance of this class to `deploy()` to specify exactly + how to deploy the model to build. If you do not pass one, an instance built + from the default deployment_hparams will be used. + """ + + def __init__(self, + num_clones=1, + clone_on_cpu=False, + replica_id=0, + num_replicas=1, + num_ps_tasks=0, + worker_job_name='worker', + ps_job_name='ps'): + """Create a DeploymentConfig. + + The config describes how to deploy a model across multiple clones and + replicas. The model will be replicated `num_clones` times in each replica. + If `clone_on_cpu` is True, each clone will placed on CPU. + + If `num_replicas` is 1, the model is deployed via a single process. In that + case `worker_device`, `num_ps_tasks`, and `ps_device` are ignored. + + If `num_replicas` is greater than 1, then `worker_device` and `ps_device` + must specify TensorFlow devices for the `worker` and `ps` jobs and + `num_ps_tasks` must be positive. + + Args: + num_clones: Number of model clones to deploy in each replica. + clone_on_cpu: If True clones would be placed on CPU. + replica_id: Integer. Index of the replica for which the model is + deployed. Usually 0 for the chief replica. + num_replicas: Number of replicas to use. + num_ps_tasks: Number of tasks for the `ps` job. 0 to not use replicas. + worker_job_name: A name for the worker job. + ps_job_name: A name for the parameter server job. + + Raises: + ValueError: If the arguments are invalid. + """ + if num_replicas > 1: + if num_ps_tasks < 1: + raise ValueError('When using replicas num_ps_tasks must be positive') + if num_replicas > 1 or num_ps_tasks > 0: + if not worker_job_name: + raise ValueError('Must specify worker_job_name when using replicas') + if not ps_job_name: + raise ValueError('Must specify ps_job_name when using parameter server') + if replica_id >= num_replicas: + raise ValueError('replica_id must be less than num_replicas') + self._num_clones = num_clones + self._clone_on_cpu = clone_on_cpu + self._replica_id = replica_id + self._num_replicas = num_replicas + self._num_ps_tasks = num_ps_tasks + self._ps_device = '/job:' + ps_job_name if num_ps_tasks > 0 else '' + self._worker_device = '/job:' + worker_job_name if num_ps_tasks > 0 else '' + + @property + def num_clones(self): + return self._num_clones + + @property + def clone_on_cpu(self): + return self._clone_on_cpu + + @property + def replica_id(self): + return self._replica_id + + @property + def num_replicas(self): + return self._num_replicas + + @property + def num_ps_tasks(self): + return self._num_ps_tasks + + @property + def ps_device(self): + return self._ps_device + + @property + def worker_device(self): + return self._worker_device + + def caching_device(self): + """Returns the device to use for caching variables. + + Variables are cached on the worker CPU when using replicas. + + Returns: + A device string or None if the variables do not need to be cached. + """ + if self._num_ps_tasks > 0: + return lambda op: op.device + else: + return None + + def clone_device(self, clone_index): + """Device used to create the clone and all the ops inside the clone. + + Args: + clone_index: Int, representing the clone_index. + + Returns: + A value suitable for `tf.device()`. + + Raises: + ValueError: if `clone_index` is greater or equal to the number of clones". + """ + if clone_index >= self._num_clones: + raise ValueError('clone_index must be less than num_clones') + device = '' + if self._num_ps_tasks > 0: + device += self._worker_device + if self._clone_on_cpu: + device += '/device:CPU:0' + else: + device += '/device:GPU:%d' % clone_index + return device + + def clone_scope(self, clone_index): + """Name scope to create the clone. + + Args: + clone_index: Int, representing the clone_index. + + Returns: + A name_scope suitable for `tf.name_scope()`. + + Raises: + ValueError: if `clone_index` is greater or equal to the number of clones". + """ + if clone_index >= self._num_clones: + raise ValueError('clone_index must be less than num_clones') + scope = '' + if self._num_clones > 1: + scope = 'clone_%d' % clone_index + return scope + + def optimizer_device(self): + """Device to use with the optimizer. + + Returns: + A value suitable for `tf.device()`. + """ + if self._num_ps_tasks > 0 or self._num_clones > 0: + return self._worker_device + '/device:CPU:0' + else: + return '' + + def inputs_device(self): + """Device to use to build the inputs. + + Returns: + A value suitable for `tf.device()`. + """ + device = '' + if self._num_ps_tasks > 0: + device += self._worker_device + device += '/device:CPU:0' + return device + + def variables_device(self, distribution_mod=None): + """Returns the device to use for variables created inside the clone. + + Returns: + A value suitable for `tf.device()`. + """ + device = '' + if self._num_ps_tasks > 0: + device += self._ps_device + device += '/device:CPU:0' + + class _PSDeviceChooser(object): + """Slim device chooser for variables when using PS.""" + + def __init__(self, device, tasks): + self._device = device + self._tasks = tasks + self._task = 0 + + def choose(self, op): + if op.device: + return op.device + node_def = op if isinstance(op, tf.NodeDef) else op.node_def + if node_def.op.startswith('Variable'): + t = self._task + self._task = (self._task + 1) % self._tasks + d = '%s/task:%d' % (self._device, t) + return d + else: + return op.device + + def op_device_chooser(op): + return op.device + + if distribution_mod is not None: + return op_device_chooser + elif not self._num_ps_tasks: + return device + else: + chooser = _PSDeviceChooser(device, self._num_ps_tasks) + return chooser.choose diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/deployment/model_deploy_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/deployment/model_deploy_test.py new file mode 100644 index 0000000..780b691 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/deployment/model_deploy_test.py @@ -0,0 +1,572 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for model_deploy.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import tensorflow as tf + +from deployment import model_deploy + +slim = tf.contrib.slim + + +class DeploymentConfigTest(tf.test.TestCase): + + def testDefaults(self): + deploy_config = model_deploy.DeploymentConfig() + + self.assertEqual(slim.get_variables(), []) + self.assertEqual(deploy_config.caching_device(), None) + self.assertDeviceEqual(deploy_config.clone_device(0), 'GPU:0') + self.assertEqual(deploy_config.clone_scope(0), '') + self.assertDeviceEqual(deploy_config.optimizer_device(), 'CPU:0') + self.assertDeviceEqual(deploy_config.inputs_device(), 'CPU:0') + self.assertDeviceEqual(deploy_config.variables_device(), 'CPU:0') + + def testCPUonly(self): + deploy_config = model_deploy.DeploymentConfig(clone_on_cpu=True) + + self.assertEqual(deploy_config.caching_device(), None) + self.assertDeviceEqual(deploy_config.clone_device(0), 'CPU:0') + self.assertEqual(deploy_config.clone_scope(0), '') + self.assertDeviceEqual(deploy_config.optimizer_device(), 'CPU:0') + self.assertDeviceEqual(deploy_config.inputs_device(), 'CPU:0') + self.assertDeviceEqual(deploy_config.variables_device(), 'CPU:0') + + def testMultiGPU(self): + deploy_config = model_deploy.DeploymentConfig(num_clones=2) + + self.assertEqual(deploy_config.caching_device(), None) + self.assertDeviceEqual(deploy_config.clone_device(0), 'GPU:0') + self.assertDeviceEqual(deploy_config.clone_device(1), 'GPU:1') + self.assertEqual(deploy_config.clone_scope(0), 'clone_0') + self.assertEqual(deploy_config.clone_scope(1), 'clone_1') + self.assertDeviceEqual(deploy_config.optimizer_device(), 'CPU:0') + self.assertDeviceEqual(deploy_config.inputs_device(), 'CPU:0') + self.assertDeviceEqual(deploy_config.variables_device(), 'CPU:0') + + def testPS(self): + deploy_config = model_deploy.DeploymentConfig(num_clones=1, num_ps_tasks=1) + + self.assertDeviceEqual(deploy_config.clone_device(0), + '/job:worker/device:GPU:0') + self.assertEqual(deploy_config.clone_scope(0), '') + self.assertDeviceEqual(deploy_config.optimizer_device(), + '/job:worker/device:CPU:0') + self.assertDeviceEqual(deploy_config.inputs_device(), + '/job:worker/device:CPU:0') + with tf.device(deploy_config.variables_device()): + a = tf.Variable(0) + b = tf.Variable(0) + c = tf.no_op() + d = slim.variable('a', [], + caching_device=deploy_config.caching_device()) + self.assertDeviceEqual(a.device, '/job:ps/task:0/device:CPU:0') + self.assertDeviceEqual(a.device, a.value().device) + self.assertDeviceEqual(b.device, '/job:ps/task:0/device:CPU:0') + self.assertDeviceEqual(b.device, b.value().device) + self.assertDeviceEqual(c.device, '') + self.assertDeviceEqual(d.device, '/job:ps/task:0/device:CPU:0') + self.assertDeviceEqual(d.value().device, '') + + def testMultiGPUPS(self): + deploy_config = model_deploy.DeploymentConfig(num_clones=2, num_ps_tasks=1) + + self.assertEqual(deploy_config.caching_device()(tf.no_op()), '') + self.assertDeviceEqual(deploy_config.clone_device(0), + '/job:worker/device:GPU:0') + self.assertDeviceEqual(deploy_config.clone_device(1), + '/job:worker/device:GPU:1') + self.assertEqual(deploy_config.clone_scope(0), 'clone_0') + self.assertEqual(deploy_config.clone_scope(1), 'clone_1') + self.assertDeviceEqual(deploy_config.optimizer_device(), + '/job:worker/device:CPU:0') + self.assertDeviceEqual(deploy_config.inputs_device(), + '/job:worker/device:CPU:0') + + def testReplicasPS(self): + deploy_config = model_deploy.DeploymentConfig(num_replicas=2, + num_ps_tasks=2) + + self.assertDeviceEqual(deploy_config.clone_device(0), + '/job:worker/device:GPU:0') + self.assertEqual(deploy_config.clone_scope(0), '') + self.assertDeviceEqual(deploy_config.optimizer_device(), + '/job:worker/device:CPU:0') + self.assertDeviceEqual(deploy_config.inputs_device(), + '/job:worker/device:CPU:0') + + def testReplicasMultiGPUPS(self): + deploy_config = model_deploy.DeploymentConfig(num_replicas=2, + num_clones=2, + num_ps_tasks=2) + self.assertDeviceEqual(deploy_config.clone_device(0), + '/job:worker/device:GPU:0') + self.assertDeviceEqual(deploy_config.clone_device(1), + '/job:worker/device:GPU:1') + self.assertEqual(deploy_config.clone_scope(0), 'clone_0') + self.assertEqual(deploy_config.clone_scope(1), 'clone_1') + self.assertDeviceEqual(deploy_config.optimizer_device(), + '/job:worker/device:CPU:0') + self.assertDeviceEqual(deploy_config.inputs_device(), + '/job:worker/device:CPU:0') + + def testVariablesPS(self): + deploy_config = model_deploy.DeploymentConfig(num_ps_tasks=2) + + with tf.device(deploy_config.variables_device()): + a = tf.Variable(0) + b = tf.Variable(0) + c = tf.no_op() + d = slim.variable('a', [], + caching_device=deploy_config.caching_device()) + + self.assertDeviceEqual(a.device, '/job:ps/task:0/device:CPU:0') + self.assertDeviceEqual(a.device, a.value().device) + self.assertDeviceEqual(b.device, '/job:ps/task:1/device:CPU:0') + self.assertDeviceEqual(b.device, b.value().device) + self.assertDeviceEqual(c.device, '') + self.assertDeviceEqual(d.device, '/job:ps/task:0/device:CPU:0') + self.assertDeviceEqual(d.value().device, '') + + +def LogisticClassifier(inputs, labels, scope=None, reuse=None): + with tf.variable_scope(scope, 'LogisticClassifier', [inputs, labels], + reuse=reuse): + predictions = slim.fully_connected(inputs, 1, activation_fn=tf.sigmoid, + scope='fully_connected') + slim.losses.log_loss(predictions, labels) + return predictions + + +def BatchNormClassifier(inputs, labels, scope=None, reuse=None): + with tf.variable_scope(scope, 'BatchNormClassifier', [inputs, labels], + reuse=reuse): + inputs = slim.batch_norm(inputs, decay=0.1, fused=True) + predictions = slim.fully_connected(inputs, 1, + activation_fn=tf.sigmoid, + scope='fully_connected') + slim.losses.log_loss(predictions, labels) + return predictions + + +class CreatecloneTest(tf.test.TestCase): + + def setUp(self): + # Create an easy training set: + np.random.seed(0) + + self._inputs = np.zeros((16, 4)) + self._labels = np.random.randint(0, 2, size=(16, 1)).astype(np.float32) + self._logdir = self.get_temp_dir() + + for i in range(16): + j = int(2 * self._labels[i] + np.random.randint(0, 2)) + self._inputs[i, j] = 1 + + def testCreateLogisticClassifier(self): + g = tf.Graph() + with g.as_default(): + tf.set_random_seed(0) + tf_inputs = tf.constant(self._inputs, dtype=tf.float32) + tf_labels = tf.constant(self._labels, dtype=tf.float32) + + model_fn = LogisticClassifier + clone_args = (tf_inputs, tf_labels) + deploy_config = model_deploy.DeploymentConfig(num_clones=1) + + self.assertEqual(slim.get_variables(), []) + clones = model_deploy.create_clones(deploy_config, model_fn, clone_args) + clone = clones[0] + self.assertEqual(len(slim.get_variables()), 2) + for v in slim.get_variables(): + self.assertDeviceEqual(v.device, 'CPU:0') + self.assertDeviceEqual(v.value().device, 'CPU:0') + self.assertEqual(clone.outputs.op.name, + 'LogisticClassifier/fully_connected/Sigmoid') + self.assertEqual(clone.scope, '') + self.assertDeviceEqual(clone.device, 'GPU:0') + self.assertEqual(len(slim.losses.get_losses()), 1) + update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) + self.assertEqual(update_ops, []) + + def testCreateSingleclone(self): + g = tf.Graph() + with g.as_default(): + tf.set_random_seed(0) + tf_inputs = tf.constant(self._inputs, dtype=tf.float32) + tf_labels = tf.constant(self._labels, dtype=tf.float32) + + model_fn = BatchNormClassifier + clone_args = (tf_inputs, tf_labels) + deploy_config = model_deploy.DeploymentConfig(num_clones=1) + + self.assertEqual(slim.get_variables(), []) + clones = model_deploy.create_clones(deploy_config, model_fn, clone_args) + clone = clones[0] + self.assertEqual(len(slim.get_variables()), 5) + for v in slim.get_variables(): + self.assertDeviceEqual(v.device, 'CPU:0') + self.assertDeviceEqual(v.value().device, 'CPU:0') + self.assertEqual(clone.outputs.op.name, + 'BatchNormClassifier/fully_connected/Sigmoid') + self.assertEqual(clone.scope, '') + self.assertDeviceEqual(clone.device, 'GPU:0') + self.assertEqual(len(slim.losses.get_losses()), 1) + update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) + self.assertEqual(len(update_ops), 2) + + def testCreateMulticlone(self): + g = tf.Graph() + with g.as_default(): + tf.set_random_seed(0) + tf_inputs = tf.constant(self._inputs, dtype=tf.float32) + tf_labels = tf.constant(self._labels, dtype=tf.float32) + + model_fn = BatchNormClassifier + clone_args = (tf_inputs, tf_labels) + num_clones = 4 + deploy_config = model_deploy.DeploymentConfig(num_clones=num_clones) + + self.assertEqual(slim.get_variables(), []) + clones = model_deploy.create_clones(deploy_config, model_fn, clone_args) + self.assertEqual(len(slim.get_variables()), 5) + for v in slim.get_variables(): + self.assertDeviceEqual(v.device, 'CPU:0') + self.assertDeviceEqual(v.value().device, 'CPU:0') + self.assertEqual(len(clones), num_clones) + for i, clone in enumerate(clones): + self.assertEqual( + clone.outputs.op.name, + 'clone_%d/BatchNormClassifier/fully_connected/Sigmoid' % i) + update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS, clone.scope) + self.assertEqual(len(update_ops), 2) + self.assertEqual(clone.scope, 'clone_%d/' % i) + self.assertDeviceEqual(clone.device, 'GPU:%d' % i) + + def testCreateOnecloneWithPS(self): + g = tf.Graph() + with g.as_default(): + tf.set_random_seed(0) + tf_inputs = tf.constant(self._inputs, dtype=tf.float32) + tf_labels = tf.constant(self._labels, dtype=tf.float32) + + model_fn = BatchNormClassifier + clone_args = (tf_inputs, tf_labels) + deploy_config = model_deploy.DeploymentConfig(num_clones=1, + num_ps_tasks=1) + + self.assertEqual(slim.get_variables(), []) + clones = model_deploy.create_clones(deploy_config, model_fn, clone_args) + self.assertEqual(len(clones), 1) + clone = clones[0] + self.assertEqual(clone.outputs.op.name, + 'BatchNormClassifier/fully_connected/Sigmoid') + self.assertDeviceEqual(clone.device, '/job:worker/device:GPU:0') + self.assertEqual(clone.scope, '') + self.assertEqual(len(slim.get_variables()), 5) + for v in slim.get_variables(): + self.assertDeviceEqual(v.device, '/job:ps/task:0/CPU:0') + self.assertDeviceEqual(v.device, v.value().device) + + def testCreateMulticloneWithPS(self): + g = tf.Graph() + with g.as_default(): + tf.set_random_seed(0) + tf_inputs = tf.constant(self._inputs, dtype=tf.float32) + tf_labels = tf.constant(self._labels, dtype=tf.float32) + + model_fn = BatchNormClassifier + clone_args = (tf_inputs, tf_labels) + deploy_config = model_deploy.DeploymentConfig(num_clones=2, + num_ps_tasks=2) + + self.assertEqual(slim.get_variables(), []) + clones = model_deploy.create_clones(deploy_config, model_fn, clone_args) + self.assertEqual(len(slim.get_variables()), 5) + for i, v in enumerate(slim.get_variables()): + t = i % 2 + self.assertDeviceEqual(v.device, '/job:ps/task:%d/device:CPU:0' % t) + self.assertDeviceEqual(v.device, v.value().device) + self.assertEqual(len(clones), 2) + for i, clone in enumerate(clones): + self.assertEqual( + clone.outputs.op.name, + 'clone_%d/BatchNormClassifier/fully_connected/Sigmoid' % i) + self.assertEqual(clone.scope, 'clone_%d/' % i) + self.assertDeviceEqual(clone.device, '/job:worker/device:GPU:%d' % i) + + +class OptimizeclonesTest(tf.test.TestCase): + + def setUp(self): + # Create an easy training set: + np.random.seed(0) + + self._inputs = np.zeros((16, 4)) + self._labels = np.random.randint(0, 2, size=(16, 1)).astype(np.float32) + self._logdir = self.get_temp_dir() + + for i in range(16): + j = int(2 * self._labels[i] + np.random.randint(0, 2)) + self._inputs[i, j] = 1 + + def testCreateLogisticClassifier(self): + g = tf.Graph() + with g.as_default(): + tf.set_random_seed(0) + tf_inputs = tf.constant(self._inputs, dtype=tf.float32) + tf_labels = tf.constant(self._labels, dtype=tf.float32) + + model_fn = LogisticClassifier + clone_args = (tf_inputs, tf_labels) + deploy_config = model_deploy.DeploymentConfig(num_clones=1) + + self.assertEqual(slim.get_variables(), []) + clones = model_deploy.create_clones(deploy_config, model_fn, clone_args) + self.assertEqual(len(slim.get_variables()), 2) + update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) + self.assertEqual(update_ops, []) + + optimizer = tf.train.GradientDescentOptimizer(learning_rate=1.0) + total_loss, grads_and_vars = model_deploy.optimize_clones(clones, + optimizer) + self.assertEqual(len(grads_and_vars), len(tf.trainable_variables())) + self.assertEqual(total_loss.op.name, 'total_loss') + for g, v in grads_and_vars: + self.assertDeviceEqual(g.device, 'GPU:0') + self.assertDeviceEqual(v.device, 'CPU:0') + + def testCreateSingleclone(self): + g = tf.Graph() + with g.as_default(): + tf.set_random_seed(0) + tf_inputs = tf.constant(self._inputs, dtype=tf.float32) + tf_labels = tf.constant(self._labels, dtype=tf.float32) + + model_fn = BatchNormClassifier + clone_args = (tf_inputs, tf_labels) + deploy_config = model_deploy.DeploymentConfig(num_clones=1) + + self.assertEqual(slim.get_variables(), []) + clones = model_deploy.create_clones(deploy_config, model_fn, clone_args) + self.assertEqual(len(slim.get_variables()), 5) + update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) + self.assertEqual(len(update_ops), 2) + + optimizer = tf.train.GradientDescentOptimizer(learning_rate=1.0) + total_loss, grads_and_vars = model_deploy.optimize_clones(clones, + optimizer) + self.assertEqual(len(grads_and_vars), len(tf.trainable_variables())) + self.assertEqual(total_loss.op.name, 'total_loss') + for g, v in grads_and_vars: + self.assertDeviceEqual(g.device, 'GPU:0') + self.assertDeviceEqual(v.device, 'CPU:0') + + def testCreateMulticlone(self): + g = tf.Graph() + with g.as_default(): + tf.set_random_seed(0) + tf_inputs = tf.constant(self._inputs, dtype=tf.float32) + tf_labels = tf.constant(self._labels, dtype=tf.float32) + + model_fn = BatchNormClassifier + clone_args = (tf_inputs, tf_labels) + num_clones = 4 + deploy_config = model_deploy.DeploymentConfig(num_clones=num_clones) + + self.assertEqual(slim.get_variables(), []) + clones = model_deploy.create_clones(deploy_config, model_fn, clone_args) + self.assertEqual(len(slim.get_variables()), 5) + update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) + self.assertEqual(len(update_ops), num_clones * 2) + + optimizer = tf.train.GradientDescentOptimizer(learning_rate=1.0) + total_loss, grads_and_vars = model_deploy.optimize_clones(clones, + optimizer) + self.assertEqual(len(grads_and_vars), len(tf.trainable_variables())) + self.assertEqual(total_loss.op.name, 'total_loss') + for g, v in grads_and_vars: + self.assertDeviceEqual(g.device, '') + self.assertDeviceEqual(v.device, 'CPU:0') + + def testCreateMulticloneCPU(self): + g = tf.Graph() + with g.as_default(): + tf.set_random_seed(0) + tf_inputs = tf.constant(self._inputs, dtype=tf.float32) + tf_labels = tf.constant(self._labels, dtype=tf.float32) + + model_fn = BatchNormClassifier + model_args = (tf_inputs, tf_labels) + num_clones = 4 + deploy_config = model_deploy.DeploymentConfig(num_clones=num_clones, + clone_on_cpu=True) + + self.assertEqual(slim.get_variables(), []) + clones = model_deploy.create_clones(deploy_config, model_fn, model_args) + self.assertEqual(len(slim.get_variables()), 5) + update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) + self.assertEqual(len(update_ops), num_clones * 2) + + optimizer = tf.train.GradientDescentOptimizer(learning_rate=1.0) + total_loss, grads_and_vars = model_deploy.optimize_clones(clones, + optimizer) + self.assertEqual(len(grads_and_vars), len(tf.trainable_variables())) + self.assertEqual(total_loss.op.name, 'total_loss') + for g, v in grads_and_vars: + self.assertDeviceEqual(g.device, '') + self.assertDeviceEqual(v.device, 'CPU:0') + + def testCreateOnecloneWithPS(self): + g = tf.Graph() + with g.as_default(): + tf.set_random_seed(0) + tf_inputs = tf.constant(self._inputs, dtype=tf.float32) + tf_labels = tf.constant(self._labels, dtype=tf.float32) + + model_fn = BatchNormClassifier + model_args = (tf_inputs, tf_labels) + deploy_config = model_deploy.DeploymentConfig(num_clones=1, + num_ps_tasks=1) + + self.assertEqual(slim.get_variables(), []) + clones = model_deploy.create_clones(deploy_config, model_fn, model_args) + self.assertEqual(len(slim.get_variables()), 5) + update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) + self.assertEqual(len(update_ops), 2) + + optimizer = tf.train.GradientDescentOptimizer(learning_rate=1.0) + total_loss, grads_and_vars = model_deploy.optimize_clones(clones, + optimizer) + self.assertEqual(len(grads_and_vars), len(tf.trainable_variables())) + self.assertEqual(total_loss.op.name, 'total_loss') + for g, v in grads_and_vars: + self.assertDeviceEqual(g.device, '/job:worker/device:GPU:0') + self.assertDeviceEqual(v.device, '/job:ps/task:0/CPU:0') + + +class DeployTest(tf.test.TestCase): + + def setUp(self): + # Create an easy training set: + np.random.seed(0) + + self._inputs = np.zeros((16, 4)) + self._labels = np.random.randint(0, 2, size=(16, 1)).astype(np.float32) + self._logdir = self.get_temp_dir() + + for i in range(16): + j = int(2 * self._labels[i] + np.random.randint(0, 2)) + self._inputs[i, j] = 1 + + def _addBesselsCorrection(self, sample_size, expected_var): + correction_factor = sample_size / (sample_size - 1) + expected_var *= correction_factor + return expected_var + + def testLocalTrainOp(self): + g = tf.Graph() + with g.as_default(): + tf.set_random_seed(0) + tf_inputs = tf.constant(self._inputs, dtype=tf.float32) + tf_labels = tf.constant(self._labels, dtype=tf.float32) + + model_fn = BatchNormClassifier + model_args = (tf_inputs, tf_labels) + deploy_config = model_deploy.DeploymentConfig(num_clones=2, + clone_on_cpu=True) + + optimizer = tf.train.GradientDescentOptimizer(learning_rate=1.0) + + self.assertEqual(slim.get_variables(), []) + model = model_deploy.deploy(deploy_config, model_fn, model_args, + optimizer=optimizer) + + update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) + self.assertEqual(len(update_ops), 4) + self.assertEqual(len(model.clones), 2) + self.assertEqual(model.total_loss.op.name, 'total_loss') + self.assertEqual(model.summary_op.op.name, 'summary_op/summary_op') + self.assertEqual(model.train_op.op.name, 'train_op') + + with tf.Session() as sess: + sess.run(tf.global_variables_initializer()) + moving_mean = tf.contrib.framework.get_variables_by_name( + 'moving_mean')[0] + moving_variance = tf.contrib.framework.get_variables_by_name( + 'moving_variance')[0] + initial_loss = sess.run(model.total_loss) + initial_mean, initial_variance = sess.run([moving_mean, + moving_variance]) + self.assertAllClose(initial_mean, [0.0, 0.0, 0.0, 0.0]) + self.assertAllClose(initial_variance, [1.0, 1.0, 1.0, 1.0]) + for _ in range(10): + sess.run(model.train_op) + final_loss = sess.run(model.total_loss) + self.assertLess(final_loss, initial_loss / 5.0) + + final_mean, final_variance = sess.run([moving_mean, + moving_variance]) + expected_mean = np.array([0.125, 0.25, 0.375, 0.25]) + expected_var = np.array([0.109375, 0.1875, 0.234375, 0.1875]) + expected_var = self._addBesselsCorrection(16, expected_var) + self.assertAllClose(final_mean, expected_mean) + self.assertAllClose(final_variance, expected_var) + + def testNoSummariesOnGPU(self): + with tf.Graph().as_default(): + deploy_config = model_deploy.DeploymentConfig(num_clones=2) + + # clone function creates a fully_connected layer with a regularizer loss. + def ModelFn(): + inputs = tf.constant(1.0, shape=(10, 20), dtype=tf.float32) + reg = tf.contrib.layers.l2_regularizer(0.001) + tf.contrib.layers.fully_connected(inputs, 30, weights_regularizer=reg) + + model = model_deploy.deploy( + deploy_config, ModelFn, + optimizer=tf.train.GradientDescentOptimizer(1.0)) + # The model summary op should have a few summary inputs and all of them + # should be on the CPU. + self.assertTrue(model.summary_op.op.inputs) + for inp in model.summary_op.op.inputs: + self.assertEqual('/device:CPU:0', inp.device) + + def testNoSummariesOnGPUForEvals(self): + with tf.Graph().as_default(): + deploy_config = model_deploy.DeploymentConfig(num_clones=2) + + # clone function creates a fully_connected layer with a regularizer loss. + def ModelFn(): + inputs = tf.constant(1.0, shape=(10, 20), dtype=tf.float32) + reg = tf.contrib.layers.l2_regularizer(0.001) + tf.contrib.layers.fully_connected(inputs, 30, weights_regularizer=reg) + + # No optimizer here, it's an eval. + model = model_deploy.deploy(deploy_config, ModelFn) + # The model summary op should have a few summary inputs and all of them + # should be on the CPU. + self.assertTrue(model.summary_op.op.inputs) + for inp in model.summary_op.op.inputs: + self.assertEqual('/device:CPU:0', inp.device) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/download_and_convert_data.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/download_and_convert_data.py new file mode 100644 index 0000000..924a3a4 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/download_and_convert_data.py @@ -0,0 +1,73 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +r"""Downloads and converts a particular dataset. + +Usage: +```shell + +$ python download_and_convert_data.py \ + --dataset_name=mnist \ + --dataset_dir=/tmp/mnist + +$ python download_and_convert_data.py \ + --dataset_name=cifar10 \ + --dataset_dir=/tmp/cifar10 + +$ python download_and_convert_data.py \ + --dataset_name=flowers \ + --dataset_dir=/tmp/flowers +``` +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from datasets import download_and_convert_cifar10 +from datasets import download_and_convert_flowers +from datasets import download_and_convert_mnist + +FLAGS = tf.app.flags.FLAGS + +tf.app.flags.DEFINE_string( + 'dataset_name', + None, + 'The name of the dataset to convert, one of "cifar10", "flowers", "mnist".') + +tf.app.flags.DEFINE_string( + 'dataset_dir', + None, + 'The directory where the output TFRecords and temporary files are saved.') + + +def main(_): + if not FLAGS.dataset_name: + raise ValueError('You must supply the dataset name with --dataset_name') + if not FLAGS.dataset_dir: + raise ValueError('You must supply the dataset directory with --dataset_dir') + + if FLAGS.dataset_name == 'cifar10': + download_and_convert_cifar10.run(FLAGS.dataset_dir) + elif FLAGS.dataset_name == 'flowers': + download_and_convert_flowers.run(FLAGS.dataset_dir) + elif FLAGS.dataset_name == 'mnist': + download_and_convert_mnist.run(FLAGS.dataset_dir) + else: + raise ValueError( + 'dataset_name [%s] was not recognized.' % FLAGS.dataset_name) + +if __name__ == '__main__': + tf.app.run() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/eval_image_classifier.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/eval_image_classifier.py new file mode 100644 index 0000000..8a42641 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/eval_image_classifier.py @@ -0,0 +1,197 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Generic evaluation script that evaluates a model using a given dataset.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import math +import tensorflow as tf + +from datasets import dataset_factory +from nets import nets_factory +from preprocessing import preprocessing_factory + +slim = tf.contrib.slim + +tf.app.flags.DEFINE_integer( + 'batch_size', 100, 'The number of samples in each batch.') + +tf.app.flags.DEFINE_integer( + 'max_num_batches', None, + 'Max number of batches to evaluate by default use all.') + +tf.app.flags.DEFINE_string( + 'master', '', 'The address of the TensorFlow master to use.') + +tf.app.flags.DEFINE_string( + 'checkpoint_path', '/tmp/tfmodel/', + 'The directory where the model was written to or an absolute path to a ' + 'checkpoint file.') + +tf.app.flags.DEFINE_string( + 'eval_dir', '/tmp/tfmodel/', 'Directory where the results are saved to.') + +tf.app.flags.DEFINE_integer( + 'num_preprocessing_threads', 4, + 'The number of threads used to create the batches.') + +tf.app.flags.DEFINE_string( + 'dataset_name', 'imagenet', 'The name of the dataset to load.') + +tf.app.flags.DEFINE_string( + 'dataset_split_name', 'test', 'The name of the train/test split.') + +tf.app.flags.DEFINE_string( + 'dataset_dir', None, 'The directory where the dataset files are stored.') + +tf.app.flags.DEFINE_integer( + 'labels_offset', 0, + 'An offset for the labels in the dataset. This flag is primarily used to ' + 'evaluate the VGG and ResNet architectures which do not use a background ' + 'class for the ImageNet dataset.') + +tf.app.flags.DEFINE_string( + 'model_name', 'inception_v3', 'The name of the architecture to evaluate.') + +tf.app.flags.DEFINE_string( + 'preprocessing_name', None, 'The name of the preprocessing to use. If left ' + 'as `None`, then the model_name flag is used.') + +tf.app.flags.DEFINE_float( + 'moving_average_decay', None, + 'The decay to use for the moving average.' + 'If left as None, then moving averages are not used.') + +tf.app.flags.DEFINE_integer( + 'eval_image_size', None, 'Eval image size') + +tf.app.flags.DEFINE_bool( + 'quantize', False, 'whether to use quantized graph or not.') + +FLAGS = tf.app.flags.FLAGS + + +def main(_): + if not FLAGS.dataset_dir: + raise ValueError('You must supply the dataset directory with --dataset_dir') + + tf.logging.set_verbosity(tf.logging.INFO) + with tf.Graph().as_default(): + tf_global_step = slim.get_or_create_global_step() + + ###################### + # Select the dataset # + ###################### + dataset = dataset_factory.get_dataset( + FLAGS.dataset_name, FLAGS.dataset_split_name, FLAGS.dataset_dir) + + #################### + # Select the model # + #################### + network_fn = nets_factory.get_network_fn( + FLAGS.model_name, + num_classes=(dataset.num_classes - FLAGS.labels_offset), + is_training=False) + + ############################################################## + # Create a dataset provider that loads data from the dataset # + ############################################################## + provider = slim.dataset_data_provider.DatasetDataProvider( + dataset, + shuffle=False, + common_queue_capacity=2 * FLAGS.batch_size, + common_queue_min=FLAGS.batch_size) + [image, label] = provider.get(['image', 'label']) + label -= FLAGS.labels_offset + + ##################################### + # Select the preprocessing function # + ##################################### + preprocessing_name = FLAGS.preprocessing_name or FLAGS.model_name + image_preprocessing_fn = preprocessing_factory.get_preprocessing( + preprocessing_name, + is_training=False) + + eval_image_size = FLAGS.eval_image_size or network_fn.default_image_size + + image = image_preprocessing_fn(image, eval_image_size, eval_image_size) + + images, labels = tf.train.batch( + [image, label], + batch_size=FLAGS.batch_size, + num_threads=FLAGS.num_preprocessing_threads, + capacity=5 * FLAGS.batch_size) + + #################### + # Define the model # + #################### + logits, _ = network_fn(images) + + if FLAGS.quantize: + tf.contrib.quantize.create_eval_graph() + + if FLAGS.moving_average_decay: + variable_averages = tf.train.ExponentialMovingAverage( + FLAGS.moving_average_decay, tf_global_step) + variables_to_restore = variable_averages.variables_to_restore( + slim.get_model_variables()) + variables_to_restore[tf_global_step.op.name] = tf_global_step + else: + variables_to_restore = slim.get_variables_to_restore() + + predictions = tf.argmax(logits, 1) + labels = tf.squeeze(labels) + + # Define the metrics: + names_to_values, names_to_updates = slim.metrics.aggregate_metric_map({ + 'Accuracy': slim.metrics.streaming_accuracy(predictions, labels), + 'Recall_5': slim.metrics.streaming_recall_at_k( + logits, labels, 5), + }) + + # Print the summaries to screen. + for name, value in names_to_values.items(): + summary_name = 'eval/%s' % name + op = tf.summary.scalar(summary_name, value, collections=[]) + op = tf.Print(op, [value], summary_name) + tf.add_to_collection(tf.GraphKeys.SUMMARIES, op) + + # TODO(sguada) use num_epochs=1 + if FLAGS.max_num_batches: + num_batches = FLAGS.max_num_batches + else: + # This ensures that we make a single pass over all of the data. + num_batches = math.ceil(dataset.num_samples / float(FLAGS.batch_size)) + + if tf.gfile.IsDirectory(FLAGS.checkpoint_path): + checkpoint_path = tf.train.latest_checkpoint(FLAGS.checkpoint_path) + else: + checkpoint_path = FLAGS.checkpoint_path + + tf.logging.info('Evaluating %s' % checkpoint_path) + + slim.evaluation.evaluate_once( + master=FLAGS.master, + checkpoint_path=checkpoint_path, + logdir=FLAGS.eval_dir, + num_evals=num_batches, + eval_op=list(names_to_updates.values()), + variables_to_restore=variables_to_restore) + + +if __name__ == '__main__': + tf.app.run() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/export_inference_graph.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/export_inference_graph.py new file mode 100644 index 0000000..864b7a5 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/export_inference_graph.py @@ -0,0 +1,156 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +r"""Saves out a GraphDef containing the architecture of the model. + +To use it, run something like this, with a model name defined by slim: + +bazel build tensorflow_models/research/slim:export_inference_graph +bazel-bin/tensorflow_models/research/slim/export_inference_graph \ +--model_name=inception_v3 --output_file=/tmp/inception_v3_inf_graph.pb + +If you then want to use the resulting model with your own or pretrained +checkpoints as part of a mobile model, you can run freeze_graph to get a graph +def with the variables inlined as constants using: + +bazel build tensorflow/python/tools:freeze_graph +bazel-bin/tensorflow/python/tools/freeze_graph \ +--input_graph=/tmp/inception_v3_inf_graph.pb \ +--input_checkpoint=/tmp/checkpoints/inception_v3.ckpt \ +--input_binary=true --output_graph=/tmp/frozen_inception_v3.pb \ +--output_node_names=InceptionV3/Predictions/Reshape_1 + +The output node names will vary depending on the model, but you can inspect and +estimate them using the summarize_graph tool: + +bazel build tensorflow/tools/graph_transforms:summarize_graph +bazel-bin/tensorflow/tools/graph_transforms/summarize_graph \ +--in_graph=/tmp/inception_v3_inf_graph.pb + +To run the resulting graph in C++, you can look at the label_image sample code: + +bazel build tensorflow/examples/label_image:label_image +bazel-bin/tensorflow/examples/label_image/label_image \ +--image=${HOME}/Pictures/flowers.jpg \ +--input_layer=input \ +--output_layer=InceptionV3/Predictions/Reshape_1 \ +--graph=/tmp/frozen_inception_v3.pb \ +--labels=/tmp/imagenet_slim_labels.txt \ +--input_mean=0 \ +--input_std=255 + +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +import os + +import tensorflow as tf + +from tensorflow.python.platform import gfile +from datasets import dataset_factory +from nets import nets_factory + + +slim = tf.contrib.slim + +tf.app.flags.DEFINE_string( + 'model_name', 'inception_v3', 'The name of the architecture to save.') + +tf.app.flags.DEFINE_boolean( + 'is_training', False, + 'Whether to save out a training-focused version of the model.') + +tf.app.flags.DEFINE_integer( + 'image_size', None, + 'The image size to use, otherwise use the model default_image_size.') + +tf.app.flags.DEFINE_integer( + 'batch_size', None, + 'Batch size for the exported model. Defaulted to "None" so batch size can ' + 'be specified at model runtime.') + +tf.app.flags.DEFINE_string('dataset_name', 'imagenet', + 'The name of the dataset to use with the model.') + +tf.app.flags.DEFINE_integer( + 'labels_offset', 0, + 'An offset for the labels in the dataset. This flag is primarily used to ' + 'evaluate the VGG and ResNet architectures which do not use a background ' + 'class for the ImageNet dataset.') + +tf.app.flags.DEFINE_string( + 'output_file', '', 'Where to save the resulting file to.') + +tf.app.flags.DEFINE_string( + 'dataset_dir', '', 'Directory to save intermediate dataset files to') + +tf.app.flags.DEFINE_bool( + 'quantize', False, 'whether to use quantized graph or not.') + +tf.app.flags.DEFINE_bool( + 'is_video_model', False, 'whether to use 5-D inputs for video model.') + +tf.app.flags.DEFINE_integer( + 'num_frames', None, + 'The number of frames to use. Only used if is_video_model is True.') + +tf.app.flags.DEFINE_bool('write_text_graphdef', False, + 'Whether to write a text version of graphdef.') + +FLAGS = tf.app.flags.FLAGS + + +def main(_): + if not FLAGS.output_file: + raise ValueError('You must supply the path to save to with --output_file') + if FLAGS.is_video_model and not FLAGS.num_frames: + raise ValueError( + 'Number of frames must be specified for video models with --num_frames') + tf.logging.set_verbosity(tf.logging.INFO) + with tf.Graph().as_default() as graph: + dataset = dataset_factory.get_dataset(FLAGS.dataset_name, 'train', + FLAGS.dataset_dir) + network_fn = nets_factory.get_network_fn( + FLAGS.model_name, + num_classes=(dataset.num_classes - FLAGS.labels_offset), + is_training=FLAGS.is_training) + image_size = FLAGS.image_size or network_fn.default_image_size + if FLAGS.is_video_model: + input_shape = [FLAGS.batch_size, FLAGS.num_frames, + image_size, image_size, 3] + else: + input_shape = [FLAGS.batch_size, image_size, image_size, 3] + placeholder = tf.placeholder(name='input', dtype=tf.float32, + shape=input_shape) + network_fn(placeholder) + + if FLAGS.quantize: + tf.contrib.quantize.create_eval_graph() + + graph_def = graph.as_graph_def() + if FLAGS.write_text_graphdef: + tf.io.write_graph( + graph_def, + os.path.dirname(FLAGS.output_file), + os.path.basename(FLAGS.output_file), + as_text=True) + else: + with gfile.GFile(FLAGS.output_file, 'wb') as f: + f.write(graph_def.SerializeToString()) + + +if __name__ == '__main__': + tf.app.run() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/export_inference_graph_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/export_inference_graph_test.py new file mode 100644 index 0000000..42474f2 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/export_inference_graph_test.py @@ -0,0 +1,44 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Tests for export_inference_graph.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import os + + +import tensorflow as tf + +from tensorflow.python.platform import gfile +import export_inference_graph + + +class ExportInferenceGraphTest(tf.test.TestCase): + + def testExportInferenceGraph(self): + tmpdir = self.get_temp_dir() + output_file = os.path.join(tmpdir, 'inception_v3.pb') + flags = tf.app.flags.FLAGS + flags.output_file = output_file + flags.model_name = 'inception_v3' + flags.dataset_dir = tmpdir + export_inference_graph.main(None) + self.assertTrue(gfile.Exists(output_file)) + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/__init__.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/__init__.py @@ -0,0 +1 @@ + diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/alexnet.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/alexnet.py new file mode 100644 index 0000000..e860a6c --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/alexnet.py @@ -0,0 +1,138 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains a model definition for AlexNet. + +This work was first described in: + ImageNet Classification with Deep Convolutional Neural Networks + Alex Krizhevsky, Ilya Sutskever and Geoffrey E. Hinton + +and later refined in: + One weird trick for parallelizing convolutional neural networks + Alex Krizhevsky, 2014 + +Here we provide the implementation proposed in "One weird trick" and not +"ImageNet Classification", as per the paper, the LRN layers have been removed. + +Usage: + with slim.arg_scope(alexnet.alexnet_v2_arg_scope()): + outputs, end_points = alexnet.alexnet_v2(inputs) + +@@alexnet_v2 +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +slim = tf.contrib.slim +trunc_normal = lambda stddev: tf.truncated_normal_initializer(0.0, stddev) + + +def alexnet_v2_arg_scope(weight_decay=0.0005): + with slim.arg_scope([slim.conv2d, slim.fully_connected], + activation_fn=tf.nn.relu, + biases_initializer=tf.constant_initializer(0.1), + weights_regularizer=slim.l2_regularizer(weight_decay)): + with slim.arg_scope([slim.conv2d], padding='SAME'): + with slim.arg_scope([slim.max_pool2d], padding='VALID') as arg_sc: + return arg_sc + + +def alexnet_v2(inputs, + num_classes=1000, + is_training=True, + dropout_keep_prob=0.5, + spatial_squeeze=True, + scope='alexnet_v2', + global_pool=False): + """AlexNet version 2. + + Described in: http://arxiv.org/pdf/1404.5997v2.pdf + Parameters from: + github.com/akrizhevsky/cuda-convnet2/blob/master/layers/ + layers-imagenet-1gpu.cfg + + Note: All the fully_connected layers have been transformed to conv2d layers. + To use in classification mode, resize input to 224x224 or set + global_pool=True. To use in fully convolutional mode, set + spatial_squeeze to false. + The LRN layers have been removed and change the initializers from + random_normal_initializer to xavier_initializer. + + Args: + inputs: a tensor of size [batch_size, height, width, channels]. + num_classes: the number of predicted classes. If 0 or None, the logits layer + is omitted and the input features to the logits layer are returned instead. + is_training: whether or not the model is being trained. + dropout_keep_prob: the probability that activations are kept in the dropout + layers during training. + spatial_squeeze: whether or not should squeeze the spatial dimensions of the + logits. Useful to remove unnecessary dimensions for classification. + scope: Optional scope for the variables. + global_pool: Optional boolean flag. If True, the input to the classification + layer is avgpooled to size 1x1, for any input size. (This is not part + of the original AlexNet.) + + Returns: + net: the output of the logits layer (if num_classes is a non-zero integer), + or the non-dropped-out input to the logits layer (if num_classes is 0 + or None). + end_points: a dict of tensors with intermediate activations. + """ + with tf.variable_scope(scope, 'alexnet_v2', [inputs]) as sc: + end_points_collection = sc.original_name_scope + '_end_points' + # Collect outputs for conv2d, fully_connected and max_pool2d. + with slim.arg_scope([slim.conv2d, slim.fully_connected, slim.max_pool2d], + outputs_collections=[end_points_collection]): + net = slim.conv2d(inputs, 64, [11, 11], 4, padding='VALID', + scope='conv1') + net = slim.max_pool2d(net, [3, 3], 2, scope='pool1') + net = slim.conv2d(net, 192, [5, 5], scope='conv2') + net = slim.max_pool2d(net, [3, 3], 2, scope='pool2') + net = slim.conv2d(net, 384, [3, 3], scope='conv3') + net = slim.conv2d(net, 384, [3, 3], scope='conv4') + net = slim.conv2d(net, 256, [3, 3], scope='conv5') + net = slim.max_pool2d(net, [3, 3], 2, scope='pool5') + + # Use conv2d instead of fully_connected layers. + with slim.arg_scope([slim.conv2d], + weights_initializer=trunc_normal(0.005), + biases_initializer=tf.constant_initializer(0.1)): + net = slim.conv2d(net, 4096, [5, 5], padding='VALID', + scope='fc6') + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout6') + net = slim.conv2d(net, 4096, [1, 1], scope='fc7') + # Convert end_points_collection into a end_point dict. + end_points = slim.utils.convert_collection_to_dict( + end_points_collection) + if global_pool: + net = tf.reduce_mean(net, [1, 2], keep_dims=True, name='global_pool') + end_points['global_pool'] = net + if num_classes: + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout7') + net = slim.conv2d(net, num_classes, [1, 1], + activation_fn=None, + normalizer_fn=None, + biases_initializer=tf.zeros_initializer(), + scope='fc8') + if spatial_squeeze: + net = tf.squeeze(net, [1, 2], name='fc8/squeezed') + end_points[sc.name + '/fc8'] = net + return net, end_points +alexnet_v2.default_image_size = 224 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/alexnet_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/alexnet_test.py new file mode 100644 index 0000000..6f85d33 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/alexnet_test.py @@ -0,0 +1,180 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for slim.nets.alexnet.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import alexnet + +slim = tf.contrib.slim + + +class AlexnetV2Test(tf.test.TestCase): + + def testBuild(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = alexnet.alexnet_v2(inputs, num_classes) + self.assertEquals(logits.op.name, 'alexnet_v2/fc8/squeezed') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + + def testFullyConvolutional(self): + batch_size = 1 + height, width = 300, 400 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = alexnet.alexnet_v2(inputs, num_classes, spatial_squeeze=False) + self.assertEquals(logits.op.name, 'alexnet_v2/fc8/BiasAdd') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, 4, 7, num_classes]) + + def testGlobalPool(self): + batch_size = 1 + height, width = 256, 256 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = alexnet.alexnet_v2(inputs, num_classes, spatial_squeeze=False, + global_pool=True) + self.assertEquals(logits.op.name, 'alexnet_v2/fc8/BiasAdd') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, 1, 1, num_classes]) + + def testEndPoints(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = alexnet.alexnet_v2(inputs, num_classes) + expected_names = ['alexnet_v2/conv1', + 'alexnet_v2/pool1', + 'alexnet_v2/conv2', + 'alexnet_v2/pool2', + 'alexnet_v2/conv3', + 'alexnet_v2/conv4', + 'alexnet_v2/conv5', + 'alexnet_v2/pool5', + 'alexnet_v2/fc6', + 'alexnet_v2/fc7', + 'alexnet_v2/fc8' + ] + self.assertSetEqual(set(end_points.keys()), set(expected_names)) + + def testNoClasses(self): + batch_size = 5 + height, width = 224, 224 + num_classes = None + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, end_points = alexnet.alexnet_v2(inputs, num_classes) + expected_names = ['alexnet_v2/conv1', + 'alexnet_v2/pool1', + 'alexnet_v2/conv2', + 'alexnet_v2/pool2', + 'alexnet_v2/conv3', + 'alexnet_v2/conv4', + 'alexnet_v2/conv5', + 'alexnet_v2/pool5', + 'alexnet_v2/fc6', + 'alexnet_v2/fc7' + ] + self.assertSetEqual(set(end_points.keys()), set(expected_names)) + self.assertTrue(net.op.name.startswith('alexnet_v2/fc7')) + self.assertListEqual(net.get_shape().as_list(), + [batch_size, 1, 1, 4096]) + + def testModelVariables(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + alexnet.alexnet_v2(inputs, num_classes) + expected_names = ['alexnet_v2/conv1/weights', + 'alexnet_v2/conv1/biases', + 'alexnet_v2/conv2/weights', + 'alexnet_v2/conv2/biases', + 'alexnet_v2/conv3/weights', + 'alexnet_v2/conv3/biases', + 'alexnet_v2/conv4/weights', + 'alexnet_v2/conv4/biases', + 'alexnet_v2/conv5/weights', + 'alexnet_v2/conv5/biases', + 'alexnet_v2/fc6/weights', + 'alexnet_v2/fc6/biases', + 'alexnet_v2/fc7/weights', + 'alexnet_v2/fc7/biases', + 'alexnet_v2/fc8/weights', + 'alexnet_v2/fc8/biases', + ] + model_variables = [v.op.name for v in slim.get_model_variables()] + self.assertSetEqual(set(model_variables), set(expected_names)) + + def testEvaluation(self): + batch_size = 2 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + eval_inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = alexnet.alexnet_v2(eval_inputs, is_training=False) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + predictions = tf.argmax(logits, 1) + self.assertListEqual(predictions.get_shape().as_list(), [batch_size]) + + def testTrainEvalWithReuse(self): + train_batch_size = 2 + eval_batch_size = 1 + train_height, train_width = 224, 224 + eval_height, eval_width = 300, 400 + num_classes = 1000 + with self.test_session(): + train_inputs = tf.random_uniform( + (train_batch_size, train_height, train_width, 3)) + logits, _ = alexnet.alexnet_v2(train_inputs) + self.assertListEqual(logits.get_shape().as_list(), + [train_batch_size, num_classes]) + tf.get_variable_scope().reuse_variables() + eval_inputs = tf.random_uniform( + (eval_batch_size, eval_height, eval_width, 3)) + logits, _ = alexnet.alexnet_v2(eval_inputs, is_training=False, + spatial_squeeze=False) + self.assertListEqual(logits.get_shape().as_list(), + [eval_batch_size, 4, 7, num_classes]) + logits = tf.reduce_mean(logits, [1, 2]) + predictions = tf.argmax(logits, 1) + self.assertEquals(predictions.get_shape().as_list(), [eval_batch_size]) + + def testForward(self): + batch_size = 1 + height, width = 224, 224 + with self.test_session() as sess: + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = alexnet.alexnet_v2(inputs) + sess.run(tf.global_variables_initializer()) + output = sess.run(logits) + self.assertTrue(output.any()) + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/cifarnet.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/cifarnet.py new file mode 100644 index 0000000..97ed944 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/cifarnet.py @@ -0,0 +1,117 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains a variant of the CIFAR-10 model definition.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +slim = tf.contrib.slim + +trunc_normal = lambda stddev: tf.truncated_normal_initializer(stddev=stddev) + + +def cifarnet(images, num_classes=10, is_training=False, + dropout_keep_prob=0.5, + prediction_fn=slim.softmax, + scope='CifarNet'): + """Creates a variant of the CifarNet model. + + Note that since the output is a set of 'logits', the values fall in the + interval of (-infinity, infinity). Consequently, to convert the outputs to a + probability distribution over the characters, one will need to convert them + using the softmax function: + + logits = cifarnet.cifarnet(images, is_training=False) + probabilities = tf.nn.softmax(logits) + predictions = tf.argmax(logits, 1) + + Args: + images: A batch of `Tensors` of size [batch_size, height, width, channels]. + num_classes: the number of classes in the dataset. If 0 or None, the logits + layer is omitted and the input features to the logits layer are returned + instead. + is_training: specifies whether or not we're currently training the model. + This variable will determine the behaviour of the dropout layer. + dropout_keep_prob: the percentage of activation values that are retained. + prediction_fn: a function to get predictions out of logits. + scope: Optional variable_scope. + + Returns: + net: a 2D Tensor with the logits (pre-softmax activations) if num_classes + is a non-zero integer, or the input to the logits layer if num_classes + is 0 or None. + end_points: a dictionary from components of the network to the corresponding + activation. + """ + end_points = {} + + with tf.variable_scope(scope, 'CifarNet', [images]): + net = slim.conv2d(images, 64, [5, 5], scope='conv1') + end_points['conv1'] = net + net = slim.max_pool2d(net, [2, 2], 2, scope='pool1') + end_points['pool1'] = net + net = tf.nn.lrn(net, 4, bias=1.0, alpha=0.001/9.0, beta=0.75, name='norm1') + net = slim.conv2d(net, 64, [5, 5], scope='conv2') + end_points['conv2'] = net + net = tf.nn.lrn(net, 4, bias=1.0, alpha=0.001/9.0, beta=0.75, name='norm2') + net = slim.max_pool2d(net, [2, 2], 2, scope='pool2') + end_points['pool2'] = net + net = slim.flatten(net) + end_points['Flatten'] = net + net = slim.fully_connected(net, 384, scope='fc3') + end_points['fc3'] = net + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout3') + net = slim.fully_connected(net, 192, scope='fc4') + end_points['fc4'] = net + if not num_classes: + return net, end_points + logits = slim.fully_connected(net, num_classes, + biases_initializer=tf.zeros_initializer(), + weights_initializer=trunc_normal(1/192.0), + weights_regularizer=None, + activation_fn=None, + scope='logits') + + end_points['Logits'] = logits + end_points['Predictions'] = prediction_fn(logits, scope='Predictions') + + return logits, end_points +cifarnet.default_image_size = 32 + + +def cifarnet_arg_scope(weight_decay=0.004): + """Defines the default cifarnet argument scope. + + Args: + weight_decay: The weight decay to use for regularizing the model. + + Returns: + An `arg_scope` to use for the inception v3 model. + """ + with slim.arg_scope( + [slim.conv2d], + weights_initializer=tf.truncated_normal_initializer(stddev=5e-2), + activation_fn=tf.nn.relu): + with slim.arg_scope( + [slim.fully_connected], + biases_initializer=tf.constant_initializer(0.1), + weights_initializer=trunc_normal(0.04), + weights_regularizer=slim.l2_regularizer(weight_decay), + activation_fn=tf.nn.relu) as sc: + return sc diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/cyclegan.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/cyclegan.py new file mode 100644 index 0000000..4f9936f --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/cyclegan.py @@ -0,0 +1,278 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Defines the CycleGAN generator and discriminator networks.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +from six.moves import xrange # pylint: disable=redefined-builtin +import tensorflow as tf + +layers = tf.contrib.layers + + +def cyclegan_arg_scope(instance_norm_center=True, + instance_norm_scale=True, + instance_norm_epsilon=0.001, + weights_init_stddev=0.02, + weight_decay=0.0): + """Returns a default argument scope for all generators and discriminators. + + Args: + instance_norm_center: Whether instance normalization applies centering. + instance_norm_scale: Whether instance normalization applies scaling. + instance_norm_epsilon: Small float added to the variance in the instance + normalization to avoid dividing by zero. + weights_init_stddev: Standard deviation of the random values to initialize + the convolution kernels with. + weight_decay: Magnitude of weight decay applied to all convolution kernel + variables of the generator. + + Returns: + An arg-scope. + """ + instance_norm_params = { + 'center': instance_norm_center, + 'scale': instance_norm_scale, + 'epsilon': instance_norm_epsilon, + } + + weights_regularizer = None + if weight_decay and weight_decay > 0.0: + weights_regularizer = layers.l2_regularizer(weight_decay) + + with tf.contrib.framework.arg_scope( + [layers.conv2d], + normalizer_fn=layers.instance_norm, + normalizer_params=instance_norm_params, + weights_initializer=tf.random_normal_initializer(0, weights_init_stddev), + weights_regularizer=weights_regularizer) as sc: + return sc + + +def cyclegan_upsample(net, num_outputs, stride, method='conv2d_transpose', + pad_mode='REFLECT', align_corners=False): + """Upsamples the given inputs. + + Args: + net: A Tensor of size [batch_size, height, width, filters]. + num_outputs: The number of output filters. + stride: A list of 2 scalars or a 1x2 Tensor indicating the scale, + relative to the inputs, of the output dimensions. For example, if kernel + size is [2, 3], then the output height and width will be twice and three + times the input size. + method: The upsampling method: 'nn_upsample_conv', 'bilinear_upsample_conv', + or 'conv2d_transpose'. + pad_mode: mode for tf.pad, one of "CONSTANT", "REFLECT", or "SYMMETRIC". + align_corners: option for method, 'bilinear_upsample_conv'. If true, the + centers of the 4 corner pixels of the input and output tensors are + aligned, preserving the values at the corner pixels. + + Returns: + A Tensor which was upsampled using the specified method. + + Raises: + ValueError: if `method` is not recognized. + """ + with tf.variable_scope('upconv'): + net_shape = tf.shape(net) + height = net_shape[1] + width = net_shape[2] + + # Reflection pad by 1 in spatial dimensions (axes 1, 2 = h, w) to make a 3x3 + # 'valid' convolution produce an output with the same dimension as the + # input. + spatial_pad_1 = np.array([[0, 0], [1, 1], [1, 1], [0, 0]]) + + if method == 'nn_upsample_conv': + net = tf.image.resize_nearest_neighbor( + net, [stride[0] * height, stride[1] * width]) + net = tf.pad(net, spatial_pad_1, pad_mode) + net = layers.conv2d(net, num_outputs, kernel_size=[3, 3], padding='valid') + elif method == 'bilinear_upsample_conv': + net = tf.image.resize_bilinear( + net, [stride[0] * height, stride[1] * width], + align_corners=align_corners) + net = tf.pad(net, spatial_pad_1, pad_mode) + net = layers.conv2d(net, num_outputs, kernel_size=[3, 3], padding='valid') + elif method == 'conv2d_transpose': + # This corrects 1 pixel offset for images with even width and height. + # conv2d is left aligned and conv2d_transpose is right aligned for even + # sized images (while doing 'SAME' padding). + # Note: This doesn't reflect actual model in paper. + net = layers.conv2d_transpose( + net, num_outputs, kernel_size=[3, 3], stride=stride, padding='valid') + net = net[:, 1:, 1:, :] + else: + raise ValueError('Unknown method: [%s]' % method) + + return net + + +def _dynamic_or_static_shape(tensor): + shape = tf.shape(tensor) + static_shape = tf.contrib.util.constant_value(shape) + return static_shape if static_shape is not None else shape + + +def cyclegan_generator_resnet(images, + arg_scope_fn=cyclegan_arg_scope, + num_resnet_blocks=6, + num_filters=64, + upsample_fn=cyclegan_upsample, + kernel_size=3, + tanh_linear_slope=0.0, + is_training=False): + """Defines the cyclegan resnet network architecture. + + As closely as possible following + https://github.com/junyanz/CycleGAN/blob/master/models/architectures.lua#L232 + + FYI: This network requires input height and width to be divisible by 4 in + order to generate an output with shape equal to input shape. Assertions will + catch this if input dimensions are known at graph construction time, but + there's no protection if unknown at graph construction time (you'll see an + error). + + Args: + images: Input image tensor of shape [batch_size, h, w, 3]. + arg_scope_fn: Function to create the global arg_scope for the network. + num_resnet_blocks: Number of ResNet blocks in the middle of the generator. + num_filters: Number of filters of the first hidden layer. + upsample_fn: Upsampling function for the decoder part of the generator. + kernel_size: Size w or list/tuple [h, w] of the filter kernels for all inner + layers. + tanh_linear_slope: Slope of the linear function to add to the tanh over the + logits. + is_training: Whether the network is created in training mode or inference + only mode. Not actually needed, just for compliance with other generator + network functions. + + Returns: + A `Tensor` representing the model output and a dictionary of model end + points. + + Raises: + ValueError: If the input height or width is known at graph construction time + and not a multiple of 4. + """ + # Neither dropout nor batch norm -> dont need is_training + del is_training + + end_points = {} + + input_size = images.shape.as_list() + height, width = input_size[1], input_size[2] + if height and height % 4 != 0: + raise ValueError('The input height must be a multiple of 4.') + if width and width % 4 != 0: + raise ValueError('The input width must be a multiple of 4.') + num_outputs = input_size[3] + + if not isinstance(kernel_size, (list, tuple)): + kernel_size = [kernel_size, kernel_size] + + kernel_height = kernel_size[0] + kernel_width = kernel_size[1] + pad_top = (kernel_height - 1) // 2 + pad_bottom = kernel_height // 2 + pad_left = (kernel_width - 1) // 2 + pad_right = kernel_width // 2 + paddings = np.array( + [[0, 0], [pad_top, pad_bottom], [pad_left, pad_right], [0, 0]], + dtype=np.int32) + spatial_pad_3 = np.array([[0, 0], [3, 3], [3, 3], [0, 0]]) + + with tf.contrib.framework.arg_scope(arg_scope_fn()): + + ########### + # Encoder # + ########### + with tf.variable_scope('input'): + # 7x7 input stage + net = tf.pad(images, spatial_pad_3, 'REFLECT') + net = layers.conv2d(net, num_filters, kernel_size=[7, 7], padding='VALID') + end_points['encoder_0'] = net + + with tf.variable_scope('encoder'): + with tf.contrib.framework.arg_scope( + [layers.conv2d], + kernel_size=kernel_size, + stride=2, + activation_fn=tf.nn.relu, + padding='VALID'): + + net = tf.pad(net, paddings, 'REFLECT') + net = layers.conv2d(net, num_filters * 2) + end_points['encoder_1'] = net + net = tf.pad(net, paddings, 'REFLECT') + net = layers.conv2d(net, num_filters * 4) + end_points['encoder_2'] = net + + ################### + # Residual Blocks # + ################### + with tf.variable_scope('residual_blocks'): + with tf.contrib.framework.arg_scope( + [layers.conv2d], + kernel_size=kernel_size, + stride=1, + activation_fn=tf.nn.relu, + padding='VALID'): + for block_id in xrange(num_resnet_blocks): + with tf.variable_scope('block_{}'.format(block_id)): + res_net = tf.pad(net, paddings, 'REFLECT') + res_net = layers.conv2d(res_net, num_filters * 4) + res_net = tf.pad(res_net, paddings, 'REFLECT') + res_net = layers.conv2d(res_net, num_filters * 4, + activation_fn=None) + net += res_net + + end_points['resnet_block_%d' % block_id] = net + + ########### + # Decoder # + ########### + with tf.variable_scope('decoder'): + + with tf.contrib.framework.arg_scope( + [layers.conv2d], + kernel_size=kernel_size, + stride=1, + activation_fn=tf.nn.relu): + + with tf.variable_scope('decoder1'): + net = upsample_fn(net, num_outputs=num_filters * 2, stride=[2, 2]) + end_points['decoder1'] = net + + with tf.variable_scope('decoder2'): + net = upsample_fn(net, num_outputs=num_filters, stride=[2, 2]) + end_points['decoder2'] = net + + with tf.variable_scope('output'): + net = tf.pad(net, spatial_pad_3, 'REFLECT') + logits = layers.conv2d( + net, + num_outputs, [7, 7], + activation_fn=None, + normalizer_fn=None, + padding='valid') + logits = tf.reshape(logits, _dynamic_or_static_shape(images)) + + end_points['logits'] = logits + end_points['predictions'] = tf.tanh(logits) + logits * tanh_linear_slope + + return end_points['predictions'], end_points diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/cyclegan_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/cyclegan_test.py new file mode 100644 index 0000000..395773e --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/cyclegan_test.py @@ -0,0 +1,112 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for tensorflow.contrib.slim.nets.cyclegan.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import cyclegan + + +# TODO(joelshor): Add a test to check generator endpoints. +class CycleganTest(tf.test.TestCase): + + def test_generator_inference(self): + """Check one inference step.""" + img_batch = tf.zeros([2, 32, 32, 3]) + model_output, _ = cyclegan.cyclegan_generator_resnet(img_batch) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + sess.run(model_output) + + def _test_generator_graph_helper(self, shape): + """Check that generator can take small and non-square inputs.""" + output_imgs, _ = cyclegan.cyclegan_generator_resnet(tf.ones(shape)) + self.assertAllEqual(shape, output_imgs.shape.as_list()) + + def test_generator_graph_small(self): + self._test_generator_graph_helper([4, 32, 32, 3]) + + def test_generator_graph_medium(self): + self._test_generator_graph_helper([3, 128, 128, 3]) + + def test_generator_graph_nonsquare(self): + self._test_generator_graph_helper([2, 80, 400, 3]) + + def test_generator_unknown_batch_dim(self): + """Check that generator can take unknown batch dimension inputs.""" + img = tf.placeholder(tf.float32, shape=[None, 32, None, 3]) + output_imgs, _ = cyclegan.cyclegan_generator_resnet(img) + + self.assertAllEqual([None, 32, None, 3], output_imgs.shape.as_list()) + + def _input_and_output_same_shape_helper(self, kernel_size): + img_batch = tf.placeholder(tf.float32, shape=[None, 32, 32, 3]) + output_img_batch, _ = cyclegan.cyclegan_generator_resnet( + img_batch, kernel_size=kernel_size) + + self.assertAllEqual(img_batch.shape.as_list(), + output_img_batch.shape.as_list()) + + def input_and_output_same_shape_kernel3(self): + self._input_and_output_same_shape_helper(3) + + def input_and_output_same_shape_kernel4(self): + self._input_and_output_same_shape_helper(4) + + def input_and_output_same_shape_kernel5(self): + self._input_and_output_same_shape_helper(5) + + def input_and_output_same_shape_kernel6(self): + self._input_and_output_same_shape_helper(6) + + def _error_if_height_not_multiple_of_four_helper(self, height): + self.assertRaisesRegexp( + ValueError, + 'The input height must be a multiple of 4.', + cyclegan.cyclegan_generator_resnet, + tf.placeholder(tf.float32, shape=[None, height, 32, 3])) + + def test_error_if_height_not_multiple_of_four_height29(self): + self._error_if_height_not_multiple_of_four_helper(29) + + def test_error_if_height_not_multiple_of_four_height30(self): + self._error_if_height_not_multiple_of_four_helper(30) + + def test_error_if_height_not_multiple_of_four_height31(self): + self._error_if_height_not_multiple_of_four_helper(31) + + def _error_if_width_not_multiple_of_four_helper(self, width): + self.assertRaisesRegexp( + ValueError, + 'The input width must be a multiple of 4.', + cyclegan.cyclegan_generator_resnet, + tf.placeholder(tf.float32, shape=[None, 32, width, 3])) + + def test_error_if_width_not_multiple_of_four_width29(self): + self._error_if_width_not_multiple_of_four_helper(29) + + def test_error_if_width_not_multiple_of_four_width30(self): + self._error_if_width_not_multiple_of_four_helper(30) + + def test_error_if_width_not_multiple_of_four_width31(self): + self._error_if_width_not_multiple_of_four_helper(31) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/dcgan.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/dcgan.py new file mode 100644 index 0000000..b13ba1e --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/dcgan.py @@ -0,0 +1,202 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""DCGAN generator and discriminator from https://arxiv.org/abs/1511.06434.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from math import log + +from six.moves import xrange # pylint: disable=redefined-builtin +import tensorflow as tf + +slim = tf.contrib.slim + + +def _validate_image_inputs(inputs): + inputs.get_shape().assert_has_rank(4) + inputs.get_shape()[1:3].assert_is_fully_defined() + if inputs.get_shape()[1] != inputs.get_shape()[2]: + raise ValueError('Input tensor does not have equal width and height: ', + inputs.get_shape()[1:3]) + width = inputs.get_shape().as_list()[1] + if log(width, 2) != int(log(width, 2)): + raise ValueError('Input tensor `width` is not a power of 2: ', width) + + +# TODO(joelshor): Use fused batch norm by default. Investigate why some GAN +# setups need the gradient of gradient FusedBatchNormGrad. +def discriminator(inputs, + depth=64, + is_training=True, + reuse=None, + scope='Discriminator', + fused_batch_norm=False): + """Discriminator network for DCGAN. + + Construct discriminator network from inputs to the final endpoint. + + Args: + inputs: A tensor of size [batch_size, height, width, channels]. Must be + floating point. + depth: Number of channels in first convolution layer. + is_training: Whether the network is for training or not. + reuse: Whether or not the network variables should be reused. `scope` + must be given to be reused. + scope: Optional variable_scope. + fused_batch_norm: If `True`, use a faster, fused implementation of + batch norm. + + Returns: + logits: The pre-softmax activations, a tensor of size [batch_size, 1] + end_points: a dictionary from components of the network to their activation. + + Raises: + ValueError: If the input image shape is not 4-dimensional, if the spatial + dimensions aren't defined at graph construction time, if the spatial + dimensions aren't square, or if the spatial dimensions aren't a power of + two. + """ + + normalizer_fn = slim.batch_norm + normalizer_fn_args = { + 'is_training': is_training, + 'zero_debias_moving_mean': True, + 'fused': fused_batch_norm, + } + + _validate_image_inputs(inputs) + inp_shape = inputs.get_shape().as_list()[1] + + end_points = {} + with tf.variable_scope(scope, values=[inputs], reuse=reuse) as scope: + with slim.arg_scope([normalizer_fn], **normalizer_fn_args): + with slim.arg_scope([slim.conv2d], + stride=2, + kernel_size=4, + activation_fn=tf.nn.leaky_relu): + net = inputs + for i in xrange(int(log(inp_shape, 2))): + scope = 'conv%i' % (i + 1) + current_depth = depth * 2**i + normalizer_fn_ = None if i == 0 else normalizer_fn + net = slim.conv2d( + net, current_depth, normalizer_fn=normalizer_fn_, scope=scope) + end_points[scope] = net + + logits = slim.conv2d(net, 1, kernel_size=1, stride=1, padding='VALID', + normalizer_fn=None, activation_fn=None) + logits = tf.reshape(logits, [-1, 1]) + end_points['logits'] = logits + + return logits, end_points + + +# TODO(joelshor): Use fused batch norm by default. Investigate why some GAN +# setups need the gradient of gradient FusedBatchNormGrad. +def generator(inputs, + depth=64, + final_size=32, + num_outputs=3, + is_training=True, + reuse=None, + scope='Generator', + fused_batch_norm=False): + """Generator network for DCGAN. + + Construct generator network from inputs to the final endpoint. + + Args: + inputs: A tensor with any size N. [batch_size, N] + depth: Number of channels in last deconvolution layer. + final_size: The shape of the final output. + num_outputs: Number of output features. For images, this is the number of + channels. + is_training: whether is training or not. + reuse: Whether or not the network has its variables should be reused. scope + must be given to be reused. + scope: Optional variable_scope. + fused_batch_norm: If `True`, use a faster, fused implementation of + batch norm. + + Returns: + logits: the pre-softmax activations, a tensor of size + [batch_size, 32, 32, channels] + end_points: a dictionary from components of the network to their activation. + + Raises: + ValueError: If `inputs` is not 2-dimensional. + ValueError: If `final_size` isn't a power of 2 or is less than 8. + """ + normalizer_fn = slim.batch_norm + normalizer_fn_args = { + 'is_training': is_training, + 'zero_debias_moving_mean': True, + 'fused': fused_batch_norm, + } + + inputs.get_shape().assert_has_rank(2) + if log(final_size, 2) != int(log(final_size, 2)): + raise ValueError('`final_size` (%i) must be a power of 2.' % final_size) + if final_size < 8: + raise ValueError('`final_size` (%i) must be greater than 8.' % final_size) + + end_points = {} + num_layers = int(log(final_size, 2)) - 1 + with tf.variable_scope(scope, values=[inputs], reuse=reuse) as scope: + with slim.arg_scope([normalizer_fn], **normalizer_fn_args): + with slim.arg_scope([slim.conv2d_transpose], + normalizer_fn=normalizer_fn, + stride=2, + kernel_size=4): + net = tf.expand_dims(tf.expand_dims(inputs, 1), 1) + + # First upscaling is different because it takes the input vector. + current_depth = depth * 2 ** (num_layers - 1) + scope = 'deconv1' + net = slim.conv2d_transpose( + net, current_depth, stride=1, padding='VALID', scope=scope) + end_points[scope] = net + + for i in xrange(2, num_layers): + scope = 'deconv%i' % (i) + current_depth = depth * 2 ** (num_layers - i) + net = slim.conv2d_transpose(net, current_depth, scope=scope) + end_points[scope] = net + + # Last layer has different normalizer and activation. + scope = 'deconv%i' % (num_layers) + net = slim.conv2d_transpose( + net, depth, normalizer_fn=None, activation_fn=None, scope=scope) + end_points[scope] = net + + # Convert to proper channels. + scope = 'logits' + logits = slim.conv2d( + net, + num_outputs, + normalizer_fn=None, + activation_fn=None, + kernel_size=1, + stride=1, + padding='VALID', + scope=scope) + end_points[scope] = logits + + logits.get_shape().assert_has_rank(4) + logits.get_shape().assert_is_compatible_with( + [None, final_size, final_size, num_outputs]) + + return logits, end_points diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/dcgan_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/dcgan_test.py new file mode 100644 index 0000000..343de62 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/dcgan_test.py @@ -0,0 +1,120 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for dcgan.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from six.moves import xrange # pylint: disable=redefined-builtin +import tensorflow as tf + +from nets import dcgan + + +class DCGANTest(tf.test.TestCase): + + def test_generator_run(self): + tf.set_random_seed(1234) + noise = tf.random_normal([100, 64]) + image, _ = dcgan.generator(noise) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + image.eval() + + def test_generator_graph(self): + tf.set_random_seed(1234) + # Check graph construction for a number of image size/depths and batch + # sizes. + for i, batch_size in zip(xrange(3, 7), xrange(3, 8)): + tf.reset_default_graph() + final_size = 2 ** i + noise = tf.random_normal([batch_size, 64]) + image, end_points = dcgan.generator( + noise, + depth=32, + final_size=final_size) + + self.assertAllEqual([batch_size, final_size, final_size, 3], + image.shape.as_list()) + + expected_names = ['deconv%i' % j for j in xrange(1, i)] + ['logits'] + self.assertSetEqual(set(expected_names), set(end_points.keys())) + + # Check layer depths. + for j in range(1, i): + layer = end_points['deconv%i' % j] + self.assertEqual(32 * 2**(i-j-1), layer.get_shape().as_list()[-1]) + + def test_generator_invalid_input(self): + wrong_dim_input = tf.zeros([5, 32, 32]) + with self.assertRaises(ValueError): + dcgan.generator(wrong_dim_input) + + correct_input = tf.zeros([3, 2]) + with self.assertRaisesRegexp(ValueError, 'must be a power of 2'): + dcgan.generator(correct_input, final_size=30) + + with self.assertRaisesRegexp(ValueError, 'must be greater than 8'): + dcgan.generator(correct_input, final_size=4) + + def test_discriminator_run(self): + image = tf.random_uniform([5, 32, 32, 3], -1, 1) + output, _ = dcgan.discriminator(image) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output.eval() + + def test_discriminator_graph(self): + # Check graph construction for a number of image size/depths and batch + # sizes. + for i, batch_size in zip(xrange(1, 6), xrange(3, 8)): + tf.reset_default_graph() + img_w = 2 ** i + image = tf.random_uniform([batch_size, img_w, img_w, 3], -1, 1) + output, end_points = dcgan.discriminator( + image, + depth=32) + + self.assertAllEqual([batch_size, 1], output.get_shape().as_list()) + + expected_names = ['conv%i' % j for j in xrange(1, i+1)] + ['logits'] + self.assertSetEqual(set(expected_names), set(end_points.keys())) + + # Check layer depths. + for j in range(1, i+1): + layer = end_points['conv%i' % j] + self.assertEqual(32 * 2**(j-1), layer.get_shape().as_list()[-1]) + + def test_discriminator_invalid_input(self): + wrong_dim_img = tf.zeros([5, 32, 32]) + with self.assertRaises(ValueError): + dcgan.discriminator(wrong_dim_img) + + spatially_undefined_shape = tf.placeholder(tf.float32, [5, 32, None, 3]) + with self.assertRaises(ValueError): + dcgan.discriminator(spatially_undefined_shape) + + not_square = tf.zeros([5, 32, 16, 3]) + with self.assertRaisesRegexp(ValueError, 'not have equal width and height'): + dcgan.discriminator(not_square) + + not_power_2 = tf.zeros([5, 30, 30, 3]) + with self.assertRaisesRegexp(ValueError, 'not a power of 2'): + dcgan.discriminator(not_power_2) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/i3d.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/i3d.py new file mode 100644 index 0000000..97fe4f2 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/i3d.py @@ -0,0 +1,177 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains the definition for Inflated 3D Inception V1 (I3D). + +The network architecture is proposed by: + Joao Carreira and Andrew Zisserman, + Quo Vadis, Action Recognition? A New Model and the Kinetics Dataset. + https://arxiv.org/abs/1705.07750 +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import i3d_utils +from nets import s3dg + +slim = tf.contrib.slim +trunc_normal = lambda stddev: tf.truncated_normal_initializer(0.0, stddev) +conv3d_spatiotemporal = i3d_utils.conv3d_spatiotemporal + + +def i3d_arg_scope(weight_decay=1e-7, + batch_norm_decay=0.999, + batch_norm_epsilon=0.001, + use_renorm=False, + separable_conv3d=False): + """Defines default arg_scope for I3D. + + Args: + weight_decay: The weight decay to use for regularizing the model. + batch_norm_decay: Decay for batch norm moving average. + batch_norm_epsilon: Small float added to variance to avoid dividing by zero + in batch norm. + use_renorm: Whether to use batch renormalization or not. + separable_conv3d: Whether to use separable 3d Convs. + + Returns: + sc: An arg_scope to use for the models. + """ + batch_norm_params = { + # Decay for the moving averages. + 'decay': batch_norm_decay, + # epsilon to prevent 0s in variance. + 'epsilon': batch_norm_epsilon, + # Turns off fused batch norm. + 'fused': False, + 'renorm': use_renorm, + # collection containing the moving mean and moving variance. + 'variables_collections': { + 'beta': None, + 'gamma': None, + 'moving_mean': ['moving_vars'], + 'moving_variance': ['moving_vars'], + } + } + + with slim.arg_scope( + [slim.conv3d, conv3d_spatiotemporal], + weights_regularizer=slim.l2_regularizer(weight_decay), + activation_fn=tf.nn.relu, + normalizer_fn=slim.batch_norm, + normalizer_params=batch_norm_params): + with slim.arg_scope( + [conv3d_spatiotemporal], separable=separable_conv3d) as sc: + return sc + + +def i3d_base(inputs, final_endpoint='Mixed_5c', + scope='InceptionV1'): + """Defines the I3D base architecture. + + Note that we use the names as defined in Inception V1 to facilitate checkpoint + conversion from an image-trained Inception V1 checkpoint to I3D checkpoint. + + Args: + inputs: A 5-D float tensor of size [batch_size, num_frames, height, width, + channels]. + final_endpoint: Specifies the endpoint to construct the network up to. It + can be one of ['Conv2d_1a_7x7', 'MaxPool_2a_3x3', 'Conv2d_2b_1x1', + 'Conv2d_2c_3x3', 'MaxPool_3a_3x3', 'Mixed_3b', 'Mixed_3c', + 'MaxPool_4a_3x3', 'Mixed_4b', 'Mixed_4c', 'Mixed_4d', 'Mixed_4e', + 'Mixed_4f', 'MaxPool_5a_2x2', 'Mixed_5b', 'Mixed_5c'] + scope: Optional variable_scope. + + Returns: + A dictionary from components of the network to the corresponding activation. + + Raises: + ValueError: if final_endpoint is not set to one of the predefined values. + """ + + return s3dg.s3dg_base( + inputs, + first_temporal_kernel_size=7, + temporal_conv_startat='Conv2d_2c_3x3', + gating_startat=None, + final_endpoint=final_endpoint, + min_depth=16, + depth_multiplier=1.0, + data_format='NDHWC', + scope=scope) + + +def i3d(inputs, + num_classes=1000, + dropout_keep_prob=0.8, + is_training=True, + prediction_fn=slim.softmax, + spatial_squeeze=True, + reuse=None, + scope='InceptionV1'): + """Defines the I3D architecture. + + The default image size used to train this network is 224x224. + + Args: + inputs: A 5-D float tensor of size [batch_size, num_frames, height, width, + channels]. + num_classes: number of predicted classes. + dropout_keep_prob: the percentage of activation values that are retained. + is_training: whether is training or not. + prediction_fn: a function to get predictions out of logits. + spatial_squeeze: if True, logits is of shape is [B, C], if false logits is + of shape [B, 1, 1, C], where B is batch_size and C is number of classes. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + + Returns: + logits: the pre-softmax activations, a tensor of size + [batch_size, num_classes] + end_points: a dictionary from components of the network to the corresponding + activation. + """ + # Final pooling and prediction + with tf.variable_scope( + scope, 'InceptionV1', [inputs, num_classes], reuse=reuse) as scope: + with slim.arg_scope( + [slim.batch_norm, slim.dropout], is_training=is_training): + net, end_points = i3d_base(inputs, scope=scope) + with tf.variable_scope('Logits'): + kernel_size = i3d_utils.reduced_kernel_size_3d(net, [2, 7, 7]) + net = slim.avg_pool3d( + net, kernel_size, stride=1, scope='AvgPool_0a_7x7') + net = slim.dropout(net, dropout_keep_prob, scope='Dropout_0b') + logits = slim.conv3d( + net, + num_classes, [1, 1, 1], + activation_fn=None, + normalizer_fn=None, + scope='Conv2d_0c_1x1') + # Temporal average pooling. + logits = tf.reduce_mean(logits, axis=1) + if spatial_squeeze: + logits = tf.squeeze(logits, [1, 2], name='SpatialSqueeze') + + end_points['Logits'] = logits + end_points['Predictions'] = prediction_fn(logits, scope='Predictions') + return logits, end_points + + +i3d.default_image_size = 224 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/i3d_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/i3d_test.py new file mode 100644 index 0000000..ec3bb56 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/i3d_test.py @@ -0,0 +1,149 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for networks.i3d.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import i3d + + +class I3DTest(tf.test.TestCase): + + def testBuildClassificationNetwork(self): + batch_size = 5 + num_frames = 64 + height, width = 224, 224 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, num_frames, height, width, 3)) + logits, end_points = i3d.i3d(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionV1/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertTrue('Predictions' in end_points) + self.assertListEqual(end_points['Predictions'].get_shape().as_list(), + [batch_size, num_classes]) + + def testBuildBaseNetwork(self): + batch_size = 5 + num_frames = 64 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, num_frames, height, width, 3)) + mixed_6c, end_points = i3d.i3d_base(inputs) + self.assertTrue(mixed_6c.op.name.startswith('InceptionV1/Mixed_5c')) + self.assertListEqual(mixed_6c.get_shape().as_list(), + [batch_size, 8, 7, 7, 1024]) + expected_endpoints = ['Conv2d_1a_7x7', 'MaxPool_2a_3x3', 'Conv2d_2b_1x1', + 'Conv2d_2c_3x3', 'MaxPool_3a_3x3', 'Mixed_3b', + 'Mixed_3c', 'MaxPool_4a_3x3', 'Mixed_4b', 'Mixed_4c', + 'Mixed_4d', 'Mixed_4e', 'Mixed_4f', 'MaxPool_5a_2x2', + 'Mixed_5b', 'Mixed_5c'] + self.assertItemsEqual(end_points.keys(), expected_endpoints) + + def testBuildOnlyUptoFinalEndpoint(self): + batch_size = 5 + num_frames = 64 + height, width = 224, 224 + endpoints = ['Conv2d_1a_7x7', 'MaxPool_2a_3x3', 'Conv2d_2b_1x1', + 'Conv2d_2c_3x3', 'MaxPool_3a_3x3', 'Mixed_3b', 'Mixed_3c', + 'MaxPool_4a_3x3', 'Mixed_4b', 'Mixed_4c', 'Mixed_4d', + 'Mixed_4e', 'Mixed_4f', 'MaxPool_5a_2x2', 'Mixed_5b', + 'Mixed_5c'] + for index, endpoint in enumerate(endpoints): + with tf.Graph().as_default(): + inputs = tf.random_uniform((batch_size, num_frames, height, width, 3)) + out_tensor, end_points = i3d.i3d_base( + inputs, final_endpoint=endpoint) + self.assertTrue(out_tensor.op.name.startswith( + 'InceptionV1/' + endpoint)) + self.assertItemsEqual(endpoints[:index+1], end_points) + + def testBuildAndCheckAllEndPointsUptoMixed5c(self): + batch_size = 5 + num_frames = 64 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, num_frames, height, width, 3)) + _, end_points = i3d.i3d_base(inputs, + final_endpoint='Mixed_5c') + endpoints_shapes = {'Conv2d_1a_7x7': [5, 32, 112, 112, 64], + 'MaxPool_2a_3x3': [5, 32, 56, 56, 64], + 'Conv2d_2b_1x1': [5, 32, 56, 56, 64], + 'Conv2d_2c_3x3': [5, 32, 56, 56, 192], + 'MaxPool_3a_3x3': [5, 32, 28, 28, 192], + 'Mixed_3b': [5, 32, 28, 28, 256], + 'Mixed_3c': [5, 32, 28, 28, 480], + 'MaxPool_4a_3x3': [5, 16, 14, 14, 480], + 'Mixed_4b': [5, 16, 14, 14, 512], + 'Mixed_4c': [5, 16, 14, 14, 512], + 'Mixed_4d': [5, 16, 14, 14, 512], + 'Mixed_4e': [5, 16, 14, 14, 528], + 'Mixed_4f': [5, 16, 14, 14, 832], + 'MaxPool_5a_2x2': [5, 8, 7, 7, 832], + 'Mixed_5b': [5, 8, 7, 7, 832], + 'Mixed_5c': [5, 8, 7, 7, 1024]} + + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name, expected_shape in endpoints_shapes.iteritems(): + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testHalfSizeImages(self): + batch_size = 5 + num_frames = 64 + height, width = 112, 112 + + inputs = tf.random_uniform((batch_size, num_frames, height, width, 3)) + mixed_5c, _ = i3d.i3d_base(inputs) + self.assertTrue(mixed_5c.op.name.startswith('InceptionV1/Mixed_5c')) + self.assertListEqual(mixed_5c.get_shape().as_list(), + [batch_size, 8, 4, 4, 1024]) + + def testTenFrames(self): + batch_size = 5 + num_frames = 10 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, num_frames, height, width, 3)) + mixed_5c, _ = i3d.i3d_base(inputs) + self.assertTrue(mixed_5c.op.name.startswith('InceptionV1/Mixed_5c')) + self.assertListEqual(mixed_5c.get_shape().as_list(), + [batch_size, 2, 7, 7, 1024]) + + def testEvaluation(self): + batch_size = 2 + num_frames = 64 + height, width = 224, 224 + num_classes = 1000 + + eval_inputs = tf.random_uniform((batch_size, num_frames, height, width, 3)) + logits, _ = i3d.i3d(eval_inputs, num_classes, + is_training=False) + predictions = tf.argmax(logits, 1) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (batch_size,)) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/i3d_utils.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/i3d_utils.py new file mode 100644 index 0000000..2b9911e --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/i3d_utils.py @@ -0,0 +1,287 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Utilities for building I3D network models.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import tensorflow as tf + + +# Orignaly, add_arg_scope = slim.add_arg_scope and layers = slim, now switch to +# more update-to-date tf.contrib.* API. +add_arg_scope = tf.contrib.framework.add_arg_scope +layers = tf.contrib.layers + + +def center_initializer(): + """Centering Initializer for I3D. + + This initializer allows identity mapping for temporal convolution at the + initialization, which is critical for a desired convergence behavior + for training a seprable I3D model. + + The centering behavior of this initializer requires an odd-sized kernel, + typically set to 3. + + Returns: + A weight initializer op used in temporal convolutional layers. + + Raises: + ValueError: Input tensor data type has to be tf.float32. + ValueError: If input tensor is not a 5-D tensor. + ValueError: If input and output channel dimensions are different. + ValueError: If spatial kernel sizes are not 1. + ValueError: If temporal kernel size is even. + """ + + def _initializer(shape, dtype=tf.float32, partition_info=None): # pylint: disable=unused-argument + """Initializer op.""" + + if dtype != tf.float32 and dtype != tf.bfloat16: + raise ValueError( + 'Input tensor data type has to be tf.float32 or tf.bfloat16.') + if len(shape) != 5: + raise ValueError('Input tensor has to be 5-D.') + if shape[3] != shape[4]: + raise ValueError('Input and output channel dimensions must be the same.') + if shape[1] != 1 or shape[2] != 1: + raise ValueError('Spatial kernel sizes must be 1 (pointwise conv).') + if shape[0] % 2 == 0: + raise ValueError('Temporal kernel size has to be odd.') + + center_pos = int(shape[0] / 2) + init_mat = np.zeros( + [shape[0], shape[1], shape[2], shape[3], shape[4]], dtype=np.float32) + for i in range(0, shape[3]): + init_mat[center_pos, 0, 0, i, i] = 1.0 + + init_op = tf.constant(init_mat, dtype=dtype) + return init_op + + return _initializer + + +@add_arg_scope +def conv3d_spatiotemporal(inputs, + num_outputs, + kernel_size, + stride=1, + padding='SAME', + activation_fn=None, + normalizer_fn=None, + normalizer_params=None, + weights_regularizer=None, + separable=False, + data_format='NDHWC', + scope=''): + """A wrapper for conv3d to model spatiotemporal representations. + + This allows switching between original 3D convolution and separable 3D + convolutions for spatial and temporal features respectively. On Kinetics, + seprable 3D convolutions yields better classification performance. + + Args: + inputs: a 5-D tensor `[batch_size, depth, height, width, channels]`. + num_outputs: integer, the number of output filters. + kernel_size: a list of length 3 + `[kernel_depth, kernel_height, kernel_width]` of the filters. Can be an + int if all values are the same. + stride: a list of length 3 `[stride_depth, stride_height, stride_width]`. + Can be an int if all strides are the same. + padding: one of `VALID` or `SAME`. + activation_fn: activation function. + normalizer_fn: normalization function to use instead of `biases`. + normalizer_params: dictionary of normalization function parameters. + weights_regularizer: Optional regularizer for the weights. + separable: If `True`, use separable spatiotemporal convolutions. + data_format: An optional string from: "NDHWC", "NCDHW". Defaults to "NDHWC". + The data format of the input and output data. With the default format + "NDHWC", the data is stored in the order of: [batch, in_depth, in_height, + in_width, in_channels]. Alternatively, the format could be "NCDHW", the + data storage order is: + [batch, in_channels, in_depth, in_height, in_width]. + scope: scope for `variable_scope`. + + Returns: + A tensor representing the output of the (separable) conv3d operation. + + """ + assert len(kernel_size) == 3 + if separable and kernel_size[0] != 1: + spatial_kernel_size = [1, kernel_size[1], kernel_size[2]] + temporal_kernel_size = [kernel_size[0], 1, 1] + if isinstance(stride, list) and len(stride) == 3: + spatial_stride = [1, stride[1], stride[2]] + temporal_stride = [stride[0], 1, 1] + else: + spatial_stride = [1, stride, stride] + temporal_stride = [stride, 1, 1] + net = layers.conv3d( + inputs, + num_outputs, + spatial_kernel_size, + stride=spatial_stride, + padding=padding, + activation_fn=activation_fn, + normalizer_fn=normalizer_fn, + normalizer_params=normalizer_params, + weights_regularizer=weights_regularizer, + data_format=data_format, + scope=scope) + net = layers.conv3d( + net, + num_outputs, + temporal_kernel_size, + stride=temporal_stride, + padding=padding, + scope=scope + '/temporal', + activation_fn=activation_fn, + normalizer_fn=None, + data_format=data_format, + weights_initializer=center_initializer()) + return net + else: + return layers.conv3d( + inputs, + num_outputs, + kernel_size, + stride=stride, + padding=padding, + activation_fn=activation_fn, + normalizer_fn=normalizer_fn, + normalizer_params=normalizer_params, + weights_regularizer=weights_regularizer, + data_format=data_format, + scope=scope) + + +@add_arg_scope +def inception_block_v1_3d(inputs, + num_outputs_0_0a, + num_outputs_1_0a, + num_outputs_1_0b, + num_outputs_2_0a, + num_outputs_2_0b, + num_outputs_3_0b, + temporal_kernel_size=3, + self_gating_fn=None, + data_format='NDHWC', + scope=''): + """A 3D Inception v1 block. + + This allows use of separable 3D convolutions and self-gating, as + described in: + Saining Xie, Chen Sun, Jonathan Huang, Zhuowen Tu and Kevin Murphy, + Rethinking Spatiotemporal Feature Learning For Video Understanding. + https://arxiv.org/abs/1712.04851. + + Args: + inputs: a 5-D tensor `[batch_size, depth, height, width, channels]`. + num_outputs_0_0a: integer, the number of output filters for Branch 0, + operation Conv2d_0a_1x1. + num_outputs_1_0a: integer, the number of output filters for Branch 1, + operation Conv2d_0a_1x1. + num_outputs_1_0b: integer, the number of output filters for Branch 1, + operation Conv2d_0b_3x3. + num_outputs_2_0a: integer, the number of output filters for Branch 2, + operation Conv2d_0a_1x1. + num_outputs_2_0b: integer, the number of output filters for Branch 2, + operation Conv2d_0b_3x3. + num_outputs_3_0b: integer, the number of output filters for Branch 3, + operation Conv2d_0b_1x1. + temporal_kernel_size: integer, the size of the temporal convolutional + filters in the conv3d_spatiotemporal blocks. + self_gating_fn: function which optionally performs self-gating. + Must have two arguments, `inputs` and `scope`, and return one output + tensor the same size as `inputs`. If `None`, no self-gating is + applied. + data_format: An optional string from: "NDHWC", "NCDHW". Defaults to "NDHWC". + The data format of the input and output data. With the default format + "NDHWC", the data is stored in the order of: [batch, in_depth, in_height, + in_width, in_channels]. Alternatively, the format could be "NCDHW", the + data storage order is: + [batch, in_channels, in_depth, in_height, in_width]. + scope: scope for `variable_scope`. + + Returns: + A 5-D tensor `[batch_size, depth, height, width, out_channels]`, where + `out_channels = num_outputs_0_0a + num_outputs_1_0b + num_outputs_2_0b + + num_outputs_3_0b`. + + """ + use_gating = self_gating_fn is not None + + with tf.variable_scope(scope): + with tf.variable_scope('Branch_0'): + branch_0 = layers.conv3d( + inputs, num_outputs_0_0a, [1, 1, 1], scope='Conv2d_0a_1x1') + if use_gating: + branch_0 = self_gating_fn(branch_0, scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = layers.conv3d( + inputs, num_outputs_1_0a, [1, 1, 1], scope='Conv2d_0a_1x1') + branch_1 = conv3d_spatiotemporal( + branch_1, num_outputs_1_0b, [temporal_kernel_size, 3, 3], + scope='Conv2d_0b_3x3') + if use_gating: + branch_1 = self_gating_fn(branch_1, scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = layers.conv3d( + inputs, num_outputs_2_0a, [1, 1, 1], scope='Conv2d_0a_1x1') + branch_2 = conv3d_spatiotemporal( + branch_2, num_outputs_2_0b, [temporal_kernel_size, 3, 3], + scope='Conv2d_0b_3x3') + if use_gating: + branch_2 = self_gating_fn(branch_2, scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = layers.max_pool3d(inputs, [3, 3, 3], scope='MaxPool_0a_3x3') + branch_3 = layers.conv3d( + branch_3, num_outputs_3_0b, [1, 1, 1], scope='Conv2d_0b_1x1') + if use_gating: + branch_3 = self_gating_fn(branch_3, scope='Conv2d_0b_1x1') + index_c = data_format.index('C') + assert 1 <= index_c <= 4, 'Cannot identify channel dimension.' + output = tf.concat([branch_0, branch_1, branch_2, branch_3], index_c) + return output + + +def reduced_kernel_size_3d(input_tensor, kernel_size): + """Define kernel size which is automatically reduced for small input. + + If the shape of the input images is unknown at graph construction time this + function assumes that the input images are large enough. + + Args: + input_tensor: input tensor of size + [batch_size, time, height, width, channels]. + kernel_size: desired kernel size of length 3, corresponding to time, + height and width. + + Returns: + a tensor with the kernel size. + """ + assert len(kernel_size) == 3 + shape = input_tensor.get_shape().as_list() + assert len(shape) == 5 + if None in shape[1:4]: + kernel_size_out = kernel_size + else: + kernel_size_out = [min(shape[1], kernel_size[0]), + min(shape[2], kernel_size[1]), + min(shape[3], kernel_size[2])] + return kernel_size_out diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception.py new file mode 100644 index 0000000..b69cd2a --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception.py @@ -0,0 +1,37 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Brings all inception models under one namespace.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +# pylint: disable=unused-import +from nets.inception_resnet_v2 import inception_resnet_v2 +from nets.inception_resnet_v2 import inception_resnet_v2_arg_scope +from nets.inception_resnet_v2 import inception_resnet_v2_base +from nets.inception_v1 import inception_v1 +from nets.inception_v1 import inception_v1_arg_scope +from nets.inception_v1 import inception_v1_base +from nets.inception_v2 import inception_v2 +from nets.inception_v2 import inception_v2_arg_scope +from nets.inception_v2 import inception_v2_base +from nets.inception_v3 import inception_v3 +from nets.inception_v3 import inception_v3_arg_scope +from nets.inception_v3 import inception_v3_base +from nets.inception_v4 import inception_v4 +from nets.inception_v4 import inception_v4_arg_scope +from nets.inception_v4 import inception_v4_base +# pylint: enable=unused-import diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_resnet_v2.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_resnet_v2.py new file mode 100644 index 0000000..f14c08e --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_resnet_v2.py @@ -0,0 +1,406 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains the definition of the Inception Resnet V2 architecture. + +As described in http://arxiv.org/abs/1602.07261. + + Inception-v4, Inception-ResNet and the Impact of Residual Connections + on Learning + Christian Szegedy, Sergey Ioffe, Vincent Vanhoucke, Alex Alemi +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + + +import tensorflow as tf + +slim = tf.contrib.slim + + +def block35(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None): + """Builds the 35x35 resnet block.""" + with tf.variable_scope(scope, 'Block35', [net], reuse=reuse): + with tf.variable_scope('Branch_0'): + tower_conv = slim.conv2d(net, 32, 1, scope='Conv2d_1x1') + with tf.variable_scope('Branch_1'): + tower_conv1_0 = slim.conv2d(net, 32, 1, scope='Conv2d_0a_1x1') + tower_conv1_1 = slim.conv2d(tower_conv1_0, 32, 3, scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + tower_conv2_0 = slim.conv2d(net, 32, 1, scope='Conv2d_0a_1x1') + tower_conv2_1 = slim.conv2d(tower_conv2_0, 48, 3, scope='Conv2d_0b_3x3') + tower_conv2_2 = slim.conv2d(tower_conv2_1, 64, 3, scope='Conv2d_0c_3x3') + mixed = tf.concat(axis=3, values=[tower_conv, tower_conv1_1, tower_conv2_2]) + up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None, + activation_fn=None, scope='Conv2d_1x1') + scaled_up = up * scale + if activation_fn == tf.nn.relu6: + # Use clip_by_value to simulate bandpass activation. + scaled_up = tf.clip_by_value(scaled_up, -6.0, 6.0) + + net += scaled_up + if activation_fn: + net = activation_fn(net) + return net + + +def block17(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None): + """Builds the 17x17 resnet block.""" + with tf.variable_scope(scope, 'Block17', [net], reuse=reuse): + with tf.variable_scope('Branch_0'): + tower_conv = slim.conv2d(net, 192, 1, scope='Conv2d_1x1') + with tf.variable_scope('Branch_1'): + tower_conv1_0 = slim.conv2d(net, 128, 1, scope='Conv2d_0a_1x1') + tower_conv1_1 = slim.conv2d(tower_conv1_0, 160, [1, 7], + scope='Conv2d_0b_1x7') + tower_conv1_2 = slim.conv2d(tower_conv1_1, 192, [7, 1], + scope='Conv2d_0c_7x1') + mixed = tf.concat(axis=3, values=[tower_conv, tower_conv1_2]) + up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None, + activation_fn=None, scope='Conv2d_1x1') + + scaled_up = up * scale + if activation_fn == tf.nn.relu6: + # Use clip_by_value to simulate bandpass activation. + scaled_up = tf.clip_by_value(scaled_up, -6.0, 6.0) + + net += scaled_up + if activation_fn: + net = activation_fn(net) + return net + + +def block8(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None): + """Builds the 8x8 resnet block.""" + with tf.variable_scope(scope, 'Block8', [net], reuse=reuse): + with tf.variable_scope('Branch_0'): + tower_conv = slim.conv2d(net, 192, 1, scope='Conv2d_1x1') + with tf.variable_scope('Branch_1'): + tower_conv1_0 = slim.conv2d(net, 192, 1, scope='Conv2d_0a_1x1') + tower_conv1_1 = slim.conv2d(tower_conv1_0, 224, [1, 3], + scope='Conv2d_0b_1x3') + tower_conv1_2 = slim.conv2d(tower_conv1_1, 256, [3, 1], + scope='Conv2d_0c_3x1') + mixed = tf.concat(axis=3, values=[tower_conv, tower_conv1_2]) + up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None, + activation_fn=None, scope='Conv2d_1x1') + + scaled_up = up * scale + if activation_fn == tf.nn.relu6: + # Use clip_by_value to simulate bandpass activation. + scaled_up = tf.clip_by_value(scaled_up, -6.0, 6.0) + + net += scaled_up + if activation_fn: + net = activation_fn(net) + return net + + +def inception_resnet_v2_base(inputs, + final_endpoint='Conv2d_7b_1x1', + output_stride=16, + align_feature_maps=False, + scope=None, + activation_fn=tf.nn.relu): + """Inception model from http://arxiv.org/abs/1602.07261. + + Constructs an Inception Resnet v2 network from inputs to the given final + endpoint. This method can construct the network up to the final inception + block Conv2d_7b_1x1. + + Args: + inputs: a tensor of size [batch_size, height, width, channels]. + final_endpoint: specifies the endpoint to construct the network up to. It + can be one of ['Conv2d_1a_3x3', 'Conv2d_2a_3x3', 'Conv2d_2b_3x3', + 'MaxPool_3a_3x3', 'Conv2d_3b_1x1', 'Conv2d_4a_3x3', 'MaxPool_5a_3x3', + 'Mixed_5b', 'Mixed_6a', 'PreAuxLogits', 'Mixed_7a', 'Conv2d_7b_1x1'] + output_stride: A scalar that specifies the requested ratio of input to + output spatial resolution. Only supports 8 and 16. + align_feature_maps: When true, changes all the VALID paddings in the network + to SAME padding so that the feature maps are aligned. + scope: Optional variable_scope. + activation_fn: Activation function for block scopes. + + Returns: + tensor_out: output tensor corresponding to the final_endpoint. + end_points: a set of activations for external use, for example summaries or + losses. + + Raises: + ValueError: if final_endpoint is not set to one of the predefined values, + or if the output_stride is not 8 or 16, or if the output_stride is 8 and + we request an end point after 'PreAuxLogits'. + """ + if output_stride != 8 and output_stride != 16: + raise ValueError('output_stride must be 8 or 16.') + + padding = 'SAME' if align_feature_maps else 'VALID' + + end_points = {} + + def add_and_check_final(name, net): + end_points[name] = net + return name == final_endpoint + + with tf.variable_scope(scope, 'InceptionResnetV2', [inputs]): + with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d], + stride=1, padding='SAME'): + # 149 x 149 x 32 + net = slim.conv2d(inputs, 32, 3, stride=2, padding=padding, + scope='Conv2d_1a_3x3') + if add_and_check_final('Conv2d_1a_3x3', net): return net, end_points + + # 147 x 147 x 32 + net = slim.conv2d(net, 32, 3, padding=padding, + scope='Conv2d_2a_3x3') + if add_and_check_final('Conv2d_2a_3x3', net): return net, end_points + # 147 x 147 x 64 + net = slim.conv2d(net, 64, 3, scope='Conv2d_2b_3x3') + if add_and_check_final('Conv2d_2b_3x3', net): return net, end_points + # 73 x 73 x 64 + net = slim.max_pool2d(net, 3, stride=2, padding=padding, + scope='MaxPool_3a_3x3') + if add_and_check_final('MaxPool_3a_3x3', net): return net, end_points + # 73 x 73 x 80 + net = slim.conv2d(net, 80, 1, padding=padding, + scope='Conv2d_3b_1x1') + if add_and_check_final('Conv2d_3b_1x1', net): return net, end_points + # 71 x 71 x 192 + net = slim.conv2d(net, 192, 3, padding=padding, + scope='Conv2d_4a_3x3') + if add_and_check_final('Conv2d_4a_3x3', net): return net, end_points + # 35 x 35 x 192 + net = slim.max_pool2d(net, 3, stride=2, padding=padding, + scope='MaxPool_5a_3x3') + if add_and_check_final('MaxPool_5a_3x3', net): return net, end_points + + # 35 x 35 x 320 + with tf.variable_scope('Mixed_5b'): + with tf.variable_scope('Branch_0'): + tower_conv = slim.conv2d(net, 96, 1, scope='Conv2d_1x1') + with tf.variable_scope('Branch_1'): + tower_conv1_0 = slim.conv2d(net, 48, 1, scope='Conv2d_0a_1x1') + tower_conv1_1 = slim.conv2d(tower_conv1_0, 64, 5, + scope='Conv2d_0b_5x5') + with tf.variable_scope('Branch_2'): + tower_conv2_0 = slim.conv2d(net, 64, 1, scope='Conv2d_0a_1x1') + tower_conv2_1 = slim.conv2d(tower_conv2_0, 96, 3, + scope='Conv2d_0b_3x3') + tower_conv2_2 = slim.conv2d(tower_conv2_1, 96, 3, + scope='Conv2d_0c_3x3') + with tf.variable_scope('Branch_3'): + tower_pool = slim.avg_pool2d(net, 3, stride=1, padding='SAME', + scope='AvgPool_0a_3x3') + tower_pool_1 = slim.conv2d(tower_pool, 64, 1, + scope='Conv2d_0b_1x1') + net = tf.concat( + [tower_conv, tower_conv1_1, tower_conv2_2, tower_pool_1], 3) + + if add_and_check_final('Mixed_5b', net): return net, end_points + # TODO(alemi): Register intermediate endpoints + net = slim.repeat(net, 10, block35, scale=0.17, + activation_fn=activation_fn) + + # 17 x 17 x 1088 if output_stride == 8, + # 33 x 33 x 1088 if output_stride == 16 + use_atrous = output_stride == 8 + + with tf.variable_scope('Mixed_6a'): + with tf.variable_scope('Branch_0'): + tower_conv = slim.conv2d(net, 384, 3, stride=1 if use_atrous else 2, + padding=padding, + scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_1'): + tower_conv1_0 = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1') + tower_conv1_1 = slim.conv2d(tower_conv1_0, 256, 3, + scope='Conv2d_0b_3x3') + tower_conv1_2 = slim.conv2d(tower_conv1_1, 384, 3, + stride=1 if use_atrous else 2, + padding=padding, + scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_2'): + tower_pool = slim.max_pool2d(net, 3, stride=1 if use_atrous else 2, + padding=padding, + scope='MaxPool_1a_3x3') + net = tf.concat([tower_conv, tower_conv1_2, tower_pool], 3) + + if add_and_check_final('Mixed_6a', net): return net, end_points + + # TODO(alemi): register intermediate endpoints + with slim.arg_scope([slim.conv2d], rate=2 if use_atrous else 1): + net = slim.repeat(net, 20, block17, scale=0.10, + activation_fn=activation_fn) + if add_and_check_final('PreAuxLogits', net): return net, end_points + + if output_stride == 8: + # TODO(gpapan): Properly support output_stride for the rest of the net. + raise ValueError('output_stride==8 is only supported up to the ' + 'PreAuxlogits end_point for now.') + + # 8 x 8 x 2080 + with tf.variable_scope('Mixed_7a'): + with tf.variable_scope('Branch_0'): + tower_conv = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1') + tower_conv_1 = slim.conv2d(tower_conv, 384, 3, stride=2, + padding=padding, + scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_1'): + tower_conv1 = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1') + tower_conv1_1 = slim.conv2d(tower_conv1, 288, 3, stride=2, + padding=padding, + scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_2'): + tower_conv2 = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1') + tower_conv2_1 = slim.conv2d(tower_conv2, 288, 3, + scope='Conv2d_0b_3x3') + tower_conv2_2 = slim.conv2d(tower_conv2_1, 320, 3, stride=2, + padding=padding, + scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_3'): + tower_pool = slim.max_pool2d(net, 3, stride=2, + padding=padding, + scope='MaxPool_1a_3x3') + net = tf.concat( + [tower_conv_1, tower_conv1_1, tower_conv2_2, tower_pool], 3) + + if add_and_check_final('Mixed_7a', net): return net, end_points + + # TODO(alemi): register intermediate endpoints + net = slim.repeat(net, 9, block8, scale=0.20, activation_fn=activation_fn) + net = block8(net, activation_fn=None) + + # 8 x 8 x 1536 + net = slim.conv2d(net, 1536, 1, scope='Conv2d_7b_1x1') + if add_and_check_final('Conv2d_7b_1x1', net): return net, end_points + + raise ValueError('final_endpoint (%s) not recognized', final_endpoint) + + +def inception_resnet_v2(inputs, num_classes=1001, is_training=True, + dropout_keep_prob=0.8, + reuse=None, + scope='InceptionResnetV2', + create_aux_logits=True, + activation_fn=tf.nn.relu): + """Creates the Inception Resnet V2 model. + + Args: + inputs: a 4-D tensor of size [batch_size, height, width, 3]. + Dimension batch_size may be undefined. If create_aux_logits is false, + also height and width may be undefined. + num_classes: number of predicted classes. If 0 or None, the logits layer + is omitted and the input features to the logits layer (before dropout) + are returned instead. + is_training: whether is training or not. + dropout_keep_prob: float, the fraction to keep before final layer. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + create_aux_logits: Whether to include the auxilliary logits. + activation_fn: Activation function for conv2d. + + Returns: + net: the output of the logits layer (if num_classes is a non-zero integer), + or the non-dropped-out input to the logits layer (if num_classes is 0 or + None). + end_points: the set of end_points from the inception model. + """ + end_points = {} + + with tf.variable_scope(scope, 'InceptionResnetV2', [inputs], + reuse=reuse) as scope: + with slim.arg_scope([slim.batch_norm, slim.dropout], + is_training=is_training): + + net, end_points = inception_resnet_v2_base(inputs, scope=scope, + activation_fn=activation_fn) + + if create_aux_logits and num_classes: + with tf.variable_scope('AuxLogits'): + aux = end_points['PreAuxLogits'] + aux = slim.avg_pool2d(aux, 5, stride=3, padding='VALID', + scope='Conv2d_1a_3x3') + aux = slim.conv2d(aux, 128, 1, scope='Conv2d_1b_1x1') + aux = slim.conv2d(aux, 768, aux.get_shape()[1:3], + padding='VALID', scope='Conv2d_2a_5x5') + aux = slim.flatten(aux) + aux = slim.fully_connected(aux, num_classes, activation_fn=None, + scope='Logits') + end_points['AuxLogits'] = aux + + with tf.variable_scope('Logits'): + # TODO(sguada,arnoegw): Consider adding a parameter global_pool which + # can be set to False to disable pooling here (as in resnet_*()). + kernel_size = net.get_shape()[1:3] + if kernel_size.is_fully_defined(): + net = slim.avg_pool2d(net, kernel_size, padding='VALID', + scope='AvgPool_1a_8x8') + else: + net = tf.reduce_mean(net, [1, 2], keep_dims=True, name='global_pool') + end_points['global_pool'] = net + if not num_classes: + return net, end_points + net = slim.flatten(net) + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='Dropout') + end_points['PreLogitsFlatten'] = net + logits = slim.fully_connected(net, num_classes, activation_fn=None, + scope='Logits') + end_points['Logits'] = logits + end_points['Predictions'] = tf.nn.softmax(logits, name='Predictions') + + return logits, end_points +inception_resnet_v2.default_image_size = 299 + + +def inception_resnet_v2_arg_scope( + weight_decay=0.00004, + batch_norm_decay=0.9997, + batch_norm_epsilon=0.001, + activation_fn=tf.nn.relu, + batch_norm_updates_collections=tf.GraphKeys.UPDATE_OPS, + batch_norm_scale=False): + """Returns the scope with the default parameters for inception_resnet_v2. + + Args: + weight_decay: the weight decay for weights variables. + batch_norm_decay: decay for the moving average of batch_norm momentums. + batch_norm_epsilon: small float added to variance to avoid dividing by zero. + activation_fn: Activation function for conv2d. + batch_norm_updates_collections: Collection for the update ops for + batch norm. + batch_norm_scale: If True, uses an explicit `gamma` multiplier to scale the + activations in the batch normalization layer. + + Returns: + a arg_scope with the parameters needed for inception_resnet_v2. + """ + # Set weight_decay for weights in conv2d and fully_connected layers. + with slim.arg_scope([slim.conv2d, slim.fully_connected], + weights_regularizer=slim.l2_regularizer(weight_decay), + biases_regularizer=slim.l2_regularizer(weight_decay)): + + batch_norm_params = { + 'decay': batch_norm_decay, + 'epsilon': batch_norm_epsilon, + 'updates_collections': batch_norm_updates_collections, + 'fused': None, # Use fused batch norm if possible. + 'scale': batch_norm_scale, + } + # Set activation_fn and parameters for batch_norm. + with slim.arg_scope([slim.conv2d], activation_fn=activation_fn, + normalizer_fn=slim.batch_norm, + normalizer_params=batch_norm_params) as scope: + return scope diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_resnet_v2_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_resnet_v2_test.py new file mode 100644 index 0000000..833ada5 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_resnet_v2_test.py @@ -0,0 +1,334 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for slim.inception_resnet_v2.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import inception + + +class InceptionTest(tf.test.TestCase): + + def testBuildLogits(self): + batch_size = 5 + height, width = 299, 299 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, endpoints = inception.inception_resnet_v2(inputs, num_classes) + self.assertTrue('AuxLogits' in endpoints) + auxlogits = endpoints['AuxLogits'] + self.assertTrue( + auxlogits.op.name.startswith('InceptionResnetV2/AuxLogits')) + self.assertListEqual(auxlogits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertTrue(logits.op.name.startswith('InceptionResnetV2/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + + def testBuildWithoutAuxLogits(self): + batch_size = 5 + height, width = 299, 299 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, endpoints = inception.inception_resnet_v2(inputs, num_classes, + create_aux_logits=False) + self.assertTrue('AuxLogits' not in endpoints) + self.assertTrue(logits.op.name.startswith('InceptionResnetV2/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + + def testBuildNoClasses(self): + batch_size = 5 + height, width = 299, 299 + num_classes = None + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, endpoints = inception.inception_resnet_v2(inputs, num_classes) + self.assertTrue('AuxLogits' not in endpoints) + self.assertTrue('Logits' not in endpoints) + self.assertTrue( + net.op.name.startswith('InceptionResnetV2/Logits/AvgPool')) + self.assertListEqual(net.get_shape().as_list(), [batch_size, 1, 1, 1536]) + + def testBuildEndPoints(self): + batch_size = 5 + height, width = 299, 299 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_resnet_v2(inputs, num_classes) + self.assertTrue('Logits' in end_points) + logits = end_points['Logits'] + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertTrue('AuxLogits' in end_points) + aux_logits = end_points['AuxLogits'] + self.assertListEqual(aux_logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Conv2d_7b_1x1'] + self.assertListEqual(pre_pool.get_shape().as_list(), + [batch_size, 8, 8, 1536]) + + def testBuildBaseNetwork(self): + batch_size = 5 + height, width = 299, 299 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, end_points = inception.inception_resnet_v2_base(inputs) + self.assertTrue(net.op.name.startswith('InceptionResnetV2/Conv2d_7b_1x1')) + self.assertListEqual(net.get_shape().as_list(), + [batch_size, 8, 8, 1536]) + expected_endpoints = ['Conv2d_1a_3x3', 'Conv2d_2a_3x3', 'Conv2d_2b_3x3', + 'MaxPool_3a_3x3', 'Conv2d_3b_1x1', 'Conv2d_4a_3x3', + 'MaxPool_5a_3x3', 'Mixed_5b', 'Mixed_6a', + 'PreAuxLogits', 'Mixed_7a', 'Conv2d_7b_1x1'] + self.assertItemsEqual(end_points.keys(), expected_endpoints) + + def testBuildOnlyUptoFinalEndpoint(self): + batch_size = 5 + height, width = 299, 299 + endpoints = ['Conv2d_1a_3x3', 'Conv2d_2a_3x3', 'Conv2d_2b_3x3', + 'MaxPool_3a_3x3', 'Conv2d_3b_1x1', 'Conv2d_4a_3x3', + 'MaxPool_5a_3x3', 'Mixed_5b', 'Mixed_6a', + 'PreAuxLogits', 'Mixed_7a', 'Conv2d_7b_1x1'] + for index, endpoint in enumerate(endpoints): + with tf.Graph().as_default(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + out_tensor, end_points = inception.inception_resnet_v2_base( + inputs, final_endpoint=endpoint) + if endpoint != 'PreAuxLogits': + self.assertTrue(out_tensor.op.name.startswith( + 'InceptionResnetV2/' + endpoint)) + self.assertItemsEqual(endpoints[:index+1], end_points.keys()) + + def testBuildAndCheckAllEndPointsUptoPreAuxLogits(self): + batch_size = 5 + height, width = 299, 299 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_resnet_v2_base( + inputs, final_endpoint='PreAuxLogits') + endpoints_shapes = {'Conv2d_1a_3x3': [5, 149, 149, 32], + 'Conv2d_2a_3x3': [5, 147, 147, 32], + 'Conv2d_2b_3x3': [5, 147, 147, 64], + 'MaxPool_3a_3x3': [5, 73, 73, 64], + 'Conv2d_3b_1x1': [5, 73, 73, 80], + 'Conv2d_4a_3x3': [5, 71, 71, 192], + 'MaxPool_5a_3x3': [5, 35, 35, 192], + 'Mixed_5b': [5, 35, 35, 320], + 'Mixed_6a': [5, 17, 17, 1088], + 'PreAuxLogits': [5, 17, 17, 1088] + } + + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name in endpoints_shapes: + expected_shape = endpoints_shapes[endpoint_name] + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testBuildAndCheckAllEndPointsUptoPreAuxLogitsWithAlignedFeatureMaps(self): + batch_size = 5 + height, width = 299, 299 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_resnet_v2_base( + inputs, final_endpoint='PreAuxLogits', align_feature_maps=True) + endpoints_shapes = {'Conv2d_1a_3x3': [5, 150, 150, 32], + 'Conv2d_2a_3x3': [5, 150, 150, 32], + 'Conv2d_2b_3x3': [5, 150, 150, 64], + 'MaxPool_3a_3x3': [5, 75, 75, 64], + 'Conv2d_3b_1x1': [5, 75, 75, 80], + 'Conv2d_4a_3x3': [5, 75, 75, 192], + 'MaxPool_5a_3x3': [5, 38, 38, 192], + 'Mixed_5b': [5, 38, 38, 320], + 'Mixed_6a': [5, 19, 19, 1088], + 'PreAuxLogits': [5, 19, 19, 1088] + } + + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name in endpoints_shapes: + expected_shape = endpoints_shapes[endpoint_name] + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testBuildAndCheckAllEndPointsUptoPreAuxLogitsWithOutputStrideEight(self): + batch_size = 5 + height, width = 299, 299 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_resnet_v2_base( + inputs, final_endpoint='PreAuxLogits', output_stride=8) + endpoints_shapes = {'Conv2d_1a_3x3': [5, 149, 149, 32], + 'Conv2d_2a_3x3': [5, 147, 147, 32], + 'Conv2d_2b_3x3': [5, 147, 147, 64], + 'MaxPool_3a_3x3': [5, 73, 73, 64], + 'Conv2d_3b_1x1': [5, 73, 73, 80], + 'Conv2d_4a_3x3': [5, 71, 71, 192], + 'MaxPool_5a_3x3': [5, 35, 35, 192], + 'Mixed_5b': [5, 35, 35, 320], + 'Mixed_6a': [5, 33, 33, 1088], + 'PreAuxLogits': [5, 33, 33, 1088] + } + + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name in endpoints_shapes: + expected_shape = endpoints_shapes[endpoint_name] + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testVariablesSetDevice(self): + batch_size = 5 + height, width = 299, 299 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + # Force all Variables to reside on the device. + with tf.variable_scope('on_cpu'), tf.device('/cpu:0'): + inception.inception_resnet_v2(inputs, num_classes) + with tf.variable_scope('on_gpu'), tf.device('/gpu:0'): + inception.inception_resnet_v2(inputs, num_classes) + for v in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='on_cpu'): + self.assertDeviceEqual(v.device, '/cpu:0') + for v in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='on_gpu'): + self.assertDeviceEqual(v.device, '/gpu:0') + + def testHalfSizeImages(self): + batch_size = 5 + height, width = 150, 150 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, end_points = inception.inception_resnet_v2(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionResnetV2/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Conv2d_7b_1x1'] + self.assertListEqual(pre_pool.get_shape().as_list(), + [batch_size, 3, 3, 1536]) + + def testGlobalPool(self): + batch_size = 1 + height, width = 330, 400 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, end_points = inception.inception_resnet_v2(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionResnetV2/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Conv2d_7b_1x1'] + self.assertListEqual(pre_pool.get_shape().as_list(), + [batch_size, 8, 11, 1536]) + + def testGlobalPoolUnknownImageShape(self): + batch_size = 1 + height, width = 330, 400 + num_classes = 1000 + with self.test_session() as sess: + inputs = tf.placeholder(tf.float32, (batch_size, None, None, 3)) + logits, end_points = inception.inception_resnet_v2( + inputs, num_classes, create_aux_logits=False) + self.assertTrue(logits.op.name.startswith('InceptionResnetV2/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Conv2d_7b_1x1'] + images = tf.random_uniform((batch_size, height, width, 3)) + sess.run(tf.global_variables_initializer()) + logits_out, pre_pool_out = sess.run([logits, pre_pool], + {inputs: images.eval()}) + self.assertTupleEqual(logits_out.shape, (batch_size, num_classes)) + self.assertTupleEqual(pre_pool_out.shape, (batch_size, 8, 11, 1536)) + + def testUnknownBatchSize(self): + batch_size = 1 + height, width = 299, 299 + num_classes = 1000 + with self.test_session() as sess: + inputs = tf.placeholder(tf.float32, (None, height, width, 3)) + logits, _ = inception.inception_resnet_v2(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionResnetV2/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [None, num_classes]) + images = tf.random_uniform((batch_size, height, width, 3)) + sess.run(tf.global_variables_initializer()) + output = sess.run(logits, {inputs: images.eval()}) + self.assertEquals(output.shape, (batch_size, num_classes)) + + def testEvaluation(self): + batch_size = 2 + height, width = 299, 299 + num_classes = 1000 + with self.test_session() as sess: + eval_inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = inception.inception_resnet_v2(eval_inputs, + num_classes, + is_training=False) + predictions = tf.argmax(logits, 1) + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (batch_size,)) + + def testTrainEvalWithReuse(self): + train_batch_size = 5 + eval_batch_size = 2 + height, width = 150, 150 + num_classes = 1000 + with self.test_session() as sess: + train_inputs = tf.random_uniform((train_batch_size, height, width, 3)) + inception.inception_resnet_v2(train_inputs, num_classes) + eval_inputs = tf.random_uniform((eval_batch_size, height, width, 3)) + logits, _ = inception.inception_resnet_v2(eval_inputs, + num_classes, + is_training=False, + reuse=True) + predictions = tf.argmax(logits, 1) + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (eval_batch_size,)) + + def testNoBatchNormScaleByDefault(self): + height, width = 299, 299 + num_classes = 1000 + inputs = tf.placeholder(tf.float32, (1, height, width, 3)) + with tf.contrib.slim.arg_scope(inception.inception_resnet_v2_arg_scope()): + inception.inception_resnet_v2(inputs, num_classes, is_training=False) + + self.assertEqual(tf.global_variables('.*/BatchNorm/gamma:0$'), []) + + def testBatchNormScale(self): + height, width = 299, 299 + num_classes = 1000 + inputs = tf.placeholder(tf.float32, (1, height, width, 3)) + with tf.contrib.slim.arg_scope( + inception.inception_resnet_v2_arg_scope(batch_norm_scale=True)): + inception.inception_resnet_v2(inputs, num_classes, is_training=False) + + gamma_names = set( + v.op.name for v in tf.global_variables('.*/BatchNorm/gamma:0$')) + self.assertGreater(len(gamma_names), 0) + for v in tf.global_variables('.*/BatchNorm/moving_mean:0$'): + self.assertIn(v.op.name[:-len('moving_mean')] + 'gamma', gamma_names) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_utils.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_utils.py new file mode 100644 index 0000000..a8c8fc1 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_utils.py @@ -0,0 +1,82 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains common code shared by all inception models. + +Usage of arg scope: + with slim.arg_scope(inception_arg_scope()): + logits, end_points = inception.inception_v3(images, num_classes, + is_training=is_training) + +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +slim = tf.contrib.slim + + +def inception_arg_scope(weight_decay=0.00004, + use_batch_norm=True, + batch_norm_decay=0.9997, + batch_norm_epsilon=0.001, + activation_fn=tf.nn.relu, + batch_norm_updates_collections=tf.GraphKeys.UPDATE_OPS, + batch_norm_scale=False): + """Defines the default arg scope for inception models. + + Args: + weight_decay: The weight decay to use for regularizing the model. + use_batch_norm: "If `True`, batch_norm is applied after each convolution. + batch_norm_decay: Decay for batch norm moving average. + batch_norm_epsilon: Small float added to variance to avoid dividing by zero + in batch norm. + activation_fn: Activation function for conv2d. + batch_norm_updates_collections: Collection for the update ops for + batch norm. + batch_norm_scale: If True, uses an explicit `gamma` multiplier to scale the + activations in the batch normalization layer. + + Returns: + An `arg_scope` to use for the inception models. + """ + batch_norm_params = { + # Decay for the moving averages. + 'decay': batch_norm_decay, + # epsilon to prevent 0s in variance. + 'epsilon': batch_norm_epsilon, + # collection containing update_ops. + 'updates_collections': batch_norm_updates_collections, + # use fused batch norm if possible. + 'fused': None, + 'scale': batch_norm_scale, + } + if use_batch_norm: + normalizer_fn = slim.batch_norm + normalizer_params = batch_norm_params + else: + normalizer_fn = None + normalizer_params = {} + # Set weight_decay for weights in Conv and FC layers. + with slim.arg_scope([slim.conv2d, slim.fully_connected], + weights_regularizer=slim.l2_regularizer(weight_decay)): + with slim.arg_scope( + [slim.conv2d], + weights_initializer=slim.variance_scaling_initializer(), + activation_fn=activation_fn, + normalizer_fn=normalizer_fn, + normalizer_params=normalizer_params) as sc: + return sc diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v1.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v1.py new file mode 100644 index 0000000..d987165 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v1.py @@ -0,0 +1,329 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains the definition for inception v1 classification network.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import inception_utils + +slim = tf.contrib.slim +trunc_normal = lambda stddev: tf.truncated_normal_initializer(0.0, stddev) + + +def inception_v1_base(inputs, + final_endpoint='Mixed_5c', + scope='InceptionV1'): + """Defines the Inception V1 base architecture. + + This architecture is defined in: + Going deeper with convolutions + Christian Szegedy, Wei Liu, Yangqing Jia, Pierre Sermanet, Scott Reed, + Dragomir Anguelov, Dumitru Erhan, Vincent Vanhoucke, Andrew Rabinovich. + http://arxiv.org/pdf/1409.4842v1.pdf. + + Args: + inputs: a tensor of size [batch_size, height, width, channels]. + final_endpoint: specifies the endpoint to construct the network up to. It + can be one of ['Conv2d_1a_7x7', 'MaxPool_2a_3x3', 'Conv2d_2b_1x1', + 'Conv2d_2c_3x3', 'MaxPool_3a_3x3', 'Mixed_3b', 'Mixed_3c', + 'MaxPool_4a_3x3', 'Mixed_4b', 'Mixed_4c', 'Mixed_4d', 'Mixed_4e', + 'Mixed_4f', 'MaxPool_5a_2x2', 'Mixed_5b', 'Mixed_5c'] + scope: Optional variable_scope. + + Returns: + A dictionary from components of the network to the corresponding activation. + + Raises: + ValueError: if final_endpoint is not set to one of the predefined values. + """ + end_points = {} + with tf.variable_scope(scope, 'InceptionV1', [inputs]): + with slim.arg_scope( + [slim.conv2d, slim.fully_connected], + weights_initializer=trunc_normal(0.01)): + with slim.arg_scope([slim.conv2d, slim.max_pool2d], + stride=1, padding='SAME'): + end_point = 'Conv2d_1a_7x7' + net = slim.conv2d(inputs, 64, [7, 7], stride=2, scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + end_point = 'MaxPool_2a_3x3' + net = slim.max_pool2d(net, [3, 3], stride=2, scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + end_point = 'Conv2d_2b_1x1' + net = slim.conv2d(net, 64, [1, 1], scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + end_point = 'Conv2d_2c_3x3' + net = slim.conv2d(net, 192, [3, 3], scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + end_point = 'MaxPool_3a_3x3' + net = slim.max_pool2d(net, [3, 3], stride=2, scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + + end_point = 'Mixed_3b' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, 64, [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, 96, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, 128, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, 16, [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, 32, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.max_pool2d(net, [3, 3], scope='MaxPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, 32, [1, 1], scope='Conv2d_0b_1x1') + net = tf.concat( + axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + + end_point = 'Mixed_3c' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, 128, [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, 128, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, 192, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, 32, [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, 96, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.max_pool2d(net, [3, 3], scope='MaxPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, 64, [1, 1], scope='Conv2d_0b_1x1') + net = tf.concat( + axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + + end_point = 'MaxPool_4a_3x3' + net = slim.max_pool2d(net, [3, 3], stride=2, scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + + end_point = 'Mixed_4b' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, 192, [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, 96, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, 208, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, 16, [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, 48, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.max_pool2d(net, [3, 3], scope='MaxPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, 64, [1, 1], scope='Conv2d_0b_1x1') + net = tf.concat( + axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + + end_point = 'Mixed_4c' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, 160, [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, 112, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, 224, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, 24, [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, 64, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.max_pool2d(net, [3, 3], scope='MaxPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, 64, [1, 1], scope='Conv2d_0b_1x1') + net = tf.concat( + axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + + end_point = 'Mixed_4d' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, 128, [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, 128, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, 256, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, 24, [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, 64, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.max_pool2d(net, [3, 3], scope='MaxPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, 64, [1, 1], scope='Conv2d_0b_1x1') + net = tf.concat( + axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + + end_point = 'Mixed_4e' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, 112, [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, 144, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, 288, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, 32, [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, 64, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.max_pool2d(net, [3, 3], scope='MaxPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, 64, [1, 1], scope='Conv2d_0b_1x1') + net = tf.concat( + axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + + end_point = 'Mixed_4f' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, 256, [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, 160, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, 320, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, 32, [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, 128, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.max_pool2d(net, [3, 3], scope='MaxPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, 128, [1, 1], scope='Conv2d_0b_1x1') + net = tf.concat( + axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + + end_point = 'MaxPool_5a_2x2' + net = slim.max_pool2d(net, [2, 2], stride=2, scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + + end_point = 'Mixed_5b' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, 256, [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, 160, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, 320, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, 32, [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, 128, [3, 3], scope='Conv2d_0a_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.max_pool2d(net, [3, 3], scope='MaxPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, 128, [1, 1], scope='Conv2d_0b_1x1') + net = tf.concat( + axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + + end_point = 'Mixed_5c' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, 384, [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, 192, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, 384, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, 48, [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, 128, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.max_pool2d(net, [3, 3], scope='MaxPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, 128, [1, 1], scope='Conv2d_0b_1x1') + net = tf.concat( + axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if final_endpoint == end_point: return net, end_points + raise ValueError('Unknown final endpoint %s' % final_endpoint) + + +def inception_v1(inputs, + num_classes=1000, + is_training=True, + dropout_keep_prob=0.8, + prediction_fn=slim.softmax, + spatial_squeeze=True, + reuse=None, + scope='InceptionV1', + global_pool=False): + """Defines the Inception V1 architecture. + + This architecture is defined in: + + Going deeper with convolutions + Christian Szegedy, Wei Liu, Yangqing Jia, Pierre Sermanet, Scott Reed, + Dragomir Anguelov, Dumitru Erhan, Vincent Vanhoucke, Andrew Rabinovich. + http://arxiv.org/pdf/1409.4842v1.pdf. + + The default image size used to train this network is 224x224. + + Args: + inputs: a tensor of size [batch_size, height, width, channels]. + num_classes: number of predicted classes. If 0 or None, the logits layer + is omitted and the input features to the logits layer (before dropout) + are returned instead. + is_training: whether is training or not. + dropout_keep_prob: the percentage of activation values that are retained. + prediction_fn: a function to get predictions out of logits. + spatial_squeeze: if True, logits is of shape [B, C], if false logits is of + shape [B, 1, 1, C], where B is batch_size and C is number of classes. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + global_pool: Optional boolean flag to control the avgpooling before the + logits layer. If false or unset, pooling is done with a fixed window + that reduces default-sized inputs to 1x1, while larger inputs lead to + larger outputs. If true, any input size is pooled down to 1x1. + + Returns: + net: a Tensor with the logits (pre-softmax activations) if num_classes + is a non-zero integer, or the non-dropped-out input to the logits layer + if num_classes is 0 or None. + end_points: a dictionary from components of the network to the corresponding + activation. + """ + # Final pooling and prediction + with tf.variable_scope(scope, 'InceptionV1', [inputs], reuse=reuse) as scope: + with slim.arg_scope([slim.batch_norm, slim.dropout], + is_training=is_training): + net, end_points = inception_v1_base(inputs, scope=scope) + with tf.variable_scope('Logits'): + if global_pool: + # Global average pooling. + net = tf.reduce_mean(net, [1, 2], keep_dims=True, name='global_pool') + end_points['global_pool'] = net + else: + # Pooling with a fixed kernel size. + net = slim.avg_pool2d(net, [7, 7], stride=1, scope='AvgPool_0a_7x7') + end_points['AvgPool_0a_7x7'] = net + if not num_classes: + return net, end_points + net = slim.dropout(net, dropout_keep_prob, scope='Dropout_0b') + logits = slim.conv2d(net, num_classes, [1, 1], activation_fn=None, + normalizer_fn=None, scope='Conv2d_0c_1x1') + if spatial_squeeze: + logits = tf.squeeze(logits, [1, 2], name='SpatialSqueeze') + + end_points['Logits'] = logits + end_points['Predictions'] = prediction_fn(logits, scope='Predictions') + return logits, end_points +inception_v1.default_image_size = 224 + +inception_v1_arg_scope = inception_utils.inception_arg_scope diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v1_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v1_test.py new file mode 100644 index 0000000..0386257 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v1_test.py @@ -0,0 +1,265 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for nets.inception_v1.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import tensorflow as tf + +from nets import inception + +slim = tf.contrib.slim + + +class InceptionV1Test(tf.test.TestCase): + + def testBuildClassificationNetwork(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, end_points = inception.inception_v1(inputs, num_classes) + self.assertTrue(logits.op.name.startswith( + 'InceptionV1/Logits/SpatialSqueeze')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertTrue('Predictions' in end_points) + self.assertListEqual(end_points['Predictions'].get_shape().as_list(), + [batch_size, num_classes]) + + def testBuildPreLogitsNetwork(self): + batch_size = 5 + height, width = 224, 224 + num_classes = None + + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, end_points = inception.inception_v1(inputs, num_classes) + self.assertTrue(net.op.name.startswith('InceptionV1/Logits/AvgPool')) + self.assertListEqual(net.get_shape().as_list(), [batch_size, 1, 1, 1024]) + self.assertFalse('Logits' in end_points) + self.assertFalse('Predictions' in end_points) + + def testBuildBaseNetwork(self): + batch_size = 5 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + mixed_6c, end_points = inception.inception_v1_base(inputs) + self.assertTrue(mixed_6c.op.name.startswith('InceptionV1/Mixed_5c')) + self.assertListEqual(mixed_6c.get_shape().as_list(), + [batch_size, 7, 7, 1024]) + expected_endpoints = ['Conv2d_1a_7x7', 'MaxPool_2a_3x3', 'Conv2d_2b_1x1', + 'Conv2d_2c_3x3', 'MaxPool_3a_3x3', 'Mixed_3b', + 'Mixed_3c', 'MaxPool_4a_3x3', 'Mixed_4b', 'Mixed_4c', + 'Mixed_4d', 'Mixed_4e', 'Mixed_4f', 'MaxPool_5a_2x2', + 'Mixed_5b', 'Mixed_5c'] + self.assertItemsEqual(end_points.keys(), expected_endpoints) + + def testBuildOnlyUptoFinalEndpoint(self): + batch_size = 5 + height, width = 224, 224 + endpoints = ['Conv2d_1a_7x7', 'MaxPool_2a_3x3', 'Conv2d_2b_1x1', + 'Conv2d_2c_3x3', 'MaxPool_3a_3x3', 'Mixed_3b', 'Mixed_3c', + 'MaxPool_4a_3x3', 'Mixed_4b', 'Mixed_4c', 'Mixed_4d', + 'Mixed_4e', 'Mixed_4f', 'MaxPool_5a_2x2', 'Mixed_5b', + 'Mixed_5c'] + for index, endpoint in enumerate(endpoints): + with tf.Graph().as_default(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + out_tensor, end_points = inception.inception_v1_base( + inputs, final_endpoint=endpoint) + self.assertTrue(out_tensor.op.name.startswith( + 'InceptionV1/' + endpoint)) + self.assertItemsEqual(endpoints[:index+1], end_points.keys()) + + def testBuildAndCheckAllEndPointsUptoMixed5c(self): + batch_size = 5 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_v1_base(inputs, + final_endpoint='Mixed_5c') + endpoints_shapes = {'Conv2d_1a_7x7': [5, 112, 112, 64], + 'MaxPool_2a_3x3': [5, 56, 56, 64], + 'Conv2d_2b_1x1': [5, 56, 56, 64], + 'Conv2d_2c_3x3': [5, 56, 56, 192], + 'MaxPool_3a_3x3': [5, 28, 28, 192], + 'Mixed_3b': [5, 28, 28, 256], + 'Mixed_3c': [5, 28, 28, 480], + 'MaxPool_4a_3x3': [5, 14, 14, 480], + 'Mixed_4b': [5, 14, 14, 512], + 'Mixed_4c': [5, 14, 14, 512], + 'Mixed_4d': [5, 14, 14, 512], + 'Mixed_4e': [5, 14, 14, 528], + 'Mixed_4f': [5, 14, 14, 832], + 'MaxPool_5a_2x2': [5, 7, 7, 832], + 'Mixed_5b': [5, 7, 7, 832], + 'Mixed_5c': [5, 7, 7, 1024]} + + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name in endpoints_shapes: + expected_shape = endpoints_shapes[endpoint_name] + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testModelHasExpectedNumberOfParameters(self): + batch_size = 5 + height, width = 224, 224 + inputs = tf.random_uniform((batch_size, height, width, 3)) + with slim.arg_scope(inception.inception_v1_arg_scope()): + inception.inception_v1_base(inputs) + total_params, _ = slim.model_analyzer.analyze_vars( + slim.get_model_variables()) + self.assertAlmostEqual(5607184, total_params) + + def testHalfSizeImages(self): + batch_size = 5 + height, width = 112, 112 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + mixed_5c, _ = inception.inception_v1_base(inputs) + self.assertTrue(mixed_5c.op.name.startswith('InceptionV1/Mixed_5c')) + self.assertListEqual(mixed_5c.get_shape().as_list(), + [batch_size, 4, 4, 1024]) + + def testUnknownImageShape(self): + tf.reset_default_graph() + batch_size = 2 + height, width = 224, 224 + num_classes = 1000 + input_np = np.random.uniform(0, 1, (batch_size, height, width, 3)) + with self.test_session() as sess: + inputs = tf.placeholder(tf.float32, shape=(batch_size, None, None, 3)) + logits, end_points = inception.inception_v1(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionV1/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Mixed_5c'] + feed_dict = {inputs: input_np} + tf.global_variables_initializer().run() + pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict) + self.assertListEqual(list(pre_pool_out.shape), [batch_size, 7, 7, 1024]) + + def testGlobalPoolUnknownImageShape(self): + tf.reset_default_graph() + batch_size = 1 + height, width = 250, 300 + num_classes = 1000 + input_np = np.random.uniform(0, 1, (batch_size, height, width, 3)) + with self.test_session() as sess: + inputs = tf.placeholder(tf.float32, shape=(batch_size, None, None, 3)) + logits, end_points = inception.inception_v1(inputs, num_classes, + global_pool=True) + self.assertTrue(logits.op.name.startswith('InceptionV1/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Mixed_5c'] + feed_dict = {inputs: input_np} + tf.global_variables_initializer().run() + pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict) + self.assertListEqual(list(pre_pool_out.shape), [batch_size, 8, 10, 1024]) + + def testUnknowBatchSize(self): + batch_size = 1 + height, width = 224, 224 + num_classes = 1000 + + inputs = tf.placeholder(tf.float32, (None, height, width, 3)) + logits, _ = inception.inception_v1(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionV1/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [None, num_classes]) + images = tf.random_uniform((batch_size, height, width, 3)) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(logits, {inputs: images.eval()}) + self.assertEquals(output.shape, (batch_size, num_classes)) + + def testEvaluation(self): + batch_size = 2 + height, width = 224, 224 + num_classes = 1000 + + eval_inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = inception.inception_v1(eval_inputs, num_classes, + is_training=False) + predictions = tf.argmax(logits, 1) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (batch_size,)) + + def testTrainEvalWithReuse(self): + train_batch_size = 5 + eval_batch_size = 2 + height, width = 224, 224 + num_classes = 1000 + + train_inputs = tf.random_uniform((train_batch_size, height, width, 3)) + inception.inception_v1(train_inputs, num_classes) + eval_inputs = tf.random_uniform((eval_batch_size, height, width, 3)) + logits, _ = inception.inception_v1(eval_inputs, num_classes, reuse=True) + predictions = tf.argmax(logits, 1) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (eval_batch_size,)) + + def testLogitsNotSqueezed(self): + num_classes = 25 + images = tf.random_uniform([1, 224, 224, 3]) + logits, _ = inception.inception_v1(images, + num_classes=num_classes, + spatial_squeeze=False) + + with self.test_session() as sess: + tf.global_variables_initializer().run() + logits_out = sess.run(logits) + self.assertListEqual(list(logits_out.shape), [1, 1, 1, num_classes]) + + def testNoBatchNormScaleByDefault(self): + height, width = 224, 224 + num_classes = 1000 + inputs = tf.placeholder(tf.float32, (1, height, width, 3)) + with slim.arg_scope(inception.inception_v1_arg_scope()): + inception.inception_v1(inputs, num_classes, is_training=False) + + self.assertEqual(tf.global_variables('.*/BatchNorm/gamma:0$'), []) + + def testBatchNormScale(self): + height, width = 224, 224 + num_classes = 1000 + inputs = tf.placeholder(tf.float32, (1, height, width, 3)) + with slim.arg_scope( + inception.inception_v1_arg_scope(batch_norm_scale=True)): + inception.inception_v1(inputs, num_classes, is_training=False) + + gamma_names = set( + v.op.name for v in tf.global_variables('.*/BatchNorm/gamma:0$')) + self.assertGreater(len(gamma_names), 0) + for v in tf.global_variables('.*/BatchNorm/moving_mean:0$'): + self.assertIn(v.op.name[:-len('moving_mean')] + 'gamma', gamma_names) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v2.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v2.py new file mode 100644 index 0000000..66290b4 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v2.py @@ -0,0 +1,572 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains the definition for inception v2 classification network.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import inception_utils + +slim = tf.contrib.slim +trunc_normal = lambda stddev: tf.truncated_normal_initializer(0.0, stddev) + + +def inception_v2_base(inputs, + final_endpoint='Mixed_5c', + min_depth=16, + depth_multiplier=1.0, + use_separable_conv=True, + data_format='NHWC', + scope=None): + """Inception v2 (6a2). + + Constructs an Inception v2 network from inputs to the given final endpoint. + This method can construct the network up to the layer inception(5b) as + described in http://arxiv.org/abs/1502.03167. + + Args: + inputs: a tensor of shape [batch_size, height, width, channels]. + final_endpoint: specifies the endpoint to construct the network up to. It + can be one of ['Conv2d_1a_7x7', 'MaxPool_2a_3x3', 'Conv2d_2b_1x1', + 'Conv2d_2c_3x3', 'MaxPool_3a_3x3', 'Mixed_3b', 'Mixed_3c', 'Mixed_4a', + 'Mixed_4b', 'Mixed_4c', 'Mixed_4d', 'Mixed_4e', 'Mixed_5a', 'Mixed_5b', + 'Mixed_5c']. + min_depth: Minimum depth value (number of channels) for all convolution ops. + Enforced when depth_multiplier < 1, and not an active constraint when + depth_multiplier >= 1. + depth_multiplier: Float multiplier for the depth (number of channels) + for all convolution ops. The value must be greater than zero. Typical + usage will be to set this value in (0, 1) to reduce the number of + parameters or computation cost of the model. + use_separable_conv: Use a separable convolution for the first layer + Conv2d_1a_7x7. If this is False, use a normal convolution instead. + data_format: Data format of the activations ('NHWC' or 'NCHW'). + scope: Optional variable_scope. + + Returns: + tensor_out: output tensor corresponding to the final_endpoint. + end_points: a set of activations for external use, for example summaries or + losses. + + Raises: + ValueError: if final_endpoint is not set to one of the predefined values, + or depth_multiplier <= 0 + """ + + # end_points will collect relevant activations for external use, for example + # summaries or losses. + end_points = {} + + # Used to find thinned depths for each layer. + if depth_multiplier <= 0: + raise ValueError('depth_multiplier is not greater than zero.') + depth = lambda d: max(int(d * depth_multiplier), min_depth) + + if data_format != 'NHWC' and data_format != 'NCHW': + raise ValueError('data_format must be either NHWC or NCHW.') + if data_format == 'NCHW' and use_separable_conv: + raise ValueError( + 'separable convolution only supports NHWC layout. NCHW data format can' + ' only be used when use_separable_conv is False.' + ) + + concat_dim = 3 if data_format == 'NHWC' else 1 + with tf.variable_scope(scope, 'InceptionV2', [inputs]): + with slim.arg_scope( + [slim.conv2d, slim.max_pool2d, slim.avg_pool2d], + stride=1, + padding='SAME', + data_format=data_format): + + # Note that sizes in the comments below assume an input spatial size of + # 224x224, however, the inputs can be of any size greater 32x32. + + # 224 x 224 x 3 + end_point = 'Conv2d_1a_7x7' + + if use_separable_conv: + # depthwise_multiplier here is different from depth_multiplier. + # depthwise_multiplier determines the output channels of the initial + # depthwise conv (see docs for tf.nn.separable_conv2d), while + # depth_multiplier controls the # channels of the subsequent 1x1 + # convolution. Must have + # in_channels * depthwise_multipler <= out_channels + # so that the separable convolution is not overparameterized. + depthwise_multiplier = min(int(depth(64) / 3), 8) + net = slim.separable_conv2d( + inputs, depth(64), [7, 7], + depth_multiplier=depthwise_multiplier, + stride=2, + padding='SAME', + weights_initializer=trunc_normal(1.0), + scope=end_point) + else: + # Use a normal convolution instead of a separable convolution. + net = slim.conv2d( + inputs, + depth(64), [7, 7], + stride=2, + weights_initializer=trunc_normal(1.0), + scope=end_point) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 112 x 112 x 64 + end_point = 'MaxPool_2a_3x3' + net = slim.max_pool2d(net, [3, 3], scope=end_point, stride=2) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 56 x 56 x 64 + end_point = 'Conv2d_2b_1x1' + net = slim.conv2d(net, depth(64), [1, 1], scope=end_point, + weights_initializer=trunc_normal(0.1)) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 56 x 56 x 64 + end_point = 'Conv2d_2c_3x3' + net = slim.conv2d(net, depth(192), [3, 3], scope=end_point) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 56 x 56 x 192 + end_point = 'MaxPool_3a_3x3' + net = slim.max_pool2d(net, [3, 3], scope=end_point, stride=2) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 28 x 28 x 192 + # Inception module. + end_point = 'Mixed_3b' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(64), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d( + net, depth(64), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(64), [3, 3], + scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d( + net, depth(64), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(96), [3, 3], + scope='Conv2d_0b_3x3') + branch_2 = slim.conv2d(branch_2, depth(96), [3, 3], + scope='Conv2d_0c_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d( + branch_3, depth(32), [1, 1], + weights_initializer=trunc_normal(0.1), + scope='Conv2d_0b_1x1') + net = tf.concat( + axis=concat_dim, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 28 x 28 x 256 + end_point = 'Mixed_3c' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(64), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d( + net, depth(64), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(96), [3, 3], + scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d( + net, depth(64), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(96), [3, 3], + scope='Conv2d_0b_3x3') + branch_2 = slim.conv2d(branch_2, depth(96), [3, 3], + scope='Conv2d_0c_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d( + branch_3, depth(64), [1, 1], + weights_initializer=trunc_normal(0.1), + scope='Conv2d_0b_1x1') + net = tf.concat( + axis=concat_dim, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 28 x 28 x 320 + end_point = 'Mixed_4a' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d( + net, depth(128), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_0 = slim.conv2d(branch_0, depth(160), [3, 3], stride=2, + scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d( + net, depth(64), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d( + branch_1, depth(96), [3, 3], scope='Conv2d_0b_3x3') + branch_1 = slim.conv2d( + branch_1, depth(96), [3, 3], stride=2, scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.max_pool2d( + net, [3, 3], stride=2, scope='MaxPool_1a_3x3') + net = tf.concat(axis=concat_dim, values=[branch_0, branch_1, branch_2]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 14 x 14 x 576 + end_point = 'Mixed_4b' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(224), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d( + net, depth(64), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d( + branch_1, depth(96), [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d( + net, depth(96), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(128), [3, 3], + scope='Conv2d_0b_3x3') + branch_2 = slim.conv2d(branch_2, depth(128), [3, 3], + scope='Conv2d_0c_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d( + branch_3, depth(128), [1, 1], + weights_initializer=trunc_normal(0.1), + scope='Conv2d_0b_1x1') + net = tf.concat( + axis=concat_dim, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 14 x 14 x 576 + end_point = 'Mixed_4c' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d( + net, depth(96), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(128), [3, 3], + scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d( + net, depth(96), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(128), [3, 3], + scope='Conv2d_0b_3x3') + branch_2 = slim.conv2d(branch_2, depth(128), [3, 3], + scope='Conv2d_0c_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d( + branch_3, depth(128), [1, 1], + weights_initializer=trunc_normal(0.1), + scope='Conv2d_0b_1x1') + net = tf.concat( + axis=concat_dim, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 14 x 14 x 576 + end_point = 'Mixed_4d' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(160), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d( + net, depth(128), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(160), [3, 3], + scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d( + net, depth(128), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(160), [3, 3], + scope='Conv2d_0b_3x3') + branch_2 = slim.conv2d(branch_2, depth(160), [3, 3], + scope='Conv2d_0c_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d( + branch_3, depth(96), [1, 1], + weights_initializer=trunc_normal(0.1), + scope='Conv2d_0b_1x1') + net = tf.concat( + axis=concat_dim, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 14 x 14 x 576 + end_point = 'Mixed_4e' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(96), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d( + net, depth(128), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(192), [3, 3], + scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d( + net, depth(160), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(192), [3, 3], + scope='Conv2d_0b_3x3') + branch_2 = slim.conv2d(branch_2, depth(192), [3, 3], + scope='Conv2d_0c_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d( + branch_3, depth(96), [1, 1], + weights_initializer=trunc_normal(0.1), + scope='Conv2d_0b_1x1') + net = tf.concat( + axis=concat_dim, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 14 x 14 x 576 + end_point = 'Mixed_5a' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d( + net, depth(128), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_0 = slim.conv2d(branch_0, depth(192), [3, 3], stride=2, + scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d( + net, depth(192), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(256), [3, 3], + scope='Conv2d_0b_3x3') + branch_1 = slim.conv2d(branch_1, depth(256), [3, 3], stride=2, + scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.max_pool2d(net, [3, 3], stride=2, + scope='MaxPool_1a_3x3') + net = tf.concat( + axis=concat_dim, values=[branch_0, branch_1, branch_2]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 7 x 7 x 1024 + end_point = 'Mixed_5b' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(352), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d( + net, depth(192), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(320), [3, 3], + scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d( + net, depth(160), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(224), [3, 3], + scope='Conv2d_0b_3x3') + branch_2 = slim.conv2d(branch_2, depth(224), [3, 3], + scope='Conv2d_0c_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d( + branch_3, depth(128), [1, 1], + weights_initializer=trunc_normal(0.1), + scope='Conv2d_0b_1x1') + net = tf.concat( + axis=concat_dim, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 7 x 7 x 1024 + end_point = 'Mixed_5c' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(352), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d( + net, depth(192), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(320), [3, 3], + scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d( + net, depth(192), [1, 1], + weights_initializer=trunc_normal(0.09), + scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(224), [3, 3], + scope='Conv2d_0b_3x3') + branch_2 = slim.conv2d(branch_2, depth(224), [3, 3], + scope='Conv2d_0c_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.max_pool2d(net, [3, 3], scope='MaxPool_0a_3x3') + branch_3 = slim.conv2d( + branch_3, depth(128), [1, 1], + weights_initializer=trunc_normal(0.1), + scope='Conv2d_0b_1x1') + net = tf.concat( + axis=concat_dim, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + raise ValueError('Unknown final endpoint %s' % final_endpoint) + + +def inception_v2(inputs, + num_classes=1000, + is_training=True, + dropout_keep_prob=0.8, + min_depth=16, + depth_multiplier=1.0, + prediction_fn=slim.softmax, + spatial_squeeze=True, + reuse=None, + scope='InceptionV2', + global_pool=False): + """Inception v2 model for classification. + + Constructs an Inception v2 network for classification as described in + http://arxiv.org/abs/1502.03167. + + The default image size used to train this network is 224x224. + + Args: + inputs: a tensor of shape [batch_size, height, width, channels]. + num_classes: number of predicted classes. If 0 or None, the logits layer + is omitted and the input features to the logits layer (before dropout) + are returned instead. + is_training: whether is training or not. + dropout_keep_prob: the percentage of activation values that are retained. + min_depth: Minimum depth value (number of channels) for all convolution ops. + Enforced when depth_multiplier < 1, and not an active constraint when + depth_multiplier >= 1. + depth_multiplier: Float multiplier for the depth (number of channels) + for all convolution ops. The value must be greater than zero. Typical + usage will be to set this value in (0, 1) to reduce the number of + parameters or computation cost of the model. + prediction_fn: a function to get predictions out of logits. + spatial_squeeze: if True, logits is of shape [B, C], if false logits is of + shape [B, 1, 1, C], where B is batch_size and C is number of classes. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + global_pool: Optional boolean flag to control the avgpooling before the + logits layer. If false or unset, pooling is done with a fixed window + that reduces default-sized inputs to 1x1, while larger inputs lead to + larger outputs. If true, any input size is pooled down to 1x1. + + Returns: + net: a Tensor with the logits (pre-softmax activations) if num_classes + is a non-zero integer, or the non-dropped-out input to the logits layer + if num_classes is 0 or None. + end_points: a dictionary from components of the network to the corresponding + activation. + + Raises: + ValueError: if final_endpoint is not set to one of the predefined values, + or depth_multiplier <= 0 + """ + if depth_multiplier <= 0: + raise ValueError('depth_multiplier is not greater than zero.') + + # Final pooling and prediction + with tf.variable_scope(scope, 'InceptionV2', [inputs], reuse=reuse) as scope: + with slim.arg_scope([slim.batch_norm, slim.dropout], + is_training=is_training): + net, end_points = inception_v2_base( + inputs, scope=scope, min_depth=min_depth, + depth_multiplier=depth_multiplier) + with tf.variable_scope('Logits'): + if global_pool: + # Global average pooling. + net = tf.reduce_mean(net, [1, 2], keep_dims=True, name='global_pool') + end_points['global_pool'] = net + else: + # Pooling with a fixed kernel size. + kernel_size = _reduced_kernel_size_for_small_input(net, [7, 7]) + net = slim.avg_pool2d(net, kernel_size, padding='VALID', + scope='AvgPool_1a_{}x{}'.format(*kernel_size)) + end_points['AvgPool_1a'] = net + if not num_classes: + return net, end_points + # 1 x 1 x 1024 + net = slim.dropout(net, keep_prob=dropout_keep_prob, scope='Dropout_1b') + logits = slim.conv2d(net, num_classes, [1, 1], activation_fn=None, + normalizer_fn=None, scope='Conv2d_1c_1x1') + if spatial_squeeze: + logits = tf.squeeze(logits, [1, 2], name='SpatialSqueeze') + end_points['Logits'] = logits + end_points['Predictions'] = prediction_fn(logits, scope='Predictions') + return logits, end_points +inception_v2.default_image_size = 224 + + +def _reduced_kernel_size_for_small_input(input_tensor, kernel_size): + """Define kernel size which is automatically reduced for small input. + + If the shape of the input images is unknown at graph construction time this + function assumes that the input images are is large enough. + + Args: + input_tensor: input tensor of size [batch_size, height, width, channels]. + kernel_size: desired kernel size of length 2: [kernel_height, kernel_width] + + Returns: + a tensor with the kernel size. + + TODO(jrru): Make this function work with unknown shapes. Theoretically, this + can be done with the code below. Problems are two-fold: (1) If the shape was + known, it will be lost. (2) inception.slim.ops._two_element_tuple cannot + handle tensors that define the kernel size. + shape = tf.shape(input_tensor) + return = tf.stack([tf.minimum(shape[1], kernel_size[0]), + tf.minimum(shape[2], kernel_size[1])]) + + """ + shape = input_tensor.get_shape().as_list() + if shape[1] is None or shape[2] is None: + kernel_size_out = kernel_size + else: + kernel_size_out = [min(shape[1], kernel_size[0]), + min(shape[2], kernel_size[1])] + return kernel_size_out + + +inception_v2_arg_scope = inception_utils.inception_arg_scope diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v2_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v2_test.py new file mode 100644 index 0000000..0bf03fd --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v2_test.py @@ -0,0 +1,379 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for nets.inception_v2.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import tensorflow as tf + +from nets import inception + +slim = tf.contrib.slim + + +class InceptionV2Test(tf.test.TestCase): + + def testBuildClassificationNetwork(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, end_points = inception.inception_v2(inputs, num_classes) + self.assertTrue(logits.op.name.startswith( + 'InceptionV2/Logits/SpatialSqueeze')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertTrue('Predictions' in end_points) + self.assertListEqual(end_points['Predictions'].get_shape().as_list(), + [batch_size, num_classes]) + + def testBuildPreLogitsNetwork(self): + batch_size = 5 + height, width = 224, 224 + num_classes = None + + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, end_points = inception.inception_v2(inputs, num_classes) + self.assertTrue(net.op.name.startswith('InceptionV2/Logits/AvgPool')) + self.assertListEqual(net.get_shape().as_list(), [batch_size, 1, 1, 1024]) + self.assertFalse('Logits' in end_points) + self.assertFalse('Predictions' in end_points) + + def testBuildBaseNetwork(self): + batch_size = 5 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + mixed_5c, end_points = inception.inception_v2_base(inputs) + self.assertTrue(mixed_5c.op.name.startswith('InceptionV2/Mixed_5c')) + self.assertListEqual(mixed_5c.get_shape().as_list(), + [batch_size, 7, 7, 1024]) + expected_endpoints = ['Mixed_3b', 'Mixed_3c', 'Mixed_4a', 'Mixed_4b', + 'Mixed_4c', 'Mixed_4d', 'Mixed_4e', 'Mixed_5a', + 'Mixed_5b', 'Mixed_5c', 'Conv2d_1a_7x7', + 'MaxPool_2a_3x3', 'Conv2d_2b_1x1', 'Conv2d_2c_3x3', + 'MaxPool_3a_3x3'] + self.assertItemsEqual(end_points.keys(), expected_endpoints) + + def testBuildOnlyUptoFinalEndpoint(self): + batch_size = 5 + height, width = 224, 224 + endpoints = ['Conv2d_1a_7x7', 'MaxPool_2a_3x3', 'Conv2d_2b_1x1', + 'Conv2d_2c_3x3', 'MaxPool_3a_3x3', 'Mixed_3b', 'Mixed_3c', + 'Mixed_4a', 'Mixed_4b', 'Mixed_4c', 'Mixed_4d', 'Mixed_4e', + 'Mixed_5a', 'Mixed_5b', 'Mixed_5c'] + for index, endpoint in enumerate(endpoints): + with tf.Graph().as_default(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + out_tensor, end_points = inception.inception_v2_base( + inputs, final_endpoint=endpoint) + self.assertTrue(out_tensor.op.name.startswith( + 'InceptionV2/' + endpoint)) + self.assertItemsEqual(endpoints[:index+1], end_points.keys()) + + def testBuildAndCheckAllEndPointsUptoMixed5c(self): + batch_size = 5 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_v2_base(inputs, + final_endpoint='Mixed_5c') + endpoints_shapes = {'Mixed_3b': [batch_size, 28, 28, 256], + 'Mixed_3c': [batch_size, 28, 28, 320], + 'Mixed_4a': [batch_size, 14, 14, 576], + 'Mixed_4b': [batch_size, 14, 14, 576], + 'Mixed_4c': [batch_size, 14, 14, 576], + 'Mixed_4d': [batch_size, 14, 14, 576], + 'Mixed_4e': [batch_size, 14, 14, 576], + 'Mixed_5a': [batch_size, 7, 7, 1024], + 'Mixed_5b': [batch_size, 7, 7, 1024], + 'Mixed_5c': [batch_size, 7, 7, 1024], + 'Conv2d_1a_7x7': [batch_size, 112, 112, 64], + 'MaxPool_2a_3x3': [batch_size, 56, 56, 64], + 'Conv2d_2b_1x1': [batch_size, 56, 56, 64], + 'Conv2d_2c_3x3': [batch_size, 56, 56, 192], + 'MaxPool_3a_3x3': [batch_size, 28, 28, 192]} + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name in endpoints_shapes: + expected_shape = endpoints_shapes[endpoint_name] + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testModelHasExpectedNumberOfParameters(self): + batch_size = 5 + height, width = 224, 224 + inputs = tf.random_uniform((batch_size, height, width, 3)) + with slim.arg_scope(inception.inception_v2_arg_scope()): + inception.inception_v2_base(inputs) + total_params, _ = slim.model_analyzer.analyze_vars( + slim.get_model_variables()) + self.assertAlmostEqual(10173112, total_params) + + def testBuildEndPointsWithDepthMultiplierLessThanOne(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_v2(inputs, num_classes) + + endpoint_keys = [key for key in end_points.keys() + if key.startswith('Mixed') or key.startswith('Conv')] + + _, end_points_with_multiplier = inception.inception_v2( + inputs, num_classes, scope='depth_multiplied_net', + depth_multiplier=0.5) + + for key in endpoint_keys: + original_depth = end_points[key].get_shape().as_list()[3] + new_depth = end_points_with_multiplier[key].get_shape().as_list()[3] + self.assertEqual(0.5 * original_depth, new_depth) + + def testBuildEndPointsWithDepthMultiplierGreaterThanOne(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_v2(inputs, num_classes) + + endpoint_keys = [key for key in end_points.keys() + if key.startswith('Mixed') or key.startswith('Conv')] + + _, end_points_with_multiplier = inception.inception_v2( + inputs, num_classes, scope='depth_multiplied_net', + depth_multiplier=2.0) + + for key in endpoint_keys: + original_depth = end_points[key].get_shape().as_list()[3] + new_depth = end_points_with_multiplier[key].get_shape().as_list()[3] + self.assertEqual(2.0 * original_depth, new_depth) + + def testRaiseValueErrorWithInvalidDepthMultiplier(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + with self.assertRaises(ValueError): + _ = inception.inception_v2(inputs, num_classes, depth_multiplier=-0.1) + with self.assertRaises(ValueError): + _ = inception.inception_v2(inputs, num_classes, depth_multiplier=0.0) + + def testBuildEndPointsWithUseSeparableConvolutionFalse(self): + batch_size = 5 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_v2_base(inputs) + + endpoint_keys = [ + key for key in end_points.keys() + if key.startswith('Mixed') or key.startswith('Conv') + ] + + _, end_points_with_replacement = inception.inception_v2_base( + inputs, use_separable_conv=False) + + # The endpoint shapes must be equal to the original shape even when the + # separable convolution is replaced with a normal convolution. + for key in endpoint_keys: + original_shape = end_points[key].get_shape().as_list() + self.assertTrue(key in end_points_with_replacement) + new_shape = end_points_with_replacement[key].get_shape().as_list() + self.assertListEqual(original_shape, new_shape) + + def testBuildEndPointsNCHWDataFormat(self): + batch_size = 5 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_v2_base(inputs) + + endpoint_keys = [ + key for key in end_points.keys() + if key.startswith('Mixed') or key.startswith('Conv') + ] + + inputs_in_nchw = tf.random_uniform((batch_size, 3, height, width)) + _, end_points_with_replacement = inception.inception_v2_base( + inputs_in_nchw, use_separable_conv=False, data_format='NCHW') + + # With the 'NCHW' data format, all endpoint activations have a transposed + # shape from the original shape with the 'NHWC' layout. + for key in endpoint_keys: + transposed_original_shape = tf.transpose( + end_points[key], [0, 3, 1, 2]).get_shape().as_list() + self.assertTrue(key in end_points_with_replacement) + new_shape = end_points_with_replacement[key].get_shape().as_list() + self.assertListEqual(transposed_original_shape, new_shape) + + def testBuildErrorsForDataFormats(self): + batch_size = 5 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + + # 'NCWH' data format is not supported. + with self.assertRaises(ValueError): + _ = inception.inception_v2_base(inputs, data_format='NCWH') + + # 'NCHW' data format is not supported for separable convolution. + with self.assertRaises(ValueError): + _ = inception.inception_v2_base(inputs, data_format='NCHW') + + def testHalfSizeImages(self): + batch_size = 5 + height, width = 112, 112 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, end_points = inception.inception_v2(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionV2/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Mixed_5c'] + self.assertListEqual(pre_pool.get_shape().as_list(), + [batch_size, 4, 4, 1024]) + + def testUnknownImageShape(self): + tf.reset_default_graph() + batch_size = 2 + height, width = 224, 224 + num_classes = 1000 + input_np = np.random.uniform(0, 1, (batch_size, height, width, 3)) + with self.test_session() as sess: + inputs = tf.placeholder(tf.float32, shape=(batch_size, None, None, 3)) + logits, end_points = inception.inception_v2(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionV2/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Mixed_5c'] + feed_dict = {inputs: input_np} + tf.global_variables_initializer().run() + pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict) + self.assertListEqual(list(pre_pool_out.shape), [batch_size, 7, 7, 1024]) + + def testGlobalPoolUnknownImageShape(self): + tf.reset_default_graph() + batch_size = 1 + height, width = 250, 300 + num_classes = 1000 + input_np = np.random.uniform(0, 1, (batch_size, height, width, 3)) + with self.test_session() as sess: + inputs = tf.placeholder(tf.float32, shape=(batch_size, None, None, 3)) + logits, end_points = inception.inception_v2(inputs, num_classes, + global_pool=True) + self.assertTrue(logits.op.name.startswith('InceptionV2/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Mixed_5c'] + feed_dict = {inputs: input_np} + tf.global_variables_initializer().run() + pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict) + self.assertListEqual(list(pre_pool_out.shape), [batch_size, 8, 10, 1024]) + + def testUnknowBatchSize(self): + batch_size = 1 + height, width = 224, 224 + num_classes = 1000 + + inputs = tf.placeholder(tf.float32, (None, height, width, 3)) + logits, _ = inception.inception_v2(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionV2/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [None, num_classes]) + images = tf.random_uniform((batch_size, height, width, 3)) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(logits, {inputs: images.eval()}) + self.assertEquals(output.shape, (batch_size, num_classes)) + + def testEvaluation(self): + batch_size = 2 + height, width = 224, 224 + num_classes = 1000 + + eval_inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = inception.inception_v2(eval_inputs, num_classes, + is_training=False) + predictions = tf.argmax(logits, 1) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (batch_size,)) + + def testTrainEvalWithReuse(self): + train_batch_size = 5 + eval_batch_size = 2 + height, width = 150, 150 + num_classes = 1000 + + train_inputs = tf.random_uniform((train_batch_size, height, width, 3)) + inception.inception_v2(train_inputs, num_classes) + eval_inputs = tf.random_uniform((eval_batch_size, height, width, 3)) + logits, _ = inception.inception_v2(eval_inputs, num_classes, reuse=True) + predictions = tf.argmax(logits, 1) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (eval_batch_size,)) + + def testLogitsNotSqueezed(self): + num_classes = 25 + images = tf.random_uniform([1, 224, 224, 3]) + logits, _ = inception.inception_v2(images, + num_classes=num_classes, + spatial_squeeze=False) + + with self.test_session() as sess: + tf.global_variables_initializer().run() + logits_out = sess.run(logits) + self.assertListEqual(list(logits_out.shape), [1, 1, 1, num_classes]) + + def testNoBatchNormScaleByDefault(self): + height, width = 224, 224 + num_classes = 1000 + inputs = tf.placeholder(tf.float32, (1, height, width, 3)) + with slim.arg_scope(inception.inception_v2_arg_scope()): + inception.inception_v2(inputs, num_classes, is_training=False) + + self.assertEqual(tf.global_variables('.*/BatchNorm/gamma:0$'), []) + + def testBatchNormScale(self): + height, width = 224, 224 + num_classes = 1000 + inputs = tf.placeholder(tf.float32, (1, height, width, 3)) + with slim.arg_scope( + inception.inception_v2_arg_scope(batch_norm_scale=True)): + inception.inception_v2(inputs, num_classes, is_training=False) + + gamma_names = set( + v.op.name for v in tf.global_variables('.*/BatchNorm/gamma:0$')) + self.assertGreater(len(gamma_names), 0) + for v in tf.global_variables('.*/BatchNorm/moving_mean:0$'): + self.assertIn(v.op.name[:-len('moving_mean')] + 'gamma', gamma_names) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v3.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v3.py new file mode 100644 index 0000000..1221779 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v3.py @@ -0,0 +1,579 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains the definition for inception v3 classification network.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import inception_utils + +slim = tf.contrib.slim +trunc_normal = lambda stddev: tf.truncated_normal_initializer(0.0, stddev) + + +def inception_v3_base(inputs, + final_endpoint='Mixed_7c', + min_depth=16, + depth_multiplier=1.0, + scope=None): + """Inception model from http://arxiv.org/abs/1512.00567. + + Constructs an Inception v3 network from inputs to the given final endpoint. + This method can construct the network up to the final inception block + Mixed_7c. + + Note that the names of the layers in the paper do not correspond to the names + of the endpoints registered by this function although they build the same + network. + + Here is a mapping from the old_names to the new names: + Old name | New name + ======================================= + conv0 | Conv2d_1a_3x3 + conv1 | Conv2d_2a_3x3 + conv2 | Conv2d_2b_3x3 + pool1 | MaxPool_3a_3x3 + conv3 | Conv2d_3b_1x1 + conv4 | Conv2d_4a_3x3 + pool2 | MaxPool_5a_3x3 + mixed_35x35x256a | Mixed_5b + mixed_35x35x288a | Mixed_5c + mixed_35x35x288b | Mixed_5d + mixed_17x17x768a | Mixed_6a + mixed_17x17x768b | Mixed_6b + mixed_17x17x768c | Mixed_6c + mixed_17x17x768d | Mixed_6d + mixed_17x17x768e | Mixed_6e + mixed_8x8x1280a | Mixed_7a + mixed_8x8x2048a | Mixed_7b + mixed_8x8x2048b | Mixed_7c + + Args: + inputs: a tensor of size [batch_size, height, width, channels]. + final_endpoint: specifies the endpoint to construct the network up to. It + can be one of ['Conv2d_1a_3x3', 'Conv2d_2a_3x3', 'Conv2d_2b_3x3', + 'MaxPool_3a_3x3', 'Conv2d_3b_1x1', 'Conv2d_4a_3x3', 'MaxPool_5a_3x3', + 'Mixed_5b', 'Mixed_5c', 'Mixed_5d', 'Mixed_6a', 'Mixed_6b', 'Mixed_6c', + 'Mixed_6d', 'Mixed_6e', 'Mixed_7a', 'Mixed_7b', 'Mixed_7c']. + min_depth: Minimum depth value (number of channels) for all convolution ops. + Enforced when depth_multiplier < 1, and not an active constraint when + depth_multiplier >= 1. + depth_multiplier: Float multiplier for the depth (number of channels) + for all convolution ops. The value must be greater than zero. Typical + usage will be to set this value in (0, 1) to reduce the number of + parameters or computation cost of the model. + scope: Optional variable_scope. + + Returns: + tensor_out: output tensor corresponding to the final_endpoint. + end_points: a set of activations for external use, for example summaries or + losses. + + Raises: + ValueError: if final_endpoint is not set to one of the predefined values, + or depth_multiplier <= 0 + """ + # end_points will collect relevant activations for external use, for example + # summaries or losses. + end_points = {} + + if depth_multiplier <= 0: + raise ValueError('depth_multiplier is not greater than zero.') + depth = lambda d: max(int(d * depth_multiplier), min_depth) + + with tf.variable_scope(scope, 'InceptionV3', [inputs]): + with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d], + stride=1, padding='VALID'): + # 299 x 299 x 3 + end_point = 'Conv2d_1a_3x3' + net = slim.conv2d(inputs, depth(32), [3, 3], stride=2, scope=end_point) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 149 x 149 x 32 + end_point = 'Conv2d_2a_3x3' + net = slim.conv2d(net, depth(32), [3, 3], scope=end_point) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 147 x 147 x 32 + end_point = 'Conv2d_2b_3x3' + net = slim.conv2d(net, depth(64), [3, 3], padding='SAME', scope=end_point) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 147 x 147 x 64 + end_point = 'MaxPool_3a_3x3' + net = slim.max_pool2d(net, [3, 3], stride=2, scope=end_point) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 73 x 73 x 64 + end_point = 'Conv2d_3b_1x1' + net = slim.conv2d(net, depth(80), [1, 1], scope=end_point) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 73 x 73 x 80. + end_point = 'Conv2d_4a_3x3' + net = slim.conv2d(net, depth(192), [3, 3], scope=end_point) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 71 x 71 x 192. + end_point = 'MaxPool_5a_3x3' + net = slim.max_pool2d(net, [3, 3], stride=2, scope=end_point) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # 35 x 35 x 192. + + # Inception blocks + with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d], + stride=1, padding='SAME'): + # mixed: 35 x 35 x 256. + end_point = 'Mixed_5b' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(64), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, depth(48), [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(64), [5, 5], + scope='Conv2d_0b_5x5') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, depth(64), [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(96), [3, 3], + scope='Conv2d_0b_3x3') + branch_2 = slim.conv2d(branch_2, depth(96), [3, 3], + scope='Conv2d_0c_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, depth(32), [1, 1], + scope='Conv2d_0b_1x1') + net = tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + + # mixed_1: 35 x 35 x 288. + end_point = 'Mixed_5c' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(64), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, depth(48), [1, 1], scope='Conv2d_0b_1x1') + branch_1 = slim.conv2d(branch_1, depth(64), [5, 5], + scope='Conv_1_0c_5x5') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, depth(64), [1, 1], + scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(96), [3, 3], + scope='Conv2d_0b_3x3') + branch_2 = slim.conv2d(branch_2, depth(96), [3, 3], + scope='Conv2d_0c_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, depth(64), [1, 1], + scope='Conv2d_0b_1x1') + net = tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + + # mixed_2: 35 x 35 x 288. + end_point = 'Mixed_5d' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(64), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, depth(48), [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(64), [5, 5], + scope='Conv2d_0b_5x5') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, depth(64), [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(96), [3, 3], + scope='Conv2d_0b_3x3') + branch_2 = slim.conv2d(branch_2, depth(96), [3, 3], + scope='Conv2d_0c_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, depth(64), [1, 1], + scope='Conv2d_0b_1x1') + net = tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + + # mixed_3: 17 x 17 x 768. + end_point = 'Mixed_6a' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(384), [3, 3], stride=2, + padding='VALID', scope='Conv2d_1a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, depth(64), [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(96), [3, 3], + scope='Conv2d_0b_3x3') + branch_1 = slim.conv2d(branch_1, depth(96), [3, 3], stride=2, + padding='VALID', scope='Conv2d_1a_1x1') + with tf.variable_scope('Branch_2'): + branch_2 = slim.max_pool2d(net, [3, 3], stride=2, padding='VALID', + scope='MaxPool_1a_3x3') + net = tf.concat(axis=3, values=[branch_0, branch_1, branch_2]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + + # mixed4: 17 x 17 x 768. + end_point = 'Mixed_6b' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, depth(128), [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(128), [1, 7], + scope='Conv2d_0b_1x7') + branch_1 = slim.conv2d(branch_1, depth(192), [7, 1], + scope='Conv2d_0c_7x1') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, depth(128), [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(128), [7, 1], + scope='Conv2d_0b_7x1') + branch_2 = slim.conv2d(branch_2, depth(128), [1, 7], + scope='Conv2d_0c_1x7') + branch_2 = slim.conv2d(branch_2, depth(128), [7, 1], + scope='Conv2d_0d_7x1') + branch_2 = slim.conv2d(branch_2, depth(192), [1, 7], + scope='Conv2d_0e_1x7') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, depth(192), [1, 1], + scope='Conv2d_0b_1x1') + net = tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + + # mixed_5: 17 x 17 x 768. + end_point = 'Mixed_6c' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, depth(160), [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(160), [1, 7], + scope='Conv2d_0b_1x7') + branch_1 = slim.conv2d(branch_1, depth(192), [7, 1], + scope='Conv2d_0c_7x1') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, depth(160), [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(160), [7, 1], + scope='Conv2d_0b_7x1') + branch_2 = slim.conv2d(branch_2, depth(160), [1, 7], + scope='Conv2d_0c_1x7') + branch_2 = slim.conv2d(branch_2, depth(160), [7, 1], + scope='Conv2d_0d_7x1') + branch_2 = slim.conv2d(branch_2, depth(192), [1, 7], + scope='Conv2d_0e_1x7') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, depth(192), [1, 1], + scope='Conv2d_0b_1x1') + net = tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # mixed_6: 17 x 17 x 768. + end_point = 'Mixed_6d' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, depth(160), [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(160), [1, 7], + scope='Conv2d_0b_1x7') + branch_1 = slim.conv2d(branch_1, depth(192), [7, 1], + scope='Conv2d_0c_7x1') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, depth(160), [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(160), [7, 1], + scope='Conv2d_0b_7x1') + branch_2 = slim.conv2d(branch_2, depth(160), [1, 7], + scope='Conv2d_0c_1x7') + branch_2 = slim.conv2d(branch_2, depth(160), [7, 1], + scope='Conv2d_0d_7x1') + branch_2 = slim.conv2d(branch_2, depth(192), [1, 7], + scope='Conv2d_0e_1x7') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, depth(192), [1, 1], + scope='Conv2d_0b_1x1') + net = tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + + # mixed_7: 17 x 17 x 768. + end_point = 'Mixed_6e' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(192), [1, 7], + scope='Conv2d_0b_1x7') + branch_1 = slim.conv2d(branch_1, depth(192), [7, 1], + scope='Conv2d_0c_7x1') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, depth(192), [7, 1], + scope='Conv2d_0b_7x1') + branch_2 = slim.conv2d(branch_2, depth(192), [1, 7], + scope='Conv2d_0c_1x7') + branch_2 = slim.conv2d(branch_2, depth(192), [7, 1], + scope='Conv2d_0d_7x1') + branch_2 = slim.conv2d(branch_2, depth(192), [1, 7], + scope='Conv2d_0e_1x7') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, depth(192), [1, 1], + scope='Conv2d_0b_1x1') + net = tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + + # mixed_8: 8 x 8 x 1280. + end_point = 'Mixed_7a' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1') + branch_0 = slim.conv2d(branch_0, depth(320), [3, 3], stride=2, + padding='VALID', scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, depth(192), [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, depth(192), [1, 7], + scope='Conv2d_0b_1x7') + branch_1 = slim.conv2d(branch_1, depth(192), [7, 1], + scope='Conv2d_0c_7x1') + branch_1 = slim.conv2d(branch_1, depth(192), [3, 3], stride=2, + padding='VALID', scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.max_pool2d(net, [3, 3], stride=2, padding='VALID', + scope='MaxPool_1a_3x3') + net = tf.concat(axis=3, values=[branch_0, branch_1, branch_2]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + # mixed_9: 8 x 8 x 2048. + end_point = 'Mixed_7b' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(320), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, depth(384), [1, 1], scope='Conv2d_0a_1x1') + branch_1 = tf.concat(axis=3, values=[ + slim.conv2d(branch_1, depth(384), [1, 3], scope='Conv2d_0b_1x3'), + slim.conv2d(branch_1, depth(384), [3, 1], scope='Conv2d_0b_3x1')]) + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, depth(448), [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d( + branch_2, depth(384), [3, 3], scope='Conv2d_0b_3x3') + branch_2 = tf.concat(axis=3, values=[ + slim.conv2d(branch_2, depth(384), [1, 3], scope='Conv2d_0c_1x3'), + slim.conv2d(branch_2, depth(384), [3, 1], scope='Conv2d_0d_3x1')]) + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d( + branch_3, depth(192), [1, 1], scope='Conv2d_0b_1x1') + net = tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + + # mixed_10: 8 x 8 x 2048. + end_point = 'Mixed_7c' + with tf.variable_scope(end_point): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, depth(320), [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, depth(384), [1, 1], scope='Conv2d_0a_1x1') + branch_1 = tf.concat(axis=3, values=[ + slim.conv2d(branch_1, depth(384), [1, 3], scope='Conv2d_0b_1x3'), + slim.conv2d(branch_1, depth(384), [3, 1], scope='Conv2d_0c_3x1')]) + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(net, depth(448), [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d( + branch_2, depth(384), [3, 3], scope='Conv2d_0b_3x3') + branch_2 = tf.concat(axis=3, values=[ + slim.conv2d(branch_2, depth(384), [1, 3], scope='Conv2d_0c_1x3'), + slim.conv2d(branch_2, depth(384), [3, 1], scope='Conv2d_0d_3x1')]) + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(net, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d( + branch_3, depth(192), [1, 1], scope='Conv2d_0b_1x1') + net = tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + end_points[end_point] = net + if end_point == final_endpoint: return net, end_points + raise ValueError('Unknown final endpoint %s' % final_endpoint) + + +def inception_v3(inputs, + num_classes=1000, + is_training=True, + dropout_keep_prob=0.8, + min_depth=16, + depth_multiplier=1.0, + prediction_fn=slim.softmax, + spatial_squeeze=True, + reuse=None, + create_aux_logits=True, + scope='InceptionV3', + global_pool=False): + """Inception model from http://arxiv.org/abs/1512.00567. + + "Rethinking the Inception Architecture for Computer Vision" + + Christian Szegedy, Vincent Vanhoucke, Sergey Ioffe, Jonathon Shlens, + Zbigniew Wojna. + + With the default arguments this method constructs the exact model defined in + the paper. However, one can experiment with variations of the inception_v3 + network by changing arguments dropout_keep_prob, min_depth and + depth_multiplier. + + The default image size used to train this network is 299x299. + + Args: + inputs: a tensor of size [batch_size, height, width, channels]. + num_classes: number of predicted classes. If 0 or None, the logits layer + is omitted and the input features to the logits layer (before dropout) + are returned instead. + is_training: whether is training or not. + dropout_keep_prob: the percentage of activation values that are retained. + min_depth: Minimum depth value (number of channels) for all convolution ops. + Enforced when depth_multiplier < 1, and not an active constraint when + depth_multiplier >= 1. + depth_multiplier: Float multiplier for the depth (number of channels) + for all convolution ops. The value must be greater than zero. Typical + usage will be to set this value in (0, 1) to reduce the number of + parameters or computation cost of the model. + prediction_fn: a function to get predictions out of logits. + spatial_squeeze: if True, logits is of shape [B, C], if false logits is of + shape [B, 1, 1, C], where B is batch_size and C is number of classes. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + create_aux_logits: Whether to create the auxiliary logits. + scope: Optional variable_scope. + global_pool: Optional boolean flag to control the avgpooling before the + logits layer. If false or unset, pooling is done with a fixed window + that reduces default-sized inputs to 1x1, while larger inputs lead to + larger outputs. If true, any input size is pooled down to 1x1. + + Returns: + net: a Tensor with the logits (pre-softmax activations) if num_classes + is a non-zero integer, or the non-dropped-out input to the logits layer + if num_classes is 0 or None. + end_points: a dictionary from components of the network to the corresponding + activation. + + Raises: + ValueError: if 'depth_multiplier' is less than or equal to zero. + """ + if depth_multiplier <= 0: + raise ValueError('depth_multiplier is not greater than zero.') + depth = lambda d: max(int(d * depth_multiplier), min_depth) + + with tf.variable_scope(scope, 'InceptionV3', [inputs], reuse=reuse) as scope: + with slim.arg_scope([slim.batch_norm, slim.dropout], + is_training=is_training): + net, end_points = inception_v3_base( + inputs, scope=scope, min_depth=min_depth, + depth_multiplier=depth_multiplier) + + # Auxiliary Head logits + if create_aux_logits and num_classes: + with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d], + stride=1, padding='SAME'): + aux_logits = end_points['Mixed_6e'] + with tf.variable_scope('AuxLogits'): + aux_logits = slim.avg_pool2d( + aux_logits, [5, 5], stride=3, padding='VALID', + scope='AvgPool_1a_5x5') + aux_logits = slim.conv2d(aux_logits, depth(128), [1, 1], + scope='Conv2d_1b_1x1') + + # Shape of feature map before the final layer. + kernel_size = _reduced_kernel_size_for_small_input( + aux_logits, [5, 5]) + aux_logits = slim.conv2d( + aux_logits, depth(768), kernel_size, + weights_initializer=trunc_normal(0.01), + padding='VALID', scope='Conv2d_2a_{}x{}'.format(*kernel_size)) + aux_logits = slim.conv2d( + aux_logits, num_classes, [1, 1], activation_fn=None, + normalizer_fn=None, weights_initializer=trunc_normal(0.001), + scope='Conv2d_2b_1x1') + if spatial_squeeze: + aux_logits = tf.squeeze(aux_logits, [1, 2], name='SpatialSqueeze') + end_points['AuxLogits'] = aux_logits + + # Final pooling and prediction + with tf.variable_scope('Logits'): + if global_pool: + # Global average pooling. + net = tf.reduce_mean(net, [1, 2], keep_dims=True, name='GlobalPool') + end_points['global_pool'] = net + else: + # Pooling with a fixed kernel size. + kernel_size = _reduced_kernel_size_for_small_input(net, [8, 8]) + net = slim.avg_pool2d(net, kernel_size, padding='VALID', + scope='AvgPool_1a_{}x{}'.format(*kernel_size)) + end_points['AvgPool_1a'] = net + if not num_classes: + return net, end_points + # 1 x 1 x 2048 + net = slim.dropout(net, keep_prob=dropout_keep_prob, scope='Dropout_1b') + end_points['PreLogits'] = net + # 2048 + logits = slim.conv2d(net, num_classes, [1, 1], activation_fn=None, + normalizer_fn=None, scope='Conv2d_1c_1x1') + if spatial_squeeze: + logits = tf.squeeze(logits, [1, 2], name='SpatialSqueeze') + # 1000 + end_points['Logits'] = logits + end_points['Predictions'] = prediction_fn(logits, scope='Predictions') + return logits, end_points +inception_v3.default_image_size = 299 + + +def _reduced_kernel_size_for_small_input(input_tensor, kernel_size): + """Define kernel size which is automatically reduced for small input. + + If the shape of the input images is unknown at graph construction time this + function assumes that the input images are is large enough. + + Args: + input_tensor: input tensor of size [batch_size, height, width, channels]. + kernel_size: desired kernel size of length 2: [kernel_height, kernel_width] + + Returns: + a tensor with the kernel size. + + TODO(jrru): Make this function work with unknown shapes. Theoretically, this + can be done with the code below. Problems are two-fold: (1) If the shape was + known, it will be lost. (2) inception.slim.ops._two_element_tuple cannot + handle tensors that define the kernel size. + shape = tf.shape(input_tensor) + return = tf.stack([tf.minimum(shape[1], kernel_size[0]), + tf.minimum(shape[2], kernel_size[1])]) + + """ + shape = input_tensor.get_shape().as_list() + if shape[1] is None or shape[2] is None: + kernel_size_out = kernel_size + else: + kernel_size_out = [min(shape[1], kernel_size[0]), + min(shape[2], kernel_size[1])] + return kernel_size_out + + +inception_v3_arg_scope = inception_utils.inception_arg_scope diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v3_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v3_test.py new file mode 100644 index 0000000..3d81aab --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v3_test.py @@ -0,0 +1,346 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for nets.inception_v1.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import tensorflow as tf + +from nets import inception + +slim = tf.contrib.slim + + +class InceptionV3Test(tf.test.TestCase): + + def testBuildClassificationNetwork(self): + batch_size = 5 + height, width = 299, 299 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, end_points = inception.inception_v3(inputs, num_classes) + self.assertTrue(logits.op.name.startswith( + 'InceptionV3/Logits/SpatialSqueeze')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertTrue('Predictions' in end_points) + self.assertListEqual(end_points['Predictions'].get_shape().as_list(), + [batch_size, num_classes]) + + def testBuildPreLogitsNetwork(self): + batch_size = 5 + height, width = 299, 299 + num_classes = None + + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, end_points = inception.inception_v3(inputs, num_classes) + self.assertTrue(net.op.name.startswith('InceptionV3/Logits/AvgPool')) + self.assertListEqual(net.get_shape().as_list(), [batch_size, 1, 1, 2048]) + self.assertFalse('Logits' in end_points) + self.assertFalse('Predictions' in end_points) + + def testBuildBaseNetwork(self): + batch_size = 5 + height, width = 299, 299 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + final_endpoint, end_points = inception.inception_v3_base(inputs) + self.assertTrue(final_endpoint.op.name.startswith( + 'InceptionV3/Mixed_7c')) + self.assertListEqual(final_endpoint.get_shape().as_list(), + [batch_size, 8, 8, 2048]) + expected_endpoints = ['Conv2d_1a_3x3', 'Conv2d_2a_3x3', 'Conv2d_2b_3x3', + 'MaxPool_3a_3x3', 'Conv2d_3b_1x1', 'Conv2d_4a_3x3', + 'MaxPool_5a_3x3', 'Mixed_5b', 'Mixed_5c', 'Mixed_5d', + 'Mixed_6a', 'Mixed_6b', 'Mixed_6c', 'Mixed_6d', + 'Mixed_6e', 'Mixed_7a', 'Mixed_7b', 'Mixed_7c'] + self.assertItemsEqual(end_points.keys(), expected_endpoints) + + def testBuildOnlyUptoFinalEndpoint(self): + batch_size = 5 + height, width = 299, 299 + endpoints = ['Conv2d_1a_3x3', 'Conv2d_2a_3x3', 'Conv2d_2b_3x3', + 'MaxPool_3a_3x3', 'Conv2d_3b_1x1', 'Conv2d_4a_3x3', + 'MaxPool_5a_3x3', 'Mixed_5b', 'Mixed_5c', 'Mixed_5d', + 'Mixed_6a', 'Mixed_6b', 'Mixed_6c', 'Mixed_6d', + 'Mixed_6e', 'Mixed_7a', 'Mixed_7b', 'Mixed_7c'] + + for index, endpoint in enumerate(endpoints): + with tf.Graph().as_default(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + out_tensor, end_points = inception.inception_v3_base( + inputs, final_endpoint=endpoint) + self.assertTrue(out_tensor.op.name.startswith( + 'InceptionV3/' + endpoint)) + self.assertItemsEqual(endpoints[:index+1], end_points.keys()) + + def testBuildAndCheckAllEndPointsUptoMixed7c(self): + batch_size = 5 + height, width = 299, 299 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_v3_base( + inputs, final_endpoint='Mixed_7c') + endpoints_shapes = {'Conv2d_1a_3x3': [batch_size, 149, 149, 32], + 'Conv2d_2a_3x3': [batch_size, 147, 147, 32], + 'Conv2d_2b_3x3': [batch_size, 147, 147, 64], + 'MaxPool_3a_3x3': [batch_size, 73, 73, 64], + 'Conv2d_3b_1x1': [batch_size, 73, 73, 80], + 'Conv2d_4a_3x3': [batch_size, 71, 71, 192], + 'MaxPool_5a_3x3': [batch_size, 35, 35, 192], + 'Mixed_5b': [batch_size, 35, 35, 256], + 'Mixed_5c': [batch_size, 35, 35, 288], + 'Mixed_5d': [batch_size, 35, 35, 288], + 'Mixed_6a': [batch_size, 17, 17, 768], + 'Mixed_6b': [batch_size, 17, 17, 768], + 'Mixed_6c': [batch_size, 17, 17, 768], + 'Mixed_6d': [batch_size, 17, 17, 768], + 'Mixed_6e': [batch_size, 17, 17, 768], + 'Mixed_7a': [batch_size, 8, 8, 1280], + 'Mixed_7b': [batch_size, 8, 8, 2048], + 'Mixed_7c': [batch_size, 8, 8, 2048]} + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name in endpoints_shapes: + expected_shape = endpoints_shapes[endpoint_name] + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testModelHasExpectedNumberOfParameters(self): + batch_size = 5 + height, width = 299, 299 + inputs = tf.random_uniform((batch_size, height, width, 3)) + with slim.arg_scope(inception.inception_v3_arg_scope()): + inception.inception_v3_base(inputs) + total_params, _ = slim.model_analyzer.analyze_vars( + slim.get_model_variables()) + self.assertAlmostEqual(21802784, total_params) + + def testBuildEndPoints(self): + batch_size = 5 + height, width = 299, 299 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_v3(inputs, num_classes) + self.assertTrue('Logits' in end_points) + logits = end_points['Logits'] + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertTrue('AuxLogits' in end_points) + aux_logits = end_points['AuxLogits'] + self.assertListEqual(aux_logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertTrue('Mixed_7c' in end_points) + pre_pool = end_points['Mixed_7c'] + self.assertListEqual(pre_pool.get_shape().as_list(), + [batch_size, 8, 8, 2048]) + self.assertTrue('PreLogits' in end_points) + pre_logits = end_points['PreLogits'] + self.assertListEqual(pre_logits.get_shape().as_list(), + [batch_size, 1, 1, 2048]) + + def testBuildEndPointsWithDepthMultiplierLessThanOne(self): + batch_size = 5 + height, width = 299, 299 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_v3(inputs, num_classes) + + endpoint_keys = [key for key in end_points.keys() + if key.startswith('Mixed') or key.startswith('Conv')] + + _, end_points_with_multiplier = inception.inception_v3( + inputs, num_classes, scope='depth_multiplied_net', + depth_multiplier=0.5) + + for key in endpoint_keys: + original_depth = end_points[key].get_shape().as_list()[3] + new_depth = end_points_with_multiplier[key].get_shape().as_list()[3] + self.assertEqual(0.5 * original_depth, new_depth) + + def testBuildEndPointsWithDepthMultiplierGreaterThanOne(self): + batch_size = 5 + height, width = 299, 299 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_v3(inputs, num_classes) + + endpoint_keys = [key for key in end_points.keys() + if key.startswith('Mixed') or key.startswith('Conv')] + + _, end_points_with_multiplier = inception.inception_v3( + inputs, num_classes, scope='depth_multiplied_net', + depth_multiplier=2.0) + + for key in endpoint_keys: + original_depth = end_points[key].get_shape().as_list()[3] + new_depth = end_points_with_multiplier[key].get_shape().as_list()[3] + self.assertEqual(2.0 * original_depth, new_depth) + + def testRaiseValueErrorWithInvalidDepthMultiplier(self): + batch_size = 5 + height, width = 299, 299 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + with self.assertRaises(ValueError): + _ = inception.inception_v3(inputs, num_classes, depth_multiplier=-0.1) + with self.assertRaises(ValueError): + _ = inception.inception_v3(inputs, num_classes, depth_multiplier=0.0) + + def testHalfSizeImages(self): + batch_size = 5 + height, width = 150, 150 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, end_points = inception.inception_v3(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionV3/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Mixed_7c'] + self.assertListEqual(pre_pool.get_shape().as_list(), + [batch_size, 3, 3, 2048]) + + def testUnknownImageShape(self): + tf.reset_default_graph() + batch_size = 2 + height, width = 299, 299 + num_classes = 1000 + input_np = np.random.uniform(0, 1, (batch_size, height, width, 3)) + with self.test_session() as sess: + inputs = tf.placeholder(tf.float32, shape=(batch_size, None, None, 3)) + logits, end_points = inception.inception_v3(inputs, num_classes) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Mixed_7c'] + feed_dict = {inputs: input_np} + tf.global_variables_initializer().run() + pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict) + self.assertListEqual(list(pre_pool_out.shape), [batch_size, 8, 8, 2048]) + + def testGlobalPoolUnknownImageShape(self): + tf.reset_default_graph() + batch_size = 1 + height, width = 330, 400 + num_classes = 1000 + input_np = np.random.uniform(0, 1, (batch_size, height, width, 3)) + with self.test_session() as sess: + inputs = tf.placeholder(tf.float32, shape=(batch_size, None, None, 3)) + logits, end_points = inception.inception_v3(inputs, num_classes, + global_pool=True) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Mixed_7c'] + feed_dict = {inputs: input_np} + tf.global_variables_initializer().run() + pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict) + self.assertListEqual(list(pre_pool_out.shape), [batch_size, 8, 11, 2048]) + + def testUnknowBatchSize(self): + batch_size = 1 + height, width = 299, 299 + num_classes = 1000 + + inputs = tf.placeholder(tf.float32, (None, height, width, 3)) + logits, _ = inception.inception_v3(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionV3/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [None, num_classes]) + images = tf.random_uniform((batch_size, height, width, 3)) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(logits, {inputs: images.eval()}) + self.assertEquals(output.shape, (batch_size, num_classes)) + + def testEvaluation(self): + batch_size = 2 + height, width = 299, 299 + num_classes = 1000 + + eval_inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = inception.inception_v3(eval_inputs, num_classes, + is_training=False) + predictions = tf.argmax(logits, 1) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (batch_size,)) + + def testTrainEvalWithReuse(self): + train_batch_size = 5 + eval_batch_size = 2 + height, width = 150, 150 + num_classes = 1000 + + train_inputs = tf.random_uniform((train_batch_size, height, width, 3)) + inception.inception_v3(train_inputs, num_classes) + eval_inputs = tf.random_uniform((eval_batch_size, height, width, 3)) + logits, _ = inception.inception_v3(eval_inputs, num_classes, + is_training=False, reuse=True) + predictions = tf.argmax(logits, 1) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (eval_batch_size,)) + + def testLogitsNotSqueezed(self): + num_classes = 25 + images = tf.random_uniform([1, 299, 299, 3]) + logits, _ = inception.inception_v3(images, + num_classes=num_classes, + spatial_squeeze=False) + + with self.test_session() as sess: + tf.global_variables_initializer().run() + logits_out = sess.run(logits) + self.assertListEqual(list(logits_out.shape), [1, 1, 1, num_classes]) + + def testNoBatchNormScaleByDefault(self): + height, width = 299, 299 + num_classes = 1000 + inputs = tf.placeholder(tf.float32, (1, height, width, 3)) + with slim.arg_scope(inception.inception_v3_arg_scope()): + inception.inception_v3(inputs, num_classes, is_training=False) + + self.assertEqual(tf.global_variables('.*/BatchNorm/gamma:0$'), []) + + def testBatchNormScale(self): + height, width = 299, 299 + num_classes = 1000 + inputs = tf.placeholder(tf.float32, (1, height, width, 3)) + with slim.arg_scope( + inception.inception_v3_arg_scope(batch_norm_scale=True)): + inception.inception_v3(inputs, num_classes, is_training=False) + + gamma_names = set( + v.op.name for v in tf.global_variables('.*/BatchNorm/gamma:0$')) + self.assertGreater(len(gamma_names), 0) + for v in tf.global_variables('.*/BatchNorm/moving_mean:0$'): + self.assertIn(v.op.name[:-len('moving_mean')] + 'gamma', gamma_names) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v4.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v4.py new file mode 100644 index 0000000..bab406a --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v4.py @@ -0,0 +1,337 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains the definition of the Inception V4 architecture. + +As described in http://arxiv.org/abs/1602.07261. + + Inception-v4, Inception-ResNet and the Impact of Residual Connections + on Learning + Christian Szegedy, Sergey Ioffe, Vincent Vanhoucke, Alex Alemi +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import inception_utils + +slim = tf.contrib.slim + + +def block_inception_a(inputs, scope=None, reuse=None): + """Builds Inception-A block for Inception v4 network.""" + # By default use stride=1 and SAME padding + with slim.arg_scope([slim.conv2d, slim.avg_pool2d, slim.max_pool2d], + stride=1, padding='SAME'): + with tf.variable_scope(scope, 'BlockInceptionA', [inputs], reuse=reuse): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(inputs, 96, [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(inputs, 64, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, 96, [3, 3], scope='Conv2d_0b_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(inputs, 64, [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, 96, [3, 3], scope='Conv2d_0b_3x3') + branch_2 = slim.conv2d(branch_2, 96, [3, 3], scope='Conv2d_0c_3x3') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(inputs, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, 96, [1, 1], scope='Conv2d_0b_1x1') + return tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + + +def block_reduction_a(inputs, scope=None, reuse=None): + """Builds Reduction-A block for Inception v4 network.""" + # By default use stride=1 and SAME padding + with slim.arg_scope([slim.conv2d, slim.avg_pool2d, slim.max_pool2d], + stride=1, padding='SAME'): + with tf.variable_scope(scope, 'BlockReductionA', [inputs], reuse=reuse): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(inputs, 384, [3, 3], stride=2, padding='VALID', + scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(inputs, 192, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, 224, [3, 3], scope='Conv2d_0b_3x3') + branch_1 = slim.conv2d(branch_1, 256, [3, 3], stride=2, + padding='VALID', scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.max_pool2d(inputs, [3, 3], stride=2, padding='VALID', + scope='MaxPool_1a_3x3') + return tf.concat(axis=3, values=[branch_0, branch_1, branch_2]) + + +def block_inception_b(inputs, scope=None, reuse=None): + """Builds Inception-B block for Inception v4 network.""" + # By default use stride=1 and SAME padding + with slim.arg_scope([slim.conv2d, slim.avg_pool2d, slim.max_pool2d], + stride=1, padding='SAME'): + with tf.variable_scope(scope, 'BlockInceptionB', [inputs], reuse=reuse): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(inputs, 384, [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(inputs, 192, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, 224, [1, 7], scope='Conv2d_0b_1x7') + branch_1 = slim.conv2d(branch_1, 256, [7, 1], scope='Conv2d_0c_7x1') + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(inputs, 192, [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, 192, [7, 1], scope='Conv2d_0b_7x1') + branch_2 = slim.conv2d(branch_2, 224, [1, 7], scope='Conv2d_0c_1x7') + branch_2 = slim.conv2d(branch_2, 224, [7, 1], scope='Conv2d_0d_7x1') + branch_2 = slim.conv2d(branch_2, 256, [1, 7], scope='Conv2d_0e_1x7') + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(inputs, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, 128, [1, 1], scope='Conv2d_0b_1x1') + return tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + + +def block_reduction_b(inputs, scope=None, reuse=None): + """Builds Reduction-B block for Inception v4 network.""" + # By default use stride=1 and SAME padding + with slim.arg_scope([slim.conv2d, slim.avg_pool2d, slim.max_pool2d], + stride=1, padding='SAME'): + with tf.variable_scope(scope, 'BlockReductionB', [inputs], reuse=reuse): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(inputs, 192, [1, 1], scope='Conv2d_0a_1x1') + branch_0 = slim.conv2d(branch_0, 192, [3, 3], stride=2, + padding='VALID', scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(inputs, 256, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, 256, [1, 7], scope='Conv2d_0b_1x7') + branch_1 = slim.conv2d(branch_1, 320, [7, 1], scope='Conv2d_0c_7x1') + branch_1 = slim.conv2d(branch_1, 320, [3, 3], stride=2, + padding='VALID', scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_2'): + branch_2 = slim.max_pool2d(inputs, [3, 3], stride=2, padding='VALID', + scope='MaxPool_1a_3x3') + return tf.concat(axis=3, values=[branch_0, branch_1, branch_2]) + + +def block_inception_c(inputs, scope=None, reuse=None): + """Builds Inception-C block for Inception v4 network.""" + # By default use stride=1 and SAME padding + with slim.arg_scope([slim.conv2d, slim.avg_pool2d, slim.max_pool2d], + stride=1, padding='SAME'): + with tf.variable_scope(scope, 'BlockInceptionC', [inputs], reuse=reuse): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(inputs, 256, [1, 1], scope='Conv2d_0a_1x1') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(inputs, 384, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = tf.concat(axis=3, values=[ + slim.conv2d(branch_1, 256, [1, 3], scope='Conv2d_0b_1x3'), + slim.conv2d(branch_1, 256, [3, 1], scope='Conv2d_0c_3x1')]) + with tf.variable_scope('Branch_2'): + branch_2 = slim.conv2d(inputs, 384, [1, 1], scope='Conv2d_0a_1x1') + branch_2 = slim.conv2d(branch_2, 448, [3, 1], scope='Conv2d_0b_3x1') + branch_2 = slim.conv2d(branch_2, 512, [1, 3], scope='Conv2d_0c_1x3') + branch_2 = tf.concat(axis=3, values=[ + slim.conv2d(branch_2, 256, [1, 3], scope='Conv2d_0d_1x3'), + slim.conv2d(branch_2, 256, [3, 1], scope='Conv2d_0e_3x1')]) + with tf.variable_scope('Branch_3'): + branch_3 = slim.avg_pool2d(inputs, [3, 3], scope='AvgPool_0a_3x3') + branch_3 = slim.conv2d(branch_3, 256, [1, 1], scope='Conv2d_0b_1x1') + return tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3]) + + +def inception_v4_base(inputs, final_endpoint='Mixed_7d', scope=None): + """Creates the Inception V4 network up to the given final endpoint. + + Args: + inputs: a 4-D tensor of size [batch_size, height, width, 3]. + final_endpoint: specifies the endpoint to construct the network up to. + It can be one of [ 'Conv2d_1a_3x3', 'Conv2d_2a_3x3', 'Conv2d_2b_3x3', + 'Mixed_3a', 'Mixed_4a', 'Mixed_5a', 'Mixed_5b', 'Mixed_5c', 'Mixed_5d', + 'Mixed_5e', 'Mixed_6a', 'Mixed_6b', 'Mixed_6c', 'Mixed_6d', 'Mixed_6e', + 'Mixed_6f', 'Mixed_6g', 'Mixed_6h', 'Mixed_7a', 'Mixed_7b', 'Mixed_7c', + 'Mixed_7d'] + scope: Optional variable_scope. + + Returns: + logits: the logits outputs of the model. + end_points: the set of end_points from the inception model. + + Raises: + ValueError: if final_endpoint is not set to one of the predefined values, + """ + end_points = {} + + def add_and_check_final(name, net): + end_points[name] = net + return name == final_endpoint + + with tf.variable_scope(scope, 'InceptionV4', [inputs]): + with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d], + stride=1, padding='SAME'): + # 299 x 299 x 3 + net = slim.conv2d(inputs, 32, [3, 3], stride=2, + padding='VALID', scope='Conv2d_1a_3x3') + if add_and_check_final('Conv2d_1a_3x3', net): return net, end_points + # 149 x 149 x 32 + net = slim.conv2d(net, 32, [3, 3], padding='VALID', + scope='Conv2d_2a_3x3') + if add_and_check_final('Conv2d_2a_3x3', net): return net, end_points + # 147 x 147 x 32 + net = slim.conv2d(net, 64, [3, 3], scope='Conv2d_2b_3x3') + if add_and_check_final('Conv2d_2b_3x3', net): return net, end_points + # 147 x 147 x 64 + with tf.variable_scope('Mixed_3a'): + with tf.variable_scope('Branch_0'): + branch_0 = slim.max_pool2d(net, [3, 3], stride=2, padding='VALID', + scope='MaxPool_0a_3x3') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, 96, [3, 3], stride=2, padding='VALID', + scope='Conv2d_0a_3x3') + net = tf.concat(axis=3, values=[branch_0, branch_1]) + if add_and_check_final('Mixed_3a', net): return net, end_points + + # 73 x 73 x 160 + with tf.variable_scope('Mixed_4a'): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, 64, [1, 1], scope='Conv2d_0a_1x1') + branch_0 = slim.conv2d(branch_0, 96, [3, 3], padding='VALID', + scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_1'): + branch_1 = slim.conv2d(net, 64, [1, 1], scope='Conv2d_0a_1x1') + branch_1 = slim.conv2d(branch_1, 64, [1, 7], scope='Conv2d_0b_1x7') + branch_1 = slim.conv2d(branch_1, 64, [7, 1], scope='Conv2d_0c_7x1') + branch_1 = slim.conv2d(branch_1, 96, [3, 3], padding='VALID', + scope='Conv2d_1a_3x3') + net = tf.concat(axis=3, values=[branch_0, branch_1]) + if add_and_check_final('Mixed_4a', net): return net, end_points + + # 71 x 71 x 192 + with tf.variable_scope('Mixed_5a'): + with tf.variable_scope('Branch_0'): + branch_0 = slim.conv2d(net, 192, [3, 3], stride=2, padding='VALID', + scope='Conv2d_1a_3x3') + with tf.variable_scope('Branch_1'): + branch_1 = slim.max_pool2d(net, [3, 3], stride=2, padding='VALID', + scope='MaxPool_1a_3x3') + net = tf.concat(axis=3, values=[branch_0, branch_1]) + if add_and_check_final('Mixed_5a', net): return net, end_points + + # 35 x 35 x 384 + # 4 x Inception-A blocks + for idx in range(4): + block_scope = 'Mixed_5' + chr(ord('b') + idx) + net = block_inception_a(net, block_scope) + if add_and_check_final(block_scope, net): return net, end_points + + # 35 x 35 x 384 + # Reduction-A block + net = block_reduction_a(net, 'Mixed_6a') + if add_and_check_final('Mixed_6a', net): return net, end_points + + # 17 x 17 x 1024 + # 7 x Inception-B blocks + for idx in range(7): + block_scope = 'Mixed_6' + chr(ord('b') + idx) + net = block_inception_b(net, block_scope) + if add_and_check_final(block_scope, net): return net, end_points + + # 17 x 17 x 1024 + # Reduction-B block + net = block_reduction_b(net, 'Mixed_7a') + if add_and_check_final('Mixed_7a', net): return net, end_points + + # 8 x 8 x 1536 + # 3 x Inception-C blocks + for idx in range(3): + block_scope = 'Mixed_7' + chr(ord('b') + idx) + net = block_inception_c(net, block_scope) + if add_and_check_final(block_scope, net): return net, end_points + raise ValueError('Unknown final endpoint %s' % final_endpoint) + + +def inception_v4(inputs, num_classes=1001, is_training=True, + dropout_keep_prob=0.8, + reuse=None, + scope='InceptionV4', + create_aux_logits=True): + """Creates the Inception V4 model. + + Args: + inputs: a 4-D tensor of size [batch_size, height, width, 3]. + num_classes: number of predicted classes. If 0 or None, the logits layer + is omitted and the input features to the logits layer (before dropout) + are returned instead. + is_training: whether is training or not. + dropout_keep_prob: float, the fraction to keep before final layer. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + create_aux_logits: Whether to include the auxiliary logits. + + Returns: + net: a Tensor with the logits (pre-softmax activations) if num_classes + is a non-zero integer, or the non-dropped input to the logits layer + if num_classes is 0 or None. + end_points: the set of end_points from the inception model. + """ + end_points = {} + with tf.variable_scope(scope, 'InceptionV4', [inputs], reuse=reuse) as scope: + with slim.arg_scope([slim.batch_norm, slim.dropout], + is_training=is_training): + net, end_points = inception_v4_base(inputs, scope=scope) + + with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d], + stride=1, padding='SAME'): + # Auxiliary Head logits + if create_aux_logits and num_classes: + with tf.variable_scope('AuxLogits'): + # 17 x 17 x 1024 + aux_logits = end_points['Mixed_6h'] + aux_logits = slim.avg_pool2d(aux_logits, [5, 5], stride=3, + padding='VALID', + scope='AvgPool_1a_5x5') + aux_logits = slim.conv2d(aux_logits, 128, [1, 1], + scope='Conv2d_1b_1x1') + aux_logits = slim.conv2d(aux_logits, 768, + aux_logits.get_shape()[1:3], + padding='VALID', scope='Conv2d_2a') + aux_logits = slim.flatten(aux_logits) + aux_logits = slim.fully_connected(aux_logits, num_classes, + activation_fn=None, + scope='Aux_logits') + end_points['AuxLogits'] = aux_logits + + # Final pooling and prediction + # TODO(sguada,arnoegw): Consider adding a parameter global_pool which + # can be set to False to disable pooling here (as in resnet_*()). + with tf.variable_scope('Logits'): + # 8 x 8 x 1536 + kernel_size = net.get_shape()[1:3] + if kernel_size.is_fully_defined(): + net = slim.avg_pool2d(net, kernel_size, padding='VALID', + scope='AvgPool_1a') + else: + net = tf.reduce_mean(net, [1, 2], keep_dims=True, + name='global_pool') + end_points['global_pool'] = net + if not num_classes: + return net, end_points + # 1 x 1 x 1536 + net = slim.dropout(net, dropout_keep_prob, scope='Dropout_1b') + net = slim.flatten(net, scope='PreLogitsFlatten') + end_points['PreLogitsFlatten'] = net + # 1536 + logits = slim.fully_connected(net, num_classes, activation_fn=None, + scope='Logits') + end_points['Logits'] = logits + end_points['Predictions'] = tf.nn.softmax(logits, name='Predictions') + return logits, end_points +inception_v4.default_image_size = 299 + + +inception_v4_arg_scope = inception_utils.inception_arg_scope diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v4_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v4_test.py new file mode 100644 index 0000000..224933f --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/inception_v4_test.py @@ -0,0 +1,283 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for slim.inception_v4.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import inception + + +class InceptionTest(tf.test.TestCase): + + def testBuildLogits(self): + batch_size = 5 + height, width = 299, 299 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, end_points = inception.inception_v4(inputs, num_classes) + auxlogits = end_points['AuxLogits'] + predictions = end_points['Predictions'] + self.assertTrue(auxlogits.op.name.startswith('InceptionV4/AuxLogits')) + self.assertListEqual(auxlogits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertTrue(logits.op.name.startswith('InceptionV4/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertTrue(predictions.op.name.startswith( + 'InceptionV4/Logits/Predictions')) + self.assertListEqual(predictions.get_shape().as_list(), + [batch_size, num_classes]) + + def testBuildPreLogitsNetwork(self): + batch_size = 5 + height, width = 299, 299 + num_classes = None + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, end_points = inception.inception_v4(inputs, num_classes) + self.assertTrue(net.op.name.startswith('InceptionV4/Logits/AvgPool')) + self.assertListEqual(net.get_shape().as_list(), [batch_size, 1, 1, 1536]) + self.assertFalse('Logits' in end_points) + self.assertFalse('Predictions' in end_points) + + def testBuildWithoutAuxLogits(self): + batch_size = 5 + height, width = 299, 299 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, endpoints = inception.inception_v4(inputs, num_classes, + create_aux_logits=False) + self.assertFalse('AuxLogits' in endpoints) + self.assertTrue(logits.op.name.startswith('InceptionV4/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + + def testAllEndPointsShapes(self): + batch_size = 5 + height, width = 299, 299 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = inception.inception_v4(inputs, num_classes) + endpoints_shapes = {'Conv2d_1a_3x3': [batch_size, 149, 149, 32], + 'Conv2d_2a_3x3': [batch_size, 147, 147, 32], + 'Conv2d_2b_3x3': [batch_size, 147, 147, 64], + 'Mixed_3a': [batch_size, 73, 73, 160], + 'Mixed_4a': [batch_size, 71, 71, 192], + 'Mixed_5a': [batch_size, 35, 35, 384], + # 4 x Inception-A blocks + 'Mixed_5b': [batch_size, 35, 35, 384], + 'Mixed_5c': [batch_size, 35, 35, 384], + 'Mixed_5d': [batch_size, 35, 35, 384], + 'Mixed_5e': [batch_size, 35, 35, 384], + # Reduction-A block + 'Mixed_6a': [batch_size, 17, 17, 1024], + # 7 x Inception-B blocks + 'Mixed_6b': [batch_size, 17, 17, 1024], + 'Mixed_6c': [batch_size, 17, 17, 1024], + 'Mixed_6d': [batch_size, 17, 17, 1024], + 'Mixed_6e': [batch_size, 17, 17, 1024], + 'Mixed_6f': [batch_size, 17, 17, 1024], + 'Mixed_6g': [batch_size, 17, 17, 1024], + 'Mixed_6h': [batch_size, 17, 17, 1024], + # Reduction-A block + 'Mixed_7a': [batch_size, 8, 8, 1536], + # 3 x Inception-C blocks + 'Mixed_7b': [batch_size, 8, 8, 1536], + 'Mixed_7c': [batch_size, 8, 8, 1536], + 'Mixed_7d': [batch_size, 8, 8, 1536], + # Logits and predictions + 'AuxLogits': [batch_size, num_classes], + 'global_pool': [batch_size, 1, 1, 1536], + 'PreLogitsFlatten': [batch_size, 1536], + 'Logits': [batch_size, num_classes], + 'Predictions': [batch_size, num_classes]} + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name in endpoints_shapes: + expected_shape = endpoints_shapes[endpoint_name] + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testBuildBaseNetwork(self): + batch_size = 5 + height, width = 299, 299 + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, end_points = inception.inception_v4_base(inputs) + self.assertTrue(net.op.name.startswith( + 'InceptionV4/Mixed_7d')) + self.assertListEqual(net.get_shape().as_list(), [batch_size, 8, 8, 1536]) + expected_endpoints = [ + 'Conv2d_1a_3x3', 'Conv2d_2a_3x3', 'Conv2d_2b_3x3', 'Mixed_3a', + 'Mixed_4a', 'Mixed_5a', 'Mixed_5b', 'Mixed_5c', 'Mixed_5d', + 'Mixed_5e', 'Mixed_6a', 'Mixed_6b', 'Mixed_6c', 'Mixed_6d', + 'Mixed_6e', 'Mixed_6f', 'Mixed_6g', 'Mixed_6h', 'Mixed_7a', + 'Mixed_7b', 'Mixed_7c', 'Mixed_7d'] + self.assertItemsEqual(end_points.keys(), expected_endpoints) + for name, op in end_points.items(): + self.assertTrue(op.name.startswith('InceptionV4/' + name)) + + def testBuildOnlyUpToFinalEndpoint(self): + batch_size = 5 + height, width = 299, 299 + all_endpoints = [ + 'Conv2d_1a_3x3', 'Conv2d_2a_3x3', 'Conv2d_2b_3x3', 'Mixed_3a', + 'Mixed_4a', 'Mixed_5a', 'Mixed_5b', 'Mixed_5c', 'Mixed_5d', + 'Mixed_5e', 'Mixed_6a', 'Mixed_6b', 'Mixed_6c', 'Mixed_6d', + 'Mixed_6e', 'Mixed_6f', 'Mixed_6g', 'Mixed_6h', 'Mixed_7a', + 'Mixed_7b', 'Mixed_7c', 'Mixed_7d'] + for index, endpoint in enumerate(all_endpoints): + with tf.Graph().as_default(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + out_tensor, end_points = inception.inception_v4_base( + inputs, final_endpoint=endpoint) + self.assertTrue(out_tensor.op.name.startswith( + 'InceptionV4/' + endpoint)) + self.assertItemsEqual(all_endpoints[:index+1], end_points.keys()) + + def testVariablesSetDevice(self): + batch_size = 5 + height, width = 299, 299 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + # Force all Variables to reside on the device. + with tf.variable_scope('on_cpu'), tf.device('/cpu:0'): + inception.inception_v4(inputs, num_classes) + with tf.variable_scope('on_gpu'), tf.device('/gpu:0'): + inception.inception_v4(inputs, num_classes) + for v in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='on_cpu'): + self.assertDeviceEqual(v.device, '/cpu:0') + for v in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='on_gpu'): + self.assertDeviceEqual(v.device, '/gpu:0') + + def testHalfSizeImages(self): + batch_size = 5 + height, width = 150, 150 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, end_points = inception.inception_v4(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionV4/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Mixed_7d'] + self.assertListEqual(pre_pool.get_shape().as_list(), + [batch_size, 3, 3, 1536]) + + def testGlobalPool(self): + batch_size = 1 + height, width = 350, 400 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, end_points = inception.inception_v4(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionV4/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Mixed_7d'] + self.assertListEqual(pre_pool.get_shape().as_list(), + [batch_size, 9, 11, 1536]) + + def testGlobalPoolUnknownImageShape(self): + batch_size = 1 + height, width = 350, 400 + num_classes = 1000 + with self.test_session() as sess: + inputs = tf.placeholder(tf.float32, (batch_size, None, None, 3)) + logits, end_points = inception.inception_v4( + inputs, num_classes, create_aux_logits=False) + self.assertTrue(logits.op.name.startswith('InceptionV4/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Mixed_7d'] + images = tf.random_uniform((batch_size, height, width, 3)) + sess.run(tf.global_variables_initializer()) + logits_out, pre_pool_out = sess.run([logits, pre_pool], + {inputs: images.eval()}) + self.assertTupleEqual(logits_out.shape, (batch_size, num_classes)) + self.assertTupleEqual(pre_pool_out.shape, (batch_size, 9, 11, 1536)) + + def testUnknownBatchSize(self): + batch_size = 1 + height, width = 299, 299 + num_classes = 1000 + with self.test_session() as sess: + inputs = tf.placeholder(tf.float32, (None, height, width, 3)) + logits, _ = inception.inception_v4(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionV4/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [None, num_classes]) + images = tf.random_uniform((batch_size, height, width, 3)) + sess.run(tf.global_variables_initializer()) + output = sess.run(logits, {inputs: images.eval()}) + self.assertEquals(output.shape, (batch_size, num_classes)) + + def testEvaluation(self): + batch_size = 2 + height, width = 299, 299 + num_classes = 1000 + with self.test_session() as sess: + eval_inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = inception.inception_v4(eval_inputs, + num_classes, + is_training=False) + predictions = tf.argmax(logits, 1) + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (batch_size,)) + + def testTrainEvalWithReuse(self): + train_batch_size = 5 + eval_batch_size = 2 + height, width = 150, 150 + num_classes = 1000 + with self.test_session() as sess: + train_inputs = tf.random_uniform((train_batch_size, height, width, 3)) + inception.inception_v4(train_inputs, num_classes) + eval_inputs = tf.random_uniform((eval_batch_size, height, width, 3)) + logits, _ = inception.inception_v4(eval_inputs, + num_classes, + is_training=False, + reuse=True) + predictions = tf.argmax(logits, 1) + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (eval_batch_size,)) + + def testNoBatchNormScaleByDefault(self): + height, width = 299, 299 + num_classes = 1000 + inputs = tf.placeholder(tf.float32, (1, height, width, 3)) + with tf.contrib.slim.arg_scope(inception.inception_v4_arg_scope()): + inception.inception_v4(inputs, num_classes, is_training=False) + + self.assertEqual(tf.global_variables('.*/BatchNorm/gamma:0$'), []) + + def testBatchNormScale(self): + height, width = 299, 299 + num_classes = 1000 + inputs = tf.placeholder(tf.float32, (1, height, width, 3)) + with tf.contrib.slim.arg_scope( + inception.inception_v4_arg_scope(batch_norm_scale=True)): + inception.inception_v4(inputs, num_classes, is_training=False) + + gamma_names = set( + v.op.name for v in tf.global_variables('.*/BatchNorm/gamma:0$')) + self.assertGreater(len(gamma_names), 0) + for v in tf.global_variables('.*/BatchNorm/moving_mean:0$'): + self.assertIn(v.op.name[:-len('moving_mean')] + 'gamma', gamma_names) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/lenet.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/lenet.py new file mode 100644 index 0000000..c79dbfa --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/lenet.py @@ -0,0 +1,97 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains a variant of the LeNet model definition.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +slim = tf.contrib.slim + + +def lenet(images, num_classes=10, is_training=False, + dropout_keep_prob=0.5, + prediction_fn=slim.softmax, + scope='LeNet'): + """Creates a variant of the LeNet model. + + Note that since the output is a set of 'logits', the values fall in the + interval of (-infinity, infinity). Consequently, to convert the outputs to a + probability distribution over the characters, one will need to convert them + using the softmax function: + + logits = lenet.lenet(images, is_training=False) + probabilities = tf.nn.softmax(logits) + predictions = tf.argmax(logits, 1) + + Args: + images: A batch of `Tensors` of size [batch_size, height, width, channels]. + num_classes: the number of classes in the dataset. If 0 or None, the logits + layer is omitted and the input features to the logits layer are returned + instead. + is_training: specifies whether or not we're currently training the model. + This variable will determine the behaviour of the dropout layer. + dropout_keep_prob: the percentage of activation values that are retained. + prediction_fn: a function to get predictions out of logits. + scope: Optional variable_scope. + + Returns: + net: a 2D Tensor with the logits (pre-softmax activations) if num_classes + is a non-zero integer, or the inon-dropped-out nput to the logits layer + if num_classes is 0 or None. + end_points: a dictionary from components of the network to the corresponding + activation. + """ + end_points = {} + + with tf.variable_scope(scope, 'LeNet', [images]): + net = end_points['conv1'] = slim.conv2d(images, 32, [5, 5], scope='conv1') + net = end_points['pool1'] = slim.max_pool2d(net, [2, 2], 2, scope='pool1') + net = end_points['conv2'] = slim.conv2d(net, 64, [5, 5], scope='conv2') + net = end_points['pool2'] = slim.max_pool2d(net, [2, 2], 2, scope='pool2') + net = slim.flatten(net) + end_points['Flatten'] = net + + net = end_points['fc3'] = slim.fully_connected(net, 1024, scope='fc3') + if not num_classes: + return net, end_points + net = end_points['dropout3'] = slim.dropout( + net, dropout_keep_prob, is_training=is_training, scope='dropout3') + logits = end_points['Logits'] = slim.fully_connected( + net, num_classes, activation_fn=None, scope='fc4') + + end_points['Predictions'] = prediction_fn(logits, scope='Predictions') + + return logits, end_points +lenet.default_image_size = 28 + + +def lenet_arg_scope(weight_decay=0.0): + """Defines the default lenet argument scope. + + Args: + weight_decay: The weight decay to use for regularizing the model. + + Returns: + An `arg_scope` to use for the inception v3 model. + """ + with slim.arg_scope( + [slim.conv2d, slim.fully_connected], + weights_regularizer=slim.l2_regularizer(weight_decay), + weights_initializer=tf.truncated_normal_initializer(stddev=0.1), + activation_fn=tf.nn.relu) as sc: + return sc diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/README.md b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/README.md new file mode 100644 index 0000000..e4699d6 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/README.md @@ -0,0 +1,73 @@ +# MobileNetV2 +This folder contains building code for MobileNetV2, based on +[MobileNetV2: Inverted Residuals and Linear Bottlenecks](https://arxiv.org/abs/1801.04381) + +# Performance +## Latency +This is the timing of [MobileNetV1](../mobilenet_v1.md) vs MobileNetV2 using +TF-Lite on the large core of Pixel 1 phone. + +![mnet_v1_vs_v2_pixel1_latency.png](mnet_v1_vs_v2_pixel1_latency.png) + +## MACs +MACs, also sometimes known as MADDs - the number of multiply-accumulates needed +to compute an inference on a single image is a common metric to measure the efficiency of the model. + +Below is the graph comparing V2 vs a few selected networks. The size +of each blob represents the number of parameters. Note for [ShuffleNet](https://arxiv.org/abs/1707.01083) there +are no published size numbers. We estimate it to be comparable to MobileNetV2 numbers. + +![madds_top1_accuracy](madds_top1_accuracy.png) + +# Pretrained models +## Imagenet Checkpoints + + Classification Checkpoint | MACs (M)| Parameters (M)| Top 1 Accuracy| Top 5 Accuracy | Mobile CPU (ms) Pixel 1 +---------------------------|---------|---------------|---------|----|------------- +| [mobilenet_v2_1.4_224](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_1.4_224.tgz) | 582 | 6.06 | 75.0 | 92.5 | 138.0 +| [mobilenet_v2_1.3_224](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_1.3_224.tgz) | 509 | 5.34 | 74.4 | 92.1 | 123.0 +| [mobilenet_v2_1.0_224](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_1.0_224.tgz) | 300 | 3.47 | 71.8 | 91.0 | 73.8 +| [mobilenet_v2_1.0_192](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_1.0_192.tgz) | 221 | 3.47 | 70.7 | 90.1 | 55.1 +| [mobilenet_v2_1.0_160](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_1.0_160.tgz) | 154 | 3.47 | 68.8 | 89.0 | 40.2 +| [mobilenet_v2_1.0_128](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_1.0_128.tgz) | 99 | 3.47 | 65.3 | 86.9 | 27.6 +| [mobilenet_v2_1.0_96](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_1.0_96.tgz) | 56 | 3.47 | 60.3 | 83.2 | 17.6 +| [mobilenet_v2_0.75_224](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.75_224.tgz) | 209 | 2.61 | 69.8 | 89.6 | 55.8 +| [mobilenet_v2_0.75_192](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.75_192.tgz) | 153 | 2.61 | 68.7 | 88.9 | 41.6 +| [mobilenet_v2_0.75_160](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.75_160.tgz) | 107 | 2.61 | 66.4 | 87.3 | 30.4 +| [mobilenet_v2_0.75_128](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.75_128.tgz) | 69 | 2.61 | 63.2 | 85.3 | 21.9 +| [mobilenet_v2_0.75_96](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.75_96.tgz) | 39 | 2.61 | 58.8 | 81.6 | 14.2 +| [mobilenet_v2_0.5_224](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.5_224.tgz) | 97 | 1.95 | 65.4 | 86.4 | 28.7 +| [mobilenet_v2_0.5_192](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.5_192.tgz) | 71 | 1.95 | 63.9 | 85.4 | 21.1 +| [mobilenet_v2_0.5_160](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.5_160.tgz) | 50 | 1.95 | 61.0 | 83.2 | 14.9 +| [mobilenet_v2_0.5_128](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.5_128.tgz) | 32 | 1.95 | 57.7 | 80.8 | 9.9 +| [mobilenet_v2_0.5_96](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.5_96.tgz) | 18 | 1.95 | 51.2 | 75.8 | 6.4 +| [mobilenet_v2_0.35_224](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.35_224.tgz) | 59 | 1.66 | 60.3 | 82.9 | 19.7 +| [mobilenet_v2_0.35_192](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.35_192.tgz) | 43 | 1.66 | 58.2 | 81.2 | 14.6 +| [mobilenet_v2_0.35_160](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.35_160.tgz) | 30 | 1.66 | 55.7 | 79.1 | 10.5 +| [mobilenet_v2_0.35_128](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.35_128.tgz) | 20 | 1.66 | 50.8 | 75.0 | 6.9 +| [mobilenet_v2_0.35_96](https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_0.35_96.tgz) | 11 | 1.66 | 45.5 | 70.4 | 4.5 + +# Training +The numbers above can be reproduced using slim's `train_image_classifier`. +Below is the set of parameters that achieves 72.0% for full size MobileNetV2, after about 700K when trained on 8 GPU. +If trained on a single GPU the full convergence is after 5.5M steps. Also note that learning rate and +num_epochs_per_decay both need to be adjusted depending on how many GPUs are being +used due to slim's internal averaging. + +```bash +--model_name="mobilenet_v2" +--learning_rate=0.045 * NUM_GPUS #slim internally averages clones so we compensate +--preprocessing_name="inception_v2" +--label_smoothing=0.1 +--moving_average_decay=0.9999 +--batch_size= 96 +--num_clones = NUM_GPUS # you can use any number here between 1 and 8 depending on your hardware setup. +--learning_rate_decay_factor=0.98 +--num_epochs_per_decay = 2.5 / NUM_GPUS # train_image_classifier does per clone epochs +``` + +# Example + + +See this [ipython notebook](mobilenet_example.ipynb) or open and run the network directly in [Colaboratory](https://colab.research.google.com/github/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet_example.ipynb). + diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/__init__.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/conv_blocks.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/conv_blocks.py new file mode 100644 index 0000000..a07d7e5 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/conv_blocks.py @@ -0,0 +1,358 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Convolution blocks for mobilenet.""" +import contextlib +import functools + +import tensorflow as tf + +slim = tf.contrib.slim + + +def _fixed_padding(inputs, kernel_size, rate=1): + """Pads the input along the spatial dimensions independently of input size. + + Pads the input such that if it was used in a convolution with 'VALID' padding, + the output would have the same dimensions as if the unpadded input was used + in a convolution with 'SAME' padding. + + Args: + inputs: A tensor of size [batch, height_in, width_in, channels]. + kernel_size: The kernel to be used in the conv2d or max_pool2d operation. + rate: An integer, rate for atrous convolution. + + Returns: + output: A tensor of size [batch, height_out, width_out, channels] with the + input, either intact (if kernel_size == 1) or padded (if kernel_size > 1). + """ + kernel_size_effective = [kernel_size[0] + (kernel_size[0] - 1) * (rate - 1), + kernel_size[0] + (kernel_size[0] - 1) * (rate - 1)] + pad_total = [kernel_size_effective[0] - 1, kernel_size_effective[1] - 1] + pad_beg = [pad_total[0] // 2, pad_total[1] // 2] + pad_end = [pad_total[0] - pad_beg[0], pad_total[1] - pad_beg[1]] + padded_inputs = tf.pad(inputs, [[0, 0], [pad_beg[0], pad_end[0]], + [pad_beg[1], pad_end[1]], [0, 0]]) + return padded_inputs + + +def _make_divisible(v, divisor, min_value=None): + if min_value is None: + min_value = divisor + new_v = max(min_value, int(v + divisor / 2) // divisor * divisor) + # Make sure that round down does not go down by more than 10%. + if new_v < 0.9 * v: + new_v += divisor + return new_v + + +def _split_divisible(num, num_ways, divisible_by=8): + """Evenly splits num, num_ways so each piece is a multiple of divisible_by.""" + assert num % divisible_by == 0 + assert num / num_ways >= divisible_by + # Note: want to round down, we adjust each split to match the total. + base = num // num_ways // divisible_by * divisible_by + result = [] + accumulated = 0 + for i in range(num_ways): + r = base + while accumulated + r < num * (i + 1) / num_ways: + r += divisible_by + result.append(r) + accumulated += r + assert accumulated == num + return result + + +@contextlib.contextmanager +def _v1_compatible_scope_naming(scope): + if scope is None: # Create uniqified separable blocks. + with tf.variable_scope(None, default_name='separable') as s, \ + tf.name_scope(s.original_name_scope): + yield '' + else: + # We use scope_depthwise, scope_pointwise for compatibility with V1 ckpts. + # which provide numbered scopes. + scope += '_' + yield scope + + +@slim.add_arg_scope +def split_separable_conv2d(input_tensor, + num_outputs, + scope=None, + normalizer_fn=None, + stride=1, + rate=1, + endpoints=None, + use_explicit_padding=False): + """Separable mobilenet V1 style convolution. + + Depthwise convolution, with default non-linearity, + followed by 1x1 depthwise convolution. This is similar to + slim.separable_conv2d, but differs in tha it applies batch + normalization and non-linearity to depthwise. This matches + the basic building of Mobilenet Paper + (https://arxiv.org/abs/1704.04861) + + Args: + input_tensor: input + num_outputs: number of outputs + scope: optional name of the scope. Note if provided it will use + scope_depthwise for deptwhise, and scope_pointwise for pointwise. + normalizer_fn: which normalizer function to use for depthwise/pointwise + stride: stride + rate: output rate (also known as dilation rate) + endpoints: optional, if provided, will export additional tensors to it. + use_explicit_padding: Use 'VALID' padding for convolutions, but prepad + inputs so that the output dimensions are the same as if 'SAME' padding + were used. + + Returns: + output tesnor + """ + + with _v1_compatible_scope_naming(scope) as scope: + dw_scope = scope + 'depthwise' + endpoints = endpoints if endpoints is not None else {} + kernel_size = [3, 3] + padding = 'SAME' + if use_explicit_padding: + padding = 'VALID' + input_tensor = _fixed_padding(input_tensor, kernel_size, rate) + net = slim.separable_conv2d( + input_tensor, + None, + kernel_size, + depth_multiplier=1, + stride=stride, + rate=rate, + normalizer_fn=normalizer_fn, + padding=padding, + scope=dw_scope) + + endpoints[dw_scope] = net + + pw_scope = scope + 'pointwise' + net = slim.conv2d( + net, + num_outputs, [1, 1], + stride=1, + normalizer_fn=normalizer_fn, + scope=pw_scope) + endpoints[pw_scope] = net + return net + + +def expand_input_by_factor(n, divisible_by=8): + return lambda num_inputs, **_: _make_divisible(num_inputs * n, divisible_by) + + +@slim.add_arg_scope +def expanded_conv(input_tensor, + num_outputs, + expansion_size=expand_input_by_factor(6), + stride=1, + rate=1, + kernel_size=(3, 3), + residual=True, + normalizer_fn=None, + project_activation_fn=tf.identity, + split_projection=1, + split_expansion=1, + expansion_transform=None, + depthwise_location='expansion', + depthwise_channel_multiplier=1, + endpoints=None, + use_explicit_padding=False, + padding='SAME', + scope=None): + """Depthwise Convolution Block with expansion. + + Builds a composite convolution that has the following structure + expansion (1x1) -> depthwise (kernel_size) -> projection (1x1) + + Args: + input_tensor: input + num_outputs: number of outputs in the final layer. + expansion_size: the size of expansion, could be a constant or a callable. + If latter it will be provided 'num_inputs' as an input. For forward + compatibility it should accept arbitrary keyword arguments. + Default will expand the input by factor of 6. + stride: depthwise stride + rate: depthwise rate + kernel_size: depthwise kernel + residual: whether to include residual connection between input + and output. + normalizer_fn: batchnorm or otherwise + project_activation_fn: activation function for the project layer + split_projection: how many ways to split projection operator + (that is conv expansion->bottleneck) + split_expansion: how many ways to split expansion op + (that is conv bottleneck->expansion) ops will keep depth divisible + by this value. + expansion_transform: Optional function that takes expansion + as a single input and returns output. + depthwise_location: where to put depthwise covnvolutions supported + values None, 'input', 'output', 'expansion' + depthwise_channel_multiplier: depthwise channel multiplier: + each input will replicated (with different filters) + that many times. So if input had c channels, + output will have c x depthwise_channel_multpilier. + endpoints: An optional dictionary into which intermediate endpoints are + placed. The keys "expansion_output", "depthwise_output", + "projection_output" and "expansion_transform" are always populated, even + if the corresponding functions are not invoked. + use_explicit_padding: Use 'VALID' padding for convolutions, but prepad + inputs so that the output dimensions are the same as if 'SAME' padding + were used. + padding: Padding type to use if `use_explicit_padding` is not set. + scope: optional scope. + + Returns: + Tensor of depth num_outputs + + Raises: + TypeError: on inval + """ + with tf.variable_scope(scope, default_name='expanded_conv') as s, \ + tf.name_scope(s.original_name_scope): + prev_depth = input_tensor.get_shape().as_list()[3] + if depthwise_location not in [None, 'input', 'output', 'expansion']: + raise TypeError('%r is unknown value for depthwise_location' % + depthwise_location) + if use_explicit_padding: + if padding != 'SAME': + raise TypeError('`use_explicit_padding` should only be used with ' + '"SAME" padding.') + padding = 'VALID' + depthwise_func = functools.partial( + slim.separable_conv2d, + num_outputs=None, + kernel_size=kernel_size, + depth_multiplier=depthwise_channel_multiplier, + stride=stride, + rate=rate, + normalizer_fn=normalizer_fn, + padding=padding, + scope='depthwise') + # b1 -> b2 * r -> b2 + # i -> (o * r) (bottleneck) -> o + input_tensor = tf.identity(input_tensor, 'input') + net = input_tensor + + if depthwise_location == 'input': + if use_explicit_padding: + net = _fixed_padding(net, kernel_size, rate) + net = depthwise_func(net, activation_fn=None) + + if callable(expansion_size): + inner_size = expansion_size(num_inputs=prev_depth) + else: + inner_size = expansion_size + + if inner_size > net.shape[3]: + net = split_conv( + net, + inner_size, + num_ways=split_expansion, + scope='expand', + stride=1, + normalizer_fn=normalizer_fn) + net = tf.identity(net, 'expansion_output') + if endpoints is not None: + endpoints['expansion_output'] = net + + if depthwise_location == 'expansion': + if use_explicit_padding: + net = _fixed_padding(net, kernel_size, rate) + net = depthwise_func(net) + + net = tf.identity(net, name='depthwise_output') + if endpoints is not None: + endpoints['depthwise_output'] = net + if expansion_transform: + net = expansion_transform(expansion_tensor=net, input_tensor=input_tensor) + # Note in contrast with expansion, we always have + # projection to produce the desired output size. + net = split_conv( + net, + num_outputs, + num_ways=split_projection, + stride=1, + scope='project', + normalizer_fn=normalizer_fn, + activation_fn=project_activation_fn) + if endpoints is not None: + endpoints['projection_output'] = net + if depthwise_location == 'output': + if use_explicit_padding: + net = _fixed_padding(net, kernel_size, rate) + net = depthwise_func(net, activation_fn=None) + + if callable(residual): # custom residual + net = residual(input_tensor=input_tensor, output_tensor=net) + elif (residual and + # stride check enforces that we don't add residuals when spatial + # dimensions are None + stride == 1 and + # Depth matches + net.get_shape().as_list()[3] == + input_tensor.get_shape().as_list()[3]): + net += input_tensor + return tf.identity(net, name='output') + + +def split_conv(input_tensor, + num_outputs, + num_ways, + scope, + divisible_by=8, + **kwargs): + """Creates a split convolution. + + Split convolution splits the input and output into + 'num_blocks' blocks of approximately the same size each, + and only connects $i$-th input to $i$ output. + + Args: + input_tensor: input tensor + num_outputs: number of output filters + num_ways: num blocks to split by. + scope: scope for all the operators. + divisible_by: make sure that every part is divisiable by this. + **kwargs: will be passed directly into conv2d operator + Returns: + tensor + """ + b = input_tensor.get_shape().as_list()[3] + + if num_ways == 1 or min(b // num_ways, + num_outputs // num_ways) < divisible_by: + # Don't do any splitting if we end up with less than 8 filters + # on either side. + return slim.conv2d(input_tensor, num_outputs, [1, 1], scope=scope, **kwargs) + + outs = [] + input_splits = _split_divisible(b, num_ways, divisible_by=divisible_by) + output_splits = _split_divisible( + num_outputs, num_ways, divisible_by=divisible_by) + inputs = tf.split(input_tensor, input_splits, axis=3, name='split_' + scope) + base = scope + for i, (input_tensor, out_size) in enumerate(zip(inputs, output_splits)): + scope = base + '_part_%d' % (i,) + n = slim.conv2d(input_tensor, out_size, [1, 1], scope=scope, **kwargs) + n = tf.identity(n, scope + '_output') + outs.append(n) + return tf.concat(outs, 3, name=scope + '_concat') diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/madds_top1_accuracy.png b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/madds_top1_accuracy.png new file mode 100644 index 0000000000000000000000000000000000000000..6a2d8c078f999caa5bfc9b573d7acffecf5268d8 GIT binary patch literal 102412 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 WdcA^UzTL$4NnemZpLx#U-v0&nzG>6| literal 0 HcmV?d00001 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet.py new file mode 100644 index 0000000..f71e73f --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet.py @@ -0,0 +1,467 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Mobilenet Base Class.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +import collections +import contextlib +import copy +import os + +import tensorflow as tf + + +slim = tf.contrib.slim + + +@slim.add_arg_scope +def apply_activation(x, name=None, activation_fn=None): + return activation_fn(x, name=name) if activation_fn else x + + +def _fixed_padding(inputs, kernel_size, rate=1): + """Pads the input along the spatial dimensions independently of input size. + + Pads the input such that if it was used in a convolution with 'VALID' padding, + the output would have the same dimensions as if the unpadded input was used + in a convolution with 'SAME' padding. + + Args: + inputs: A tensor of size [batch, height_in, width_in, channels]. + kernel_size: The kernel to be used in the conv2d or max_pool2d operation. + rate: An integer, rate for atrous convolution. + + Returns: + output: A tensor of size [batch, height_out, width_out, channels] with the + input, either intact (if kernel_size == 1) or padded (if kernel_size > 1). + """ + kernel_size_effective = [kernel_size[0] + (kernel_size[0] - 1) * (rate - 1), + kernel_size[0] + (kernel_size[0] - 1) * (rate - 1)] + pad_total = [kernel_size_effective[0] - 1, kernel_size_effective[1] - 1] + pad_beg = [pad_total[0] // 2, pad_total[1] // 2] + pad_end = [pad_total[0] - pad_beg[0], pad_total[1] - pad_beg[1]] + padded_inputs = tf.pad(inputs, [[0, 0], [pad_beg[0], pad_end[0]], + [pad_beg[1], pad_end[1]], [0, 0]]) + return padded_inputs + + +def _make_divisible(v, divisor, min_value=None): + if min_value is None: + min_value = divisor + new_v = max(min_value, int(v + divisor / 2) // divisor * divisor) + # Make sure that round down does not go down by more than 10%. + if new_v < 0.9 * v: + new_v += divisor + return new_v + + +@contextlib.contextmanager +def _set_arg_scope_defaults(defaults): + """Sets arg scope defaults for all items present in defaults. + + Args: + defaults: dictionary/list of pairs, containing a mapping from + function to a dictionary of default args. + + Yields: + context manager where all defaults are set. + """ + if hasattr(defaults, 'items'): + items = list(defaults.items()) + else: + items = defaults + if not items: + yield + else: + func, default_arg = items[0] + with slim.arg_scope(func, **default_arg): + with _set_arg_scope_defaults(items[1:]): + yield + + +@slim.add_arg_scope +def depth_multiplier(output_params, + multiplier, + divisible_by=8, + min_depth=8, + **unused_kwargs): + if 'num_outputs' not in output_params: + return + d = output_params['num_outputs'] + output_params['num_outputs'] = _make_divisible(d * multiplier, divisible_by, + min_depth) + + +_Op = collections.namedtuple('Op', ['op', 'params', 'multiplier_func']) + + +def op(opfunc, **params): + multiplier = params.pop('multiplier_transorm', depth_multiplier) + return _Op(opfunc, params=params, multiplier_func=multiplier) + + +class NoOpScope(object): + """No-op context manager.""" + + def __enter__(self): + return None + + def __exit__(self, exc_type, exc_value, traceback): + return False + + +def safe_arg_scope(funcs, **kwargs): + """Returns `slim.arg_scope` with all None arguments removed. + + Arguments: + funcs: Functions to pass to `arg_scope`. + **kwargs: Arguments to pass to `arg_scope`. + + Returns: + arg_scope or No-op context manager. + + Note: can be useful if None value should be interpreted as "do not overwrite + this parameter value". + """ + filtered_args = {name: value for name, value in kwargs.items() + if value is not None} + if filtered_args: + return slim.arg_scope(funcs, **filtered_args) + else: + return NoOpScope() + + +@slim.add_arg_scope +def mobilenet_base( # pylint: disable=invalid-name + inputs, + conv_defs, + multiplier=1.0, + final_endpoint=None, + output_stride=None, + use_explicit_padding=False, + scope=None, + is_training=False): + """Mobilenet base network. + + Constructs a network from inputs to the given final endpoint. By default + the network is constructed in inference mode. To create network + in training mode use: + + with slim.arg_scope(mobilenet.training_scope()): + logits, endpoints = mobilenet_base(...) + + Args: + inputs: a tensor of shape [batch_size, height, width, channels]. + conv_defs: A list of op(...) layers specifying the net architecture. + multiplier: Float multiplier for the depth (number of channels) + for all convolution ops. The value must be greater than zero. Typical + usage will be to set this value in (0, 1) to reduce the number of + parameters or computation cost of the model. + final_endpoint: The name of last layer, for early termination for + for V1-based networks: last layer is "layer_14", for V2: "layer_20" + output_stride: An integer that specifies the requested ratio of input to + output spatial resolution. If not None, then we invoke atrous convolution + if necessary to prevent the network from reducing the spatial resolution + of the activation maps. Allowed values are 1 or any even number, excluding + zero. Typical values are 8 (accurate fully convolutional mode), 16 + (fast fully convolutional mode), and 32 (classification mode). + + NOTE- output_stride relies on all consequent operators to support dilated + operators via "rate" parameter. This might require wrapping non-conv + operators to operate properly. + + use_explicit_padding: Use 'VALID' padding for convolutions, but prepad + inputs so that the output dimensions are the same as if 'SAME' padding + were used. + scope: optional variable scope. + is_training: How to setup batch_norm and other ops. Note: most of the time + this does not need be set directly. Use mobilenet.training_scope() to set + up training instead. This parameter is here for backward compatibility + only. It is safe to set it to the value matching + training_scope(is_training=...). It is also safe to explicitly set + it to False, even if there is outer training_scope set to to training. + (The network will be built in inference mode). If this is set to None, + no arg_scope is added for slim.batch_norm's is_training parameter. + + Returns: + tensor_out: output tensor. + end_points: a set of activations for external use, for example summaries or + losses. + + Raises: + ValueError: depth_multiplier <= 0, or the target output_stride is not + allowed. + """ + if multiplier <= 0: + raise ValueError('multiplier is not greater than zero.') + + # Set conv defs defaults and overrides. + conv_defs_defaults = conv_defs.get('defaults', {}) + conv_defs_overrides = conv_defs.get('overrides', {}) + if use_explicit_padding: + conv_defs_overrides = copy.deepcopy(conv_defs_overrides) + conv_defs_overrides[ + (slim.conv2d, slim.separable_conv2d)] = {'padding': 'VALID'} + + if output_stride is not None: + if output_stride == 0 or (output_stride > 1 and output_stride % 2): + raise ValueError('Output stride must be None, 1 or a multiple of 2.') + + # a) Set the tensorflow scope + # b) set padding to default: note we might consider removing this + # since it is also set by mobilenet_scope + # c) set all defaults + # d) set all extra overrides. + with _scope_all(scope, default_scope='Mobilenet'), \ + safe_arg_scope([slim.batch_norm], is_training=is_training), \ + _set_arg_scope_defaults(conv_defs_defaults), \ + _set_arg_scope_defaults(conv_defs_overrides): + # The current_stride variable keeps track of the output stride of the + # activations, i.e., the running product of convolution strides up to the + # current network layer. This allows us to invoke atrous convolution + # whenever applying the next convolution would result in the activations + # having output stride larger than the target output_stride. + current_stride = 1 + + # The atrous convolution rate parameter. + rate = 1 + + net = inputs + # Insert default parameters before the base scope which includes + # any custom overrides set in mobilenet. + end_points = {} + scopes = {} + for i, opdef in enumerate(conv_defs['spec']): + params = dict(opdef.params) + opdef.multiplier_func(params, multiplier) + stride = params.get('stride', 1) + if output_stride is not None and current_stride == output_stride: + # If we have reached the target output_stride, then we need to employ + # atrous convolution with stride=1 and multiply the atrous rate by the + # current unit's stride for use in subsequent layers. + layer_stride = 1 + layer_rate = rate + rate *= stride + else: + layer_stride = stride + layer_rate = 1 + current_stride *= stride + # Update params. + params['stride'] = layer_stride + # Only insert rate to params if rate > 1. + if layer_rate > 1: + params['rate'] = layer_rate + # Set padding + if use_explicit_padding: + if 'kernel_size' in params: + net = _fixed_padding(net, params['kernel_size'], layer_rate) + else: + params['use_explicit_padding'] = True + + end_point = 'layer_%d' % (i + 1) + try: + net = opdef.op(net, **params) + except Exception: + print('Failed to create op %i: %r params: %r' % (i, opdef, params)) + raise + end_points[end_point] = net + scope = os.path.dirname(net.name) + scopes[scope] = end_point + if final_endpoint is not None and end_point == final_endpoint: + break + + # Add all tensors that end with 'output' to + # endpoints + for t in net.graph.get_operations(): + scope = os.path.dirname(t.name) + bn = os.path.basename(t.name) + if scope in scopes and t.name.endswith('output'): + end_points[scopes[scope] + '/' + bn] = t.outputs[0] + return net, end_points + + +@contextlib.contextmanager +def _scope_all(scope, default_scope=None): + with tf.variable_scope(scope, default_name=default_scope) as s,\ + tf.name_scope(s.original_name_scope): + yield s + + +@slim.add_arg_scope +def mobilenet(inputs, + num_classes=1001, + prediction_fn=slim.softmax, + reuse=None, + scope='Mobilenet', + base_only=False, + **mobilenet_args): + """Mobilenet model for classification, supports both V1 and V2. + + Note: default mode is inference, use mobilenet.training_scope to create + training network. + + + Args: + inputs: a tensor of shape [batch_size, height, width, channels]. + num_classes: number of predicted classes. If 0 or None, the logits layer + is omitted and the input features to the logits layer (before dropout) + are returned instead. + prediction_fn: a function to get predictions out of logits + (default softmax). + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + base_only: if True will only create the base of the network (no pooling + and no logits). + **mobilenet_args: passed to mobilenet_base verbatim. + - conv_defs: list of conv defs + - multiplier: Float multiplier for the depth (number of channels) + for all convolution ops. The value must be greater than zero. Typical + usage will be to set this value in (0, 1) to reduce the number of + parameters or computation cost of the model. + - output_stride: will ensure that the last layer has at most total stride. + If the architecture calls for more stride than that provided + (e.g. output_stride=16, but the architecture has 5 stride=2 operators), + it will replace output_stride with fractional convolutions using Atrous + Convolutions. + + Returns: + logits: the pre-softmax activations, a tensor of size + [batch_size, num_classes] + end_points: a dictionary from components of the network to the corresponding + activation tensor. + + Raises: + ValueError: Input rank is invalid. + """ + is_training = mobilenet_args.get('is_training', False) + input_shape = inputs.get_shape().as_list() + if len(input_shape) != 4: + raise ValueError('Expected rank 4 input, was: %d' % len(input_shape)) + + with tf.variable_scope(scope, 'Mobilenet', reuse=reuse) as scope: + inputs = tf.identity(inputs, 'input') + net, end_points = mobilenet_base(inputs, scope=scope, **mobilenet_args) + if base_only: + return net, end_points + + net = tf.identity(net, name='embedding') + + with tf.variable_scope('Logits'): + net = global_pool(net) + end_points['global_pool'] = net + if not num_classes: + return net, end_points + net = slim.dropout(net, scope='Dropout', is_training=is_training) + # 1 x 1 x num_classes + # Note: legacy scope name. + logits = slim.conv2d( + net, + num_classes, [1, 1], + activation_fn=None, + normalizer_fn=None, + biases_initializer=tf.zeros_initializer(), + scope='Conv2d_1c_1x1') + + logits = tf.squeeze(logits, [1, 2]) + + logits = tf.identity(logits, name='output') + end_points['Logits'] = logits + if prediction_fn: + end_points['Predictions'] = prediction_fn(logits, 'Predictions') + return logits, end_points + + +def global_pool(input_tensor, pool_op=tf.nn.avg_pool): + """Applies avg pool to produce 1x1 output. + + NOTE: This function is funcitonally equivalenet to reduce_mean, but it has + baked in average pool which has better support across hardware. + + Args: + input_tensor: input tensor + pool_op: pooling op (avg pool is default) + Returns: + a tensor batch_size x 1 x 1 x depth. + """ + shape = input_tensor.get_shape().as_list() + if shape[1] is None or shape[2] is None: + kernel_size = tf.convert_to_tensor( + [1, tf.shape(input_tensor)[1], + tf.shape(input_tensor)[2], 1]) + else: + kernel_size = [1, shape[1], shape[2], 1] + output = pool_op( + input_tensor, ksize=kernel_size, strides=[1, 1, 1, 1], padding='VALID') + # Recover output shape, for unknown shape. + output.set_shape([None, 1, 1, None]) + return output + + +def training_scope(is_training=True, + weight_decay=0.00004, + stddev=0.09, + dropout_keep_prob=0.8, + bn_decay=0.997): + """Defines Mobilenet training scope. + + Usage: + with tf.contrib.slim.arg_scope(mobilenet.training_scope()): + logits, endpoints = mobilenet_v2.mobilenet(input_tensor) + + # the network created will be trainble with dropout/batch norm + # initialized appropriately. + Args: + is_training: if set to False this will ensure that all customizations are + set to non-training mode. This might be helpful for code that is reused + across both training/evaluation, but most of the time training_scope with + value False is not needed. If this is set to None, the parameters is not + added to the batch_norm arg_scope. + + weight_decay: The weight decay to use for regularizing the model. + stddev: Standard deviation for initialization, if negative uses xavier. + dropout_keep_prob: dropout keep probability (not set if equals to None). + bn_decay: decay for the batch norm moving averages (not set if equals to + None). + + Returns: + An argument scope to use via arg_scope. + """ + # Note: do not introduce parameters that would change the inference + # model here (for example whether to use bias), modify conv_def instead. + batch_norm_params = { + 'decay': bn_decay, + 'is_training': is_training + } + if stddev < 0: + weight_intitializer = slim.initializers.xavier_initializer() + else: + weight_intitializer = tf.truncated_normal_initializer(stddev=stddev) + + # Set weight_decay for weights in Conv and FC layers. + with slim.arg_scope( + [slim.conv2d, slim.fully_connected, slim.separable_conv2d], + weights_initializer=weight_intitializer, + normalizer_fn=slim.batch_norm), \ + slim.arg_scope([mobilenet_base, mobilenet], is_training=is_training),\ + safe_arg_scope([slim.batch_norm], **batch_norm_params), \ + safe_arg_scope([slim.dropout], is_training=is_training, + keep_prob=dropout_keep_prob), \ + slim.arg_scope([slim.conv2d], \ + weights_regularizer=slim.l2_regularizer(weight_decay)), \ + slim.arg_scope([slim.separable_conv2d], weights_regularizer=None) as s: + return s diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet_example.ipynb b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet_example.ipynb new file mode 100644 index 0000000..a17880e --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet_example.ipynb @@ -0,0 +1,445 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "toc", + "id": "aUVxY7xOGD1G" + }, + "source": [ + "\u003e[Prerequisites (downloading tensorflow_models and checkpoints)](#scrollTo=T_cETKXHDTXu)\n", + "\n", + "\u003e[Checkpoint based inference](#scrollTo=fxMe7_pkk_Vo)\n", + "\n", + "\u003e[Frozen inference](#scrollTo=PlwvpK3ElBk6)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "T_cETKXHDTXu" + }, + "source": [ + "# Prerequisites (downloading tensorflow_models and checkpoints)" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab": { + "autoexec": { + "startup": false, + "wait_interval": 0 + }, + "base_uri": "https://localhost:8080/", + "height": 125, + "output_extras": [ + {} + ] + }, + "colab_type": "code", + "executionInfo": { + "elapsed": 31129, + "status": "ok", + "timestamp": 1521483961674, + "user": { + "displayName": "Mark Sandler", + "photoUrl": "//lh5.googleusercontent.com/-CjnV3zpGrlw/AAAAAAAAAAI/AAAAAAAABRU/dfjRy_tzX5M/s50-c-k-no/photo.jpg", + "userId": "108034853522252017283" + }, + "user_tz": 420 + }, + "id": "zo5GyseklSVH", + "outputId": "e12a8a80-c0d2-4ebc-9230-b170f11d236e" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cloning into 'models'...\n", + "remote: Counting objects: 13504, done.\u001b[K\n", + "remote: Total 13504 (delta 2), reused 2 (delta 2), pack-reused 13501\u001b[K\n", + "Receiving objects: 100% (13504/13504), 422.07 MiB | 37.42 MiB/s, done.\n", + "Resolving deltas: 100% (7635/7635), done.\n", + "Checking out files: 100% (1946/1946), done.\n" + ] + } + ], + "source": [ + "!git clone https://github.com/tensorflow/models" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "cellView": "both", + "colab": { + "autoexec": { + "startup": false, + "wait_interval": 0 + }, + "base_uri": "https://localhost:8080/", + "height": 35, + "output_extras": [ + {} + ] + }, + "colab_type": "code", + "executionInfo": { + "elapsed": 4504, + "status": "ok", + "timestamp": 1521493157017, + "user": { + "displayName": "Mark Sandler", + "photoUrl": "//lh5.googleusercontent.com/-CjnV3zpGrlw/AAAAAAAAAAI/AAAAAAAABRU/dfjRy_tzX5M/s50-c-k-no/photo.jpg", + "userId": "108034853522252017283" + }, + "user_tz": 420 + }, + "id": "obaW6O8bz3mA", + "outputId": "79b3fb23-caa7-4683-9575-ba7c2f55ebdb" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Successfully downloaded the checkpoint. It is available as mobilenet_v2_1.0_224.ckpt\n" + ] + } + ], + "source": [ + "from __future__ import print_function\n", + "from IPython import display \n", + "checkpoint_name = 'mobilenet_v2_1.0_224' #@param\n", + "url = 'https://storage.googleapis.com/mobilenet_v2/checkpoints/' + checkpoint_name + '.tgz'\n", + "print('Downloading from ', url)\n", + "!wget {url}\n", + "print('Unpacking')\n", + "!tar -xvf {base_name}.tgz\n", + "checkpoint = base_name + '.ckpt'\n", + "\n", + "display.clear_output()\n", + "print('Successfully downloaded checkpoint from ', url,\n", + " '. It is available as', checkpoint)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab": { + "autoexec": { + "startup": false, + "wait_interval": 0 + }, + "base_uri": "https://localhost:8080/", + "height": 215, + "output_extras": [ + {} + ] + }, + "colab_type": "code", + "executionInfo": { + "elapsed": 1486, + "status": "ok", + "timestamp": 1521485010457, + "user": { + "displayName": "Mark Sandler", + "photoUrl": "//lh5.googleusercontent.com/-CjnV3zpGrlw/AAAAAAAAAAI/AAAAAAAABRU/dfjRy_tzX5M/s50-c-k-no/photo.jpg", + "userId": "108034853522252017283" + }, + "user_tz": 420 + }, + "id": "qZDfLegf3hpw", + "outputId": "334ed084-b90e-4bd0-bd5e-125434a9a30f" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--2018-03-19 18:43:29-- https://upload.wikimedia.org/wikipedia/commons/f/fe/Giant_Panda_in_Beijing_Zoo_1.JPG\n", + "Resolving upload.wikimedia.org (upload.wikimedia.org)... 208.80.154.240, 2620:0:860:ed1a::2:b\n", + "Connecting to upload.wikimedia.org (upload.wikimedia.org)|208.80.154.240|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 116068 (113K) [image/jpeg]\n", + "Saving to: ‘panda.jpg’\n", + "\n", + "panda.jpg 100%[===================\u003e] 113.35K --.-KB/s in 0.03s \n", + "\n", + "2018-03-19 18:43:30 (3.18 MB/s) - ‘panda.jpg’ saved [116068/116068]\n", + "\n" + ] + } + ], + "source": [ + "!wget https://upload.wikimedia.org/wikipedia/commons/f/fe/Giant_Panda_in_Beijing_Zoo_1.JPG -O panda.jpg" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab": { + "autoexec": { + "startup": false, + "wait_interval": 0 + } + }, + "colab_type": "code", + "id": "g0H2RDadndug" + }, + "outputs": [], + "source": [ + "# setup path\n", + "import sys\n", + "sys.path.append('/content/models/research/slim')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "fxMe7_pkk_Vo" + }, + "source": [ + "# Checkpoint based inference" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab": { + "autoexec": { + "startup": false, + "wait_interval": 0 + } + }, + "colab_type": "code", + "id": "GrQemT66CxXt" + }, + "outputs": [], + "source": [ + "import tensorflow as tf\n", + "from nets.mobilenet import mobilenet_v2\n", + "\n", + "tf.reset_default_graph()\n", + "\n", + "# For simplicity we just decode jpeg inside tensorflow.\n", + "# But one can provide any input obviously.\n", + "file_input = tf.placeholder(tf.string, ())\n", + "\n", + "image = tf.image.decode_jpeg(tf.read_file(file_input))\n", + "\n", + "images = tf.expand_dims(image, 0)\n", + "images = tf.cast(images, tf.float32) / 128. - 1\n", + "images.set_shape((None, None, None, 3))\n", + "images = tf.image.resize_images(images, (224, 224))\n", + "\n", + "# Note: arg_scope is optional for inference.\n", + "with tf.contrib.slim.arg_scope(mobilenet_v2.training_scope(is_training=False)):\n", + " logits, endpoints = mobilenet_v2.mobilenet(images)\n", + " \n", + "# Restore using exponential moving average since it produces (1.5-2%) higher \n", + "# accuracy\n", + "ema = tf.train.ExponentialMovingAverage(0.999)\n", + "vars = ema.variables_to_restore()\n", + "\n", + "saver = tf.train.Saver(vars) " + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab": { + "autoexec": { + "startup": false, + "wait_interval": 0 + }, + "base_uri": "https://localhost:8080/", + "height": 666, + "output_extras": [ + {}, + {} + ] + }, + "colab_type": "code", + "executionInfo": { + "elapsed": 1422, + "status": "ok", + "timestamp": 1521493723379, + "user": { + "displayName": "Mark Sandler", + "photoUrl": "//lh5.googleusercontent.com/-CjnV3zpGrlw/AAAAAAAAAAI/AAAAAAAABRU/dfjRy_tzX5M/s50-c-k-no/photo.jpg", + "userId": "108034853522252017283" + }, + "user_tz": 420 + }, + "id": "TJbLYo_FCxXy", + "outputId": "17a4fbaa-dec0-4997-b233-15ba69806083" + }, + "outputs": [ + { + "data": { + "image/jpeg": "/9j/4AAQSkZJRgABAQEAYABgAAD/4SjTRXhpZgAASUkqAAgAAAAKAA8BAgASAAAAhgAAABABAgAK\nAAAAmAAAABIBAwABAAAAAAAAABoBBQABAAAAogAAABsBBQABAAAAqgAAACgBAwABAAAAAgAAADEB\nAgALAAAAsgAAADIBAgAUAAAAvgAAABMCAwABAAAAAgAAAGmHBAABAAAA0gAAAIwDAABOSUtPTiBD\nT1JQT1JBVElPTgBOSUtPTiBEODAALAEAAAEAAAAsAQAAAQAAAFBpY2FzYSAzLjAAADIwMDc6MTE6\nMTggMTM6MTM6MDcAKACaggUAAQAAALgCAACdggUAAQAAAMACAAAiiAMAAQAAAAIAAAAniAMAAQAA\nAEAGAAAAkAcABAAAADAyMjEDkAIAFAAAAMgCAAAEkAIAFAAAANwCAAABkQcABAAAAAECAwACkQUA\nAQAAAPACAAAEkgoAAQAAAPgCAAAFkgUAAQAAAAADAAAHkgMAAQAAAAIAAAAIkgMAAQAAAAAAAAAJ\nkgMAAQAAAAAAAAAKkgUAAQAAAAgDAACGkgcALAAAABADAACQkgIAAwAAADEwAACRkgIAAwAAADEw\nAACSkgIAAwAAADEwAAAAoAcABAAAADAxMDABoAMAAQAAAP//AAACoAMAAQAAALgCAAADoAMAAQAA\nAGUCAAAFoAQAAQAAAG4DAAAXogMAAQAAAAIAAAAAowcAAQAAAAMAAAABowcAAQAAAAEAAAACowcA\nCAAAADwDAAABpAMAAQAAAAAAAAACpAMAAQAAAAAAAAADpAMAAQAAAAAAAAAEpAUAAQAAAEQDAAAF\npAMAAQAAAEUAAAAGpAMAAQAAAAAAAAAHpAMAAQAAAAIAAAAIpAMAAQAAAAAAAAAJpAMAAQAAAAAA\nAAAKpAMAAQAAAAAAAAAMpAMAAQAAAAAAAAAgpAIAIQAAAEwDAAAAAAAACgAAAIgTAABuAAAACgAA\nADIwMDc6MTE6MTggMTM6MTM6MDcAMjAwNzoxMToxOCAxMzoxMzowNwACAAAAAQAAAAAAAAAGAAAA\nMAAAAAoAAADMAQAACgAAAEFTQ0lJAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\nICAgAAIAAgECAAEBAAAAAQAAAGQzMzk2MmE2YzhmOWMwZTZmNDY5ZmQ5OWQ3NmE0ZTFhAAACAAEA\n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\nsvj4Ejqg8oXv9K9VEKf/2Q==\n", + "text/plain": [ + "\u003cIPython.core.display.Image object\u003e" + ] + }, + "metadata": { + "tags": [] + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:tensorflow:Restoring parameters from mobilenet_v2_1.0_224.ckpt\n", + "Top 1 prediction: 389 giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca 0.90984344\n" + ] + } + ], + "source": [ + "from IPython import display\n", + "import pylab\n", + "from datasets import imagenet\n", + "import PIL\n", + "display.display(display.Image('panda.jpg'))\n", + "\n", + "with tf.Session() as sess:\n", + " saver.restore(sess, checkpoint)\n", + " x = endpoints['Predictions'].eval(feed_dict={file_input: 'panda.jpg'})\n", + "label_map = imagenet.create_readable_names_for_imagenet_labels() \n", + "print(\"Top 1 prediction: \", x.argmax(),label_map[x.argmax()], x.max())\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "PlwvpK3ElBk6" + }, + "source": [ + "# Frozen inference" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab": { + "autoexec": { + "startup": false, + "wait_interval": 0 + } + }, + "colab_type": "code", + "id": "o0BIbQUUlVrf" + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "img = np.array(PIL.Image.open('panda.jpg').resize((224, 224))).astype(np.float) / 128 - 1\n", + "gd = tf.GraphDef.FromString(open(base_name + '_frozen.pb', 'rb').read())\n", + "inp, predictions = tf.import_graph_def(gd, return_elements = ['input:0', 'MobilenetV2/Predictions/Reshape_1:0'])" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab": { + "autoexec": { + "startup": false, + "wait_interval": 0 + }, + "base_uri": "https://localhost:8080/", + "height": 35, + "output_extras": [ + {} + ] + }, + "colab_type": "code", + "executionInfo": { + "elapsed": 1350, + "status": "ok", + "timestamp": 1521493472822, + "user": { + "displayName": "Mark Sandler", + "photoUrl": "//lh5.googleusercontent.com/-CjnV3zpGrlw/AAAAAAAAAAI/AAAAAAAABRU/dfjRy_tzX5M/s50-c-k-no/photo.jpg", + "userId": "108034853522252017283" + }, + "user_tz": 420 + }, + "id": "qSU2h5NRlN7V", + "outputId": "4fb09105-b729-45c3-b5ef-83c8da30a215" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Top 1 Prediction: 389 giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca 0.9220208\n" + ] + } + ], + "source": [ + "with tf.Session(graph=inp.graph):\n", + " x = predictions.eval(feed_dict={inp: img.reshape(1, 224,224, 3)})\n", + "\n", + "label_map = imagenet.create_readable_names_for_imagenet_labels() \n", + "print(\"Top 1 Prediction: \", x.argmax(),label_map[x.argmax()], x.max())" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab": { + "autoexec": { + "startup": false, + "wait_interval": 0 + } + }, + "colab_type": "code", + "id": "CU8dJF8kCo6X" + }, + "outputs": [], + "source": [ + "" + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [ + "T_cETKXHDTXu" + ], + "default_view": {}, + "name": "Mobilenet Example.ipynb", + "provenance": [ + { + "file_id": "1ylt6hB0JlXmWU9Bm6O1zGKVPgc2csZf5", + "timestamp": 1521507068201 + } + ], + "version": "0.3.2", + "views": {} + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet_v2.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet_v2.py new file mode 100644 index 0000000..5bf4a13 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet_v2.py @@ -0,0 +1,216 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Implementation of Mobilenet V2. + +Architecture: https://arxiv.org/abs/1801.04381 + +The base model gives 72.2% accuracy on ImageNet, with 300MMadds, +3.4 M parameters. +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import copy +import functools + +import tensorflow as tf + +from nets.mobilenet import conv_blocks as ops +from nets.mobilenet import mobilenet as lib + +slim = tf.contrib.slim +op = lib.op + +expand_input = ops.expand_input_by_factor + +# pyformat: disable +# Architecture: https://arxiv.org/abs/1801.04381 +V2_DEF = dict( + defaults={ + # Note: these parameters of batch norm affect the architecture + # that's why they are here and not in training_scope. + (slim.batch_norm,): {'center': True, 'scale': True}, + (slim.conv2d, slim.fully_connected, slim.separable_conv2d): { + 'normalizer_fn': slim.batch_norm, 'activation_fn': tf.nn.relu6 + }, + (ops.expanded_conv,): { + 'expansion_size': expand_input(6), + 'split_expansion': 1, + 'normalizer_fn': slim.batch_norm, + 'residual': True + }, + (slim.conv2d, slim.separable_conv2d): {'padding': 'SAME'} + }, + spec=[ + op(slim.conv2d, stride=2, num_outputs=32, kernel_size=[3, 3]), + op(ops.expanded_conv, + expansion_size=expand_input(1, divisible_by=1), + num_outputs=16), + op(ops.expanded_conv, stride=2, num_outputs=24), + op(ops.expanded_conv, stride=1, num_outputs=24), + op(ops.expanded_conv, stride=2, num_outputs=32), + op(ops.expanded_conv, stride=1, num_outputs=32), + op(ops.expanded_conv, stride=1, num_outputs=32), + op(ops.expanded_conv, stride=2, num_outputs=64), + op(ops.expanded_conv, stride=1, num_outputs=64), + op(ops.expanded_conv, stride=1, num_outputs=64), + op(ops.expanded_conv, stride=1, num_outputs=64), + op(ops.expanded_conv, stride=1, num_outputs=96), + op(ops.expanded_conv, stride=1, num_outputs=96), + op(ops.expanded_conv, stride=1, num_outputs=96), + op(ops.expanded_conv, stride=2, num_outputs=160), + op(ops.expanded_conv, stride=1, num_outputs=160), + op(ops.expanded_conv, stride=1, num_outputs=160), + op(ops.expanded_conv, stride=1, num_outputs=320), + op(slim.conv2d, stride=1, kernel_size=[1, 1], num_outputs=1280) + ], +) +# pyformat: enable + + +@slim.add_arg_scope +def mobilenet(input_tensor, + num_classes=1001, + depth_multiplier=1.0, + scope='MobilenetV2', + conv_defs=None, + finegrain_classification_mode=False, + min_depth=None, + divisible_by=None, + activation_fn=None, + **kwargs): + """Creates mobilenet V2 network. + + Inference mode is created by default. To create training use training_scope + below. + + with tf.contrib.slim.arg_scope(mobilenet_v2.training_scope()): + logits, endpoints = mobilenet_v2.mobilenet(input_tensor) + + Args: + input_tensor: The input tensor + num_classes: number of classes + depth_multiplier: The multiplier applied to scale number of + channels in each layer. Note: this is called depth multiplier in the + paper but the name is kept for consistency with slim's model builder. + scope: Scope of the operator + conv_defs: Allows to override default conv def. + finegrain_classification_mode: When set to True, the model + will keep the last layer large even for small multipliers. Following + https://arxiv.org/abs/1801.04381 + suggests that it improves performance for ImageNet-type of problems. + *Note* ignored if final_endpoint makes the builder exit earlier. + min_depth: If provided, will ensure that all layers will have that + many channels after application of depth multiplier. + divisible_by: If provided will ensure that all layers # channels + will be divisible by this number. + activation_fn: Activation function to use, defaults to tf.nn.relu6 if not + specified. + **kwargs: passed directly to mobilenet.mobilenet: + prediction_fn- what prediction function to use. + reuse-: whether to reuse variables (if reuse set to true, scope + must be given). + Returns: + logits/endpoints pair + + Raises: + ValueError: On invalid arguments + """ + if conv_defs is None: + conv_defs = V2_DEF + if 'multiplier' in kwargs: + raise ValueError('mobilenetv2 doesn\'t support generic ' + 'multiplier parameter use "depth_multiplier" instead.') + if finegrain_classification_mode: + conv_defs = copy.deepcopy(conv_defs) + if depth_multiplier < 1: + conv_defs['spec'][-1].params['num_outputs'] /= depth_multiplier + if activation_fn: + conv_defs = copy.deepcopy(conv_defs) + defaults = conv_defs['defaults'] + conv_defaults = ( + defaults[(slim.conv2d, slim.fully_connected, slim.separable_conv2d)]) + conv_defaults['activation_fn'] = activation_fn + + depth_args = {} + # NB: do not set depth_args unless they are provided to avoid overriding + # whatever default depth_multiplier might have thanks to arg_scope. + if min_depth is not None: + depth_args['min_depth'] = min_depth + if divisible_by is not None: + depth_args['divisible_by'] = divisible_by + + with slim.arg_scope((lib.depth_multiplier,), **depth_args): + return lib.mobilenet( + input_tensor, + num_classes=num_classes, + conv_defs=conv_defs, + scope=scope, + multiplier=depth_multiplier, + **kwargs) + +mobilenet.default_image_size = 224 + + +def wrapped_partial(func, *args, **kwargs): + partial_func = functools.partial(func, *args, **kwargs) + functools.update_wrapper(partial_func, func) + return partial_func + + +# Wrappers for mobilenet v2 with depth-multipliers. Be noticed that +# 'finegrain_classification_mode' is set to True, which means the embedding +# layer will not be shrinked when given a depth-multiplier < 1.0. +mobilenet_v2_140 = wrapped_partial(mobilenet, depth_multiplier=1.4) +mobilenet_v2_050 = wrapped_partial(mobilenet, depth_multiplier=0.50, + finegrain_classification_mode=True) +mobilenet_v2_035 = wrapped_partial(mobilenet, depth_multiplier=0.35, + finegrain_classification_mode=True) + + +@slim.add_arg_scope +def mobilenet_base(input_tensor, depth_multiplier=1.0, **kwargs): + """Creates base of the mobilenet (no pooling and no logits) .""" + return mobilenet(input_tensor, + depth_multiplier=depth_multiplier, + base_only=True, **kwargs) + + +def training_scope(**kwargs): + """Defines MobilenetV2 training scope. + + Usage: + with tf.contrib.slim.arg_scope(mobilenet_v2.training_scope()): + logits, endpoints = mobilenet_v2.mobilenet(input_tensor) + + with slim. + + Args: + **kwargs: Passed to mobilenet.training_scope. The following parameters + are supported: + weight_decay- The weight decay to use for regularizing the model. + stddev- Standard deviation for initialization, if negative uses xavier. + dropout_keep_prob- dropout keep probability + bn_decay- decay for the batch norm moving averages. + + Returns: + An `arg_scope` to use for the mobilenet v2 model. + """ + return lib.training_scope(**kwargs) + + +__all__ = ['training_scope', 'mobilenet_base', 'mobilenet', 'V2_DEF'] diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet_v2_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet_v2_test.py new file mode 100644 index 0000000..7ce1993 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet/mobilenet_v2_test.py @@ -0,0 +1,189 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for mobilenet_v2.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +import copy +import tensorflow as tf +from nets.mobilenet import conv_blocks as ops +from nets.mobilenet import mobilenet +from nets.mobilenet import mobilenet_v2 + + +slim = tf.contrib.slim + + +def find_ops(optype): + """Find ops of a given type in graphdef or a graph. + + Args: + optype: operation type (e.g. Conv2D) + Returns: + List of operations. + """ + gd = tf.get_default_graph() + return [var for var in gd.get_operations() if var.type == optype] + + +class MobilenetV2Test(tf.test.TestCase): + + def setUp(self): + tf.reset_default_graph() + + def testCreation(self): + spec = dict(mobilenet_v2.V2_DEF) + _, ep = mobilenet.mobilenet( + tf.placeholder(tf.float32, (10, 224, 224, 16)), conv_defs=spec) + num_convs = len(find_ops('Conv2D')) + + # This is mostly a sanity test. No deep reason for these particular + # constants. + # + # All but first 2 and last one have two convolutions, and there is one + # extra conv that is not in the spec. (logits) + self.assertEqual(num_convs, len(spec['spec']) * 2 - 2) + # Check that depthwise are exposed. + for i in range(2, 17): + self.assertIn('layer_%d/depthwise_output' % i, ep) + + def testCreationNoClasses(self): + spec = copy.deepcopy(mobilenet_v2.V2_DEF) + net, ep = mobilenet.mobilenet( + tf.placeholder(tf.float32, (10, 224, 224, 16)), conv_defs=spec, + num_classes=None) + self.assertIs(net, ep['global_pool']) + + def testImageSizes(self): + for input_size, output_size in [(224, 7), (192, 6), (160, 5), + (128, 4), (96, 3)]: + tf.reset_default_graph() + _, ep = mobilenet_v2.mobilenet( + tf.placeholder(tf.float32, (10, input_size, input_size, 3))) + + self.assertEqual(ep['layer_18/output'].get_shape().as_list()[1:3], + [output_size] * 2) + + def testWithSplits(self): + spec = copy.deepcopy(mobilenet_v2.V2_DEF) + spec['overrides'] = { + (ops.expanded_conv,): dict(split_expansion=2), + } + _, _ = mobilenet.mobilenet( + tf.placeholder(tf.float32, (10, 224, 224, 16)), conv_defs=spec) + num_convs = len(find_ops('Conv2D')) + # All but 3 op has 3 conv operatore, the remainign 3 have one + # and there is one unaccounted. + self.assertEqual(num_convs, len(spec['spec']) * 3 - 5) + + def testWithOutputStride8(self): + out, _ = mobilenet.mobilenet_base( + tf.placeholder(tf.float32, (10, 224, 224, 16)), + conv_defs=mobilenet_v2.V2_DEF, + output_stride=8, + scope='MobilenetV2') + self.assertEqual(out.get_shape().as_list()[1:3], [28, 28]) + + def testDivisibleBy(self): + tf.reset_default_graph() + mobilenet_v2.mobilenet( + tf.placeholder(tf.float32, (10, 224, 224, 16)), + conv_defs=mobilenet_v2.V2_DEF, + divisible_by=16, + min_depth=32) + s = [op.outputs[0].get_shape().as_list()[-1] for op in find_ops('Conv2D')] + s = set(s) + self.assertSameElements([32, 64, 96, 160, 192, 320, 384, 576, 960, 1280, + 1001], s) + + def testDivisibleByWithArgScope(self): + tf.reset_default_graph() + # Verifies that depth_multiplier arg scope actually works + # if no default min_depth is provided. + with slim.arg_scope((mobilenet.depth_multiplier,), min_depth=32): + mobilenet_v2.mobilenet( + tf.placeholder(tf.float32, (10, 224, 224, 2)), + conv_defs=mobilenet_v2.V2_DEF, depth_multiplier=0.1) + s = [op.outputs[0].get_shape().as_list()[-1] for op in find_ops('Conv2D')] + s = set(s) + self.assertSameElements(s, [32, 192, 128, 1001]) + + def testFineGrained(self): + tf.reset_default_graph() + # Verifies that depth_multiplier arg scope actually works + # if no default min_depth is provided. + + mobilenet_v2.mobilenet( + tf.placeholder(tf.float32, (10, 224, 224, 2)), + conv_defs=mobilenet_v2.V2_DEF, depth_multiplier=0.01, + finegrain_classification_mode=True) + s = [op.outputs[0].get_shape().as_list()[-1] for op in find_ops('Conv2D')] + s = set(s) + # All convolutions will be 8->48, except for the last one. + self.assertSameElements(s, [8, 48, 1001, 1280]) + + def testMobilenetBase(self): + tf.reset_default_graph() + # Verifies that mobilenet_base returns pre-pooling layer. + with slim.arg_scope((mobilenet.depth_multiplier,), min_depth=32): + net, _ = mobilenet_v2.mobilenet_base( + tf.placeholder(tf.float32, (10, 224, 224, 16)), + conv_defs=mobilenet_v2.V2_DEF, depth_multiplier=0.1) + self.assertEqual(net.get_shape().as_list(), [10, 7, 7, 128]) + + def testWithOutputStride16(self): + tf.reset_default_graph() + out, _ = mobilenet.mobilenet_base( + tf.placeholder(tf.float32, (10, 224, 224, 16)), + conv_defs=mobilenet_v2.V2_DEF, + output_stride=16) + self.assertEqual(out.get_shape().as_list()[1:3], [14, 14]) + + def testWithOutputStride8AndExplicitPadding(self): + tf.reset_default_graph() + out, _ = mobilenet.mobilenet_base( + tf.placeholder(tf.float32, (10, 224, 224, 16)), + conv_defs=mobilenet_v2.V2_DEF, + output_stride=8, + use_explicit_padding=True, + scope='MobilenetV2') + self.assertEqual(out.get_shape().as_list()[1:3], [28, 28]) + + def testWithOutputStride16AndExplicitPadding(self): + tf.reset_default_graph() + out, _ = mobilenet.mobilenet_base( + tf.placeholder(tf.float32, (10, 224, 224, 16)), + conv_defs=mobilenet_v2.V2_DEF, + output_stride=16, + use_explicit_padding=True) + self.assertEqual(out.get_shape().as_list()[1:3], [14, 14]) + + def testBatchNormScopeDoesNotHaveIsTrainingWhenItsSetToNone(self): + sc = mobilenet.training_scope(is_training=None) + self.assertNotIn('is_training', sc[slim.arg_scope_func_key( + slim.batch_norm)]) + + def testBatchNormScopeDoesHasIsTrainingWhenItsNotNone(self): + sc = mobilenet.training_scope(is_training=False) + self.assertIn('is_training', sc[slim.arg_scope_func_key(slim.batch_norm)]) + sc = mobilenet.training_scope(is_training=True) + self.assertIn('is_training', sc[slim.arg_scope_func_key(slim.batch_norm)]) + sc = mobilenet.training_scope() + self.assertIn('is_training', sc[slim.arg_scope_func_key(slim.batch_norm)]) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1.md b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1.md new file mode 100644 index 0000000..94e91a5 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1.md @@ -0,0 +1,136 @@ +# Mobilenet_v2 +For Mobilenet V2 see this file [mobilenet/README.md] + +# MobileNet_v1 + +[MobileNets](https://arxiv.org/abs/1704.04861) are small, low-latency, low-power models parameterized to meet the resource constraints of a variety of use cases. They can be built upon for classification, detection, embeddings and segmentation similar to how other popular large scale models, such as Inception, are used. MobileNets can be run efficiently on mobile devices with [TensorFlow Mobile](https://www.tensorflow.org/mobile/). + +MobileNets trade off between latency, size and accuracy while comparing favorably with popular models from the literature. + +![alt text](mobilenet_v1.png "MobileNet Graph") + +# Pre-trained Models + +Choose the right MobileNet model to fit your latency and size budget. The size of the network in memory and on disk is proportional to the number of parameters. The latency and power usage of the network scales with the number of Multiply-Accumulates (MACs) which measures the number of fused Multiplication and Addition operations. These MobileNet models have been trained on the +[ILSVRC-2012-CLS](http://www.image-net.org/challenges/LSVRC/2012/) +image classification dataset. Accuracies were computed by evaluating using a single image crop. + +Model | Million MACs | Million Parameters | Top-1 Accuracy| Top-5 Accuracy | +:----:|:------------:|:----------:|:-------:|:-------:| +[MobileNet_v1_1.0_224](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_224.tgz)|569|4.24|70.9|89.9| +[MobileNet_v1_1.0_192](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_192.tgz)|418|4.24|70.0|89.2| +[MobileNet_v1_1.0_160](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_160.tgz)|291|4.24|68.0|87.7| +[MobileNet_v1_1.0_128](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_128.tgz)|186|4.24|65.2|85.8| +[MobileNet_v1_0.75_224](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.75_224.tgz)|317|2.59|68.4|88.2| +[MobileNet_v1_0.75_192](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.75_192.tgz)|233|2.59|67.2|87.3| +[MobileNet_v1_0.75_160](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.75_160.tgz)|162|2.59|65.3|86.0| +[MobileNet_v1_0.75_128](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.75_128.tgz)|104|2.59|62.1|83.9| +[MobileNet_v1_0.50_224](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.5_224.tgz)|150|1.34|63.3|84.9| +[MobileNet_v1_0.50_192](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.5_192.tgz)|110|1.34|61.7|83.6| +[MobileNet_v1_0.50_160](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.5_160.tgz)|77|1.34|59.1|81.9| +[MobileNet_v1_0.50_128](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.5_128.tgz)|49|1.34|56.3|79.4| +[MobileNet_v1_0.25_224](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.25_224.tgz)|41|0.47|49.8|74.2| +[MobileNet_v1_0.25_192](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.25_192.tgz)|34|0.47|47.7|72.3| +[MobileNet_v1_0.25_160](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.25_160.tgz)|21|0.47|45.5|70.3| +[MobileNet_v1_0.25_128](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.25_128.tgz)|14|0.47|41.5|66.3| +[MobileNet_v1_1.0_224_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_224_quant.tgz)|569|4.24|70.1|88.9| +[MobileNet_v1_1.0_192_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_192_quant.tgz)|418|4.24|69.2|88.3| +[MobileNet_v1_1.0_160_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_160_quant.tgz)|291|4.24|67.2|86.7| +[MobileNet_v1_1.0_128_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_128_quant.tgz)|186|4.24|63.4|84.2| +[MobileNet_v1_0.75_224_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.75_224_quant.tgz)|317|2.59|66.8|87.0| +[MobileNet_v1_0.75_192_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.75_192_quant.tgz)|233|2.59|66.1|86.4| +[MobileNet_v1_0.75_160_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.75_160_quant.tgz)|162|2.59|62.3|83.8| +[MobileNet_v1_0.75_128_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.75_128_quant.tgz)|104|2.59|55.8|78.8| +[MobileNet_v1_0.50_224_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.5_224_quant.tgz)|150|1.34|60.7|83.2| +[MobileNet_v1_0.50_192_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.5_192_quant.tgz)|110|1.34|60.0|82.2| +[MobileNet_v1_0.50_160_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.5_160_quant.tgz)|77|1.34|57.7|80.4| +[MobileNet_v1_0.50_128_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.5_128_quant.tgz)|49|1.34|54.5|77.7| +[MobileNet_v1_0.25_224_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.25_224_quant.tgz)|41|0.47|48.0|72.8| +[MobileNet_v1_0.25_192_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.25_192_quant.tgz)|34|0.47|46.0|71.2| +[MobileNet_v1_0.25_160_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.25_160_quant.tgz)|21|0.47|43.4|68.5| +[MobileNet_v1_0.25_128_quant](http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.25_128_quant.tgz)|14|0.47|39.5|64.4| + +Revisions to models: +* July 12, 2018: Update to TFLite models that fixes an accuracy issue resolved by making conversion support weights with narrow_range. We now report validation on the actual TensorFlow Lite model rather than the emulated quantization number of TensorFlow. +* August 2, 2018: Update to TFLite models that fixes an accuracy issue resolved by making sure the numerics of quantization match TF quantized training accurately. + +The linked model tar files contain the following: +* Trained model checkpoints +* Eval graph text protos (to be easily viewed) +* Frozen trained models +* Info file containing input and output information +* Converted [TensorFlow Lite](https://www.tensorflow.org/mobile/tflite/) flatbuffer model + +Note that quantized model GraphDefs are still float models, they just have FakeQuantization +operation embedded to simulate quantization. These are converted by [TensorFlow Lite](https://www.tensorflow.org/mobile/tflite/) +to be fully quantized. The final effect of quantization can be seen by comparing the frozen fake +quantized graph to the size of the TFLite flatbuffer, i.e. The TFLite flatbuffer is about 1/4 +the size. +For more information on the quantization techniques used here, see +[here](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/quantize). + +Here is an example of how to download the MobileNet_v1_1.0_224 checkpoint: + +```shell +$ CHECKPOINT_DIR=/tmp/checkpoints +$ mkdir ${CHECKPOINT_DIR} +$ wget http://download.tensorflow.org/models/mobilenet_v1_2018_02_22/mobilenet_v1_1.0_224.tgz +$ tar -xvf mobilenet_v1_1.0_224.tgz +$ mv mobilenet_v1_1.0_224.ckpt.* ${CHECKPOINT_DIR} +``` + +# MobileNet V1 scripts + +This package contains scripts for training floating point and eight-bit fixed +point TensorFlow models. + +Quantization tools used are described in [contrib/quantize](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/quantize). + +Conversion to fully quantized models for mobile can be done through [TensorFlow Lite](https://www.tensorflow.org/mobile/tflite/). + +## Usage + +### Build for GPU + +``` +$ bazel build -c opt --config=cuda mobilenet_v1_{eval,train} +``` + +### Running + +#### Float Training and Eval + +Train: + +``` +$ ./bazel-bin/mobilenet_v1_train --dataset_dir "path/to/dataset" --checkpoint_dir "path/to/checkpoints" +``` + +Eval: + +``` +$ ./bazel-bin/mobilenet_v1_eval --dataset_dir "path/to/dataset" --checkpoint_dir "path/to/checkpoints" +``` + +#### Quantized Training and Eval + +Train from preexisting float checkpoint: + +``` +$ ./bazel-bin/mobilenet_v1_train --dataset_dir "path/to/dataset" --checkpoint_dir "path/to/checkpoints" \ + --quantize=True --fine_tune_checkpoint=float/checkpoint/path +``` + +Train from scratch: + +``` +$ ./bazel-bin/mobilenet_v1_train --dataset_dir "path/to/dataset" --checkpoint_dir "path/to/checkpoints" --quantize=True +``` + +Eval: + +``` +$ ./bazel-bin/mobilenet_v1_eval --dataset_dir "path/to/dataset" --checkpoint_dir "path/to/checkpoints" --quantize=True +``` + +The resulting float and quantized models can be run on-device via [TensorFlow Lite](https://www.tensorflow.org/mobile/tflite/). diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1.png b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1.png new file mode 100644 index 0000000000000000000000000000000000000000..a458345174a12073a653e26d6747914a4e58e516 GIT binary patch literal 100916 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 z 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

28S;~r`@&Z*|%K=(VQZy942UO zhl$jx^mqjC;Dd(0xV6l>tAqrvc7L#RS_1PT%FG--rbqPfFb$ofS|y#BQ(9I)zR`7= z%IJ2RA1}?)&F<87$q>0qy!Up0R)hKy;WD&yGG>3bg<>)^WdF~MrGrvkz{ z#e0xj97Y4(nR(3XS9OM6SV~*-vfZq0L?mHasNT!3!&c2WhO<-!Eeu1CVvaBk>bUGfVUSkHEAc{ z7P`OQbzoRJ02BMB%ieQn4)MBzUaMz?KLakKcCA%j`GC3K`BSKFzdxfyvOH6PovYvG zhdPbVl%9Bhd)c=;NvBHqZ>A#j9XkBUOXhAF5QU%l7al*3;!Aw-Ng@bW`J^dWoP;2Zt0%=RmVB0k7b+{;?Gg>XMIHd)(PW4Mb-ic#2QX|=9gi`U4yZ-ckk0Yj zu4=T&2!dkyU6eqGOldh?rd0o0&@&g-3Ai!UF8odBiNZfO2&1P0fvDhOD(VywdwIe3 zd6+BN^?pjnR%RsKtELin^8kQbG}my17_7H5Egp#gzt>mWAQEsdK__I@ZJEu_XMGRN z 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 1). + """ + kernel_size_effective = [kernel_size[0] + (kernel_size[0] - 1) * (rate - 1), + kernel_size[0] + (kernel_size[0] - 1) * (rate - 1)] + pad_total = [kernel_size_effective[0] - 1, kernel_size_effective[1] - 1] + pad_beg = [pad_total[0] // 2, pad_total[1] // 2] + pad_end = [pad_total[0] - pad_beg[0], pad_total[1] - pad_beg[1]] + padded_inputs = tf.pad(inputs, [[0, 0], [pad_beg[0], pad_end[0]], + [pad_beg[1], pad_end[1]], [0, 0]]) + return padded_inputs + + +def mobilenet_v1_base(inputs, + final_endpoint='Conv2d_13_pointwise', + min_depth=8, + depth_multiplier=1.0, + conv_defs=None, + output_stride=None, + use_explicit_padding=False, + scope=None): + """Mobilenet v1. + + Constructs a Mobilenet v1 network from inputs to the given final endpoint. + + Args: + inputs: a tensor of shape [batch_size, height, width, channels]. + final_endpoint: specifies the endpoint to construct the network up to. It + can be one of ['Conv2d_0', 'Conv2d_1_pointwise', 'Conv2d_2_pointwise', + 'Conv2d_3_pointwise', 'Conv2d_4_pointwise', 'Conv2d_5'_pointwise, + 'Conv2d_6_pointwise', 'Conv2d_7_pointwise', 'Conv2d_8_pointwise', + 'Conv2d_9_pointwise', 'Conv2d_10_pointwise', 'Conv2d_11_pointwise', + 'Conv2d_12_pointwise', 'Conv2d_13_pointwise']. + min_depth: Minimum depth value (number of channels) for all convolution ops. + Enforced when depth_multiplier < 1, and not an active constraint when + depth_multiplier >= 1. + depth_multiplier: Float multiplier for the depth (number of channels) + for all convolution ops. The value must be greater than zero. Typical + usage will be to set this value in (0, 1) to reduce the number of + parameters or computation cost of the model. + conv_defs: A list of ConvDef namedtuples specifying the net architecture. + output_stride: An integer that specifies the requested ratio of input to + output spatial resolution. If not None, then we invoke atrous convolution + if necessary to prevent the network from reducing the spatial resolution + of the activation maps. Allowed values are 8 (accurate fully convolutional + mode), 16 (fast fully convolutional mode), 32 (classification mode). + use_explicit_padding: Use 'VALID' padding for convolutions, but prepad + inputs so that the output dimensions are the same as if 'SAME' padding + were used. + scope: Optional variable_scope. + + Returns: + tensor_out: output tensor corresponding to the final_endpoint. + end_points: a set of activations for external use, for example summaries or + losses. + + Raises: + ValueError: if final_endpoint is not set to one of the predefined values, + or depth_multiplier <= 0, or the target output_stride is not + allowed. + """ + depth = lambda d: max(int(d * depth_multiplier), min_depth) + end_points = {} + + # Used to find thinned depths for each layer. + if depth_multiplier <= 0: + raise ValueError('depth_multiplier is not greater than zero.') + + if conv_defs is None: + conv_defs = MOBILENETV1_CONV_DEFS + + if output_stride is not None and output_stride not in [8, 16, 32]: + raise ValueError('Only allowed output_stride values are 8, 16, 32.') + + padding = 'SAME' + if use_explicit_padding: + padding = 'VALID' + with tf.variable_scope(scope, 'MobilenetV1', [inputs]): + with slim.arg_scope([slim.conv2d, slim.separable_conv2d], padding=padding): + # The current_stride variable keeps track of the output stride of the + # activations, i.e., the running product of convolution strides up to the + # current network layer. This allows us to invoke atrous convolution + # whenever applying the next convolution would result in the activations + # having output stride larger than the target output_stride. + current_stride = 1 + + # The atrous convolution rate parameter. + rate = 1 + + net = inputs + for i, conv_def in enumerate(conv_defs): + end_point_base = 'Conv2d_%d' % i + + if output_stride is not None and current_stride == output_stride: + # If we have reached the target output_stride, then we need to employ + # atrous convolution with stride=1 and multiply the atrous rate by the + # current unit's stride for use in subsequent layers. + layer_stride = 1 + layer_rate = rate + rate *= conv_def.stride + else: + layer_stride = conv_def.stride + layer_rate = 1 + current_stride *= conv_def.stride + + if isinstance(conv_def, Conv): + end_point = end_point_base + if use_explicit_padding: + net = _fixed_padding(net, conv_def.kernel) + net = slim.conv2d(net, depth(conv_def.depth), conv_def.kernel, + stride=conv_def.stride, + scope=end_point) + end_points[end_point] = net + if end_point == final_endpoint: + return net, end_points + + elif isinstance(conv_def, DepthSepConv): + end_point = end_point_base + '_depthwise' + + # By passing filters=None + # separable_conv2d produces only a depthwise convolution layer + if use_explicit_padding: + net = _fixed_padding(net, conv_def.kernel, layer_rate) + net = slim.separable_conv2d(net, None, conv_def.kernel, + depth_multiplier=1, + stride=layer_stride, + rate=layer_rate, + scope=end_point) + + end_points[end_point] = net + if end_point == final_endpoint: + return net, end_points + + end_point = end_point_base + '_pointwise' + + net = slim.conv2d(net, depth(conv_def.depth), [1, 1], + stride=1, + scope=end_point) + + end_points[end_point] = net + if end_point == final_endpoint: + return net, end_points + else: + raise ValueError('Unknown convolution type %s for layer %d' + % (conv_def.ltype, i)) + raise ValueError('Unknown final endpoint %s' % final_endpoint) + + +def mobilenet_v1(inputs, + num_classes=1000, + dropout_keep_prob=0.999, + is_training=True, + min_depth=8, + depth_multiplier=1.0, + conv_defs=None, + prediction_fn=tf.contrib.layers.softmax, + spatial_squeeze=True, + reuse=None, + scope='MobilenetV1', + global_pool=False): + """Mobilenet v1 model for classification. + + Args: + inputs: a tensor of shape [batch_size, height, width, channels]. + num_classes: number of predicted classes. If 0 or None, the logits layer + is omitted and the input features to the logits layer (before dropout) + are returned instead. + dropout_keep_prob: the percentage of activation values that are retained. + is_training: whether is training or not. + min_depth: Minimum depth value (number of channels) for all convolution ops. + Enforced when depth_multiplier < 1, and not an active constraint when + depth_multiplier >= 1. + depth_multiplier: Float multiplier for the depth (number of channels) + for all convolution ops. The value must be greater than zero. Typical + usage will be to set this value in (0, 1) to reduce the number of + parameters or computation cost of the model. + conv_defs: A list of ConvDef namedtuples specifying the net architecture. + prediction_fn: a function to get predictions out of logits. + spatial_squeeze: if True, logits is of shape is [B, C], if false logits is + of shape [B, 1, 1, C], where B is batch_size and C is number of classes. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + global_pool: Optional boolean flag to control the avgpooling before the + logits layer. If false or unset, pooling is done with a fixed window + that reduces default-sized inputs to 1x1, while larger inputs lead to + larger outputs. If true, any input size is pooled down to 1x1. + + Returns: + net: a 2D Tensor with the logits (pre-softmax activations) if num_classes + is a non-zero integer, or the non-dropped-out input to the logits layer + if num_classes is 0 or None. + end_points: a dictionary from components of the network to the corresponding + activation. + + Raises: + ValueError: Input rank is invalid. + """ + input_shape = inputs.get_shape().as_list() + if len(input_shape) != 4: + raise ValueError('Invalid input tensor rank, expected 4, was: %d' % + len(input_shape)) + + with tf.variable_scope(scope, 'MobilenetV1', [inputs], reuse=reuse) as scope: + with slim.arg_scope([slim.batch_norm, slim.dropout], + is_training=is_training): + net, end_points = mobilenet_v1_base(inputs, scope=scope, + min_depth=min_depth, + depth_multiplier=depth_multiplier, + conv_defs=conv_defs) + with tf.variable_scope('Logits'): + if global_pool: + # Global average pooling. + net = tf.reduce_mean(net, [1, 2], keep_dims=True, name='global_pool') + end_points['global_pool'] = net + else: + # Pooling with a fixed kernel size. + kernel_size = _reduced_kernel_size_for_small_input(net, [7, 7]) + net = slim.avg_pool2d(net, kernel_size, padding='VALID', + scope='AvgPool_1a') + end_points['AvgPool_1a'] = net + if not num_classes: + return net, end_points + # 1 x 1 x 1024 + net = slim.dropout(net, keep_prob=dropout_keep_prob, scope='Dropout_1b') + logits = slim.conv2d(net, num_classes, [1, 1], activation_fn=None, + normalizer_fn=None, scope='Conv2d_1c_1x1') + if spatial_squeeze: + logits = tf.squeeze(logits, [1, 2], name='SpatialSqueeze') + end_points['Logits'] = logits + if prediction_fn: + end_points['Predictions'] = prediction_fn(logits, scope='Predictions') + return logits, end_points + +mobilenet_v1.default_image_size = 224 + + +def wrapped_partial(func, *args, **kwargs): + partial_func = functools.partial(func, *args, **kwargs) + functools.update_wrapper(partial_func, func) + return partial_func + + +mobilenet_v1_075 = wrapped_partial(mobilenet_v1, depth_multiplier=0.75) +mobilenet_v1_050 = wrapped_partial(mobilenet_v1, depth_multiplier=0.50) +mobilenet_v1_025 = wrapped_partial(mobilenet_v1, depth_multiplier=0.25) + + +def _reduced_kernel_size_for_small_input(input_tensor, kernel_size): + """Define kernel size which is automatically reduced for small input. + + If the shape of the input images is unknown at graph construction time this + function assumes that the input images are large enough. + + Args: + input_tensor: input tensor of size [batch_size, height, width, channels]. + kernel_size: desired kernel size of length 2: [kernel_height, kernel_width] + + Returns: + a tensor with the kernel size. + """ + shape = input_tensor.get_shape().as_list() + if shape[1] is None or shape[2] is None: + kernel_size_out = kernel_size + else: + kernel_size_out = [min(shape[1], kernel_size[0]), + min(shape[2], kernel_size[1])] + return kernel_size_out + + +def mobilenet_v1_arg_scope( + is_training=True, + weight_decay=0.00004, + stddev=0.09, + regularize_depthwise=False, + batch_norm_decay=0.9997, + batch_norm_epsilon=0.001, + batch_norm_updates_collections=tf.GraphKeys.UPDATE_OPS, + normalizer_fn=slim.batch_norm): + """Defines the default MobilenetV1 arg scope. + + Args: + is_training: Whether or not we're training the model. If this is set to + None, the parameter is not added to the batch_norm arg_scope. + weight_decay: The weight decay to use for regularizing the model. + stddev: The standard deviation of the trunctated normal weight initializer. + regularize_depthwise: Whether or not apply regularization on depthwise. + batch_norm_decay: Decay for batch norm moving average. + batch_norm_epsilon: Small float added to variance to avoid dividing by zero + in batch norm. + batch_norm_updates_collections: Collection for the update ops for + batch norm. + normalizer_fn: Normalization function to apply after convolution. + + Returns: + An `arg_scope` to use for the mobilenet v1 model. + """ + batch_norm_params = { + 'center': True, + 'scale': True, + 'decay': batch_norm_decay, + 'epsilon': batch_norm_epsilon, + 'updates_collections': batch_norm_updates_collections, + } + if is_training is not None: + batch_norm_params['is_training'] = is_training + + # Set weight_decay for weights in Conv and DepthSepConv layers. + weights_init = tf.truncated_normal_initializer(stddev=stddev) + regularizer = tf.contrib.layers.l2_regularizer(weight_decay) + if regularize_depthwise: + depthwise_regularizer = regularizer + else: + depthwise_regularizer = None + with slim.arg_scope([slim.conv2d, slim.separable_conv2d], + weights_initializer=weights_init, + activation_fn=tf.nn.relu6, normalizer_fn=normalizer_fn): + with slim.arg_scope([slim.batch_norm], **batch_norm_params): + with slim.arg_scope([slim.conv2d], weights_regularizer=regularizer): + with slim.arg_scope([slim.separable_conv2d], + weights_regularizer=depthwise_regularizer) as sc: + return sc diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1_eval.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1_eval.py new file mode 100644 index 0000000..5b42a38 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1_eval.py @@ -0,0 +1,152 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Validate mobilenet_v1 with options for quantization.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import math +import tensorflow as tf + +from datasets import dataset_factory +from nets import mobilenet_v1 +from preprocessing import preprocessing_factory + +slim = tf.contrib.slim + +flags = tf.app.flags + +flags.DEFINE_string('master', '', 'Session master') +flags.DEFINE_integer('batch_size', 250, 'Batch size') +flags.DEFINE_integer('num_classes', 1001, 'Number of classes to distinguish') +flags.DEFINE_integer('num_examples', 50000, 'Number of examples to evaluate') +flags.DEFINE_integer('image_size', 224, 'Input image resolution') +flags.DEFINE_float('depth_multiplier', 1.0, 'Depth multiplier for mobilenet') +flags.DEFINE_bool('quantize', False, 'Quantize training') +flags.DEFINE_string('checkpoint_dir', '', 'The directory for checkpoints') +flags.DEFINE_string('eval_dir', '', 'Directory for writing eval event logs') +flags.DEFINE_string('dataset_dir', '', 'Location of dataset') + +FLAGS = flags.FLAGS + + +def imagenet_input(is_training): + """Data reader for imagenet. + + Reads in imagenet data and performs pre-processing on the images. + + Args: + is_training: bool specifying if train or validation dataset is needed. + Returns: + A batch of images and labels. + """ + if is_training: + dataset = dataset_factory.get_dataset('imagenet', 'train', + FLAGS.dataset_dir) + else: + dataset = dataset_factory.get_dataset('imagenet', 'validation', + FLAGS.dataset_dir) + + provider = slim.dataset_data_provider.DatasetDataProvider( + dataset, + shuffle=is_training, + common_queue_capacity=2 * FLAGS.batch_size, + common_queue_min=FLAGS.batch_size) + [image, label] = provider.get(['image', 'label']) + + image_preprocessing_fn = preprocessing_factory.get_preprocessing( + 'mobilenet_v1', is_training=is_training) + + image = image_preprocessing_fn(image, FLAGS.image_size, FLAGS.image_size) + + images, labels = tf.train.batch( + tensors=[image, label], + batch_size=FLAGS.batch_size, + num_threads=4, + capacity=5 * FLAGS.batch_size) + return images, labels + + +def metrics(logits, labels): + """Specify the metrics for eval. + + Args: + logits: Logits output from the graph. + labels: Ground truth labels for inputs. + + Returns: + Eval Op for the graph. + """ + labels = tf.squeeze(labels) + names_to_values, names_to_updates = slim.metrics.aggregate_metric_map({ + 'Accuracy': tf.metrics.accuracy(tf.argmax(logits, 1), labels), + 'Recall_5': tf.metrics.recall_at_k(labels, logits, 5), + }) + for name, value in names_to_values.iteritems(): + slim.summaries.add_scalar_summary( + value, name, prefix='eval', print_summary=True) + return names_to_updates.values() + + +def build_model(): + """Build the mobilenet_v1 model for evaluation. + + Returns: + g: graph with rewrites after insertion of quantization ops and batch norm + folding. + eval_ops: eval ops for inference. + variables_to_restore: List of variables to restore from checkpoint. + """ + g = tf.Graph() + with g.as_default(): + inputs, labels = imagenet_input(is_training=False) + + scope = mobilenet_v1.mobilenet_v1_arg_scope( + is_training=False, weight_decay=0.0) + with slim.arg_scope(scope): + logits, _ = mobilenet_v1.mobilenet_v1( + inputs, + is_training=False, + depth_multiplier=FLAGS.depth_multiplier, + num_classes=FLAGS.num_classes) + + if FLAGS.quantize: + tf.contrib.quantize.create_eval_graph() + + eval_ops = metrics(logits, labels) + + return g, eval_ops + + +def eval_model(): + """Evaluates mobilenet_v1.""" + g, eval_ops = build_model() + with g.as_default(): + num_batches = math.ceil(FLAGS.num_examples / float(FLAGS.batch_size)) + slim.evaluation.evaluate_once( + FLAGS.master, + FLAGS.checkpoint_dir, + logdir=FLAGS.eval_dir, + num_evals=num_batches, + eval_op=eval_ops) + + +def main(unused_arg): + eval_model() + + +if __name__ == '__main__': + tf.app.run(main) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1_test.py new file mode 100644 index 0000000..669a3ae --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1_test.py @@ -0,0 +1,534 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================= +"""Tests for MobileNet v1.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import tensorflow as tf + +from nets import mobilenet_v1 + +slim = tf.contrib.slim + + +class MobilenetV1Test(tf.test.TestCase): + + def testBuildClassificationNetwork(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, end_points = mobilenet_v1.mobilenet_v1(inputs, num_classes) + self.assertTrue(logits.op.name.startswith( + 'MobilenetV1/Logits/SpatialSqueeze')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertTrue('Predictions' in end_points) + self.assertListEqual(end_points['Predictions'].get_shape().as_list(), + [batch_size, num_classes]) + + def testBuildPreLogitsNetwork(self): + batch_size = 5 + height, width = 224, 224 + num_classes = None + + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, end_points = mobilenet_v1.mobilenet_v1(inputs, num_classes) + self.assertTrue(net.op.name.startswith('MobilenetV1/Logits/AvgPool')) + self.assertListEqual(net.get_shape().as_list(), [batch_size, 1, 1, 1024]) + self.assertFalse('Logits' in end_points) + self.assertFalse('Predictions' in end_points) + + def testBuildBaseNetwork(self): + batch_size = 5 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, end_points = mobilenet_v1.mobilenet_v1_base(inputs) + self.assertTrue(net.op.name.startswith('MobilenetV1/Conv2d_13')) + self.assertListEqual(net.get_shape().as_list(), + [batch_size, 7, 7, 1024]) + expected_endpoints = ['Conv2d_0', + 'Conv2d_1_depthwise', 'Conv2d_1_pointwise', + 'Conv2d_2_depthwise', 'Conv2d_2_pointwise', + 'Conv2d_3_depthwise', 'Conv2d_3_pointwise', + 'Conv2d_4_depthwise', 'Conv2d_4_pointwise', + 'Conv2d_5_depthwise', 'Conv2d_5_pointwise', + 'Conv2d_6_depthwise', 'Conv2d_6_pointwise', + 'Conv2d_7_depthwise', 'Conv2d_7_pointwise', + 'Conv2d_8_depthwise', 'Conv2d_8_pointwise', + 'Conv2d_9_depthwise', 'Conv2d_9_pointwise', + 'Conv2d_10_depthwise', 'Conv2d_10_pointwise', + 'Conv2d_11_depthwise', 'Conv2d_11_pointwise', + 'Conv2d_12_depthwise', 'Conv2d_12_pointwise', + 'Conv2d_13_depthwise', 'Conv2d_13_pointwise'] + self.assertItemsEqual(end_points.keys(), expected_endpoints) + + def testBuildOnlyUptoFinalEndpoint(self): + batch_size = 5 + height, width = 224, 224 + endpoints = ['Conv2d_0', + 'Conv2d_1_depthwise', 'Conv2d_1_pointwise', + 'Conv2d_2_depthwise', 'Conv2d_2_pointwise', + 'Conv2d_3_depthwise', 'Conv2d_3_pointwise', + 'Conv2d_4_depthwise', 'Conv2d_4_pointwise', + 'Conv2d_5_depthwise', 'Conv2d_5_pointwise', + 'Conv2d_6_depthwise', 'Conv2d_6_pointwise', + 'Conv2d_7_depthwise', 'Conv2d_7_pointwise', + 'Conv2d_8_depthwise', 'Conv2d_8_pointwise', + 'Conv2d_9_depthwise', 'Conv2d_9_pointwise', + 'Conv2d_10_depthwise', 'Conv2d_10_pointwise', + 'Conv2d_11_depthwise', 'Conv2d_11_pointwise', + 'Conv2d_12_depthwise', 'Conv2d_12_pointwise', + 'Conv2d_13_depthwise', 'Conv2d_13_pointwise'] + for index, endpoint in enumerate(endpoints): + with tf.Graph().as_default(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + out_tensor, end_points = mobilenet_v1.mobilenet_v1_base( + inputs, final_endpoint=endpoint) + self.assertTrue(out_tensor.op.name.startswith( + 'MobilenetV1/' + endpoint)) + self.assertItemsEqual(endpoints[:index+1], end_points.keys()) + + def testBuildCustomNetworkUsingConvDefs(self): + batch_size = 5 + height, width = 224, 224 + conv_defs = [ + mobilenet_v1.Conv(kernel=[3, 3], stride=2, depth=32), + mobilenet_v1.DepthSepConv(kernel=[3, 3], stride=1, depth=64), + mobilenet_v1.DepthSepConv(kernel=[3, 3], stride=2, depth=128), + mobilenet_v1.DepthSepConv(kernel=[3, 3], stride=1, depth=512) + ] + + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, end_points = mobilenet_v1.mobilenet_v1_base( + inputs, final_endpoint='Conv2d_3_pointwise', conv_defs=conv_defs) + self.assertTrue(net.op.name.startswith('MobilenetV1/Conv2d_3')) + self.assertListEqual(net.get_shape().as_list(), + [batch_size, 56, 56, 512]) + expected_endpoints = ['Conv2d_0', + 'Conv2d_1_depthwise', 'Conv2d_1_pointwise', + 'Conv2d_2_depthwise', 'Conv2d_2_pointwise', + 'Conv2d_3_depthwise', 'Conv2d_3_pointwise'] + self.assertItemsEqual(end_points.keys(), expected_endpoints) + + def testBuildAndCheckAllEndPointsUptoConv2d_13(self): + batch_size = 5 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + with slim.arg_scope([slim.conv2d, slim.separable_conv2d], + normalizer_fn=slim.batch_norm): + _, end_points = mobilenet_v1.mobilenet_v1_base( + inputs, final_endpoint='Conv2d_13_pointwise') + _, explicit_padding_end_points = mobilenet_v1.mobilenet_v1_base( + inputs, final_endpoint='Conv2d_13_pointwise', + use_explicit_padding=True) + endpoints_shapes = {'Conv2d_0': [batch_size, 112, 112, 32], + 'Conv2d_1_depthwise': [batch_size, 112, 112, 32], + 'Conv2d_1_pointwise': [batch_size, 112, 112, 64], + 'Conv2d_2_depthwise': [batch_size, 56, 56, 64], + 'Conv2d_2_pointwise': [batch_size, 56, 56, 128], + 'Conv2d_3_depthwise': [batch_size, 56, 56, 128], + 'Conv2d_3_pointwise': [batch_size, 56, 56, 128], + 'Conv2d_4_depthwise': [batch_size, 28, 28, 128], + 'Conv2d_4_pointwise': [batch_size, 28, 28, 256], + 'Conv2d_5_depthwise': [batch_size, 28, 28, 256], + 'Conv2d_5_pointwise': [batch_size, 28, 28, 256], + 'Conv2d_6_depthwise': [batch_size, 14, 14, 256], + 'Conv2d_6_pointwise': [batch_size, 14, 14, 512], + 'Conv2d_7_depthwise': [batch_size, 14, 14, 512], + 'Conv2d_7_pointwise': [batch_size, 14, 14, 512], + 'Conv2d_8_depthwise': [batch_size, 14, 14, 512], + 'Conv2d_8_pointwise': [batch_size, 14, 14, 512], + 'Conv2d_9_depthwise': [batch_size, 14, 14, 512], + 'Conv2d_9_pointwise': [batch_size, 14, 14, 512], + 'Conv2d_10_depthwise': [batch_size, 14, 14, 512], + 'Conv2d_10_pointwise': [batch_size, 14, 14, 512], + 'Conv2d_11_depthwise': [batch_size, 14, 14, 512], + 'Conv2d_11_pointwise': [batch_size, 14, 14, 512], + 'Conv2d_12_depthwise': [batch_size, 7, 7, 512], + 'Conv2d_12_pointwise': [batch_size, 7, 7, 1024], + 'Conv2d_13_depthwise': [batch_size, 7, 7, 1024], + 'Conv2d_13_pointwise': [batch_size, 7, 7, 1024]} + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name, expected_shape in endpoints_shapes.items(): + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + self.assertItemsEqual(endpoints_shapes.keys(), + explicit_padding_end_points.keys()) + for endpoint_name, expected_shape in endpoints_shapes.items(): + self.assertTrue(endpoint_name in explicit_padding_end_points) + self.assertListEqual( + explicit_padding_end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testOutputStride16BuildAndCheckAllEndPointsUptoConv2d_13(self): + batch_size = 5 + height, width = 224, 224 + output_stride = 16 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + with slim.arg_scope([slim.conv2d, slim.separable_conv2d], + normalizer_fn=slim.batch_norm): + _, end_points = mobilenet_v1.mobilenet_v1_base( + inputs, output_stride=output_stride, + final_endpoint='Conv2d_13_pointwise') + _, explicit_padding_end_points = mobilenet_v1.mobilenet_v1_base( + inputs, output_stride=output_stride, + final_endpoint='Conv2d_13_pointwise', use_explicit_padding=True) + endpoints_shapes = {'Conv2d_0': [batch_size, 112, 112, 32], + 'Conv2d_1_depthwise': [batch_size, 112, 112, 32], + 'Conv2d_1_pointwise': [batch_size, 112, 112, 64], + 'Conv2d_2_depthwise': [batch_size, 56, 56, 64], + 'Conv2d_2_pointwise': [batch_size, 56, 56, 128], + 'Conv2d_3_depthwise': [batch_size, 56, 56, 128], + 'Conv2d_3_pointwise': [batch_size, 56, 56, 128], + 'Conv2d_4_depthwise': [batch_size, 28, 28, 128], + 'Conv2d_4_pointwise': [batch_size, 28, 28, 256], + 'Conv2d_5_depthwise': [batch_size, 28, 28, 256], + 'Conv2d_5_pointwise': [batch_size, 28, 28, 256], + 'Conv2d_6_depthwise': [batch_size, 14, 14, 256], + 'Conv2d_6_pointwise': [batch_size, 14, 14, 512], + 'Conv2d_7_depthwise': [batch_size, 14, 14, 512], + 'Conv2d_7_pointwise': [batch_size, 14, 14, 512], + 'Conv2d_8_depthwise': [batch_size, 14, 14, 512], + 'Conv2d_8_pointwise': [batch_size, 14, 14, 512], + 'Conv2d_9_depthwise': [batch_size, 14, 14, 512], + 'Conv2d_9_pointwise': [batch_size, 14, 14, 512], + 'Conv2d_10_depthwise': [batch_size, 14, 14, 512], + 'Conv2d_10_pointwise': [batch_size, 14, 14, 512], + 'Conv2d_11_depthwise': [batch_size, 14, 14, 512], + 'Conv2d_11_pointwise': [batch_size, 14, 14, 512], + 'Conv2d_12_depthwise': [batch_size, 14, 14, 512], + 'Conv2d_12_pointwise': [batch_size, 14, 14, 1024], + 'Conv2d_13_depthwise': [batch_size, 14, 14, 1024], + 'Conv2d_13_pointwise': [batch_size, 14, 14, 1024]} + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name, expected_shape in endpoints_shapes.items(): + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + self.assertItemsEqual(endpoints_shapes.keys(), + explicit_padding_end_points.keys()) + for endpoint_name, expected_shape in endpoints_shapes.items(): + self.assertTrue(endpoint_name in explicit_padding_end_points) + self.assertListEqual( + explicit_padding_end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testOutputStride8BuildAndCheckAllEndPointsUptoConv2d_13(self): + batch_size = 5 + height, width = 224, 224 + output_stride = 8 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + with slim.arg_scope([slim.conv2d, slim.separable_conv2d], + normalizer_fn=slim.batch_norm): + _, end_points = mobilenet_v1.mobilenet_v1_base( + inputs, output_stride=output_stride, + final_endpoint='Conv2d_13_pointwise') + _, explicit_padding_end_points = mobilenet_v1.mobilenet_v1_base( + inputs, output_stride=output_stride, + final_endpoint='Conv2d_13_pointwise', use_explicit_padding=True) + endpoints_shapes = {'Conv2d_0': [batch_size, 112, 112, 32], + 'Conv2d_1_depthwise': [batch_size, 112, 112, 32], + 'Conv2d_1_pointwise': [batch_size, 112, 112, 64], + 'Conv2d_2_depthwise': [batch_size, 56, 56, 64], + 'Conv2d_2_pointwise': [batch_size, 56, 56, 128], + 'Conv2d_3_depthwise': [batch_size, 56, 56, 128], + 'Conv2d_3_pointwise': [batch_size, 56, 56, 128], + 'Conv2d_4_depthwise': [batch_size, 28, 28, 128], + 'Conv2d_4_pointwise': [batch_size, 28, 28, 256], + 'Conv2d_5_depthwise': [batch_size, 28, 28, 256], + 'Conv2d_5_pointwise': [batch_size, 28, 28, 256], + 'Conv2d_6_depthwise': [batch_size, 28, 28, 256], + 'Conv2d_6_pointwise': [batch_size, 28, 28, 512], + 'Conv2d_7_depthwise': [batch_size, 28, 28, 512], + 'Conv2d_7_pointwise': [batch_size, 28, 28, 512], + 'Conv2d_8_depthwise': [batch_size, 28, 28, 512], + 'Conv2d_8_pointwise': [batch_size, 28, 28, 512], + 'Conv2d_9_depthwise': [batch_size, 28, 28, 512], + 'Conv2d_9_pointwise': [batch_size, 28, 28, 512], + 'Conv2d_10_depthwise': [batch_size, 28, 28, 512], + 'Conv2d_10_pointwise': [batch_size, 28, 28, 512], + 'Conv2d_11_depthwise': [batch_size, 28, 28, 512], + 'Conv2d_11_pointwise': [batch_size, 28, 28, 512], + 'Conv2d_12_depthwise': [batch_size, 28, 28, 512], + 'Conv2d_12_pointwise': [batch_size, 28, 28, 1024], + 'Conv2d_13_depthwise': [batch_size, 28, 28, 1024], + 'Conv2d_13_pointwise': [batch_size, 28, 28, 1024]} + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name, expected_shape in endpoints_shapes.items(): + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + self.assertItemsEqual(endpoints_shapes.keys(), + explicit_padding_end_points.keys()) + for endpoint_name, expected_shape in endpoints_shapes.items(): + self.assertTrue(endpoint_name in explicit_padding_end_points) + self.assertListEqual( + explicit_padding_end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testBuildAndCheckAllEndPointsApproximateFaceNet(self): + batch_size = 5 + height, width = 128, 128 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + with slim.arg_scope([slim.conv2d, slim.separable_conv2d], + normalizer_fn=slim.batch_norm): + _, end_points = mobilenet_v1.mobilenet_v1_base( + inputs, final_endpoint='Conv2d_13_pointwise', depth_multiplier=0.75) + _, explicit_padding_end_points = mobilenet_v1.mobilenet_v1_base( + inputs, final_endpoint='Conv2d_13_pointwise', depth_multiplier=0.75, + use_explicit_padding=True) + # For the Conv2d_0 layer FaceNet has depth=16 + endpoints_shapes = {'Conv2d_0': [batch_size, 64, 64, 24], + 'Conv2d_1_depthwise': [batch_size, 64, 64, 24], + 'Conv2d_1_pointwise': [batch_size, 64, 64, 48], + 'Conv2d_2_depthwise': [batch_size, 32, 32, 48], + 'Conv2d_2_pointwise': [batch_size, 32, 32, 96], + 'Conv2d_3_depthwise': [batch_size, 32, 32, 96], + 'Conv2d_3_pointwise': [batch_size, 32, 32, 96], + 'Conv2d_4_depthwise': [batch_size, 16, 16, 96], + 'Conv2d_4_pointwise': [batch_size, 16, 16, 192], + 'Conv2d_5_depthwise': [batch_size, 16, 16, 192], + 'Conv2d_5_pointwise': [batch_size, 16, 16, 192], + 'Conv2d_6_depthwise': [batch_size, 8, 8, 192], + 'Conv2d_6_pointwise': [batch_size, 8, 8, 384], + 'Conv2d_7_depthwise': [batch_size, 8, 8, 384], + 'Conv2d_7_pointwise': [batch_size, 8, 8, 384], + 'Conv2d_8_depthwise': [batch_size, 8, 8, 384], + 'Conv2d_8_pointwise': [batch_size, 8, 8, 384], + 'Conv2d_9_depthwise': [batch_size, 8, 8, 384], + 'Conv2d_9_pointwise': [batch_size, 8, 8, 384], + 'Conv2d_10_depthwise': [batch_size, 8, 8, 384], + 'Conv2d_10_pointwise': [batch_size, 8, 8, 384], + 'Conv2d_11_depthwise': [batch_size, 8, 8, 384], + 'Conv2d_11_pointwise': [batch_size, 8, 8, 384], + 'Conv2d_12_depthwise': [batch_size, 4, 4, 384], + 'Conv2d_12_pointwise': [batch_size, 4, 4, 768], + 'Conv2d_13_depthwise': [batch_size, 4, 4, 768], + 'Conv2d_13_pointwise': [batch_size, 4, 4, 768]} + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name, expected_shape in endpoints_shapes.items(): + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + self.assertItemsEqual(endpoints_shapes.keys(), + explicit_padding_end_points.keys()) + for endpoint_name, expected_shape in endpoints_shapes.items(): + self.assertTrue(endpoint_name in explicit_padding_end_points) + self.assertListEqual( + explicit_padding_end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testModelHasExpectedNumberOfParameters(self): + batch_size = 5 + height, width = 224, 224 + inputs = tf.random_uniform((batch_size, height, width, 3)) + with slim.arg_scope([slim.conv2d, slim.separable_conv2d], + normalizer_fn=slim.batch_norm): + mobilenet_v1.mobilenet_v1_base(inputs) + total_params, _ = slim.model_analyzer.analyze_vars( + slim.get_model_variables()) + self.assertAlmostEqual(3217920, total_params) + + def testBuildEndPointsWithDepthMultiplierLessThanOne(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = mobilenet_v1.mobilenet_v1(inputs, num_classes) + + endpoint_keys = [key for key in end_points.keys() if key.startswith('Conv')] + + _, end_points_with_multiplier = mobilenet_v1.mobilenet_v1( + inputs, num_classes, scope='depth_multiplied_net', + depth_multiplier=0.5) + + for key in endpoint_keys: + original_depth = end_points[key].get_shape().as_list()[3] + new_depth = end_points_with_multiplier[key].get_shape().as_list()[3] + self.assertEqual(0.5 * original_depth, new_depth) + + def testBuildEndPointsWithDepthMultiplierGreaterThanOne(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = mobilenet_v1.mobilenet_v1(inputs, num_classes) + + endpoint_keys = [key for key in end_points.keys() + if key.startswith('Mixed') or key.startswith('Conv')] + + _, end_points_with_multiplier = mobilenet_v1.mobilenet_v1( + inputs, num_classes, scope='depth_multiplied_net', + depth_multiplier=2.0) + + for key in endpoint_keys: + original_depth = end_points[key].get_shape().as_list()[3] + new_depth = end_points_with_multiplier[key].get_shape().as_list()[3] + self.assertEqual(2.0 * original_depth, new_depth) + + def testRaiseValueErrorWithInvalidDepthMultiplier(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + with self.assertRaises(ValueError): + _ = mobilenet_v1.mobilenet_v1( + inputs, num_classes, depth_multiplier=-0.1) + with self.assertRaises(ValueError): + _ = mobilenet_v1.mobilenet_v1( + inputs, num_classes, depth_multiplier=0.0) + + def testHalfSizeImages(self): + batch_size = 5 + height, width = 112, 112 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, end_points = mobilenet_v1.mobilenet_v1(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('MobilenetV1/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Conv2d_13_pointwise'] + self.assertListEqual(pre_pool.get_shape().as_list(), + [batch_size, 4, 4, 1024]) + + def testUnknownImageShape(self): + tf.reset_default_graph() + batch_size = 2 + height, width = 224, 224 + num_classes = 1000 + input_np = np.random.uniform(0, 1, (batch_size, height, width, 3)) + with self.test_session() as sess: + inputs = tf.placeholder(tf.float32, shape=(batch_size, None, None, 3)) + logits, end_points = mobilenet_v1.mobilenet_v1(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('MobilenetV1/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Conv2d_13_pointwise'] + feed_dict = {inputs: input_np} + tf.global_variables_initializer().run() + pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict) + self.assertListEqual(list(pre_pool_out.shape), [batch_size, 7, 7, 1024]) + + def testGlobalPoolUnknownImageShape(self): + tf.reset_default_graph() + batch_size = 1 + height, width = 250, 300 + num_classes = 1000 + input_np = np.random.uniform(0, 1, (batch_size, height, width, 3)) + with self.test_session() as sess: + inputs = tf.placeholder(tf.float32, shape=(batch_size, None, None, 3)) + logits, end_points = mobilenet_v1.mobilenet_v1(inputs, num_classes, + global_pool=True) + self.assertTrue(logits.op.name.startswith('MobilenetV1/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + pre_pool = end_points['Conv2d_13_pointwise'] + feed_dict = {inputs: input_np} + tf.global_variables_initializer().run() + pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict) + self.assertListEqual(list(pre_pool_out.shape), [batch_size, 8, 10, 1024]) + + def testUnknowBatchSize(self): + batch_size = 1 + height, width = 224, 224 + num_classes = 1000 + + inputs = tf.placeholder(tf.float32, (None, height, width, 3)) + logits, _ = mobilenet_v1.mobilenet_v1(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('MobilenetV1/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [None, num_classes]) + images = tf.random_uniform((batch_size, height, width, 3)) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(logits, {inputs: images.eval()}) + self.assertEquals(output.shape, (batch_size, num_classes)) + + def testEvaluation(self): + batch_size = 2 + height, width = 224, 224 + num_classes = 1000 + + eval_inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = mobilenet_v1.mobilenet_v1(eval_inputs, num_classes, + is_training=False) + predictions = tf.argmax(logits, 1) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (batch_size,)) + + def testTrainEvalWithReuse(self): + train_batch_size = 5 + eval_batch_size = 2 + height, width = 150, 150 + num_classes = 1000 + + train_inputs = tf.random_uniform((train_batch_size, height, width, 3)) + mobilenet_v1.mobilenet_v1(train_inputs, num_classes) + eval_inputs = tf.random_uniform((eval_batch_size, height, width, 3)) + logits, _ = mobilenet_v1.mobilenet_v1(eval_inputs, num_classes, + reuse=True) + predictions = tf.argmax(logits, 1) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (eval_batch_size,)) + + def testLogitsNotSqueezed(self): + num_classes = 25 + images = tf.random_uniform([1, 224, 224, 3]) + logits, _ = mobilenet_v1.mobilenet_v1(images, + num_classes=num_classes, + spatial_squeeze=False) + + with self.test_session() as sess: + tf.global_variables_initializer().run() + logits_out = sess.run(logits) + self.assertListEqual(list(logits_out.shape), [1, 1, 1, num_classes]) + + def testBatchNormScopeDoesNotHaveIsTrainingWhenItsSetToNone(self): + sc = mobilenet_v1.mobilenet_v1_arg_scope(is_training=None) + self.assertNotIn('is_training', sc[slim.arg_scope_func_key( + slim.batch_norm)]) + + def testBatchNormScopeDoesHasIsTrainingWhenItsNotNone(self): + sc = mobilenet_v1.mobilenet_v1_arg_scope(is_training=True) + self.assertIn('is_training', sc[slim.arg_scope_func_key(slim.batch_norm)]) + sc = mobilenet_v1.mobilenet_v1_arg_scope(is_training=False) + self.assertIn('is_training', sc[slim.arg_scope_func_key(slim.batch_norm)]) + sc = mobilenet_v1.mobilenet_v1_arg_scope() + self.assertIn('is_training', sc[slim.arg_scope_func_key(slim.batch_norm)]) + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1_train.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1_train.py new file mode 100644 index 0000000..f8328aa --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/mobilenet_v1_train.py @@ -0,0 +1,212 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Build and train mobilenet_v1 with options for quantization.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from datasets import dataset_factory +from nets import mobilenet_v1 +from preprocessing import preprocessing_factory + +slim = tf.contrib.slim + +flags = tf.app.flags + +flags.DEFINE_string('master', '', 'Session master') +flags.DEFINE_integer('task', 0, 'Task') +flags.DEFINE_integer('ps_tasks', 0, 'Number of ps') +flags.DEFINE_integer('batch_size', 64, 'Batch size') +flags.DEFINE_integer('num_classes', 1001, 'Number of classes to distinguish') +flags.DEFINE_integer('number_of_steps', None, + 'Number of training steps to perform before stopping') +flags.DEFINE_integer('image_size', 224, 'Input image resolution') +flags.DEFINE_float('depth_multiplier', 1.0, 'Depth multiplier for mobilenet') +flags.DEFINE_bool('quantize', False, 'Quantize training') +flags.DEFINE_string('fine_tune_checkpoint', '', + 'Checkpoint from which to start finetuning.') +flags.DEFINE_string('checkpoint_dir', '', + 'Directory for writing training checkpoints and logs') +flags.DEFINE_string('dataset_dir', '', 'Location of dataset') +flags.DEFINE_integer('log_every_n_steps', 100, 'Number of steps per log') +flags.DEFINE_integer('save_summaries_secs', 100, + 'How often to save summaries, secs') +flags.DEFINE_integer('save_interval_secs', 100, + 'How often to save checkpoints, secs') + +FLAGS = flags.FLAGS + +_LEARNING_RATE_DECAY_FACTOR = 0.94 + + +def get_learning_rate(): + if FLAGS.fine_tune_checkpoint: + # If we are fine tuning a checkpoint we need to start at a lower learning + # rate since we are farther along on training. + return 1e-4 + else: + return 0.045 + + +def get_quant_delay(): + if FLAGS.fine_tune_checkpoint: + # We can start quantizing immediately if we are finetuning. + return 0 + else: + # We need to wait for the model to train a bit before we quantize if we are + # training from scratch. + return 250000 + + +def imagenet_input(is_training): + """Data reader for imagenet. + + Reads in imagenet data and performs pre-processing on the images. + + Args: + is_training: bool specifying if train or validation dataset is needed. + Returns: + A batch of images and labels. + """ + if is_training: + dataset = dataset_factory.get_dataset('imagenet', 'train', + FLAGS.dataset_dir) + else: + dataset = dataset_factory.get_dataset('imagenet', 'validation', + FLAGS.dataset_dir) + + provider = slim.dataset_data_provider.DatasetDataProvider( + dataset, + shuffle=is_training, + common_queue_capacity=2 * FLAGS.batch_size, + common_queue_min=FLAGS.batch_size) + [image, label] = provider.get(['image', 'label']) + + image_preprocessing_fn = preprocessing_factory.get_preprocessing( + 'mobilenet_v1', is_training=is_training) + + image = image_preprocessing_fn(image, FLAGS.image_size, FLAGS.image_size) + + images, labels = tf.train.batch( + [image, label], + batch_size=FLAGS.batch_size, + num_threads=4, + capacity=5 * FLAGS.batch_size) + labels = slim.one_hot_encoding(labels, FLAGS.num_classes) + return images, labels + + +def build_model(): + """Builds graph for model to train with rewrites for quantization. + + Returns: + g: Graph with fake quantization ops and batch norm folding suitable for + training quantized weights. + train_tensor: Train op for execution during training. + """ + g = tf.Graph() + with g.as_default(), tf.device( + tf.train.replica_device_setter(FLAGS.ps_tasks)): + inputs, labels = imagenet_input(is_training=True) + with slim.arg_scope(mobilenet_v1.mobilenet_v1_arg_scope(is_training=True)): + logits, _ = mobilenet_v1.mobilenet_v1( + inputs, + is_training=True, + depth_multiplier=FLAGS.depth_multiplier, + num_classes=FLAGS.num_classes) + + tf.losses.softmax_cross_entropy(labels, logits) + + # Call rewriter to produce graph with fake quant ops and folded batch norms + # quant_delay delays start of quantization till quant_delay steps, allowing + # for better model accuracy. + if FLAGS.quantize: + tf.contrib.quantize.create_training_graph(quant_delay=get_quant_delay()) + + total_loss = tf.losses.get_total_loss(name='total_loss') + # Configure the learning rate using an exponential decay. + num_epochs_per_decay = 2.5 + imagenet_size = 1271167 + decay_steps = int(imagenet_size / FLAGS.batch_size * num_epochs_per_decay) + + learning_rate = tf.train.exponential_decay( + get_learning_rate(), + tf.train.get_or_create_global_step(), + decay_steps, + _LEARNING_RATE_DECAY_FACTOR, + staircase=True) + opt = tf.train.GradientDescentOptimizer(learning_rate) + + train_tensor = slim.learning.create_train_op( + total_loss, + optimizer=opt) + + slim.summaries.add_scalar_summary(total_loss, 'total_loss', 'losses') + slim.summaries.add_scalar_summary(learning_rate, 'learning_rate', 'training') + return g, train_tensor + + +def get_checkpoint_init_fn(): + """Returns the checkpoint init_fn if the checkpoint is provided.""" + if FLAGS.fine_tune_checkpoint: + variables_to_restore = slim.get_variables_to_restore() + global_step_reset = tf.assign(tf.train.get_or_create_global_step(), 0) + # When restoring from a floating point model, the min/max values for + # quantized weights and activations are not present. + # We instruct slim to ignore variables that are missing during restoration + # by setting ignore_missing_vars=True + slim_init_fn = slim.assign_from_checkpoint_fn( + FLAGS.fine_tune_checkpoint, + variables_to_restore, + ignore_missing_vars=True) + + def init_fn(sess): + slim_init_fn(sess) + # If we are restoring from a floating point model, we need to initialize + # the global step to zero for the exponential decay to result in + # reasonable learning rates. + sess.run(global_step_reset) + return init_fn + else: + return None + + +def train_model(): + """Trains mobilenet_v1.""" + g, train_tensor = build_model() + with g.as_default(): + slim.learning.train( + train_tensor, + FLAGS.checkpoint_dir, + is_chief=(FLAGS.task == 0), + master=FLAGS.master, + log_every_n_steps=FLAGS.log_every_n_steps, + graph=g, + number_of_steps=FLAGS.number_of_steps, + save_summaries_secs=FLAGS.save_summaries_secs, + save_interval_secs=FLAGS.save_interval_secs, + init_fn=get_checkpoint_init_fn(), + global_step=tf.train.get_global_step()) + + +def main(unused_arg): + train_model() + + +if __name__ == '__main__': + tf.app.run(main) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/README.md b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/README.md new file mode 100644 index 0000000..3955ad1 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/README.md @@ -0,0 +1,64 @@ +# TensorFlow-Slim NASNet-A Implementation/Checkpoints +This directory contains the code for the NASNet-A model from the paper +[Learning Transferable Architectures for Scalable Image Recognition](https://arxiv.org/abs/1707.07012) by Zoph et al. +In nasnet.py there are three different configurations of NASNet-A that are implementented. One of the models is the NASNet-A built for CIFAR-10 and the +other two are variants of NASNet-A trained on ImageNet, which are listed below. + +# Pre-Trained Models +Two NASNet-A checkpoints are available that have been trained on the +[ILSVRC-2012-CLS](http://www.image-net.org/challenges/LSVRC/2012/) +image classification dataset. Accuracies were computed by evaluating using a single image crop. + +Model Checkpoint | Million MACs | Million Parameters | Top-1 Accuracy| Top-5 Accuracy | +:----:|:------------:|:----------:|:-------:|:-------:| +[NASNet-A_Mobile_224](https://storage.googleapis.com/download.tensorflow.org/models/nasnet-a_mobile_04_10_2017.tar.gz)|564|5.3|74.0|91.6| +[NASNet-A_Large_331](https://storage.googleapis.com/download.tensorflow.org/models/nasnet-a_large_04_10_2017.tar.gz)|23800|88.9|82.7|96.2| + + +Here is an example of how to download the NASNet-A_Mobile_224 checkpoint. The way to download the NASNet-A_Large_331 is the same. + +```shell +CHECKPOINT_DIR=/tmp/checkpoints +mkdir ${CHECKPOINT_DIR} +cd ${CHECKPOINT_DIR} +wget https://storage.googleapis.com/download.tensorflow.org/models/nasnet-a_mobile_04_10_2017.tar.gz +tar -xvf nasnet-a_mobile_04_10_2017.tar.gz +rm nasnet-a_mobile_04_10_2017.tar.gz +``` +More information on integrating NASNet Models into your project can be found at the [TF-Slim Image Classification Library](https://github.com/tensorflow/models/blob/master/research/slim/README.md). + +To get started running models on-device go to [TensorFlow Mobile](https://www.tensorflow.org/mobile/). + +## Sample Commands for using NASNet-A Mobile and Large Checkpoints for Inference +------- +Run eval with the NASNet-A mobile ImageNet model + +```shell +DATASET_DIR=/tmp/imagenet +EVAL_DIR=/tmp/tfmodel/eval +CHECKPOINT_DIR=/tmp/checkpoints/model.ckpt +python tensorflow_models/research/slim/eval_image_classifier \ +--checkpoint_path=${CHECKPOINT_DIR} \ +--eval_dir=${EVAL_DIR} \ +--dataset_dir=${DATASET_DIR} \ +--dataset_name=imagenet \ +--dataset_split_name=validation \ +--model_name=nasnet_mobile \ +--eval_image_size=224 +``` + +Run eval with the NASNet-A large ImageNet model + +```shell +DATASET_DIR=/tmp/imagenet +EVAL_DIR=/tmp/tfmodel/eval +CHECKPOINT_DIR=/tmp/checkpoints/model.ckpt +python tensorflow_models/research/slim/eval_image_classifier \ +--checkpoint_path=${CHECKPOINT_DIR} \ +--eval_dir=${EVAL_DIR} \ +--dataset_dir=${DATASET_DIR} \ +--dataset_name=imagenet \ +--dataset_split_name=validation \ +--model_name=nasnet_large \ +--eval_image_size=331 +``` diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/__init__.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/__init__.py @@ -0,0 +1 @@ + diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet.py new file mode 100644 index 0000000..a5dc0dc --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet.py @@ -0,0 +1,547 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains the definition for the NASNet classification networks. + +Paper: https://arxiv.org/abs/1707.07012 +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import copy +import tensorflow as tf + +from nets.nasnet import nasnet_utils + +arg_scope = tf.contrib.framework.arg_scope +slim = tf.contrib.slim + + +# Notes for training NASNet Cifar Model +# ------------------------------------- +# batch_size: 32 +# learning rate: 0.025 +# cosine (single period) learning rate decay +# auxiliary head loss weighting: 0.4 +# clip global norm of all gradients by 5 +def cifar_config(): + return tf.contrib.training.HParams( + stem_multiplier=3.0, + drop_path_keep_prob=0.6, + num_cells=18, + use_aux_head=1, + num_conv_filters=32, + dense_dropout_keep_prob=1.0, + filter_scaling_rate=2.0, + num_reduction_layers=2, + data_format='NHWC', + skip_reduction_layer_input=0, + # 600 epochs with a batch size of 32 + # This is used for the drop path probabilities since it needs to increase + # the drop out probability over the course of training. + total_training_steps=937500, + use_bounded_activation=False, + ) + + +# Notes for training large NASNet model on ImageNet +# ------------------------------------- +# batch size (per replica): 16 +# learning rate: 0.015 * 100 +# learning rate decay factor: 0.97 +# num epochs per decay: 2.4 +# sync sgd with 100 replicas +# auxiliary head loss weighting: 0.4 +# label smoothing: 0.1 +# clip global norm of all gradients by 10 +def large_imagenet_config(): + return tf.contrib.training.HParams( + stem_multiplier=3.0, + dense_dropout_keep_prob=0.5, + num_cells=18, + filter_scaling_rate=2.0, + num_conv_filters=168, + drop_path_keep_prob=0.7, + use_aux_head=1, + num_reduction_layers=2, + data_format='NHWC', + skip_reduction_layer_input=1, + total_training_steps=250000, + use_bounded_activation=False, + ) + + +# Notes for training the mobile NASNet ImageNet model +# ------------------------------------- +# batch size (per replica): 32 +# learning rate: 0.04 * 50 +# learning rate scaling factor: 0.97 +# num epochs per decay: 2.4 +# sync sgd with 50 replicas +# auxiliary head weighting: 0.4 +# label smoothing: 0.1 +# clip global norm of all gradients by 10 +def mobile_imagenet_config(): + return tf.contrib.training.HParams( + stem_multiplier=1.0, + dense_dropout_keep_prob=0.5, + num_cells=12, + filter_scaling_rate=2.0, + drop_path_keep_prob=1.0, + num_conv_filters=44, + use_aux_head=1, + num_reduction_layers=2, + data_format='NHWC', + skip_reduction_layer_input=0, + total_training_steps=250000, + use_bounded_activation=False, + ) + + +def _update_hparams(hparams, is_training): + """Update hparams for given is_training option.""" + if not is_training: + hparams.set_hparam('drop_path_keep_prob', 1.0) + + +def nasnet_cifar_arg_scope(weight_decay=5e-4, + batch_norm_decay=0.9, + batch_norm_epsilon=1e-5): + """Defines the default arg scope for the NASNet-A Cifar model. + + Args: + weight_decay: The weight decay to use for regularizing the model. + batch_norm_decay: Decay for batch norm moving average. + batch_norm_epsilon: Small float added to variance to avoid dividing by zero + in batch norm. + + Returns: + An `arg_scope` to use for the NASNet Cifar Model. + """ + batch_norm_params = { + # Decay for the moving averages. + 'decay': batch_norm_decay, + # epsilon to prevent 0s in variance. + 'epsilon': batch_norm_epsilon, + 'scale': True, + 'fused': True, + } + weights_regularizer = tf.contrib.layers.l2_regularizer(weight_decay) + weights_initializer = tf.contrib.layers.variance_scaling_initializer( + mode='FAN_OUT') + with arg_scope([slim.fully_connected, slim.conv2d, slim.separable_conv2d], + weights_regularizer=weights_regularizer, + weights_initializer=weights_initializer): + with arg_scope([slim.fully_connected], + activation_fn=None, scope='FC'): + with arg_scope([slim.conv2d, slim.separable_conv2d], + activation_fn=None, biases_initializer=None): + with arg_scope([slim.batch_norm], **batch_norm_params) as sc: + return sc + + +def nasnet_mobile_arg_scope(weight_decay=4e-5, + batch_norm_decay=0.9997, + batch_norm_epsilon=1e-3): + """Defines the default arg scope for the NASNet-A Mobile ImageNet model. + + Args: + weight_decay: The weight decay to use for regularizing the model. + batch_norm_decay: Decay for batch norm moving average. + batch_norm_epsilon: Small float added to variance to avoid dividing by zero + in batch norm. + + Returns: + An `arg_scope` to use for the NASNet Mobile Model. + """ + batch_norm_params = { + # Decay for the moving averages. + 'decay': batch_norm_decay, + # epsilon to prevent 0s in variance. + 'epsilon': batch_norm_epsilon, + 'scale': True, + 'fused': True, + } + weights_regularizer = tf.contrib.layers.l2_regularizer(weight_decay) + weights_initializer = tf.contrib.layers.variance_scaling_initializer( + mode='FAN_OUT') + with arg_scope([slim.fully_connected, slim.conv2d, slim.separable_conv2d], + weights_regularizer=weights_regularizer, + weights_initializer=weights_initializer): + with arg_scope([slim.fully_connected], + activation_fn=None, scope='FC'): + with arg_scope([slim.conv2d, slim.separable_conv2d], + activation_fn=None, biases_initializer=None): + with arg_scope([slim.batch_norm], **batch_norm_params) as sc: + return sc + + +def nasnet_large_arg_scope(weight_decay=5e-5, + batch_norm_decay=0.9997, + batch_norm_epsilon=1e-3): + """Defines the default arg scope for the NASNet-A Large ImageNet model. + + Args: + weight_decay: The weight decay to use for regularizing the model. + batch_norm_decay: Decay for batch norm moving average. + batch_norm_epsilon: Small float added to variance to avoid dividing by zero + in batch norm. + + Returns: + An `arg_scope` to use for the NASNet Large Model. + """ + batch_norm_params = { + # Decay for the moving averages. + 'decay': batch_norm_decay, + # epsilon to prevent 0s in variance. + 'epsilon': batch_norm_epsilon, + 'scale': True, + 'fused': True, + } + weights_regularizer = tf.contrib.layers.l2_regularizer(weight_decay) + weights_initializer = tf.contrib.layers.variance_scaling_initializer( + mode='FAN_OUT') + with arg_scope([slim.fully_connected, slim.conv2d, slim.separable_conv2d], + weights_regularizer=weights_regularizer, + weights_initializer=weights_initializer): + with arg_scope([slim.fully_connected], + activation_fn=None, scope='FC'): + with arg_scope([slim.conv2d, slim.separable_conv2d], + activation_fn=None, biases_initializer=None): + with arg_scope([slim.batch_norm], **batch_norm_params) as sc: + return sc + + +def _build_aux_head(net, end_points, num_classes, hparams, scope): + """Auxiliary head used for all models across all datasets.""" + activation_fn = tf.nn.relu6 if hparams.use_bounded_activation else tf.nn.relu + with tf.variable_scope(scope): + aux_logits = tf.identity(net) + with tf.variable_scope('aux_logits'): + aux_logits = slim.avg_pool2d( + aux_logits, [5, 5], stride=3, padding='VALID') + aux_logits = slim.conv2d(aux_logits, 128, [1, 1], scope='proj') + aux_logits = slim.batch_norm(aux_logits, scope='aux_bn0') + aux_logits = activation_fn(aux_logits) + # Shape of feature map before the final layer. + shape = aux_logits.shape + if hparams.data_format == 'NHWC': + shape = shape[1:3] + else: + shape = shape[2:4] + aux_logits = slim.conv2d(aux_logits, 768, shape, padding='VALID') + aux_logits = slim.batch_norm(aux_logits, scope='aux_bn1') + aux_logits = activation_fn(aux_logits) + aux_logits = tf.contrib.layers.flatten(aux_logits) + aux_logits = slim.fully_connected(aux_logits, num_classes) + end_points['AuxLogits'] = aux_logits + + +def _imagenet_stem(inputs, hparams, stem_cell, current_step=None): + """Stem used for models trained on ImageNet.""" + num_stem_cells = 2 + + # 149 x 149 x 32 + num_stem_filters = int(32 * hparams.stem_multiplier) + net = slim.conv2d( + inputs, num_stem_filters, [3, 3], stride=2, scope='conv0', + padding='VALID') + net = slim.batch_norm(net, scope='conv0_bn') + + # Run the reduction cells + cell_outputs = [None, net] + filter_scaling = 1.0 / (hparams.filter_scaling_rate**num_stem_cells) + for cell_num in range(num_stem_cells): + net = stem_cell( + net, + scope='cell_stem_{}'.format(cell_num), + filter_scaling=filter_scaling, + stride=2, + prev_layer=cell_outputs[-2], + cell_num=cell_num, + current_step=current_step) + cell_outputs.append(net) + filter_scaling *= hparams.filter_scaling_rate + return net, cell_outputs + + +def _cifar_stem(inputs, hparams): + """Stem used for models trained on Cifar.""" + num_stem_filters = int(hparams.num_conv_filters * hparams.stem_multiplier) + net = slim.conv2d( + inputs, + num_stem_filters, + 3, + scope='l1_stem_3x3') + net = slim.batch_norm(net, scope='l1_stem_bn') + return net, [None, net] + + +def build_nasnet_cifar(images, num_classes, + is_training=True, + config=None, + current_step=None): + """Build NASNet model for the Cifar Dataset.""" + hparams = cifar_config() if config is None else copy.deepcopy(config) + _update_hparams(hparams, is_training) + + if tf.test.is_gpu_available() and hparams.data_format == 'NHWC': + tf.logging.info('A GPU is available on the machine, consider using NCHW ' + 'data format for increased speed on GPU.') + + if hparams.data_format == 'NCHW': + images = tf.transpose(images, [0, 3, 1, 2]) + + # Calculate the total number of cells in the network + # Add 2 for the reduction cells + total_num_cells = hparams.num_cells + 2 + + normal_cell = nasnet_utils.NasNetANormalCell( + hparams.num_conv_filters, hparams.drop_path_keep_prob, + total_num_cells, hparams.total_training_steps, + hparams.use_bounded_activation) + reduction_cell = nasnet_utils.NasNetAReductionCell( + hparams.num_conv_filters, hparams.drop_path_keep_prob, + total_num_cells, hparams.total_training_steps, + hparams.use_bounded_activation) + with arg_scope([slim.dropout, nasnet_utils.drop_path, slim.batch_norm], + is_training=is_training): + with arg_scope([slim.avg_pool2d, + slim.max_pool2d, + slim.conv2d, + slim.batch_norm, + slim.separable_conv2d, + nasnet_utils.factorized_reduction, + nasnet_utils.global_avg_pool, + nasnet_utils.get_channel_index, + nasnet_utils.get_channel_dim], + data_format=hparams.data_format): + return _build_nasnet_base(images, + normal_cell=normal_cell, + reduction_cell=reduction_cell, + num_classes=num_classes, + hparams=hparams, + is_training=is_training, + stem_type='cifar', + current_step=current_step) +build_nasnet_cifar.default_image_size = 32 + + +def build_nasnet_mobile(images, num_classes, + is_training=True, + final_endpoint=None, + config=None, + current_step=None): + """Build NASNet Mobile model for the ImageNet Dataset.""" + hparams = (mobile_imagenet_config() if config is None + else copy.deepcopy(config)) + _update_hparams(hparams, is_training) + + if tf.test.is_gpu_available() and hparams.data_format == 'NHWC': + tf.logging.info('A GPU is available on the machine, consider using NCHW ' + 'data format for increased speed on GPU.') + + if hparams.data_format == 'NCHW': + images = tf.transpose(images, [0, 3, 1, 2]) + + # Calculate the total number of cells in the network + # Add 2 for the reduction cells + total_num_cells = hparams.num_cells + 2 + # If ImageNet, then add an additional two for the stem cells + total_num_cells += 2 + + normal_cell = nasnet_utils.NasNetANormalCell( + hparams.num_conv_filters, hparams.drop_path_keep_prob, + total_num_cells, hparams.total_training_steps, + hparams.use_bounded_activation) + reduction_cell = nasnet_utils.NasNetAReductionCell( + hparams.num_conv_filters, hparams.drop_path_keep_prob, + total_num_cells, hparams.total_training_steps, + hparams.use_bounded_activation) + with arg_scope([slim.dropout, nasnet_utils.drop_path, slim.batch_norm], + is_training=is_training): + with arg_scope([slim.avg_pool2d, + slim.max_pool2d, + slim.conv2d, + slim.batch_norm, + slim.separable_conv2d, + nasnet_utils.factorized_reduction, + nasnet_utils.global_avg_pool, + nasnet_utils.get_channel_index, + nasnet_utils.get_channel_dim], + data_format=hparams.data_format): + return _build_nasnet_base(images, + normal_cell=normal_cell, + reduction_cell=reduction_cell, + num_classes=num_classes, + hparams=hparams, + is_training=is_training, + stem_type='imagenet', + final_endpoint=final_endpoint, + current_step=current_step) +build_nasnet_mobile.default_image_size = 224 + + +def build_nasnet_large(images, num_classes, + is_training=True, + final_endpoint=None, + config=None, + current_step=None): + """Build NASNet Large model for the ImageNet Dataset.""" + hparams = (large_imagenet_config() if config is None + else copy.deepcopy(config)) + _update_hparams(hparams, is_training) + + if tf.test.is_gpu_available() and hparams.data_format == 'NHWC': + tf.logging.info('A GPU is available on the machine, consider using NCHW ' + 'data format for increased speed on GPU.') + + if hparams.data_format == 'NCHW': + images = tf.transpose(images, [0, 3, 1, 2]) + + # Calculate the total number of cells in the network + # Add 2 for the reduction cells + total_num_cells = hparams.num_cells + 2 + # If ImageNet, then add an additional two for the stem cells + total_num_cells += 2 + + normal_cell = nasnet_utils.NasNetANormalCell( + hparams.num_conv_filters, hparams.drop_path_keep_prob, + total_num_cells, hparams.total_training_steps, + hparams.use_bounded_activation) + reduction_cell = nasnet_utils.NasNetAReductionCell( + hparams.num_conv_filters, hparams.drop_path_keep_prob, + total_num_cells, hparams.total_training_steps, + hparams.use_bounded_activation) + with arg_scope([slim.dropout, nasnet_utils.drop_path, slim.batch_norm], + is_training=is_training): + with arg_scope([slim.avg_pool2d, + slim.max_pool2d, + slim.conv2d, + slim.batch_norm, + slim.separable_conv2d, + nasnet_utils.factorized_reduction, + nasnet_utils.global_avg_pool, + nasnet_utils.get_channel_index, + nasnet_utils.get_channel_dim], + data_format=hparams.data_format): + return _build_nasnet_base(images, + normal_cell=normal_cell, + reduction_cell=reduction_cell, + num_classes=num_classes, + hparams=hparams, + is_training=is_training, + stem_type='imagenet', + final_endpoint=final_endpoint, + current_step=current_step) +build_nasnet_large.default_image_size = 331 + + +def _build_nasnet_base(images, + normal_cell, + reduction_cell, + num_classes, + hparams, + is_training, + stem_type, + final_endpoint=None, + current_step=None): + """Constructs a NASNet image model.""" + + end_points = {} + def add_and_check_endpoint(endpoint_name, net): + end_points[endpoint_name] = net + return final_endpoint and (endpoint_name == final_endpoint) + + # Find where to place the reduction cells or stride normal cells + reduction_indices = nasnet_utils.calc_reduction_layers( + hparams.num_cells, hparams.num_reduction_layers) + stem_cell = reduction_cell + + if stem_type == 'imagenet': + stem = lambda: _imagenet_stem(images, hparams, stem_cell) + elif stem_type == 'cifar': + stem = lambda: _cifar_stem(images, hparams) + else: + raise ValueError('Unknown stem_type: ', stem_type) + net, cell_outputs = stem() + if add_and_check_endpoint('Stem', net): return net, end_points + + # Setup for building in the auxiliary head. + aux_head_cell_idxes = [] + if len(reduction_indices) >= 2: + aux_head_cell_idxes.append(reduction_indices[1] - 1) + + # Run the cells + filter_scaling = 1.0 + # true_cell_num accounts for the stem cells + true_cell_num = 2 if stem_type == 'imagenet' else 0 + activation_fn = tf.nn.relu6 if hparams.use_bounded_activation else tf.nn.relu + for cell_num in range(hparams.num_cells): + stride = 1 + if hparams.skip_reduction_layer_input: + prev_layer = cell_outputs[-2] + if cell_num in reduction_indices: + filter_scaling *= hparams.filter_scaling_rate + net = reduction_cell( + net, + scope='reduction_cell_{}'.format(reduction_indices.index(cell_num)), + filter_scaling=filter_scaling, + stride=2, + prev_layer=cell_outputs[-2], + cell_num=true_cell_num, + current_step=current_step) + if add_and_check_endpoint( + 'Reduction_Cell_{}'.format(reduction_indices.index(cell_num)), net): + return net, end_points + true_cell_num += 1 + cell_outputs.append(net) + if not hparams.skip_reduction_layer_input: + prev_layer = cell_outputs[-2] + net = normal_cell( + net, + scope='cell_{}'.format(cell_num), + filter_scaling=filter_scaling, + stride=stride, + prev_layer=prev_layer, + cell_num=true_cell_num, + current_step=current_step) + + if add_and_check_endpoint('Cell_{}'.format(cell_num), net): + return net, end_points + true_cell_num += 1 + if (hparams.use_aux_head and cell_num in aux_head_cell_idxes and + num_classes and is_training): + aux_net = activation_fn(net) + _build_aux_head(aux_net, end_points, num_classes, hparams, + scope='aux_{}'.format(cell_num)) + cell_outputs.append(net) + + # Final softmax layer + with tf.variable_scope('final_layer'): + net = activation_fn(net) + net = nasnet_utils.global_avg_pool(net) + if add_and_check_endpoint('global_pool', net) or not num_classes: + return net, end_points + net = slim.dropout(net, hparams.dense_dropout_keep_prob, scope='dropout') + logits = slim.fully_connected(net, num_classes) + + if add_and_check_endpoint('Logits', logits): + return net, end_points + + predictions = tf.nn.softmax(logits, name='predictions') + if add_and_check_endpoint('Predictions', predictions): + return net, end_points + return logits, end_points diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet_test.py new file mode 100644 index 0000000..d438354 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet_test.py @@ -0,0 +1,410 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for slim.nasnet.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets.nasnet import nasnet + +slim = tf.contrib.slim + + +class NASNetTest(tf.test.TestCase): + + def testBuildLogitsCifarModel(self): + batch_size = 5 + height, width = 32, 32 + num_classes = 10 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(nasnet.nasnet_cifar_arg_scope()): + logits, end_points = nasnet.build_nasnet_cifar(inputs, num_classes) + auxlogits = end_points['AuxLogits'] + predictions = end_points['Predictions'] + self.assertListEqual(auxlogits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertListEqual(predictions.get_shape().as_list(), + [batch_size, num_classes]) + + def testBuildLogitsMobileModel(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(nasnet.nasnet_mobile_arg_scope()): + logits, end_points = nasnet.build_nasnet_mobile(inputs, num_classes) + auxlogits = end_points['AuxLogits'] + predictions = end_points['Predictions'] + self.assertListEqual(auxlogits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertListEqual(predictions.get_shape().as_list(), + [batch_size, num_classes]) + + def testBuildLogitsLargeModel(self): + batch_size = 5 + height, width = 331, 331 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(nasnet.nasnet_large_arg_scope()): + logits, end_points = nasnet.build_nasnet_large(inputs, num_classes) + auxlogits = end_points['AuxLogits'] + predictions = end_points['Predictions'] + self.assertListEqual(auxlogits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertListEqual(predictions.get_shape().as_list(), + [batch_size, num_classes]) + + def testBuildPreLogitsCifarModel(self): + batch_size = 5 + height, width = 32, 32 + num_classes = None + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(nasnet.nasnet_cifar_arg_scope()): + net, end_points = nasnet.build_nasnet_cifar(inputs, num_classes) + self.assertFalse('AuxLogits' in end_points) + self.assertFalse('Predictions' in end_points) + self.assertTrue(net.op.name.startswith('final_layer/Mean')) + self.assertListEqual(net.get_shape().as_list(), [batch_size, 768]) + + def testBuildPreLogitsMobileModel(self): + batch_size = 5 + height, width = 224, 224 + num_classes = None + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(nasnet.nasnet_mobile_arg_scope()): + net, end_points = nasnet.build_nasnet_mobile(inputs, num_classes) + self.assertFalse('AuxLogits' in end_points) + self.assertFalse('Predictions' in end_points) + self.assertTrue(net.op.name.startswith('final_layer/Mean')) + self.assertListEqual(net.get_shape().as_list(), [batch_size, 1056]) + + def testBuildPreLogitsLargeModel(self): + batch_size = 5 + height, width = 331, 331 + num_classes = None + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(nasnet.nasnet_large_arg_scope()): + net, end_points = nasnet.build_nasnet_large(inputs, num_classes) + self.assertFalse('AuxLogits' in end_points) + self.assertFalse('Predictions' in end_points) + self.assertTrue(net.op.name.startswith('final_layer/Mean')) + self.assertListEqual(net.get_shape().as_list(), [batch_size, 4032]) + + def testAllEndPointsShapesCifarModel(self): + batch_size = 5 + height, width = 32, 32 + num_classes = 10 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(nasnet.nasnet_cifar_arg_scope()): + _, end_points = nasnet.build_nasnet_cifar(inputs, num_classes) + endpoints_shapes = {'Stem': [batch_size, 32, 32, 96], + 'Cell_0': [batch_size, 32, 32, 192], + 'Cell_1': [batch_size, 32, 32, 192], + 'Cell_2': [batch_size, 32, 32, 192], + 'Cell_3': [batch_size, 32, 32, 192], + 'Cell_4': [batch_size, 32, 32, 192], + 'Cell_5': [batch_size, 32, 32, 192], + 'Cell_6': [batch_size, 16, 16, 384], + 'Cell_7': [batch_size, 16, 16, 384], + 'Cell_8': [batch_size, 16, 16, 384], + 'Cell_9': [batch_size, 16, 16, 384], + 'Cell_10': [batch_size, 16, 16, 384], + 'Cell_11': [batch_size, 16, 16, 384], + 'Cell_12': [batch_size, 8, 8, 768], + 'Cell_13': [batch_size, 8, 8, 768], + 'Cell_14': [batch_size, 8, 8, 768], + 'Cell_15': [batch_size, 8, 8, 768], + 'Cell_16': [batch_size, 8, 8, 768], + 'Cell_17': [batch_size, 8, 8, 768], + 'Reduction_Cell_0': [batch_size, 16, 16, 256], + 'Reduction_Cell_1': [batch_size, 8, 8, 512], + 'global_pool': [batch_size, 768], + # Logits and predictions + 'AuxLogits': [batch_size, num_classes], + 'Logits': [batch_size, num_classes], + 'Predictions': [batch_size, num_classes]} + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name in endpoints_shapes: + tf.logging.info('Endpoint name: {}'.format(endpoint_name)) + expected_shape = endpoints_shapes[endpoint_name] + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testNoAuxHeadCifarModel(self): + batch_size = 5 + height, width = 32, 32 + num_classes = 10 + for use_aux_head in (True, False): + tf.reset_default_graph() + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + config = nasnet.cifar_config() + config.set_hparam('use_aux_head', int(use_aux_head)) + with slim.arg_scope(nasnet.nasnet_cifar_arg_scope()): + _, end_points = nasnet.build_nasnet_cifar(inputs, num_classes, + config=config) + self.assertEqual('AuxLogits' in end_points, use_aux_head) + + def testAllEndPointsShapesMobileModel(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(nasnet.nasnet_mobile_arg_scope()): + _, end_points = nasnet.build_nasnet_mobile(inputs, num_classes) + endpoints_shapes = {'Stem': [batch_size, 28, 28, 88], + 'Cell_0': [batch_size, 28, 28, 264], + 'Cell_1': [batch_size, 28, 28, 264], + 'Cell_2': [batch_size, 28, 28, 264], + 'Cell_3': [batch_size, 28, 28, 264], + 'Cell_4': [batch_size, 14, 14, 528], + 'Cell_5': [batch_size, 14, 14, 528], + 'Cell_6': [batch_size, 14, 14, 528], + 'Cell_7': [batch_size, 14, 14, 528], + 'Cell_8': [batch_size, 7, 7, 1056], + 'Cell_9': [batch_size, 7, 7, 1056], + 'Cell_10': [batch_size, 7, 7, 1056], + 'Cell_11': [batch_size, 7, 7, 1056], + 'Reduction_Cell_0': [batch_size, 14, 14, 352], + 'Reduction_Cell_1': [batch_size, 7, 7, 704], + 'global_pool': [batch_size, 1056], + # Logits and predictions + 'AuxLogits': [batch_size, num_classes], + 'Logits': [batch_size, num_classes], + 'Predictions': [batch_size, num_classes]} + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name in endpoints_shapes: + tf.logging.info('Endpoint name: {}'.format(endpoint_name)) + expected_shape = endpoints_shapes[endpoint_name] + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testNoAuxHeadMobileModel(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + for use_aux_head in (True, False): + tf.reset_default_graph() + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + config = nasnet.mobile_imagenet_config() + config.set_hparam('use_aux_head', int(use_aux_head)) + with slim.arg_scope(nasnet.nasnet_mobile_arg_scope()): + _, end_points = nasnet.build_nasnet_mobile(inputs, num_classes, + config=config) + self.assertEqual('AuxLogits' in end_points, use_aux_head) + + def testAllEndPointsShapesLargeModel(self): + batch_size = 5 + height, width = 331, 331 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(nasnet.nasnet_large_arg_scope()): + _, end_points = nasnet.build_nasnet_large(inputs, num_classes) + endpoints_shapes = {'Stem': [batch_size, 42, 42, 336], + 'Cell_0': [batch_size, 42, 42, 1008], + 'Cell_1': [batch_size, 42, 42, 1008], + 'Cell_2': [batch_size, 42, 42, 1008], + 'Cell_3': [batch_size, 42, 42, 1008], + 'Cell_4': [batch_size, 42, 42, 1008], + 'Cell_5': [batch_size, 42, 42, 1008], + 'Cell_6': [batch_size, 21, 21, 2016], + 'Cell_7': [batch_size, 21, 21, 2016], + 'Cell_8': [batch_size, 21, 21, 2016], + 'Cell_9': [batch_size, 21, 21, 2016], + 'Cell_10': [batch_size, 21, 21, 2016], + 'Cell_11': [batch_size, 21, 21, 2016], + 'Cell_12': [batch_size, 11, 11, 4032], + 'Cell_13': [batch_size, 11, 11, 4032], + 'Cell_14': [batch_size, 11, 11, 4032], + 'Cell_15': [batch_size, 11, 11, 4032], + 'Cell_16': [batch_size, 11, 11, 4032], + 'Cell_17': [batch_size, 11, 11, 4032], + 'Reduction_Cell_0': [batch_size, 21, 21, 1344], + 'Reduction_Cell_1': [batch_size, 11, 11, 2688], + 'global_pool': [batch_size, 4032], + # Logits and predictions + 'AuxLogits': [batch_size, num_classes], + 'Logits': [batch_size, num_classes], + 'Predictions': [batch_size, num_classes]} + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name in endpoints_shapes: + tf.logging.info('Endpoint name: {}'.format(endpoint_name)) + expected_shape = endpoints_shapes[endpoint_name] + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testNoAuxHeadLargeModel(self): + batch_size = 5 + height, width = 331, 331 + num_classes = 1000 + for use_aux_head in (True, False): + tf.reset_default_graph() + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + config = nasnet.large_imagenet_config() + config.set_hparam('use_aux_head', int(use_aux_head)) + with slim.arg_scope(nasnet.nasnet_large_arg_scope()): + _, end_points = nasnet.build_nasnet_large(inputs, num_classes, + config=config) + self.assertEqual('AuxLogits' in end_points, use_aux_head) + + def testVariablesSetDeviceMobileModel(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + # Force all Variables to reside on the device. + with tf.variable_scope('on_cpu'), tf.device('/cpu:0'): + with slim.arg_scope(nasnet.nasnet_mobile_arg_scope()): + nasnet.build_nasnet_mobile(inputs, num_classes) + with tf.variable_scope('on_gpu'), tf.device('/gpu:0'): + with slim.arg_scope(nasnet.nasnet_mobile_arg_scope()): + nasnet.build_nasnet_mobile(inputs, num_classes) + for v in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='on_cpu'): + self.assertDeviceEqual(v.device, '/cpu:0') + for v in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='on_gpu'): + self.assertDeviceEqual(v.device, '/gpu:0') + + def testUnknownBatchSizeMobileModel(self): + batch_size = 1 + height, width = 224, 224 + num_classes = 1000 + with self.test_session() as sess: + inputs = tf.placeholder(tf.float32, (None, height, width, 3)) + with slim.arg_scope(nasnet.nasnet_mobile_arg_scope()): + logits, _ = nasnet.build_nasnet_mobile(inputs, num_classes) + self.assertListEqual(logits.get_shape().as_list(), + [None, num_classes]) + images = tf.random_uniform((batch_size, height, width, 3)) + sess.run(tf.global_variables_initializer()) + output = sess.run(logits, {inputs: images.eval()}) + self.assertEquals(output.shape, (batch_size, num_classes)) + + def testEvaluationMobileModel(self): + batch_size = 2 + height, width = 224, 224 + num_classes = 1000 + with self.test_session() as sess: + eval_inputs = tf.random_uniform((batch_size, height, width, 3)) + with slim.arg_scope(nasnet.nasnet_mobile_arg_scope()): + logits, _ = nasnet.build_nasnet_mobile(eval_inputs, + num_classes, + is_training=False) + predictions = tf.argmax(logits, 1) + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (batch_size,)) + + def testOverrideHParamsCifarModel(self): + batch_size = 5 + height, width = 32, 32 + num_classes = 10 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + config = nasnet.cifar_config() + config.set_hparam('data_format', 'NCHW') + with slim.arg_scope(nasnet.nasnet_cifar_arg_scope()): + _, end_points = nasnet.build_nasnet_cifar( + inputs, num_classes, config=config) + self.assertListEqual( + end_points['Stem'].shape.as_list(), [batch_size, 96, 32, 32]) + + def testOverrideHParamsMobileModel(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + config = nasnet.mobile_imagenet_config() + config.set_hparam('data_format', 'NCHW') + with slim.arg_scope(nasnet.nasnet_mobile_arg_scope()): + _, end_points = nasnet.build_nasnet_mobile( + inputs, num_classes, config=config) + self.assertListEqual( + end_points['Stem'].shape.as_list(), [batch_size, 88, 28, 28]) + + def testOverrideHParamsLargeModel(self): + batch_size = 5 + height, width = 331, 331 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + config = nasnet.large_imagenet_config() + config.set_hparam('data_format', 'NCHW') + with slim.arg_scope(nasnet.nasnet_large_arg_scope()): + _, end_points = nasnet.build_nasnet_large( + inputs, num_classes, config=config) + self.assertListEqual( + end_points['Stem'].shape.as_list(), [batch_size, 336, 42, 42]) + + def testCurrentStepCifarModel(self): + batch_size = 5 + height, width = 32, 32 + num_classes = 10 + inputs = tf.random_uniform((batch_size, height, width, 3)) + global_step = tf.train.create_global_step() + with slim.arg_scope(nasnet.nasnet_cifar_arg_scope()): + logits, end_points = nasnet.build_nasnet_cifar(inputs, + num_classes, + current_step=global_step) + auxlogits = end_points['AuxLogits'] + predictions = end_points['Predictions'] + self.assertListEqual(auxlogits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertListEqual(predictions.get_shape().as_list(), + [batch_size, num_classes]) + + def testUseBoundedAcitvationCifarModel(self): + batch_size = 1 + height, width = 32, 32 + num_classes = 10 + for use_bounded_activation in (True, False): + tf.reset_default_graph() + inputs = tf.random_uniform((batch_size, height, width, 3)) + config = nasnet.cifar_config() + config.set_hparam('use_bounded_activation', use_bounded_activation) + with slim.arg_scope(nasnet.nasnet_cifar_arg_scope()): + _, _ = nasnet.build_nasnet_cifar( + inputs, num_classes, config=config) + for node in tf.get_default_graph().as_graph_def().node: + if node.op.startswith('Relu'): + self.assertEqual(node.op == 'Relu6', use_bounded_activation) + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet_utils.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet_utils.py new file mode 100644 index 0000000..caa39b9 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet_utils.py @@ -0,0 +1,524 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""A custom module for some common operations used by NASNet. + +Functions exposed in this file: +- calc_reduction_layers +- get_channel_index +- get_channel_dim +- global_avg_pool +- factorized_reduction +- drop_path + +Classes exposed in this file: +- NasNetABaseCell +- NasNetANormalCell +- NasNetAReductionCell +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + + +arg_scope = tf.contrib.framework.arg_scope +slim = tf.contrib.slim + +DATA_FORMAT_NCHW = 'NCHW' +DATA_FORMAT_NHWC = 'NHWC' +INVALID = 'null' +# The cap for tf.clip_by_value, it's hinted from the activation distribution +# that the majority of activation values are in the range [-6, 6]. +CLIP_BY_VALUE_CAP = 6 + + +def calc_reduction_layers(num_cells, num_reduction_layers): + """Figure out what layers should have reductions.""" + reduction_layers = [] + for pool_num in range(1, num_reduction_layers + 1): + layer_num = (float(pool_num) / (num_reduction_layers + 1)) * num_cells + layer_num = int(layer_num) + reduction_layers.append(layer_num) + return reduction_layers + + +@tf.contrib.framework.add_arg_scope +def get_channel_index(data_format=INVALID): + assert data_format != INVALID + axis = 3 if data_format == 'NHWC' else 1 + return axis + + +@tf.contrib.framework.add_arg_scope +def get_channel_dim(shape, data_format=INVALID): + assert data_format != INVALID + assert len(shape) == 4 + if data_format == 'NHWC': + return int(shape[3]) + elif data_format == 'NCHW': + return int(shape[1]) + else: + raise ValueError('Not a valid data_format', data_format) + + +@tf.contrib.framework.add_arg_scope +def global_avg_pool(x, data_format=INVALID): + """Average pool away the height and width spatial dimensions of x.""" + assert data_format != INVALID + assert data_format in ['NHWC', 'NCHW'] + assert x.shape.ndims == 4 + if data_format == 'NHWC': + return tf.reduce_mean(x, [1, 2]) + else: + return tf.reduce_mean(x, [2, 3]) + + +@tf.contrib.framework.add_arg_scope +def factorized_reduction(net, output_filters, stride, data_format=INVALID): + """Reduces the shape of net without information loss due to striding.""" + assert data_format != INVALID + if stride == 1: + net = slim.conv2d(net, output_filters, 1, scope='path_conv') + net = slim.batch_norm(net, scope='path_bn') + return net + if data_format == 'NHWC': + stride_spec = [1, stride, stride, 1] + else: + stride_spec = [1, 1, stride, stride] + + # Skip path 1 + path1 = tf.nn.avg_pool( + net, [1, 1, 1, 1], stride_spec, 'VALID', data_format=data_format) + path1 = slim.conv2d(path1, int(output_filters / 2), 1, scope='path1_conv') + + # Skip path 2 + # First pad with 0's on the right and bottom, then shift the filter to + # include those 0's that were added. + if data_format == 'NHWC': + pad_arr = [[0, 0], [0, 1], [0, 1], [0, 0]] + path2 = tf.pad(net, pad_arr)[:, 1:, 1:, :] + concat_axis = 3 + else: + pad_arr = [[0, 0], [0, 0], [0, 1], [0, 1]] + path2 = tf.pad(net, pad_arr)[:, :, 1:, 1:] + concat_axis = 1 + + path2 = tf.nn.avg_pool( + path2, [1, 1, 1, 1], stride_spec, 'VALID', data_format=data_format) + + # If odd number of filters, add an additional one to the second path. + final_filter_size = int(output_filters / 2) + int(output_filters % 2) + path2 = slim.conv2d(path2, final_filter_size, 1, scope='path2_conv') + + # Concat and apply BN + final_path = tf.concat(values=[path1, path2], axis=concat_axis) + final_path = slim.batch_norm(final_path, scope='final_path_bn') + return final_path + + +@tf.contrib.framework.add_arg_scope +def drop_path(net, keep_prob, is_training=True): + """Drops out a whole example hiddenstate with the specified probability.""" + if is_training: + batch_size = tf.shape(net)[0] + noise_shape = [batch_size, 1, 1, 1] + random_tensor = keep_prob + random_tensor += tf.random_uniform(noise_shape, dtype=tf.float32) + binary_tensor = tf.cast(tf.floor(random_tensor), net.dtype) + keep_prob_inv = tf.cast(1.0 / keep_prob, net.dtype) + net = net * keep_prob_inv * binary_tensor + + return net + + +def _operation_to_filter_shape(operation): + splitted_operation = operation.split('x') + filter_shape = int(splitted_operation[0][-1]) + assert filter_shape == int( + splitted_operation[1][0]), 'Rectangular filters not supported.' + return filter_shape + + +def _operation_to_num_layers(operation): + splitted_operation = operation.split('_') + if 'x' in splitted_operation[-1]: + return 1 + return int(splitted_operation[-1]) + + +def _operation_to_info(operation): + """Takes in operation name and returns meta information. + + An example would be 'separable_3x3_4' -> (3, 4). + + Args: + operation: String that corresponds to convolution operation. + + Returns: + Tuple of (filter shape, num layers). + """ + num_layers = _operation_to_num_layers(operation) + filter_shape = _operation_to_filter_shape(operation) + return num_layers, filter_shape + + +def _stacked_separable_conv(net, stride, operation, filter_size, + use_bounded_activation): + """Takes in an operations and parses it to the correct sep operation.""" + num_layers, kernel_size = _operation_to_info(operation) + activation_fn = tf.nn.relu6 if use_bounded_activation else tf.nn.relu + for layer_num in range(num_layers - 1): + net = activation_fn(net) + net = slim.separable_conv2d( + net, + filter_size, + kernel_size, + depth_multiplier=1, + scope='separable_{0}x{0}_{1}'.format(kernel_size, layer_num + 1), + stride=stride) + net = slim.batch_norm( + net, scope='bn_sep_{0}x{0}_{1}'.format(kernel_size, layer_num + 1)) + stride = 1 + net = activation_fn(net) + net = slim.separable_conv2d( + net, + filter_size, + kernel_size, + depth_multiplier=1, + scope='separable_{0}x{0}_{1}'.format(kernel_size, num_layers), + stride=stride) + net = slim.batch_norm( + net, scope='bn_sep_{0}x{0}_{1}'.format(kernel_size, num_layers)) + return net + + +def _operation_to_pooling_type(operation): + """Takes in the operation string and returns the pooling type.""" + splitted_operation = operation.split('_') + return splitted_operation[0] + + +def _operation_to_pooling_shape(operation): + """Takes in the operation string and returns the pooling kernel shape.""" + splitted_operation = operation.split('_') + shape = splitted_operation[-1] + assert 'x' in shape + filter_height, filter_width = shape.split('x') + assert filter_height == filter_width + return int(filter_height) + + +def _operation_to_pooling_info(operation): + """Parses the pooling operation string to return its type and shape.""" + pooling_type = _operation_to_pooling_type(operation) + pooling_shape = _operation_to_pooling_shape(operation) + return pooling_type, pooling_shape + + +def _pooling(net, stride, operation, use_bounded_activation): + """Parses operation and performs the correct pooling operation on net.""" + padding = 'SAME' + pooling_type, pooling_shape = _operation_to_pooling_info(operation) + if use_bounded_activation: + net = tf.nn.relu6(net) + if pooling_type == 'avg': + net = slim.avg_pool2d(net, pooling_shape, stride=stride, padding=padding) + elif pooling_type == 'max': + net = slim.max_pool2d(net, pooling_shape, stride=stride, padding=padding) + else: + raise NotImplementedError('Unimplemented pooling type: ', pooling_type) + return net + + +class NasNetABaseCell(object): + """NASNet Cell class that is used as a 'layer' in image architectures. + + Args: + num_conv_filters: The number of filters for each convolution operation. + operations: List of operations that are performed in the NASNet Cell in + order. + used_hiddenstates: Binary array that signals if the hiddenstate was used + within the cell. This is used to determine what outputs of the cell + should be concatenated together. + hiddenstate_indices: Determines what hiddenstates should be combined + together with the specified operations to create the NASNet cell. + use_bounded_activation: Whether or not to use bounded activations. Bounded + activations better lend themselves to quantized inference. + """ + + def __init__(self, num_conv_filters, operations, used_hiddenstates, + hiddenstate_indices, drop_path_keep_prob, total_num_cells, + total_training_steps, use_bounded_activation=False): + self._num_conv_filters = num_conv_filters + self._operations = operations + self._used_hiddenstates = used_hiddenstates + self._hiddenstate_indices = hiddenstate_indices + self._drop_path_keep_prob = drop_path_keep_prob + self._total_num_cells = total_num_cells + self._total_training_steps = total_training_steps + self._use_bounded_activation = use_bounded_activation + + def _reduce_prev_layer(self, prev_layer, curr_layer): + """Matches dimension of prev_layer to the curr_layer.""" + # Set the prev layer to the current layer if it is none + if prev_layer is None: + return curr_layer + curr_num_filters = self._filter_size + prev_num_filters = get_channel_dim(prev_layer.shape) + curr_filter_shape = int(curr_layer.shape[2]) + prev_filter_shape = int(prev_layer.shape[2]) + activation_fn = tf.nn.relu6 if self._use_bounded_activation else tf.nn.relu + if curr_filter_shape != prev_filter_shape: + prev_layer = activation_fn(prev_layer) + prev_layer = factorized_reduction( + prev_layer, curr_num_filters, stride=2) + elif curr_num_filters != prev_num_filters: + prev_layer = activation_fn(prev_layer) + prev_layer = slim.conv2d( + prev_layer, curr_num_filters, 1, scope='prev_1x1') + prev_layer = slim.batch_norm(prev_layer, scope='prev_bn') + return prev_layer + + def _cell_base(self, net, prev_layer): + """Runs the beginning of the conv cell before the predicted ops are run.""" + num_filters = self._filter_size + + # Check to be sure prev layer stuff is setup correctly + prev_layer = self._reduce_prev_layer(prev_layer, net) + + net = tf.nn.relu6(net) if self._use_bounded_activation else tf.nn.relu(net) + net = slim.conv2d(net, num_filters, 1, scope='1x1') + net = slim.batch_norm(net, scope='beginning_bn') + # num_or_size_splits=1 + net = [net] + net.append(prev_layer) + return net + + def __call__(self, net, scope=None, filter_scaling=1, stride=1, + prev_layer=None, cell_num=-1, current_step=None): + """Runs the conv cell.""" + self._cell_num = cell_num + self._filter_scaling = filter_scaling + self._filter_size = int(self._num_conv_filters * filter_scaling) + + i = 0 + with tf.variable_scope(scope): + net = self._cell_base(net, prev_layer) + for iteration in range(5): + with tf.variable_scope('comb_iter_{}'.format(iteration)): + left_hiddenstate_idx, right_hiddenstate_idx = ( + self._hiddenstate_indices[i], + self._hiddenstate_indices[i + 1]) + original_input_left = left_hiddenstate_idx < 2 + original_input_right = right_hiddenstate_idx < 2 + h1 = net[left_hiddenstate_idx] + h2 = net[right_hiddenstate_idx] + + operation_left = self._operations[i] + operation_right = self._operations[i+1] + i += 2 + # Apply conv operations + with tf.variable_scope('left'): + h1 = self._apply_conv_operation(h1, operation_left, + stride, original_input_left, + current_step) + with tf.variable_scope('right'): + h2 = self._apply_conv_operation(h2, operation_right, + stride, original_input_right, + current_step) + + # Combine hidden states using 'add'. + with tf.variable_scope('combine'): + h = h1 + h2 + if self._use_bounded_activation: + h = tf.nn.relu6(h) + + # Add hiddenstate to the list of hiddenstates we can choose from + net.append(h) + + with tf.variable_scope('cell_output'): + net = self._combine_unused_states(net) + + return net + + def _apply_conv_operation(self, net, operation, + stride, is_from_original_input, current_step): + """Applies the predicted conv operation to net.""" + # Dont stride if this is not one of the original hiddenstates + if stride > 1 and not is_from_original_input: + stride = 1 + input_filters = get_channel_dim(net.shape) + filter_size = self._filter_size + if 'separable' in operation: + net = _stacked_separable_conv(net, stride, operation, filter_size, + self._use_bounded_activation) + if self._use_bounded_activation: + net = tf.clip_by_value(net, -CLIP_BY_VALUE_CAP, CLIP_BY_VALUE_CAP) + elif operation in ['none']: + if self._use_bounded_activation: + net = tf.nn.relu6(net) + # Check if a stride is needed, then use a strided 1x1 here + if stride > 1 or (input_filters != filter_size): + if not self._use_bounded_activation: + net = tf.nn.relu(net) + net = slim.conv2d(net, filter_size, 1, stride=stride, scope='1x1') + net = slim.batch_norm(net, scope='bn_1') + if self._use_bounded_activation: + net = tf.clip_by_value(net, -CLIP_BY_VALUE_CAP, CLIP_BY_VALUE_CAP) + elif 'pool' in operation: + net = _pooling(net, stride, operation, self._use_bounded_activation) + if input_filters != filter_size: + net = slim.conv2d(net, filter_size, 1, stride=1, scope='1x1') + net = slim.batch_norm(net, scope='bn_1') + if self._use_bounded_activation: + net = tf.clip_by_value(net, -CLIP_BY_VALUE_CAP, CLIP_BY_VALUE_CAP) + else: + raise ValueError('Unimplemented operation', operation) + + if operation != 'none': + net = self._apply_drop_path(net, current_step=current_step) + return net + + def _combine_unused_states(self, net): + """Concatenate the unused hidden states of the cell.""" + used_hiddenstates = self._used_hiddenstates + + final_height = int(net[-1].shape[2]) + final_num_filters = get_channel_dim(net[-1].shape) + assert len(used_hiddenstates) == len(net) + for idx, used_h in enumerate(used_hiddenstates): + curr_height = int(net[idx].shape[2]) + curr_num_filters = get_channel_dim(net[idx].shape) + + # Determine if a reduction should be applied to make the number of + # filters match. + should_reduce = final_num_filters != curr_num_filters + should_reduce = (final_height != curr_height) or should_reduce + should_reduce = should_reduce and not used_h + if should_reduce: + stride = 2 if final_height != curr_height else 1 + with tf.variable_scope('reduction_{}'.format(idx)): + net[idx] = factorized_reduction( + net[idx], final_num_filters, stride) + + states_to_combine = ( + [h for h, is_used in zip(net, used_hiddenstates) if not is_used]) + + # Return the concat of all the states + concat_axis = get_channel_index() + net = tf.concat(values=states_to_combine, axis=concat_axis) + return net + + @tf.contrib.framework.add_arg_scope # No public API. For internal use only. + def _apply_drop_path(self, net, current_step=None, + use_summaries=False, drop_connect_version='v3'): + """Apply drop_path regularization. + + Args: + net: the Tensor that gets drop_path regularization applied. + current_step: a float32 Tensor with the current global_step value, + to be divided by hparams.total_training_steps. Usually None, which + defaults to tf.train.get_or_create_global_step() properly casted. + use_summaries: a Python boolean. If set to False, no summaries are output. + drop_connect_version: one of 'v1', 'v2', 'v3', controlling whether + the dropout rate is scaled by current_step (v1), layer (v2), or + both (v3, the default). + + Returns: + The dropped-out value of `net`. + """ + drop_path_keep_prob = self._drop_path_keep_prob + if drop_path_keep_prob < 1.0: + assert drop_connect_version in ['v1', 'v2', 'v3'] + if drop_connect_version in ['v2', 'v3']: + # Scale keep prob by layer number + assert self._cell_num != -1 + # The added 2 is for the reduction cells + num_cells = self._total_num_cells + layer_ratio = (self._cell_num + 1)/float(num_cells) + if use_summaries: + with tf.device('/cpu:0'): + tf.summary.scalar('layer_ratio', layer_ratio) + drop_path_keep_prob = 1 - layer_ratio * (1 - drop_path_keep_prob) + if drop_connect_version in ['v1', 'v3']: + # Decrease the keep probability over time + if current_step is None: + current_step = tf.train.get_or_create_global_step() + current_step = tf.cast(current_step, tf.float32) + drop_path_burn_in_steps = self._total_training_steps + current_ratio = current_step / drop_path_burn_in_steps + current_ratio = tf.minimum(1.0, current_ratio) + if use_summaries: + with tf.device('/cpu:0'): + tf.summary.scalar('current_ratio', current_ratio) + drop_path_keep_prob = (1 - current_ratio * (1 - drop_path_keep_prob)) + if use_summaries: + with tf.device('/cpu:0'): + tf.summary.scalar('drop_path_keep_prob', drop_path_keep_prob) + net = drop_path(net, drop_path_keep_prob) + return net + + +class NasNetANormalCell(NasNetABaseCell): + """NASNetA Normal Cell.""" + + def __init__(self, num_conv_filters, drop_path_keep_prob, total_num_cells, + total_training_steps, use_bounded_activation=False): + operations = ['separable_5x5_2', + 'separable_3x3_2', + 'separable_5x5_2', + 'separable_3x3_2', + 'avg_pool_3x3', + 'none', + 'avg_pool_3x3', + 'avg_pool_3x3', + 'separable_3x3_2', + 'none'] + used_hiddenstates = [1, 0, 0, 0, 0, 0, 0] + hiddenstate_indices = [0, 1, 1, 1, 0, 1, 1, 1, 0, 0] + super(NasNetANormalCell, self).__init__(num_conv_filters, operations, + used_hiddenstates, + hiddenstate_indices, + drop_path_keep_prob, + total_num_cells, + total_training_steps, + use_bounded_activation) + + +class NasNetAReductionCell(NasNetABaseCell): + """NASNetA Reduction Cell.""" + + def __init__(self, num_conv_filters, drop_path_keep_prob, total_num_cells, + total_training_steps, use_bounded_activation=False): + operations = ['separable_5x5_2', + 'separable_7x7_2', + 'max_pool_3x3', + 'separable_7x7_2', + 'avg_pool_3x3', + 'separable_5x5_2', + 'none', + 'avg_pool_3x3', + 'separable_3x3_2', + 'max_pool_3x3'] + used_hiddenstates = [1, 1, 1, 0, 0, 0, 0] + hiddenstate_indices = [0, 1, 0, 1, 0, 1, 3, 2, 2, 0] + super(NasNetAReductionCell, self).__init__(num_conv_filters, operations, + used_hiddenstates, + hiddenstate_indices, + drop_path_keep_prob, + total_num_cells, + total_training_steps, + use_bounded_activation) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet_utils_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet_utils_test.py new file mode 100644 index 0000000..60bf902 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/nasnet_utils_test.py @@ -0,0 +1,62 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for slim.nets.nasnet.nasnet_utils.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets.nasnet import nasnet_utils + + +class NasnetUtilsTest(tf.test.TestCase): + + def testCalcReductionLayers(self): + num_cells = 18 + num_reduction_layers = 2 + reduction_layers = nasnet_utils.calc_reduction_layers( + num_cells, num_reduction_layers) + self.assertEqual(len(reduction_layers), 2) + self.assertEqual(reduction_layers[0], 6) + self.assertEqual(reduction_layers[1], 12) + + def testGetChannelIndex(self): + data_formats = ['NHWC', 'NCHW'] + for data_format in data_formats: + index = nasnet_utils.get_channel_index(data_format) + correct_index = 3 if data_format == 'NHWC' else 1 + self.assertEqual(index, correct_index) + + def testGetChannelDim(self): + data_formats = ['NHWC', 'NCHW'] + shape = [10, 20, 30, 40] + for data_format in data_formats: + dim = nasnet_utils.get_channel_dim(shape, data_format) + correct_dim = shape[3] if data_format == 'NHWC' else shape[1] + self.assertEqual(dim, correct_dim) + + def testGlobalAvgPool(self): + data_formats = ['NHWC', 'NCHW'] + inputs = tf.placeholder(tf.float32, (5, 10, 20, 10)) + for data_format in data_formats: + output = nasnet_utils.global_avg_pool( + inputs, data_format) + self.assertEqual(output.shape, [5, 10]) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/pnasnet.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/pnasnet.py new file mode 100644 index 0000000..8e8427f --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/pnasnet.py @@ -0,0 +1,280 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains the definition for the PNASNet classification networks. + +Paper: https://arxiv.org/abs/1712.00559 +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import copy +import tensorflow as tf + +from nets.nasnet import nasnet +from nets.nasnet import nasnet_utils + +arg_scope = tf.contrib.framework.arg_scope +slim = tf.contrib.slim + + +def large_imagenet_config(): + """Large ImageNet configuration based on PNASNet-5.""" + return tf.contrib.training.HParams( + stem_multiplier=3.0, + dense_dropout_keep_prob=0.5, + num_cells=12, + filter_scaling_rate=2.0, + num_conv_filters=216, + drop_path_keep_prob=0.6, + use_aux_head=1, + num_reduction_layers=2, + data_format='NHWC', + skip_reduction_layer_input=1, + total_training_steps=250000, + use_bounded_activation=False, + ) + + +def mobile_imagenet_config(): + """Mobile ImageNet configuration based on PNASNet-5.""" + return tf.contrib.training.HParams( + stem_multiplier=1.0, + dense_dropout_keep_prob=0.5, + num_cells=9, + filter_scaling_rate=2.0, + num_conv_filters=54, + drop_path_keep_prob=1.0, + use_aux_head=1, + num_reduction_layers=2, + data_format='NHWC', + skip_reduction_layer_input=1, + total_training_steps=250000, + use_bounded_activation=False, + ) + + +def pnasnet_large_arg_scope(weight_decay=4e-5, batch_norm_decay=0.9997, + batch_norm_epsilon=0.001): + """Default arg scope for the PNASNet Large ImageNet model.""" + return nasnet.nasnet_large_arg_scope( + weight_decay, batch_norm_decay, batch_norm_epsilon) + + +def pnasnet_mobile_arg_scope(weight_decay=4e-5, + batch_norm_decay=0.9997, + batch_norm_epsilon=0.001): + """Default arg scope for the PNASNet Mobile ImageNet model.""" + return nasnet.nasnet_mobile_arg_scope(weight_decay, batch_norm_decay, + batch_norm_epsilon) + + +def _build_pnasnet_base(images, + normal_cell, + num_classes, + hparams, + is_training, + final_endpoint=None): + """Constructs a PNASNet image model.""" + + end_points = {} + + def add_and_check_endpoint(endpoint_name, net): + end_points[endpoint_name] = net + return final_endpoint and (endpoint_name == final_endpoint) + + # Find where to place the reduction cells or stride normal cells + reduction_indices = nasnet_utils.calc_reduction_layers( + hparams.num_cells, hparams.num_reduction_layers) + + # pylint: disable=protected-access + stem = lambda: nasnet._imagenet_stem(images, hparams, normal_cell) + # pylint: enable=protected-access + net, cell_outputs = stem() + if add_and_check_endpoint('Stem', net): + return net, end_points + + # Setup for building in the auxiliary head. + aux_head_cell_idxes = [] + if len(reduction_indices) >= 2: + aux_head_cell_idxes.append(reduction_indices[1] - 1) + + # Run the cells + filter_scaling = 1.0 + # true_cell_num accounts for the stem cells + true_cell_num = 2 + activation_fn = tf.nn.relu6 if hparams.use_bounded_activation else tf.nn.relu + for cell_num in range(hparams.num_cells): + is_reduction = cell_num in reduction_indices + stride = 2 if is_reduction else 1 + if is_reduction: filter_scaling *= hparams.filter_scaling_rate + if hparams.skip_reduction_layer_input or not is_reduction: + prev_layer = cell_outputs[-2] + net = normal_cell( + net, + scope='cell_{}'.format(cell_num), + filter_scaling=filter_scaling, + stride=stride, + prev_layer=prev_layer, + cell_num=true_cell_num) + if add_and_check_endpoint('Cell_{}'.format(cell_num), net): + return net, end_points + true_cell_num += 1 + cell_outputs.append(net) + + if (hparams.use_aux_head and cell_num in aux_head_cell_idxes and + num_classes and is_training): + aux_net = activation_fn(net) + # pylint: disable=protected-access + nasnet._build_aux_head(aux_net, end_points, num_classes, hparams, + scope='aux_{}'.format(cell_num)) + # pylint: enable=protected-access + + # Final softmax layer + with tf.variable_scope('final_layer'): + net = activation_fn(net) + net = nasnet_utils.global_avg_pool(net) + if add_and_check_endpoint('global_pool', net) or not num_classes: + return net, end_points + net = slim.dropout(net, hparams.dense_dropout_keep_prob, scope='dropout') + logits = slim.fully_connected(net, num_classes) + + if add_and_check_endpoint('Logits', logits): + return net, end_points + + predictions = tf.nn.softmax(logits, name='predictions') + if add_and_check_endpoint('Predictions', predictions): + return net, end_points + return logits, end_points + + +def build_pnasnet_large(images, + num_classes, + is_training=True, + final_endpoint=None, + config=None): + """Build PNASNet Large model for the ImageNet Dataset.""" + hparams = copy.deepcopy(config) if config else large_imagenet_config() + # pylint: disable=protected-access + nasnet._update_hparams(hparams, is_training) + # pylint: enable=protected-access + + if tf.test.is_gpu_available() and hparams.data_format == 'NHWC': + tf.logging.info('A GPU is available on the machine, consider using NCHW ' + 'data format for increased speed on GPU.') + + if hparams.data_format == 'NCHW': + images = tf.transpose(images, [0, 3, 1, 2]) + + # Calculate the total number of cells in the network. + # There is no distinction between reduction and normal cells in PNAS so the + # total number of cells is equal to the number normal cells plus the number + # of stem cells (two by default). + total_num_cells = hparams.num_cells + 2 + + normal_cell = PNasNetNormalCell(hparams.num_conv_filters, + hparams.drop_path_keep_prob, total_num_cells, + hparams.total_training_steps, + hparams.use_bounded_activation) + with arg_scope( + [slim.dropout, nasnet_utils.drop_path, slim.batch_norm], + is_training=is_training): + with arg_scope([slim.avg_pool2d, slim.max_pool2d, slim.conv2d, + slim.batch_norm, slim.separable_conv2d, + nasnet_utils.factorized_reduction, + nasnet_utils.global_avg_pool, + nasnet_utils.get_channel_index, + nasnet_utils.get_channel_dim], + data_format=hparams.data_format): + return _build_pnasnet_base( + images, + normal_cell=normal_cell, + num_classes=num_classes, + hparams=hparams, + is_training=is_training, + final_endpoint=final_endpoint) +build_pnasnet_large.default_image_size = 331 + + +def build_pnasnet_mobile(images, + num_classes, + is_training=True, + final_endpoint=None, + config=None): + """Build PNASNet Mobile model for the ImageNet Dataset.""" + hparams = copy.deepcopy(config) if config else mobile_imagenet_config() + # pylint: disable=protected-access + nasnet._update_hparams(hparams, is_training) + # pylint: enable=protected-access + + if tf.test.is_gpu_available() and hparams.data_format == 'NHWC': + tf.logging.info('A GPU is available on the machine, consider using NCHW ' + 'data format for increased speed on GPU.') + + if hparams.data_format == 'NCHW': + images = tf.transpose(images, [0, 3, 1, 2]) + + # Calculate the total number of cells in the network. + # There is no distinction between reduction and normal cells in PNAS so the + # total number of cells is equal to the number normal cells plus the number + # of stem cells (two by default). + total_num_cells = hparams.num_cells + 2 + + normal_cell = PNasNetNormalCell(hparams.num_conv_filters, + hparams.drop_path_keep_prob, total_num_cells, + hparams.total_training_steps, + hparams.use_bounded_activation) + with arg_scope( + [slim.dropout, nasnet_utils.drop_path, slim.batch_norm], + is_training=is_training): + with arg_scope( + [ + slim.avg_pool2d, slim.max_pool2d, slim.conv2d, slim.batch_norm, + slim.separable_conv2d, nasnet_utils.factorized_reduction, + nasnet_utils.global_avg_pool, nasnet_utils.get_channel_index, + nasnet_utils.get_channel_dim + ], + data_format=hparams.data_format): + return _build_pnasnet_base( + images, + normal_cell=normal_cell, + num_classes=num_classes, + hparams=hparams, + is_training=is_training, + final_endpoint=final_endpoint) + + +build_pnasnet_mobile.default_image_size = 224 + + +class PNasNetNormalCell(nasnet_utils.NasNetABaseCell): + """PNASNet Normal Cell.""" + + def __init__(self, num_conv_filters, drop_path_keep_prob, total_num_cells, + total_training_steps, use_bounded_activation=False): + # Configuration for the PNASNet-5 model. + operations = [ + 'separable_5x5_2', 'max_pool_3x3', 'separable_7x7_2', 'max_pool_3x3', + 'separable_5x5_2', 'separable_3x3_2', 'separable_3x3_2', 'max_pool_3x3', + 'separable_3x3_2', 'none' + ] + used_hiddenstates = [1, 1, 0, 0, 0, 0, 0] + hiddenstate_indices = [1, 1, 0, 0, 0, 0, 4, 0, 1, 0] + + super(PNasNetNormalCell, self).__init__( + num_conv_filters, operations, used_hiddenstates, hiddenstate_indices, + drop_path_keep_prob, total_num_cells, total_training_steps, + use_bounded_activation) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/pnasnet_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/pnasnet_test.py new file mode 100644 index 0000000..2cbd816 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nasnet/pnasnet_test.py @@ -0,0 +1,256 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for slim.pnasnet.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets.nasnet import pnasnet + +slim = tf.contrib.slim + + +class PNASNetTest(tf.test.TestCase): + + def testBuildLogitsLargeModel(self): + batch_size = 5 + height, width = 331, 331 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(pnasnet.pnasnet_large_arg_scope()): + logits, end_points = pnasnet.build_pnasnet_large(inputs, num_classes) + auxlogits = end_points['AuxLogits'] + predictions = end_points['Predictions'] + self.assertListEqual(auxlogits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertListEqual(predictions.get_shape().as_list(), + [batch_size, num_classes]) + + def testBuildLogitsMobileModel(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(pnasnet.pnasnet_mobile_arg_scope()): + logits, end_points = pnasnet.build_pnasnet_mobile(inputs, num_classes) + auxlogits = end_points['AuxLogits'] + predictions = end_points['Predictions'] + self.assertListEqual(auxlogits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertListEqual(predictions.get_shape().as_list(), + [batch_size, num_classes]) + + def testBuildNonExistingLayerLargeModel(self): + """Tests that the model is built correctly without unnecessary layers.""" + inputs = tf.random_uniform((5, 331, 331, 3)) + tf.train.create_global_step() + with slim.arg_scope(pnasnet.pnasnet_large_arg_scope()): + pnasnet.build_pnasnet_large(inputs, 1000) + vars_names = [x.op.name for x in tf.trainable_variables()] + self.assertIn('cell_stem_0/1x1/weights', vars_names) + self.assertNotIn('cell_stem_1/comb_iter_0/right/1x1/weights', vars_names) + + def testBuildNonExistingLayerMobileModel(self): + """Tests that the model is built correctly without unnecessary layers.""" + inputs = tf.random_uniform((5, 224, 224, 3)) + tf.train.create_global_step() + with slim.arg_scope(pnasnet.pnasnet_mobile_arg_scope()): + pnasnet.build_pnasnet_mobile(inputs, 1000) + vars_names = [x.op.name for x in tf.trainable_variables()] + self.assertIn('cell_stem_0/1x1/weights', vars_names) + self.assertNotIn('cell_stem_1/comb_iter_0/right/1x1/weights', vars_names) + + def testBuildPreLogitsLargeModel(self): + batch_size = 5 + height, width = 331, 331 + num_classes = None + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(pnasnet.pnasnet_large_arg_scope()): + net, end_points = pnasnet.build_pnasnet_large(inputs, num_classes) + self.assertFalse('AuxLogits' in end_points) + self.assertFalse('Predictions' in end_points) + self.assertTrue(net.op.name.startswith('final_layer/Mean')) + self.assertListEqual(net.get_shape().as_list(), [batch_size, 4320]) + + def testBuildPreLogitsMobileModel(self): + batch_size = 5 + height, width = 224, 224 + num_classes = None + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(pnasnet.pnasnet_mobile_arg_scope()): + net, end_points = pnasnet.build_pnasnet_mobile(inputs, num_classes) + self.assertFalse('AuxLogits' in end_points) + self.assertFalse('Predictions' in end_points) + self.assertTrue(net.op.name.startswith('final_layer/Mean')) + self.assertListEqual(net.get_shape().as_list(), [batch_size, 1080]) + + def testAllEndPointsShapesLargeModel(self): + batch_size = 5 + height, width = 331, 331 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(pnasnet.pnasnet_large_arg_scope()): + _, end_points = pnasnet.build_pnasnet_large(inputs, num_classes) + + endpoints_shapes = {'Stem': [batch_size, 42, 42, 540], + 'Cell_0': [batch_size, 42, 42, 1080], + 'Cell_1': [batch_size, 42, 42, 1080], + 'Cell_2': [batch_size, 42, 42, 1080], + 'Cell_3': [batch_size, 42, 42, 1080], + 'Cell_4': [batch_size, 21, 21, 2160], + 'Cell_5': [batch_size, 21, 21, 2160], + 'Cell_6': [batch_size, 21, 21, 2160], + 'Cell_7': [batch_size, 21, 21, 2160], + 'Cell_8': [batch_size, 11, 11, 4320], + 'Cell_9': [batch_size, 11, 11, 4320], + 'Cell_10': [batch_size, 11, 11, 4320], + 'Cell_11': [batch_size, 11, 11, 4320], + 'global_pool': [batch_size, 4320], + # Logits and predictions + 'AuxLogits': [batch_size, 1000], + 'Predictions': [batch_size, 1000], + 'Logits': [batch_size, 1000], + } + self.assertEqual(len(end_points), 17) + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name in endpoints_shapes: + tf.logging.info('Endpoint name: {}'.format(endpoint_name)) + expected_shape = endpoints_shapes[endpoint_name] + self.assertIn(endpoint_name, end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testAllEndPointsShapesMobileModel(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + with slim.arg_scope(pnasnet.pnasnet_mobile_arg_scope()): + _, end_points = pnasnet.build_pnasnet_mobile(inputs, num_classes) + + endpoints_shapes = { + 'Stem': [batch_size, 28, 28, 135], + 'Cell_0': [batch_size, 28, 28, 270], + 'Cell_1': [batch_size, 28, 28, 270], + 'Cell_2': [batch_size, 28, 28, 270], + 'Cell_3': [batch_size, 14, 14, 540], + 'Cell_4': [batch_size, 14, 14, 540], + 'Cell_5': [batch_size, 14, 14, 540], + 'Cell_6': [batch_size, 7, 7, 1080], + 'Cell_7': [batch_size, 7, 7, 1080], + 'Cell_8': [batch_size, 7, 7, 1080], + 'global_pool': [batch_size, 1080], + # Logits and predictions + 'AuxLogits': [batch_size, num_classes], + 'Predictions': [batch_size, num_classes], + 'Logits': [batch_size, num_classes], + } + self.assertEqual(len(end_points), 14) + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name in endpoints_shapes: + tf.logging.info('Endpoint name: {}'.format(endpoint_name)) + expected_shape = endpoints_shapes[endpoint_name] + self.assertIn(endpoint_name, end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testNoAuxHeadLargeModel(self): + batch_size = 5 + height, width = 331, 331 + num_classes = 1000 + for use_aux_head in (True, False): + tf.reset_default_graph() + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + config = pnasnet.large_imagenet_config() + config.set_hparam('use_aux_head', int(use_aux_head)) + with slim.arg_scope(pnasnet.pnasnet_large_arg_scope()): + _, end_points = pnasnet.build_pnasnet_large(inputs, num_classes, + config=config) + self.assertEqual('AuxLogits' in end_points, use_aux_head) + + def testNoAuxHeadMobileModel(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + for use_aux_head in (True, False): + tf.reset_default_graph() + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + config = pnasnet.mobile_imagenet_config() + config.set_hparam('use_aux_head', int(use_aux_head)) + with slim.arg_scope(pnasnet.pnasnet_mobile_arg_scope()): + _, end_points = pnasnet.build_pnasnet_mobile( + inputs, num_classes, config=config) + self.assertEqual('AuxLogits' in end_points, use_aux_head) + + def testOverrideHParamsLargeModel(self): + batch_size = 5 + height, width = 331, 331 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + config = pnasnet.large_imagenet_config() + config.set_hparam('data_format', 'NCHW') + with slim.arg_scope(pnasnet.pnasnet_large_arg_scope()): + _, end_points = pnasnet.build_pnasnet_large( + inputs, num_classes, config=config) + self.assertListEqual( + end_points['Stem'].shape.as_list(), [batch_size, 540, 42, 42]) + + def testOverrideHParamsMobileModel(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + inputs = tf.random_uniform((batch_size, height, width, 3)) + tf.train.create_global_step() + config = pnasnet.mobile_imagenet_config() + config.set_hparam('data_format', 'NCHW') + with slim.arg_scope(pnasnet.pnasnet_mobile_arg_scope()): + _, end_points = pnasnet.build_pnasnet_mobile( + inputs, num_classes, config=config) + self.assertListEqual(end_points['Stem'].shape.as_list(), + [batch_size, 135, 28, 28]) + + def testUseBoundedAcitvationMobileModel(self): + batch_size = 1 + height, width = 224, 224 + num_classes = 1000 + for use_bounded_activation in (True, False): + tf.reset_default_graph() + inputs = tf.random_uniform((batch_size, height, width, 3)) + config = pnasnet.mobile_imagenet_config() + config.set_hparam('use_bounded_activation', use_bounded_activation) + with slim.arg_scope(pnasnet.pnasnet_mobile_arg_scope()): + _, _ = pnasnet.build_pnasnet_mobile( + inputs, num_classes, config=config) + for node in tf.get_default_graph().as_graph_def().node: + if node.op.startswith('Relu'): + self.assertEqual(node.op == 'Relu6', use_bounded_activation) + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nets_factory.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nets_factory.py new file mode 100644 index 0000000..c64afcb --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nets_factory.py @@ -0,0 +1,159 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains a factory for building various models.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +import functools + +import tensorflow as tf + +from nets import alexnet +from nets import cifarnet +from nets import i3d +from nets import inception +from nets import lenet +from nets import mobilenet_v1 +from nets import overfeat +from nets import resnet_v1 +from nets import resnet_v2 +from nets import s3dg +from nets import vgg +from nets.mobilenet import mobilenet_v2 +from nets.nasnet import nasnet +from nets.nasnet import pnasnet + + +slim = tf.contrib.slim + +networks_map = {'alexnet_v2': alexnet.alexnet_v2, + 'cifarnet': cifarnet.cifarnet, + 'overfeat': overfeat.overfeat, + 'vgg_a': vgg.vgg_a, + 'vgg_16': vgg.vgg_16, + 'vgg_19': vgg.vgg_19, + 'inception_v1': inception.inception_v1, + 'inception_v2': inception.inception_v2, + 'inception_v3': inception.inception_v3, + 'inception_v4': inception.inception_v4, + 'inception_resnet_v2': inception.inception_resnet_v2, + 'i3d': i3d.i3d, + 's3dg': s3dg.s3dg, + 'lenet': lenet.lenet, + 'resnet_v1_50': resnet_v1.resnet_v1_50, + 'resnet_v1_101': resnet_v1.resnet_v1_101, + 'resnet_v1_152': resnet_v1.resnet_v1_152, + 'resnet_v1_200': resnet_v1.resnet_v1_200, + 'resnet_v2_50': resnet_v2.resnet_v2_50, + 'resnet_v2_101': resnet_v2.resnet_v2_101, + 'resnet_v2_152': resnet_v2.resnet_v2_152, + 'resnet_v2_200': resnet_v2.resnet_v2_200, + 'mobilenet_v1': mobilenet_v1.mobilenet_v1, + 'mobilenet_v1_075': mobilenet_v1.mobilenet_v1_075, + 'mobilenet_v1_050': mobilenet_v1.mobilenet_v1_050, + 'mobilenet_v1_025': mobilenet_v1.mobilenet_v1_025, + 'mobilenet_v2': mobilenet_v2.mobilenet, + 'mobilenet_v2_140': mobilenet_v2.mobilenet_v2_140, + 'mobilenet_v2_035': mobilenet_v2.mobilenet_v2_035, + 'nasnet_cifar': nasnet.build_nasnet_cifar, + 'nasnet_mobile': nasnet.build_nasnet_mobile, + 'nasnet_large': nasnet.build_nasnet_large, + 'pnasnet_large': pnasnet.build_pnasnet_large, + 'pnasnet_mobile': pnasnet.build_pnasnet_mobile, + } + +arg_scopes_map = {'alexnet_v2': alexnet.alexnet_v2_arg_scope, + 'cifarnet': cifarnet.cifarnet_arg_scope, + 'overfeat': overfeat.overfeat_arg_scope, + 'vgg_a': vgg.vgg_arg_scope, + 'vgg_16': vgg.vgg_arg_scope, + 'vgg_19': vgg.vgg_arg_scope, + 'inception_v1': inception.inception_v3_arg_scope, + 'inception_v2': inception.inception_v3_arg_scope, + 'inception_v3': inception.inception_v3_arg_scope, + 'inception_v4': inception.inception_v4_arg_scope, + 'inception_resnet_v2': + inception.inception_resnet_v2_arg_scope, + 'i3d': i3d.i3d_arg_scope, + 's3dg': s3dg.s3dg_arg_scope, + 'lenet': lenet.lenet_arg_scope, + 'resnet_v1_50': resnet_v1.resnet_arg_scope, + 'resnet_v1_101': resnet_v1.resnet_arg_scope, + 'resnet_v1_152': resnet_v1.resnet_arg_scope, + 'resnet_v1_200': resnet_v1.resnet_arg_scope, + 'resnet_v2_50': resnet_v2.resnet_arg_scope, + 'resnet_v2_101': resnet_v2.resnet_arg_scope, + 'resnet_v2_152': resnet_v2.resnet_arg_scope, + 'resnet_v2_200': resnet_v2.resnet_arg_scope, + 'mobilenet_v1': mobilenet_v1.mobilenet_v1_arg_scope, + 'mobilenet_v1_075': mobilenet_v1.mobilenet_v1_arg_scope, + 'mobilenet_v1_050': mobilenet_v1.mobilenet_v1_arg_scope, + 'mobilenet_v1_025': mobilenet_v1.mobilenet_v1_arg_scope, + 'mobilenet_v2': mobilenet_v2.training_scope, + 'mobilenet_v2_035': mobilenet_v2.training_scope, + 'mobilenet_v2_140': mobilenet_v2.training_scope, + 'nasnet_cifar': nasnet.nasnet_cifar_arg_scope, + 'nasnet_mobile': nasnet.nasnet_mobile_arg_scope, + 'nasnet_large': nasnet.nasnet_large_arg_scope, + 'pnasnet_large': pnasnet.pnasnet_large_arg_scope, + 'pnasnet_mobile': pnasnet.pnasnet_mobile_arg_scope, + } + + +def get_network_fn(name, num_classes, weight_decay=0.0, is_training=False): + """Returns a network_fn such as `logits, end_points = network_fn(images)`. + + Args: + name: The name of the network. + num_classes: The number of classes to use for classification. If 0 or None, + the logits layer is omitted and its input features are returned instead. + weight_decay: The l2 coefficient for the model weights. + is_training: `True` if the model is being used for training and `False` + otherwise. + + Returns: + network_fn: A function that applies the model to a batch of images. It has + the following signature: + net, end_points = network_fn(images) + The `images` input is a tensor of shape [batch_size, height, width, 3] + with height = width = network_fn.default_image_size. (The permissibility + and treatment of other sizes depends on the network_fn.) + The returned `end_points` are a dictionary of intermediate activations. + The returned `net` is the topmost layer, depending on `num_classes`: + If `num_classes` was a non-zero integer, `net` is a logits tensor + of shape [batch_size, num_classes]. + If `num_classes` was 0 or `None`, `net` is a tensor with the input + to the logits layer of shape [batch_size, 1, 1, num_features] or + [batch_size, num_features]. Dropout has not been applied to this + (even if the network's original classification does); it remains for + the caller to do this or not. + + Raises: + ValueError: If network `name` is not recognized. + """ + if name not in networks_map: + raise ValueError('Name of network unknown %s' % name) + func = networks_map[name] + @functools.wraps(func) + def network_fn(images, **kwargs): + arg_scope = arg_scopes_map[name](weight_decay=weight_decay) + with slim.arg_scope(arg_scope): + return func(images, num_classes=num_classes, is_training=is_training, + **kwargs) + if hasattr(func, 'default_image_size'): + network_fn.default_image_size = func.default_image_size + + return network_fn diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nets_factory_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nets_factory_test.py new file mode 100644 index 0000000..e111fc2 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/nets_factory_test.py @@ -0,0 +1,81 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Tests for slim.inception.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + + +import tensorflow as tf + +from nets import nets_factory + + +class NetworksTest(tf.test.TestCase): + + def testGetNetworkFnFirstHalf(self): + batch_size = 5 + num_classes = 1000 + for net in list(nets_factory.networks_map.keys())[:10]: + with tf.Graph().as_default() as g, self.test_session(g): + net_fn = nets_factory.get_network_fn(net, num_classes=num_classes) + # Most networks use 224 as their default_image_size + image_size = getattr(net_fn, 'default_image_size', 224) + if net not in ['i3d', 's3dg']: + inputs = tf.random_uniform( + (batch_size, image_size, image_size, 3)) + logits, end_points = net_fn(inputs) + self.assertTrue(isinstance(logits, tf.Tensor)) + self.assertTrue(isinstance(end_points, dict)) + self.assertEqual(logits.get_shape().as_list()[0], batch_size) + self.assertEqual(logits.get_shape().as_list()[-1], num_classes) + + def testGetNetworkFnSecondHalf(self): + batch_size = 5 + num_classes = 1000 + for net in list(nets_factory.networks_map.keys())[10:]: + with tf.Graph().as_default() as g, self.test_session(g): + net_fn = nets_factory.get_network_fn(net, num_classes=num_classes) + # Most networks use 224 as their default_image_size + image_size = getattr(net_fn, 'default_image_size', 224) + if net not in ['i3d', 's3dg']: + inputs = tf.random_uniform( + (batch_size, image_size, image_size, 3)) + logits, end_points = net_fn(inputs) + self.assertTrue(isinstance(logits, tf.Tensor)) + self.assertTrue(isinstance(end_points, dict)) + self.assertEqual(logits.get_shape().as_list()[0], batch_size) + self.assertEqual(logits.get_shape().as_list()[-1], num_classes) + + def testGetNetworkFnVideoModels(self): + batch_size = 5 + num_classes = 400 + for net in ['i3d', 's3dg']: + with tf.Graph().as_default() as g, self.test_session(g): + net_fn = nets_factory.get_network_fn(net, num_classes=num_classes) + # Most networks use 224 as their default_image_size + image_size = getattr(net_fn, 'default_image_size', 224) // 2 + inputs = tf.random_uniform( + (batch_size, 10, image_size, image_size, 3)) + logits, end_points = net_fn(inputs) + self.assertTrue(isinstance(logits, tf.Tensor)) + self.assertTrue(isinstance(end_points, dict)) + self.assertEqual(logits.get_shape().as_list()[0], batch_size) + self.assertEqual(logits.get_shape().as_list()[-1], num_classes) + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/overfeat.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/overfeat.py new file mode 100644 index 0000000..069f550 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/overfeat.py @@ -0,0 +1,131 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains the model definition for the OverFeat network. + +The definition for the network was obtained from: + OverFeat: Integrated Recognition, Localization and Detection using + Convolutional Networks + Pierre Sermanet, David Eigen, Xiang Zhang, Michael Mathieu, Rob Fergus and + Yann LeCun, 2014 + http://arxiv.org/abs/1312.6229 + +Usage: + with slim.arg_scope(overfeat.overfeat_arg_scope()): + outputs, end_points = overfeat.overfeat(inputs) + +@@overfeat +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +slim = tf.contrib.slim +trunc_normal = lambda stddev: tf.truncated_normal_initializer(0.0, stddev) + + +def overfeat_arg_scope(weight_decay=0.0005): + with slim.arg_scope([slim.conv2d, slim.fully_connected], + activation_fn=tf.nn.relu, + weights_regularizer=slim.l2_regularizer(weight_decay), + biases_initializer=tf.zeros_initializer()): + with slim.arg_scope([slim.conv2d], padding='SAME'): + with slim.arg_scope([slim.max_pool2d], padding='VALID') as arg_sc: + return arg_sc + + +def overfeat(inputs, + num_classes=1000, + is_training=True, + dropout_keep_prob=0.5, + spatial_squeeze=True, + scope='overfeat', + global_pool=False): + """Contains the model definition for the OverFeat network. + + The definition for the network was obtained from: + OverFeat: Integrated Recognition, Localization and Detection using + Convolutional Networks + Pierre Sermanet, David Eigen, Xiang Zhang, Michael Mathieu, Rob Fergus and + Yann LeCun, 2014 + http://arxiv.org/abs/1312.6229 + + Note: All the fully_connected layers have been transformed to conv2d layers. + To use in classification mode, resize input to 231x231. To use in fully + convolutional mode, set spatial_squeeze to false. + + Args: + inputs: a tensor of size [batch_size, height, width, channels]. + num_classes: number of predicted classes. If 0 or None, the logits layer is + omitted and the input features to the logits layer are returned instead. + is_training: whether or not the model is being trained. + dropout_keep_prob: the probability that activations are kept in the dropout + layers during training. + spatial_squeeze: whether or not should squeeze the spatial dimensions of the + outputs. Useful to remove unnecessary dimensions for classification. + scope: Optional scope for the variables. + global_pool: Optional boolean flag. If True, the input to the classification + layer is avgpooled to size 1x1, for any input size. (This is not part + of the original OverFeat.) + + Returns: + net: the output of the logits layer (if num_classes is a non-zero integer), + or the non-dropped-out input to the logits layer (if num_classes is 0 or + None). + end_points: a dict of tensors with intermediate activations. + """ + with tf.variable_scope(scope, 'overfeat', [inputs]) as sc: + end_points_collection = sc.original_name_scope + '_end_points' + # Collect outputs for conv2d, fully_connected and max_pool2d + with slim.arg_scope([slim.conv2d, slim.fully_connected, slim.max_pool2d], + outputs_collections=end_points_collection): + net = slim.conv2d(inputs, 64, [11, 11], 4, padding='VALID', + scope='conv1') + net = slim.max_pool2d(net, [2, 2], scope='pool1') + net = slim.conv2d(net, 256, [5, 5], padding='VALID', scope='conv2') + net = slim.max_pool2d(net, [2, 2], scope='pool2') + net = slim.conv2d(net, 512, [3, 3], scope='conv3') + net = slim.conv2d(net, 1024, [3, 3], scope='conv4') + net = slim.conv2d(net, 1024, [3, 3], scope='conv5') + net = slim.max_pool2d(net, [2, 2], scope='pool5') + + # Use conv2d instead of fully_connected layers. + with slim.arg_scope([slim.conv2d], + weights_initializer=trunc_normal(0.005), + biases_initializer=tf.constant_initializer(0.1)): + net = slim.conv2d(net, 3072, [6, 6], padding='VALID', scope='fc6') + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout6') + net = slim.conv2d(net, 4096, [1, 1], scope='fc7') + # Convert end_points_collection into a end_point dict. + end_points = slim.utils.convert_collection_to_dict( + end_points_collection) + if global_pool: + net = tf.reduce_mean(net, [1, 2], keep_dims=True, name='global_pool') + end_points['global_pool'] = net + if num_classes: + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout7') + net = slim.conv2d(net, num_classes, [1, 1], + activation_fn=None, + normalizer_fn=None, + biases_initializer=tf.zeros_initializer(), + scope='fc8') + if spatial_squeeze: + net = tf.squeeze(net, [1, 2], name='fc8/squeezed') + end_points[sc.name + '/fc8'] = net + return net, end_points +overfeat.default_image_size = 231 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/overfeat_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/overfeat_test.py new file mode 100644 index 0000000..dab0039 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/overfeat_test.py @@ -0,0 +1,178 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for slim.nets.overfeat.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import overfeat + +slim = tf.contrib.slim + + +class OverFeatTest(tf.test.TestCase): + + def testBuild(self): + batch_size = 5 + height, width = 231, 231 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = overfeat.overfeat(inputs, num_classes) + self.assertEquals(logits.op.name, 'overfeat/fc8/squeezed') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + + def testFullyConvolutional(self): + batch_size = 1 + height, width = 281, 281 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = overfeat.overfeat(inputs, num_classes, spatial_squeeze=False) + self.assertEquals(logits.op.name, 'overfeat/fc8/BiasAdd') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, 2, 2, num_classes]) + + def testGlobalPool(self): + batch_size = 1 + height, width = 281, 281 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = overfeat.overfeat(inputs, num_classes, spatial_squeeze=False, + global_pool=True) + self.assertEquals(logits.op.name, 'overfeat/fc8/BiasAdd') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, 1, 1, num_classes]) + + def testEndPoints(self): + batch_size = 5 + height, width = 231, 231 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = overfeat.overfeat(inputs, num_classes) + expected_names = ['overfeat/conv1', + 'overfeat/pool1', + 'overfeat/conv2', + 'overfeat/pool2', + 'overfeat/conv3', + 'overfeat/conv4', + 'overfeat/conv5', + 'overfeat/pool5', + 'overfeat/fc6', + 'overfeat/fc7', + 'overfeat/fc8' + ] + self.assertSetEqual(set(end_points.keys()), set(expected_names)) + + def testNoClasses(self): + batch_size = 5 + height, width = 231, 231 + num_classes = None + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, end_points = overfeat.overfeat(inputs, num_classes) + expected_names = ['overfeat/conv1', + 'overfeat/pool1', + 'overfeat/conv2', + 'overfeat/pool2', + 'overfeat/conv3', + 'overfeat/conv4', + 'overfeat/conv5', + 'overfeat/pool5', + 'overfeat/fc6', + 'overfeat/fc7' + ] + self.assertSetEqual(set(end_points.keys()), set(expected_names)) + self.assertTrue(net.op.name.startswith('overfeat/fc7')) + + def testModelVariables(self): + batch_size = 5 + height, width = 231, 231 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + overfeat.overfeat(inputs, num_classes) + expected_names = ['overfeat/conv1/weights', + 'overfeat/conv1/biases', + 'overfeat/conv2/weights', + 'overfeat/conv2/biases', + 'overfeat/conv3/weights', + 'overfeat/conv3/biases', + 'overfeat/conv4/weights', + 'overfeat/conv4/biases', + 'overfeat/conv5/weights', + 'overfeat/conv5/biases', + 'overfeat/fc6/weights', + 'overfeat/fc6/biases', + 'overfeat/fc7/weights', + 'overfeat/fc7/biases', + 'overfeat/fc8/weights', + 'overfeat/fc8/biases', + ] + model_variables = [v.op.name for v in slim.get_model_variables()] + self.assertSetEqual(set(model_variables), set(expected_names)) + + def testEvaluation(self): + batch_size = 2 + height, width = 231, 231 + num_classes = 1000 + with self.test_session(): + eval_inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = overfeat.overfeat(eval_inputs, is_training=False) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + predictions = tf.argmax(logits, 1) + self.assertListEqual(predictions.get_shape().as_list(), [batch_size]) + + def testTrainEvalWithReuse(self): + train_batch_size = 2 + eval_batch_size = 1 + train_height, train_width = 231, 231 + eval_height, eval_width = 281, 281 + num_classes = 1000 + with self.test_session(): + train_inputs = tf.random_uniform( + (train_batch_size, train_height, train_width, 3)) + logits, _ = overfeat.overfeat(train_inputs) + self.assertListEqual(logits.get_shape().as_list(), + [train_batch_size, num_classes]) + tf.get_variable_scope().reuse_variables() + eval_inputs = tf.random_uniform( + (eval_batch_size, eval_height, eval_width, 3)) + logits, _ = overfeat.overfeat(eval_inputs, is_training=False, + spatial_squeeze=False) + self.assertListEqual(logits.get_shape().as_list(), + [eval_batch_size, 2, 2, num_classes]) + logits = tf.reduce_mean(logits, [1, 2]) + predictions = tf.argmax(logits, 1) + self.assertEquals(predictions.get_shape().as_list(), [eval_batch_size]) + + def testForward(self): + batch_size = 1 + height, width = 231, 231 + with self.test_session() as sess: + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = overfeat.overfeat(inputs) + sess.run(tf.global_variables_initializer()) + output = sess.run(logits) + self.assertTrue(output.any()) + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/pix2pix.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/pix2pix.py new file mode 100644 index 0000000..8c3a2e9 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/pix2pix.py @@ -0,0 +1,295 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================= +"""Implementation of the Image-to-Image Translation model. + +This network represents a port of the following work: + + Image-to-Image Translation with Conditional Adversarial Networks + Phillip Isola, Jun-Yan Zhu, Tinghui Zhou and Alexei A. Efros + Arxiv, 2017 + https://phillipi.github.io/pix2pix/ + +A reference implementation written in Lua can be found at: +https://github.com/phillipi/pix2pix/blob/master/models.lua +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import collections +import functools + +import tensorflow as tf + +layers = tf.contrib.layers + + +def pix2pix_arg_scope(): + """Returns a default argument scope for isola_net. + + Returns: + An arg scope. + """ + # These parameters come from the online port, which don't necessarily match + # those in the paper. + # TODO(nsilberman): confirm these values with Philip. + instance_norm_params = { + 'center': True, + 'scale': True, + 'epsilon': 0.00001, + } + + with tf.contrib.framework.arg_scope( + [layers.conv2d, layers.conv2d_transpose], + normalizer_fn=layers.instance_norm, + normalizer_params=instance_norm_params, + weights_initializer=tf.random_normal_initializer(0, 0.02)) as sc: + return sc + + +def upsample(net, num_outputs, kernel_size, method='nn_upsample_conv'): + """Upsamples the given inputs. + + Args: + net: A `Tensor` of size [batch_size, height, width, filters]. + num_outputs: The number of output filters. + kernel_size: A list of 2 scalars or a 1x2 `Tensor` indicating the scale, + relative to the inputs, of the output dimensions. For example, if kernel + size is [2, 3], then the output height and width will be twice and three + times the input size. + method: The upsampling method. + + Returns: + An `Tensor` which was upsampled using the specified method. + + Raises: + ValueError: if `method` is not recognized. + """ + net_shape = tf.shape(net) + height = net_shape[1] + width = net_shape[2] + + if method == 'nn_upsample_conv': + net = tf.image.resize_nearest_neighbor( + net, [kernel_size[0] * height, kernel_size[1] * width]) + net = layers.conv2d(net, num_outputs, [4, 4], activation_fn=None) + elif method == 'conv2d_transpose': + net = layers.conv2d_transpose( + net, num_outputs, [4, 4], stride=kernel_size, activation_fn=None) + else: + raise ValueError('Unknown method: [%s]' % method) + + return net + + +class Block( + collections.namedtuple('Block', ['num_filters', 'decoder_keep_prob'])): + """Represents a single block of encoder and decoder processing. + + The Image-to-Image translation paper works a bit differently than the original + U-Net model. In particular, each block represents a single operation in the + encoder which is concatenated with the corresponding decoder representation. + A dropout layer follows the concatenation and convolution of the concatenated + features. + """ + pass + + +def _default_generator_blocks(): + """Returns the default generator block definitions. + + Returns: + A list of generator blocks. + """ + return [ + Block(64, 0.5), + Block(128, 0.5), + Block(256, 0.5), + Block(512, 0), + Block(512, 0), + Block(512, 0), + Block(512, 0), + ] + + +def pix2pix_generator(net, + num_outputs, + blocks=None, + upsample_method='nn_upsample_conv', + is_training=False): # pylint: disable=unused-argument + """Defines the network architecture. + + Args: + net: A `Tensor` of size [batch, height, width, channels]. Note that the + generator currently requires square inputs (e.g. height=width). + num_outputs: The number of (per-pixel) outputs. + blocks: A list of generator blocks or `None` to use the default generator + definition. + upsample_method: The method of upsampling images, one of 'nn_upsample_conv' + or 'conv2d_transpose' + is_training: Whether or not we're in training or testing mode. + + Returns: + A `Tensor` representing the model output and a dictionary of model end + points. + + Raises: + ValueError: if the input heights do not match their widths. + """ + end_points = {} + + blocks = blocks or _default_generator_blocks() + + input_size = net.get_shape().as_list() + + input_size[3] = num_outputs + + upsample_fn = functools.partial(upsample, method=upsample_method) + + encoder_activations = [] + + ########### + # Encoder # + ########### + with tf.variable_scope('encoder'): + with tf.contrib.framework.arg_scope( + [layers.conv2d], + kernel_size=[4, 4], + stride=2, + activation_fn=tf.nn.leaky_relu): + + for block_id, block in enumerate(blocks): + # No normalizer for the first encoder layers as per 'Image-to-Image', + # Section 5.1.1 + if block_id == 0: + # First layer doesn't use normalizer_fn + net = layers.conv2d(net, block.num_filters, normalizer_fn=None) + elif block_id < len(blocks) - 1: + net = layers.conv2d(net, block.num_filters) + else: + # Last layer doesn't use activation_fn nor normalizer_fn + net = layers.conv2d( + net, block.num_filters, activation_fn=None, normalizer_fn=None) + + encoder_activations.append(net) + end_points['encoder%d' % block_id] = net + + ########### + # Decoder # + ########### + reversed_blocks = list(blocks) + reversed_blocks.reverse() + + with tf.variable_scope('decoder'): + # Dropout is used at both train and test time as per 'Image-to-Image', + # Section 2.1 (last paragraph). + with tf.contrib.framework.arg_scope([layers.dropout], is_training=True): + + for block_id, block in enumerate(reversed_blocks): + if block_id > 0: + net = tf.concat([net, encoder_activations[-block_id - 1]], axis=3) + + # The Relu comes BEFORE the upsample op: + net = tf.nn.relu(net) + net = upsample_fn(net, block.num_filters, [2, 2]) + if block.decoder_keep_prob > 0: + net = layers.dropout(net, keep_prob=block.decoder_keep_prob) + end_points['decoder%d' % block_id] = net + + with tf.variable_scope('output'): + # Explicitly set the normalizer_fn to None to override any default value + # that may come from an arg_scope, such as pix2pix_arg_scope. + logits = layers.conv2d( + net, num_outputs, [4, 4], activation_fn=None, normalizer_fn=None) + logits = tf.reshape(logits, input_size) + + end_points['logits'] = logits + end_points['predictions'] = tf.tanh(logits) + + return logits, end_points + + +def pix2pix_discriminator(net, num_filters, padding=2, pad_mode='REFLECT', + activation_fn=tf.nn.leaky_relu, is_training=False): + """Creates the Image2Image Translation Discriminator. + + Args: + net: A `Tensor` of size [batch_size, height, width, channels] representing + the input. + num_filters: A list of the filters in the discriminator. The length of the + list determines the number of layers in the discriminator. + padding: Amount of reflection padding applied before each convolution. + pad_mode: mode for tf.pad, one of "CONSTANT", "REFLECT", or "SYMMETRIC". + activation_fn: activation fn for layers.conv2d. + is_training: Whether or not the model is training or testing. + + Returns: + A logits `Tensor` of size [batch_size, N, N, 1] where N is the number of + 'patches' we're attempting to discriminate and a dictionary of model end + points. + """ + del is_training + end_points = {} + + num_layers = len(num_filters) + + def padded(net, scope): + if padding: + with tf.variable_scope(scope): + spatial_pad = tf.constant( + [[0, 0], [padding, padding], [padding, padding], [0, 0]], + dtype=tf.int32) + return tf.pad(net, spatial_pad, pad_mode) + else: + return net + + with tf.contrib.framework.arg_scope( + [layers.conv2d], + kernel_size=[4, 4], + stride=2, + padding='valid', + activation_fn=activation_fn): + + # No normalization on the input layer. + net = layers.conv2d( + padded(net, 'conv0'), num_filters[0], normalizer_fn=None, scope='conv0') + + end_points['conv0'] = net + + for i in range(1, num_layers - 1): + net = layers.conv2d( + padded(net, 'conv%d' % i), num_filters[i], scope='conv%d' % i) + end_points['conv%d' % i] = net + + # Stride 1 on the last layer. + net = layers.conv2d( + padded(net, 'conv%d' % (num_layers - 1)), + num_filters[-1], + stride=1, + scope='conv%d' % (num_layers - 1)) + end_points['conv%d' % (num_layers - 1)] = net + + # 1-dim logits, stride 1, no activation, no normalization. + logits = layers.conv2d( + padded(net, 'conv%d' % num_layers), + 1, + stride=1, + activation_fn=None, + normalizer_fn=None, + scope='conv%d' % num_layers) + end_points['logits'] = logits + end_points['predictions'] = tf.sigmoid(logits) + return logits, end_points diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/pix2pix_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/pix2pix_test.py new file mode 100644 index 0000000..ab5acb5 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/pix2pix_test.py @@ -0,0 +1,156 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================= +"""Tests for pix2pix.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf +from nets import pix2pix + + +class GeneratorTest(tf.test.TestCase): + + def _reduced_default_blocks(self): + """Returns the default blocks, scaled down to make test run faster.""" + return [pix2pix.Block(b.num_filters // 32, b.decoder_keep_prob) + for b in pix2pix._default_generator_blocks()] + + def test_output_size_nn_upsample_conv(self): + batch_size = 2 + height, width = 256, 256 + num_outputs = 4 + + images = tf.ones((batch_size, height, width, 3)) + with tf.contrib.framework.arg_scope(pix2pix.pix2pix_arg_scope()): + logits, _ = pix2pix.pix2pix_generator( + images, num_outputs, blocks=self._reduced_default_blocks(), + upsample_method='nn_upsample_conv') + + with self.test_session() as session: + session.run(tf.global_variables_initializer()) + np_outputs = session.run(logits) + self.assertListEqual([batch_size, height, width, num_outputs], + list(np_outputs.shape)) + + def test_output_size_conv2d_transpose(self): + batch_size = 2 + height, width = 256, 256 + num_outputs = 4 + + images = tf.ones((batch_size, height, width, 3)) + with tf.contrib.framework.arg_scope(pix2pix.pix2pix_arg_scope()): + logits, _ = pix2pix.pix2pix_generator( + images, num_outputs, blocks=self._reduced_default_blocks(), + upsample_method='conv2d_transpose') + + with self.test_session() as session: + session.run(tf.global_variables_initializer()) + np_outputs = session.run(logits) + self.assertListEqual([batch_size, height, width, num_outputs], + list(np_outputs.shape)) + + def test_block_number_dictates_number_of_layers(self): + batch_size = 2 + height, width = 256, 256 + num_outputs = 4 + + images = tf.ones((batch_size, height, width, 3)) + blocks = [ + pix2pix.Block(64, 0.5), + pix2pix.Block(128, 0), + ] + with tf.contrib.framework.arg_scope(pix2pix.pix2pix_arg_scope()): + _, end_points = pix2pix.pix2pix_generator( + images, num_outputs, blocks) + + num_encoder_layers = 0 + num_decoder_layers = 0 + for end_point in end_points: + if end_point.startswith('encoder'): + num_encoder_layers += 1 + elif end_point.startswith('decoder'): + num_decoder_layers += 1 + + self.assertEqual(num_encoder_layers, len(blocks)) + self.assertEqual(num_decoder_layers, len(blocks)) + + +class DiscriminatorTest(tf.test.TestCase): + + def _layer_output_size(self, input_size, kernel_size=4, stride=2, pad=2): + return (input_size + pad * 2 - kernel_size) // stride + 1 + + def test_four_layers(self): + batch_size = 2 + input_size = 256 + + output_size = self._layer_output_size(input_size) + output_size = self._layer_output_size(output_size) + output_size = self._layer_output_size(output_size) + output_size = self._layer_output_size(output_size, stride=1) + output_size = self._layer_output_size(output_size, stride=1) + + images = tf.ones((batch_size, input_size, input_size, 3)) + with tf.contrib.framework.arg_scope(pix2pix.pix2pix_arg_scope()): + logits, end_points = pix2pix.pix2pix_discriminator( + images, num_filters=[64, 128, 256, 512]) + self.assertListEqual([batch_size, output_size, output_size, 1], + logits.shape.as_list()) + self.assertListEqual([batch_size, output_size, output_size, 1], + end_points['predictions'].shape.as_list()) + + def test_four_layers_no_padding(self): + batch_size = 2 + input_size = 256 + + output_size = self._layer_output_size(input_size, pad=0) + output_size = self._layer_output_size(output_size, pad=0) + output_size = self._layer_output_size(output_size, pad=0) + output_size = self._layer_output_size(output_size, stride=1, pad=0) + output_size = self._layer_output_size(output_size, stride=1, pad=0) + + images = tf.ones((batch_size, input_size, input_size, 3)) + with tf.contrib.framework.arg_scope(pix2pix.pix2pix_arg_scope()): + logits, end_points = pix2pix.pix2pix_discriminator( + images, num_filters=[64, 128, 256, 512], padding=0) + self.assertListEqual([batch_size, output_size, output_size, 1], + logits.shape.as_list()) + self.assertListEqual([batch_size, output_size, output_size, 1], + end_points['predictions'].shape.as_list()) + + def test_four_layers_wrog_paddig(self): + batch_size = 2 + input_size = 256 + + images = tf.ones((batch_size, input_size, input_size, 3)) + with tf.contrib.framework.arg_scope(pix2pix.pix2pix_arg_scope()): + with self.assertRaises(TypeError): + pix2pix.pix2pix_discriminator( + images, num_filters=[64, 128, 256, 512], padding=1.5) + + def test_four_layers_negative_padding(self): + batch_size = 2 + input_size = 256 + + images = tf.ones((batch_size, input_size, input_size, 3)) + with tf.contrib.framework.arg_scope(pix2pix.pix2pix_arg_scope()): + with self.assertRaises(ValueError): + pix2pix.pix2pix_discriminator( + images, num_filters=[64, 128, 256, 512], padding=-1) + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_utils.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_utils.py new file mode 100644 index 0000000..b4fc0e0 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_utils.py @@ -0,0 +1,275 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains building blocks for various versions of Residual Networks. + +Residual networks (ResNets) were proposed in: + Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun + Deep Residual Learning for Image Recognition. arXiv:1512.03385, 2015 + +More variants were introduced in: + Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun + Identity Mappings in Deep Residual Networks. arXiv: 1603.05027, 2016 + +We can obtain different ResNet variants by changing the network depth, width, +and form of residual unit. This module implements the infrastructure for +building them. Concrete ResNet units and full ResNet networks are implemented in +the accompanying resnet_v1.py and resnet_v2.py modules. + +Compared to https://github.com/KaimingHe/deep-residual-networks, in the current +implementation we subsample the output activations in the last residual unit of +each block, instead of subsampling the input activations in the first residual +unit of each block. The two implementations give identical results but our +implementation is more memory efficient. +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import collections +import tensorflow as tf + +slim = tf.contrib.slim + + +class Block(collections.namedtuple('Block', ['scope', 'unit_fn', 'args'])): + """A named tuple describing a ResNet block. + + Its parts are: + scope: The scope of the `Block`. + unit_fn: The ResNet unit function which takes as input a `Tensor` and + returns another `Tensor` with the output of the ResNet unit. + args: A list of length equal to the number of units in the `Block`. The list + contains one (depth, depth_bottleneck, stride) tuple for each unit in the + block to serve as argument to unit_fn. + """ + + +def subsample(inputs, factor, scope=None): + """Subsamples the input along the spatial dimensions. + + Args: + inputs: A `Tensor` of size [batch, height_in, width_in, channels]. + factor: The subsampling factor. + scope: Optional variable_scope. + + Returns: + output: A `Tensor` of size [batch, height_out, width_out, channels] with the + input, either intact (if factor == 1) or subsampled (if factor > 1). + """ + if factor == 1: + return inputs + else: + return slim.max_pool2d(inputs, [1, 1], stride=factor, scope=scope) + + +def conv2d_same(inputs, num_outputs, kernel_size, stride, rate=1, scope=None): + """Strided 2-D convolution with 'SAME' padding. + + When stride > 1, then we do explicit zero-padding, followed by conv2d with + 'VALID' padding. + + Note that + + net = conv2d_same(inputs, num_outputs, 3, stride=stride) + + is equivalent to + + net = slim.conv2d(inputs, num_outputs, 3, stride=1, padding='SAME') + net = subsample(net, factor=stride) + + whereas + + net = slim.conv2d(inputs, num_outputs, 3, stride=stride, padding='SAME') + + is different when the input's height or width is even, which is why we add the + current function. For more details, see ResnetUtilsTest.testConv2DSameEven(). + + Args: + inputs: A 4-D tensor of size [batch, height_in, width_in, channels]. + num_outputs: An integer, the number of output filters. + kernel_size: An int with the kernel_size of the filters. + stride: An integer, the output stride. + rate: An integer, rate for atrous convolution. + scope: Scope. + + Returns: + output: A 4-D tensor of size [batch, height_out, width_out, channels] with + the convolution output. + """ + if stride == 1: + return slim.conv2d(inputs, num_outputs, kernel_size, stride=1, rate=rate, + padding='SAME', scope=scope) + else: + kernel_size_effective = kernel_size + (kernel_size - 1) * (rate - 1) + pad_total = kernel_size_effective - 1 + pad_beg = pad_total // 2 + pad_end = pad_total - pad_beg + inputs = tf.pad(inputs, + [[0, 0], [pad_beg, pad_end], [pad_beg, pad_end], [0, 0]]) + return slim.conv2d(inputs, num_outputs, kernel_size, stride=stride, + rate=rate, padding='VALID', scope=scope) + + +@slim.add_arg_scope +def stack_blocks_dense(net, blocks, output_stride=None, + store_non_strided_activations=False, + outputs_collections=None): + """Stacks ResNet `Blocks` and controls output feature density. + + First, this function creates scopes for the ResNet in the form of + 'block_name/unit_1', 'block_name/unit_2', etc. + + Second, this function allows the user to explicitly control the ResNet + output_stride, which is the ratio of the input to output spatial resolution. + This is useful for dense prediction tasks such as semantic segmentation or + object detection. + + Most ResNets consist of 4 ResNet blocks and subsample the activations by a + factor of 2 when transitioning between consecutive ResNet blocks. This results + to a nominal ResNet output_stride equal to 8. If we set the output_stride to + half the nominal network stride (e.g., output_stride=4), then we compute + responses twice. + + Control of the output feature density is implemented by atrous convolution. + + Args: + net: A `Tensor` of size [batch, height, width, channels]. + blocks: A list of length equal to the number of ResNet `Blocks`. Each + element is a ResNet `Block` object describing the units in the `Block`. + output_stride: If `None`, then the output will be computed at the nominal + network stride. If output_stride is not `None`, it specifies the requested + ratio of input to output spatial resolution, which needs to be equal to + the product of unit strides from the start up to some level of the ResNet. + For example, if the ResNet employs units with strides 1, 2, 1, 3, 4, 1, + then valid values for the output_stride are 1, 2, 6, 24 or None (which + is equivalent to output_stride=24). + store_non_strided_activations: If True, we compute non-strided (undecimated) + activations at the last unit of each block and store them in the + `outputs_collections` before subsampling them. This gives us access to + higher resolution intermediate activations which are useful in some + dense prediction problems but increases 4x the computation and memory cost + at the last unit of each block. + outputs_collections: Collection to add the ResNet block outputs. + + Returns: + net: Output tensor with stride equal to the specified output_stride. + + Raises: + ValueError: If the target output_stride is not valid. + """ + # The current_stride variable keeps track of the effective stride of the + # activations. This allows us to invoke atrous convolution whenever applying + # the next residual unit would result in the activations having stride larger + # than the target output_stride. + current_stride = 1 + + # The atrous convolution rate parameter. + rate = 1 + + for block in blocks: + with tf.variable_scope(block.scope, 'block', [net]) as sc: + block_stride = 1 + for i, unit in enumerate(block.args): + if store_non_strided_activations and i == len(block.args) - 1: + # Move stride from the block's last unit to the end of the block. + block_stride = unit.get('stride', 1) + unit = dict(unit, stride=1) + + with tf.variable_scope('unit_%d' % (i + 1), values=[net]): + # If we have reached the target output_stride, then we need to employ + # atrous convolution with stride=1 and multiply the atrous rate by the + # current unit's stride for use in subsequent layers. + if output_stride is not None and current_stride == output_stride: + net = block.unit_fn(net, rate=rate, **dict(unit, stride=1)) + rate *= unit.get('stride', 1) + + else: + net = block.unit_fn(net, rate=1, **unit) + current_stride *= unit.get('stride', 1) + if output_stride is not None and current_stride > output_stride: + raise ValueError('The target output_stride cannot be reached.') + + # Collect activations at the block's end before performing subsampling. + net = slim.utils.collect_named_outputs(outputs_collections, sc.name, net) + + # Subsampling of the block's output activations. + if output_stride is not None and current_stride == output_stride: + rate *= block_stride + else: + net = subsample(net, block_stride) + current_stride *= block_stride + if output_stride is not None and current_stride > output_stride: + raise ValueError('The target output_stride cannot be reached.') + + if output_stride is not None and current_stride != output_stride: + raise ValueError('The target output_stride cannot be reached.') + + return net + + +def resnet_arg_scope(weight_decay=0.0001, + batch_norm_decay=0.997, + batch_norm_epsilon=1e-5, + batch_norm_scale=True, + activation_fn=tf.nn.relu, + use_batch_norm=True, + batch_norm_updates_collections=tf.GraphKeys.UPDATE_OPS): + """Defines the default ResNet arg scope. + + TODO(gpapan): The batch-normalization related default values above are + appropriate for use in conjunction with the reference ResNet models + released at https://github.com/KaimingHe/deep-residual-networks. When + training ResNets from scratch, they might need to be tuned. + + Args: + weight_decay: The weight decay to use for regularizing the model. + batch_norm_decay: The moving average decay when estimating layer activation + statistics in batch normalization. + batch_norm_epsilon: Small constant to prevent division by zero when + normalizing activations by their variance in batch normalization. + batch_norm_scale: If True, uses an explicit `gamma` multiplier to scale the + activations in the batch normalization layer. + activation_fn: The activation function which is used in ResNet. + use_batch_norm: Whether or not to use batch normalization. + batch_norm_updates_collections: Collection for the update ops for + batch norm. + + Returns: + An `arg_scope` to use for the resnet models. + """ + batch_norm_params = { + 'decay': batch_norm_decay, + 'epsilon': batch_norm_epsilon, + 'scale': batch_norm_scale, + 'updates_collections': batch_norm_updates_collections, + 'fused': None, # Use fused batch norm if possible. + } + + with slim.arg_scope( + [slim.conv2d], + weights_regularizer=slim.l2_regularizer(weight_decay), + weights_initializer=slim.variance_scaling_initializer(), + activation_fn=activation_fn, + normalizer_fn=slim.batch_norm if use_batch_norm else None, + normalizer_params=batch_norm_params): + with slim.arg_scope([slim.batch_norm], **batch_norm_params): + # The following implies padding='SAME' for pool1, which makes feature + # alignment easier for dense prediction tasks. This is also used in + # https://github.com/facebook/fb.resnet.torch. However the accompanying + # code of 'Deep Residual Learning for Image Recognition' uses + # padding='VALID' for pool1. You can switch to that choice by setting + # slim.arg_scope([slim.max_pool2d], padding='VALID'). + with slim.arg_scope([slim.max_pool2d], padding='SAME') as arg_sc: + return arg_sc diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v1.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v1.py new file mode 100644 index 0000000..95e1a11 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v1.py @@ -0,0 +1,375 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains definitions for the original form of Residual Networks. + +The 'v1' residual networks (ResNets) implemented in this module were proposed +by: +[1] Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun + Deep Residual Learning for Image Recognition. arXiv:1512.03385 + +Other variants were introduced in: +[2] Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun + Identity Mappings in Deep Residual Networks. arXiv: 1603.05027 + +The networks defined in this module utilize the bottleneck building block of +[1] with projection shortcuts only for increasing depths. They employ batch +normalization *after* every weight layer. This is the architecture used by +MSRA in the Imagenet and MSCOCO 2016 competition models ResNet-101 and +ResNet-152. See [2; Fig. 1a] for a comparison between the current 'v1' +architecture and the alternative 'v2' architecture of [2] which uses batch +normalization *before* every weight layer in the so-called full pre-activation +units. + +Typical use: + + from tensorflow.contrib.slim.nets import resnet_v1 + +ResNet-101 for image classification into 1000 classes: + + # inputs has shape [batch, 224, 224, 3] + with slim.arg_scope(resnet_v1.resnet_arg_scope()): + net, end_points = resnet_v1.resnet_v1_101(inputs, 1000, is_training=False) + +ResNet-101 for semantic segmentation into 21 classes: + + # inputs has shape [batch, 513, 513, 3] + with slim.arg_scope(resnet_v1.resnet_arg_scope()): + net, end_points = resnet_v1.resnet_v1_101(inputs, + 21, + is_training=False, + global_pool=False, + output_stride=16) +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import resnet_utils + + +resnet_arg_scope = resnet_utils.resnet_arg_scope +slim = tf.contrib.slim + + +class NoOpScope(object): + """No-op context manager.""" + + def __enter__(self): + return None + + def __exit__(self, exc_type, exc_value, traceback): + return False + + +@slim.add_arg_scope +def bottleneck(inputs, + depth, + depth_bottleneck, + stride, + rate=1, + outputs_collections=None, + scope=None, + use_bounded_activations=False): + """Bottleneck residual unit variant with BN after convolutions. + + This is the original residual unit proposed in [1]. See Fig. 1(a) of [2] for + its definition. Note that we use here the bottleneck variant which has an + extra bottleneck layer. + + When putting together two consecutive ResNet blocks that use this unit, one + should use stride = 2 in the last unit of the first block. + + Args: + inputs: A tensor of size [batch, height, width, channels]. + depth: The depth of the ResNet unit output. + depth_bottleneck: The depth of the bottleneck layers. + stride: The ResNet unit's stride. Determines the amount of downsampling of + the units output compared to its input. + rate: An integer, rate for atrous convolution. + outputs_collections: Collection to add the ResNet unit output. + scope: Optional variable_scope. + use_bounded_activations: Whether or not to use bounded activations. Bounded + activations better lend themselves to quantized inference. + + Returns: + The ResNet unit's output. + """ + with tf.variable_scope(scope, 'bottleneck_v1', [inputs]) as sc: + depth_in = slim.utils.last_dimension(inputs.get_shape(), min_rank=4) + if depth == depth_in: + shortcut = resnet_utils.subsample(inputs, stride, 'shortcut') + else: + shortcut = slim.conv2d( + inputs, + depth, [1, 1], + stride=stride, + activation_fn=tf.nn.relu6 if use_bounded_activations else None, + scope='shortcut') + + residual = slim.conv2d(inputs, depth_bottleneck, [1, 1], stride=1, + scope='conv1') + residual = resnet_utils.conv2d_same(residual, depth_bottleneck, 3, stride, + rate=rate, scope='conv2') + residual = slim.conv2d(residual, depth, [1, 1], stride=1, + activation_fn=None, scope='conv3') + + if use_bounded_activations: + # Use clip_by_value to simulate bandpass activation. + residual = tf.clip_by_value(residual, -6.0, 6.0) + output = tf.nn.relu6(shortcut + residual) + else: + output = tf.nn.relu(shortcut + residual) + + return slim.utils.collect_named_outputs(outputs_collections, + sc.name, + output) + + +def resnet_v1(inputs, + blocks, + num_classes=None, + is_training=True, + global_pool=True, + output_stride=None, + include_root_block=True, + spatial_squeeze=True, + store_non_strided_activations=False, + reuse=None, + scope=None): + """Generator for v1 ResNet models. + + This function generates a family of ResNet v1 models. See the resnet_v1_*() + methods for specific model instantiations, obtained by selecting different + block instantiations that produce ResNets of various depths. + + Training for image classification on Imagenet is usually done with [224, 224] + inputs, resulting in [7, 7] feature maps at the output of the last ResNet + block for the ResNets defined in [1] that have nominal stride equal to 32. + However, for dense prediction tasks we advise that one uses inputs with + spatial dimensions that are multiples of 32 plus 1, e.g., [321, 321]. In + this case the feature maps at the ResNet output will have spatial shape + [(height - 1) / output_stride + 1, (width - 1) / output_stride + 1] + and corners exactly aligned with the input image corners, which greatly + facilitates alignment of the features to the image. Using as input [225, 225] + images results in [8, 8] feature maps at the output of the last ResNet block. + + For dense prediction tasks, the ResNet needs to run in fully-convolutional + (FCN) mode and global_pool needs to be set to False. The ResNets in [1, 2] all + have nominal stride equal to 32 and a good choice in FCN mode is to use + output_stride=16 in order to increase the density of the computed features at + small computational and memory overhead, cf. http://arxiv.org/abs/1606.00915. + + Args: + inputs: A tensor of size [batch, height_in, width_in, channels]. + blocks: A list of length equal to the number of ResNet blocks. Each element + is a resnet_utils.Block object describing the units in the block. + num_classes: Number of predicted classes for classification tasks. + If 0 or None, we return the features before the logit layer. + is_training: whether batch_norm layers are in training mode. If this is set + to None, the callers can specify slim.batch_norm's is_training parameter + from an outer slim.arg_scope. + global_pool: If True, we perform global average pooling before computing the + logits. Set to True for image classification, False for dense prediction. + output_stride: If None, then the output will be computed at the nominal + network stride. If output_stride is not None, it specifies the requested + ratio of input to output spatial resolution. + include_root_block: If True, include the initial convolution followed by + max-pooling, if False excludes it. + spatial_squeeze: if True, logits is of shape [B, C], if false logits is + of shape [B, 1, 1, C], where B is batch_size and C is number of classes. + To use this parameter, the input images must be smaller than 300x300 + pixels, in which case the output logit layer does not contain spatial + information and can be removed. + store_non_strided_activations: If True, we compute non-strided (undecimated) + activations at the last unit of each block and store them in the + `outputs_collections` before subsampling them. This gives us access to + higher resolution intermediate activations which are useful in some + dense prediction problems but increases 4x the computation and memory cost + at the last unit of each block. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + + Returns: + net: A rank-4 tensor of size [batch, height_out, width_out, channels_out]. + If global_pool is False, then height_out and width_out are reduced by a + factor of output_stride compared to the respective height_in and width_in, + else both height_out and width_out equal one. If num_classes is 0 or None, + then net is the output of the last ResNet block, potentially after global + average pooling. If num_classes a non-zero integer, net contains the + pre-softmax activations. + end_points: A dictionary from components of the network to the corresponding + activation. + + Raises: + ValueError: If the target output_stride is not valid. + """ + with tf.variable_scope(scope, 'resnet_v1', [inputs], reuse=reuse) as sc: + end_points_collection = sc.original_name_scope + '_end_points' + with slim.arg_scope([slim.conv2d, bottleneck, + resnet_utils.stack_blocks_dense], + outputs_collections=end_points_collection): + with (slim.arg_scope([slim.batch_norm], is_training=is_training) + if is_training is not None else NoOpScope()): + net = inputs + if include_root_block: + if output_stride is not None: + if output_stride % 4 != 0: + raise ValueError('The output_stride needs to be a multiple of 4.') + output_stride /= 4 + net = resnet_utils.conv2d_same(net, 64, 7, stride=2, scope='conv1') + net = slim.max_pool2d(net, [3, 3], stride=2, scope='pool1') + net = resnet_utils.stack_blocks_dense(net, blocks, output_stride, + store_non_strided_activations) + # Convert end_points_collection into a dictionary of end_points. + end_points = slim.utils.convert_collection_to_dict( + end_points_collection) + + if global_pool: + # Global average pooling. + net = tf.reduce_mean(net, [1, 2], name='pool5', keep_dims=True) + end_points['global_pool'] = net + if num_classes: + net = slim.conv2d(net, num_classes, [1, 1], activation_fn=None, + normalizer_fn=None, scope='logits') + end_points[sc.name + '/logits'] = net + if spatial_squeeze: + net = tf.squeeze(net, [1, 2], name='SpatialSqueeze') + end_points[sc.name + '/spatial_squeeze'] = net + end_points['predictions'] = slim.softmax(net, scope='predictions') + return net, end_points +resnet_v1.default_image_size = 224 + + +def resnet_v1_block(scope, base_depth, num_units, stride): + """Helper function for creating a resnet_v1 bottleneck block. + + Args: + scope: The scope of the block. + base_depth: The depth of the bottleneck layer for each unit. + num_units: The number of units in the block. + stride: The stride of the block, implemented as a stride in the last unit. + All other units have stride=1. + + Returns: + A resnet_v1 bottleneck block. + """ + return resnet_utils.Block(scope, bottleneck, [{ + 'depth': base_depth * 4, + 'depth_bottleneck': base_depth, + 'stride': 1 + }] * (num_units - 1) + [{ + 'depth': base_depth * 4, + 'depth_bottleneck': base_depth, + 'stride': stride + }]) + + +def resnet_v1_50(inputs, + num_classes=None, + is_training=True, + global_pool=True, + output_stride=None, + spatial_squeeze=True, + store_non_strided_activations=False, + reuse=None, + scope='resnet_v1_50'): + """ResNet-50 model of [1]. See resnet_v1() for arg and return description.""" + blocks = [ + resnet_v1_block('block1', base_depth=64, num_units=3, stride=2), + resnet_v1_block('block2', base_depth=128, num_units=4, stride=2), + resnet_v1_block('block3', base_depth=256, num_units=6, stride=2), + resnet_v1_block('block4', base_depth=512, num_units=3, stride=1), + ] + return resnet_v1(inputs, blocks, num_classes, is_training, + global_pool=global_pool, output_stride=output_stride, + include_root_block=True, spatial_squeeze=spatial_squeeze, + store_non_strided_activations=store_non_strided_activations, + reuse=reuse, scope=scope) +resnet_v1_50.default_image_size = resnet_v1.default_image_size + + +def resnet_v1_101(inputs, + num_classes=None, + is_training=True, + global_pool=True, + output_stride=None, + spatial_squeeze=True, + store_non_strided_activations=False, + reuse=None, + scope='resnet_v1_101'): + """ResNet-101 model of [1]. See resnet_v1() for arg and return description.""" + blocks = [ + resnet_v1_block('block1', base_depth=64, num_units=3, stride=2), + resnet_v1_block('block2', base_depth=128, num_units=4, stride=2), + resnet_v1_block('block3', base_depth=256, num_units=23, stride=2), + resnet_v1_block('block4', base_depth=512, num_units=3, stride=1), + ] + return resnet_v1(inputs, blocks, num_classes, is_training, + global_pool=global_pool, output_stride=output_stride, + include_root_block=True, spatial_squeeze=spatial_squeeze, + store_non_strided_activations=store_non_strided_activations, + reuse=reuse, scope=scope) +resnet_v1_101.default_image_size = resnet_v1.default_image_size + + +def resnet_v1_152(inputs, + num_classes=None, + is_training=True, + global_pool=True, + output_stride=None, + store_non_strided_activations=False, + spatial_squeeze=True, + reuse=None, + scope='resnet_v1_152'): + """ResNet-152 model of [1]. See resnet_v1() for arg and return description.""" + blocks = [ + resnet_v1_block('block1', base_depth=64, num_units=3, stride=2), + resnet_v1_block('block2', base_depth=128, num_units=8, stride=2), + resnet_v1_block('block3', base_depth=256, num_units=36, stride=2), + resnet_v1_block('block4', base_depth=512, num_units=3, stride=1), + ] + return resnet_v1(inputs, blocks, num_classes, is_training, + global_pool=global_pool, output_stride=output_stride, + include_root_block=True, spatial_squeeze=spatial_squeeze, + store_non_strided_activations=store_non_strided_activations, + reuse=reuse, scope=scope) +resnet_v1_152.default_image_size = resnet_v1.default_image_size + + +def resnet_v1_200(inputs, + num_classes=None, + is_training=True, + global_pool=True, + output_stride=None, + store_non_strided_activations=False, + spatial_squeeze=True, + reuse=None, + scope='resnet_v1_200'): + """ResNet-200 model of [2]. See resnet_v1() for arg and return description.""" + blocks = [ + resnet_v1_block('block1', base_depth=64, num_units=3, stride=2), + resnet_v1_block('block2', base_depth=128, num_units=24, stride=2), + resnet_v1_block('block3', base_depth=256, num_units=36, stride=2), + resnet_v1_block('block4', base_depth=512, num_units=3, stride=1), + ] + return resnet_v1(inputs, blocks, num_classes, is_training, + global_pool=global_pool, output_stride=output_stride, + include_root_block=True, spatial_squeeze=spatial_squeeze, + store_non_strided_activations=store_non_strided_activations, + reuse=reuse, scope=scope) +resnet_v1_200.default_image_size = resnet_v1.default_image_size diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v1_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v1_test.py new file mode 100644 index 0000000..c40e7f8 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v1_test.py @@ -0,0 +1,555 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for slim.nets.resnet_v1.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import tensorflow as tf + +from nets import resnet_utils +from nets import resnet_v1 + +slim = tf.contrib.slim + + +def create_test_input(batch_size, height, width, channels): + """Create test input tensor. + + Args: + batch_size: The number of images per batch or `None` if unknown. + height: The height of each image or `None` if unknown. + width: The width of each image or `None` if unknown. + channels: The number of channels per image or `None` if unknown. + + Returns: + Either a placeholder `Tensor` of dimension + [batch_size, height, width, channels] if any of the inputs are `None` or a + constant `Tensor` with the mesh grid values along the spatial dimensions. + """ + if None in [batch_size, height, width, channels]: + return tf.placeholder(tf.float32, (batch_size, height, width, channels)) + else: + return tf.to_float( + np.tile( + np.reshape( + np.reshape(np.arange(height), [height, 1]) + + np.reshape(np.arange(width), [1, width]), + [1, height, width, 1]), + [batch_size, 1, 1, channels])) + + +class ResnetUtilsTest(tf.test.TestCase): + + def testSubsampleThreeByThree(self): + x = tf.reshape(tf.to_float(tf.range(9)), [1, 3, 3, 1]) + x = resnet_utils.subsample(x, 2) + expected = tf.reshape(tf.constant([0, 2, 6, 8]), [1, 2, 2, 1]) + with self.test_session(): + self.assertAllClose(x.eval(), expected.eval()) + + def testSubsampleFourByFour(self): + x = tf.reshape(tf.to_float(tf.range(16)), [1, 4, 4, 1]) + x = resnet_utils.subsample(x, 2) + expected = tf.reshape(tf.constant([0, 2, 8, 10]), [1, 2, 2, 1]) + with self.test_session(): + self.assertAllClose(x.eval(), expected.eval()) + + def testConv2DSameEven(self): + n, n2 = 4, 2 + + # Input image. + x = create_test_input(1, n, n, 1) + + # Convolution kernel. + w = create_test_input(1, 3, 3, 1) + w = tf.reshape(w, [3, 3, 1, 1]) + + tf.get_variable('Conv/weights', initializer=w) + tf.get_variable('Conv/biases', initializer=tf.zeros([1])) + tf.get_variable_scope().reuse_variables() + + y1 = slim.conv2d(x, 1, [3, 3], stride=1, scope='Conv') + y1_expected = tf.to_float([[14, 28, 43, 26], + [28, 48, 66, 37], + [43, 66, 84, 46], + [26, 37, 46, 22]]) + y1_expected = tf.reshape(y1_expected, [1, n, n, 1]) + + y2 = resnet_utils.subsample(y1, 2) + y2_expected = tf.to_float([[14, 43], + [43, 84]]) + y2_expected = tf.reshape(y2_expected, [1, n2, n2, 1]) + + y3 = resnet_utils.conv2d_same(x, 1, 3, stride=2, scope='Conv') + y3_expected = y2_expected + + y4 = slim.conv2d(x, 1, [3, 3], stride=2, scope='Conv') + y4_expected = tf.to_float([[48, 37], + [37, 22]]) + y4_expected = tf.reshape(y4_expected, [1, n2, n2, 1]) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + self.assertAllClose(y1.eval(), y1_expected.eval()) + self.assertAllClose(y2.eval(), y2_expected.eval()) + self.assertAllClose(y3.eval(), y3_expected.eval()) + self.assertAllClose(y4.eval(), y4_expected.eval()) + + def testConv2DSameOdd(self): + n, n2 = 5, 3 + + # Input image. + x = create_test_input(1, n, n, 1) + + # Convolution kernel. + w = create_test_input(1, 3, 3, 1) + w = tf.reshape(w, [3, 3, 1, 1]) + + tf.get_variable('Conv/weights', initializer=w) + tf.get_variable('Conv/biases', initializer=tf.zeros([1])) + tf.get_variable_scope().reuse_variables() + + y1 = slim.conv2d(x, 1, [3, 3], stride=1, scope='Conv') + y1_expected = tf.to_float([[14, 28, 43, 58, 34], + [28, 48, 66, 84, 46], + [43, 66, 84, 102, 55], + [58, 84, 102, 120, 64], + [34, 46, 55, 64, 30]]) + y1_expected = tf.reshape(y1_expected, [1, n, n, 1]) + + y2 = resnet_utils.subsample(y1, 2) + y2_expected = tf.to_float([[14, 43, 34], + [43, 84, 55], + [34, 55, 30]]) + y2_expected = tf.reshape(y2_expected, [1, n2, n2, 1]) + + y3 = resnet_utils.conv2d_same(x, 1, 3, stride=2, scope='Conv') + y3_expected = y2_expected + + y4 = slim.conv2d(x, 1, [3, 3], stride=2, scope='Conv') + y4_expected = y2_expected + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + self.assertAllClose(y1.eval(), y1_expected.eval()) + self.assertAllClose(y2.eval(), y2_expected.eval()) + self.assertAllClose(y3.eval(), y3_expected.eval()) + self.assertAllClose(y4.eval(), y4_expected.eval()) + + def _resnet_plain(self, inputs, blocks, output_stride=None, scope=None): + """A plain ResNet without extra layers before or after the ResNet blocks.""" + with tf.variable_scope(scope, values=[inputs]): + with slim.arg_scope([slim.conv2d], outputs_collections='end_points'): + net = resnet_utils.stack_blocks_dense(inputs, blocks, output_stride) + end_points = slim.utils.convert_collection_to_dict('end_points') + return net, end_points + + def testEndPointsV1(self): + """Test the end points of a tiny v1 bottleneck network.""" + blocks = [ + resnet_v1.resnet_v1_block( + 'block1', base_depth=1, num_units=2, stride=2), + resnet_v1.resnet_v1_block( + 'block2', base_depth=2, num_units=2, stride=1), + ] + inputs = create_test_input(2, 32, 16, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_plain(inputs, blocks, scope='tiny') + expected = [ + 'tiny/block1/unit_1/bottleneck_v1/shortcut', + 'tiny/block1/unit_1/bottleneck_v1/conv1', + 'tiny/block1/unit_1/bottleneck_v1/conv2', + 'tiny/block1/unit_1/bottleneck_v1/conv3', + 'tiny/block1/unit_2/bottleneck_v1/conv1', + 'tiny/block1/unit_2/bottleneck_v1/conv2', + 'tiny/block1/unit_2/bottleneck_v1/conv3', + 'tiny/block2/unit_1/bottleneck_v1/shortcut', + 'tiny/block2/unit_1/bottleneck_v1/conv1', + 'tiny/block2/unit_1/bottleneck_v1/conv2', + 'tiny/block2/unit_1/bottleneck_v1/conv3', + 'tiny/block2/unit_2/bottleneck_v1/conv1', + 'tiny/block2/unit_2/bottleneck_v1/conv2', + 'tiny/block2/unit_2/bottleneck_v1/conv3'] + self.assertItemsEqual(expected, end_points.keys()) + + def _stack_blocks_nondense(self, net, blocks): + """A simplified ResNet Block stacker without output stride control.""" + for block in blocks: + with tf.variable_scope(block.scope, 'block', [net]): + for i, unit in enumerate(block.args): + with tf.variable_scope('unit_%d' % (i + 1), values=[net]): + net = block.unit_fn(net, rate=1, **unit) + return net + + def testAtrousValuesBottleneck(self): + """Verify the values of dense feature extraction by atrous convolution. + + Make sure that dense feature extraction by stack_blocks_dense() followed by + subsampling gives identical results to feature extraction at the nominal + network output stride using the simple self._stack_blocks_nondense() above. + """ + block = resnet_v1.resnet_v1_block + blocks = [ + block('block1', base_depth=1, num_units=2, stride=2), + block('block2', base_depth=2, num_units=2, stride=2), + block('block3', base_depth=4, num_units=2, stride=2), + block('block4', base_depth=8, num_units=2, stride=1), + ] + nominal_stride = 8 + + # Test both odd and even input dimensions. + height = 30 + width = 31 + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + with slim.arg_scope([slim.batch_norm], is_training=False): + for output_stride in [1, 2, 4, 8, None]: + with tf.Graph().as_default(): + with self.test_session() as sess: + tf.set_random_seed(0) + inputs = create_test_input(1, height, width, 3) + # Dense feature extraction followed by subsampling. + output = resnet_utils.stack_blocks_dense(inputs, + blocks, + output_stride) + if output_stride is None: + factor = 1 + else: + factor = nominal_stride // output_stride + + output = resnet_utils.subsample(output, factor) + # Make the two networks use the same weights. + tf.get_variable_scope().reuse_variables() + # Feature extraction at the nominal network rate. + expected = self._stack_blocks_nondense(inputs, blocks) + sess.run(tf.global_variables_initializer()) + output, expected = sess.run([output, expected]) + self.assertAllClose(output, expected, atol=1e-4, rtol=1e-4) + + def testStridingLastUnitVsSubsampleBlockEnd(self): + """Compares subsampling at the block's last unit or block's end. + + Makes sure that the final output is the same when we use a stride at the + last unit of a block vs. we subsample activations at the end of a block. + """ + block = resnet_v1.resnet_v1_block + + blocks = [ + block('block1', base_depth=1, num_units=2, stride=2), + block('block2', base_depth=2, num_units=2, stride=2), + block('block3', base_depth=4, num_units=2, stride=2), + block('block4', base_depth=8, num_units=2, stride=1), + ] + + # Test both odd and even input dimensions. + height = 30 + width = 31 + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + with slim.arg_scope([slim.batch_norm], is_training=False): + for output_stride in [1, 2, 4, 8, None]: + with tf.Graph().as_default(): + with self.test_session() as sess: + tf.set_random_seed(0) + inputs = create_test_input(1, height, width, 3) + + # Subsampling at the last unit of the block. + output = resnet_utils.stack_blocks_dense( + inputs, blocks, output_stride, + store_non_strided_activations=False, + outputs_collections='output') + output_end_points = slim.utils.convert_collection_to_dict( + 'output') + + # Make the two networks use the same weights. + tf.get_variable_scope().reuse_variables() + + # Subsample activations at the end of the blocks. + expected = resnet_utils.stack_blocks_dense( + inputs, blocks, output_stride, + store_non_strided_activations=True, + outputs_collections='expected') + expected_end_points = slim.utils.convert_collection_to_dict( + 'expected') + + sess.run(tf.global_variables_initializer()) + + # Make sure that the final output is the same. + output, expected = sess.run([output, expected]) + self.assertAllClose(output, expected, atol=1e-4, rtol=1e-4) + + # Make sure that intermediate block activations in + # output_end_points are subsampled versions of the corresponding + # ones in expected_end_points. + for i, block in enumerate(blocks[:-1:]): + output = output_end_points[block.scope] + expected = expected_end_points[block.scope] + atrous_activated = (output_stride is not None and + 2 ** i >= output_stride) + if not atrous_activated: + expected = resnet_utils.subsample(expected, 2) + output, expected = sess.run([output, expected]) + self.assertAllClose(output, expected, atol=1e-4, rtol=1e-4) + + +class ResnetCompleteNetworkTest(tf.test.TestCase): + """Tests with complete small ResNet v1 networks.""" + + def _resnet_small(self, + inputs, + num_classes=None, + is_training=True, + global_pool=True, + output_stride=None, + include_root_block=True, + spatial_squeeze=True, + reuse=None, + scope='resnet_v1_small'): + """A shallow and thin ResNet v1 for faster tests.""" + block = resnet_v1.resnet_v1_block + blocks = [ + block('block1', base_depth=1, num_units=3, stride=2), + block('block2', base_depth=2, num_units=3, stride=2), + block('block3', base_depth=4, num_units=3, stride=2), + block('block4', base_depth=8, num_units=2, stride=1), + ] + return resnet_v1.resnet_v1(inputs, blocks, num_classes, + is_training=is_training, + global_pool=global_pool, + output_stride=output_stride, + include_root_block=include_root_block, + spatial_squeeze=spatial_squeeze, + reuse=reuse, + scope=scope) + + def testClassificationEndPoints(self): + global_pool = True + num_classes = 10 + inputs = create_test_input(2, 224, 224, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + logits, end_points = self._resnet_small(inputs, num_classes, + global_pool=global_pool, + spatial_squeeze=False, + scope='resnet') + self.assertTrue(logits.op.name.startswith('resnet/logits')) + self.assertListEqual(logits.get_shape().as_list(), [2, 1, 1, num_classes]) + self.assertTrue('predictions' in end_points) + self.assertListEqual(end_points['predictions'].get_shape().as_list(), + [2, 1, 1, num_classes]) + self.assertTrue('global_pool' in end_points) + self.assertListEqual(end_points['global_pool'].get_shape().as_list(), + [2, 1, 1, 32]) + + def testClassificationEndPointsWithNoBatchNormArgscope(self): + global_pool = True + num_classes = 10 + inputs = create_test_input(2, 224, 224, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + logits, end_points = self._resnet_small(inputs, num_classes, + global_pool=global_pool, + spatial_squeeze=False, + is_training=None, + scope='resnet') + self.assertTrue(logits.op.name.startswith('resnet/logits')) + self.assertListEqual(logits.get_shape().as_list(), [2, 1, 1, num_classes]) + self.assertTrue('predictions' in end_points) + self.assertListEqual(end_points['predictions'].get_shape().as_list(), + [2, 1, 1, num_classes]) + self.assertTrue('global_pool' in end_points) + self.assertListEqual(end_points['global_pool'].get_shape().as_list(), + [2, 1, 1, 32]) + + def testEndpointNames(self): + # Like ResnetUtilsTest.testEndPointsV1(), but for the public API. + global_pool = True + num_classes = 10 + inputs = create_test_input(2, 224, 224, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_small(inputs, num_classes, + global_pool=global_pool, + scope='resnet') + expected = ['resnet/conv1'] + for block in range(1, 5): + for unit in range(1, 4 if block < 4 else 3): + for conv in range(1, 4): + expected.append('resnet/block%d/unit_%d/bottleneck_v1/conv%d' % + (block, unit, conv)) + expected.append('resnet/block%d/unit_%d/bottleneck_v1' % (block, unit)) + expected.append('resnet/block%d/unit_1/bottleneck_v1/shortcut' % block) + expected.append('resnet/block%d' % block) + expected.extend(['global_pool', 'resnet/logits', 'resnet/spatial_squeeze', + 'predictions']) + self.assertItemsEqual(end_points.keys(), expected) + + def testClassificationShapes(self): + global_pool = True + num_classes = 10 + inputs = create_test_input(2, 224, 224, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_small(inputs, num_classes, + global_pool=global_pool, + scope='resnet') + endpoint_to_shape = { + 'resnet/block1': [2, 28, 28, 4], + 'resnet/block2': [2, 14, 14, 8], + 'resnet/block3': [2, 7, 7, 16], + 'resnet/block4': [2, 7, 7, 32]} + for endpoint in endpoint_to_shape: + shape = endpoint_to_shape[endpoint] + self.assertListEqual(end_points[endpoint].get_shape().as_list(), shape) + + def testFullyConvolutionalEndpointShapes(self): + global_pool = False + num_classes = 10 + inputs = create_test_input(2, 321, 321, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_small(inputs, num_classes, + global_pool=global_pool, + spatial_squeeze=False, + scope='resnet') + endpoint_to_shape = { + 'resnet/block1': [2, 41, 41, 4], + 'resnet/block2': [2, 21, 21, 8], + 'resnet/block3': [2, 11, 11, 16], + 'resnet/block4': [2, 11, 11, 32]} + for endpoint in endpoint_to_shape: + shape = endpoint_to_shape[endpoint] + self.assertListEqual(end_points[endpoint].get_shape().as_list(), shape) + + def testRootlessFullyConvolutionalEndpointShapes(self): + global_pool = False + num_classes = 10 + inputs = create_test_input(2, 128, 128, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_small(inputs, num_classes, + global_pool=global_pool, + include_root_block=False, + spatial_squeeze=False, + scope='resnet') + endpoint_to_shape = { + 'resnet/block1': [2, 64, 64, 4], + 'resnet/block2': [2, 32, 32, 8], + 'resnet/block3': [2, 16, 16, 16], + 'resnet/block4': [2, 16, 16, 32]} + for endpoint in endpoint_to_shape: + shape = endpoint_to_shape[endpoint] + self.assertListEqual(end_points[endpoint].get_shape().as_list(), shape) + + def testAtrousFullyConvolutionalEndpointShapes(self): + global_pool = False + num_classes = 10 + output_stride = 8 + inputs = create_test_input(2, 321, 321, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_small(inputs, + num_classes, + global_pool=global_pool, + output_stride=output_stride, + spatial_squeeze=False, + scope='resnet') + endpoint_to_shape = { + 'resnet/block1': [2, 41, 41, 4], + 'resnet/block2': [2, 41, 41, 8], + 'resnet/block3': [2, 41, 41, 16], + 'resnet/block4': [2, 41, 41, 32]} + for endpoint in endpoint_to_shape: + shape = endpoint_to_shape[endpoint] + self.assertListEqual(end_points[endpoint].get_shape().as_list(), shape) + + def testAtrousFullyConvolutionalValues(self): + """Verify dense feature extraction with atrous convolution.""" + nominal_stride = 32 + for output_stride in [4, 8, 16, 32, None]: + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + with tf.Graph().as_default(): + with self.test_session() as sess: + tf.set_random_seed(0) + inputs = create_test_input(2, 81, 81, 3) + # Dense feature extraction followed by subsampling. + output, _ = self._resnet_small(inputs, None, is_training=False, + global_pool=False, + output_stride=output_stride) + if output_stride is None: + factor = 1 + else: + factor = nominal_stride // output_stride + output = resnet_utils.subsample(output, factor) + # Make the two networks use the same weights. + tf.get_variable_scope().reuse_variables() + # Feature extraction at the nominal network rate. + expected, _ = self._resnet_small(inputs, None, is_training=False, + global_pool=False) + sess.run(tf.global_variables_initializer()) + self.assertAllClose(output.eval(), expected.eval(), + atol=1e-4, rtol=1e-4) + + def testUnknownBatchSize(self): + batch = 2 + height, width = 65, 65 + global_pool = True + num_classes = 10 + inputs = create_test_input(None, height, width, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + logits, _ = self._resnet_small(inputs, num_classes, + global_pool=global_pool, + spatial_squeeze=False, + scope='resnet') + self.assertTrue(logits.op.name.startswith('resnet/logits')) + self.assertListEqual(logits.get_shape().as_list(), + [None, 1, 1, num_classes]) + images = create_test_input(batch, height, width, 3) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(logits, {inputs: images.eval()}) + self.assertEqual(output.shape, (batch, 1, 1, num_classes)) + + def testFullyConvolutionalUnknownHeightWidth(self): + batch = 2 + height, width = 65, 65 + global_pool = False + inputs = create_test_input(batch, None, None, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + output, _ = self._resnet_small(inputs, None, global_pool=global_pool) + self.assertListEqual(output.get_shape().as_list(), + [batch, None, None, 32]) + images = create_test_input(batch, height, width, 3) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(output, {inputs: images.eval()}) + self.assertEqual(output.shape, (batch, 3, 3, 32)) + + def testAtrousFullyConvolutionalUnknownHeightWidth(self): + batch = 2 + height, width = 65, 65 + global_pool = False + output_stride = 8 + inputs = create_test_input(batch, None, None, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + output, _ = self._resnet_small(inputs, + None, + global_pool=global_pool, + output_stride=output_stride) + self.assertListEqual(output.get_shape().as_list(), + [batch, None, None, 32]) + images = create_test_input(batch, height, width, 3) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(output, {inputs: images.eval()}) + self.assertEqual(output.shape, (batch, 9, 9, 32)) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v2.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v2.py new file mode 100644 index 0000000..c719c1b --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v2.py @@ -0,0 +1,337 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains definitions for the preactivation form of Residual Networks. + +Residual networks (ResNets) were originally proposed in: +[1] Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun + Deep Residual Learning for Image Recognition. arXiv:1512.03385 + +The full preactivation 'v2' ResNet variant implemented in this module was +introduced by: +[2] Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun + Identity Mappings in Deep Residual Networks. arXiv: 1603.05027 + +The key difference of the full preactivation 'v2' variant compared to the +'v1' variant in [1] is the use of batch normalization before every weight layer. + +Typical use: + + from tensorflow.contrib.slim.nets import resnet_v2 + +ResNet-101 for image classification into 1000 classes: + + # inputs has shape [batch, 224, 224, 3] + with slim.arg_scope(resnet_v2.resnet_arg_scope()): + net, end_points = resnet_v2.resnet_v2_101(inputs, 1000, is_training=False) + +ResNet-101 for semantic segmentation into 21 classes: + + # inputs has shape [batch, 513, 513, 3] + with slim.arg_scope(resnet_v2.resnet_arg_scope()): + net, end_points = resnet_v2.resnet_v2_101(inputs, + 21, + is_training=False, + global_pool=False, + output_stride=16) +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import resnet_utils + +slim = tf.contrib.slim +resnet_arg_scope = resnet_utils.resnet_arg_scope + + +@slim.add_arg_scope +def bottleneck(inputs, depth, depth_bottleneck, stride, rate=1, + outputs_collections=None, scope=None): + """Bottleneck residual unit variant with BN before convolutions. + + This is the full preactivation residual unit variant proposed in [2]. See + Fig. 1(b) of [2] for its definition. Note that we use here the bottleneck + variant which has an extra bottleneck layer. + + When putting together two consecutive ResNet blocks that use this unit, one + should use stride = 2 in the last unit of the first block. + + Args: + inputs: A tensor of size [batch, height, width, channels]. + depth: The depth of the ResNet unit output. + depth_bottleneck: The depth of the bottleneck layers. + stride: The ResNet unit's stride. Determines the amount of downsampling of + the units output compared to its input. + rate: An integer, rate for atrous convolution. + outputs_collections: Collection to add the ResNet unit output. + scope: Optional variable_scope. + + Returns: + The ResNet unit's output. + """ + with tf.variable_scope(scope, 'bottleneck_v2', [inputs]) as sc: + depth_in = slim.utils.last_dimension(inputs.get_shape(), min_rank=4) + preact = slim.batch_norm(inputs, activation_fn=tf.nn.relu, scope='preact') + if depth == depth_in: + shortcut = resnet_utils.subsample(inputs, stride, 'shortcut') + else: + shortcut = slim.conv2d(preact, depth, [1, 1], stride=stride, + normalizer_fn=None, activation_fn=None, + scope='shortcut') + + residual = slim.conv2d(preact, depth_bottleneck, [1, 1], stride=1, + scope='conv1') + residual = resnet_utils.conv2d_same(residual, depth_bottleneck, 3, stride, + rate=rate, scope='conv2') + residual = slim.conv2d(residual, depth, [1, 1], stride=1, + normalizer_fn=None, activation_fn=None, + scope='conv3') + + output = shortcut + residual + + return slim.utils.collect_named_outputs(outputs_collections, + sc.name, + output) + + +def resnet_v2(inputs, + blocks, + num_classes=None, + is_training=True, + global_pool=True, + output_stride=None, + include_root_block=True, + spatial_squeeze=True, + reuse=None, + scope=None): + """Generator for v2 (preactivation) ResNet models. + + This function generates a family of ResNet v2 models. See the resnet_v2_*() + methods for specific model instantiations, obtained by selecting different + block instantiations that produce ResNets of various depths. + + Training for image classification on Imagenet is usually done with [224, 224] + inputs, resulting in [7, 7] feature maps at the output of the last ResNet + block for the ResNets defined in [1] that have nominal stride equal to 32. + However, for dense prediction tasks we advise that one uses inputs with + spatial dimensions that are multiples of 32 plus 1, e.g., [321, 321]. In + this case the feature maps at the ResNet output will have spatial shape + [(height - 1) / output_stride + 1, (width - 1) / output_stride + 1] + and corners exactly aligned with the input image corners, which greatly + facilitates alignment of the features to the image. Using as input [225, 225] + images results in [8, 8] feature maps at the output of the last ResNet block. + + For dense prediction tasks, the ResNet needs to run in fully-convolutional + (FCN) mode and global_pool needs to be set to False. The ResNets in [1, 2] all + have nominal stride equal to 32 and a good choice in FCN mode is to use + output_stride=16 in order to increase the density of the computed features at + small computational and memory overhead, cf. http://arxiv.org/abs/1606.00915. + + Args: + inputs: A tensor of size [batch, height_in, width_in, channels]. + blocks: A list of length equal to the number of ResNet blocks. Each element + is a resnet_utils.Block object describing the units in the block. + num_classes: Number of predicted classes for classification tasks. + If 0 or None, we return the features before the logit layer. + is_training: whether batch_norm layers are in training mode. + global_pool: If True, we perform global average pooling before computing the + logits. Set to True for image classification, False for dense prediction. + output_stride: If None, then the output will be computed at the nominal + network stride. If output_stride is not None, it specifies the requested + ratio of input to output spatial resolution. + include_root_block: If True, include the initial convolution followed by + max-pooling, if False excludes it. If excluded, `inputs` should be the + results of an activation-less convolution. + spatial_squeeze: if True, logits is of shape [B, C], if false logits is + of shape [B, 1, 1, C], where B is batch_size and C is number of classes. + To use this parameter, the input images must be smaller than 300x300 + pixels, in which case the output logit layer does not contain spatial + information and can be removed. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + scope: Optional variable_scope. + + + Returns: + net: A rank-4 tensor of size [batch, height_out, width_out, channels_out]. + If global_pool is False, then height_out and width_out are reduced by a + factor of output_stride compared to the respective height_in and width_in, + else both height_out and width_out equal one. If num_classes is 0 or None, + then net is the output of the last ResNet block, potentially after global + average pooling. If num_classes is a non-zero integer, net contains the + pre-softmax activations. + end_points: A dictionary from components of the network to the corresponding + activation. + + Raises: + ValueError: If the target output_stride is not valid. + """ + with tf.variable_scope(scope, 'resnet_v2', [inputs], reuse=reuse) as sc: + end_points_collection = sc.original_name_scope + '_end_points' + with slim.arg_scope([slim.conv2d, bottleneck, + resnet_utils.stack_blocks_dense], + outputs_collections=end_points_collection): + with slim.arg_scope([slim.batch_norm], is_training=is_training): + net = inputs + if include_root_block: + if output_stride is not None: + if output_stride % 4 != 0: + raise ValueError('The output_stride needs to be a multiple of 4.') + output_stride /= 4 + # We do not include batch normalization or activation functions in + # conv1 because the first ResNet unit will perform these. Cf. + # Appendix of [2]. + with slim.arg_scope([slim.conv2d], + activation_fn=None, normalizer_fn=None): + net = resnet_utils.conv2d_same(net, 64, 7, stride=2, scope='conv1') + net = slim.max_pool2d(net, [3, 3], stride=2, scope='pool1') + net = resnet_utils.stack_blocks_dense(net, blocks, output_stride) + # This is needed because the pre-activation variant does not have batch + # normalization or activation functions in the residual unit output. See + # Appendix of [2]. + net = slim.batch_norm(net, activation_fn=tf.nn.relu, scope='postnorm') + # Convert end_points_collection into a dictionary of end_points. + end_points = slim.utils.convert_collection_to_dict( + end_points_collection) + + if global_pool: + # Global average pooling. + net = tf.reduce_mean(net, [1, 2], name='pool5', keep_dims=True) + end_points['global_pool'] = net + if num_classes: + net = slim.conv2d(net, num_classes, [1, 1], activation_fn=None, + normalizer_fn=None, scope='logits') + end_points[sc.name + '/logits'] = net + if spatial_squeeze: + net = tf.squeeze(net, [1, 2], name='SpatialSqueeze') + end_points[sc.name + '/spatial_squeeze'] = net + end_points['predictions'] = slim.softmax(net, scope='predictions') + return net, end_points +resnet_v2.default_image_size = 224 + + +def resnet_v2_block(scope, base_depth, num_units, stride): + """Helper function for creating a resnet_v2 bottleneck block. + + Args: + scope: The scope of the block. + base_depth: The depth of the bottleneck layer for each unit. + num_units: The number of units in the block. + stride: The stride of the block, implemented as a stride in the last unit. + All other units have stride=1. + + Returns: + A resnet_v2 bottleneck block. + """ + return resnet_utils.Block(scope, bottleneck, [{ + 'depth': base_depth * 4, + 'depth_bottleneck': base_depth, + 'stride': 1 + }] * (num_units - 1) + [{ + 'depth': base_depth * 4, + 'depth_bottleneck': base_depth, + 'stride': stride + }]) +resnet_v2.default_image_size = 224 + + +def resnet_v2_50(inputs, + num_classes=None, + is_training=True, + global_pool=True, + output_stride=None, + spatial_squeeze=True, + reuse=None, + scope='resnet_v2_50'): + """ResNet-50 model of [1]. See resnet_v2() for arg and return description.""" + blocks = [ + resnet_v2_block('block1', base_depth=64, num_units=3, stride=2), + resnet_v2_block('block2', base_depth=128, num_units=4, stride=2), + resnet_v2_block('block3', base_depth=256, num_units=6, stride=2), + resnet_v2_block('block4', base_depth=512, num_units=3, stride=1), + ] + return resnet_v2(inputs, blocks, num_classes, is_training=is_training, + global_pool=global_pool, output_stride=output_stride, + include_root_block=True, spatial_squeeze=spatial_squeeze, + reuse=reuse, scope=scope) +resnet_v2_50.default_image_size = resnet_v2.default_image_size + + +def resnet_v2_101(inputs, + num_classes=None, + is_training=True, + global_pool=True, + output_stride=None, + spatial_squeeze=True, + reuse=None, + scope='resnet_v2_101'): + """ResNet-101 model of [1]. See resnet_v2() for arg and return description.""" + blocks = [ + resnet_v2_block('block1', base_depth=64, num_units=3, stride=2), + resnet_v2_block('block2', base_depth=128, num_units=4, stride=2), + resnet_v2_block('block3', base_depth=256, num_units=23, stride=2), + resnet_v2_block('block4', base_depth=512, num_units=3, stride=1), + ] + return resnet_v2(inputs, blocks, num_classes, is_training=is_training, + global_pool=global_pool, output_stride=output_stride, + include_root_block=True, spatial_squeeze=spatial_squeeze, + reuse=reuse, scope=scope) +resnet_v2_101.default_image_size = resnet_v2.default_image_size + + +def resnet_v2_152(inputs, + num_classes=None, + is_training=True, + global_pool=True, + output_stride=None, + spatial_squeeze=True, + reuse=None, + scope='resnet_v2_152'): + """ResNet-152 model of [1]. See resnet_v2() for arg and return description.""" + blocks = [ + resnet_v2_block('block1', base_depth=64, num_units=3, stride=2), + resnet_v2_block('block2', base_depth=128, num_units=8, stride=2), + resnet_v2_block('block3', base_depth=256, num_units=36, stride=2), + resnet_v2_block('block4', base_depth=512, num_units=3, stride=1), + ] + return resnet_v2(inputs, blocks, num_classes, is_training=is_training, + global_pool=global_pool, output_stride=output_stride, + include_root_block=True, spatial_squeeze=spatial_squeeze, + reuse=reuse, scope=scope) +resnet_v2_152.default_image_size = resnet_v2.default_image_size + + +def resnet_v2_200(inputs, + num_classes=None, + is_training=True, + global_pool=True, + output_stride=None, + spatial_squeeze=True, + reuse=None, + scope='resnet_v2_200'): + """ResNet-200 model of [2]. See resnet_v2() for arg and return description.""" + blocks = [ + resnet_v2_block('block1', base_depth=64, num_units=3, stride=2), + resnet_v2_block('block2', base_depth=128, num_units=24, stride=2), + resnet_v2_block('block3', base_depth=256, num_units=36, stride=2), + resnet_v2_block('block4', base_depth=512, num_units=3, stride=1), + ] + return resnet_v2(inputs, blocks, num_classes, is_training=is_training, + global_pool=global_pool, output_stride=output_stride, + include_root_block=True, spatial_squeeze=spatial_squeeze, + reuse=reuse, scope=scope) +resnet_v2_200.default_image_size = resnet_v2.default_image_size diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v2_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v2_test.py new file mode 100644 index 0000000..891816d --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/resnet_v2_test.py @@ -0,0 +1,475 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for slim.nets.resnet_v2.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import tensorflow as tf + +from nets import resnet_utils +from nets import resnet_v2 + +slim = tf.contrib.slim + + +def create_test_input(batch_size, height, width, channels): + """Create test input tensor. + + Args: + batch_size: The number of images per batch or `None` if unknown. + height: The height of each image or `None` if unknown. + width: The width of each image or `None` if unknown. + channels: The number of channels per image or `None` if unknown. + + Returns: + Either a placeholder `Tensor` of dimension + [batch_size, height, width, channels] if any of the inputs are `None` or a + constant `Tensor` with the mesh grid values along the spatial dimensions. + """ + if None in [batch_size, height, width, channels]: + return tf.placeholder(tf.float32, (batch_size, height, width, channels)) + else: + return tf.to_float( + np.tile( + np.reshape( + np.reshape(np.arange(height), [height, 1]) + + np.reshape(np.arange(width), [1, width]), + [1, height, width, 1]), + [batch_size, 1, 1, channels])) + + +class ResnetUtilsTest(tf.test.TestCase): + + def testSubsampleThreeByThree(self): + x = tf.reshape(tf.to_float(tf.range(9)), [1, 3, 3, 1]) + x = resnet_utils.subsample(x, 2) + expected = tf.reshape(tf.constant([0, 2, 6, 8]), [1, 2, 2, 1]) + with self.test_session(): + self.assertAllClose(x.eval(), expected.eval()) + + def testSubsampleFourByFour(self): + x = tf.reshape(tf.to_float(tf.range(16)), [1, 4, 4, 1]) + x = resnet_utils.subsample(x, 2) + expected = tf.reshape(tf.constant([0, 2, 8, 10]), [1, 2, 2, 1]) + with self.test_session(): + self.assertAllClose(x.eval(), expected.eval()) + + def testConv2DSameEven(self): + n, n2 = 4, 2 + + # Input image. + x = create_test_input(1, n, n, 1) + + # Convolution kernel. + w = create_test_input(1, 3, 3, 1) + w = tf.reshape(w, [3, 3, 1, 1]) + + tf.get_variable('Conv/weights', initializer=w) + tf.get_variable('Conv/biases', initializer=tf.zeros([1])) + tf.get_variable_scope().reuse_variables() + + y1 = slim.conv2d(x, 1, [3, 3], stride=1, scope='Conv') + y1_expected = tf.to_float([[14, 28, 43, 26], + [28, 48, 66, 37], + [43, 66, 84, 46], + [26, 37, 46, 22]]) + y1_expected = tf.reshape(y1_expected, [1, n, n, 1]) + + y2 = resnet_utils.subsample(y1, 2) + y2_expected = tf.to_float([[14, 43], + [43, 84]]) + y2_expected = tf.reshape(y2_expected, [1, n2, n2, 1]) + + y3 = resnet_utils.conv2d_same(x, 1, 3, stride=2, scope='Conv') + y3_expected = y2_expected + + y4 = slim.conv2d(x, 1, [3, 3], stride=2, scope='Conv') + y4_expected = tf.to_float([[48, 37], + [37, 22]]) + y4_expected = tf.reshape(y4_expected, [1, n2, n2, 1]) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + self.assertAllClose(y1.eval(), y1_expected.eval()) + self.assertAllClose(y2.eval(), y2_expected.eval()) + self.assertAllClose(y3.eval(), y3_expected.eval()) + self.assertAllClose(y4.eval(), y4_expected.eval()) + + def testConv2DSameOdd(self): + n, n2 = 5, 3 + + # Input image. + x = create_test_input(1, n, n, 1) + + # Convolution kernel. + w = create_test_input(1, 3, 3, 1) + w = tf.reshape(w, [3, 3, 1, 1]) + + tf.get_variable('Conv/weights', initializer=w) + tf.get_variable('Conv/biases', initializer=tf.zeros([1])) + tf.get_variable_scope().reuse_variables() + + y1 = slim.conv2d(x, 1, [3, 3], stride=1, scope='Conv') + y1_expected = tf.to_float([[14, 28, 43, 58, 34], + [28, 48, 66, 84, 46], + [43, 66, 84, 102, 55], + [58, 84, 102, 120, 64], + [34, 46, 55, 64, 30]]) + y1_expected = tf.reshape(y1_expected, [1, n, n, 1]) + + y2 = resnet_utils.subsample(y1, 2) + y2_expected = tf.to_float([[14, 43, 34], + [43, 84, 55], + [34, 55, 30]]) + y2_expected = tf.reshape(y2_expected, [1, n2, n2, 1]) + + y3 = resnet_utils.conv2d_same(x, 1, 3, stride=2, scope='Conv') + y3_expected = y2_expected + + y4 = slim.conv2d(x, 1, [3, 3], stride=2, scope='Conv') + y4_expected = y2_expected + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + self.assertAllClose(y1.eval(), y1_expected.eval()) + self.assertAllClose(y2.eval(), y2_expected.eval()) + self.assertAllClose(y3.eval(), y3_expected.eval()) + self.assertAllClose(y4.eval(), y4_expected.eval()) + + def _resnet_plain(self, inputs, blocks, output_stride=None, scope=None): + """A plain ResNet without extra layers before or after the ResNet blocks.""" + with tf.variable_scope(scope, values=[inputs]): + with slim.arg_scope([slim.conv2d], outputs_collections='end_points'): + net = resnet_utils.stack_blocks_dense(inputs, blocks, output_stride) + end_points = slim.utils.convert_collection_to_dict('end_points') + return net, end_points + + def testEndPointsV2(self): + """Test the end points of a tiny v2 bottleneck network.""" + blocks = [ + resnet_v2.resnet_v2_block( + 'block1', base_depth=1, num_units=2, stride=2), + resnet_v2.resnet_v2_block( + 'block2', base_depth=2, num_units=2, stride=1), + ] + inputs = create_test_input(2, 32, 16, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_plain(inputs, blocks, scope='tiny') + expected = [ + 'tiny/block1/unit_1/bottleneck_v2/shortcut', + 'tiny/block1/unit_1/bottleneck_v2/conv1', + 'tiny/block1/unit_1/bottleneck_v2/conv2', + 'tiny/block1/unit_1/bottleneck_v2/conv3', + 'tiny/block1/unit_2/bottleneck_v2/conv1', + 'tiny/block1/unit_2/bottleneck_v2/conv2', + 'tiny/block1/unit_2/bottleneck_v2/conv3', + 'tiny/block2/unit_1/bottleneck_v2/shortcut', + 'tiny/block2/unit_1/bottleneck_v2/conv1', + 'tiny/block2/unit_1/bottleneck_v2/conv2', + 'tiny/block2/unit_1/bottleneck_v2/conv3', + 'tiny/block2/unit_2/bottleneck_v2/conv1', + 'tiny/block2/unit_2/bottleneck_v2/conv2', + 'tiny/block2/unit_2/bottleneck_v2/conv3'] + self.assertItemsEqual(expected, end_points.keys()) + + def _stack_blocks_nondense(self, net, blocks): + """A simplified ResNet Block stacker without output stride control.""" + for block in blocks: + with tf.variable_scope(block.scope, 'block', [net]): + for i, unit in enumerate(block.args): + with tf.variable_scope('unit_%d' % (i + 1), values=[net]): + net = block.unit_fn(net, rate=1, **unit) + return net + + def testAtrousValuesBottleneck(self): + """Verify the values of dense feature extraction by atrous convolution. + + Make sure that dense feature extraction by stack_blocks_dense() followed by + subsampling gives identical results to feature extraction at the nominal + network output stride using the simple self._stack_blocks_nondense() above. + """ + block = resnet_v2.resnet_v2_block + blocks = [ + block('block1', base_depth=1, num_units=2, stride=2), + block('block2', base_depth=2, num_units=2, stride=2), + block('block3', base_depth=4, num_units=2, stride=2), + block('block4', base_depth=8, num_units=2, stride=1), + ] + nominal_stride = 8 + + # Test both odd and even input dimensions. + height = 30 + width = 31 + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + with slim.arg_scope([slim.batch_norm], is_training=False): + for output_stride in [1, 2, 4, 8, None]: + with tf.Graph().as_default(): + with self.test_session() as sess: + tf.set_random_seed(0) + inputs = create_test_input(1, height, width, 3) + # Dense feature extraction followed by subsampling. + output = resnet_utils.stack_blocks_dense(inputs, + blocks, + output_stride) + if output_stride is None: + factor = 1 + else: + factor = nominal_stride // output_stride + + output = resnet_utils.subsample(output, factor) + # Make the two networks use the same weights. + tf.get_variable_scope().reuse_variables() + # Feature extraction at the nominal network rate. + expected = self._stack_blocks_nondense(inputs, blocks) + sess.run(tf.global_variables_initializer()) + output, expected = sess.run([output, expected]) + self.assertAllClose(output, expected, atol=1e-4, rtol=1e-4) + + +class ResnetCompleteNetworkTest(tf.test.TestCase): + """Tests with complete small ResNet v2 networks.""" + + def _resnet_small(self, + inputs, + num_classes=None, + is_training=True, + global_pool=True, + output_stride=None, + include_root_block=True, + spatial_squeeze=True, + reuse=None, + scope='resnet_v2_small'): + """A shallow and thin ResNet v2 for faster tests.""" + block = resnet_v2.resnet_v2_block + blocks = [ + block('block1', base_depth=1, num_units=3, stride=2), + block('block2', base_depth=2, num_units=3, stride=2), + block('block3', base_depth=4, num_units=3, stride=2), + block('block4', base_depth=8, num_units=2, stride=1), + ] + return resnet_v2.resnet_v2(inputs, blocks, num_classes, + is_training=is_training, + global_pool=global_pool, + output_stride=output_stride, + include_root_block=include_root_block, + spatial_squeeze=spatial_squeeze, + reuse=reuse, + scope=scope) + + def testClassificationEndPoints(self): + global_pool = True + num_classes = 10 + inputs = create_test_input(2, 224, 224, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + logits, end_points = self._resnet_small(inputs, num_classes, + global_pool=global_pool, + spatial_squeeze=False, + scope='resnet') + self.assertTrue(logits.op.name.startswith('resnet/logits')) + self.assertListEqual(logits.get_shape().as_list(), [2, 1, 1, num_classes]) + self.assertTrue('predictions' in end_points) + self.assertListEqual(end_points['predictions'].get_shape().as_list(), + [2, 1, 1, num_classes]) + self.assertTrue('global_pool' in end_points) + self.assertListEqual(end_points['global_pool'].get_shape().as_list(), + [2, 1, 1, 32]) + + def testEndpointNames(self): + # Like ResnetUtilsTest.testEndPointsV2(), but for the public API. + global_pool = True + num_classes = 10 + inputs = create_test_input(2, 224, 224, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_small(inputs, num_classes, + global_pool=global_pool, + scope='resnet') + expected = ['resnet/conv1'] + for block in range(1, 5): + for unit in range(1, 4 if block < 4 else 3): + for conv in range(1, 4): + expected.append('resnet/block%d/unit_%d/bottleneck_v2/conv%d' % + (block, unit, conv)) + expected.append('resnet/block%d/unit_%d/bottleneck_v2' % (block, unit)) + expected.append('resnet/block%d/unit_1/bottleneck_v2/shortcut' % block) + expected.append('resnet/block%d' % block) + expected.extend(['global_pool', 'resnet/logits', 'resnet/spatial_squeeze', + 'predictions']) + self.assertItemsEqual(end_points.keys(), expected) + + def testClassificationShapes(self): + global_pool = True + num_classes = 10 + inputs = create_test_input(2, 224, 224, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_small(inputs, num_classes, + global_pool=global_pool, + scope='resnet') + endpoint_to_shape = { + 'resnet/block1': [2, 28, 28, 4], + 'resnet/block2': [2, 14, 14, 8], + 'resnet/block3': [2, 7, 7, 16], + 'resnet/block4': [2, 7, 7, 32]} + for endpoint in endpoint_to_shape: + shape = endpoint_to_shape[endpoint] + self.assertListEqual(end_points[endpoint].get_shape().as_list(), shape) + + def testFullyConvolutionalEndpointShapes(self): + global_pool = False + num_classes = 10 + inputs = create_test_input(2, 321, 321, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_small(inputs, num_classes, + global_pool=global_pool, + spatial_squeeze=False, + scope='resnet') + endpoint_to_shape = { + 'resnet/block1': [2, 41, 41, 4], + 'resnet/block2': [2, 21, 21, 8], + 'resnet/block3': [2, 11, 11, 16], + 'resnet/block4': [2, 11, 11, 32]} + for endpoint in endpoint_to_shape: + shape = endpoint_to_shape[endpoint] + self.assertListEqual(end_points[endpoint].get_shape().as_list(), shape) + + def testRootlessFullyConvolutionalEndpointShapes(self): + global_pool = False + num_classes = 10 + inputs = create_test_input(2, 128, 128, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_small(inputs, num_classes, + global_pool=global_pool, + include_root_block=False, + spatial_squeeze=False, + scope='resnet') + endpoint_to_shape = { + 'resnet/block1': [2, 64, 64, 4], + 'resnet/block2': [2, 32, 32, 8], + 'resnet/block3': [2, 16, 16, 16], + 'resnet/block4': [2, 16, 16, 32]} + for endpoint in endpoint_to_shape: + shape = endpoint_to_shape[endpoint] + self.assertListEqual(end_points[endpoint].get_shape().as_list(), shape) + + def testAtrousFullyConvolutionalEndpointShapes(self): + global_pool = False + num_classes = 10 + output_stride = 8 + inputs = create_test_input(2, 321, 321, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + _, end_points = self._resnet_small(inputs, + num_classes, + global_pool=global_pool, + output_stride=output_stride, + spatial_squeeze=False, + scope='resnet') + endpoint_to_shape = { + 'resnet/block1': [2, 41, 41, 4], + 'resnet/block2': [2, 41, 41, 8], + 'resnet/block3': [2, 41, 41, 16], + 'resnet/block4': [2, 41, 41, 32]} + for endpoint in endpoint_to_shape: + shape = endpoint_to_shape[endpoint] + self.assertListEqual(end_points[endpoint].get_shape().as_list(), shape) + + def testAtrousFullyConvolutionalValues(self): + """Verify dense feature extraction with atrous convolution.""" + nominal_stride = 32 + for output_stride in [4, 8, 16, 32, None]: + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + with tf.Graph().as_default(): + with self.test_session() as sess: + tf.set_random_seed(0) + inputs = create_test_input(2, 81, 81, 3) + # Dense feature extraction followed by subsampling. + output, _ = self._resnet_small(inputs, None, + is_training=False, + global_pool=False, + output_stride=output_stride) + if output_stride is None: + factor = 1 + else: + factor = nominal_stride // output_stride + output = resnet_utils.subsample(output, factor) + # Make the two networks use the same weights. + tf.get_variable_scope().reuse_variables() + # Feature extraction at the nominal network rate. + expected, _ = self._resnet_small(inputs, None, + is_training=False, + global_pool=False) + sess.run(tf.global_variables_initializer()) + self.assertAllClose(output.eval(), expected.eval(), + atol=1e-4, rtol=1e-4) + + def testUnknownBatchSize(self): + batch = 2 + height, width = 65, 65 + global_pool = True + num_classes = 10 + inputs = create_test_input(None, height, width, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + logits, _ = self._resnet_small(inputs, num_classes, + global_pool=global_pool, + spatial_squeeze=False, + scope='resnet') + self.assertTrue(logits.op.name.startswith('resnet/logits')) + self.assertListEqual(logits.get_shape().as_list(), + [None, 1, 1, num_classes]) + images = create_test_input(batch, height, width, 3) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(logits, {inputs: images.eval()}) + self.assertEqual(output.shape, (batch, 1, 1, num_classes)) + + def testFullyConvolutionalUnknownHeightWidth(self): + batch = 2 + height, width = 65, 65 + global_pool = False + inputs = create_test_input(batch, None, None, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + output, _ = self._resnet_small(inputs, None, + global_pool=global_pool) + self.assertListEqual(output.get_shape().as_list(), + [batch, None, None, 32]) + images = create_test_input(batch, height, width, 3) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(output, {inputs: images.eval()}) + self.assertEqual(output.shape, (batch, 3, 3, 32)) + + def testAtrousFullyConvolutionalUnknownHeightWidth(self): + batch = 2 + height, width = 65, 65 + global_pool = False + output_stride = 8 + inputs = create_test_input(batch, None, None, 3) + with slim.arg_scope(resnet_utils.resnet_arg_scope()): + output, _ = self._resnet_small(inputs, + None, + global_pool=global_pool, + output_stride=output_stride) + self.assertListEqual(output.get_shape().as_list(), + [batch, None, None, 32]) + images = create_test_input(batch, height, width, 3) + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(output, {inputs: images.eval()}) + self.assertEqual(output.shape, (batch, 9, 9, 32)) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/s3dg.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/s3dg.py new file mode 100644 index 0000000..a13375e --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/s3dg.py @@ -0,0 +1,599 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains the definition for Gated Separable 3D network (S3D-G). + +The network architecture is proposed by: + Saining Xie, Chen Sun, Jonathan Huang, Zhuowen Tu and Kevin Murphy, + Rethinking Spatiotemporal Feature Learning For Video Understanding. + https://arxiv.org/abs/1712.04851. +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import i3d_utils + +trunc_normal = lambda stddev: tf.truncated_normal_initializer(0.0, stddev) +conv3d_spatiotemporal = i3d_utils.conv3d_spatiotemporal +inception_block_v1_3d = i3d_utils.inception_block_v1_3d + +# Orignaly, arg_scope = slim.arg_scope and layers = slim, now switch to more +# update-to-date tf.contrib.* API. +arg_scope = tf.contrib.framework.arg_scope +layers = tf.contrib.layers + + +def s3dg_arg_scope(weight_decay=1e-7, + batch_norm_decay=0.999, + batch_norm_epsilon=0.001): + """Defines default arg_scope for S3D-G. + + Args: + weight_decay: The weight decay to use for regularizing the model. + batch_norm_decay: Decay for batch norm moving average. + batch_norm_epsilon: Small float added to variance to avoid dividing by zero + in batch norm. + + Returns: + sc: An arg_scope to use for the models. + """ + batch_norm_params = { + # Decay for the moving averages. + 'decay': batch_norm_decay, + # epsilon to prevent 0s in variance. + 'epsilon': batch_norm_epsilon, + # Turns off fused batch norm. + 'fused': False, + # collection containing the moving mean and moving variance. + 'variables_collections': { + 'beta': None, + 'gamma': None, + 'moving_mean': ['moving_vars'], + 'moving_variance': ['moving_vars'], + } + } + + with arg_scope( + [layers.conv3d, conv3d_spatiotemporal], + weights_regularizer=layers.l2_regularizer(weight_decay), + activation_fn=tf.nn.relu, + normalizer_fn=layers.batch_norm, + normalizer_params=batch_norm_params): + with arg_scope([conv3d_spatiotemporal], separable=True) as sc: + return sc + + +def self_gating(input_tensor, scope, data_format='NDHWC'): + """Feature gating as used in S3D-G. + + Transforms the input features by aggregating features from all + spatial and temporal locations, and applying gating conditioned + on the aggregated features. More details can be found at: + https://arxiv.org/abs/1712.04851 + + Args: + input_tensor: A 5-D float tensor of size [batch_size, num_frames, + height, width, channels]. + scope: scope for `variable_scope`. + data_format: An optional string from: "NDHWC", "NCDHW". Defaults to "NDHWC". + The data format of the input and output data. With the default format + "NDHWC", the data is stored in the order of: [batch, in_depth, in_height, + in_width, in_channels]. Alternatively, the format could be "NCDHW", the + data storage order is: + [batch, in_channels, in_depth, in_height, in_width]. + + Returns: + A tensor with the same shape as input_tensor. + """ + + index_c = data_format.index('C') + index_d = data_format.index('D') + index_h = data_format.index('H') + index_w = data_format.index('W') + input_shape = input_tensor.get_shape().as_list() + t = input_shape[index_d] + w = input_shape[index_w] + h = input_shape[index_h] + num_channels = input_shape[index_c] + + spatiotemporal_average = layers.avg_pool3d( + input_tensor, [t, w, h], + stride=1, + data_format=data_format, + scope=scope + '/self_gating/avg_pool3d') + + weights = layers.conv3d( + spatiotemporal_average, + num_channels, [1, 1, 1], + activation_fn=None, + normalizer_fn=None, + biases_initializer=None, + data_format=data_format, + weights_initializer=trunc_normal(0.01), + scope=scope + '/self_gating/transformer_W') + + tile_multiples = [1, t, w, h] + tile_multiples.insert(index_c, 1) + weights = tf.tile(weights, tile_multiples) + weights = tf.nn.sigmoid(weights) + + return tf.multiply(weights, input_tensor) + + +def s3dg_base(inputs, + first_temporal_kernel_size=3, + temporal_conv_startat='Conv2d_2c_3x3', + gating_startat='Conv2d_2c_3x3', + final_endpoint='Mixed_5c', + min_depth=16, + depth_multiplier=1.0, + data_format='NDHWC', + scope='InceptionV1'): + """Defines the I3D/S3DG base architecture. + + Note that we use the names as defined in Inception V1 to facilitate checkpoint + conversion from an image-trained Inception V1 checkpoint to I3D checkpoint. + + Args: + inputs: A 5-D float tensor of size [batch_size, num_frames, height, width, + channels]. + first_temporal_kernel_size: Specifies the temporal kernel size for the first + conv3d filter. A larger value slows down the model but provides little + accuracy improvement. The default is 7 in the original I3D and S3D-G but 3 + gives better performance. Must be set to one of 1, 3, 5 or 7. + temporal_conv_startat: Specifies the first conv block to use 3D or separable + 3D convs rather than 2D convs (implemented as [1, k, k] 3D conv). This is + used to construct the inverted pyramid models. 'Conv2d_2c_3x3' is the + first valid block to use separable 3D convs. If provided block name is + not present, all valid blocks will use separable 3D convs. Note that + 'Conv2d_1a_7x7' cannot be made into a separable 3D conv, but can be made + into a 2D or 3D conv using the `first_temporal_kernel_size` option. + gating_startat: Specifies the first conv block to use self gating. + 'Conv2d_2c_3x3' is the first valid block to use self gating. If provided + block name is not present, all valid blocks will use separable 3D convs. + final_endpoint: Specifies the endpoint to construct the network up to. It + can be one of ['Conv2d_1a_7x7', 'MaxPool_2a_3x3', 'Conv2d_2b_1x1', + 'Conv2d_2c_3x3', 'MaxPool_3a_3x3', 'Mixed_3b', 'Mixed_3c', + 'MaxPool_4a_3x3', 'Mixed_4b', 'Mixed_4c', 'Mixed_4d', 'Mixed_4e', + 'Mixed_4f', 'MaxPool_5a_2x2', 'Mixed_5b', 'Mixed_5c'] + min_depth: Minimum depth value (number of channels) for all convolution ops. + Enforced when depth_multiplier < 1, and not an active constraint when + depth_multiplier >= 1. + depth_multiplier: Float multiplier for the depth (number of channels) + for all convolution ops. The value must be greater than zero. Typical + usage will be to set this value in (0, 1) to reduce the number of + parameters or computation cost of the model. + data_format: An optional string from: "NDHWC", "NCDHW". Defaults to "NDHWC". + The data format of the input and output data. With the default format + "NDHWC", the data is stored in the order of: [batch, in_depth, in_height, + in_width, in_channels]. Alternatively, the format could be "NCDHW", the + data storage order is: + [batch, in_channels, in_depth, in_height, in_width]. + scope: Optional variable_scope. + + Returns: + A dictionary from components of the network to the corresponding activation. + + Raises: + ValueError: if final_endpoint is not set to one of the predefined values, or + if depth_multiplier <= 0. + """ + + assert data_format in ['NDHWC', 'NCDHW'] + end_points = {} + t = 1 + # For inverted pyramid models, we start with gating switched off. + use_gating = False + self_gating_fn = None + def gating_fn(inputs, scope): + return self_gating(inputs, scope, data_format=data_format) + + if depth_multiplier <= 0: + raise ValueError('depth_multiplier is not greater than zero.') + depth = lambda d: max(int(d * depth_multiplier), min_depth) + + with tf.variable_scope(scope, 'InceptionV1', [inputs]): + with arg_scope([layers.conv3d], weights_initializer=trunc_normal(0.01)): + with arg_scope( + [layers.conv3d, layers.max_pool3d, conv3d_spatiotemporal], + stride=1, + data_format=data_format, + padding='SAME'): + # batch_size x 32 x 112 x 112 x 64 + end_point = 'Conv2d_1a_7x7' + if first_temporal_kernel_size not in [1, 3, 5, 7]: + raise ValueError( + 'first_temporal_kernel_size can only be 1, 3, 5 or 7.') + # Separable conv is slow when used at first conv layer. + net = conv3d_spatiotemporal( + inputs, + depth(64), [first_temporal_kernel_size, 7, 7], + stride=2, + separable=False, + scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + # batch_size x 32 x 56 x 56 x 64 + end_point = 'MaxPool_2a_3x3' + net = layers.max_pool3d( + net, [1, 3, 3], stride=[1, 2, 2], scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + # batch_size x 32 x 56 x 56 x 64 + end_point = 'Conv2d_2b_1x1' + net = layers.conv3d(net, depth(64), [1, 1, 1], scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + # batch_size x 32 x 56 x 56 x 192 + end_point = 'Conv2d_2c_3x3' + if temporal_conv_startat == end_point: + t = 3 + if gating_startat == end_point: + use_gating = True + self_gating_fn = gating_fn + net = conv3d_spatiotemporal(net, depth(192), [t, 3, 3], scope=end_point) + if use_gating: + net = self_gating(net, scope=end_point, data_format=data_format) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + # batch_size x 32 x 28 x 28 x 192 + end_point = 'MaxPool_3a_3x3' + net = layers.max_pool3d( + net, [1, 3, 3], stride=[1, 2, 2], scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + + # batch_size x 32 x 28 x 28 x 256 + end_point = 'Mixed_3b' + if temporal_conv_startat == end_point: + t = 3 + if gating_startat == end_point: + use_gating = True + self_gating_fn = gating_fn + net = inception_block_v1_3d( + net, + num_outputs_0_0a=depth(64), + num_outputs_1_0a=depth(96), + num_outputs_1_0b=depth(128), + num_outputs_2_0a=depth(16), + num_outputs_2_0b=depth(32), + num_outputs_3_0b=depth(32), + temporal_kernel_size=t, + self_gating_fn=self_gating_fn, + data_format=data_format, + scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + + end_point = 'Mixed_3c' + if temporal_conv_startat == end_point: + t = 3 + if gating_startat == end_point: + use_gating = True + self_gating_fn = gating_fn + net = inception_block_v1_3d( + net, + num_outputs_0_0a=depth(128), + num_outputs_1_0a=depth(128), + num_outputs_1_0b=depth(192), + num_outputs_2_0a=depth(32), + num_outputs_2_0b=depth(96), + num_outputs_3_0b=depth(64), + temporal_kernel_size=t, + self_gating_fn=self_gating_fn, + data_format=data_format, + scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + + end_point = 'MaxPool_4a_3x3' + net = layers.max_pool3d( + net, [3, 3, 3], stride=[2, 2, 2], scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + + # batch_size x 16 x 14 x 14 x 512 + end_point = 'Mixed_4b' + if temporal_conv_startat == end_point: + t = 3 + if gating_startat == end_point: + use_gating = True + self_gating_fn = gating_fn + net = inception_block_v1_3d( + net, + num_outputs_0_0a=depth(192), + num_outputs_1_0a=depth(96), + num_outputs_1_0b=depth(208), + num_outputs_2_0a=depth(16), + num_outputs_2_0b=depth(48), + num_outputs_3_0b=depth(64), + temporal_kernel_size=t, + self_gating_fn=self_gating_fn, + data_format=data_format, + scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + + # batch_size x 16 x 14 x 14 x 512 + end_point = 'Mixed_4c' + if temporal_conv_startat == end_point: + t = 3 + if gating_startat == end_point: + use_gating = True + self_gating_fn = gating_fn + net = inception_block_v1_3d( + net, + num_outputs_0_0a=depth(160), + num_outputs_1_0a=depth(112), + num_outputs_1_0b=depth(224), + num_outputs_2_0a=depth(24), + num_outputs_2_0b=depth(64), + num_outputs_3_0b=depth(64), + temporal_kernel_size=t, + self_gating_fn=self_gating_fn, + data_format=data_format, + scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + + # batch_size x 16 x 14 x 14 x 512 + end_point = 'Mixed_4d' + if temporal_conv_startat == end_point: + t = 3 + if gating_startat == end_point: + use_gating = True + self_gating_fn = gating_fn + net = inception_block_v1_3d( + net, + num_outputs_0_0a=depth(128), + num_outputs_1_0a=depth(128), + num_outputs_1_0b=depth(256), + num_outputs_2_0a=depth(24), + num_outputs_2_0b=depth(64), + num_outputs_3_0b=depth(64), + temporal_kernel_size=t, + self_gating_fn=self_gating_fn, + data_format=data_format, + scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + + # batch_size x 16 x 14 x 14 x 528 + end_point = 'Mixed_4e' + if temporal_conv_startat == end_point: + t = 3 + if gating_startat == end_point: + use_gating = True + self_gating_fn = gating_fn + net = inception_block_v1_3d( + net, + num_outputs_0_0a=depth(112), + num_outputs_1_0a=depth(144), + num_outputs_1_0b=depth(288), + num_outputs_2_0a=depth(32), + num_outputs_2_0b=depth(64), + num_outputs_3_0b=depth(64), + temporal_kernel_size=t, + self_gating_fn=self_gating_fn, + data_format=data_format, + scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + + # batch_size x 16 x 14 x 14 x 832 + end_point = 'Mixed_4f' + if temporal_conv_startat == end_point: + t = 3 + if gating_startat == end_point: + use_gating = True + self_gating_fn = gating_fn + net = inception_block_v1_3d( + net, + num_outputs_0_0a=depth(256), + num_outputs_1_0a=depth(160), + num_outputs_1_0b=depth(320), + num_outputs_2_0a=depth(32), + num_outputs_2_0b=depth(128), + num_outputs_3_0b=depth(128), + temporal_kernel_size=t, + self_gating_fn=self_gating_fn, + data_format=data_format, + scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + + end_point = 'MaxPool_5a_2x2' + net = layers.max_pool3d( + net, [2, 2, 2], stride=[2, 2, 2], scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + + # batch_size x 8 x 7 x 7 x 832 + end_point = 'Mixed_5b' + if temporal_conv_startat == end_point: + t = 3 + if gating_startat == end_point: + use_gating = True + self_gating_fn = gating_fn + net = inception_block_v1_3d( + net, + num_outputs_0_0a=depth(256), + num_outputs_1_0a=depth(160), + num_outputs_1_0b=depth(320), + num_outputs_2_0a=depth(32), + num_outputs_2_0b=depth(128), + num_outputs_3_0b=depth(128), + temporal_kernel_size=t, + self_gating_fn=self_gating_fn, + data_format=data_format, + scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + + # batch_size x 8 x 7 x 7 x 1024 + end_point = 'Mixed_5c' + if temporal_conv_startat == end_point: + t = 3 + if gating_startat == end_point: + use_gating = True + self_gating_fn = gating_fn + net = inception_block_v1_3d( + net, + num_outputs_0_0a=depth(384), + num_outputs_1_0a=depth(192), + num_outputs_1_0b=depth(384), + num_outputs_2_0a=depth(48), + num_outputs_2_0b=depth(128), + num_outputs_3_0b=depth(128), + temporal_kernel_size=t, + self_gating_fn=self_gating_fn, + data_format=data_format, + scope=end_point) + end_points[end_point] = net + if final_endpoint == end_point: + return net, end_points + raise ValueError('Unknown final endpoint %s' % final_endpoint) + + +def s3dg(inputs, + num_classes=1000, + first_temporal_kernel_size=3, + temporal_conv_startat='Conv2d_2c_3x3', + gating_startat='Conv2d_2c_3x3', + final_endpoint='Mixed_5c', + min_depth=16, + depth_multiplier=1.0, + dropout_keep_prob=0.8, + is_training=True, + prediction_fn=layers.softmax, + spatial_squeeze=True, + reuse=None, + data_format='NDHWC', + scope='InceptionV1'): + """Defines the S3D-G architecture. + + The default image size used to train this network is 224x224. + + Args: + inputs: A 5-D float tensor of size [batch_size, num_frames, height, width, + channels]. + num_classes: number of predicted classes. + first_temporal_kernel_size: Specifies the temporal kernel size for the first + conv3d filter. A larger value slows down the model but provides little + accuracy improvement. Must be set to one of 1, 3, 5 or 7. + temporal_conv_startat: Specifies the first conv block to use separable 3D + convs rather than 2D convs (implemented as [1, k, k] 3D conv). This is + used to construct the inverted pyramid models. 'Conv2d_2c_3x3' is the + first valid block to use separable 3D convs. If provided block name is + not present, all valid blocks will use separable 3D convs. + gating_startat: Specifies the first conv block to use self gating. + 'Conv2d_2c_3x3' is the first valid block to use self gating. If provided + block name is not present, all valid blocks will use separable 3D convs. + final_endpoint: Specifies the endpoint to construct the network up to. It + can be one of ['Conv2d_1a_7x7', 'MaxPool_2a_3x3', 'Conv2d_2b_1x1', + 'Conv2d_2c_3x3', 'MaxPool_3a_3x3', 'Mixed_3b', 'Mixed_3c', + 'MaxPool_4a_3x3', 'Mixed_4b', 'Mixed_4c', 'Mixed_4d', 'Mixed_4e', + 'Mixed_4f', 'MaxPool_5a_2x2', 'Mixed_5b', 'Mixed_5c'] + min_depth: Minimum depth value (number of channels) for all convolution ops. + Enforced when depth_multiplier < 1, and not an active constraint when + depth_multiplier >= 1. + depth_multiplier: Float multiplier for the depth (number of channels) + for all convolution ops. The value must be greater than zero. Typical + usage will be to set this value in (0, 1) to reduce the number of + parameters or computation cost of the model. + dropout_keep_prob: the percentage of activation values that are retained. + is_training: whether is training or not. + prediction_fn: a function to get predictions out of logits. + spatial_squeeze: if True, logits is of shape is [B, C], if false logits is + of shape [B, 1, 1, C], where B is batch_size and C is number of classes. + reuse: whether or not the network and its variables should be reused. To be + able to reuse 'scope' must be given. + data_format: An optional string from: "NDHWC", "NCDHW". Defaults to "NDHWC". + The data format of the input and output data. With the default format + "NDHWC", the data is stored in the order of: [batch, in_depth, in_height, + in_width, in_channels]. Alternatively, the format could be "NCDHW", the + data storage order is: + [batch, in_channels, in_depth, in_height, in_width]. + scope: Optional variable_scope. + + Returns: + logits: the pre-softmax activations, a tensor of size + [batch_size, num_classes] + end_points: a dictionary from components of the network to the corresponding + activation. + """ + assert data_format in ['NDHWC', 'NCDHW'] + # Final pooling and prediction + with tf.variable_scope( + scope, 'InceptionV1', [inputs, num_classes], reuse=reuse) as scope: + with arg_scope( + [layers.batch_norm, layers.dropout], is_training=is_training): + net, end_points = s3dg_base( + inputs, + first_temporal_kernel_size=first_temporal_kernel_size, + temporal_conv_startat=temporal_conv_startat, + gating_startat=gating_startat, + final_endpoint=final_endpoint, + min_depth=min_depth, + depth_multiplier=depth_multiplier, + data_format=data_format, + scope=scope) + with tf.variable_scope('Logits'): + if data_format.startswith('NC'): + net = tf.transpose(net, [0, 2, 3, 4, 1]) + kernel_size = i3d_utils.reduced_kernel_size_3d(net, [2, 7, 7]) + net = layers.avg_pool3d( + net, + kernel_size, + stride=1, + data_format='NDHWC', + scope='AvgPool_0a_7x7') + net = layers.dropout(net, dropout_keep_prob, scope='Dropout_0b') + logits = layers.conv3d( + net, + num_classes, [1, 1, 1], + activation_fn=None, + normalizer_fn=None, + data_format='NDHWC', + scope='Conv2d_0c_1x1') + # Temporal average pooling. + logits = tf.reduce_mean(logits, axis=1) + if spatial_squeeze: + logits = tf.squeeze(logits, [1, 2], name='SpatialSqueeze') + + end_points['Logits'] = logits + end_points['Predictions'] = prediction_fn(logits, scope='Predictions') + return logits, end_points + + +s3dg.default_image_size = 224 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/s3dg_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/s3dg_test.py new file mode 100644 index 0000000..1758797 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/s3dg_test.py @@ -0,0 +1,150 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for networks.s3dg.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import s3dg + + +class S3DGTest(tf.test.TestCase): + + def testBuildClassificationNetwork(self): + batch_size = 5 + num_frames = 64 + height, width = 224, 224 + num_classes = 1000 + + inputs = tf.random_uniform((batch_size, num_frames, height, width, 3)) + logits, end_points = s3dg.s3dg(inputs, num_classes) + self.assertTrue(logits.op.name.startswith('InceptionV1/Logits')) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + self.assertTrue('Predictions' in end_points) + self.assertListEqual(end_points['Predictions'].get_shape().as_list(), + [batch_size, num_classes]) + + def testBuildBaseNetwork(self): + batch_size = 5 + num_frames = 64 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, num_frames, height, width, 3)) + mixed_6c, end_points = s3dg.s3dg_base(inputs) + self.assertTrue(mixed_6c.op.name.startswith('InceptionV1/Mixed_5c')) + self.assertListEqual(mixed_6c.get_shape().as_list(), + [batch_size, 8, 7, 7, 1024]) + expected_endpoints = ['Conv2d_1a_7x7', 'MaxPool_2a_3x3', 'Conv2d_2b_1x1', + 'Conv2d_2c_3x3', 'MaxPool_3a_3x3', 'Mixed_3b', + 'Mixed_3c', 'MaxPool_4a_3x3', 'Mixed_4b', 'Mixed_4c', + 'Mixed_4d', 'Mixed_4e', 'Mixed_4f', 'MaxPool_5a_2x2', + 'Mixed_5b', 'Mixed_5c'] + self.assertItemsEqual(end_points.keys(), expected_endpoints) + + def testBuildOnlyUptoFinalEndpointNoGating(self): + batch_size = 5 + num_frames = 64 + height, width = 224, 224 + endpoints = ['Conv2d_1a_7x7', 'MaxPool_2a_3x3', 'Conv2d_2b_1x1', + 'Conv2d_2c_3x3', 'MaxPool_3a_3x3', 'Mixed_3b', 'Mixed_3c', + 'MaxPool_4a_3x3', 'Mixed_4b', 'Mixed_4c', 'Mixed_4d', + 'Mixed_4e', 'Mixed_4f', 'MaxPool_5a_2x2', 'Mixed_5b', + 'Mixed_5c'] + for index, endpoint in enumerate(endpoints): + with tf.Graph().as_default(): + inputs = tf.random_uniform((batch_size, num_frames, height, width, 3)) + out_tensor, end_points = s3dg.s3dg_base( + inputs, final_endpoint=endpoint, gating_startat=None) + print(endpoint, out_tensor.op.name) + self.assertTrue(out_tensor.op.name.startswith( + 'InceptionV1/' + endpoint)) + self.assertItemsEqual(endpoints[:index+1], end_points) + + def testBuildAndCheckAllEndPointsUptoMixed5c(self): + batch_size = 5 + num_frames = 64 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, num_frames, height, width, 3)) + _, end_points = s3dg.s3dg_base(inputs, + final_endpoint='Mixed_5c') + endpoints_shapes = {'Conv2d_1a_7x7': [5, 32, 112, 112, 64], + 'MaxPool_2a_3x3': [5, 32, 56, 56, 64], + 'Conv2d_2b_1x1': [5, 32, 56, 56, 64], + 'Conv2d_2c_3x3': [5, 32, 56, 56, 192], + 'MaxPool_3a_3x3': [5, 32, 28, 28, 192], + 'Mixed_3b': [5, 32, 28, 28, 256], + 'Mixed_3c': [5, 32, 28, 28, 480], + 'MaxPool_4a_3x3': [5, 16, 14, 14, 480], + 'Mixed_4b': [5, 16, 14, 14, 512], + 'Mixed_4c': [5, 16, 14, 14, 512], + 'Mixed_4d': [5, 16, 14, 14, 512], + 'Mixed_4e': [5, 16, 14, 14, 528], + 'Mixed_4f': [5, 16, 14, 14, 832], + 'MaxPool_5a_2x2': [5, 8, 7, 7, 832], + 'Mixed_5b': [5, 8, 7, 7, 832], + 'Mixed_5c': [5, 8, 7, 7, 1024]} + + self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys()) + for endpoint_name, expected_shape in endpoints_shapes.iteritems(): + self.assertTrue(endpoint_name in end_points) + self.assertListEqual(end_points[endpoint_name].get_shape().as_list(), + expected_shape) + + def testHalfSizeImages(self): + batch_size = 5 + num_frames = 64 + height, width = 112, 112 + + inputs = tf.random_uniform((batch_size, num_frames, height, width, 3)) + mixed_5c, _ = s3dg.s3dg_base(inputs) + self.assertTrue(mixed_5c.op.name.startswith('InceptionV1/Mixed_5c')) + self.assertListEqual(mixed_5c.get_shape().as_list(), + [batch_size, 8, 4, 4, 1024]) + + def testTenFrames(self): + batch_size = 5 + num_frames = 10 + height, width = 224, 224 + + inputs = tf.random_uniform((batch_size, num_frames, height, width, 3)) + mixed_5c, _ = s3dg.s3dg_base(inputs) + self.assertTrue(mixed_5c.op.name.startswith('InceptionV1/Mixed_5c')) + self.assertListEqual(mixed_5c.get_shape().as_list(), + [batch_size, 2, 7, 7, 1024]) + + def testEvaluation(self): + batch_size = 2 + num_frames = 64 + height, width = 224, 224 + num_classes = 1000 + + eval_inputs = tf.random_uniform((batch_size, num_frames, height, width, 3)) + logits, _ = s3dg.s3dg(eval_inputs, num_classes, + is_training=False) + predictions = tf.argmax(logits, 1) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + output = sess.run(predictions) + self.assertEquals(output.shape, (batch_size,)) + + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/vgg.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/vgg.py new file mode 100644 index 0000000..33a6630 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/vgg.py @@ -0,0 +1,302 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains model definitions for versions of the Oxford VGG network. + +These model definitions were introduced in the following technical report: + + Very Deep Convolutional Networks For Large-Scale Image Recognition + Karen Simonyan and Andrew Zisserman + arXiv technical report, 2015 + PDF: http://arxiv.org/pdf/1409.1556.pdf + ILSVRC 2014 Slides: http://www.robots.ox.ac.uk/~karen/pdf/ILSVRC_2014.pdf + CC-BY-4.0 + +More information can be obtained from the VGG website: +www.robots.ox.ac.uk/~vgg/research/very_deep/ + +Usage: + with slim.arg_scope(vgg.vgg_arg_scope()): + outputs, end_points = vgg.vgg_a(inputs) + + with slim.arg_scope(vgg.vgg_arg_scope()): + outputs, end_points = vgg.vgg_16(inputs) + +@@vgg_a +@@vgg_16 +@@vgg_19 +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +slim = tf.contrib.slim + + +def vgg_arg_scope(weight_decay=0.0005): + """Defines the VGG arg scope. + + Args: + weight_decay: The l2 regularization coefficient. + + Returns: + An arg_scope. + """ + with slim.arg_scope([slim.conv2d, slim.fully_connected], + activation_fn=tf.nn.relu, + weights_regularizer=slim.l2_regularizer(weight_decay), + biases_initializer=tf.zeros_initializer()): + with slim.arg_scope([slim.conv2d], padding='SAME') as arg_sc: + return arg_sc + + +def vgg_a(inputs, + num_classes=1000, + is_training=True, + dropout_keep_prob=0.5, + spatial_squeeze=True, + scope='vgg_a', + fc_conv_padding='VALID', + global_pool=False): + """Oxford Net VGG 11-Layers version A Example. + + Note: All the fully_connected layers have been transformed to conv2d layers. + To use in classification mode, resize input to 224x224. + + Args: + inputs: a tensor of size [batch_size, height, width, channels]. + num_classes: number of predicted classes. If 0 or None, the logits layer is + omitted and the input features to the logits layer are returned instead. + is_training: whether or not the model is being trained. + dropout_keep_prob: the probability that activations are kept in the dropout + layers during training. + spatial_squeeze: whether or not should squeeze the spatial dimensions of the + outputs. Useful to remove unnecessary dimensions for classification. + scope: Optional scope for the variables. + fc_conv_padding: the type of padding to use for the fully connected layer + that is implemented as a convolutional layer. Use 'SAME' padding if you + are applying the network in a fully convolutional manner and want to + get a prediction map downsampled by a factor of 32 as an output. + Otherwise, the output prediction map will be (input / 32) - 6 in case of + 'VALID' padding. + global_pool: Optional boolean flag. If True, the input to the classification + layer is avgpooled to size 1x1, for any input size. (This is not part + of the original VGG architecture.) + + Returns: + net: the output of the logits layer (if num_classes is a non-zero integer), + or the input to the logits layer (if num_classes is 0 or None). + end_points: a dict of tensors with intermediate activations. + """ + with tf.variable_scope(scope, 'vgg_a', [inputs]) as sc: + end_points_collection = sc.original_name_scope + '_end_points' + # Collect outputs for conv2d, fully_connected and max_pool2d. + with slim.arg_scope([slim.conv2d, slim.max_pool2d], + outputs_collections=end_points_collection): + net = slim.repeat(inputs, 1, slim.conv2d, 64, [3, 3], scope='conv1') + net = slim.max_pool2d(net, [2, 2], scope='pool1') + net = slim.repeat(net, 1, slim.conv2d, 128, [3, 3], scope='conv2') + net = slim.max_pool2d(net, [2, 2], scope='pool2') + net = slim.repeat(net, 2, slim.conv2d, 256, [3, 3], scope='conv3') + net = slim.max_pool2d(net, [2, 2], scope='pool3') + net = slim.repeat(net, 2, slim.conv2d, 512, [3, 3], scope='conv4') + net = slim.max_pool2d(net, [2, 2], scope='pool4') + net = slim.repeat(net, 2, slim.conv2d, 512, [3, 3], scope='conv5') + net = slim.max_pool2d(net, [2, 2], scope='pool5') + + # Use conv2d instead of fully_connected layers. + net = slim.conv2d(net, 4096, [7, 7], padding=fc_conv_padding, scope='fc6') + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout6') + net = slim.conv2d(net, 4096, [1, 1], scope='fc7') + # Convert end_points_collection into a end_point dict. + end_points = slim.utils.convert_collection_to_dict(end_points_collection) + if global_pool: + net = tf.reduce_mean(net, [1, 2], keep_dims=True, name='global_pool') + end_points['global_pool'] = net + if num_classes: + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout7') + net = slim.conv2d(net, num_classes, [1, 1], + activation_fn=None, + normalizer_fn=None, + scope='fc8') + if spatial_squeeze: + net = tf.squeeze(net, [1, 2], name='fc8/squeezed') + end_points[sc.name + '/fc8'] = net + return net, end_points +vgg_a.default_image_size = 224 + + +def vgg_16(inputs, + num_classes=1000, + is_training=True, + dropout_keep_prob=0.5, + spatial_squeeze=True, + scope='vgg_16', + fc_conv_padding='VALID', + global_pool=False): + """Oxford Net VGG 16-Layers version D Example. + + Note: All the fully_connected layers have been transformed to conv2d layers. + To use in classification mode, resize input to 224x224. + + Args: + inputs: a tensor of size [batch_size, height, width, channels]. + num_classes: number of predicted classes. If 0 or None, the logits layer is + omitted and the input features to the logits layer are returned instead. + is_training: whether or not the model is being trained. + dropout_keep_prob: the probability that activations are kept in the dropout + layers during training. + spatial_squeeze: whether or not should squeeze the spatial dimensions of the + outputs. Useful to remove unnecessary dimensions for classification. + scope: Optional scope for the variables. + fc_conv_padding: the type of padding to use for the fully connected layer + that is implemented as a convolutional layer. Use 'SAME' padding if you + are applying the network in a fully convolutional manner and want to + get a prediction map downsampled by a factor of 32 as an output. + Otherwise, the output prediction map will be (input / 32) - 6 in case of + 'VALID' padding. + global_pool: Optional boolean flag. If True, the input to the classification + layer is avgpooled to size 1x1, for any input size. (This is not part + of the original VGG architecture.) + + Returns: + net: the output of the logits layer (if num_classes is a non-zero integer), + or the input to the logits layer (if num_classes is 0 or None). + end_points: a dict of tensors with intermediate activations. + """ + with tf.variable_scope(scope, 'vgg_16', [inputs]) as sc: + end_points_collection = sc.original_name_scope + '_end_points' + # Collect outputs for conv2d, fully_connected and max_pool2d. + with slim.arg_scope([slim.conv2d, slim.fully_connected, slim.max_pool2d], + outputs_collections=end_points_collection): + net = slim.repeat(inputs, 2, slim.conv2d, 64, [3, 3], scope='conv1') + net = slim.max_pool2d(net, [2, 2], scope='pool1') + net = slim.repeat(net, 2, slim.conv2d, 128, [3, 3], scope='conv2') + net = slim.max_pool2d(net, [2, 2], scope='pool2') + net = slim.repeat(net, 3, slim.conv2d, 256, [3, 3], scope='conv3') + net = slim.max_pool2d(net, [2, 2], scope='pool3') + net = slim.repeat(net, 3, slim.conv2d, 512, [3, 3], scope='conv4') + net = slim.max_pool2d(net, [2, 2], scope='pool4') + net = slim.repeat(net, 3, slim.conv2d, 512, [3, 3], scope='conv5') + net = slim.max_pool2d(net, [2, 2], scope='pool5') + + # Use conv2d instead of fully_connected layers. + net = slim.conv2d(net, 4096, [7, 7], padding=fc_conv_padding, scope='fc6') + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout6') + net = slim.conv2d(net, 4096, [1, 1], scope='fc7') + # Convert end_points_collection into a end_point dict. + end_points = slim.utils.convert_collection_to_dict(end_points_collection) + if global_pool: + net = tf.reduce_mean(net, [1, 2], keep_dims=True, name='global_pool') + end_points['global_pool'] = net + if num_classes: + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout7') + net = slim.conv2d(net, num_classes, [1, 1], + activation_fn=None, + normalizer_fn=None, + scope='fc8') + if spatial_squeeze: + net = tf.squeeze(net, [1, 2], name='fc8/squeezed') + end_points[sc.name + '/fc8'] = net + return net, end_points +vgg_16.default_image_size = 224 + + +def vgg_19(inputs, + num_classes=1000, + is_training=True, + dropout_keep_prob=0.5, + spatial_squeeze=True, + scope='vgg_19', + fc_conv_padding='VALID', + global_pool=False): + """Oxford Net VGG 19-Layers version E Example. + + Note: All the fully_connected layers have been transformed to conv2d layers. + To use in classification mode, resize input to 224x224. + + Args: + inputs: a tensor of size [batch_size, height, width, channels]. + num_classes: number of predicted classes. If 0 or None, the logits layer is + omitted and the input features to the logits layer are returned instead. + is_training: whether or not the model is being trained. + dropout_keep_prob: the probability that activations are kept in the dropout + layers during training. + spatial_squeeze: whether or not should squeeze the spatial dimensions of the + outputs. Useful to remove unnecessary dimensions for classification. + scope: Optional scope for the variables. + fc_conv_padding: the type of padding to use for the fully connected layer + that is implemented as a convolutional layer. Use 'SAME' padding if you + are applying the network in a fully convolutional manner and want to + get a prediction map downsampled by a factor of 32 as an output. + Otherwise, the output prediction map will be (input / 32) - 6 in case of + 'VALID' padding. + global_pool: Optional boolean flag. If True, the input to the classification + layer is avgpooled to size 1x1, for any input size. (This is not part + of the original VGG architecture.) + + Returns: + net: the output of the logits layer (if num_classes is a non-zero integer), + or the non-dropped-out input to the logits layer (if num_classes is 0 or + None). + end_points: a dict of tensors with intermediate activations. + """ + with tf.variable_scope(scope, 'vgg_19', [inputs]) as sc: + end_points_collection = sc.original_name_scope + '_end_points' + # Collect outputs for conv2d, fully_connected and max_pool2d. + with slim.arg_scope([slim.conv2d, slim.fully_connected, slim.max_pool2d], + outputs_collections=end_points_collection): + net = slim.repeat(inputs, 2, slim.conv2d, 64, [3, 3], scope='conv1') + net = slim.max_pool2d(net, [2, 2], scope='pool1') + net = slim.repeat(net, 2, slim.conv2d, 128, [3, 3], scope='conv2') + net = slim.max_pool2d(net, [2, 2], scope='pool2') + net = slim.repeat(net, 4, slim.conv2d, 256, [3, 3], scope='conv3') + net = slim.max_pool2d(net, [2, 2], scope='pool3') + net = slim.repeat(net, 4, slim.conv2d, 512, [3, 3], scope='conv4') + net = slim.max_pool2d(net, [2, 2], scope='pool4') + net = slim.repeat(net, 4, slim.conv2d, 512, [3, 3], scope='conv5') + net = slim.max_pool2d(net, [2, 2], scope='pool5') + + # Use conv2d instead of fully_connected layers. + net = slim.conv2d(net, 4096, [7, 7], padding=fc_conv_padding, scope='fc6') + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout6') + net = slim.conv2d(net, 4096, [1, 1], scope='fc7') + # Convert end_points_collection into a end_point dict. + end_points = slim.utils.convert_collection_to_dict(end_points_collection) + if global_pool: + net = tf.reduce_mean(net, [1, 2], keep_dims=True, name='global_pool') + end_points['global_pool'] = net + if num_classes: + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout7') + net = slim.conv2d(net, num_classes, [1, 1], + activation_fn=None, + normalizer_fn=None, + scope='fc8') + if spatial_squeeze: + net = tf.squeeze(net, [1, 2], name='fc8/squeezed') + end_points[sc.name + '/fc8'] = net + return net, end_points +vgg_19.default_image_size = 224 + +# Alias +vgg_d = vgg_16 +vgg_e = vgg_19 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/vgg_test.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/vgg_test.py new file mode 100644 index 0000000..6760c36 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/nets/vgg_test.py @@ -0,0 +1,583 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for slim.nets.vgg.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from nets import vgg + +slim = tf.contrib.slim + + +class VGGATest(tf.test.TestCase): + + def testBuild(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_a(inputs, num_classes) + self.assertEquals(logits.op.name, 'vgg_a/fc8/squeezed') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + + def testFullyConvolutional(self): + batch_size = 1 + height, width = 256, 256 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_a(inputs, num_classes, spatial_squeeze=False) + self.assertEquals(logits.op.name, 'vgg_a/fc8/BiasAdd') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, 2, 2, num_classes]) + + def testGlobalPool(self): + batch_size = 1 + height, width = 256, 256 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_a(inputs, num_classes, spatial_squeeze=False, + global_pool=True) + self.assertEquals(logits.op.name, 'vgg_a/fc8/BiasAdd') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, 1, 1, num_classes]) + + def testEndPoints(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = vgg.vgg_a(inputs, num_classes) + expected_names = ['vgg_a/conv1/conv1_1', + 'vgg_a/pool1', + 'vgg_a/conv2/conv2_1', + 'vgg_a/pool2', + 'vgg_a/conv3/conv3_1', + 'vgg_a/conv3/conv3_2', + 'vgg_a/pool3', + 'vgg_a/conv4/conv4_1', + 'vgg_a/conv4/conv4_2', + 'vgg_a/pool4', + 'vgg_a/conv5/conv5_1', + 'vgg_a/conv5/conv5_2', + 'vgg_a/pool5', + 'vgg_a/fc6', + 'vgg_a/fc7', + 'vgg_a/fc8' + ] + self.assertSetEqual(set(end_points.keys()), set(expected_names)) + + def testNoClasses(self): + batch_size = 5 + height, width = 224, 224 + num_classes = None + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, end_points = vgg.vgg_a(inputs, num_classes) + expected_names = ['vgg_a/conv1/conv1_1', + 'vgg_a/pool1', + 'vgg_a/conv2/conv2_1', + 'vgg_a/pool2', + 'vgg_a/conv3/conv3_1', + 'vgg_a/conv3/conv3_2', + 'vgg_a/pool3', + 'vgg_a/conv4/conv4_1', + 'vgg_a/conv4/conv4_2', + 'vgg_a/pool4', + 'vgg_a/conv5/conv5_1', + 'vgg_a/conv5/conv5_2', + 'vgg_a/pool5', + 'vgg_a/fc6', + 'vgg_a/fc7', + ] + self.assertSetEqual(set(end_points.keys()), set(expected_names)) + self.assertTrue(net.op.name.startswith('vgg_a/fc7')) + + def testModelVariables(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + vgg.vgg_a(inputs, num_classes) + expected_names = ['vgg_a/conv1/conv1_1/weights', + 'vgg_a/conv1/conv1_1/biases', + 'vgg_a/conv2/conv2_1/weights', + 'vgg_a/conv2/conv2_1/biases', + 'vgg_a/conv3/conv3_1/weights', + 'vgg_a/conv3/conv3_1/biases', + 'vgg_a/conv3/conv3_2/weights', + 'vgg_a/conv3/conv3_2/biases', + 'vgg_a/conv4/conv4_1/weights', + 'vgg_a/conv4/conv4_1/biases', + 'vgg_a/conv4/conv4_2/weights', + 'vgg_a/conv4/conv4_2/biases', + 'vgg_a/conv5/conv5_1/weights', + 'vgg_a/conv5/conv5_1/biases', + 'vgg_a/conv5/conv5_2/weights', + 'vgg_a/conv5/conv5_2/biases', + 'vgg_a/fc6/weights', + 'vgg_a/fc6/biases', + 'vgg_a/fc7/weights', + 'vgg_a/fc7/biases', + 'vgg_a/fc8/weights', + 'vgg_a/fc8/biases', + ] + model_variables = [v.op.name for v in slim.get_model_variables()] + self.assertSetEqual(set(model_variables), set(expected_names)) + + def testEvaluation(self): + batch_size = 2 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + eval_inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_a(eval_inputs, is_training=False) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + predictions = tf.argmax(logits, 1) + self.assertListEqual(predictions.get_shape().as_list(), [batch_size]) + + def testTrainEvalWithReuse(self): + train_batch_size = 2 + eval_batch_size = 1 + train_height, train_width = 224, 224 + eval_height, eval_width = 256, 256 + num_classes = 1000 + with self.test_session(): + train_inputs = tf.random_uniform( + (train_batch_size, train_height, train_width, 3)) + logits, _ = vgg.vgg_a(train_inputs) + self.assertListEqual(logits.get_shape().as_list(), + [train_batch_size, num_classes]) + tf.get_variable_scope().reuse_variables() + eval_inputs = tf.random_uniform( + (eval_batch_size, eval_height, eval_width, 3)) + logits, _ = vgg.vgg_a(eval_inputs, is_training=False, + spatial_squeeze=False) + self.assertListEqual(logits.get_shape().as_list(), + [eval_batch_size, 2, 2, num_classes]) + logits = tf.reduce_mean(logits, [1, 2]) + predictions = tf.argmax(logits, 1) + self.assertEquals(predictions.get_shape().as_list(), [eval_batch_size]) + + def testForward(self): + batch_size = 1 + height, width = 224, 224 + with self.test_session() as sess: + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_a(inputs) + sess.run(tf.global_variables_initializer()) + output = sess.run(logits) + self.assertTrue(output.any()) + + +class VGG16Test(tf.test.TestCase): + + def testBuild(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_16(inputs, num_classes) + self.assertEquals(logits.op.name, 'vgg_16/fc8/squeezed') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + + def testFullyConvolutional(self): + batch_size = 1 + height, width = 256, 256 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_16(inputs, num_classes, spatial_squeeze=False) + self.assertEquals(logits.op.name, 'vgg_16/fc8/BiasAdd') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, 2, 2, num_classes]) + + def testGlobalPool(self): + batch_size = 1 + height, width = 256, 256 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_16(inputs, num_classes, spatial_squeeze=False, + global_pool=True) + self.assertEquals(logits.op.name, 'vgg_16/fc8/BiasAdd') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, 1, 1, num_classes]) + + def testEndPoints(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = vgg.vgg_16(inputs, num_classes) + expected_names = ['vgg_16/conv1/conv1_1', + 'vgg_16/conv1/conv1_2', + 'vgg_16/pool1', + 'vgg_16/conv2/conv2_1', + 'vgg_16/conv2/conv2_2', + 'vgg_16/pool2', + 'vgg_16/conv3/conv3_1', + 'vgg_16/conv3/conv3_2', + 'vgg_16/conv3/conv3_3', + 'vgg_16/pool3', + 'vgg_16/conv4/conv4_1', + 'vgg_16/conv4/conv4_2', + 'vgg_16/conv4/conv4_3', + 'vgg_16/pool4', + 'vgg_16/conv5/conv5_1', + 'vgg_16/conv5/conv5_2', + 'vgg_16/conv5/conv5_3', + 'vgg_16/pool5', + 'vgg_16/fc6', + 'vgg_16/fc7', + 'vgg_16/fc8' + ] + self.assertSetEqual(set(end_points.keys()), set(expected_names)) + + def testNoClasses(self): + batch_size = 5 + height, width = 224, 224 + num_classes = None + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, end_points = vgg.vgg_16(inputs, num_classes) + expected_names = ['vgg_16/conv1/conv1_1', + 'vgg_16/conv1/conv1_2', + 'vgg_16/pool1', + 'vgg_16/conv2/conv2_1', + 'vgg_16/conv2/conv2_2', + 'vgg_16/pool2', + 'vgg_16/conv3/conv3_1', + 'vgg_16/conv3/conv3_2', + 'vgg_16/conv3/conv3_3', + 'vgg_16/pool3', + 'vgg_16/conv4/conv4_1', + 'vgg_16/conv4/conv4_2', + 'vgg_16/conv4/conv4_3', + 'vgg_16/pool4', + 'vgg_16/conv5/conv5_1', + 'vgg_16/conv5/conv5_2', + 'vgg_16/conv5/conv5_3', + 'vgg_16/pool5', + 'vgg_16/fc6', + 'vgg_16/fc7', + ] + self.assertSetEqual(set(end_points.keys()), set(expected_names)) + self.assertTrue(net.op.name.startswith('vgg_16/fc7')) + + def testModelVariables(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + vgg.vgg_16(inputs, num_classes) + expected_names = ['vgg_16/conv1/conv1_1/weights', + 'vgg_16/conv1/conv1_1/biases', + 'vgg_16/conv1/conv1_2/weights', + 'vgg_16/conv1/conv1_2/biases', + 'vgg_16/conv2/conv2_1/weights', + 'vgg_16/conv2/conv2_1/biases', + 'vgg_16/conv2/conv2_2/weights', + 'vgg_16/conv2/conv2_2/biases', + 'vgg_16/conv3/conv3_1/weights', + 'vgg_16/conv3/conv3_1/biases', + 'vgg_16/conv3/conv3_2/weights', + 'vgg_16/conv3/conv3_2/biases', + 'vgg_16/conv3/conv3_3/weights', + 'vgg_16/conv3/conv3_3/biases', + 'vgg_16/conv4/conv4_1/weights', + 'vgg_16/conv4/conv4_1/biases', + 'vgg_16/conv4/conv4_2/weights', + 'vgg_16/conv4/conv4_2/biases', + 'vgg_16/conv4/conv4_3/weights', + 'vgg_16/conv4/conv4_3/biases', + 'vgg_16/conv5/conv5_1/weights', + 'vgg_16/conv5/conv5_1/biases', + 'vgg_16/conv5/conv5_2/weights', + 'vgg_16/conv5/conv5_2/biases', + 'vgg_16/conv5/conv5_3/weights', + 'vgg_16/conv5/conv5_3/biases', + 'vgg_16/fc6/weights', + 'vgg_16/fc6/biases', + 'vgg_16/fc7/weights', + 'vgg_16/fc7/biases', + 'vgg_16/fc8/weights', + 'vgg_16/fc8/biases', + ] + model_variables = [v.op.name for v in slim.get_model_variables()] + self.assertSetEqual(set(model_variables), set(expected_names)) + + def testEvaluation(self): + batch_size = 2 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + eval_inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_16(eval_inputs, is_training=False) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + predictions = tf.argmax(logits, 1) + self.assertListEqual(predictions.get_shape().as_list(), [batch_size]) + + def testTrainEvalWithReuse(self): + train_batch_size = 2 + eval_batch_size = 1 + train_height, train_width = 224, 224 + eval_height, eval_width = 256, 256 + num_classes = 1000 + with self.test_session(): + train_inputs = tf.random_uniform( + (train_batch_size, train_height, train_width, 3)) + logits, _ = vgg.vgg_16(train_inputs) + self.assertListEqual(logits.get_shape().as_list(), + [train_batch_size, num_classes]) + tf.get_variable_scope().reuse_variables() + eval_inputs = tf.random_uniform( + (eval_batch_size, eval_height, eval_width, 3)) + logits, _ = vgg.vgg_16(eval_inputs, is_training=False, + spatial_squeeze=False) + self.assertListEqual(logits.get_shape().as_list(), + [eval_batch_size, 2, 2, num_classes]) + logits = tf.reduce_mean(logits, [1, 2]) + predictions = tf.argmax(logits, 1) + self.assertEquals(predictions.get_shape().as_list(), [eval_batch_size]) + + def testForward(self): + batch_size = 1 + height, width = 224, 224 + with self.test_session() as sess: + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_16(inputs) + sess.run(tf.global_variables_initializer()) + output = sess.run(logits) + self.assertTrue(output.any()) + + +class VGG19Test(tf.test.TestCase): + + def testBuild(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_19(inputs, num_classes) + self.assertEquals(logits.op.name, 'vgg_19/fc8/squeezed') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + + def testFullyConvolutional(self): + batch_size = 1 + height, width = 256, 256 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_19(inputs, num_classes, spatial_squeeze=False) + self.assertEquals(logits.op.name, 'vgg_19/fc8/BiasAdd') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, 2, 2, num_classes]) + + def testGlobalPool(self): + batch_size = 1 + height, width = 256, 256 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_19(inputs, num_classes, spatial_squeeze=False, + global_pool=True) + self.assertEquals(logits.op.name, 'vgg_19/fc8/BiasAdd') + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, 1, 1, num_classes]) + + def testEndPoints(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + _, end_points = vgg.vgg_19(inputs, num_classes) + expected_names = [ + 'vgg_19/conv1/conv1_1', + 'vgg_19/conv1/conv1_2', + 'vgg_19/pool1', + 'vgg_19/conv2/conv2_1', + 'vgg_19/conv2/conv2_2', + 'vgg_19/pool2', + 'vgg_19/conv3/conv3_1', + 'vgg_19/conv3/conv3_2', + 'vgg_19/conv3/conv3_3', + 'vgg_19/conv3/conv3_4', + 'vgg_19/pool3', + 'vgg_19/conv4/conv4_1', + 'vgg_19/conv4/conv4_2', + 'vgg_19/conv4/conv4_3', + 'vgg_19/conv4/conv4_4', + 'vgg_19/pool4', + 'vgg_19/conv5/conv5_1', + 'vgg_19/conv5/conv5_2', + 'vgg_19/conv5/conv5_3', + 'vgg_19/conv5/conv5_4', + 'vgg_19/pool5', + 'vgg_19/fc6', + 'vgg_19/fc7', + 'vgg_19/fc8' + ] + self.assertSetEqual(set(end_points.keys()), set(expected_names)) + + def testNoClasses(self): + batch_size = 5 + height, width = 224, 224 + num_classes = None + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + net, end_points = vgg.vgg_19(inputs, num_classes) + expected_names = [ + 'vgg_19/conv1/conv1_1', + 'vgg_19/conv1/conv1_2', + 'vgg_19/pool1', + 'vgg_19/conv2/conv2_1', + 'vgg_19/conv2/conv2_2', + 'vgg_19/pool2', + 'vgg_19/conv3/conv3_1', + 'vgg_19/conv3/conv3_2', + 'vgg_19/conv3/conv3_3', + 'vgg_19/conv3/conv3_4', + 'vgg_19/pool3', + 'vgg_19/conv4/conv4_1', + 'vgg_19/conv4/conv4_2', + 'vgg_19/conv4/conv4_3', + 'vgg_19/conv4/conv4_4', + 'vgg_19/pool4', + 'vgg_19/conv5/conv5_1', + 'vgg_19/conv5/conv5_2', + 'vgg_19/conv5/conv5_3', + 'vgg_19/conv5/conv5_4', + 'vgg_19/pool5', + 'vgg_19/fc6', + 'vgg_19/fc7', + ] + self.assertSetEqual(set(end_points.keys()), set(expected_names)) + self.assertTrue(net.op.name.startswith('vgg_19/fc7')) + + def testModelVariables(self): + batch_size = 5 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + inputs = tf.random_uniform((batch_size, height, width, 3)) + vgg.vgg_19(inputs, num_classes) + expected_names = [ + 'vgg_19/conv1/conv1_1/weights', + 'vgg_19/conv1/conv1_1/biases', + 'vgg_19/conv1/conv1_2/weights', + 'vgg_19/conv1/conv1_2/biases', + 'vgg_19/conv2/conv2_1/weights', + 'vgg_19/conv2/conv2_1/biases', + 'vgg_19/conv2/conv2_2/weights', + 'vgg_19/conv2/conv2_2/biases', + 'vgg_19/conv3/conv3_1/weights', + 'vgg_19/conv3/conv3_1/biases', + 'vgg_19/conv3/conv3_2/weights', + 'vgg_19/conv3/conv3_2/biases', + 'vgg_19/conv3/conv3_3/weights', + 'vgg_19/conv3/conv3_3/biases', + 'vgg_19/conv3/conv3_4/weights', + 'vgg_19/conv3/conv3_4/biases', + 'vgg_19/conv4/conv4_1/weights', + 'vgg_19/conv4/conv4_1/biases', + 'vgg_19/conv4/conv4_2/weights', + 'vgg_19/conv4/conv4_2/biases', + 'vgg_19/conv4/conv4_3/weights', + 'vgg_19/conv4/conv4_3/biases', + 'vgg_19/conv4/conv4_4/weights', + 'vgg_19/conv4/conv4_4/biases', + 'vgg_19/conv5/conv5_1/weights', + 'vgg_19/conv5/conv5_1/biases', + 'vgg_19/conv5/conv5_2/weights', + 'vgg_19/conv5/conv5_2/biases', + 'vgg_19/conv5/conv5_3/weights', + 'vgg_19/conv5/conv5_3/biases', + 'vgg_19/conv5/conv5_4/weights', + 'vgg_19/conv5/conv5_4/biases', + 'vgg_19/fc6/weights', + 'vgg_19/fc6/biases', + 'vgg_19/fc7/weights', + 'vgg_19/fc7/biases', + 'vgg_19/fc8/weights', + 'vgg_19/fc8/biases', + ] + model_variables = [v.op.name for v in slim.get_model_variables()] + self.assertSetEqual(set(model_variables), set(expected_names)) + + def testEvaluation(self): + batch_size = 2 + height, width = 224, 224 + num_classes = 1000 + with self.test_session(): + eval_inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_19(eval_inputs, is_training=False) + self.assertListEqual(logits.get_shape().as_list(), + [batch_size, num_classes]) + predictions = tf.argmax(logits, 1) + self.assertListEqual(predictions.get_shape().as_list(), [batch_size]) + + def testTrainEvalWithReuse(self): + train_batch_size = 2 + eval_batch_size = 1 + train_height, train_width = 224, 224 + eval_height, eval_width = 256, 256 + num_classes = 1000 + with self.test_session(): + train_inputs = tf.random_uniform( + (train_batch_size, train_height, train_width, 3)) + logits, _ = vgg.vgg_19(train_inputs) + self.assertListEqual(logits.get_shape().as_list(), + [train_batch_size, num_classes]) + tf.get_variable_scope().reuse_variables() + eval_inputs = tf.random_uniform( + (eval_batch_size, eval_height, eval_width, 3)) + logits, _ = vgg.vgg_19(eval_inputs, is_training=False, + spatial_squeeze=False) + self.assertListEqual(logits.get_shape().as_list(), + [eval_batch_size, 2, 2, num_classes]) + logits = tf.reduce_mean(logits, [1, 2]) + predictions = tf.argmax(logits, 1) + self.assertEquals(predictions.get_shape().as_list(), [eval_batch_size]) + + def testForward(self): + batch_size = 1 + height, width = 224, 224 + with self.test_session() as sess: + inputs = tf.random_uniform((batch_size, height, width, 3)) + logits, _ = vgg.vgg_19(inputs) + sess.run(tf.global_variables_initializer()) + output = sess.run(logits) + self.assertTrue(output.any()) + +if __name__ == '__main__': + tf.test.main() diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/__init__.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/__init__.py @@ -0,0 +1 @@ + diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/cifarnet_preprocessing.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/cifarnet_preprocessing.py new file mode 100644 index 0000000..0b5a88f --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/cifarnet_preprocessing.py @@ -0,0 +1,128 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Provides utilities to preprocess images in CIFAR-10. + +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +_PADDING = 4 + +slim = tf.contrib.slim + + +def preprocess_for_train(image, + output_height, + output_width, + padding=_PADDING, + add_image_summaries=True): + """Preprocesses the given image for training. + + Note that the actual resizing scale is sampled from + [`resize_size_min`, `resize_size_max`]. + + Args: + image: A `Tensor` representing an image of arbitrary size. + output_height: The height of the image after preprocessing. + output_width: The width of the image after preprocessing. + padding: The amound of padding before and after each dimension of the image. + add_image_summaries: Enable image summaries. + + Returns: + A preprocessed image. + """ + if add_image_summaries: + tf.summary.image('image', tf.expand_dims(image, 0)) + + # Transform the image to floats. + image = tf.to_float(image) + if padding > 0: + image = tf.pad(image, [[padding, padding], [padding, padding], [0, 0]]) + # Randomly crop a [height, width] section of the image. + distorted_image = tf.random_crop(image, + [output_height, output_width, 3]) + + # Randomly flip the image horizontally. + distorted_image = tf.image.random_flip_left_right(distorted_image) + + if add_image_summaries: + tf.summary.image('distorted_image', tf.expand_dims(distorted_image, 0)) + + # Because these operations are not commutative, consider randomizing + # the order their operation. + distorted_image = tf.image.random_brightness(distorted_image, + max_delta=63) + distorted_image = tf.image.random_contrast(distorted_image, + lower=0.2, upper=1.8) + # Subtract off the mean and divide by the variance of the pixels. + return tf.image.per_image_standardization(distorted_image) + + +def preprocess_for_eval(image, output_height, output_width, + add_image_summaries=True): + """Preprocesses the given image for evaluation. + + Args: + image: A `Tensor` representing an image of arbitrary size. + output_height: The height of the image after preprocessing. + output_width: The width of the image after preprocessing. + add_image_summaries: Enable image summaries. + + Returns: + A preprocessed image. + """ + if add_image_summaries: + tf.summary.image('image', tf.expand_dims(image, 0)) + # Transform the image to floats. + image = tf.to_float(image) + + # Resize and crop if needed. + resized_image = tf.image.resize_image_with_crop_or_pad(image, + output_width, + output_height) + if add_image_summaries: + tf.summary.image('resized_image', tf.expand_dims(resized_image, 0)) + + # Subtract off the mean and divide by the variance of the pixels. + return tf.image.per_image_standardization(resized_image) + + +def preprocess_image(image, output_height, output_width, is_training=False, + add_image_summaries=True): + """Preprocesses the given image. + + Args: + image: A `Tensor` representing an image of arbitrary size. + output_height: The height of the image after preprocessing. + output_width: The width of the image after preprocessing. + is_training: `True` if we're preprocessing the image for training and + `False` otherwise. + add_image_summaries: Enable image summaries. + + Returns: + A preprocessed image. + """ + if is_training: + return preprocess_for_train( + image, output_height, output_width, + add_image_summaries=add_image_summaries) + else: + return preprocess_for_eval( + image, output_height, output_width, + add_image_summaries=add_image_summaries) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/inception_preprocessing.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/inception_preprocessing.py new file mode 100644 index 0000000..846b81b --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/inception_preprocessing.py @@ -0,0 +1,318 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Provides utilities to preprocess images for the Inception networks.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from tensorflow.python.ops import control_flow_ops + + +def apply_with_random_selector(x, func, num_cases): + """Computes func(x, sel), with sel sampled from [0...num_cases-1]. + + Args: + x: input Tensor. + func: Python function to apply. + num_cases: Python int32, number of cases to sample sel from. + + Returns: + The result of func(x, sel), where func receives the value of the + selector as a python integer, but sel is sampled dynamically. + """ + sel = tf.random_uniform([], maxval=num_cases, dtype=tf.int32) + # Pass the real x only to one of the func calls. + return control_flow_ops.merge([ + func(control_flow_ops.switch(x, tf.equal(sel, case))[1], case) + for case in range(num_cases)])[0] + + +def distort_color(image, color_ordering=0, fast_mode=True, scope=None): + """Distort the color of a Tensor image. + + Each color distortion is non-commutative and thus ordering of the color ops + matters. Ideally we would randomly permute the ordering of the color ops. + Rather then adding that level of complication, we select a distinct ordering + of color ops for each preprocessing thread. + + Args: + image: 3-D Tensor containing single image in [0, 1]. + color_ordering: Python int, a type of distortion (valid values: 0-3). + fast_mode: Avoids slower ops (random_hue and random_contrast) + scope: Optional scope for name_scope. + Returns: + 3-D Tensor color-distorted image on range [0, 1] + Raises: + ValueError: if color_ordering not in [0, 3] + """ + with tf.name_scope(scope, 'distort_color', [image]): + if fast_mode: + if color_ordering == 0: + image = tf.image.random_brightness(image, max_delta=32. / 255.) + image = tf.image.random_saturation(image, lower=0.5, upper=1.5) + else: + image = tf.image.random_saturation(image, lower=0.5, upper=1.5) + image = tf.image.random_brightness(image, max_delta=32. / 255.) + else: + if color_ordering == 0: + image = tf.image.random_brightness(image, max_delta=32. / 255.) + image = tf.image.random_saturation(image, lower=0.5, upper=1.5) + image = tf.image.random_hue(image, max_delta=0.2) + image = tf.image.random_contrast(image, lower=0.5, upper=1.5) + elif color_ordering == 1: + image = tf.image.random_saturation(image, lower=0.5, upper=1.5) + image = tf.image.random_brightness(image, max_delta=32. / 255.) + image = tf.image.random_contrast(image, lower=0.5, upper=1.5) + image = tf.image.random_hue(image, max_delta=0.2) + elif color_ordering == 2: + image = tf.image.random_contrast(image, lower=0.5, upper=1.5) + image = tf.image.random_hue(image, max_delta=0.2) + image = tf.image.random_brightness(image, max_delta=32. / 255.) + image = tf.image.random_saturation(image, lower=0.5, upper=1.5) + elif color_ordering == 3: + image = tf.image.random_hue(image, max_delta=0.2) + image = tf.image.random_saturation(image, lower=0.5, upper=1.5) + image = tf.image.random_contrast(image, lower=0.5, upper=1.5) + image = tf.image.random_brightness(image, max_delta=32. / 255.) + else: + raise ValueError('color_ordering must be in [0, 3]') + + # The random_* ops do not necessarily clamp. + return tf.clip_by_value(image, 0.0, 1.0) + + +def distorted_bounding_box_crop(image, + bbox, + min_object_covered=0.1, + aspect_ratio_range=(0.75, 1.33), + area_range=(0.05, 1.0), + max_attempts=100, + scope=None): + """Generates cropped_image using a one of the bboxes randomly distorted. + + See `tf.image.sample_distorted_bounding_box` for more documentation. + + Args: + image: 3-D Tensor of image (it will be converted to floats in [0, 1]). + bbox: 3-D float Tensor of bounding boxes arranged [1, num_boxes, coords] + where each coordinate is [0, 1) and the coordinates are arranged + as [ymin, xmin, ymax, xmax]. If num_boxes is 0 then it would use the whole + image. + min_object_covered: An optional `float`. Defaults to `0.1`. The cropped + area of the image must contain at least this fraction of any bounding box + supplied. + aspect_ratio_range: An optional list of `floats`. The cropped area of the + image must have an aspect ratio = width / height within this range. + area_range: An optional list of `floats`. The cropped area of the image + must contain a fraction of the supplied image within in this range. + max_attempts: An optional `int`. Number of attempts at generating a cropped + region of the image of the specified constraints. After `max_attempts` + failures, return the entire image. + scope: Optional scope for name_scope. + Returns: + A tuple, a 3-D Tensor cropped_image and the distorted bbox + """ + with tf.name_scope(scope, 'distorted_bounding_box_crop', [image, bbox]): + # Each bounding box has shape [1, num_boxes, box coords] and + # the coordinates are ordered [ymin, xmin, ymax, xmax]. + + # A large fraction of image datasets contain a human-annotated bounding + # box delineating the region of the image containing the object of interest. + # We choose to create a new bounding box for the object which is a randomly + # distorted version of the human-annotated bounding box that obeys an + # allowed range of aspect ratios, sizes and overlap with the human-annotated + # bounding box. If no box is supplied, then we assume the bounding box is + # the entire image. + sample_distorted_bounding_box = tf.image.sample_distorted_bounding_box( + tf.shape(image), + bounding_boxes=bbox, + min_object_covered=min_object_covered, + aspect_ratio_range=aspect_ratio_range, + area_range=area_range, + max_attempts=max_attempts, + use_image_if_no_bounding_boxes=True) + bbox_begin, bbox_size, distort_bbox = sample_distorted_bounding_box + + # Crop the image to the specified bounding box. + cropped_image = tf.slice(image, bbox_begin, bbox_size) + return cropped_image, distort_bbox + + +def preprocess_for_train(image, height, width, bbox, + fast_mode=True, + scope=None, + add_image_summaries=True): + """Distort one image for training a network. + + Distorting images provides a useful technique for augmenting the data + set during training in order to make the network invariant to aspects + of the image that do not effect the label. + + Additionally it would create image_summaries to display the different + transformations applied to the image. + + Args: + image: 3-D Tensor of image. If dtype is tf.float32 then the range should be + [0, 1], otherwise it would converted to tf.float32 assuming that the range + is [0, MAX], where MAX is largest positive representable number for + int(8/16/32) data type (see `tf.image.convert_image_dtype` for details). + height: integer + width: integer + bbox: 3-D float Tensor of bounding boxes arranged [1, num_boxes, coords] + where each coordinate is [0, 1) and the coordinates are arranged + as [ymin, xmin, ymax, xmax]. + fast_mode: Optional boolean, if True avoids slower transformations (i.e. + bi-cubic resizing, random_hue or random_contrast). + scope: Optional scope for name_scope. + add_image_summaries: Enable image summaries. + Returns: + 3-D float Tensor of distorted image used for training with range [-1, 1]. + """ + with tf.name_scope(scope, 'distort_image', [image, height, width, bbox]): + if bbox is None: + bbox = tf.constant([0.0, 0.0, 1.0, 1.0], + dtype=tf.float32, + shape=[1, 1, 4]) + if image.dtype != tf.float32: + image = tf.image.convert_image_dtype(image, dtype=tf.float32) + # Each bounding box has shape [1, num_boxes, box coords] and + # the coordinates are ordered [ymin, xmin, ymax, xmax]. + image_with_box = tf.image.draw_bounding_boxes(tf.expand_dims(image, 0), + bbox) + if add_image_summaries: + tf.summary.image('image_with_bounding_boxes', image_with_box) + + distorted_image, distorted_bbox = distorted_bounding_box_crop(image, bbox) + # Restore the shape since the dynamic slice based upon the bbox_size loses + # the third dimension. + distorted_image.set_shape([None, None, 3]) + image_with_distorted_box = tf.image.draw_bounding_boxes( + tf.expand_dims(image, 0), distorted_bbox) + if add_image_summaries: + tf.summary.image('images_with_distorted_bounding_box', + image_with_distorted_box) + + # This resizing operation may distort the images because the aspect + # ratio is not respected. We select a resize method in a round robin + # fashion based on the thread number. + # Note that ResizeMethod contains 4 enumerated resizing methods. + + # We select only 1 case for fast_mode bilinear. + num_resize_cases = 1 if fast_mode else 4 + distorted_image = apply_with_random_selector( + distorted_image, + lambda x, method: tf.image.resize_images(x, [height, width], method), + num_cases=num_resize_cases) + + if add_image_summaries: + tf.summary.image('cropped_resized_image', + tf.expand_dims(distorted_image, 0)) + + # Randomly flip the image horizontally. + distorted_image = tf.image.random_flip_left_right(distorted_image) + + # Randomly distort the colors. There are 1 or 4 ways to do it. + num_distort_cases = 1 if fast_mode else 4 + distorted_image = apply_with_random_selector( + distorted_image, + lambda x, ordering: distort_color(x, ordering, fast_mode), + num_cases=num_distort_cases) + + if add_image_summaries: + tf.summary.image('final_distorted_image', + tf.expand_dims(distorted_image, 0)) + distorted_image = tf.subtract(distorted_image, 0.5) + distorted_image = tf.multiply(distorted_image, 2.0) + return distorted_image + + +def preprocess_for_eval(image, height, width, + central_fraction=0.875, scope=None): + """Prepare one image for evaluation. + + If height and width are specified it would output an image with that size by + applying resize_bilinear. + + If central_fraction is specified it would crop the central fraction of the + input image. + + Args: + image: 3-D Tensor of image. If dtype is tf.float32 then the range should be + [0, 1], otherwise it would converted to tf.float32 assuming that the range + is [0, MAX], where MAX is largest positive representable number for + int(8/16/32) data type (see `tf.image.convert_image_dtype` for details). + height: integer + width: integer + central_fraction: Optional Float, fraction of the image to crop. + scope: Optional scope for name_scope. + Returns: + 3-D float Tensor of prepared image. + """ + with tf.name_scope(scope, 'eval_image', [image, height, width]): + if image.dtype != tf.float32: + image = tf.image.convert_image_dtype(image, dtype=tf.float32) + # Crop the central region of the image with an area containing 87.5% of + # the original image. + if central_fraction: + image = tf.image.central_crop(image, central_fraction=central_fraction) + + if height and width: + # Resize the image to the specified height and width. + image = tf.expand_dims(image, 0) + image = tf.image.resize_bilinear(image, [height, width], + align_corners=False) + image = tf.squeeze(image, [0]) + image = tf.subtract(image, 0.5) + image = tf.multiply(image, 2.0) + return image + + +def preprocess_image(image, height, width, + is_training=False, + bbox=None, + fast_mode=True, + add_image_summaries=True): + """Pre-process one image for training or evaluation. + + Args: + image: 3-D Tensor [height, width, channels] with the image. If dtype is + tf.float32 then the range should be [0, 1], otherwise it would converted + to tf.float32 assuming that the range is [0, MAX], where MAX is largest + positive representable number for int(8/16/32) data type (see + `tf.image.convert_image_dtype` for details). + height: integer, image expected height. + width: integer, image expected width. + is_training: Boolean. If true it would transform an image for train, + otherwise it would transform it for evaluation. + bbox: 3-D float Tensor of bounding boxes arranged [1, num_boxes, coords] + where each coordinate is [0, 1) and the coordinates are arranged as + [ymin, xmin, ymax, xmax]. + fast_mode: Optional boolean, if True avoids slower transformations. + add_image_summaries: Enable image summaries. + + Returns: + 3-D float Tensor containing an appropriately scaled image + + Raises: + ValueError: if user does not provide bounding box + """ + if is_training: + return preprocess_for_train(image, height, width, bbox, fast_mode, + add_image_summaries=add_image_summaries) + else: + return preprocess_for_eval(image, height, width) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/lenet_preprocessing.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/lenet_preprocessing.py new file mode 100644 index 0000000..ac5e71a --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/lenet_preprocessing.py @@ -0,0 +1,44 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Provides utilities for preprocessing.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +slim = tf.contrib.slim + + +def preprocess_image(image, output_height, output_width, is_training): + """Preprocesses the given image. + + Args: + image: A `Tensor` representing an image of arbitrary size. + output_height: The height of the image after preprocessing. + output_width: The width of the image after preprocessing. + is_training: `True` if we're preprocessing the image for training and + `False` otherwise. + + Returns: + A preprocessed image. + """ + image = tf.to_float(image) + image = tf.image.resize_image_with_crop_or_pad( + image, output_width, output_height) + image = tf.subtract(image, 128.0) + image = tf.div(image, 128.0) + return image diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/preprocessing_factory.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/preprocessing_factory.py new file mode 100644 index 0000000..a805e92 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/preprocessing_factory.py @@ -0,0 +1,85 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains a factory for building various models.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from preprocessing import cifarnet_preprocessing +from preprocessing import inception_preprocessing +from preprocessing import lenet_preprocessing +from preprocessing import vgg_preprocessing + +slim = tf.contrib.slim + + +def get_preprocessing(name, is_training=False): + """Returns preprocessing_fn(image, height, width, **kwargs). + + Args: + name: The name of the preprocessing function. + is_training: `True` if the model is being used for training and `False` + otherwise. + + Returns: + preprocessing_fn: A function that preprocessing a single image (pre-batch). + It has the following signature: + image = preprocessing_fn(image, output_height, output_width, ...). + + Raises: + ValueError: If Preprocessing `name` is not recognized. + """ + preprocessing_fn_map = { + 'cifarnet': cifarnet_preprocessing, + 'inception': inception_preprocessing, + 'inception_v1': inception_preprocessing, + 'inception_v2': inception_preprocessing, + 'inception_v3': inception_preprocessing, + 'inception_v4': inception_preprocessing, + 'inception_resnet_v2': inception_preprocessing, + 'lenet': lenet_preprocessing, + 'mobilenet_v1': inception_preprocessing, + 'mobilenet_v2': inception_preprocessing, + 'mobilenet_v2_035': inception_preprocessing, + 'mobilenet_v2_140': inception_preprocessing, + 'nasnet_mobile': inception_preprocessing, + 'nasnet_large': inception_preprocessing, + 'pnasnet_mobile': inception_preprocessing, + 'pnasnet_large': inception_preprocessing, + 'resnet_v1_50': vgg_preprocessing, + 'resnet_v1_101': vgg_preprocessing, + 'resnet_v1_152': vgg_preprocessing, + 'resnet_v1_200': vgg_preprocessing, + 'resnet_v2_50': vgg_preprocessing, + 'resnet_v2_101': vgg_preprocessing, + 'resnet_v2_152': vgg_preprocessing, + 'resnet_v2_200': vgg_preprocessing, + 'vgg': vgg_preprocessing, + 'vgg_a': vgg_preprocessing, + 'vgg_16': vgg_preprocessing, + 'vgg_19': vgg_preprocessing, + } + + if name not in preprocessing_fn_map: + raise ValueError('Preprocessing name [%s] was not recognized' % name) + + def preprocessing_fn(image, output_height, output_width, **kwargs): + return preprocessing_fn_map[name].preprocess_image( + image, output_height, output_width, is_training=is_training, **kwargs) + + return preprocessing_fn diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/vgg_preprocessing.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/vgg_preprocessing.py new file mode 100644 index 0000000..3bd5059 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/preprocessing/vgg_preprocessing.py @@ -0,0 +1,365 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Provides utilities to preprocess images. + +The preprocessing steps for VGG were introduced in the following technical +report: + + Very Deep Convolutional Networks For Large-Scale Image Recognition + Karen Simonyan and Andrew Zisserman + arXiv technical report, 2015 + PDF: http://arxiv.org/pdf/1409.1556.pdf + ILSVRC 2014 Slides: http://www.robots.ox.ac.uk/~karen/pdf/ILSVRC_2014.pdf + CC-BY-4.0 + +More information can be obtained from the VGG website: +www.robots.ox.ac.uk/~vgg/research/very_deep/ +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +slim = tf.contrib.slim + +_R_MEAN = 123.68 +_G_MEAN = 116.78 +_B_MEAN = 103.94 + +_RESIZE_SIDE_MIN = 256 +_RESIZE_SIDE_MAX = 512 + + +def _crop(image, offset_height, offset_width, crop_height, crop_width): + """Crops the given image using the provided offsets and sizes. + + Note that the method doesn't assume we know the input image size but it does + assume we know the input image rank. + + Args: + image: an image of shape [height, width, channels]. + offset_height: a scalar tensor indicating the height offset. + offset_width: a scalar tensor indicating the width offset. + crop_height: the height of the cropped image. + crop_width: the width of the cropped image. + + Returns: + the cropped (and resized) image. + + Raises: + InvalidArgumentError: if the rank is not 3 or if the image dimensions are + less than the crop size. + """ + original_shape = tf.shape(image) + + rank_assertion = tf.Assert( + tf.equal(tf.rank(image), 3), + ['Rank of image must be equal to 3.']) + with tf.control_dependencies([rank_assertion]): + cropped_shape = tf.stack([crop_height, crop_width, original_shape[2]]) + + size_assertion = tf.Assert( + tf.logical_and( + tf.greater_equal(original_shape[0], crop_height), + tf.greater_equal(original_shape[1], crop_width)), + ['Crop size greater than the image size.']) + + offsets = tf.to_int32(tf.stack([offset_height, offset_width, 0])) + + # Use tf.slice instead of crop_to_bounding box as it accepts tensors to + # define the crop size. + with tf.control_dependencies([size_assertion]): + image = tf.slice(image, offsets, cropped_shape) + return tf.reshape(image, cropped_shape) + + +def _random_crop(image_list, crop_height, crop_width): + """Crops the given list of images. + + The function applies the same crop to each image in the list. This can be + effectively applied when there are multiple image inputs of the same + dimension such as: + + image, depths, normals = _random_crop([image, depths, normals], 120, 150) + + Args: + image_list: a list of image tensors of the same dimension but possibly + varying channel. + crop_height: the new height. + crop_width: the new width. + + Returns: + the image_list with cropped images. + + Raises: + ValueError: if there are multiple image inputs provided with different size + or the images are smaller than the crop dimensions. + """ + if not image_list: + raise ValueError('Empty image_list.') + + # Compute the rank assertions. + rank_assertions = [] + for i in range(len(image_list)): + image_rank = tf.rank(image_list[i]) + rank_assert = tf.Assert( + tf.equal(image_rank, 3), + ['Wrong rank for tensor %s [expected] [actual]', + image_list[i].name, 3, image_rank]) + rank_assertions.append(rank_assert) + + with tf.control_dependencies([rank_assertions[0]]): + image_shape = tf.shape(image_list[0]) + image_height = image_shape[0] + image_width = image_shape[1] + crop_size_assert = tf.Assert( + tf.logical_and( + tf.greater_equal(image_height, crop_height), + tf.greater_equal(image_width, crop_width)), + ['Crop size greater than the image size.']) + + asserts = [rank_assertions[0], crop_size_assert] + + for i in range(1, len(image_list)): + image = image_list[i] + asserts.append(rank_assertions[i]) + with tf.control_dependencies([rank_assertions[i]]): + shape = tf.shape(image) + height = shape[0] + width = shape[1] + + height_assert = tf.Assert( + tf.equal(height, image_height), + ['Wrong height for tensor %s [expected][actual]', + image.name, height, image_height]) + width_assert = tf.Assert( + tf.equal(width, image_width), + ['Wrong width for tensor %s [expected][actual]', + image.name, width, image_width]) + asserts.extend([height_assert, width_assert]) + + # Create a random bounding box. + # + # Use tf.random_uniform and not numpy.random.rand as doing the former would + # generate random numbers at graph eval time, unlike the latter which + # generates random numbers at graph definition time. + with tf.control_dependencies(asserts): + max_offset_height = tf.reshape(image_height - crop_height + 1, []) + with tf.control_dependencies(asserts): + max_offset_width = tf.reshape(image_width - crop_width + 1, []) + offset_height = tf.random_uniform( + [], maxval=max_offset_height, dtype=tf.int32) + offset_width = tf.random_uniform( + [], maxval=max_offset_width, dtype=tf.int32) + + return [_crop(image, offset_height, offset_width, + crop_height, crop_width) for image in image_list] + + +def _central_crop(image_list, crop_height, crop_width): + """Performs central crops of the given image list. + + Args: + image_list: a list of image tensors of the same dimension but possibly + varying channel. + crop_height: the height of the image following the crop. + crop_width: the width of the image following the crop. + + Returns: + the list of cropped images. + """ + outputs = [] + for image in image_list: + image_height = tf.shape(image)[0] + image_width = tf.shape(image)[1] + + offset_height = (image_height - crop_height) / 2 + offset_width = (image_width - crop_width) / 2 + + outputs.append(_crop(image, offset_height, offset_width, + crop_height, crop_width)) + return outputs + + +def _mean_image_subtraction(image, means): + """Subtracts the given means from each image channel. + + For example: + means = [123.68, 116.779, 103.939] + image = _mean_image_subtraction(image, means) + + Note that the rank of `image` must be known. + + Args: + image: a tensor of size [height, width, C]. + means: a C-vector of values to subtract from each channel. + + Returns: + the centered image. + + Raises: + ValueError: If the rank of `image` is unknown, if `image` has a rank other + than three or if the number of channels in `image` doesn't match the + number of values in `means`. + """ + if image.get_shape().ndims != 3: + raise ValueError('Input must be of size [height, width, C>0]') + num_channels = image.get_shape().as_list()[-1] + if len(means) != num_channels: + raise ValueError('len(means) must match the number of channels') + + channels = tf.split(axis=2, num_or_size_splits=num_channels, value=image) + for i in range(num_channels): + channels[i] -= means[i] + return tf.concat(axis=2, values=channels) + + +def _smallest_size_at_least(height, width, smallest_side): + """Computes new shape with the smallest side equal to `smallest_side`. + + Computes new shape with the smallest side equal to `smallest_side` while + preserving the original aspect ratio. + + Args: + height: an int32 scalar tensor indicating the current height. + width: an int32 scalar tensor indicating the current width. + smallest_side: A python integer or scalar `Tensor` indicating the size of + the smallest side after resize. + + Returns: + new_height: an int32 scalar tensor indicating the new height. + new_width: and int32 scalar tensor indicating the new width. + """ + smallest_side = tf.convert_to_tensor(smallest_side, dtype=tf.int32) + + height = tf.to_float(height) + width = tf.to_float(width) + smallest_side = tf.to_float(smallest_side) + + scale = tf.cond(tf.greater(height, width), + lambda: smallest_side / width, + lambda: smallest_side / height) + new_height = tf.to_int32(tf.rint(height * scale)) + new_width = tf.to_int32(tf.rint(width * scale)) + return new_height, new_width + + +def _aspect_preserving_resize(image, smallest_side): + """Resize images preserving the original aspect ratio. + + Args: + image: A 3-D image `Tensor`. + smallest_side: A python integer or scalar `Tensor` indicating the size of + the smallest side after resize. + + Returns: + resized_image: A 3-D tensor containing the resized image. + """ + smallest_side = tf.convert_to_tensor(smallest_side, dtype=tf.int32) + + shape = tf.shape(image) + height = shape[0] + width = shape[1] + new_height, new_width = _smallest_size_at_least(height, width, smallest_side) + image = tf.expand_dims(image, 0) + resized_image = tf.image.resize_bilinear(image, [new_height, new_width], + align_corners=False) + resized_image = tf.squeeze(resized_image) + resized_image.set_shape([None, None, 3]) + return resized_image + + +def preprocess_for_train(image, + output_height, + output_width, + resize_side_min=_RESIZE_SIDE_MIN, + resize_side_max=_RESIZE_SIDE_MAX): + """Preprocesses the given image for training. + + Note that the actual resizing scale is sampled from + [`resize_size_min`, `resize_size_max`]. + + Args: + image: A `Tensor` representing an image of arbitrary size. + output_height: The height of the image after preprocessing. + output_width: The width of the image after preprocessing. + resize_side_min: The lower bound for the smallest side of the image for + aspect-preserving resizing. + resize_side_max: The upper bound for the smallest side of the image for + aspect-preserving resizing. + + Returns: + A preprocessed image. + """ + resize_side = tf.random_uniform( + [], minval=resize_side_min, maxval=resize_side_max+1, dtype=tf.int32) + + image = _aspect_preserving_resize(image, resize_side) + image = _random_crop([image], output_height, output_width)[0] + image.set_shape([output_height, output_width, 3]) + image = tf.to_float(image) + image = tf.image.random_flip_left_right(image) + return _mean_image_subtraction(image, [_R_MEAN, _G_MEAN, _B_MEAN]) + + +def preprocess_for_eval(image, output_height, output_width, resize_side): + """Preprocesses the given image for evaluation. + + Args: + image: A `Tensor` representing an image of arbitrary size. + output_height: The height of the image after preprocessing. + output_width: The width of the image after preprocessing. + resize_side: The smallest side of the image for aspect-preserving resizing. + + Returns: + A preprocessed image. + """ + image = _aspect_preserving_resize(image, resize_side) + image = _central_crop([image], output_height, output_width)[0] + image.set_shape([output_height, output_width, 3]) + image = tf.to_float(image) + return _mean_image_subtraction(image, [_R_MEAN, _G_MEAN, _B_MEAN]) + + +def preprocess_image(image, output_height, output_width, is_training=False, + resize_side_min=_RESIZE_SIDE_MIN, + resize_side_max=_RESIZE_SIDE_MAX): + """Preprocesses the given image. + + Args: + image: A `Tensor` representing an image of arbitrary size. + output_height: The height of the image after preprocessing. + output_width: The width of the image after preprocessing. + is_training: `True` if we're preprocessing the image for training and + `False` otherwise. + resize_side_min: The lower bound for the smallest side of the image for + aspect-preserving resizing. If `is_training` is `False`, then this value + is used for rescaling. + resize_side_max: The upper bound for the smallest side of the image for + aspect-preserving resizing. If `is_training` is `False`, this value is + ignored. Otherwise, the resize side is sampled from + [resize_size_min, resize_size_max]. + + Returns: + A preprocessed image. + """ + if is_training: + return preprocess_for_train(image, output_height, output_width, + resize_side_min, resize_side_max) + else: + return preprocess_for_eval(image, output_height, output_width, + resize_side_min) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/export_mobilenet.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/export_mobilenet.sh new file mode 100755 index 0000000..bddabe1 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/export_mobilenet.sh @@ -0,0 +1,132 @@ +#!/bin/bash +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +# This script prepares the various different versions of MobileNet models for +# use in a mobile application. If you don't specify your own trained checkpoint +# file, it will download pretrained checkpoints for ImageNet. You'll also need +# to have a copy of the TensorFlow source code to run some of the commands, +# by default it will be looked for in ./tensorflow, but you can set the +# TENSORFLOW_PATH environment variable before calling the script if your source +# is in a different location. +# The main slim/nets/mobilenet_v1.md description has more details about the +# model, but the main points are that it comes in four size versions, 1.0, 0.75, +# 0.50, and 0.25, which controls the number of parameters and so the file size +# of the model, and the input image size, which can be 224, 192, 160, or 128 +# pixels, and affects the amount of computation needed, and the latency. +# Here's an example generating a frozen model from pretrained weights: +# + +set -e + +print_usage () { + echo "Creates a frozen mobilenet model suitable for mobile use" + echo "Usage:" + echo "$0 [checkpoint path]" +} + +MOBILENET_VERSION=$1 +IMAGE_SIZE=$2 +CHECKPOINT=$3 + +if [[ ${MOBILENET_VERSION} = "1.0" ]]; then + SLIM_NAME=mobilenet_v1 +elif [[ ${MOBILENET_VERSION} = "0.75" ]]; then + SLIM_NAME=mobilenet_v1_075 +elif [[ ${MOBILENET_VERSION} = "0.50" ]]; then + SLIM_NAME=mobilenet_v1_050 +elif [[ ${MOBILENET_VERSION} = "0.25" ]]; then + SLIM_NAME=mobilenet_v1_025 +else + echo "Bad mobilenet version, should be one of 1.0, 0.75, 0.50, or 0.25" + print_usage + exit 1 +fi + +if [[ ${IMAGE_SIZE} -ne "224" ]] && [[ ${IMAGE_SIZE} -ne "192" ]] && [[ ${IMAGE_SIZE} -ne "160" ]] && [[ ${IMAGE_SIZE} -ne "128" ]]; then + echo "Bad input image size, should be one of 224, 192, 160, or 128" + print_usage + exit 1 +fi + +if [[ ${TENSORFLOW_PATH} -eq "" ]]; then + TENSORFLOW_PATH=../tensorflow +fi + +if [[ ! -d ${TENSORFLOW_PATH} ]]; then + echo "TensorFlow source folder not found. You should download the source and then set" + echo "the TENSORFLOW_PATH environment variable to point to it, like this:" + echo "export TENSORFLOW_PATH=/my/path/to/tensorflow" + print_usage + exit 1 +fi + +MODEL_FOLDER=/tmp/mobilenet_v1_${MOBILENET_VERSION}_${IMAGE_SIZE} +if [[ -d ${MODEL_FOLDER} ]]; then + echo "Model folder ${MODEL_FOLDER} already exists!" + echo "If you want to overwrite it, then 'rm -rf ${MODEL_FOLDER}' first." + print_usage + exit 1 +fi +mkdir ${MODEL_FOLDER} + +if [[ ${CHECKPOINT} = "" ]]; then + echo "*******" + echo "Downloading pretrained weights" + echo "*******" + curl "http://download.tensorflow.org/models/mobilenet_v1_${MOBILENET_VERSION}_${IMAGE_SIZE}_2017_06_14.tar.gz" \ + -o ${MODEL_FOLDER}/checkpoints.tar.gz + tar xzf ${MODEL_FOLDER}/checkpoints.tar.gz --directory ${MODEL_FOLDER} + CHECKPOINT=${MODEL_FOLDER}/mobilenet_v1_${MOBILENET_VERSION}_${IMAGE_SIZE}.ckpt +fi + +echo "*******" +echo "Exporting graph architecture to ${MODEL_FOLDER}/unfrozen_graph.pb" +echo "*******" +bazel run slim:export_inference_graph -- \ + --model_name=${SLIM_NAME} --image_size=${IMAGE_SIZE} --logtostderr \ + --output_file=${MODEL_FOLDER}/unfrozen_graph.pb --dataset_dir=${MODEL_FOLDER} + +cd ../tensorflow + +echo "*******" +echo "Freezing graph to ${MODEL_FOLDER}/frozen_graph.pb" +echo "*******" +bazel run tensorflow/python/tools:freeze_graph -- \ + --input_graph=${MODEL_FOLDER}/unfrozen_graph.pb \ + --input_checkpoint=${CHECKPOINT} \ + --input_binary=true --output_graph=${MODEL_FOLDER}/frozen_graph.pb \ + --output_node_names=MobilenetV1/Predictions/Reshape_1 + +echo "Quantizing weights to ${MODEL_FOLDER}/quantized_graph.pb" +bazel run tensorflow/tools/graph_transforms:transform_graph -- \ + --in_graph=${MODEL_FOLDER}/frozen_graph.pb \ + --out_graph=${MODEL_FOLDER}/quantized_graph.pb \ + --inputs=input --outputs=MobilenetV1/Predictions/Reshape_1 \ + --transforms='fold_constants fold_batch_norms quantize_weights' + +echo "*******" +echo "Running label_image using the graph" +echo "*******" +bazel build tensorflow/examples/label_image:label_image +bazel-bin/tensorflow/examples/label_image/label_image \ + --input_layer=input --output_layer=MobilenetV1/Predictions/Reshape_1 \ + --graph=${MODEL_FOLDER}/quantized_graph.pb --input_mean=-127 --input_std=127 \ + --image=tensorflow/examples/label_image/data/grace_hopper.jpg \ + --input_width=${IMAGE_SIZE} --input_height=${IMAGE_SIZE} --labels=${MODEL_FOLDER}/labels.txt + +echo "*******" +echo "Saved graphs to ${MODEL_FOLDER}/frozen_graph.pb and ${MODEL_FOLDER}/quantized_graph.pb" +echo "*******" diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_inception_resnet_v2_on_flowers.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_inception_resnet_v2_on_flowers.sh new file mode 100644 index 0000000..ad003ba --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_inception_resnet_v2_on_flowers.sh @@ -0,0 +1,109 @@ +#!/bin/bash +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +# +# This script performs the following operations: +# 1. Downloads the Flowers dataset +# 2. Fine-tunes an Inception Resnet V2 model on the Flowers training set. +# 3. Evaluates the model on the Flowers validation set. +# +# Usage: +# cd slim +# ./slim/scripts/finetune_inception_resnet_v2_on_flowers.sh +set -e + +# Where the pre-trained Inception Resnet V2 checkpoint is saved to. +PRETRAINED_CHECKPOINT_DIR=/tmp/checkpoints + +# Where the pre-trained Inception Resnet V2 checkpoint is saved to. +MODEL_NAME=inception_resnet_v2 + +# Where the training (fine-tuned) checkpoint and logs will be saved to. +TRAIN_DIR=/tmp/flowers-models/${MODEL_NAME} + +# Where the dataset is saved to. +DATASET_DIR=/tmp/flowers + +# Download the pre-trained checkpoint. +if [ ! -d "$PRETRAINED_CHECKPOINT_DIR" ]; then + mkdir ${PRETRAINED_CHECKPOINT_DIR} +fi +if [ ! -f ${PRETRAINED_CHECKPOINT_DIR}/${MODEL_NAME}.ckpt ]; then + wget http://download.tensorflow.org/models/inception_resnet_v2_2016_08_30.tar.gz + tar -xvf inception_resnet_v2_2016_08_30.tar.gz + mv inception_resnet_v2.ckpt ${PRETRAINED_CHECKPOINT_DIR}/${MODEL_NAME}.ckpt + rm inception_resnet_v2_2016_08_30.tar.gz +fi + +# Download the dataset +python download_and_convert_data.py \ + --dataset_name=flowers \ + --dataset_dir=${DATASET_DIR} + +# Fine-tune only the new layers for 1000 steps. +python train_image_classifier.py \ + --train_dir=${TRAIN_DIR} \ + --dataset_name=flowers \ + --dataset_split_name=train \ + --dataset_dir=${DATASET_DIR} \ + --model_name=${MODEL_NAME} \ + --checkpoint_path=${PRETRAINED_CHECKPOINT_DIR}/${MODEL_NAME}.ckpt \ + --checkpoint_exclude_scopes=InceptionResnetV2/Logits,InceptionResnetV2/AuxLogits \ + --trainable_scopes=InceptionResnetV2/Logits,InceptionResnetV2/AuxLogits \ + --max_number_of_steps=1000 \ + --batch_size=32 \ + --learning_rate=0.01 \ + --learning_rate_decay_type=fixed \ + --save_interval_secs=60 \ + --save_summaries_secs=60 \ + --log_every_n_steps=10 \ + --optimizer=rmsprop \ + --weight_decay=0.00004 + +# Run evaluation. +python eval_image_classifier.py \ + --checkpoint_path=${TRAIN_DIR} \ + --eval_dir=${TRAIN_DIR} \ + --dataset_name=flowers \ + --dataset_split_name=validation \ + --dataset_dir=${DATASET_DIR} \ + --model_name=${MODEL_NAME} + +# Fine-tune all the new layers for 500 steps. +python train_image_classifier.py \ + --train_dir=${TRAIN_DIR}/all \ + --dataset_name=flowers \ + --dataset_split_name=train \ + --dataset_dir=${DATASET_DIR} \ + --model_name=${MODEL_NAME} \ + --checkpoint_path=${TRAIN_DIR} \ + --max_number_of_steps=500 \ + --batch_size=32 \ + --learning_rate=0.0001 \ + --learning_rate_decay_type=fixed \ + --save_interval_secs=60 \ + --save_summaries_secs=60 \ + --log_every_n_steps=10 \ + --optimizer=rmsprop \ + --weight_decay=0.00004 + +# Run evaluation. +python eval_image_classifier.py \ + --checkpoint_path=${TRAIN_DIR}/all \ + --eval_dir=${TRAIN_DIR}/all \ + --dataset_name=flowers \ + --dataset_split_name=validation \ + --dataset_dir=${DATASET_DIR} \ + --model_name=${MODEL_NAME} diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_inception_v1_on_flowers.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_inception_v1_on_flowers.sh new file mode 100644 index 0000000..fee482a --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_inception_v1_on_flowers.sh @@ -0,0 +1,104 @@ +#!/bin/bash +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +# +# This script performs the following operations: +# 1. Downloads the Flowers dataset +# 2. Fine-tunes an InceptionV1 model on the Flowers training set. +# 3. Evaluates the model on the Flowers validation set. +# +# Usage: +# cd slim +# ./slim/scripts/finetune_inception_v1_on_flowers.sh +set -e + +# Where the pre-trained InceptionV1 checkpoint is saved to. +PRETRAINED_CHECKPOINT_DIR=/tmp/checkpoints + +# Where the training (fine-tuned) checkpoint and logs will be saved to. +TRAIN_DIR=/tmp/flowers-models/inception_v1 + +# Where the dataset is saved to. +DATASET_DIR=/tmp/flowers + +# Download the pre-trained checkpoint. +if [ ! -d "$PRETRAINED_CHECKPOINT_DIR" ]; then + mkdir ${PRETRAINED_CHECKPOINT_DIR} +fi +if [ ! -f ${PRETRAINED_CHECKPOINT_DIR}/inception_v1.ckpt ]; then + wget http://download.tensorflow.org/models/inception_v1_2016_08_28.tar.gz + tar -xvf inception_v1_2016_08_28.tar.gz + mv inception_v1.ckpt ${PRETRAINED_CHECKPOINT_DIR}/inception_v1.ckpt + rm inception_v1_2016_08_28.tar.gz +fi + +# Download the dataset +python download_and_convert_data.py \ + --dataset_name=flowers \ + --dataset_dir=${DATASET_DIR} + +# Fine-tune only the new layers for 2000 steps. +python train_image_classifier.py \ + --train_dir=${TRAIN_DIR} \ + --dataset_name=flowers \ + --dataset_split_name=train \ + --dataset_dir=${DATASET_DIR} \ + --model_name=inception_v1 \ + --checkpoint_path=${PRETRAINED_CHECKPOINT_DIR}/inception_v1.ckpt \ + --checkpoint_exclude_scopes=InceptionV1/Logits \ + --trainable_scopes=InceptionV1/Logits \ + --max_number_of_steps=3000 \ + --batch_size=32 \ + --learning_rate=0.01 \ + --save_interval_secs=60 \ + --save_summaries_secs=60 \ + --log_every_n_steps=100 \ + --optimizer=rmsprop \ + --weight_decay=0.00004 + +# Run evaluation. +python eval_image_classifier.py \ + --checkpoint_path=${TRAIN_DIR} \ + --eval_dir=${TRAIN_DIR} \ + --dataset_name=flowers \ + --dataset_split_name=validation \ + --dataset_dir=${DATASET_DIR} \ + --model_name=inception_v1 + +# Fine-tune all the new layers for 1000 steps. +python train_image_classifier.py \ + --train_dir=${TRAIN_DIR}/all \ + --dataset_name=flowers \ + --dataset_split_name=train \ + --dataset_dir=${DATASET_DIR} \ + --checkpoint_path=${TRAIN_DIR} \ + --model_name=inception_v1 \ + --max_number_of_steps=1000 \ + --batch_size=32 \ + --learning_rate=0.001 \ + --save_interval_secs=60 \ + --save_summaries_secs=60 \ + --log_every_n_steps=100 \ + --optimizer=rmsprop \ + --weight_decay=0.00004 + +# Run evaluation. +python eval_image_classifier.py \ + --checkpoint_path=${TRAIN_DIR}/all \ + --eval_dir=${TRAIN_DIR}/all \ + --dataset_name=flowers \ + --dataset_split_name=validation \ + --dataset_dir=${DATASET_DIR} \ + --model_name=inception_v1 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_inception_v3_on_flowers.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_inception_v3_on_flowers.sh new file mode 100644 index 0000000..3998663 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_inception_v3_on_flowers.sh @@ -0,0 +1,106 @@ +#!/bin/bash +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +# +# This script performs the following operations: +# 1. Downloads the Flowers dataset +# 2. Fine-tunes an InceptionV3 model on the Flowers training set. +# 3. Evaluates the model on the Flowers validation set. +# +# Usage: +# cd slim +# ./slim/scripts/finetune_inception_v3_on_flowers.sh +set -e + +# Where the pre-trained InceptionV3 checkpoint is saved to. +PRETRAINED_CHECKPOINT_DIR=/tmp/checkpoints + +# Where the training (fine-tuned) checkpoint and logs will be saved to. +TRAIN_DIR=/tmp/flowers-models/inception_v3 + +# Where the dataset is saved to. +DATASET_DIR=/tmp/flowers + +# Download the pre-trained checkpoint. +if [ ! -d "$PRETRAINED_CHECKPOINT_DIR" ]; then + mkdir ${PRETRAINED_CHECKPOINT_DIR} +fi +if [ ! -f ${PRETRAINED_CHECKPOINT_DIR}/inception_v3.ckpt ]; then + wget http://download.tensorflow.org/models/inception_v3_2016_08_28.tar.gz + tar -xvf inception_v3_2016_08_28.tar.gz + mv inception_v3.ckpt ${PRETRAINED_CHECKPOINT_DIR}/inception_v3.ckpt + rm inception_v3_2016_08_28.tar.gz +fi + +# Download the dataset +python download_and_convert_data.py \ + --dataset_name=flowers \ + --dataset_dir=${DATASET_DIR} + +# Fine-tune only the new layers for 1000 steps. +python train_image_classifier.py \ + --train_dir=${TRAIN_DIR} \ + --dataset_name=flowers \ + --dataset_split_name=train \ + --dataset_dir=${DATASET_DIR} \ + --model_name=inception_v3 \ + --checkpoint_path=${PRETRAINED_CHECKPOINT_DIR}/inception_v3.ckpt \ + --checkpoint_exclude_scopes=InceptionV3/Logits,InceptionV3/AuxLogits \ + --trainable_scopes=InceptionV3/Logits,InceptionV3/AuxLogits \ + --max_number_of_steps=1000 \ + --batch_size=32 \ + --learning_rate=0.01 \ + --learning_rate_decay_type=fixed \ + --save_interval_secs=60 \ + --save_summaries_secs=60 \ + --log_every_n_steps=100 \ + --optimizer=rmsprop \ + --weight_decay=0.00004 + +# Run evaluation. +python eval_image_classifier.py \ + --checkpoint_path=${TRAIN_DIR} \ + --eval_dir=${TRAIN_DIR} \ + --dataset_name=flowers \ + --dataset_split_name=validation \ + --dataset_dir=${DATASET_DIR} \ + --model_name=inception_v3 + +# Fine-tune all the new layers for 500 steps. +python train_image_classifier.py \ + --train_dir=${TRAIN_DIR}/all \ + --dataset_name=flowers \ + --dataset_split_name=train \ + --dataset_dir=${DATASET_DIR} \ + --model_name=inception_v3 \ + --checkpoint_path=${TRAIN_DIR} \ + --max_number_of_steps=500 \ + --batch_size=32 \ + --learning_rate=0.0001 \ + --learning_rate_decay_type=fixed \ + --save_interval_secs=60 \ + --save_summaries_secs=60 \ + --log_every_n_steps=10 \ + --optimizer=rmsprop \ + --weight_decay=0.00004 + +# Run evaluation. +python eval_image_classifier.py \ + --checkpoint_path=${TRAIN_DIR}/all \ + --eval_dir=${TRAIN_DIR}/all \ + --dataset_name=flowers \ + --dataset_split_name=validation \ + --dataset_dir=${DATASET_DIR} \ + --model_name=inception_v3 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_resnet_v1_50_on_flowers.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_resnet_v1_50_on_flowers.sh new file mode 100644 index 0000000..00d9043 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/finetune_resnet_v1_50_on_flowers.sh @@ -0,0 +1,104 @@ +#!/bin/bash +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +# +# This script performs the following operations: +# 1. Downloads the Flowers dataset +# 2. Fine-tunes a ResNetV1-50 model on the Flowers training set. +# 3. Evaluates the model on the Flowers validation set. +# +# Usage: +# cd slim +# ./slim/scripts/finetune_resnet_v1_50_on_flowers.sh +set -e + +# Where the pre-trained ResNetV1-50 checkpoint is saved to. +PRETRAINED_CHECKPOINT_DIR=/tmp/checkpoints + +# Where the training (fine-tuned) checkpoint and logs will be saved to. +TRAIN_DIR=/tmp/flowers-models/resnet_v1_50 + +# Where the dataset is saved to. +DATASET_DIR=/tmp/flowers + +# Download the pre-trained checkpoint. +if [ ! -d "$PRETRAINED_CHECKPOINT_DIR" ]; then + mkdir ${PRETRAINED_CHECKPOINT_DIR} +fi +if [ ! -f ${PRETRAINED_CHECKPOINT_DIR}/resnet_v1_50.ckpt ]; then + wget http://download.tensorflow.org/models/resnet_v1_50_2016_08_28.tar.gz + tar -xvf resnet_v1_50_2016_08_28.tar.gz + mv resnet_v1_50.ckpt ${PRETRAINED_CHECKPOINT_DIR}/resnet_v1_50.ckpt + rm resnet_v1_50_2016_08_28.tar.gz +fi + +# Download the dataset +python download_and_convert_data.py \ + --dataset_name=flowers \ + --dataset_dir=${DATASET_DIR} + +# Fine-tune only the new layers for 3000 steps. +python train_image_classifier.py \ + --train_dir=${TRAIN_DIR} \ + --dataset_name=flowers \ + --dataset_split_name=train \ + --dataset_dir=${DATASET_DIR} \ + --model_name=resnet_v1_50 \ + --checkpoint_path=${PRETRAINED_CHECKPOINT_DIR}/resnet_v1_50.ckpt \ + --checkpoint_exclude_scopes=resnet_v1_50/logits \ + --trainable_scopes=resnet_v1_50/logits \ + --max_number_of_steps=3000 \ + --batch_size=32 \ + --learning_rate=0.01 \ + --save_interval_secs=60 \ + --save_summaries_secs=60 \ + --log_every_n_steps=100 \ + --optimizer=rmsprop \ + --weight_decay=0.00004 + +# Run evaluation. +python eval_image_classifier.py \ + --checkpoint_path=${TRAIN_DIR} \ + --eval_dir=${TRAIN_DIR} \ + --dataset_name=flowers \ + --dataset_split_name=validation \ + --dataset_dir=${DATASET_DIR} \ + --model_name=resnet_v1_50 + +# Fine-tune all the new layers for 1000 steps. +python train_image_classifier.py \ + --train_dir=${TRAIN_DIR}/all \ + --dataset_name=flowers \ + --dataset_split_name=train \ + --dataset_dir=${DATASET_DIR} \ + --checkpoint_path=${TRAIN_DIR} \ + --model_name=resnet_v1_50 \ + --max_number_of_steps=1000 \ + --batch_size=32 \ + --learning_rate=0.001 \ + --save_interval_secs=60 \ + --save_summaries_secs=60 \ + --log_every_n_steps=100 \ + --optimizer=rmsprop \ + --weight_decay=0.00004 + +# Run evaluation. +python eval_image_classifier.py \ + --checkpoint_path=${TRAIN_DIR}/all \ + --eval_dir=${TRAIN_DIR}/all \ + --dataset_name=flowers \ + --dataset_split_name=validation \ + --dataset_dir=${DATASET_DIR} \ + --model_name=resnet_v1_50 diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/train_cifarnet_on_cifar10.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/train_cifarnet_on_cifar10.sh new file mode 100644 index 0000000..4613ad1 --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/train_cifarnet_on_cifar10.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +# +# This script performs the following operations: +# 1. Downloads the Cifar10 dataset +# 2. Trains a CifarNet model on the Cifar10 training set. +# 3. Evaluates the model on the Cifar10 testing set. +# +# Usage: +# cd slim +# ./scripts/train_cifarnet_on_cifar10.sh +set -e + +# Where the checkpoint and logs will be saved to. +TRAIN_DIR=/tmp/cifarnet-model + +# Where the dataset is saved to. +DATASET_DIR=/tmp/cifar10 + +# Download the dataset +python download_and_convert_data.py \ + --dataset_name=cifar10 \ + --dataset_dir=${DATASET_DIR} + +# Run training. +python train_image_classifier.py \ + --train_dir=${TRAIN_DIR} \ + --dataset_name=cifar10 \ + --dataset_split_name=train \ + --dataset_dir=${DATASET_DIR} \ + --model_name=cifarnet \ + --preprocessing_name=cifarnet \ + --max_number_of_steps=100000 \ + --batch_size=128 \ + --save_interval_secs=120 \ + --save_summaries_secs=120 \ + --log_every_n_steps=100 \ + --optimizer=sgd \ + --learning_rate=0.1 \ + --learning_rate_decay_factor=0.1 \ + --num_epochs_per_decay=200 \ + --weight_decay=0.004 + +# Run evaluation. +python eval_image_classifier.py \ + --checkpoint_path=${TRAIN_DIR} \ + --eval_dir=${TRAIN_DIR} \ + --dataset_name=cifar10 \ + --dataset_split_name=test \ + --dataset_dir=${DATASET_DIR} \ + --model_name=cifarnet diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/train_lenet_on_mnist.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/train_lenet_on_mnist.sh new file mode 100644 index 0000000..1d588eb --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/scripts/train_lenet_on_mnist.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +# +# This script performs the following operations: +# 1. Downloads the MNIST dataset +# 2. Trains a LeNet model on the MNIST training set. +# 3. Evaluates the model on the MNIST testing set. +# +# Usage: +# cd slim +# ./slim/scripts/train_lenet_on_mnist.sh +set -e + +# Where the checkpoint and logs will be saved to. +TRAIN_DIR=/tmp/lenet-model + +# Where the dataset is saved to. +DATASET_DIR=/tmp/mnist + +# Download the dataset +python download_and_convert_data.py \ + --dataset_name=mnist \ + --dataset_dir=${DATASET_DIR} + +# Run training. +python train_image_classifier.py \ + --train_dir=${TRAIN_DIR} \ + --dataset_name=mnist \ + --dataset_split_name=train \ + --dataset_dir=${DATASET_DIR} \ + --model_name=lenet \ + --preprocessing_name=lenet \ + --max_number_of_steps=20000 \ + --batch_size=50 \ + --learning_rate=0.01 \ + --save_interval_secs=60 \ + --save_summaries_secs=60 \ + --log_every_n_steps=100 \ + --optimizer=sgd \ + --learning_rate_decay_type=fixed \ + --weight_decay=0 + +# Run evaluation. +python eval_image_classifier.py \ + --checkpoint_path=${TRAIN_DIR} \ + --eval_dir=${TRAIN_DIR} \ + --dataset_name=mnist \ + --dataset_split_name=test \ + --dataset_dir=${DATASET_DIR} \ + --model_name=lenet diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/setup.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/setup.py new file mode 100644 index 0000000..3ec7ecd --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/setup.py @@ -0,0 +1,27 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Setup script for slim.""" + +from setuptools import find_packages +from setuptools import setup + + +setup( + name='slim', + version='0.1', + include_package_data=True, + packages=find_packages(), + description='tf-slim', +) diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/slim_walkthrough.ipynb b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/slim_walkthrough.ipynb new file mode 100644 index 0000000..262281a --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/slim_walkthrough.ipynb @@ -0,0 +1,1141 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# TF-Slim Walkthrough\n", + "\n", + "This notebook will walk you through the basics of using TF-Slim to define, train and evaluate neural networks on various tasks. It assumes a basic knowledge of neural networks. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Table of contents\n", + "\n", + "Installation and setup
\n", + "Creating your first neural network with TF-Slim
\n", + "Reading Data with TF-Slim
\n", + "Training a convolutional neural network (CNN)
\n", + "Using pre-trained models
\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Installation and setup\n", + "\n", + "\n", + "Since the stable release of TF 1.0, the latest version of slim has been available as `tf.contrib.slim`.\n", + "To test that your installation is working, execute the following command; it should run without raising any errors.\n", + "\n", + "```\n", + "python -c \"import tensorflow.contrib.slim as slim; eval = slim.evaluation.evaluate_once\"\n", + "```\n", + "\n", + "Although, to use TF-Slim for image classification (as we do in this notebook), you also have to install the TF-Slim image models library from [here](https://github.com/tensorflow/models/tree/master/research/slim). Let's suppose you install this into a directory called TF_MODELS. Then you should change directory to TF_MODELS/research/slim **before** running this notebook, so that these files are in your python path.\n", + "\n", + "To check you've got these two steps to work, just execute the cell below. If it complains about unknown modules, restart the notebook after moving to the TF-Slim models directory.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from __future__ import absolute_import\n", + "from __future__ import division\n", + "from __future__ import print_function\n", + "\n", + "import matplotlib\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import math\n", + "import numpy as np\n", + "import tensorflow as tf\n", + "import time\n", + "\n", + "from datasets import dataset_utils\n", + "\n", + "# Main slim library\n", + "from tensorflow.contrib import slim" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Creating your first neural network with TF-Slim\n", + "\n", + "\n", + "Below we give some code to create a simple multilayer perceptron (MLP) which can be used\n", + "for regression problems. The model has 2 hidden layers.\n", + "The output is a single node. \n", + "When this function is called, it will create various nodes, and silently add them to whichever global TF graph is currently in scope. When a node which corresponds to a layer with adjustable parameters (eg., a fully connected layer) is created, additional parameter variable nodes are silently created, and added to the graph. (We will discuss how to train the parameters later.)\n", + "\n", + "We use variable scope to put all the nodes under a common name,\n", + "so that the graph has some hierarchical structure.\n", + "This is useful when we want to visualize the TF graph in tensorboard, or if we want to query related\n", + "variables. \n", + "The fully connected layers all use the same L2 weight decay and ReLu activations, as specified by **arg_scope**. (However, the final layer overrides these defaults, and uses an identity activation function.)\n", + "\n", + "We also illustrate how to add a dropout layer after the first fully connected layer (FC1). Note that at test time, \n", + "we do not drop out nodes, but instead use the average activations; hence we need to know whether the model is being\n", + "constructed for training or testing, since the computational graph will be different in the two cases\n", + "(although the variables, storing the model parameters, will be shared, since they have the same name/scope)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def regression_model(inputs, is_training=True, scope=\"deep_regression\"):\n", + " \"\"\"Creates the regression model.\n", + "\n", + " Args:\n", + " inputs: A node that yields a `Tensor` of size [batch_size, dimensions].\n", + " is_training: Whether or not we're currently training the model.\n", + " scope: An optional variable_op scope for the model.\n", + "\n", + " Returns:\n", + " predictions: 1-D `Tensor` of shape [batch_size] of responses.\n", + " end_points: A dict of end points representing the hidden layers.\n", + " \"\"\"\n", + " with tf.variable_scope(scope, 'deep_regression', [inputs]):\n", + " end_points = {}\n", + " # Set the default weight _regularizer and acvitation for each fully_connected layer.\n", + " with slim.arg_scope([slim.fully_connected],\n", + " activation_fn=tf.nn.relu,\n", + " weights_regularizer=slim.l2_regularizer(0.01)):\n", + "\n", + " # Creates a fully connected layer from the inputs with 32 hidden units.\n", + " net = slim.fully_connected(inputs, 32, scope='fc1')\n", + " end_points['fc1'] = net\n", + "\n", + " # Adds a dropout layer to prevent over-fitting.\n", + " net = slim.dropout(net, 0.8, is_training=is_training)\n", + "\n", + " # Adds another fully connected layer with 16 hidden units.\n", + " net = slim.fully_connected(net, 16, scope='fc2')\n", + " end_points['fc2'] = net\n", + "\n", + " # Creates a fully-connected layer with a single hidden unit. Note that the\n", + " # layer is made linear by setting activation_fn=None.\n", + " predictions = slim.fully_connected(net, 1, activation_fn=None, scope='prediction')\n", + " end_points['out'] = predictions\n", + "\n", + " return predictions, end_points" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Let's create the model and examine its structure.\n", + "\n", + "We create a TF graph and call regression_model(), which adds nodes (tensors) to the graph. We then examine their shape, and print the names of all the model variables which have been implicitly created inside of each layer. We see that the names of the variables follow the scopes that we specified." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "with tf.Graph().as_default():\n", + " # Dummy placeholders for arbitrary number of 1d inputs and outputs\n", + " inputs = tf.placeholder(tf.float32, shape=(None, 1))\n", + " outputs = tf.placeholder(tf.float32, shape=(None, 1))\n", + "\n", + " # Build model\n", + " predictions, end_points = regression_model(inputs)\n", + "\n", + " # Print name and shape of each tensor.\n", + " print(\"Layers\")\n", + " for k, v in end_points.items():\n", + " print('name = {}, shape = {}'.format(v.name, v.get_shape()))\n", + "\n", + " # Print name and shape of parameter nodes (values not yet initialized)\n", + " print(\"\\n\")\n", + " print(\"Parameters\")\n", + " for v in slim.get_model_variables():\n", + " print('name = {}, shape = {}'.format(v.name, v.get_shape()))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Let's create some 1d regression data .\n", + "\n", + "We will train and test the model on some noisy observations of a nonlinear function.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def produce_batch(batch_size, noise=0.3):\n", + " xs = np.random.random(size=[batch_size, 1]) * 10\n", + " ys = np.sin(xs) + 5 + np.random.normal(size=[batch_size, 1], scale=noise)\n", + " return [xs.astype(np.float32), ys.astype(np.float32)]\n", + "\n", + "x_train, y_train = produce_batch(200)\n", + "x_test, y_test = produce_batch(200)\n", + "plt.scatter(x_train, y_train)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Let's fit the model to the data\n", + "\n", + "The user has to specify the loss function and the optimizer, and slim does the rest.\n", + "In particular, the slim.learning.train function does the following:\n", + "\n", + "- For each iteration, evaluate the train_op, which updates the parameters using the optimizer applied to the current minibatch. Also, update the global_step.\n", + "- Occasionally store the model checkpoint in the specified directory. This is useful in case your machine crashes - then you can simply restart from the specified checkpoint." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def convert_data_to_tensors(x, y):\n", + " inputs = tf.constant(x)\n", + " inputs.set_shape([None, 1])\n", + " \n", + " outputs = tf.constant(y)\n", + " outputs.set_shape([None, 1])\n", + " return inputs, outputs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# The following snippet trains the regression model using a mean_squared_error loss.\n", + "ckpt_dir = '/tmp/regression_model/'\n", + "\n", + "with tf.Graph().as_default():\n", + " tf.logging.set_verbosity(tf.logging.INFO)\n", + " \n", + " inputs, targets = convert_data_to_tensors(x_train, y_train)\n", + "\n", + " # Make the model.\n", + " predictions, nodes = regression_model(inputs, is_training=True)\n", + "\n", + " # Add the loss function to the graph.\n", + " loss = tf.losses.mean_squared_error(labels=targets, predictions=predictions)\n", + " \n", + " # The total loss is the user's loss plus any regularization losses.\n", + " total_loss = slim.losses.get_total_loss()\n", + "\n", + " # Specify the optimizer and create the train op:\n", + " optimizer = tf.train.AdamOptimizer(learning_rate=0.005)\n", + " train_op = slim.learning.create_train_op(total_loss, optimizer) \n", + "\n", + " # Run the training inside a session.\n", + " final_loss = slim.learning.train(\n", + " train_op,\n", + " logdir=ckpt_dir,\n", + " number_of_steps=5000,\n", + " save_summaries_secs=5,\n", + " log_every_n_steps=500)\n", + " \n", + "print(\"Finished training. Last batch loss:\", final_loss)\n", + "print(\"Checkpoint saved in %s\" % ckpt_dir)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Training with multiple loss functions.\n", + "\n", + "Sometimes we have multiple objectives we want to simultaneously optimize.\n", + "In slim, it is easy to add more losses, as we show below. (We do not optimize the total loss in this example,\n", + "but we show how to compute it.)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "with tf.Graph().as_default():\n", + " inputs, targets = convert_data_to_tensors(x_train, y_train)\n", + " predictions, end_points = regression_model(inputs, is_training=True)\n", + "\n", + " # Add multiple loss nodes.\n", + " mean_squared_error_loss = tf.losses.mean_squared_error(labels=targets, predictions=predictions)\n", + " absolute_difference_loss = slim.losses.absolute_difference(predictions, targets)\n", + "\n", + " # The following two ways to compute the total loss are equivalent\n", + " regularization_loss = tf.add_n(slim.losses.get_regularization_losses())\n", + " total_loss1 = mean_squared_error_loss + absolute_difference_loss + regularization_loss\n", + "\n", + " # Regularization Loss is included in the total loss by default.\n", + " # This is good for training, but not for testing.\n", + " total_loss2 = slim.losses.get_total_loss(add_regularization_losses=True)\n", + " \n", + " init_op = tf.global_variables_initializer()\n", + " \n", + " with tf.Session() as sess:\n", + " sess.run(init_op) # Will initialize the parameters with random weights.\n", + " \n", + " total_loss1, total_loss2 = sess.run([total_loss1, total_loss2])\n", + " \n", + " print('Total Loss1: %f' % total_loss1)\n", + " print('Total Loss2: %f' % total_loss2)\n", + "\n", + " print('Regularization Losses:')\n", + " for loss in slim.losses.get_regularization_losses():\n", + " print(loss)\n", + "\n", + " print('Loss Functions:')\n", + " for loss in slim.losses.get_losses():\n", + " print(loss)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Let's load the saved model and use it for prediction." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "with tf.Graph().as_default():\n", + " inputs, targets = convert_data_to_tensors(x_test, y_test)\n", + " \n", + " # Create the model structure. (Parameters will be loaded below.)\n", + " predictions, end_points = regression_model(inputs, is_training=False)\n", + "\n", + " # Make a session which restores the old parameters from a checkpoint.\n", + " sv = tf.train.Supervisor(logdir=ckpt_dir)\n", + " with sv.managed_session() as sess:\n", + " inputs, predictions, targets = sess.run([inputs, predictions, targets])\n", + "\n", + "plt.scatter(inputs, targets, c='r');\n", + "plt.scatter(inputs, predictions, c='b');\n", + "plt.title('red=true, blue=predicted')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Let's compute various evaluation metrics on the test set.\n", + "\n", + "In TF-Slim termiology, losses are optimized, but metrics (which may not be differentiable, e.g., precision and recall) are just measured. As an illustration, the code below computes mean squared error and mean absolute error metrics on the test set.\n", + "\n", + "Each metric declaration creates several local variables (which must be initialized via tf.initialize_local_variables()) and returns both a value_op and an update_op. When evaluated, the value_op returns the current value of the metric. The update_op loads a new batch of data, runs the model, obtains the predictions and accumulates the metric statistics appropriately before returning the current value of the metric. We store these value nodes and update nodes in 2 dictionaries.\n", + "\n", + "After creating the metric nodes, we can pass them to slim.evaluation.evaluation, which repeatedly evaluates these nodes the specified number of times. (This allows us to compute the evaluation in a streaming fashion across minibatches, which is usefulf for large datasets.) Finally, we print the final value of each metric.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "with tf.Graph().as_default():\n", + " inputs, targets = convert_data_to_tensors(x_test, y_test)\n", + " predictions, end_points = regression_model(inputs, is_training=False)\n", + "\n", + " # Specify metrics to evaluate:\n", + " names_to_value_nodes, names_to_update_nodes = slim.metrics.aggregate_metric_map({\n", + " 'Mean Squared Error': slim.metrics.streaming_mean_squared_error(predictions, targets),\n", + " 'Mean Absolute Error': slim.metrics.streaming_mean_absolute_error(predictions, targets)\n", + " })\n", + "\n", + " # Make a session which restores the old graph parameters, and then run eval.\n", + " sv = tf.train.Supervisor(logdir=ckpt_dir)\n", + " with sv.managed_session() as sess:\n", + " metric_values = slim.evaluation.evaluation(\n", + " sess,\n", + " num_evals=1, # Single pass over data\n", + " eval_op=names_to_update_nodes.values(),\n", + " final_op=names_to_value_nodes.values())\n", + "\n", + " names_to_values = dict(zip(names_to_value_nodes.keys(), metric_values))\n", + " for key, value in names_to_values.items():\n", + " print('%s: %f' % (key, value))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Reading Data with TF-Slim\n", + "\n", + "\n", + "Reading data with TF-Slim has two main components: A\n", + "[Dataset](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/slim/python/slim/data/dataset.py) and a \n", + "[DatasetDataProvider](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/slim/python/slim/data/dataset_data_provider.py). The former is a descriptor of a dataset, while the latter performs the actions necessary for actually reading the data. Lets look at each one in detail:\n", + "\n", + "\n", + "## Dataset\n", + "A TF-Slim\n", + "[Dataset](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/slim/python/slim/data/dataset.py)\n", + "contains descriptive information about a dataset necessary for reading it, such as the list of data files and how to decode them. It also contains metadata including class labels, the size of the train/test splits and descriptions of the tensors that the dataset provides. For example, some datasets contain images with labels. Others augment this data with bounding box annotations, etc. The Dataset object allows us to write generic code using the same API, regardless of the data content and encoding type.\n", + "\n", + "TF-Slim's Dataset works especially well when the data is stored as a (possibly sharded)\n", + "[TFRecords file](https://www.tensorflow.org/versions/r0.10/how_tos/reading_data/index.html#file-formats), where each record contains a [tf.train.Example protocol buffer](https://github.com/tensorflow/tensorflow/blob/r0.10/tensorflow/core/example/example.proto).\n", + "TF-Slim uses a consistent convention for naming the keys and values inside each Example record. \n", + "\n", + "## DatasetDataProvider\n", + "\n", + "A\n", + "[DatasetDataProvider](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/slim/python/slim/data/dataset_data_provider.py) is a class which actually reads the data from a dataset. It is highly configurable to read the data in various ways that may make a big impact on the efficiency of your training process. For example, it can be single or multi-threaded. If your data is sharded across many files, it can read each files serially, or from every file simultaneously.\n", + "\n", + "## Demo: The Flowers Dataset\n", + "\n", + "For convenience, we've include scripts to convert several common image datasets into TFRecord format and have provided\n", + "the Dataset descriptor files necessary for reading them. We demonstrate how easy it is to use these dataset via the Flowers dataset below." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download the Flowers Dataset\n", + "\n", + "\n", + "We've made available a tarball of the Flowers dataset which has already been converted to TFRecord format." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import tensorflow as tf\n", + "from datasets import dataset_utils\n", + "\n", + "url = \"http://download.tensorflow.org/data/flowers.tar.gz\"\n", + "flowers_data_dir = '/tmp/flowers'\n", + "\n", + "if not tf.gfile.Exists(flowers_data_dir):\n", + " tf.gfile.MakeDirs(flowers_data_dir)\n", + "\n", + "dataset_utils.download_and_uncompress_tarball(url, flowers_data_dir) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Display some of the data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from datasets import flowers\n", + "import tensorflow as tf\n", + "\n", + "from tensorflow.contrib import slim\n", + "\n", + "with tf.Graph().as_default(): \n", + " dataset = flowers.get_split('train', flowers_data_dir)\n", + " data_provider = slim.dataset_data_provider.DatasetDataProvider(\n", + " dataset, common_queue_capacity=32, common_queue_min=1)\n", + " image, label = data_provider.get(['image', 'label'])\n", + " \n", + " with tf.Session() as sess: \n", + " with slim.queues.QueueRunners(sess):\n", + " for i in range(4):\n", + " np_image, np_label = sess.run([image, label])\n", + " height, width, _ = np_image.shape\n", + " class_name = name = dataset.labels_to_names[np_label]\n", + " \n", + " plt.figure()\n", + " plt.imshow(np_image)\n", + " plt.title('%s, %d x %d' % (name, height, width))\n", + " plt.axis('off')\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Convolutional neural nets (CNNs).\n", + "\n", + "\n", + "In this section, we show how to train an image classifier using a simple CNN.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define the model.\n", + "\n", + "Below we define a simple CNN. Note that the output layer is linear function - we will apply softmax transformation externally to the model, either in the loss function (for training), or in the prediction function (during testing)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def my_cnn(images, num_classes, is_training): # is_training is not used...\n", + " with slim.arg_scope([slim.max_pool2d], kernel_size=[3, 3], stride=2):\n", + " net = slim.conv2d(images, 64, [5, 5])\n", + " net = slim.max_pool2d(net)\n", + " net = slim.conv2d(net, 64, [5, 5])\n", + " net = slim.max_pool2d(net)\n", + " net = slim.flatten(net)\n", + " net = slim.fully_connected(net, 192)\n", + " net = slim.fully_connected(net, num_classes, activation_fn=None) \n", + " return net" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Apply the model to some randomly generated images." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import tensorflow as tf\n", + "\n", + "with tf.Graph().as_default():\n", + " # The model can handle any input size because the first layer is convolutional.\n", + " # The size of the model is determined when image_node is first passed into the my_cnn function.\n", + " # Once the variables are initialized, the size of all the weight matrices is fixed.\n", + " # Because of the fully connected layers, this means that all subsequent images must have the same\n", + " # input size as the first image.\n", + " batch_size, height, width, channels = 3, 28, 28, 3\n", + " images = tf.random_uniform([batch_size, height, width, channels], maxval=1)\n", + " \n", + " # Create the model.\n", + " num_classes = 10\n", + " logits = my_cnn(images, num_classes, is_training=True)\n", + " probabilities = tf.nn.softmax(logits)\n", + " \n", + " # Initialize all the variables (including parameters) randomly.\n", + " init_op = tf.global_variables_initializer()\n", + " \n", + " with tf.Session() as sess:\n", + " # Run the init_op, evaluate the model outputs and print the results:\n", + " sess.run(init_op)\n", + " probabilities = sess.run(probabilities)\n", + " \n", + "print('Probabilities Shape:')\n", + "print(probabilities.shape) # batch_size x num_classes \n", + "\n", + "print('\\nProbabilities:')\n", + "print(probabilities)\n", + "\n", + "print('\\nSumming across all classes (Should equal 1):')\n", + "print(np.sum(probabilities, 1)) # Each row sums to 1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Train the model on the Flowers dataset.\n", + "\n", + "Before starting, make sure you've run the code to Download the Flowers dataset. Now, we'll get a sense of what it looks like to use TF-Slim's training functions found in\n", + "[learning.py](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/slim/python/slim/learning.py). First, we'll create a function, `load_batch`, that loads batches of dataset from a dataset. Next, we'll train a model for a single step (just to demonstrate the API), and evaluate the results." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from preprocessing import inception_preprocessing\n", + "import tensorflow as tf\n", + "\n", + "from tensorflow.contrib import slim\n", + "\n", + "\n", + "def load_batch(dataset, batch_size=32, height=299, width=299, is_training=False):\n", + " \"\"\"Loads a single batch of data.\n", + " \n", + " Args:\n", + " dataset: The dataset to load.\n", + " batch_size: The number of images in the batch.\n", + " height: The size of each image after preprocessing.\n", + " width: The size of each image after preprocessing.\n", + " is_training: Whether or not we're currently training or evaluating.\n", + " \n", + " Returns:\n", + " images: A Tensor of size [batch_size, height, width, 3], image samples that have been preprocessed.\n", + " images_raw: A Tensor of size [batch_size, height, width, 3], image samples that can be used for visualization.\n", + " labels: A Tensor of size [batch_size], whose values range between 0 and dataset.num_classes.\n", + " \"\"\"\n", + " data_provider = slim.dataset_data_provider.DatasetDataProvider(\n", + " dataset, common_queue_capacity=32,\n", + " common_queue_min=8)\n", + " image_raw, label = data_provider.get(['image', 'label'])\n", + " \n", + " # Preprocess image for usage by Inception.\n", + " image = inception_preprocessing.preprocess_image(image_raw, height, width, is_training=is_training)\n", + " \n", + " # Preprocess the image for display purposes.\n", + " image_raw = tf.expand_dims(image_raw, 0)\n", + " image_raw = tf.image.resize_images(image_raw, [height, width])\n", + " image_raw = tf.squeeze(image_raw)\n", + "\n", + " # Batch it up.\n", + " images, images_raw, labels = tf.train.batch(\n", + " [image, image_raw, label],\n", + " batch_size=batch_size,\n", + " num_threads=1,\n", + " capacity=2 * batch_size)\n", + " \n", + " return images, images_raw, labels" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from datasets import flowers\n", + "\n", + "# This might take a few minutes.\n", + "train_dir = '/tmp/tfslim_model/'\n", + "print('Will save model to %s' % train_dir)\n", + "\n", + "with tf.Graph().as_default():\n", + " tf.logging.set_verbosity(tf.logging.INFO)\n", + "\n", + " dataset = flowers.get_split('train', flowers_data_dir)\n", + " images, _, labels = load_batch(dataset)\n", + " \n", + " # Create the model:\n", + " logits = my_cnn(images, num_classes=dataset.num_classes, is_training=True)\n", + " \n", + " # Specify the loss function:\n", + " one_hot_labels = slim.one_hot_encoding(labels, dataset.num_classes)\n", + " slim.losses.softmax_cross_entropy(logits, one_hot_labels)\n", + " total_loss = slim.losses.get_total_loss()\n", + "\n", + " # Create some summaries to visualize the training process:\n", + " tf.summary.scalar('losses/Total Loss', total_loss)\n", + " \n", + " # Specify the optimizer and create the train op:\n", + " optimizer = tf.train.AdamOptimizer(learning_rate=0.01)\n", + " train_op = slim.learning.create_train_op(total_loss, optimizer)\n", + "\n", + " # Run the training:\n", + " final_loss = slim.learning.train(\n", + " train_op,\n", + " logdir=train_dir,\n", + " number_of_steps=1, # For speed, we just do 1 epoch\n", + " save_summaries_secs=1)\n", + " \n", + " print('Finished training. Final batch loss %d' % final_loss)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Evaluate some metrics.\n", + "\n", + "As we discussed above, we can compute various metrics besides the loss.\n", + "Below we show how to compute prediction accuracy of the trained model, as well as top-5 classification accuracy. (The difference between evaluation and evaluation_loop is that the latter writes the results to a log directory, so they can be viewed in tensorboard.)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from datasets import flowers\n", + "\n", + "# This might take a few minutes.\n", + "with tf.Graph().as_default():\n", + " tf.logging.set_verbosity(tf.logging.DEBUG)\n", + " \n", + " dataset = flowers.get_split('train', flowers_data_dir)\n", + " images, _, labels = load_batch(dataset)\n", + " \n", + " logits = my_cnn(images, num_classes=dataset.num_classes, is_training=False)\n", + " predictions = tf.argmax(logits, 1)\n", + " \n", + " # Define the metrics:\n", + " names_to_values, names_to_updates = slim.metrics.aggregate_metric_map({\n", + " 'eval/Accuracy': slim.metrics.streaming_accuracy(predictions, labels),\n", + " 'eval/Recall@5': slim.metrics.streaming_recall_at_k(logits, labels, 5),\n", + " })\n", + "\n", + " print('Running evaluation Loop...')\n", + " checkpoint_path = tf.train.latest_checkpoint(train_dir)\n", + " metric_values = slim.evaluation.evaluate_once(\n", + " master='',\n", + " checkpoint_path=checkpoint_path,\n", + " logdir=train_dir,\n", + " eval_op=names_to_updates.values(),\n", + " final_op=names_to_values.values())\n", + "\n", + " names_to_values = dict(zip(names_to_values.keys(), metric_values))\n", + " for name in names_to_values:\n", + " print('%s: %f' % (name, names_to_values[name]))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Using pre-trained models\n", + "\n", + "\n", + "Neural nets work best when they have many parameters, making them very flexible function approximators.\n", + "However, this means they must be trained on big datasets. Since this process is slow, we provide various pre-trained models - see the list [here](https://github.com/tensorflow/models/tree/master/research/slim#pre-trained-models).\n", + "\n", + "\n", + "You can either use these models as-is, or you can perform \"surgery\" on them, to modify them for some other task. For example, it is common to \"chop off\" the final pre-softmax layer, and replace it with a new set of weights corresponding to some new set of labels. You can then quickly fine tune the new model on a small new dataset. We illustrate this below, using inception-v1 as the base model. While models like Inception V3 are more powerful, Inception V1 is used for speed purposes.\n", + "\n", + "Take into account that VGG and ResNet final layers have only 1000 outputs rather than 1001. The ImageNet dataset provied has an empty background class which can be used to fine-tune the model to other tasks. VGG and ResNet models provided here don't use that class. We provide two examples of using pretrained models: Inception V1 and VGG-19 models to highlight this difference.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download the Inception V1 checkpoint\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from datasets import dataset_utils\n", + "\n", + "url = \"http://download.tensorflow.org/models/inception_v1_2016_08_28.tar.gz\"\n", + "checkpoints_dir = '/tmp/checkpoints'\n", + "\n", + "if not tf.gfile.Exists(checkpoints_dir):\n", + " tf.gfile.MakeDirs(checkpoints_dir)\n", + "\n", + "dataset_utils.download_and_uncompress_tarball(url, checkpoints_dir)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### Apply Pre-trained Inception V1 model to Images.\n", + "\n", + "We have to convert each image to the size expected by the model checkpoint.\n", + "There is no easy way to determine this size from the checkpoint itself.\n", + "So we use a preprocessor to enforce this." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import os\n", + "import tensorflow as tf\n", + "\n", + "try:\n", + " import urllib2 as urllib\n", + "except ImportError:\n", + " import urllib.request as urllib\n", + "\n", + "from datasets import imagenet\n", + "from nets import inception\n", + "from preprocessing import inception_preprocessing\n", + "\n", + "from tensorflow.contrib import slim\n", + "\n", + "image_size = inception.inception_v1.default_image_size\n", + "\n", + "with tf.Graph().as_default():\n", + " url = 'https://upload.wikimedia.org/wikipedia/commons/7/70/EnglishCockerSpaniel_simon.jpg'\n", + " image_string = urllib.urlopen(url).read()\n", + " image = tf.image.decode_jpeg(image_string, channels=3)\n", + " processed_image = inception_preprocessing.preprocess_image(image, image_size, image_size, is_training=False)\n", + " processed_images = tf.expand_dims(processed_image, 0)\n", + " \n", + " # Create the model, use the default arg scope to configure the batch norm parameters.\n", + " with slim.arg_scope(inception.inception_v1_arg_scope()):\n", + " logits, _ = inception.inception_v1(processed_images, num_classes=1001, is_training=False)\n", + " probabilities = tf.nn.softmax(logits)\n", + " \n", + " init_fn = slim.assign_from_checkpoint_fn(\n", + " os.path.join(checkpoints_dir, 'inception_v1.ckpt'),\n", + " slim.get_model_variables('InceptionV1'))\n", + " \n", + " with tf.Session() as sess:\n", + " init_fn(sess)\n", + " np_image, probabilities = sess.run([image, probabilities])\n", + " probabilities = probabilities[0, 0:]\n", + " sorted_inds = [i[0] for i in sorted(enumerate(-probabilities), key=lambda x:x[1])]\n", + " \n", + " plt.figure()\n", + " plt.imshow(np_image.astype(np.uint8))\n", + " plt.axis('off')\n", + " plt.show()\n", + "\n", + " names = imagenet.create_readable_names_for_imagenet_labels()\n", + " for i in range(5):\n", + " index = sorted_inds[i]\n", + " print('Probability %0.2f%% => [%s]' % (probabilities[index] * 100, names[index]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download the VGG-16 checkpoint" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from datasets import dataset_utils\n", + "import tensorflow as tf\n", + "\n", + "url = \"http://download.tensorflow.org/models/vgg_16_2016_08_28.tar.gz\"\n", + "checkpoints_dir = '/tmp/checkpoints'\n", + "\n", + "if not tf.gfile.Exists(checkpoints_dir):\n", + " tf.gfile.MakeDirs(checkpoints_dir)\n", + "\n", + "dataset_utils.download_and_uncompress_tarball(url, checkpoints_dir)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### Apply Pre-trained VGG-16 model to Images.\n", + "\n", + "We have to convert each image to the size expected by the model checkpoint.\n", + "There is no easy way to determine this size from the checkpoint itself.\n", + "So we use a preprocessor to enforce this. Pay attention to the difference caused by 1000 classes instead of 1001." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import os\n", + "import tensorflow as tf\n", + "\n", + "try:\n", + " import urllib2\n", + "except ImportError:\n", + " import urllib.request as urllib\n", + "\n", + "from datasets import imagenet\n", + "from nets import vgg\n", + "from preprocessing import vgg_preprocessing\n", + "\n", + "from tensorflow.contrib import slim\n", + "\n", + "image_size = vgg.vgg_16.default_image_size\n", + "\n", + "with tf.Graph().as_default():\n", + " url = 'https://upload.wikimedia.org/wikipedia/commons/d/d9/First_Student_IC_school_bus_202076.jpg'\n", + " image_string = urllib.urlopen(url).read()\n", + " image = tf.image.decode_jpeg(image_string, channels=3)\n", + " processed_image = vgg_preprocessing.preprocess_image(image, image_size, image_size, is_training=False)\n", + " processed_images = tf.expand_dims(processed_image, 0)\n", + " \n", + " # Create the model, use the default arg scope to configure the batch norm parameters.\n", + " with slim.arg_scope(vgg.vgg_arg_scope()):\n", + " # 1000 classes instead of 1001.\n", + " logits, _ = vgg.vgg_16(processed_images, num_classes=1000, is_training=False)\n", + " probabilities = tf.nn.softmax(logits)\n", + " \n", + " init_fn = slim.assign_from_checkpoint_fn(\n", + " os.path.join(checkpoints_dir, 'vgg_16.ckpt'),\n", + " slim.get_model_variables('vgg_16'))\n", + " \n", + " with tf.Session() as sess:\n", + " init_fn(sess)\n", + " np_image, probabilities = sess.run([image, probabilities])\n", + " probabilities = probabilities[0, 0:]\n", + " sorted_inds = [i[0] for i in sorted(enumerate(-probabilities), key=lambda x:x[1])]\n", + " \n", + " plt.figure()\n", + " plt.imshow(np_image.astype(np.uint8))\n", + " plt.axis('off')\n", + " plt.show()\n", + " \n", + " names = imagenet.create_readable_names_for_imagenet_labels()\n", + " for i in range(5):\n", + " index = sorted_inds[i]\n", + " # Shift the index of a class name by one. \n", + " print('Probability %0.2f%% => [%s]' % (probabilities[index] * 100, names[index+1]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Fine-tune the model on a different set of labels.\n", + "\n", + "We will fine tune the inception model on the Flowers dataset." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Note that this may take several minutes.\n", + "\n", + "import os\n", + "\n", + "from datasets import flowers\n", + "from nets import inception\n", + "from preprocessing import inception_preprocessing\n", + "\n", + "from tensorflow.contrib import slim\n", + "image_size = inception.inception_v1.default_image_size\n", + "\n", + "\n", + "def get_init_fn():\n", + " \"\"\"Returns a function run by the chief worker to warm-start the training.\"\"\"\n", + " checkpoint_exclude_scopes=[\"InceptionV1/Logits\", \"InceptionV1/AuxLogits\"]\n", + " \n", + " exclusions = [scope.strip() for scope in checkpoint_exclude_scopes]\n", + "\n", + " variables_to_restore = []\n", + " for var in slim.get_model_variables():\n", + " for exclusion in exclusions:\n", + " if var.op.name.startswith(exclusion):\n", + " break\n", + " else:\n", + " variables_to_restore.append(var)\n", + "\n", + " return slim.assign_from_checkpoint_fn(\n", + " os.path.join(checkpoints_dir, 'inception_v1.ckpt'),\n", + " variables_to_restore)\n", + "\n", + "\n", + "train_dir = '/tmp/inception_finetuned/'\n", + "\n", + "with tf.Graph().as_default():\n", + " tf.logging.set_verbosity(tf.logging.INFO)\n", + " \n", + " dataset = flowers.get_split('train', flowers_data_dir)\n", + " images, _, labels = load_batch(dataset, height=image_size, width=image_size)\n", + " \n", + " # Create the model, use the default arg scope to configure the batch norm parameters.\n", + " with slim.arg_scope(inception.inception_v1_arg_scope()):\n", + " logits, _ = inception.inception_v1(images, num_classes=dataset.num_classes, is_training=True)\n", + " \n", + " # Specify the loss function:\n", + " one_hot_labels = slim.one_hot_encoding(labels, dataset.num_classes)\n", + " slim.losses.softmax_cross_entropy(logits, one_hot_labels)\n", + " total_loss = slim.losses.get_total_loss()\n", + "\n", + " # Create some summaries to visualize the training process:\n", + " tf.summary.scalar('losses/Total Loss', total_loss)\n", + " \n", + " # Specify the optimizer and create the train op:\n", + " optimizer = tf.train.AdamOptimizer(learning_rate=0.01)\n", + " train_op = slim.learning.create_train_op(total_loss, optimizer)\n", + " \n", + " # Run the training:\n", + " final_loss = slim.learning.train(\n", + " train_op,\n", + " logdir=train_dir,\n", + " init_fn=get_init_fn(),\n", + " number_of_steps=2)\n", + " \n", + " \n", + "print('Finished training. Last batch loss %f' % final_loss)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Apply fine tuned model to some images." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import tensorflow as tf\n", + "from datasets import flowers\n", + "from nets import inception\n", + "\n", + "from tensorflow.contrib import slim\n", + "\n", + "image_size = inception.inception_v1.default_image_size\n", + "batch_size = 3\n", + "\n", + "with tf.Graph().as_default():\n", + " tf.logging.set_verbosity(tf.logging.INFO)\n", + " \n", + " dataset = flowers.get_split('train', flowers_data_dir)\n", + " images, images_raw, labels = load_batch(dataset, height=image_size, width=image_size)\n", + " \n", + " # Create the model, use the default arg scope to configure the batch norm parameters.\n", + " with slim.arg_scope(inception.inception_v1_arg_scope()):\n", + " logits, _ = inception.inception_v1(images, num_classes=dataset.num_classes, is_training=True)\n", + "\n", + " probabilities = tf.nn.softmax(logits)\n", + " \n", + " checkpoint_path = tf.train.latest_checkpoint(train_dir)\n", + " init_fn = slim.assign_from_checkpoint_fn(\n", + " checkpoint_path,\n", + " slim.get_variables_to_restore())\n", + " \n", + " with tf.Session() as sess:\n", + " with slim.queues.QueueRunners(sess):\n", + " sess.run(tf.initialize_local_variables())\n", + " init_fn(sess)\n", + " np_probabilities, np_images_raw, np_labels = sess.run([probabilities, images_raw, labels])\n", + " \n", + " for i in range(batch_size): \n", + " image = np_images_raw[i, :, :, :]\n", + " true_label = np_labels[i]\n", + " predicted_label = np.argmax(np_probabilities[i, :])\n", + " predicted_name = dataset.labels_to_names[predicted_label]\n", + " true_name = dataset.labels_to_names[true_label]\n", + " \n", + " plt.figure()\n", + " plt.imshow(image.astype(np.uint8))\n", + " plt.title('Ground Truth: [%s], Prediction [%s]' % (true_name, predicted_name))\n", + " plt.axis('off')\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.1" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/slim/train_image_classifier.py b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/train_image_classifier.py new file mode 100644 index 0000000..a704f4c --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/slim/train_image_classifier.py @@ -0,0 +1,590 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Generic training script that trains a model using a given dataset.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +from datasets import dataset_factory +from deployment import model_deploy +from nets import nets_factory +from preprocessing import preprocessing_factory + +slim = tf.contrib.slim + +tf.app.flags.DEFINE_string( + 'master', '', 'The address of the TensorFlow master to use.') + +tf.app.flags.DEFINE_string( + 'train_dir', '/tmp/tfmodel/', + 'Directory where checkpoints and event logs are written to.') + +tf.app.flags.DEFINE_integer('num_clones', 1, + 'Number of model clones to deploy. Note For ' + 'historical reasons loss from all clones averaged ' + 'out and learning rate decay happen per clone ' + 'epochs') + +tf.app.flags.DEFINE_boolean('clone_on_cpu', False, + 'Use CPUs to deploy clones.') + +tf.app.flags.DEFINE_integer('worker_replicas', 1, 'Number of worker replicas.') + +tf.app.flags.DEFINE_integer( + 'num_ps_tasks', 0, + 'The number of parameter servers. If the value is 0, then the parameters ' + 'are handled locally by the worker.') + +tf.app.flags.DEFINE_integer( + 'num_readers', 4, + 'The number of parallel readers that read data from the dataset.') + +tf.app.flags.DEFINE_integer( + 'num_preprocessing_threads', 4, + 'The number of threads used to create the batches.') + +tf.app.flags.DEFINE_integer( + 'log_every_n_steps', 10, + 'The frequency with which logs are print.') + +tf.app.flags.DEFINE_integer( + 'save_summaries_secs', 600, + 'The frequency with which summaries are saved, in seconds.') + +tf.app.flags.DEFINE_integer( + 'save_interval_secs', 600, + 'The frequency with which the model is saved, in seconds.') + +tf.app.flags.DEFINE_integer( + 'task', 0, 'Task id of the replica running the training.') + +###################### +# Optimization Flags # +###################### + +tf.app.flags.DEFINE_float( + 'weight_decay', 0.00004, 'The weight decay on the model weights.') + +tf.app.flags.DEFINE_string( + 'optimizer', 'rmsprop', + 'The name of the optimizer, one of "adadelta", "adagrad", "adam",' + '"ftrl", "momentum", "sgd" or "rmsprop".') + +tf.app.flags.DEFINE_float( + 'adadelta_rho', 0.95, + 'The decay rate for adadelta.') + +tf.app.flags.DEFINE_float( + 'adagrad_initial_accumulator_value', 0.1, + 'Starting value for the AdaGrad accumulators.') + +tf.app.flags.DEFINE_float( + 'adam_beta1', 0.9, + 'The exponential decay rate for the 1st moment estimates.') + +tf.app.flags.DEFINE_float( + 'adam_beta2', 0.999, + 'The exponential decay rate for the 2nd moment estimates.') + +tf.app.flags.DEFINE_float('opt_epsilon', 1.0, 'Epsilon term for the optimizer.') + +tf.app.flags.DEFINE_float('ftrl_learning_rate_power', -0.5, + 'The learning rate power.') + +tf.app.flags.DEFINE_float( + 'ftrl_initial_accumulator_value', 0.1, + 'Starting value for the FTRL accumulators.') + +tf.app.flags.DEFINE_float( + 'ftrl_l1', 0.0, 'The FTRL l1 regularization strength.') + +tf.app.flags.DEFINE_float( + 'ftrl_l2', 0.0, 'The FTRL l2 regularization strength.') + +tf.app.flags.DEFINE_float( + 'momentum', 0.9, + 'The momentum for the MomentumOptimizer and RMSPropOptimizer.') + +tf.app.flags.DEFINE_float('rmsprop_momentum', 0.9, 'Momentum.') + +tf.app.flags.DEFINE_float('rmsprop_decay', 0.9, 'Decay term for RMSProp.') + +tf.app.flags.DEFINE_integer( + 'quantize_delay', -1, + 'Number of steps to start quantized training. Set to -1 would disable ' + 'quantized training.') + +####################### +# Learning Rate Flags # +####################### + +tf.app.flags.DEFINE_string( + 'learning_rate_decay_type', + 'exponential', + 'Specifies how the learning rate is decayed. One of "fixed", "exponential",' + ' or "polynomial"') + +tf.app.flags.DEFINE_float('learning_rate', 0.01, 'Initial learning rate.') + +tf.app.flags.DEFINE_float( + 'end_learning_rate', 0.0001, + 'The minimal end learning rate used by a polynomial decay learning rate.') + +tf.app.flags.DEFINE_float( + 'label_smoothing', 0.0, 'The amount of label smoothing.') + +tf.app.flags.DEFINE_float( + 'learning_rate_decay_factor', 0.94, 'Learning rate decay factor.') + +tf.app.flags.DEFINE_float( + 'num_epochs_per_decay', 2.0, + 'Number of epochs after which learning rate decays. Note: this flag counts ' + 'epochs per clone but aggregates per sync replicas. So 1.0 means that ' + 'each clone will go over full epoch individually, but replicas will go ' + 'once across all replicas.') + +tf.app.flags.DEFINE_bool( + 'sync_replicas', False, + 'Whether or not to synchronize the replicas during training.') + +tf.app.flags.DEFINE_integer( + 'replicas_to_aggregate', 1, + 'The Number of gradients to collect before updating params.') + +tf.app.flags.DEFINE_float( + 'moving_average_decay', None, + 'The decay to use for the moving average.' + 'If left as None, then moving averages are not used.') + +####################### +# Dataset Flags # +####################### + +tf.app.flags.DEFINE_string( + 'dataset_name', 'imagenet', 'The name of the dataset to load.') + +tf.app.flags.DEFINE_string( + 'dataset_split_name', 'train', 'The name of the train/test split.') + +tf.app.flags.DEFINE_string( + 'dataset_dir', None, 'The directory where the dataset files are stored.') + +tf.app.flags.DEFINE_integer( + 'labels_offset', 0, + 'An offset for the labels in the dataset. This flag is primarily used to ' + 'evaluate the VGG and ResNet architectures which do not use a background ' + 'class for the ImageNet dataset.') + +tf.app.flags.DEFINE_string( + 'model_name', 'inception_v3', 'The name of the architecture to train.') + +tf.app.flags.DEFINE_string( + 'preprocessing_name', None, 'The name of the preprocessing to use. If left ' + 'as `None`, then the model_name flag is used.') + +tf.app.flags.DEFINE_integer( + 'batch_size', 32, 'The number of samples in each batch.') + +tf.app.flags.DEFINE_integer( + 'train_image_size', None, 'Train image size') + +tf.app.flags.DEFINE_integer('max_number_of_steps', None, + 'The maximum number of training steps.') + +##################### +# Fine-Tuning Flags # +##################### + +tf.app.flags.DEFINE_string( + 'checkpoint_path', None, + 'The path to a checkpoint from which to fine-tune.') + +tf.app.flags.DEFINE_string( + 'checkpoint_exclude_scopes', None, + 'Comma-separated list of scopes of variables to exclude when restoring ' + 'from a checkpoint.') + +tf.app.flags.DEFINE_string( + 'trainable_scopes', None, + 'Comma-separated list of scopes to filter the set of variables to train.' + 'By default, None would train all the variables.') + +tf.app.flags.DEFINE_boolean( + 'ignore_missing_vars', False, + 'When restoring a checkpoint would ignore missing variables.') + +FLAGS = tf.app.flags.FLAGS + + +def _configure_learning_rate(num_samples_per_epoch, global_step): + """Configures the learning rate. + + Args: + num_samples_per_epoch: The number of samples in each epoch of training. + global_step: The global_step tensor. + + Returns: + A `Tensor` representing the learning rate. + + Raises: + ValueError: if + """ + # Note: when num_clones is > 1, this will actually have each clone to go + # over each epoch FLAGS.num_epochs_per_decay times. This is different + # behavior from sync replicas and is expected to produce different results. + decay_steps = int(num_samples_per_epoch * FLAGS.num_epochs_per_decay / + FLAGS.batch_size) + + if FLAGS.sync_replicas: + decay_steps /= FLAGS.replicas_to_aggregate + + if FLAGS.learning_rate_decay_type == 'exponential': + return tf.train.exponential_decay(FLAGS.learning_rate, + global_step, + decay_steps, + FLAGS.learning_rate_decay_factor, + staircase=True, + name='exponential_decay_learning_rate') + elif FLAGS.learning_rate_decay_type == 'fixed': + return tf.constant(FLAGS.learning_rate, name='fixed_learning_rate') + elif FLAGS.learning_rate_decay_type == 'polynomial': + return tf.train.polynomial_decay(FLAGS.learning_rate, + global_step, + decay_steps, + FLAGS.end_learning_rate, + power=1.0, + cycle=False, + name='polynomial_decay_learning_rate') + else: + raise ValueError('learning_rate_decay_type [%s] was not recognized' % + FLAGS.learning_rate_decay_type) + + +def _configure_optimizer(learning_rate): + """Configures the optimizer used for training. + + Args: + learning_rate: A scalar or `Tensor` learning rate. + + Returns: + An instance of an optimizer. + + Raises: + ValueError: if FLAGS.optimizer is not recognized. + """ + if FLAGS.optimizer == 'adadelta': + optimizer = tf.train.AdadeltaOptimizer( + learning_rate, + rho=FLAGS.adadelta_rho, + epsilon=FLAGS.opt_epsilon) + elif FLAGS.optimizer == 'adagrad': + optimizer = tf.train.AdagradOptimizer( + learning_rate, + initial_accumulator_value=FLAGS.adagrad_initial_accumulator_value) + elif FLAGS.optimizer == 'adam': + optimizer = tf.train.AdamOptimizer( + learning_rate, + beta1=FLAGS.adam_beta1, + beta2=FLAGS.adam_beta2, + epsilon=FLAGS.opt_epsilon) + elif FLAGS.optimizer == 'ftrl': + optimizer = tf.train.FtrlOptimizer( + learning_rate, + learning_rate_power=FLAGS.ftrl_learning_rate_power, + initial_accumulator_value=FLAGS.ftrl_initial_accumulator_value, + l1_regularization_strength=FLAGS.ftrl_l1, + l2_regularization_strength=FLAGS.ftrl_l2) + elif FLAGS.optimizer == 'momentum': + optimizer = tf.train.MomentumOptimizer( + learning_rate, + momentum=FLAGS.momentum, + name='Momentum') + elif FLAGS.optimizer == 'rmsprop': + optimizer = tf.train.RMSPropOptimizer( + learning_rate, + decay=FLAGS.rmsprop_decay, + momentum=FLAGS.rmsprop_momentum, + epsilon=FLAGS.opt_epsilon) + elif FLAGS.optimizer == 'sgd': + optimizer = tf.train.GradientDescentOptimizer(learning_rate) + else: + raise ValueError('Optimizer [%s] was not recognized' % FLAGS.optimizer) + return optimizer + + +def _get_init_fn(): + """Returns a function run by the chief worker to warm-start the training. + + Note that the init_fn is only run when initializing the model during the very + first global step. + + Returns: + An init function run by the supervisor. + """ + if FLAGS.checkpoint_path is None: + return None + + # Warn the user if a checkpoint exists in the train_dir. Then we'll be + # ignoring the checkpoint anyway. + if tf.train.latest_checkpoint(FLAGS.train_dir): + tf.logging.info( + 'Ignoring --checkpoint_path because a checkpoint already exists in %s' + % FLAGS.train_dir) + return None + + exclusions = [] + if FLAGS.checkpoint_exclude_scopes: + exclusions = [scope.strip() + for scope in FLAGS.checkpoint_exclude_scopes.split(',')] + + # TODO(sguada) variables.filter_variables() + variables_to_restore = [] + for var in slim.get_model_variables(): + for exclusion in exclusions: + if var.op.name.startswith(exclusion): + break + else: + variables_to_restore.append(var) + + if tf.gfile.IsDirectory(FLAGS.checkpoint_path): + checkpoint_path = tf.train.latest_checkpoint(FLAGS.checkpoint_path) + else: + checkpoint_path = FLAGS.checkpoint_path + + tf.logging.info('Fine-tuning from %s' % checkpoint_path) + + return slim.assign_from_checkpoint_fn( + checkpoint_path, + variables_to_restore, + ignore_missing_vars=FLAGS.ignore_missing_vars) + + +def _get_variables_to_train(): + """Returns a list of variables to train. + + Returns: + A list of variables to train by the optimizer. + """ + if FLAGS.trainable_scopes is None: + return tf.trainable_variables() + else: + scopes = [scope.strip() for scope in FLAGS.trainable_scopes.split(',')] + + variables_to_train = [] + for scope in scopes: + variables = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope) + variables_to_train.extend(variables) + return variables_to_train + + +def main(_): + if not FLAGS.dataset_dir: + raise ValueError('You must supply the dataset directory with --dataset_dir') + + tf.logging.set_verbosity(tf.logging.INFO) + with tf.Graph().as_default(): + ####################### + # Config model_deploy # + ####################### + deploy_config = model_deploy.DeploymentConfig( + num_clones=FLAGS.num_clones, + clone_on_cpu=FLAGS.clone_on_cpu, + replica_id=FLAGS.task, + num_replicas=FLAGS.worker_replicas, + num_ps_tasks=FLAGS.num_ps_tasks) + + # Create global_step + with tf.device(deploy_config.variables_device()): + global_step = slim.create_global_step() + + ###################### + # Select the dataset # + ###################### + dataset = dataset_factory.get_dataset( + FLAGS.dataset_name, FLAGS.dataset_split_name, FLAGS.dataset_dir) + + ###################### + # Select the network # + ###################### + network_fn = nets_factory.get_network_fn( + FLAGS.model_name, + num_classes=(dataset.num_classes - FLAGS.labels_offset), + weight_decay=FLAGS.weight_decay, + is_training=True) + + ##################################### + # Select the preprocessing function # + ##################################### + preprocessing_name = FLAGS.preprocessing_name or FLAGS.model_name + image_preprocessing_fn = preprocessing_factory.get_preprocessing( + preprocessing_name, + is_training=True) + + ############################################################## + # Create a dataset provider that loads data from the dataset # + ############################################################## + with tf.device(deploy_config.inputs_device()): + provider = slim.dataset_data_provider.DatasetDataProvider( + dataset, + num_readers=FLAGS.num_readers, + common_queue_capacity=20 * FLAGS.batch_size, + common_queue_min=10 * FLAGS.batch_size) + [image, label] = provider.get(['image', 'label']) + label -= FLAGS.labels_offset + + train_image_size = FLAGS.train_image_size or network_fn.default_image_size + + image = image_preprocessing_fn(image, train_image_size, train_image_size) + + images, labels = tf.train.batch( + [image, label], + batch_size=FLAGS.batch_size, + num_threads=FLAGS.num_preprocessing_threads, + capacity=5 * FLAGS.batch_size) + labels = slim.one_hot_encoding( + labels, dataset.num_classes - FLAGS.labels_offset) + batch_queue = slim.prefetch_queue.prefetch_queue( + [images, labels], capacity=2 * deploy_config.num_clones) + + #################### + # Define the model # + #################### + def clone_fn(batch_queue): + """Allows data parallelism by creating multiple clones of network_fn.""" + images, labels = batch_queue.dequeue() + logits, end_points = network_fn(images) + + ############################# + # Specify the loss function # + ############################# + if 'AuxLogits' in end_points: + slim.losses.softmax_cross_entropy( + end_points['AuxLogits'], labels, + label_smoothing=FLAGS.label_smoothing, weights=0.4, + scope='aux_loss') + slim.losses.softmax_cross_entropy( + logits, labels, label_smoothing=FLAGS.label_smoothing, weights=1.0) + return end_points + + # Gather initial summaries. + summaries = set(tf.get_collection(tf.GraphKeys.SUMMARIES)) + + clones = model_deploy.create_clones(deploy_config, clone_fn, [batch_queue]) + first_clone_scope = deploy_config.clone_scope(0) + # Gather update_ops from the first clone. These contain, for example, + # the updates for the batch_norm variables created by network_fn. + update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS, first_clone_scope) + + # Add summaries for end_points. + end_points = clones[0].outputs + for end_point in end_points: + x = end_points[end_point] + summaries.add(tf.summary.histogram('activations/' + end_point, x)) + summaries.add(tf.summary.scalar('sparsity/' + end_point, + tf.nn.zero_fraction(x))) + + # Add summaries for losses. + for loss in tf.get_collection(tf.GraphKeys.LOSSES, first_clone_scope): + summaries.add(tf.summary.scalar('losses/%s' % loss.op.name, loss)) + + # Add summaries for variables. + for variable in slim.get_model_variables(): + summaries.add(tf.summary.histogram(variable.op.name, variable)) + + ################################# + # Configure the moving averages # + ################################# + if FLAGS.moving_average_decay: + moving_average_variables = slim.get_model_variables() + variable_averages = tf.train.ExponentialMovingAverage( + FLAGS.moving_average_decay, global_step) + else: + moving_average_variables, variable_averages = None, None + + if FLAGS.quantize_delay >= 0: + tf.contrib.quantize.create_training_graph( + quant_delay=FLAGS.quantize_delay) + + ######################################### + # Configure the optimization procedure. # + ######################################### + with tf.device(deploy_config.optimizer_device()): + learning_rate = _configure_learning_rate(dataset.num_samples, global_step) + optimizer = _configure_optimizer(learning_rate) + summaries.add(tf.summary.scalar('learning_rate', learning_rate)) + + if FLAGS.sync_replicas: + # If sync_replicas is enabled, the averaging will be done in the chief + # queue runner. + optimizer = tf.train.SyncReplicasOptimizer( + opt=optimizer, + replicas_to_aggregate=FLAGS.replicas_to_aggregate, + total_num_replicas=FLAGS.worker_replicas, + variable_averages=variable_averages, + variables_to_average=moving_average_variables) + elif FLAGS.moving_average_decay: + # Update ops executed locally by trainer. + update_ops.append(variable_averages.apply(moving_average_variables)) + + # Variables to train. + variables_to_train = _get_variables_to_train() + + # and returns a train_tensor and summary_op + total_loss, clones_gradients = model_deploy.optimize_clones( + clones, + optimizer, + var_list=variables_to_train) + # Add total_loss to summary. + summaries.add(tf.summary.scalar('total_loss', total_loss)) + + # Create gradient updates. + grad_updates = optimizer.apply_gradients(clones_gradients, + global_step=global_step) + update_ops.append(grad_updates) + + update_op = tf.group(*update_ops) + with tf.control_dependencies([update_op]): + train_tensor = tf.identity(total_loss, name='train_op') + + # Add the summaries from the first clone. These contain the summaries + # created by model_fn and either optimize_clones() or _gather_clone_loss(). + summaries |= set(tf.get_collection(tf.GraphKeys.SUMMARIES, + first_clone_scope)) + + # Merge all summaries together. + summary_op = tf.summary.merge(list(summaries), name='summary_op') + + ########################### + # Kicks off the training. # + ########################### + slim.learning.train( + train_tensor, + logdir=FLAGS.train_dir, + master=FLAGS.master, + is_chief=(FLAGS.task == 0), + init_fn=_get_init_fn(), + summary_op=summary_op, + number_of_steps=FLAGS.max_number_of_steps, + log_every_n_steps=FLAGS.log_every_n_steps, + save_summaries_secs=FLAGS.save_summaries_secs, + save_interval_secs=FLAGS.save_interval_secs, + sync_optimizer=optimizer if FLAGS.sync_replicas else None) + + +if __name__ == '__main__': + tf.app.run() From 711da5c966a710a9ec3e280f029581b281802a77 Mon Sep 17 00:00:00 2001 From: Naveen M Date: Mon, 9 Dec 2019 01:38:41 -0600 Subject: [PATCH 2/6] Deeplabv3 Pytorch model with LMS --- .../pytorch-deeplab-xception/LICENSE | 21 + .../pytorch-deeplab-xception/README.md | 83 ++++ .../dataloaders/__init__.py | 24 + .../dataloaders/custom_transforms.py | 165 +++++++ .../dataloaders/datasets/__init__.py | 0 .../dataloaders/datasets/cityscapes.py | 146 ++++++ .../dataloaders/datasets/coco.py | 160 +++++++ .../dataloaders/datasets/combine_dbs.py | 100 +++++ .../dataloaders/datasets/pascal.py | 145 ++++++ .../dataloaders/datasets/sbd.py | 129 ++++++ .../dataloaders/utils.py | 101 +++++ .../doc/deeplab_resnet.py | 315 +++++++++++++ .../doc/deeplab_xception.py | 424 ++++++++++++++++++ .../pytorch-deeplab-xception/doc/results.png | Bin 0 -> 521261 bytes .../modeling/__init__.py | 0 .../pytorch-deeplab-xception/modeling/aspp.py | 95 ++++ .../modeling/backbone/__init__.py | 13 + .../modeling/backbone/drn.py | 402 +++++++++++++++++ .../modeling/backbone/mobilenet.py | 151 +++++++ .../modeling/backbone/resnet.py | 162 +++++++ .../modeling/backbone/xception.py | 288 ++++++++++++ .../modeling/decoder.py | 57 +++ .../modeling/deeplab.py | 71 +++ .../modeling/sync_batchnorm/__init__.py | 12 + .../modeling/sync_batchnorm/batchnorm.py | 282 ++++++++++++ .../modeling/sync_batchnorm/comm.py | 129 ++++++ .../modeling/sync_batchnorm/replicate.py | 88 ++++ .../modeling/sync_batchnorm/unittest.py | 29 ++ .../pytorch-deeplab-xception/mypath.py | 14 + .../pytorch-deeplab-xception/train.py | 358 +++++++++++++++ .../pytorch-deeplab-xception/train_coco.sh | 1 + .../pytorch-deeplab-xception/train_voc.sh | 93 ++++ .../utils/calculate_weights.py | 29 ++ .../pytorch-deeplab-xception/utils/loss.py | 63 +++ .../utils/lr_scheduler.py | 70 +++ .../pytorch-deeplab-xception/utils/metrics.py | 50 +++ .../pytorch-deeplab-xception/utils/saver.py | 61 +++ .../utils/summaries.py | 24 + 38 files changed, 4355 insertions(+) create mode 100644 examples/performance_models/pytorch-deeplab-xception/LICENSE create mode 100644 examples/performance_models/pytorch-deeplab-xception/README.md create mode 100644 examples/performance_models/pytorch-deeplab-xception/dataloaders/__init__.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/dataloaders/custom_transforms.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/__init__.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/cityscapes.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/coco.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/combine_dbs.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/pascal.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/sbd.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/dataloaders/utils.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/doc/deeplab_resnet.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/doc/deeplab_xception.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/doc/results.png create mode 100644 examples/performance_models/pytorch-deeplab-xception/modeling/__init__.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/modeling/aspp.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/modeling/backbone/__init__.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/modeling/backbone/drn.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/modeling/backbone/mobilenet.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/modeling/backbone/resnet.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/modeling/backbone/xception.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/modeling/decoder.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/modeling/deeplab.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/modeling/sync_batchnorm/__init__.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/modeling/sync_batchnorm/batchnorm.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/modeling/sync_batchnorm/comm.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/modeling/sync_batchnorm/replicate.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/modeling/sync_batchnorm/unittest.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/mypath.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/train.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/train_coco.sh create mode 100644 examples/performance_models/pytorch-deeplab-xception/train_voc.sh create mode 100644 examples/performance_models/pytorch-deeplab-xception/utils/calculate_weights.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/utils/loss.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/utils/lr_scheduler.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/utils/metrics.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/utils/saver.py create mode 100644 examples/performance_models/pytorch-deeplab-xception/utils/summaries.py diff --git a/examples/performance_models/pytorch-deeplab-xception/LICENSE b/examples/performance_models/pytorch-deeplab-xception/LICENSE new file mode 100644 index 0000000..9888aa6 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Pyjcsx + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/examples/performance_models/pytorch-deeplab-xception/README.md b/examples/performance_models/pytorch-deeplab-xception/README.md new file mode 100644 index 0000000..398405c --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/README.md @@ -0,0 +1,83 @@ +# pytorch-deeplab-xception + +**Update on 2018/12/06. Provide model trained on VOC and SBD datasets.** + +**Update on 2018/11/24. Release newest version code, which fix some previous issues and also add support for new backbones and multi-gpu training. For previous code, please see in `previous` branch** + +### TODO +- [x] Support different backbones +- [x] Support VOC, SBD, Cityscapes and COCO datasets +- [x] Multi-GPU training + + + +| Backbone | train/eval os |mIoU in val |Pretrained Model| +| :-------- | :------------: |:---------: |:--------------:| +| ResNet | 16/16 | 78.43% | [google drive](https://drive.google.com/open?id=1NwcwlWqA-0HqAPk3dSNNPipGMF0iS0Zu) | +| MobileNet | 16/16 | 70.81% | [google drive](https://drive.google.com/open?id=1G9mWafUAj09P4KvGSRVzIsV_U5OqFLdt) | +| DRN | 16/16 | 78.87% | [google drive](https://drive.google.com/open?id=131gZN_dKEXO79NknIQazPJ-4UmRrZAfI) | + + + +### Introduction +This is a PyTorch(0.4.1) implementation of [DeepLab-V3-Plus](https://arxiv.org/pdf/1802.02611). It +can use Modified Aligned Xception and ResNet as backbone. Currently, we train DeepLab V3 Plus +using Pascal VOC 2012, SBD and Cityscapes datasets. + +![Results](doc/results.png) + + +### Installation +The code was tested with Anaconda and Python 3.6. After installing the Anaconda environment: + +0. Clone the repo: + ```Shell + git clone https://github.com/jfzhang95/pytorch-deeplab-xception.git + cd pytorch-deeplab-xception + ``` + +1. Install dependencies: + + For PyTorch dependency, see [pytorch.org](https://pytorch.org/) for more details. + + For custom dependencies: + ```Shell + pip install matplotlib pillow tensorboardX tqdm + ``` +### Training +Fellow steps below to train your model: + +0. Configure your dataset path in [mypath.py](https://github.com/jfzhang95/pytorch-deeplab-xception/blob/master/mypath.py). + +1. Input arguments: (see full input arguments via python train.py --help): + ```Shell + usage: train.py [-h] [--backbone {resnet,xception,drn,mobilenet}] + [--out-stride OUT_STRIDE] [--dataset {pascal,coco,cityscapes}] + [--use-sbd] [--workers N] [--base-size BASE_SIZE] + [--crop-size CROP_SIZE] [--sync-bn SYNC_BN] + [--freeze-bn FREEZE_BN] [--loss-type {ce,focal}] [--epochs N] + [--start_epoch N] [--batch-size N] [--test-batch-size N] + [--use-balanced-weights] [--lr LR] + [--lr-scheduler {poly,step,cos}] [--momentum M] + [--weight-decay M] [--nesterov] [--no-cuda] + [--gpu-ids GPU_IDS] [--seed S] [--resume RESUME] + [--checkname CHECKNAME] [--ft] [--eval-interval EVAL_INTERVAL] + [--no-val] + + ``` + +2. To train deeplabv3+ using Pascal VOC dataset and ResNet as backbone: + ```Shell + bash train_voc.sh + ``` +3. To train deeplabv3+ using COCO dataset and ResNet as backbone: + ```Shell + bash train_coco.sh + ``` + +### Acknowledgement +[PyTorch-Encoding](https://github.com/zhanghang1989/PyTorch-Encoding) + +[Synchronized-BatchNorm-PyTorch](https://github.com/vacancy/Synchronized-BatchNorm-PyTorch) + +[drn](https://github.com/fyu/drn) diff --git a/examples/performance_models/pytorch-deeplab-xception/dataloaders/__init__.py b/examples/performance_models/pytorch-deeplab-xception/dataloaders/__init__.py new file mode 100644 index 0000000..431f84e --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/dataloaders/__init__.py @@ -0,0 +1,24 @@ +from dataloaders.datasets import combine_dbs, pascal, sbd +from torch.utils.data import DataLoader +import torch + +def make_data_loader(args, **kwargs): + + if args.dataset == 'pascal': + train_set = pascal.VOCSegmentation(args, split='train') + val_set = pascal.VOCSegmentation(args, split='val') + if args.use_sbd: + sbd_train = sbd.SBDSegmentation(args, split=['train', 'val']) + train_set = combine_dbs.CombineDBs([train_set, sbd_train], excluded=[val_set]) + + num_class = train_set.NUM_CLASSES + train_sampler = torch.utils.data.distributed.DistributedSampler(train_set) + train_loader = DataLoader(train_set, batch_size=args.batch_size, sampler=train_sampler, **kwargs) + val_loader = DataLoader(val_set, batch_size=args.batch_size, shuffle=False, **kwargs) + test_loader = None + + return train_loader, val_loader, test_loader, num_class + + else: + raise NotImplementedError + diff --git a/examples/performance_models/pytorch-deeplab-xception/dataloaders/custom_transforms.py b/examples/performance_models/pytorch-deeplab-xception/dataloaders/custom_transforms.py new file mode 100644 index 0000000..1158e1f --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/dataloaders/custom_transforms.py @@ -0,0 +1,165 @@ +import torch +import random +import numpy as np + +from PIL import Image, ImageOps, ImageFilter + +class Normalize(object): + """Normalize a tensor image with mean and standard deviation. + Args: + mean (tuple): means for each channel. + std (tuple): standard deviations for each channel. + """ + def __init__(self, mean=(0., 0., 0.), std=(1., 1., 1.)): + self.mean = mean + self.std = std + + def __call__(self, sample): + img = sample['image'] + mask = sample['label'] + img = np.array(img).astype(np.float32) + mask = np.array(mask).astype(np.float32) + img /= 255.0 + img -= self.mean + img /= self.std + + return {'image': img, + 'label': mask} + + +class ToTensor(object): + """Convert ndarrays in sample to Tensors.""" + + def __call__(self, sample): + # swap color axis because + # numpy image: H x W x C + # torch image: C X H X W + img = sample['image'] + mask = sample['label'] + img = np.array(img).astype(np.float32).transpose((2, 0, 1)) + mask = np.array(mask).astype(np.float32) + + img = torch.from_numpy(img).float() + mask = torch.from_numpy(mask).float() + + return {'image': img, + 'label': mask} + + +class RandomHorizontalFlip(object): + def __call__(self, sample): + img = sample['image'] + mask = sample['label'] + if random.random() < 0.5: + img = img.transpose(Image.FLIP_LEFT_RIGHT) + mask = mask.transpose(Image.FLIP_LEFT_RIGHT) + + return {'image': img, + 'label': mask} + + +class RandomRotate(object): + def __init__(self, degree): + self.degree = degree + + def __call__(self, sample): + img = sample['image'] + mask = sample['label'] + rotate_degree = random.uniform(-1*self.degree, self.degree) + img = img.rotate(rotate_degree, Image.BILINEAR) + mask = mask.rotate(rotate_degree, Image.NEAREST) + + return {'image': img, + 'label': mask} + + +class RandomGaussianBlur(object): + def __call__(self, sample): + img = sample['image'] + mask = sample['label'] + if random.random() < 0.5: + img = img.filter(ImageFilter.GaussianBlur( + radius=random.random())) + + return {'image': img, + 'label': mask} + + +class RandomScaleCrop(object): + def __init__(self, base_size, crop_size, fill=0): + self.base_size = base_size + self.crop_size = crop_size + self.fill = fill + + def __call__(self, sample): + img = sample['image'] + mask = sample['label'] + # random scale (short edge) + short_size = random.randint(int(self.base_size * 0.5), int(self.base_size * 2.0)) + w, h = img.size + if h > w: + ow = short_size + oh = int(1.0 * h * ow / w) + else: + oh = short_size + ow = int(1.0 * w * oh / h) + img = img.resize((ow, oh), Image.BILINEAR) + mask = mask.resize((ow, oh), Image.NEAREST) + # pad crop + if short_size < self.crop_size: + padh = self.crop_size - oh if oh < self.crop_size else 0 + padw = self.crop_size - ow if ow < self.crop_size else 0 + img = ImageOps.expand(img, border=(0, 0, padw, padh), fill=0) + mask = ImageOps.expand(mask, border=(0, 0, padw, padh), fill=self.fill) + # random crop crop_size + w, h = img.size + x1 = random.randint(0, w - self.crop_size) + y1 = random.randint(0, h - self.crop_size) + img = img.crop((x1, y1, x1 + self.crop_size, y1 + self.crop_size)) + mask = mask.crop((x1, y1, x1 + self.crop_size, y1 + self.crop_size)) + + return {'image': img, + 'label': mask} + + +class FixScaleCrop(object): + def __init__(self, crop_size): + self.crop_size = crop_size + + def __call__(self, sample): + img = sample['image'] + mask = sample['label'] + w, h = img.size + if w > h: + oh = self.crop_size + ow = int(1.0 * w * oh / h) + else: + ow = self.crop_size + oh = int(1.0 * h * ow / w) + img = img.resize((ow, oh), Image.BILINEAR) + mask = mask.resize((ow, oh), Image.NEAREST) + # center crop + w, h = img.size + x1 = int(round((w - self.crop_size) / 2.)) + y1 = int(round((h - self.crop_size) / 2.)) + img = img.crop((x1, y1, x1 + self.crop_size, y1 + self.crop_size)) + mask = mask.crop((x1, y1, x1 + self.crop_size, y1 + self.crop_size)) + + return {'image': img, + 'label': mask} + +class FixedResize(object): + def __init__(self, size): + self.size = (size, size) # size: (h, w) + + def __call__(self, sample): + img = sample['image'] + mask = sample['label'] + + assert img.size == mask.size + + img = img.resize(self.size, Image.BILINEAR) + mask = mask.resize(self.size, Image.NEAREST) + + return {'image': img, + 'label': mask} \ No newline at end of file diff --git a/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/__init__.py b/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/cityscapes.py b/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/cityscapes.py new file mode 100644 index 0000000..4717a5f --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/cityscapes.py @@ -0,0 +1,146 @@ +import os +import numpy as np +import scipy.misc as m +from PIL import Image +from torch.utils import data +from mypath import Path +from torchvision import transforms +from dataloaders import custom_transforms as tr + +class CityscapesSegmentation(data.Dataset): + NUM_CLASSES = 19 + + def __init__(self, args, root=Path.db_root_dir('cityscapes'), split="train"): + + self.root = root + self.split = split + self.args = args + self.files = {} + + self.images_base = os.path.join(self.root, 'leftImg8bit', self.split) + self.annotations_base = os.path.join(self.root, 'gtFine_trainvaltest', 'gtFine', self.split) + + self.files[split] = self.recursive_glob(rootdir=self.images_base, suffix='.png') + + self.void_classes = [0, 1, 2, 3, 4, 5, 6, 9, 10, 14, 15, 16, 18, 29, 30, -1] + self.valid_classes = [7, 8, 11, 12, 13, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 31, 32, 33] + self.class_names = ['unlabelled', 'road', 'sidewalk', 'building', 'wall', 'fence', \ + 'pole', 'traffic_light', 'traffic_sign', 'vegetation', 'terrain', \ + 'sky', 'person', 'rider', 'car', 'truck', 'bus', 'train', \ + 'motorcycle', 'bicycle'] + + self.ignore_index = 255 + self.class_map = dict(zip(self.valid_classes, range(self.NUM_CLASSES))) + + if not self.files[split]: + raise Exception("No files for split=[%s] found in %s" % (split, self.images_base)) + + print("Found %d %s images" % (len(self.files[split]), split)) + + def __len__(self): + return len(self.files[self.split]) + + def __getitem__(self, index): + + img_path = self.files[self.split][index].rstrip() + lbl_path = os.path.join(self.annotations_base, + img_path.split(os.sep)[-2], + os.path.basename(img_path)[:-15] + 'gtFine_labelIds.png') + + _img = Image.open(img_path).convert('RGB') + _tmp = np.array(Image.open(lbl_path), dtype=np.uint8) + _tmp = self.encode_segmap(_tmp) + _target = Image.fromarray(_tmp) + + sample = {'image': _img, 'label': _target} + + if self.split == 'train': + return self.transform_tr(sample) + elif self.split == 'val': + return self.transform_val(sample) + elif self.split == 'test': + return self.transform_ts(sample) + + def encode_segmap(self, mask): + # Put all void classes to zero + for _voidc in self.void_classes: + mask[mask == _voidc] = self.ignore_index + for _validc in self.valid_classes: + mask[mask == _validc] = self.class_map[_validc] + return mask + + def recursive_glob(self, rootdir='.', suffix=''): + """Performs recursive glob with given suffix and rootdir + :param rootdir is the root directory + :param suffix is the suffix to be searched + """ + return [os.path.join(looproot, filename) + for looproot, _, filenames in os.walk(rootdir) + for filename in filenames if filename.endswith(suffix)] + + def transform_tr(self, sample): + composed_transforms = transforms.Compose([ + tr.RandomHorizontalFlip(), + tr.RandomScaleCrop(base_size=self.args.base_size, crop_size=self.args.crop_size, fill=255), + tr.RandomGaussianBlur(), + tr.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)), + tr.ToTensor()]) + + return composed_transforms(sample) + + def transform_val(self, sample): + + composed_transforms = transforms.Compose([ + tr.FixScaleCrop(crop_size=self.args.crop_size), + tr.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)), + tr.ToTensor()]) + + return composed_transforms(sample) + + def transform_ts(self, sample): + + composed_transforms = transforms.Compose([ + tr.FixedResize(size=self.args.crop_size), + tr.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)), + tr.ToTensor()]) + + return composed_transforms(sample) + +if __name__ == '__main__': + from dataloaders.utils import decode_segmap + from torch.utils.data import DataLoader + import matplotlib.pyplot as plt + import argparse + + parser = argparse.ArgumentParser() + args = parser.parse_args() + args.base_size = 513 + args.crop_size = 513 + + cityscapes_train = CityscapesSegmentation(args, split='train') + + dataloader = DataLoader(cityscapes_train, batch_size=2, shuffle=True, num_workers=2) + + for ii, sample in enumerate(dataloader): + for jj in range(sample["image"].size()[0]): + img = sample['image'].numpy() + gt = sample['label'].numpy() + tmp = np.array(gt[jj]).astype(np.uint8) + segmap = decode_segmap(tmp, dataset='cityscapes') + img_tmp = np.transpose(img[jj], axes=[1, 2, 0]) + img_tmp *= (0.229, 0.224, 0.225) + img_tmp += (0.485, 0.456, 0.406) + img_tmp *= 255.0 + img_tmp = img_tmp.astype(np.uint8) + plt.figure() + plt.title('display') + plt.subplot(211) + plt.imshow(img_tmp) + plt.subplot(212) + plt.imshow(segmap) + + if ii == 1: + break + + plt.show(block=True) + diff --git a/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/coco.py b/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/coco.py new file mode 100644 index 0000000..85f91b2 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/coco.py @@ -0,0 +1,160 @@ +import numpy as np +import torch +from torch.utils.data import Dataset +from mypath import Path +from tqdm import trange +import os +from pycocotools.coco import COCO +from pycocotools import mask +from torchvision import transforms +from dataloaders import custom_transforms as tr +from PIL import Image, ImageFile +ImageFile.LOAD_TRUNCATED_IMAGES = True + + +class COCOSegmentation(Dataset): + NUM_CLASSES = 21 + CAT_LIST = [0, 5, 2, 16, 9, 44, 6, 3, 17, 62, 21, 67, 18, 19, 4, + 1, 64, 20, 63, 7, 72] + + def __init__(self, + args, + base_dir=Path.db_root_dir('coco'), + split='train', + year='2017'): + super().__init__() + ann_file = os.path.join(base_dir, 'annotations/instances_{}{}.json'.format(split, year)) + ids_file = os.path.join(base_dir, 'annotations/{}_ids_{}.pth'.format(split, year)) + self.img_dir = os.path.join(base_dir, 'images/{}{}'.format(split, year)) + self.split = split + self.coco = COCO(ann_file) + self.coco_mask = mask + if os.path.exists(ids_file): + self.ids = torch.load(ids_file) + else: + ids = list(self.coco.imgs.keys()) + self.ids = self._preprocess(ids, ids_file) + self.args = args + + def __getitem__(self, index): + _img, _target = self._make_img_gt_point_pair(index) + sample = {'image': _img, 'label': _target} + + if self.split == "train": + return self.transform_tr(sample) + elif self.split == 'val': + return self.transform_val(sample) + + def _make_img_gt_point_pair(self, index): + coco = self.coco + img_id = self.ids[index] + img_metadata = coco.loadImgs(img_id)[0] + path = img_metadata['file_name'] + _img = Image.open(os.path.join(self.img_dir, path)).convert('RGB') + cocotarget = coco.loadAnns(coco.getAnnIds(imgIds=img_id)) + _target = Image.fromarray(self._gen_seg_mask( + cocotarget, img_metadata['height'], img_metadata['width'])) + + return _img, _target + + def _preprocess(self, ids, ids_file): + print("Preprocessing mask, this will take a while. " + \ + "But don't worry, it only run once for each split.") + tbar = trange(len(ids)) + new_ids = [] + for i in tbar: + img_id = ids[i] + cocotarget = self.coco.loadAnns(self.coco.getAnnIds(imgIds=img_id)) + img_metadata = self.coco.loadImgs(img_id)[0] + mask = self._gen_seg_mask(cocotarget, img_metadata['height'], + img_metadata['width']) + # more than 1k pixels + if (mask > 0).sum() > 1000: + new_ids.append(img_id) + tbar.set_description('Doing: {}/{}, got {} qualified images'. \ + format(i, len(ids), len(new_ids))) + print('Found number of qualified images: ', len(new_ids)) + torch.save(new_ids, ids_file) + return new_ids + + def _gen_seg_mask(self, target, h, w): + mask = np.zeros((h, w), dtype=np.uint8) + coco_mask = self.coco_mask + for instance in target: + rle = coco_mask.frPyObjects(instance['segmentation'], h, w) + m = coco_mask.decode(rle) + cat = instance['category_id'] + if cat in self.CAT_LIST: + c = self.CAT_LIST.index(cat) + else: + continue + if len(m.shape) < 3: + mask[:, :] += (mask == 0) * (m * c) + else: + mask[:, :] += (mask == 0) * (((np.sum(m, axis=2)) > 0) * c).astype(np.uint8) + return mask + + def transform_tr(self, sample): + composed_transforms = transforms.Compose([ + tr.RandomHorizontalFlip(), + tr.RandomScaleCrop(base_size=self.args.base_size, crop_size=self.args.crop_size), + tr.RandomGaussianBlur(), + tr.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)), + tr.ToTensor()]) + + return composed_transforms(sample) + + def transform_val(self, sample): + + composed_transforms = transforms.Compose([ + tr.FixScaleCrop(crop_size=self.args.crop_size), + tr.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)), + tr.ToTensor()]) + + return composed_transforms(sample) + + + def __len__(self): + return len(self.ids) + + + +if __name__ == "__main__": + from dataloaders import custom_transforms as tr + from dataloaders.utils import decode_segmap + from torch.utils.data import DataLoader + from torchvision import transforms + import matplotlib.pyplot as plt + import argparse + + parser = argparse.ArgumentParser() + args = parser.parse_args() + args.base_size = 513 + args.crop_size = 513 + + coco_val = COCOSegmentation(args, split='val', year='2017') + + dataloader = DataLoader(coco_val, batch_size=4, shuffle=True, num_workers=0) + + for ii, sample in enumerate(dataloader): + for jj in range(sample["image"].size()[0]): + img = sample['image'].numpy() + gt = sample['label'].numpy() + tmp = np.array(gt[jj]).astype(np.uint8) + segmap = decode_segmap(tmp, dataset='coco') + img_tmp = np.transpose(img[jj], axes=[1, 2, 0]) + img_tmp *= (0.229, 0.224, 0.225) + img_tmp += (0.485, 0.456, 0.406) + img_tmp *= 255.0 + img_tmp = img_tmp.astype(np.uint8) + plt.figure() + plt.title('display') + plt.subplot(211) + plt.imshow(img_tmp) + plt.subplot(212) + plt.imshow(segmap) + + if ii == 1: + break + + plt.show(block=True) \ No newline at end of file diff --git a/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/combine_dbs.py b/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/combine_dbs.py new file mode 100644 index 0000000..73ece2b --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/combine_dbs.py @@ -0,0 +1,100 @@ +import torch.utils.data as data + + +class CombineDBs(data.Dataset): + NUM_CLASSES = 21 + def __init__(self, dataloaders, excluded=None): + self.dataloaders = dataloaders + self.excluded = excluded + self.im_ids = [] + + # Combine object lists + for dl in dataloaders: + for elem in dl.im_ids: + if elem not in self.im_ids: + self.im_ids.append(elem) + + # Exclude + if excluded: + for dl in excluded: + for elem in dl.im_ids: + if elem in self.im_ids: + self.im_ids.remove(elem) + + # Get object pointers + self.cat_list = [] + self.im_list = [] + new_im_ids = [] + num_images = 0 + for ii, dl in enumerate(dataloaders): + for jj, curr_im_id in enumerate(dl.im_ids): + if (curr_im_id in self.im_ids) and (curr_im_id not in new_im_ids): + num_images += 1 + new_im_ids.append(curr_im_id) + self.cat_list.append({'db_ii': ii, 'cat_ii': jj}) + + self.im_ids = new_im_ids + print('Combined number of images: {:d}'.format(num_images)) + + def __getitem__(self, index): + + _db_ii = self.cat_list[index]["db_ii"] + _cat_ii = self.cat_list[index]['cat_ii'] + sample = self.dataloaders[_db_ii].__getitem__(_cat_ii) + + if 'meta' in sample.keys(): + sample['meta']['db'] = str(self.dataloaders[_db_ii]) + + return sample + + def __len__(self): + return len(self.cat_list) + + def __str__(self): + include_db = [str(db) for db in self.dataloaders] + exclude_db = [str(db) for db in self.excluded] + return 'Included datasets:'+str(include_db)+'\n'+'Excluded datasets:'+str(exclude_db) + + +if __name__ == "__main__": + import matplotlib.pyplot as plt + from dataloaders.datasets import pascal, sbd + from dataloaders import sbd + import torch + import numpy as np + from dataloaders.utils import decode_segmap + import argparse + + parser = argparse.ArgumentParser() + args = parser.parse_args() + args.base_size = 513 + args.crop_size = 513 + + pascal_voc_val = pascal.VOCSegmentation(args, split='val') + sbd = sbd.SBDSegmentation(args, split=['train', 'val']) + pascal_voc_train = pascal.VOCSegmentation(args, split='train') + + dataset = CombineDBs([pascal_voc_train, sbd], excluded=[pascal_voc_val]) + dataloader = torch.utils.data.DataLoader(dataset, batch_size=2, shuffle=True, num_workers=0) + + for ii, sample in enumerate(dataloader): + for jj in range(sample["image"].size()[0]): + img = sample['image'].numpy() + gt = sample['label'].numpy() + tmp = np.array(gt[jj]).astype(np.uint8) + segmap = decode_segmap(tmp, dataset='pascal') + img_tmp = np.transpose(img[jj], axes=[1, 2, 0]) + img_tmp *= (0.229, 0.224, 0.225) + img_tmp += (0.485, 0.456, 0.406) + img_tmp *= 255.0 + img_tmp = img_tmp.astype(np.uint8) + plt.figure() + plt.title('display') + plt.subplot(211) + plt.imshow(img_tmp) + plt.subplot(212) + plt.imshow(segmap) + + if ii == 1: + break + plt.show(block=True) \ No newline at end of file diff --git a/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/pascal.py b/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/pascal.py new file mode 100644 index 0000000..0ab1fc9 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/pascal.py @@ -0,0 +1,145 @@ +from __future__ import print_function, division +import os +from PIL import Image +import numpy as np +from torch.utils.data import Dataset +from mypath import Path +from torchvision import transforms +from dataloaders import custom_transforms as tr + +class VOCSegmentation(Dataset): + """ + PascalVoc dataset + """ + NUM_CLASSES = 21 + + def __init__(self, + args, + base_dir=Path.db_root_dir('pascal'), + split='train', + ): + """ + :param base_dir: path to VOC dataset directory + :param split: train/val + :param transform: transform to apply + """ + super().__init__() + self._base_dir = base_dir + self._image_dir = os.path.join(self._base_dir, 'JPEGImages') + self._cat_dir = os.path.join(self._base_dir, 'SegmentationClass') + + if isinstance(split, str): + self.split = [split] + else: + split.sort() + self.split = split + + self.args = args + + _splits_dir = os.path.join(self._base_dir, 'ImageSets', 'Segmentation') + + self.im_ids = [] + self.images = [] + self.categories = [] + + for splt in self.split: + with open(os.path.join(os.path.join(_splits_dir, splt + '.txt')), "r") as f: + lines = f.read().splitlines() + + for ii, line in enumerate(lines): + _image = os.path.join(self._image_dir, line + ".jpg") + _cat = os.path.join(self._cat_dir, line + ".png") + assert os.path.isfile(_image) + assert os.path.isfile(_cat) + self.im_ids.append(line) + self.images.append(_image) + self.categories.append(_cat) + + assert (len(self.images) == len(self.categories)) + + # Display stats + print('Number of images in {}: {:d}'.format(split, len(self.images))) + + def __len__(self): + return len(self.images) + + + def __getitem__(self, index): + _img, _target = self._make_img_gt_point_pair(index) + sample = {'image': _img, 'label': _target} + + for split in self.split: + if split == "train": + return self.transform_tr(sample) + elif split == 'val': + return self.transform_val(sample) + + + def _make_img_gt_point_pair(self, index): + _img = Image.open(self.images[index]).convert('RGB') + _target = Image.open(self.categories[index]) + + return _img, _target + + def transform_tr(self, sample): + composed_transforms = transforms.Compose([ + tr.RandomHorizontalFlip(), + tr.FixScaleCrop(crop_size=self.args.crop_size), + tr.RandomGaussianBlur(), + tr.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)), + tr.ToTensor()]) + + return composed_transforms(sample) + + def transform_val(self, sample): + + composed_transforms = transforms.Compose([ + tr.FixScaleCrop(crop_size=self.args.crop_size), + tr.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)), + tr.ToTensor()]) + + return composed_transforms(sample) + + def __str__(self): + return 'VOC2012(split=' + str(self.split) + ')' + + +if __name__ == '__main__': + from dataloaders.utils import decode_segmap + from torch.utils.data import DataLoader + import matplotlib.pyplot as plt + import argparse + + parser = argparse.ArgumentParser() + args = parser.parse_args() + args.base_size = 513 + args.crop_size = 513 + + voc_train = VOCSegmentation(args, split='train') + + dataloader = DataLoader(voc_train, batch_size=5, shuffle=True, num_workers=0) + + for ii, sample in enumerate(dataloader): + for jj in range(sample["image"].size()[0]): + img = sample['image'].numpy() + gt = sample['label'].numpy() + tmp = np.array(gt[jj]).astype(np.uint8) + segmap = decode_segmap(tmp, dataset='pascal') + img_tmp = np.transpose(img[jj], axes=[1, 2, 0]) + img_tmp *= (0.229, 0.224, 0.225) + img_tmp += (0.485, 0.456, 0.406) + img_tmp *= 255.0 + img_tmp = img_tmp.astype(np.uint8) + plt.figure() + plt.title('display') + plt.subplot(211) + plt.imshow(img_tmp) + plt.subplot(212) + plt.imshow(segmap) + + if ii == 1: + break + + plt.show(block=True) + + diff --git a/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/sbd.py b/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/sbd.py new file mode 100644 index 0000000..bd3755d --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/dataloaders/datasets/sbd.py @@ -0,0 +1,129 @@ +from __future__ import print_function, division +import os + +import numpy as np +import scipy.io +import torch.utils.data as data +from PIL import Image +from mypath import Path + +from torchvision import transforms +from dataloaders import custom_transforms as tr + +class SBDSegmentation(data.Dataset): + NUM_CLASSES = 21 + + def __init__(self, + args, + base_dir=Path.db_root_dir('sbd'), + split='train', + ): + """ + :param base_dir: path to VOC dataset directory + :param split: train/val + :param transform: transform to apply + """ + super().__init__() + self._base_dir = base_dir + self._dataset_dir = os.path.join(self._base_dir, 'dataset') + self._image_dir = os.path.join(self._dataset_dir, 'img') + self._cat_dir = os.path.join(self._dataset_dir, 'cls') + + + if isinstance(split, str): + self.split = [split] + else: + split.sort() + self.split = split + + self.args = args + + # Get list of all images from the split and check that the files exist + self.im_ids = [] + self.images = [] + self.categories = [] + for splt in self.split: + with open(os.path.join(self._dataset_dir, splt + '.txt'), "r") as f: + lines = f.read().splitlines() + + for line in lines: + _image = os.path.join(self._image_dir, line + ".jpg") + _categ= os.path.join(self._cat_dir, line + ".mat") + assert os.path.isfile(_image) + assert os.path.isfile(_categ) + self.im_ids.append(line) + self.images.append(_image) + self.categories.append(_categ) + + assert (len(self.images) == len(self.categories)) + + # Display stats + print('Number of images: {:d}'.format(len(self.images))) + + + def __getitem__(self, index): + _img, _target = self._make_img_gt_point_pair(index) + sample = {'image': _img, 'label': _target} + + return self.transform(sample) + + def __len__(self): + return len(self.images) + + def _make_img_gt_point_pair(self, index): + _img = Image.open(self.images[index]).convert('RGB') + _target = Image.fromarray(scipy.io.loadmat(self.categories[index])["GTcls"][0]['Segmentation'][0]) + + return _img, _target + + def transform(self, sample): + composed_transforms = transforms.Compose([ + tr.RandomHorizontalFlip(), + tr.RandomScaleCrop(base_size=self.args.base_size, crop_size=self.args.crop_size), + tr.RandomGaussianBlur(), + tr.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)), + tr.ToTensor()]) + + return composed_transforms(sample) + + + def __str__(self): + return 'SBDSegmentation(split=' + str(self.split) + ')' + + +if __name__ == '__main__': + from dataloaders.utils import decode_segmap + from torch.utils.data import DataLoader + import matplotlib.pyplot as plt + import argparse + + parser = argparse.ArgumentParser() + args = parser.parse_args() + args.base_size = 513 + args.crop_size = 513 + + sbd_train = SBDSegmentation(args, split='train') + dataloader = DataLoader(sbd_train, batch_size=2, shuffle=True, num_workers=2) + + for ii, sample in enumerate(dataloader): + for jj in range(sample["image"].size()[0]): + img = sample['image'].numpy() + gt = sample['label'].numpy() + tmp = np.array(gt[jj]).astype(np.uint8) + segmap = decode_segmap(tmp, dataset='pascal') + img_tmp = np.transpose(img[jj], axes=[1, 2, 0]) + img_tmp *= (0.229, 0.224, 0.225) + img_tmp += (0.485, 0.456, 0.406) + img_tmp *= 255.0 + img_tmp = img_tmp.astype(np.uint8) + plt.figure() + plt.title('display') + plt.subplot(211) + plt.imshow(img_tmp) + plt.subplot(212) + plt.imshow(segmap) + + if ii == 1: + break + + plt.show(block=True) \ No newline at end of file diff --git a/examples/performance_models/pytorch-deeplab-xception/dataloaders/utils.py b/examples/performance_models/pytorch-deeplab-xception/dataloaders/utils.py new file mode 100644 index 0000000..b4a80ba --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/dataloaders/utils.py @@ -0,0 +1,101 @@ +import matplotlib.pyplot as plt +import numpy as np +import torch + +def decode_seg_map_sequence(label_masks, dataset='pascal'): + rgb_masks = [] + for label_mask in label_masks: + rgb_mask = decode_segmap(label_mask, dataset) + rgb_masks.append(rgb_mask) + rgb_masks = torch.from_numpy(np.array(rgb_masks).transpose([0, 3, 1, 2])) + return rgb_masks + + +def decode_segmap(label_mask, dataset, plot=False): + """Decode segmentation class labels into a color image + Args: + label_mask (np.ndarray): an (M,N) array of integer values denoting + the class label at each spatial location. + plot (bool, optional): whether to show the resulting color image + in a figure. + Returns: + (np.ndarray, optional): the resulting decoded color image. + """ + if dataset == 'pascal' or dataset == 'coco': + n_classes = 21 + label_colours = get_pascal_labels() + elif dataset == 'cityscapes': + n_classes = 19 + label_colours = get_cityscapes_labels() + else: + raise NotImplementedError + + r = label_mask.copy() + g = label_mask.copy() + b = label_mask.copy() + for ll in range(0, n_classes): + r[label_mask == ll] = label_colours[ll, 0] + g[label_mask == ll] = label_colours[ll, 1] + b[label_mask == ll] = label_colours[ll, 2] + rgb = np.zeros((label_mask.shape[0], label_mask.shape[1], 3)) + rgb[:, :, 0] = r / 255.0 + rgb[:, :, 1] = g / 255.0 + rgb[:, :, 2] = b / 255.0 + if plot: + plt.imshow(rgb) + plt.show() + else: + return rgb + + +def encode_segmap(mask): + """Encode segmentation label images as pascal classes + Args: + mask (np.ndarray): raw segmentation label image of dimension + (M, N, 3), in which the Pascal classes are encoded as colours. + Returns: + (np.ndarray): class map with dimensions (M,N), where the value at + a given location is the integer denoting the class index. + """ + mask = mask.astype(int) + label_mask = np.zeros((mask.shape[0], mask.shape[1]), dtype=np.int16) + for ii, label in enumerate(get_pascal_labels()): + label_mask[np.where(np.all(mask == label, axis=-1))[:2]] = ii + label_mask = label_mask.astype(int) + return label_mask + + +def get_cityscapes_labels(): + return np.array([ + [128, 64, 128], + [244, 35, 232], + [70, 70, 70], + [102, 102, 156], + [190, 153, 153], + [153, 153, 153], + [250, 170, 30], + [220, 220, 0], + [107, 142, 35], + [152, 251, 152], + [0, 130, 180], + [220, 20, 60], + [255, 0, 0], + [0, 0, 142], + [0, 0, 70], + [0, 60, 100], + [0, 80, 100], + [0, 0, 230], + [119, 11, 32]]) + + +def get_pascal_labels(): + """Load the mapping that associates pascal classes with label colors + Returns: + np.ndarray with dimensions (21, 3) + """ + return np.asarray([[0, 0, 0], [128, 0, 0], [0, 128, 0], [128, 128, 0], + [0, 0, 128], [128, 0, 128], [0, 128, 128], [128, 128, 128], + [64, 0, 0], [192, 0, 0], [64, 128, 0], [192, 128, 0], + [64, 0, 128], [192, 0, 128], [64, 128, 128], [192, 128, 128], + [0, 64, 0], [128, 64, 0], [0, 192, 0], [128, 192, 0], + [0, 64, 128]]) \ No newline at end of file diff --git a/examples/performance_models/pytorch-deeplab-xception/doc/deeplab_resnet.py b/examples/performance_models/pytorch-deeplab-xception/doc/deeplab_resnet.py new file mode 100644 index 0000000..6e623ab --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/doc/deeplab_resnet.py @@ -0,0 +1,315 @@ +import math +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.model_zoo as model_zoo +from modeling.sync_batchnorm.batchnorm import SynchronizedBatchNorm2d + +BatchNorm2d = SynchronizedBatchNorm2d + +class Bottleneck(nn.Module): + expansion = 4 + + def __init__(self, inplanes, planes, stride=1, dilation=1, downsample=None): + super(Bottleneck, self).__init__() + self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False) + self.bn1 = BatchNorm2d(planes) + self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, + dilation=dilation, padding=dilation, bias=False) + self.bn2 = BatchNorm2d(planes) + self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False) + self.bn3 = BatchNorm2d(planes * 4) + self.relu = nn.ReLU(inplace=True) + self.downsample = downsample + self.stride = stride + self.dilation = dilation + + def forward(self, x): + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + out = self.relu(out) + + out = self.conv3(out) + out = self.bn3(out) + + if self.downsample is not None: + residual = self.downsample(x) + + out += residual + out = self.relu(out) + + return out + +class ResNet(nn.Module): + + def __init__(self, nInputChannels, block, layers, os=16, pretrained=False): + self.inplanes = 64 + super(ResNet, self).__init__() + if os == 16: + strides = [1, 2, 2, 1] + dilations = [1, 1, 1, 2] + blocks = [1, 2, 4] + elif os == 8: + strides = [1, 2, 1, 1] + dilations = [1, 1, 2, 2] + blocks = [1, 2, 1] + else: + raise NotImplementedError + + # Modules + self.conv1 = nn.Conv2d(nInputChannels, 64, kernel_size=7, stride=2, padding=3, + bias=False) + self.bn1 = BatchNorm2d(64) + self.relu = nn.ReLU(inplace=True) + self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) + + self.layer1 = self._make_layer(block, 64, layers[0], stride=strides[0], dilation=dilations[0]) + self.layer2 = self._make_layer(block, 128, layers[1], stride=strides[1], dilation=dilations[1]) + self.layer3 = self._make_layer(block, 256, layers[2], stride=strides[2], dilation=dilations[2]) + self.layer4 = self._make_MG_unit(block, 512, blocks=blocks, stride=strides[3], dilation=dilations[3]) + + self._init_weight() + + if pretrained: + self._load_pretrained_model() + + def _make_layer(self, block, planes, blocks, stride=1, dilation=1): + downsample = None + if stride != 1 or self.inplanes != planes * block.expansion: + downsample = nn.Sequential( + nn.Conv2d(self.inplanes, planes * block.expansion, + kernel_size=1, stride=stride, bias=False), + BatchNorm2d(planes * block.expansion), + ) + + layers = [] + layers.append(block(self.inplanes, planes, stride, dilation, downsample)) + self.inplanes = planes * block.expansion + for i in range(1, blocks): + layers.append(block(self.inplanes, planes)) + + return nn.Sequential(*layers) + + def _make_MG_unit(self, block, planes, blocks=[1, 2, 4], stride=1, dilation=1): + downsample = None + if stride != 1 or self.inplanes != planes * block.expansion: + downsample = nn.Sequential( + nn.Conv2d(self.inplanes, planes * block.expansion, + kernel_size=1, stride=stride, bias=False), + BatchNorm2d(planes * block.expansion), + ) + + layers = [] + layers.append(block(self.inplanes, planes, stride, dilation=blocks[0]*dilation, downsample=downsample)) + self.inplanes = planes * block.expansion + for i in range(1, len(blocks)): + layers.append(block(self.inplanes, planes, stride=1, dilation=blocks[i]*dilation)) + + return nn.Sequential(*layers) + + def forward(self, input): + x = self.conv1(input) + x = self.bn1(x) + x = self.relu(x) + x = self.maxpool(x) + + x = self.layer1(x) + low_level_feat = x + x = self.layer2(x) + x = self.layer3(x) + x = self.layer4(x) + return x, low_level_feat + + def _init_weight(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + m.weight.data.normal_(0, math.sqrt(2. / n)) + elif isinstance(m, BatchNorm2d): + m.weight.data.fill_(1) + m.bias.data.zero_() + + def _load_pretrained_model(self): + pretrain_dict = model_zoo.load_url('https://download.pytorch.org/models/resnet101-5d3b4d8f.pth') + model_dict = {} + state_dict = self.state_dict() + for k, v in pretrain_dict.items(): + if k in state_dict: + model_dict[k] = v + state_dict.update(model_dict) + self.load_state_dict(state_dict) + +def ResNet101(nInputChannels=3, os=16, pretrained=False): + model = ResNet(nInputChannels, Bottleneck, [3, 4, 23, 3], os, pretrained=pretrained) + return model + + +class ASPP_module(nn.Module): + def __init__(self, inplanes, planes, dilation): + super(ASPP_module, self).__init__() + if dilation == 1: + kernel_size = 1 + padding = 0 + else: + kernel_size = 3 + padding = dilation + self.atrous_convolution = nn.Conv2d(inplanes, planes, kernel_size=kernel_size, + stride=1, padding=padding, dilation=dilation, bias=False) + self.bn = BatchNorm2d(planes) + self.relu = nn.ReLU() + + self._init_weight() + + def forward(self, x): + x = self.atrous_convolution(x) + x = self.bn(x) + + return self.relu(x) + + def _init_weight(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + m.weight.data.normal_(0, math.sqrt(2. / n)) + elif isinstance(m, BatchNorm2d): + m.weight.data.fill_(1) + m.bias.data.zero_() + + +class DeepLabv3_plus(nn.Module): + def __init__(self, nInputChannels=3, n_classes=21, os=16, pretrained=False, freeze_bn=False, _print=True): + if _print: + print("Constructing DeepLabv3+ model...") + print("Backbone: Resnet-101") + print("Number of classes: {}".format(n_classes)) + print("Output stride: {}".format(os)) + print("Number of Input Channels: {}".format(nInputChannels)) + super(DeepLabv3_plus, self).__init__() + + # Atrous Conv + self.resnet_features = ResNet101(nInputChannels, os, pretrained=pretrained) + + # ASPP + if os == 16: + dilations = [1, 6, 12, 18] + elif os == 8: + dilations = [1, 12, 24, 36] + else: + raise NotImplementedError + + self.aspp1 = ASPP_module(2048, 256, dilation=dilations[0]) + self.aspp2 = ASPP_module(2048, 256, dilation=dilations[1]) + self.aspp3 = ASPP_module(2048, 256, dilation=dilations[2]) + self.aspp4 = ASPP_module(2048, 256, dilation=dilations[3]) + + self.relu = nn.ReLU() + + self.global_avg_pool = nn.Sequential(nn.AdaptiveAvgPool2d((1, 1)), + nn.Conv2d(2048, 256, 1, stride=1, bias=False), + BatchNorm2d(256), + nn.ReLU()) + + self.conv1 = nn.Conv2d(1280, 256, 1, bias=False) + self.bn1 = BatchNorm2d(256) + + # adopt [1x1, 48] for channel reduction. + self.conv2 = nn.Conv2d(256, 48, 1, bias=False) + self.bn2 = BatchNorm2d(48) + + self.last_conv = nn.Sequential(nn.Conv2d(304, 256, kernel_size=3, stride=1, padding=1, bias=False), + BatchNorm2d(256), + nn.ReLU(), + nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1, bias=False), + BatchNorm2d(256), + nn.ReLU(), + nn.Conv2d(256, n_classes, kernel_size=1, stride=1)) + if freeze_bn: + self._freeze_bn() + + def forward(self, input): + x, low_level_features = self.resnet_features(input) + x1 = self.aspp1(x) + x2 = self.aspp2(x) + x3 = self.aspp3(x) + x4 = self.aspp4(x) + x5 = self.global_avg_pool(x) + x5 = F.upsample(x5, size=x4.size()[2:], mode='bilinear', align_corners=True) + + x = torch.cat((x1, x2, x3, x4, x5), dim=1) + + x = self.conv1(x) + x = self.bn1(x) + x = self.relu(x) + x = F.upsample(x, size=(int(math.ceil(input.size()[-2]/4)), + int(math.ceil(input.size()[-1]/4))), mode='bilinear', align_corners=True) + + low_level_features = self.conv2(low_level_features) + low_level_features = self.bn2(low_level_features) + low_level_features = self.relu(low_level_features) + + + x = torch.cat((x, low_level_features), dim=1) + x = self.last_conv(x) + x = F.interpolate(x, size=input.size()[2:], mode='bilinear', align_corners=True) + + return x + + def _freeze_bn(self): + for m in self.modules(): + if isinstance(m, BatchNorm2d): + m.eval() + + def _init_weight(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + m.weight.data.normal_(0, math.sqrt(2. / n)) + elif isinstance(m, BatchNorm2d): + m.weight.data.fill_(1) + m.bias.data.zero_() + +def get_1x_lr_params(model): + """ + This generator returns all the parameters of the net except for + the last classification layer. Note that for each batchnorm layer, + requires_grad is set to False in deeplab_resnet.py, therefore this function does not return + any batchnorm parameter + """ + b = [model.resnet_features] + for i in range(len(b)): + for k in b[i].parameters(): + if k.requires_grad: + yield k + + +def get_10x_lr_params(model): + """ + This generator returns all the parameters for the last layer of the net, + which does the classification of pixel into classes + """ + b = [model.aspp1, model.aspp2, model.aspp3, model.aspp4, model.conv1, model.conv2, model.last_conv] + for j in range(len(b)): + for k in b[j].parameters(): + if k.requires_grad: + yield k + + +if __name__ == "__main__": + model = DeepLabv3_plus(nInputChannels=3, n_classes=21, os=16, pretrained=True, _print=True) + model.eval() + image = torch.randn(1, 3, 512, 512) + with torch.no_grad(): + output = model.forward(image) + print(output.size()) + + + + + + diff --git a/examples/performance_models/pytorch-deeplab-xception/doc/deeplab_xception.py b/examples/performance_models/pytorch-deeplab-xception/doc/deeplab_xception.py new file mode 100644 index 0000000..3d202d6 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/doc/deeplab_xception.py @@ -0,0 +1,424 @@ +import math +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.model_zoo as model_zoo +from modeling.sync_batchnorm.batchnorm import SynchronizedBatchNorm2d + +BatchNorm2d = SynchronizedBatchNorm2d + +class SeparableConv2d(nn.Module): + def __init__(self, inplanes, planes, kernel_size=3, stride=1, padding=0, dilation=1, bias=False): + super(SeparableConv2d, self)._init_() + + self.conv1 = nn.Conv2d(inplanes, inplanes, kernel_size, stride, padding, dilation, + groups=inplanes, bias=bias) + self.pointwise = nn.Conv2d(inplanes, planes, 1, 1, 0, 1, 1, bias=bias) + + def forward(self, x): + x = self.conv1(x) + x = self.pointwise(x) + return x + + +def fixed_padding(inputs, kernel_size, dilation): + kernel_size_effective = kernel_size + (kernel_size - 1) * (dilation - 1) + pad_total = kernel_size_effective - 1 + pad_beg = pad_total // 2 + pad_end = pad_total - pad_beg + padded_inputs = F.pad(inputs, (pad_beg, pad_end, pad_beg, pad_end)) + return padded_inputs + + +class SeparableConv2d_same(nn.Module): + def __init__(self, inplanes, planes, kernel_size=3, stride=1, dilation=1, bias=False): + super(SeparableConv2d_same, self).__init__() + + self.conv1 = nn.Conv2d(inplanes, inplanes, kernel_size, stride, 0, dilation, + groups=inplanes, bias=bias) + self.pointwise = nn.Conv2d(inplanes, planes, 1, 1, 0, 1, 1, bias=bias) + + def forward(self, x): + x = fixed_padding(x, self.conv1.kernel_size[0], dilation=self.conv1.dilation[0]) + x = self.conv1(x) + x = self.pointwise(x) + return x + + +class Block(nn.Module): + def __init__(self, inplanes, planes, reps, stride=1, dilation=1, start_with_relu=True, grow_first=True, is_last=False): + super(Block, self).__init__() + + if planes != inplanes or stride != 1: + self.skip = nn.Conv2d(inplanes, planes, 1, stride=stride, bias=False) + self.skipbn = BatchNorm2d(planes) + else: + self.skip = None + + self.relu = nn.ReLU(inplace=True) + rep = [] + + filters = inplanes + if grow_first: + rep.append(self.relu) + rep.append(SeparableConv2d_same(inplanes, planes, 3, stride=1, dilation=dilation)) + rep.append(BatchNorm2d(planes)) + filters = planes + + for i in range(reps - 1): + rep.append(self.relu) + rep.append(SeparableConv2d_same(filters, filters, 3, stride=1, dilation=dilation)) + rep.append(BatchNorm2d(filters)) + + if not grow_first: + rep.append(self.relu) + rep.append(SeparableConv2d_same(inplanes, planes, 3, stride=1, dilation=dilation)) + rep.append(BatchNorm2d(planes)) + + if not start_with_relu: + rep = rep[1:] + + if stride != 1: + rep.append(SeparableConv2d_same(planes, planes, 3, stride=2)) + + if stride == 1 and is_last: + rep.append(SeparableConv2d_same(planes, planes, 3, stride=1)) + + + self.rep = nn.Sequential(*rep) + + def forward(self, inp): + x = self.rep(inp) + + if self.skip is not None: + skip = self.skip(inp) + skip = self.skipbn(skip) + else: + skip = inp + + x += skip + + return x + + +class Xception(nn.Module): + """ + Modified Alighed Xception + """ + def __init__(self, inplanes=3, os=16, pretrained=False): + super(Xception, self).__init__() + + if os == 16: + entry_block3_stride = 2 + middle_block_dilation = 1 + exit_block_dilations = (1, 2) + elif os == 8: + entry_block3_stride = 1 + middle_block_dilation = 2 + exit_block_dilations = (2, 4) + else: + raise NotImplementedError + + + # Entry flow + self.conv1 = nn.Conv2d(inplanes, 32, 3, stride=2, padding=1, bias=False) + self.bn1 = BatchNorm2d(32) + self.relu = nn.ReLU(inplace=True) + + self.conv2 = nn.Conv2d(32, 64, 3, stride=1, padding=1, bias=False) + self.bn2 = BatchNorm2d(64) + + self.block1 = Block(64, 128, reps=2, stride=2, start_with_relu=False) + self.block2 = Block(128, 256, reps=2, stride=2, start_with_relu=True, grow_first=True) + self.block3 = Block(256, 728, reps=2, stride=entry_block3_stride, start_with_relu=True, grow_first=True, + is_last=True) + + # Middle flow + self.block4 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block5 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block6 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block7 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block8 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block9 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block10 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block11 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block12 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block13 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block14 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block15 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block16 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block17 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block18 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + self.block19 = Block(728, 728, reps=3, stride=1, dilation=middle_block_dilation, start_with_relu=True, grow_first=True) + + # Exit flow + self.block20 = Block(728, 1024, reps=2, stride=1, dilation=exit_block_dilations[0], + start_with_relu=True, grow_first=False, is_last=True) + + self.conv3 = SeparableConv2d_same(1024, 1536, 3, stride=1, dilation=exit_block_dilations[1]) + self.bn3 = BatchNorm2d(1536) + + self.conv4 = SeparableConv2d_same(1536, 1536, 3, stride=1, dilation=exit_block_dilations[1]) + self.bn4 = BatchNorm2d(1536) + + self.conv5 = SeparableConv2d_same(1536, 2048, 3, stride=1, dilation=exit_block_dilations[1]) + self.bn5 = BatchNorm2d(2048) + + # Init weights + self._init_weight() + + # Load pretrained model + if pretrained: + self._load_xception_pretrained() + + def forward(self, x): + # Entry flow + x = self.conv1(x) + x = self.bn1(x) + x = self.relu(x) + + x = self.conv2(x) + x = self.bn2(x) + x = self.relu(x) + + x = self.block1(x) + low_level_feat = x + x = self.block2(x) + x = self.block3(x) + + # Middle flow + x = self.block4(x) + x = self.block5(x) + x = self.block6(x) + x = self.block7(x) + x = self.block8(x) + x = self.block9(x) + x = self.block10(x) + x = self.block11(x) + x = self.block12(x) + x = self.block13(x) + x = self.block14(x) + x = self.block15(x) + x = self.block16(x) + x = self.block17(x) + x = self.block18(x) + x = self.block19(x) + + # Exit flow + x = self.block20(x) + x = self.conv3(x) + x = self.bn3(x) + x = self.relu(x) + + x = self.conv4(x) + x = self.bn4(x) + x = self.relu(x) + + x = self.conv5(x) + x = self.bn5(x) + x = self.relu(x) + + return x, low_level_feat + + def _init_weight(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + m.weight.data.normal_(0, math.sqrt(2. / n)) + elif isinstance(m, BatchNorm2d): + m.weight.data.fill_(1) + m.bias.data.zero_() + + def _load_xception_pretrained(self): + pretrain_dict = model_zoo.load_url('http://data.lip6.fr/cadene/pretrainedmodels/xception-b5690688.pth') + model_dict = {} + state_dict = self.state_dict() + + for k, v in pretrain_dict.items(): + if k in model_dict: + if 'pointwise' in k: + v = v.unsqueeze(-1).unsqueeze(-1) + if k.startswith('block11'): + model_dict[k] = v + model_dict[k.replace('block11', 'block12')] = v + model_dict[k.replace('block11', 'block13')] = v + model_dict[k.replace('block11', 'block14')] = v + model_dict[k.replace('block11', 'block15')] = v + model_dict[k.replace('block11', 'block16')] = v + model_dict[k.replace('block11', 'block17')] = v + model_dict[k.replace('block11', 'block18')] = v + model_dict[k.replace('block11', 'block19')] = v + elif k.startswith('block12'): + model_dict[k.replace('block12', 'block20')] = v + elif k.startswith('bn3'): + model_dict[k] = v + model_dict[k.replace('bn3', 'bn4')] = v + elif k.startswith('conv4'): + model_dict[k.replace('conv4', 'conv5')] = v + elif k.startswith('bn4'): + model_dict[k.replace('bn4', 'bn5')] = v + else: + model_dict[k] = v + state_dict.update(model_dict) + self.load_state_dict(state_dict) + +class ASPP_module(nn.Module): + def __init__(self, inplanes, planes, dilation): + super(ASPP_module, self).__init__() + if dilation == 1: + kernel_size = 1 + padding = 0 + else: + kernel_size = 3 + padding = dilation + self.atrous_convolution = nn.Conv2d(inplanes, planes, kernel_size=kernel_size, + stride=1, padding=padding, dilation=dilation, bias=False) + self.bn = BatchNorm2d(planes) + self.relu = nn.ReLU() + + self._init_weight() + + def forward(self, x): + x = self.atrous_convolution(x) + x = self.bn(x) + + return self.relu(x) + + def _init_weight(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + m.weight.data.normal_(0, math.sqrt(2. / n)) + elif isinstance(m, BatchNorm2d): + m.weight.data.fill_(1) + m.bias.data.zero_() + + +class DeepLabv3_plus(nn.Module): + def __init__(self, nInputChannels=3, n_classes=21, os=16, pretrained=False, freeze_bn=False, _print=True): + if _print: + print("Constructing DeepLabv3+ model...") + print("Backbone: Xception") + print("Number of classes: {}".format(n_classes)) + print("Output stride: {}".format(os)) + print("Number of Input Channels: {}".format(nInputChannels)) + super(DeepLabv3_plus, self).__init__() + + # Atrous Conv + self.xception_features = Xception(nInputChannels, os, pretrained) + + # ASPP + if os == 16: + dilations = [1, 6, 12, 18] + elif os == 8: + dilations = [1, 12, 24, 36] + else: + raise NotImplementedError + + self.aspp1 = ASPP_module(2048, 256, dilation=dilations[0]) + self.aspp2 = ASPP_module(2048, 256, dilation=dilations[1]) + self.aspp3 = ASPP_module(2048, 256, dilation=dilations[2]) + self.aspp4 = ASPP_module(2048, 256, dilation=dilations[3]) + + self.relu = nn.ReLU() + + self.global_avg_pool = nn.Sequential(nn.AdaptiveAvgPool2d((1, 1)), + nn.Conv2d(2048, 256, 1, stride=1, bias=False), + BatchNorm2d(256), + nn.ReLU()) + + self.conv1 = nn.Conv2d(1280, 256, 1, bias=False) + self.bn1 = BatchNorm2d(256) + + # adopt [1x1, 48] for channel reduction. + self.conv2 = nn.Conv2d(128, 48, 1, bias=False) + self.bn2 = BatchNorm2d(48) + + self.last_conv = nn.Sequential(nn.Conv2d(304, 256, kernel_size=3, stride=1, padding=1, bias=False), + BatchNorm2d(256), + nn.ReLU(), + nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1, bias=False), + BatchNorm2d(256), + nn.ReLU(), + nn.Conv2d(256, n_classes, kernel_size=1, stride=1)) + if freeze_bn: + self._freeze_bn() + + def forward(self, input): + x, low_level_features = self.xception_features(input) + x1 = self.aspp1(x) + x2 = self.aspp2(x) + x3 = self.aspp3(x) + x4 = self.aspp4(x) + x5 = self.global_avg_pool(x) + x5 = F.interpolate(x5, size=x4.size()[2:], mode='bilinear', align_corners=True) + + x = torch.cat((x1, x2, x3, x4, x5), dim=1) + + x = self.conv1(x) + x = self.bn1(x) + x = self.relu(x) + x = F.interpolate(x, size=(int(math.ceil(input.size()[-2]/4)), + int(math.ceil(input.size()[-1]/4))), mode='bilinear', align_corners=True) + + low_level_features = self.conv2(low_level_features) + low_level_features = self.bn2(low_level_features) + low_level_features = self.relu(low_level_features) + + + x = torch.cat((x, low_level_features), dim=1) + x = self.last_conv(x) + x = F.interpolate(x, size=input.size()[2:], mode='bilinear', align_corners=True) + + return x + + def _freeze_bn(self): + for m in self.modules(): + if isinstance(m, BatchNorm2d): + m.eval() + + def _init_weight(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + m.weight.data.normal_(0, math.sqrt(2. / n)) + elif isinstance(m, BatchNorm2d): + m.weight.data.fill_(1) + m.bias.data.zero_() + +def get_1x_lr_params(model): + """ + This generator returns all the parameters of the net except for + the last classification layer. Note that for each batchnorm layer, + requires_grad is set to False in deeplab_resnet.py, therefore this function does not return + any batchnorm parameter + """ + b = [model.xception_features] + for i in range(len(b)): + for k in b[i].parameters(): + if k.requires_grad: + yield k + + +def get_10x_lr_params(model): + """ + This generator returns all the parameters for the last layer of the net, + which does the classification of pixel into classes + """ + b = [model.aspp1, model.aspp2, model.aspp3, model.aspp4, model.conv1, model.conv2, model.last_conv] + for j in range(len(b)): + for k in b[j].parameters(): + if k.requires_grad: + yield k + + +if __name__ == "__main__": + model = DeepLabv3_plus(nInputChannels=3, n_classes=21, os=16, pretrained=True, _print=True) + model.eval() + image = torch.randn(1, 3, 512, 512) + with torch.no_grad(): + output = model.forward(image) + print(output.size()) + + + diff --git a/examples/performance_models/pytorch-deeplab-xception/doc/results.png b/examples/performance_models/pytorch-deeplab-xception/doc/results.png new file mode 100644 index 0000000000000000000000000000000000000000..4f182e3fef2c0421263ed1c15478244ede9b2fce GIT binary patch literal 521261 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

4raM?95X@xMTc(9n*a5o8pehd6u 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

%%5IXf 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 1, 'BatchNorm computes unbiased standard-deviation, which requires size > 1.' + mean = sum_ / size + sumvar = ssum - sum_ * mean + unbias_var = sumvar / (size - 1) + bias_var = sumvar / size + + self.running_mean = (1 - self.momentum) * self.running_mean + self.momentum * mean.data + self.running_var = (1 - self.momentum) * self.running_var + self.momentum * unbias_var.data + + return mean, bias_var.clamp(self.eps) ** -0.5 + + +class SynchronizedBatchNorm1d(_SynchronizedBatchNorm): + r"""Applies Synchronized Batch Normalization over a 2d or 3d input that is seen as a + mini-batch. + .. math:: + y = \frac{x - mean[x]}{ \sqrt{Var[x] + \epsilon}} * gamma + beta + This module differs from the built-in PyTorch BatchNorm1d as the mean and + standard-deviation are reduced across all devices during training. + For example, when one uses `nn.DataParallel` to wrap the network during + training, PyTorch's implementation normalize the tensor on each device using + the statistics only on that device, which accelerated the computation and + is also easy to implement, but the statistics might be inaccurate. + Instead, in this synchronized version, the statistics will be computed + over all training samples distributed on multiple devices. + + Note that, for one-GPU or CPU-only case, this module behaves exactly same + as the built-in PyTorch implementation. + The mean and standard-deviation are calculated per-dimension over + the mini-batches and gamma and beta are learnable parameter vectors + of size C (where C is the input size). + During training, this layer keeps a running estimate of its computed mean + and variance. The running sum is kept with a default momentum of 0.1. + During evaluation, this running mean/variance is used for normalization. + Because the BatchNorm is done over the `C` dimension, computing statistics + on `(N, L)` slices, it's common terminology to call this Temporal BatchNorm + Args: + num_features: num_features from an expected input of size + `batch_size x num_features [x width]` + eps: a value added to the denominator for numerical stability. + Default: 1e-5 + momentum: the value used for the running_mean and running_var + computation. Default: 0.1 + affine: a boolean value that when set to ``True``, gives the layer learnable + affine parameters. Default: ``True`` + Shape: + - Input: :math:`(N, C)` or :math:`(N, C, L)` + - Output: :math:`(N, C)` or :math:`(N, C, L)` (same shape as input) + Examples: + >>> # With Learnable Parameters + >>> m = SynchronizedBatchNorm1d(100) + >>> # Without Learnable Parameters + >>> m = SynchronizedBatchNorm1d(100, affine=False) + >>> input = torch.autograd.Variable(torch.randn(20, 100)) + >>> output = m(input) + """ + + def _check_input_dim(self, input): + if input.dim() != 2 and input.dim() != 3: + raise ValueError('expected 2D or 3D input (got {}D input)' + .format(input.dim())) + super(SynchronizedBatchNorm1d, self)._check_input_dim(input) + + +class SynchronizedBatchNorm2d(_SynchronizedBatchNorm): + r"""Applies Batch Normalization over a 4d input that is seen as a mini-batch + of 3d inputs + .. math:: + y = \frac{x - mean[x]}{ \sqrt{Var[x] + \epsilon}} * gamma + beta + This module differs from the built-in PyTorch BatchNorm2d as the mean and + standard-deviation are reduced across all devices during training. + For example, when one uses `nn.DataParallel` to wrap the network during + training, PyTorch's implementation normalize the tensor on each device using + the statistics only on that device, which accelerated the computation and + is also easy to implement, but the statistics might be inaccurate. + Instead, in this synchronized version, the statistics will be computed + over all training samples distributed on multiple devices. + + Note that, for one-GPU or CPU-only case, this module behaves exactly same + as the built-in PyTorch implementation. + The mean and standard-deviation are calculated per-dimension over + the mini-batches and gamma and beta are learnable parameter vectors + of size C (where C is the input size). + During training, this layer keeps a running estimate of its computed mean + and variance. The running sum is kept with a default momentum of 0.1. + During evaluation, this running mean/variance is used for normalization. + Because the BatchNorm is done over the `C` dimension, computing statistics + on `(N, H, W)` slices, it's common terminology to call this Spatial BatchNorm + Args: + num_features: num_features from an expected input of + size batch_size x num_features x height x width + eps: a value added to the denominator for numerical stability. + Default: 1e-5 + momentum: the value used for the running_mean and running_var + computation. Default: 0.1 + affine: a boolean value that when set to ``True``, gives the layer learnable + affine parameters. Default: ``True`` + Shape: + - Input: :math:`(N, C, H, W)` + - Output: :math:`(N, C, H, W)` (same shape as input) + Examples: + >>> # With Learnable Parameters + >>> m = SynchronizedBatchNorm2d(100) + >>> # Without Learnable Parameters + >>> m = SynchronizedBatchNorm2d(100, affine=False) + >>> input = torch.autograd.Variable(torch.randn(20, 100, 35, 45)) + >>> output = m(input) + """ + + def _check_input_dim(self, input): + if input.dim() != 4: + raise ValueError('expected 4D input (got {}D input)' + .format(input.dim())) + super(SynchronizedBatchNorm2d, self)._check_input_dim(input) + + +class SynchronizedBatchNorm3d(_SynchronizedBatchNorm): + r"""Applies Batch Normalization over a 5d input that is seen as a mini-batch + of 4d inputs + .. math:: + y = \frac{x - mean[x]}{ \sqrt{Var[x] + \epsilon}} * gamma + beta + This module differs from the built-in PyTorch BatchNorm3d as the mean and + standard-deviation are reduced across all devices during training. + For example, when one uses `nn.DataParallel` to wrap the network during + training, PyTorch's implementation normalize the tensor on each device using + the statistics only on that device, which accelerated the computation and + is also easy to implement, but the statistics might be inaccurate. + Instead, in this synchronized version, the statistics will be computed + over all training samples distributed on multiple devices. + + Note that, for one-GPU or CPU-only case, this module behaves exactly same + as the built-in PyTorch implementation. + The mean and standard-deviation are calculated per-dimension over + the mini-batches and gamma and beta are learnable parameter vectors + of size C (where C is the input size). + During training, this layer keeps a running estimate of its computed mean + and variance. The running sum is kept with a default momentum of 0.1. + During evaluation, this running mean/variance is used for normalization. + Because the BatchNorm is done over the `C` dimension, computing statistics + on `(N, D, H, W)` slices, it's common terminology to call this Volumetric BatchNorm + or Spatio-temporal BatchNorm + Args: + num_features: num_features from an expected input of + size batch_size x num_features x depth x height x width + eps: a value added to the denominator for numerical stability. + Default: 1e-5 + momentum: the value used for the running_mean and running_var + computation. Default: 0.1 + affine: a boolean value that when set to ``True``, gives the layer learnable + affine parameters. Default: ``True`` + Shape: + - Input: :math:`(N, C, D, H, W)` + - Output: :math:`(N, C, D, H, W)` (same shape as input) + Examples: + >>> # With Learnable Parameters + >>> m = SynchronizedBatchNorm3d(100) + >>> # Without Learnable Parameters + >>> m = SynchronizedBatchNorm3d(100, affine=False) + >>> input = torch.autograd.Variable(torch.randn(20, 100, 35, 45, 10)) + >>> output = m(input) + """ + + def _check_input_dim(self, input): + if input.dim() != 5: + raise ValueError('expected 5D input (got {}D input)' + .format(input.dim())) + super(SynchronizedBatchNorm3d, self)._check_input_dim(input) \ No newline at end of file diff --git a/examples/performance_models/pytorch-deeplab-xception/modeling/sync_batchnorm/comm.py b/examples/performance_models/pytorch-deeplab-xception/modeling/sync_batchnorm/comm.py new file mode 100644 index 0000000..8f2f701 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/modeling/sync_batchnorm/comm.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +# File : comm.py +# Author : Jiayuan Mao +# Email : maojiayuan@gmail.com +# Date : 27/01/2018 +# +# This file is part of Synchronized-BatchNorm-PyTorch. +# https://github.com/vacancy/Synchronized-BatchNorm-PyTorch +# Distributed under MIT License. + +import queue +import collections +import threading + +__all__ = ['FutureResult', 'SlavePipe', 'SyncMaster'] + + +class FutureResult(object): + """A thread-safe future implementation. Used only as one-to-one pipe.""" + + def __init__(self): + self._result = None + self._lock = threading.Lock() + self._cond = threading.Condition(self._lock) + + def put(self, result): + with self._lock: + assert self._result is None, 'Previous result has\'t been fetched.' + self._result = result + self._cond.notify() + + def get(self): + with self._lock: + if self._result is None: + self._cond.wait() + + res = self._result + self._result = None + return res + + +_MasterRegistry = collections.namedtuple('MasterRegistry', ['result']) +_SlavePipeBase = collections.namedtuple('_SlavePipeBase', ['identifier', 'queue', 'result']) + + +class SlavePipe(_SlavePipeBase): + """Pipe for master-slave communication.""" + + def run_slave(self, msg): + self.queue.put((self.identifier, msg)) + ret = self.result.get() + self.queue.put(True) + return ret + + +class SyncMaster(object): + """An abstract `SyncMaster` object. + - During the replication, as the data parallel will trigger an callback of each module, all slave devices should + call `register(id)` and obtain an `SlavePipe` to communicate with the master. + - During the forward pass, master device invokes `run_master`, all messages from slave devices will be collected, + and passed to a registered callback. + - After receiving the messages, the master device should gather the information and determine to message passed + back to each slave devices. + """ + + def __init__(self, master_callback): + """ + Args: + master_callback: a callback to be invoked after having collected messages from slave devices. + """ + self._master_callback = master_callback + self._queue = queue.Queue() + self._registry = collections.OrderedDict() + self._activated = False + + def __getstate__(self): + return {'master_callback': self._master_callback} + + def __setstate__(self, state): + self.__init__(state['master_callback']) + + def register_slave(self, identifier): + """ + Register an slave device. + Args: + identifier: an identifier, usually is the device id. + Returns: a `SlavePipe` object which can be used to communicate with the master device. + """ + if self._activated: + assert self._queue.empty(), 'Queue is not clean before next initialization.' + self._activated = False + self._registry.clear() + future = FutureResult() + self._registry[identifier] = _MasterRegistry(future) + return SlavePipe(identifier, self._queue, future) + + def run_master(self, master_msg): + """ + Main entry for the master device in each forward pass. + The messages were first collected from each devices (including the master device), and then + an callback will be invoked to compute the message to be sent back to each devices + (including the master device). + Args: + master_msg: the message that the master want to send to itself. This will be placed as the first + message when calling `master_callback`. For detailed usage, see `_SynchronizedBatchNorm` for an example. + Returns: the message to be sent back to the master device. + """ + self._activated = True + + intermediates = [(0, master_msg)] + for i in range(self.nr_slaves): + intermediates.append(self._queue.get()) + + results = self._master_callback(intermediates) + assert results[0][0] == 0, 'The first result should belongs to the master.' + + for i, res in results: + if i == 0: + continue + self._registry[i].result.put(res) + + for i in range(self.nr_slaves): + assert self._queue.get() is True + + return results[0][1] + + @property + def nr_slaves(self): + return len(self._registry) diff --git a/examples/performance_models/pytorch-deeplab-xception/modeling/sync_batchnorm/replicate.py b/examples/performance_models/pytorch-deeplab-xception/modeling/sync_batchnorm/replicate.py new file mode 100644 index 0000000..3734266 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/modeling/sync_batchnorm/replicate.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# File : replicate.py +# Author : Jiayuan Mao +# Email : maojiayuan@gmail.com +# Date : 27/01/2018 +# +# This file is part of Synchronized-BatchNorm-PyTorch. +# https://github.com/vacancy/Synchronized-BatchNorm-PyTorch +# Distributed under MIT License. + +import functools + +from torch.nn.parallel.data_parallel import DataParallel + +__all__ = [ + 'CallbackContext', + 'execute_replication_callbacks', + 'DataParallelWithCallback', + 'patch_replication_callback' +] + + +class CallbackContext(object): + pass + + +def execute_replication_callbacks(modules): + """ + Execute an replication callback `__data_parallel_replicate__` on each module created by original replication. + The callback will be invoked with arguments `__data_parallel_replicate__(ctx, copy_id)` + Note that, as all modules are isomorphism, we assign each sub-module with a context + (shared among multiple copies of this module on different devices). + Through this context, different copies can share some information. + We guarantee that the callback on the master copy (the first copy) will be called ahead of calling the callback + of any slave copies. + """ + master_copy = modules[0] + nr_modules = len(list(master_copy.modules())) + ctxs = [CallbackContext() for _ in range(nr_modules)] + + for i, module in enumerate(modules): + for j, m in enumerate(module.modules()): + if hasattr(m, '__data_parallel_replicate__'): + m.__data_parallel_replicate__(ctxs[j], i) + + +class DataParallelWithCallback(DataParallel): + """ + Data Parallel with a replication callback. + An replication callback `__data_parallel_replicate__` of each module will be invoked after being created by + original `replicate` function. + The callback will be invoked with arguments `__data_parallel_replicate__(ctx, copy_id)` + Examples: + > sync_bn = SynchronizedBatchNorm1d(10, eps=1e-5, affine=False) + > sync_bn = DataParallelWithCallback(sync_bn, device_ids=[0, 1]) + # sync_bn.__data_parallel_replicate__ will be invoked. + """ + + def replicate(self, module, device_ids): + modules = super(DataParallelWithCallback, self).replicate(module, device_ids) + execute_replication_callbacks(modules) + return modules + + +def patch_replication_callback(data_parallel): + """ + Monkey-patch an existing `DataParallel` object. Add the replication callback. + Useful when you have customized `DataParallel` implementation. + Examples: + > sync_bn = SynchronizedBatchNorm1d(10, eps=1e-5, affine=False) + > sync_bn = DataParallel(sync_bn, device_ids=[0, 1]) + > patch_replication_callback(sync_bn) + # this is equivalent to + > sync_bn = SynchronizedBatchNorm1d(10, eps=1e-5, affine=False) + > sync_bn = DataParallelWithCallback(sync_bn, device_ids=[0, 1]) + """ + + assert isinstance(data_parallel, DataParallel) + + old_replicate = data_parallel.replicate + + @functools.wraps(old_replicate) + def new_replicate(module, device_ids): + modules = old_replicate(module, device_ids) + execute_replication_callbacks(modules) + return modules + + data_parallel.replicate = new_replicate \ No newline at end of file diff --git a/examples/performance_models/pytorch-deeplab-xception/modeling/sync_batchnorm/unittest.py b/examples/performance_models/pytorch-deeplab-xception/modeling/sync_batchnorm/unittest.py new file mode 100644 index 0000000..f826560 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/modeling/sync_batchnorm/unittest.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# File : unittest.py +# Author : Jiayuan Mao +# Email : maojiayuan@gmail.com +# Date : 27/01/2018 +# +# This file is part of Synchronized-BatchNorm-PyTorch. +# https://github.com/vacancy/Synchronized-BatchNorm-PyTorch +# Distributed under MIT License. + +import unittest + +import numpy as np +from torch.autograd import Variable + + +def as_numpy(v): + if isinstance(v, Variable): + v = v.data + return v.cpu().numpy() + + +class TorchTestCase(unittest.TestCase): + def assertTensorClose(self, a, b, atol=1e-3, rtol=1e-3): + npa, npb = as_numpy(a), as_numpy(b) + self.assertTrue( + np.allclose(npa, npb, atol=atol), + 'Tensor close check failed\n{}\n{}\nadiff={}, rdiff={}'.format(a, b, np.abs(npa - npb).max(), np.abs((npa - npb) / np.fmax(npa, 1e-5)).max()) + ) diff --git a/examples/performance_models/pytorch-deeplab-xception/mypath.py b/examples/performance_models/pytorch-deeplab-xception/mypath.py new file mode 100644 index 0000000..89f6d6d --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/mypath.py @@ -0,0 +1,14 @@ +class Path(object): + @staticmethod + def db_root_dir(dataset): + if dataset == 'pascal': + return '/mnt/pai/home/yfeng/deeplab/VOCdevkit/VOC2012/' # folder that contains VOCdevkit/. + elif dataset == 'sbd': + return '/path/to/datasets/benchmark_RELEASE/' # folder that contains dataset/. + elif dataset == 'cityscapes': + return '/path/to/datasets/cityscapes/' # foler that contains leftImg8bit/ + elif dataset == 'coco': + return '/path/to/datasets/coco/' + else: + print('Dataset {} not available.'.format(dataset)) + raise NotImplementedError diff --git a/examples/performance_models/pytorch-deeplab-xception/train.py b/examples/performance_models/pytorch-deeplab-xception/train.py new file mode 100644 index 0000000..7b344c6 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/train.py @@ -0,0 +1,358 @@ +import argparse +import os +import numpy as np + +from mypath import Path +from dataloaders import make_data_loader +from modeling.sync_batchnorm.replicate import patch_replication_callback +from modeling.deeplab import * +from utils.loss import SegmentationLosses +from utils.calculate_weights import calculate_weigths_labels +from utils.lr_scheduler import LR_Scheduler +from utils.saver import Saver +from utils.summaries import TensorboardSummary +from utils.metrics import Evaluator +import time +from math import ceil +import torch +import torch.distributed as dist +import torch.nn.parallel +import pyddl +import os +import json + +class Trainer(object): + def __init__(self, args): + self.args = args + self.iterations = 0 + + # Define Saver + self.saver = Saver(args) + self.saver.save_experiment_config() + # Define Tensorboard Summary + self.summary = TensorboardSummary(self.saver.experiment_dir) + self.writer = self.summary.create_summary() + # Initialize distributed training + if args.cuda: + + if args.dist_backend == 'nccl': + os.environ["RANK"] = os.getenv('OMPI_COMM_WORLD_RANK') + os.environ["WORLD_SIZE"] = os.getenv('OMPI_COMM_WORLD_SIZE') + os.environ["MASTER_ADDR"] = self.args.master_addr + os.environ["MASTER_PORT"] = self.args.master_port + # DDL: Set device accoridng to local rank + torch.cuda.set_device(pyddl.local_rank()) + + # DDL: Init backend processor group & wrap model with DistributedDataParallel + dist.init_process_group(backend=self.args.dist_backend, init_method='env://') + + # Define Dataloader + kwargs = {'num_workers': args.workers, 'pin_memory': True, 'drop_last':True} + self.train_loader, self.val_loader, self.test_loader, self.nclass = make_data_loader(args, **kwargs) + + # Define network + model = DeepLab(num_classes=self.nclass, + backbone=args.backbone, + output_stride=args.out_stride, + sync_bn=args.sync_bn, + freeze_bn=args.freeze_bn) + + train_params = [{'params': model.get_1x_lr_params(), 'lr': args.lr}, + {'params': model.get_10x_lr_params(), 'lr': args.lr * 10}] + + # Define Optimizer + optimizer = torch.optim.SGD(train_params, momentum=args.momentum, + weight_decay=args.weight_decay, nesterov=args.nesterov) + + # Define Criterion + # whether to use class balanced weights + if args.use_balanced_weights: + classes_weights_path = os.path.join(Path.db_root_dir(args.dataset), args.dataset+'_classes_weights.npy') + if os.path.isfile(classes_weights_path): + weight = np.load(classes_weights_path) + else: + weight = calculate_weigths_labels(args.dataset, self.train_loader, self.nclass) + weight = torch.from_numpy(weight.astype(np.float32)) + else: + weight = None + self.criterion = SegmentationLosses(weight=weight, cuda=args.cuda).build_loss(mode=args.loss_type) + self.model, self.optimizer = model, optimizer + + # Define Evaluator + self.evaluator = Evaluator(self.nclass) + # Define lr scheduler + self.scheduler = LR_Scheduler(args.lr_scheduler, args.lr, + args.epochs, len(self.train_loader)) + + # Using cuda + if args.cuda: + # DDL: Convert model to use torch.nn.SyncBatchNorm. only for DistributedDataParallel gpu/process + self.model = self.model.cuda() + #self.model = torch.nn.SyncBatchNorm.convert_sync_batchnorm(self.model) + self.model = torch.nn.parallel.DistributedDataParallel(self.model, device_ids=[pyddl.local_rank()]) + #self.model = torch.nn.DataParallel(self.model, device_ids=self.args.gpu_ids) + #patch_replication_callback(self.model) + + # Resuming checkpoint + self.best_pred = 0.0 + if args.resume is not None: + if not os.path.isfile(args.resume): + raise RuntimeError("=> no checkpoint found at '{}'" .format(args.resume)) + checkpoint = torch.load(args.resume) + args.start_epoch = checkpoint['epoch'] + if args.cuda: + self.model.module.load_state_dict(checkpoint['state_dict']) + else: + self.model.load_state_dict(checkpoint['state_dict']) + if not args.ft: + self.optimizer.load_state_dict(checkpoint['optimizer']) + self.best_pred = checkpoint['best_pred'] + print("=> loaded checkpoint '{}' (epoch {})" + .format(args.resume, checkpoint['epoch'])) + + # Clear start epoch if fine-tuning + if args.ft: + args.start_epoch = 0 + + def training(self, epoch): + train_loss = 0.0 + self.model.train() + num_img_tr = len(self.train_loader) + for i, sample in enumerate(self.train_loader): + self.iterations += 1 + time_begin_iter = time.time() + image, target = sample['image'], sample['label'] + if self.args.cuda: + image, target = image.cuda(), target.cuda() + self.scheduler(self.optimizer, i, epoch, self.best_pred) + self.optimizer.zero_grad() + output = self.model(image) + loss = self.criterion(output, target) + loss.backward() + self.optimizer.step() + train_loss += loss.item() + time_end_iter = time.time() + + current_gpu = pyddl.local_rank() + max_active = torch.cuda.max_memory_active()/float(1024 ** 2) + reclaimed = torch.cuda.memory_reclaimed()/float(1024 ** 2) + duration = time_end_iter - time_begin_iter + alloc_dist = torch.cuda.alloc_distribution() + print("GPU=%s, max_active=%.2fMB, reclaimed=%.2fMB, step %4d: %3.3f(sec/step) dist=%s num_img_tr=%d" % (current_gpu, max_active, reclaimed, self.iterations, duration, json.dumps(alloc_dist),num_img_tr)) + torch.cuda.reset_max_memory_active() + torch.cuda.reset_memory_reclaimed() + torch.cuda.reset_alloc_distribution() + if self.iterations >= self.args.max_iterations: + break + #print('Train loss: %.3f' % (train_loss / (i + 1))) + self.writer.add_scalar('train/total_loss_iter', loss.item(), i + num_img_tr * epoch) + + # Show 10 * 3 inference results each epoch + #if i % (num_img_tr // 10) == 0: + # global_step = i + num_img_tr * epoch + # self.summary.visualize_image(self.writer, self.args.dataset, image, target, output, global_step) + + #self.writer.add_scalar('train/total_loss_epoch', train_loss, epoch) + print('[Epoch: %d, numImages: %5d]' % (epoch, i * self.args.batch_size + image.data.shape[0])) + #print('Loss: %.3f' % train_loss) + if pyddl.local_rank()==0: + if self.args.no_val: + # save checkpoint every epoch + is_best = False + self.saver.save_checkpoint({ + 'epoch': epoch + 1, + 'state_dict': self.model.module.state_dict(), + 'optimizer': self.optimizer.state_dict(), + 'best_pred': self.best_pred, + }, is_best) + + + def validation(self, epoch): + self.model.eval() + self.evaluator.reset() + test_loss = 0.0 + for i, sample in enumerate(self.val_loader): + image, target = sample['image'], sample['label'] + if self.args.cuda: + image, target = image.cuda(), target.cuda() + with torch.no_grad(): + output = self.model(image) + loss = self.criterion(output, target) + test_loss += loss.item() + print('Test loss: %.3f' % (test_loss / (i + 1))) + pred = output.data.cpu().numpy() + target = target.cpu().numpy() + pred = np.argmax(pred, axis=1) + # Add batch sample into evaluator + self.evaluator.add_batch(target, pred) + + # Fast test during the training + Acc = self.evaluator.Pixel_Accuracy() + Acc_class = self.evaluator.Pixel_Accuracy_Class() + mIoU = self.evaluator.Mean_Intersection_over_Union() + FWIoU = self.evaluator.Frequency_Weighted_Intersection_over_Union() + self.writer.add_scalar('val/total_loss_epoch', test_loss, epoch) + self.writer.add_scalar('val/mIoU', mIoU, epoch) + self.writer.add_scalar('val/Acc', Acc, epoch) + self.writer.add_scalar('val/Acc_class', Acc_class, epoch) + self.writer.add_scalar('val/fwIoU', FWIoU, epoch) + print('Validation:') + print('[Epoch: %d, numImages: %5d]' % (epoch, i * self.args.batch_size + image.data.shape[0])) + print("Acc:{}, Acc_class:{}, mIoU:{}, fwIoU: {}".format(Acc, Acc_class, mIoU, FWIoU)) + print('Loss: %.3f' % test_loss) + + new_pred = mIoU + if new_pred > self.best_pred: + is_best = True + self.best_pred = new_pred + self.saver.save_checkpoint({ + 'epoch': epoch + 1, + 'state_dict': self.model.module.state_dict(), + 'optimizer': self.optimizer.state_dict(), + 'best_pred': self.best_pred, + }, is_best) + +def main(): + #torch.cuda.set_enabled_lms(True) + parser = argparse.ArgumentParser(description="PyTorch DeeplabV3Plus Training") + parser.add_argument('--backbone', type=str, default='resnet', + choices=['resnet', 'xception', 'drn', 'mobilenet'], + help='backbone name (default: resnet)') + parser.add_argument('--out-stride', type=int, default=16, + help='network output stride (default: 8)') + parser.add_argument('--dataset', type=str, default='pascal', + choices=['pascal', 'coco', 'cityscapes'], + help='dataset name (default: pascal)') + parser.add_argument('--use-sbd', action='store_true', default=False, + help='whether to use SBD dataset (default: True)') + parser.add_argument('--workers', type=int, default=4, + metavar='N', help='dataloader threads') + parser.add_argument('--max-iterations', type=int, default=1000, + help='max iterations to run') + parser.add_argument('--base-size', type=int, default=513, + help='base image size') + parser.add_argument('--crop-size', type=int, default=513, + help='crop image size') + parser.add_argument('--sync-bn', type=bool, default=None, + help='whether to use sync bn (default: auto)') + parser.add_argument('--lms', action='store_true', default=False, + help=' where to turn on lms (default: True)') + parser.add_argument('--freeze-bn', type=bool, default=False, + help='whether to freeze bn parameters (default: False)') + parser.add_argument('--loss-type', type=str, default='ce', + choices=['ce', 'focal'], + help='loss func type (default: ce)') + # training hyper params + parser.add_argument('--epochs', type=int, default=None, metavar='N', + help='number of epochs to train (default: auto)') + parser.add_argument('--start_epoch', type=int, default=0, + metavar='N', help='start epochs (default:0)') + parser.add_argument('--batch-size', type=int, default=None, + metavar='N', help='input batch size for \ + training (default: auto)') + parser.add_argument('--test-batch-size', type=int, default=None, + metavar='N', help='input batch size for \ + testing (default: auto)') + parser.add_argument('--use-balanced-weights', action='store_true', default=False, + help='whether to use balanced weights (default: False)') + parser.add_argument('--set-limit-lms', type=int, default=0, + help='Define soft limit in bytes on GPU memory allocated for tensors ') + # optimizer params + parser.add_argument('--lr', type=float, default=None, metavar='LR', + help='learning rate (default: auto)') + parser.add_argument('--lr-scheduler', type=str, default='poly', + choices=['poly', 'step', 'cos'], + help='lr scheduler mode: (default: poly)') + parser.add_argument('--momentum', type=float, default=0.9, + metavar='M', help='momentum (default: 0.9)') + parser.add_argument('--weight-decay', type=float, default=5e-4, + metavar='M', help='w-decay (default: 5e-4)') + parser.add_argument('--nesterov', action='store_true', default=False, + help='whether use nesterov (default: False)') + # cuda, seed and logging + parser.add_argument('--no-cuda', action='store_true', default= + False, help='disables CUDA training') + parser.add_argument('--gpu-ids', type=str, default='0', + help='use which gpu to train, must be a \ + comma-separated list of integers only (default=0)') + parser.add_argument('--seed', type=int, default=1, metavar='S', + help='random seed (default: 1)') + # checking point + parser.add_argument('--resume', type=str, default=None, + help='put the path to resuming file if needed') + parser.add_argument('--checkname', type=str, default=None, + help='set the checkpoint name') + # finetuning pre-trained models + parser.add_argument('--ft', action='store_true', default=False, + help='finetuning on a different dataset') + # evaluation option + parser.add_argument('--eval-interval', type=int, default=1, + help='evaluuation interval (default: 1)') + parser.add_argument('--no-val', action='store_true', default=False, + help='skip validation during training') + parser.add_argument('--dist-backend', type=str, default='ddl', + help='Process group selected for DistributedDataParallel') + parser.add_argument('--master-addr', type=str, default='192.168.1.1', + help='Adress of Node containg rank 0') + parser.add_argument('--master-port', type=str, default='1234', + help='Free port open for communication') + + args = parser.parse_args() + if args.lms: + torch.cuda.set_enabled_lms(True) + torch.cuda.set_limit_lms(args.set_limit_lms) + args.cuda = not args.no_cuda and torch.cuda.is_available() + if args.cuda: + try: + args.gpu_ids = [int(s) for s in args.gpu_ids.split(',')] + except ValueError: + raise ValueError('Argument --gpu_ids must be a comma-separated list of integers only') + + if args.sync_bn is None: + if args.cuda and len(args.gpu_ids) > 1: + args.sync_bn = True + else: + args.sync_bn = False + + # default settings for epochs, batch_size and lr + if args.epochs is None: + epoches = { + 'coco': 30, + 'cityscapes': 200, + 'pascal': 50, + } + args.epochs = epoches[args.dataset.lower()] + + if args.batch_size is None: + args.batch_size = 4 * len(args.gpu_ids) + + if args.test_batch_size is None: + args.test_batch_size = args.batch_size + + if args.lr is None: + lrs = { + 'coco': 0.1, + 'cityscapes': 0.01, + 'pascal': 0.007, + } + args.lr = lrs[args.dataset.lower()] / (4 * len(args.gpu_ids)) * args.batch_size + + + if args.checkname is None: + args.checkname = 'deeplab-'+str(args.backbone) + print(args) + torch.manual_seed(args.seed) + trainer = Trainer(args) + print('Starting Epoch:', trainer.args.start_epoch) + print('Total Epoches:', trainer.args.epochs) + for epoch in range(trainer.args.start_epoch, trainer.args.epochs): + trainer.training(epoch) + if not trainer.args.no_val and epoch % args.eval_interval == (args.eval_interval - 1): + trainer.validation(epoch) + + trainer.writer.close() + +if __name__ == "__main__": + # Avoid deadlocks when using multiple worker processes for dataloading. + torch.multiprocessing.set_start_method('spawn') + main() diff --git a/examples/performance_models/pytorch-deeplab-xception/train_coco.sh b/examples/performance_models/pytorch-deeplab-xception/train_coco.sh new file mode 100644 index 0000000..e284a5a --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/train_coco.sh @@ -0,0 +1 @@ +CUDA_VISIBLE_DEVICES=0,1,2,3 python train.py --backbone resnet --lr 0.01 --workers 4 --epochs 40 --batch-size 16 --gpu-ids 0,1,2,3 --checkname deeplab-resnet --eval-interval 1 --dataset coco diff --git a/examples/performance_models/pytorch-deeplab-xception/train_voc.sh b/examples/performance_models/pytorch-deeplab-xception/train_voc.sh new file mode 100644 index 0000000..627a865 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/train_voc.sh @@ -0,0 +1,93 @@ +arch=$1 +res=$2 +batch_size=$3 +lms=$4 +num_gpu=$5 +alternate=$6 +max_iter=$7 +lms_limit=$8 +lms_limit=${lms_limit:-0} + +#Compute the batch size +#batch_size=$(( $num_gpu * $batch_size )) +epochs=$(( $batch_size* $max_iter * num_gpu )) +#epochs=$(( $epochs/1464)) +#echo "BATCH_SIZE="$batch_size + +#To account for the current number of epochs in the 4GPU case +epochs=$(python -c "from math import ceil;print(ceil($epochs/1464) + 2)") +inBytes=$(python -c "from math import floor;print(floor(${lms_limit}*1024*1024*1024))") + +echo "LMS limit in BYTES="$inBytes" GB="${lms_limit} +lms_limit=$inBytes +echo "LMS limit in BYTES="${lms_limit} + +echo "EPOCHS="$epochs + + +GPU_DEVICE_CMDLINE="CUDA_VISIBLE_DEVICES=" +GPU_IDS="--gpu-ids=" + +if [ "$num_gpu" = "1" ];then + GPU_DEVICE_CMDLINE+="0 " + GPU_IDS+="0 " + if [ "$arch" = "p9" ] + then + NUM_ACTL_CMDLINE=" numactl --cpunodebind=0 --membind=0 " + else + NUM_ACTL_CMDLINE="" + fi +fi + +if [ "$num_gpu" = "2" ];then + if [ "$alternate" = "yes" ]; then + GPU_DEVICE_CMDLINE+="0,2 " + GPU_IDS+="0,1 " + else + GPU_DEVICE_CMDLINE+="0,1 " + GPU_IDS+="0,1 " + fi +fi + +if [ "$num_gpu" = "4" ];then + if [ "$alternate" = "yes" ]; then + GPU_DEVICE_CMDLINE+="0,3,4,7 " + GPU_IDS+="0,1,2,3 " + else + GPU_DEVICE_CMDLINE+="0,1,2,3 " + GPU_IDS+="0,1,2,3 " + fi +fi + +if [ "$num_gpu" = "8" ];then + GPU_DEVICE_CMDLINE+="0,1,2,3,4,5,6,7 " + GPU_IDS+="0,1,2,3,4,5,6,7 " +fi + +#echo $GPU_DEVICE_CMDLINE +#echo $GPU_IDS + +if [ "$lms" = "lms" ];then + LMS_CMDLINE=" --lms " +else + LMS_CMDLINE=" " +fi + +CMD=$GPU_DEVICE_CMDLINE +CMD+=$NUM_ACTL_CMDLINE +CMD+="python train.py --backbone xception --lr 0.007 --workers 40 --checkname deeplab-xception --eval-interval 1 --dataset pascal --no-val " +CMD+=$GPU_IDS +CMD+=" --crop-size "${res} +CMD+=" --base-size "${res} +CMD+=" --batch-size "${batch_size} +CMD+=${LMS_CMDLINE} +CMD+=" --epochs "$epochs +CMD+=" --max-iterations "$max_iter +CMD+=" --set-limit-lms "$lms_limit + +# Pass in direct arguments to training script +CMD+=" ${@:9}" +echo $CMD +eval $CMD + +#CUDA_VISIBLE_DEVICES=0 python train.py --backbone xception --lr 0.007 --workers 4 --epochs 10 --gpu-ids 0 --checkname deeplab-xception --eval-interval 1 --dataset pascal --crop-size $res --base-size $res --batch-size $batch_size --no-val --lms diff --git a/examples/performance_models/pytorch-deeplab-xception/utils/calculate_weights.py b/examples/performance_models/pytorch-deeplab-xception/utils/calculate_weights.py new file mode 100644 index 0000000..2c2c982 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/utils/calculate_weights.py @@ -0,0 +1,29 @@ +import os +from tqdm import tqdm +import numpy as np +from mypath import Path + +def calculate_weigths_labels(dataset, dataloader, num_classes): + # Create an instance from the data loader + z = np.zeros((num_classes,)) + # Initialize tqdm + tqdm_batch = tqdm(dataloader) + print('Calculating classes weights') + for sample in tqdm_batch: + y = sample['label'] + y = y.detach().cpu().numpy() + mask = (y >= 0) & (y < num_classes) + labels = y[mask].astype(np.uint8) + count_l = np.bincount(labels, minlength=num_classes) + z += count_l + tqdm_batch.close() + total_frequency = np.sum(z) + class_weights = [] + for frequency in z: + class_weight = 1 / (np.log(1.02 + (frequency / total_frequency))) + class_weights.append(class_weight) + ret = np.array(class_weights) + classes_weights_path = os.path.join(Path.db_root_dir(dataset), dataset+'_classes_weights.npy') + np.save(classes_weights_path, ret) + + return ret \ No newline at end of file diff --git a/examples/performance_models/pytorch-deeplab-xception/utils/loss.py b/examples/performance_models/pytorch-deeplab-xception/utils/loss.py new file mode 100644 index 0000000..a3c3d33 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/utils/loss.py @@ -0,0 +1,63 @@ +import torch +import torch.nn as nn + +class SegmentationLosses(object): + def __init__(self, weight=None, size_average=True, batch_average=True, ignore_index=255, cuda=False): + self.ignore_index = ignore_index + self.weight = weight + self.size_average = size_average + self.batch_average = batch_average + self.cuda = cuda + + def build_loss(self, mode='ce'): + """Choices: ['ce' or 'focal']""" + if mode == 'ce': + return self.CrossEntropyLoss + elif mode == 'focal': + return self.FocalLoss + else: + raise NotImplementedError + + def CrossEntropyLoss(self, logit, target): + n, c, h, w = logit.size() + criterion = nn.CrossEntropyLoss(weight=self.weight, ignore_index=self.ignore_index, + size_average=self.size_average) + if self.cuda: + criterion = criterion.cuda() + + loss = criterion(logit, target.long()) + + if self.batch_average: + loss /= n + + return loss + + def FocalLoss(self, logit, target, gamma=2, alpha=0.5): + n, c, h, w = logit.size() + criterion = nn.CrossEntropyLoss(weight=self.weight, ignore_index=self.ignore_index, + size_average=self.size_average) + if self.cuda: + criterion = criterion.cuda() + + logpt = -criterion(logit, target.long()) + pt = torch.exp(logpt) + if alpha is not None: + logpt *= alpha + loss = -((1 - pt) ** gamma) * logpt + + if self.batch_average: + loss /= n + + return loss + +if __name__ == "__main__": + loss = SegmentationLosses(cuda=True) + a = torch.rand(1, 3, 7, 7).cuda() + b = torch.rand(1, 7, 7).cuda() + print(loss.CrossEntropyLoss(a, b).item()) + print(loss.FocalLoss(a, b, gamma=0, alpha=None).item()) + print(loss.FocalLoss(a, b, gamma=2, alpha=0.5).item()) + + + + diff --git a/examples/performance_models/pytorch-deeplab-xception/utils/lr_scheduler.py b/examples/performance_models/pytorch-deeplab-xception/utils/lr_scheduler.py new file mode 100644 index 0000000..0f790e6 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/utils/lr_scheduler.py @@ -0,0 +1,70 @@ +##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +## Created by: Hang Zhang +## ECE Department, Rutgers University +## Email: zhang.hang@rutgers.edu +## Copyright (c) 2017 +## +## This source code is licensed under the MIT-style license found in the +## LICENSE file in the root directory of this source tree +##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +import math + +class LR_Scheduler(object): + """Learning Rate Scheduler + + Step mode: ``lr = baselr * 0.1 ^ {floor(epoch-1 / lr_step)}`` + + Cosine mode: ``lr = baselr * 0.5 * (1 + cos(iter/maxiter))`` + + Poly mode: ``lr = baselr * (1 - iter/maxiter) ^ 0.9`` + + Args: + args: + :attr:`args.lr_scheduler` lr scheduler mode (`cos`, `poly`), + :attr:`args.lr` base learning rate, :attr:`args.epochs` number of epochs, + :attr:`args.lr_step` + + iters_per_epoch: number of iterations per epoch + """ + def __init__(self, mode, base_lr, num_epochs, iters_per_epoch=0, + lr_step=0, warmup_epochs=0): + self.mode = mode + print('Using {} LR Scheduler!'.format(self.mode)) + self.lr = base_lr + if mode == 'step': + assert lr_step + self.lr_step = lr_step + self.iters_per_epoch = iters_per_epoch + self.N = num_epochs * iters_per_epoch + self.epoch = -1 + self.warmup_iters = warmup_epochs * iters_per_epoch + + def __call__(self, optimizer, i, epoch, best_pred): + T = epoch * self.iters_per_epoch + i + if self.mode == 'cos': + lr = 0.5 * self.lr * (1 + math.cos(1.0 * T / self.N * math.pi)) + elif self.mode == 'poly': + lr = self.lr * pow((1 - 1.0 * T / self.N), 0.9) + elif self.mode == 'step': + lr = self.lr * (0.1 ** (epoch // self.lr_step)) + else: + raise NotImplemented + # warm up lr schedule + if self.warmup_iters > 0 and T < self.warmup_iters: + lr = lr * 1.0 * T / self.warmup_iters + if epoch > self.epoch: + print('\n=>Epoches %i, learning rate = %.4f, \ + previous best = %.4f' % (epoch, lr, best_pred)) + self.epoch = epoch + assert lr >= 0 + self._adjust_learning_rate(optimizer, lr) + + def _adjust_learning_rate(self, optimizer, lr): + if len(optimizer.param_groups) == 1: + optimizer.param_groups[0]['lr'] = lr + else: + # enlarge the lr at the head + optimizer.param_groups[0]['lr'] = lr + for i in range(1, len(optimizer.param_groups)): + optimizer.param_groups[i]['lr'] = lr * 10 diff --git a/examples/performance_models/pytorch-deeplab-xception/utils/metrics.py b/examples/performance_models/pytorch-deeplab-xception/utils/metrics.py new file mode 100644 index 0000000..58a7a1a --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/utils/metrics.py @@ -0,0 +1,50 @@ +import numpy as np + + +class Evaluator(object): + def __init__(self, num_class): + self.num_class = num_class + self.confusion_matrix = np.zeros((self.num_class,)*2) + + def Pixel_Accuracy(self): + Acc = np.diag(self.confusion_matrix).sum() / self.confusion_matrix.sum() + return Acc + + def Pixel_Accuracy_Class(self): + Acc = np.diag(self.confusion_matrix) / self.confusion_matrix.sum(axis=1) + Acc = np.nanmean(Acc) + return Acc + + def Mean_Intersection_over_Union(self): + MIoU = np.diag(self.confusion_matrix) / ( + np.sum(self.confusion_matrix, axis=1) + np.sum(self.confusion_matrix, axis=0) - + np.diag(self.confusion_matrix)) + MIoU = np.nanmean(MIoU) + return MIoU + + def Frequency_Weighted_Intersection_over_Union(self): + freq = np.sum(self.confusion_matrix, axis=1) / np.sum(self.confusion_matrix) + iu = np.diag(self.confusion_matrix) / ( + np.sum(self.confusion_matrix, axis=1) + np.sum(self.confusion_matrix, axis=0) - + np.diag(self.confusion_matrix)) + + FWIoU = (freq[freq > 0] * iu[freq > 0]).sum() + return FWIoU + + def _generate_matrix(self, gt_image, pre_image): + mask = (gt_image >= 0) & (gt_image < self.num_class) + label = self.num_class * gt_image[mask].astype('int') + pre_image[mask] + count = np.bincount(label, minlength=self.num_class**2) + confusion_matrix = count.reshape(self.num_class, self.num_class) + return confusion_matrix + + def add_batch(self, gt_image, pre_image): + assert gt_image.shape == pre_image.shape + self.confusion_matrix += self._generate_matrix(gt_image, pre_image) + + def reset(self): + self.confusion_matrix = np.zeros((self.num_class,) * 2) + + + + diff --git a/examples/performance_models/pytorch-deeplab-xception/utils/saver.py b/examples/performance_models/pytorch-deeplab-xception/utils/saver.py new file mode 100644 index 0000000..c462631 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/utils/saver.py @@ -0,0 +1,61 @@ +import os +import shutil +import torch +from collections import OrderedDict +import glob +import pyddl + +class Saver(object): + + def __init__(self, args): + self.args = args + self.directory = os.path.join('run', args.dataset, args.checkname) + self.runs = sorted(glob.glob(os.path.join(self.directory, 'experiment_*'))) + run_id = int(self.runs[-1].split('_')[-1]) + 1 if self.runs else 0 + # DDL: Create a folder for each process/gpu + self.experiment_dir = os.path.join(self.directory, 'experiment_{}'.format(str(run_id)), str(pyddl.rank())) + if not os.path.exists(self.experiment_dir): + os.makedirs(self.experiment_dir) + + def save_checkpoint(self, state, is_best, filename='checkpoint.pth.tar'): + """Saves checkpoint to disk""" + filename = os.path.join(self.experiment_dir, filename) + torch.save(state, filename) + if is_best: + best_pred = state['best_pred'] + with open(os.path.join(self.experiment_dir, 'best_pred.txt'), 'w') as f: + f.write(str(best_pred)) + if self.runs: + previous_miou = [0.0] + for run in self.runs: + run_id = run.split('_')[-1] + path = os.path.join(self.directory, 'experiment_{}'.format(str(run_id)), 'best_pred.txt') + if os.path.exists(path): + with open(path, 'r') as f: + miou = float(f.readline()) + previous_miou.append(miou) + else: + continue + max_miou = max(previous_miou) + if best_pred > max_miou: + shutil.copyfile(filename, os.path.join(self.directory, 'model_best.pth.tar')) + else: + shutil.copyfile(filename, os.path.join(self.directory, 'model_best.pth.tar')) + + def save_experiment_config(self): + logfile = os.path.join(self.experiment_dir, 'parameters.txt') + log_file = open(logfile, 'w') + p = OrderedDict() + p['datset'] = self.args.dataset + p['backbone'] = self.args.backbone + p['out_stride'] = self.args.out_stride + p['lr'] = self.args.lr + p['lr_scheduler'] = self.args.lr_scheduler + p['loss_type'] = self.args.loss_type + p['epoch'] = self.args.epochs + p['base_size'] = self.args.base_size + p['crop_size'] = self.args.crop_size + + for key, val in p.items(): + log_file.write(key + ':' + str(val) + '\n') + log_file.close() diff --git a/examples/performance_models/pytorch-deeplab-xception/utils/summaries.py b/examples/performance_models/pytorch-deeplab-xception/utils/summaries.py new file mode 100644 index 0000000..c9f40fc --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/utils/summaries.py @@ -0,0 +1,24 @@ +import os +import torch +from torchvision.utils import make_grid +from tensorboardX import SummaryWriter +from dataloaders.utils import decode_seg_map_sequence + +class TensorboardSummary(object): + def __init__(self, directory): + self.directory = directory + + def create_summary(self): + #log_dir is not longer used in newer tensorboardX + writer = SummaryWriter(os.path.join(self.directory)) + return writer + + def visualize_image(self, writer, dataset, image, target, output, global_step): + grid_image = make_grid(image[:3].clone().cpu().data, 3, normalize=True) + writer.add_image('Image', grid_image, global_step) + grid_image = make_grid(decode_seg_map_sequence(torch.max(output[:3], 1)[1].detach().cpu().numpy(), + dataset=dataset), 3, normalize=False, range=(0, 255)) + writer.add_image('Predicted label', grid_image, global_step) + grid_image = make_grid(decode_seg_map_sequence(torch.squeeze(target[:3], 1).detach().cpu().numpy(), + dataset=dataset), 3, normalize=False, range=(0, 255)) + writer.add_image('Groundtruth label', grid_image, global_step) From 469c9da85d3768dc57b31f723aa4e864e27ebba0 Mon Sep 17 00:00:00 2001 From: Naveen M Date: Mon, 9 Dec 2019 02:41:22 -0600 Subject: [PATCH 3/6] Scripts to launch deeplab --- .../research/deeplab_lmsv2.sh | 48 +++++++++++++++++++ .../research/launch_deeplab.sh | 9 ++++ 2 files changed, 57 insertions(+) create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab_lmsv2.sh create mode 100644 examples/performance_models/deeplabv3/tensorflow-models/research/launch_deeplab.sh diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab_lmsv2.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab_lmsv2.sh new file mode 100644 index 0000000..0253b0b --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab_lmsv2.sh @@ -0,0 +1,48 @@ +export TF_CUDA_HOST_MEM_LIMIT_IN_MB=500000 + +export TF_LMS_SIMULATOR_MEM_RATIO=1.0 + +export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim +cd .. +clones=1 +res=2100 +batch_size=1 +iter=4000 +lms=true +swapout_threshold=1 +swapin_ahead=1 +swapin_groupby=0 +sync_mode=0 + + + +echo "##############################################" + +echo "##############################################" + +echo "# Cuda_Host_Limit $TF_CUDA_HOST_MEM_LIMIT_IN_MB" +echo "# TF_Lms_Simulator_Mem_Ratio $TF_LMS_SIMULATOR_MEM_RATIO" +echo "# Use numactl ${use_numactl} " + +echo "# Running clones ${clones}" +echo "# Running resolution ${res}" +echo "# Running batchsize ${batch_size}" +echo "# Running iterations ${iter}" +echo "# Running lms ${lms}" + +if [ $lms = "true" ] +then +echo "# lmsv2 knob swapout_threshold ${swapout_threshold}" +echo "# lmsv2 knob swapin_ahead ${swapin_ahead}" +echo "# lmsv2 knob swapin_groupby ${swapin_groupby}" +echo "# lmsv2 knob sync_mode ${sync_mode}" +fi + +echo "##############################################" + +echo "##############################################" + +echo "###############AFTER###########################" +ls $HOME/Deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train/ + +python $HOME/Deeplabv3/tensorflow-models/research/deeplab/train.py --logtostderr --train_split=trainval --model_variant=xception_65 --atrous_rates=6 --atrous_rates=12 --atrous_rates=18 --output_stride=16 --decoder_output_stride=4 --train_batch_size=$batch_size --training_number_of_steps=$iter --fine_tune_batch_norm=true --tf_initial_checkpoint=$HOME/Deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/init_models/deeplabv3_pascal_train_aug/model.ckpt --train_logdir=$HOME/Deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train --dataset_dir=$HOME/Deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/tfrecord --train_crop_size=$res --train_crop_size=$res --use_tflms=$lms --num_clones=$clones --swapout_threshold=$swapout_threshold --swapin_ahead=$swapin_ahead --swapin_groupby=$swapin_groupby --sync_mode=$sync_mode --disable_layout_optimizer=true diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/launch_deeplab.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/launch_deeplab.sh new file mode 100644 index 0000000..c3e580d --- /dev/null +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/launch_deeplab.sh @@ -0,0 +1,9 @@ +#!/bin/bash +export CUDA_VISIBLE_DEVICES=0,1,2,3 + + +ls $HOME/Deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train/ +rm $HOME/Deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train/* +echo "-------------------REMOVED----------------" +ls $HOME/Deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train/ +ddlrun -t --accelerators 4 -m b ./deeplab_lmsv2.sh From 15eada821413d60ea53b097d38ef3040df009329 Mon Sep 17 00:00:00 2001 From: Naveen M Date: Mon, 9 Dec 2019 05:57:11 -0600 Subject: [PATCH 4/6] Scripts to launch deeplab and Steps to recreate the setup --- .../deeplabv3/RecreatingSteps.txt | 25 +++++++++++++++++++ .../research/deeplab/train.py | 2 +- .../research/deeplab_lmsv2.sh | 5 ++-- .../research/launch_deeplab.sh | 8 +++--- 4 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 examples/performance_models/deeplabv3/RecreatingSteps.txt mode change 100644 => 100755 examples/performance_models/deeplabv3/tensorflow-models/research/deeplab_lmsv2.sh diff --git a/examples/performance_models/deeplabv3/RecreatingSteps.txt b/examples/performance_models/deeplabv3/RecreatingSteps.txt new file mode 100644 index 0000000..7bbf7b6 --- /dev/null +++ b/examples/performance_models/deeplabv3/RecreatingSteps.txt @@ -0,0 +1,25 @@ +#Clone the repository from https://github.com/IBM/powerai +#Install WMLCE-1.6.1 (conda install powerai=1.6.1) + +#Apply the learning patch +cd powerai/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab +patch $CONDA_PREFIX/lib/python3.6/site-packages/tensorflow/contrib/slim/python/slim/learning.py < learning.py.patch + +#Download the dataset and convert to TF records +cd datasets +sh download_and_convert_voc2012.sh + +#Download the initial checkpoint +mkdir pascal_voc_seg/init_models +cd pascal_voc_seg/init_models/ +wget -nd -c http://download.tensorflow.org/models/deeplabv3_pascal_train_aug_2018_01_04.tar.gz +tar -xf deeplabv3_pascal_train_aug_2018_01_04.tar.gz +cd ../ +mkdir -p exp/train_on_trainval_set/train + +#Go back to the research directory +cd ./../../../ +chmod +x deeplab_lmsv2.sh +bash launch_deeplab.sh + + diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/train.py b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/train.py index 4975ef4..06fbcf6 100644 --- a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/train.py +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/train.py @@ -70,7 +70,7 @@ flags.DEFINE_integer('save_interval_secs', 1200, 'How often, in seconds, we save the model to disk.') -flags.DEFINE_integer('save_summaries_secs', 600, +flags.DEFINE_integer('save_summaries_secs', 600000000, 'How often, in seconds, we compute the summaries.') flags.DEFINE_boolean('save_summaries_images', False, diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab_lmsv2.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab_lmsv2.sh old mode 100644 new mode 100755 index 0253b0b..a8013fe --- a/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab_lmsv2.sh +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab_lmsv2.sh @@ -43,6 +43,7 @@ echo "##############################################" echo "##############################################" echo "###############AFTER###########################" -ls $HOME/Deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train/ +ls $HOME/powerai/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train/ +#/home/cuml/powerai/examples/performance_models/deeplabv3/tensorflow-models/research -python $HOME/Deeplabv3/tensorflow-models/research/deeplab/train.py --logtostderr --train_split=trainval --model_variant=xception_65 --atrous_rates=6 --atrous_rates=12 --atrous_rates=18 --output_stride=16 --decoder_output_stride=4 --train_batch_size=$batch_size --training_number_of_steps=$iter --fine_tune_batch_norm=true --tf_initial_checkpoint=$HOME/Deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/init_models/deeplabv3_pascal_train_aug/model.ckpt --train_logdir=$HOME/Deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train --dataset_dir=$HOME/Deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/tfrecord --train_crop_size=$res --train_crop_size=$res --use_tflms=$lms --num_clones=$clones --swapout_threshold=$swapout_threshold --swapin_ahead=$swapin_ahead --swapin_groupby=$swapin_groupby --sync_mode=$sync_mode --disable_layout_optimizer=true +python $HOME/powerai/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/train.py --logtostderr --train_split=trainval --model_variant=xception_65 --atrous_rates=6 --atrous_rates=12 --atrous_rates=18 --output_stride=16 --decoder_output_stride=4 --train_batch_size=$batch_size --training_number_of_steps=$iter --fine_tune_batch_norm=true --tf_initial_checkpoint=$HOME/powerai/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/init_models/deeplabv3_pascal_train_aug/model.ckpt --train_logdir=$HOME/powerai/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train --dataset_dir=$HOME/powerai/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/tfrecord --train_crop_size=$res --train_crop_size=$res --use_tflms=$lms --num_clones=$clones --swapout_threshold=$swapout_threshold --swapin_ahead=$swapin_ahead --swapin_groupby=$swapin_groupby --sync_mode=$sync_mode --disable_layout_optimizer=True diff --git a/examples/performance_models/deeplabv3/tensorflow-models/research/launch_deeplab.sh b/examples/performance_models/deeplabv3/tensorflow-models/research/launch_deeplab.sh index c3e580d..83d8b84 100644 --- a/examples/performance_models/deeplabv3/tensorflow-models/research/launch_deeplab.sh +++ b/examples/performance_models/deeplabv3/tensorflow-models/research/launch_deeplab.sh @@ -2,8 +2,8 @@ export CUDA_VISIBLE_DEVICES=0,1,2,3 -ls $HOME/Deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train/ -rm $HOME/Deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train/* +ls $HOME/powerai/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train/ +rm $HOME/powerai/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train/* echo "-------------------REMOVED----------------" -ls $HOME/Deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train/ -ddlrun -t --accelerators 4 -m b ./deeplab_lmsv2.sh +ls $HOME/powerai/examples/performance_models/deeplabv3/tensorflow-models/research/deeplab/datasets/pascal_voc_seg/exp/train_on_trainval_set/train/ +ddlrun --mpiarg -pami_noib --accelerators 4 -m b ./deeplab_lmsv2.sh From da320a15410a0fae93edccf9c3a80cee80175f9d Mon Sep 17 00:00:00 2001 From: Naveen M Date: Mon, 9 Dec 2019 07:16:42 -0600 Subject: [PATCH 5/6] Scripts to launch and recreate the deeplab LMS observations for Pytorch --- .../pytorch-deeplab-xception/RecreateSteps.txt | 13 +++++++++++++ .../pytorch-deeplab-xception/launch_deeplab.sh | 1 + .../pytorch-deeplab-xception/train.py | 7 ++----- .../pytorch-deeplab-xception/train_voc.sh | 2 +- 4 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 examples/performance_models/pytorch-deeplab-xception/RecreateSteps.txt create mode 100644 examples/performance_models/pytorch-deeplab-xception/launch_deeplab.sh diff --git a/examples/performance_models/pytorch-deeplab-xception/RecreateSteps.txt b/examples/performance_models/pytorch-deeplab-xception/RecreateSteps.txt new file mode 100644 index 0000000..f039e63 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/RecreateSteps.txt @@ -0,0 +1,13 @@ +#Install WMLCE-1.6.1 +1. Perform a "conda install tqdm" in the same environment as the WMLCE-1.6.1 +2. Install tensorboardx using " conda install -c conda-forge tensorboardx=1.6" + +#Open mypath.py and in line number 5 ,set the path to downloaded VOC2012 dataset + if dataset == 'pascal': + 5 return '/mnt/pai/home/yfeng/deeplab/VOCdevkit/VOC2012/' + +#Launch the run +bash launch_deeplab.sh + +Notes: +The first launch will download a checkpoint from the below location -"http://data.lip6.fr/cadene/pretrainedmodels/xception-b5690688.pth" diff --git a/examples/performance_models/pytorch-deeplab-xception/launch_deeplab.sh b/examples/performance_models/pytorch-deeplab-xception/launch_deeplab.sh new file mode 100644 index 0000000..2de5014 --- /dev/null +++ b/examples/performance_models/pytorch-deeplab-xception/launch_deeplab.sh @@ -0,0 +1 @@ + ddlrun --mpiarg -pami_noib --accelerators 4 -m b bash train_voc.sh p9 2200 2 lms 4 no 4000 diff --git a/examples/performance_models/pytorch-deeplab-xception/train.py b/examples/performance_models/pytorch-deeplab-xception/train.py index 7b344c6..917bcd2 100644 --- a/examples/performance_models/pytorch-deeplab-xception/train.py +++ b/examples/performance_models/pytorch-deeplab-xception/train.py @@ -135,13 +135,10 @@ def training(self, epoch): current_gpu = pyddl.local_rank() max_active = torch.cuda.max_memory_active()/float(1024 ** 2) - reclaimed = torch.cuda.memory_reclaimed()/float(1024 ** 2) duration = time_end_iter - time_begin_iter - alloc_dist = torch.cuda.alloc_distribution() - print("GPU=%s, max_active=%.2fMB, reclaimed=%.2fMB, step %4d: %3.3f(sec/step) dist=%s num_img_tr=%d" % (current_gpu, max_active, reclaimed, self.iterations, duration, json.dumps(alloc_dist),num_img_tr)) + if self.iterations % 10 == 0: + print("GPU=%s, max_active=%.2fMB, step %4d: %3.3f(sec/step) num_img_tr=%d" % (current_gpu, max_active, self.iterations, duration, num_img_tr)) torch.cuda.reset_max_memory_active() - torch.cuda.reset_memory_reclaimed() - torch.cuda.reset_alloc_distribution() if self.iterations >= self.args.max_iterations: break #print('Train loss: %.3f' % (train_loss / (i + 1))) diff --git a/examples/performance_models/pytorch-deeplab-xception/train_voc.sh b/examples/performance_models/pytorch-deeplab-xception/train_voc.sh index 627a865..1042207 100644 --- a/examples/performance_models/pytorch-deeplab-xception/train_voc.sh +++ b/examples/performance_models/pytorch-deeplab-xception/train_voc.sh @@ -75,7 +75,7 @@ fi CMD=$GPU_DEVICE_CMDLINE CMD+=$NUM_ACTL_CMDLINE -CMD+="python train.py --backbone xception --lr 0.007 --workers 40 --checkname deeplab-xception --eval-interval 1 --dataset pascal --no-val " +CMD+="python train.py --backbone xception --lr 0.007 --workers 4 --checkname deeplab-xception --eval-interval 1 --dataset pascal --no-val " CMD+=$GPU_IDS CMD+=" --crop-size "${res} CMD+=" --base-size "${res} From 8dabb1e0e729d3b449c59c1f0f4013bc665beacc Mon Sep 17 00:00:00 2001 From: Naveen M Date: Tue, 10 Dec 2019 00:00:51 -0600 Subject: [PATCH 6/6] Added a Readme to the location of the performance models and their setup --- examples/performance_models/README.txt | 12 ++++++++++++ .../{RecreatingSteps.txt => RecreateSteps.txt} | 0 .../deeplabv3/tensorflow-models/README.md | 5 ++--- .../pytorch-deeplab-xception/RecreateSteps.txt | 2 +- .../pytorch-deeplab-xception/mypath.py | 2 +- 5 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 examples/performance_models/README.txt rename examples/performance_models/deeplabv3/{RecreatingSteps.txt => RecreateSteps.txt} (100%) diff --git a/examples/performance_models/README.txt b/examples/performance_models/README.txt new file mode 100644 index 0000000..a163f19 --- /dev/null +++ b/examples/performance_models/README.txt @@ -0,0 +1,12 @@ +This directory contains the Deeplabv3+ Tensorflow and Pytorch models with LMS(Large Model Support) enabled that can run on WMLCE-1.6.1 + +Deeplabv3+ model with Tensorflow LMS: +"powerai/examples/performance_models/deeplabv3" +Steps for setup -- "powerai/examples/performance_models/deeplabv3 /RecreateSteps.txt" +The code is from https://github.com/tensorflow/models at commit `078575a121c79f1f1594b03f5bc70bbf0b3fb744` + + +Deeplabv3+ model with Pytorch LMS: +"powerai/examples/performance_models/pytorch-deeplab-xception" +Steps for setup -- "powerai/examples/performance_models/pytorch-deeplab-xception/RecreateSteps.txt +The code is from https://github.com/jfzhang95/pytorch-deeplab-xception at commit 'c8ff02c6eeb2b774ad5a25557a60ee48e04635c6' diff --git a/examples/performance_models/deeplabv3/RecreatingSteps.txt b/examples/performance_models/deeplabv3/RecreateSteps.txt similarity index 100% rename from examples/performance_models/deeplabv3/RecreatingSteps.txt rename to examples/performance_models/deeplabv3/RecreateSteps.txt diff --git a/examples/performance_models/deeplabv3/tensorflow-models/README.md b/examples/performance_models/deeplabv3/tensorflow-models/README.md index 9168ffd..df4f48e 100644 --- a/examples/performance_models/deeplabv3/tensorflow-models/README.md +++ b/examples/performance_models/deeplabv3/tensorflow-models/README.md @@ -1,8 +1,7 @@ -The repository code in the powerai-1.6.0 branch -came from https://github.com/tensorflow/models at commit `078575a121c79f1f1594b03f5bc70bbf0b3fb744`. +The code is from https://github.com/tensorflow/models at commit `078575a121c79f1f1594b03f5bc70bbf0b3fb744`. It contains the DeepLabV3+ model that was used for the TensorFlow Large Model -Support performance investigation on top of PowerAI 1.6.0. +Support performance investigation on top of WMLCE-1.6.1 # TensorFlow Models diff --git a/examples/performance_models/pytorch-deeplab-xception/RecreateSteps.txt b/examples/performance_models/pytorch-deeplab-xception/RecreateSteps.txt index f039e63..683c91e 100644 --- a/examples/performance_models/pytorch-deeplab-xception/RecreateSteps.txt +++ b/examples/performance_models/pytorch-deeplab-xception/RecreateSteps.txt @@ -4,7 +4,7 @@ #Open mypath.py and in line number 5 ,set the path to downloaded VOC2012 dataset if dataset == 'pascal': - 5 return '/mnt/pai/home/yfeng/deeplab/VOCdevkit/VOC2012/' + 5 return '/path/to/VOCdevkit/VOC2012/' #Launch the run bash launch_deeplab.sh diff --git a/examples/performance_models/pytorch-deeplab-xception/mypath.py b/examples/performance_models/pytorch-deeplab-xception/mypath.py index 89f6d6d..40fed48 100644 --- a/examples/performance_models/pytorch-deeplab-xception/mypath.py +++ b/examples/performance_models/pytorch-deeplab-xception/mypath.py @@ -2,7 +2,7 @@ class Path(object): @staticmethod def db_root_dir(dataset): if dataset == 'pascal': - return '/mnt/pai/home/yfeng/deeplab/VOCdevkit/VOC2012/' # folder that contains VOCdevkit/. + return '/path/to/VOCdevkit/VOC2012/' # folder that contains VOCdevkit/. . Please specify the full path here elif dataset == 'sbd': return '/path/to/datasets/benchmark_RELEASE/' # folder that contains dataset/. elif dataset == 'cityscapes':