From 373a7a14eea49f6ff23f61f80412229609b00951 Mon Sep 17 00:00:00 2001 From: Oindrila Saha Date: Sat, 3 Oct 2020 01:44:20 +0530 Subject: [PATCH] Merge RNNPool Codes (#201) * added bidirectional * bidirectional in BaseRNN * updated all rnn for new bidirectional * debugging for fastgrnncuda * fix for fastgrnncuda * visual wakeword * visual wakewords evaluation * visual wakeword evaluation * updated readme for eval * face detection * update face detection * rnn edit * test update * model loading change * update readme * update eval tools in readme * update train * readme * readme * readme * requirements * requirements * readme * rnn * update s3fd_net * update s3fd_net * update s3fd_net * train * train * add additional args * add additional args * arg changes in wider_test * added arg for using new ckpt * readme * remove old modelsupport * readme * readme * requirements * readme * eval on all format * support for calculating MAP * update readme * Update README.md * readme * readme * readme * readme * fix for warnings * readme * readme scores * add dump weights and traces support * readme * remove eval warnings * eval remove import warnings * readme changes * readme changes * support for qvga monochrome * readme update * readme update * Update README.md * readme update * environment key update * config files * update both config files text * change architecture * readme update * quantized cpp rnnpool * Update README.md * Update README.md * Update README.md * smaller model for qvga * Update RPool_Face_QVGA_monochrome.py * update to ssd code * update to init * update to init * update to dataloader * tf code for face detection * tf code for face detection * add tf face detection code * eval file * fix weights and detect function * Delete factory.py * Update RPool_Face_QVGA_monochrome.py * Update RPool_Face_QVGA_monochrome.py * Update RPool_Face_C.py * Update RPool_Face_Quant.py * Update augmentations.py * Update detection.py * Update eval.py * vww updates * removed tf code * Update fastcell_example.py * Update widerface.py * Update rnnpool.py * Update fastTrainer.py * Update fastTrainer.py * Update fastTrainer.py * Update model_mobilenet_2rnnpool.py * Update model_mobilenet_rnnpool.py * Delete top_level.txt * Delete dependency_links.txt * remove egg-info * Update fastcell_example.py * file copyright edits * Update README.md * delete output blank file * remove input trace file Co-authored-by: Harsha Vardhan Simhadri Co-authored-by: Ubuntu Co-authored-by: Harsha Vardhan Simhadri --- .../pytorch/vision/Face_Detection/README.md | 146 + .../vision/Face_Detection/data/__init__.py | 31 + .../Face_Detection/data/choose_config.py | 15 + .../vision/Face_Detection/data/config.py | 65 + .../vision/Face_Detection/data/config_qvga.py | 64 + .../vision/Face_Detection/data/widerface.py | 115 + .../vision/Face_Detection/dump_model.py | 191 + .../pytorch/vision/Face_Detection/eval.py | 133 + .../vision/Face_Detection/imrgb20ft.png | Bin 0 -> 399556 bytes .../vision/Face_Detection/layers/__init__.py | 5 + .../Face_Detection/layers/bbox_utils.py | 306 + .../layers/functions/__init__.py | 8 + .../layers/functions/detection.py | 59 + .../layers/functions/prior_box.py | 51 + .../Face_Detection/layers/modules/__init__.py | 8 + .../Face_Detection/layers/modules/l2norm.py | 29 + .../layers/modules/multibox_loss.py | 118 + .../Face_Detection/models/RPool_Face_C.py | 382 + .../models/RPool_Face_QVGA_monochrome.py | 348 + .../Face_Detection/models/RPool_Face_Quant.py | 375 + .../vision/Face_Detection/models/__init__.py | 6 + .../Face_Detection/prepare_wider_data.py | 86 + .../vision/Face_Detection/requirements.txt | 10 + .../pytorch/vision/Face_Detection/train.py | 244 + .../vision/Face_Detection/utils/__init__.py | 4 + .../Face_Detection/utils/augmentations.py | 862 ++ .../vision/Face_Detection/wider_test.py | 272 + .../pytorch/vision/Visual_Wakeword/README.md | 71 + .../pytorch/vision/Visual_Wakeword/eval.py | 91 + .../model_mobilenet_2rnnpool.py | 208 + .../model_mobilenet_rnnpool.py | 206 + .../vision/Visual_Wakeword/requirements.txt | 9 + .../create_coco_train_minival_split.py | 120 + .../create_visualwakewords_annotations.py | 217 + .../scripts/download_mscoco.sh | 80 + .../scripts/mscoco_minival_ids.txt | 8059 +++++++++++++++++ .../Visual_Wakeword/train_visualwakewords.py | 249 + examples/pytorch/vision/cpp/README.md | 18 + examples/pytorch/vision/cpp/data.h | 59 + .../pytorch/vision/cpp/rnnpool_quantized.cpp | 535 ++ pytorch/edgeml_pytorch/graph/rnn.py | 201 +- pytorch/edgeml_pytorch/graph/rnnpool.py | 66 + 42 files changed, 14078 insertions(+), 44 deletions(-) create mode 100755 examples/pytorch/vision/Face_Detection/README.md create mode 100755 examples/pytorch/vision/Face_Detection/data/__init__.py create mode 100644 examples/pytorch/vision/Face_Detection/data/choose_config.py create mode 100755 examples/pytorch/vision/Face_Detection/data/config.py create mode 100644 examples/pytorch/vision/Face_Detection/data/config_qvga.py create mode 100755 examples/pytorch/vision/Face_Detection/data/widerface.py create mode 100644 examples/pytorch/vision/Face_Detection/dump_model.py create mode 100644 examples/pytorch/vision/Face_Detection/eval.py create mode 100755 examples/pytorch/vision/Face_Detection/imrgb20ft.png create mode 100755 examples/pytorch/vision/Face_Detection/layers/__init__.py create mode 100755 examples/pytorch/vision/Face_Detection/layers/bbox_utils.py create mode 100755 examples/pytorch/vision/Face_Detection/layers/functions/__init__.py create mode 100755 examples/pytorch/vision/Face_Detection/layers/functions/detection.py create mode 100755 examples/pytorch/vision/Face_Detection/layers/functions/prior_box.py create mode 100755 examples/pytorch/vision/Face_Detection/layers/modules/__init__.py create mode 100755 examples/pytorch/vision/Face_Detection/layers/modules/l2norm.py create mode 100755 examples/pytorch/vision/Face_Detection/layers/modules/multibox_loss.py create mode 100755 examples/pytorch/vision/Face_Detection/models/RPool_Face_C.py create mode 100644 examples/pytorch/vision/Face_Detection/models/RPool_Face_QVGA_monochrome.py create mode 100755 examples/pytorch/vision/Face_Detection/models/RPool_Face_Quant.py create mode 100644 examples/pytorch/vision/Face_Detection/models/__init__.py create mode 100755 examples/pytorch/vision/Face_Detection/prepare_wider_data.py create mode 100644 examples/pytorch/vision/Face_Detection/requirements.txt create mode 100755 examples/pytorch/vision/Face_Detection/train.py create mode 100755 examples/pytorch/vision/Face_Detection/utils/__init__.py create mode 100755 examples/pytorch/vision/Face_Detection/utils/augmentations.py create mode 100755 examples/pytorch/vision/Face_Detection/wider_test.py create mode 100755 examples/pytorch/vision/Visual_Wakeword/README.md create mode 100644 examples/pytorch/vision/Visual_Wakeword/eval.py create mode 100755 examples/pytorch/vision/Visual_Wakeword/model_mobilenet_2rnnpool.py create mode 100755 examples/pytorch/vision/Visual_Wakeword/model_mobilenet_rnnpool.py create mode 100644 examples/pytorch/vision/Visual_Wakeword/requirements.txt create mode 100755 examples/pytorch/vision/Visual_Wakeword/scripts/create_coco_train_minival_split.py create mode 100755 examples/pytorch/vision/Visual_Wakeword/scripts/create_visualwakewords_annotations.py create mode 100755 examples/pytorch/vision/Visual_Wakeword/scripts/download_mscoco.sh create mode 100644 examples/pytorch/vision/Visual_Wakeword/scripts/mscoco_minival_ids.txt create mode 100755 examples/pytorch/vision/Visual_Wakeword/train_visualwakewords.py create mode 100644 examples/pytorch/vision/cpp/README.md create mode 100644 examples/pytorch/vision/cpp/data.h create mode 100644 examples/pytorch/vision/cpp/rnnpool_quantized.cpp create mode 100644 pytorch/edgeml_pytorch/graph/rnnpool.py diff --git a/examples/pytorch/vision/Face_Detection/README.md b/examples/pytorch/vision/Face_Detection/README.md new file mode 100755 index 00000000..a4fa7d6c --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/README.md @@ -0,0 +1,146 @@ +# Code for Face Detection experiments with RNNPool +## Requirements +1. Follow instructions to install requirements for EdgeML operators and the EdgeML operators [here](https://github.com/microsoft/EdgeML/blob/master/pytorch/README.md). +2. Install requirements for face detection model using +``` pip install -r requirements.txt ``` +We have tested the installation and the code on Ubuntu 18.04 with Cuda 10.2 and CuDNN 7.6 + +## Dataset +1. Download WIDER face dataset images and annotations from http://shuoyang1213.me/WIDERFACE/ and place them all in a folder with name 'WIDER_FACE'. That is, download WIDER_train.zip, WIDER_test.zip, WIDER_val.zip, wider_face_split.zip and place it in WIDER_FACE folder, and unzip files using: + +```shell +cd WIDER_FACE +unzip WIDER_train.zip +unzip WIDER_test.zip +unzip WIDER_val.zip +unzip wider_face_split.zip +cd .. + +``` + +2. In `data/config.py` , set _C.HOME to the parent directory of the above folder, and set the _C.FACE.WIDER_DIR to the folder path. +That is, if the WIDER_FACE folder is created in /mnt folder, then _C.HOME='/mnt' +_C.FACE.WIDER_DIR='/mnt/WIDER_FACE'. +Similarly, change `data/config_qvga.py` to set _C.HOME and _C.FACE.WIDER_DIR. +3. Run +``` python prepare_wider_data.py ``` + + +# Usage + +## Training + +```shell + +IS_QVGA_MONO=0 python train.py --batch_size 32 --model_arch RPool_Face_Quant --cuda True --multigpu True --save_folder weights/ --epochs 300 --save_frequency 5000 + +``` + +For QVGA: +```shell + +IS_QVGA_MONO=1 python train.py --batch_size 64 --model_arch RPool_Face_QVGA_monochrome --cuda True --multigpu True --save_folder weights/ --epochs 300 --save_frequency 5000 + +``` +This will save checkpoints after every '--save_frequency' number of iterations in a weight file with 'checkpoint.pth' at the end and weights for the best state in a file with 'best_state.pth' at the end. These will be saved in '--save_folder'. For resuming training from a checkpoint, use '--resume .pth' with the above command. For example, + + +```shell + +IS_QVGA_MONO=1 python train.py --batch_size 64 --model_arch RPool_Face_QVGA_monochrome --cuda True --multigpu True --save_folder weights/ --epochs 300 --save_frequency 5000 --resume .pth + +``` + +If IS_QVGA_MONO is 0 then training input images will be 640x640 and RGB. +If IS_QVGA_MONO is 1 then training input images will be 320x320 and converted to monochrome. + +Input images for training models are cropped and reshaped to square to maintain consistency with [S3FD](https://arxiv.org/abs/1708.05237). However testing can be done on any size of images, thus we resize testing input image size to have area equal to VGA (640x480)/QVGA (320x240), so that aspect ratio is not changed. + +The architecture RPool_Face_QVGA_monochrome is for QVGA monochrome format while RPool_Face_C and RPool_Face_Quant are for VGA RGB format. + + +## Test +There are two modes of testing the trained model -- the evaluation mode to generate bounding boxes for a set of sample images, and the test mode to compute statistics like mAP scores. + +#### Evaluation Mode + +Given a set of images in , `eval/py` generates bounding boxes around faces (where the confidence is higher than certain threshold) and write the images in . To evaluate the `rpool_face_best_state.pth` model (stored in ./weights), execute the following command: + +```shell +IS_QVGA_MONO=0 python eval.py --model_arch RPool_Face_Quant --model ./weights/RPool_Face_Quant_best_state.pth --image_folder --save_dir +``` + +For QVGA: +```shell +IS_QVGA_MONO=1 python eval.py --model_arch RPool_Face_QVGA_monochrome --model ./weights/RPool_Face_QVGA_monochrome_best_state.pth --image_folder --save_dir +``` + +This will save images in with bounding boxes around faces, where the confidence is high. Here is an example image with a single bounding box. + +![Camera: Himax0360](imrgb20ft.png) + +If IS_QVGA_MONO=0 the evaluation code accepts an image of any size and resizes it to 640x480x3 while preserving original image aspect ratio. + +If IS_QVGA_MONO=1 the evaluation code accepts an image of any size and resizes and converts it to monochrome to make it 320x240x1 while preserving original image aspect ratio. + +#### WIDER Set Test +In this mode, we test the generated model against the provided WIDER_FACE validation and test dataset. + +For this, first run the following to generate predictions of the model and store output in the '--save_folder' folder. + +```shell +IS_QVGA_MONO=0 python wider_test.py --model_arch RPool_Face_Quant --model ./weights/RPool_Face_Quant_best_state.pth --save_folder rpool_face_quant_val --subset val +``` + +For QVGA: +```shell +IS_QVGA_MONO=1 python wider_test.py --model_arch RPool_Face_QVGA_monochrome --model ./weights/RPool_Face_QVGA_monochrome_best_state.pth --save_folder rpool_face_qvgamono_val --subset val +``` + +The above command generates predictions for each image in the "validation" dataset. For each image, a separate prediction file is provided (image_name.txt file in appropriate folder). The first line of the prediction file contains the total number of boxes identified. +Then each line in the file corresponds to an identified box. For each box, five numbers are generated: length of the box, height of the box, x-axis offset, y-axis offset, confidence value for presence of a face in the box. + +If IS_QVGA_MONO=1 then testing is done by converting images to monochrome and QVGA, else if IS_QVGA_MONO=0 then testing is done on VGA RGB images. + +The architecture RPool_Face_QVGA_monochrome is for QVGA monochrome format while RPool_Face_C and RPool_Face_Quant are for VGA RGB format. + +###### For calculating MAP scores: +Now using these boxes, we can compute the standard MAP score that is widely used in this literature (see [here](https://medium.com/@jonathan_hui/map-mean-average-precision-for-object-detection-45c121a31173) for more details) as follows: + +1. Download eval_tools.zip from http://shuoyang1213.me/WIDERFACE/support/eval_script/eval_tools.zip and unzip in a folder of same name in this directory. + +Example code: + +```shell +wget http://shuoyang1213.me/WIDERFACE/support/eval_script/eval_tools.zip +unzip eval_tools.zip +``` + +2. Set up scripts to use the Matlab '.mat' data files in eval_tools/ground_truth folder for MAP calculation: The following installs python files that provide the same functionality as the '.m' matlab scripts in eval_tools folder. +``` +cd eval_tools +git clone https://github.com/wondervictor/WiderFace-Evaluation.git +cd WiderFace-Evaluation +python3 setup.py build_ext --inplace +``` + +3. Run ```python3 evaluation.py -p -g ``` in WiderFace-Evaluation folder + +where `prediction_dir` is the '--save_folder' used for `wider_test.py` above and is the subfolder `eval_tools/ground_truth`. That is in, WiderFace-Evaluation directory, run: + +```shell +python3 evaluation.py -p -g ../ground_truth +``` +This script should output the MAP for the WIDER-easy, WIDER-medium, and WIDER-hard subsets of the dataset. Our best performance using RPool_Face_Quant model is: 0.80 (WIDER-easy), 0.78 (WIDER-medium), 0.53 (WIDER-hard). + + +##### Dump RNNPool Input Output Traces and Weights + +To save model weights and/or input output pairs for each patch through RNNPool in numpy format use the command below. Put images which you want to save traces for in . Specify output folder for saving model weights in numpy format in . Specify output folder for saving input output traces of RNNPool in numpy format in . Note that input traces will be saved in a folder named 'inputs' and output traces in a folder named 'outputs' inside . + +```shell +python3 dump_model.py --model ./weights/RPool_Face_QVGA_monochrome_best_state.pth --model_arch RPool_Face_Quant --image_folder --save_model_npy_dir --save_traces_npy_dir +``` +If you wish to save only model weights, do not specify --save_traces_npy_dir. If you wish to save only traces do not specify --save_model_npy_dir. + +Code has been built upon https://github.com/yxlijun/S3FD.pytorch \ No newline at end of file diff --git a/examples/pytorch/vision/Face_Detection/data/__init__.py b/examples/pytorch/vision/Face_Detection/data/__init__.py new file mode 100755 index 00000000..ba320eee --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/data/__init__.py @@ -0,0 +1,31 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +from .widerface import WIDERDetection + +from data.choose_config import cfg +cfg = cfg.cfg + + +import torch + + +def detection_collate(batch): + """Custom collate fn for dealing with batches of images that have a different + number of associated object annotations (bounding boxes). + + Arguments: + batch: (tuple) A tuple of tensor images and lists of annotations + + Return: + A tuple containing: + 1) (tensor) batch of images stacked on their 0 dim + 2) (list of tensors) annotations for a given image are stacked on + 0 dim + """ + targets = [] + imgs = [] + for sample in batch: + imgs.append(sample[0]) + targets.append(torch.FloatTensor(sample[1])) + return torch.stack(imgs, 0), targets \ No newline at end of file diff --git a/examples/pytorch/vision/Face_Detection/data/choose_config.py b/examples/pytorch/vision/Face_Detection/data/choose_config.py new file mode 100644 index 00000000..e86c18d8 --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/data/choose_config.py @@ -0,0 +1,15 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +import os +from importlib import import_module + +IS_QVGA_MONO = os.environ['IS_QVGA_MONO'] + + +name = 'config' +if IS_QVGA_MONO == '1': + name = name + '_qvga' + + +cfg = import_module('data.' + name) \ No newline at end of file diff --git a/examples/pytorch/vision/Face_Detection/data/config.py b/examples/pytorch/vision/Face_Detection/data/config.py new file mode 100755 index 00000000..86760a00 --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/data/config.py @@ -0,0 +1,65 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +import os +from easydict import EasyDict +import numpy as np + + +_C = EasyDict() +cfg = _C +# data augument config +_C.expand_prob = 0.5 +_C.expand_max_ratio = 4 +_C.hue_prob = 0.5 +_C.hue_delta = 18 +_C.contrast_prob = 0.5 +_C.contrast_delta = 0.5 +_C.saturation_prob = 0.5 +_C.saturation_delta = 0.5 +_C.brightness_prob = 0.5 +_C.brightness_delta = 0.125 +_C.data_anchor_sampling_prob = 0.5 +_C.min_face_size = 6.0 +_C.apply_distort = True +_C.apply_expand = False +_C.img_mean = np.array([104., 117., 123.])[:, np.newaxis, np.newaxis].astype( + 'float32') +_C.resize_width = 640 +_C.resize_height = 640 +_C.scale = 1 / 127.0 +_C.anchor_sampling = True +_C.filter_min_face = True + + +_C.IS_MONOCHROME = False + + +# anchor config +_C.FEATURE_MAPS = [160, 80, 40, 20, 10, 5] +_C.INPUT_SIZE = 640 +_C.STEPS = [4, 8, 16, 32, 64, 128] +_C.ANCHOR_SIZES = [16, 32, 64, 128, 256, 512] +_C.CLIP = False +_C.VARIANCE = [0.1, 0.2] + +# detection config +_C.NMS_THRESH = 0.3 +_C.NMS_TOP_K = 5000 +_C.TOP_K = 750 +_C.CONF_THRESH = 0.01 + +# loss config +_C.NEG_POS_RATIOS = 3 +_C.NUM_CLASSES = 2 +_C.USE_NMS = True + +# dataset config +_C.HOME = '/mnt/' ## change here ---------- + +# face config +_C.FACE = EasyDict() +_C.FACE.TRAIN_FILE = './data/face_train.txt' +_C.FACE.VAL_FILE = './data/face_val.txt' +_C.FACE.WIDER_DIR = '/mnt/WIDER_FACE' ## change here --------- +_C.FACE.OVERLAP_THRESH = [0.1, 0.35, 0.5] diff --git a/examples/pytorch/vision/Face_Detection/data/config_qvga.py b/examples/pytorch/vision/Face_Detection/data/config_qvga.py new file mode 100644 index 00000000..06417bac --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/data/config_qvga.py @@ -0,0 +1,64 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +import os +from easydict import EasyDict +import numpy as np + + +_C = EasyDict() +cfg = _C +# data augument config +_C.expand_prob = 0.5 +_C.expand_max_ratio = 2 +_C.hue_prob = 0.5 +_C.hue_delta = 18 +_C.contrast_prob = 0.5 +_C.contrast_delta = 0.5 +_C.saturation_prob = 0.5 +_C.saturation_delta = 0.5 +_C.brightness_prob = 0.5 +_C.brightness_delta = 0.125 +_C.data_anchor_sampling_prob = 0.5 +_C.min_face_size = 1.0 +_C.apply_distort = True +_C.apply_expand = False +_C.img_mean = np.array([104., 117., 123.])[:, np.newaxis, np.newaxis].astype( + 'float32') +_C.resize_width = 320 +_C.resize_height = 320 +_C.scale = 1 / 127.0 +_C.anchor_sampling = True +_C.filter_min_face = True + + +_C.IS_MONOCHROME = True + +# anchor config +_C.FEATURE_MAPS = [40, 40, 20, 20] +_C.INPUT_SIZE = 320 +_C.STEPS = [8, 8, 16, 16] +_C.ANCHOR_SIZES = [8, 16, 32, 48] +_C.CLIP = False +_C.VARIANCE = [0.1, 0.2] + +# detection config +_C.NMS_THRESH = 0.3 +_C.NMS_TOP_K = 5000 +_C.TOP_K = 750 +_C.CONF_THRESH = 0.05 + +# loss config +_C.NEG_POS_RATIOS = 3 +_C.NUM_CLASSES = 2 +_C.USE_NMS = True + +# dataset config +_C.HOME = '/mnt/' + +# face config +_C.FACE = EasyDict() +_C.FACE.TRAIN_FILE = './data/face_train.txt' +_C.FACE.VAL_FILE = './data/face_val.txt' +_C.FACE.WIDER_DIR = '/mnt/WIDER_FACE' +_C.FACE.OVERLAP_THRESH = [0.1, 0.35, 0.5] diff --git a/examples/pytorch/vision/Face_Detection/data/widerface.py b/examples/pytorch/vision/Face_Detection/data/widerface.py new file mode 100755 index 00000000..afe0523e --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/data/widerface.py @@ -0,0 +1,115 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +import torch +from PIL import Image, ImageDraw +import torch.utils.data as data +import numpy as np +import random +import sys; sys.path.append('../') +from utils.augmentations import preprocess + + +class WIDERDetection(data.Dataset): + """docstring for WIDERDetection""" + + def __init__(self, list_file, mode='train', mono_mode=False): + super(WIDERDetection, self).__init__() + self.mode = mode + self.mono_mode = mono_mode + self.fnames = [] + self.boxes = [] + self.labels = [] + + with open(list_file) as f: + lines = f.readlines() + + for line in lines: + line = line.strip().split() + num_faces = int(line[1]) + box = [] + label = [] + for i in range(num_faces): + x = float(line[2 + 5 * i]) + y = float(line[3 + 5 * i]) + w = float(line[4 + 5 * i]) + h = float(line[5 + 5 * i]) + c = int(line[6 + 5 * i]) + if w <= 0 or h <= 0: + continue + box.append([x, y, x + w, y + h]) + label.append(c) + if len(box) > 0: + self.fnames.append(line[0]) + self.boxes.append(box) + self.labels.append(label) + + self.num_samples = len(self.boxes) + + def __len__(self): + return self.num_samples + + def __getitem__(self, index): + img, target, h, w = self.pull_item(index) + return img, target + + def pull_item(self, index): + while True: + image_path = self.fnames[index] + img = Image.open(image_path) + if img.mode == 'L': + img = img.convert('RGB') + + im_width, im_height = img.size + boxes = self.annotransform( + np.array(self.boxes[index]), im_width, im_height) + label = np.array(self.labels[index]) + bbox_labels = np.hstack((label[:, np.newaxis], boxes)).tolist() + img, sample_labels = preprocess( + img, bbox_labels, self.mode, image_path) + sample_labels = np.array(sample_labels) + if len(sample_labels) > 0: + target = np.hstack( + (sample_labels[:, 1:], sample_labels[:, 0][:, np.newaxis])) + + assert (target[:, 2] > target[:, 0]).any() + assert (target[:, 3] > target[:, 1]).any() + break + else: + index = random.randrange(0, self.num_samples) + + + if self.mono_mode==True: + im = 0.299 * img[0] + 0.587 * img[1] + 0.114 * img[2] + return torch.from_numpy(np.expand_dims(im,axis=0)), target, im_height, im_width + + return torch.from_numpy(img), target, im_height, im_width + + + def annotransform(self, boxes, im_width, im_height): + boxes[:, 0] /= im_width + boxes[:, 1] /= im_height + boxes[:, 2] /= im_width + boxes[:, 3] /= im_height + return boxes + + +def detection_collate(batch): + """Custom collate fn for dealing with batches of images that have a different + number of associated object annotations (bounding boxes). + + Arguments: + batch: (tuple) A tuple of tensor images and lists of annotations + + Return: + A tuple containing: + 1) (tensor) batch of images stacked on their 0 dim + 2) (list of tensors) annotations for a given image are stacked on + 0 dim + """ + targets = [] + imgs = [] + for sample in batch: + imgs.append(sample[0]) + targets.append(torch.FloatTensor(sample[1])) + return torch.stack(imgs, 0), targets diff --git a/examples/pytorch/vision/Face_Detection/dump_model.py b/examples/pytorch/vision/Face_Detection/dump_model.py new file mode 100644 index 00000000..1a2d76d6 --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/dump_model.py @@ -0,0 +1,191 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +from __future__ import division +from __future__ import absolute_import +from __future__ import print_function + +import os +import torch +import argparse +import torch.nn as nn +import torch.utils.data as data +import torch.backends.cudnn as cudnn +import torchvision.transforms as transforms + +import cv2 +import time +import numpy as np +from PIL import Image, ImageFilter + +from data.config import cfg +from torch.autograd import Variable +from utils.augmentations import to_chw_bgr + +from importlib import import_module + +import warnings +warnings.filterwarnings("ignore") + + +parser = argparse.ArgumentParser(description='face detection dump') + +parser.add_argument('--model', type=str, + default='weights/rpool_face_c.pth', help='trained model') + #small_fgrnn_smallram_sd.pth', help='trained model') +parser.add_argument('--model_arch', + default='RPool_Face_C', type=str, + choices=['RPool_Face_C', 'RPool_Face_B', 'RPool_Face_A', 'RPool_Face_Quant'], + help='choose architecture among rpool variants') +parser.add_argument('--image_folder', default=None, type=str, help='folder containing images') +parser.add_argument('--save_model_npy_dir', default=None, type=str, help='Directory for saving model in numpy array format') +parser.add_argument('--save_traces_npy_dir', default=None, type=str, help='Directory for saving RNNPool input and output traces in numpy array format') + + +args = parser.parse_args() + + +use_cuda = torch.cuda.is_available() + +if use_cuda: + torch.set_default_tensor_type('torch.cuda.FloatTensor') +else: + torch.set_default_tensor_type('torch.FloatTensor') + + + +def saveModelNpy(net): + if os.path.isdir(args.save_model_npy_dir) is False: + try: + os.mkdir(args.save_model_npy_dir) + except OSError: + print("Creation of the directory %s failed" % args.save_model_npy_dir) + return + + np.save(args.save_model_npy_dir+'/W1.npy', net.rnn_model.cell_rnn.cell.W.cpu().detach().numpy()) + np.save(args.save_model_npy_dir+'/W2.npy', net.rnn_model.cell_bidirrnn.cell.W.cpu().detach().numpy()) + np.save(args.save_model_npy_dir+'/U1.npy', net.rnn_model.cell_rnn.cell.U.cpu().detach().numpy()) + np.save(args.save_model_npy_dir+'/U2.npy', net.rnn_model.cell_bidirrnn.cell.U.cpu().detach().numpy()) + np.save(args.save_model_npy_dir+'/Bg1.npy', net.rnn_model.cell_rnn.cell.bias_gate.cpu().detach().numpy()) + np.save(args.save_model_npy_dir+'/Bg2.npy', net.rnn_model.cell_bidirrnn.cell.bias_gate.cpu().detach().numpy()) + np.save(args.save_model_npy_dir+'/Bh1.npy', net.rnn_model.cell_rnn.cell.bias_update.cpu().detach().numpy()) + np.save(args.save_model_npy_dir+'/Bh2.npy', net.rnn_model.cell_bidirrnn.cell.bias_update.cpu().detach().numpy()) + np.save(args.save_model_npy_dir+'/nu1.npy', net.rnn_model.cell_rnn.cell.nu.cpu().detach().numpy()) + np.save(args.save_model_npy_dir+'/nu2.npy', net.rnn_model.cell_bidirrnn.cell.nu.cpu().detach().numpy()) + np.save(args.save_model_npy_dir+'/zeta1.npy', net.rnn_model.cell_rnn.cell.zeta.cpu().detach().numpy()) + np.save(args.save_model_npy_dir+'/zeta2.npy', net.rnn_model.cell_bidirrnn.cell.zeta.cpu().detach().numpy()) + + + +activation = {} +def get_activation(name): + def hook(model, input, output): + activation[name] = output.detach() + return hook + +def saveTracesNpy(net, img_list): + if os.path.isdir(args.save_traces_npy_dir) is False: + try: + os.mkdir(args.save_traces_npy_dir) + except OSError: + print("Creation of the directory %s failed" % args.save_traces_npy_dir) + return + + if os.path.isdir(os.path.join(args.save_traces_npy_dir,'inputs')) is False: + try: + os.mkdir(os.path.join(args.save_traces_npy_dir,'inputs')) + except OSError: + print("Creation of the directory %s failed" % os.path.join(args.save_traces_npy_dir,'inputs')) + return + + if os.path.isdir(os.path.join(args.save_traces_npy_dir,'outputs')) is False: + try: + os.mkdir(os.path.join(args.save_traces_npy_dir,'outputs')) + except OSError: + print("Creation of the directory %s failed" % os.path.join(args.save_traces_npy_dir,'outputs')) + return + + inputDims = net.rnn_model.inputDims + nRows = net.rnn_model.nRows + nCols = net.rnn_model.nCols + count=0 + for img_path in img_list: + img = Image.open(os.path.join(args.image_folder, img_path)) + + img = img.convert('RGB') + + img = np.array(img) + max_im_shrink = np.sqrt( + 640 * 480 / (img.shape[0] * img.shape[1])) + image = cv2.resize(img, None, None, fx=max_im_shrink, + fy=max_im_shrink, interpolation=cv2.INTER_LINEAR) + + x = to_chw_bgr(image) + x = x.astype('float32') + x -= cfg.img_mean + x = x[[2, 1, 0], :, :] + + x = Variable(torch.from_numpy(x).unsqueeze(0)) + if use_cuda: + x = x.cuda() + t1 = time.time() + y = net(x) + + + patches = activation['prepatch'] + patches = torch.cat(torch.unbind(patches,dim=2),dim=0) + patches = torch.reshape(patches,(-1,inputDims,nRows,nCols)) + + rnnX = activation['rnn_model'] + + patches_all = torch.stack(torch.split(patches, split_size_or_sections=1, dim=0),dim=-1) + rnnX_all = torch.stack(torch.split(rnnX, split_size_or_sections=1, dim=0),dim=-1) + + for k in range(patches_all.shape[-1]): + patches_tosave = patches_all[0,:,:,:,k].cpu().numpy().transpose(1,2,0) + rnnX_tosave = rnnX_all[0,:,k].cpu().numpy() + np.save(args.save_traces_npy_dir+'/inputs/trace_'+str(count)+'_'+str(k)+'.npy', patches_tosave) + np.save(args.save_traces_npy_dir+'/outputs/trace_'+str(count)+'_'+str(k)+'.npy', rnnX_tosave) + + count+=1 + + + + + + +if __name__ == '__main__': + + module = import_module('models.' + args.model_arch) + net = module.build_s3fd('test', cfg.NUM_CLASSES) + + # net = torch.nn.DataParallel(net) + + checkpoint_dict = torch.load(args.model) + + model_dict = net.state_dict() + + + model_dict.update(checkpoint_dict) + net.load_state_dict(model_dict) + + + + net.eval() + + if use_cuda: + net.cuda() + cudnn.benckmark = True + + + + if args.save_model_npy_dir is not None: + saveModelNpy(net) + + if args.save_traces_npy_dir is not None: + net.unfold.register_forward_hook(get_activation('prepatch')) + net.rnn_model.register_forward_hook(get_activation('rnn_model')) + img_path = args.image_folder + img_list = [os.path.join(img_path, x) + for x in os.listdir(img_path)] + saveTracesNpy(net, img_list) diff --git a/examples/pytorch/vision/Face_Detection/eval.py b/examples/pytorch/vision/Face_Detection/eval.py new file mode 100644 index 00000000..00063d94 --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/eval.py @@ -0,0 +1,133 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +import torch +import torch.nn as nn +import torch.utils.data as data +import torch.backends.cudnn as cudnn +import torchvision.transforms as transforms + +import os +import time +import argparse +import numpy as np +from PIL import Image +import cv2 + +from data.choose_config import cfg +cfg = cfg.cfg + +from utils.augmentations import to_chw_bgr + +from importlib import import_module + + +parser = argparse.ArgumentParser(description='face detection demo') +parser.add_argument('--save_dir', type=str, default='results/', + help='Directory for detect result') +parser.add_argument('--model', type=str, + default='weights/rpool_face_c.pth', help='trained model') +parser.add_argument('--thresh', default=0.17, type=float, + help='Final confidence threshold') +parser.add_argument('--model_arch', + default='RPool_Face_C', type=str, + choices=['RPool_Face_C', 'RPool_Face_Quant', 'RPool_Face_QVGA_monochrome'], + help='choose architecture among rpool variants') +parser.add_argument('--image_folder', default=None, type=str, help='folder containing images') + + +args = parser.parse_args() + +if not os.path.exists(args.save_dir): + os.makedirs(args.save_dir) + +use_cuda = torch.cuda.is_available() + +if use_cuda: + torch.set_default_tensor_type('torch.cuda.FloatTensor') +else: + torch.set_default_tensor_type('torch.FloatTensor') + + +def detect(net, img_path, thresh): + img = Image.open(img_path) + img = img.convert('RGB') + img = np.array(img) + height, width, _ = img.shape + + if os.environ['IS_QVGA_MONO'] == '1': + max_im_shrink = np.sqrt( + 320 * 240 / (img.shape[0] * img.shape[1])) + else: + max_im_shrink = np.sqrt( + 640 * 480 / (img.shape[0] * img.shape[1])) + + image = cv2.resize(img, None, None, fx=max_im_shrink, + fy=max_im_shrink, interpolation=cv2.INTER_LINEAR) + # img = cv2.resize(img, (640, 640)) + x = to_chw_bgr(image) + x = x.astype('float32') + x -= cfg.img_mean + x = x[[2, 1, 0], :, :] + + + if cfg.IS_MONOCHROME == True: + x = 0.299 * x[0] + 0.587 * x[1] + 0.114 * x[2] + x = torch.from_numpy(x).unsqueeze(0).unsqueeze(0) + else: + x = torch.from_numpy(x).unsqueeze(0) + if use_cuda: + x = x.cuda() + t1 = time.time() + y = net(x) + detections = y.data + scale = torch.Tensor([img.shape[1], img.shape[0], + img.shape[1], img.shape[0]]) + + img = cv2.imread(img_path, cv2.IMREAD_COLOR) + + for i in range(detections.size(1)): + j = 0 + while detections[0, i, j, 0] >= thresh: + score = detections[0, i, j, 0] + pt = (detections[0, i, j, 1:] * scale).cpu().numpy() + left_up, right_bottom = (pt[0], pt[1]), (pt[2], pt[3]) + j += 1 + cv2.rectangle(img, left_up, right_bottom, (0, 0, 255), 2) + conf = "{:.3f}".format(score) + point = (int(left_up[0]), int(left_up[1] - 5)) + cv2.putText(img, conf, point, cv2.FONT_HERSHEY_COMPLEX, + 0.6, (0, 255, 0), 1) + + t2 = time.time() + print('detect:{} timer:{}'.format(img_path, t2 - t1)) + + cv2.imwrite(os.path.join(args.save_dir, os.path.basename(img_path)), img) + + +if __name__ == '__main__': + + module = import_module('models.' + args.model_arch) + net = module.build_s3fd('test', cfg.NUM_CLASSES) + + net = torch.nn.DataParallel(net) + + checkpoint_dict = torch.load(args.model) + + model_dict = net.state_dict() + + + model_dict.update(checkpoint_dict) + net.load_state_dict(model_dict) + + net.eval() + + if use_cuda: + net.cuda() + cudnn.benckmark = True + + img_path = args.image_folder + img_list = [os.path.join(img_path, x) + for x in os.listdir(img_path)] + for path in img_list: + detect(net, path, args.thresh) \ No newline at end of file diff --git a/examples/pytorch/vision/Face_Detection/imrgb20ft.png b/examples/pytorch/vision/Face_Detection/imrgb20ft.png new file mode 100755 index 0000000000000000000000000000000000000000..bb5df2253a3e6908a88acd62655a0139e059601a GIT binary patch literal 399556 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≺v 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 z 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 t%=149kTa73ULG$R>!OIYb(IXiv5 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 z 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 [A,1,2] -> [A,B,2] + [B,2] -> [1,B,2] -> [A,B,2] + Then we compute the area of intersect between box_a and box_b. + Args: + box_a: (tensor) bounding boxes, Shape: [A,4]. + box_b: (tensor) bounding boxes, Shape: [B,4]. + Return: + (tensor) intersection area, Shape: [A,B]. + """ + A = box_a.size(0) + B = box_b.size(0) + max_xy = torch.min(box_a[:, 2:].unsqueeze(1).expand(A, B, 2), + box_b[:, 2:].unsqueeze(0).expand(A, B, 2)) + min_xy = torch.max(box_a[:, :2].unsqueeze(1).expand(A, B, 2), + box_b[:, :2].unsqueeze(0).expand(A, B, 2)) + inter = torch.clamp((max_xy - min_xy), min=0) + return inter[:, :, 0] * inter[:, :, 1] + + +def jaccard(box_a, box_b): + """Compute the jaccard overlap of two sets of boxes. The jaccard overlap + is simply the intersection over union of two boxes. Here we operate on + ground truth boxes and default boxes. + E.g.: + A ∩ B / A ∪ B = A ∩ B / (area(A) + area(B) - A ∩ B) + Args: + box_a: (tensor) Ground truth bounding boxes, Shape: [num_objects,4] + box_b: (tensor) Prior boxes from priorbox layers, Shape: [num_priors,4] + Return: + jaccard overlap: (tensor) Shape: [box_a.size(0), box_b.size(0)] + """ + inter = intersect(box_a, box_b) + area_a = ((box_a[:, 2] - box_a[:, 0]) * + (box_a[:, 3] - box_a[:, 1])).unsqueeze(1).expand_as(inter) # [A,B] + area_b = ((box_b[:, 2] - box_b[:, 0]) * + (box_b[:, 3] - box_b[:, 1])).unsqueeze(0).expand_as(inter) # [A,B] + union = area_a + area_b - inter + return inter / union # [A,B] + + +def match(threshold, truths, priors, variances, labels, loc_t, conf_t, idx): + """Match each prior box with the ground truth box of the highest jaccard + overlap, encode the bounding boxes, then return the matched indices + corresponding to both confidence and location preds. + Args: + threshold: (float) The overlap threshold used when mathing boxes. + truths: (tensor) Ground truth boxes, Shape: [num_obj, num_priors]. + priors: (tensor) Prior boxes from priorbox layers, Shape: [n_priors,4]. + variances: (tensor) Variances corresponding to each prior coord, + Shape: [num_priors, 4]. + labels: (tensor) All the class labels for the image, Shape: [num_obj]. + loc_t: (tensor) Tensor to be filled w/ endcoded location targets. + conf_t: (tensor) Tensor to be filled w/ matched indices for conf preds. + idx: (int) current batch index + Return: + The matched indices corresponding to 1)location and 2)confidence preds. + """ + # jaccard index + overlaps = jaccard( + truths, + point_form(priors) + ) + # (Bipartite Matching) + # [1,num_objects] best prior for each ground truth + best_prior_overlap, best_prior_idx = overlaps.max(1, keepdim=True) + # [1,num_priors] best ground truth for each prior + best_truth_overlap, best_truth_idx = overlaps.max( + 0, keepdim=True) # 0-2000 + best_truth_idx.squeeze_(0) + best_truth_overlap.squeeze_(0) + best_prior_idx.squeeze_(1) + best_prior_overlap.squeeze_(1) + best_truth_overlap.index_fill_(0, best_prior_idx, 2) # ensure best prior + # TODO refactor: index best_prior_idx with long tensor + # ensure every gt matches with its prior of max overlap + for j in range(best_prior_idx.size(0)): + best_truth_idx[best_prior_idx[j]] = j + _th1, _th2, _th3 = threshold # _th1 = 0.1 ,_th2 = 0.35,_th3 = 0.5 + + N = (torch.sum(best_prior_overlap >= _th2) + + torch.sum(best_prior_overlap >= _th3)) // 2 + matches = truths[best_truth_idx] # Shape: [num_priors,4] + conf = labels[best_truth_idx] # Shape: [num_priors] + conf[best_truth_overlap < _th2] = 0 # label as background + + best_truth_overlap_clone = best_truth_overlap.clone() + add_idx = best_truth_overlap_clone.gt( + _th1).eq(best_truth_overlap_clone.lt(_th2)) + best_truth_overlap_clone[~add_idx] = 0 + stage2_overlap, stage2_idx = best_truth_overlap_clone.sort(descending=True) + + stage2_overlap = stage2_overlap.gt(_th1) + + if N > 0: + N = torch.sum(stage2_overlap[:N]) if torch.sum( + stage2_overlap[:N]) < N else N + conf[stage2_idx[:N]] += 1 + + loc = encode(matches, priors, variances) + loc_t[idx] = loc # [num_priors,4] encoded offsets to learn + conf_t[idx] = conf # [num_priors] top class label for each prior + + +def match_ssd(threshold, truths, priors, variances, labels, loc_t, conf_t, idx): + """Match each prior box with the ground truth box of the highest jaccard + overlap, encode the bounding boxes, then return the matched indices + corresponding to both confidence and location preds. + Args: + threshold: (float) The overlap threshold used when mathing boxes. + truths: (tensor) Ground truth boxes, Shape: [num_obj, num_priors]. + priors: (tensor) Prior boxes from priorbox layers, Shape: [n_priors,4]. + variances: (tensor) Variances corresponding to each prior coord, + Shape: [num_priors, 4]. + labels: (tensor) All the class labels for the image, Shape: [num_obj]. + loc_t: (tensor) Tensor to be filled w/ endcoded location targets. + conf_t: (tensor) Tensor to be filled w/ matched indices for conf preds. + idx: (int) current batch index + Return: + The matched indices corresponding to 1)location and 2)confidence preds. + """ + # jaccard index + overlaps = jaccard( + truths, + point_form(priors) + ) + # (Bipartite Matching) + # [1,num_objects] best prior for each ground truth + best_prior_overlap, best_prior_idx = overlaps.max(1, keepdim=True) + # [1,num_priors] best ground truth for each prior + best_truth_overlap, best_truth_idx = overlaps.max( + 0, keepdim=True) # 0-2000 + best_truth_idx.squeeze_(0) + best_truth_overlap.squeeze_(0) + best_prior_idx.squeeze_(1) + best_prior_overlap.squeeze_(1) + best_truth_overlap.index_fill_(0, best_prior_idx, 2) # ensure best prior + # TODO refactor: index best_prior_idx with long tensor + # ensure every gt matches with its prior of max overlap + for j in range(best_prior_idx.size(0)): + best_truth_idx[best_prior_idx[j]] = j + matches = truths[best_truth_idx] # Shape: [num_priors,4] + conf = labels[best_truth_idx] # Shape: [num_priors] + conf[best_truth_overlap < threshold] = 0 # label as background + loc = encode(matches, priors, variances) + loc_t[idx] = loc # [num_priors,4] encoded offsets to learn + conf_t[idx] = conf # [num_priors] top class label for each prior + + +def encode(matched, priors, variances): + """Encode the variances from the priorbox layers into the ground truth boxes + we have matched (based on jaccard overlap) with the prior boxes. + Args: + matched: (tensor) Coords of ground truth for each prior in point-form + Shape: [num_priors, 4]. + priors: (tensor) Prior boxes in center-offset form + Shape: [num_priors,4]. + variances: (list[float]) Variances of priorboxes + Return: + encoded boxes (tensor), Shape: [num_priors, 4] + """ + + # dist b/t match center and prior's center + g_cxcy = (matched[:, :2] + matched[:, 2:]) / 2 - priors[:, :2] + # encode variance + g_cxcy /= (variances[0] * priors[:, 2:]) + # match wh / prior wh + g_wh = (matched[:, 2:] - matched[:, :2]) / priors[:, 2:] + #g_wh = torch.log(g_wh) / variances[1] + g_wh = torch.log(g_wh) / variances[1] + # return target for smooth_l1_loss + return torch.cat([g_cxcy, g_wh], 1) # [num_priors,4] + + +# Adapted from https://github.com/Hakuyume/chainer-ssd +def decode(loc, priors, variances): + """Decode locations from predictions using priors to undo + the encoding we did for offset regression at train time. + Args: + loc (tensor): location predictions for loc layers, + Shape: [num_priors,4] + priors (tensor): Prior boxes in center-offset form. + Shape: [num_priors,4]. + variances: (list[float]) Variances of priorboxes + Return: + decoded bounding box predictions + """ + + boxes = torch.cat(( + priors[:, :2] + loc[:, :2] * variances[0] * priors[:, 2:], + priors[:, 2:] * torch.exp(loc[:, 2:] * variances[1])), 1) + boxes[:, :2] -= boxes[:, 2:] / 2 + boxes[:, 2:] += boxes[:, :2] + return boxes + + +def log_sum_exp(x): + """Utility function for computing log_sum_exp while determining + This will be used to determine unaveraged confidence loss across + all examples in a batch. + Args: + x (Variable(tensor)): conf_preds from conf layers + """ + x_max = x.data.max() + return torch.log(torch.sum(torch.exp(x - x_max), 1, keepdim=True)) + x_max + + +# Original author: Francisco Massa: +# https://github.com/fmassa/object-detection.torch +# Ported to PyTorch by Max deGroot (02/01/2017) +def nms(boxes, scores, overlap=0.5, top_k=200): + """Apply non-maximum suppression at test time to avoid detecting too many + overlapping bounding boxes for a given object. + Args: + boxes: (tensor) The location preds for the img, Shape: [num_priors,4]. + scores: (tensor) The class predscores for the img, Shape:[num_priors]. + overlap: (float) The overlap thresh for suppressing unnecessary boxes. + top_k: (int) The Maximum number of box preds to consider. + Return: + The indices of the kept boxes with respect to num_priors. + """ + + keep = scores.new(scores.size(0)).zero_().long() + if boxes.numel() == 0: + return keep + x1 = boxes[:, 0] + y1 = boxes[:, 1] + x2 = boxes[:, 2] + y2 = boxes[:, 3] + area = torch.mul(x2 - x1, y2 - y1) + v, idx = scores.sort(0) # sort in ascending order + # I = I[v >= 0.01] + idx = idx[-top_k:] # indices of the top-k largest vals + xx1 = boxes.new() + yy1 = boxes.new() + xx2 = boxes.new() + yy2 = boxes.new() + w = boxes.new() + h = boxes.new() + + # keep = torch.Tensor() + count = 0 + while idx.numel() > 0: + i = idx[-1] # index of current largest val + # keep.append(i) + keep[count] = i + count += 1 + if idx.size(0) == 1: + break + idx = idx[:-1] # remove kept element from view + # load bboxes of next highest vals + torch.index_select(x1, 0, idx, out=xx1) + torch.index_select(y1, 0, idx, out=yy1) + torch.index_select(x2, 0, idx, out=xx2) + torch.index_select(y2, 0, idx, out=yy2) + # store element-wise max with next highest score + xx1 = torch.clamp(xx1, min=x1[i]) + yy1 = torch.clamp(yy1, min=y1[i]) + xx2 = torch.clamp(xx2, max=x2[i]) + yy2 = torch.clamp(yy2, max=y2[i]) + w.resize_as_(xx2) + h.resize_as_(yy2) + w = xx2 - xx1 + h = yy2 - yy1 + # check sizes of xx1 and xx2.. after each iteration + w = torch.clamp(w, min=0.0) + h = torch.clamp(h, min=0.0) + inter = w * h + # IoU = i / (area(a) + area(b) - i) + rem_areas = torch.index_select(area, 0, idx) # load remaining areas) + union = (rem_areas - inter) + area[i] + IoU = inter / union # store result in iou + # keep only elements with an IoU <= overlap + idx = idx[IoU.le(overlap)] + return keep, count diff --git a/examples/pytorch/vision/Face_Detection/layers/functions/__init__.py b/examples/pytorch/vision/Face_Detection/layers/functions/__init__.py new file mode 100755 index 00000000..8ae7faa1 --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/layers/functions/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +from .prior_box import PriorBox +from .detection import detect_function + +__all__=['detect_function','PriorBox'] + diff --git a/examples/pytorch/vision/Face_Detection/layers/functions/detection.py b/examples/pytorch/vision/Face_Detection/layers/functions/detection.py new file mode 100755 index 00000000..1fb45085 --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/layers/functions/detection.py @@ -0,0 +1,59 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +from __future__ import division +from __future__ import absolute_import +from __future__ import print_function + +import torch + +from ..bbox_utils import decode, nms + + + +def detect_function(cfg, loc_data, conf_data, prior_data): + """ + Args: + loc_data: (tensor) Loc preds from loc layers + Shape: [batch,num_priors*4] + conf_data: (tensor) Shape: Conf preds from conf layers + Shape: [batch*num_priors,num_classes] + prior_data: (tensor) Prior boxes and variances from priorbox layers + Shape: [1,num_priors,4] + """ + with torch.no_grad(): + num = loc_data.size(0) + num_priors = prior_data.size(0) + + conf_preds = conf_data.view( + num, num_priors, cfg.NUM_CLASSES).transpose(2, 1) + batch_priors = prior_data.view(-1, num_priors, + 4).expand(num, num_priors, 4) + batch_priors = batch_priors.contiguous().view(-1, 4) + + decoded_boxes = decode(loc_data.view(-1, 4), + batch_priors, cfg.VARIANCE) + decoded_boxes = decoded_boxes.view(num, num_priors, 4) + + output = torch.zeros(num, cfg.NUM_CLASSES, cfg.TOP_K, 5) + + for i in range(num): + boxes = decoded_boxes[i].clone() + conf_scores = conf_preds[i].clone() + + for cl in range(1, cfg.NUM_CLASSES): + c_mask = conf_scores[cl].gt(cfg.CONF_THRESH) + scores = conf_scores[cl][c_mask] + + if scores.dim() == 0: + continue + l_mask = c_mask.unsqueeze(1).expand_as(boxes) + boxes_ = boxes[l_mask].view(-1, 4) + ids, count = nms( + boxes_, scores, cfg.NMS_THRESH, cfg.NMS_TOP_K) + count = count if count < cfg.TOP_K else cfg.TOP_K + + output[i, cl, :count] = torch.cat((scores[ids[:count]].unsqueeze(1), + boxes_[ids[:count]]), 1) + + return output diff --git a/examples/pytorch/vision/Face_Detection/layers/functions/prior_box.py b/examples/pytorch/vision/Face_Detection/layers/functions/prior_box.py new file mode 100755 index 00000000..9c84dab0 --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/layers/functions/prior_box.py @@ -0,0 +1,51 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +import torch +from itertools import product as product +import math + + +class PriorBox(object): + """Compute priorbox coordinates in center-offset form for each source + feature map. + """ + + def __init__(self, input_size, feature_maps,cfg): + super(PriorBox, self).__init__() + self.imh = input_size[0] + self.imw = input_size[1] + + # number of priors for feature map location (either 4 or 6) + self.variance = cfg.VARIANCE or [0.1] + #self.feature_maps = cfg.FEATURE_MAPS + self.min_sizes = cfg.ANCHOR_SIZES + self.steps = cfg.STEPS + self.clip = cfg.CLIP + for v in self.variance: + if v <= 0: + raise ValueError('Variances must be greater than 0') + self.feature_maps = feature_maps + + + def forward(self): + mean = [] + for k in range(len(self.feature_maps)): + feath = self.feature_maps[k][0] + featw = self.feature_maps[k][1] + for i, j in product(range(feath), range(featw)): + f_kw = self.imw / self.steps[k] + f_kh = self.imh / self.steps[k] + + cx = (j + 0.5) / f_kw + cy = (i + 0.5) / f_kh + + s_kw = self.min_sizes[k] / self.imw + s_kh = self.min_sizes[k] / self.imh + + mean += [cx, cy, s_kw, s_kh] + + output = torch.Tensor(mean).view(-1, 4) + if self.clip: + output.clamp_(max=1, min=0) + return output \ No newline at end of file diff --git a/examples/pytorch/vision/Face_Detection/layers/modules/__init__.py b/examples/pytorch/vision/Face_Detection/layers/modules/__init__.py new file mode 100755 index 00000000..8c236578 --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/layers/modules/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +from .l2norm import L2Norm +from .multibox_loss import MultiBoxLoss + +__all__ = ['L2Norm', 'MultiBoxLoss'] + diff --git a/examples/pytorch/vision/Face_Detection/layers/modules/l2norm.py b/examples/pytorch/vision/Face_Detection/layers/modules/l2norm.py new file mode 100755 index 00000000..e6c909e6 --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/layers/modules/l2norm.py @@ -0,0 +1,29 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +import torch +import torch.nn as nn +import torch.nn.init as init + + +class L2Norm(nn.Module): + def __init__(self,n_channels, scale): + super(L2Norm,self).__init__() + self.n_channels = n_channels + self.gamma = scale or None + self.eps = 1e-10 + self.weight = nn.Parameter(torch.Tensor(self.n_channels)) + self.reset_parameters() + + def reset_parameters(self): + init.constant_(self.weight,self.gamma) + + def forward(self, x): + norm = x.pow(2).sum(dim=1, keepdim=True).sqrt()+self.eps + #x /= norm + x = torch.div(x,norm) + out = self.weight.unsqueeze(0).unsqueeze(2).unsqueeze(3).expand_as(x) * x + return out + + + \ No newline at end of file diff --git a/examples/pytorch/vision/Face_Detection/layers/modules/multibox_loss.py b/examples/pytorch/vision/Face_Detection/layers/modules/multibox_loss.py new file mode 100755 index 00000000..5ad634cc --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/layers/modules/multibox_loss.py @@ -0,0 +1,118 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +import math +import torch +import torch.nn as nn +import torch.nn.functional as F +from torch.autograd import Variable + + +from ..bbox_utils import match, log_sum_exp, match_ssd + + +class MultiBoxLoss(nn.Module): + """SSD Weighted Loss Function + Compute Targets: + 1) Produce Confidence Target Indices by matching ground truth boxes + with (default) 'priorboxes' that have jaccard index > threshold parameter + (default threshold: 0.5). + 2) Produce localization target by 'encoding' variance into offsets of ground + truth boxes and their matched 'priorboxes'. + 3) Hard negative mining to filter the excessive number of negative examples + that comes with using a large number of default bounding boxes. + (default negative:positive ratio 3:1) + Objective Loss: + L(x,c,l,g) = (Lconf(x, c) + αLloc(x,l,g)) / N + Where, Lconf is the CrossEntropy Loss and Lloc is the SmoothL1 Loss + weighted by α which is set to 1 by cross val. + Args: + c: class confidences, + l: predicted boxes, + g: ground truth boxes + N: number of matched default boxes + See: https://arxiv.org/pdf/1512.02325.pdf for more details. + """ + + def __init__(self, cfg, dataset, use_gpu=True): + super(MultiBoxLoss, self).__init__() + self.use_gpu = use_gpu + self.num_classes = cfg.NUM_CLASSES + self.negpos_ratio = cfg.NEG_POS_RATIOS + self.variance = cfg.VARIANCE + self.dataset = dataset + + self.threshold = cfg.FACE.OVERLAP_THRESH + self.match = match + + def forward(self, predictions, targets): + """Multibox Loss + Args: + predictions (tuple): A tuple containing loc preds, conf preds, + and prior boxes from SSD net. + conf shape: torch.size(batch_size,num_priors,num_classes) + loc shape: torch.size(batch_size,num_priors,4) + priors shape: torch.size(num_priors,4) + + targets (tensor): Ground truth boxes and labels for a batch, + shape: [batch_size,num_objs,5] (last idx is the label). + """ + loc_data, conf_data, priors = predictions + num = loc_data.size(0) + priors = priors[:loc_data.size(1), :] + num_priors = (priors.size(0)) + num_classes = self.num_classes + + # match priors (default boxes) and ground truth boxes + loc_t = torch.Tensor(num, num_priors, 4) + conf_t = torch.LongTensor(num, num_priors) + for idx in range(num): + truths = targets[idx][:, :-1].data + labels = targets[idx][:, -1].data + defaults = priors.data + self.match(self.threshold, truths, defaults, self.variance, labels, + loc_t, conf_t, idx) + if self.use_gpu: + loc_t = loc_t.cuda() + conf_t = conf_t.cuda() + # wrap targets + loc_t = Variable(loc_t, requires_grad=False) + conf_t = Variable(conf_t, requires_grad=False) + + pos = conf_t > 0 + num_pos = pos.sum(dim=1, keepdim=True) + # Localization Loss (Smooth L1) + # Shape: [batch,num_priors,4] + pos_idx = pos.unsqueeze(pos.dim()).expand_as(loc_data) + loc_p = loc_data[pos_idx].view(-1, 4) + loc_t = loc_t[pos_idx].view(-1, 4) + loss_l = F.smooth_l1_loss(loc_p, loc_t, size_average=False) + # print(loc_p) + # Compute max conf across batch for hard negative mining + batch_conf = conf_data.view(-1, self.num_classes) + loss_c = log_sum_exp(batch_conf) - \ + batch_conf.gather(1, conf_t.view(-1, 1)) + + # Hard Negative Mining + loss_c[pos.view(-1, 1)] = 0 # filter out pos boxes for now + loss_c = loss_c.view(num, -1) + _, loss_idx = loss_c.sort(1, descending=True) + _, idx_rank = loss_idx.sort(1) + num_pos = pos.long().sum(1, keepdim=True) + num_neg = torch.clamp(self.negpos_ratio * + num_pos, max=pos.size(1) - 1) + neg = idx_rank < num_neg.expand_as(idx_rank) + + # Confidence Loss Including Positive and Negative Examples + pos_idx = pos.unsqueeze(2).expand_as(conf_data) + neg_idx = neg.unsqueeze(2).expand_as(conf_data) + conf_p = conf_data[(pos_idx + neg_idx).gt(0) + ].view(-1, self.num_classes) + targets_weighted = conf_t[(pos + neg).gt(0)] + loss_c = F.cross_entropy(conf_p, targets_weighted, size_average=False) + + # Sum of losses: L(x,c,l,g) = (Lconf(x, c) + αLloc(x,l,g)) / N + N = num_pos.data.sum() if num_pos.data.sum() > 0 else num + loss_l /= N + loss_c /= N + return loss_l, loss_c \ No newline at end of file diff --git a/examples/pytorch/vision/Face_Detection/models/RPool_Face_C.py b/examples/pytorch/vision/Face_Detection/models/RPool_Face_C.py new file mode 100755 index 00000000..96396061 --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/models/RPool_Face_C.py @@ -0,0 +1,382 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +from __future__ import division +from __future__ import absolute_import +from __future__ import print_function + +import os +import torch +import torch.nn as nn +import torch.nn.init as init +import torch.nn.functional as F + + +from layers import * +from data.config import cfg +import numpy as np + +from edgeml_pytorch.graph.rnnpool import * + +class S3FD(nn.Module): + """Single Shot Multibox Architecture + The network is composed of a base VGG network followed by the + added multibox conv layers. Each multibox layer branches into + 1) conv2d for class conf scores + 2) conv2d for localization predictions + 3) associated priorbox layer to produce default bounding + boxes specific to the layer's feature map size. + See: https://arxiv.org/pdf/1512.02325.pdf for more details. + + Args: + phase: (string) Can be "test" or "train" + size: input image size + base: VGG16 layers for input, size of either 300 or 500 + extras: extra layers that feed to multibox loc and conf layers + head: "multibox head" consists of loc and conf conv layers + """ + + def __init__(self, phase, base, head, num_classes): + super(S3FD, self).__init__() + self.phase = phase + self.num_classes = num_classes + ''' + self.priorbox = PriorBox(size,cfg) + self.priors = Variable(self.priorbox.forward(), volatile=True) + ''' + # SSD network + + self.unfold = nn.Unfold(kernel_size=(8,8),stride=(4,4)) + + self.rnn_model = RNNPool(8, 8, 16, 16, 3) + + self.mob = nn.ModuleList(base) + # Layer learns to scale the l2 normalized features from conv4_3 + self.L2Norm3_3 = L2Norm(24, 10) + self.L2Norm4_3 = L2Norm(32, 8) + self.L2Norm5_3 = L2Norm(64, 5) + + + self.loc = nn.ModuleList(head[0]) + self.conf = nn.ModuleList(head[1]) + + if self.phase == 'test': + self.softmax = nn.Softmax(dim=-1) + # self.detect = Detect(cfg) + + + + def forward(self, x): + """Applies network layers and ops on input image(s) x. + + Args: + x: input image or batch of images. Shape: [batch,3,300,300]. + + Return: + Depending on phase: + test: + Variable(tensor) of output class label predictions, + confidence score, and corresponding location predictions for + each object detected. Shape: [batch,topk,7] + + train: + list of concat outputs from: + 1: confidence layers, Shape: [batch*num_priors,num_classes] + 2: localization layers, Shape: [batch,num_priors*4] + 3: priorbox layers, Shape: [2,num_priors*4] + """ + size = x.size()[2:] + batch_size = x.shape[0] + sources = list() + loc = list() + conf = list() + + patches = self.unfold(x) + patches = torch.cat(torch.unbind(patches,dim=2),dim=0) + patches = torch.reshape(patches,(-1,3,8,8)) + + output_x = int((x.shape[2]-8)/4 + 1) + output_y = int((x.shape[3]-8)/4 + 1) + + rnnX = self.rnn_model(patches, int(batch_size)*output_x*output_y) + + x = torch.stack(torch.split(rnnX, split_size_or_sections=int(batch_size), dim=0),dim=2) + + x = F.fold(x, kernel_size=(1,1), output_size=(output_x,output_y)) + + x = F.pad(x, (0,1,0,1), mode='replicate') + + + + for k in range(2): + x = self.mob[k](x) + + s = self.L2Norm3_3(x) + sources.append(s) + + for k in range(2, 5): + x = self.mob[k](x) + + s = self.L2Norm4_3(x) + sources.append(s) + + for k in range(5, 9): + x = self.mob[k](x) + + s = self.L2Norm5_3(x) + sources.append(s) + + for k in range(9, 12): + x = self.mob[k](x) + sources.append(x) + + for k in range(12, 14): + x = self.mob[k](x) + sources.append(x) + + for k in range(14, 15): + x = self.mob[k](x) + sources.append(x) + + + + # apply multibox head to source layers + + loc_x = self.loc[0](sources[0]) + conf_x = self.conf[0](sources[0]) + + max_conf, _ = torch.max(conf_x[:, 0:3, :, :], dim=1, keepdim=True) + conf_x = torch.cat((max_conf, conf_x[:, 3:, :, :]), dim=1) + + loc.append(loc_x.permute(0, 2, 3, 1).contiguous()) + conf.append(conf_x.permute(0, 2, 3, 1).contiguous()) + + for i in range(1, len(sources)): + x = sources[i] + conf.append(self.conf[i](x).permute(0, 2, 3, 1).contiguous()) + loc.append(self.loc[i](x).permute(0, 2, 3, 1).contiguous()) + + + features_maps = [] + for i in range(len(loc)): + feat = [] + feat += [loc[i].size(1), loc[i].size(2)] + features_maps += [feat] + + self.priorbox = PriorBox(size, features_maps, cfg) + self.priors = self.priorbox.forward() + + loc = torch.cat([o.view(o.size(0), -1) for o in loc], 1) + conf = torch.cat([o.view(o.size(0), -1) for o in conf], 1) + + + if self.phase == 'test': + output = detect_function( + loc.view(loc.size(0), -1, 4), # loc preds + self.softmax(conf.view(conf.size(0), -1, + self.num_classes)), # conf preds + self.priors.type(type(x.data)) # default boxes + ) + + else: + output = ( + loc.view(loc.size(0), -1, 4), + conf.view(conf.size(0), -1, self.num_classes), + self.priors + ) + return output + + def load_weights(self, base_file): + other, ext = os.path.splitext(base_file) + if ext == '.pkl' or '.pth': + print('Loading weights into state dict...') + mdata = torch.load(base_file, + map_location=lambda storage, loc: storage) + weights = mdata['weight'] + epoch = mdata['epoch'] + self.load_state_dict(weights) + print('Finished!') + else: + print('Sorry only .pth and .pkl files supported.') + return epoch + + def xavier(self, param): + init.xavier_uniform(param) + + def weights_init(self, m): + if isinstance(m, nn.Conv2d): + self.xavier(m.weight.data) + m.bias.data.zero_() + + + + +def _make_divisible(v, divisor, min_value=None): + """ + This function is taken from the original tf repo. + It ensures that all layers have a channel number that is divisible by 8 + It can be seen here: + https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py + :param v: + :param divisor: + :param min_value: + :return: + """ + 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 + + +class ConvBNReLU(nn.Sequential): + def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1): + padding = (kernel_size - 1) // 2 + super(ConvBNReLU, self).__init__( + nn.Conv2d(in_planes, out_planes, kernel_size, stride, padding, groups=groups, bias=False), + nn.BatchNorm2d(out_planes), + nn.ReLU6(inplace=True) + ) + + +class InvertedResidual(nn.Module): + def __init__(self, inp, oup, stride, expand_ratio): + super(InvertedResidual, self).__init__() + self.stride = stride + assert stride in [1, 2] + + hidden_dim = int(round(inp * expand_ratio)) + self.use_res_connect = self.stride == 1 and inp == oup + + layers = [] + if expand_ratio != 1: + # pw + layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1)) + layers.extend([ + # dw + ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim), + # pw-linear + nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), + nn.BatchNorm2d(oup), + ]) + self.conv = nn.Sequential(*layers) + + def forward(self, x): + if self.use_res_connect: + return x + self.conv(x) + else: + return self.conv(x) + + +class MobileNetV2(nn.Module): + def __init__(self, num_classes=1000, width_mult=1.0, inverted_residual_setting=None, round_nearest=8): + """ + MobileNet V2 main class + Args: + num_classes (int): Number of classes + width_mult (float): Width multiplier - adjusts number of channels in each layer by this amount + inverted_residual_setting: Network structure + round_nearest (int): Round the number of channels in each layer to be a multiple of this number + Set to 1 to turn off rounding + """ + super(MobileNetV2, self).__init__() + block = InvertedResidual + input_channel = 64 + + if inverted_residual_setting is None: + inverted_residual_setting = [ + # t, c, n, s + # [1, 16, 1, 1], + [1, 24, 1, 1], + [6, 24, 1, 1], + [6, 32, 3, 2], + [6, 64, 4, 2], + [6, 96, 3, 2], + [6, 160, 2, 2], + [6, 320, 1, 2], + ] + + if len(inverted_residual_setting) == 0 or len(inverted_residual_setting[0]) != 4: + raise ValueError("inverted_residual_setting should be non-empty " + "or a 4-element list, got {}".format(inverted_residual_setting)) + + # building first layer + input_channel = _make_divisible(input_channel * width_mult, round_nearest) + self.last_channel = _make_divisible(last_channel * max(1.0, width_mult), round_nearest) + self.layers = [] + # building inverted residual blocks + for t, c, n, s in inverted_residual_setting: + output_channel = _make_divisible(c * width_mult, round_nearest) + for i in range(n): + stride = s if i == 0 else 1 + self.layers.append(block(input_channel, output_channel, stride, expand_ratio=t)) + input_channel = output_channel + + # weight initialization + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight, mode='fan_out') + if m.bias is not None: + nn.init.zeros_(m.bias) + elif isinstance(m, nn.BatchNorm2d): + nn.init.ones_(m.weight) + nn.init.zeros_(m.bias) + elif isinstance(m, nn.Linear): + nn.init.normal_(m.weight, 0, 0.01) + nn.init.zeros_(m.bias) + + + +def multibox(mobilenet, num_classes): + loc_layers = [] + conf_layers = [] + + loc_layers += [nn.Conv2d(24, 4, + kernel_size=5, padding=2)] + conf_layers += [nn.Conv2d(24, + 3 + (num_classes-1), kernel_size=5, padding=2)] + + loc_layers += [nn.Conv2d(32, + 4, kernel_size=5, padding=2)] + conf_layers += [nn.Conv2d(32, + num_classes, kernel_size=5, padding=2)] + + loc_layers += [nn.Conv2d(64, + 4, kernel_size=5, padding=2)] + conf_layers += [nn.Conv2d(64, + num_classes, kernel_size=5, padding=2)] + + loc_layers += [nn.Conv2d(96, + 4, kernel_size=1, padding=0)] + conf_layers += [nn.Conv2d(96, + num_classes, kernel_size=1, padding=0)] + + loc_layers += [nn.Conv2d(160, + 4, kernel_size=1, padding=0)] + conf_layers += [nn.Conv2d(160, + num_classes, kernel_size=1, padding=0)] + + loc_layers += [nn.Conv2d(320, + 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(320, + num_classes, kernel_size=3, padding=1)] + + + + return mobilenet, (loc_layers, conf_layers) + + +def build_s3fd(phase, num_classes=2): + base_, head_ = multibox( + MobileNetV2().layers, num_classes) + + return S3FD(phase, base_, head_, num_classes) + + +if __name__ == '__main__': + net = build_s3fd('train', num_classes=2) + inputs = Variable(torch.randn(4, 3, 640, 640)) + output = net(inputs) + diff --git a/examples/pytorch/vision/Face_Detection/models/RPool_Face_QVGA_monochrome.py b/examples/pytorch/vision/Face_Detection/models/RPool_Face_QVGA_monochrome.py new file mode 100644 index 00000000..bb796f1a --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/models/RPool_Face_QVGA_monochrome.py @@ -0,0 +1,348 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +from __future__ import division +from __future__ import absolute_import +from __future__ import print_function + +import os +import torch +import torch.nn as nn +import torch.nn.init as init +import torch.nn.functional as F + + +from layers import * +from data.config_qvga import cfg +import numpy as np + +from edgeml_pytorch.graph.rnnpool import * + +class S3FD(nn.Module): + """Single Shot Multibox Architecture + The network is composed of a base VGG network followed by the + added multibox conv layers. Each multibox layer branches into + 1) conv2d for class conf scores + 2) conv2d for localization predictions + 3) associated priorbox layer to produce default bounding + boxes specific to the layer's feature map size. + See: https://arxiv.org/pdf/1512.02325.pdf for more details. + Args: + phase: (string) Can be "test" or "train" + size: input image size + base: VGG16 layers for input, size of either 300 or 500 + extras: extra layers that feed to multibox loc and conf layers + head: "multibox head" consists of loc and conf conv layers + """ + + def __init__(self, phase, base, head, num_classes): + super(S3FD, self).__init__() + self.phase = phase + self.num_classes = num_classes + ''' + self.priorbox = PriorBox(size,cfg) + self.priors = Variable(self.priorbox.forward(), volatile=True) + ''' + # SSD network + self.conv = ConvBNReLU(1, 4, stride=2) + + self.unfold = nn.Unfold(kernel_size=(8,8),stride=(4,4)) + + self.rnn_model = RNNPool(8, 8, 16, 16, 4)#num_init_features) + + self.mob = nn.ModuleList(base) + # Layer learns to scale the l2 normalized features from conv4_3 + self.L2Norm3_3 = L2Norm(32, 10) + self.L2Norm4_3 = L2Norm(32, 8) + self.L2Norm5_3 = L2Norm(96, 5) + + + self.loc = nn.ModuleList(head[0]) + self.conf = nn.ModuleList(head[1]) + + + if self.phase == 'test': + self.softmax = nn.Softmax(dim=-1) + + + def forward(self, x): + """Applies network layers and ops on input image(s) x. + Args: + x: input image or batch of images. Shape: [batch,3,300,300]. + Return: + Depending on phase: + test: + Variable(tensor) of output class label predictions, + confidence score, and corresponding location predictions for + each object detected. Shape: [batch,topk,7] + train: + list of concat outputs from: + 1: confidence layers, Shape: [batch*num_priors,num_classes] + 2: localization layers, Shape: [batch,num_priors*4] + 3: priorbox layers, Shape: [2,num_priors*4] + """ + size = x.size()[2:] + batch_size = x.shape[0] + sources = list() + loc = list() + conf = list() + + x = self.conv(x) + + patches = self.unfold(x) + patches = torch.cat(torch.unbind(patches,dim=2),dim=0) + patches = torch.reshape(patches,(-1,4,8,8)) + + output_x = int((x.shape[2]-8)/4 + 1) + output_y = int((x.shape[3]-8)/4 + 1) + + rnnX = self.rnn_model(patches, int(batch_size)*output_x*output_y) + + x = torch.stack(torch.split(rnnX, split_size_or_sections=int(batch_size), dim=0),dim=2) + + x = F.fold(x, kernel_size=(1,1), output_size=(output_x,output_y)) + + x = F.pad(x, (0,1,0,1), mode='replicate') + + for k in range(4): + x = self.mob[k](x) + + s = self.L2Norm3_3(x) + sources.append(s) + + for k in range(4, 8): + x = self.mob[k](x) + + s = self.L2Norm4_3(x) + sources.append(s) + + for k in range(8, 11): + x = self.mob[k](x) + + s = self.L2Norm5_3(x) + sources.append(s) + + for k in range(11, 14): + x = self.mob[k](x) + sources.append(x) + + + # apply multibox head to source layers + + loc_x = self.loc[0](sources[0]) + conf_x = self.conf[0](sources[0]) + + max_conf, _ = torch.max(conf_x[:, 0:3, :, :], dim=1, keepdim=True) + conf_x = torch.cat((max_conf, conf_x[:, 3:, :, :]), dim=1) + + loc.append(loc_x.permute(0, 2, 3, 1).contiguous()) + conf.append(conf_x.permute(0, 2, 3, 1).contiguous()) + + for i in range(1, len(sources)): + x = sources[i] + conf.append(self.conf[i](x).permute(0, 2, 3, 1).contiguous()) + loc.append(self.loc[i](x).permute(0, 2, 3, 1).contiguous()) + + + features_maps = [] + for i in range(len(loc)): + feat = [] + feat += [loc[i].size(1), loc[i].size(2)] + features_maps += [feat] + + self.priorbox = PriorBox(size, features_maps, cfg) + + self.priors = self.priorbox.forward() + + loc = torch.cat([o.view(o.size(0), -1) for o in loc], 1) + conf = torch.cat([o.view(o.size(0), -1) for o in conf], 1) + + + if self.phase == 'test': + output = detect_function(cfg, + loc.view(loc.size(0), -1, 4), # loc preds + self.softmax(conf.view(conf.size(0), -1, + self.num_classes)), # conf preds + self.priors.type(type(x.data)) # default boxes + ) + + else: + output = ( + loc.view(loc.size(0), -1, 4), + conf.view(conf.size(0), -1, self.num_classes), + self.priors + ) + return output + + def load_weights(self, base_file): + other, ext = os.path.splitext(base_file) + if ext == '.pkl' or '.pth': + print('Loading weights into state dict...') + mdata = torch.load(base_file, + map_location=lambda storage, loc: storage) + weights = mdata['weight'] + epoch = mdata['epoch'] + self.load_state_dict(weights) + print('Finished!') + else: + print('Sorry only .pth and .pkl files supported.') + return epoch + + def xavier(self, param): + init.xavier_uniform(param) + + def weights_init(self, m): + if isinstance(m, nn.Conv2d): + self.xavier(m.weight.data) + m.bias.data.zero_() + + + + +def _make_divisible(v, divisor, min_value=None): + """ + This function is taken from the original tf repo. + It ensures that all layers have a channel number that is divisible by 8 + It can be seen here: + https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py + :param v: + :param divisor: + :param min_value: + :return: + """ + 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 + + +class ConvBNReLU(nn.Sequential): + def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1): + padding = (kernel_size - 1) // 2 + super(ConvBNReLU, self).__init__( + nn.Conv2d(in_planes, out_planes, kernel_size, stride, padding, groups=groups, bias=False), + nn.BatchNorm2d(out_planes), + nn.ReLU6(inplace=True) + ) + + +class InvertedResidual(nn.Module): + def __init__(self, inp, oup, stride, expand_ratio): + super(InvertedResidual, self).__init__() + self.stride = stride + assert stride in [1, 2] + + hidden_dim = int(round(inp * expand_ratio)) + self.use_res_connect = self.stride == 1 and inp == oup + + layers = [] + if expand_ratio != 1: + # pw + layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1)) + layers.extend([ + # dw + ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim), + # pw-linear + nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), + nn.BatchNorm2d(oup), + ]) + self.conv = nn.Sequential(*layers) + + def forward(self, x): + if self.use_res_connect: + return x + self.conv(x) + else: + return self.conv(x) + + +class MobileNetV2(nn.Module): + def __init__(self, num_classes=1000, width_mult=1.0, inverted_residual_setting=None, round_nearest=8): + """ + MobileNet V2 main class + Args: + num_classes (int): Number of classes + width_mult (float): Width multiplier - adjusts number of channels in each layer by this amount + inverted_residual_setting: Network structure + round_nearest (int): Round the number of channels in each layer to be a multiple of this number + Set to 1 to turn off rounding + """ + super(MobileNetV2, self).__init__() + block = InvertedResidual + input_channel = 64 + + if inverted_residual_setting is None: + inverted_residual_setting = [ + # t, c, n, s + [2, 32, 4, 1], + [2, 32, 4, 1], + [2, 96, 3, 2], + [2, 128, 3, 1], + ] + + # only check the first element, assuming user knows t,c,n,s are required + if len(inverted_residual_setting) == 0 or len(inverted_residual_setting[0]) != 4: + raise ValueError("inverted_residual_setting should be non-empty " + "or a 4-element list, got {}".format(inverted_residual_setting)) + + # building first layer + input_channel = _make_divisible(input_channel * width_mult, round_nearest) + self.last_channel = _make_divisible(last_channel * max(1.0, width_mult), round_nearest) + self.layers = [] + # building inverted residual blocks + for t, c, n, s in inverted_residual_setting: + output_channel = _make_divisible(c * width_mult, round_nearest) + for i in range(n): + stride = s if i == 0 else 1 + self.layers.append(block(input_channel, output_channel, stride, expand_ratio=t)) + input_channel = output_channel + + # weight initialization + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight, mode='fan_out') + if m.bias is not None: + nn.init.zeros_(m.bias) + elif isinstance(m, nn.BatchNorm2d): + nn.init.ones_(m.weight) + nn.init.zeros_(m.bias) + elif isinstance(m, nn.Linear): + nn.init.normal_(m.weight, 0, 0.01) + nn.init.zeros_(m.bias) + + + + +def multibox(mobilenet, num_classes): + loc_layers = [] + conf_layers = [] + + loc_layers += [nn.Conv2d(32, 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(32, 3 + (num_classes-1), kernel_size=3, padding=1)] + + loc_layers += [nn.Conv2d(32, 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(32, num_classes, kernel_size=3, padding=1)] + + loc_layers += [nn.Conv2d(96, 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(96, num_classes, kernel_size=3, padding=1)] + + loc_layers += [nn.Conv2d(128, 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(128, num_classes, kernel_size=3, padding=1)] + + + return mobilenet, (loc_layers, conf_layers) + + +def build_s3fd(phase, num_classes=2): + base_, head_ = multibox( + MobileNetV2().layers, num_classes) + + return S3FD(phase, base_, head_, num_classes) + + +if __name__ == '__main__': + net = build_s3fd('train', num_classes=2) + inputs = Variable(torch.randn(4, 1, 320, 320)) + output = net(inputs) diff --git a/examples/pytorch/vision/Face_Detection/models/RPool_Face_Quant.py b/examples/pytorch/vision/Face_Detection/models/RPool_Face_Quant.py new file mode 100755 index 00000000..6cac8fa9 --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/models/RPool_Face_Quant.py @@ -0,0 +1,375 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +from __future__ import division +from __future__ import absolute_import +from __future__ import print_function + +import os +import torch +import torch.nn as nn +import torch.nn.init as init +import torch.nn.functional as F + + +from layers import * +from data.config import cfg +import numpy as np + +from edgeml_pytorch.graph.rnnpool import * + +class S3FD(nn.Module): + """Single Shot Multibox Architecture + The network is composed of a base VGG network followed by the + added multibox conv layers. Each multibox layer branches into + 1) conv2d for class conf scores + 2) conv2d for localization predictions + 3) associated priorbox layer to produce default bounding + boxes specific to the layer's feature map size. + See: https://arxiv.org/pdf/1512.02325.pdf for more details. + Args: + phase: (string) Can be "test" or "train" + size: input image size + base: VGG16 layers for input, size of either 300 or 500 + extras: extra layers that feed to multibox loc and conf layers + head: "multibox head" consists of loc and conf conv layers + """ + + def __init__(self, phase, base, head, num_classes): + super(S3FD, self).__init__() + self.phase = phase + self.num_classes = num_classes + ''' + self.priorbox = PriorBox(size,cfg) + self.priors = Variable(self.priorbox.forward(), volatile=True) + ''' + # SSD network + + self.conv_top = nn.Sequential(ConvBNReLU(3, 4, kernel_size=3, stride=2), ConvBNReLU(4, 4, kernel_size=3)) + + self.unfold = nn.Unfold(kernel_size=(8,8),stride=(4,4)) + + self.rnn_model = RNNPool(8, 8, 8, 8, 4) + + self.mob = nn.ModuleList(base) + # Layer learns to scale the l2 normalized features from conv4_3 + self.L2Norm3_3 = L2Norm(4, 10) + self.L2Norm4_3 = L2Norm(16, 8) + self.L2Norm5_3 = L2Norm(24, 5) + + + self.loc = nn.ModuleList(head[0]) + self.conf = nn.ModuleList(head[1]) + + if self.phase == 'test': + self.softmax = nn.Softmax(dim=-1) + + + def forward(self, x): + """Applies network layers and ops on input image(s) x. + Args: + x: input image or batch of images. Shape: [batch,3,300,300]. + Return: + Depending on phase: + test: + Variable(tensor) of output class label predictions, + confidence score, and corresponding location predictions for + each object detected. Shape: [batch,topk,7] + train: + list of concat outputs from: + 1: confidence layers, Shape: [batch*num_priors,num_classes] + 2: localization layers, Shape: [batch,num_priors*4] + 3: priorbox layers, Shape: [2,num_priors*4] + """ + size = x.size()[2:] + batch_size = x.shape[0] + sources = list() + loc = list() + conf = list() + + x = self.conv_top(x) + + s = self.L2Norm3_3(x) + sources.append(s) + + patches = self.unfold(x) + patches = torch.cat(torch.unbind(patches,dim=2),dim=0) + patches = torch.reshape(patches,(-1,4,8,8)) + + output_x = int((x.shape[2]-8)/4 + 1) + output_y = int((x.shape[3]-8)/4 + 1) + + rnnX = self.rnn_model(patches, int(batch_size)*output_x*output_y) + + x = torch.stack(torch.split(rnnX, split_size_or_sections=int(batch_size), dim=0),dim=2) + + x = F.fold(x, kernel_size=(1,1), output_size=(output_x,output_y)) + + x = F.pad(x, (0,1,0,1), mode='replicate') + + for k in range(4): + x = self.mob[k](x) + + s = self.L2Norm4_3(x) + sources.append(s) + + for k in range(4, 8): + x = self.mob[k](x) + + s = self.L2Norm5_3(x) + sources.append(s) + + for k in range(8, 10): + x = self.mob[k](x) + sources.append(x) + + for k in range(10, 11): + x = self.mob[k](x) + sources.append(x) + + for k in range(11, 12): + x = self.mob[k](x) + sources.append(x) + + + + # apply multibox head to source layers + + loc_x = self.loc[0](sources[0]) + conf_x = self.conf[0](sources[0]) + + loc_x = self.loc[1](loc_x) + conf_x = self.conf[1](conf_x) + + max_conf, _ = torch.max(conf_x[:, 0:3, :, :], dim=1, keepdim=True) + conf_x = torch.cat((max_conf, conf_x[:, 3:, :, :]), dim=1) + + loc.append(loc_x.permute(0, 2, 3, 1).contiguous()) + conf.append(conf_x.permute(0, 2, 3, 1).contiguous()) + + for i in range(1, len(sources)): + x = sources[i] + conf.append(self.conf[i+1](x).permute(0, 2, 3, 1).contiguous()) + loc.append(self.loc[i+1](x).permute(0, 2, 3, 1).contiguous()) + + + features_maps = [] + for i in range(len(loc)): + feat = [] + feat += [loc[i].size(1), loc[i].size(2)] + features_maps += [feat] + + self.priorbox = PriorBox(size, features_maps, cfg) + self.priors = self.priorbox.forward() + + loc = torch.cat([o.view(o.size(0), -1) for o in loc], 1) + conf = torch.cat([o.view(o.size(0), -1) for o in conf], 1) + + + if self.phase == 'test': + output = detect_function(cfg, + loc.view(loc.size(0), -1, 4), # loc preds + self.softmax(conf.view(conf.size(0), -1, + self.num_classes)), # conf preds + self.priors.type(type(x.data)) # default boxes + ) + + else: + output = ( + loc.view(loc.size(0), -1, 4), + conf.view(conf.size(0), -1, self.num_classes), + self.priors + ) + return output + + def load_weights(self, base_file): + other, ext = os.path.splitext(base_file) + if ext == '.pkl' or '.pth': + print('Loading weights into state dict...') + mdata = torch.load(base_file, + map_location=lambda storage, loc: storage) + weights = mdata['weight'] + epoch = mdata['epoch'] + self.load_state_dict(weights) + print('Finished!') + else: + print('Sorry only .pth and .pkl files supported.') + return epoch + + def xavier(self, param): + init.xavier_uniform(param) + + def weights_init(self, m): + if isinstance(m, nn.Conv2d): + self.xavier(m.weight.data) + m.bias.data.zero_() + + + + +def _make_divisible(v, divisor, min_value=None): + """ + This function is taken from the original tf repo. + It ensures that all layers have a channel number that is divisible by 8 + It can be seen here: + https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py + :param v: + :param divisor: + :param min_value: + :return: + """ + 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 + + +class ConvBNReLU(nn.Sequential): + def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1): + padding = (kernel_size - 1) // 2 + super(ConvBNReLU, self).__init__( + nn.Conv2d(in_planes, out_planes, kernel_size, stride, padding, groups=groups, bias=False), + nn.BatchNorm2d(out_planes), + nn.ReLU6(inplace=True) + ) + + +class InvertedResidual(nn.Module): + def __init__(self, inp, oup, stride, expand_ratio): + super(InvertedResidual, self).__init__() + self.stride = stride + assert stride in [1, 2] + + hidden_dim = int(round(inp * expand_ratio)) + self.use_res_connect = self.stride == 1 and inp == oup + + layers = [] + if expand_ratio != 1: + # pw + layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1)) + layers.extend([ + # dw + ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim), + # pw-linear + nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), + nn.BatchNorm2d(oup), + ]) + self.conv = nn.Sequential(*layers) + + def forward(self, x): + if self.use_res_connect: + return x + self.conv(x) + else: + return self.conv(x) + + +class MobileNetV2(nn.Module): + def __init__(self, num_classes=1000, width_mult=1.0, inverted_residual_setting=None, round_nearest=8): + """ + MobileNet V2 main class + Args: + num_classes (int): Number of classes + width_mult (float): Width multiplier - adjusts number of channels in each layer by this amount + inverted_residual_setting: Network structure + round_nearest (int): Round the number of channels in each layer to be a multiple of this number + Set to 1 to turn off rounding + """ + super(MobileNetV2, self).__init__() + block = InvertedResidual + input_channel = 32 + + if inverted_residual_setting is None: + inverted_residual_setting = [ + # t, c, n, s + [2, 16, 4, 1], + [2, 24, 4, 2], + [2, 32, 2, 2], + [2, 64, 1, 2], + [2, 96, 1, 2], + ] + + if len(inverted_residual_setting) == 0 or len(inverted_residual_setting[0]) != 4: + raise ValueError("inverted_residual_setting should be non-empty " + "or a 4-element list, got {}".format(inverted_residual_setting)) + + # building first layer + input_channel = _make_divisible(input_channel * width_mult, round_nearest) + self.last_channel = _make_divisible(last_channel * max(1.0, width_mult), round_nearest) + self.layers = [] + # building inverted residual blocks + for t, c, n, s in inverted_residual_setting: + output_channel = _make_divisible(c * width_mult, round_nearest) + for i in range(n): + stride = s if i == 0 else 1 + self.layers.append(block(input_channel, output_channel, stride, expand_ratio=t)) + input_channel = output_channel + + # weight initialization + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight, mode='fan_out') + if m.bias is not None: + nn.init.zeros_(m.bias) + elif isinstance(m, nn.BatchNorm2d): + nn.init.ones_(m.weight) + nn.init.zeros_(m.bias) + elif isinstance(m, nn.Linear): + nn.init.normal_(m.weight, 0, 0.01) + nn.init.zeros_(m.bias) + + + + +def multibox(mobilenet, num_classes): + loc_layers = [] + conf_layers = [] + + loc_layers += nn.Sequential(ConvBNReLU(4, 8, kernel_size=3, stride=2), + nn.Conv2d(8, 4, kernel_size=3, padding=1)) + conf_layers += nn.Sequential(ConvBNReLU(4, 8, kernel_size=3, stride=2), + nn.Conv2d(8, 3 + (num_classes-1), kernel_size=3, padding=1)) + + loc_layers += [nn.Conv2d(16, + 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(16, + num_classes, kernel_size=3, padding=1)] + + loc_layers += [nn.Conv2d(24, + 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(24, + num_classes, kernel_size=3, padding=1)] + + loc_layers += [nn.Conv2d(32, + 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(32, + num_classes, kernel_size=3, padding=1)] + + loc_layers += [nn.Conv2d(64, + 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(64, + num_classes, kernel_size=3, padding=1)] + + loc_layers += [nn.Conv2d(96, + 4, kernel_size=3, padding=1)] + conf_layers += [nn.Conv2d(96, + num_classes, kernel_size=3, padding=1)] + + + + return mobilenet, (loc_layers, conf_layers) + + +def build_s3fd(phase, num_classes=2): + base_, head_ = multibox( + MobileNetV2().layers, num_classes) + + return S3FD(phase, base_, head_, num_classes) + + +if __name__ == '__main__': + net = build_s3fd('train', num_classes=2) + inputs = Variable(torch.randn(4, 3, 640, 640)) + output = net(inputs) diff --git a/examples/pytorch/vision/Face_Detection/models/__init__.py b/examples/pytorch/vision/Face_Detection/models/__init__.py new file mode 100644 index 00000000..f8dc538e --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/models/__init__.py @@ -0,0 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +from __future__ import absolute_import +from .RPool_Face_C import * +from .RPool_Face_Quant import * diff --git a/examples/pytorch/vision/Face_Detection/prepare_wider_data.py b/examples/pytorch/vision/Face_Detection/prepare_wider_data.py new file mode 100755 index 00000000..bc6985c0 --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/prepare_wider_data.py @@ -0,0 +1,86 @@ +## This code is built on https://github.com/yxlijun/S3FD.pytorch +#-*- coding:utf-8 -*- + +from __future__ import division +from __future__ import absolute_import +from __future__ import print_function + + +import os +from data.config import cfg +import cv2 + +WIDER_ROOT = os.path.join(cfg.HOME, 'WIDER_FACE') +train_list_file = os.path.join(WIDER_ROOT, 'wider_face_split', + 'wider_face_train_bbx_gt.txt') +val_list_file = os.path.join(WIDER_ROOT, 'wider_face_split', + 'wider_face_val_bbx_gt.txt') + +WIDER_TRAIN = os.path.join(WIDER_ROOT, 'WIDER_train', 'images') +WIDER_VAL = os.path.join(WIDER_ROOT, 'WIDER_val', 'images') + + +def parse_wider_file(root, file): + with open(file, 'r') as fr: + lines = fr.readlines() + face_count = [] + img_paths = [] + face_loc = [] + img_faces = [] + count = 0 + flag = False + for k, line in enumerate(lines): + line = line.strip().strip('\n') + if count > 0: + line = line.split(' ') + count -= 1 + loc = [int(line[0]), int(line[1]), int(line[2]), int(line[3])] + face_loc += [loc] + if flag: + face_count += [int(line)] + flag = False + count = int(line) + if 'jpg' in line: + img_paths += [os.path.join(root, line)] + flag = True + + total_face = 0 + for k in face_count: + face_ = [] + for x in range(total_face, total_face + k): + face_.append(face_loc[x]) + img_faces += [face_] + total_face += k + return img_paths, img_faces + + +def wider_data_file(): + img_paths, bbox = parse_wider_file(WIDER_TRAIN, train_list_file) + fw = open(cfg.FACE.TRAIN_FILE, 'w') + for index in range(len(img_paths)): + path = img_paths[index] + boxes = bbox[index] + fw.write(path) + fw.write(' {}'.format(len(boxes))) + for box in boxes: + data = ' {} {} {} {} {}'.format(box[0], box[1], box[2], box[3], 1) + fw.write(data) + fw.write('\n') + fw.close() + + img_paths, bbox = parse_wider_file(WIDER_VAL, val_list_file) + fw = open(cfg.FACE.VAL_FILE, 'w') + for index in range(len(img_paths)): + path = img_paths[index] + boxes = bbox[index] + fw.write(path) + fw.write(' {}'.format(len(boxes))) + for box in boxes: + data = ' {} {} {} {} {}'.format(box[0], box[1], box[2], box[3], 1) + fw.write(data) + fw.write('\n') + fw.close() + + +if __name__ == '__main__': + wider_data_file() diff --git a/examples/pytorch/vision/Face_Detection/requirements.txt b/examples/pytorch/vision/Face_Detection/requirements.txt new file mode 100644 index 00000000..6d3a8719 --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/requirements.txt @@ -0,0 +1,10 @@ +Cython==0.29.15 +easydict==1.9 +importlib-metadata==1.5.0 +matplotlib==3.2.1 +opencv-python-headless==4.2.0.32 +PyYAML==3.12 +scikit-image==0.15.0 +tensorboard==1.14.0 +tensorboardX==1.9 +tqdm==4.36.1 \ No newline at end of file diff --git a/examples/pytorch/vision/Face_Detection/train.py b/examples/pytorch/vision/Face_Detection/train.py new file mode 100755 index 00000000..1b52089c --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/train.py @@ -0,0 +1,244 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +from data import * +from layers.modules import MultiBoxLoss +import os +import time +import torch +import torch.nn as nn +import torch.optim as optim +import torch.nn.init as init +import torch.utils.data as data +import numpy as np +import argparse +import torch.backends.cudnn as cudnn + +from data.choose_config import cfg +cfg = cfg.cfg +from importlib import import_module + + +def str2bool(v): + return v.lower() in ("yes", "true", "t", "1") + +parser = argparse.ArgumentParser( + description='S3FD face Detector Training With Pytorch') +train_set = parser.add_mutually_exclusive_group() +parser.add_argument('--dataset', + default='face', + choices=['hand', 'face', 'head'], + help='Train target') +parser.add_argument('--basenet', + default='vgg16_reducedfc.pth', + help='Pretrained base model') +parser.add_argument('--batch_size', + default=16, type=int, + help='Batch size for training') +parser.add_argument('--resume', + default=None, type=str, + help='Checkpoint state_dict file to resume training from') +parser.add_argument('--model_arch', + default='RPool_Face_C', type=str, + choices=['RPool_Face_C', 'RPool_Face_Quant', 'RPool_Face_QVGA_monochrome'], + help='choose architecture among rpool variants') +parser.add_argument('--num_workers', + default=128, type=int, + help='Number of workers used in dataloading') +parser.add_argument('--cuda', + default=True, type=str2bool, + help='Use CUDA to train model') +parser.add_argument('--lr', '--learning-rate', + default=1e-2, type=float, + help='initial learning rate') +parser.add_argument('--momentum', + default=0.9, type=float, + help='Momentum value for optim') +parser.add_argument('--weight_decay', + default=5e-4, type=float, + help='Weight decay for SGD') +parser.add_argument('--gamma', + default=0.1, type=float, + help='Gamma update for SGD') +parser.add_argument('--multigpu', + default=False, type=str2bool, + help='Use mutil Gpu training') +parser.add_argument('--save_folder', + default='weights/', + help='Directory for saving checkpoint models') +parser.add_argument('--epochs', + default=300, type=int, + help='total epochs') +parser.add_argument('--save_frequency', + default=5000, type=int, + help='iterations interval after which checkpoint is saved') +args = parser.parse_args() + + +if torch.cuda.is_available(): + if args.cuda: + torch.set_default_tensor_type('torch.cuda.FloatTensor') + if not args.cuda: + print("WARNING: It looks like you have a CUDA device, but aren't " + + "using CUDA.\nRun with --cuda for optimal training speed.") + torch.set_default_tensor_type('torch.FloatTensor') +else: + torch.set_default_tensor_type('torch.FloatTensor') + +if not os.path.exists(args.save_folder): + os.makedirs(args.save_folder) + + +train_dataset = WIDERDetection(cfg.FACE.TRAIN_FILE, mode='train', mono_mode=cfg.IS_MONOCHROME) +val_dataset = WIDERDetection(cfg.FACE.VAL_FILE, mode='val', mono_mode=cfg.IS_MONOCHROME) + +train_loader = data.DataLoader(train_dataset, args.batch_size, + num_workers=args.num_workers, + shuffle=True, + collate_fn=detection_collate, + pin_memory=True) + +val_batchsize = args.batch_size // 2 +val_loader = data.DataLoader(val_dataset, val_batchsize, + num_workers=args.num_workers, + shuffle=False, + collate_fn=detection_collate, + pin_memory=True) + +min_loss = np.inf +start_epoch = 0 + +module = import_module('models.' + args.model_arch) +net = module.build_s3fd('train', cfg.NUM_CLASSES) + + + +if args.cuda: + if args.multigpu: + net = torch.nn.DataParallel(net) + net = net.cuda() + cudnn.benckmark = True + +if args.resume: + print('Resuming training, loading {}...'.format(args.resume)) + net.load_state_dict(torch.load(args.resume)) + +optimizer = optim.SGD(net.parameters(), lr=args.lr, momentum=args.momentum, + weight_decay=args.weight_decay) + +criterion = MultiBoxLoss(cfg, args.dataset, args.cuda) +print('Loading wider dataset...') +print('Using the specified args:') +print(args) + + +def train(): + step_index = 0 + iteration = 0 + + for epoch in range(start_epoch, args.epochs): + net.train() + losses = 0 + train_loader_len = len(train_loader) + for batch_idx, (images, targets) in enumerate(train_loader): + adjust_learning_rate(optimizer, epoch, batch_idx, train_loader_len) + + if args.cuda: + images = images.cuda() + targets = [ann.cuda() + for ann in targets] + else: + images = images + targets = [ann for ann in targets] + + + t0 = time.time() + out = net(images) + # backprop + optimizer.zero_grad() + loss_l, loss_c = criterion(out, targets) + loss = loss_l + loss_c + loss.backward() + optimizer.step() + t1 = time.time() + losses += loss.item() + + if iteration % 10 == 0: + tloss = losses / (batch_idx + 1) + print('Timer: %.4f' % (t1 - t0)) + print('epoch:' + repr(epoch) + ' || iter:' + + repr(iteration) + ' || Loss:%.4f' % (tloss)) + print('->> conf loss:{:.4f} || loc loss:{:.4f}'.format( + loss_c.item(), loss_l.item())) + print('->>lr:{:.6f}'.format(optimizer.param_groups[0]['lr'])) + + if iteration != 0 and iteration % args.save_frequency == 0: + print('Saving state, iter:', iteration) + file = 'rpool_' + args.dataset + '_' + repr(iteration) + '_checkpoint.pth' + torch.save(net.state_dict(), + os.path.join(args.save_folder, file)) + iteration += 1 + + val(epoch) + if iteration == cfg.MAX_STEPS: + break + + +def val(epoch): + net.eval() + loc_loss = 0 + conf_loss = 0 + step = 0 + t1 = time.time() + with torch.no_grad(): + for batch_idx, (images, targets) in enumerate(val_loader): + if args.cuda: + images = images.cuda() + targets = [ann.cuda() + for ann in targets] + else: + images = images + targets = [ann for ann in targets] + + out = net(images) + loss_l, loss_c = criterion(out, targets) + loss = loss_l + loss_c + loc_loss += loss_l.item() + conf_loss += loss_c.item() + step += 1 + + tloss = (loc_loss + conf_loss) / step + t2 = time.time() + print('Timer: %.4f' % (t2 - t1)) + print('test epoch:' + repr(epoch) + ' || Loss:%.4f' % (tloss)) + + global min_loss + if tloss < min_loss: + print('Saving best state,epoch', epoch) + file = '{}_best_state.pth'.format(args.model_arch) + torch.save(net.state_dict(), os.path.join( + args.save_folder, file)) + min_loss = tloss + + + +from math import cos, pi +def adjust_learning_rate(optimizer, epoch, iteration, num_iter): + lr = optimizer.param_groups[0]['lr'] + + warmup_epoch = 5 + warmup_iter = warmup_epoch * num_iter + current_iter = iteration + epoch * num_iter + max_iter = args.epochs * num_iter + + lr = args.lr * (1 + cos(pi * (current_iter - warmup_iter) / (max_iter - warmup_iter))) / 2 + + if epoch < warmup_epoch: + lr = args.lr * current_iter / warmup_iter + + for param_group in optimizer.param_groups: + param_group['lr'] = lr + + +if __name__ == '__main__': + train() \ No newline at end of file diff --git a/examples/pytorch/vision/Face_Detection/utils/__init__.py b/examples/pytorch/vision/Face_Detection/utils/__init__.py new file mode 100755 index 00000000..279e648c --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/utils/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +from .augmentations import * \ No newline at end of file diff --git a/examples/pytorch/vision/Face_Detection/utils/augmentations.py b/examples/pytorch/vision/Face_Detection/utils/augmentations.py new file mode 100755 index 00000000..3b902aac --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/utils/augmentations.py @@ -0,0 +1,862 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + + +import torch +from torchvision import transforms +import cv2 +import numpy as np +import types +from PIL import Image, ImageEnhance, ImageDraw +import math +import six + +import sys; sys.path.append('../') +from data.choose_config import cfg +cfg = cfg.cfg +import random + + +class sampler(): + + def __init__(self, + max_sample, + max_trial, + min_scale, + max_scale, + min_aspect_ratio, + max_aspect_ratio, + min_jaccard_overlap, + max_jaccard_overlap, + min_object_coverage, + max_object_coverage, + use_square=False): + self.max_sample = max_sample + self.max_trial = max_trial + self.min_scale = min_scale + self.max_scale = max_scale + self.min_aspect_ratio = min_aspect_ratio + self.max_aspect_ratio = max_aspect_ratio + self.min_jaccard_overlap = min_jaccard_overlap + self.max_jaccard_overlap = max_jaccard_overlap + self.min_object_coverage = min_object_coverage + self.max_object_coverage = max_object_coverage + self.use_square = use_square + + +def intersect(box_a, box_b): + max_xy = np.minimum(box_a[:, 2:], box_b[2:]) + min_xy = np.maximum(box_a[:, :2], box_b[:2]) + inter = np.clip((max_xy - min_xy), a_min=0, a_max=np.inf) + return inter[:, 0] * inter[:, 1] + + +def jaccard_numpy(box_a, box_b): + """Compute the jaccard overlap of two sets of boxes. The jaccard overlap + is simply the intersection over union of two boxes. + E.g.: + A ∩ B / A ∪ B = A ∩ B / (area(A) + area(B) - A ∩ B) + Args: + box_a: Multiple bounding boxes, Shape: [num_boxes,4] + box_b: Single bounding box, Shape: [4] + Return: + jaccard overlap: Shape: [box_a.shape[0], box_a.shape[1]] + """ + inter = intersect(box_a, box_b) + area_a = ((box_a[:, 2] - box_a[:, 0]) * + (box_a[:, 3] - box_a[:, 1])) # [A,B] + area_b = ((box_b[2] - box_b[0]) * + (box_b[3] - box_b[1])) # [A,B] + union = area_a + area_b - inter + return inter / union # [A,B] + + +class bbox(): + + def __init__(self, xmin, ymin, xmax, ymax): + self.xmin = xmin + self.ymin = ymin + self.xmax = xmax + self.ymax = ymax + + +def random_brightness(img): + prob = np.random.uniform(0, 1) + if prob < cfg.brightness_prob: + delta = np.random.uniform(-cfg.brightness_delta, + cfg.brightness_delta) + 1 + img = ImageEnhance.Brightness(img).enhance(delta) + return img + + +def random_contrast(img): + prob = np.random.uniform(0, 1) + if prob < cfg.contrast_prob: + delta = np.random.uniform(-cfg.contrast_delta, + cfg.contrast_delta) + 1 + img = ImageEnhance.Contrast(img).enhance(delta) + return img + + +def random_saturation(img): + prob = np.random.uniform(0, 1) + if prob < cfg.saturation_prob: + delta = np.random.uniform(-cfg.saturation_delta, + cfg.saturation_delta) + 1 + img = ImageEnhance.Color(img).enhance(delta) + return img + + +def random_hue(img): + prob = np.random.uniform(0, 1) + if prob < cfg.hue_prob: + delta = np.random.uniform(-cfg.hue_delta, cfg.hue_delta) + img_hsv = np.array(img.convert('HSV')) + img_hsv[:, :, 0] = img_hsv[:, :, 0] + delta + img = Image.fromarray(img_hsv, mode='HSV').convert('RGB') + return img + + +def distort_image(img): + prob = np.random.uniform(0, 1) + # Apply different distort order + if prob > 0.5: + img = random_brightness(img) + img = random_contrast(img) + img = random_saturation(img) + img = random_hue(img) + else: + img = random_brightness(img) + img = random_saturation(img) + img = random_hue(img) + img = random_contrast(img) + return img + + +def meet_emit_constraint(src_bbox, sample_bbox): + center_x = (src_bbox.xmax + src_bbox.xmin) / 2 + center_y = (src_bbox.ymax + src_bbox.ymin) / 2 + if center_x >= sample_bbox.xmin and \ + center_x <= sample_bbox.xmax and \ + center_y >= sample_bbox.ymin and \ + center_y <= sample_bbox.ymax: + return True + return False + + +def project_bbox(object_bbox, sample_bbox): + if object_bbox.xmin >= sample_bbox.xmax or \ + object_bbox.xmax <= sample_bbox.xmin or \ + object_bbox.ymin >= sample_bbox.ymax or \ + object_bbox.ymax <= sample_bbox.ymin: + return False + else: + proj_bbox = bbox(0, 0, 0, 0) + sample_width = sample_bbox.xmax - sample_bbox.xmin + sample_height = sample_bbox.ymax - sample_bbox.ymin + proj_bbox.xmin = (object_bbox.xmin - sample_bbox.xmin) / sample_width + proj_bbox.ymin = (object_bbox.ymin - sample_bbox.ymin) / sample_height + proj_bbox.xmax = (object_bbox.xmax - sample_bbox.xmin) / sample_width + proj_bbox.ymax = (object_bbox.ymax - sample_bbox.ymin) / sample_height + proj_bbox = clip_bbox(proj_bbox) + if bbox_area(proj_bbox) > 0: + return proj_bbox + else: + return False + + +def transform_labels(bbox_labels, sample_bbox): + sample_labels = [] + for i in range(len(bbox_labels)): + sample_label = [] + object_bbox = bbox(bbox_labels[i][1], bbox_labels[i][2], + bbox_labels[i][3], bbox_labels[i][4]) + if not meet_emit_constraint(object_bbox, sample_bbox): + continue + proj_bbox = project_bbox(object_bbox, sample_bbox) + if proj_bbox: + sample_label.append(bbox_labels[i][0]) + sample_label.append(float(proj_bbox.xmin)) + sample_label.append(float(proj_bbox.ymin)) + sample_label.append(float(proj_bbox.xmax)) + sample_label.append(float(proj_bbox.ymax)) + sample_label = sample_label + bbox_labels[i][5:] + sample_labels.append(sample_label) + return sample_labels + + +def expand_image(img, bbox_labels, img_width, img_height): + prob = np.random.uniform(0, 1) + if prob < cfg.expand_prob: + if cfg.expand_max_ratio - 1 >= 0.01: + expand_ratio = np.random.uniform(1, cfg.expand_max_ratio) + height = int(img_height * expand_ratio) + width = int(img_width * expand_ratio) + h_off = math.floor(np.random.uniform(0, height - img_height)) + w_off = math.floor(np.random.uniform(0, width - img_width)) + expand_bbox = bbox(-w_off / img_width, -h_off / img_height, + (width - w_off) / img_width, + (height - h_off) / img_height) + expand_img = np.ones((height, width, 3)) + expand_img = np.uint8(expand_img * np.squeeze(cfg.img_mean)) + expand_img = Image.fromarray(expand_img) + expand_img.paste(img, (int(w_off), int(h_off))) + bbox_labels = transform_labels(bbox_labels, expand_bbox) + return expand_img, bbox_labels, width, height + return img, bbox_labels, img_width, img_height + + +def clip_bbox(src_bbox): + src_bbox.xmin = max(min(src_bbox.xmin, 1.0), 0.0) + src_bbox.ymin = max(min(src_bbox.ymin, 1.0), 0.0) + src_bbox.xmax = max(min(src_bbox.xmax, 1.0), 0.0) + src_bbox.ymax = max(min(src_bbox.ymax, 1.0), 0.0) + return src_bbox + + +def bbox_area(src_bbox): + if src_bbox.xmax < src_bbox.xmin or src_bbox.ymax < src_bbox.ymin: + return 0. + else: + width = src_bbox.xmax - src_bbox.xmin + height = src_bbox.ymax - src_bbox.ymin + return width * height + + +def intersect_bbox(bbox1, bbox2): + if bbox2.xmin > bbox1.xmax or bbox2.xmax < bbox1.xmin or \ + bbox2.ymin > bbox1.ymax or bbox2.ymax < bbox1.ymin: + intersection_box = bbox(0.0, 0.0, 0.0, 0.0) + else: + intersection_box = bbox( + max(bbox1.xmin, bbox2.xmin), + max(bbox1.ymin, bbox2.ymin), + min(bbox1.xmax, bbox2.xmax), min(bbox1.ymax, bbox2.ymax)) + return intersection_box + + +def bbox_coverage(bbox1, bbox2): + inter_box = intersect_bbox(bbox1, bbox2) + intersect_size = bbox_area(inter_box) + + if intersect_size > 0: + bbox1_size = bbox_area(bbox1) + return intersect_size / bbox1_size + else: + return 0. + + +def generate_batch_random_samples(batch_sampler, bbox_labels, image_width, + image_height, scale_array, resize_width, + resize_height): + sampled_bbox = [] + for sampler in batch_sampler: + found = 0 + for i in range(sampler.max_trial): + if found >= sampler.max_sample: + break + sample_bbox = data_anchor_sampling( + sampler, bbox_labels, image_width, image_height, scale_array, + resize_width, resize_height) + if sample_bbox == 0: + break + if satisfy_sample_constraint(sampler, sample_bbox, bbox_labels): + sampled_bbox.append(sample_bbox) + found = found + 1 + return sampled_bbox + + +def data_anchor_sampling(sampler, bbox_labels, image_width, image_height, + scale_array, resize_width, resize_height): + num_gt = len(bbox_labels) + # np.random.randint range: [low, high) + rand_idx = np.random.randint(0, num_gt) if num_gt != 0 else 0 + + if num_gt != 0: + norm_xmin = bbox_labels[rand_idx][1] + norm_ymin = bbox_labels[rand_idx][2] + norm_xmax = bbox_labels[rand_idx][3] + norm_ymax = bbox_labels[rand_idx][4] + + xmin = norm_xmin * image_width + ymin = norm_ymin * image_height + wid = image_width * (norm_xmax - norm_xmin) + hei = image_height * (norm_ymax - norm_ymin) + range_size = 0 + + area = wid * hei + for scale_ind in range(0, len(scale_array) - 1): + if area > scale_array[scale_ind] ** 2 and area < \ + scale_array[scale_ind + 1] ** 2: + range_size = scale_ind + 1 + break + + if area > scale_array[len(scale_array) - 2]**2: + range_size = len(scale_array) - 2 + scale_choose = 0.0 + if range_size == 0: + rand_idx_size = 0 + else: + # np.random.randint range: [low, high) + rng_rand_size = np.random.randint(0, range_size + 1) + rand_idx_size = rng_rand_size % (range_size + 1) + + if rand_idx_size == range_size: + min_resize_val = scale_array[rand_idx_size] / 2.0 + max_resize_val = min(2.0 * scale_array[rand_idx_size], + 2 * math.sqrt(wid * hei)) + scale_choose = random.uniform(min_resize_val, max_resize_val) + else: + min_resize_val = scale_array[rand_idx_size] / 2.0 + max_resize_val = 2.0 * scale_array[rand_idx_size] + scale_choose = random.uniform(min_resize_val, max_resize_val) + + sample_bbox_size = wid * resize_width / scale_choose + + w_off_orig = 0.0 + h_off_orig = 0.0 + if sample_bbox_size < max(image_height, image_width): + if wid <= sample_bbox_size: + w_off_orig = np.random.uniform(xmin + wid - sample_bbox_size, + xmin) + else: + w_off_orig = np.random.uniform(xmin, + xmin + wid - sample_bbox_size) + + if hei <= sample_bbox_size: + h_off_orig = np.random.uniform(ymin + hei - sample_bbox_size, + ymin) + else: + h_off_orig = np.random.uniform(ymin, + ymin + hei - sample_bbox_size) + + else: + w_off_orig = np.random.uniform(image_width - sample_bbox_size, 0.0) + h_off_orig = np.random.uniform( + image_height - sample_bbox_size, 0.0) + + w_off_orig = math.floor(w_off_orig) + h_off_orig = math.floor(h_off_orig) + + # Figure out top left coordinates. + w_off = 0.0 + h_off = 0.0 + w_off = float(w_off_orig / image_width) + h_off = float(h_off_orig / image_height) + + sampled_bbox = bbox(w_off, h_off, + w_off + float(sample_bbox_size / image_width), + h_off + float(sample_bbox_size / image_height)) + + return sampled_bbox + else: + return 0 + + +def jaccard_overlap(sample_bbox, object_bbox): + if sample_bbox.xmin >= object_bbox.xmax or \ + sample_bbox.xmax <= object_bbox.xmin or \ + sample_bbox.ymin >= object_bbox.ymax or \ + sample_bbox.ymax <= object_bbox.ymin: + return 0 + intersect_xmin = max(sample_bbox.xmin, object_bbox.xmin) + intersect_ymin = max(sample_bbox.ymin, object_bbox.ymin) + intersect_xmax = min(sample_bbox.xmax, object_bbox.xmax) + intersect_ymax = min(sample_bbox.ymax, object_bbox.ymax) + intersect_size = (intersect_xmax - intersect_xmin) * ( + intersect_ymax - intersect_ymin) + sample_bbox_size = bbox_area(sample_bbox) + object_bbox_size = bbox_area(object_bbox) + overlap = intersect_size / ( + sample_bbox_size + object_bbox_size - intersect_size) + return overlap + + +def satisfy_sample_constraint(sampler, sample_bbox, bbox_labels): + if sampler.min_jaccard_overlap == 0 and sampler.max_jaccard_overlap == 0: + has_jaccard_overlap = False + else: + has_jaccard_overlap = True + if sampler.min_object_coverage == 0 and sampler.max_object_coverage == 0: + has_object_coverage = False + else: + has_object_coverage = True + + if not has_jaccard_overlap and not has_object_coverage: + return True + found = False + for i in range(len(bbox_labels)): + object_bbox = bbox(bbox_labels[i][1], bbox_labels[i][2], + bbox_labels[i][3], bbox_labels[i][4]) + if has_jaccard_overlap: + overlap = jaccard_overlap(sample_bbox, object_bbox) + if sampler.min_jaccard_overlap != 0 and \ + overlap < sampler.min_jaccard_overlap: + continue + if sampler.max_jaccard_overlap != 0 and \ + overlap > sampler.max_jaccard_overlap: + continue + found = True + if has_object_coverage: + object_coverage = bbox_coverage(object_bbox, sample_bbox) + if sampler.min_object_coverage != 0 and \ + object_coverage < sampler.min_object_coverage: + continue + if sampler.max_object_coverage != 0 and \ + object_coverage > sampler.max_object_coverage: + continue + found = True + if found: + return True + return found + + +def crop_image_sampling(img, bbox_labels, sample_bbox, image_width, + image_height, resize_width, resize_height, + min_face_size): + # no clipping here + xmin = int(sample_bbox.xmin * image_width) + xmax = int(sample_bbox.xmax * image_width) + ymin = int(sample_bbox.ymin * image_height) + ymax = int(sample_bbox.ymax * image_height) + w_off = xmin + h_off = ymin + width = xmax - xmin + height = ymax - ymin + + cross_xmin = max(0.0, float(w_off)) + cross_ymin = max(0.0, float(h_off)) + cross_xmax = min(float(w_off + width - 1.0), float(image_width)) + cross_ymax = min(float(h_off + height - 1.0), float(image_height)) + cross_width = cross_xmax - cross_xmin + cross_height = cross_ymax - cross_ymin + + roi_xmin = 0 if w_off >= 0 else abs(w_off) + roi_ymin = 0 if h_off >= 0 else abs(h_off) + roi_width = cross_width + roi_height = cross_height + + roi_y1 = int(roi_ymin) + roi_y2 = int(roi_ymin + roi_height) + roi_x1 = int(roi_xmin) + roi_x2 = int(roi_xmin + roi_width) + + cross_y1 = int(cross_ymin) + cross_y2 = int(cross_ymin + cross_height) + cross_x1 = int(cross_xmin) + cross_x2 = int(cross_xmin + cross_width) + + sample_img = np.zeros((height, width, 3)) + # print(sample_img.shape) + sample_img[roi_y1 : roi_y2, roi_x1 : roi_x2] = \ + img[cross_y1: cross_y2, cross_x1: cross_x2] + sample_img = cv2.resize( + sample_img, (resize_width, resize_height), interpolation=cv2.INTER_AREA) + + resize_val = resize_width + sample_labels = transform_labels_sampling(bbox_labels, sample_bbox, + resize_val, min_face_size) + return sample_img, sample_labels + + +def transform_labels_sampling(bbox_labels, sample_bbox, resize_val, + min_face_size): + sample_labels = [] + for i in range(len(bbox_labels)): + sample_label = [] + object_bbox = bbox(bbox_labels[i][1], bbox_labels[i][2], + bbox_labels[i][3], bbox_labels[i][4]) + if not meet_emit_constraint(object_bbox, sample_bbox): + continue + proj_bbox = project_bbox(object_bbox, sample_bbox) + if proj_bbox: + real_width = float((proj_bbox.xmax - proj_bbox.xmin) * resize_val) + real_height = float((proj_bbox.ymax - proj_bbox.ymin) * resize_val) + if real_width * real_height < float(min_face_size * min_face_size): + continue + else: + sample_label.append(bbox_labels[i][0]) + sample_label.append(float(proj_bbox.xmin)) + sample_label.append(float(proj_bbox.ymin)) + sample_label.append(float(proj_bbox.xmax)) + sample_label.append(float(proj_bbox.ymax)) + sample_label = sample_label + bbox_labels[i][5:] + sample_labels.append(sample_label) + + return sample_labels + + +def generate_sample(sampler, image_width, image_height): + scale = np.random.uniform(sampler.min_scale, sampler.max_scale) + aspect_ratio = np.random.uniform(sampler.min_aspect_ratio, + sampler.max_aspect_ratio) + aspect_ratio = max(aspect_ratio, (scale**2.0)) + aspect_ratio = min(aspect_ratio, 1 / (scale**2.0)) + + bbox_width = scale * (aspect_ratio**0.5) + bbox_height = scale / (aspect_ratio**0.5) + + # guarantee a squared image patch after cropping + if sampler.use_square: + if image_height < image_width: + bbox_width = bbox_height * image_height / image_width + else: + bbox_height = bbox_width * image_width / image_height + + xmin_bound = 1 - bbox_width + ymin_bound = 1 - bbox_height + xmin = np.random.uniform(0, xmin_bound) + ymin = np.random.uniform(0, ymin_bound) + xmax = xmin + bbox_width + ymax = ymin + bbox_height + sampled_bbox = bbox(xmin, ymin, xmax, ymax) + return sampled_bbox + + +def generate_batch_samples(batch_sampler, bbox_labels, image_width, + image_height): + sampled_bbox = [] + for sampler in batch_sampler: + found = 0 + for i in range(sampler.max_trial): + if found >= sampler.max_sample: + break + sample_bbox = generate_sample(sampler, image_width, image_height) + if satisfy_sample_constraint(sampler, sample_bbox, bbox_labels): + sampled_bbox.append(sample_bbox) + found = found + 1 + return sampled_bbox + + +def crop_image(img, bbox_labels, sample_bbox, image_width, image_height, + resize_width, resize_height, min_face_size): + sample_bbox = clip_bbox(sample_bbox) + xmin = int(sample_bbox.xmin * image_width) + xmax = int(sample_bbox.xmax * image_width) + ymin = int(sample_bbox.ymin * image_height) + ymax = int(sample_bbox.ymax * image_height) + + sample_img = img[ymin:ymax, xmin:xmax] + resize_val = resize_width + sample_labels = transform_labels_sampling(bbox_labels, sample_bbox, + resize_val, min_face_size) + return sample_img, sample_labels + + +def to_chw_bgr(image): + """ + Transpose image from HWC to CHW and from RBG to BGR. + Args: + image (np.array): an image with HWC and RBG layout. + """ + # HWC to CHW + if len(image.shape) == 3: + image = np.swapaxes(image, 1, 2) + image = np.swapaxes(image, 1, 0) + # RBG to BGR + image = image[[2, 1, 0], :, :] + return image + + +def anchor_crop_image_sampling(img, + bbox_labels, + scale_array, + img_width, + img_height): + mean = np.array([104, 117, 123], dtype=np.float32) + maxSize = 12000 # max size + infDistance = 9999999 + bbox_labels = np.array(bbox_labels) + scale = np.array([img_width, img_height, img_width, img_height]) + + boxes = bbox_labels[:, 1:5] * scale + labels = bbox_labels[:, 0] + + boxArea = (boxes[:, 2] - boxes[:, 0] + 1) * (boxes[:, 3] - boxes[:, 1] + 1) + # argsort = np.argsort(boxArea) + # rand_idx = random.randint(min(len(argsort),6)) + # print('rand idx',rand_idx) + rand_idx = np.random.randint(len(boxArea)) + rand_Side = boxArea[rand_idx] ** 0.5 + # rand_Side = min(boxes[rand_idx,2] - boxes[rand_idx,0] + 1, + # boxes[rand_idx,3] - boxes[rand_idx,1] + 1) + + distance = infDistance + anchor_idx = 5 + for i, anchor in enumerate(scale_array): + if abs(anchor - rand_Side) < distance: + distance = abs(anchor - rand_Side) + anchor_idx = i + + target_anchor = random.choice(scale_array[0:min(anchor_idx + 1, 5) + 1]) + ratio = float(target_anchor) / rand_Side + ratio = ratio * (2**random.uniform(-1, 1)) + + if int(img_height * ratio * img_width * ratio) > maxSize * maxSize: + ratio = (maxSize * maxSize / (img_height * img_width))**0.5 + + interp_methods = [cv2.INTER_LINEAR, cv2.INTER_CUBIC, + cv2.INTER_AREA, cv2.INTER_NEAREST, cv2.INTER_LANCZOS4] + interp_method = random.choice(interp_methods) + image = cv2.resize(img, None, None, fx=ratio, + fy=ratio, interpolation=interp_method) + + boxes[:, 0] *= ratio + boxes[:, 1] *= ratio + boxes[:, 2] *= ratio + boxes[:, 3] *= ratio + + height, width, _ = image.shape + + sample_boxes = [] + + xmin = boxes[rand_idx, 0] + ymin = boxes[rand_idx, 1] + bw = (boxes[rand_idx, 2] - boxes[rand_idx, 0] + 1) + bh = (boxes[rand_idx, 3] - boxes[rand_idx, 1] + 1) + + w = h = cfg.INPUT_SIZE + + for _ in range(50): + if w < max(height, width): + if bw <= w: + w_off = random.uniform(xmin + bw - w, xmin) + else: + w_off = random.uniform(xmin, xmin + bw - w) + + if bh <= h: + h_off = random.uniform(ymin + bh - h, ymin) + else: + h_off = random.uniform(ymin, ymin + bh - h) + else: + w_off = random.uniform(width - w, 0) + h_off = random.uniform(height - h, 0) + + w_off = math.floor(w_off) + h_off = math.floor(h_off) + + # convert to integer rect x1,y1,x2,y2 + rect = np.array( + [int(w_off), int(h_off), int(w_off + w), int(h_off + h)]) + + # keep overlap with gt box IF center in sampled patch + centers = (boxes[:, :2] + boxes[:, 2:]) / 2.0 + # mask in all gt boxes that above and to the left of centers + m1 = (rect[0] <= boxes[:, 0]) * (rect[1] <= boxes[:, 1]) + # mask in all gt boxes that under and to the right of centers + m2 = (rect[2] >= boxes[:, 2]) * (rect[3] >= boxes[:, 3]) + # mask in that both m1 and m2 are true + mask = m1 * m2 + + overlap = jaccard_numpy(boxes, rect) + # have any valid boxes? try again if not + if not mask.any() and not overlap.max() > 0.7: + continue + else: + sample_boxes.append(rect) + + sampled_labels = [] + + if len(sample_boxes) > 0: + choice_idx = np.random.randint(len(sample_boxes)) + choice_box = sample_boxes[choice_idx] + # print('crop the box :',choice_box) + centers = (boxes[:, :2] + boxes[:, 2:]) / 2.0 + m1 = (choice_box[0] < centers[:, 0]) * \ + (choice_box[1] < centers[:, 1]) + m2 = (choice_box[2] > centers[:, 0]) * \ + (choice_box[3] > centers[:, 1]) + mask = m1 * m2 + current_boxes = boxes[mask, :].copy() + current_labels = labels[mask] + current_boxes[:, :2] -= choice_box[:2] + current_boxes[:, 2:] -= choice_box[:2] + + if choice_box[0] < 0 or choice_box[1] < 0: + new_img_width = width if choice_box[ + 0] >= 0 else width - choice_box[0] + new_img_height = height if choice_box[ + 1] >= 0 else height - choice_box[1] + image_pad = np.zeros( + (new_img_height, new_img_width, 3), dtype=float) + image_pad[:, :, :] = mean + start_left = 0 if choice_box[0] >= 0 else -choice_box[0] + start_top = 0 if choice_box[1] >= 0 else -choice_box[1] + image_pad[start_top:, start_left:, :] = image + + choice_box_w = choice_box[2] - choice_box[0] + choice_box_h = choice_box[3] - choice_box[1] + + start_left = choice_box[0] if choice_box[0] >= 0 else 0 + start_top = choice_box[1] if choice_box[1] >= 0 else 0 + end_right = start_left + choice_box_w + end_bottom = start_top + choice_box_h + current_image = image_pad[ + start_top:end_bottom, start_left:end_right, :].copy() + image_height, image_width, _ = current_image.shape + if cfg.filter_min_face: + bbox_w = current_boxes[:, 2] - current_boxes[:, 0] + bbox_h = current_boxes[:, 3] - current_boxes[:, 1] + bbox_area = bbox_w * bbox_h + mask = bbox_area > (cfg.min_face_size * cfg.min_face_size) + current_boxes = current_boxes[mask] + current_labels = current_labels[mask] + for i in range(len(current_boxes)): + sample_label = [] + sample_label.append(current_labels[i]) + sample_label.append(current_boxes[i][0] / image_width) + sample_label.append(current_boxes[i][1] / image_height) + sample_label.append(current_boxes[i][2] / image_width) + sample_label.append(current_boxes[i][3] / image_height) + sampled_labels += [sample_label] + sampled_labels = np.array(sampled_labels) + else: + current_boxes /= np.array([image_width, + image_height, image_width, image_height]) + sampled_labels = np.hstack( + (current_labels[:, np.newaxis], current_boxes)) + + return current_image, sampled_labels + + current_image = image[choice_box[1]:choice_box[ + 3], choice_box[0]:choice_box[2], :].copy() + image_height, image_width, _ = current_image.shape + + if cfg.filter_min_face: + bbox_w = current_boxes[:, 2] - current_boxes[:, 0] + bbox_h = current_boxes[:, 3] - current_boxes[:, 1] + bbox_area = bbox_w * bbox_h + mask = bbox_area > (cfg.min_face_size * cfg.min_face_size) + current_boxes = current_boxes[mask] + current_labels = current_labels[mask] + for i in range(len(current_boxes)): + sample_label = [] + sample_label.append(current_labels[i]) + sample_label.append(current_boxes[i][0] / image_width) + sample_label.append(current_boxes[i][1] / image_height) + sample_label.append(current_boxes[i][2] / image_width) + sample_label.append(current_boxes[i][3] / image_height) + sampled_labels += [sample_label] + sampled_labels = np.array(sampled_labels) + else: + current_boxes /= np.array([image_width, + image_height, image_width, image_height]) + sampled_labels = np.hstack( + (current_labels[:, np.newaxis], current_boxes)) + + return current_image, sampled_labels + else: + image_height, image_width, _ = image.shape + if cfg.filter_min_face: + bbox_w = boxes[:, 2] - boxes[:, 0] + bbox_h = boxes[:, 3] - boxes[:, 1] + bbox_area = bbox_w * bbox_h + mask = bbox_area > (cfg.min_face_size * cfg.min_face_size) + boxes = boxes[mask] + labels = labels[mask] + for i in range(len(boxes)): + sample_label = [] + sample_label.append(labels[i]) + sample_label.append(boxes[i][0] / image_width) + sample_label.append(boxes[i][1] / image_height) + sample_label.append(boxes[i][2] / image_width) + sample_label.append(boxes[i][3] / image_height) + sampled_labels += [sample_label] + sampled_labels = np.array(sampled_labels) + else: + boxes /= np.array([image_width, image_height, + image_width, image_height]) + sampled_labels = np.hstack( + (labels[:, np.newaxis], boxes)) + + return image, sampled_labels + + +def preprocess(img, bbox_labels, mode, image_path): + img_width, img_height = img.size + sampled_labels = bbox_labels + if mode == 'train': + if cfg.apply_distort: + img = distort_image(img) + if cfg.apply_expand: + img, bbox_labels, img_width, img_height = expand_image( + img, bbox_labels, img_width, img_height) + + batch_sampler = [] + prob = np.random.uniform(0., 1.) + if prob > cfg.data_anchor_sampling_prob and cfg.anchor_sampling: + scale_array = np.array(cfg.ANCHOR_SIZES)#[16, 32, 64, 128, 256, 512]) + ''' + batch_sampler.append( + sampler(1, 50, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.6, 0.0, True)) + sampled_bbox = generate_batch_random_samples( + batch_sampler, bbox_labels, img_width, img_height, scale_array, + cfg.resize_width, cfg.resize_height) + ''' + img = np.array(img) + img, sampled_labels = anchor_crop_image_sampling( + img, bbox_labels, scale_array, img_width, img_height) + ''' + if len(sampled_bbox) > 0: + idx = int(np.random.uniform(0, len(sampled_bbox))) + img, sampled_labels = crop_image_sampling( + img, bbox_labels, sampled_bbox[idx], img_width, img_height, + cfg.resize_width, cfg.resize_height, cfg.min_face_size) + ''' + img = img.astype('uint8') + img = Image.fromarray(img) + else: + batch_sampler.append(sampler(1, 50, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, + 0.0, True)) + batch_sampler.append(sampler(1, 50, 0.3, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, + 0.0, True)) + batch_sampler.append(sampler(1, 50, 0.3, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, + 0.0, True)) + batch_sampler.append(sampler(1, 50, 0.3, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, + 0.0, True)) + batch_sampler.append(sampler(1, 50, 0.3, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, + 0.0, True)) + sampled_bbox = generate_batch_samples( + batch_sampler, bbox_labels, img_width, img_height) + + img = np.array(img) + if len(sampled_bbox) > 0: + idx = int(np.random.uniform(0, len(sampled_bbox))) + img, sampled_labels = crop_image( + img, bbox_labels, sampled_bbox[idx], img_width, img_height, + cfg.resize_width, cfg.resize_height, cfg.min_face_size) + + img = Image.fromarray(img) + + interp_mode = [ + Image.BILINEAR, Image.HAMMING, Image.NEAREST, Image.BICUBIC, + Image.LANCZOS + ] + interp_indx = np.random.randint(0, 5) + + img = img.resize((cfg.resize_width, cfg.resize_height), + resample=interp_mode[interp_indx]) + + img = np.array(img) + + if mode == 'train': + mirror = int(np.random.uniform(0, 2)) + if mirror == 1: + img = img[:, ::-1, :] + for i in six.moves.xrange(len(sampled_labels)): + tmp = sampled_labels[i][1] + sampled_labels[i][1] = 1 - sampled_labels[i][3] + sampled_labels[i][3] = 1 - tmp + + #img = Image.fromarray(img) + img = to_chw_bgr(img) + img = img.astype('float32') + img -= cfg.img_mean + img = img[[2, 1, 0], :, :] # to RGB + #img = img * cfg.scale + + return img, sampled_labels diff --git a/examples/pytorch/vision/Face_Detection/wider_test.py b/examples/pytorch/vision/Face_Detection/wider_test.py new file mode 100755 index 00000000..df585fe0 --- /dev/null +++ b/examples/pytorch/vision/Face_Detection/wider_test.py @@ -0,0 +1,272 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +import os +import argparse +import torch +import torch.nn as nn +import torch.utils.data as data +import torch.backends.cudnn as cudnn +import torchvision.transforms as transforms +import os.path as osp + +import cv2 +import time +import numpy as np +from PIL import Image +import scipy.io as sio + +from data.choose_config import cfg +cfg = cfg.cfg + +from torch.autograd import Variable +from utils.augmentations import to_chw_bgr + +from importlib import import_module + +import warnings +warnings.filterwarnings("ignore") + +parser = argparse.ArgumentParser(description='s3fd evaluatuon wider') +parser.add_argument('--model', type=str, + default='./weights/rpool_face_c.pth', help='trained model') +parser.add_argument('--thresh', default=0.05, type=float, + help='Final confidence threshold') +parser.add_argument('--model_arch', + default='RPool_Face_C', type=str, + choices=['RPool_Face_C', 'RPool_Face_Quant', 'RPool_Face_QVGA_monochrome'], + help='choose architecture among rpool variants') +parser.add_argument('--save_folder', type=str, + default='rpool_face_predictions', help='folder for saving predictions') +parser.add_argument('--subset', type=str, + default='val', + choices=['val', 'test'], + help='choose which set to run testing on') + +args = parser.parse_args() + + +use_cuda = torch.cuda.is_available() + +if use_cuda: + torch.set_default_tensor_type('torch.cuda.FloatTensor') +else: + torch.set_default_tensor_type('torch.FloatTensor') + + +def detect_face(net, img, shrink): + if shrink != 1: + img = cv2.resize(img, None, None, fx=shrink, fy=shrink, + interpolation=cv2.INTER_LINEAR) + + x = to_chw_bgr(img) + x = x.astype('float32') + x -= cfg.img_mean + x = x[[2, 1, 0], :, :] + + if cfg.IS_MONOCHROME == True: + x = 0.299 * x[0] + 0.587 * x[1] + 0.114 * x[2] + x = torch.from_numpy(x).unsqueeze(0).unsqueeze(0) + else: + x = torch.from_numpy(x).unsqueeze(0) + + if use_cuda: + x = x.cuda() + + y = net(x) + detections = y.data + detections = detections.cpu().numpy() + + det_conf = detections[0, 1, :, 0] + det_xmin = img.shape[1] * detections[0, 1, :, 1] / shrink + det_ymin = img.shape[0] * detections[0, 1, :, 2] / shrink + det_xmax = img.shape[1] * detections[0, 1, :, 3] / shrink + det_ymax = img.shape[0] * detections[0, 1, :, 4] / shrink + det = np.column_stack((det_xmin, det_ymin, det_xmax, det_ymax, det_conf)) + + keep_index = np.where(det[:, 4] >= args.thresh)[0] + det = det[keep_index, :] + + return det + + +def multi_scale_test(net, image, max_im_shrink): + # shrink detecting and shrink only detect big face + st = 0.5 if max_im_shrink >= 0.75 else 0.5 * max_im_shrink + det_s = detect_face(net, image, st) + index = np.where(np.maximum( + det_s[:, 2] - det_s[:, 0] + 1, det_s[:, 3] - det_s[:, 1] + 1) > 30)[0] + det_s = det_s[index, :] + + # enlarge one times + bt = min(2, max_im_shrink) if max_im_shrink > 1 else ( + st + max_im_shrink) / 2 + det_b = detect_face(net, image, bt) + + # enlarge small image x times for small face + if max_im_shrink > 2: + bt *= 2 + while bt < max_im_shrink: + det_b = np.row_stack((det_b, detect_face(net, image, bt))) + bt *= 2 + det_b = np.row_stack((det_b, detect_face(net, image, max_im_shrink))) + + # enlarge only detect small face + if bt > 1: + index = np.where(np.minimum( + det_b[:, 2] - det_b[:, 0] + 1, det_b[:, 3] - det_b[:, 1] + 1) < 100)[0] + det_b = det_b[index, :] + else: + index = np.where(np.maximum( + det_b[:, 2] - det_b[:, 0] + 1, det_b[:, 3] - det_b[:, 1] + 1) > 30)[0] + det_b = det_b[index, :] + + return det_s, det_b + + +def flip_test(net, image, shrink): + image_f = cv2.flip(image, 1) + det_f = detect_face(net, image_f, shrink) + + det_t = np.zeros(det_f.shape) + det_t[:, 0] = image.shape[1] - det_f[:, 2] + det_t[:, 1] = det_f[:, 1] + det_t[:, 2] = image.shape[1] - det_f[:, 0] + det_t[:, 3] = det_f[:, 3] + det_t[:, 4] = det_f[:, 4] + return det_t + + +def bbox_vote(det): + order = det[:, 4].ravel().argsort()[::-1] + det = det[order, :] + while det.shape[0] > 0: + # IOU + area = (det[:, 2] - det[:, 0] + 1) * (det[:, 3] - det[:, 1] + 1) + xx1 = np.maximum(det[0, 0], det[:, 0]) + yy1 = np.maximum(det[0, 1], det[:, 1]) + xx2 = np.minimum(det[0, 2], det[:, 2]) + yy2 = np.minimum(det[0, 3], det[:, 3]) + w = np.maximum(0.0, xx2 - xx1 + 1) + h = np.maximum(0.0, yy2 - yy1 + 1) + inter = w * h + o = inter / (area[0] + area[:] - inter) + + # get needed merge det and delete these det + merge_index = np.where(o >= 0.3)[0] + det_accu = det[merge_index, :] + det = np.delete(det, merge_index, 0) + + if merge_index.shape[0] <= 1: + continue + det_accu[:, 0:4] = det_accu[:, 0:4] * np.tile(det_accu[:, -1:], (1, 4)) + max_score = np.max(det_accu[:, 4]) + det_accu_sum = np.zeros((1, 5)) + det_accu_sum[:, 0:4] = np.sum( + det_accu[:, 0:4], axis=0) / np.sum(det_accu[:, -1:]) + det_accu_sum[:, 4] = max_score + try: + dets = np.row_stack((dets, det_accu_sum)) + except: + dets = det_accu_sum + + dets = dets[0:750, :] + return dets + + +def get_data(): + subset = args.subset + + WIDER_ROOT = os.path.join(cfg.HOME, 'WIDER_FACE') + if subset == 'val': + wider_face = sio.loadmat( + os.path.join(WIDER_ROOT, 'wider_face_split', + 'wider_face_val.mat')) + else: + wider_face = sio.loadmat( + os.path.join(WIDER_ROOT, 'wider_face_split', + 'wider_face_test.mat')) + event_list = wider_face['event_list'] + file_list = wider_face['file_list'] + del wider_face + + imgs_path = os.path.join( + cfg.FACE.WIDER_DIR, 'WIDER_{}'.format(subset), 'images') + save_path = './{}'.format(args.save_folder) + + return event_list, file_list, imgs_path, save_path + +if __name__ == '__main__': + event_list, file_list, imgs_path, save_path = get_data() + cfg.USE_NMS = False + + module = import_module('models.' + args.model_arch) + net = module.build_s3fd('test', cfg.NUM_CLASSES) + + net = torch.nn.DataParallel(net) + + + checkpoint_dict = torch.load(args.model) + + model_dict = net.state_dict() + + + model_dict.update(checkpoint_dict) + net.load_state_dict(model_dict) + + + net.eval() + + + if use_cuda: + net.cuda() + cudnn.benckmark = True + + + counter = 0 + + for index, event in enumerate(event_list): + filelist = file_list[index][0] + path = os.path.join(save_path, str(event[0][0]))#.encode('utf-8')) + if not os.path.exists(path): + os.makedirs(path) + + for num, file in enumerate(filelist): + im_name = str(file[0][0])#.encode('utf-8') + in_file = os.path.join(imgs_path, event[0][0], im_name[:] + '.jpg') + img = Image.open(in_file) + if img.mode == 'L': + img = img.convert('RGB') + img = np.array(img) + + + max_im_shrink = np.sqrt( + 1700 * 1200 / (img.shape[0] * img.shape[1])) + + shrink = max_im_shrink if max_im_shrink < 1 else 1 + counter += 1 + + t1 = time.time() + det0 = detect_face(net, img, shrink) + + det1 = flip_test(net, img, shrink) # flip test + [det2, det3] = multi_scale_test(net, img, max_im_shrink) + + det = np.row_stack((det0, det1, det2, det3)) + dets = bbox_vote(det) + + t2 = time.time() + print('Detect %04d th image costs %.4f' % (counter, t2 - t1)) + + fout = open(osp.join(save_path, str(event[0][ + 0]), im_name + '.txt'), 'w') + fout.write('{:s}\n'.format(str(event[0][0]) + '/' + im_name + '.jpg')) + fout.write('{:d}\n'.format(dets.shape[0])) + for i in range(dets.shape[0]): + xmin = dets[i][0] + ymin = dets[i][1] + xmax = dets[i][2] + ymax = dets[i][3] + score = dets[i][4] + fout.write('{:.1f} {:.1f} {:.1f} {:.1f} {:.3f}\n'. + format(xmin, ymin, (xmax - xmin + 1), (ymax - ymin + 1), score)) diff --git a/examples/pytorch/vision/Visual_Wakeword/README.md b/examples/pytorch/vision/Visual_Wakeword/README.md new file mode 100755 index 00000000..618fee20 --- /dev/null +++ b/examples/pytorch/vision/Visual_Wakeword/README.md @@ -0,0 +1,71 @@ +# Code for Visual Wake Words experiments with RNNPool + +The Visual Wake Word challenge is a binary classification problem of detecting whether a person is present in +an image or not, as introduced by [Chowdhery et. al](https://arxiv.org/abs/1906.05721). + +## Dataset +The Visual Wake Words Dataset is derived from the publicly available [COCO](cocodataset.org/#/home) dataset. The Visual Wake Words Challenge evaluates accuracy on the [minival image ids](https://raw.githubusercontent.com/tensorflow/models/master/research/object_detection/data/mscoco_minival_ids.txt), +and for training uses the remaining 115k images of the COCO training/validation dataset. The process of creating the Visual Wake Words dataset from COCO dataset is as follows. +Each image is assigned a label 1 or 0. +The label 1 is assigned as long as it has at least one bounding box corresponding +to the object of interest (e.g. person) with the box area greater than a certain threshold +(e.g. 0.5% of the image area). + +To download the COCO dataset use the script `download_coco.sh` +```bash +bash scripts/download_mscoco.sh path-to-mscoco-dataset +``` + +To create COCO annotation files that converts to the minival split use: +`scripts/create_coco_train_minival_split.py` + +```bash +TRAIN_ANNOTATIONS_FILE="path-to-mscoco-dataset/annotations/instances_train2014.json" +VAL_ANNOTATIONS_FILE="path-to-mscoco-dataset/annotations/instances_val2014.json" +DIR="path-to-mscoco-dataset/annotations/" +python scripts/create_coco_train_minival_split.py \ + --train_annotations_file="${TRAIN_ANNOTATIONS_FILE}" \ + --val_annotations_file="${VAL_ANNOTATIONS_FILE}" \ + --output_dir="${DIR}" +``` + + +To generate the new annotations, use the script `scripts/create_visualwakewords_annotations.py`. +```bash +MAXITRAIN_ANNOTATIONS_FILE="path-to-mscoco-dataset/annotations/instances_maxitrain.json" +MINIVAL_ANNOTATIONS_FILE="path-to-mscoco-dataset/annotations/instances_minival.json" +VWW_OUTPUT_DIR="new-path-to-visualwakewords-dataset/annotations/" +python scripts/create_visualwakewords_annotations.py \ + --train_annotations_file="${MAXITRAIN_ANNOTATIONS_FILE}" \ + --val_annotations_file="${MINIVAL_ANNOTATIONS_FILE}" \ + --output_dir="${VWW_OUTPUT_DIR}" \ + --threshold=0.005 \ + --foreground_class='person' +``` + + +# Training + +```bash +python train_visualwakewords.py \ + --model_arch model_mobilenet_rnnpool \ + --lr 0.05 \ + --epochs 900 \ + --data "path-to-mscoco-dataset" \ + --ann "new-path-to-visualwakewords-dataset" +``` +Specify the paths used for storing MS COCO dataset and the Visual Wakeword dataset as used in dataset creation steps in --data and --ann respectively. This script should reach a validation accuracy of about 89.57 upon completion. + +# Evaluation + +```bash +python eval.py \ + --weights vww_rnnpool.pth \ + --model_arch model_mobilenet_rnnpool \ + --image_folder images \ +``` + +The weights argument is the saved checkpoint of the model trained with architecture which is passed in model_arch argument. The folder with images for evaluation has to be passed in image_folder argument. This script will print 'Person present' or 'No person present' for each image in the folder specified. + + +Dataset creation code is from https://github.com/Mxbonn/visualwakewords/ diff --git a/examples/pytorch/vision/Visual_Wakeword/eval.py b/examples/pytorch/vision/Visual_Wakeword/eval.py new file mode 100644 index 00000000..46200cb1 --- /dev/null +++ b/examples/pytorch/vision/Visual_Wakeword/eval.py @@ -0,0 +1,91 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +import torch +import torch.nn as nn +import torch.optim as optim +import torch.nn.functional as F +import torch.backends.cudnn as cudnn +import torchvision +import torchvision.transforms as transforms +import os +import argparse +import random +from PIL import Image +import numpy as np +from importlib import import_module +import skimage +from skimage import filters + + + + + +device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + +torch.backends.cudnn.benchmark = True +torch.backends.cudnn.enabled = True + + +#Arg parser +parser = argparse.ArgumentParser(description='PyTorch VisualWakeWords evaluation') +parser.add_argument('--weights', default=None, type=str, help='load from checkpoint') +parser.add_argument('--model_arch', + default='model_mobilenet_rnnpool', type=str, + choices=['model_mobilenet_rnnpool', 'model_mobilenet_2rnnpool'], + help='choose architecture among rpool variants') +parser.add_argument('--image_folder', default=None, type=str, help='folder containing images') + +args = parser.parse_args() + + +normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + +transform_test = transforms.Compose([ + transforms.Resize(256), + transforms.CenterCrop(224), + transforms.ToTensor(), + normalize +]) + + + + +if __name__ == '__main__': + + module = import_module(args.model_arch) + model = module.mobilenetv2_rnnpool(num_classes=2, width_mult=0.35, last_channel=320) + model = model.to(device) + model = torch.nn.DataParallel(model) + + + + checkpoint = torch.load(args.weights) + checkpoint_dict = checkpoint['model'] + model_dict = model.state_dict() + model_dict.update(checkpoint_dict) + model.load_state_dict(model_dict) + + model.eval() + img_path = args.image_folder + img_list = [os.path.join(img_path, x) + for x in os.listdir(img_path) if x.endswith('bmp')] + + for path in sorted(img_list): + img = Image.open(path).convert('RGB') + img = transform_test(img) + img = (img.cuda()) + img = img.unsqueeze(0) + + out = model(img) + + print(path) + print(out) + if out[0][0]>0.15: + print('No person present') + else: + print('Person present') + + + diff --git a/examples/pytorch/vision/Visual_Wakeword/model_mobilenet_2rnnpool.py b/examples/pytorch/vision/Visual_Wakeword/model_mobilenet_2rnnpool.py new file mode 100755 index 00000000..4de11995 --- /dev/null +++ b/examples/pytorch/vision/Visual_Wakeword/model_mobilenet_2rnnpool.py @@ -0,0 +1,208 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +import re +import torch +import torch.nn as nn +import torch.nn.functional as F +import numpy as np +import torch.utils.checkpoint as cp +from collections import OrderedDict +from torchvision.models.utils import load_state_dict_from_url +import sys; sys.path.append('..') +from rnnpool import * + +__all__ = ['MobileNetV2', 'mobilenetv2_rnnpool'] + + +model_urls = { + 'mobilenet_v2': 'https://download.pytorch.org/models/mobilenet_v2-b0353104.pth', +} + + +def _make_divisible(v, divisor, min_value=None): + """ + This function is taken from the original tf repo. + It ensures that all layers have a channel number that is divisible by 8 + It can be seen here: + https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py + :param v: + :param divisor: + :param min_value: + :return: + """ + 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 + + +class ConvBNReLU(nn.Sequential): + def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1): + padding = (kernel_size - 1) // 2 + super(ConvBNReLU, self).__init__( + nn.Conv2d(in_planes, out_planes, kernel_size, stride, padding, groups=groups, bias=False), + nn.BatchNorm2d(out_planes, momentum=0.01), + nn.ReLU6(inplace=True) + ) + + +class InvertedResidual(nn.Module): + def __init__(self, inp, oup, stride, expand_ratio): + super(InvertedResidual, self).__init__() + self.stride = stride + assert stride in [1, 2] + + hidden_dim = int(round(inp * expand_ratio)) + self.use_res_connect = self.stride == 1 and inp == oup + + layers = [] + if expand_ratio != 1: + # pw + layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1)) + layers.extend([ + # dw + ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim), + # pw-linear + nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), + nn.BatchNorm2d(oup, momentum=0.01), + ]) + self.conv = nn.Sequential(*layers) + + def forward(self, x): + if self.use_res_connect: + return x + self.conv(x) + else: + return self.conv(x) + + +class MobileNetV2(nn.Module): + def __init__(self, + num_classes=1000, + width_mult=0.5, + inverted_residual_setting=None, + round_nearest=8, + block=None, + last_channel = 1280): + """ + MobileNet V2 main class + Args: + num_classes (int): Number of classes + width_mult (float): Width multiplier - adjusts number of channels in each layer by this amount + inverted_residual_setting: Network structure + round_nearest (int): Round the number of channels in each layer to be a multiple of this number + Set to 1 to turn off rounding + block: Module specifying inverted residual building block for mobilenet + """ + super(MobileNetV2, self).__init__() + + if block is None: + block = InvertedResidual + input_channel = 8 + #last_channel = 1280 + + if inverted_residual_setting is None: + inverted_residual_setting = [ + # t, c, n, s + [6, 64, 4, 2], + [6, 96, 3, 1], + [6, 160, 3, 2], + [6, 320, 1, 1], + ] + + # only check the first element, assuming user knows t,c,n,s are required + if len(inverted_residual_setting) == 0 or len(inverted_residual_setting[0]) != 4: + raise ValueError("inverted_residual_setting should be non-empty " + "or a 4-element list, got {}".format(inverted_residual_setting)) + + # building first layer + input_channel = _make_divisible(input_channel, round_nearest) + self.last_channel = _make_divisible(last_channel * max(1.0, width_mult), round_nearest) + self.features_init = ConvBNReLU(3, input_channel, stride=2) + + self.unfold = nn.Unfold(kernel_size=(6,6),stride=(4,4)) + + self.rnn_model = RNNPool(6, 6, 8, 8, input_channel)#num_init_features) + self.fold = nn.Fold(kernel_size=(1,1),output_size=(27,27)) + + self.rnn_model_end = RNNPool(7, 7, int(self.last_channel/4), int(self.last_channel/4), self.last_channel) + + features=[] + + input_channel = 32 + + # building inverted residual blocks + for t, c, n, s in inverted_residual_setting: + output_channel = _make_divisible(c * width_mult, round_nearest) + for i in range(n): + stride = s if i == 0 else 1 + features.append(block(input_channel, output_channel, stride, expand_ratio=t)) + input_channel = output_channel + # building last several layers + features.append(ConvBNReLU(input_channel, self.last_channel, kernel_size=1)) + # make it nn.Sequential + self.features = nn.Sequential(*features) + + # building classifier + self.classifier = nn.Sequential( + #nn.Dropout(0.2), + nn.Linear(self.last_channel, num_classes), + ) + + # weight initialization + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight, mode='fan_out') + if m.bias is not None: + nn.init.zeros_(m.bias) + elif isinstance(m, nn.BatchNorm2d): + nn.init.ones_(m.weight) + nn.init.zeros_(m.bias) + elif isinstance(m, nn.Linear): + nn.init.normal_(m.weight, 0, 0.01) + nn.init.zeros_(m.bias) + + def forward(self, x): + batch_size = x.shape[0] + + x = self.features_init(x) + + patches = self.unfold(x) + patches = torch.cat(torch.unbind(patches,dim=2),dim=0) + patches = torch.reshape(patches,(-1,8,6,6)) + + + output_x = int((x.shape[2]-6)/4 + 1) + output_y = int((x.shape[3]-6)/4 + 1) + + rnnX = self.rnn_model(patches, int(batch_size)*output_x*output_y) + + x = torch.stack(torch.split(rnnX, split_size_or_sections=int(batch_size), dim=0),dim=2) + + x = self.fold(x) + + x = F.pad(x, (0,1,0,1), mode='replicate') + + x = self.features(x) + x = self.rnn_model_end(x, batch_size) + x = self.classifier(x) + return x + + +def mobilenetv2_rnnpool(pretrained=False, progress=True, **kwargs): + """ + Constructs a MobileNetV2 architecture from + `"MobileNetV2: Inverted Residuals and Linear Bottlenecks" `_. + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + progress (bool): If True, displays a progress bar of the download to stderr + """ + model = MobileNetV2(**kwargs) + if pretrained: + state_dict = load_state_dict_from_url(model_urls['mobilenet_v2'], + progress=progress) + model.load_state_dict(state_dict) + return model diff --git a/examples/pytorch/vision/Visual_Wakeword/model_mobilenet_rnnpool.py b/examples/pytorch/vision/Visual_Wakeword/model_mobilenet_rnnpool.py new file mode 100755 index 00000000..40f30ecf --- /dev/null +++ b/examples/pytorch/vision/Visual_Wakeword/model_mobilenet_rnnpool.py @@ -0,0 +1,206 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +import re +import torch +import torch.nn as nn +import torch.nn.functional as F +import numpy as np +import torch.utils.checkpoint as cp +from collections import OrderedDict +from torchvision.models.utils import load_state_dict_from_url +from edgeml_pytorch.graph.rnnpool import * + +__all__ = ['MobileNetV2', 'mobilenetv2_rnnpool'] + + +model_urls = { + 'mobilenet_v2': 'https://download.pytorch.org/models/mobilenet_v2-b0353104.pth', +} + + +def _make_divisible(v, divisor, min_value=None): + """ + This function is taken from the original tf repo. + It ensures that all layers have a channel number that is divisible by 8 + It can be seen here: + https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py + :param v: + :param divisor: + :param min_value: + :return: + """ + 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 + + +class ConvBNReLU(nn.Sequential): + def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1): + padding = (kernel_size - 1) // 2 + super(ConvBNReLU, self).__init__( + nn.Conv2d(in_planes, out_planes, kernel_size, stride, padding, groups=groups, bias=False), + nn.BatchNorm2d(out_planes, momentum=0.01), + nn.ReLU6(inplace=True) + ) + + +class InvertedResidual(nn.Module): + def __init__(self, inp, oup, stride, expand_ratio): + super(InvertedResidual, self).__init__() + self.stride = stride + assert stride in [1, 2] + + hidden_dim = int(round(inp * expand_ratio)) + self.use_res_connect = self.stride == 1 and inp == oup + + layers = [] + if expand_ratio != 1: + # pw + layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1)) + layers.extend([ + # dw + ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim), + # pw-linear + nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), + nn.BatchNorm2d(oup, momentum=0.01), + ]) + self.conv = nn.Sequential(*layers) + + def forward(self, x): + if self.use_res_connect: + return x + self.conv(x) + else: + return self.conv(x) + + +class MobileNetV2(nn.Module): + def __init__(self, + num_classes=1000, + width_mult=0.5, + inverted_residual_setting=None, + round_nearest=8, + block=None, + last_channel = 1280): + """ + MobileNet V2 main class + Args: + num_classes (int): Number of classes + width_mult (float): Width multiplier - adjusts number of channels in each layer by this amount + inverted_residual_setting: Network structure + round_nearest (int): Round the number of channels in each layer to be a multiple of this number + Set to 1 to turn off rounding + block: Module specifying inverted residual building block for mobilenet + """ + super(MobileNetV2, self).__init__() + + if block is None: + block = InvertedResidual + input_channel = 8 + #last_channel = 1280 + + if inverted_residual_setting is None: + inverted_residual_setting = [ + # t, c, n, s + [6, 64, 4, 2], + [6, 96, 3, 1], + [6, 160, 3, 2], + [6, 320, 1, 1], + ] + + # only check the first element, assuming user knows t,c,n,s are required + if len(inverted_residual_setting) == 0 or len(inverted_residual_setting[0]) != 4: + raise ValueError("inverted_residual_setting should be non-empty " + "or a 4-element list, got {}".format(inverted_residual_setting)) + + # building first layer + input_channel = _make_divisible(input_channel, round_nearest) + self.last_channel = _make_divisible(last_channel * max(1.0, width_mult), round_nearest) + self.features_init = ConvBNReLU(3, input_channel, stride=2) + + self.unfold = nn.Unfold(kernel_size=(6,6),stride=(4,4)) + + self.rnn_model = RNNPool(6, 6, 8, 8, input_channel)#num_init_features) + self.fold = nn.Fold(kernel_size=(1,1),output_size=(27,27)) + + + features=[] + + input_channel = 32 + + # building inverted residual blocks + for t, c, n, s in inverted_residual_setting: + output_channel = _make_divisible(c * width_mult, round_nearest) + for i in range(n): + stride = s if i == 0 else 1 + features.append(block(input_channel, output_channel, stride, expand_ratio=t)) + input_channel = output_channel + # building last several layers + features.append(ConvBNReLU(input_channel, self.last_channel, kernel_size=1)) + self.features = nn.Sequential(*features) + + # building classifier + self.classifier = nn.Sequential( + nn.Dropout(0.2), + nn.Linear(self.last_channel, num_classes), + ) + + # weight initialization + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight, mode='fan_out') + if m.bias is not None: + nn.init.zeros_(m.bias) + elif isinstance(m, nn.BatchNorm2d): + nn.init.ones_(m.weight) + nn.init.zeros_(m.bias) + elif isinstance(m, nn.Linear): + nn.init.normal_(m.weight, 0, 0.01) + nn.init.zeros_(m.bias) + + def forward(self, x): + batch_size = x.shape[0] + + + x = self.features_init(x) + + patches = self.unfold(x) + patches = torch.cat(torch.unbind(patches,dim=2),dim=0) + patches = torch.reshape(patches,(-1,8,6,6)) + + + output_x = int((x.shape[2]-6)/4 + 1) + output_y = int((x.shape[3]-6)/4 + 1) + + rnnX = self.rnn_model(patches, int(batch_size)*output_x*output_y) + + x = torch.stack(torch.split(rnnX, split_size_or_sections=int(batch_size), dim=0),dim=2) + + x = self.fold(x) + + x = F.pad(x, (0,1,0,1), mode='replicate') + + x = self.features(x) + x = x.mean([2, 3]) + x = self.classifier(x) + return x + + +def mobilenetv2_rnnpool(pretrained=False, progress=True, **kwargs): + """ + Constructs a MobileNetV2 architecture from + `"MobileNetV2: Inverted Residuals and Linear Bottlenecks" `_. + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + progress (bool): If True, displays a progress bar of the download to stderr + """ + model = MobileNetV2(**kwargs) + if pretrained: + state_dict = load_state_dict_from_url(model_urls['mobilenet_v2'], + progress=progress) + model.load_state_dict(state_dict) + return model diff --git a/examples/pytorch/vision/Visual_Wakeword/requirements.txt b/examples/pytorch/vision/Visual_Wakeword/requirements.txt new file mode 100644 index 00000000..f05a38c8 --- /dev/null +++ b/examples/pytorch/vision/Visual_Wakeword/requirements.txt @@ -0,0 +1,9 @@ +pycocotools +pyvww +easydict==1.9 +importlib-metadata==1.5.0 +matplotlib==3.2.1 +opencv-python-headless==4.2.0.32 +scikit-image==0.15.0 +tensorboard==1.14.0 +tensorboardX==1.9 \ No newline at end of file diff --git a/examples/pytorch/vision/Visual_Wakeword/scripts/create_coco_train_minival_split.py b/examples/pytorch/vision/Visual_Wakeword/scripts/create_coco_train_minival_split.py new file mode 100755 index 00000000..967b8c4a --- /dev/null +++ b/examples/pytorch/vision/Visual_Wakeword/scripts/create_coco_train_minival_split.py @@ -0,0 +1,120 @@ +## Code from https://github.com/Mxbonn/visualwakewords + + +"""Create maxitrain and minival annotations. + This script generates a new train validation split with 115k training and 8k validation images. + Based on the split used by Google + (https://raw.githubusercontent.com/tensorflow/models/master/research/object_detection/data/mscoco_minival_ids.txt). + + Usage: + From this folder, run the following commands: (2014 can be replaced by 2017 if you downloaded the 2017 dataset) + TRAIN_ANNOTATIONS_FILE="path-to-mscoco-dataset/annotations/instances_train2014.json" + VAL_ANNOTATIONS_FILE="path-to-mscoco-dataset/annotations/instances_val2014.json" + OUTPUT_DIR="path-to-mscoco-dataset/annotations/" + python create_coco_train_minival_split.py \ + --train_annotations_file="${TRAIN_ANNOTATIONS_FILE}" \ + --val_annotations_file="${VAL_ANNOTATIONS_FILE}" \ + --output_dir="${OUTPUT_DIR}" +""" +import json +import os +from argparse import ArgumentParser + + +def create_maxitrain_minival(train_file, val_file, output_dir): + """ Generate maxitrain and minival annotations files. + Loads COCO 2014/2017 train and validation json files and creates a new split with + 115k training images and 8k validation images. + Based on the split used by Google + (https://raw.githubusercontent.com/tensorflow/models/master/research/object_detection/data/mscoco_minival_ids.txt). + Args: + train_file: JSON file containing COCO 2014 or 2017 train annotations + val_file: JSON file containing COCO 2014 or 2017 validation annotations + output_dir: Directory where the new annotation files will be stored. + """ + maxitrain_path = os.path.join( + output_dir, 'instances_maxitrain.json') + minival_path = os.path.join( + output_dir, 'instances_minival.json') + train_json = json.load(open(train_file, 'r')) + val_json = json.load(open(val_file, 'r')) + + info = train_json['info'] + categories = train_json['categories'] + licenses = train_json['licenses'] + + dir_path = os.path.dirname(os.path.realpath(__file__)) + file_path = os.path.join(dir_path, 'mscoco_minival_ids.txt') + minival_ids_f = open(file_path, 'r') + minival_ids = minival_ids_f.readlines() + minival_ids = [int(i) for i in minival_ids] + + train_images = train_json['images'] + val_images = val_json['images'] + train_annotations = train_json['annotations'] + val_annotations = val_json['annotations'] + + maxitrain_images = [] + minival_images = [] + maxitrain_annotations = [] + minival_annotations = [] + + for _images in [train_images, val_images]: + for img in _images: + img_id = img['id'] + if img_id in minival_ids: + minival_images.append(img) + else: + maxitrain_images.append(img) + + for _annotations in [train_annotations, val_annotations]: + for ann in _annotations: + img_id = ann['image_id'] + if img_id in minival_ids: + minival_annotations.append(ann) + else: + maxitrain_annotations.append(ann) + + with open(maxitrain_path, 'w') as fp: + json.dump( + { + "info": info, + "licenses": licenses, + 'images': maxitrain_images, + 'annotations': maxitrain_annotations, + 'categories': categories, + }, fp) + + with open(minival_path, 'w') as fp: + json.dump( + { + "info": info, + "licenses": licenses, + 'images': minival_images, + 'annotations': minival_annotations, + 'categories': categories, + }, fp) + + +def main(args): + output_dir = os.path.realpath(os.path.expanduser(args.output_dir)) + train_annotations_file = os.path.realpath(os.path.expanduser(args.train_annotations_file)) + val_annotations_file = os.path.realpath(os.path.expanduser(args.val_annotations_file)) + + if not os.path.isdir(output_dir): + os.makedirs(output_dir) + create_maxitrain_minival(train_annotations_file, val_annotations_file, output_dir) + + +if __name__ == '__main__': + parser = ArgumentParser(description="Script that takes the 2014/2017 training and validation annotations and" + "creates a train split of 115k images and a minival of 8k.") + parser.add_argument('--train_annotations_file', type=str, required=True, + help='COCO2014/2017 Training annotations JSON file') + parser.add_argument('--val_annotations_file', type=str, required=True, + help='COCO2014/2017 Validation annotations JSON file') + parser.add_argument('--output_dir', type=str, required=True, + help='Output directory where the maxitrain and minival annotations files will be stored') + + args = parser.parse_args() + main(args) diff --git a/examples/pytorch/vision/Visual_Wakeword/scripts/create_visualwakewords_annotations.py b/examples/pytorch/vision/Visual_Wakeword/scripts/create_visualwakewords_annotations.py new file mode 100755 index 00000000..f0b97acc --- /dev/null +++ b/examples/pytorch/vision/Visual_Wakeword/scripts/create_visualwakewords_annotations.py @@ -0,0 +1,217 @@ +## Code from https://github.com/Mxbonn/visualwakewords + + +"""Create Visual Wakewords annotations. + This script generates the Visual WakeWords dataset annotations from the raw COCO dataset. + The resulting annotations can then be used with `pyvww.utils.VisualWakeWords` and + `pyvww.pytorch.VisualWakeWordsClassification`. + + Visual WakeWords Dataset is derived from the COCO dataset to design tiny models + classifying two classes, such as person/not-person. The COCO annotations + are filtered to two classes: foreground_class and background + (for e.g. person and not-person). Bounding boxes for small objects + with area less than 5% of the image area are filtered out. + The resulting annotations file follows the COCO data format. + { + "info" : info, + "images" : [image], + "annotations" : [annotation], + "licenses" : [license], + } + + info{ + "year" : int, + "version" : str, + "description" : str, + "url" : str, + } + + image{ + "id" : int, + "width" : int, + "height" : int, + "file_name" : str, + "license" : int, + "flickr_url" : str, + "coco_url" : str, + "date_captured" : datetime, + } + + license{ + "id" : int, + "name" : str, + "url" : str, + } + + annotation{ + "id" : int, + "image_id" : int, + "category_id" : int, + "area" : float, + "bbox" : [x,y,width,height], + "iscrowd" : 0 or 1, + } + + Example usage: + From this folder, run the following commands: + bash download_mscoco.sh path-to-mscoco-dataset + TRAIN_ANNOTATIONS_FILE="path-to-mscoco-dataset/annotations/instances_train2014.json" + VAL_ANNOTATIONS_FILE="path-to-mscoco-dataset/annotations/instances_val2014.json" + DIR="path-to-mscoco-dataset/annotations/" + python create_coco_train_minival_split.py \ + --train_annotations_file="${TRAIN_ANNOTATIONS_FILE}" \ + --val_annotations_file="${VAL_ANNOTATIONS_FILE}" \ + --output_dir="${DIR}" + MAXITRAIN_ANNOTATIONS_FILE="path-to-mscoco-dataset/annotations/instances_maxitrain.json" + MINIVAL_ANNOTATIONS_FILE="path-to-mscoco-dataset/annotations/instances_minival.json" + VWW_OUTPUT_DIR="new-path-to-visualwakewords-dataset/annotations/" + python create_visualwakewords_annotations.py \ + --train_annotations_file="${MAXITRAIN_ANNOTATIONS_FILE}" \ + --val_annotations_file="${MINIVAL_ANNOTATIONS_FILE}" \ + --output_dir="${VWW_OUTPUT_DIR}" \ + --threshold=0.005 \ + --foreground_class='person' +""" + +import json +import os +from argparse import ArgumentParser + +from pycocotools.coco import COCO + + +def create_visual_wakeword_annotations(annotations_file, + visualwakewords_annotations_path, + object_area_threshold, + foreground_class_name): + """Generate visual wake words annotations file. + Loads COCO annotation json files and filters to foreground_class_name/not-foreground_class_name + (by default it will be person/not-person) to generate visual wake words annotations file. + Each image is assigned a label 1 or 0. The label 1 is assigned as long + as it has at least one foreground_class_name (e.g. person) + bounding box greater than object_area_threshold (e.g. 5% of the image area). + Args: + annotations_file: JSON file containing COCO bounding box annotations + visualwakewords_annotations_path: output path to annotations file + object_area_threshold: threshold on fraction of image area below which + small object bounding boxes are filtered + foreground_class_name: category from COCO dataset that is filtered by + the visual wakewords dataset + """ + print('Processing {}...'.format(annotations_file)) + coco = COCO(annotations_file) + + info = {"description": "Visual Wake Words Dataset", + "url": "https://arxiv.org/abs/1906.05721", + "version": "1.0", + "year": 2019, + } + + # default object of interest is person + foreground_class_id = 1 + dataset = coco.dataset + licenses = dataset['licenses'] + + images = dataset['images'] + # Create category index + foreground_category = None + background_category = {'supercategory': 'background', 'id': 0, 'name': 'background'} + for category in dataset['categories']: + if category['name'] == foreground_class_name: + foreground_class_id = category['id'] + foreground_category = category + foreground_category['id'] = 1 + background_category['name'] = "not-{}".format(foreground_category['name']) + categories = [background_category, foreground_category] + + if not 'annotations' in dataset: + raise KeyError('Need annotations in json file to build the dataset.') + new_ann_id = 0 + annotations = [] + positive_img_ids = set() + foreground_imgs_ids = coco.getImgIds(catIds=foreground_class_id) + for img_id in foreground_imgs_ids: + img = coco.imgs[img_id] + img_area = img['height'] * img['width'] + for ann_id in coco.getAnnIds(imgIds=img_id, catIds=foreground_class_id): + ann = coco.anns[ann_id] + if 'area' in ann: + normalized_ann_area = ann['area'] / img_area + if normalized_ann_area > object_area_threshold: + new_ann = { + "id": new_ann_id, + "image_id": img_id, + "category_id": 1, + "area": ann["area"], + "bbox": ann["bbox"], + "iscrowd": ann["iscrowd"], + } + annotations.append(new_ann) + positive_img_ids.add(img_id) + new_ann_id += 1 + print("There are {} images that now have label {}, of the {} images in total.".format(len(positive_img_ids), + foreground_class_name, + len(coco.imgs))) + negative_img_ids = list(set(coco.imgs.keys()) - positive_img_ids) + for img_id in negative_img_ids: + new_ann = { + "id": new_ann_id, + "image_id": img_id, + "category_id": 0, + "area": 0.0, + "bbox": [], + "iscrowd": 0, + } + annotations.append(new_ann) + new_ann_id += 1 + + # Output Visual WakeWords annotations and labels + with open(visualwakewords_annotations_path, 'w') as fp: + json.dump( + { + "info": info, + "licenses": licenses, + 'images': images, + 'annotations': annotations, + 'categories': categories, + }, fp) + + +def main(args): + output_dir = os.path.realpath(os.path.expanduser(args.output_dir)) + train_annotations_file = os.path.realpath(os.path.expanduser(args.train_annotations_file)) + val_annotations_file = os.path.realpath(os.path.expanduser(args.val_annotations_file)) + visualwakewords_annotations_train = os.path.join( + output_dir, 'instances_train.json') + visualwakewords_annotations_val = os.path.join( + output_dir, 'instances_val.json') + small_object_area_threshold = args.threshold + foreground_class_of_interest = args.foreground_class + + # Create the Visual WakeWords annotations from COCO annotations + if not os.path.isdir(output_dir): + os.makedirs(output_dir) + create_visual_wakeword_annotations( + train_annotations_file, visualwakewords_annotations_train, + small_object_area_threshold, foreground_class_of_interest) + create_visual_wakeword_annotations( + val_annotations_file, visualwakewords_annotations_val, + small_object_area_threshold, foreground_class_of_interest) + + +if __name__ == '__main__': + parser = ArgumentParser() + parser.add_argument('--train_annotations_file', type=str, required=True, + help='(COCO) Training annotations JSON file') + parser.add_argument('--val_annotations_file', type=str, required=True, + help='(COCO) Validation annotations JSON file') + parser.add_argument('--output_dir', type=str, default='/tmp/visualwakewords/', + help='Output directory where the Visual WakeWords annotations files be stored') + parser.add_argument('--threshold', type=float, default=0.005, + help='Threshold of fraction of image area below which small objects are filtered.') + parser.add_argument('--foreground_class', type=str, default='person', + help='Annotations will have a label indicating if this object is present or absent' + 'in the scene (default is person/not-person).') + + args = parser.parse_args() + main(args) diff --git a/examples/pytorch/vision/Visual_Wakeword/scripts/download_mscoco.sh b/examples/pytorch/vision/Visual_Wakeword/scripts/download_mscoco.sh new file mode 100755 index 00000000..763f1fcf --- /dev/null +++ b/examples/pytorch/vision/Visual_Wakeword/scripts/download_mscoco.sh @@ -0,0 +1,80 @@ +# Copyright 2020 Maxim Bonnaerens. All Rights Reserved. +# +# Copyright 2019 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. +# ============================================================================== +# File modified from tensorflow/models/research/slim/datasets/download_mscoco.sh + +# Script to download the COCO dataset. See +# http://cocodataset.org/#overview for an overview of the dataset. +# +# usage: +# bash scripts/download_mscoco.sh path-to-COCO-dataset +# +set -e + +YEAR=${2:-2014} +if [ -z "$1" ]; then + echo "usage download_mscoco.sh [data dir] (2014|2017)" + exit +fi + +if [ "$(uname)" == "Darwin" ]; then + UNZIP="tar -xf" +else + UNZIP="unzip -nq" +fi + +# Create the output directories. +OUTPUT_DIR="${1%/}" +mkdir -p "${OUTPUT_DIR}" + +# Helper function to download and unpack a .zip file. +function download_and_unzip() { + local BASE_URL=${1} + local FILENAME=${2} + + if [ ! -f "${FILENAME}" ]; then + echo "Downloading ${FILENAME} to $(pwd)" + wget -nd -c "${BASE_URL}/${FILENAME}" + else + echo "Skipping download of ${FILENAME}" + fi + echo "Unzipping ${FILENAME}" + ${UNZIP} "${FILENAME}" + rm "${FILENAME}" +} + +cd "${OUTPUT_DIR}" + +# Download the images. +BASE_IMAGE_URL="http://images.cocodataset.org/zips" + +TRAIN_IMAGE_FILE="train${YEAR}.zip" +download_and_unzip ${BASE_IMAGE_URL} "${TRAIN_IMAGE_FILE}" +TRAIN_IMAGE_DIR="${OUTPUT_DIR}/train${YEAR}" + +VAL_IMAGE_FILE="val${YEAR}.zip" +download_and_unzip ${BASE_IMAGE_URL} "${VAL_IMAGE_FILE}" +VAL_IMAGE_DIR="${OUTPUT_DIR}/val${YEAR}" + +COMMON_DIR="all$YEAR" +mkdir -p "${COMMON_DIR}" +for i in ${TRAIN_IMAGE_DIR}/*; do cp --symbolic-link "$i" ${COMMON_DIR}/; done +for i in ${VAL_IMAGE_DIR}/*; do cp --symbolic-link "$i" ${COMMON_DIR}/; done + +# Download the annotations. +BASE_INSTANCES_URL="http://images.cocodataset.org/annotations" +INSTANCES_FILE="annotations_trainval${YEAR}.zip" +download_and_unzip ${BASE_INSTANCES_URL} "${INSTANCES_FILE}" diff --git a/examples/pytorch/vision/Visual_Wakeword/scripts/mscoco_minival_ids.txt b/examples/pytorch/vision/Visual_Wakeword/scripts/mscoco_minival_ids.txt new file mode 100644 index 00000000..5bbff3c1 --- /dev/null +++ b/examples/pytorch/vision/Visual_Wakeword/scripts/mscoco_minival_ids.txt @@ -0,0 +1,8059 @@ +25096 +251824 +35313 +546011 +524186 +205866 +511403 +313916 +47471 +258628 +233560 +576017 +404517 +410056 +178690 +248980 +511724 +429718 +163076 +244111 +126766 +313182 +191981 +139992 +325237 +248129 +214519 +175438 +493321 +174103 +563762 +536795 +289960 +473720 +515540 +292118 +360851 +267175 +532876 +171613 +581415 +259819 +441841 +381682 +58157 +4980 +473929 +70626 +93773 +283412 +36765 +495020 +278401 +329307 +192810 +491784 +506416 +225495 +553747 +86442 +242208 +132686 +385877 +290248 +525705 +5476 +486521 +332512 +138556 +348083 +284375 +40018 +296994 +38685 +432429 +183407 +434358 +472164 +530494 +570693 +193401 +392612 +98872 +445766 +532209 +98322 +285114 +267725 +51605 +314812 +91105 +535506 +540264 +375341 +449828 +277659 +68933 +76873 +217554 +213592 +190776 +516224 +474479 +343599 +578813 +128669 +546292 +475365 +377626 +128833 +427091 +547227 +11742 +80213 +462241 +374574 +121572 +29151 +13892 +262394 +303667 +198724 +7320 +448492 +419080 +460379 +483965 +556516 +139181 +1103 +308715 +207507 +213827 +216083 +445597 +240275 +379585 +116389 +138124 +559051 +326898 +419386 +503660 +519460 +23893 +24458 +518109 +462982 +151492 +514254 +2477 +147165 +570394 +548766 +250083 +364341 +351967 +386277 +328084 +511299 +499349 +315501 +234965 +428562 +219771 +288150 +136021 +168619 +298316 +75118 +189752 +243857 +296222 +554002 +533628 +384596 +202981 +498350 +391463 +183991 +528062 +451084 +7899 +408534 +329030 +318566 +22492 +361285 +226973 +213356 +417265 +105622 +161169 +261487 +167477 +233370 +142999 +256713 +305833 +103579 +352538 +135763 +392144 +61181 +200302 +456908 +286858 +179850 +488075 +174511 +194755 +317822 +2302 +304596 +172556 +548275 +341678 +55299 +134760 +352936 +545129 +377012 +141328 +103757 +552837 +28246 +125167 +328745 +278760 +337133 +403389 +146825 +502558 +265916 +428985 +492041 +113403 +372037 +306103 +287574 +187495 +479805 +336309 +162043 +95899 +43133 +464248 +149115 +247438 +74030 +130645 +282841 +127092 +101172 +536743 +179642 +58133 +49667 +170605 +11347 +365277 +201970 +292663 +217219 +463226 +41924 +281102 +357816 +490878 +100343 +525058 +133503 +416145 +29341 +415413 +125527 +507951 +262609 +240210 +581781 +345137 +526342 +268641 +328777 +32001 +137538 +39115 +415958 +6771 +421865 +64909 +383601 +206907 +420840 +370980 +28452 +571893 +153520 +185890 +392991 +547013 +257359 +279879 +478614 +131919 +40937 +22874 +173375 +106344 +44801 +205401 +312870 +400886 +351530 +344013 +173500 +470423 +396729 +402499 +276585 +377097 +367619 +518908 +263866 +332292 +67805 +152211 +515025 +221350 +525247 +78490 +504342 +95908 +82668 +256199 +220270 +552065 +242379 +84866 +152281 +228464 +223122 +67537 +456968 +368349 +101985 +14681 +543551 +107558 +372009 +99054 +126540 +86877 +492785 +482585 +571564 +501116 +296871 +20395 +181518 +568041 +121154 +56187 +190018 +97156 +310325 +393274 +214574 +243222 +289949 +452121 +150508 +341752 +310757 +24040 +228551 +335589 +12020 +529597 +459884 +344888 +229713 +51948 +370929 +552061 +261072 +120070 +332067 +263014 +158993 +451714 +397327 +20965 +414340 +574946 +370266 +487534 +492246 +264771 +73702 +43997 +235124 +301093 +400048 +77681 +58472 +331386 +13783 +242513 +419158 +59325 +383033 +393258 +529041 +249276 +182775 +351793 +9727 +334069 +566771 +539355 +38662 +423617 +47559 +120592 +508303 +462565 +47916 +218208 +182362 +562101 +441442 +71239 +395378 +522637 +25603 +484450 +872 +171483 +527248 +323155 +240754 +15032 +419144 +313214 +250917 +333430 +242757 +221914 +283190 +194297 +228506 +550691 +172513 +312192 +530619 +113867 +323552 +374115 +35435 +160239 +62877 +441873 +196574 +62858 +557114 +427612 +242869 +356733 +304828 +24880 +490509 +407083 +457877 +402788 +536416 +385912 +544121 +500389 +451102 +12120 +483476 +70987 +482799 +542549 +49236 +424258 +435783 +182366 +438093 +501824 +232845 +53965 +223198 +288933 +450458 +285664 +196484 +408930 +519815 +290981 +398567 +315792 +490683 +257136 +75611 +302498 +332153 +82293 +416911 +558608 +564659 +536195 +370260 +57904 +527270 +6593 +145620 +551650 +470832 +515785 +251404 +287331 +150788 +334006 +266117 +10039 +579158 +328397 +468351 +550400 +31745 +405970 +16761 +323515 +459598 +558457 +570736 +476939 +472610 +72155 +112517 +13659 +530905 +458768 +43486 +560893 +493174 +31217 +262736 +412204 +142722 +151231 +480643 +197245 +398666 +444869 +110999 +191724 +479057 +492420 +170638 +277329 +301908 +395644 +537611 +141887 +47149 +403432 +34818 +372495 +67994 +337497 +478586 +249815 +533462 +281032 +289941 +151911 +271215 +407868 +360700 +508582 +103873 +353658 +369081 +406403 +331692 +26430 +105655 +572630 +37181 +91336 +484587 +318284 +113019 +33055 +25293 +229324 +374052 +384111 +213951 +315195 +319283 +539453 +17655 +308974 +326243 +539436 +417876 +526940 +356347 +221932 +73753 +292648 +262284 +304924 +558587 +374858 +253518 +311744 +539636 +40924 +136624 +334305 +365997 +63355 +191226 +526732 +367128 +575198 +500657 +50637 +17182 +424792 +565353 +563040 +383494 +74458 +155142 +197125 +223857 +428241 +440830 +371289 +437303 +330449 +93771 +82715 +499631 +381257 +563951 +192834 +528600 +404273 +270554 +208053 +188613 +484760 +432016 +129800 +91756 +523097 +317018 +487282 +444913 +159500 +126822 +540564 +105812 +560756 +306099 +471226 +123842 +513219 +154877 +497034 +283928 +564003 +238602 +194780 +462728 +558640 +524373 +455624 +3690 +560367 +316351 +455772 +223777 +161517 +243034 +250440 +239975 +441008 +324715 +152106 +246973 +462805 +296521 +412767 +530913 +370165 +292526 +107244 +217440 +330204 +220176 +577735 +197022 +127451 +518701 +212322 +204887 +27696 +348474 +119233 +282804 +230040 +425690 +409241 +296825 +296353 +375909 +123136 +573891 +338256 +198247 +373375 +151051 +500084 +557596 +120478 +44989 +283380 +149005 +522065 +626 +17198 +309633 +524245 +291589 +322714 +455847 +248468 +371948 +444928 +20438 +481670 +147195 +95022 +548159 +553165 +395324 +391371 +86884 +561121 +219737 +38875 +338159 +377881 +185472 +359277 +114861 +378048 +126226 +10217 +320246 +15827 +178236 +370279 +352978 +408101 +77615 +337044 +223714 +20796 +352445 +263834 +156704 +377867 +119402 +399567 +1180 +257941 +560675 +390471 +209290 +258382 +466339 +56437 +195042 +384230 +203214 +36077 +283038 +38323 +158770 +532381 +395903 +375461 +397857 +326798 +371699 +369503 +495626 +464328 +462211 +397719 +434089 +424793 +476770 +531852 +303538 +525849 +480917 +419653 +265063 +48956 +5184 +279149 +396727 +374266 +124429 +36124 +240213 +147556 +339512 +577182 +288599 +257169 +178254 +393869 +122314 +28713 +48133 +540681 +100974 +368459 +500110 +73634 +460982 +203878 +578344 +443602 +502012 +399666 +103603 +22090 +257529 +176328 +536656 +408873 +116881 +460972 +33835 +460781 +51223 +46463 +89395 +407646 +337453 +461715 +16257 +426987 +234889 +3125 +165643 +517472 +451435 +206800 +112128 +331236 +163306 +94185 +498716 +532732 +146509 +458567 +153832 +105996 +353398 +546976 +283060 +247624 +110048 +243491 +154798 +543600 +149962 +355256 +352900 +203081 +372203 +284605 +516244 +190494 +150301 +326082 +64146 +402858 +413538 +399510 +460251 +94336 +458721 +57345 +424162 +423508 +69356 +567220 +509786 +37038 +111535 +341318 +372067 +358120 +244909 +180653 +39852 +438560 +357041 +67065 +51928 +171717 +520430 +552395 +431355 +528084 +20913 +309610 +262323 +573784 +449485 +154846 +283438 +430871 +199578 +516318 +563912 +348483 +485613 +143440 +94922 +168817 +74457 +45830 +66297 +514173 +99186 +296236 +230903 +452312 +476444 +568981 +100811 +237350 +194724 +453622 +49559 +270609 +113701 +415393 +92173 +137004 +188795 +148280 +448114 +575964 +163155 +518719 +219329 +214247 +363927 +65357 +87617 +552612 +457817 +124796 +47740 +560463 +513968 +273637 +354212 +95959 +261061 +307265 +316237 +191342 +463272 +169273 +396518 +93261 +572733 +407386 +202658 +446497 +420852 +229274 +432724 +34900 +352533 +49891 +66144 +146831 +467484 +97988 +561647 +301155 +507421 +173217 +577584 +451940 +99927 +350639 +178941 +485155 +175948 +360673 +92963 +361321 +48739 +577310 +517795 +93405 +506458 +394681 +167920 +16995 +519573 +270532 +527750 +563403 +494608 +557780 +178691 +8676 +186927 +550173 +361656 +575911 +281315 +534377 +57570 +340894 +37624 +143103 +538243 +425077 +376545 +108129 +170974 +7522 +408906 +264279 +79415 +344025 +186797 +234349 +226472 +123639 +225177 +237984 +38714 +223671 +358247 +152465 +521405 +453722 +361111 +557117 +235832 +309341 +268469 +108353 +532531 +357279 +537280 +437618 +122953 +7088 +36693 +127659 +431901 +57244 +567565 +568111 +202926 +504516 +555685 +322369 +347620 +110231 +568982 +295340 +529798 +300341 +158160 +73588 +119476 +387216 +154994 +259755 +211282 +433971 +263588 +299468 +570138 +123017 +355106 +540172 +406215 +8401 +548844 +161820 +396432 +495348 +222407 +53123 +491556 +108130 +440617 +448309 +22596 +346841 +213829 +135076 +56326 +233139 +487418 +227326 +137763 +383389 +47882 +207797 +167452 +112065 +150703 +421109 +171753 +158279 +240800 +66821 +152886 +163640 +475466 +301799 +106712 +470885 +536370 +420389 +396768 +281950 +18903 +357529 +33650 +168243 +201004 +389295 +557150 +185327 +181256 +557396 +182025 +61564 +301928 +332455 +199403 +18444 +177452 +204206 +38465 +215906 +153103 +445019 +324527 +299207 +429281 +574675 +157067 +241269 +100850 +502818 +576566 +296775 +873 +280363 +355240 +383445 +286182 +67327 +422778 +494855 +337246 +266853 +47516 +381991 +44081 +403862 +381430 +370798 +173383 +387173 +22396 +484066 +349414 +262235 +492814 +65238 +209420 +336276 +453328 +407286 +420490 +360328 +158440 +398534 +489475 +477389 +297108 +69750 +507833 +198992 +99736 +546444 +514914 +482574 +54355 +63478 +191693 +61684 +412914 +267408 +424641 +56872 +318080 +30290 +33441 +199310 +337403 +26731 +453390 +506137 +188945 +185950 +239843 +357944 +290570 +523637 +551952 +513397 +357870 +523517 +277048 +259879 +186991 +521943 +21900 +281074 +187194 +526723 +568147 +513037 +177338 +243831 +203488 +208494 +188460 +289943 +399177 +404668 +160761 +271143 +76087 +478922 +440045 +449432 +61025 +331138 +227019 +147577 +548337 +444294 +458663 +236837 +6854 +444926 +484816 +516641 +397863 +188534 +64822 +213453 +66561 +43218 +514901 +322844 +498453 +488788 +391656 +298994 +64088 +464706 +193720 +199017 +186427 +15278 +350386 +342335 +372024 +550939 +35594 +381382 +235902 +26630 +213765 +550001 +129706 +577149 +353096 +376891 +28499 +427041 +314965 +231163 +5728 +347836 +184388 +27476 +284860 +476872 +301317 +99546 +147653 +529515 +311922 +20777 +2613 +59463 +430670 +560744 +60677 +332087 +296724 +353321 +103306 +363887 +76431 +423058 +120340 +119452 +6723 +462327 +163127 +402723 +489382 +183181 +107656 +375409 +355228 +430762 +512468 +409125 +270544 +559113 +495388 +529434 +38355 +422025 +379667 +131386 +183409 +573536 +581317 +425404 +350084 +472 +28532 +329717 +230220 +187196 +484166 +97434 +224595 +87483 +516998 +314876 +32610 +514586 +344816 +394418 +402330 +305993 +371497 +315790 +294908 +207431 +561014 +26584 +368671 +374990 +54747 +47571 +449424 +283761 +84735 +522127 +120473 +524656 +479659 +131627 +450959 +153300 +580908 +207785 +49115 +284991 +96505 +278306 +291655 +1404 +489304 +557459 +37740 +157465 +390475 +119166 +33871 +247428 +75905 +20779 +65035 +333556 +375415 +383676 +505243 +87327 +16451 +287235 +70190 +245067 +417520 +229234 +183786 +333018 +554156 +198915 +108021 +128262 +412443 +242543 +555050 +436511 +445233 +207886 +156397 +526257 +521357 +413043 +427189 +401614 +94823 +351130 +105945 +182314 +305879 +526197 +64409 +496800 +236461 +138175 +43816 +185904 +345711 +72536 +526737 +360400 +556537 +426053 +59044 +28290 +222548 +434915 +418623 +246454 +111801 +12448 +427133 +459117 +11262 +169045 +469996 +304390 +513096 +322822 +196371 +504977 +395364 +243950 +216218 +417217 +106736 +58194 +504101 +478522 +379314 +30432 +207027 +297146 +91844 +176031 +98287 +278095 +196053 +343692 +523137 +220224 +349485 +376193 +407067 +185781 +37871 +336464 +46331 +44244 +80274 +170147 +361106 +468499 +537864 +467457 +267343 +291528 +287828 +555648 +388284 +576085 +531973 +350122 +422253 +509811 +78093 +410019 +133090 +581205 +343976 +9007 +92478 +450674 +486306 +503978 +46378 +335578 +404071 +225558 +217923 +406217 +138054 +575815 +234990 +336257 +159240 +399516 +226408 +531126 +138599 +61693 +89861 +29504 +163296 +477906 +48419 +25595 +195594 +97592 +392555 +203849 +139248 +245651 +275755 +245426 +127279 +521359 +517623 +235747 +475906 +11198 +336101 +70134 +505447 +218996 +30080 +484457 +120441 +575643 +132703 +197915 +505576 +90956 +99741 +517819 +240918 +150834 +207306 +132682 +88250 +213599 +462584 +413321 +361521 +496081 +410583 +440027 +417284 +397069 +280498 +473171 +129739 +279774 +29370 +518899 +509867 +85556 +434930 +280710 +55077 +348793 +157756 +281111 +190689 +281447 +502854 +232894 +268742 +199553 +220808 +137330 +256903 +116017 +466416 +41635 +110906 +340934 +557501 +146767 +517617 +487159 +1561 +417281 +489014 +292463 +113533 +412247 +263973 +515444 +343561 +310200 +293804 +225867 +150320 +183914 +9707 +89999 +177842 +296524 +287829 +68300 +363654 +465986 +159969 +313948 +522779 +219820 +198352 +12959 +266727 +8016 +175804 +497867 +307892 +287527 +309638 +205854 +114119 +23023 +322586 +383341 +134198 +553522 +70426 +329138 +105367 +175597 +187791 +17944 +366611 +93493 +242422 +41842 +558840 +32203 +19667 +124297 +383726 +252625 +234794 +498228 +102906 +287967 +69021 +51326 +243896 +509423 +440124 +122582 +344325 +34455 +442478 +23587 +236904 +185633 +349841 +44294 +112568 +186296 +71914 +3837 +135486 +223747 +557517 +385181 +265313 +404263 +26564 +516867 +497096 +332351 +345139 +444304 +510877 +356387 +561214 +311471 +408789 +561729 +291380 +174671 +45710 +435136 +388858 +361693 +50811 +531134 +573605 +340175 +534988 +382671 +327047 +348400 +547137 +401037 +490711 +499266 +236370 +449075 +334015 +107234 +232315 +462953 +252048 +186822 +410168 +28994 +45550 +453626 +417957 +468577 +106338 +391684 +375143 +217622 +357903 +347648 +142182 +213843 +299148 +352587 +436676 +161875 +144655 +304741 +235017 +181799 +211042 +335507 +553731 +412531 +229740 +437129 +423830 +561806 +337666 +52016 +138057 +70254 +494393 +73119 +262425 +565395 +305329 +489611 +377080 +569450 +549766 +332940 +235302 +53893 +203781 +38449 +114870 +18699 +396338 +449839 +423613 +379767 +369594 +375812 +359219 +229311 +291675 +224907 +416885 +32964 +573406 +17282 +103375 +81860 +576886 +461334 +35672 +243442 +217269 +445055 +211112 +455675 +412384 +88967 +550643 +24223 +504074 +9275 +155546 +329542 +172658 +331600 +315492 +194208 +162867 +324614 +432017 +140860 +157944 +406616 +486079 +361172 +258346 +494140 +315384 +451014 +242619 +413684 +386187 +408501 +121089 +343603 +232538 +558671 +551596 +32992 +406647 +435260 +11156 +40896 +175382 +110560 +252968 +189694 +63154 +564816 +72004 +164788 +434583 +453104 +111878 +268484 +290768 +473215 +450620 +32673 +277479 +529917 +315868 +562419 +378347 +398637 +84097 +120527 +134193 +431472 +400238 +86426 +208830 +524535 +22213 +516813 +526044 +386193 +246672 +386739 +559252 +153344 +236123 +246074 +323615 +92644 +408621 +323231 +499940 +296105 +578902 +150098 +145015 +131431 +318618 +68409 +497928 +362520 +467755 +112702 +163219 +277289 +192362 +497674 +525439 +56267 +465868 +407570 +551608 +345211 +179653 +55295 +97315 +534041 +505822 +411082 +132375 +25378 +272008 +536605 +123511 +148737 +577712 +493751 +29587 +468297 +528458 +491058 +558976 +181421 +209685 +147545 +486964 +570516 +168662 +19446 +395997 +242911 +232511 +317035 +354527 +5961 +513793 +124390 +370123 +113397 +195790 +252813 +326919 +432414 +409239 +458221 +115667 +212239 +279279 +375554 +546622 +317188 +260818 +286021 +377111 +209868 +243148 +132037 +560624 +459721 +193498 +22623 +254164 +112841 +383470 +62692 +227940 +471335 +44858 +213649 +179898 +102837 +474078 +44478 +256197 +309492 +182923 +421139 +275695 +104965 +480780 +449749 +76513 +578591 +336695 +247474 +320490 +246105 +53183 +485740 +575823 +510735 +290741 +37017 +348708 +279784 +453634 +567644 +434192 +482719 +435324 +544299 +106896 +569926 +301574 +492885 +103462 +487151 +513585 +219647 +303685 +459645 +76292 +188579 +154883 +207728 +425074 +310493 +27221 +371694 +119404 +399665 +273556 +454577 +580698 +267664 +295769 +423740 +22461 +22667 +508443 +390401 +369997 +524627 +193349 +132223 +576743 +130586 +487741 +107542 +501420 +520109 +308156 +540581 +231362 +86471 +472930 +351133 +463605 +575577 +159842 +39504 +223020 +63525 +298627 +139883 +375205 +303549 +16838 +495680 +408112 +394474 +188044 +472143 +463751 +31481 +378139 +190853 +442614 +172006 +140270 +133051 +178028 +495090 +88455 +13232 +46323 +346275 +425905 +487013 +433136 +514402 +521906 +4157 +61418 +567205 +213351 +304008 +296492 +506561 +408120 +415961 +323186 +480379 +349199 +201918 +135023 +456483 +136173 +237917 +4972 +99081 +331569 +150007 +36450 +93400 +487461 +203629 +218093 +487181 +113935 +139512 +210981 +358883 +47419 +248382 +80357 +462663 +83097 +26159 +80429 +283055 +452676 +50159 +12326 +29430 +303264 +158122 +569070 +52925 +534876 +46975 +426376 +170293 +434417 +235517 +218476 +445008 +482774 +305632 +116848 +557252 +229270 +453485 +382214 +54759 +59171 +193328 +17152 +238071 +148531 +409725 +75434 +65358 +473057 +415408 +579415 +48636 +269606 +298784 +162799 +356400 +326854 +24601 +66499 +340247 +20992 +190218 +548464 +122203 +405306 +495376 +536028 +5713 +206831 +9395 +503939 +194440 +474253 +395849 +165141 +204935 +412621 +402922 +87141 +570664 +202622 +137362 +221737 +78947 +112129 +341957 +169562 +164780 +360216 +107641 +415015 +444955 +559102 +123070 +176592 +309366 +116461 +222075 +530470 +214363 +414487 +471567 +292123 +370210 +364243 +510254 +396350 +141524 +220310 +398604 +145436 +392476 +17482 +78032 +336171 +130812 +489743 +346638 +418854 +139072 +263860 +458240 +383443 +337533 +182334 +535608 +517946 +489924 +308117 +129945 +59973 +538364 +513458 +449433 +25165 +335851 +487688 +153834 +347612 +349689 +443688 +486008 +479149 +442286 +61108 +315338 +511546 +506444 +775 +121839 +291412 +497626 +387223 +367095 +557896 +196118 +530652 +447991 +215622 +232160 +296731 +272273 +473415 +364705 +235790 +479950 +141278 +547903 +66523 +353989 +121875 +237735 +100083 +348941 +288983 +390083 +168248 +120776 +489764 +219135 +551713 +256035 +309005 +112493 +579759 +114972 +458992 +295768 +158497 +309696 +363844 +507966 +313491 +280779 +327130 +292901 +127761 +183843 +456521 +164475 +224281 +443713 +72514 +567383 +476215 +565650 +17708 +474471 +248334 +196313 +164759 +212453 +319024 +332916 +35436 +113139 +172716 +7570 +161609 +144534 +137475 +561411 +45844 +332027 +36990 +190160 +421231 +283210 +365611 +511407 +400887 +485071 +481214 +347203 +153506 +397403 +229599 +357322 +76034 +101189 +567444 +92363 +526767 +218811 +362812 +339120 +579696 +399269 +10705 +549012 +410428 +105623 +535307 +419235 +119911 +236604 +515779 +188173 +66397 +549119 +478742 +256180 +128224 +440539 +112818 +315434 +97513 +171970 +433483 +226008 +83217 +424548 +343753 +350334 +479280 +208808 +43266 +399893 +444386 +47687 +499093 +565269 +465835 +167486 +433460 +169872 +299640 +158466 +241373 +50576 +161567 +73560 +349804 +181745 +352684 +450357 +532693 +88335 +256518 +94926 +541197 +14629 +276149 +539439 +498738 +25654 +291330 +146465 +160190 +513064 +75748 +499007 +164464 +134042 +422416 +543315 +34056 +303197 +394801 +293071 +44964 +529083 +414522 +331180 +227599 +581040 +382850 +159898 +176841 +205352 +540782 +406591 +184499 +14380 +350230 +458175 +528786 +314935 +111086 +2191 +20371 +337042 +558371 +296907 +539937 +511463 +574856 +87864 +403817 +152598 +169712 +533227 +173545 +478862 +19455 +258433 +373440 +460229 +525682 +176857 +525050 +277025 +156416 +206784 +415179 +183204 +210374 +312868 +514366 +65208 +376342 +515792 +383066 +85247 +119132 +338007 +88748 +206705 +495808 +532164 +150686 +35474 +207860 +111165 +391199 +346011 +537721 +11390 +487482 +360983 +400347 +92795 +347506 +324322 +371958 +101280 +222842 +563604 +210299 +150616 +96351 +330455 +273551 +228749 +248051 +495252 +372265 +52664 +191874 +157416 +446428 +136681 +1228 +321811 +93791 +477867 +192520 +157124 +40620 +200541 +103904 +329494 +60093 +112573 +489125 +513115 +322968 +561619 +74309 +572462 +248252 +375376 +217312 +243213 +79878 +452218 +349754 +554291 +434043 +460373 +452591 +567787 +504711 +196007 +511153 +312416 +296056 +308849 +203667 +253223 +331230 +465545 +363048 +69392 +301506 +216198 +147979 +6005 +381870 +56983 +320972 +144122 +210855 +151480 +299288 +462486 +103931 +321079 +4134 +239861 +540006 +413805 +221222 +198943 +450790 +380597 +388298 +58737 +246197 +160726 +398554 +513946 +222235 +323851 +364703 +125643 +169800 +445662 +223764 +575372 +489207 +559474 +7155 +453819 +402720 +102355 +415076 +287436 +35705 +111076 +395865 +310862 +570834 +54728 +215778 +80053 +35148 +350488 +524140 +190097 +36661 +302110 +96884 +383397 +245462 +446958 +138937 +424712 +561814 +276964 +148034 +411068 +357824 +103257 +322149 +508899 +580294 +214386 +114419 +271429 +168260 +209835 +573072 +252269 +31980 +161308 +281508 +192714 +247599 +188948 +180563 +419601 +233660 +154804 +311846 +181499 +5535 +175082 +531018 +412338 +166995 +441411 +427820 +516846 +287366 +67959 +271266 +330845 +74209 +508167 +542699 +66485 +453756 +158412 +443784 +118097 +265050 +29074 +152623 +532493 +292988 +530384 +192660 +502336 +472648 +151657 +351626 +241010 +115070 +268356 +539557 +304698 +251140 +497158 +527445 +385428 +179200 +512394 +184978 +141910 +36311 +579457 +19129 +424960 +181714 +126216 +512911 +488360 +379533 +337551 +325410 +364587 +468885 +211107 +90062 +500446 +105960 +451951 +431431 +134178 +164548 +173826 +373988 +15157 +3091 +393557 +380011 +75372 +37403 +209995 +493610 +315899 +353299 +355040 +547000 +86133 +58174 +377326 +510230 +480583 +158588 +432529 +311206 +127626 +239980 +166340 +104185 +405174 +507211 +542782 +448078 +253477 +542694 +567308 +214853 +288824 +283268 +480757 +503200 +221089 +112388 +171539 +124452 +224200 +206362 +428754 +256192 +119414 +351620 +330050 +547504 +216398 +94261 +19916 +163242 +432588 +143824 +361103 +271138 +260150 +313627 +141086 +308263 +388453 +153217 +372794 +514787 +251910 +351335 +92683 +465836 +18442 +404128 +208476 +47873 +303219 +201622 +367489 +32760 +436174 +401926 +338419 +45248 +328464 +312216 +156282 +315702 +300701 +345401 +515350 +29094 +284296 +466449 +351057 +110672 +364853 +10014 +415828 +397522 +451412 +433124 +158277 +93476 +183387 +109889 +223326 +105547 +530061 +256301 +526778 +80974 +86650 +45835 +202154 +92678 +315991 +423919 +455044 +491168 +272253 +146627 +285349 +86001 +44171 +162332 +257328 +432820 +519275 +380639 +269436 +236016 +543215 +346752 +575970 +423498 +136926 +195648 +126634 +133078 +138656 +490012 +122388 +195165 +434900 +533625 +504167 +333697 +216576 +538775 +125072 +391154 +545007 +150292 +566717 +367362 +490991 +356623 +141271 +402795 +516786 +39499 +536716 +293324 +212853 +276381 +57124 +325992 +394659 +452178 +117674 +461172 +518586 +497021 +462345 +526570 +17328 +202928 +62566 +411277 +256983 +49473 +211206 +398031 +277955 +531178 +453959 +27946 +252844 +30273 +536933 +500298 +229111 +7977 +27642 +303726 +79927 +110313 +527691 +442205 +33345 +365851 +233236 +239157 +409221 +400803 +32947 +422516 +359727 +215872 +559454 +289716 +450247 +57827 +312298 +530383 +260048 +35857 +224222 +299533 +13296 +325907 +117869 +54088 +391011 +340478 +205344 +347823 +468604 +78701 +101414 +197499 +490871 +89273 +380343 +441974 +35974 +486114 +354398 +535536 +294030 +7276 +278742 +137028 +98721 +372764 +429802 +72105 +220307 +116845 +195406 +333000 +130401 +264382 +125458 +363036 +286994 +531070 +113801 +4108 +47603 +130118 +573924 +302990 +237566 +21470 +577926 +139436 +425925 +36844 +63602 +399791 +35894 +347228 +225617 +504813 +245320 +466007 +553931 +166731 +164885 +19090 +457262 +247806 +502895 +167593 +352491 +520 +26386 +497348 +352000 +386164 +32901 +730 +30925 +333167 +150361 +231747 +462244 +504958 +260738 +313762 +346645 +486118 +202998 +541613 +183884 +230245 +83172 +126638 +51844 +421673 +118625 +377723 +229427 +371326 +104345 +361687 +114246 +397354 +104137 +120850 +260516 +389168 +234555 +26348 +78522 +409784 +303024 +377949 +69887 +546983 +113736 +298197 +476810 +137315 +376321 +410337 +492905 +119785 +158167 +185930 +354061 +106563 +328452 +506587 +536517 +480173 +570688 +376441 +252127 +247720 +132554 +41923 +400317 +170041 +151938 +198650 +6437 +49091 +221820 +455966 +309859 +300659 +15850 +388014 +253386 +65415 +238228 +548882 +302155 +93483 +371869 +397287 +315249 +360564 +448410 +21382 +477474 +144862 +517515 +230190 +322353 +231568 +14940 +132719 +498942 +182469 +113720 +168890 +94852 +246077 +117535 +52596 +419116 +522020 +255338 +125228 +564332 +106375 +249534 +220915 +177758 +293057 +222430 +196878 +554980 +375606 +173081 +84936 +418907 +562229 +457616 +125700 +66038 +239274 +574110 +305540 +98431 +167347 +53345 +438481 +286010 +5569 +343606 +168898 +191301 +236338 +291394 +715 +520237 +236954 +192212 +524002 +471625 +476029 +413124 +203455 +483328 +476417 +114389 +372428 +369221 +322654 +388157 +561314 +264540 +418680 +359540 +426182 +521613 +92248 +74478 +398905 +554273 +125909 +430583 +418959 +503522 +382999 +403145 +536375 +352618 +108193 +279696 +163253 +439007 +204536 +552186 +269926 +372147 +399921 +201418 +240565 +471483 +91619 +393971 +331648 +385856 +567440 +81922 +391722 +372894 +535997 +134096 +545958 +239943 +186929 +34222 +177714 +277812 +197111 +281878 +532003 +557172 +142890 +196116 +385454 +322845 +374987 +123137 +255112 +111207 +304819 +523526 +336046 +42893 +241273 +240049 +90659 +271364 +408008 +253282 +167067 +354278 +178317 +229653 +93333 +163666 +566920 +495199 +100329 +218119 +558864 +257382 +406152 +206587 +420339 +325919 +278853 +555763 +293200 +151000 +209664 +79380 +197177 +353953 +464522 +392260 +46144 +154202 +164366 +206025 +511236 +24921 +497907 +393226 +318138 +364125 +157321 +492395 +187857 +109939 +441500 +144251 +368581 +51403 +283498 +43555 +89356 +404601 +23272 +425762 +460682 +544629 +209829 +322029 +199247 +307262 +571242 +124236 +162393 +104829 +250766 +563938 +237399 +131516 +483001 +21994 +97958 +540187 +264497 +384808 +343187 +51277 +6712 +566103 +435384 +292082 +359039 +165157 +267972 +263796 +489313 +392722 +541924 +554433 +571034 +146112 +201934 +518716 +64116 +294992 +289586 +159970 +479617 +269006 +140465 +513260 +554805 +6579 +452696 +34445 +548296 +372983 +509656 +199339 +130030 +128372 +449454 +139306 +247914 +99024 +499134 +536653 +468917 +412813 +404338 +215303 +455414 +413497 +574988 +397117 +188631 +378701 +241867 +143129 +419884 +412749 +496954 +317732 +16977 +398309 +162363 +147576 +100016 +209018 +92660 +173302 +525732 +449198 +99734 +12733 +172946 +168032 +210988 +340697 +4795 +534887 +483553 +278323 +178175 +190095 +357542 +230432 +227460 +334609 +562121 +378126 +555357 +325666 +451859 +526837 +531710 +297249 +294839 +499785 +254976 +527220 +173057 +11760 +163012 +215998 +114420 +57812 +563712 +513887 +201859 +36333 +291990 +338375 +460621 +518889 +337502 +133050 +80172 +537007 +295270 +335644 +227852 +336044 +204137 +82259 +165675 +295713 +343937 +442567 +356002 +346932 +62985 +180925 +525381 +13081 +377406 +159774 +462643 +359105 +185821 +390201 +84168 +128059 +80340 +481159 +491902 +306619 +353807 +390569 +541562 +292616 +64621 +439224 +96288 +449798 +160927 +496324 +90778 +126145 +97230 +572767 +11570 +539075 +350988 +3779 +208135 +551315 +216449 +169606 +502 +67765 +281414 +118594 +146127 +543985 +124927 +471394 +385508 +373783 +501315 +140974 +42757 +527054 +202387 +513056 +329931 +153973 +510152 +520812 +534601 +131282 +386638 +508538 +234779 +229329 +396568 +153568 +229478 +153574 +356299 +436694 +324139 +299409 +212462 +478155 +393266 +117836 +190760 +213605 +196 +444382 +445211 +363845 +433277 +521141 +464786 +169076 +301402 +4495 +177258 +328962 +183757 +452966 +416059 +113233 +559417 +280678 +481398 +328372 +234910 +30667 +343062 +383046 +370953 +258089 +404229 +456931 +535183 +300867 +60507 +262672 +7288 +81100 +575395 +539951 +347848 +437594 +352005 +14941 +196453 +528386 +466939 +482187 +293468 +494077 +217285 +362951 +435751 +411480 +517315 +480015 +60610 +353001 +376442 +430265 +478338 +303069 +525344 +437331 +389315 +8179 +31981 +313872 +330920 +515465 +258905 +142249 +323128 +389699 +565012 +124636 +488693 +376608 +309424 +370596 +261940 +39871 +226984 +152866 +515050 +116861 +412876 +120411 +550452 +565273 +273791 +181466 +183155 +293505 +336113 +569997 +303738 +331049 +147030 +74058 +198176 +23991 +198841 +79816 +85183 +261535 +566756 +386291 +318200 +569849 +57429 +36049 +420827 +519271 +24391 +172087 +158795 +133002 +522198 +133698 +499365 +79261 +258860 +457718 +179948 +421875 +558073 +206684 +529762 +456756 +65773 +425722 +53102 +294264 +416730 +38574 +176275 +404297 +127494 +242060 +272212 +189244 +510861 +421370 +208516 +206431 +248457 +39502 +375087 +130839 +308730 +572453 +263474 +544611 +255708 +412604 +390094 +578131 +234463 +493563 +9450 +381914 +148999 +32300 +423576 +569758 +347253 +92939 +112212 +13923 +39472 +363736 +289659 +269949 +88349 +188522 +488915 +129054 +573823 +316000 +440562 +408818 +539302 +199575 +122300 +340047 +322816 +472878 +313922 +228071 +265648 +400166 +169166 +10040 +125245 +148766 +31281 +172599 +431067 +208236 +441824 +175611 +15148 +431199 +521587 +50025 +443139 +349822 +515056 +27530 +571970 +82367 +7115 +424333 +157601 +537506 +447187 +115182 +547597 +5586 +143040 +31650 +196336 +279818 +206273 +403104 +514248 +243190 +558642 +548246 +16848 +391539 +89614 +284589 +191314 +259452 +208380 +209441 +465463 +385005 +321385 +223569 +11727 +87574 +566470 +210890 +323598 +427193 +425676 +401240 +94021 +259571 +447553 +456053 +84693 +14278 +119995 +234595 +408696 +136271 +143560 +357578 +28071 +36561 +157102 +293789 +392251 +356622 +180274 +48320 +475779 +301326 +100977 +413551 +574010 +404479 +80725 +552221 +575441 +197424 +124601 +215633 +359546 +25386 +73199 +334466 +156572 +124614 +34121 +460049 +327623 +441695 +292488 +476514 +464018 +348571 +113413 +125208 +129690 +446218 +493761 +383413 +460390 +343149 +374041 +525211 +451263 +333683 +385194 +107427 +102872 +517249 +475879 +575755 +147787 +297180 +343774 +112437 +142240 +384503 +511111 +51089 +145408 +143582 +408138 +162858 +71850 +126925 +222781 +314616 +425609 +203928 +337563 +223300 +52644 +272566 +232597 +374430 +469075 +267164 +265851 +28134 +308889 +465795 +47263 +233727 +42 +493117 +124621 +533378 +361259 +458750 +429033 +383289 +490927 +520964 +174420 +64425 +378859 +401850 +281475 +46508 +205300 +280736 +110961 +230679 +151956 +321497 +73665 +488736 +165353 +365983 +556230 +21465 +581226 +448861 +3793 +347335 +150726 +75319 +2521 +285894 +133876 +104589 +346013 +63516 +83656 +491515 +326256 +49942 +28508 +475413 +270222 +235839 +48554 +327777 +111179 +507171 +425973 +449490 +205239 +82375 +459575 +432300 +91885 +340922 +270239 +195894 +121417 +344831 +439651 +232148 +391688 +480793 +534275 +260823 +469294 +8688 +255654 +191300 +383464 +81594 +21240 +478077 +517596 +555953 +294119 +402234 +459500 +564280 +106849 +167501 +98328 +267411 +145512 +272599 +50054 +414156 +161129 +418226 +11796 +502090 +390350 +440500 +240727 +104406 +163682 +437910 +143767 +358901 +527631 +500543 +28377 +231097 +227985 +556703 +421566 +73201 +478393 +280347 +15497 +131969 +515760 +295440 +462527 +42147 +120007 +212895 +425361 +454143 +5758 +366782 +213932 +229848 +458861 +132791 +476664 +150365 +343038 +529649 +180515 +499810 +329041 +15660 +419228 +396295 +502644 +321085 +245049 +34193 +217323 +446455 +528046 +375573 +15802 +147448 +407291 +84000 +280891 +150487 +510606 +163025 +249964 +126123 +233771 +118507 +97278 +357386 +23121 +10580 +2153 +176017 +371472 +373289 +173908 +296797 +334083 +301107 +577522 +125404 +278359 +575032 +273002 +266371 +108315 +255633 +503490 +250051 +143927 +117407 +198271 +447043 +329789 +399991 +458388 +87489 +228411 +494634 +260802 +454161 +446322 +231079 +438373 +395665 +244539 +212427 +356660 +347276 +183287 +498374 +21167 +544522 +418533 +288493 +245660 +406103 +406976 +367313 +455555 +117337 +384465 +185697 +160393 +463825 +276852 +181462 +176288 +452816 +102497 +54277 +225791 +361046 +197278 +9857 +227736 +398992 +55868 +170914 +181677 +467803 +560470 +264599 +540372 +559442 +201207 +137227 +267643 +355471 +245431 +555669 +344498 +84783 +193474 +102411 +401860 +119469 +448786 +449990 +568082 +340472 +307573 +231828 +307547 +82052 +15140 +493612 +503972 +386592 +473219 +495557 +159440 +355869 +311531 +209733 +240119 +415048 +296098 +249482 +15663 +151432 +263011 +488539 +463913 +502798 +174276 +495613 +407861 +229304 +146742 +545039 +161202 +295134 +162144 +453317 +52759 +335201 +222903 +20333 +559550 +336049 +346140 +491223 +306611 +102746 +455355 +449921 +477288 +77821 +289712 +452663 +147758 +129571 +490869 +345961 +94501 +160394 +432993 +178796 +372494 +316323 +383435 +194940 +74583 +148911 +518027 +431827 +32724 +158548 +227227 +500330 +54679 +321024 +471175 +252074 +476569 +573258 +337247 +294373 +558661 +148898 +563267 +163112 +411968 +193565 +455210 +349344 +337160 +160456 +255158 +553678 +123843 +549687 +381968 +579471 +100604 +379841 +357526 +197263 +14756 +412639 +210915 +47204 +539251 +166255 +490199 +260363 +91654 +170550 +187888 +97362 +285418 +176993 +292741 +361901 +296988 +223496 +493753 +114907 +151358 +316534 +472509 +499802 +348519 +347747 +58851 +104790 +396779 +130528 +2255 +19624 +526800 +233950 +505945 +131207 +290750 +114090 +196665 +8708 +134688 +394715 +115088 +492196 +530099 +518729 +291572 +421457 +445365 +78929 +415461 +551796 +210002 +207913 +344878 +303893 +149196 +353275 +122413 +553361 +519132 +467135 +431439 +17089 +322119 +228214 +35062 +105689 +366141 +285651 +60409 +472671 +401446 +492846 +21023 +421952 +374100 +265200 +506628 +62298 +243626 +212122 +350648 +409921 +428140 +399212 +388267 +198921 +429246 +202040 +570001 +261346 +61171 +131815 +455448 +82696 +554607 +102174 +386803 +188421 +191846 +209898 +380117 +321064 +119617 +188651 +132210 +244299 +174072 +542910 +378334 +118405 +543347 +183657 +581180 +395289 +64760 +265584 +29573 +493720 +94795 +315601 +416596 +260106 +244019 +463884 +579468 +112085 +300972 +238528 +382542 +57672 +165298 +46889 +289497 +337180 +481252 +7913 +432150 +288161 +403758 +257336 +565331 +346589 +270785 +205670 +231580 +508580 +98871 +239997 +554579 +160057 +404922 +78771 +380756 +171199 +148077 +22892 +145378 +26967 +235200 +176007 +90349 +554377 +189744 +257053 +270515 +66508 +113890 +291983 +558927 +420916 +140908 +58384 +438226 +575776 +106935 +40602 +468993 +494810 +210408 +365685 +483722 +39430 +258793 +272615 +51476 +189919 +443887 +391648 +422670 +445135 +198959 +405529 +459757 +465489 +81827 +262576 +408289 +309237 +76249 +460091 +512630 +45959 +280320 +200492 +404652 +48475 +18480 +457097 +65889 +162256 +265950 +520752 +299082 +51500 +499313 +104906 +35438 +167647 +7274 +387824 +242139 +173166 +399830 +12014 +510642 +154053 +67785 +78170 +514118 +87998 +52703 +203539 +534533 +85926 +274438 +401653 +458790 +509262 +144481 +387515 +246649 +503207 +235131 +501531 +62025 +43286 +272323 +326128 +561889 +167529 +171067 +50778 +301282 +469719 +509388 +480317 +379055 +546428 +192763 +445602 +420882 +232790 +174332 +232865 +292822 +511145 +119502 +312591 +110330 +281353 +116244 +58778 +428079 +64902 +520840 +232054 +473214 +572574 +296684 +351590 +217997 +178761 +71618 +226496 +285212 +381195 +499903 +232849 +468997 +345559 +503097 +578570 +396404 +405223 +578752 +403500 +188958 +504498 +491623 +462929 +525762 +395550 +574227 +240751 +169356 +524694 +40886 +571635 +487774 +86220 +95677 +268987 +502599 +155270 +103855 +125100 +241355 +220214 +391774 +110618 +154587 +134483 +458781 +360877 +465963 +194595 +346934 +127153 +188078 +553869 +102665 +400547 +33759 +42779 +397587 +140295 +151807 +549136 +470288 +89738 +328368 +546934 +164255 +563683 +399988 +360951 +217303 +326781 +546133 +135399 +94666 +330037 +569839 +411070 +497466 +404805 +417854 +318442 +255036 +457230 +346863 +307438 +370448 +5124 +152582 +38118 +12179 +58462 +308420 +329456 +74920 +250368 +186428 +556073 +111806 +361244 +80273 +230964 +156754 +503101 +75173 +389404 +195538 +88848 +286018 +245481 +140929 +533721 +268378 +70048 +315467 +46269 +372807 +192403 +387328 +163033 +481314 +65306 +192529 +321107 +112232 +441216 +412399 +565391 +220670 +61471 +463290 +346707 +67587 +147624 +13031 +396754 +278601 +439426 +42834 +281829 +376209 +353148 +556562 +97579 +217989 +319530 +82551 +235319 +431799 +53892 +52853 +54533 +88897 +225093 +386777 +546742 +273684 +413900 +245447 +577995 +16249 +188414 +485142 +199602 +89258 +109679 +502397 +14494 +13632 +51674 +244999 +305050 +455956 +426795 +560700 +327306 +410301 +343803 +539422 +156740 +527845 +100582 +9941 +466585 +61515 +231895 +157052 +41271 +148128 +141172 +320232 +78565 +539883 +391300 +365182 +322194 +116517 +323496 +473783 +519874 +440706 +361587 +265153 +329946 +342814 +32258 +153510 +194555 +309317 +245006 +300303 +97767 +218224 +370170 +290477 +207178 +456730 +209480 +513775 +199516 +581542 +32524 +416337 +96241 +506279 +422893 +248911 +509855 +355183 +201220 +234914 +333436 +68198 +429074 +328430 +160531 +467854 +280688 +140661 +349525 +267315 +565543 +313162 +25751 +232574 +560358 +505213 +494427 +160308 +287335 +99182 +413260 +558808 +290839 +122954 +229221 +192007 +243189 +117645 +552824 +366111 +102056 +356949 +566298 +97899 +422545 +343769 +13127 +179273 +104486 +37660 +304099 +517570 +20207 +36484 +36492 +155974 +107257 +534019 +522371 +222825 +96183 +509227 +302260 +95078 +280918 +367582 +317033 +347982 +73209 +290521 +187243 +425151 +483723 +573796 +187249 +144114 +132992 +35887 +546067 +426532 +45626 +461805 +129989 +541478 +485489 +578498 +485483 +144784 +248224 +372362 +92050 +423519 +473118 +177207 +105455 +276434 +157767 +384335 +509497 +338191 +224010 +327388 +96988 +43376 +67867 +320743 +555197 +104453 +14439 +512194 +396387 +252559 +108953 +461262 +66320 +97946 +238065 +306139 +572408 +577864 +81004 +464526 +89378 +193389 +259049 +85665 +381134 +412419 +308947 +557510 +502084 +288290 +254609 +188752 +439525 +13980 +140513 +240173 +305268 +38678 +394050 +402926 +364079 +159260 +293034 +55429 +289640 +291028 +211120 +48050 +93887 +361029 +486026 +388374 +207803 +540174 +530630 +430359 +36420 +120099 +199764 +492911 +84498 +200882 +139843 +4975 +421209 +259513 +520324 +211317 +236457 +419344 +3867 +287846 +50434 +26624 +507235 +16238 +103705 +497555 +440060 +175825 +245460 +308276 +178535 +391735 +206391 +201550 +400945 +194634 +262360 +554142 +407574 +225225 +246057 +498627 +486172 +226571 +461751 +459733 +345869 +503841 +286460 +45644 +22861 +285599 +580284 +569565 +286778 +150024 +542101 +484075 +538153 +20470 +128034 +544120 +357109 +450728 +550968 +326230 +558809 +76334 +555387 +47121 +523978 +11081 +378134 +116279 +364884 +488250 +551957 +322824 +545564 +255573 +286327 +355453 +361933 +434897 +32597 +226761 +166482 +557564 +208166 +232115 +283520 +137395 +555894 +103509 +174284 +458313 +316147 +344059 +370701 +548930 +89894 +373662 +572095 +19324 +574411 +45746 +480122 +63950 +92339 +201111 +157053 +401539 +427956 +339099 +274651 +159537 +556101 +323399 +564337 +514915 +556025 +66427 +322357 +173737 +369128 +420230 +45176 +509675 +374677 +272311 +109797 +384723 +383678 +453040 +91080 +301634 +533003 +40361 +221605 +216228 +104002 +161011 +146123 +214421 +496252 +264948 +9759 +138856 +316189 +145734 +50411 +325157 +259099 +516856 +529668 +135976 +467130 +367433 +385598 +520933 +102805 +30066 +436696 +216837 +380754 +350457 +126974 +565374 +73832 +214703 +110501 +380609 +135872 +140231 +251816 +133836 +398866 +230362 +426815 +2240 +51484 +546325 +224093 +221190 +525024 +238806 +99908 +165795 +109146 +537727 +496571 +183803 +211175 +433845 +168692 +526394 +368402 +256309 +468972 +139169 +398440 +171678 +547341 +64332 +533589 +483249 +406000 +330348 +439188 +572886 +252829 +242724 +139127 +404568 +45809 +52257 +458727 +334509 +559665 +60992 +290896 +503106 +27972 +536891 +410855 +31202 +457882 +403315 +87399 +395291 +322141 +226377 +202799 +420826 +553034 +212077 +97693 +266370 +101656 +504142 +342933 +87567 +342060 +268854 +437028 +20175 +198625 +405047 +382374 +338291 +403975 +527906 +322429 +545550 +140043 +107389 +74059 +315621 +110138 +78381 +295576 +494438 +106335 +472349 +15818 +162358 +366484 +44604 +66524 +118606 +366873 +270721 +556478 +350789 +298628 +163314 +262800 +459428 +491725 +285421 +406332 +498280 +34535 +524282 +315744 +226592 +218294 +459141 +242034 +114164 +293733 +248242 +452881 +441496 +54358 +177489 +372861 +349489 +483941 +572802 +356494 +193875 +146570 +58253 +21338 +6220 +341933 +533368 +1818 +428248 +293026 +227656 +193021 +326938 +512966 +226020 +343059 +249720 +540106 +375278 +300023 +126512 +517135 +472540 +361439 +132702 +503294 +109537 +540669 +332007 +245266 +313999 +10386 +225715 +311567 +103837 +302405 +248616 +102654 +155087 +124756 +379659 +569272 +160166 +428234 +422280 +174425 +133412 +174503 +216581 +345063 +52949 +69536 +216161 +272728 +200870 +120792 +193480 +493923 +445567 +558539 +51938 +422706 +416271 +244160 +437898 +327352 +305480 +349459 +522418 +485219 +225133 +361400 +546569 +190015 +348216 +421822 +457683 +178683 +40894 +234526 +465074 +518725 +168096 +210190 +139605 +35195 +463640 +286770 +141651 +112022 +532552 +325327 +227224 +17272 +84163 +331475 +126065 +289309 +8583 +52952 +189427 +579693 +437947 +187565 +215982 +356424 +453731 +463522 +372316 +251797 +70187 +280515 +556608 +341635 +391067 +469480 +476298 +57917 +146672 +122747 +394328 +12209 +80013 +573291 +278449 +129659 +579560 +557190 +227468 +334782 +51157 +23774 +9426 +86582 +39211 +275751 +131597 +51250 +357255 +9041 +346482 +9647 +157019 +409016 +273416 +114414 +298172 +388854 +275025 +58079 +518034 +503518 +146710 +120632 +474680 +303713 +259097 +479630 +208318 +437298 +173704 +361831 +371638 +344279 +230175 +72507 +417980 +72621 +163057 +92894 +543525 +577364 +263696 +472732 +66027 +391584 +197745 +131019 +65604 +91318 +535934 +212646 +576354 +482071 +160556 +120129 +7260 +344881 +447548 +318193 +30383 +527002 +34904 +35677 +526222 +105261 +401897 +399452 +25660 +524595 +384512 +117543 +514600 +268944 +112664 +222340 +569058 +495332 +192153 +75591 +286711 +174888 +577065 +25508 +169972 +401820 +425475 +290700 +173091 +559101 +122418 +244124 +198645 +325519 +276437 +528276 +146614 +45574 +417804 +326420 +250594 +27353 +310407 +370103 +274957 +561160 +167598 +397166 +257458 +404546 +148392 +373396 +62230 +493522 +563665 +274240 +269815 +79024 +527427 +84674 +486788 +267690 +443347 +149304 +412285 +207041 +412916 +10764 +151338 +299000 +17882 +475510 +398188 +558213 +70493 +180779 +347210 +280211 +58146 +379022 +504125 +537604 +464858 +329573 +568623 +228309 +454444 +552775 +557884 +435671 +168706 +142257 +571437 +574845 +387773 +321008 +574208 +405811 +375426 +321887 +256852 +433554 +517029 +125870 +80395 +497139 +490008 +405279 +571857 +225738 +514913 +456239 +499402 +96440 +487607 +370999 +319617 +370233 +60760 +352703 +478575 +84170 +134112 +77689 +185036 +73738 +547502 +104782 +213276 +136908 +436273 +442149 +355000 +374061 +249884 +105711 +136464 +146997 +76351 +388487 +99115 +124135 +24721 +132931 +1149 +182403 +386089 +81691 +480657 +441522 +60989 +268000 +55840 +514321 +577959 +359638 +457986 +533596 +60332 +367082 +772 +535842 +473541 +270677 +409009 +259216 +302318 +117036 +331372 +231125 +384486 +405214 +20760 +579760 +172995 +359110 +83110 +410068 +109916 +328757 +299261 +19028 +515660 +40757 +10256 +442695 +553097 +185903 +74388 +425120 +241326 +299609 +29397 +328728 +283881 +344029 +367336 +27075 +163628 +127263 +488979 +460147 +473050 +405762 +221547 +131581 +561187 +406489 +140696 +452721 +530466 +118965 +398803 +218365 +298738 +19441 +521550 +120157 +498687 +4754 +365866 +70865 +235156 +133386 +142742 +221183 +262391 +567053 +520982 +121349 +448779 +440354 +3983 +578993 +519691 +160703 +103307 +300408 +137106 +488377 +523660 +318022 +132578 +302520 +153040 +408817 +145227 +311190 +159662 +202923 +256775 +359864 +384848 +336404 +185303 +421703 +362682 +464622 +246590 +422729 +165500 +42563 +219216 +520232 +95063 +265547 +532686 +290558 +112591 +448211 +315281 +545475 +225850 +232460 +82740 +272880 +347254 +122047 +352151 +541486 +97249 +200252 +544782 +499571 +379014 +303534 +479909 +305464 +323682 +181524 +273855 +190783 +567801 +119752 +241503 +536429 +327323 +128756 +349868 +500495 +372260 +315824 +484986 +364993 +124759 +300124 +329319 +68628 +14549 +121897 +506595 +115709 +199610 +230150 +31717 +139549 +222332 +534161 +360393 +541664 +507167 +286523 +158660 +66926 +195750 +80022 +589 +252220 +47255 +247014 +49881 +455005 +232453 +445722 +516805 +544122 +541917 +469356 +370042 +130522 +502163 +307866 +408894 +524247 +52233 +177861 +348881 +357943 +295303 +475389 +431691 +61316 +143998 +503483 +340155 +488785 +133636 +133567 +251627 +470095 +34873 +88815 +261178 +468612 +127477 +157960 +15687 +303089 +572331 +456708 +190515 +126131 +239194 +332074 +129765 +107167 +478184 +421833 +359715 +112440 +331317 +74492 +505386 +247839 +534210 +134503 +422700 +352111 +98674 +546219 +520508 +503008 +461953 +101913 +362092 +22103 +359128 +316666 +335579 +414750 +297980 +365652 +53635 +547601 +97589 +570515 +7125 +99828 +321437 +80671 +426275 +294883 +212605 +424293 +338108 +25005 +6949 +234291 +428399 +7149 +343076 +575287 +431848 +307611 +293909 +542511 +564739 +573843 +356878 +472864 +336793 +121904 +161060 +254004 +269873 +216428 +77172 +346517 +498555 +203690 +348973 +117704 +552672 +275270 +208107 +314016 +427518 +278134 +53420 +318777 +238980 +350614 +467315 +61233 +272188 +550797 +125051 +553965 +187286 +282912 +102532 +156076 +467848 +130875 +531585 +523470 +507684 +332582 +438989 +489209 +125944 +127474 +371957 +570349 +283286 +541635 +547106 +253630 +388677 +572525 +542302 +554537 +367205 +228300 +443498 +356432 +123946 +490441 +211063 +224542 +116574 +434510 +33116 +353136 +134167 +128291 +542510 +433963 +147453 +365766 +374806 +336600 +38238 +165476 +535578 +127788 +157099 +173640 +114348 +496722 +58141 +467296 +235864 +5154 +22775 +422536 +136820 +453438 +446359 +41990 +422240 +39267 +391392 +233825 +308504 +478250 +87328 +4079 +127074 +267709 +377635 +353231 +185768 +487897 +124215 +249757 +341681 +557552 +280733 +374734 +281601 +456420 +222266 +491947 +432732 +467157 +94025 +410328 +428291 +397639 +163528 +234697 +557573 +208363 +515962 +358658 +373075 +438995 +425672 +450169 +216103 +254638 +288591 +53626 +43417 +372252 +5038 +218357 +120860 +399349 +485509 +530261 +477087 +352302 +96075 +495443 +133928 +197175 +134074 +212553 +448181 +152000 +254277 +105734 +75481 +343662 +479350 +554347 +71090 +297426 +22176 +277622 +469235 +163041 +221272 +154263 +89296 +68411 +192871 +183217 +258141 +53058 +540529 +566414 +560948 +254535 +246076 +135972 +420069 +431023 +343643 +32682 +515176 +222635 +377155 +547041 +513283 +26017 +366096 +252133 +138078 +25685 +321798 +549361 +14088 +423048 +570810 +374974 +447501 +492544 +554046 +575357 +420791 +6019 +340451 +66800 +565575 +148055 +330432 +483038 +455004 +288765 +11034 +86988 +347142 +450559 +543581 +293757 +556901 +533032 +333020 +260266 +22420 +13948 +512657 +214124 +231236 +177149 +560879 +491793 +35767 +312878 +118542 +450596 +423773 +48653 +224523 +509577 +462677 +75405 +350023 +452122 +42008 +302555 +382309 +468483 +368684 +372580 +31333 +153697 +124876 +330023 +315672 +53990 +136533 +82815 +356836 +414821 +268717 +7333 +77544 +525373 +371042 +227048 +576327 +419309 +239773 +8119 +424135 +297425 +222711 +489909 +393995 +31019 +539326 +517612 +102461 +199989 +483374 +44952 +103863 +528980 +441543 +85381 +247234 +50924 +483994 +87456 +424271 +356091 +534669 +378831 +560662 +298773 +257896 +498274 +305800 +40517 +183949 +276840 +84442 +297620 +298252 +119088 +233315 +283977 +345154 +287649 +427311 +63399 +4700 +463611 +224104 +209388 +431655 +364190 +28864 +412455 +283290 +228541 +422200 +985 +133596 +323853 +503081 +130732 +224675 +199688 +230862 +21396 +485390 +1532 +125778 +235541 +370478 +522478 +514292 +384338 +531707 +178746 +532747 +62915 +519491 +140691 +112093 +358024 +263687 +297595 +506085 +102446 +325768 +29558 +222054 +466965 +316254 +546500 +216785 +194184 +464390 +348371 +231582 +208995 +464339 +308856 +340946 +214604 +570586 +182227 +248441 +89078 +376310 +73450 +115924 +308235 +15994 +8749 +429679 +37751 +122040 +284286 +388707 +248163 +11320 +427997 +282062 +237600 +376751 +223314 +86215 +12443 +163255 +564940 +462640 +522713 +306303 +460675 +126833 +26201 +224757 +357899 +546782 +96427 +480944 +479556 +569273 +520528 +190690 +344832 +462466 +270354 +559776 +279259 +280909 +227781 +163798 +491098 +439658 +416088 +107375 +74132 +379800 +511654 +346687 +226161 +578849 +544272 +146149 +570624 +178299 +126671 +356380 +530766 +175954 +158798 +422095 +55780 +512276 +560626 +187329 +513125 +347216 +306486 +161840 +180917 +188192 +421437 +93120 +324891 +252216 +488476 +578347 +101959 +10693 +170038 +213586 +210439 +469202 +381463 +343248 +127785 +287328 +538690 +16382 +293022 +112378 +435785 +56092 +381504 +284365 +406129 +233119 +53629 +188509 +191053 +81056 +82252 +538319 +38439 +181948 +439710 +529344 +434035 +342958 +563882 +37734 +364743 +330986 +546226 +463211 +62210 +442724 +232241 +293858 +119345 +61953 +577033 +522015 +381587 +350107 +4936 +511307 +228771 +177811 +231450 +176168 +84540 +259408 +264238 +539738 +255827 +459382 +221105 +431742 +204337 +227741 +336356 +37655 +167159 +59352 +165937 +53956 +378712 +88462 +495786 +542938 +566498 +367228 +157577 +442661 +62363 +390689 +480664 +521540 +414249 +20571 +160855 +451683 +156832 +570045 +326542 +568276 +568717 +563311 +113579 +218268 +546095 +160661 +341118 +150649 +462632 +198972 +220025 +61720 +430681 +524011 +457217 +40064 +285583 +314493 +78023 +470882 +298722 +555597 +489829 +314779 +367818 +138503 +243737 +580255 +444565 +386677 +190841 +493074 +234347 +466988 +227033 +519039 +351554 +390585 +443303 +140983 +81079 +538005 +169757 +368780 +457322 +341804 +409116 +181805 +284292 +551358 +344548 +503569 +336587 +417055 +522315 +58705 +148955 +375530 +474934 +577893 +28881 +360772 +445267 +244737 +355777 +72811 +190788 +54513 +243075 +518551 +487530 +292169 +69293 +397303 +129285 +429996 +109532 +53802 +340573 +91280 +535602 +270908 +381925 +549220 +488573 +47131 +32735 +117525 +279085 +43961 +188906 +394677 +395 +185201 +189365 +127596 +32712 +504810 +3703 +182874 +146981 +306755 +453093 +520503 +169808 +225670 +91063 +348584 +461802 +572555 +185922 +131497 +46736 +536006 +256505 +214975 +13445 +350736 +98115 +50304 +361180 +511333 +564820 +429717 +222500 +40083 +538230 +349438 +371250 +528578 +240418 +302380 +261758 +535809 +308388 +578878 +509451 +46919 +562592 +499950 +90374 +318146 +195353 +355325 +314515 +237277 +203024 +238911 +32039 +145591 +16030 +135411 +229350 +421757 +48034 +183704 +307292 +97974 +275999 +448256 +451915 +119113 +143503 +494141 +50124 +306553 +35526 +255279 +560908 +247264 +367599 +192782 +511324 +574350 +67569 +204360 +111907 +2839 +513971 +245201 +185240 +339468 +540101 +539673 +194425 +22168 +520150 +301595 +96006 +68286 +131280 +356662 +182441 +284749 +107108 +49761 +386718 +55244 +187990 +248678 +147721 +425727 +360350 +310797 +76765 +400489 +247639 +279864 +44699 +356145 +69138 +445041 +560598 +165464 +536343 +7818 +322831 +334760 +451463 +348730 +285967 +286353 +201887 +166165 +359 +465591 +519359 +550444 +402711 +3661 +132706 +534983 +306281 +150317 +15978 +580029 +496090 +267127 +210980 +384015 +222559 +2235 +255649 +278168 +440840 +27326 +202562 +230268 +362712 +1573 +107661 +464515 +373132 +447242 +547440 +43613 +200143 +260883 +250901 +64693 +408480 +204757 +319933 +147471 +381332 +518197 +27656 +260257 +434580 +159203 +568630 +497441 +499597 +60179 +574804 +343254 +501762 +220704 +524536 +86946 +456046 +62937 +49633 +144305 +475593 +478553 +574145 +63648 +3794 +303177 +1340 +82835 +371427 +156747 +448694 +219567 +75095 +242615 +492077 +132776 +199125 +349622 +195754 +455548 +181873 +138185 +338044 +362797 +180953 +505826 +69773 +304834 +162580 +154090 +519853 +319687 +132328 +27969 +52166 +100547 +568131 +415218 +348045 +478159 +402869 +10211 +26547 +551692 +105432 +313340 +182348 +383419 +570947 +345353 +226883 +255784 +214199 +262262 +283261 +449708 +299970 +392391 +245997 +330410 +343571 +519542 +37470 +42144 +342521 +498537 +10935 +443860 +512648 +146099 +98599 +123932 +489861 +262895 +184700 +218587 +363581 +21001 +481404 +249356 +64240 +492349 +199236 +481064 +353405 +116479 +132024 +138768 +524665 +434511 +326970 +138784 +340368 +312081 +366615 +171942 +21232 +473850 +93686 +295574 +51054 +162692 +174091 +20070 +270066 +492816 +20904 +484500 +147140 +242972 +420081 +63563 +261712 +316396 +49413 +520787 +510955 +393840 +142487 +19817 +261180 +413736 +230619 +484614 +337011 +496575 +4338 +552545 +5601 +75426 +568863 +184227 +170629 +438567 +505132 +541353 +284674 +322567 +182423 +312051 +18896 +40471 +321725 +188850 +37119 +95569 +187362 +397133 +528972 +487131 +174989 +370325 +223554 +385633 +103485 +537574 +63240 +256566 +86467 +401092 +486968 +308441 +280017 +527464 +131965 +310479 +125556 +220160 +532963 +310052 +107963 +293841 +388534 +45603 +368949 +391825 +5107 +569705 +231549 +250108 +152933 +206433 +358817 +434006 +283904 +152808 +539975 +24629 +410231 +13465 +502318 +51961 +445594 +209062 +38726 +295420 +430079 +240147 +561512 +35795 +102589 +505619 +565469 +271772 +520561 +372300 +178807 +492805 +1083 +303704 +125635 +217521 +278032 +208688 +335325 +140435 +313990 +143822 +320857 +549230 +76844 +424219 +463876 +243199 +2988 +215170 +30012 +377738 +408568 +490624 +404839 +138316 +157206 +404461 +122934 +263346 +21327 +99913 +67975 +339676 +391891 +365305 +337055 +233834 +125524 +46869 +32577 +304744 +104176 +167356 +210404 +307989 +217223 +196046 +454414 +16356 +244487 +543660 +197461 +199681 +476787 +455085 +307074 +260547 +107468 +334769 +29437 +166837 +53838 +502979 +82678 +288860 +535523 +311950 +237723 +98656 +223123 +273930 +58057 +544334 +324857 +198043 +535326 +316505 +12991 +576820 +43611 +107839 +275749 +456695 +78188 +375786 +466239 +184830 +537128 +434513 +244344 +374576 +69140 +434247 +555009 +510857 +220819 +20598 +99416 +74967 +533129 +515577 +213361 +330974 +548848 +431557 +503278 +130043 +402570 +320554 +559884 +252629 +364596 +423484 +271230 +105552 +143143 +285751 +49994 +204162 +80646 +381393 +123415 +118417 +30932 +425412 +388130 +551243 +468337 +484893 +25014 +174390 +463781 +124647 +60823 +361964 +425702 +575110 +532390 +230881 +84592 +189997 +221307 +361472 +32364 +71918 +316365 +492378 +234251 +48504 +418070 +89884 +562045 +506552 +66360 +122962 +262605 +529939 +345229 +294853 +344397 +56091 +8599 +459823 +175785 +226128 +259983 +354515 +379144 +384995 +205253 +116786 +441432 +448810 +83452 +465129 +506906 +90616 +551959 +406404 +157891 +362090 +439630 +45099 +61960 +478430 +489605 +127050 +579872 +475798 +64510 +447733 +33066 +102848 +538819 +323760 +200401 +179765 +251317 +239376 +83836 +578092 +522452 +393056 +278848 +27787 +377239 +473427 +83065 +377005 +576539 +248019 +473370 +536369 +92648 +332461 +437609 +274800 +388846 +323048 +193407 +541898 +480140 +46526 +26432 +339738 +325991 +37705 +528033 +542922 +313420 +190463 +531000 +454907 +26448 +238199 +476652 +457147 +364256 +72632 +430380 +315448 +353320 +18158 +91527 +454252 +546987 +386370 +38064 +19763 +64152 +453216 +55223 +361860 +522566 +509531 +438432 +31164 +163290 +389197 +333440 +173464 +447842 +381615 +99961 +156126 +103134 +394940 +165638 +261706 +378311 +534081 +373848 +401642 +338019 +378096 +289610 +547421 +174672 +133343 +191360 +293751 +520892 +145214 +167668 +37456 +460962 +465267 +292804 +347529 +203661 +10766 +27371 +203845 +155736 +136715 +463588 +26640 +547612 +131453 +184274 +442456 +265085 +223256 +129420 +23019 +536467 +194532 +127585 +392637 +330408 +524775 +31993 +433924 +502852 +553129 +559364 +297343 +71360 +225537 +271148 +345499 +475893 +237463 +5278 +501243 +413235 +444236 +541071 +380088 +468063 +94858 +225913 +295614 +210276 +170975 +205570 +422375 +550365 +308702 +484627 +565031 +98979 +480345 +579548 +272673 +436875 +287874 +16502 +274917 +281809 +442968 +289263 +347766 +160933 +84533 +266409 +122199 +396200 +30958 +504541 +1591 +89432 +387150 +306383 +15260 +154515 +50752 +166913 +102644 +100196 +160278 +349579 +442536 +17923 +310564 +62020 +152004 +578330 +126299 +527025 +83494 +226400 +268435 +445334 +310391 +505156 +19157 +44677 +318171 +447765 +354369 +527486 +329939 +184771 +134856 +467675 +517133 +89697 +447080 +70685 +144938 +519673 +485758 +454957 +564851 +189451 +408757 +192616 +280734 +305060 +243946 +99179 +303971 +170519 +48917 +549965 +300245 +384101 +576607 +186709 +516341 +241668 +133470 +134811 +500825 +464689 +29833 +343820 +213429 +387434 +279305 +444207 +210777 +372043 +189868 +572229 +8495 +370090 +450282 +277080 +199158 +109612 +567708 +245659 +485129 +268363 +23448 +5352 +235597 +6871 +348720 +94113 +314613 +63729 +114458 +215394 +460460 +240387 +398726 +135604 +571728 +415770 +286908 +138151 +146272 +344094 +345209 +241187 +282768 +113037 +545583 +219283 +145873 +285957 +489235 +157271 +197458 +502671 +499845 +334884 +79084 +505573 +115618 +561491 +354202 +279838 +190734 +134738 +269450 +482784 +144610 +52774 +290659 +440646 +25807 +442952 +159215 +318224 +73445 +211653 +527960 +401862 +431026 +488755 +292278 +400554 +272630 +382668 +470298 +166426 +129645 +28820 +161227 +417696 +560677 +283216 +28978 +310302 +154419 +230450 +328289 +73118 +104691 +15085 +405574 +510548 +470005 +102928 +569249 +413126 +77282 +96732 +359020 +42182 +250875 +106206 +354929 +320796 +453341 +237318 +254834 +137265 +399865 +292685 +152252 +319579 +81484 +16599 +162257 +351034 +396051 +502275 +308278 +34483 +13333 +320290 +321579 +349794 +99219 +200162 +369470 +487583 +62703 +251639 +138246 +157170 +477112 +283963 +74860 +307057 +364075 +295491 +34757 +400161 +170194 +120874 +492817 +3817 +183973 +135436 +512989 +114744 +379210 +201072 +293785 +578385 +237420 +7888 +18224 +155317 +522406 +441440 +110482 +173400 +183348 +552504 +475660 +166948 +147025 +443259 +578792 +245227 +546687 +474519 +393284 +249668 +87493 +151651 +100306 +540466 +546556 +212675 +282942 +21310 +385535 +7304 +303409 +386116 +574297 +514550 +217133 +533553 +447152 +578703 +45392 +166205 +180154 +25143 +338802 +330110 +261389 +343506 +442726 +285388 +554934 +421316 +479912 +85192 +34874 +487266 +226173 +20748 +360660 +574509 +543364 +1554 +125539 +566931 +312889 +466945 +444804 +257187 +568587 +427160 +71123 +563849 +138589 +162841 +129663 +107226 +140686 +321663 +437117 +179808 +321718 +62398 +16497 +468933 +219841 +355430 +293554 +293044 +109516 +485887 +490620 +579893 +427135 +31636 +217919 +432441 +314396 +119802 +393682 +201764 +146193 +116358 +84825 +208311 +419774 +177468 +72052 +142585 +519598 +464006 +556083 +412136 +169361 +442929 +84567 +549932 +75560 +74656 +93314 +393838 +383018 +372433 +431281 +556278 +5513 +108503 +500478 +148588 +138713 +368153 +22646 +303778 +270758 +276706 +275429 +492025 +169111 +494328 +35891 +70258 +400528 +165229 +460494 +269311 +307658 +98283 +369294 +319345 +414578 +541550 +425388 +129855 +99477 +383073 +387906 +293124 +155873 +549224 +266021 +52869 +1584 +421902 +498535 +277235 +153013 +452013 +553561 +138040 +20820 +58483 +423506 +569001 +325153 +383039 +213421 +38825 +453283 +384661 +127702 +238147 +104893 +577826 +64974 +240655 +459153 +145665 +49810 +65008 +545385 +125070 +46433 +143329 +429174 +52947 +321314 +253341 +157365 +453162 +111910 +339019 +239575 +362219 +80652 +247317 +460286 +365724 +160875 +372220 +483389 +572181 +146190 +580975 +54761 +348488 +416104 +468778 +18833 +251537 +234366 +510078 +14723 +338595 +153797 +513098 +467138 +404618 +261982 +545730 +135846 +108244 +562557 +180524 +227370 +341856 +131743 +255691 +497878 +68878 +430640 +441473 +347664 +214369 +347018 +225238 +421762 +317024 +6180 +172004 +303101 +22488 +193494 +199346 +409627 +315350 +263463 +190722 +523292 +363902 +573778 +437290 +389812 +517082 +145073 +37907 +489763 +456261 +270386 +508917 +566823 +543897 +362482 +130966 +66632 +181962 +274613 +135708 +549746 +323766 +366714 +353295 +318813 +153307 +213693 +293378 +149446 +199927 +580543 +331727 +238488 +472833 +308645 +424225 +228746 +110435 +495377 +240646 +274491 +130921 +140006 +4688 +115241 +76962 +66650 +47718 +224991 +434187 +272048 +11169 +158222 +154000 +507436 +443499 +109937 +309692 +534018 +22797 +163339 +168683 +210098 +246069 +137954 +143320 +262587 +414795 +226938 +536831 +128791 +459590 +50514 +30067 +317479 +378655 +229968 +522702 +11122 +515266 +136600 +224509 +149912 +97656 +120747 +349480 +155199 +528731 +523807 +168544 +325664 +229981 +434410 +431208 +508996 +63791 +89225 +513690 +136740 +224364 +515424 +508302 +418175 +465552 +439907 +272097 +451087 +396304 +342273 +52507 +300066 +380089 +326248 +167906 +37846 +262993 +60090 +499249 +90432 +74456 +264660 +325598 +480985 +245411 +425644 +224724 +475439 +246478 +487438 +563731 +441854 +522665 +245915 +85747 +315162 +108761 +407521 +388528 +389453 +298331 +447791 +368820 +440034 +305677 +122208 +182369 +543531 +151820 +63650 +457580 +563381 +320899 +14869 +137260 +61925 +376307 +80367 +269089 +203705 +274835 +267321 +418106 +471273 +74037 +227855 +519758 +89045 +321217 +324203 +479129 +503431 +368528 +527718 +278579 +13525 +291582 +301837 +31667 +68120 +14007 +114158 +124262 +33626 +53949 +187585 +192247 +208844 +212766 +318671 +575012 +439339 +364073 +419624 +178078 +427783 +302159 +339368 +190680 +23807 +288579 +312720 +15778 +553558 +571834 +574376 +122161 +493815 +472376 +483432 +149123 +51628 +264628 +26609 +23696 +485081 +441323 +451679 +42055 +378795 +86439 +366493 +520996 +332869 +18014 +554523 +83476 +6040 +421834 +424392 +308160 +335233 +249809 +349098 +358090 +187349 +61782 +35498 +386514 +207108 +578418 +84447 +104108 +126107 +211674 +111909 +490708 +477025 +206757 +556205 +142484 +454296 +464366 +358254 +215482 +468548 +82680 +100909 +405432 +85764 +94651 +63973 +8131 +288592 +257470 +47597 +321557 +34520 +134066 +246701 +317797 +282365 +78176 +29577 +311075 +331937 +190395 +5802 +245112 +111032 +140556 +199127 +376491 +305253 +300375 +545903 +357782 +377911 +74963 +329336 +25057 +3244 +252020 +293474 +171050 +239306 +189772 +238090 +160031 +36761 +445675 +252716 +152214 +239466 +55155 +479829 +420281 +445812 +118106 +434576 +451104 +316708 +438535 +300322 +167952 +390072 +487220 +20247 +9400 +43944 +35770 +487351 +425462 +212203 +9668 +8981 +574241 +332096 +535563 +192944 +498733 +276151 +550645 +507037 +9769 +404249 +236747 +376416 +306415 +45966 +191296 +576875 +493932 +225075 +536444 +79920 +561681 +60700 +99874 +219437 +509819 +466665 +579326 +428739 +394611 +263083 +379554 +279391 +178516 +133690 +77396 +300137 +6861 +435359 +314108 +444152 +500139 +92749 +89188 +300233 +414201 +443204 +211097 diff --git a/examples/pytorch/vision/Visual_Wakeword/train_visualwakewords.py b/examples/pytorch/vision/Visual_Wakeword/train_visualwakewords.py new file mode 100755 index 00000000..0b88fe9f --- /dev/null +++ b/examples/pytorch/vision/Visual_Wakeword/train_visualwakewords.py @@ -0,0 +1,249 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +import torch +import torch.nn as nn +import torch.optim as optim +import torch.nn.functional as F +import torch.backends.cudnn as cudnn +import torchvision +import torchvision.models as models +import torchvision.transforms as transforms +import os +import argparse +import random +from PIL import Image +import numpy as np +from torchvision.datasets.vision import VisionDataset +from importlib import import_module +from pyvww.utils import VisualWakeWords + + + + + +device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + +torch.backends.cudnn.benchmark = True +torch.backends.cudnn.enabled = True + +best_acc = 0 # best test accuracy +start_epoch = 0 + +#Arg parser +parser = argparse.ArgumentParser(description='PyTorch CIFAR10 Training') +parser.add_argument('--lr', default=0.05, type=float, help='learning rate') +parser.add_argument('--epochs', default=900, type=int, help='total epochs') +parser.add_argument('--resume', default=None, type=str, help='load from checkpoint') +parser.add_argument('--model_arch', + default='model_mobilenet_rnnpool', type=str, + choices=['model_mobilenet_rnnpool', 'model_mobilenet_2rnnpool'], + help='choose architecture among rpool variants') +parser.add_argument('--ann', default=None, type=str, + help='specify new-path-to-visualwakewords-dataset used in dataset creation step') +parser.add_argument('--data', default=None, type=str, + help='specify path-to-mscoco-dataset used in dataset creation step') +args = parser.parse_args() + + +# Data + +class VisualWakeWordsClassification(VisionDataset): + """`Visual Wake Words `_ Dataset. + Args: + root (string): Root directory where COCO images are downloaded to. + annFile (string): Path to json visual wake words annotation file. + transform (callable, optional): A function/transform that takes in an PIL image + and returns a transformed version. E.g, ``transforms.ToTensor`` + target_transform (callable, optional): A function/transform that takes in the + target and transforms it. + """ + def __init__(self, root, annFile, transform=None, target_transform=None, split='val'): + # super(VisualWakeWordsClassification, self).__init__(root, annFile, transform, target_transform, split) + self.vww = VisualWakeWords(annFile) + self.ids = list(sorted(self.vww.imgs.keys())) + self.split = split + + self.transform = transform + self.target_transform = target_transform + self.root = root + + def __getitem__(self, index): + """ + Args: + index (int): Index + Returns: + tuple: Tuple (image, target). target is the index of the target class. + """ + vww = self.vww + img_id = self.ids[index] + ann_ids = vww.getAnnIds(imgIds=img_id) + target = vww.loadAnns(ann_ids)[0]['category_id'] + + path = vww.loadImgs(img_id)[0]['file_name'] + + img = Image.open(os.path.join(self.root, path)).convert('RGB') + + + if self.transform is not None: + img = self.transform(img) + + + if self.target_transform is not None: + target = self.target_transform(target) + + return img, target + + def __len__(self): + return len(self.ids) + + +normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + +transform_train = transforms.Compose([ + # transforms.RandomAffine(10, translate=None, shear=(5,5,5,5), resample=False, fillcolor=0), + transforms.RandomResizedCrop(size=(224,224), scale=(0.2,1.0)), + transforms.RandomHorizontalFlip(), + #transforms.RandomAffine(10, translate=None, shear=(5,5,5,5), resample=False, fillcolor=0), + # transforms.ColorJitter(brightness=(0.6,1.4), saturation=(0.9,1.1), hue=(-0.1,0.1)), + transforms.ToTensor(), + normalize +]) + +transform_test = transforms.Compose([ + transforms.Resize(256), + transforms.CenterCrop(224), + transforms.ToTensor(), + normalize +]) + + + + + +trainset = VisualWakeWordsClassification(root=os.path.join(args.data,'all2014'), + annFile=os.path.join(args.ann, 'annotations/instances_train.json'), + transform=transform_train, split='train') + +trainloader = torch.utils.data.DataLoader(trainset, batch_size=256, shuffle=True, + num_workers=32) + +testset = VisualWakeWordsClassification(root=os.path.join(args.data,'all2014'), + annFile=os.path.join(args.ann, 'annotations/instances_val.json'), + transform=transform_test, split='val') + +testloader = torch.utils.data.DataLoader(testset, batch_size=256, shuffle=False, + num_workers=32) + + +# Model + +module = import_module(args.model_arch) +model = module.mobilenetv2_rnnpool(num_classes=2, width_mult=0.35, last_channel=320) +model = model.to(device) +model = torch.nn.DataParallel(model) + + + +if args.resume: + # Load checkpoint. + print('==> Resuming from checkpoint..') + assert os.path.isdir('./checkpoints/'), 'Error: no checkpoint directory found!' + checkpoint = torch.load('./checkpoints/' + args.resume) + best_acc = checkpoint['acc'] + start_epoch = checkpoint['epoch'] + +criterion = nn.CrossEntropyLoss().cuda() + +optimizer = optim.SGD(model.parameters(), lr=0.05, momentum=0.9, weight_decay=4e-5)#, alpha=0.9) + + +# Training +def train(epoch): + print('\nEpoch: %d' % epoch) + model.train() + train_loss = 0 + correct = 0 + total = 0 + train_loader_len = len(trainloader) + for batch_idx, (inputs, targets) in enumerate(trainloader): + adjust_learning_rate(optimizer, epoch, batch_idx, train_loader_len) + + batch_size = inputs.shape[0] + inputs, targets = inputs.to(device), targets.to(device) + optimizer.zero_grad() + outputs = model(inputs) + + loss = criterion(outputs, targets) + loss.backward() + optimizer.step() + + train_loss += loss.item() + _, predicted = outputs.max(1) + total += targets.size(0) + correct += predicted.eq(targets).sum().item() + + print('train_loss: ',train_loss/total, ' acc: ', correct/total) + print('->>lr:{:.6f}'.format(optimizer.param_groups[0]['lr'])) + +def test(epoch): + global best_acc + model.eval() + test_loss = 0 + correct = 0 + total = 0 + with torch.no_grad(): + for batch_idx, (inputs, targets) in enumerate(testloader): + batch_size = inputs.shape[0] + inputs, targets = inputs.to(device), targets.to(device) + outputs = model(inputs) + + loss = criterion(outputs, targets) + + test_loss += loss.item() + _, predicted = outputs.max(1) + total += targets.size(0) + correct += predicted.eq(targets).sum().item() + + print('test_loss: ',test_loss/total, ' test_acc: ', correct/total) + + # Save checkpoint. + print('best acc: ', best_acc) + acc = 100.*correct/total + if acc > best_acc: + print('Saving..') + state = { + 'model': model.state_dict(), + 'acc': acc, + 'epoch': epoch, + } + if not os.path.isdir('./checkpoints/'): + os.mkdir('./checkpoints/') + torch.save(state, './checkpoints/model_mobilenet_rnnpool.pth') + best_acc = acc + + +from math import cos, pi +def adjust_learning_rate(optimizer, epoch, iteration, num_iter): + lr = optimizer.param_groups[0]['lr'] + + warmup_epoch = 0 + warmup_iter = warmup_epoch * num_iter + current_iter = iteration + epoch * num_iter + max_iter = 150 * num_iter + + + lr = args.lr * (1 + cos(pi * (current_iter - warmup_iter) / (max_iter - warmup_iter))) / 2 + + if epoch < warmup_epoch: + lr = args.lr * current_iter / warmup_iter + + + for param_group in optimizer.param_groups: + param_group['lr'] = lr + + +for epoch in range(start_epoch, start_epoch+args.epochs): + train(epoch) + test(epoch) diff --git a/examples/pytorch/vision/cpp/README.md b/examples/pytorch/vision/cpp/README.md new file mode 100644 index 00000000..54c4e4e4 --- /dev/null +++ b/examples/pytorch/vision/cpp/README.md @@ -0,0 +1,18 @@ +# RNNPool quantized sample code + +The `rnnpool_quantized.cpp` code takes the activations preceding the RNNpool layer +and produces the output of a quantized RNN pool layer. The input numpy file consists +of all activation patches corresponding to a single image. In `trace_0_input.npy`, +there are 6241 patches of dimensions 8x8 with 4 channels to which RNNPool is applied. +The output is of size 6241*4*8. This can be compared to the floatin point output stored in +`trace_0_output.npy` + +```shell +g++ -o rnnpool_quantized rnnpool_quantized.cpp + +# Usage: ./rnnpool_quantized <#patches> +./rnnpool_quantized 6241 trace_0_input.npy trace_0_output_quantized.npy +``` + +Copyright (c) Microsoft Corporation. All rights reserved. +Licensed under the MIT license diff --git a/examples/pytorch/vision/cpp/data.h b/examples/pytorch/vision/cpp/data.h new file mode 100644 index 00000000..bd4e5633 --- /dev/null +++ b/examples/pytorch/vision/cpp/data.h @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// // Licensed under the MIT license + +int16_t W1[4][8] = {{7069, 3262, 5513, 4733, -2708, -10109, 5233, 4489} +, {-10390, -38, -17036, -404, -1288, -138, 226, -1100} +, {1562, -1144, -14616, 4106, -18129, 2064, 831, 2845} +, {-1993, -996, -6637, -1105, -1833, 1207, -1910, -1262} +}; //16384 + +int16_t U1[8][8] = {{15238, -4081, -18973, -1468, 3401, 12650, -911, -1588} +, {-1372, -2625, 23200, 5474, 7390, -3379, 5065, 7849} +, {-931, -10160, -4142, -3773, 1400, 1952, -7027, -4937} +, {-311, 3353, 10395, -410, 2437, 426, 5921, 4664} +, {3195, -2369, -20748, -7006, 5303, -2544, -1009, -11564} +, {-4775, 5477, -4431, 2161, 829, 18282, 1428, 3197} +, {-435, 4946, 11025, 4571, 1986, -2559, -1213, 4943} +, {16, 3484, 10337, 5800, 2855, 549, 5397, 561} +}; //32768 + +int16_t Bg1[1][8] = {{-18778, -9519, 4055, -7310, 8584, -17258, -5281, -7934} +}; //16384 + +int16_t Bh1[1][8] = {{9658, 19740, -10058, 19114, 17227, 12226, 19080, 15855} +}; //32768 + +int16_t zeta1 = 32522; //32768 + +int16_t nu1 = 235; //32768 + +int16_t W2[8][8] = {{-850, 359, -9842, 5701, 7390, -4590, -3959, 2759} +, {-1536, -6107, -1978, -5420, -1215, -5065, 77, -4658} +, {10036, -340, 745, -3625, 1684, -1927, 2312, 2028} +, {-3593, -1295, -997, -1, 1441, 2806, -1718, -3687} +, {-287, -221, -1398, 439, -1651, 3409, -19972, -193} +, {-6120, -4338, -1679, -9576, 13070, -12784, -56, -5648} +, {-5623, -2853, -862, -3739, 2595, -285, -673, -5104} +, {-3761, -842, -713, 396, 1405, 3339, -1477, -3670} +}; //16384 + +int16_t U2[8][8] = {{8755, 2010, -3642, -913, 5998, -2312, -389, -1571} +, {-906, 9661, -1875, -328, 4034, -3910, -355, -5117} +, {-2433, 1688, 1328, -1493, 4122, 769, -177, 9988} +, {-2759, 2240, 1795, 6117, 6542, -6011, 710, 283} +, {-3163, 5634, 15468, -1189, 704, -1739, 483, 3409} +, {-4224, 5383, -15324, -2616, 19957, 2042, -579, -319} +, {181, -1085, 863, 1111, -4614, 4177, 3342, 4059} +, {312, 996, -3600, -867, 2397, -1214, -917, 8633} +}; //16384 + +int16_t Bg2[1][8] = {{-5411, -15415, -13003, -12122, -18931, -17923, -8693, -12151} +}; //16384 + +int16_t Bh2[1][8] = {{21417, 6457, 6421, 8970, 6601, 836, 3060, 8468} +}; //16384 + +int16_t zeta2 = 32520; //32768 + +int16_t nu2 = 256; //32768 + diff --git a/examples/pytorch/vision/cpp/rnnpool_quantized.cpp b/examples/pytorch/vision/cpp/rnnpool_quantized.cpp new file mode 100644 index 00000000..b3a41c54 --- /dev/null +++ b/examples/pytorch/vision/cpp/rnnpool_quantized.cpp @@ -0,0 +1,535 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +#define MYINT int16_t +#define MYITE int16_t + +#include "data.h" + +#define SHIFT + +#ifdef SHIFT +#define MYSCL int16_t +unordered_map scale = { + {"X", 12}, + + {"one", 14}, + + {"W1",14}, + {"H1",14}, + {"U1",15}, + {"Bg1",14}, + {"Bh1",15}, + {"zeta1",15}, + {"nu1",15}, + + {"a1",11}, + {"b1",13}, + {"c1",11}, + {"cBg1",11}, + {"cBh1",11}, + {"g1",14}, + {"h1",14}, + {"z1",14}, + {"y1",14}, + {"w1",14}, + {"v1",14}, + {"u1",14}, + + {"intermediate", 14}, + + {"W2",14}, + {"H2",14}, + {"U2",14}, + {"Bg2",14}, + {"Bh2",14}, + {"zeta2",15}, + {"nu2",15}, + + {"a2",14}, + {"b2",13}, + {"c2",13}, + {"cBg2",11}, + {"cBh2",11}, + {"g2",14}, + {"h2",14}, + {"z2",15}, + {"y2",14}, + {"w2",14}, + {"v2",14}, + {"u2",14}, + + {"Y",14}, +}; +#else +#define MYSCL int32_t +unordered_map scale = { + {"X", 4096}, + + {"one", 16384}, + + {"W1",16384}, + {"H1",16384}, + {"U1",32768}, + {"Bg1",16384}, + {"Bh1",32768}, + {"zeta1",32768}, + {"nu1",32768}, + + {"a1",2048}, + {"b1",8192}, + {"c1",2048}, + {"cBg1",2048}, + {"cBh1",2048}, + {"g1",16384}, + {"h1",16384}, + {"z1",16384}, + {"y1",16384}, + {"w1",16384}, + {"v1",16384}, + {"u1",16384}, + + {"intermediate", 16384}, + + {"W2",16384}, + {"H2",16384}, + {"U2",16384}, + {"Bg2",16384}, + {"Bh2",16384}, + {"zeta2",32768}, + {"nu2",32768}, + + {"a2",16384}, + {"b2",8192}, + {"c2",8192}, + {"cBg2",2048}, + {"cBh2",2048}, + {"g2",16384}, + {"h2",16384}, + {"z2",32768}, + {"y2",16384}, + {"w2",16384}, + {"v2",16384}, + {"u2",16384}, + + {"Y",16384}, +}; +#endif + + + +void MatMul(int16_t* A, int16_t* B, int16_t* C, MYINT I, MYINT J, MYINT K, MYSCL scA, MYSCL scB, MYSCL scC) { + +#ifdef SHIFT + MYSCL addshrP = 1, addshr = 0; + while (addshrP < J) { + addshrP *= 2; + addshr += 1; + } +#else + MYSCL addshr = 1; + while (addshr < J) + addshr *= 2; +#endif + +#ifdef SHIFT + MYSCL shr = scA + scB - scC - addshr; +#else + MYSCL shr = (scA * scB) / (scC * addshr); +#endif + + for (int i = 0; i < I; i++) { + for (int k = 0; k < K; k++) { + int32_t s = 0; + for (int j = 0; j < J; j++) { +#ifdef SHIFT + s += ((int32_t)A[i * J + j] * (int32_t)B[j * K + k]) >> addshr; +#else + s += ((int32_t)A[i * J + j] * (int32_t)B[j * K + k]) / addshr; +#endif + } +#ifdef SHIFT + C[i * K + k] = s >> shr; +#else + C[i * K + k] = s / shr; +#endif + } + } +} + +inline MYINT min(MYINT a, MYINT b) { + return a < b ? a : b; +} + +inline MYINT max(MYINT a, MYINT b) { + return a > b ? a : b; +} + +void MatAdd(int16_t* A, int16_t* B, int16_t* C, MYINT I, MYINT J, MYSCL scA, MYSCL scB, MYSCL scC) { + + MYSCL shrmin = min(scA, scB); +#ifdef SHIFT + MYSCL shra = scA - shrmin; + MYSCL shrb = scB - shrmin; + MYSCL shrc = shrmin - scC; +#else + MYSCL shra = scA / shrmin; + MYSCL shrb = scB / shrmin; + MYSCL shrc = shrmin / scC; +#endif + + for (int i = 0; i < I; i++) { + for (int j = 0; j < J; j++) { +#ifdef SHIFT + C[i * J + j] = ((A[i * J + j] >> (shra + shrc)) + (B[i * J + j] >> (shrb + shrc))); +#else + C[i * J + j] = ((A[i * J + j] / (shra * shrc)) + (B[i * J + j] / (shrb * shrc))); +#endif + } + } +} + +void ScalarMatSub(int16_t A, int16_t* B, int16_t* C, MYINT I, MYINT J, MYSCL scA, MYSCL scB, MYSCL scC) { + + MYSCL shrmin = min(scA, scB); +#ifdef SHIFT + MYSCL shra = scA - shrmin; + MYSCL shrb = scB - shrmin; + MYSCL shrc = shrmin - scC; +#else + MYSCL shra = scA / shrmin; + MYSCL shrb = scB / shrmin; + MYSCL shrc = shrmin / scC; +#endif + + for (int i = 0; i < I; i++) { + for (int j = 0; j < J; j++) { +#ifdef SHIFT + C[i * J + j] = ((A >> (shra + shrc)) - (B[i * J + j] >> (shrb + shrc))); +#else + C[i * J + j] = ((A / (shra * shrc)) - (B[i * J + j] / (shrb * shrc))); +#endif + } + } +} + +void ScalarMatAdd(int16_t A, int16_t* B, int16_t* C, MYINT I, MYINT J, MYSCL scA, MYSCL scB, MYSCL scC) { + + MYSCL shrmin = min(scA, scB); +#ifdef SHIFT + MYSCL shra = scA - shrmin; + MYSCL shrb = scB - shrmin; + MYSCL shrc = shrmin - scC; +#else + MYSCL shra = scA / shrmin; + MYSCL shrb = scB / shrmin; + MYSCL shrc = shrmin / scC; +#endif + + for (int i = 0; i < I; i++) { + for (int j = 0; j < J; j++) { +#ifdef SHIFT + C[i * J + j] = ((A >> (shra + shrc)) + (B[i * J + j] >> (shrb + shrc))); +#else + C[i * J + j] = ((A / (shra * shrc)) + (B[i * J + j] / (shrb * shrc))); +#endif + } + } +} + +void HadMul(int16_t* A, int16_t* B, int16_t* C, MYINT I, MYINT J, MYSCL scA, MYSCL scB, MYSCL scC) { + +#ifdef SHIFT + MYSCL shr = (scA + scB) - scC; +#else + MYSCL shr = (scA * scB) / scC; +#endif + + for (int i = 0; i < I; i++) { + for (int j = 0; j < J; j++) { +#ifdef SHIFT + C[i * J + j] = (((int32_t)A[i * J + j]) * ((int32_t)B[i * J + j])) >> shr; +#else + C[i * J + j] = (((int32_t)A[i * J + j]) * ((int32_t)B[i * J + j])) / shr; +#endif + } + } +} + +void ScalarMul(int16_t A, int16_t* B, int16_t* C, MYINT I, MYINT J, MYSCL scA, MYSCL scB, MYSCL scC) { + +#ifdef SHIFT + MYSCL shr = (scA + scB) - scC; +#else + MYSCL shr = (scA * scB) / scC; +#endif + + for (int i = 0; i < I; i++) { + for (int j = 0; j < J; j++) { +#ifdef SHIFT + C[i * J + j] = ((int32_t)(A) * (int32_t)(B[i * J + j])) >> shr; +#else + C[i * J + j] = ((int32_t)(A) * (int32_t)(B[i * J + j])) / shr; +#endif + } + } +} + +void SigmoidNew16(int16_t* A, MYINT I, MYINT J, int16_t* B) { + for (MYITE i = 0; i < I; i++) { + for (MYITE j = 0; j < J; j++) { + int16_t a = A[i * J + j]; + B[i * J + j] = 8 * max(min((a + 2048) / 2, 2048), 0); + } + } + return; +} + +void TanHNew16(int16_t* A, MYINT I, MYINT J, int16_t* B) { + for (MYITE i = 0; i < I; i++) { + for (MYITE j = 0; j < J; j++) { + int16_t a = A[i * J + j]; + B[i * J + j] = 8 * max(min(a, 2048), -2048); + } + } + return; +} + +void reverse(int16_t* A, int16_t* B, int I, int J) { + for (int i = 0; i < I; i++) { + for (int j = 0; j < J; j++) { + B[i * J + j] = A[(I - i - 1) * J + j]; + } + } +} + + +void print(int16_t* var, int I, int J, MYSCL scale) { + for (int i = 0; i < I; i++) { + for (int j = 0; j < J; j++) { + cout << ((float)var[i * J + j]) / scale << " "; + } + cout << endl; + } + //exit(1); +} + +void FastGRNN1(int16_t X[8][4], int16_t* H, int timestep) { + memset(&H[0], 0, 8 * 2); + + for (int i = 0; i < timestep; i++) { + int16_t a[1][8]; + MatMul(&X[i][0], &W1[0][0], &a[0][0], 1, 4, 8, scale["X"], scale["W1"], scale["a1"]); + int16_t b[1][8]; + MatMul(&H[0], &U1[0][0], &b[0][0], 1, 8, 8, scale["H1"], scale["U1"], scale["b1"]); + int16_t c[1][8]; + MatAdd(&a[0][0], &b[0][0], &c[0][0], 1, 8, scale["a1"], scale["b1"], scale["c1"]); + int16_t cBg[1][8]; + MatAdd(&c[0][0], &Bg1[0][0], &cBg[0][0], 1, 8, scale["c1"], scale["Bg1"], scale["cBg1"]); + int16_t g[1][8]; + SigmoidNew16(&cBg[0][0], 1, 8, &g[0][0]); + int16_t cBh[1][8]; + MatAdd(&c[0][0], &Bh1[0][0], &cBh[0][0], 1, 8, scale["c1"], scale["Bh1"], scale["cBh1"]); + int16_t h[1][8]; + TanHNew16(&cBh[0][0], 1, 8, &h[0][0]); + int16_t z[1][8]; + HadMul(&g[0][0], &H[0], &z[0][0], 1, 8, scale["g1"], scale["H1"], scale["z1"]); + int16_t y[1][8]; + ScalarMatSub(16384, &g[0][0], &y[0][0], 1, 8, scale["one"], scale["g1"], scale["y1"]); + int16_t w[1][8]; + ScalarMul(zeta1, &y[0][0], &w[0][0], 1, 8, scale["zeta1"], scale["y1"], scale["w1"]); + int16_t v[1][8]; + ScalarMatAdd(nu1, &w[0][0], &v[0][0], 1, 8, scale["nu1"], scale["w1"], scale["v1"]); + int16_t u[1][8]; + HadMul(&w[0][0], &h[0][0], &u[0][0], 1, 8, scale["w1"], scale["h1"], scale["u1"]); + + MatAdd(&z[0][0], &u[0][0], &H[0], 1, 8, scale["z1"], scale["u1"], scale["H1"]); + } +} + +void FastGRNN2(int16_t X[8][8], int16_t* H, int timestep) { + memset(&H[0], 0, 8 * 2); + + for (int i = 0; i < timestep; i++) { + int16_t a[1][8]; + MatMul(&X[i][0], &W2[0][0], &a[0][0], 1, 8, 8, scale["intermediate"], scale["W2"], scale["a2"]); + + int16_t b[1][8]; + MatMul(&H[0], &U2[0][0], &b[0][0], 1, 8, 8, scale["H2"], scale["U2"], scale["b2"]); + int16_t c[1][8]; + MatAdd(&a[0][0], &b[0][0], &c[0][0], 1, 8, scale["a2"], scale["b2"], scale["c2"]); + int16_t cBg[1][8]; + MatAdd(&c[0][0], &Bg2[0][0], &cBg[0][0], 1, 8, scale["c2"], scale["Bg2"], scale["cBg2"]); + int16_t g[1][8]; + SigmoidNew16(&cBg[0][0], 1, 8, &g[0][0]); + int16_t cBh[1][8]; + MatAdd(&c[0][0], &Bh2[0][0], &cBh[0][0], 1, 8, scale["c2"], scale["Bh2"], scale["cBh2"]); + int16_t h[1][8]; + TanHNew16(&cBh[0][0], 1, 8, &h[0][0]); + int16_t z[1][8]; + HadMul(&g[0][0], &H[0], &z[0][0], 1, 8, scale["g2"], scale["H2"], scale["z2"]); + int16_t y[1][8]; + ScalarMatSub(16384, &g[0][0], &y[0][0], 1, 8, scale["one"], scale["g2"], scale["y2"]); + int16_t w[1][8]; + ScalarMul(zeta2, &y[0][0], &w[0][0], 1, 8, scale["zeta2"], scale["y2"], scale["w2"]); + int16_t v[1][8]; + ScalarMatAdd(nu2, &w[0][0], &v[0][0], 1, 8, scale["nu2"], scale["w2"], scale["v2"]); + int16_t u[1][8]; + HadMul(&w[0][0], &h[0][0], &u[0][0], 1, 8, scale["w2"], scale["h2"], scale["u2"]); + + MatAdd(&z[0][0], &u[0][0], &H[0], 1, 8, scale["z2"], scale["u2"], scale["H2"]); + } +} + +void RNNPool(int16_t X[8][8][4], int16_t pred[1][32]) { + + int16_t biinput1[8][8], biinput1r[8][8]; + for (int i = 0; i < 8; i++) { + int16_t subX[8][4]; + for (int j = 0; j < 8; j++) { + for (int k = 0; k < 4; k++) { + subX[j][k] = X[i][j][k]; + } + } + int16_t H[1][8]; + FastGRNN1(subX, &H[0][0], 8); + + for (int j = 0; j < 8; j++) { + biinput1[i][j] = H[0][j]; + } + } + + int16_t res1[1][8], res2[1][8]; + FastGRNN2(biinput1, &res1[0][0], 8); + reverse(&biinput1[0][0], &biinput1r[0][0], 8, 8); + FastGRNN2(biinput1r, &res2[0][0], 8); + + int16_t biinput2[8][8], biinput2r[8][8]; + for (int i = 0; i < 8; i++) { + int16_t subX[8][4]; + for (int j = 0; j < 8; j++) { + for (int k = 0; k < 4; k++) { + subX[j][k] = X[j][i][k]; + } + } + int16_t H[1][8]; + FastGRNN1(subX, &H[0][0], 8); + + for (int j = 0; j < 8; j++) { + biinput2[i][j] = H[0][j]; + } + } + + + int16_t res3[1][8], res4[1][8]; + FastGRNN2(biinput2, &res3[0][0], 8); + reverse(&biinput2[0][0], &biinput2r[0][0], 8, 8); + FastGRNN2(biinput2r, &res4[0][0], 8); + + for (int i = 0; i < 8; i++) + pred[0][i] = res1[0][i]; + for (int i = 0; i < 8; i++) + pred[0][i + 8] = res2[0][i]; + for (int i = 0; i < 8; i++) + pred[0][i + 16] = res3[0][i]; + for (int i = 0; i < 8; i++) + pred[0][i + 24] = res4[0][i]; +} + +int main(int argc, char* argv[]) { + string inputfile, outputfile; + int patches; + if (argc != 4) { + cerr << "Improper number of arguments" << endl; + return -1; + } + else { + patches = atoi(argv[1]); + inputfile = string(argv[2]); + outputfile = string(argv[3]); + } + + fstream Xfile, Yfile; + + Xfile.open(inputfile, ios::in | ios::binary); + Yfile.open(outputfile, ios::out | ios::binary); + + + char line[8]; + Xfile.read(line, 8); + int headerSize; + Xfile.read((char*)&headerSize, 1 * 2); + + char* headerLine = new char[headerSize]; //Ignored + Xfile.read(headerLine, headerSize); + delete[] headerLine; + + char numpyMagix = 147; + char numpyVersionMajor = 1, numpyVersionMinor = 0; + string numpyMetaHeader = ""; + numpyMetaHeader += numpyMagix; + numpyMetaHeader += "NUMPY"; + numpyMetaHeader += numpyVersionMajor; + numpyMetaHeader += numpyVersionMinor; + + string numpyHeader = "{'descr': '