[
  {
    "path": "Image Processor/.gitignore",
    "content": "# Data files and directories common in repo root\ndatasets/\nlogs/\n*.h5\nresults/\ntemp/\ntest/\n\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# Distribution / packaging\n.Python\nenv/\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\n*.egg-info/\n.installed.cfg\n*.egg\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# VS Studio Code\n.vscode\n\n# PyCharm\n.idea/\n\n# Dropbox\n.dropbox.attr\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# pyenv\n.python-version\n\n# dotenv\n.env\n\n# virtualenv\n.venv\nvenv/\nENV/\n"
  },
  {
    "path": "Image Processor/Dick_Pic_Mask-RCNN_Trainer.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 11,\n   \"metadata\": {\n    \"tags\": []\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"from mrcnn.config import Config\\n\",\n    \"from mrcnn import model as modellib\\n\",\n    \"from mrcnn import visualize\\n\",\n    \"import mrcnn\\n\",\n    \"from mrcnn import utils\\n\",\n    \"from mrcnn.utils import Dataset\\n\",\n    \"from mrcnn.model import MaskRCNN\\n\",\n    \"\\n\",\n    \"import numpy as np\\n\",\n    \"from numpy import zeros\\n\",\n    \"from numpy import asarray\\n\",\n    \"import colorsys\\n\",\n    \"import argparse\\n\",\n    \"import imutils\\n\",\n    \"import random\\n\",\n    \"import cv2\\n\",\n    \"import os\\n\",\n    \"import time\\n\",\n    \"\\n\",\n    \"from matplotlib import pyplot\\n\",\n    \"from matplotlib.patches import Rectangle\\n\",\n    \"from keras.models import load_model\\n\",\n    \"\\n\",\n    \"%matplotlib inline\\n\",\n    \"\\n\",\n    \"from os import listdir\\n\",\n    \"from pathlib import Path\\n\",\n    \"import tarfile\\n\",\n    \"from xml.etree import ElementTree\\n\",\n    \"\\n\",\n    \"from download_utils import download_file_from_google_drive\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"#inherting  from Config class\\n\",\n    \"\\n\",\n    \"class myMaskRCNNConfig(Config):\\n\",\n    \"    # give the configuration a recognizable name\\n\",\n    \"    NAME = \\\"MaskRCNN_config\\\"\\n\",\n    \" \\n\",\n    \"    # set the number of GPUs to use along with the number of images\\n\",\n    \"    # per GPU\\n\",\n    \"    GPU_COUNT = 1\\n\",\n    \"    IMAGES_PER_GPU = 1\\n\",\n    \" \\n\",\n    \"    # number of classes (we would normally add +1 for the background)\\n\",\n    \"     # kangaroo + BG\\n\",\n    \"    NUM_CLASSES = 1+1\\n\",\n    \"   \\n\",\n    \"    # Number of training steps per epoch\\n\",\n    \"    STEPS_PER_EPOCH = 131\\n\",\n    \"    \\n\",\n    \"    # Learning rate\\n\",\n    \"    LEARNING_RATE=0.006\\n\",\n    \"    \\n\",\n    \"    # Skip detections with < 90% confidence\\n\",\n    \"    DETECTION_MIN_CONFIDENCE = 0.9\\n\",\n    \"    \\n\",\n    \"    # setting Max ground truth instances\\n\",\n    \"    MAX_GT_INSTANCES=10\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"config= myMaskRCNNConfig()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {\n    \"tags\": []\n   },\n   \"outputs\": [\n    {\n     \"output_type\": \"stream\",\n     \"name\": \"stdout\",\n     \"text\": \"\\nConfigurations:\\nBACKBONE                       resnet101\\nBACKBONE_STRIDES               [4, 8, 16, 32, 64]\\nBATCH_SIZE                     1\\nBBOX_STD_DEV                   [0.1 0.1 0.2 0.2]\\nCOMPUTE_BACKBONE_SHAPE         None\\nDETECTION_MAX_INSTANCES        100\\nDETECTION_MIN_CONFIDENCE       0.9\\nDETECTION_NMS_THRESHOLD        0.3\\nFPN_CLASSIF_FC_LAYERS_SIZE     1024\\nGPU_COUNT                      1\\nGRADIENT_CLIP_NORM             5.0\\nIMAGES_PER_GPU                 1\\nIMAGE_CHANNEL_COUNT            3\\nIMAGE_MAX_DIM                  1024\\nIMAGE_META_SIZE                14\\nIMAGE_MIN_DIM                  800\\nIMAGE_MIN_SCALE                0\\nIMAGE_RESIZE_MODE              square\\nIMAGE_SHAPE                    [1024 1024    3]\\nLEARNING_MOMENTUM              0.9\\nLEARNING_RATE                  0.006\\nLOSS_WEIGHTS                   {'rpn_class_loss': 1.0, 'rpn_bbox_loss': 1.0, 'mrcnn_class_loss': 1.0, 'mrcnn_bbox_loss': 1.0, 'mrcnn_mask_loss': 1.0}\\nMASK_POOL_SIZE                 14\\nMASK_SHAPE                     [28, 28]\\nMAX_GT_INSTANCES               10\\nMEAN_PIXEL                     [123.7 116.8 103.9]\\nMINI_MASK_SHAPE                (56, 56)\\nNAME                           MaskRCNN_config\\nNUM_CLASSES                    2\\nPOOL_SIZE                      7\\nPOST_NMS_ROIS_INFERENCE        1000\\nPOST_NMS_ROIS_TRAINING         2000\\nPRE_NMS_LIMIT                  6000\\nROI_POSITIVE_RATIO             0.33\\nRPN_ANCHOR_RATIOS              [0.5, 1, 2]\\nRPN_ANCHOR_SCALES              (32, 64, 128, 256, 512)\\nRPN_ANCHOR_STRIDE              1\\nRPN_BBOX_STD_DEV               [0.1 0.1 0.2 0.2]\\nRPN_NMS_THRESHOLD              0.7\\nRPN_TRAIN_ANCHORS_PER_IMAGE    256\\nSTEPS_PER_EPOCH                131\\nTOP_DOWN_PYRAMID_SIZE          256\\nTRAIN_BN                       False\\nTRAIN_ROIS_PER_IMAGE           200\\nUSE_MINI_MASK                  True\\nUSE_RPN_ROIS                   True\\nVALIDATION_STEPS               50\\nWEIGHT_DECAY                   0.0001\\n\\n\\n\"\n    }\n   ],\n   \"source\": [\n    \"config.display()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {\n    \"tags\": []\n   },\n   \"outputs\": [\n    {\n     \"output_type\": \"stream\",\n     \"name\": \"stdout\",\n     \"text\": \"Loading Mask R-CNN model...\\nWARNING:tensorflow:From C:\\\\Users\\\\Sayon_Desktop\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\backend\\\\tensorflow_backend.py:541: The name tf.placeholder is deprecated. Please use tf.compat.v1.placeholder instead.\\n\\nWARNING:tensorflow:From C:\\\\Users\\\\Sayon_Desktop\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\backend\\\\tensorflow_backend.py:66: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.\\n\\nWARNING:tensorflow:From C:\\\\Users\\\\Sayon_Desktop\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\backend\\\\tensorflow_backend.py:4432: The name tf.random_uniform is deprecated. Please use tf.random.uniform instead.\\n\\nWARNING:tensorflow:From C:\\\\Users\\\\Sayon_Desktop\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\backend\\\\tensorflow_backend.py:2139: The name tf.nn.fused_batch_norm is deprecated. Please use tf.compat.v1.nn.fused_batch_norm instead.\\n\\nWARNING:tensorflow:From C:\\\\Users\\\\Sayon_Desktop\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\backend\\\\tensorflow_backend.py:4267: The name tf.nn.max_pool is deprecated. Please use tf.nn.max_pool2d instead.\\n\\nWARNING:tensorflow:From C:\\\\Users\\\\Sayon_Desktop\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\backend\\\\tensorflow_backend.py:2239: The name tf.image.resize_nearest_neighbor is deprecated. Please use tf.compat.v1.image.resize_nearest_neighbor instead.\\n\\nWARNING:tensorflow:From C:\\\\Users\\\\Sayon_Desktop\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\tensorflow_core\\\\python\\\\ops\\\\array_ops.py:1475: where (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\\nInstructions for updating:\\nUse tf.where in 2.0, which has the same broadcast rule as np.where\\nWARNING:tensorflow:From d:\\\\Vue\\\\TDPDNE\\\\git_repo\\\\Dataset Creator\\\\Mask_RCNN\\\\mrcnn\\\\model.py:553: The name tf.random_shuffle is deprecated. Please use tf.random.shuffle instead.\\n\\nWARNING:tensorflow:From d:\\\\Vue\\\\TDPDNE\\\\git_repo\\\\Dataset Creator\\\\Mask_RCNN\\\\mrcnn\\\\utils.py:202: The name tf.log is deprecated. Please use tf.math.log instead.\\n\\nWARNING:tensorflow:From d:\\\\Vue\\\\TDPDNE\\\\git_repo\\\\Dataset Creator\\\\Mask_RCNN\\\\mrcnn\\\\model.py:600: calling crop_and_resize_v1 (from tensorflow.python.ops.image_ops_impl) with box_ind is deprecated and will be removed in a future version.\\nInstructions for updating:\\nbox_ind is deprecated, use box_indices instead\\n\"\n    }\n   ],\n   \"source\": [\n    \"# initialize the Mask R-CNN model for inference \\n\",\n    \"print(\\\"Loading Mask R-CNN model...\\\")\\n\",\n    \"model = modellib.MaskRCNN(mode=\\\"training\\\", config=config, model_dir='./')\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 6,\n   \"metadata\": {\n    \"tags\": [\n     \"outputPrepend\"\n    ]\n   },\n   \"outputs\": [\n    {\n     \"output_type\": \"stream\",\n     \"name\": \"stdout\",\n     \"text\": \"0]              \\n__________________________________________________________________________________________________\\nres5b_branch2c (Conv2D)         (None, None, None, 2 1050624     activation_65[0][0]              \\n__________________________________________________________________________________________________\\nbn5b_branch2c (BatchNorm)       (None, None, None, 2 8192        res5b_branch2c[0][0]             \\n__________________________________________________________________________________________________\\nadd_32 (Add)                    (None, None, None, 2 0           bn5b_branch2c[0][0]              \\n                                                                 res5a_out[0][0]                  \\n__________________________________________________________________________________________________\\nres5b_out (Activation)          (None, None, None, 2 0           add_32[0][0]                     \\n__________________________________________________________________________________________________\\nres5c_branch2a (Conv2D)         (None, None, None, 5 1049088     res5b_out[0][0]                  \\n__________________________________________________________________________________________________\\nbn5c_branch2a (BatchNorm)       (None, None, None, 5 2048        res5c_branch2a[0][0]             \\n__________________________________________________________________________________________________\\nactivation_66 (Activation)      (None, None, None, 5 0           bn5c_branch2a[0][0]              \\n__________________________________________________________________________________________________\\nres5c_branch2b (Conv2D)         (None, None, None, 5 2359808     activation_66[0][0]              \\n__________________________________________________________________________________________________\\nbn5c_branch2b (BatchNorm)       (None, None, None, 5 2048        res5c_branch2b[0][0]             \\n__________________________________________________________________________________________________\\nactivation_67 (Activation)      (None, None, None, 5 0           bn5c_branch2b[0][0]              \\n__________________________________________________________________________________________________\\nres5c_branch2c (Conv2D)         (None, None, None, 2 1050624     activation_67[0][0]              \\n__________________________________________________________________________________________________\\nbn5c_branch2c (BatchNorm)       (None, None, None, 2 8192        res5c_branch2c[0][0]             \\n__________________________________________________________________________________________________\\nadd_33 (Add)                    (None, None, None, 2 0           bn5c_branch2c[0][0]              \\n                                                                 res5b_out[0][0]                  \\n__________________________________________________________________________________________________\\nres5c_out (Activation)          (None, None, None, 2 0           add_33[0][0]                     \\n__________________________________________________________________________________________________\\nfpn_c5p5 (Conv2D)               (None, None, None, 2 524544      res5c_out[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_p5upsampled (UpSampling2D)  (None, None, None, 2 0           fpn_c5p5[0][0]                   \\n__________________________________________________________________________________________________\\nfpn_c4p4 (Conv2D)               (None, None, None, 2 262400      res4w_out[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_p4add (Add)                 (None, None, None, 2 0           fpn_p5upsampled[0][0]            \\n                                                                 fpn_c4p4[0][0]                   \\n__________________________________________________________________________________________________\\nfpn_p4upsampled (UpSampling2D)  (None, None, None, 2 0           fpn_p4add[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_c3p3 (Conv2D)               (None, None, None, 2 131328      res3d_out[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_p3add (Add)                 (None, None, None, 2 0           fpn_p4upsampled[0][0]            \\n                                                                 fpn_c3p3[0][0]                   \\n__________________________________________________________________________________________________\\nfpn_p3upsampled (UpSampling2D)  (None, None, None, 2 0           fpn_p3add[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_c2p2 (Conv2D)               (None, None, None, 2 65792       res2c_out[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_p2add (Add)                 (None, None, None, 2 0           fpn_p3upsampled[0][0]            \\n                                                                 fpn_c2p2[0][0]                   \\n__________________________________________________________________________________________________\\nfpn_p5 (Conv2D)                 (None, None, None, 2 590080      fpn_c5p5[0][0]                   \\n__________________________________________________________________________________________________\\nfpn_p2 (Conv2D)                 (None, None, None, 2 590080      fpn_p2add[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_p3 (Conv2D)                 (None, None, None, 2 590080      fpn_p3add[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_p4 (Conv2D)                 (None, None, None, 2 590080      fpn_p4add[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_p6 (MaxPooling2D)           (None, None, None, 2 0           fpn_p5[0][0]                     \\n__________________________________________________________________________________________________\\nrpn_model (Model)               [(None, None, 2), (N 1189394     fpn_p2[0][0]                     \\n                                                                 fpn_p3[0][0]                     \\n                                                                 fpn_p4[0][0]                     \\n                                                                 fpn_p5[0][0]                     \\n                                                                 fpn_p6[0][0]                     \\n__________________________________________________________________________________________________\\nrpn_class (Concatenate)         (None, None, 2)      0           rpn_model[1][1]                  \\n                                                                 rpn_model[2][1]                  \\n                                                                 rpn_model[3][1]                  \\n                                                                 rpn_model[4][1]                  \\n                                                                 rpn_model[5][1]                  \\n__________________________________________________________________________________________________\\nrpn_bbox (Concatenate)          (None, None, 4)      0           rpn_model[1][2]                  \\n                                                                 rpn_model[2][2]                  \\n                                                                 rpn_model[3][2]                  \\n                                                                 rpn_model[4][2]                  \\n                                                                 rpn_model[5][2]                  \\n__________________________________________________________________________________________________\\nanchors (Lambda)                (1, 261888, 4)       0           input_image[0][0]                \\n__________________________________________________________________________________________________\\ninput_gt_boxes (InputLayer)     (None, None, 4)      0                                            \\n__________________________________________________________________________________________________\\nROI (ProposalLayer)             (None, 2000, 4)      0           rpn_class[0][0]                  \\n                                                                 rpn_bbox[0][0]                   \\n                                                                 anchors[0][0]                    \\n__________________________________________________________________________________________________\\ninput_gt_class_ids (InputLayer) (None, None)         0                                            \\n__________________________________________________________________________________________________\\nlambda_1 (Lambda)               (None, None, 4)      0           input_gt_boxes[0][0]             \\n__________________________________________________________________________________________________\\ninput_gt_masks (InputLayer)     (None, 56, 56, None) 0                                            \\n__________________________________________________________________________________________________\\nproposal_targets (DetectionTarg [(None, 200, 4), (No 0           ROI[0][0]                        \\n                                                                 input_gt_class_ids[0][0]         \\n                                                                 lambda_1[0][0]                   \\n                                                                 input_gt_masks[0][0]             \\n__________________________________________________________________________________________________\\ninput_image_meta (InputLayer)   (None, 14)           0                                            \\n__________________________________________________________________________________________________\\nroi_align_mask (PyramidROIAlign (None, 200, 14, 14,  0           proposal_targets[0][0]           \\n                                                                 input_image_meta[0][0]           \\n                                                                 fpn_p2[0][0]                     \\n                                                                 fpn_p3[0][0]                     \\n                                                                 fpn_p4[0][0]                     \\n                                                                 fpn_p5[0][0]                     \\n__________________________________________________________________________________________________\\nmrcnn_mask_conv1 (TimeDistribut (None, 200, 14, 14,  590080      roi_align_mask[0][0]             \\n__________________________________________________________________________________________________\\nmrcnn_mask_bn1 (TimeDistributed (None, 200, 14, 14,  1024        mrcnn_mask_conv1[0][0]           \\n__________________________________________________________________________________________________\\nactivation_71 (Activation)      (None, 200, 14, 14,  0           mrcnn_mask_bn1[0][0]             \\n__________________________________________________________________________________________________\\nmrcnn_mask_conv2 (TimeDistribut (None, 200, 14, 14,  590080      activation_71[0][0]              \\n__________________________________________________________________________________________________\\nroi_align_classifier (PyramidRO (None, 200, 7, 7, 25 0           proposal_targets[0][0]           \\n                                                                 input_image_meta[0][0]           \\n                                                                 fpn_p2[0][0]                     \\n                                                                 fpn_p3[0][0]                     \\n                                                                 fpn_p4[0][0]                     \\n                                                                 fpn_p5[0][0]                     \\n__________________________________________________________________________________________________\\nmrcnn_mask_bn2 (TimeDistributed (None, 200, 14, 14,  1024        mrcnn_mask_conv2[0][0]           \\n__________________________________________________________________________________________________\\nmrcnn_class_conv1 (TimeDistribu (None, 200, 1, 1, 10 12846080    roi_align_classifier[0][0]       \\n__________________________________________________________________________________________________\\nactivation_72 (Activation)      (None, 200, 14, 14,  0           mrcnn_mask_bn2[0][0]             \\n__________________________________________________________________________________________________\\nmrcnn_class_bn1 (TimeDistribute (None, 200, 1, 1, 10 4096        mrcnn_class_conv1[0][0]          \\n__________________________________________________________________________________________________\\nmrcnn_mask_conv3 (TimeDistribut (None, 200, 14, 14,  590080      activation_72[0][0]              \\n__________________________________________________________________________________________________\\nactivation_68 (Activation)      (None, 200, 1, 1, 10 0           mrcnn_class_bn1[0][0]            \\n__________________________________________________________________________________________________\\nmrcnn_mask_bn3 (TimeDistributed (None, 200, 14, 14,  1024        mrcnn_mask_conv3[0][0]           \\n__________________________________________________________________________________________________\\nmrcnn_class_conv2 (TimeDistribu (None, 200, 1, 1, 10 1049600     activation_68[0][0]              \\n__________________________________________________________________________________________________\\nactivation_73 (Activation)      (None, 200, 14, 14,  0           mrcnn_mask_bn3[0][0]             \\n__________________________________________________________________________________________________\\nmrcnn_class_bn2 (TimeDistribute (None, 200, 1, 1, 10 4096        mrcnn_class_conv2[0][0]          \\n__________________________________________________________________________________________________\\nmrcnn_mask_conv4 (TimeDistribut (None, 200, 14, 14,  590080      activation_73[0][0]              \\n__________________________________________________________________________________________________\\nactivation_69 (Activation)      (None, 200, 1, 1, 10 0           mrcnn_class_bn2[0][0]            \\n__________________________________________________________________________________________________\\nmrcnn_mask_bn4 (TimeDistributed (None, 200, 14, 14,  1024        mrcnn_mask_conv4[0][0]           \\n__________________________________________________________________________________________________\\npool_squeeze (Lambda)           (None, 200, 1024)    0           activation_69[0][0]              \\n__________________________________________________________________________________________________\\nactivation_74 (Activation)      (None, 200, 14, 14,  0           mrcnn_mask_bn4[0][0]             \\n__________________________________________________________________________________________________\\nmrcnn_bbox_fc (TimeDistributed) (None, 200, 8)       8200        pool_squeeze[0][0]               \\n__________________________________________________________________________________________________\\nmrcnn_mask_deconv (TimeDistribu (None, 200, 28, 28,  262400      activation_74[0][0]              \\n__________________________________________________________________________________________________\\nrpn_class_logits (Concatenate)  (None, None, 2)      0           rpn_model[1][0]                  \\n                                                                 rpn_model[2][0]                  \\n                                                                 rpn_model[3][0]                  \\n                                                                 rpn_model[4][0]                  \\n                                                                 rpn_model[5][0]                  \\n__________________________________________________________________________________________________\\nmrcnn_class_logits (TimeDistrib (None, 200, 2)       2050        pool_squeeze[0][0]               \\n__________________________________________________________________________________________________\\nmrcnn_bbox (Reshape)            (None, 200, 2, 4)    0           mrcnn_bbox_fc[0][0]              \\n__________________________________________________________________________________________________\\nmrcnn_mask (TimeDistributed)    (None, 200, 28, 28,  514         mrcnn_mask_deconv[0][0]          \\n__________________________________________________________________________________________________\\ninput_rpn_match (InputLayer)    (None, None, 1)      0                                            \\n__________________________________________________________________________________________________\\ninput_rpn_bbox (InputLayer)     (None, None, 4)      0                                            \\n__________________________________________________________________________________________________\\nlambda_4 (Lambda)               (None, 2)            0           input_image_meta[0][0]           \\n__________________________________________________________________________________________________\\nmrcnn_class (TimeDistributed)   (None, 200, 2)       0           mrcnn_class_logits[0][0]         \\n__________________________________________________________________________________________________\\noutput_rois (Lambda)            (None, 200, 4)       0           proposal_targets[0][0]           \\n__________________________________________________________________________________________________\\nrpn_class_loss (Lambda)         ()                   0           input_rpn_match[0][0]            \\n                                                                 rpn_class_logits[0][0]           \\n__________________________________________________________________________________________________\\nrpn_bbox_loss (Lambda)          ()                   0           input_rpn_bbox[0][0]             \\n                                                                 input_rpn_match[0][0]            \\n                                                                 rpn_bbox[0][0]                   \\n__________________________________________________________________________________________________\\nmrcnn_class_loss (Lambda)       ()                   0           proposal_targets[0][1]           \\n                                                                 mrcnn_class_logits[0][0]         \\n                                                                 lambda_4[0][0]                   \\n__________________________________________________________________________________________________\\nmrcnn_bbox_loss (Lambda)        ()                   0           proposal_targets[0][2]           \\n                                                                 proposal_targets[0][1]           \\n                                                                 mrcnn_bbox[0][0]                 \\n__________________________________________________________________________________________________\\nmrcnn_mask_loss (Lambda)        ()                   0           proposal_targets[0][3]           \\n                                                                 proposal_targets[0][1]           \\n                                                                 mrcnn_mask[0][0]                 \\n==================================================================================================\\nTotal params: 63,733,406\\nTrainable params: 63,621,918\\nNon-trainable params: 111,488\\n__________________________________________________________________________________________________\\n\"\n    }\n   ],\n   \"source\": [\n    \"model.keras_model.summary()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 7,\n   \"metadata\": {\n    \"tags\": []\n   },\n   \"outputs\": [\n    {\n     \"output_type\": \"stream\",\n     \"name\": \"stdout\",\n     \"text\": \"Downloading pretrained model to mask_rcnn_coco.h5 ...\\n... done downloading pretrained model!\\nWARNING:tensorflow:From C:\\\\Users\\\\Sayon_Desktop\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\backend\\\\tensorflow_backend.py:190: The name tf.get_default_session is deprecated. Please use tf.compat.v1.get_default_session instead.\\n\\nWARNING:tensorflow:From C:\\\\Users\\\\Sayon_Desktop\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\backend\\\\tensorflow_backend.py:200: The name tf.ConfigProto is deprecated. Please use tf.compat.v1.ConfigProto instead.\\n\\nWARNING:tensorflow:From C:\\\\Users\\\\Sayon_Desktop\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\backend\\\\tensorflow_backend.py:203: The name tf.Session is deprecated. Please use tf.compat.v1.Session instead.\\n\\nWARNING:tensorflow:From C:\\\\Users\\\\Sayon_Desktop\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\backend\\\\tensorflow_backend.py:207: The name tf.global_variables is deprecated. Please use tf.compat.v1.global_variables instead.\\n\\nWARNING:tensorflow:From C:\\\\Users\\\\Sayon_Desktop\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\backend\\\\tensorflow_backend.py:216: The name tf.is_variable_initialized is deprecated. Please use tf.compat.v1.is_variable_initialized instead.\\n\\nWARNING:tensorflow:From C:\\\\Users\\\\Sayon_Desktop\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\backend\\\\tensorflow_backend.py:223: The name tf.variables_initializer is deprecated. Please use tf.compat.v1.variables_initializer instead.\\n\\n\"\n    }\n   ],\n   \"source\": [\n    \"# Local path to trained weights file\\n\",\n    \"COCO_MODEL_PATH = \\\"mask_rcnn_coco.h5\\\"\\n\",\n    \"# Download COCO trained weights from Releases if needed\\n\",\n    \"if not os.path.exists(COCO_MODEL_PATH):\\n\",\n    \"    utils.download_trained_weights(COCO_MODEL_PATH)\\n\",\n    \"\\n\",\n    \"#n load the weights for COCO\\n\",\n    \"model.load_weights(COCO_MODEL_PATH,\\n\",\n    \"                   by_name=True, \\n\",\n    \"                   exclude=[\\\"mrcnn_class_logits\\\", \\\"mrcnn_bbox_fc\\\",  \\\"mrcnn_bbox\\\", \\\"mrcnn_mask\\\"])\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 8,\n   \"metadata\": {\n    \"tags\": [\n     \"outputPrepend\"\n    ]\n   },\n   \"outputs\": [\n    {\n     \"output_type\": \"stream\",\n     \"name\": \"stdout\",\n     \"text\": \"0]              \\n__________________________________________________________________________________________________\\nres5b_branch2c (Conv2D)         (None, None, None, 2 1050624     activation_65[0][0]              \\n__________________________________________________________________________________________________\\nbn5b_branch2c (BatchNorm)       (None, None, None, 2 8192        res5b_branch2c[0][0]             \\n__________________________________________________________________________________________________\\nadd_32 (Add)                    (None, None, None, 2 0           bn5b_branch2c[0][0]              \\n                                                                 res5a_out[0][0]                  \\n__________________________________________________________________________________________________\\nres5b_out (Activation)          (None, None, None, 2 0           add_32[0][0]                     \\n__________________________________________________________________________________________________\\nres5c_branch2a (Conv2D)         (None, None, None, 5 1049088     res5b_out[0][0]                  \\n__________________________________________________________________________________________________\\nbn5c_branch2a (BatchNorm)       (None, None, None, 5 2048        res5c_branch2a[0][0]             \\n__________________________________________________________________________________________________\\nactivation_66 (Activation)      (None, None, None, 5 0           bn5c_branch2a[0][0]              \\n__________________________________________________________________________________________________\\nres5c_branch2b (Conv2D)         (None, None, None, 5 2359808     activation_66[0][0]              \\n__________________________________________________________________________________________________\\nbn5c_branch2b (BatchNorm)       (None, None, None, 5 2048        res5c_branch2b[0][0]             \\n__________________________________________________________________________________________________\\nactivation_67 (Activation)      (None, None, None, 5 0           bn5c_branch2b[0][0]              \\n__________________________________________________________________________________________________\\nres5c_branch2c (Conv2D)         (None, None, None, 2 1050624     activation_67[0][0]              \\n__________________________________________________________________________________________________\\nbn5c_branch2c (BatchNorm)       (None, None, None, 2 8192        res5c_branch2c[0][0]             \\n__________________________________________________________________________________________________\\nadd_33 (Add)                    (None, None, None, 2 0           bn5c_branch2c[0][0]              \\n                                                                 res5b_out[0][0]                  \\n__________________________________________________________________________________________________\\nres5c_out (Activation)          (None, None, None, 2 0           add_33[0][0]                     \\n__________________________________________________________________________________________________\\nfpn_c5p5 (Conv2D)               (None, None, None, 2 524544      res5c_out[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_p5upsampled (UpSampling2D)  (None, None, None, 2 0           fpn_c5p5[0][0]                   \\n__________________________________________________________________________________________________\\nfpn_c4p4 (Conv2D)               (None, None, None, 2 262400      res4w_out[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_p4add (Add)                 (None, None, None, 2 0           fpn_p5upsampled[0][0]            \\n                                                                 fpn_c4p4[0][0]                   \\n__________________________________________________________________________________________________\\nfpn_p4upsampled (UpSampling2D)  (None, None, None, 2 0           fpn_p4add[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_c3p3 (Conv2D)               (None, None, None, 2 131328      res3d_out[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_p3add (Add)                 (None, None, None, 2 0           fpn_p4upsampled[0][0]            \\n                                                                 fpn_c3p3[0][0]                   \\n__________________________________________________________________________________________________\\nfpn_p3upsampled (UpSampling2D)  (None, None, None, 2 0           fpn_p3add[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_c2p2 (Conv2D)               (None, None, None, 2 65792       res2c_out[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_p2add (Add)                 (None, None, None, 2 0           fpn_p3upsampled[0][0]            \\n                                                                 fpn_c2p2[0][0]                   \\n__________________________________________________________________________________________________\\nfpn_p5 (Conv2D)                 (None, None, None, 2 590080      fpn_c5p5[0][0]                   \\n__________________________________________________________________________________________________\\nfpn_p2 (Conv2D)                 (None, None, None, 2 590080      fpn_p2add[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_p3 (Conv2D)                 (None, None, None, 2 590080      fpn_p3add[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_p4 (Conv2D)                 (None, None, None, 2 590080      fpn_p4add[0][0]                  \\n__________________________________________________________________________________________________\\nfpn_p6 (MaxPooling2D)           (None, None, None, 2 0           fpn_p5[0][0]                     \\n__________________________________________________________________________________________________\\nrpn_model (Model)               [(None, None, 2), (N 1189394     fpn_p2[0][0]                     \\n                                                                 fpn_p3[0][0]                     \\n                                                                 fpn_p4[0][0]                     \\n                                                                 fpn_p5[0][0]                     \\n                                                                 fpn_p6[0][0]                     \\n__________________________________________________________________________________________________\\nrpn_class (Concatenate)         (None, None, 2)      0           rpn_model[1][1]                  \\n                                                                 rpn_model[2][1]                  \\n                                                                 rpn_model[3][1]                  \\n                                                                 rpn_model[4][1]                  \\n                                                                 rpn_model[5][1]                  \\n__________________________________________________________________________________________________\\nrpn_bbox (Concatenate)          (None, None, 4)      0           rpn_model[1][2]                  \\n                                                                 rpn_model[2][2]                  \\n                                                                 rpn_model[3][2]                  \\n                                                                 rpn_model[4][2]                  \\n                                                                 rpn_model[5][2]                  \\n__________________________________________________________________________________________________\\nanchors (Lambda)                (1, 261888, 4)       0           input_image[0][0]                \\n__________________________________________________________________________________________________\\ninput_gt_boxes (InputLayer)     (None, None, 4)      0                                            \\n__________________________________________________________________________________________________\\nROI (ProposalLayer)             (None, 2000, 4)      0           rpn_class[0][0]                  \\n                                                                 rpn_bbox[0][0]                   \\n                                                                 anchors[0][0]                    \\n__________________________________________________________________________________________________\\ninput_gt_class_ids (InputLayer) (None, None)         0                                            \\n__________________________________________________________________________________________________\\nlambda_1 (Lambda)               (None, None, 4)      0           input_gt_boxes[0][0]             \\n__________________________________________________________________________________________________\\ninput_gt_masks (InputLayer)     (None, 56, 56, None) 0                                            \\n__________________________________________________________________________________________________\\nproposal_targets (DetectionTarg [(None, 200, 4), (No 0           ROI[0][0]                        \\n                                                                 input_gt_class_ids[0][0]         \\n                                                                 lambda_1[0][0]                   \\n                                                                 input_gt_masks[0][0]             \\n__________________________________________________________________________________________________\\ninput_image_meta (InputLayer)   (None, 14)           0                                            \\n__________________________________________________________________________________________________\\nroi_align_mask (PyramidROIAlign (None, 200, 14, 14,  0           proposal_targets[0][0]           \\n                                                                 input_image_meta[0][0]           \\n                                                                 fpn_p2[0][0]                     \\n                                                                 fpn_p3[0][0]                     \\n                                                                 fpn_p4[0][0]                     \\n                                                                 fpn_p5[0][0]                     \\n__________________________________________________________________________________________________\\nmrcnn_mask_conv1 (TimeDistribut (None, 200, 14, 14,  590080      roi_align_mask[0][0]             \\n__________________________________________________________________________________________________\\nmrcnn_mask_bn1 (TimeDistributed (None, 200, 14, 14,  1024        mrcnn_mask_conv1[0][0]           \\n__________________________________________________________________________________________________\\nactivation_71 (Activation)      (None, 200, 14, 14,  0           mrcnn_mask_bn1[0][0]             \\n__________________________________________________________________________________________________\\nmrcnn_mask_conv2 (TimeDistribut (None, 200, 14, 14,  590080      activation_71[0][0]              \\n__________________________________________________________________________________________________\\nroi_align_classifier (PyramidRO (None, 200, 7, 7, 25 0           proposal_targets[0][0]           \\n                                                                 input_image_meta[0][0]           \\n                                                                 fpn_p2[0][0]                     \\n                                                                 fpn_p3[0][0]                     \\n                                                                 fpn_p4[0][0]                     \\n                                                                 fpn_p5[0][0]                     \\n__________________________________________________________________________________________________\\nmrcnn_mask_bn2 (TimeDistributed (None, 200, 14, 14,  1024        mrcnn_mask_conv2[0][0]           \\n__________________________________________________________________________________________________\\nmrcnn_class_conv1 (TimeDistribu (None, 200, 1, 1, 10 12846080    roi_align_classifier[0][0]       \\n__________________________________________________________________________________________________\\nactivation_72 (Activation)      (None, 200, 14, 14,  0           mrcnn_mask_bn2[0][0]             \\n__________________________________________________________________________________________________\\nmrcnn_class_bn1 (TimeDistribute (None, 200, 1, 1, 10 4096        mrcnn_class_conv1[0][0]          \\n__________________________________________________________________________________________________\\nmrcnn_mask_conv3 (TimeDistribut (None, 200, 14, 14,  590080      activation_72[0][0]              \\n__________________________________________________________________________________________________\\nactivation_68 (Activation)      (None, 200, 1, 1, 10 0           mrcnn_class_bn1[0][0]            \\n__________________________________________________________________________________________________\\nmrcnn_mask_bn3 (TimeDistributed (None, 200, 14, 14,  1024        mrcnn_mask_conv3[0][0]           \\n__________________________________________________________________________________________________\\nmrcnn_class_conv2 (TimeDistribu (None, 200, 1, 1, 10 1049600     activation_68[0][0]              \\n__________________________________________________________________________________________________\\nactivation_73 (Activation)      (None, 200, 14, 14,  0           mrcnn_mask_bn3[0][0]             \\n__________________________________________________________________________________________________\\nmrcnn_class_bn2 (TimeDistribute (None, 200, 1, 1, 10 4096        mrcnn_class_conv2[0][0]          \\n__________________________________________________________________________________________________\\nmrcnn_mask_conv4 (TimeDistribut (None, 200, 14, 14,  590080      activation_73[0][0]              \\n__________________________________________________________________________________________________\\nactivation_69 (Activation)      (None, 200, 1, 1, 10 0           mrcnn_class_bn2[0][0]            \\n__________________________________________________________________________________________________\\nmrcnn_mask_bn4 (TimeDistributed (None, 200, 14, 14,  1024        mrcnn_mask_conv4[0][0]           \\n__________________________________________________________________________________________________\\npool_squeeze (Lambda)           (None, 200, 1024)    0           activation_69[0][0]              \\n__________________________________________________________________________________________________\\nactivation_74 (Activation)      (None, 200, 14, 14,  0           mrcnn_mask_bn4[0][0]             \\n__________________________________________________________________________________________________\\nmrcnn_bbox_fc (TimeDistributed) (None, 200, 8)       8200        pool_squeeze[0][0]               \\n__________________________________________________________________________________________________\\nmrcnn_mask_deconv (TimeDistribu (None, 200, 28, 28,  262400      activation_74[0][0]              \\n__________________________________________________________________________________________________\\nrpn_class_logits (Concatenate)  (None, None, 2)      0           rpn_model[1][0]                  \\n                                                                 rpn_model[2][0]                  \\n                                                                 rpn_model[3][0]                  \\n                                                                 rpn_model[4][0]                  \\n                                                                 rpn_model[5][0]                  \\n__________________________________________________________________________________________________\\nmrcnn_class_logits (TimeDistrib (None, 200, 2)       2050        pool_squeeze[0][0]               \\n__________________________________________________________________________________________________\\nmrcnn_bbox (Reshape)            (None, 200, 2, 4)    0           mrcnn_bbox_fc[0][0]              \\n__________________________________________________________________________________________________\\nmrcnn_mask (TimeDistributed)    (None, 200, 28, 28,  514         mrcnn_mask_deconv[0][0]          \\n__________________________________________________________________________________________________\\ninput_rpn_match (InputLayer)    (None, None, 1)      0                                            \\n__________________________________________________________________________________________________\\ninput_rpn_bbox (InputLayer)     (None, None, 4)      0                                            \\n__________________________________________________________________________________________________\\nlambda_4 (Lambda)               (None, 2)            0           input_image_meta[0][0]           \\n__________________________________________________________________________________________________\\nmrcnn_class (TimeDistributed)   (None, 200, 2)       0           mrcnn_class_logits[0][0]         \\n__________________________________________________________________________________________________\\noutput_rois (Lambda)            (None, 200, 4)       0           proposal_targets[0][0]           \\n__________________________________________________________________________________________________\\nrpn_class_loss (Lambda)         ()                   0           input_rpn_match[0][0]            \\n                                                                 rpn_class_logits[0][0]           \\n__________________________________________________________________________________________________\\nrpn_bbox_loss (Lambda)          ()                   0           input_rpn_bbox[0][0]             \\n                                                                 input_rpn_match[0][0]            \\n                                                                 rpn_bbox[0][0]                   \\n__________________________________________________________________________________________________\\nmrcnn_class_loss (Lambda)       ()                   0           proposal_targets[0][1]           \\n                                                                 mrcnn_class_logits[0][0]         \\n                                                                 lambda_4[0][0]                   \\n__________________________________________________________________________________________________\\nmrcnn_bbox_loss (Lambda)        ()                   0           proposal_targets[0][2]           \\n                                                                 proposal_targets[0][1]           \\n                                                                 mrcnn_bbox[0][0]                 \\n__________________________________________________________________________________________________\\nmrcnn_mask_loss (Lambda)        ()                   0           proposal_targets[0][3]           \\n                                                                 proposal_targets[0][1]           \\n                                                                 mrcnn_mask[0][0]                 \\n==================================================================================================\\nTotal params: 63,733,406\\nTrainable params: 63,621,918\\nNon-trainable params: 111,488\\n__________________________________________________________________________________________________\\n\"\n    }\n   ],\n   \"source\": [\n    \"model.keras_model.summary()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 24,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class PPDataset(Dataset):\\n\",\n    \"    # load the dataset definitions\\n\",\n    \"    def load_dataset(self, dataset_dir, is_train=True):\\n\",\n    \"        \\n\",\n    \"        # Add classes. We have only one class to add.\\n\",\n    \"        self.add_class(\\\"dataset\\\", 1, \\\"pp\\\")\\n\",\n    \"\\n\",\n    \"        # define data locations for images and annotations\\n\",\n    \"        images_dir = dataset_dir/'images'\\n\",\n    \"        annotations_dir = dataset_dir/'annotations'\\n\",\n    \"        \\n\",\n    \"        # Iterate through all files in the folder to \\n\",\n    \"        #add class, images and annotaions\\n\",\n    \"        for i, image_path in enumerate(images_dir.iterdir()):\\n\",\n    \"            \\n\",\n    \"            # extract image id\\n\",\n    \"            image_id = image_path.stem\\n\",\n    \"    \\n\",\n    \"            # skip all images after 150 if we are building the train set\\n\",\n    \"            if is_train and i >= 200:\\n\",\n    \"                continue\\n\",\n    \"            # skip all images before 150 if we are building the test/val set\\n\",\n    \"            if not is_train and i < 200:\\n\",\n    \"                continue\\n\",\n    \"            \\n\",\n    \"            # setting annotations file\\n\",\n    \"            ann_path = annotations_dir/(str(image_id) + '.xml')\\n\",\n    \"            \\n\",\n    \"            # adding images and annotations to dataset\\n\",\n    \"            self.add_image('dataset', image_id=image_id, path=image_path, annotation=ann_path)\\n\",\n    \"\\n\",\n    \"    # extract bounding boxes from an annotation file\\n\",\n    \"    def extract_boxes(self, filename):\\n\",\n    \"        \\n\",\n    \"        # load and parse the file\\n\",\n    \"        tree = ElementTree.parse(filename)\\n\",\n    \"        # get the root of the document\\n\",\n    \"        root = tree.getroot()\\n\",\n    \"        # extract each bounding box\\n\",\n    \"        boxes = list()\\n\",\n    \"        for box in root.findall('.//bndbox'):\\n\",\n    \"            xmin = int(box.find('xmin').text)\\n\",\n    \"            ymin = int(box.find('ymin').text)\\n\",\n    \"            xmax = int(box.find('xmax').text)\\n\",\n    \"            ymax = int(box.find('ymax').text)\\n\",\n    \"            coors = [xmin, ymin, xmax, ymax]\\n\",\n    \"            boxes.append(coors)\\n\",\n    \"        \\n\",\n    \"        # extract image dimensions\\n\",\n    \"        width = int(root.find('.//size/width').text)\\n\",\n    \"        height = int(root.find('.//size/height').text)\\n\",\n    \"        return boxes, width, height\\n\",\n    \"\\n\",\n    \"    # load the masks for an image\\n\",\n    \"    \\\"\\\"\\\"Generate instance masks for an image.\\n\",\n    \"       Returns:\\n\",\n    \"        masks: A bool array of shape [height, width, instance count] with\\n\",\n    \"            one mask per instance.\\n\",\n    \"        class_ids: a 1D array of class IDs of the instance masks.\\n\",\n    \"     \\\"\\\"\\\"\\n\",\n    \"    def load_mask(self, image_id):\\n\",\n    \"        # get details of image\\n\",\n    \"        info = self.image_info[image_id]\\n\",\n    \"        \\n\",\n    \"        # define anntation  file location\\n\",\n    \"        path = info['annotation']\\n\",\n    \"        \\n\",\n    \"        # load XML\\n\",\n    \"        boxes, w, h = self.extract_boxes(path)\\n\",\n    \"       \\n\",\n    \"        # create one array for all masks, each on a different channel\\n\",\n    \"        masks = zeros([h, w, len(boxes)], dtype='uint8')\\n\",\n    \"        \\n\",\n    \"        # create masks\\n\",\n    \"        class_ids = list()\\n\",\n    \"        for i in range(len(boxes)):\\n\",\n    \"            box = boxes[i]\\n\",\n    \"            row_s, row_e = box[1], box[3]\\n\",\n    \"            col_s, col_e = box[0], box[2]\\n\",\n    \"            masks[row_s:row_e, col_s:col_e, i] = 1\\n\",\n    \"            class_ids.append(self.class_names.index('pp'))\\n\",\n    \"        return masks, asarray(class_ids, dtype='int32')\\n\",\n    \"\\n\",\n    \"    # load an image reference\\n\",\n    \"    #Return the path of the image.\\\"\\\"\\\"\\n\",\n    \"    def image_reference(self, image_id):\\n\",\n    \"        info = self.image_info[image_id]\\n\",\n    \"        print(info)\\n\",\n    \"        return info['path']\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 25,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"data_folder = Path('labeled_images')\\n\",\n    \"\\n\",\n    \"if not data_folder.exists():\\n\",\n    \"    if not (data_folder/'.tar.gz').exists():\\n\",\n    \"        download_file_from_google_drive('1bFiLPB2z4SF6ebJ_gurwyQKYAlmtpeqL', f'{data_folder}.tar.gz')\\n\",\n    \"\\n\",\n    \"    tar = tarfile.open(f'{data_folder}.tar.gz', \\\"r:gz\\\")\\n\",\n    \"    tar.extractall()\\n\",\n    \"    tar.close()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 26,\n   \"metadata\": {\n    \"tags\": []\n   },\n   \"outputs\": [\n    {\n     \"output_type\": \"stream\",\n     \"name\": \"stdout\",\n     \"text\": \"Train: 200\\nTest: 110\\n\"\n    }\n   ],\n   \"source\": [\n    \"# prepare train set\\n\",\n    \"train_set = PPDataset()\\n\",\n    \"train_set.load_dataset(data_folder, is_train=True)\\n\",\n    \"train_set.prepare()\\n\",\n    \"print('Train: %d' % len(train_set.image_ids))\\n\",\n    \"# prepare test/val set\\n\",\n    \"test_set = PPDataset()\\n\",\n    \"test_set.load_dataset(data_folder, is_train=False)\\n\",\n    \"test_set.prepare()\\n\",\n    \"print('Test: %d' % len(test_set.image_ids))\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 27,\n   \"metadata\": {\n    \"tags\": []\n   },\n   \"outputs\": [\n    {\n     \"output_type\": \"stream\",\n     \"name\": \"stdout\",\n     \"text\": \"\\nStarting at epoch 0. LR=0.006\\n\\nCheckpoint Path: ./maskrcnn_config20200730T1557\\\\mask_rcnn_maskrcnn_config_{epoch:04d}.h5\\nSelecting layers to train\\nfpn_c5p5               (Conv2D)\\nfpn_c4p4               (Conv2D)\\nfpn_c3p3               (Conv2D)\\nfpn_c2p2               (Conv2D)\\nfpn_p5                 (Conv2D)\\nfpn_p2                 (Conv2D)\\nfpn_p3                 (Conv2D)\\nfpn_p4                 (Conv2D)\\nIn model:  rpn_model\\n    rpn_conv_shared        (Conv2D)\\n    rpn_class_raw          (Conv2D)\\n    rpn_bbox_pred          (Conv2D)\\nmrcnn_mask_conv1       (TimeDistributed)\\nmrcnn_mask_bn1         (TimeDistributed)\\nmrcnn_mask_conv2       (TimeDistributed)\\nmrcnn_mask_bn2         (TimeDistributed)\\nmrcnn_class_conv1      (TimeDistributed)\\nmrcnn_class_bn1        (TimeDistributed)\\nmrcnn_mask_conv3       (TimeDistributed)\\nmrcnn_mask_bn3         (TimeDistributed)\\nmrcnn_class_conv2      (TimeDistributed)\\nmrcnn_class_bn2        (TimeDistributed)\\nmrcnn_mask_conv4       (TimeDistributed)\\nmrcnn_mask_bn4         (TimeDistributed)\\nmrcnn_bbox_fc          (TimeDistributed)\\nmrcnn_mask_deconv      (TimeDistributed)\\nmrcnn_class_logits     (TimeDistributed)\\nmrcnn_mask             (TimeDistributed)\\nEpoch 1/1\\n  6/131 [>.............................] - ETA: 44:14 - loss: 3.7280 - rpn_class_loss: 0.0043 - rpn_bbox_loss: 0.2835 - mrcnn_class_loss: 0.5508 - mrcnn_bbox_loss: 1.4554 - mrcnn_mask_loss: 1.4340\"\n    },\n    {\n     \"output_type\": \"error\",\n     \"ename\": \"KeyboardInterrupt\",\n     \"evalue\": \"\",\n     \"traceback\": [\n      \"\\u001b[1;31m---------------------------------------------------------------------------\\u001b[0m\",\n      \"\\u001b[1;31mKeyboardInterrupt\\u001b[0m                         Traceback (most recent call last)\",\n      \"\\u001b[1;32m<ipython-input-27-70409532d318>\\u001b[0m in \\u001b[0;36m<module>\\u001b[1;34m\\u001b[0m\\n\\u001b[0;32m      2\\u001b[0m \\u001b[1;31m## train heads with higher lr to speedup the learning\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m      3\\u001b[0m \\u001b[0mepochs\\u001b[0m \\u001b[1;33m=\\u001b[0m \\u001b[1;36m1\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m----> 4\\u001b[1;33m \\u001b[0mmodel\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mtrain\\u001b[0m\\u001b[1;33m(\\u001b[0m\\u001b[0mtrain_set\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mtest_set\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mlearning_rate\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0mconfig\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mLEARNING_RATE\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mepochs\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0mepochs\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mlayers\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[1;34m'heads'\\u001b[0m\\u001b[1;33m)\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[0;32m      5\\u001b[0m \\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m      6\\u001b[0m \\u001b[0mhistory\\u001b[0m \\u001b[1;33m=\\u001b[0m \\u001b[0mmodel\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mkeras_model\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mhistory\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mhistory\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[1;32md:\\\\Vue\\\\TDPDNE\\\\git_repo\\\\Dataset Creator\\\\Mask_RCNN\\\\mrcnn\\\\model.py\\u001b[0m in \\u001b[0;36mtrain\\u001b[1;34m(self, train_dataset, val_dataset, learning_rate, epochs, layers, augmentation, custom_callbacks, no_augmentation_sources)\\u001b[0m\\n\\u001b[0;32m   2372\\u001b[0m             \\u001b[0mmax_queue_size\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[1;36m100\\u001b[0m\\u001b[1;33m,\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m   2373\\u001b[0m             \\u001b[0mworkers\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0mworkers\\u001b[0m\\u001b[1;33m,\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m-> 2374\\u001b[1;33m             \\u001b[0muse_multiprocessing\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[1;32mTrue\\u001b[0m\\u001b[1;33m,\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[0;32m   2375\\u001b[0m         )\\n\\u001b[0;32m   2376\\u001b[0m         \\u001b[0mself\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mepoch\\u001b[0m \\u001b[1;33m=\\u001b[0m \\u001b[0mmax\\u001b[0m\\u001b[1;33m(\\u001b[0m\\u001b[0mself\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mepoch\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mepochs\\u001b[0m\\u001b[1;33m)\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[1;32m~\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\legacy\\\\interfaces.py\\u001b[0m in \\u001b[0;36mwrapper\\u001b[1;34m(*args, **kwargs)\\u001b[0m\\n\\u001b[0;32m     89\\u001b[0m                 warnings.warn('Update your `' + object_name + '` call to the ' +\\n\\u001b[0;32m     90\\u001b[0m                               'Keras 2 API: ' + signature, stacklevel=2)\\n\\u001b[1;32m---> 91\\u001b[1;33m             \\u001b[1;32mreturn\\u001b[0m \\u001b[0mfunc\\u001b[0m\\u001b[1;33m(\\u001b[0m\\u001b[1;33m*\\u001b[0m\\u001b[0margs\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[1;33m**\\u001b[0m\\u001b[0mkwargs\\u001b[0m\\u001b[1;33m)\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[0;32m     92\\u001b[0m         \\u001b[0mwrapper\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0m_original_function\\u001b[0m \\u001b[1;33m=\\u001b[0m \\u001b[0mfunc\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m     93\\u001b[0m         \\u001b[1;32mreturn\\u001b[0m \\u001b[0mwrapper\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[1;32m~\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\engine\\\\training.py\\u001b[0m in \\u001b[0;36mfit_generator\\u001b[1;34m(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, validation_freq, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)\\u001b[0m\\n\\u001b[0;32m   1656\\u001b[0m             \\u001b[0muse_multiprocessing\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0muse_multiprocessing\\u001b[0m\\u001b[1;33m,\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m   1657\\u001b[0m             \\u001b[0mshuffle\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0mshuffle\\u001b[0m\\u001b[1;33m,\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m-> 1658\\u001b[1;33m             initial_epoch=initial_epoch)\\n\\u001b[0m\\u001b[0;32m   1659\\u001b[0m \\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m   1660\\u001b[0m     \\u001b[1;33m@\\u001b[0m\\u001b[0minterfaces\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mlegacy_generator_methods_support\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[1;32m~\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\keras\\\\engine\\\\training_generator.py\\u001b[0m in \\u001b[0;36mfit_generator\\u001b[1;34m(model, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, validation_freq, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)\\u001b[0m\\n\\u001b[0;32m    179\\u001b[0m             \\u001b[0mbatch_index\\u001b[0m \\u001b[1;33m=\\u001b[0m \\u001b[1;36m0\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m    180\\u001b[0m             \\u001b[1;32mwhile\\u001b[0m \\u001b[0msteps_done\\u001b[0m \\u001b[1;33m<\\u001b[0m \\u001b[0msteps_per_epoch\\u001b[0m\\u001b[1;33m:\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m--> 181\\u001b[1;33m                 \\u001b[0mgenerator_output\\u001b[0m \\u001b[1;33m=\\u001b[0m \\u001b[0mnext\\u001b[0m\\u001b[1;33m(\\u001b[0m\\u001b[0moutput_generator\\u001b[0m\\u001b[1;33m)\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[0;32m    182\\u001b[0m \\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m    183\\u001b[0m                 \\u001b[1;32mif\\u001b[0m \\u001b[1;32mnot\\u001b[0m \\u001b[0mhasattr\\u001b[0m\\u001b[1;33m(\\u001b[0m\\u001b[0mgenerator_output\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[1;34m'__len__'\\u001b[0m\\u001b[1;33m)\\u001b[0m\\u001b[1;33m:\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[1;32md:\\\\Vue\\\\TDPDNE\\\\git_repo\\\\Dataset Creator\\\\Mask_RCNN\\\\mrcnn\\\\model.py\\u001b[0m in \\u001b[0;36mdata_generator\\u001b[1;34m(dataset, config, shuffle, augment, augmentation, random_rois, batch_size, detection_targets, no_augmentation_sources)\\u001b[0m\\n\\u001b[0;32m   1707\\u001b[0m                     load_image_gt(dataset, config, image_id, augment=augment,\\n\\u001b[0;32m   1708\\u001b[0m                                 \\u001b[0maugmentation\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0maugmentation\\u001b[0m\\u001b[1;33m,\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m-> 1709\\u001b[1;33m                                 use_mini_mask=config.USE_MINI_MASK)\\n\\u001b[0m\\u001b[0;32m   1710\\u001b[0m \\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m   1711\\u001b[0m             \\u001b[1;31m# Skip images that have no instances. This can happen in cases\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[1;32md:\\\\Vue\\\\TDPDNE\\\\git_repo\\\\Dataset Creator\\\\Mask_RCNN\\\\mrcnn\\\\model.py\\u001b[0m in \\u001b[0;36mload_image_gt\\u001b[1;34m(dataset, config, image_id, augment, augmentation, use_mini_mask)\\u001b[0m\\n\\u001b[0;32m   1217\\u001b[0m         \\u001b[0mmin_scale\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0mconfig\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mIMAGE_MIN_SCALE\\u001b[0m\\u001b[1;33m,\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m   1218\\u001b[0m         \\u001b[0mmax_dim\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0mconfig\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mIMAGE_MAX_DIM\\u001b[0m\\u001b[1;33m,\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m-> 1219\\u001b[1;33m         mode=config.IMAGE_RESIZE_MODE)\\n\\u001b[0m\\u001b[0;32m   1220\\u001b[0m     \\u001b[0mmask\\u001b[0m \\u001b[1;33m=\\u001b[0m \\u001b[0mutils\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mresize_mask\\u001b[0m\\u001b[1;33m(\\u001b[0m\\u001b[0mmask\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mscale\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mpadding\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mcrop\\u001b[0m\\u001b[1;33m)\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m   1221\\u001b[0m \\u001b[1;33m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[1;32md:\\\\Vue\\\\TDPDNE\\\\git_repo\\\\Dataset Creator\\\\Mask_RCNN\\\\mrcnn\\\\utils.py\\u001b[0m in \\u001b[0;36mresize_image\\u001b[1;34m(image, min_dim, max_dim, min_scale, mode)\\u001b[0m\\n\\u001b[0;32m    446\\u001b[0m     \\u001b[1;32mif\\u001b[0m \\u001b[0mscale\\u001b[0m \\u001b[1;33m!=\\u001b[0m \\u001b[1;36m1\\u001b[0m\\u001b[1;33m:\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m    447\\u001b[0m         image = resize(image, (round(h * scale), round(w * scale)),\\n\\u001b[1;32m--> 448\\u001b[1;33m                        preserve_range=True)\\n\\u001b[0m\\u001b[0;32m    449\\u001b[0m \\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m    450\\u001b[0m     \\u001b[1;31m# Need padding or cropping?\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[1;32md:\\\\Vue\\\\TDPDNE\\\\git_repo\\\\Dataset Creator\\\\Mask_RCNN\\\\mrcnn\\\\utils.py\\u001b[0m in \\u001b[0;36mresize\\u001b[1;34m(image, output_shape, order, mode, cval, clip, preserve_range, anti_aliasing, anti_aliasing_sigma)\\u001b[0m\\n\\u001b[0;32m    901\\u001b[0m             \\u001b[0morder\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0morder\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mmode\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0mmode\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mcval\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0mcval\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mclip\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0mclip\\u001b[0m\\u001b[1;33m,\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m    902\\u001b[0m             \\u001b[0mpreserve_range\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0mpreserve_range\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0manti_aliasing\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0manti_aliasing\\u001b[0m\\u001b[1;33m,\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m--> 903\\u001b[1;33m             anti_aliasing_sigma=anti_aliasing_sigma)\\n\\u001b[0m\\u001b[0;32m    904\\u001b[0m     \\u001b[1;32melse\\u001b[0m\\u001b[1;33m:\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m    905\\u001b[0m         return skimage.transform.resize(\\n\",\n      \"\\u001b[1;32m~\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\skimage\\\\transform\\\\_warps.py\\u001b[0m in \\u001b[0;36mresize\\u001b[1;34m(image, output_shape, order, mode, cval, clip, preserve_range, anti_aliasing, anti_aliasing_sigma)\\u001b[0m\\n\\u001b[0;32m    164\\u001b[0m         out = warp(image, tform, output_shape=output_shape, order=order,\\n\\u001b[0;32m    165\\u001b[0m                    \\u001b[0mmode\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0mmode\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mcval\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0mcval\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mclip\\u001b[0m\\u001b[1;33m=\\u001b[0m\\u001b[0mclip\\u001b[0m\\u001b[1;33m,\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m--> 166\\u001b[1;33m                    preserve_range=preserve_range)\\n\\u001b[0m\\u001b[0;32m    167\\u001b[0m \\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m    168\\u001b[0m     \\u001b[1;32melse\\u001b[0m\\u001b[1;33m:\\u001b[0m  \\u001b[1;31m# n-dimensional interpolation\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[1;32m~\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\skimage\\\\transform\\\\_warps.py\\u001b[0m in \\u001b[0;36mwarp\\u001b[1;34m(image, inverse_map, map_args, output_shape, order, mode, cval, clip, preserve_range)\\u001b[0m\\n\\u001b[0;32m    807\\u001b[0m         \\u001b[1;32mraise\\u001b[0m \\u001b[0mValueError\\u001b[0m\\u001b[1;33m(\\u001b[0m\\u001b[1;34m\\\"Cannot warp empty image with dimensions\\\"\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mimage\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mshape\\u001b[0m\\u001b[1;33m)\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m    808\\u001b[0m \\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m--> 809\\u001b[1;33m     \\u001b[0mimage\\u001b[0m \\u001b[1;33m=\\u001b[0m \\u001b[0mconvert_to_float\\u001b[0m\\u001b[1;33m(\\u001b[0m\\u001b[0mimage\\u001b[0m\\u001b[1;33m,\\u001b[0m \\u001b[0mpreserve_range\\u001b[0m\\u001b[1;33m)\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[0;32m    810\\u001b[0m \\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m    811\\u001b[0m     \\u001b[0minput_shape\\u001b[0m \\u001b[1;33m=\\u001b[0m \\u001b[0mnp\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0marray\\u001b[0m\\u001b[1;33m(\\u001b[0m\\u001b[0mimage\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mshape\\u001b[0m\\u001b[1;33m)\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[1;32m~\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\lib\\\\site-packages\\\\skimage\\\\_shared\\\\utils.py\\u001b[0m in \\u001b[0;36mconvert_to_float\\u001b[1;34m(image, preserve_range)\\u001b[0m\\n\\u001b[0;32m    252\\u001b[0m         \\u001b[1;31m# precision float\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m    253\\u001b[0m         \\u001b[1;32mif\\u001b[0m \\u001b[0mimage\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mdtype\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mchar\\u001b[0m \\u001b[1;32mnot\\u001b[0m \\u001b[1;32min\\u001b[0m \\u001b[1;34m'df'\\u001b[0m\\u001b[1;33m:\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[1;32m--> 254\\u001b[1;33m             \\u001b[0mimage\\u001b[0m \\u001b[1;33m=\\u001b[0m \\u001b[0mimage\\u001b[0m\\u001b[1;33m.\\u001b[0m\\u001b[0mastype\\u001b[0m\\u001b[1;33m(\\u001b[0m\\u001b[0mfloat\\u001b[0m\\u001b[1;33m)\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0m\\u001b[0;32m    255\\u001b[0m     \\u001b[1;32melse\\u001b[0m\\u001b[1;33m:\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\\u001b[0;32m    256\\u001b[0m         \\u001b[0mimage\\u001b[0m \\u001b[1;33m=\\u001b[0m \\u001b[0mimg_as_float\\u001b[0m\\u001b[1;33m(\\u001b[0m\\u001b[0mimage\\u001b[0m\\u001b[1;33m)\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[1;33m\\u001b[0m\\u001b[0m\\n\",\n      \"\\u001b[1;31mKeyboardInterrupt\\u001b[0m: \"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# train weights (output layers or 'heads')\\n\",\n    \"## train heads with higher lr to speedup the learning\\n\",\n    \"epochs = 1\\n\",\n    \"model.train(train_set, test_set, learning_rate=config.LEARNING_RATE, epochs=epochs, layers='heads')\\n\",\n    \"\\n\",\n    \"history = model.keras_model.history.history\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 20,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"output_type\": \"execute_result\",\n     \"data\": {\n      \"text/plain\": \"[<keras.layers.convolutional.Conv2D at 0x1ec6c7b2fc8>,\\n <mrcnn.model.BatchNorm at 0x1ec6c7b68c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c7deac8>,\\n <mrcnn.model.BatchNorm at 0x1ec6c7e8308>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c7f2dc8>,\\n <mrcnn.model.BatchNorm at 0x1ec6c7f1588>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c813bc8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c821148>,\\n <mrcnn.model.BatchNorm at 0x1ec6c805888>,\\n <mrcnn.model.BatchNorm at 0x1ec6c82b748>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c844248>,\\n <mrcnn.model.BatchNorm at 0x1ec6c841d48>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c85cb48>,\\n <mrcnn.model.BatchNorm at 0x1ec6c85ef88>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c872bc8>,\\n <mrcnn.model.BatchNorm at 0x1ec6c873308>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c88d308>,\\n <mrcnn.model.BatchNorm at 0x1ec6c87ad88>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c8a4c08>,\\n <mrcnn.model.BatchNorm at 0x1ec6c8aa0c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c8bbc88>,\\n <mrcnn.model.BatchNorm at 0x1ec6c8c13c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c8d60c8>,\\n <mrcnn.model.BatchNorm at 0x1ec6c8d7e88>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c8e7d48>,\\n <mrcnn.model.BatchNorm at 0x1ec6c8ed208>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c905cc8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c911148>,\\n <mrcnn.model.BatchNorm at 0x1ec6c908588>,\\n <mrcnn.model.BatchNorm at 0x1ec6c920488>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c937788>,\\n <mrcnn.model.BatchNorm at 0x1ec6c934c08>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c949b08>,\\n <mrcnn.model.BatchNorm at 0x1ec6c952f88>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c965e88>,\\n <mrcnn.model.BatchNorm at 0x1ec6c96a348>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c977188>,\\n <mrcnn.model.BatchNorm at 0x1ec6c982ec8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c998dc8>,\\n <mrcnn.model.BatchNorm at 0x1ec6c994288>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c9aed48>,\\n <mrcnn.model.BatchNorm at 0x1ec6c9b1608>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c9ca3c8>,\\n <mrcnn.model.BatchNorm at 0x1ec6c9ce1c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c9dfc88>,\\n <mrcnn.model.BatchNorm at 0x1ec6c9e4548>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6c9fcc08>,\\n <mrcnn.model.BatchNorm at 0x1ec6c9f68c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6ca10048>,\\n <mrcnn.model.BatchNorm at 0x1ec6ca14448>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6ca2cb48>,\\n <mrcnn.model.BatchNorm at 0x1ec6ca1f808>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6ca44ec8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6ca51388>,\\n <mrcnn.model.BatchNorm at 0x1ec6ca35b88>,\\n <mrcnn.model.BatchNorm at 0x1ec6ca5f308>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6da43408>,\\n <mrcnn.model.BatchNorm at 0x1ec6da48248>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6da5bd08>,\\n <mrcnn.model.BatchNorm at 0x1ec6da575c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6da76c88>,\\n <mrcnn.model.BatchNorm at 0x1ec6da78948>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6da850c8>,\\n <mrcnn.model.BatchNorm at 0x1ec6da93508>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6daa8bc8>,\\n <mrcnn.model.BatchNorm at 0x1ec6daa1888>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dabf988>,\\n <mrcnn.model.BatchNorm at 0x1ec6dabcc08>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dad93c8>,\\n <mrcnn.model.BatchNorm at 0x1ec6dadb7c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6daf0e88>,\\n <mrcnn.model.BatchNorm at 0x1ec6daedb48>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6db07848>,\\n <mrcnn.model.BatchNorm at 0x1ec6db0bec8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6db26688>,\\n <mrcnn.model.BatchNorm at 0x1ec6db22a88>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6db3a748>,\\n <mrcnn.model.BatchNorm at 0x1ec6db3fe08>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6db52d08>,\\n <mrcnn.model.BatchNorm at 0x1ec6db581c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6db6b248>,\\n <mrcnn.model.BatchNorm at 0x1ec6db6dd48>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6db83c48>,\\n <mrcnn.model.BatchNorm at 0x1ec6db8a108>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6db9bfc8>,\\n <mrcnn.model.BatchNorm at 0x1ec6db96488>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dbb6248>,\\n <mrcnn.model.BatchNorm at 0x1ec6dbbb048>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dbcdf08>,\\n <mrcnn.model.BatchNorm at 0x1ec6dbd33c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dbe1b08>,\\n <mrcnn.model.BatchNorm at 0x1ec6dbe8748>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dbfe608>,\\n <mrcnn.model.BatchNorm at 0x1ec6dc04308>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dc0bc88>,\\n <mrcnn.model.BatchNorm at 0x1ec6dc12948>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dc2dc08>,\\n <mrcnn.model.BatchNorm at 0x1ec6dc1fd08>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dc4b4c8>,\\n <mrcnn.model.BatchNorm at 0x1ec6dc4c8c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dc61748>,\\n <mrcnn.model.BatchNorm at 0x1ec6dc5fc48>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dc78948>,\\n <mrcnn.model.BatchNorm at 0x1ec6dc7f048>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dc93788>,\\n <mrcnn.model.BatchNorm at 0x1ec6dc96bc8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dca9ac8>,\\n <mrcnn.model.BatchNorm at 0x1ec6dcadf48>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dcc2c48>,\\n <mrcnn.model.BatchNorm at 0x1ec6dcc7348>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dcd93c8>,\\n <mrcnn.model.BatchNorm at 0x1ec6dcddec8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dcf4dc8>,\\n <mrcnn.model.BatchNorm at 0x1ec6dcfa288>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dd0bf88>,\\n <mrcnn.model.BatchNorm at 0x1ec6dd0f648>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dd27408>,\\n <mrcnn.model.BatchNorm at 0x1ec6dd2b208>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dd3dcc8>,\\n <mrcnn.model.BatchNorm at 0x1ec6dd35588>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dd57c48>,\\n <mrcnn.model.BatchNorm at 0x1ec6dd58908>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dd67088>,\\n <mrcnn.model.BatchNorm at 0x1ec6dd76508>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dd8abc8>,\\n <mrcnn.model.BatchNorm at 0x1ec6dd85888>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dda2748>,\\n <mrcnn.model.BatchNorm at 0x1ec6dda4c48>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6ddbc408>,\\n <mrcnn.model.BatchNorm at 0x1ec6ddbf808>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6ddd48c8>,\\n <mrcnn.model.BatchNorm at 0x1ec6ddd3b88>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6ddeaac8>,\\n <mrcnn.model.BatchNorm at 0x1ec6ddeef48>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6de08688>,\\n <mrcnn.model.BatchNorm at 0x1ec6de00b08>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6de1e808>,\\n <mrcnn.model.BatchNorm at 0x1ec6de21e88>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6de36dc8>,\\n <mrcnn.model.BatchNorm at 0x1ec6de3a288>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6de4f308>,\\n <mrcnn.model.BatchNorm at 0x1ec6de51e08>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6de62d08>,\\n <mrcnn.model.BatchNorm at 0x1ec6de6c1c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6de7fcc8>,\\n <mrcnn.model.BatchNorm at 0x1ec6de83588>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6de9a348>,\\n <mrcnn.model.BatchNorm at 0x1ec6de9f148>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6deb0388>,\\n <mrcnn.model.BatchNorm at 0x1ec6deb64c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6deccbc8>,\\n <mrcnn.model.BatchNorm at 0x1ec6decd888>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dee0108>,\\n <mrcnn.model.BatchNorm at 0x1ec6dee4448>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6defcb08>,\\n <mrcnn.model.BatchNorm at 0x1ec6deee7c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6df15ec8>,\\n <mrcnn.model.BatchNorm at 0x1ec6df05b88>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6df32348>,\\n <mrcnn.model.BatchNorm at 0x1ec6df2f748>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6df48e08>,\\n <mrcnn.model.BatchNorm at 0x1ec6df38ac8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6df5e808>,\\n <mrcnn.model.BatchNorm at 0x1ec6df63e88>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6df7a5c8>,\\n <mrcnn.model.BatchNorm at 0x1ec6df7ca48>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6df8c708>,\\n <mrcnn.model.BatchNorm at 0x1ec6df93dc8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dfa6d08>,\\n <mrcnn.model.BatchNorm at 0x1ec6dfad1c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dfc1248>,\\n <mrcnn.model.BatchNorm at 0x1ec6dfc4d48>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dfd9c48>,\\n <mrcnn.model.BatchNorm at 0x1ec6dfe1108>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6dff13c8>,\\n <mrcnn.model.BatchNorm at 0x1ec6dff64c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e00c288>,\\n <mrcnn.model.BatchNorm at 0x1ec6e011088>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e024f48>,\\n <mrcnn.model.BatchNorm at 0x1ec6e029408>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e038508>,\\n <mrcnn.model.BatchNorm at 0x1ec6e02f7c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e057588>,\\n <mrcnn.model.BatchNorm at 0x1ec6e05c388>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e070ac8>,\\n <mrcnn.model.BatchNorm at 0x1ec6e071708>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e088e08>,\\n <mrcnn.model.BatchNorm at 0x1ec6e084ac8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e0a3288>,\\n <mrcnn.model.BatchNorm at 0x1ec6e0a5688>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e0b9d48>,\\n <mrcnn.model.BatchNorm at 0x1ec6e0baa08>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e0d2708>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e0de5c8>,\\n <mrcnn.model.BatchNorm at 0x1ec6e0d6dc8>,\\n <mrcnn.model.BatchNorm at 0x1ec6e0ed548>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e0f8048>,\\n <mrcnn.model.BatchNorm at 0x1ec6e103488>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e11db48>,\\n <mrcnn.model.BatchNorm at 0x1ec6e116808>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e130f08>,\\n <mrcnn.model.BatchNorm at 0x1ec6e124bc8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e14f308>,\\n <mrcnn.model.BatchNorm at 0x1ec6e14e788>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e165e48>,\\n <mrcnn.model.BatchNorm at 0x1ec6e163b08>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e178908>,\\n <mrcnn.model.BatchNorm at 0x1ec6e182ec8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e14f288>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e1a5208>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6e1b6ec8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6f195188>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6f1bde88>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6f199e48>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6f1aa388>,\\n <keras.layers.convolutional.Conv2D at 0x1ec6f1b2bc8>,\\n <keras.engine.training.Model at 0x1ec6f2150c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec70173d88>,\\n <mrcnn.model.BatchNorm at 0x1ec701d9288>,\\n <keras.layers.convolutional.Conv2D at 0x1ec701efd08>,\\n <mrcnn.model.BatchNorm at 0x1ec701f5048>,\\n <keras.layers.convolutional.Conv2D at 0x1ec700a83c8>,\\n <mrcnn.model.BatchNorm at 0x1ec7010f488>,\\n <keras.layers.convolutional.Conv2D at 0x1ec70211b48>,\\n <mrcnn.model.BatchNorm at 0x1ec70213e48>,\\n <keras.layers.convolutional.Conv2D at 0x1ec7012ae88>,\\n <mrcnn.model.BatchNorm at 0x1ec701321c8>,\\n <keras.layers.convolutional.Conv2D at 0x1ec7022e988>,\\n <mrcnn.model.BatchNorm at 0x1ec70232c88>,\\n <keras.layers.core.Dense at 0x1ec70157188>,\\n <keras.layers.convolutional.Conv2DTranspose at 0x1ec7024c788>,\\n <keras.layers.core.Dense at 0x1ec7014a788>,\\n <keras.layers.convolutional.Conv2D at 0x1ec7024fa48>]\"\n     },\n     \"metadata\": {},\n     \"execution_count\": 20\n    }\n   ],\n   \"source\": [\n    \"model.get_trainable_layers()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 30,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"model_path = f'mask_rcnn_model.h5'\\n\",\n    \"model.keras_model.save_weights(model_path)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 28,\n   \"metadata\": {\n    \"tags\": []\n   },\n   \"outputs\": [\n    {\n     \"output_type\": \"stream\",\n     \"name\": \"stdout\",\n     \"text\": \"\\nConfigurations:\\nBACKBONE                       resnet101\\nBACKBONE_STRIDES               [4, 8, 16, 32, 64]\\nBATCH_SIZE                     1\\nBBOX_STD_DEV                   [0.1 0.1 0.2 0.2]\\nCOMPUTE_BACKBONE_SHAPE         None\\nDETECTION_MAX_INSTANCES        100\\nDETECTION_MIN_CONFIDENCE       0.9\\nDETECTION_NMS_THRESHOLD        0.3\\nFPN_CLASSIF_FC_LAYERS_SIZE     1024\\nGPU_COUNT                      1\\nGRADIENT_CLIP_NORM             5.0\\nIMAGES_PER_GPU                 1\\nIMAGE_CHANNEL_COUNT            3\\nIMAGE_MAX_DIM                  1024\\nIMAGE_META_SIZE                14\\nIMAGE_MIN_DIM                  800\\nIMAGE_MIN_SCALE                0\\nIMAGE_RESIZE_MODE              square\\nIMAGE_SHAPE                    [1024 1024    3]\\nLEARNING_MOMENTUM              0.9\\nLEARNING_RATE                  0.006\\nLOSS_WEIGHTS                   {'rpn_class_loss': 1.0, 'rpn_bbox_loss': 1.0, 'mrcnn_class_loss': 1.0, 'mrcnn_bbox_loss': 1.0, 'mrcnn_mask_loss': 1.0}\\nMASK_POOL_SIZE                 14\\nMASK_SHAPE                     [28, 28]\\nMAX_GT_INSTANCES               10\\nMEAN_PIXEL                     [123.7 116.8 103.9]\\nMINI_MASK_SHAPE                (56, 56)\\nNAME                           MaskRCNN_config\\nNUM_CLASSES                    2\\nPOOL_SIZE                      7\\nPOST_NMS_ROIS_INFERENCE        1000\\nPOST_NMS_ROIS_TRAINING         2000\\nPRE_NMS_LIMIT                  6000\\nROI_POSITIVE_RATIO             0.33\\nRPN_ANCHOR_RATIOS              [0.5, 1, 2]\\nRPN_ANCHOR_SCALES              (32, 64, 128, 256, 512)\\nRPN_ANCHOR_STRIDE              1\\nRPN_BBOX_STD_DEV               [0.1 0.1 0.2 0.2]\\nRPN_NMS_THRESHOLD              0.7\\nRPN_TRAIN_ANCHORS_PER_IMAGE    256\\nSTEPS_PER_EPOCH                131\\nTOP_DOWN_PYRAMID_SIZE          256\\nTRAIN_BN                       False\\nTRAIN_ROIS_PER_IMAGE           200\\nUSE_MINI_MASK                  True\\nUSE_RPN_ROIS                   True\\nVALIDATION_STEPS               50\\nWEIGHT_DECAY                   0.0001\\n\\n\\n\"\n    }\n   ],\n   \"source\": [\n    \"# class that defines and loads the kangaroo dataset\\n\",\n    \"\\n\",\n    \"# prepare config\\n\",\n    \"config = myMaskRCNNConfig()\\n\",\n    \"config.display()\\n\",\n    \"# define the model\\n\",\n    \"model = MaskRCNN(mode='training', model_dir='./', config=config)\\n\",\n    \"\\n\",\n    \"# load weights (mscoco) and exclude the output layers\\n\",\n    \"\\n\",\n    \"model.load_weights(model_path, by_name=True)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 29,\n   \"metadata\": {\n    \"tags\": []\n   },\n   \"outputs\": [\n    {\n     \"output_type\": \"stream\",\n     \"name\": \"stdout\",\n     \"text\": \"(800, 600, 3)\\n[0 1]\\n(800, 600, 1)\\n[1]\\n\"\n    },\n    {\n     \"output_type\": \"display_data\",\n     \"data\": {\n      \"text/plain\": \"<Figure size 432x288 with 1 Axes>\",\n      \"image/svg+xml\": \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\" standalone=\\\"no\\\"?>\\r\\n<!DOCTYPE svg PUBLIC \\\"-//W3C//DTD SVG 1.1//EN\\\"\\r\\n  \\\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\\\">\\r\\n<!-- Created with matplotlib (https://matplotlib.org/) -->\\r\\n<svg height=\\\"252.181444pt\\\" version=\\\"1.1\\\" viewBox=\\\"0 0 203.5675 252.181444\\\" width=\\\"203.5675pt\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" xmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\">\\r\\n <defs>\\r\\n  <style type=\\\"text/css\\\">\\r\\n*{stroke-linecap:butt;stroke-linejoin:round;}\\r\\n  </style>\\r\\n </defs>\\r\\n <g id=\\\"figure_1\\\">\\r\\n  <g id=\\\"patch_1\\\">\\r\\n   <path d=\\\"M 0 252.181444 \\r\\nL 203.5675 252.181444 \\r\\nL 203.5675 0 \\r\\nL 0 0 \\r\\nz\\r\\n\\\" style=\\\"fill:none;\\\"/>\\r\\n  </g>\\r\\n  <g id=\\\"axes_1\\\">\\r\\n   <g id=\\\"patch_2\\\">\\r\\n    <path d=\\\"M 33.2875 228.303319 \\r\\nL 196.3675 228.303319 \\r\\nL 196.3675 10.863319 \\r\\nL 33.2875 10.863319 \\r\\nz\\r\\n\\\" style=\\\"fill:#ffffff;\\\"/>\\r\\n   </g>\\r\\n   <g clip-path=\\\"url(#p54fb5baeed)\\\">\\r\\n    <image height=\\\"218\\\" id=\\\"imagec4dd16c967\\\" transform=\\\"scale(1 -1)translate(0 -218)\\\" width=\\\"164\\\" x=\\\"33\\\" xlink:href=\\\"data:image/png;base64,\\r\\n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\\\" y=\\\"-10.181444\\\"/>\\r\\n   </g>\\r\\n   <g id=\\\"matplotlib.axis_1\\\">\\r\\n    <g id=\\\"xtick_1\\\">\\r\\n     <g id=\\\"line2d_1\\\">\\r\\n      <defs>\\r\\n       <path d=\\\"M 0 0 \\r\\nL 0 3.5 \\r\\n\\\" id=\\\"md3ad19a830\\\" style=\\\"stroke:#000000;stroke-width:0.8;\\\"/>\\r\\n      </defs>\\r\\n      <g>\\r\\n       <use style=\\\"stroke:#000000;stroke-width:0.8;\\\" x=\\\"33.4234\\\" xlink:href=\\\"#md3ad19a830\\\" y=\\\"228.303319\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n     <g id=\\\"text_1\\\">\\r\\n      <!-- 0 -->\\r\\n      <defs>\\r\\n       <path d=\\\"M 31.78125 66.40625 \\r\\nQ 24.171875 66.40625 20.328125 58.90625 \\r\\nQ 16.5 51.421875 16.5 36.375 \\r\\nQ 16.5 21.390625 20.328125 13.890625 \\r\\nQ 24.171875 6.390625 31.78125 6.390625 \\r\\nQ 39.453125 6.390625 43.28125 13.890625 \\r\\nQ 47.125 21.390625 47.125 36.375 \\r\\nQ 47.125 51.421875 43.28125 58.90625 \\r\\nQ 39.453125 66.40625 31.78125 66.40625 \\r\\nz\\r\\nM 31.78125 74.21875 \\r\\nQ 44.046875 74.21875 50.515625 64.515625 \\r\\nQ 56.984375 54.828125 56.984375 36.375 \\r\\nQ 56.984375 17.96875 50.515625 8.265625 \\r\\nQ 44.046875 -1.421875 31.78125 -1.421875 \\r\\nQ 19.53125 -1.421875 13.0625 8.265625 \\r\\nQ 6.59375 17.96875 6.59375 36.375 \\r\\nQ 6.59375 54.828125 13.0625 64.515625 \\r\\nQ 19.53125 74.21875 31.78125 74.21875 \\r\\nz\\r\\n\\\" id=\\\"DejaVuSans-48\\\"/>\\r\\n      </defs>\\r\\n      <g transform=\\\"translate(30.24215 242.901756)scale(0.1 -0.1)\\\">\\r\\n       <use xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n    </g>\\r\\n    <g id=\\\"xtick_2\\\">\\r\\n     <g id=\\\"line2d_2\\\">\\r\\n      <g>\\r\\n       <use style=\\\"stroke:#000000;stroke-width:0.8;\\\" x=\\\"87.7834\\\" xlink:href=\\\"#md3ad19a830\\\" y=\\\"228.303319\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n     <g id=\\\"text_2\\\">\\r\\n      <!-- 200 -->\\r\\n      <defs>\\r\\n       <path d=\\\"M 19.1875 8.296875 \\r\\nL 53.609375 8.296875 \\r\\nL 53.609375 0 \\r\\nL 7.328125 0 \\r\\nL 7.328125 8.296875 \\r\\nQ 12.9375 14.109375 22.625 23.890625 \\r\\nQ 32.328125 33.6875 34.8125 36.53125 \\r\\nQ 39.546875 41.84375 41.421875 45.53125 \\r\\nQ 43.3125 49.21875 43.3125 52.78125 \\r\\nQ 43.3125 58.59375 39.234375 62.25 \\r\\nQ 35.15625 65.921875 28.609375 65.921875 \\r\\nQ 23.96875 65.921875 18.8125 64.3125 \\r\\nQ 13.671875 62.703125 7.8125 59.421875 \\r\\nL 7.8125 69.390625 \\r\\nQ 13.765625 71.78125 18.9375 73 \\r\\nQ 24.125 74.21875 28.421875 74.21875 \\r\\nQ 39.75 74.21875 46.484375 68.546875 \\r\\nQ 53.21875 62.890625 53.21875 53.421875 \\r\\nQ 53.21875 48.921875 51.53125 44.890625 \\r\\nQ 49.859375 40.875 45.40625 35.40625 \\r\\nQ 44.1875 33.984375 37.640625 27.21875 \\r\\nQ 31.109375 20.453125 19.1875 8.296875 \\r\\nz\\r\\n\\\" id=\\\"DejaVuSans-50\\\"/>\\r\\n      </defs>\\r\\n      <g transform=\\\"translate(78.23965 242.901756)scale(0.1 -0.1)\\\">\\r\\n       <use xlink:href=\\\"#DejaVuSans-50\\\"/>\\r\\n       <use x=\\\"63.623047\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n       <use x=\\\"127.246094\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n    </g>\\r\\n    <g id=\\\"xtick_3\\\">\\r\\n     <g id=\\\"line2d_3\\\">\\r\\n      <g>\\r\\n       <use style=\\\"stroke:#000000;stroke-width:0.8;\\\" x=\\\"142.1434\\\" xlink:href=\\\"#md3ad19a830\\\" y=\\\"228.303319\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n     <g id=\\\"text_3\\\">\\r\\n      <!-- 400 -->\\r\\n      <defs>\\r\\n       <path d=\\\"M 37.796875 64.3125 \\r\\nL 12.890625 25.390625 \\r\\nL 37.796875 25.390625 \\r\\nz\\r\\nM 35.203125 72.90625 \\r\\nL 47.609375 72.90625 \\r\\nL 47.609375 25.390625 \\r\\nL 58.015625 25.390625 \\r\\nL 58.015625 17.1875 \\r\\nL 47.609375 17.1875 \\r\\nL 47.609375 0 \\r\\nL 37.796875 0 \\r\\nL 37.796875 17.1875 \\r\\nL 4.890625 17.1875 \\r\\nL 4.890625 26.703125 \\r\\nz\\r\\n\\\" id=\\\"DejaVuSans-52\\\"/>\\r\\n      </defs>\\r\\n      <g transform=\\\"translate(132.59965 242.901756)scale(0.1 -0.1)\\\">\\r\\n       <use xlink:href=\\\"#DejaVuSans-52\\\"/>\\r\\n       <use x=\\\"63.623047\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n       <use x=\\\"127.246094\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n    </g>\\r\\n   </g>\\r\\n   <g id=\\\"matplotlib.axis_2\\\">\\r\\n    <g id=\\\"ytick_1\\\">\\r\\n     <g id=\\\"line2d_4\\\">\\r\\n      <defs>\\r\\n       <path d=\\\"M 0 0 \\r\\nL -3.5 0 \\r\\n\\\" id=\\\"mad14233197\\\" style=\\\"stroke:#000000;stroke-width:0.8;\\\"/>\\r\\n      </defs>\\r\\n      <g>\\r\\n       <use style=\\\"stroke:#000000;stroke-width:0.8;\\\" x=\\\"33.2875\\\" xlink:href=\\\"#mad14233197\\\" y=\\\"10.999219\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n     <g id=\\\"text_4\\\">\\r\\n      <!-- 0 -->\\r\\n      <g transform=\\\"translate(19.925 14.798438)scale(0.1 -0.1)\\\">\\r\\n       <use xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n    </g>\\r\\n    <g id=\\\"ytick_2\\\">\\r\\n     <g id=\\\"line2d_5\\\">\\r\\n      <g>\\r\\n       <use style=\\\"stroke:#000000;stroke-width:0.8;\\\" x=\\\"33.2875\\\" xlink:href=\\\"#mad14233197\\\" y=\\\"38.179219\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n     <g id=\\\"text_5\\\">\\r\\n      <!-- 100 -->\\r\\n      <defs>\\r\\n       <path d=\\\"M 12.40625 8.296875 \\r\\nL 28.515625 8.296875 \\r\\nL 28.515625 63.921875 \\r\\nL 10.984375 60.40625 \\r\\nL 10.984375 69.390625 \\r\\nL 28.421875 72.90625 \\r\\nL 38.28125 72.90625 \\r\\nL 38.28125 8.296875 \\r\\nL 54.390625 8.296875 \\r\\nL 54.390625 0 \\r\\nL 12.40625 0 \\r\\nz\\r\\n\\\" id=\\\"DejaVuSans-49\\\"/>\\r\\n      </defs>\\r\\n      <g transform=\\\"translate(7.2 41.978438)scale(0.1 -0.1)\\\">\\r\\n       <use xlink:href=\\\"#DejaVuSans-49\\\"/>\\r\\n       <use x=\\\"63.623047\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n       <use x=\\\"127.246094\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n    </g>\\r\\n    <g id=\\\"ytick_3\\\">\\r\\n     <g id=\\\"line2d_6\\\">\\r\\n      <g>\\r\\n       <use style=\\\"stroke:#000000;stroke-width:0.8;\\\" x=\\\"33.2875\\\" xlink:href=\\\"#mad14233197\\\" y=\\\"65.359219\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n     <g id=\\\"text_6\\\">\\r\\n      <!-- 200 -->\\r\\n      <g transform=\\\"translate(7.2 69.158438)scale(0.1 -0.1)\\\">\\r\\n       <use xlink:href=\\\"#DejaVuSans-50\\\"/>\\r\\n       <use x=\\\"63.623047\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n       <use x=\\\"127.246094\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n    </g>\\r\\n    <g id=\\\"ytick_4\\\">\\r\\n     <g id=\\\"line2d_7\\\">\\r\\n      <g>\\r\\n       <use style=\\\"stroke:#000000;stroke-width:0.8;\\\" x=\\\"33.2875\\\" xlink:href=\\\"#mad14233197\\\" y=\\\"92.539219\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n     <g id=\\\"text_7\\\">\\r\\n      <!-- 300 -->\\r\\n      <defs>\\r\\n       <path d=\\\"M 40.578125 39.3125 \\r\\nQ 47.65625 37.796875 51.625 33 \\r\\nQ 55.609375 28.21875 55.609375 21.1875 \\r\\nQ 55.609375 10.40625 48.1875 4.484375 \\r\\nQ 40.765625 -1.421875 27.09375 -1.421875 \\r\\nQ 22.515625 -1.421875 17.65625 -0.515625 \\r\\nQ 12.796875 0.390625 7.625 2.203125 \\r\\nL 7.625 11.71875 \\r\\nQ 11.71875 9.328125 16.59375 8.109375 \\r\\nQ 21.484375 6.890625 26.8125 6.890625 \\r\\nQ 36.078125 6.890625 40.9375 10.546875 \\r\\nQ 45.796875 14.203125 45.796875 21.1875 \\r\\nQ 45.796875 27.640625 41.28125 31.265625 \\r\\nQ 36.765625 34.90625 28.71875 34.90625 \\r\\nL 20.21875 34.90625 \\r\\nL 20.21875 43.015625 \\r\\nL 29.109375 43.015625 \\r\\nQ 36.375 43.015625 40.234375 45.921875 \\r\\nQ 44.09375 48.828125 44.09375 54.296875 \\r\\nQ 44.09375 59.90625 40.109375 62.90625 \\r\\nQ 36.140625 65.921875 28.71875 65.921875 \\r\\nQ 24.65625 65.921875 20.015625 65.03125 \\r\\nQ 15.375 64.15625 9.8125 62.3125 \\r\\nL 9.8125 71.09375 \\r\\nQ 15.4375 72.65625 20.34375 73.4375 \\r\\nQ 25.25 74.21875 29.59375 74.21875 \\r\\nQ 40.828125 74.21875 47.359375 69.109375 \\r\\nQ 53.90625 64.015625 53.90625 55.328125 \\r\\nQ 53.90625 49.265625 50.4375 45.09375 \\r\\nQ 46.96875 40.921875 40.578125 39.3125 \\r\\nz\\r\\n\\\" id=\\\"DejaVuSans-51\\\"/>\\r\\n      </defs>\\r\\n      <g transform=\\\"translate(7.2 96.338437)scale(0.1 -0.1)\\\">\\r\\n       <use xlink:href=\\\"#DejaVuSans-51\\\"/>\\r\\n       <use x=\\\"63.623047\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n       <use x=\\\"127.246094\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n    </g>\\r\\n    <g id=\\\"ytick_5\\\">\\r\\n     <g id=\\\"line2d_8\\\">\\r\\n      <g>\\r\\n       <use style=\\\"stroke:#000000;stroke-width:0.8;\\\" x=\\\"33.2875\\\" xlink:href=\\\"#mad14233197\\\" y=\\\"119.719219\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n     <g id=\\\"text_8\\\">\\r\\n      <!-- 400 -->\\r\\n      <g transform=\\\"translate(7.2 123.518438)scale(0.1 -0.1)\\\">\\r\\n       <use xlink:href=\\\"#DejaVuSans-52\\\"/>\\r\\n       <use x=\\\"63.623047\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n       <use x=\\\"127.246094\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n    </g>\\r\\n    <g id=\\\"ytick_6\\\">\\r\\n     <g id=\\\"line2d_9\\\">\\r\\n      <g>\\r\\n       <use style=\\\"stroke:#000000;stroke-width:0.8;\\\" x=\\\"33.2875\\\" xlink:href=\\\"#mad14233197\\\" y=\\\"146.899219\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n     <g id=\\\"text_9\\\">\\r\\n      <!-- 500 -->\\r\\n      <defs>\\r\\n       <path d=\\\"M 10.796875 72.90625 \\r\\nL 49.515625 72.90625 \\r\\nL 49.515625 64.59375 \\r\\nL 19.828125 64.59375 \\r\\nL 19.828125 46.734375 \\r\\nQ 21.96875 47.46875 24.109375 47.828125 \\r\\nQ 26.265625 48.1875 28.421875 48.1875 \\r\\nQ 40.625 48.1875 47.75 41.5 \\r\\nQ 54.890625 34.8125 54.890625 23.390625 \\r\\nQ 54.890625 11.625 47.5625 5.09375 \\r\\nQ 40.234375 -1.421875 26.90625 -1.421875 \\r\\nQ 22.3125 -1.421875 17.546875 -0.640625 \\r\\nQ 12.796875 0.140625 7.71875 1.703125 \\r\\nL 7.71875 11.625 \\r\\nQ 12.109375 9.234375 16.796875 8.0625 \\r\\nQ 21.484375 6.890625 26.703125 6.890625 \\r\\nQ 35.15625 6.890625 40.078125 11.328125 \\r\\nQ 45.015625 15.765625 45.015625 23.390625 \\r\\nQ 45.015625 31 40.078125 35.4375 \\r\\nQ 35.15625 39.890625 26.703125 39.890625 \\r\\nQ 22.75 39.890625 18.8125 39.015625 \\r\\nQ 14.890625 38.140625 10.796875 36.28125 \\r\\nz\\r\\n\\\" id=\\\"DejaVuSans-53\\\"/>\\r\\n      </defs>\\r\\n      <g transform=\\\"translate(7.2 150.698438)scale(0.1 -0.1)\\\">\\r\\n       <use xlink:href=\\\"#DejaVuSans-53\\\"/>\\r\\n       <use x=\\\"63.623047\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n       <use x=\\\"127.246094\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n    </g>\\r\\n    <g id=\\\"ytick_7\\\">\\r\\n     <g id=\\\"line2d_10\\\">\\r\\n      <g>\\r\\n       <use style=\\\"stroke:#000000;stroke-width:0.8;\\\" x=\\\"33.2875\\\" xlink:href=\\\"#mad14233197\\\" y=\\\"174.079219\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n     <g id=\\\"text_10\\\">\\r\\n      <!-- 600 -->\\r\\n      <defs>\\r\\n       <path d=\\\"M 33.015625 40.375 \\r\\nQ 26.375 40.375 22.484375 35.828125 \\r\\nQ 18.609375 31.296875 18.609375 23.390625 \\r\\nQ 18.609375 15.53125 22.484375 10.953125 \\r\\nQ 26.375 6.390625 33.015625 6.390625 \\r\\nQ 39.65625 6.390625 43.53125 10.953125 \\r\\nQ 47.40625 15.53125 47.40625 23.390625 \\r\\nQ 47.40625 31.296875 43.53125 35.828125 \\r\\nQ 39.65625 40.375 33.015625 40.375 \\r\\nz\\r\\nM 52.59375 71.296875 \\r\\nL 52.59375 62.3125 \\r\\nQ 48.875 64.0625 45.09375 64.984375 \\r\\nQ 41.3125 65.921875 37.59375 65.921875 \\r\\nQ 27.828125 65.921875 22.671875 59.328125 \\r\\nQ 17.53125 52.734375 16.796875 39.40625 \\r\\nQ 19.671875 43.65625 24.015625 45.921875 \\r\\nQ 28.375 48.1875 33.59375 48.1875 \\r\\nQ 44.578125 48.1875 50.953125 41.515625 \\r\\nQ 57.328125 34.859375 57.328125 23.390625 \\r\\nQ 57.328125 12.15625 50.6875 5.359375 \\r\\nQ 44.046875 -1.421875 33.015625 -1.421875 \\r\\nQ 20.359375 -1.421875 13.671875 8.265625 \\r\\nQ 6.984375 17.96875 6.984375 36.375 \\r\\nQ 6.984375 53.65625 15.1875 63.9375 \\r\\nQ 23.390625 74.21875 37.203125 74.21875 \\r\\nQ 40.921875 74.21875 44.703125 73.484375 \\r\\nQ 48.484375 72.75 52.59375 71.296875 \\r\\nz\\r\\n\\\" id=\\\"DejaVuSans-54\\\"/>\\r\\n      </defs>\\r\\n      <g transform=\\\"translate(7.2 177.878437)scale(0.1 -0.1)\\\">\\r\\n       <use xlink:href=\\\"#DejaVuSans-54\\\"/>\\r\\n       <use x=\\\"63.623047\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n       <use x=\\\"127.246094\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n    </g>\\r\\n    <g id=\\\"ytick_8\\\">\\r\\n     <g id=\\\"line2d_11\\\">\\r\\n      <g>\\r\\n       <use style=\\\"stroke:#000000;stroke-width:0.8;\\\" x=\\\"33.2875\\\" xlink:href=\\\"#mad14233197\\\" y=\\\"201.259219\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n     <g id=\\\"text_11\\\">\\r\\n      <!-- 700 -->\\r\\n      <defs>\\r\\n       <path d=\\\"M 8.203125 72.90625 \\r\\nL 55.078125 72.90625 \\r\\nL 55.078125 68.703125 \\r\\nL 28.609375 0 \\r\\nL 18.3125 0 \\r\\nL 43.21875 64.59375 \\r\\nL 8.203125 64.59375 \\r\\nz\\r\\n\\\" id=\\\"DejaVuSans-55\\\"/>\\r\\n      </defs>\\r\\n      <g transform=\\\"translate(7.2 205.058437)scale(0.1 -0.1)\\\">\\r\\n       <use xlink:href=\\\"#DejaVuSans-55\\\"/>\\r\\n       <use x=\\\"63.623047\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n       <use x=\\\"127.246094\\\" xlink:href=\\\"#DejaVuSans-48\\\"/>\\r\\n      </g>\\r\\n     </g>\\r\\n    </g>\\r\\n   </g>\\r\\n   <g id=\\\"patch_3\\\">\\r\\n    <path d=\\\"M 33.2875 228.303319 \\r\\nL 33.2875 10.863319 \\r\\n\\\" style=\\\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;\\\"/>\\r\\n   </g>\\r\\n   <g id=\\\"patch_4\\\">\\r\\n    <path d=\\\"M 196.3675 228.303319 \\r\\nL 196.3675 10.863319 \\r\\n\\\" style=\\\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;\\\"/>\\r\\n   </g>\\r\\n   <g id=\\\"patch_5\\\">\\r\\n    <path d=\\\"M 33.2875 228.303319 \\r\\nL 196.3675 228.303319 \\r\\n\\\" style=\\\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;\\\"/>\\r\\n   </g>\\r\\n   <g id=\\\"patch_6\\\">\\r\\n    <path d=\\\"M 33.2875 10.863319 \\r\\nL 196.3675 10.863319 \\r\\n\\\" style=\\\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;\\\"/>\\r\\n   </g>\\r\\n  </g>\\r\\n </g>\\r\\n <defs>\\r\\n  <clipPath id=\\\"p54fb5baeed\\\">\\r\\n   <rect height=\\\"217.44\\\" width=\\\"163.08\\\" x=\\\"33.2875\\\" y=\\\"10.863319\\\"/>\\r\\n  </clipPath>\\r\\n </defs>\\r\\n</svg>\\r\\n\",\n      \"image/png\": \"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\\n\"\n     },\n     \"metadata\": {\n      \"needs_background\": \"light\"\n     }\n    }\n   ],\n   \"source\": [\n    \"# load an image\\n\",\n    \"image_id = 20\\n\",\n    \"image = test_set.load_image(image_id)\\n\",\n    \"print(image.shape)\\n\",\n    \"print(test_set.class_ids)\\n\",\n    \"# load image mask\\n\",\n    \"mask, class_ids = test_set.load_mask(image_id)\\n\",\n    \"\\n\",\n    \"print(mask.shape)\\n\",\n    \"print(class_ids)\\n\",\n    \"# plot image\\n\",\n    \"pyplot.imshow(image)\\n\",\n    \"# plot mask\\n\",\n    \"pyplot.imshow(mask[:, :, 0], cmap='gray', alpha=0.4)\\n\",\n    \"\\n\",\n    \"pyplot.show()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 33,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def get_ax(rows=1, cols=1, size=16):\\n\",\n    \"    \\\"\\\"\\\"Return a Matplotlib Axes array to be used in\\n\",\n    \"    all visualizations in the notebook. Provide a\\n\",\n    \"    central point to control graph sizes.\\n\",\n    \"    \\n\",\n    \"    Adjust the size attribute to control how big to render images\\n\",\n    \"    \\\"\\\"\\\"\\n\",\n    \"    _, ax = pyplot.subplots(rows, cols, figsize=(size*cols, size*rows))\\n\",\n    \"    return ax\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 34,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from keras.preprocessing.image import load_img\\n\",\n    \"from keras.preprocessing.image import img_to_array\\n\",\n    \"\\n\",\n    \"#Loading the model in the inference mode\\n\",\n    \"model = modellib.MaskRCNN(mode=\\\"inference\\\", config=config, model_dir='./')\\n\",\n    \"\\n\",\n    \"# loading the trained weights o the custom dataset\\n\",\n    \"model.load_weights(model_path, by_name=True)\\n\",\n    \"img = load_img(r\\\"D:\\\\Datasets\\\\reddit submissions\\\\dk\\\\images\\\\qjeeer3lgdm01.jpg\\\")\\n\",\n    \"img = img_to_array(img)\\n\",\n    \"\\n\",\n    \"# detecting objects in the image\\n\",\n    \"result= model.detect([img])\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 51,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"data\": {\n      \"text/plain\": [\n       \"['BG', 'pp']\"\n      ]\n     },\n     \"execution_count\": 51,\n     \"metadata\": {},\n     \"output_type\": \"execute_result\"\n    }\n   ],\n   \"source\": [\n    \"test_set.class_names\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 57,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"{'id': '0h4sb9p716m11', 'source': 'dataset', 'path': WindowsPath('D:/Datasets/reddit submissions/dk/labeled_images/images/0h4sb9p716m11.jpg'), 'annotation': WindowsPath('D:/Datasets/reddit submissions/dk/labeled_images/annotations/0h4sb9p716m11.xml')}\\n\",\n      \"image ID: dataset.0h4sb9p716m11 (8) D:\\\\Datasets\\\\reddit submissions\\\\dk\\\\labeled_images\\\\images\\\\0h4sb9p716m11.jpg\\n\",\n      \"Processing 1 images\\n\",\n      \"image                    shape: (1024, 1024, 3)       min:    0.00000  max:  255.00000  uint8\\n\",\n      \"molded_images            shape: (1, 1024, 1024, 3)    min: -123.70000  max:  151.10000  float64\\n\",\n      \"image_metas              shape: (1, 14)               min:    0.00000  max: 1024.00000  int32\\n\",\n      \"anchors                  shape: (1, 261888, 4)        min:   -0.35390  max:    1.29134  float32\\n\"\n     ]\n    },\n    {\n     \"data\": {\n      \"image/png\": \"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\\n\",\n      \"text/plain\": [\n       \"<Figure size 1152x1152 with 1 Axes>\"\n      ]\n     },\n     \"metadata\": {\n      \"needs_background\": \"light\"\n     },\n     \"output_type\": \"display_data\"\n    }\n   ],\n   \"source\": [\n    \"#image_id = random.choice(test_set.image_ids)\\n\",\n    \"\\n\",\n    \"image_id = 8\\n\",\n    \"image, image_meta, gt_class_id, gt_bbox, gt_mask = modellib.load_image_gt(test_set, config, image_id, use_mini_mask=False)\\n\",\n    \"info = test_set.image_info[image_id]\\n\",\n    \"print(\\\"image ID: {}.{} ({}) {}\\\".format(info[\\\"source\\\"], info[\\\"id\\\"], image_id, \\n\",\n    \"                                       test_set.image_reference(image_id)))\\n\",\n    \"# Run object detection\\n\",\n    \"results = model.detect([image], verbose=1)\\n\",\n    \"\\n\",\n    \"# Display results\\n\",\n    \"\\n\",\n    \"r = results[0]\\n\",\n    \"visualize.display_instances(image, r['rois'], r['masks'], r['class_ids'], \\n\",\n    \"                            test_set.class_names, r['scores'],\\n\",\n    \"                            title=\\\"Predictions\\\")\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 24,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"[[  56  446 2261 1372]]\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from mrcnn.visualize import display_instances\\n\",\n    \"r = result[0]\\n\",\n    \"print(r['rois'])\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.5-final\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}"
  },
  {
    "path": "Image Processor/LICENSE",
    "content": "Mask R-CNN\n\nThe MIT License (MIT)\n\nCopyright (c) 2017 Matterport, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "Image Processor/MANIFEST.in",
    "content": "include README.md\ninclude LICENSE\ninclude requirements.txt"
  },
  {
    "path": "Image Processor/README.md",
    "content": "# Mask R-CNN for Object Detection and Segmentation\n\nThis is an implementation of [Mask R-CNN](https://arxiv.org/abs/1703.06870) on Python 3, Keras, and TensorFlow. The model generates bounding boxes and segmentation masks for each instance of an object in the image. It's based on Feature Pyramid Network (FPN) and a ResNet101 backbone.\n\n![Instance Segmentation Sample](assets/street.png)\n\nThe repository includes:\n* Source code of Mask R-CNN built on FPN and ResNet101.\n* Training code for MS COCO\n* Pre-trained weights for MS COCO\n* Jupyter notebooks to visualize the detection pipeline at every step\n* ParallelModel class for multi-GPU training\n* Evaluation on MS COCO metrics (AP)\n* Example of training on your own dataset\n\n\nThe code is documented and designed to be easy to extend. If you use it in your research, please consider citing this repository (bibtex below). If you work on 3D vision, you might find our recently released [Matterport3D](https://matterport.com/blog/2017/09/20/announcing-matterport3d-research-dataset/) dataset useful as well.\nThis dataset was created from 3D-reconstructed spaces captured by our customers who agreed to make them publicly available for academic use. You can see more examples [here](https://matterport.com/gallery/).\n\n# Getting Started\n* [demo.ipynb](samples/demo.ipynb) Is the easiest way to start. It shows an example of using a model pre-trained on MS COCO to segment objects in your own images.\nIt includes code to run object detection and instance segmentation on arbitrary images.\n\n* [train_shapes.ipynb](samples/shapes/train_shapes.ipynb) shows how to train Mask R-CNN on your own dataset. This notebook introduces a toy dataset (Shapes) to demonstrate training on a new dataset.\n\n* ([model.py](mrcnn/model.py), [utils.py](mrcnn/utils.py), [config.py](mrcnn/config.py)): These files contain the main Mask RCNN implementation. \n\n\n* [inspect_data.ipynb](samples/coco/inspect_data.ipynb). This notebook visualizes the different pre-processing steps\nto prepare the training data.\n\n* [inspect_model.ipynb](samples/coco/inspect_model.ipynb) This notebook goes in depth into the steps performed to detect and segment objects. It provides visualizations of every step of the pipeline.\n\n* [inspect_weights.ipynb](samples/coco/inspect_weights.ipynb)\nThis notebooks inspects the weights of a trained model and looks for anomalies and odd patterns.\n\n\n# Step by Step Detection\nTo help with debugging and understanding the model, there are 3 notebooks \n([inspect_data.ipynb](samples/coco/inspect_data.ipynb), [inspect_model.ipynb](samples/coco/inspect_model.ipynb),\n[inspect_weights.ipynb](samples/coco/inspect_weights.ipynb)) that provide a lot of visualizations and allow running the model step by step to inspect the output at each point. Here are a few examples:\n\n\n\n## 1. Anchor sorting and filtering\nVisualizes every step of the first stage Region Proposal Network and displays positive and negative anchors along with anchor box refinement.\n![](assets/detection_anchors.png)\n\n## 2. Bounding Box Refinement\nThis is an example of final detection boxes (dotted lines) and the refinement applied to them (solid lines) in the second stage.\n![](assets/detection_refinement.png)\n\n## 3. Mask Generation\nExamples of generated masks. These then get scaled and placed on the image in the right location.\n\n![](assets/detection_masks.png)\n\n## 4.Layer activations\nOften it's useful to inspect the activations at different layers to look for signs of trouble (all zeros or random noise).\n\n![](assets/detection_activations.png)\n\n## 5. Weight Histograms\nAnother useful debugging tool is to inspect the weight histograms. These are included in the inspect_weights.ipynb notebook.\n\n![](assets/detection_histograms.png)\n\n## 6. Logging to TensorBoard\nTensorBoard is another great debugging and visualization tool. The model is configured to log losses and save weights at the end of every epoch.\n\n![](assets/detection_tensorboard.png)\n\n## 6. Composing the different pieces into a final result\n\n![](assets/detection_final.png)\n\n\n# Training on MS COCO\nWe're providing pre-trained weights for MS COCO to make it easier to start. You can\nuse those weights as a starting point to train your own variation on the network.\nTraining and evaluation code is in `samples/coco/coco.py`. You can import this\nmodule in Jupyter notebook (see the provided notebooks for examples) or you\ncan run it directly from the command line as such:\n\n```\n# Train a new model starting from pre-trained COCO weights\npython3 samples/coco/coco.py train --dataset=/path/to/coco/ --model=coco\n\n# Train a new model starting from ImageNet weights\npython3 samples/coco/coco.py train --dataset=/path/to/coco/ --model=imagenet\n\n# Continue training a model that you had trained earlier\npython3 samples/coco/coco.py train --dataset=/path/to/coco/ --model=/path/to/weights.h5\n\n# Continue training the last model you trained. This will find\n# the last trained weights in the model directory.\npython3 samples/coco/coco.py train --dataset=/path/to/coco/ --model=last\n```\n\nYou can also run the COCO evaluation code with:\n```\n# Run COCO evaluation on the last trained model\npython3 samples/coco/coco.py evaluate --dataset=/path/to/coco/ --model=last\n```\n\nThe training schedule, learning rate, and other parameters should be set in `samples/coco/coco.py`.\n\n\n# Training on Your Own Dataset\n\nStart by reading this [blog post about the balloon color splash sample](https://engineering.matterport.com/splash-of-color-instance-segmentation-with-mask-r-cnn-and-tensorflow-7c761e238b46). It covers the process starting from annotating images to training to using the results in a sample application.\n\nIn summary, to train the model on your own dataset you'll need to extend two classes:\n\n```Config```\nThis class contains the default configuration. Subclass it and modify the attributes you need to change.\n\n```Dataset```\nThis class provides a consistent way to work with any dataset. \nIt allows you to use new datasets for training without having to change \nthe code of the model. It also supports loading multiple datasets at the\nsame time, which is useful if the objects you want to detect are not \nall available in one dataset. \n\nSee examples in `samples/shapes/train_shapes.ipynb`, `samples/coco/coco.py`, `samples/balloon/balloon.py`, and `samples/nucleus/nucleus.py`.\n\n## Differences from the Official Paper\nThis implementation follows the Mask RCNN paper for the most part, but there are a few cases where we deviated in favor of code simplicity and generalization. These are some of the differences we're aware of. If you encounter other differences, please do let us know.\n\n* **Image Resizing:** To support training multiple images per batch we resize all images to the same size. For example, 1024x1024px on MS COCO. We preserve the aspect ratio, so if an image is not square we pad it with zeros. In the paper the resizing is done such that the smallest side is 800px and the largest is trimmed at 1000px.\n* **Bounding Boxes**: Some datasets provide bounding boxes and some provide masks only. To support training on multiple datasets we opted to ignore the bounding boxes that come with the dataset and generate them on the fly instead. We pick the smallest box that encapsulates all the pixels of the mask as the bounding box. This simplifies the implementation and also makes it easy to apply image augmentations that would otherwise be harder to apply to bounding boxes, such as image rotation.\n\n    To validate this approach, we compared our computed bounding boxes to those provided by the COCO dataset.\nWe found that ~2% of bounding boxes differed by 1px or more, ~0.05% differed by 5px or more, \nand only 0.01% differed by 10px or more.\n\n* **Learning Rate:** The paper uses a learning rate of 0.02, but we found that to be\ntoo high, and often causes the weights to explode, especially when using a small batch\nsize. It might be related to differences between how Caffe and TensorFlow compute \ngradients (sum vs mean across batches and GPUs). Or, maybe the official model uses gradient\nclipping to avoid this issue. We do use gradient clipping, but don't set it too aggressively.\nWe found that smaller learning rates converge faster anyway so we go with that.\n\n## Citation\nUse this bibtex to cite this repository:\n```\n@misc{matterport_maskrcnn_2017,\n  title={Mask R-CNN for object detection and instance segmentation on Keras and TensorFlow},\n  author={Waleed Abdulla},\n  year={2017},\n  publisher={Github},\n  journal={GitHub repository},\n  howpublished={\\url{https://github.com/matterport/Mask_RCNN}},\n}\n```\n\n## Contributing\nContributions to this repository are welcome. Examples of things you can contribute:\n* Speed Improvements. Like re-writing some Python code in TensorFlow or Cython.\n* Training on other datasets.\n* Accuracy Improvements.\n* Visualizations and examples.\n\nYou can also [join our team](https://matterport.com/careers/) and help us build even more projects like this one.\n\n## Requirements\nPython 3.4, TensorFlow 1.3, Keras 2.0.8 and other common packages listed in `requirements.txt`.\n\n### MS COCO Requirements:\nTo train or test on MS COCO, you'll also need:\n* pycocotools (installation instructions below)\n* [MS COCO Dataset](http://cocodataset.org/#home)\n* Download the 5K [minival](https://dl.dropboxusercontent.com/s/o43o90bna78omob/instances_minival2014.json.zip?dl=0)\n  and the 35K [validation-minus-minival](https://dl.dropboxusercontent.com/s/s3tw5zcg7395368/instances_valminusminival2014.json.zip?dl=0)\n  subsets. More details in the original [Faster R-CNN implementation](https://github.com/rbgirshick/py-faster-rcnn/blob/master/data/README.md).\n\nIf you use Docker, the code has been verified to work on\n[this Docker container](https://hub.docker.com/r/waleedka/modern-deep-learning/).\n\n\n## Installation\n1. Clone this repository\n2. Install dependencies\n   ```bash\n   pip3 install -r requirements.txt\n   ```\n3. Run setup from the repository root directory\n    ```bash\n    python3 setup.py install\n    ``` \n3. Download pre-trained COCO weights (mask_rcnn_coco.h5) from the [releases page](https://github.com/matterport/Mask_RCNN/releases).\n4. (Optional) To train or test on MS COCO install `pycocotools` from one of these repos. They are forks of the original pycocotools with fixes for Python3 and Windows (the official repo doesn't seem to be active anymore).\n\n    * Linux: https://github.com/waleedka/coco\n    * Windows: https://github.com/philferriere/cocoapi.\n    You must have the Visual C++ 2015 build tools on your path (see the repo for additional details)\n\n# Projects Using this Model\nIf you extend this model to other datasets or build projects that use it, we'd love to hear from you.\n\n### [4K Video Demo](https://www.youtube.com/watch?v=OOT3UIXZztE) by Karol Majek.\n[![Mask RCNN on 4K Video](assets/4k_video.gif)](https://www.youtube.com/watch?v=OOT3UIXZztE)\n\n### [Images to OSM](https://github.com/jremillard/images-to-osm): Improve OpenStreetMap by adding baseball, soccer, tennis, football, and basketball fields.\n\n![Identify sport fields in satellite images](assets/images_to_osm.png)\n\n### [Splash of Color](https://engineering.matterport.com/splash-of-color-instance-segmentation-with-mask-r-cnn-and-tensorflow-7c761e238b46). A blog post explaining how to train this model from scratch and use it to implement a color splash effect.\n![Balloon Color Splash](assets/balloon_color_splash.gif)\n\n\n### [Segmenting Nuclei in Microscopy Images](samples/nucleus). Built for the [2018 Data Science Bowl](https://www.kaggle.com/c/data-science-bowl-2018)\nCode is in the `samples/nucleus` directory.\n\n![Nucleus Segmentation](assets/nucleus_segmentation.png)\n\n### [Detection and Segmentation for Surgery Robots](https://github.com/SUYEgit/Surgery-Robot-Detection-Segmentation) by the NUS Control & Mechatronics Lab.\n![Surgery Robot Detection and Segmentation](https://github.com/SUYEgit/Surgery-Robot-Detection-Segmentation/raw/master/assets/video.gif)\n\n### [Reconstructing 3D buildings from aerial LiDAR](https://medium.com/geoai/reconstructing-3d-buildings-from-aerial-lidar-with-ai-details-6a81cb3079c0)\nA proof of concept project by [Esri](https://www.esri.com/), in collaboration with Nvidia and Miami-Dade County. Along with a great write up and code by Dmitry Kudinov, Daniel Hedges, and Omar Maher.\n![3D Building Reconstruction](assets/project_3dbuildings.png)\n\n### [Usiigaci: Label-free Cell Tracking in Phase Contrast Microscopy](https://github.com/oist/usiigaci)\nA project from Japan to automatically track cells in a microfluidics platform. Paper is pending, but the source code is released.\n\n![](assets/project_usiigaci1.gif) ![](assets/project_usiigaci2.gif)\n\n### [Characterization of Arctic Ice-Wedge Polygons in Very High Spatial Resolution Aerial Imagery](http://www.mdpi.com/2072-4292/10/9/1487)\nResearch project to understand the complex processes between degradations in the Arctic and climate change. By Weixing Zhang, Chandi Witharana, Anna Liljedahl, and Mikhail Kanevskiy.\n![image](assets/project_ice_wedge_polygons.png)\n\n### [Mask-RCNN Shiny](https://github.com/huuuuusy/Mask-RCNN-Shiny)\nA computer vision class project by HU Shiyu to apply the color pop effect on people with beautiful results.\n![](assets/project_shiny1.jpg)\n\n### [Mapping Challenge](https://github.com/crowdAI/crowdai-mapping-challenge-mask-rcnn): Convert satellite imagery to maps for use by humanitarian organisations.\n![Mapping Challenge](assets/mapping_challenge.png)\n\n### [GRASS GIS Addon](https://github.com/ctu-geoforall-lab/i.ann.maskrcnn) to generate vector masks from geospatial imagery. Based on a [Master's thesis](https://github.com/ctu-geoforall-lab-projects/dp-pesek-2018) by Ondřej Pešek.\n![GRASS GIS Image](assets/project_grass_gis.png)\n"
  },
  {
    "path": "Image Processor/__init__.py",
    "content": ""
  },
  {
    "path": "Image Processor/align_images.py",
    "content": "import math\r\nimport pickle\r\nfrom pathlib import Path\r\nfrom random import randint\r\nimport json\r\nfrom multiprocessing import Pool, Queue\r\nimport traceback\r\n\r\nimport cv2\r\nimport numpy as np\r\nfrom keras.preprocessing.image import img_to_array, load_img\r\nfrom tqdm import tqdm\r\n\r\nimport cv_tools\r\nfrom mrcnn import model as modellib\r\nfrom mrcnn import visualize\r\nfrom mrcnn.config import Config\r\n\r\ndef multi_worker(queue):\r\n    while 1:\r\n        try:\r\n            align_data = queue.get()\r\n            if isinstance(align_data, str) and align_data == 'kill process':\r\n                print('Killing listener.')\r\n                break\r\n            try:\r\n                aligned = align(**align_data['mask_info'])\r\n                padded = pad_image(aligned)\r\n                cv2.imwrite(str(align_data['save_name']), padded)\r\n            except:\r\n                pass\r\n        except:\r\n            # prints exceptions from another process\r\n            traceback.print_exc()\r\n            pass\r\n\r\ndef vis(image_path, r):\r\n    img = load_img(image_path)\r\n    img = img_to_array(img)\r\n    visualize.display_instances(img, r['rois'], r['masks'], r['class_ids'],\r\n                                ['BG', 'pp'], r['scores'],\r\n                                title=\"Predictions\")\r\n\r\n\r\ndef detect(model, image_path):\r\n    image = load_img(image_path)\r\n    image = img_to_array(image)\r\n\r\n    result = model.detect([image])\r\n\r\n    return result[0]\r\n\r\n\r\ndef align(image, mask_rcnn_res):\r\n    top_left, bottom_right, mask = get_best_bbox(mask_rcnn_res)\r\n    mask_img = (mask*255).astype(np.uint8)\r\n    centre, e1, _ = cv_tools.compute_PCA(mask_img)\r\n\r\n    # make a binary image to represent the bounding box so we can rotate later\r\n    bb_mask = make_bb_mask(image, top_left, bottom_right)\r\n\r\n    tilt_angle = get_tilt(centre, e1)\r\n\r\n    rotated = rotate_image(image, -tilt_angle, image_centre=centre)\r\n    rotated_mask = rotate_image(bb_mask, -tilt_angle, image_centre=centre)\r\n\r\n    top_left, bottom_right = get_largest_bbox(rotated_mask)\r\n\r\n    cropped = cv_tools.crop(rotated, top_left, bottom_right)\r\n\r\n    return cropped\r\n\r\n\r\ndef pad_image(image, side_length=512):\r\n    padded_image = cv_tools.pad_to_square(image)\r\n    resize_dim = (side_length, side_length)\r\n\r\n    if padded_image.shape[0] < side_length:\r\n        interpolation = cv2.INTER_CUBIC\r\n        padded_image = cv2.resize(padded_image, resize_dim,\r\n                                  interpolation=interpolation)\r\n    elif padded_image.shape[0] > side_length:\r\n        interpolation = cv2.INTER_AREA\r\n        padded_image = cv2.resize(padded_image, resize_dim,\r\n                                  interpolation=interpolation)\r\n\r\n    return padded_image\r\n\r\n\r\ndef get_largest_bbox(mask):\r\n    foreground_rows, foreground_cols = np.where(mask == 1)\r\n\r\n    top_left = min(foreground_cols), min(foreground_rows)\r\n    bottom_right = max(foreground_cols), max(foreground_rows)\r\n\r\n    mask = cv2.cvtColor((mask*255).astype(np.uint8), cv2.COLOR_GRAY2BGR)\r\n    cv2.rectangle(mask, top_left, bottom_right, (255, 0, 0), 2)\r\n    # cv_tools.show(cv_tools.resize(mask, 0.3))\r\n\r\n    return top_left, bottom_right\r\n\r\n\r\ndef rotate_image(image, angle, image_centre=None):\r\n    if image_centre is None:\r\n        image_centre = tuple(np.array(image.shape[1::-1]) / 2)\r\n    rot_mat = cv2.getRotationMatrix2D(image_centre, angle, 1.0)\r\n    result = cv2.warpAffine(\r\n        image, rot_mat, image.shape[1::-1], flags=cv2.INTER_LINEAR)\r\n    return result\r\n\r\n\r\ndef make_bb_mask(image, top_left, bottom_right):\r\n    x1, y1 = top_left[0], top_left[1]\r\n    x2, y2 = bottom_right[0], bottom_right[1]\r\n    height, width = image.shape[:2]\r\n\r\n    bb_mask = np.zeros((height, width))\r\n\r\n    bb_mask[y1:y2, x1:x2] = 1\r\n\r\n    return bb_mask\r\n\r\n\r\ndef angle_trunc(a):\r\n    while a < 0.0:\r\n        a += math.pi * 2\r\n    return a\r\n\r\n\r\ndef get_tilt(p1, p2, tilt_from='vertical', degrees=True):\r\n\r\n    if not tilt_from in ['vertical', 'horizontal']:\r\n        raise ValueError('Tilt must be calculated from vertical or horizontal')\r\n\r\n    x1, y1 = p1[0], p1[1]\r\n    x2, y2 = p2[0], p2[1]\r\n    deltaY = y2 - y1\r\n    deltaX = x2 - x1\r\n\r\n    rads = angle_trunc(math.atan2(deltaY, deltaX))\r\n    if abs(rads) > math.pi:\r\n        rads = -(2*math.pi - rads)\r\n    if tilt_from == 'vertical':\r\n        rads = math.pi/2 - rads\r\n    if degrees:\r\n        return math.degrees(rads)\r\n    return rads\r\n\r\n\r\ndef get_best_bbox(result):\r\n    best_index = np.argmax(result['scores'])\r\n    y1, x1, y2, x2 = result['rois'][best_index]\r\n    mask = result['masks'][:, :, best_index]\r\n\r\n    top_left = (x1, y1)\r\n    bottom_right = (x2, y2)\r\n\r\n    return top_left, bottom_right, mask\r\n\r\n\r\nclass myMaskRCNNConfig(Config):\r\n    # give the configuration a recognizable name\r\n    NAME = \"MaskRCNN_config\"\r\n\r\n    # set the number of GPUs to use along with the number of images\r\n    # per GPU\r\n    GPU_COUNT = 1\r\n    IMAGES_PER_GPU = 1\r\n\r\n    # number of classes (we would normally add +1 for the background)\r\n    # kangaroo + BG\r\n    NUM_CLASSES = 1+1\r\n\r\n    # Number of training steps per epoch\r\n    STEPS_PER_EPOCH = 1000\r\n\r\n    # Skip detections with < 90% confidence\r\n    DETECTION_MIN_CONFIDENCE = 0.9\r\n\r\n    # setting Max ground truth instances\r\n    MAX_GT_INSTANCES = 10\r\n\r\n\r\nif __name__ == '__main__':\r\n\r\n    # LOAD MASK R-CNN\r\n    config = myMaskRCNNConfig()\r\n    # Loading the model in the inference mode\r\n    model = modellib.MaskRCNN(mode=\"inference\", config=config, model_dir='./')\r\n    model_path = Path('mask_rcnn_model.h5')\r\n    if not model_path.exists():\r\n        download_file_from_google_drive('1gJDCxx1cExbdCxhtPIFfBxa6F4obzRHY', model_path)\r\n    # loading the trained weights o the custom dataset\r\n    model.load_weights(model_path, by_name=True)\r\n\r\n    save_folder = Path('../aligned_images')\r\n    if not save_folder.exists():\r\n        save_folder.mkdir()\r\n\r\n    images = list(Path('../images').iterdir())\r\n\r\n    # just a text file that lists the already done images in case we\r\n    # want to stop and continue later\r\n    progress_file = Path('done.txt')\r\n    if not progress_file.exists():\r\n        progress_file.mkdir()\r\n\r\n    with open('done.txt', 'r') as f:\r\n        done = f.read().split('\\n')\r\n\r\n    # alignment and mask r-cnn happen in parallel\r\n    # alignment uses cpu, mask r-cnn uses the gpu\r\n    # this way we cut the time needed by a factor of\r\n    # at least 4\r\n    \r\n    # alignment queue\r\n    queue = Queue()\r\n    Pool = Pool(4, multi_worker, (queue,))\r\n\r\n    for i in tqdm(images):\r\n        skip = False\r\n        save_name = save_folder/i.name\r\n        if save_name.exists() or str(i.name) in done:\r\n            skip = True\r\n        try:\r\n            image = cv2.imread(str(i))\r\n            # image not available\r\n            if image.shape == (81, 161, 3):\r\n                skip = True\r\n        except:\r\n            print('Error in:', i.name)\r\n            skip = True\r\n\r\n        if not skip:\r\n            result = detect(model, i)\r\n            # if mask r-cnn detects a pp, put into\r\n            # the alignment queue for processing\r\n            if len(result['rois']):\r\n                queue.put({\r\n                            'mask_info': {'image': image,\r\n                                        'mask_rcnn_res': result},\r\n                            'save_name': save_name\r\n                        })\r\n\r\n        with open('done.txt', 'a') as f:\r\n            f.write(str(i.name) + '\\n')\r\n    queue.put('kill process')"
  },
  {
    "path": "Image Processor/cv_tools.py",
    "content": "import os\r\nimport random\r\n\r\nimport cv2\r\nimport numpy as np\r\n\r\nimport math\r\nimport sys\r\nfrom collections import defaultdict\r\nfrom pathlib import Path\r\nfrom typing import List, Tuple\r\n\r\nimport cv2\r\nimport numpy as np\r\n\r\n\r\ndef show(image: np.ndarray) -> None:\r\n    \"\"\"\r\n    Displays the image in an opencv window.\r\n\r\n    Args:\r\n        image: 2D np.array\r\n    \"\"\"\r\n    cv2.imshow('img', image)\r\n    cv2.waitKey(0)\r\n\r\n\r\ndef resize(image: np.ndarray, resize_factor=None, resize_to=None) -> np.ndarray:\r\n    if resize_factor is None and resize_to is None:\r\n        raise ValueError('Must resize by a factor or to a size.')\r\n    elif resize_factor is not None and resize_to is not None:\r\n        raise ValueError('Must choose only one of resizing by a factor or to a size.')\r\n\r\n    if resize_factor:\r\n        if 0 < resize_factor < 1:\r\n            interpolation = cv2.INTER_AREA\r\n        elif resize_factor > 1:\r\n            interpolation = cv2.INTER_CUBIC\r\n        else:\r\n            raise ValueError('Resize factor must be above 0, and not 1.')\r\n\r\n        resized = cv2.resize(image, None, fx=resize_factor,\r\n                             fy=resize_factor, interpolation=interpolation)\r\n\r\n    elif resize_to:\r\n        if image.shape[0] < resize_to:\r\n            interpolation = cv2.INTER_CUBIC\r\n\r\n        elif image.shape[0] > resize_to:\r\n            interpolation = cv2.INTER_AREA\r\n        \r\n        elif image.shape[0] == resize_to:\r\n            # resizing to the same shape\r\n            interpolation = cv2.INTER_AREA\r\n\r\n        resized = cv2.resize(image, (resize_to, resize_to),\r\n                             interpolation=interpolation)\r\n\r\n    return resized\r\n\r\n\r\ndef crop(image: np.ndarray, top_left: Tuple[int], bottom_right: Tuple[int]) -> np.ndarray:\r\n    height, width = image.shape[:2]\r\n\r\n    x1, y1 = top_left[0], top_left[1]\r\n    x2, y2 = bottom_right[0], bottom_right[1]\r\n\r\n    return image[y1:y2, x1:x2]\r\n\r\n\r\ndef compute_PCA(image: np.ndarray, display=False) -> tuple:\r\n    mat = np.argwhere(image != 0)\r\n    mat[:, [0, 1]] = mat[:, [1, 0]]\r\n    mat = np.array(mat).astype(np.float32)  # have to convert type for PCA\r\n\r\n    # mean (e. g. the geometrical center)\r\n    # and eigenvectors (e. g. directions of principal components)\r\n    m, e = cv2.PCACompute(mat, mean=np.array([]))\r\n\r\n    # now to draw: let's scale our primary axis by 100,\r\n    # and the secondary by 50\r\n    centre = tuple(m[0])\r\n    endpoint1 = tuple(m[0] + e[0]*100)\r\n    endpoint2 = tuple(m[0] + e[1]*50)\r\n\r\n    if display:\r\n        img_show = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)\r\n\r\n        cv2.circle(img_show, centre, 5, (255, 255, 0))\r\n        cv2.line(img_show, centre, endpoint1, (255, 255, 0))\r\n        cv2.line(img_show, centre, endpoint2, (255, 255, 0))\r\n\r\n        show(img_show)\r\n\r\n    return centre, endpoint1, endpoint2\r\n\r\n\r\ndef threshold(image: np.ndarray, show_thresholded: bool = False, show_morphed: bool = False) -> np.ndarray:\r\n    \"\"\"\r\n    Main thresholding function.\r\n\r\n    Args:\r\n        image: 2D np.array\r\n        show_thresholded: Will display the thresholded image if True\r\n        show_morphed: Will display the morphologically transformed image if True\r\n\r\n    Returns:\r\n        morphed: Thresholded and morphologically transformed image\r\n    \"\"\"\r\n    # Adaptive thresholding to account for lighting\r\n    thresh = cv2.adaptiveThreshold(\r\n        image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 51, -2)\r\n    if show_thresholded:\r\n        show(thresh)\r\n\r\n    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))\r\n    morphed = cv2.erode(thresh, kernel, iterations=1)\r\n    morphed = cv2.morphologyEx(morphed, cv2.MORPH_CLOSE, kernel, iterations=10)\r\n\r\n    if show_morphed:\r\n        show(morphed)\r\n\r\n    return morphed\r\n\r\n\r\ndef find_contours(image: np.ndarray) -> List[np.ndarray]:\r\n    \"\"\"\r\n    Finds the contours in a given image.\r\n\r\n    Args:\r\n        image: 2D numpy array\r\n\r\n    Returns:\r\n        contours: list of contours found with cv2.findContours()\r\n    \"\"\"\r\n    contours, _ = cv2.findContours(\r\n        image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[-2:]\r\n\r\n    return contours\r\n\r\n\r\ndef draw_contours(image: np.ndarray, contours: List[np.ndarray]) -> np.ndarray:\r\n    \"\"\"\r\n    Draws the contours in a given image using cv2.drawContours.\r\n    input image must be RGB so the lines can be seen\r\n    \"\"\"\r\n\r\n    clr_img = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)\r\n    cv2.drawContours(clr_img, contours, -1, (0, 255, 0), 3)\r\n\r\n    return clr_img\r\n\r\n\r\ndef draw_lines(image: np.ndarray, lines: List[np.ndarray]) -> np.ndarray:\r\n    \"\"\"\r\n    Draws the lines found in an image from cv2.HoughLines()\r\n    input image must be RGB so the lines can be seen\r\n\r\n    Args:\r\n        image: 2D numpy array\r\n        lines: lines returned from cv2.HoughLines()\r\n\r\n    Returns:\r\n        image: 2D numpy array\r\n    \"\"\"\r\n\r\n    for line in lines:\r\n        # visit https://docs.opencv.org/3.4/d9/db0/tutorial_hough_lines.html\r\n        # for explanation on each line parameter\r\n        rho = line[0][0]\r\n        theta = line[0][1]\r\n        a = math.cos(theta)\r\n        b = math.sin(theta)\r\n        x0 = a * rho\r\n        y0 = b * rho\r\n        pt1 = (int(x0 + 1000*(-b)), int(y0 + 1000*(a)))\r\n        pt2 = (int(x0 - 1000*(-b)), int(y0 - 1000*(a)))\r\n        cv2.line(image, pt1, pt2, (0, 0, 255), 3, cv2.LINE_AA)\r\n\r\n    return image\r\n\r\n\r\ndef hough_lines(image: np.ndarray) -> (np.ndarray, List[np.ndarray]):\r\n    \"\"\"\r\n    Uses the hough transform to find lines in an image.\r\n    Converts to a coloured image first, so the lines can be seen\r\n\r\n    Args:\r\n        image: 2D numpy array\r\n\r\n    Returns:\r\n        clr_img: the coloured image (which can be used to draw the lines)\r\n        lines: the lines that were returned from cv2.HoughLines()\r\n    \"\"\"\r\n    clr_img = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)\r\n\r\n    edges = cv2.Canny(image, 50, 150, apertureSize=3)  # Canny edge detection\r\n    lines = cv2.HoughLines(edges, 1, np.pi / 180, 40)  # Hough line detection\r\n\r\n    return clr_img, lines\r\n\r\n\r\ndef filter_lines(lines: List[np.ndarray], angle_thresh: list = [(0, 45), (135, 180)]) -> List[np.ndarray]:\r\n    \"\"\"\r\n    Filters a list of lines found with cv2.HoughLines()\r\n    Can filter based on the angles you want to exclude.\r\n\r\n    OpenCV makes zero degrees a vertical line, and increases\r\n    going clockwise up to 180. Since these lines are of\r\n    infinite length, this covers a full circle.\r\n\r\n    Args:\r\n        lines: list of lines found with cv2.HoughLines()\r\n        angle_thresh: list of angle thresholds, each indicated with a tuple or list.\r\n                      For example, if you want from 0-30 degrees and 150-180,\r\n                      set angle thresh to [(0,30),(150,180)].\r\n\r\n    Returns:\r\n        filtered_lines: list of lines that are filtered.\r\n    \"\"\"\r\n\r\n    filtered_lines = []\r\n    for line in lines:\r\n        # theta in radians\r\n        theta = line[0][1]\r\n        # convert to degrees\r\n        degrees = theta*(180/math.pi)\r\n        for thresh in angle_thresh:\r\n            if thresh[0] <= degrees <= thresh[1]:\r\n                filtered_lines.append(line)\r\n    return filtered_lines\r\n\r\n\r\ndef segment_by_angle_kmeans(lines: np.ndarray, k: int = 2, **kwargs) -> List[List[np.ndarray]]:\r\n    \"\"\"Groups lines based on angle with k-means.\r\n    Used to make sure we don't check intersections between two\r\n    almost parallel lines. Uses k-means clustering to make\r\n    two groups with different angles.\r\n\r\n    Uses k-means on the coordinates of the angle on the unit circle \r\n    to segment `k` angles inside `lines`.\r\n    \"\"\"\r\n\r\n    # Define criteria = (type, max_iter, epsilon)\r\n    default_criteria_type = cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER\r\n    criteria = kwargs.get('criteria', (default_criteria_type, 10, 1.0))\r\n    flags = kwargs.get('flags', cv2.KMEANS_RANDOM_CENTERS)\r\n    attempts = kwargs.get('attempts', 10)\r\n\r\n    # returns angles in [0, pi] in radians\r\n    angles = np.array([line[0][1] for line in lines])\r\n    # multiply the angles by two and find coordinates of that angle\r\n    pts = np.array([[np.cos(2*angle), np.sin(2*angle)]\r\n                    for angle in angles], dtype=np.float32)\r\n\r\n    # run kmeans on the coords\r\n    labels, centers = cv2.kmeans(pts, k, None, criteria, attempts, flags)[1:]\r\n    labels = labels.reshape(-1)  # transpose to row vec\r\n\r\n    # segment lines based on their kmeans label\r\n    segmented = defaultdict(list)\r\n    for i, line in zip(range(len(lines)), lines):\r\n        segmented[labels[i]].append(line)\r\n    segmented = list(segmented.values())\r\n    return segmented\r\n\r\n\r\ndef segmented_intersections(lines: np.ndarray) -> List[List[int]]:\r\n    \"\"\"Finds the intersections between groups of lines.\"\"\"\r\n\r\n    intersections = []\r\n    for i, group in enumerate(lines[:-1]):\r\n        for next_group in lines[i+1:]:\r\n            for line1 in group:\r\n                for line2 in next_group:\r\n                    intersections.append(intersection(line1, line2))\r\n\r\n    return intersections\r\n\r\n\r\ndef intersection(line1: np.ndarray, line2: np.ndarray) -> List[int]:\r\n    \"\"\"Finds the intersection of two lines given in Hesse normal form.\r\n\r\n    Returns closest integer pixel locations.\r\n    See https://stackoverflow.com/a/383527/5087436\r\n    \"\"\"\r\n    rho1, theta1 = line1[0]\r\n    rho2, theta2 = line2[0]\r\n    A = np.array([\r\n        [np.cos(theta1), np.sin(theta1)],\r\n        [np.cos(theta2), np.sin(theta2)]\r\n    ])\r\n    b = np.array([[rho1], [rho2]])\r\n    # make sure A is invertable\r\n    if np.linalg.cond(A) < 1/sys.float_info.epsilon:\r\n        x0, y0 = np.linalg.solve(A, b)\r\n        x0, y0 = int(np.round(x0)), int(np.round(y0))\r\n    else:\r\n        x0 = y0 = None\r\n    return [x0, y0]\r\n\r\n\r\ndef filter_intersects(intersects: List[List[int]], pad_thickness: int, height: int, width: int) -> List[List[int]]:\r\n    \"\"\"\r\n    Filters the intersections found with intersection()\r\n\r\n    Args:\r\n        intersects: list of intersections found with intersection()\r\n        pad_thickness: the padding that was set\r\n        height: height of the image\r\n        width: width of the image\r\n\r\n    Returns:\r\n        filtered_intersects: list of filtered intersections \r\n    \"\"\"\r\n    filtered_intersects = []\r\n    for x, y in intersects:\r\n        if x is not None and y is not None:\r\n            # the intersection can be between the edge of\r\n            # the image (including the pad thickness)\r\n            # and the intersection can be between a third of\r\n            # the way down the picture, to above the picture (including the pad thickness)\r\n            if -pad_thickness < x < width+pad_thickness and -pad_thickness < y < height*0.2:\r\n                filtered_intersects.append([x, y])\r\n\r\n    return filtered_intersects\r\n\r\n\r\ndef draw_intersections(image: np.ndarray, intersects: list, pad_thickness: int) -> np.ndarray:\r\n    \"\"\"\r\n    Draws the intersections between the lines as little circles.\r\n\r\n    Args:\r\n        image: 2D numpy array\r\n        intersects: list of intersections\r\n        pad_thickness: the padding that was set\r\n\r\n    Returns:\r\n        image: image with the intersections drawn on it\r\n    \"\"\"\r\n    for x, y in intersects:\r\n        cv2.circle(image, (x+pad_thickness, y+pad_thickness),\r\n                   2, (0, 255, 0), -1)\r\n\r\n    return image\r\n\r\n\r\ndef pad_to_square(img, pad_value=0):\r\n    rows, columns = img.shape[:2]\r\n    dimensions = len(img.shape)\r\n\r\n    if rows < columns:\r\n        # image is wider than it is tall\r\n        # to make it square,, you have to add height\r\n        pad_height = columns - rows\r\n        pad_width = 0\r\n    elif rows > columns:\r\n        # image is taller than it is wide\r\n        # to make it square, you have to add width\r\n        pad_height = 0\r\n        pad_width = rows - columns\r\n    else:\r\n        # image is already square\r\n        pad_height = pad_width = 0\r\n\r\n    # evenly distribute the padding between the two sides\r\n    top_pad = bottom_pad = pad_height // 2\r\n    left_pad = right_pad = pad_width // 2\r\n\r\n    # if the padding needed is odd, add 1 row/column\r\n    if (pad_width % 2) != 0:\r\n        left_pad += 1\r\n    elif (pad_height % 2) != 0:\r\n        top_pad += 1\r\n\r\n    # if we don't want the background to be 0\r\n    if pad_value != 0:\r\n        # finding all edge values of the image\r\n        # concatenates values found in the top, right, bottom, left edges respectively\r\n        edges = [img[0, :-1], img[:-1, -1], img[-1, ::-1], img[-2:0:-1, 0]]\r\n        edges = np.concatenate(edges)\r\n        # pad with the median of the edges (which should be the background)\r\n        pad_value = int(np.median(edges))\r\n\r\n    if dimensions == 2:\r\n        padded = np.pad(img, ((top_pad, bottom_pad), (left_pad, right_pad)), 'constant',\r\n                        constant_values=pad_value)\r\n    elif dimensions == 3:\r\n        padded = np.pad(img, ((top_pad, bottom_pad), (left_pad, right_pad), (0, 0)), 'constant',\r\n                        constant_values=pad_value)\r\n\r\n    return padded\r\n\r\n\r\ndef find_bbox(contours):\r\n    xmin = 999\r\n    ymin = 999\r\n    xmax = 0\r\n    ymax = 0\r\n    for cnt in contours:\r\n        x, y, w, h = cv2.boundingRect(cnt)\r\n\r\n        xmin = min(xmin, x)\r\n        ymin = min(ymin, y)\r\n        xmax = max(xmax, x+w)\r\n        ymax = max(ymax, y+h)\r\n\r\n    return xmin, ymin, xmax, ymax\r\n\r\n\r\ndef crop_resize(img, resize_size=64, foreground='black', show_bbox=False):\r\n    \"\"\"\r\n    Finds ROI, crops it out, then resizes to the desired square image.\r\n    \"\"\"\r\n    if foreground == 'black':\r\n        threshold_type = cv2.THRESH_BINARY_INV\r\n    elif foreground == 'white':\r\n        threshold_type = cv2.THRESH_BINARY\r\n    else:\r\n        raise ValueError('foreground must be either black or white')\r\n\r\n    # threshold and find contours for bounding box\r\n    _, thresh = cv2.threshold(\r\n        img, 30, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)\r\n    contours, _ = cv2.findContours(\r\n        thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[-2:]\r\n\r\n    xmin, ymin, xmax, ymax = find_bbox(contours)\r\n\r\n    if show_bbox:\r\n        colour_img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)\r\n\r\n        cv2.rectangle(colour_img, (xmin, ymin), (xmax, ymax), (255, 0, 0), 2)\r\n\r\n        cv2.imshow('bounding box', colour_img)\r\n\r\n    # crop\r\n    roi = img[ymin:ymax, xmin:xmax]\r\n\r\n    # add padding to keep aspect ratio\r\n    roi = pad_to_square(roi)\r\n\r\n    return cv2.resize(roi, (resize_size, resize_size), interpolation=cv2.INTER_AREA)\r\n"
  },
  {
    "path": "Image Processor/download_utils.py",
    "content": "import requests\r\n\r\ndef download_file_from_google_drive(id, destination):\r\n    def get_confirm_token(response):\r\n        for key, value in response.cookies.items():\r\n            if key.startswith('download_warning'):\r\n                return value\r\n\r\n        return None\r\n\r\n    def save_response_content(response, destination):\r\n        CHUNK_SIZE = 32768\r\n\r\n        with open(destination, \"wb\") as f:\r\n            for chunk in response.iter_content(CHUNK_SIZE):\r\n                if chunk: # filter out keep-alive new chunks\r\n                    f.write(chunk)\r\n\r\n    URL = \"https://docs.google.com/uc?export=download\"\r\n\r\n    session = requests.Session()\r\n\r\n    response = session.get(URL, params = { 'id' : id }, stream = True)\r\n    token = get_confirm_token(response)\r\n\r\n    if token:\r\n        params = { 'id' : id, 'confirm' : token }\r\n        response = session.get(URL, params = params, stream = True)\r\n\r\n    save_response_content(response, destination)"
  },
  {
    "path": "Image Processor/mrcnn/__init__.py",
    "content": "\n"
  },
  {
    "path": "Image Processor/mrcnn/config.py",
    "content": "\"\"\"\nMask R-CNN\nBase Configurations class.\n\nCopyright (c) 2017 Matterport, Inc.\nLicensed under the MIT License (see LICENSE for details)\nWritten by Waleed Abdulla\n\"\"\"\n\nimport numpy as np\n\n\n# Base Configuration Class\n# Don't use this class directly. Instead, sub-class it and override\n# the configurations you need to change.\n\nclass Config(object):\n    \"\"\"Base configuration class. For custom configurations, create a\n    sub-class that inherits from this one and override properties\n    that need to be changed.\n    \"\"\"\n    # Name the configurations. For example, 'COCO', 'Experiment 3', ...etc.\n    # Useful if your code needs to do things differently depending on which\n    # experiment is running.\n    NAME = None  # Override in sub-classes\n\n    # NUMBER OF GPUs to use. When using only a CPU, this needs to be set to 1.\n    GPU_COUNT = 1\n\n    # Number of images to train with on each GPU. A 12GB GPU can typically\n    # handle 2 images of 1024x1024px.\n    # Adjust based on your GPU memory and image sizes. Use the highest\n    # number that your GPU can handle for best performance.\n    IMAGES_PER_GPU = 2\n\n    # Number of training steps per epoch\n    # This doesn't need to match the size of the training set. Tensorboard\n    # updates are saved at the end of each epoch, so setting this to a\n    # smaller number means getting more frequent TensorBoard updates.\n    # Validation stats are also calculated at each epoch end and they\n    # might take a while, so don't set this too small to avoid spending\n    # a lot of time on validation stats.\n    STEPS_PER_EPOCH = 1000\n\n    # Number of validation steps to run at the end of every training epoch.\n    # A bigger number improves accuracy of validation stats, but slows\n    # down the training.\n    VALIDATION_STEPS = 50\n\n    # Backbone network architecture\n    # Supported values are: resnet50, resnet101.\n    # You can also provide a callable that should have the signature\n    # of model.resnet_graph. If you do so, you need to supply a callable\n    # to COMPUTE_BACKBONE_SHAPE as well\n    BACKBONE = \"resnet101\"\n\n    # Only useful if you supply a callable to BACKBONE. Should compute\n    # the shape of each layer of the FPN Pyramid.\n    # See model.compute_backbone_shapes\n    COMPUTE_BACKBONE_SHAPE = None\n\n    # The strides of each layer of the FPN Pyramid. These values\n    # are based on a Resnet101 backbone.\n    BACKBONE_STRIDES = [4, 8, 16, 32, 64]\n\n    # Size of the fully-connected layers in the classification graph\n    FPN_CLASSIF_FC_LAYERS_SIZE = 1024\n\n    # Size of the top-down layers used to build the feature pyramid\n    TOP_DOWN_PYRAMID_SIZE = 256\n\n    # Number of classification classes (including background)\n    NUM_CLASSES = 1  # Override in sub-classes\n\n    # Length of square anchor side in pixels\n    RPN_ANCHOR_SCALES = (32, 64, 128, 256, 512)\n\n    # Ratios of anchors at each cell (width/height)\n    # A value of 1 represents a square anchor, and 0.5 is a wide anchor\n    RPN_ANCHOR_RATIOS = [0.5, 1, 2]\n\n    # Anchor stride\n    # If 1 then anchors are created for each cell in the backbone feature map.\n    # If 2, then anchors are created for every other cell, and so on.\n    RPN_ANCHOR_STRIDE = 1\n\n    # Non-max suppression threshold to filter RPN proposals.\n    # You can increase this during training to generate more propsals.\n    RPN_NMS_THRESHOLD = 0.7\n\n    # How many anchors per image to use for RPN training\n    RPN_TRAIN_ANCHORS_PER_IMAGE = 256\n    \n    # ROIs kept after tf.nn.top_k and before non-maximum suppression\n    PRE_NMS_LIMIT = 6000\n\n    # ROIs kept after non-maximum suppression (training and inference)\n    POST_NMS_ROIS_TRAINING = 2000\n    POST_NMS_ROIS_INFERENCE = 1000\n\n    # If enabled, resizes instance masks to a smaller size to reduce\n    # memory load. Recommended when using high-resolution images.\n    USE_MINI_MASK = True\n    MINI_MASK_SHAPE = (56, 56)  # (height, width) of the mini-mask\n\n    # Input image resizing\n    # Generally, use the \"square\" resizing mode for training and predicting\n    # and it should work well in most cases. In this mode, images are scaled\n    # up such that the small side is = IMAGE_MIN_DIM, but ensuring that the\n    # scaling doesn't make the long side > IMAGE_MAX_DIM. Then the image is\n    # padded with zeros to make it a square so multiple images can be put\n    # in one batch.\n    # Available resizing modes:\n    # none:   No resizing or padding. Return the image unchanged.\n    # square: Resize and pad with zeros to get a square image\n    #         of size [max_dim, max_dim].\n    # pad64:  Pads width and height with zeros to make them multiples of 64.\n    #         If IMAGE_MIN_DIM or IMAGE_MIN_SCALE are not None, then it scales\n    #         up before padding. IMAGE_MAX_DIM is ignored in this mode.\n    #         The multiple of 64 is needed to ensure smooth scaling of feature\n    #         maps up and down the 6 levels of the FPN pyramid (2**6=64).\n    # crop:   Picks random crops from the image. First, scales the image based\n    #         on IMAGE_MIN_DIM and IMAGE_MIN_SCALE, then picks a random crop of\n    #         size IMAGE_MIN_DIM x IMAGE_MIN_DIM. Can be used in training only.\n    #         IMAGE_MAX_DIM is not used in this mode.\n    IMAGE_RESIZE_MODE = \"square\"\n    IMAGE_MIN_DIM = 800\n    IMAGE_MAX_DIM = 1024\n    # Minimum scaling ratio. Checked after MIN_IMAGE_DIM and can force further\n    # up scaling. For example, if set to 2 then images are scaled up to double\n    # the width and height, or more, even if MIN_IMAGE_DIM doesn't require it.\n    # However, in 'square' mode, it can be overruled by IMAGE_MAX_DIM.\n    IMAGE_MIN_SCALE = 0\n    # Number of color channels per image. RGB = 3, grayscale = 1, RGB-D = 4\n    # Changing this requires other changes in the code. See the WIKI for more\n    # details: https://github.com/matterport/Mask_RCNN/wiki\n    IMAGE_CHANNEL_COUNT = 3\n\n    # Image mean (RGB)\n    MEAN_PIXEL = np.array([123.7, 116.8, 103.9])\n\n    # Number of ROIs per image to feed to classifier/mask heads\n    # The Mask RCNN paper uses 512 but often the RPN doesn't generate\n    # enough positive proposals to fill this and keep a positive:negative\n    # ratio of 1:3. You can increase the number of proposals by adjusting\n    # the RPN NMS threshold.\n    TRAIN_ROIS_PER_IMAGE = 200\n\n    # Percent of positive ROIs used to train classifier/mask heads\n    ROI_POSITIVE_RATIO = 0.33\n\n    # Pooled ROIs\n    POOL_SIZE = 7\n    MASK_POOL_SIZE = 14\n\n    # Shape of output mask\n    # To change this you also need to change the neural network mask branch\n    MASK_SHAPE = [28, 28]\n\n    # Maximum number of ground truth instances to use in one image\n    MAX_GT_INSTANCES = 100\n\n    # Bounding box refinement standard deviation for RPN and final detections.\n    RPN_BBOX_STD_DEV = np.array([0.1, 0.1, 0.2, 0.2])\n    BBOX_STD_DEV = np.array([0.1, 0.1, 0.2, 0.2])\n\n    # Max number of final detections\n    DETECTION_MAX_INSTANCES = 100\n\n    # Minimum probability value to accept a detected instance\n    # ROIs below this threshold are skipped\n    DETECTION_MIN_CONFIDENCE = 0.7\n\n    # Non-maximum suppression threshold for detection\n    DETECTION_NMS_THRESHOLD = 0.3\n\n    # Learning rate and momentum\n    # The Mask RCNN paper uses lr=0.02, but on TensorFlow it causes\n    # weights to explode. Likely due to differences in optimizer\n    # implementation.\n    LEARNING_RATE = 0.001\n    LEARNING_MOMENTUM = 0.9\n\n    # Weight decay regularization\n    WEIGHT_DECAY = 0.0001\n\n    # Loss weights for more precise optimization.\n    # Can be used for R-CNN training setup.\n    LOSS_WEIGHTS = {\n        \"rpn_class_loss\": 1.,\n        \"rpn_bbox_loss\": 1.,\n        \"mrcnn_class_loss\": 1.,\n        \"mrcnn_bbox_loss\": 1.,\n        \"mrcnn_mask_loss\": 1.\n    }\n\n    # Use RPN ROIs or externally generated ROIs for training\n    # Keep this True for most situations. Set to False if you want to train\n    # the head branches on ROI generated by code rather than the ROIs from\n    # the RPN. For example, to debug the classifier head without having to\n    # train the RPN.\n    USE_RPN_ROIS = True\n\n    # Train or freeze batch normalization layers\n    #     None: Train BN layers. This is the normal mode\n    #     False: Freeze BN layers. Good when using a small batch size\n    #     True: (don't use). Set layer in training mode even when predicting\n    TRAIN_BN = False  # Defaulting to False since batch size is often small\n\n    # Gradient norm clipping\n    GRADIENT_CLIP_NORM = 5.0\n\n    def __init__(self):\n        \"\"\"Set values of computed attributes.\"\"\"\n        # Effective batch size\n        self.BATCH_SIZE = self.IMAGES_PER_GPU * self.GPU_COUNT\n\n        # Input image size\n        if self.IMAGE_RESIZE_MODE == \"crop\":\n            self.IMAGE_SHAPE = np.array([self.IMAGE_MIN_DIM, self.IMAGE_MIN_DIM,\n                self.IMAGE_CHANNEL_COUNT])\n        else:\n            self.IMAGE_SHAPE = np.array([self.IMAGE_MAX_DIM, self.IMAGE_MAX_DIM,\n                self.IMAGE_CHANNEL_COUNT])\n\n        # Image meta data length\n        # See compose_image_meta() for details\n        self.IMAGE_META_SIZE = 1 + 3 + 3 + 4 + 1 + self.NUM_CLASSES\n\n    def display(self):\n        \"\"\"Display Configuration values.\"\"\"\n        print(\"\\nConfigurations:\")\n        for a in dir(self):\n            if not a.startswith(\"__\") and not callable(getattr(self, a)):\n                print(\"{:30} {}\".format(a, getattr(self, a)))\n        print(\"\\n\")\n"
  },
  {
    "path": "Image Processor/mrcnn/model.py",
    "content": "\"\"\"\nMask R-CNN\nThe main Mask R-CNN model implementation.\n\nCopyright (c) 2017 Matterport, Inc.\nLicensed under the MIT License (see LICENSE for details)\nWritten by Waleed Abdulla\n\"\"\"\n\nimport os\nimport random\nimport datetime\nimport re\nimport math\nimport logging\nfrom collections import OrderedDict\nimport multiprocessing\nimport numpy as np\nimport tensorflow as tf\nimport keras\nimport keras.backend as K\nimport keras.layers as KL\nimport keras.engine as KE\nimport keras.models as KM\n\nfrom mrcnn import utils\n\n# Requires TensorFlow 1.3+ and Keras 2.0.8+.\nfrom distutils.version import LooseVersion\nassert LooseVersion(tf.__version__) >= LooseVersion(\"1.3\")\nassert LooseVersion(keras.__version__) >= LooseVersion('2.0.8')\n\n\n############################################################\n#  Utility Functions\n############################################################\n\ndef log(text, array=None):\n    \"\"\"Prints a text message. And, optionally, if a Numpy array is provided it\n    prints it's shape, min, and max values.\n    \"\"\"\n    if array is not None:\n        text = text.ljust(25)\n        text += (\"shape: {:20}  \".format(str(array.shape)))\n        if array.size:\n            text += (\"min: {:10.5f}  max: {:10.5f}\".format(array.min(),array.max()))\n        else:\n            text += (\"min: {:10}  max: {:10}\".format(\"\",\"\"))\n        text += \"  {}\".format(array.dtype)\n    print(text)\n\n\nclass BatchNorm(KL.BatchNormalization):\n    \"\"\"Extends the Keras BatchNormalization class to allow a central place\n    to make changes if needed.\n\n    Batch normalization has a negative effect on training if batches are small\n    so this layer is often frozen (via setting in Config class) and functions\n    as linear layer.\n    \"\"\"\n    def call(self, inputs, training=None):\n        \"\"\"\n        Note about training values:\n            None: Train BN layers. This is the normal mode\n            False: Freeze BN layers. Good when batch size is small\n            True: (don't use). Set layer in training mode even when making inferences\n        \"\"\"\n        return super(self.__class__, self).call(inputs, training=training)\n\n\ndef compute_backbone_shapes(config, image_shape):\n    \"\"\"Computes the width and height of each stage of the backbone network.\n\n    Returns:\n        [N, (height, width)]. Where N is the number of stages\n    \"\"\"\n    if callable(config.BACKBONE):\n        return config.COMPUTE_BACKBONE_SHAPE(image_shape)\n\n    # Currently supports ResNet only\n    assert config.BACKBONE in [\"resnet50\", \"resnet101\"]\n    return np.array(\n        [[int(math.ceil(image_shape[0] / stride)),\n            int(math.ceil(image_shape[1] / stride))]\n            for stride in config.BACKBONE_STRIDES])\n\n\n############################################################\n#  Resnet Graph\n############################################################\n\n# Code adopted from:\n# https://github.com/fchollet/deep-learning-models/blob/master/resnet50.py\n\ndef identity_block(input_tensor, kernel_size, filters, stage, block,\n                   use_bias=True, train_bn=True):\n    \"\"\"The identity_block is the block that has no conv layer at shortcut\n    # Arguments\n        input_tensor: input tensor\n        kernel_size: default 3, the kernel size of middle conv layer at main path\n        filters: list of integers, the nb_filters of 3 conv layer at main path\n        stage: integer, current stage label, used for generating layer names\n        block: 'a','b'..., current block label, used for generating layer names\n        use_bias: Boolean. To use or not use a bias in conv layers.\n        train_bn: Boolean. Train or freeze Batch Norm layers\n    \"\"\"\n    nb_filter1, nb_filter2, nb_filter3 = filters\n    conv_name_base = 'res' + str(stage) + block + '_branch'\n    bn_name_base = 'bn' + str(stage) + block + '_branch'\n\n    x = KL.Conv2D(nb_filter1, (1, 1), name=conv_name_base + '2a',\n                  use_bias=use_bias)(input_tensor)\n    x = BatchNorm(name=bn_name_base + '2a')(x, training=train_bn)\n    x = KL.Activation('relu')(x)\n\n    x = KL.Conv2D(nb_filter2, (kernel_size, kernel_size), padding='same',\n                  name=conv_name_base + '2b', use_bias=use_bias)(x)\n    x = BatchNorm(name=bn_name_base + '2b')(x, training=train_bn)\n    x = KL.Activation('relu')(x)\n\n    x = KL.Conv2D(nb_filter3, (1, 1), name=conv_name_base + '2c',\n                  use_bias=use_bias)(x)\n    x = BatchNorm(name=bn_name_base + '2c')(x, training=train_bn)\n\n    x = KL.Add()([x, input_tensor])\n    x = KL.Activation('relu', name='res' + str(stage) + block + '_out')(x)\n    return x\n\n\ndef conv_block(input_tensor, kernel_size, filters, stage, block,\n               strides=(2, 2), use_bias=True, train_bn=True):\n    \"\"\"conv_block is the block that has a conv layer at shortcut\n    # Arguments\n        input_tensor: input tensor\n        kernel_size: default 3, the kernel size of middle conv layer at main path\n        filters: list of integers, the nb_filters of 3 conv layer at main path\n        stage: integer, current stage label, used for generating layer names\n        block: 'a','b'..., current block label, used for generating layer names\n        use_bias: Boolean. To use or not use a bias in conv layers.\n        train_bn: Boolean. Train or freeze Batch Norm layers\n    Note that from stage 3, the first conv layer at main path is with subsample=(2,2)\n    And the shortcut should have subsample=(2,2) as well\n    \"\"\"\n    nb_filter1, nb_filter2, nb_filter3 = filters\n    conv_name_base = 'res' + str(stage) + block + '_branch'\n    bn_name_base = 'bn' + str(stage) + block + '_branch'\n\n    x = KL.Conv2D(nb_filter1, (1, 1), strides=strides,\n                  name=conv_name_base + '2a', use_bias=use_bias)(input_tensor)\n    x = BatchNorm(name=bn_name_base + '2a')(x, training=train_bn)\n    x = KL.Activation('relu')(x)\n\n    x = KL.Conv2D(nb_filter2, (kernel_size, kernel_size), padding='same',\n                  name=conv_name_base + '2b', use_bias=use_bias)(x)\n    x = BatchNorm(name=bn_name_base + '2b')(x, training=train_bn)\n    x = KL.Activation('relu')(x)\n\n    x = KL.Conv2D(nb_filter3, (1, 1), name=conv_name_base +\n                  '2c', use_bias=use_bias)(x)\n    x = BatchNorm(name=bn_name_base + '2c')(x, training=train_bn)\n\n    shortcut = KL.Conv2D(nb_filter3, (1, 1), strides=strides,\n                         name=conv_name_base + '1', use_bias=use_bias)(input_tensor)\n    shortcut = BatchNorm(name=bn_name_base + '1')(shortcut, training=train_bn)\n\n    x = KL.Add()([x, shortcut])\n    x = KL.Activation('relu', name='res' + str(stage) + block + '_out')(x)\n    return x\n\n\ndef resnet_graph(input_image, architecture, stage5=False, train_bn=True):\n    \"\"\"Build a ResNet graph.\n        architecture: Can be resnet50 or resnet101\n        stage5: Boolean. If False, stage5 of the network is not created\n        train_bn: Boolean. Train or freeze Batch Norm layers\n    \"\"\"\n    assert architecture in [\"resnet50\", \"resnet101\"]\n    # Stage 1\n    x = KL.ZeroPadding2D((3, 3))(input_image)\n    x = KL.Conv2D(64, (7, 7), strides=(2, 2), name='conv1', use_bias=True)(x)\n    x = BatchNorm(name='bn_conv1')(x, training=train_bn)\n    x = KL.Activation('relu')(x)\n    C1 = x = KL.MaxPooling2D((3, 3), strides=(2, 2), padding=\"same\")(x)\n    # Stage 2\n    x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1), train_bn=train_bn)\n    x = identity_block(x, 3, [64, 64, 256], stage=2, block='b', train_bn=train_bn)\n    C2 = x = identity_block(x, 3, [64, 64, 256], stage=2, block='c', train_bn=train_bn)\n    # Stage 3\n    x = conv_block(x, 3, [128, 128, 512], stage=3, block='a', train_bn=train_bn)\n    x = identity_block(x, 3, [128, 128, 512], stage=3, block='b', train_bn=train_bn)\n    x = identity_block(x, 3, [128, 128, 512], stage=3, block='c', train_bn=train_bn)\n    C3 = x = identity_block(x, 3, [128, 128, 512], stage=3, block='d', train_bn=train_bn)\n    # Stage 4\n    x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a', train_bn=train_bn)\n    block_count = {\"resnet50\": 5, \"resnet101\": 22}[architecture]\n    for i in range(block_count):\n        x = identity_block(x, 3, [256, 256, 1024], stage=4, block=chr(98 + i), train_bn=train_bn)\n    C4 = x\n    # Stage 5\n    if stage5:\n        x = conv_block(x, 3, [512, 512, 2048], stage=5, block='a', train_bn=train_bn)\n        x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b', train_bn=train_bn)\n        C5 = x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c', train_bn=train_bn)\n    else:\n        C5 = None\n    return [C1, C2, C3, C4, C5]\n\n\n############################################################\n#  Proposal Layer\n############################################################\n\ndef apply_box_deltas_graph(boxes, deltas):\n    \"\"\"Applies the given deltas to the given boxes.\n    boxes: [N, (y1, x1, y2, x2)] boxes to update\n    deltas: [N, (dy, dx, log(dh), log(dw))] refinements to apply\n    \"\"\"\n    # Convert to y, x, h, w\n    height = boxes[:, 2] - boxes[:, 0]\n    width = boxes[:, 3] - boxes[:, 1]\n    center_y = boxes[:, 0] + 0.5 * height\n    center_x = boxes[:, 1] + 0.5 * width\n    # Apply deltas\n    center_y += deltas[:, 0] * height\n    center_x += deltas[:, 1] * width\n    height *= tf.exp(deltas[:, 2])\n    width *= tf.exp(deltas[:, 3])\n    # Convert back to y1, x1, y2, x2\n    y1 = center_y - 0.5 * height\n    x1 = center_x - 0.5 * width\n    y2 = y1 + height\n    x2 = x1 + width\n    result = tf.stack([y1, x1, y2, x2], axis=1, name=\"apply_box_deltas_out\")\n    return result\n\n\ndef clip_boxes_graph(boxes, window):\n    \"\"\"\n    boxes: [N, (y1, x1, y2, x2)]\n    window: [4] in the form y1, x1, y2, x2\n    \"\"\"\n    # Split\n    wy1, wx1, wy2, wx2 = tf.split(window, 4)\n    y1, x1, y2, x2 = tf.split(boxes, 4, axis=1)\n    # Clip\n    y1 = tf.maximum(tf.minimum(y1, wy2), wy1)\n    x1 = tf.maximum(tf.minimum(x1, wx2), wx1)\n    y2 = tf.maximum(tf.minimum(y2, wy2), wy1)\n    x2 = tf.maximum(tf.minimum(x2, wx2), wx1)\n    clipped = tf.concat([y1, x1, y2, x2], axis=1, name=\"clipped_boxes\")\n    clipped.set_shape((clipped.shape[0], 4))\n    return clipped\n\n\nclass ProposalLayer(KE.Layer):\n    \"\"\"Receives anchor scores and selects a subset to pass as proposals\n    to the second stage. Filtering is done based on anchor scores and\n    non-max suppression to remove overlaps. It also applies bounding\n    box refinement deltas to anchors.\n\n    Inputs:\n        rpn_probs: [batch, num_anchors, (bg prob, fg prob)]\n        rpn_bbox: [batch, num_anchors, (dy, dx, log(dh), log(dw))]\n        anchors: [batch, num_anchors, (y1, x1, y2, x2)] anchors in normalized coordinates\n\n    Returns:\n        Proposals in normalized coordinates [batch, rois, (y1, x1, y2, x2)]\n    \"\"\"\n\n    def __init__(self, proposal_count, nms_threshold, config=None, **kwargs):\n        super(ProposalLayer, self).__init__(**kwargs)\n        self.config = config\n        self.proposal_count = proposal_count\n        self.nms_threshold = nms_threshold\n\n    def call(self, inputs):\n        # Box Scores. Use the foreground class confidence. [Batch, num_rois, 1]\n        scores = inputs[0][:, :, 1]\n        # Box deltas [batch, num_rois, 4]\n        deltas = inputs[1]\n        deltas = deltas * np.reshape(self.config.RPN_BBOX_STD_DEV, [1, 1, 4])\n        # Anchors\n        anchors = inputs[2]\n\n        # Improve performance by trimming to top anchors by score\n        # and doing the rest on the smaller subset.\n        pre_nms_limit = tf.minimum(self.config.PRE_NMS_LIMIT, tf.shape(anchors)[1])\n        ix = tf.nn.top_k(scores, pre_nms_limit, sorted=True,\n                         name=\"top_anchors\").indices\n        scores = utils.batch_slice([scores, ix], lambda x, y: tf.gather(x, y),\n                                   self.config.IMAGES_PER_GPU)\n        deltas = utils.batch_slice([deltas, ix], lambda x, y: tf.gather(x, y),\n                                   self.config.IMAGES_PER_GPU)\n        pre_nms_anchors = utils.batch_slice([anchors, ix], lambda a, x: tf.gather(a, x),\n                                    self.config.IMAGES_PER_GPU,\n                                    names=[\"pre_nms_anchors\"])\n\n        # Apply deltas to anchors to get refined anchors.\n        # [batch, N, (y1, x1, y2, x2)]\n        boxes = utils.batch_slice([pre_nms_anchors, deltas],\n                                  lambda x, y: apply_box_deltas_graph(x, y),\n                                  self.config.IMAGES_PER_GPU,\n                                  names=[\"refined_anchors\"])\n\n        # Clip to image boundaries. Since we're in normalized coordinates,\n        # clip to 0..1 range. [batch, N, (y1, x1, y2, x2)]\n        window = np.array([0, 0, 1, 1], dtype=np.float32)\n        boxes = utils.batch_slice(boxes,\n                                  lambda x: clip_boxes_graph(x, window),\n                                  self.config.IMAGES_PER_GPU,\n                                  names=[\"refined_anchors_clipped\"])\n\n        # Filter out small boxes\n        # According to Xinlei Chen's paper, this reduces detection accuracy\n        # for small objects, so we're skipping it.\n\n        # Non-max suppression\n        def nms(boxes, scores):\n            indices = tf.image.non_max_suppression(\n                boxes, scores, self.proposal_count,\n                self.nms_threshold, name=\"rpn_non_max_suppression\")\n            proposals = tf.gather(boxes, indices)\n            # Pad if needed\n            padding = tf.maximum(self.proposal_count - tf.shape(proposals)[0], 0)\n            proposals = tf.pad(proposals, [(0, padding), (0, 0)])\n            return proposals\n        proposals = utils.batch_slice([boxes, scores], nms,\n                                      self.config.IMAGES_PER_GPU)\n        return proposals\n\n    def compute_output_shape(self, input_shape):\n        return (None, self.proposal_count, 4)\n\n\n############################################################\n#  ROIAlign Layer\n############################################################\n\ndef log2_graph(x):\n    \"\"\"Implementation of Log2. TF doesn't have a native implementation.\"\"\"\n    return tf.log(x) / tf.log(2.0)\n\n\nclass PyramidROIAlign(KE.Layer):\n    \"\"\"Implements ROI Pooling on multiple levels of the feature pyramid.\n\n    Params:\n    - pool_shape: [pool_height, pool_width] of the output pooled regions. Usually [7, 7]\n\n    Inputs:\n    - boxes: [batch, num_boxes, (y1, x1, y2, x2)] in normalized\n             coordinates. Possibly padded with zeros if not enough\n             boxes to fill the array.\n    - image_meta: [batch, (meta data)] Image details. See compose_image_meta()\n    - feature_maps: List of feature maps from different levels of the pyramid.\n                    Each is [batch, height, width, channels]\n\n    Output:\n    Pooled regions in the shape: [batch, num_boxes, pool_height, pool_width, channels].\n    The width and height are those specific in the pool_shape in the layer\n    constructor.\n    \"\"\"\n\n    def __init__(self, pool_shape, **kwargs):\n        super(PyramidROIAlign, self).__init__(**kwargs)\n        self.pool_shape = tuple(pool_shape)\n\n    def call(self, inputs):\n        # Crop boxes [batch, num_boxes, (y1, x1, y2, x2)] in normalized coords\n        boxes = inputs[0]\n\n        # Image meta\n        # Holds details about the image. See compose_image_meta()\n        image_meta = inputs[1]\n\n        # Feature Maps. List of feature maps from different level of the\n        # feature pyramid. Each is [batch, height, width, channels]\n        feature_maps = inputs[2:]\n\n        # Assign each ROI to a level in the pyramid based on the ROI area.\n        y1, x1, y2, x2 = tf.split(boxes, 4, axis=2)\n        h = y2 - y1\n        w = x2 - x1\n        # Use shape of first image. Images in a batch must have the same size.\n        image_shape = parse_image_meta_graph(image_meta)['image_shape'][0]\n        # Equation 1 in the Feature Pyramid Networks paper. Account for\n        # the fact that our coordinates are normalized here.\n        # e.g. a 224x224 ROI (in pixels) maps to P4\n        image_area = tf.cast(image_shape[0] * image_shape[1], tf.float32)\n        roi_level = log2_graph(tf.sqrt(h * w) / (224.0 / tf.sqrt(image_area)))\n        roi_level = tf.minimum(5, tf.maximum(\n            2, 4 + tf.cast(tf.round(roi_level), tf.int32)))\n        roi_level = tf.squeeze(roi_level, 2)\n\n        # Loop through levels and apply ROI pooling to each. P2 to P5.\n        pooled = []\n        box_to_level = []\n        for i, level in enumerate(range(2, 6)):\n            ix = tf.where(tf.equal(roi_level, level))\n            level_boxes = tf.gather_nd(boxes, ix)\n\n            # Box indices for crop_and_resize.\n            box_indices = tf.cast(ix[:, 0], tf.int32)\n\n            # Keep track of which box is mapped to which level\n            box_to_level.append(ix)\n\n            # Stop gradient propogation to ROI proposals\n            level_boxes = tf.stop_gradient(level_boxes)\n            box_indices = tf.stop_gradient(box_indices)\n\n            # Crop and Resize\n            # From Mask R-CNN paper: \"We sample four regular locations, so\n            # that we can evaluate either max or average pooling. In fact,\n            # interpolating only a single value at each bin center (without\n            # pooling) is nearly as effective.\"\n            #\n            # Here we use the simplified approach of a single value per bin,\n            # which is how it's done in tf.crop_and_resize()\n            # Result: [batch * num_boxes, pool_height, pool_width, channels]\n            pooled.append(tf.image.crop_and_resize(\n                feature_maps[i], level_boxes, box_indices, self.pool_shape,\n                method=\"bilinear\"))\n\n        # Pack pooled features into one tensor\n        pooled = tf.concat(pooled, axis=0)\n\n        # Pack box_to_level mapping into one array and add another\n        # column representing the order of pooled boxes\n        box_to_level = tf.concat(box_to_level, axis=0)\n        box_range = tf.expand_dims(tf.range(tf.shape(box_to_level)[0]), 1)\n        box_to_level = tf.concat([tf.cast(box_to_level, tf.int32), box_range],\n                                 axis=1)\n\n        # Rearrange pooled features to match the order of the original boxes\n        # Sort box_to_level by batch then box index\n        # TF doesn't have a way to sort by two columns, so merge them and sort.\n        sorting_tensor = box_to_level[:, 0] * 100000 + box_to_level[:, 1]\n        ix = tf.nn.top_k(sorting_tensor, k=tf.shape(\n            box_to_level)[0]).indices[::-1]\n        ix = tf.gather(box_to_level[:, 2], ix)\n        pooled = tf.gather(pooled, ix)\n\n        # Re-add the batch dimension\n        shape = tf.concat([tf.shape(boxes)[:2], tf.shape(pooled)[1:]], axis=0)\n        pooled = tf.reshape(pooled, shape)\n        return pooled\n\n    def compute_output_shape(self, input_shape):\n        return input_shape[0][:2] + self.pool_shape + (input_shape[2][-1], )\n\n\n############################################################\n#  Detection Target Layer\n############################################################\n\ndef overlaps_graph(boxes1, boxes2):\n    \"\"\"Computes IoU overlaps between two sets of boxes.\n    boxes1, boxes2: [N, (y1, x1, y2, x2)].\n    \"\"\"\n    # 1. Tile boxes2 and repeat boxes1. This allows us to compare\n    # every boxes1 against every boxes2 without loops.\n    # TF doesn't have an equivalent to np.repeat() so simulate it\n    # using tf.tile() and tf.reshape.\n    b1 = tf.reshape(tf.tile(tf.expand_dims(boxes1, 1),\n                            [1, 1, tf.shape(boxes2)[0]]), [-1, 4])\n    b2 = tf.tile(boxes2, [tf.shape(boxes1)[0], 1])\n    # 2. Compute intersections\n    b1_y1, b1_x1, b1_y2, b1_x2 = tf.split(b1, 4, axis=1)\n    b2_y1, b2_x1, b2_y2, b2_x2 = tf.split(b2, 4, axis=1)\n    y1 = tf.maximum(b1_y1, b2_y1)\n    x1 = tf.maximum(b1_x1, b2_x1)\n    y2 = tf.minimum(b1_y2, b2_y2)\n    x2 = tf.minimum(b1_x2, b2_x2)\n    intersection = tf.maximum(x2 - x1, 0) * tf.maximum(y2 - y1, 0)\n    # 3. Compute unions\n    b1_area = (b1_y2 - b1_y1) * (b1_x2 - b1_x1)\n    b2_area = (b2_y2 - b2_y1) * (b2_x2 - b2_x1)\n    union = b1_area + b2_area - intersection\n    # 4. Compute IoU and reshape to [boxes1, boxes2]\n    iou = intersection / union\n    overlaps = tf.reshape(iou, [tf.shape(boxes1)[0], tf.shape(boxes2)[0]])\n    return overlaps\n\n\ndef detection_targets_graph(proposals, gt_class_ids, gt_boxes, gt_masks, config):\n    \"\"\"Generates detection targets for one image. Subsamples proposals and\n    generates target class IDs, bounding box deltas, and masks for each.\n\n    Inputs:\n    proposals: [POST_NMS_ROIS_TRAINING, (y1, x1, y2, x2)] in normalized coordinates. Might\n               be zero padded if there are not enough proposals.\n    gt_class_ids: [MAX_GT_INSTANCES] int class IDs\n    gt_boxes: [MAX_GT_INSTANCES, (y1, x1, y2, x2)] in normalized coordinates.\n    gt_masks: [height, width, MAX_GT_INSTANCES] of boolean type.\n\n    Returns: Target ROIs and corresponding class IDs, bounding box shifts,\n    and masks.\n    rois: [TRAIN_ROIS_PER_IMAGE, (y1, x1, y2, x2)] in normalized coordinates\n    class_ids: [TRAIN_ROIS_PER_IMAGE]. Integer class IDs. Zero padded.\n    deltas: [TRAIN_ROIS_PER_IMAGE, (dy, dx, log(dh), log(dw))]\n    masks: [TRAIN_ROIS_PER_IMAGE, height, width]. Masks cropped to bbox\n           boundaries and resized to neural network output size.\n\n    Note: Returned arrays might be zero padded if not enough target ROIs.\n    \"\"\"\n    # Assertions\n    asserts = [\n        tf.Assert(tf.greater(tf.shape(proposals)[0], 0), [proposals],\n                  name=\"roi_assertion\"),\n    ]\n    with tf.control_dependencies(asserts):\n        proposals = tf.identity(proposals)\n\n    # Remove zero padding\n    proposals, _ = trim_zeros_graph(proposals, name=\"trim_proposals\")\n    gt_boxes, non_zeros = trim_zeros_graph(gt_boxes, name=\"trim_gt_boxes\")\n    gt_class_ids = tf.boolean_mask(gt_class_ids, non_zeros,\n                                   name=\"trim_gt_class_ids\")\n    gt_masks = tf.gather(gt_masks, tf.where(non_zeros)[:, 0], axis=2,\n                         name=\"trim_gt_masks\")\n\n    # Handle COCO crowds\n    # A crowd box in COCO is a bounding box around several instances. Exclude\n    # them from training. A crowd box is given a negative class ID.\n    crowd_ix = tf.where(gt_class_ids < 0)[:, 0]\n    non_crowd_ix = tf.where(gt_class_ids > 0)[:, 0]\n    crowd_boxes = tf.gather(gt_boxes, crowd_ix)\n    gt_class_ids = tf.gather(gt_class_ids, non_crowd_ix)\n    gt_boxes = tf.gather(gt_boxes, non_crowd_ix)\n    gt_masks = tf.gather(gt_masks, non_crowd_ix, axis=2)\n\n    # Compute overlaps matrix [proposals, gt_boxes]\n    overlaps = overlaps_graph(proposals, gt_boxes)\n\n    # Compute overlaps with crowd boxes [proposals, crowd_boxes]\n    crowd_overlaps = overlaps_graph(proposals, crowd_boxes)\n    crowd_iou_max = tf.reduce_max(crowd_overlaps, axis=1)\n    no_crowd_bool = (crowd_iou_max < 0.001)\n\n    # Determine positive and negative ROIs\n    roi_iou_max = tf.reduce_max(overlaps, axis=1)\n    # 1. Positive ROIs are those with >= 0.5 IoU with a GT box\n    positive_roi_bool = (roi_iou_max >= 0.5)\n    positive_indices = tf.where(positive_roi_bool)[:, 0]\n    # 2. Negative ROIs are those with < 0.5 with every GT box. Skip crowds.\n    negative_indices = tf.where(tf.logical_and(roi_iou_max < 0.5, no_crowd_bool))[:, 0]\n\n    # Subsample ROIs. Aim for 33% positive\n    # Positive ROIs\n    positive_count = int(config.TRAIN_ROIS_PER_IMAGE *\n                         config.ROI_POSITIVE_RATIO)\n    positive_indices = tf.random_shuffle(positive_indices)[:positive_count]\n    positive_count = tf.shape(positive_indices)[0]\n    # Negative ROIs. Add enough to maintain positive:negative ratio.\n    r = 1.0 / config.ROI_POSITIVE_RATIO\n    negative_count = tf.cast(r * tf.cast(positive_count, tf.float32), tf.int32) - positive_count\n    negative_indices = tf.random_shuffle(negative_indices)[:negative_count]\n    # Gather selected ROIs\n    positive_rois = tf.gather(proposals, positive_indices)\n    negative_rois = tf.gather(proposals, negative_indices)\n\n    # Assign positive ROIs to GT boxes.\n    positive_overlaps = tf.gather(overlaps, positive_indices)\n    roi_gt_box_assignment = tf.cond(\n        tf.greater(tf.shape(positive_overlaps)[1], 0),\n        true_fn = lambda: tf.argmax(positive_overlaps, axis=1),\n        false_fn = lambda: tf.cast(tf.constant([]),tf.int64)\n    )\n    roi_gt_boxes = tf.gather(gt_boxes, roi_gt_box_assignment)\n    roi_gt_class_ids = tf.gather(gt_class_ids, roi_gt_box_assignment)\n\n    # Compute bbox refinement for positive ROIs\n    deltas = utils.box_refinement_graph(positive_rois, roi_gt_boxes)\n    deltas /= config.BBOX_STD_DEV\n\n    # Assign positive ROIs to GT masks\n    # Permute masks to [N, height, width, 1]\n    transposed_masks = tf.expand_dims(tf.transpose(gt_masks, [2, 0, 1]), -1)\n    # Pick the right mask for each ROI\n    roi_masks = tf.gather(transposed_masks, roi_gt_box_assignment)\n\n    # Compute mask targets\n    boxes = positive_rois\n    if config.USE_MINI_MASK:\n        # Transform ROI coordinates from normalized image space\n        # to normalized mini-mask space.\n        y1, x1, y2, x2 = tf.split(positive_rois, 4, axis=1)\n        gt_y1, gt_x1, gt_y2, gt_x2 = tf.split(roi_gt_boxes, 4, axis=1)\n        gt_h = gt_y2 - gt_y1\n        gt_w = gt_x2 - gt_x1\n        y1 = (y1 - gt_y1) / gt_h\n        x1 = (x1 - gt_x1) / gt_w\n        y2 = (y2 - gt_y1) / gt_h\n        x2 = (x2 - gt_x1) / gt_w\n        boxes = tf.concat([y1, x1, y2, x2], 1)\n    box_ids = tf.range(0, tf.shape(roi_masks)[0])\n    masks = tf.image.crop_and_resize(tf.cast(roi_masks, tf.float32), boxes,\n                                     box_ids,\n                                     config.MASK_SHAPE)\n    # Remove the extra dimension from masks.\n    masks = tf.squeeze(masks, axis=3)\n\n    # Threshold mask pixels at 0.5 to have GT masks be 0 or 1 to use with\n    # binary cross entropy loss.\n    masks = tf.round(masks)\n\n    # Append negative ROIs and pad bbox deltas and masks that\n    # are not used for negative ROIs with zeros.\n    rois = tf.concat([positive_rois, negative_rois], axis=0)\n    N = tf.shape(negative_rois)[0]\n    P = tf.maximum(config.TRAIN_ROIS_PER_IMAGE - tf.shape(rois)[0], 0)\n    rois = tf.pad(rois, [(0, P), (0, 0)])\n    roi_gt_boxes = tf.pad(roi_gt_boxes, [(0, N + P), (0, 0)])\n    roi_gt_class_ids = tf.pad(roi_gt_class_ids, [(0, N + P)])\n    deltas = tf.pad(deltas, [(0, N + P), (0, 0)])\n    masks = tf.pad(masks, [[0, N + P], (0, 0), (0, 0)])\n\n    return rois, roi_gt_class_ids, deltas, masks\n\n\nclass DetectionTargetLayer(KE.Layer):\n    \"\"\"Subsamples proposals and generates target box refinement, class_ids,\n    and masks for each.\n\n    Inputs:\n    proposals: [batch, N, (y1, x1, y2, x2)] in normalized coordinates. Might\n               be zero padded if there are not enough proposals.\n    gt_class_ids: [batch, MAX_GT_INSTANCES] Integer class IDs.\n    gt_boxes: [batch, MAX_GT_INSTANCES, (y1, x1, y2, x2)] in normalized\n              coordinates.\n    gt_masks: [batch, height, width, MAX_GT_INSTANCES] of boolean type\n\n    Returns: Target ROIs and corresponding class IDs, bounding box shifts,\n    and masks.\n    rois: [batch, TRAIN_ROIS_PER_IMAGE, (y1, x1, y2, x2)] in normalized\n          coordinates\n    target_class_ids: [batch, TRAIN_ROIS_PER_IMAGE]. Integer class IDs.\n    target_deltas: [batch, TRAIN_ROIS_PER_IMAGE, (dy, dx, log(dh), log(dw)]\n    target_mask: [batch, TRAIN_ROIS_PER_IMAGE, height, width]\n                 Masks cropped to bbox boundaries and resized to neural\n                 network output size.\n\n    Note: Returned arrays might be zero padded if not enough target ROIs.\n    \"\"\"\n\n    def __init__(self, config, **kwargs):\n        super(DetectionTargetLayer, self).__init__(**kwargs)\n        self.config = config\n\n    def call(self, inputs):\n        proposals = inputs[0]\n        gt_class_ids = inputs[1]\n        gt_boxes = inputs[2]\n        gt_masks = inputs[3]\n\n        # Slice the batch and run a graph for each slice\n        # TODO: Rename target_bbox to target_deltas for clarity\n        names = [\"rois\", \"target_class_ids\", \"target_bbox\", \"target_mask\"]\n        outputs = utils.batch_slice(\n            [proposals, gt_class_ids, gt_boxes, gt_masks],\n            lambda w, x, y, z: detection_targets_graph(\n                w, x, y, z, self.config),\n            self.config.IMAGES_PER_GPU, names=names)\n        return outputs\n\n    def compute_output_shape(self, input_shape):\n        return [\n            (None, self.config.TRAIN_ROIS_PER_IMAGE, 4),  # rois\n            (None, self.config.TRAIN_ROIS_PER_IMAGE),  # class_ids\n            (None, self.config.TRAIN_ROIS_PER_IMAGE, 4),  # deltas\n            (None, self.config.TRAIN_ROIS_PER_IMAGE, self.config.MASK_SHAPE[0],\n             self.config.MASK_SHAPE[1])  # masks\n        ]\n\n    def compute_mask(self, inputs, mask=None):\n        return [None, None, None, None]\n\n\n############################################################\n#  Detection Layer\n############################################################\n\ndef refine_detections_graph(rois, probs, deltas, window, config):\n    \"\"\"Refine classified proposals and filter overlaps and return final\n    detections.\n\n    Inputs:\n        rois: [N, (y1, x1, y2, x2)] in normalized coordinates\n        probs: [N, num_classes]. Class probabilities.\n        deltas: [N, num_classes, (dy, dx, log(dh), log(dw))]. Class-specific\n                bounding box deltas.\n        window: (y1, x1, y2, x2) in normalized coordinates. The part of the image\n            that contains the image excluding the padding.\n\n    Returns detections shaped: [num_detections, (y1, x1, y2, x2, class_id, score)] where\n        coordinates are normalized.\n    \"\"\"\n    # Class IDs per ROI\n    class_ids = tf.argmax(probs, axis=1, output_type=tf.int32)\n    # Class probability of the top class of each ROI\n    indices = tf.stack([tf.range(probs.shape[0]), class_ids], axis=1)\n    class_scores = tf.gather_nd(probs, indices)\n    # Class-specific bounding box deltas\n    deltas_specific = tf.gather_nd(deltas, indices)\n    # Apply bounding box deltas\n    # Shape: [boxes, (y1, x1, y2, x2)] in normalized coordinates\n    refined_rois = apply_box_deltas_graph(\n        rois, deltas_specific * config.BBOX_STD_DEV)\n    # Clip boxes to image window\n    refined_rois = clip_boxes_graph(refined_rois, window)\n\n    # TODO: Filter out boxes with zero area\n\n    # Filter out background boxes\n    keep = tf.where(class_ids > 0)[:, 0]\n    # Filter out low confidence boxes\n    if config.DETECTION_MIN_CONFIDENCE:\n        conf_keep = tf.where(class_scores >= config.DETECTION_MIN_CONFIDENCE)[:, 0]\n        keep = tf.sets.set_intersection(tf.expand_dims(keep, 0),\n                                        tf.expand_dims(conf_keep, 0))\n        keep = tf.sparse_tensor_to_dense(keep)[0]\n\n    # Apply per-class NMS\n    # 1. Prepare variables\n    pre_nms_class_ids = tf.gather(class_ids, keep)\n    pre_nms_scores = tf.gather(class_scores, keep)\n    pre_nms_rois = tf.gather(refined_rois,   keep)\n    unique_pre_nms_class_ids = tf.unique(pre_nms_class_ids)[0]\n\n    def nms_keep_map(class_id):\n        \"\"\"Apply Non-Maximum Suppression on ROIs of the given class.\"\"\"\n        # Indices of ROIs of the given class\n        ixs = tf.where(tf.equal(pre_nms_class_ids, class_id))[:, 0]\n        # Apply NMS\n        class_keep = tf.image.non_max_suppression(\n                tf.gather(pre_nms_rois, ixs),\n                tf.gather(pre_nms_scores, ixs),\n                max_output_size=config.DETECTION_MAX_INSTANCES,\n                iou_threshold=config.DETECTION_NMS_THRESHOLD)\n        # Map indices\n        class_keep = tf.gather(keep, tf.gather(ixs, class_keep))\n        # Pad with -1 so returned tensors have the same shape\n        gap = config.DETECTION_MAX_INSTANCES - tf.shape(class_keep)[0]\n        class_keep = tf.pad(class_keep, [(0, gap)],\n                            mode='CONSTANT', constant_values=-1)\n        # Set shape so map_fn() can infer result shape\n        class_keep.set_shape([config.DETECTION_MAX_INSTANCES])\n        return class_keep\n\n    # 2. Map over class IDs\n    nms_keep = tf.map_fn(nms_keep_map, unique_pre_nms_class_ids,\n                         dtype=tf.int64)\n    # 3. Merge results into one list, and remove -1 padding\n    nms_keep = tf.reshape(nms_keep, [-1])\n    nms_keep = tf.gather(nms_keep, tf.where(nms_keep > -1)[:, 0])\n    # 4. Compute intersection between keep and nms_keep\n    keep = tf.sets.set_intersection(tf.expand_dims(keep, 0),\n                                    tf.expand_dims(nms_keep, 0))\n    keep = tf.sparse_tensor_to_dense(keep)[0]\n    # Keep top detections\n    roi_count = config.DETECTION_MAX_INSTANCES\n    class_scores_keep = tf.gather(class_scores, keep)\n    num_keep = tf.minimum(tf.shape(class_scores_keep)[0], roi_count)\n    top_ids = tf.nn.top_k(class_scores_keep, k=num_keep, sorted=True)[1]\n    keep = tf.gather(keep, top_ids)\n\n    # Arrange output as [N, (y1, x1, y2, x2, class_id, score)]\n    # Coordinates are normalized.\n    detections = tf.concat([\n        tf.gather(refined_rois, keep),\n        tf.to_float(tf.gather(class_ids, keep))[..., tf.newaxis],\n        tf.gather(class_scores, keep)[..., tf.newaxis]\n        ], axis=1)\n\n    # Pad with zeros if detections < DETECTION_MAX_INSTANCES\n    gap = config.DETECTION_MAX_INSTANCES - tf.shape(detections)[0]\n    detections = tf.pad(detections, [(0, gap), (0, 0)], \"CONSTANT\")\n    return detections\n\n\nclass DetectionLayer(KE.Layer):\n    \"\"\"Takes classified proposal boxes and their bounding box deltas and\n    returns the final detection boxes.\n\n    Returns:\n    [batch, num_detections, (y1, x1, y2, x2, class_id, class_score)] where\n    coordinates are normalized.\n    \"\"\"\n\n    def __init__(self, config=None, **kwargs):\n        super(DetectionLayer, self).__init__(**kwargs)\n        self.config = config\n\n    def call(self, inputs):\n        rois = inputs[0]\n        mrcnn_class = inputs[1]\n        mrcnn_bbox = inputs[2]\n        image_meta = inputs[3]\n\n        # Get windows of images in normalized coordinates. Windows are the area\n        # in the image that excludes the padding.\n        # Use the shape of the first image in the batch to normalize the window\n        # because we know that all images get resized to the same size.\n        m = parse_image_meta_graph(image_meta)\n        image_shape = m['image_shape'][0]\n        window = norm_boxes_graph(m['window'], image_shape[:2])\n\n        # Run detection refinement graph on each item in the batch\n        detections_batch = utils.batch_slice(\n            [rois, mrcnn_class, mrcnn_bbox, window],\n            lambda x, y, w, z: refine_detections_graph(x, y, w, z, self.config),\n            self.config.IMAGES_PER_GPU)\n\n        # Reshape output\n        # [batch, num_detections, (y1, x1, y2, x2, class_id, class_score)] in\n        # normalized coordinates\n        return tf.reshape(\n            detections_batch,\n            [self.config.BATCH_SIZE, self.config.DETECTION_MAX_INSTANCES, 6])\n\n    def compute_output_shape(self, input_shape):\n        return (None, self.config.DETECTION_MAX_INSTANCES, 6)\n\n\n############################################################\n#  Region Proposal Network (RPN)\n############################################################\n\ndef rpn_graph(feature_map, anchors_per_location, anchor_stride):\n    \"\"\"Builds the computation graph of Region Proposal Network.\n\n    feature_map: backbone features [batch, height, width, depth]\n    anchors_per_location: number of anchors per pixel in the feature map\n    anchor_stride: Controls the density of anchors. Typically 1 (anchors for\n                   every pixel in the feature map), or 2 (every other pixel).\n\n    Returns:\n        rpn_class_logits: [batch, H * W * anchors_per_location, 2] Anchor classifier logits (before softmax)\n        rpn_probs: [batch, H * W * anchors_per_location, 2] Anchor classifier probabilities.\n        rpn_bbox: [batch, H * W * anchors_per_location, (dy, dx, log(dh), log(dw))] Deltas to be\n                  applied to anchors.\n    \"\"\"\n    # TODO: check if stride of 2 causes alignment issues if the feature map\n    # is not even.\n    # Shared convolutional base of the RPN\n    shared = KL.Conv2D(512, (3, 3), padding='same', activation='relu',\n                       strides=anchor_stride,\n                       name='rpn_conv_shared')(feature_map)\n\n    # Anchor Score. [batch, height, width, anchors per location * 2].\n    x = KL.Conv2D(2 * anchors_per_location, (1, 1), padding='valid',\n                  activation='linear', name='rpn_class_raw')(shared)\n\n    # Reshape to [batch, anchors, 2]\n    rpn_class_logits = KL.Lambda(\n        lambda t: tf.reshape(t, [tf.shape(t)[0], -1, 2]))(x)\n\n    # Softmax on last dimension of BG/FG.\n    rpn_probs = KL.Activation(\n        \"softmax\", name=\"rpn_class_xxx\")(rpn_class_logits)\n\n    # Bounding box refinement. [batch, H, W, anchors per location * depth]\n    # where depth is [x, y, log(w), log(h)]\n    x = KL.Conv2D(anchors_per_location * 4, (1, 1), padding=\"valid\",\n                  activation='linear', name='rpn_bbox_pred')(shared)\n\n    # Reshape to [batch, anchors, 4]\n    rpn_bbox = KL.Lambda(lambda t: tf.reshape(t, [tf.shape(t)[0], -1, 4]))(x)\n\n    return [rpn_class_logits, rpn_probs, rpn_bbox]\n\n\ndef build_rpn_model(anchor_stride, anchors_per_location, depth):\n    \"\"\"Builds a Keras model of the Region Proposal Network.\n    It wraps the RPN graph so it can be used multiple times with shared\n    weights.\n\n    anchors_per_location: number of anchors per pixel in the feature map\n    anchor_stride: Controls the density of anchors. Typically 1 (anchors for\n                   every pixel in the feature map), or 2 (every other pixel).\n    depth: Depth of the backbone feature map.\n\n    Returns a Keras Model object. The model outputs, when called, are:\n    rpn_class_logits: [batch, H * W * anchors_per_location, 2] Anchor classifier logits (before softmax)\n    rpn_probs: [batch, H * W * anchors_per_location, 2] Anchor classifier probabilities.\n    rpn_bbox: [batch, H * W * anchors_per_location, (dy, dx, log(dh), log(dw))] Deltas to be\n                applied to anchors.\n    \"\"\"\n    input_feature_map = KL.Input(shape=[None, None, depth],\n                                 name=\"input_rpn_feature_map\")\n    outputs = rpn_graph(input_feature_map, anchors_per_location, anchor_stride)\n    return KM.Model([input_feature_map], outputs, name=\"rpn_model\")\n\n\n############################################################\n#  Feature Pyramid Network Heads\n############################################################\n\ndef fpn_classifier_graph(rois, feature_maps, image_meta,\n                         pool_size, num_classes, train_bn=True,\n                         fc_layers_size=1024):\n    \"\"\"Builds the computation graph of the feature pyramid network classifier\n    and regressor heads.\n\n    rois: [batch, num_rois, (y1, x1, y2, x2)] Proposal boxes in normalized\n          coordinates.\n    feature_maps: List of feature maps from different layers of the pyramid,\n                  [P2, P3, P4, P5]. Each has a different resolution.\n    image_meta: [batch, (meta data)] Image details. See compose_image_meta()\n    pool_size: The width of the square feature map generated from ROI Pooling.\n    num_classes: number of classes, which determines the depth of the results\n    train_bn: Boolean. Train or freeze Batch Norm layers\n    fc_layers_size: Size of the 2 FC layers\n\n    Returns:\n        logits: [batch, num_rois, NUM_CLASSES] classifier logits (before softmax)\n        probs: [batch, num_rois, NUM_CLASSES] classifier probabilities\n        bbox_deltas: [batch, num_rois, NUM_CLASSES, (dy, dx, log(dh), log(dw))] Deltas to apply to\n                     proposal boxes\n    \"\"\"\n    # ROI Pooling\n    # Shape: [batch, num_rois, POOL_SIZE, POOL_SIZE, channels]\n    x = PyramidROIAlign([pool_size, pool_size],\n                        name=\"roi_align_classifier\")([rois, image_meta] + feature_maps)\n    # Two 1024 FC layers (implemented with Conv2D for consistency)\n    x = KL.TimeDistributed(KL.Conv2D(fc_layers_size, (pool_size, pool_size), padding=\"valid\"),\n                           name=\"mrcnn_class_conv1\")(x)\n    x = KL.TimeDistributed(BatchNorm(), name='mrcnn_class_bn1')(x, training=train_bn)\n    x = KL.Activation('relu')(x)\n    x = KL.TimeDistributed(KL.Conv2D(fc_layers_size, (1, 1)),\n                           name=\"mrcnn_class_conv2\")(x)\n    x = KL.TimeDistributed(BatchNorm(), name='mrcnn_class_bn2')(x, training=train_bn)\n    x = KL.Activation('relu')(x)\n\n    shared = KL.Lambda(lambda x: K.squeeze(K.squeeze(x, 3), 2),\n                       name=\"pool_squeeze\")(x)\n\n    # Classifier head\n    mrcnn_class_logits = KL.TimeDistributed(KL.Dense(num_classes),\n                                            name='mrcnn_class_logits')(shared)\n    mrcnn_probs = KL.TimeDistributed(KL.Activation(\"softmax\"),\n                                     name=\"mrcnn_class\")(mrcnn_class_logits)\n\n    # BBox head\n    # [batch, num_rois, NUM_CLASSES * (dy, dx, log(dh), log(dw))]\n    x = KL.TimeDistributed(KL.Dense(num_classes * 4, activation='linear'),\n                           name='mrcnn_bbox_fc')(shared)\n    # Reshape to [batch, num_rois, NUM_CLASSES, (dy, dx, log(dh), log(dw))]\n    s = K.int_shape(x)\n    mrcnn_bbox = KL.Reshape((s[1], num_classes, 4), name=\"mrcnn_bbox\")(x)\n\n    return mrcnn_class_logits, mrcnn_probs, mrcnn_bbox\n\n\ndef build_fpn_mask_graph(rois, feature_maps, image_meta,\n                         pool_size, num_classes, train_bn=True):\n    \"\"\"Builds the computation graph of the mask head of Feature Pyramid Network.\n\n    rois: [batch, num_rois, (y1, x1, y2, x2)] Proposal boxes in normalized\n          coordinates.\n    feature_maps: List of feature maps from different layers of the pyramid,\n                  [P2, P3, P4, P5]. Each has a different resolution.\n    image_meta: [batch, (meta data)] Image details. See compose_image_meta()\n    pool_size: The width of the square feature map generated from ROI Pooling.\n    num_classes: number of classes, which determines the depth of the results\n    train_bn: Boolean. Train or freeze Batch Norm layers\n\n    Returns: Masks [batch, num_rois, MASK_POOL_SIZE, MASK_POOL_SIZE, NUM_CLASSES]\n    \"\"\"\n    # ROI Pooling\n    # Shape: [batch, num_rois, MASK_POOL_SIZE, MASK_POOL_SIZE, channels]\n    x = PyramidROIAlign([pool_size, pool_size],\n                        name=\"roi_align_mask\")([rois, image_meta] + feature_maps)\n\n    # Conv layers\n    x = KL.TimeDistributed(KL.Conv2D(256, (3, 3), padding=\"same\"),\n                           name=\"mrcnn_mask_conv1\")(x)\n    x = KL.TimeDistributed(BatchNorm(),\n                           name='mrcnn_mask_bn1')(x, training=train_bn)\n    x = KL.Activation('relu')(x)\n\n    x = KL.TimeDistributed(KL.Conv2D(256, (3, 3), padding=\"same\"),\n                           name=\"mrcnn_mask_conv2\")(x)\n    x = KL.TimeDistributed(BatchNorm(),\n                           name='mrcnn_mask_bn2')(x, training=train_bn)\n    x = KL.Activation('relu')(x)\n\n    x = KL.TimeDistributed(KL.Conv2D(256, (3, 3), padding=\"same\"),\n                           name=\"mrcnn_mask_conv3\")(x)\n    x = KL.TimeDistributed(BatchNorm(),\n                           name='mrcnn_mask_bn3')(x, training=train_bn)\n    x = KL.Activation('relu')(x)\n\n    x = KL.TimeDistributed(KL.Conv2D(256, (3, 3), padding=\"same\"),\n                           name=\"mrcnn_mask_conv4\")(x)\n    x = KL.TimeDistributed(BatchNorm(),\n                           name='mrcnn_mask_bn4')(x, training=train_bn)\n    x = KL.Activation('relu')(x)\n\n    x = KL.TimeDistributed(KL.Conv2DTranspose(256, (2, 2), strides=2, activation=\"relu\"),\n                           name=\"mrcnn_mask_deconv\")(x)\n    x = KL.TimeDistributed(KL.Conv2D(num_classes, (1, 1), strides=1, activation=\"sigmoid\"),\n                           name=\"mrcnn_mask\")(x)\n    return x\n\n\n############################################################\n#  Loss Functions\n############################################################\n\ndef smooth_l1_loss(y_true, y_pred):\n    \"\"\"Implements Smooth-L1 loss.\n    y_true and y_pred are typically: [N, 4], but could be any shape.\n    \"\"\"\n    diff = K.abs(y_true - y_pred)\n    less_than_one = K.cast(K.less(diff, 1.0), \"float32\")\n    loss = (less_than_one * 0.5 * diff**2) + (1 - less_than_one) * (diff - 0.5)\n    return loss\n\n\ndef rpn_class_loss_graph(rpn_match, rpn_class_logits):\n    \"\"\"RPN anchor classifier loss.\n\n    rpn_match: [batch, anchors, 1]. Anchor match type. 1=positive,\n               -1=negative, 0=neutral anchor.\n    rpn_class_logits: [batch, anchors, 2]. RPN classifier logits for BG/FG.\n    \"\"\"\n    # Squeeze last dim to simplify\n    rpn_match = tf.squeeze(rpn_match, -1)\n    # Get anchor classes. Convert the -1/+1 match to 0/1 values.\n    anchor_class = K.cast(K.equal(rpn_match, 1), tf.int32)\n    # Positive and Negative anchors contribute to the loss,\n    # but neutral anchors (match value = 0) don't.\n    indices = tf.where(K.not_equal(rpn_match, 0))\n    # Pick rows that contribute to the loss and filter out the rest.\n    rpn_class_logits = tf.gather_nd(rpn_class_logits, indices)\n    anchor_class = tf.gather_nd(anchor_class, indices)\n    # Cross entropy loss\n    loss = K.sparse_categorical_crossentropy(target=anchor_class,\n                                             output=rpn_class_logits,\n                                             from_logits=True)\n    loss = K.switch(tf.size(loss) > 0, K.mean(loss), tf.constant(0.0))\n    return loss\n\n\ndef rpn_bbox_loss_graph(config, target_bbox, rpn_match, rpn_bbox):\n    \"\"\"Return the RPN bounding box loss graph.\n\n    config: the model config object.\n    target_bbox: [batch, max positive anchors, (dy, dx, log(dh), log(dw))].\n        Uses 0 padding to fill in unsed bbox deltas.\n    rpn_match: [batch, anchors, 1]. Anchor match type. 1=positive,\n               -1=negative, 0=neutral anchor.\n    rpn_bbox: [batch, anchors, (dy, dx, log(dh), log(dw))]\n    \"\"\"\n    # Positive anchors contribute to the loss, but negative and\n    # neutral anchors (match value of 0 or -1) don't.\n    rpn_match = K.squeeze(rpn_match, -1)\n    indices = tf.where(K.equal(rpn_match, 1))\n\n    # Pick bbox deltas that contribute to the loss\n    rpn_bbox = tf.gather_nd(rpn_bbox, indices)\n\n    # Trim target bounding box deltas to the same length as rpn_bbox.\n    batch_counts = K.sum(K.cast(K.equal(rpn_match, 1), tf.int32), axis=1)\n    target_bbox = batch_pack_graph(target_bbox, batch_counts,\n                                   config.IMAGES_PER_GPU)\n\n    loss = smooth_l1_loss(target_bbox, rpn_bbox)\n    \n    loss = K.switch(tf.size(loss) > 0, K.mean(loss), tf.constant(0.0))\n    return loss\n\n\ndef mrcnn_class_loss_graph(target_class_ids, pred_class_logits,\n                           active_class_ids):\n    \"\"\"Loss for the classifier head of Mask RCNN.\n\n    target_class_ids: [batch, num_rois]. Integer class IDs. Uses zero\n        padding to fill in the array.\n    pred_class_logits: [batch, num_rois, num_classes]\n    active_class_ids: [batch, num_classes]. Has a value of 1 for\n        classes that are in the dataset of the image, and 0\n        for classes that are not in the dataset.\n    \"\"\"\n    # During model building, Keras calls this function with\n    # target_class_ids of type float32. Unclear why. Cast it\n    # to int to get around it.\n    target_class_ids = tf.cast(target_class_ids, 'int64')\n\n    # Find predictions of classes that are not in the dataset.\n    pred_class_ids = tf.argmax(pred_class_logits, axis=2)\n    # TODO: Update this line to work with batch > 1. Right now it assumes all\n    #       images in a batch have the same active_class_ids\n    pred_active = tf.gather(active_class_ids[0], pred_class_ids)\n\n    # Loss\n    loss = tf.nn.sparse_softmax_cross_entropy_with_logits(\n        labels=target_class_ids, logits=pred_class_logits)\n\n    # Erase losses of predictions of classes that are not in the active\n    # classes of the image.\n    loss = loss * pred_active\n\n    # Computer loss mean. Use only predictions that contribute\n    # to the loss to get a correct mean.\n    loss = tf.reduce_sum(loss) / tf.reduce_sum(pred_active)\n    return loss\n\n\ndef mrcnn_bbox_loss_graph(target_bbox, target_class_ids, pred_bbox):\n    \"\"\"Loss for Mask R-CNN bounding box refinement.\n\n    target_bbox: [batch, num_rois, (dy, dx, log(dh), log(dw))]\n    target_class_ids: [batch, num_rois]. Integer class IDs.\n    pred_bbox: [batch, num_rois, num_classes, (dy, dx, log(dh), log(dw))]\n    \"\"\"\n    # Reshape to merge batch and roi dimensions for simplicity.\n    target_class_ids = K.reshape(target_class_ids, (-1,))\n    target_bbox = K.reshape(target_bbox, (-1, 4))\n    pred_bbox = K.reshape(pred_bbox, (-1, K.int_shape(pred_bbox)[2], 4))\n\n    # Only positive ROIs contribute to the loss. And only\n    # the right class_id of each ROI. Get their indices.\n    positive_roi_ix = tf.where(target_class_ids > 0)[:, 0]\n    positive_roi_class_ids = tf.cast(\n        tf.gather(target_class_ids, positive_roi_ix), tf.int64)\n    indices = tf.stack([positive_roi_ix, positive_roi_class_ids], axis=1)\n\n    # Gather the deltas (predicted and true) that contribute to loss\n    target_bbox = tf.gather(target_bbox, positive_roi_ix)\n    pred_bbox = tf.gather_nd(pred_bbox, indices)\n\n    # Smooth-L1 Loss\n    loss = K.switch(tf.size(target_bbox) > 0,\n                    smooth_l1_loss(y_true=target_bbox, y_pred=pred_bbox),\n                    tf.constant(0.0))\n    loss = K.mean(loss)\n    return loss\n\n\ndef mrcnn_mask_loss_graph(target_masks, target_class_ids, pred_masks):\n    \"\"\"Mask binary cross-entropy loss for the masks head.\n\n    target_masks: [batch, num_rois, height, width].\n        A float32 tensor of values 0 or 1. Uses zero padding to fill array.\n    target_class_ids: [batch, num_rois]. Integer class IDs. Zero padded.\n    pred_masks: [batch, proposals, height, width, num_classes] float32 tensor\n                with values from 0 to 1.\n    \"\"\"\n    # Reshape for simplicity. Merge first two dimensions into one.\n    target_class_ids = K.reshape(target_class_ids, (-1,))\n    mask_shape = tf.shape(target_masks)\n    target_masks = K.reshape(target_masks, (-1, mask_shape[2], mask_shape[3]))\n    pred_shape = tf.shape(pred_masks)\n    pred_masks = K.reshape(pred_masks,\n                           (-1, pred_shape[2], pred_shape[3], pred_shape[4]))\n    # Permute predicted masks to [N, num_classes, height, width]\n    pred_masks = tf.transpose(pred_masks, [0, 3, 1, 2])\n\n    # Only positive ROIs contribute to the loss. And only\n    # the class specific mask of each ROI.\n    positive_ix = tf.where(target_class_ids > 0)[:, 0]\n    positive_class_ids = tf.cast(\n        tf.gather(target_class_ids, positive_ix), tf.int64)\n    indices = tf.stack([positive_ix, positive_class_ids], axis=1)\n\n    # Gather the masks (predicted and true) that contribute to loss\n    y_true = tf.gather(target_masks, positive_ix)\n    y_pred = tf.gather_nd(pred_masks, indices)\n\n    # Compute binary cross entropy. If no positive ROIs, then return 0.\n    # shape: [batch, roi, num_classes]\n    loss = K.switch(tf.size(y_true) > 0,\n                    K.binary_crossentropy(target=y_true, output=y_pred),\n                    tf.constant(0.0))\n    loss = K.mean(loss)\n    return loss\n\n\n############################################################\n#  Data Generator\n############################################################\n\ndef load_image_gt(dataset, config, image_id, augment=False, augmentation=None,\n                  use_mini_mask=False):\n    \"\"\"Load and return ground truth data for an image (image, mask, bounding boxes).\n\n    augment: (deprecated. Use augmentation instead). If true, apply random\n        image augmentation. Currently, only horizontal flipping is offered.\n    augmentation: Optional. An imgaug (https://github.com/aleju/imgaug) augmentation.\n        For example, passing imgaug.augmenters.Fliplr(0.5) flips images\n        right/left 50% of the time.\n    use_mini_mask: If False, returns full-size masks that are the same height\n        and width as the original image. These can be big, for example\n        1024x1024x100 (for 100 instances). Mini masks are smaller, typically,\n        224x224 and are generated by extracting the bounding box of the\n        object and resizing it to MINI_MASK_SHAPE.\n\n    Returns:\n    image: [height, width, 3]\n    shape: the original shape of the image before resizing and cropping.\n    class_ids: [instance_count] Integer class IDs\n    bbox: [instance_count, (y1, x1, y2, x2)]\n    mask: [height, width, instance_count]. The height and width are those\n        of the image unless use_mini_mask is True, in which case they are\n        defined in MINI_MASK_SHAPE.\n    \"\"\"\n    # Load image and mask\n    image = dataset.load_image(image_id)\n    mask, class_ids = dataset.load_mask(image_id)\n    original_shape = image.shape\n    image, window, scale, padding, crop = utils.resize_image(\n        image,\n        min_dim=config.IMAGE_MIN_DIM,\n        min_scale=config.IMAGE_MIN_SCALE,\n        max_dim=config.IMAGE_MAX_DIM,\n        mode=config.IMAGE_RESIZE_MODE)\n    mask = utils.resize_mask(mask, scale, padding, crop)\n\n    # Random horizontal flips.\n    # TODO: will be removed in a future update in favor of augmentation\n    if augment:\n        logging.warning(\"'augment' is deprecated. Use 'augmentation' instead.\")\n        if random.randint(0, 1):\n            image = np.fliplr(image)\n            mask = np.fliplr(mask)\n\n    # Augmentation\n    # This requires the imgaug lib (https://github.com/aleju/imgaug)\n    if augmentation:\n        import imgaug\n\n        # Augmenters that are safe to apply to masks\n        # Some, such as Affine, have settings that make them unsafe, so always\n        # test your augmentation on masks\n        MASK_AUGMENTERS = [\"Sequential\", \"SomeOf\", \"OneOf\", \"Sometimes\",\n                           \"Fliplr\", \"Flipud\", \"CropAndPad\",\n                           \"Affine\", \"PiecewiseAffine\"]\n\n        def hook(images, augmenter, parents, default):\n            \"\"\"Determines which augmenters to apply to masks.\"\"\"\n            return augmenter.__class__.__name__ in MASK_AUGMENTERS\n\n        # Store shapes before augmentation to compare\n        image_shape = image.shape\n        mask_shape = mask.shape\n        # Make augmenters deterministic to apply similarly to images and masks\n        det = augmentation.to_deterministic()\n        image = det.augment_image(image)\n        # Change mask to np.uint8 because imgaug doesn't support np.bool\n        mask = det.augment_image(mask.astype(np.uint8),\n                                 hooks=imgaug.HooksImages(activator=hook))\n        # Verify that shapes didn't change\n        assert image.shape == image_shape, \"Augmentation shouldn't change image size\"\n        assert mask.shape == mask_shape, \"Augmentation shouldn't change mask size\"\n        # Change mask back to bool\n        mask = mask.astype(np.bool)\n\n    # Note that some boxes might be all zeros if the corresponding mask got cropped out.\n    # and here is to filter them out\n    _idx = np.sum(mask, axis=(0, 1)) > 0\n    mask = mask[:, :, _idx]\n    class_ids = class_ids[_idx]\n    # Bounding boxes. Note that some boxes might be all zeros\n    # if the corresponding mask got cropped out.\n    # bbox: [num_instances, (y1, x1, y2, x2)]\n    bbox = utils.extract_bboxes(mask)\n\n    # Active classes\n    # Different datasets have different classes, so track the\n    # classes supported in the dataset of this image.\n    active_class_ids = np.zeros([dataset.num_classes], dtype=np.int32)\n    source_class_ids = dataset.source_class_ids[dataset.image_info[image_id][\"source\"]]\n    active_class_ids[source_class_ids] = 1\n\n    # Resize masks to smaller size to reduce memory usage\n    if use_mini_mask:\n        mask = utils.minimize_mask(bbox, mask, config.MINI_MASK_SHAPE)\n\n    # Image meta data\n    image_meta = compose_image_meta(image_id, original_shape, image.shape,\n                                    window, scale, active_class_ids)\n\n    return image, image_meta, class_ids, bbox, mask\n\n\ndef build_detection_targets(rpn_rois, gt_class_ids, gt_boxes, gt_masks, config):\n    \"\"\"Generate targets for training Stage 2 classifier and mask heads.\n    This is not used in normal training. It's useful for debugging or to train\n    the Mask RCNN heads without using the RPN head.\n\n    Inputs:\n    rpn_rois: [N, (y1, x1, y2, x2)] proposal boxes.\n    gt_class_ids: [instance count] Integer class IDs\n    gt_boxes: [instance count, (y1, x1, y2, x2)]\n    gt_masks: [height, width, instance count] Ground truth masks. Can be full\n              size or mini-masks.\n\n    Returns:\n    rois: [TRAIN_ROIS_PER_IMAGE, (y1, x1, y2, x2)]\n    class_ids: [TRAIN_ROIS_PER_IMAGE]. Integer class IDs.\n    bboxes: [TRAIN_ROIS_PER_IMAGE, NUM_CLASSES, (y, x, log(h), log(w))]. Class-specific\n            bbox refinements.\n    masks: [TRAIN_ROIS_PER_IMAGE, height, width, NUM_CLASSES). Class specific masks cropped\n           to bbox boundaries and resized to neural network output size.\n    \"\"\"\n    assert rpn_rois.shape[0] > 0\n    assert gt_class_ids.dtype == np.int32, \"Expected int but got {}\".format(\n        gt_class_ids.dtype)\n    assert gt_boxes.dtype == np.int32, \"Expected int but got {}\".format(\n        gt_boxes.dtype)\n    assert gt_masks.dtype == np.bool_, \"Expected bool but got {}\".format(\n        gt_masks.dtype)\n\n    # It's common to add GT Boxes to ROIs but we don't do that here because\n    # according to XinLei Chen's paper, it doesn't help.\n\n    # Trim empty padding in gt_boxes and gt_masks parts\n    instance_ids = np.where(gt_class_ids > 0)[0]\n    assert instance_ids.shape[0] > 0, \"Image must contain instances.\"\n    gt_class_ids = gt_class_ids[instance_ids]\n    gt_boxes = gt_boxes[instance_ids]\n    gt_masks = gt_masks[:, :, instance_ids]\n\n    # Compute areas of ROIs and ground truth boxes.\n    rpn_roi_area = (rpn_rois[:, 2] - rpn_rois[:, 0]) * \\\n        (rpn_rois[:, 3] - rpn_rois[:, 1])\n    gt_box_area = (gt_boxes[:, 2] - gt_boxes[:, 0]) * \\\n        (gt_boxes[:, 3] - gt_boxes[:, 1])\n\n    # Compute overlaps [rpn_rois, gt_boxes]\n    overlaps = np.zeros((rpn_rois.shape[0], gt_boxes.shape[0]))\n    for i in range(overlaps.shape[1]):\n        gt = gt_boxes[i]\n        overlaps[:, i] = utils.compute_iou(\n            gt, rpn_rois, gt_box_area[i], rpn_roi_area)\n\n    # Assign ROIs to GT boxes\n    rpn_roi_iou_argmax = np.argmax(overlaps, axis=1)\n    rpn_roi_iou_max = overlaps[np.arange(\n        overlaps.shape[0]), rpn_roi_iou_argmax]\n    # GT box assigned to each ROI\n    rpn_roi_gt_boxes = gt_boxes[rpn_roi_iou_argmax]\n    rpn_roi_gt_class_ids = gt_class_ids[rpn_roi_iou_argmax]\n\n    # Positive ROIs are those with >= 0.5 IoU with a GT box.\n    fg_ids = np.where(rpn_roi_iou_max > 0.5)[0]\n\n    # Negative ROIs are those with max IoU 0.1-0.5 (hard example mining)\n    # TODO: To hard example mine or not to hard example mine, that's the question\n    # bg_ids = np.where((rpn_roi_iou_max >= 0.1) & (rpn_roi_iou_max < 0.5))[0]\n    bg_ids = np.where(rpn_roi_iou_max < 0.5)[0]\n\n    # Subsample ROIs. Aim for 33% foreground.\n    # FG\n    fg_roi_count = int(config.TRAIN_ROIS_PER_IMAGE * config.ROI_POSITIVE_RATIO)\n    if fg_ids.shape[0] > fg_roi_count:\n        keep_fg_ids = np.random.choice(fg_ids, fg_roi_count, replace=False)\n    else:\n        keep_fg_ids = fg_ids\n    # BG\n    remaining = config.TRAIN_ROIS_PER_IMAGE - keep_fg_ids.shape[0]\n    if bg_ids.shape[0] > remaining:\n        keep_bg_ids = np.random.choice(bg_ids, remaining, replace=False)\n    else:\n        keep_bg_ids = bg_ids\n    # Combine indices of ROIs to keep\n    keep = np.concatenate([keep_fg_ids, keep_bg_ids])\n    # Need more?\n    remaining = config.TRAIN_ROIS_PER_IMAGE - keep.shape[0]\n    if remaining > 0:\n        # Looks like we don't have enough samples to maintain the desired\n        # balance. Reduce requirements and fill in the rest. This is\n        # likely different from the Mask RCNN paper.\n\n        # There is a small chance we have neither fg nor bg samples.\n        if keep.shape[0] == 0:\n            # Pick bg regions with easier IoU threshold\n            bg_ids = np.where(rpn_roi_iou_max < 0.5)[0]\n            assert bg_ids.shape[0] >= remaining\n            keep_bg_ids = np.random.choice(bg_ids, remaining, replace=False)\n            assert keep_bg_ids.shape[0] == remaining\n            keep = np.concatenate([keep, keep_bg_ids])\n        else:\n            # Fill the rest with repeated bg rois.\n            keep_extra_ids = np.random.choice(\n                keep_bg_ids, remaining, replace=True)\n            keep = np.concatenate([keep, keep_extra_ids])\n    assert keep.shape[0] == config.TRAIN_ROIS_PER_IMAGE, \\\n        \"keep doesn't match ROI batch size {}, {}\".format(\n            keep.shape[0], config.TRAIN_ROIS_PER_IMAGE)\n\n    # Reset the gt boxes assigned to BG ROIs.\n    rpn_roi_gt_boxes[keep_bg_ids, :] = 0\n    rpn_roi_gt_class_ids[keep_bg_ids] = 0\n\n    # For each kept ROI, assign a class_id, and for FG ROIs also add bbox refinement.\n    rois = rpn_rois[keep]\n    roi_gt_boxes = rpn_roi_gt_boxes[keep]\n    roi_gt_class_ids = rpn_roi_gt_class_ids[keep]\n    roi_gt_assignment = rpn_roi_iou_argmax[keep]\n\n    # Class-aware bbox deltas. [y, x, log(h), log(w)]\n    bboxes = np.zeros((config.TRAIN_ROIS_PER_IMAGE,\n                       config.NUM_CLASSES, 4), dtype=np.float32)\n    pos_ids = np.where(roi_gt_class_ids > 0)[0]\n    bboxes[pos_ids, roi_gt_class_ids[pos_ids]] = utils.box_refinement(\n        rois[pos_ids], roi_gt_boxes[pos_ids, :4])\n    # Normalize bbox refinements\n    bboxes /= config.BBOX_STD_DEV\n\n    # Generate class-specific target masks\n    masks = np.zeros((config.TRAIN_ROIS_PER_IMAGE, config.MASK_SHAPE[0], config.MASK_SHAPE[1], config.NUM_CLASSES),\n                     dtype=np.float32)\n    for i in pos_ids:\n        class_id = roi_gt_class_ids[i]\n        assert class_id > 0, \"class id must be greater than 0\"\n        gt_id = roi_gt_assignment[i]\n        class_mask = gt_masks[:, :, gt_id]\n\n        if config.USE_MINI_MASK:\n            # Create a mask placeholder, the size of the image\n            placeholder = np.zeros(config.IMAGE_SHAPE[:2], dtype=bool)\n            # GT box\n            gt_y1, gt_x1, gt_y2, gt_x2 = gt_boxes[gt_id]\n            gt_w = gt_x2 - gt_x1\n            gt_h = gt_y2 - gt_y1\n            # Resize mini mask to size of GT box\n            placeholder[gt_y1:gt_y2, gt_x1:gt_x2] = \\\n                np.round(utils.resize(class_mask, (gt_h, gt_w))).astype(bool)\n            # Place the mini batch in the placeholder\n            class_mask = placeholder\n\n        # Pick part of the mask and resize it\n        y1, x1, y2, x2 = rois[i].astype(np.int32)\n        m = class_mask[y1:y2, x1:x2]\n        mask = utils.resize(m, config.MASK_SHAPE)\n        masks[i, :, :, class_id] = mask\n\n    return rois, roi_gt_class_ids, bboxes, masks\n\n\ndef build_rpn_targets(image_shape, anchors, gt_class_ids, gt_boxes, config):\n    \"\"\"Given the anchors and GT boxes, compute overlaps and identify positive\n    anchors and deltas to refine them to match their corresponding GT boxes.\n\n    anchors: [num_anchors, (y1, x1, y2, x2)]\n    gt_class_ids: [num_gt_boxes] Integer class IDs.\n    gt_boxes: [num_gt_boxes, (y1, x1, y2, x2)]\n\n    Returns:\n    rpn_match: [N] (int32) matches between anchors and GT boxes.\n               1 = positive anchor, -1 = negative anchor, 0 = neutral\n    rpn_bbox: [N, (dy, dx, log(dh), log(dw))] Anchor bbox deltas.\n    \"\"\"\n    # RPN Match: 1 = positive anchor, -1 = negative anchor, 0 = neutral\n    rpn_match = np.zeros([anchors.shape[0]], dtype=np.int32)\n    # RPN bounding boxes: [max anchors per image, (dy, dx, log(dh), log(dw))]\n    rpn_bbox = np.zeros((config.RPN_TRAIN_ANCHORS_PER_IMAGE, 4))\n\n    # Handle COCO crowds\n    # A crowd box in COCO is a bounding box around several instances. Exclude\n    # them from training. A crowd box is given a negative class ID.\n    crowd_ix = np.where(gt_class_ids < 0)[0]\n    if crowd_ix.shape[0] > 0:\n        # Filter out crowds from ground truth class IDs and boxes\n        non_crowd_ix = np.where(gt_class_ids > 0)[0]\n        crowd_boxes = gt_boxes[crowd_ix]\n        gt_class_ids = gt_class_ids[non_crowd_ix]\n        gt_boxes = gt_boxes[non_crowd_ix]\n        # Compute overlaps with crowd boxes [anchors, crowds]\n        crowd_overlaps = utils.compute_overlaps(anchors, crowd_boxes)\n        crowd_iou_max = np.amax(crowd_overlaps, axis=1)\n        no_crowd_bool = (crowd_iou_max < 0.001)\n    else:\n        # All anchors don't intersect a crowd\n        no_crowd_bool = np.ones([anchors.shape[0]], dtype=bool)\n\n    # Compute overlaps [num_anchors, num_gt_boxes]\n    overlaps = utils.compute_overlaps(anchors, gt_boxes)\n\n    # Match anchors to GT Boxes\n    # If an anchor overlaps a GT box with IoU >= 0.7 then it's positive.\n    # If an anchor overlaps a GT box with IoU < 0.3 then it's negative.\n    # Neutral anchors are those that don't match the conditions above,\n    # and they don't influence the loss function.\n    # However, don't keep any GT box unmatched (rare, but happens). Instead,\n    # match it to the closest anchor (even if its max IoU is < 0.3).\n    #\n    # 1. Set negative anchors first. They get overwritten below if a GT box is\n    # matched to them. Skip boxes in crowd areas.\n    anchor_iou_argmax = np.argmax(overlaps, axis=1)\n    anchor_iou_max = overlaps[np.arange(overlaps.shape[0]), anchor_iou_argmax]\n    rpn_match[(anchor_iou_max < 0.3) & (no_crowd_bool)] = -1\n    # 2. Set an anchor for each GT box (regardless of IoU value).\n    # If multiple anchors have the same IoU match all of them\n    gt_iou_argmax = np.argwhere(overlaps == np.max(overlaps, axis=0))[:,0]\n    rpn_match[gt_iou_argmax] = 1\n    # 3. Set anchors with high overlap as positive.\n    rpn_match[anchor_iou_max >= 0.7] = 1\n\n    # Subsample to balance positive and negative anchors\n    # Don't let positives be more than half the anchors\n    ids = np.where(rpn_match == 1)[0]\n    extra = len(ids) - (config.RPN_TRAIN_ANCHORS_PER_IMAGE // 2)\n    if extra > 0:\n        # Reset the extra ones to neutral\n        ids = np.random.choice(ids, extra, replace=False)\n        rpn_match[ids] = 0\n    # Same for negative proposals\n    ids = np.where(rpn_match == -1)[0]\n    extra = len(ids) - (config.RPN_TRAIN_ANCHORS_PER_IMAGE -\n                        np.sum(rpn_match == 1))\n    if extra > 0:\n        # Rest the extra ones to neutral\n        ids = np.random.choice(ids, extra, replace=False)\n        rpn_match[ids] = 0\n\n    # For positive anchors, compute shift and scale needed to transform them\n    # to match the corresponding GT boxes.\n    ids = np.where(rpn_match == 1)[0]\n    ix = 0  # index into rpn_bbox\n    # TODO: use box_refinement() rather than duplicating the code here\n    for i, a in zip(ids, anchors[ids]):\n        # Closest gt box (it might have IoU < 0.7)\n        gt = gt_boxes[anchor_iou_argmax[i]]\n\n        # Convert coordinates to center plus width/height.\n        # GT Box\n        gt_h = gt[2] - gt[0]\n        gt_w = gt[3] - gt[1]\n        gt_center_y = gt[0] + 0.5 * gt_h\n        gt_center_x = gt[1] + 0.5 * gt_w\n        # Anchor\n        a_h = a[2] - a[0]\n        a_w = a[3] - a[1]\n        a_center_y = a[0] + 0.5 * a_h\n        a_center_x = a[1] + 0.5 * a_w\n\n        # Compute the bbox refinement that the RPN should predict.\n        rpn_bbox[ix] = [\n            (gt_center_y - a_center_y) / a_h,\n            (gt_center_x - a_center_x) / a_w,\n            np.log(gt_h / a_h),\n            np.log(gt_w / a_w),\n        ]\n        # Normalize\n        rpn_bbox[ix] /= config.RPN_BBOX_STD_DEV\n        ix += 1\n\n    return rpn_match, rpn_bbox\n\n\ndef generate_random_rois(image_shape, count, gt_class_ids, gt_boxes):\n    \"\"\"Generates ROI proposals similar to what a region proposal network\n    would generate.\n\n    image_shape: [Height, Width, Depth]\n    count: Number of ROIs to generate\n    gt_class_ids: [N] Integer ground truth class IDs\n    gt_boxes: [N, (y1, x1, y2, x2)] Ground truth boxes in pixels.\n\n    Returns: [count, (y1, x1, y2, x2)] ROI boxes in pixels.\n    \"\"\"\n    # placeholder\n    rois = np.zeros((count, 4), dtype=np.int32)\n\n    # Generate random ROIs around GT boxes (90% of count)\n    rois_per_box = int(0.9 * count / gt_boxes.shape[0])\n    for i in range(gt_boxes.shape[0]):\n        gt_y1, gt_x1, gt_y2, gt_x2 = gt_boxes[i]\n        h = gt_y2 - gt_y1\n        w = gt_x2 - gt_x1\n        # random boundaries\n        r_y1 = max(gt_y1 - h, 0)\n        r_y2 = min(gt_y2 + h, image_shape[0])\n        r_x1 = max(gt_x1 - w, 0)\n        r_x2 = min(gt_x2 + w, image_shape[1])\n\n        # To avoid generating boxes with zero area, we generate double what\n        # we need and filter out the extra. If we get fewer valid boxes\n        # than we need, we loop and try again.\n        while True:\n            y1y2 = np.random.randint(r_y1, r_y2, (rois_per_box * 2, 2))\n            x1x2 = np.random.randint(r_x1, r_x2, (rois_per_box * 2, 2))\n            # Filter out zero area boxes\n            threshold = 1\n            y1y2 = y1y2[np.abs(y1y2[:, 0] - y1y2[:, 1]) >=\n                        threshold][:rois_per_box]\n            x1x2 = x1x2[np.abs(x1x2[:, 0] - x1x2[:, 1]) >=\n                        threshold][:rois_per_box]\n            if y1y2.shape[0] == rois_per_box and x1x2.shape[0] == rois_per_box:\n                break\n\n        # Sort on axis 1 to ensure x1 <= x2 and y1 <= y2 and then reshape\n        # into x1, y1, x2, y2 order\n        x1, x2 = np.split(np.sort(x1x2, axis=1), 2, axis=1)\n        y1, y2 = np.split(np.sort(y1y2, axis=1), 2, axis=1)\n        box_rois = np.hstack([y1, x1, y2, x2])\n        rois[rois_per_box * i:rois_per_box * (i + 1)] = box_rois\n\n    # Generate random ROIs anywhere in the image (10% of count)\n    remaining_count = count - (rois_per_box * gt_boxes.shape[0])\n    # To avoid generating boxes with zero area, we generate double what\n    # we need and filter out the extra. If we get fewer valid boxes\n    # than we need, we loop and try again.\n    while True:\n        y1y2 = np.random.randint(0, image_shape[0], (remaining_count * 2, 2))\n        x1x2 = np.random.randint(0, image_shape[1], (remaining_count * 2, 2))\n        # Filter out zero area boxes\n        threshold = 1\n        y1y2 = y1y2[np.abs(y1y2[:, 0] - y1y2[:, 1]) >=\n                    threshold][:remaining_count]\n        x1x2 = x1x2[np.abs(x1x2[:, 0] - x1x2[:, 1]) >=\n                    threshold][:remaining_count]\n        if y1y2.shape[0] == remaining_count and x1x2.shape[0] == remaining_count:\n            break\n\n    # Sort on axis 1 to ensure x1 <= x2 and y1 <= y2 and then reshape\n    # into x1, y1, x2, y2 order\n    x1, x2 = np.split(np.sort(x1x2, axis=1), 2, axis=1)\n    y1, y2 = np.split(np.sort(y1y2, axis=1), 2, axis=1)\n    global_rois = np.hstack([y1, x1, y2, x2])\n    rois[-remaining_count:] = global_rois\n    return rois\n\n\ndef data_generator(dataset, config, shuffle=True, augment=False, augmentation=None,\n                   random_rois=0, batch_size=1, detection_targets=False,\n                   no_augmentation_sources=None):\n    \"\"\"A generator that returns images and corresponding target class ids,\n    bounding box deltas, and masks.\n\n    dataset: The Dataset object to pick data from\n    config: The model config object\n    shuffle: If True, shuffles the samples before every epoch\n    augment: (deprecated. Use augmentation instead). If true, apply random\n        image augmentation. Currently, only horizontal flipping is offered.\n    augmentation: Optional. An imgaug (https://github.com/aleju/imgaug) augmentation.\n        For example, passing imgaug.augmenters.Fliplr(0.5) flips images\n        right/left 50% of the time.\n    random_rois: If > 0 then generate proposals to be used to train the\n                 network classifier and mask heads. Useful if training\n                 the Mask RCNN part without the RPN.\n    batch_size: How many images to return in each call\n    detection_targets: If True, generate detection targets (class IDs, bbox\n        deltas, and masks). Typically for debugging or visualizations because\n        in trainig detection targets are generated by DetectionTargetLayer.\n    no_augmentation_sources: Optional. List of sources to exclude for\n        augmentation. A source is string that identifies a dataset and is\n        defined in the Dataset class.\n\n    Returns a Python generator. Upon calling next() on it, the\n    generator returns two lists, inputs and outputs. The contents\n    of the lists differs depending on the received arguments:\n    inputs list:\n    - images: [batch, H, W, C]\n    - image_meta: [batch, (meta data)] Image details. See compose_image_meta()\n    - rpn_match: [batch, N] Integer (1=positive anchor, -1=negative, 0=neutral)\n    - rpn_bbox: [batch, N, (dy, dx, log(dh), log(dw))] Anchor bbox deltas.\n    - gt_class_ids: [batch, MAX_GT_INSTANCES] Integer class IDs\n    - gt_boxes: [batch, MAX_GT_INSTANCES, (y1, x1, y2, x2)]\n    - gt_masks: [batch, height, width, MAX_GT_INSTANCES]. The height and width\n                are those of the image unless use_mini_mask is True, in which\n                case they are defined in MINI_MASK_SHAPE.\n\n    outputs list: Usually empty in regular training. But if detection_targets\n        is True then the outputs list contains target class_ids, bbox deltas,\n        and masks.\n    \"\"\"\n    b = 0  # batch item index\n    image_index = -1\n    image_ids = np.copy(dataset.image_ids)\n    error_count = 0\n    no_augmentation_sources = no_augmentation_sources or []\n\n    # Anchors\n    # [anchor_count, (y1, x1, y2, x2)]\n    backbone_shapes = compute_backbone_shapes(config, config.IMAGE_SHAPE)\n    anchors = utils.generate_pyramid_anchors(config.RPN_ANCHOR_SCALES,\n                                             config.RPN_ANCHOR_RATIOS,\n                                             backbone_shapes,\n                                             config.BACKBONE_STRIDES,\n                                             config.RPN_ANCHOR_STRIDE)\n\n    # Keras requires a generator to run indefinitely.\n    while True:\n        try:\n            # Increment index to pick next image. Shuffle if at the start of an epoch.\n            image_index = (image_index + 1) % len(image_ids)\n            if shuffle and image_index == 0:\n                np.random.shuffle(image_ids)\n\n            # Get GT bounding boxes and masks for image.\n            image_id = image_ids[image_index]\n\n            # If the image source is not to be augmented pass None as augmentation\n            if dataset.image_info[image_id]['source'] in no_augmentation_sources:\n                image, image_meta, gt_class_ids, gt_boxes, gt_masks = \\\n                load_image_gt(dataset, config, image_id, augment=augment,\n                              augmentation=None,\n                              use_mini_mask=config.USE_MINI_MASK)\n            else:\n                image, image_meta, gt_class_ids, gt_boxes, gt_masks = \\\n                    load_image_gt(dataset, config, image_id, augment=augment,\n                                augmentation=augmentation,\n                                use_mini_mask=config.USE_MINI_MASK)\n\n            # Skip images that have no instances. This can happen in cases\n            # where we train on a subset of classes and the image doesn't\n            # have any of the classes we care about.\n            if not np.any(gt_class_ids > 0):\n                continue\n\n            # RPN Targets\n            rpn_match, rpn_bbox = build_rpn_targets(image.shape, anchors,\n                                                    gt_class_ids, gt_boxes, config)\n\n            # Mask R-CNN Targets\n            if random_rois:\n                rpn_rois = generate_random_rois(\n                    image.shape, random_rois, gt_class_ids, gt_boxes)\n                if detection_targets:\n                    rois, mrcnn_class_ids, mrcnn_bbox, mrcnn_mask =\\\n                        build_detection_targets(\n                            rpn_rois, gt_class_ids, gt_boxes, gt_masks, config)\n\n            # Init batch arrays\n            if b == 0:\n                batch_image_meta = np.zeros(\n                    (batch_size,) + image_meta.shape, dtype=image_meta.dtype)\n                batch_rpn_match = np.zeros(\n                    [batch_size, anchors.shape[0], 1], dtype=rpn_match.dtype)\n                batch_rpn_bbox = np.zeros(\n                    [batch_size, config.RPN_TRAIN_ANCHORS_PER_IMAGE, 4], dtype=rpn_bbox.dtype)\n                batch_images = np.zeros(\n                    (batch_size,) + image.shape, dtype=np.float32)\n                batch_gt_class_ids = np.zeros(\n                    (batch_size, config.MAX_GT_INSTANCES), dtype=np.int32)\n                batch_gt_boxes = np.zeros(\n                    (batch_size, config.MAX_GT_INSTANCES, 4), dtype=np.int32)\n                batch_gt_masks = np.zeros(\n                    (batch_size, gt_masks.shape[0], gt_masks.shape[1],\n                     config.MAX_GT_INSTANCES), dtype=gt_masks.dtype)\n                if random_rois:\n                    batch_rpn_rois = np.zeros(\n                        (batch_size, rpn_rois.shape[0], 4), dtype=rpn_rois.dtype)\n                    if detection_targets:\n                        batch_rois = np.zeros(\n                            (batch_size,) + rois.shape, dtype=rois.dtype)\n                        batch_mrcnn_class_ids = np.zeros(\n                            (batch_size,) + mrcnn_class_ids.shape, dtype=mrcnn_class_ids.dtype)\n                        batch_mrcnn_bbox = np.zeros(\n                            (batch_size,) + mrcnn_bbox.shape, dtype=mrcnn_bbox.dtype)\n                        batch_mrcnn_mask = np.zeros(\n                            (batch_size,) + mrcnn_mask.shape, dtype=mrcnn_mask.dtype)\n\n            # If more instances than fits in the array, sub-sample from them.\n            if gt_boxes.shape[0] > config.MAX_GT_INSTANCES:\n                ids = np.random.choice(\n                    np.arange(gt_boxes.shape[0]), config.MAX_GT_INSTANCES, replace=False)\n                gt_class_ids = gt_class_ids[ids]\n                gt_boxes = gt_boxes[ids]\n                gt_masks = gt_masks[:, :, ids]\n\n            # Add to batch\n            batch_image_meta[b] = image_meta\n            batch_rpn_match[b] = rpn_match[:, np.newaxis]\n            batch_rpn_bbox[b] = rpn_bbox\n            batch_images[b] = mold_image(image.astype(np.float32), config)\n            batch_gt_class_ids[b, :gt_class_ids.shape[0]] = gt_class_ids\n            batch_gt_boxes[b, :gt_boxes.shape[0]] = gt_boxes\n            batch_gt_masks[b, :, :, :gt_masks.shape[-1]] = gt_masks\n            if random_rois:\n                batch_rpn_rois[b] = rpn_rois\n                if detection_targets:\n                    batch_rois[b] = rois\n                    batch_mrcnn_class_ids[b] = mrcnn_class_ids\n                    batch_mrcnn_bbox[b] = mrcnn_bbox\n                    batch_mrcnn_mask[b] = mrcnn_mask\n            b += 1\n\n            # Batch full?\n            if b >= batch_size:\n                inputs = [batch_images, batch_image_meta, batch_rpn_match, batch_rpn_bbox,\n                          batch_gt_class_ids, batch_gt_boxes, batch_gt_masks]\n                outputs = []\n\n                if random_rois:\n                    inputs.extend([batch_rpn_rois])\n                    if detection_targets:\n                        inputs.extend([batch_rois])\n                        # Keras requires that output and targets have the same number of dimensions\n                        batch_mrcnn_class_ids = np.expand_dims(\n                            batch_mrcnn_class_ids, -1)\n                        outputs.extend(\n                            [batch_mrcnn_class_ids, batch_mrcnn_bbox, batch_mrcnn_mask])\n\n                yield inputs, outputs\n\n                # start a new batch\n                b = 0\n        except (GeneratorExit, KeyboardInterrupt):\n            raise\n        except:\n            # Log it and skip the image\n            logging.exception(\"Error processing image {}\".format(\n                dataset.image_info[image_id]))\n            error_count += 1\n            if error_count > 5:\n                raise\n\n\n############################################################\n#  MaskRCNN Class\n############################################################\n\nclass MaskRCNN():\n    \"\"\"Encapsulates the Mask RCNN model functionality.\n\n    The actual Keras model is in the keras_model property.\n    \"\"\"\n\n    def __init__(self, mode, config, model_dir):\n        \"\"\"\n        mode: Either \"training\" or \"inference\"\n        config: A Sub-class of the Config class\n        model_dir: Directory to save training logs and trained weights\n        \"\"\"\n        assert mode in ['training', 'inference']\n        self.mode = mode\n        self.config = config\n        self.model_dir = model_dir\n        self.set_log_dir()\n        self.keras_model = self.build(mode=mode, config=config)\n\n    def build(self, mode, config):\n        \"\"\"Build Mask R-CNN architecture.\n            input_shape: The shape of the input image.\n            mode: Either \"training\" or \"inference\". The inputs and\n                outputs of the model differ accordingly.\n        \"\"\"\n        assert mode in ['training', 'inference']\n\n        # Image size must be dividable by 2 multiple times\n        h, w = config.IMAGE_SHAPE[:2]\n        if h / 2**6 != int(h / 2**6) or w / 2**6 != int(w / 2**6):\n            raise Exception(\"Image size must be dividable by 2 at least 6 times \"\n                            \"to avoid fractions when downscaling and upscaling.\"\n                            \"For example, use 256, 320, 384, 448, 512, ... etc. \")\n\n        # Inputs\n        input_image = KL.Input(\n            shape=[None, None, config.IMAGE_SHAPE[2]], name=\"input_image\")\n        input_image_meta = KL.Input(shape=[config.IMAGE_META_SIZE],\n                                    name=\"input_image_meta\")\n        if mode == \"training\":\n            # RPN GT\n            input_rpn_match = KL.Input(\n                shape=[None, 1], name=\"input_rpn_match\", dtype=tf.int32)\n            input_rpn_bbox = KL.Input(\n                shape=[None, 4], name=\"input_rpn_bbox\", dtype=tf.float32)\n\n            # Detection GT (class IDs, bounding boxes, and masks)\n            # 1. GT Class IDs (zero padded)\n            input_gt_class_ids = KL.Input(\n                shape=[None], name=\"input_gt_class_ids\", dtype=tf.int32)\n            # 2. GT Boxes in pixels (zero padded)\n            # [batch, MAX_GT_INSTANCES, (y1, x1, y2, x2)] in image coordinates\n            input_gt_boxes = KL.Input(\n                shape=[None, 4], name=\"input_gt_boxes\", dtype=tf.float32)\n            # Normalize coordinates\n            gt_boxes = KL.Lambda(lambda x: norm_boxes_graph(\n                x, K.shape(input_image)[1:3]))(input_gt_boxes)\n            # 3. GT Masks (zero padded)\n            # [batch, height, width, MAX_GT_INSTANCES]\n            if config.USE_MINI_MASK:\n                input_gt_masks = KL.Input(\n                    shape=[config.MINI_MASK_SHAPE[0],\n                           config.MINI_MASK_SHAPE[1], None],\n                    name=\"input_gt_masks\", dtype=bool)\n            else:\n                input_gt_masks = KL.Input(\n                    shape=[config.IMAGE_SHAPE[0], config.IMAGE_SHAPE[1], None],\n                    name=\"input_gt_masks\", dtype=bool)\n        elif mode == \"inference\":\n            # Anchors in normalized coordinates\n            input_anchors = KL.Input(shape=[None, 4], name=\"input_anchors\")\n\n        # Build the shared convolutional layers.\n        # Bottom-up Layers\n        # Returns a list of the last layers of each stage, 5 in total.\n        # Don't create the thead (stage 5), so we pick the 4th item in the list.\n        if callable(config.BACKBONE):\n            _, C2, C3, C4, C5 = config.BACKBONE(input_image, stage5=True,\n                                                train_bn=config.TRAIN_BN)\n        else:\n            _, C2, C3, C4, C5 = resnet_graph(input_image, config.BACKBONE,\n                                             stage5=True, train_bn=config.TRAIN_BN)\n        # Top-down Layers\n        # TODO: add assert to varify feature map sizes match what's in config\n        P5 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (1, 1), name='fpn_c5p5')(C5)\n        P4 = KL.Add(name=\"fpn_p4add\")([\n            KL.UpSampling2D(size=(2, 2), name=\"fpn_p5upsampled\")(P5),\n            KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (1, 1), name='fpn_c4p4')(C4)])\n        P3 = KL.Add(name=\"fpn_p3add\")([\n            KL.UpSampling2D(size=(2, 2), name=\"fpn_p4upsampled\")(P4),\n            KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (1, 1), name='fpn_c3p3')(C3)])\n        P2 = KL.Add(name=\"fpn_p2add\")([\n            KL.UpSampling2D(size=(2, 2), name=\"fpn_p3upsampled\")(P3),\n            KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (1, 1), name='fpn_c2p2')(C2)])\n        # Attach 3x3 conv to all P layers to get the final feature maps.\n        P2 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (3, 3), padding=\"SAME\", name=\"fpn_p2\")(P2)\n        P3 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (3, 3), padding=\"SAME\", name=\"fpn_p3\")(P3)\n        P4 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (3, 3), padding=\"SAME\", name=\"fpn_p4\")(P4)\n        P5 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (3, 3), padding=\"SAME\", name=\"fpn_p5\")(P5)\n        # P6 is used for the 5th anchor scale in RPN. Generated by\n        # subsampling from P5 with stride of 2.\n        P6 = KL.MaxPooling2D(pool_size=(1, 1), strides=2, name=\"fpn_p6\")(P5)\n\n        # Note that P6 is used in RPN, but not in the classifier heads.\n        rpn_feature_maps = [P2, P3, P4, P5, P6]\n        mrcnn_feature_maps = [P2, P3, P4, P5]\n\n        # Anchors\n        if mode == \"training\":\n            anchors = self.get_anchors(config.IMAGE_SHAPE)\n            # Duplicate across the batch dimension because Keras requires it\n            # TODO: can this be optimized to avoid duplicating the anchors?\n            anchors = np.broadcast_to(anchors, (config.BATCH_SIZE,) + anchors.shape)\n            # A hack to get around Keras's bad support for constants\n            anchors = KL.Lambda(lambda x: tf.Variable(anchors), name=\"anchors\")(input_image)\n        else:\n            anchors = input_anchors\n\n        # RPN Model\n        rpn = build_rpn_model(config.RPN_ANCHOR_STRIDE,\n                              len(config.RPN_ANCHOR_RATIOS), config.TOP_DOWN_PYRAMID_SIZE)\n        # Loop through pyramid layers\n        layer_outputs = []  # list of lists\n        for p in rpn_feature_maps:\n            layer_outputs.append(rpn([p]))\n        # Concatenate layer outputs\n        # Convert from list of lists of level outputs to list of lists\n        # of outputs across levels.\n        # e.g. [[a1, b1, c1], [a2, b2, c2]] => [[a1, a2], [b1, b2], [c1, c2]]\n        output_names = [\"rpn_class_logits\", \"rpn_class\", \"rpn_bbox\"]\n        outputs = list(zip(*layer_outputs))\n        outputs = [KL.Concatenate(axis=1, name=n)(list(o))\n                   for o, n in zip(outputs, output_names)]\n\n        rpn_class_logits, rpn_class, rpn_bbox = outputs\n\n        # Generate proposals\n        # Proposals are [batch, N, (y1, x1, y2, x2)] in normalized coordinates\n        # and zero padded.\n        proposal_count = config.POST_NMS_ROIS_TRAINING if mode == \"training\"\\\n            else config.POST_NMS_ROIS_INFERENCE\n        rpn_rois = ProposalLayer(\n            proposal_count=proposal_count,\n            nms_threshold=config.RPN_NMS_THRESHOLD,\n            name=\"ROI\",\n            config=config)([rpn_class, rpn_bbox, anchors])\n\n        if mode == \"training\":\n            # Class ID mask to mark class IDs supported by the dataset the image\n            # came from.\n            active_class_ids = KL.Lambda(\n                lambda x: parse_image_meta_graph(x)[\"active_class_ids\"]\n                )(input_image_meta)\n\n            if not config.USE_RPN_ROIS:\n                # Ignore predicted ROIs and use ROIs provided as an input.\n                input_rois = KL.Input(shape=[config.POST_NMS_ROIS_TRAINING, 4],\n                                      name=\"input_roi\", dtype=np.int32)\n                # Normalize coordinates\n                target_rois = KL.Lambda(lambda x: norm_boxes_graph(\n                    x, K.shape(input_image)[1:3]))(input_rois)\n            else:\n                target_rois = rpn_rois\n\n            # Generate detection targets\n            # Subsamples proposals and generates target outputs for training\n            # Note that proposal class IDs, gt_boxes, and gt_masks are zero\n            # padded. Equally, returned rois and targets are zero padded.\n            rois, target_class_ids, target_bbox, target_mask =\\\n                DetectionTargetLayer(config, name=\"proposal_targets\")([\n                    target_rois, input_gt_class_ids, gt_boxes, input_gt_masks])\n\n            # Network Heads\n            # TODO: verify that this handles zero padded ROIs\n            mrcnn_class_logits, mrcnn_class, mrcnn_bbox =\\\n                fpn_classifier_graph(rois, mrcnn_feature_maps, input_image_meta,\n                                     config.POOL_SIZE, config.NUM_CLASSES,\n                                     train_bn=config.TRAIN_BN,\n                                     fc_layers_size=config.FPN_CLASSIF_FC_LAYERS_SIZE)\n\n            mrcnn_mask = build_fpn_mask_graph(rois, mrcnn_feature_maps,\n                                              input_image_meta,\n                                              config.MASK_POOL_SIZE,\n                                              config.NUM_CLASSES,\n                                              train_bn=config.TRAIN_BN)\n\n            # TODO: clean up (use tf.identify if necessary)\n            output_rois = KL.Lambda(lambda x: x * 1, name=\"output_rois\")(rois)\n\n            # Losses\n            rpn_class_loss = KL.Lambda(lambda x: rpn_class_loss_graph(*x), name=\"rpn_class_loss\")(\n                [input_rpn_match, rpn_class_logits])\n            rpn_bbox_loss = KL.Lambda(lambda x: rpn_bbox_loss_graph(config, *x), name=\"rpn_bbox_loss\")(\n                [input_rpn_bbox, input_rpn_match, rpn_bbox])\n            class_loss = KL.Lambda(lambda x: mrcnn_class_loss_graph(*x), name=\"mrcnn_class_loss\")(\n                [target_class_ids, mrcnn_class_logits, active_class_ids])\n            bbox_loss = KL.Lambda(lambda x: mrcnn_bbox_loss_graph(*x), name=\"mrcnn_bbox_loss\")(\n                [target_bbox, target_class_ids, mrcnn_bbox])\n            mask_loss = KL.Lambda(lambda x: mrcnn_mask_loss_graph(*x), name=\"mrcnn_mask_loss\")(\n                [target_mask, target_class_ids, mrcnn_mask])\n\n            # Model\n            inputs = [input_image, input_image_meta,\n                      input_rpn_match, input_rpn_bbox, input_gt_class_ids, input_gt_boxes, input_gt_masks]\n            if not config.USE_RPN_ROIS:\n                inputs.append(input_rois)\n            outputs = [rpn_class_logits, rpn_class, rpn_bbox,\n                       mrcnn_class_logits, mrcnn_class, mrcnn_bbox, mrcnn_mask,\n                       rpn_rois, output_rois,\n                       rpn_class_loss, rpn_bbox_loss, class_loss, bbox_loss, mask_loss]\n            model = KM.Model(inputs, outputs, name='mask_rcnn')\n        else:\n            # Network Heads\n            # Proposal classifier and BBox regressor heads\n            mrcnn_class_logits, mrcnn_class, mrcnn_bbox =\\\n                fpn_classifier_graph(rpn_rois, mrcnn_feature_maps, input_image_meta,\n                                     config.POOL_SIZE, config.NUM_CLASSES,\n                                     train_bn=config.TRAIN_BN,\n                                     fc_layers_size=config.FPN_CLASSIF_FC_LAYERS_SIZE)\n\n            # Detections\n            # output is [batch, num_detections, (y1, x1, y2, x2, class_id, score)] in\n            # normalized coordinates\n            detections = DetectionLayer(config, name=\"mrcnn_detection\")(\n                [rpn_rois, mrcnn_class, mrcnn_bbox, input_image_meta])\n\n            # Create masks for detections\n            detection_boxes = KL.Lambda(lambda x: x[..., :4])(detections)\n            mrcnn_mask = build_fpn_mask_graph(detection_boxes, mrcnn_feature_maps,\n                                              input_image_meta,\n                                              config.MASK_POOL_SIZE,\n                                              config.NUM_CLASSES,\n                                              train_bn=config.TRAIN_BN)\n\n            model = KM.Model([input_image, input_image_meta, input_anchors],\n                             [detections, mrcnn_class, mrcnn_bbox,\n                                 mrcnn_mask, rpn_rois, rpn_class, rpn_bbox],\n                             name='mask_rcnn')\n\n        # Add multi-GPU support.\n        if config.GPU_COUNT > 1:\n            from mrcnn.parallel_model import ParallelModel\n            model = ParallelModel(model, config.GPU_COUNT)\n\n        return model\n\n    def find_last(self):\n        \"\"\"Finds the last checkpoint file of the last trained model in the\n        model directory.\n        Returns:\n            The path of the last checkpoint file\n        \"\"\"\n        # Get directory names. Each directory corresponds to a model\n        dir_names = next(os.walk(self.model_dir))[1]\n        key = self.config.NAME.lower()\n        dir_names = filter(lambda f: f.startswith(key), dir_names)\n        dir_names = sorted(dir_names)\n        if not dir_names:\n            import errno\n            raise FileNotFoundError(\n                errno.ENOENT,\n                \"Could not find model directory under {}\".format(self.model_dir))\n        # Pick last directory\n        dir_name = os.path.join(self.model_dir, dir_names[-1])\n        # Find the last checkpoint\n        checkpoints = next(os.walk(dir_name))[2]\n        checkpoints = filter(lambda f: f.startswith(\"mask_rcnn\"), checkpoints)\n        checkpoints = sorted(checkpoints)\n        if not checkpoints:\n            import errno\n            raise FileNotFoundError(\n                errno.ENOENT, \"Could not find weight files in {}\".format(dir_name))\n        checkpoint = os.path.join(dir_name, checkpoints[-1])\n        return checkpoint\n\n    def load_weights(self, filepath, by_name=False, exclude=None):\n        \"\"\"Modified version of the corresponding Keras function with\n        the addition of multi-GPU support and the ability to exclude\n        some layers from loading.\n        exclude: list of layer names to exclude\n        \"\"\"\n        import h5py\n        # Conditional import to support versions of Keras before 2.2\n        # TODO: remove in about 6 months (end of 2018)\n        try:\n            from keras.engine import saving\n        except ImportError:\n            # Keras before 2.2 used the 'topology' namespace.\n            from keras.engine import topology as saving\n\n        if exclude:\n            by_name = True\n\n        if h5py is None:\n            raise ImportError('`load_weights` requires h5py.')\n        f = h5py.File(filepath, mode='r')\n        if 'layer_names' not in f.attrs and 'model_weights' in f:\n            f = f['model_weights']\n\n        # In multi-GPU training, we wrap the model. Get layers\n        # of the inner model because they have the weights.\n        keras_model = self.keras_model\n        layers = keras_model.inner_model.layers if hasattr(keras_model, \"inner_model\")\\\n            else keras_model.layers\n\n        # Exclude some layers\n        if exclude:\n            layers = filter(lambda l: l.name not in exclude, layers)\n\n        if by_name:\n            saving.load_weights_from_hdf5_group_by_name(f, layers)\n        else:\n            saving.load_weights_from_hdf5_group(f, layers)\n        if hasattr(f, 'close'):\n            f.close()\n\n        # Update the log directory\n        self.set_log_dir(filepath)\n\n    def get_imagenet_weights(self):\n        \"\"\"Downloads ImageNet trained weights from Keras.\n        Returns path to weights file.\n        \"\"\"\n        from keras.utils.data_utils import get_file\n        TF_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/'\\\n                                 'releases/download/v0.2/'\\\n                                 'resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5'\n        weights_path = get_file('resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5',\n                                TF_WEIGHTS_PATH_NO_TOP,\n                                cache_subdir='models',\n                                md5_hash='a268eb855778b3df3c7506639542a6af')\n        return weights_path\n\n    def compile(self, learning_rate, momentum):\n        \"\"\"Gets the model ready for training. Adds losses, regularization, and\n        metrics. Then calls the Keras compile() function.\n        \"\"\"\n        # Optimizer object\n        optimizer = keras.optimizers.SGD(\n            lr=learning_rate, momentum=momentum,\n            clipnorm=self.config.GRADIENT_CLIP_NORM)\n        # Add Losses\n        # First, clear previously set losses to avoid duplication\n        self.keras_model._losses = []\n        self.keras_model._per_input_losses = {}\n        loss_names = [\n            \"rpn_class_loss\",  \"rpn_bbox_loss\",\n            \"mrcnn_class_loss\", \"mrcnn_bbox_loss\", \"mrcnn_mask_loss\"]\n        for name in loss_names:\n            layer = self.keras_model.get_layer(name)\n            if layer.output in self.keras_model.losses:\n                continue\n            loss = (\n                tf.reduce_mean(layer.output, keepdims=True)\n                * self.config.LOSS_WEIGHTS.get(name, 1.))\n            self.keras_model.add_loss(loss)\n\n        # Add L2 Regularization\n        # Skip gamma and beta weights of batch normalization layers.\n        reg_losses = [\n            keras.regularizers.l2(self.config.WEIGHT_DECAY)(w) / tf.cast(tf.size(w), tf.float32)\n            for w in self.keras_model.trainable_weights\n            if 'gamma' not in w.name and 'beta' not in w.name]\n        self.keras_model.add_loss(tf.add_n(reg_losses))\n\n        # Compile\n        self.keras_model.compile(\n            optimizer=optimizer,\n            loss=[None] * len(self.keras_model.outputs))\n\n        # Add metrics for losses\n        for name in loss_names:\n            if name in self.keras_model.metrics_names:\n                continue\n            layer = self.keras_model.get_layer(name)\n            self.keras_model.metrics_names.append(name)\n            loss = (\n                tf.reduce_mean(layer.output, keepdims=True)\n                * self.config.LOSS_WEIGHTS.get(name, 1.))\n            self.keras_model.metrics_tensors.append(loss)\n\n    def set_trainable(self, layer_regex, keras_model=None, indent=0, verbose=1):\n        \"\"\"Sets model layers as trainable if their names match\n        the given regular expression.\n        \"\"\"\n        # Print message on the first call (but not on recursive calls)\n        if verbose > 0 and keras_model is None:\n            log(\"Selecting layers to train\")\n\n        keras_model = keras_model or self.keras_model\n\n        # In multi-GPU training, we wrap the model. Get layers\n        # of the inner model because they have the weights.\n        layers = keras_model.inner_model.layers if hasattr(keras_model, \"inner_model\")\\\n            else keras_model.layers\n\n        for layer in layers:\n            # Is the layer a model?\n            if layer.__class__.__name__ == 'Model':\n                print(\"In model: \", layer.name)\n                self.set_trainable(\n                    layer_regex, keras_model=layer, indent=indent + 4)\n                continue\n\n            if not layer.weights:\n                continue\n            # Is it trainable?\n            trainable = bool(re.fullmatch(layer_regex, layer.name))\n            # Update layer. If layer is a container, update inner layer.\n            if layer.__class__.__name__ == 'TimeDistributed':\n                layer.layer.trainable = trainable\n            else:\n                layer.trainable = trainable\n            # Print trainable layer names\n            if trainable and verbose > 0:\n                log(\"{}{:20}   ({})\".format(\" \" * indent, layer.name,\n                                            layer.__class__.__name__))\n\n    def set_log_dir(self, model_path=None):\n        \"\"\"Sets the model log directory and epoch counter.\n\n        model_path: If None, or a format different from what this code uses\n            then set a new log directory and start epochs from 0. Otherwise,\n            extract the log directory and the epoch counter from the file\n            name.\n        \"\"\"\n        # Set date and epoch counter as if starting a new model\n        self.epoch = 0\n        now = datetime.datetime.now()\n\n        # If we have a model path with date and epochs use them\n        if model_path:\n            # Continue from we left of. Get epoch and date from the file name\n            # A sample model path might look like:\n            # \\path\\to\\logs\\coco20171029T2315\\mask_rcnn_coco_0001.h5 (Windows)\n            # /path/to/logs/coco20171029T2315/mask_rcnn_coco_0001.h5 (Linux)\n            regex = r\".*[/\\\\][\\w-]+(\\d{4})(\\d{2})(\\d{2})T(\\d{2})(\\d{2})[/\\\\]mask\\_rcnn\\_[\\w-]+(\\d{4})\\.h5\"\n            m = re.match(regex, model_path)\n            if m:\n                now = datetime.datetime(int(m.group(1)), int(m.group(2)), int(m.group(3)),\n                                        int(m.group(4)), int(m.group(5)))\n                # Epoch number in file is 1-based, and in Keras code it's 0-based.\n                # So, adjust for that then increment by one to start from the next epoch\n                self.epoch = int(m.group(6)) - 1 + 1\n                print('Re-starting from epoch %d' % self.epoch)\n\n        # Directory for training logs\n        self.log_dir = os.path.join(self.model_dir, \"{}{:%Y%m%dT%H%M}\".format(\n            self.config.NAME.lower(), now))\n\n        # Path to save after each epoch. Include placeholders that get filled by Keras.\n        self.checkpoint_path = os.path.join(self.log_dir, \"mask_rcnn_{}_*epoch*.h5\".format(\n            self.config.NAME.lower()))\n        self.checkpoint_path = self.checkpoint_path.replace(\n            \"*epoch*\", \"{epoch:04d}\")\n\n    def train(self, train_dataset, val_dataset, learning_rate, epochs, layers,\n              augmentation=None, custom_callbacks=None, no_augmentation_sources=None):\n        \"\"\"Train the model.\n        train_dataset, val_dataset: Training and validation Dataset objects.\n        learning_rate: The learning rate to train with\n        epochs: Number of training epochs. Note that previous training epochs\n                are considered to be done alreay, so this actually determines\n                the epochs to train in total rather than in this particaular\n                call.\n        layers: Allows selecting wich layers to train. It can be:\n            - A regular expression to match layer names to train\n            - One of these predefined values:\n              heads: The RPN, classifier and mask heads of the network\n              all: All the layers\n              3+: Train Resnet stage 3 and up\n              4+: Train Resnet stage 4 and up\n              5+: Train Resnet stage 5 and up\n        augmentation: Optional. An imgaug (https://github.com/aleju/imgaug)\n            augmentation. For example, passing imgaug.augmenters.Fliplr(0.5)\n            flips images right/left 50% of the time. You can pass complex\n            augmentations as well. This augmentation applies 50% of the\n            time, and when it does it flips images right/left half the time\n            and adds a Gaussian blur with a random sigma in range 0 to 5.\n\n                augmentation = imgaug.augmenters.Sometimes(0.5, [\n                    imgaug.augmenters.Fliplr(0.5),\n                    imgaug.augmenters.GaussianBlur(sigma=(0.0, 5.0))\n                ])\n\t    custom_callbacks: Optional. Add custom callbacks to be called\n\t        with the keras fit_generator method. Must be list of type keras.callbacks.\n        no_augmentation_sources: Optional. List of sources to exclude for\n            augmentation. A source is string that identifies a dataset and is\n            defined in the Dataset class.\n        \"\"\"\n        assert self.mode == \"training\", \"Create model in training mode.\"\n\n        # Pre-defined layer regular expressions\n        layer_regex = {\n            # all layers but the backbone\n            \"heads\": r\"(mrcnn\\_.*)|(rpn\\_.*)|(fpn\\_.*)\",\n            # From a specific Resnet stage and up\n            \"3+\": r\"(res3.*)|(bn3.*)|(res4.*)|(bn4.*)|(res5.*)|(bn5.*)|(mrcnn\\_.*)|(rpn\\_.*)|(fpn\\_.*)\",\n            \"4+\": r\"(res4.*)|(bn4.*)|(res5.*)|(bn5.*)|(mrcnn\\_.*)|(rpn\\_.*)|(fpn\\_.*)\",\n            \"5+\": r\"(res5.*)|(bn5.*)|(mrcnn\\_.*)|(rpn\\_.*)|(fpn\\_.*)\",\n            # All layers\n            \"all\": \".*\",\n        }\n        if layers in layer_regex.keys():\n            layers = layer_regex[layers]\n\n        # Data generators\n        train_generator = data_generator(train_dataset, self.config, shuffle=True,\n                                         augmentation=augmentation,\n                                         batch_size=self.config.BATCH_SIZE,\n                                         no_augmentation_sources=no_augmentation_sources)\n        val_generator = data_generator(val_dataset, self.config, shuffle=True,\n                                       batch_size=self.config.BATCH_SIZE)\n\n        # Create log_dir if it does not exist\n        if not os.path.exists(self.log_dir):\n            os.makedirs(self.log_dir)\n\n        # Callbacks\n        callbacks = [\n            keras.callbacks.TensorBoard(log_dir=self.log_dir,\n                                        histogram_freq=0, write_graph=True, write_images=False),\n            keras.callbacks.ModelCheckpoint(self.checkpoint_path,\n                                            verbose=0, save_weights_only=True),\n        ]\n\n        # Add custom callbacks to the list\n        if custom_callbacks:\n            callbacks += custom_callbacks\n\n        # Train\n        log(\"\\nStarting at epoch {}. LR={}\\n\".format(self.epoch, learning_rate))\n        log(\"Checkpoint Path: {}\".format(self.checkpoint_path))\n        self.set_trainable(layers)\n        self.compile(learning_rate, self.config.LEARNING_MOMENTUM)\n\n        # Work-around for Windows: Keras fails on Windows when using\n        # multiprocessing workers. See discussion here:\n        # https://github.com/matterport/Mask_RCNN/issues/13#issuecomment-353124009\n        if os.name is 'nt':\n            workers = 0\n        else:\n            workers = multiprocessing.cpu_count()\n\n        self.keras_model.fit_generator(\n            train_generator,\n            initial_epoch=self.epoch,\n            epochs=epochs,\n            steps_per_epoch=self.config.STEPS_PER_EPOCH,\n            callbacks=callbacks,\n            validation_data=val_generator,\n            validation_steps=self.config.VALIDATION_STEPS,\n            max_queue_size=100,\n            workers=workers,\n            use_multiprocessing=True,\n        )\n        self.epoch = max(self.epoch, epochs)\n\n    def mold_inputs(self, images):\n        \"\"\"Takes a list of images and modifies them to the format expected\n        as an input to the neural network.\n        images: List of image matrices [height,width,depth]. Images can have\n            different sizes.\n\n        Returns 3 Numpy matrices:\n        molded_images: [N, h, w, 3]. Images resized and normalized.\n        image_metas: [N, length of meta data]. Details about each image.\n        windows: [N, (y1, x1, y2, x2)]. The portion of the image that has the\n            original image (padding excluded).\n        \"\"\"\n        molded_images = []\n        image_metas = []\n        windows = []\n        for image in images:\n            # Resize image\n            # TODO: move resizing to mold_image()\n            molded_image, window, scale, padding, crop = utils.resize_image(\n                image,\n                min_dim=self.config.IMAGE_MIN_DIM,\n                min_scale=self.config.IMAGE_MIN_SCALE,\n                max_dim=self.config.IMAGE_MAX_DIM,\n                mode=self.config.IMAGE_RESIZE_MODE)\n            molded_image = mold_image(molded_image, self.config)\n            # Build image_meta\n            image_meta = compose_image_meta(\n                0, image.shape, molded_image.shape, window, scale,\n                np.zeros([self.config.NUM_CLASSES], dtype=np.int32))\n            # Append\n            molded_images.append(molded_image)\n            windows.append(window)\n            image_metas.append(image_meta)\n        # Pack into arrays\n        molded_images = np.stack(molded_images)\n        image_metas = np.stack(image_metas)\n        windows = np.stack(windows)\n        return molded_images, image_metas, windows\n\n    def unmold_detections(self, detections, mrcnn_mask, original_image_shape,\n                          image_shape, window):\n        \"\"\"Reformats the detections of one image from the format of the neural\n        network output to a format suitable for use in the rest of the\n        application.\n\n        detections: [N, (y1, x1, y2, x2, class_id, score)] in normalized coordinates\n        mrcnn_mask: [N, height, width, num_classes]\n        original_image_shape: [H, W, C] Original image shape before resizing\n        image_shape: [H, W, C] Shape of the image after resizing and padding\n        window: [y1, x1, y2, x2] Pixel coordinates of box in the image where the real\n                image is excluding the padding.\n\n        Returns:\n        boxes: [N, (y1, x1, y2, x2)] Bounding boxes in pixels\n        class_ids: [N] Integer class IDs for each bounding box\n        scores: [N] Float probability scores of the class_id\n        masks: [height, width, num_instances] Instance masks\n        \"\"\"\n        # How many detections do we have?\n        # Detections array is padded with zeros. Find the first class_id == 0.\n        zero_ix = np.where(detections[:, 4] == 0)[0]\n        N = zero_ix[0] if zero_ix.shape[0] > 0 else detections.shape[0]\n\n        # Extract boxes, class_ids, scores, and class-specific masks\n        boxes = detections[:N, :4]\n        class_ids = detections[:N, 4].astype(np.int32)\n        scores = detections[:N, 5]\n        masks = mrcnn_mask[np.arange(N), :, :, class_ids]\n\n        # Translate normalized coordinates in the resized image to pixel\n        # coordinates in the original image before resizing\n        window = utils.norm_boxes(window, image_shape[:2])\n        wy1, wx1, wy2, wx2 = window\n        shift = np.array([wy1, wx1, wy1, wx1])\n        wh = wy2 - wy1  # window height\n        ww = wx2 - wx1  # window width\n        scale = np.array([wh, ww, wh, ww])\n        # Convert boxes to normalized coordinates on the window\n        boxes = np.divide(boxes - shift, scale)\n        # Convert boxes to pixel coordinates on the original image\n        boxes = utils.denorm_boxes(boxes, original_image_shape[:2])\n\n        # Filter out detections with zero area. Happens in early training when\n        # network weights are still random\n        exclude_ix = np.where(\n            (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1]) <= 0)[0]\n        if exclude_ix.shape[0] > 0:\n            boxes = np.delete(boxes, exclude_ix, axis=0)\n            class_ids = np.delete(class_ids, exclude_ix, axis=0)\n            scores = np.delete(scores, exclude_ix, axis=0)\n            masks = np.delete(masks, exclude_ix, axis=0)\n            N = class_ids.shape[0]\n\n        # Resize masks to original image size and set boundary threshold.\n        full_masks = []\n        for i in range(N):\n            # Convert neural network mask to full size mask\n            full_mask = utils.unmold_mask(masks[i], boxes[i], original_image_shape)\n            full_masks.append(full_mask)\n        full_masks = np.stack(full_masks, axis=-1)\\\n            if full_masks else np.empty(original_image_shape[:2] + (0,))\n\n        return boxes, class_ids, scores, full_masks\n\n    def detect(self, images, verbose=0):\n        \"\"\"Runs the detection pipeline.\n\n        images: List of images, potentially of different sizes.\n\n        Returns a list of dicts, one dict per image. The dict contains:\n        rois: [N, (y1, x1, y2, x2)] detection bounding boxes\n        class_ids: [N] int class IDs\n        scores: [N] float probability scores for the class IDs\n        masks: [H, W, N] instance binary masks\n        \"\"\"\n        assert self.mode == \"inference\", \"Create model in inference mode.\"\n        assert len(\n            images) == self.config.BATCH_SIZE, \"len(images) must be equal to BATCH_SIZE\"\n\n        if verbose:\n            log(\"Processing {} images\".format(len(images)))\n            for image in images:\n                log(\"image\", image)\n\n        # Mold inputs to format expected by the neural network\n        molded_images, image_metas, windows = self.mold_inputs(images)\n\n        # Validate image sizes\n        # All images in a batch MUST be of the same size\n        image_shape = molded_images[0].shape\n        for g in molded_images[1:]:\n            assert g.shape == image_shape,\\\n                \"After resizing, all images must have the same size. Check IMAGE_RESIZE_MODE and image sizes.\"\n\n        # Anchors\n        anchors = self.get_anchors(image_shape)\n        # Duplicate across the batch dimension because Keras requires it\n        # TODO: can this be optimized to avoid duplicating the anchors?\n        anchors = np.broadcast_to(anchors, (self.config.BATCH_SIZE,) + anchors.shape)\n\n        if verbose:\n            log(\"molded_images\", molded_images)\n            log(\"image_metas\", image_metas)\n            log(\"anchors\", anchors)\n        # Run object detection\n        detections, _, _, mrcnn_mask, _, _, _ =\\\n            self.keras_model.predict([molded_images, image_metas, anchors], verbose=0)\n        # Process detections\n        results = []\n        for i, image in enumerate(images):\n            final_rois, final_class_ids, final_scores, final_masks =\\\n                self.unmold_detections(detections[i], mrcnn_mask[i],\n                                       image.shape, molded_images[i].shape,\n                                       windows[i])\n            results.append({\n                \"rois\": final_rois,\n                \"class_ids\": final_class_ids,\n                \"scores\": final_scores,\n                \"masks\": final_masks,\n            })\n        return results\n\n    def detect_molded(self, molded_images, image_metas, verbose=0):\n        \"\"\"Runs the detection pipeline, but expect inputs that are\n        molded already. Used mostly for debugging and inspecting\n        the model.\n\n        molded_images: List of images loaded using load_image_gt()\n        image_metas: image meta data, also returned by load_image_gt()\n\n        Returns a list of dicts, one dict per image. The dict contains:\n        rois: [N, (y1, x1, y2, x2)] detection bounding boxes\n        class_ids: [N] int class IDs\n        scores: [N] float probability scores for the class IDs\n        masks: [H, W, N] instance binary masks\n        \"\"\"\n        assert self.mode == \"inference\", \"Create model in inference mode.\"\n        assert len(molded_images) == self.config.BATCH_SIZE,\\\n            \"Number of images must be equal to BATCH_SIZE\"\n\n        if verbose:\n            log(\"Processing {} images\".format(len(molded_images)))\n            for image in molded_images:\n                log(\"image\", image)\n\n        # Validate image sizes\n        # All images in a batch MUST be of the same size\n        image_shape = molded_images[0].shape\n        for g in molded_images[1:]:\n            assert g.shape == image_shape, \"Images must have the same size\"\n\n        # Anchors\n        anchors = self.get_anchors(image_shape)\n        # Duplicate across the batch dimension because Keras requires it\n        # TODO: can this be optimized to avoid duplicating the anchors?\n        anchors = np.broadcast_to(anchors, (self.config.BATCH_SIZE,) + anchors.shape)\n\n        if verbose:\n            log(\"molded_images\", molded_images)\n            log(\"image_metas\", image_metas)\n            log(\"anchors\", anchors)\n        # Run object detection\n        detections, _, _, mrcnn_mask, _, _, _ =\\\n            self.keras_model.predict([molded_images, image_metas, anchors], verbose=0)\n        # Process detections\n        results = []\n        for i, image in enumerate(molded_images):\n            window = [0, 0, image.shape[0], image.shape[1]]\n            final_rois, final_class_ids, final_scores, final_masks =\\\n                self.unmold_detections(detections[i], mrcnn_mask[i],\n                                       image.shape, molded_images[i].shape,\n                                       window)\n            results.append({\n                \"rois\": final_rois,\n                \"class_ids\": final_class_ids,\n                \"scores\": final_scores,\n                \"masks\": final_masks,\n            })\n        return results\n\n    def get_anchors(self, image_shape):\n        \"\"\"Returns anchor pyramid for the given image size.\"\"\"\n        backbone_shapes = compute_backbone_shapes(self.config, image_shape)\n        # Cache anchors and reuse if image shape is the same\n        if not hasattr(self, \"_anchor_cache\"):\n            self._anchor_cache = {}\n        if not tuple(image_shape) in self._anchor_cache:\n            # Generate Anchors\n            a = utils.generate_pyramid_anchors(\n                self.config.RPN_ANCHOR_SCALES,\n                self.config.RPN_ANCHOR_RATIOS,\n                backbone_shapes,\n                self.config.BACKBONE_STRIDES,\n                self.config.RPN_ANCHOR_STRIDE)\n            # Keep a copy of the latest anchors in pixel coordinates because\n            # it's used in inspect_model notebooks.\n            # TODO: Remove this after the notebook are refactored to not use it\n            self.anchors = a\n            # Normalize coordinates\n            self._anchor_cache[tuple(image_shape)] = utils.norm_boxes(a, image_shape[:2])\n        return self._anchor_cache[tuple(image_shape)]\n\n    def ancestor(self, tensor, name, checked=None):\n        \"\"\"Finds the ancestor of a TF tensor in the computation graph.\n        tensor: TensorFlow symbolic tensor.\n        name: Name of ancestor tensor to find\n        checked: For internal use. A list of tensors that were already\n                 searched to avoid loops in traversing the graph.\n        \"\"\"\n        checked = checked if checked is not None else []\n        # Put a limit on how deep we go to avoid very long loops\n        if len(checked) > 500:\n            return None\n        # Convert name to a regex and allow matching a number prefix\n        # because Keras adds them automatically\n        if isinstance(name, str):\n            name = re.compile(name.replace(\"/\", r\"(\\_\\d+)*/\"))\n\n        parents = tensor.op.inputs\n        for p in parents:\n            if p in checked:\n                continue\n            if bool(re.fullmatch(name, p.name)):\n                return p\n            checked.append(p)\n            a = self.ancestor(p, name, checked)\n            if a is not None:\n                return a\n        return None\n\n    def find_trainable_layer(self, layer):\n        \"\"\"If a layer is encapsulated by another layer, this function\n        digs through the encapsulation and returns the layer that holds\n        the weights.\n        \"\"\"\n        if layer.__class__.__name__ == 'TimeDistributed':\n            return self.find_trainable_layer(layer.layer)\n        return layer\n\n    def get_trainable_layers(self):\n        \"\"\"Returns a list of layers that have weights.\"\"\"\n        layers = []\n        # Loop through all layers\n        for l in self.keras_model.layers:\n            # If layer is a wrapper, find inner trainable layer\n            l = self.find_trainable_layer(l)\n            # Include layer if it has weights\n            if l.get_weights():\n                layers.append(l)\n        return layers\n\n    def run_graph(self, images, outputs, image_metas=None):\n        \"\"\"Runs a sub-set of the computation graph that computes the given\n        outputs.\n\n        image_metas: If provided, the images are assumed to be already\n            molded (i.e. resized, padded, and normalized)\n\n        outputs: List of tuples (name, tensor) to compute. The tensors are\n            symbolic TensorFlow tensors and the names are for easy tracking.\n\n        Returns an ordered dict of results. Keys are the names received in the\n        input and values are Numpy arrays.\n        \"\"\"\n        model = self.keras_model\n\n        # Organize desired outputs into an ordered dict\n        outputs = OrderedDict(outputs)\n        for o in outputs.values():\n            assert o is not None\n\n        # Build a Keras function to run parts of the computation graph\n        inputs = model.inputs\n        if model.uses_learning_phase and not isinstance(K.learning_phase(), int):\n            inputs += [K.learning_phase()]\n        kf = K.function(model.inputs, list(outputs.values()))\n\n        # Prepare inputs\n        if image_metas is None:\n            molded_images, image_metas, _ = self.mold_inputs(images)\n        else:\n            molded_images = images\n        image_shape = molded_images[0].shape\n        # Anchors\n        anchors = self.get_anchors(image_shape)\n        # Duplicate across the batch dimension because Keras requires it\n        # TODO: can this be optimized to avoid duplicating the anchors?\n        anchors = np.broadcast_to(anchors, (self.config.BATCH_SIZE,) + anchors.shape)\n        model_in = [molded_images, image_metas, anchors]\n\n        # Run inference\n        if model.uses_learning_phase and not isinstance(K.learning_phase(), int):\n            model_in.append(0.)\n        outputs_np = kf(model_in)\n\n        # Pack the generated Numpy arrays into a a dict and log the results.\n        outputs_np = OrderedDict([(k, v)\n                                  for k, v in zip(outputs.keys(), outputs_np)])\n        for k, v in outputs_np.items():\n            log(k, v)\n        return outputs_np\n\n\n############################################################\n#  Data Formatting\n############################################################\n\ndef compose_image_meta(image_id, original_image_shape, image_shape,\n                       window, scale, active_class_ids):\n    \"\"\"Takes attributes of an image and puts them in one 1D array.\n\n    image_id: An int ID of the image. Useful for debugging.\n    original_image_shape: [H, W, C] before resizing or padding.\n    image_shape: [H, W, C] after resizing and padding\n    window: (y1, x1, y2, x2) in pixels. The area of the image where the real\n            image is (excluding the padding)\n    scale: The scaling factor applied to the original image (float32)\n    active_class_ids: List of class_ids available in the dataset from which\n        the image came. Useful if training on images from multiple datasets\n        where not all classes are present in all datasets.\n    \"\"\"\n    meta = np.array(\n        [image_id] +                  # size=1\n        list(original_image_shape) +  # size=3\n        list(image_shape) +           # size=3\n        list(window) +                # size=4 (y1, x1, y2, x2) in image cooredinates\n        [scale] +                     # size=1\n        list(active_class_ids)        # size=num_classes\n    )\n    return meta\n\n\ndef parse_image_meta(meta):\n    \"\"\"Parses an array that contains image attributes to its components.\n    See compose_image_meta() for more details.\n\n    meta: [batch, meta length] where meta length depends on NUM_CLASSES\n\n    Returns a dict of the parsed values.\n    \"\"\"\n    image_id = meta[:, 0]\n    original_image_shape = meta[:, 1:4]\n    image_shape = meta[:, 4:7]\n    window = meta[:, 7:11]  # (y1, x1, y2, x2) window of image in in pixels\n    scale = meta[:, 11]\n    active_class_ids = meta[:, 12:]\n    return {\n        \"image_id\": image_id.astype(np.int32),\n        \"original_image_shape\": original_image_shape.astype(np.int32),\n        \"image_shape\": image_shape.astype(np.int32),\n        \"window\": window.astype(np.int32),\n        \"scale\": scale.astype(np.float32),\n        \"active_class_ids\": active_class_ids.astype(np.int32),\n    }\n\n\ndef parse_image_meta_graph(meta):\n    \"\"\"Parses a tensor that contains image attributes to its components.\n    See compose_image_meta() for more details.\n\n    meta: [batch, meta length] where meta length depends on NUM_CLASSES\n\n    Returns a dict of the parsed tensors.\n    \"\"\"\n    image_id = meta[:, 0]\n    original_image_shape = meta[:, 1:4]\n    image_shape = meta[:, 4:7]\n    window = meta[:, 7:11]  # (y1, x1, y2, x2) window of image in in pixels\n    scale = meta[:, 11]\n    active_class_ids = meta[:, 12:]\n    return {\n        \"image_id\": image_id,\n        \"original_image_shape\": original_image_shape,\n        \"image_shape\": image_shape,\n        \"window\": window,\n        \"scale\": scale,\n        \"active_class_ids\": active_class_ids,\n    }\n\n\ndef mold_image(images, config):\n    \"\"\"Expects an RGB image (or array of images) and subtracts\n    the mean pixel and converts it to float. Expects image\n    colors in RGB order.\n    \"\"\"\n    return images.astype(np.float32) - config.MEAN_PIXEL\n\n\ndef unmold_image(normalized_images, config):\n    \"\"\"Takes a image normalized with mold() and returns the original.\"\"\"\n    return (normalized_images + config.MEAN_PIXEL).astype(np.uint8)\n\n\n############################################################\n#  Miscellenous Graph Functions\n############################################################\n\ndef trim_zeros_graph(boxes, name='trim_zeros'):\n    \"\"\"Often boxes are represented with matrices of shape [N, 4] and\n    are padded with zeros. This removes zero boxes.\n\n    boxes: [N, 4] matrix of boxes.\n    non_zeros: [N] a 1D boolean mask identifying the rows to keep\n    \"\"\"\n    non_zeros = tf.cast(tf.reduce_sum(tf.abs(boxes), axis=1), tf.bool)\n    boxes = tf.boolean_mask(boxes, non_zeros, name=name)\n    return boxes, non_zeros\n\n\ndef batch_pack_graph(x, counts, num_rows):\n    \"\"\"Picks different number of values from each row\n    in x depending on the values in counts.\n    \"\"\"\n    outputs = []\n    for i in range(num_rows):\n        outputs.append(x[i, :counts[i]])\n    return tf.concat(outputs, axis=0)\n\n\ndef norm_boxes_graph(boxes, shape):\n    \"\"\"Converts boxes from pixel coordinates to normalized coordinates.\n    boxes: [..., (y1, x1, y2, x2)] in pixel coordinates\n    shape: [..., (height, width)] in pixels\n\n    Note: In pixel coordinates (y2, x2) is outside the box. But in normalized\n    coordinates it's inside the box.\n\n    Returns:\n        [..., (y1, x1, y2, x2)] in normalized coordinates\n    \"\"\"\n    h, w = tf.split(tf.cast(shape, tf.float32), 2)\n    scale = tf.concat([h, w, h, w], axis=-1) - tf.constant(1.0)\n    shift = tf.constant([0., 0., 1., 1.])\n    return tf.divide(boxes - shift, scale)\n\n\ndef denorm_boxes_graph(boxes, shape):\n    \"\"\"Converts boxes from normalized coordinates to pixel coordinates.\n    boxes: [..., (y1, x1, y2, x2)] in normalized coordinates\n    shape: [..., (height, width)] in pixels\n\n    Note: In pixel coordinates (y2, x2) is outside the box. But in normalized\n    coordinates it's inside the box.\n\n    Returns:\n        [..., (y1, x1, y2, x2)] in pixel coordinates\n    \"\"\"\n    h, w = tf.split(tf.cast(shape, tf.float32), 2)\n    scale = tf.concat([h, w, h, w], axis=-1) - tf.constant(1.0)\n    shift = tf.constant([0., 0., 1., 1.])\n    return tf.cast(tf.round(tf.multiply(boxes, scale) + shift), tf.int32)\n"
  },
  {
    "path": "Image Processor/mrcnn/parallel_model.py",
    "content": "\"\"\"\nMask R-CNN\nMulti-GPU Support for Keras.\n\nCopyright (c) 2017 Matterport, Inc.\nLicensed under the MIT License (see LICENSE for details)\nWritten by Waleed Abdulla\n\nIdeas and a small code snippets from these sources:\nhttps://github.com/fchollet/keras/issues/2436\nhttps://medium.com/@kuza55/transparent-multi-gpu-training-on-tensorflow-with-keras-8b0016fd9012\nhttps://github.com/avolkov1/keras_experiments/blob/master/keras_exp/multigpu/\nhttps://github.com/fchollet/keras/blob/master/keras/utils/training_utils.py\n\"\"\"\n\nimport tensorflow as tf\nimport keras.backend as K\nimport keras.layers as KL\nimport keras.models as KM\n\n\nclass ParallelModel(KM.Model):\n    \"\"\"Subclasses the standard Keras Model and adds multi-GPU support.\n    It works by creating a copy of the model on each GPU. Then it slices\n    the inputs and sends a slice to each copy of the model, and then\n    merges the outputs together and applies the loss on the combined\n    outputs.\n    \"\"\"\n\n    def __init__(self, keras_model, gpu_count):\n        \"\"\"Class constructor.\n        keras_model: The Keras model to parallelize\n        gpu_count: Number of GPUs. Must be > 1\n        \"\"\"\n        self.inner_model = keras_model\n        self.gpu_count = gpu_count\n        merged_outputs = self.make_parallel()\n        super(ParallelModel, self).__init__(inputs=self.inner_model.inputs,\n                                            outputs=merged_outputs)\n\n    def __getattribute__(self, attrname):\n        \"\"\"Redirect loading and saving methods to the inner model. That's where\n        the weights are stored.\"\"\"\n        if 'load' in attrname or 'save' in attrname:\n            return getattr(self.inner_model, attrname)\n        return super(ParallelModel, self).__getattribute__(attrname)\n\n    def summary(self, *args, **kwargs):\n        \"\"\"Override summary() to display summaries of both, the wrapper\n        and inner models.\"\"\"\n        super(ParallelModel, self).summary(*args, **kwargs)\n        self.inner_model.summary(*args, **kwargs)\n\n    def make_parallel(self):\n        \"\"\"Creates a new wrapper model that consists of multiple replicas of\n        the original model placed on different GPUs.\n        \"\"\"\n        # Slice inputs. Slice inputs on the CPU to avoid sending a copy\n        # of the full inputs to all GPUs. Saves on bandwidth and memory.\n        input_slices = {name: tf.split(x, self.gpu_count)\n                        for name, x in zip(self.inner_model.input_names,\n                                           self.inner_model.inputs)}\n\n        output_names = self.inner_model.output_names\n        outputs_all = []\n        for i in range(len(self.inner_model.outputs)):\n            outputs_all.append([])\n\n        # Run the model call() on each GPU to place the ops there\n        for i in range(self.gpu_count):\n            with tf.device('/gpu:%d' % i):\n                with tf.name_scope('tower_%d' % i):\n                    # Run a slice of inputs through this replica\n                    zipped_inputs = zip(self.inner_model.input_names,\n                                        self.inner_model.inputs)\n                    inputs = [\n                        KL.Lambda(lambda s: input_slices[name][i],\n                                  output_shape=lambda s: (None,) + s[1:])(tensor)\n                        for name, tensor in zipped_inputs]\n                    # Create the model replica and get the outputs\n                    outputs = self.inner_model(inputs)\n                    if not isinstance(outputs, list):\n                        outputs = [outputs]\n                    # Save the outputs for merging back together later\n                    for l, o in enumerate(outputs):\n                        outputs_all[l].append(o)\n\n        # Merge outputs on CPU\n        with tf.device('/cpu:0'):\n            merged = []\n            for outputs, name in zip(outputs_all, output_names):\n                # Concatenate or average outputs?\n                # Outputs usually have a batch dimension and we concatenate\n                # across it. If they don't, then the output is likely a loss\n                # or a metric value that gets averaged across the batch.\n                # Keras expects losses and metrics to be scalars.\n                if K.int_shape(outputs[0]) == ():\n                    # Average\n                    m = KL.Lambda(lambda o: tf.add_n(o) / len(outputs), name=name)(outputs)\n                else:\n                    # Concatenate\n                    m = KL.Concatenate(axis=0, name=name)(outputs)\n                merged.append(m)\n        return merged\n\n\nif __name__ == \"__main__\":\n    # Testing code below. It creates a simple model to train on MNIST and\n    # tries to run it on 2 GPUs. It saves the graph so it can be viewed\n    # in TensorBoard. Run it as:\n    #\n    # python3 parallel_model.py\n\n    import os\n    import numpy as np\n    import keras.optimizers\n    from keras.datasets import mnist\n    from keras.preprocessing.image import ImageDataGenerator\n\n    GPU_COUNT = 2\n\n    # Root directory of the project\n    ROOT_DIR = os.path.abspath(\"../\")\n\n    # Directory to save logs and trained model\n    MODEL_DIR = os.path.join(ROOT_DIR, \"logs\")\n\n    def build_model(x_train, num_classes):\n        # Reset default graph. Keras leaves old ops in the graph,\n        # which are ignored for execution but clutter graph\n        # visualization in TensorBoard.\n        tf.reset_default_graph()\n\n        inputs = KL.Input(shape=x_train.shape[1:], name=\"input_image\")\n        x = KL.Conv2D(32, (3, 3), activation='relu', padding=\"same\",\n                      name=\"conv1\")(inputs)\n        x = KL.Conv2D(64, (3, 3), activation='relu', padding=\"same\",\n                      name=\"conv2\")(x)\n        x = KL.MaxPooling2D(pool_size=(2, 2), name=\"pool1\")(x)\n        x = KL.Flatten(name=\"flat1\")(x)\n        x = KL.Dense(128, activation='relu', name=\"dense1\")(x)\n        x = KL.Dense(num_classes, activation='softmax', name=\"dense2\")(x)\n\n        return KM.Model(inputs, x, \"digit_classifier_model\")\n\n    # Load MNIST Data\n    (x_train, y_train), (x_test, y_test) = mnist.load_data()\n    x_train = np.expand_dims(x_train, -1).astype('float32') / 255\n    x_test = np.expand_dims(x_test, -1).astype('float32') / 255\n\n    print('x_train shape:', x_train.shape)\n    print('x_test shape:', x_test.shape)\n\n    # Build data generator and model\n    datagen = ImageDataGenerator()\n    model = build_model(x_train, 10)\n\n    # Add multi-GPU support.\n    model = ParallelModel(model, GPU_COUNT)\n\n    optimizer = keras.optimizers.SGD(lr=0.01, momentum=0.9, clipnorm=5.0)\n\n    model.compile(loss='sparse_categorical_crossentropy',\n                  optimizer=optimizer, metrics=['accuracy'])\n\n    model.summary()\n\n    # Train\n    model.fit_generator(\n        datagen.flow(x_train, y_train, batch_size=64),\n        steps_per_epoch=50, epochs=10, verbose=1,\n        validation_data=(x_test, y_test),\n        callbacks=[keras.callbacks.TensorBoard(log_dir=MODEL_DIR,\n                                               write_graph=True)]\n    )\n"
  },
  {
    "path": "Image Processor/mrcnn/utils.py",
    "content": "\"\"\"\nMask R-CNN\nCommon utility functions and classes.\n\nCopyright (c) 2017 Matterport, Inc.\nLicensed under the MIT License (see LICENSE for details)\nWritten by Waleed Abdulla\n\"\"\"\n\nimport sys\nimport os\nimport logging\nimport math\nimport random\nimport numpy as np\nimport tensorflow as tf\nimport scipy\nimport skimage.color\nimport skimage.io\nimport skimage.transform\nimport urllib.request\nimport shutil\nimport warnings\nfrom distutils.version import LooseVersion\n\n# URL from which to download the latest COCO trained weights\nCOCO_MODEL_URL = \"https://github.com/matterport/Mask_RCNN/releases/download/v2.0/mask_rcnn_coco.h5\"\n\n\n############################################################\n#  Bounding Boxes\n############################################################\n\ndef extract_bboxes(mask):\n    \"\"\"Compute bounding boxes from masks.\n    mask: [height, width, num_instances]. Mask pixels are either 1 or 0.\n\n    Returns: bbox array [num_instances, (y1, x1, y2, x2)].\n    \"\"\"\n    boxes = np.zeros([mask.shape[-1], 4], dtype=np.int32)\n    for i in range(mask.shape[-1]):\n        m = mask[:, :, i]\n        # Bounding box.\n        horizontal_indicies = np.where(np.any(m, axis=0))[0]\n        vertical_indicies = np.where(np.any(m, axis=1))[0]\n        if horizontal_indicies.shape[0]:\n            x1, x2 = horizontal_indicies[[0, -1]]\n            y1, y2 = vertical_indicies[[0, -1]]\n            # x2 and y2 should not be part of the box. Increment by 1.\n            x2 += 1\n            y2 += 1\n        else:\n            # No mask for this instance. Might happen due to\n            # resizing or cropping. Set bbox to zeros\n            x1, x2, y1, y2 = 0, 0, 0, 0\n        boxes[i] = np.array([y1, x1, y2, x2])\n    return boxes.astype(np.int32)\n\n\ndef compute_iou(box, boxes, box_area, boxes_area):\n    \"\"\"Calculates IoU of the given box with the array of the given boxes.\n    box: 1D vector [y1, x1, y2, x2]\n    boxes: [boxes_count, (y1, x1, y2, x2)]\n    box_area: float. the area of 'box'\n    boxes_area: array of length boxes_count.\n\n    Note: the areas are passed in rather than calculated here for\n    efficiency. Calculate once in the caller to avoid duplicate work.\n    \"\"\"\n    # Calculate intersection areas\n    y1 = np.maximum(box[0], boxes[:, 0])\n    y2 = np.minimum(box[2], boxes[:, 2])\n    x1 = np.maximum(box[1], boxes[:, 1])\n    x2 = np.minimum(box[3], boxes[:, 3])\n    intersection = np.maximum(x2 - x1, 0) * np.maximum(y2 - y1, 0)\n    union = box_area + boxes_area[:] - intersection[:]\n    iou = intersection / union\n    return iou\n\n\ndef compute_overlaps(boxes1, boxes2):\n    \"\"\"Computes IoU overlaps between two sets of boxes.\n    boxes1, boxes2: [N, (y1, x1, y2, x2)].\n\n    For better performance, pass the largest set first and the smaller second.\n    \"\"\"\n    # Areas of anchors and GT boxes\n    area1 = (boxes1[:, 2] - boxes1[:, 0]) * (boxes1[:, 3] - boxes1[:, 1])\n    area2 = (boxes2[:, 2] - boxes2[:, 0]) * (boxes2[:, 3] - boxes2[:, 1])\n\n    # Compute overlaps to generate matrix [boxes1 count, boxes2 count]\n    # Each cell contains the IoU value.\n    overlaps = np.zeros((boxes1.shape[0], boxes2.shape[0]))\n    for i in range(overlaps.shape[1]):\n        box2 = boxes2[i]\n        overlaps[:, i] = compute_iou(box2, boxes1, area2[i], area1)\n    return overlaps\n\n\ndef compute_overlaps_masks(masks1, masks2):\n    \"\"\"Computes IoU overlaps between two sets of masks.\n    masks1, masks2: [Height, Width, instances]\n    \"\"\"\n    \n    # If either set of masks is empty return empty result\n    if masks1.shape[-1] == 0 or masks2.shape[-1] == 0:\n        return np.zeros((masks1.shape[-1], masks2.shape[-1]))\n    # flatten masks and compute their areas\n    masks1 = np.reshape(masks1 > .5, (-1, masks1.shape[-1])).astype(np.float32)\n    masks2 = np.reshape(masks2 > .5, (-1, masks2.shape[-1])).astype(np.float32)\n    area1 = np.sum(masks1, axis=0)\n    area2 = np.sum(masks2, axis=0)\n\n    # intersections and union\n    intersections = np.dot(masks1.T, masks2)\n    union = area1[:, None] + area2[None, :] - intersections\n    overlaps = intersections / union\n\n    return overlaps\n\n\ndef non_max_suppression(boxes, scores, threshold):\n    \"\"\"Performs non-maximum suppression and returns indices of kept boxes.\n    boxes: [N, (y1, x1, y2, x2)]. Notice that (y2, x2) lays outside the box.\n    scores: 1-D array of box scores.\n    threshold: Float. IoU threshold to use for filtering.\n    \"\"\"\n    assert boxes.shape[0] > 0\n    if boxes.dtype.kind != \"f\":\n        boxes = boxes.astype(np.float32)\n\n    # Compute box areas\n    y1 = boxes[:, 0]\n    x1 = boxes[:, 1]\n    y2 = boxes[:, 2]\n    x2 = boxes[:, 3]\n    area = (y2 - y1) * (x2 - x1)\n\n    # Get indicies of boxes sorted by scores (highest first)\n    ixs = scores.argsort()[::-1]\n\n    pick = []\n    while len(ixs) > 0:\n        # Pick top box and add its index to the list\n        i = ixs[0]\n        pick.append(i)\n        # Compute IoU of the picked box with the rest\n        iou = compute_iou(boxes[i], boxes[ixs[1:]], area[i], area[ixs[1:]])\n        # Identify boxes with IoU over the threshold. This\n        # returns indices into ixs[1:], so add 1 to get\n        # indices into ixs.\n        remove_ixs = np.where(iou > threshold)[0] + 1\n        # Remove indices of the picked and overlapped boxes.\n        ixs = np.delete(ixs, remove_ixs)\n        ixs = np.delete(ixs, 0)\n    return np.array(pick, dtype=np.int32)\n\n\ndef apply_box_deltas(boxes, deltas):\n    \"\"\"Applies the given deltas to the given boxes.\n    boxes: [N, (y1, x1, y2, x2)]. Note that (y2, x2) is outside the box.\n    deltas: [N, (dy, dx, log(dh), log(dw))]\n    \"\"\"\n    boxes = boxes.astype(np.float32)\n    # Convert to y, x, h, w\n    height = boxes[:, 2] - boxes[:, 0]\n    width = boxes[:, 3] - boxes[:, 1]\n    center_y = boxes[:, 0] + 0.5 * height\n    center_x = boxes[:, 1] + 0.5 * width\n    # Apply deltas\n    center_y += deltas[:, 0] * height\n    center_x += deltas[:, 1] * width\n    height *= np.exp(deltas[:, 2])\n    width *= np.exp(deltas[:, 3])\n    # Convert back to y1, x1, y2, x2\n    y1 = center_y - 0.5 * height\n    x1 = center_x - 0.5 * width\n    y2 = y1 + height\n    x2 = x1 + width\n    return np.stack([y1, x1, y2, x2], axis=1)\n\n\ndef box_refinement_graph(box, gt_box):\n    \"\"\"Compute refinement needed to transform box to gt_box.\n    box and gt_box are [N, (y1, x1, y2, x2)]\n    \"\"\"\n    box = tf.cast(box, tf.float32)\n    gt_box = tf.cast(gt_box, tf.float32)\n\n    height = box[:, 2] - box[:, 0]\n    width = box[:, 3] - box[:, 1]\n    center_y = box[:, 0] + 0.5 * height\n    center_x = box[:, 1] + 0.5 * width\n\n    gt_height = gt_box[:, 2] - gt_box[:, 0]\n    gt_width = gt_box[:, 3] - gt_box[:, 1]\n    gt_center_y = gt_box[:, 0] + 0.5 * gt_height\n    gt_center_x = gt_box[:, 1] + 0.5 * gt_width\n\n    dy = (gt_center_y - center_y) / height\n    dx = (gt_center_x - center_x) / width\n    dh = tf.log(gt_height / height)\n    dw = tf.log(gt_width / width)\n\n    result = tf.stack([dy, dx, dh, dw], axis=1)\n    return result\n\n\ndef box_refinement(box, gt_box):\n    \"\"\"Compute refinement needed to transform box to gt_box.\n    box and gt_box are [N, (y1, x1, y2, x2)]. (y2, x2) is\n    assumed to be outside the box.\n    \"\"\"\n    box = box.astype(np.float32)\n    gt_box = gt_box.astype(np.float32)\n\n    height = box[:, 2] - box[:, 0]\n    width = box[:, 3] - box[:, 1]\n    center_y = box[:, 0] + 0.5 * height\n    center_x = box[:, 1] + 0.5 * width\n\n    gt_height = gt_box[:, 2] - gt_box[:, 0]\n    gt_width = gt_box[:, 3] - gt_box[:, 1]\n    gt_center_y = gt_box[:, 0] + 0.5 * gt_height\n    gt_center_x = gt_box[:, 1] + 0.5 * gt_width\n\n    dy = (gt_center_y - center_y) / height\n    dx = (gt_center_x - center_x) / width\n    dh = np.log(gt_height / height)\n    dw = np.log(gt_width / width)\n\n    return np.stack([dy, dx, dh, dw], axis=1)\n\n\n############################################################\n#  Dataset\n############################################################\n\nclass Dataset(object):\n    \"\"\"The base class for dataset classes.\n    To use it, create a new class that adds functions specific to the dataset\n    you want to use. For example:\n\n    class CatsAndDogsDataset(Dataset):\n        def load_cats_and_dogs(self):\n            ...\n        def load_mask(self, image_id):\n            ...\n        def image_reference(self, image_id):\n            ...\n\n    See COCODataset and ShapesDataset as examples.\n    \"\"\"\n\n    def __init__(self, class_map=None):\n        self._image_ids = []\n        self.image_info = []\n        # Background is always the first class\n        self.class_info = [{\"source\": \"\", \"id\": 0, \"name\": \"BG\"}]\n        self.source_class_ids = {}\n\n    def add_class(self, source, class_id, class_name):\n        assert \".\" not in source, \"Source name cannot contain a dot\"\n        # Does the class exist already?\n        for info in self.class_info:\n            if info['source'] == source and info[\"id\"] == class_id:\n                # source.class_id combination already available, skip\n                return\n        # Add the class\n        self.class_info.append({\n            \"source\": source,\n            \"id\": class_id,\n            \"name\": class_name,\n        })\n\n    def add_image(self, source, image_id, path, **kwargs):\n        image_info = {\n            \"id\": image_id,\n            \"source\": source,\n            \"path\": path,\n        }\n        image_info.update(kwargs)\n        self.image_info.append(image_info)\n\n    def image_reference(self, image_id):\n        \"\"\"Return a link to the image in its source Website or details about\n        the image that help looking it up or debugging it.\n\n        Override for your dataset, but pass to this function\n        if you encounter images not in your dataset.\n        \"\"\"\n        return \"\"\n\n    def prepare(self, class_map=None):\n        \"\"\"Prepares the Dataset class for use.\n\n        TODO: class map is not supported yet. When done, it should handle mapping\n              classes from different datasets to the same class ID.\n        \"\"\"\n\n        def clean_name(name):\n            \"\"\"Returns a shorter version of object names for cleaner display.\"\"\"\n            return \",\".join(name.split(\",\")[:1])\n\n        # Build (or rebuild) everything else from the info dicts.\n        self.num_classes = len(self.class_info)\n        self.class_ids = np.arange(self.num_classes)\n        self.class_names = [clean_name(c[\"name\"]) for c in self.class_info]\n        self.num_images = len(self.image_info)\n        self._image_ids = np.arange(self.num_images)\n\n        # Mapping from source class and image IDs to internal IDs\n        self.class_from_source_map = {\"{}.{}\".format(info['source'], info['id']): id\n                                      for info, id in zip(self.class_info, self.class_ids)}\n        self.image_from_source_map = {\"{}.{}\".format(info['source'], info['id']): id\n                                      for info, id in zip(self.image_info, self.image_ids)}\n\n        # Map sources to class_ids they support\n        self.sources = list(set([i['source'] for i in self.class_info]))\n        self.source_class_ids = {}\n        # Loop over datasets\n        for source in self.sources:\n            self.source_class_ids[source] = []\n            # Find classes that belong to this dataset\n            for i, info in enumerate(self.class_info):\n                # Include BG class in all datasets\n                if i == 0 or source == info['source']:\n                    self.source_class_ids[source].append(i)\n\n    def map_source_class_id(self, source_class_id):\n        \"\"\"Takes a source class ID and returns the int class ID assigned to it.\n\n        For example:\n        dataset.map_source_class_id(\"coco.12\") -> 23\n        \"\"\"\n        return self.class_from_source_map[source_class_id]\n\n    def get_source_class_id(self, class_id, source):\n        \"\"\"Map an internal class ID to the corresponding class ID in the source dataset.\"\"\"\n        info = self.class_info[class_id]\n        assert info['source'] == source\n        return info['id']\n\n    @property\n    def image_ids(self):\n        return self._image_ids\n\n    def source_image_link(self, image_id):\n        \"\"\"Returns the path or URL to the image.\n        Override this to return a URL to the image if it's available online for easy\n        debugging.\n        \"\"\"\n        return self.image_info[image_id][\"path\"]\n\n    def load_image(self, image_id):\n        \"\"\"Load the specified image and return a [H,W,3] Numpy array.\n        \"\"\"\n        # Load image\n        image = skimage.io.imread(self.image_info[image_id]['path'])\n        # If grayscale. Convert to RGB for consistency.\n        if image.ndim != 3:\n            image = skimage.color.gray2rgb(image)\n        # If has an alpha channel, remove it for consistency\n        if image.shape[-1] == 4:\n            image = image[..., :3]\n        return image\n\n    def load_mask(self, image_id):\n        \"\"\"Load instance masks for the given image.\n\n        Different datasets use different ways to store masks. Override this\n        method to load instance masks and return them in the form of am\n        array of binary masks of shape [height, width, instances].\n\n        Returns:\n            masks: A bool array of shape [height, width, instance count] with\n                a binary mask per instance.\n            class_ids: a 1D array of class IDs of the instance masks.\n        \"\"\"\n        # Override this function to load a mask from your dataset.\n        # Otherwise, it returns an empty mask.\n        logging.warning(\"You are using the default load_mask(), maybe you need to define your own one.\")\n        mask = np.empty([0, 0, 0])\n        class_ids = np.empty([0], np.int32)\n        return mask, class_ids\n\n\ndef resize_image(image, min_dim=None, max_dim=None, min_scale=None, mode=\"square\"):\n    \"\"\"Resizes an image keeping the aspect ratio unchanged.\n\n    min_dim: if provided, resizes the image such that it's smaller\n        dimension == min_dim\n    max_dim: if provided, ensures that the image longest side doesn't\n        exceed this value.\n    min_scale: if provided, ensure that the image is scaled up by at least\n        this percent even if min_dim doesn't require it.\n    mode: Resizing mode.\n        none: No resizing. Return the image unchanged.\n        square: Resize and pad with zeros to get a square image\n            of size [max_dim, max_dim].\n        pad64: Pads width and height with zeros to make them multiples of 64.\n               If min_dim or min_scale are provided, it scales the image up\n               before padding. max_dim is ignored in this mode.\n               The multiple of 64 is needed to ensure smooth scaling of feature\n               maps up and down the 6 levels of the FPN pyramid (2**6=64).\n        crop: Picks random crops from the image. First, scales the image based\n              on min_dim and min_scale, then picks a random crop of\n              size min_dim x min_dim. Can be used in training only.\n              max_dim is not used in this mode.\n\n    Returns:\n    image: the resized image\n    window: (y1, x1, y2, x2). If max_dim is provided, padding might\n        be inserted in the returned image. If so, this window is the\n        coordinates of the image part of the full image (excluding\n        the padding). The x2, y2 pixels are not included.\n    scale: The scale factor used to resize the image\n    padding: Padding added to the image [(top, bottom), (left, right), (0, 0)]\n    \"\"\"\n    # Keep track of image dtype and return results in the same dtype\n    image_dtype = image.dtype\n    # Default window (y1, x1, y2, x2) and default scale == 1.\n    h, w = image.shape[:2]\n    window = (0, 0, h, w)\n    scale = 1\n    padding = [(0, 0), (0, 0), (0, 0)]\n    crop = None\n\n    if mode == \"none\":\n        return image, window, scale, padding, crop\n\n    # Scale?\n    if min_dim:\n        # Scale up but not down\n        scale = max(1, min_dim / min(h, w))\n    if min_scale and scale < min_scale:\n        scale = min_scale\n\n    # Does it exceed max dim?\n    if max_dim and mode == \"square\":\n        image_max = max(h, w)\n        if round(image_max * scale) > max_dim:\n            scale = max_dim / image_max\n\n    # Resize image using bilinear interpolation\n    if scale != 1:\n        image = resize(image, (round(h * scale), round(w * scale)),\n                       preserve_range=True)\n\n    # Need padding or cropping?\n    if mode == \"square\":\n        # Get new height and width\n        h, w = image.shape[:2]\n        top_pad = (max_dim - h) // 2\n        bottom_pad = max_dim - h - top_pad\n        left_pad = (max_dim - w) // 2\n        right_pad = max_dim - w - left_pad\n        padding = [(top_pad, bottom_pad), (left_pad, right_pad), (0, 0)]\n        image = np.pad(image, padding, mode='constant', constant_values=0)\n        window = (top_pad, left_pad, h + top_pad, w + left_pad)\n    elif mode == \"pad64\":\n        h, w = image.shape[:2]\n        # Both sides must be divisible by 64\n        assert min_dim % 64 == 0, \"Minimum dimension must be a multiple of 64\"\n        # Height\n        if h % 64 > 0:\n            max_h = h - (h % 64) + 64\n            top_pad = (max_h - h) // 2\n            bottom_pad = max_h - h - top_pad\n        else:\n            top_pad = bottom_pad = 0\n        # Width\n        if w % 64 > 0:\n            max_w = w - (w % 64) + 64\n            left_pad = (max_w - w) // 2\n            right_pad = max_w - w - left_pad\n        else:\n            left_pad = right_pad = 0\n        padding = [(top_pad, bottom_pad), (left_pad, right_pad), (0, 0)]\n        image = np.pad(image, padding, mode='constant', constant_values=0)\n        window = (top_pad, left_pad, h + top_pad, w + left_pad)\n    elif mode == \"crop\":\n        # Pick a random crop\n        h, w = image.shape[:2]\n        y = random.randint(0, (h - min_dim))\n        x = random.randint(0, (w - min_dim))\n        crop = (y, x, min_dim, min_dim)\n        image = image[y:y + min_dim, x:x + min_dim]\n        window = (0, 0, min_dim, min_dim)\n    else:\n        raise Exception(\"Mode {} not supported\".format(mode))\n    return image.astype(image_dtype), window, scale, padding, crop\n\n\ndef resize_mask(mask, scale, padding, crop=None):\n    \"\"\"Resizes a mask using the given scale and padding.\n    Typically, you get the scale and padding from resize_image() to\n    ensure both, the image and the mask, are resized consistently.\n\n    scale: mask scaling factor\n    padding: Padding to add to the mask in the form\n            [(top, bottom), (left, right), (0, 0)]\n    \"\"\"\n    # Suppress warning from scipy 0.13.0, the output shape of zoom() is\n    # calculated with round() instead of int()\n    with warnings.catch_warnings():\n        warnings.simplefilter(\"ignore\")\n        mask = scipy.ndimage.zoom(mask, zoom=[scale, scale, 1], order=0)\n    if crop is not None:\n        y, x, h, w = crop\n        mask = mask[y:y + h, x:x + w]\n    else:\n        mask = np.pad(mask, padding, mode='constant', constant_values=0)\n    return mask\n\n\ndef minimize_mask(bbox, mask, mini_shape):\n    \"\"\"Resize masks to a smaller version to reduce memory load.\n    Mini-masks can be resized back to image scale using expand_masks()\n\n    See inspect_data.ipynb notebook for more details.\n    \"\"\"\n    mini_mask = np.zeros(mini_shape + (mask.shape[-1],), dtype=bool)\n    for i in range(mask.shape[-1]):\n        # Pick slice and cast to bool in case load_mask() returned wrong dtype\n        m = mask[:, :, i].astype(bool)\n        y1, x1, y2, x2 = bbox[i][:4]\n        m = m[y1:y2, x1:x2]\n        if m.size == 0:\n            raise Exception(\"Invalid bounding box with area of zero\")\n        # Resize with bilinear interpolation\n        m = resize(m, mini_shape)\n        mini_mask[:, :, i] = np.around(m).astype(np.bool)\n    return mini_mask\n\n\ndef expand_mask(bbox, mini_mask, image_shape):\n    \"\"\"Resizes mini masks back to image size. Reverses the change\n    of minimize_mask().\n\n    See inspect_data.ipynb notebook for more details.\n    \"\"\"\n    mask = np.zeros(image_shape[:2] + (mini_mask.shape[-1],), dtype=bool)\n    for i in range(mask.shape[-1]):\n        m = mini_mask[:, :, i]\n        y1, x1, y2, x2 = bbox[i][:4]\n        h = y2 - y1\n        w = x2 - x1\n        # Resize with bilinear interpolation\n        m = resize(m, (h, w))\n        mask[y1:y2, x1:x2, i] = np.around(m).astype(np.bool)\n    return mask\n\n\n# TODO: Build and use this function to reduce code duplication\ndef mold_mask(mask, config):\n    pass\n\n\ndef unmold_mask(mask, bbox, image_shape):\n    \"\"\"Converts a mask generated by the neural network to a format similar\n    to its original shape.\n    mask: [height, width] of type float. A small, typically 28x28 mask.\n    bbox: [y1, x1, y2, x2]. The box to fit the mask in.\n\n    Returns a binary mask with the same size as the original image.\n    \"\"\"\n    threshold = 0.5\n    y1, x1, y2, x2 = bbox\n    mask = resize(mask, (y2 - y1, x2 - x1))\n    mask = np.where(mask >= threshold, 1, 0).astype(np.bool)\n\n    # Put the mask in the right location.\n    full_mask = np.zeros(image_shape[:2], dtype=np.bool)\n    full_mask[y1:y2, x1:x2] = mask\n    return full_mask\n\n\n############################################################\n#  Anchors\n############################################################\n\ndef generate_anchors(scales, ratios, shape, feature_stride, anchor_stride):\n    \"\"\"\n    scales: 1D array of anchor sizes in pixels. Example: [32, 64, 128]\n    ratios: 1D array of anchor ratios of width/height. Example: [0.5, 1, 2]\n    shape: [height, width] spatial shape of the feature map over which\n            to generate anchors.\n    feature_stride: Stride of the feature map relative to the image in pixels.\n    anchor_stride: Stride of anchors on the feature map. For example, if the\n        value is 2 then generate anchors for every other feature map pixel.\n    \"\"\"\n    # Get all combinations of scales and ratios\n    scales, ratios = np.meshgrid(np.array(scales), np.array(ratios))\n    scales = scales.flatten()\n    ratios = ratios.flatten()\n\n    # Enumerate heights and widths from scales and ratios\n    heights = scales / np.sqrt(ratios)\n    widths = scales * np.sqrt(ratios)\n\n    # Enumerate shifts in feature space\n    shifts_y = np.arange(0, shape[0], anchor_stride) * feature_stride\n    shifts_x = np.arange(0, shape[1], anchor_stride) * feature_stride\n    shifts_x, shifts_y = np.meshgrid(shifts_x, shifts_y)\n\n    # Enumerate combinations of shifts, widths, and heights\n    box_widths, box_centers_x = np.meshgrid(widths, shifts_x)\n    box_heights, box_centers_y = np.meshgrid(heights, shifts_y)\n\n    # Reshape to get a list of (y, x) and a list of (h, w)\n    box_centers = np.stack(\n        [box_centers_y, box_centers_x], axis=2).reshape([-1, 2])\n    box_sizes = np.stack([box_heights, box_widths], axis=2).reshape([-1, 2])\n\n    # Convert to corner coordinates (y1, x1, y2, x2)\n    boxes = np.concatenate([box_centers - 0.5 * box_sizes,\n                            box_centers + 0.5 * box_sizes], axis=1)\n    return boxes\n\n\ndef generate_pyramid_anchors(scales, ratios, feature_shapes, feature_strides,\n                             anchor_stride):\n    \"\"\"Generate anchors at different levels of a feature pyramid. Each scale\n    is associated with a level of the pyramid, but each ratio is used in\n    all levels of the pyramid.\n\n    Returns:\n    anchors: [N, (y1, x1, y2, x2)]. All generated anchors in one array. Sorted\n        with the same order of the given scales. So, anchors of scale[0] come\n        first, then anchors of scale[1], and so on.\n    \"\"\"\n    # Anchors\n    # [anchor_count, (y1, x1, y2, x2)]\n    anchors = []\n    for i in range(len(scales)):\n        anchors.append(generate_anchors(scales[i], ratios, feature_shapes[i],\n                                        feature_strides[i], anchor_stride))\n    return np.concatenate(anchors, axis=0)\n\n\n############################################################\n#  Miscellaneous\n############################################################\n\ndef trim_zeros(x):\n    \"\"\"It's common to have tensors larger than the available data and\n    pad with zeros. This function removes rows that are all zeros.\n\n    x: [rows, columns].\n    \"\"\"\n    assert len(x.shape) == 2\n    return x[~np.all(x == 0, axis=1)]\n\n\ndef compute_matches(gt_boxes, gt_class_ids, gt_masks,\n                    pred_boxes, pred_class_ids, pred_scores, pred_masks,\n                    iou_threshold=0.5, score_threshold=0.0):\n    \"\"\"Finds matches between prediction and ground truth instances.\n\n    Returns:\n        gt_match: 1-D array. For each GT box it has the index of the matched\n                  predicted box.\n        pred_match: 1-D array. For each predicted box, it has the index of\n                    the matched ground truth box.\n        overlaps: [pred_boxes, gt_boxes] IoU overlaps.\n    \"\"\"\n    # Trim zero padding\n    # TODO: cleaner to do zero unpadding upstream\n    gt_boxes = trim_zeros(gt_boxes)\n    gt_masks = gt_masks[..., :gt_boxes.shape[0]]\n    pred_boxes = trim_zeros(pred_boxes)\n    pred_scores = pred_scores[:pred_boxes.shape[0]]\n    # Sort predictions by score from high to low\n    indices = np.argsort(pred_scores)[::-1]\n    pred_boxes = pred_boxes[indices]\n    pred_class_ids = pred_class_ids[indices]\n    pred_scores = pred_scores[indices]\n    pred_masks = pred_masks[..., indices]\n\n    # Compute IoU overlaps [pred_masks, gt_masks]\n    overlaps = compute_overlaps_masks(pred_masks, gt_masks)\n\n    # Loop through predictions and find matching ground truth boxes\n    match_count = 0\n    pred_match = -1 * np.ones([pred_boxes.shape[0]])\n    gt_match = -1 * np.ones([gt_boxes.shape[0]])\n    for i in range(len(pred_boxes)):\n        # Find best matching ground truth box\n        # 1. Sort matches by score\n        sorted_ixs = np.argsort(overlaps[i])[::-1]\n        # 2. Remove low scores\n        low_score_idx = np.where(overlaps[i, sorted_ixs] < score_threshold)[0]\n        if low_score_idx.size > 0:\n            sorted_ixs = sorted_ixs[:low_score_idx[0]]\n        # 3. Find the match\n        for j in sorted_ixs:\n            # If ground truth box is already matched, go to next one\n            if gt_match[j] > -1:\n                continue\n            # If we reach IoU smaller than the threshold, end the loop\n            iou = overlaps[i, j]\n            if iou < iou_threshold:\n                break\n            # Do we have a match?\n            if pred_class_ids[i] == gt_class_ids[j]:\n                match_count += 1\n                gt_match[j] = i\n                pred_match[i] = j\n                break\n\n    return gt_match, pred_match, overlaps\n\n\ndef compute_ap(gt_boxes, gt_class_ids, gt_masks,\n               pred_boxes, pred_class_ids, pred_scores, pred_masks,\n               iou_threshold=0.5):\n    \"\"\"Compute Average Precision at a set IoU threshold (default 0.5).\n\n    Returns:\n    mAP: Mean Average Precision\n    precisions: List of precisions at different class score thresholds.\n    recalls: List of recall values at different class score thresholds.\n    overlaps: [pred_boxes, gt_boxes] IoU overlaps.\n    \"\"\"\n    # Get matches and overlaps\n    gt_match, pred_match, overlaps = compute_matches(\n        gt_boxes, gt_class_ids, gt_masks,\n        pred_boxes, pred_class_ids, pred_scores, pred_masks,\n        iou_threshold)\n\n    # Compute precision and recall at each prediction box step\n    precisions = np.cumsum(pred_match > -1) / (np.arange(len(pred_match)) + 1)\n    recalls = np.cumsum(pred_match > -1).astype(np.float32) / len(gt_match)\n\n    # Pad with start and end values to simplify the math\n    precisions = np.concatenate([[0], precisions, [0]])\n    recalls = np.concatenate([[0], recalls, [1]])\n\n    # Ensure precision values decrease but don't increase. This way, the\n    # precision value at each recall threshold is the maximum it can be\n    # for all following recall thresholds, as specified by the VOC paper.\n    for i in range(len(precisions) - 2, -1, -1):\n        precisions[i] = np.maximum(precisions[i], precisions[i + 1])\n\n    # Compute mean AP over recall range\n    indices = np.where(recalls[:-1] != recalls[1:])[0] + 1\n    mAP = np.sum((recalls[indices] - recalls[indices - 1]) *\n                 precisions[indices])\n\n    return mAP, precisions, recalls, overlaps\n\n\ndef compute_ap_range(gt_box, gt_class_id, gt_mask,\n                     pred_box, pred_class_id, pred_score, pred_mask,\n                     iou_thresholds=None, verbose=1):\n    \"\"\"Compute AP over a range or IoU thresholds. Default range is 0.5-0.95.\"\"\"\n    # Default is 0.5 to 0.95 with increments of 0.05\n    iou_thresholds = iou_thresholds or np.arange(0.5, 1.0, 0.05)\n    \n    # Compute AP over range of IoU thresholds\n    AP = []\n    for iou_threshold in iou_thresholds:\n        ap, precisions, recalls, overlaps =\\\n            compute_ap(gt_box, gt_class_id, gt_mask,\n                        pred_box, pred_class_id, pred_score, pred_mask,\n                        iou_threshold=iou_threshold)\n        if verbose:\n            print(\"AP @{:.2f}:\\t {:.3f}\".format(iou_threshold, ap))\n        AP.append(ap)\n    AP = np.array(AP).mean()\n    if verbose:\n        print(\"AP @{:.2f}-{:.2f}:\\t {:.3f}\".format(\n            iou_thresholds[0], iou_thresholds[-1], AP))\n    return AP\n\n\ndef compute_recall(pred_boxes, gt_boxes, iou):\n    \"\"\"Compute the recall at the given IoU threshold. It's an indication\n    of how many GT boxes were found by the given prediction boxes.\n\n    pred_boxes: [N, (y1, x1, y2, x2)] in image coordinates\n    gt_boxes: [N, (y1, x1, y2, x2)] in image coordinates\n    \"\"\"\n    # Measure overlaps\n    overlaps = compute_overlaps(pred_boxes, gt_boxes)\n    iou_max = np.max(overlaps, axis=1)\n    iou_argmax = np.argmax(overlaps, axis=1)\n    positive_ids = np.where(iou_max >= iou)[0]\n    matched_gt_boxes = iou_argmax[positive_ids]\n\n    recall = len(set(matched_gt_boxes)) / gt_boxes.shape[0]\n    return recall, positive_ids\n\n\n# ## Batch Slicing\n# Some custom layers support a batch size of 1 only, and require a lot of work\n# to support batches greater than 1. This function slices an input tensor\n# across the batch dimension and feeds batches of size 1. Effectively,\n# an easy way to support batches > 1 quickly with little code modification.\n# In the long run, it's more efficient to modify the code to support large\n# batches and getting rid of this function. Consider this a temporary solution\ndef batch_slice(inputs, graph_fn, batch_size, names=None):\n    \"\"\"Splits inputs into slices and feeds each slice to a copy of the given\n    computation graph and then combines the results. It allows you to run a\n    graph on a batch of inputs even if the graph is written to support one\n    instance only.\n\n    inputs: list of tensors. All must have the same first dimension length\n    graph_fn: A function that returns a TF tensor that's part of a graph.\n    batch_size: number of slices to divide the data into.\n    names: If provided, assigns names to the resulting tensors.\n    \"\"\"\n    if not isinstance(inputs, list):\n        inputs = [inputs]\n\n    outputs = []\n    for i in range(batch_size):\n        inputs_slice = [x[i] for x in inputs]\n        output_slice = graph_fn(*inputs_slice)\n        if not isinstance(output_slice, (tuple, list)):\n            output_slice = [output_slice]\n        outputs.append(output_slice)\n    # Change outputs from a list of slices where each is\n    # a list of outputs to a list of outputs and each has\n    # a list of slices\n    outputs = list(zip(*outputs))\n\n    if names is None:\n        names = [None] * len(outputs)\n\n    result = [tf.stack(o, axis=0, name=n)\n              for o, n in zip(outputs, names)]\n    if len(result) == 1:\n        result = result[0]\n\n    return result\n\n\ndef download_trained_weights(coco_model_path, verbose=1):\n    \"\"\"Download COCO trained weights from Releases.\n\n    coco_model_path: local path of COCO trained weights\n    \"\"\"\n    if verbose > 0:\n        print(\"Downloading pretrained model to \" + coco_model_path + \" ...\")\n    with urllib.request.urlopen(COCO_MODEL_URL) as resp, open(coco_model_path, 'wb') as out:\n        shutil.copyfileobj(resp, out)\n    if verbose > 0:\n        print(\"... done downloading pretrained model!\")\n\n\ndef norm_boxes(boxes, shape):\n    \"\"\"Converts boxes from pixel coordinates to normalized coordinates.\n    boxes: [N, (y1, x1, y2, x2)] in pixel coordinates\n    shape: [..., (height, width)] in pixels\n\n    Note: In pixel coordinates (y2, x2) is outside the box. But in normalized\n    coordinates it's inside the box.\n\n    Returns:\n        [N, (y1, x1, y2, x2)] in normalized coordinates\n    \"\"\"\n    h, w = shape\n    scale = np.array([h - 1, w - 1, h - 1, w - 1])\n    shift = np.array([0, 0, 1, 1])\n    return np.divide((boxes - shift), scale).astype(np.float32)\n\n\ndef denorm_boxes(boxes, shape):\n    \"\"\"Converts boxes from normalized coordinates to pixel coordinates.\n    boxes: [N, (y1, x1, y2, x2)] in normalized coordinates\n    shape: [..., (height, width)] in pixels\n\n    Note: In pixel coordinates (y2, x2) is outside the box. But in normalized\n    coordinates it's inside the box.\n\n    Returns:\n        [N, (y1, x1, y2, x2)] in pixel coordinates\n    \"\"\"\n    h, w = shape\n    scale = np.array([h - 1, w - 1, h - 1, w - 1])\n    shift = np.array([0, 0, 1, 1])\n    return np.around(np.multiply(boxes, scale) + shift).astype(np.int32)\n\n\ndef resize(image, output_shape, order=1, mode='constant', cval=0, clip=True,\n           preserve_range=False, anti_aliasing=False, anti_aliasing_sigma=None):\n    \"\"\"A wrapper for Scikit-Image resize().\n\n    Scikit-Image generates warnings on every call to resize() if it doesn't\n    receive the right parameters. The right parameters depend on the version\n    of skimage. This solves the problem by using different parameters per\n    version. And it provides a central place to control resizing defaults.\n    \"\"\"\n    if LooseVersion(skimage.__version__) >= LooseVersion(\"0.14\"):\n        # New in 0.14: anti_aliasing. Default it to False for backward\n        # compatibility with skimage 0.13.\n        return skimage.transform.resize(\n            image, output_shape,\n            order=order, mode=mode, cval=cval, clip=clip,\n            preserve_range=preserve_range, anti_aliasing=anti_aliasing,\n            anti_aliasing_sigma=anti_aliasing_sigma)\n    else:\n        return skimage.transform.resize(\n            image, output_shape,\n            order=order, mode=mode, cval=cval, clip=clip,\n            preserve_range=preserve_range)\n"
  },
  {
    "path": "Image Processor/mrcnn/visualize.py",
    "content": "\"\"\"\nMask R-CNN\nDisplay and Visualization Functions.\n\nCopyright (c) 2017 Matterport, Inc.\nLicensed under the MIT License (see LICENSE for details)\nWritten by Waleed Abdulla\n\"\"\"\n\nimport os\nimport sys\nimport random\nimport itertools\nimport colorsys\n\nimport numpy as np\nfrom skimage.measure import find_contours\nimport matplotlib.pyplot as plt\nfrom matplotlib import patches,  lines\nfrom matplotlib.patches import Polygon\nimport IPython.display\n\n# Root directory of the project\nROOT_DIR = os.path.abspath(\"../\")\n\n# Import Mask RCNN\nsys.path.append(ROOT_DIR)  # To find local version of the library\nfrom mrcnn import utils\n\n\n############################################################\n#  Visualization\n############################################################\n\ndef display_images(images, titles=None, cols=4, cmap=None, norm=None,\n                   interpolation=None):\n    \"\"\"Display the given set of images, optionally with titles.\n    images: list or array of image tensors in HWC format.\n    titles: optional. A list of titles to display with each image.\n    cols: number of images per row\n    cmap: Optional. Color map to use. For example, \"Blues\".\n    norm: Optional. A Normalize instance to map values to colors.\n    interpolation: Optional. Image interpolation to use for display.\n    \"\"\"\n    titles = titles if titles is not None else [\"\"] * len(images)\n    rows = len(images) // cols + 1\n    plt.figure(figsize=(14, 14 * rows // cols))\n    i = 1\n    for image, title in zip(images, titles):\n        plt.subplot(rows, cols, i)\n        plt.title(title, fontsize=9)\n        plt.axis('off')\n        plt.imshow(image.astype(np.uint8), cmap=cmap,\n                   norm=norm, interpolation=interpolation)\n        i += 1\n    plt.show()\n\n\ndef random_colors(N, bright=True):\n    \"\"\"\n    Generate random colors.\n    To get visually distinct colors, generate them in HSV space then\n    convert to RGB.\n    \"\"\"\n    brightness = 1.0 if bright else 0.7\n    hsv = [(i / N, 1, brightness) for i in range(N)]\n    colors = list(map(lambda c: colorsys.hsv_to_rgb(*c), hsv))\n    random.shuffle(colors)\n    return colors\n\n\ndef apply_mask(image, mask, color, alpha=0.5):\n    \"\"\"Apply the given mask to the image.\n    \"\"\"\n    for c in range(3):\n        image[:, :, c] = np.where(mask == 1,\n                                  image[:, :, c] *\n                                  (1 - alpha) + alpha * color[c] * 255,\n                                  image[:, :, c])\n    return image\n\n\ndef display_instances(image, boxes, masks, class_ids, class_names,\n                      scores=None, title=\"\",\n                      figsize=(16, 16), ax=None,\n                      show_mask=True, show_bbox=True,\n                      colors=None, captions=None):\n    \"\"\"\n    boxes: [num_instance, (y1, x1, y2, x2, class_id)] in image coordinates.\n    masks: [height, width, num_instances]\n    class_ids: [num_instances]\n    class_names: list of class names of the dataset\n    scores: (optional) confidence scores for each box\n    title: (optional) Figure title\n    show_mask, show_bbox: To show masks and bounding boxes or not\n    figsize: (optional) the size of the image\n    colors: (optional) An array or colors to use with each object\n    captions: (optional) A list of strings to use as captions for each object\n    \"\"\"\n    # Number of instances\n    N = boxes.shape[0]\n    if not N:\n        print(\"\\n*** No instances to display *** \\n\")\n    else:\n        assert boxes.shape[0] == masks.shape[-1] == class_ids.shape[0]\n\n    # If no axis is passed, create one and automatically call show()\n    auto_show = False\n    if not ax:\n        _, ax = plt.subplots(1, figsize=figsize)\n        auto_show = True\n\n    # Generate random colors\n    colors = colors or random_colors(N)\n\n    # Show area outside image boundaries.\n    height, width = image.shape[:2]\n    ax.set_ylim(height + 10, -10)\n    ax.set_xlim(-10, width + 10)\n    ax.axis('off')\n    ax.set_title(title)\n\n    masked_image = image.astype(np.uint32).copy()\n    for i in range(N):\n        color = colors[i]\n\n        # Bounding box\n        if not np.any(boxes[i]):\n            # Skip this instance. Has no bbox. Likely lost in image cropping.\n            continue\n        y1, x1, y2, x2 = boxes[i]\n        if show_bbox:\n            p = patches.Rectangle((x1, y1), x2 - x1, y2 - y1, linewidth=2,\n                                alpha=0.7, linestyle=\"dashed\",\n                                edgecolor=color, facecolor='none')\n            ax.add_patch(p)\n\n        # Label\n        if not captions:\n            class_id = class_ids[i]\n            score = scores[i] if scores is not None else None\n            label = class_names[class_id]\n            caption = \"{} {:.3f}\".format(label, score) if score else label\n        else:\n            caption = captions[i]\n        ax.text(x1, y1 + 8, caption,\n                color='w', size=11, backgroundcolor=\"none\")\n\n        # Mask\n        mask = masks[:, :, i]\n        if show_mask:\n            masked_image = apply_mask(masked_image, mask, color)\n\n        # Mask Polygon\n        # Pad to ensure proper polygons for masks that touch image edges.\n        padded_mask = np.zeros(\n            (mask.shape[0] + 2, mask.shape[1] + 2), dtype=np.uint8)\n        padded_mask[1:-1, 1:-1] = mask\n        contours = find_contours(padded_mask, 0.5)\n        for verts in contours:\n            # Subtract the padding and flip (y, x) to (x, y)\n            verts = np.fliplr(verts) - 1\n            p = Polygon(verts, facecolor=\"none\", edgecolor=color)\n            ax.add_patch(p)\n    ax.imshow(masked_image.astype(np.uint8))\n    if auto_show:\n        plt.show()\n\n\ndef display_differences(image,\n                        gt_box, gt_class_id, gt_mask,\n                        pred_box, pred_class_id, pred_score, pred_mask,\n                        class_names, title=\"\", ax=None,\n                        show_mask=True, show_box=True,\n                        iou_threshold=0.5, score_threshold=0.5):\n    \"\"\"Display ground truth and prediction instances on the same image.\"\"\"\n    # Match predictions to ground truth\n    gt_match, pred_match, overlaps = utils.compute_matches(\n        gt_box, gt_class_id, gt_mask,\n        pred_box, pred_class_id, pred_score, pred_mask,\n        iou_threshold=iou_threshold, score_threshold=score_threshold)\n    # Ground truth = green. Predictions = red\n    colors = [(0, 1, 0, .8)] * len(gt_match)\\\n           + [(1, 0, 0, 1)] * len(pred_match)\n    # Concatenate GT and predictions\n    class_ids = np.concatenate([gt_class_id, pred_class_id])\n    scores = np.concatenate([np.zeros([len(gt_match)]), pred_score])\n    boxes = np.concatenate([gt_box, pred_box])\n    masks = np.concatenate([gt_mask, pred_mask], axis=-1)\n    # Captions per instance show score/IoU\n    captions = [\"\" for m in gt_match] + [\"{:.2f} / {:.2f}\".format(\n        pred_score[i],\n        (overlaps[i, int(pred_match[i])]\n            if pred_match[i] > -1 else overlaps[i].max()))\n            for i in range(len(pred_match))]\n    # Set title if not provided\n    title = title or \"Ground Truth and Detections\\n GT=green, pred=red, captions: score/IoU\"\n    # Display\n    display_instances(\n        image,\n        boxes, masks, class_ids,\n        class_names, scores, ax=ax,\n        show_bbox=show_box, show_mask=show_mask,\n        colors=colors, captions=captions,\n        title=title)\n\n\ndef draw_rois(image, rois, refined_rois, mask, class_ids, class_names, limit=10):\n    \"\"\"\n    anchors: [n, (y1, x1, y2, x2)] list of anchors in image coordinates.\n    proposals: [n, 4] the same anchors but refined to fit objects better.\n    \"\"\"\n    masked_image = image.copy()\n\n    # Pick random anchors in case there are too many.\n    ids = np.arange(rois.shape[0], dtype=np.int32)\n    ids = np.random.choice(\n        ids, limit, replace=False) if ids.shape[0] > limit else ids\n\n    fig, ax = plt.subplots(1, figsize=(12, 12))\n    if rois.shape[0] > limit:\n        plt.title(\"Showing {} random ROIs out of {}\".format(\n            len(ids), rois.shape[0]))\n    else:\n        plt.title(\"{} ROIs\".format(len(ids)))\n\n    # Show area outside image boundaries.\n    ax.set_ylim(image.shape[0] + 20, -20)\n    ax.set_xlim(-50, image.shape[1] + 20)\n    ax.axis('off')\n\n    for i, id in enumerate(ids):\n        color = np.random.rand(3)\n        class_id = class_ids[id]\n        # ROI\n        y1, x1, y2, x2 = rois[id]\n        p = patches.Rectangle((x1, y1), x2 - x1, y2 - y1, linewidth=2,\n                              edgecolor=color if class_id else \"gray\",\n                              facecolor='none', linestyle=\"dashed\")\n        ax.add_patch(p)\n        # Refined ROI\n        if class_id:\n            ry1, rx1, ry2, rx2 = refined_rois[id]\n            p = patches.Rectangle((rx1, ry1), rx2 - rx1, ry2 - ry1, linewidth=2,\n                                  edgecolor=color, facecolor='none')\n            ax.add_patch(p)\n            # Connect the top-left corners of the anchor and proposal for easy visualization\n            ax.add_line(lines.Line2D([x1, rx1], [y1, ry1], color=color))\n\n            # Label\n            label = class_names[class_id]\n            ax.text(rx1, ry1 + 8, \"{}\".format(label),\n                    color='w', size=11, backgroundcolor=\"none\")\n\n            # Mask\n            m = utils.unmold_mask(mask[id], rois[id]\n                                  [:4].astype(np.int32), image.shape)\n            masked_image = apply_mask(masked_image, m, color)\n\n    ax.imshow(masked_image)\n\n    # Print stats\n    print(\"Positive ROIs: \", class_ids[class_ids > 0].shape[0])\n    print(\"Negative ROIs: \", class_ids[class_ids == 0].shape[0])\n    print(\"Positive Ratio: {:.2f}\".format(\n        class_ids[class_ids > 0].shape[0] / class_ids.shape[0]))\n\n\n# TODO: Replace with matplotlib equivalent?\ndef draw_box(image, box, color):\n    \"\"\"Draw 3-pixel width bounding boxes on the given image array.\n    color: list of 3 int values for RGB.\n    \"\"\"\n    y1, x1, y2, x2 = box\n    image[y1:y1 + 2, x1:x2] = color\n    image[y2:y2 + 2, x1:x2] = color\n    image[y1:y2, x1:x1 + 2] = color\n    image[y1:y2, x2:x2 + 2] = color\n    return image\n\n\ndef display_top_masks(image, mask, class_ids, class_names, limit=4):\n    \"\"\"Display the given image and the top few class masks.\"\"\"\n    to_display = []\n    titles = []\n    to_display.append(image)\n    titles.append(\"H x W={}x{}\".format(image.shape[0], image.shape[1]))\n    # Pick top prominent classes in this image\n    unique_class_ids = np.unique(class_ids)\n    mask_area = [np.sum(mask[:, :, np.where(class_ids == i)[0]])\n                 for i in unique_class_ids]\n    top_ids = [v[0] for v in sorted(zip(unique_class_ids, mask_area),\n                                    key=lambda r: r[1], reverse=True) if v[1] > 0]\n    # Generate images and titles\n    for i in range(limit):\n        class_id = top_ids[i] if i < len(top_ids) else -1\n        # Pull masks of instances belonging to the same class.\n        m = mask[:, :, np.where(class_ids == class_id)[0]]\n        m = np.sum(m * np.arange(1, m.shape[-1] + 1), -1)\n        to_display.append(m)\n        titles.append(class_names[class_id] if class_id != -1 else \"-\")\n    display_images(to_display, titles=titles, cols=limit + 1, cmap=\"Blues_r\")\n\n\ndef plot_precision_recall(AP, precisions, recalls):\n    \"\"\"Draw the precision-recall curve.\n\n    AP: Average precision at IoU >= 0.5\n    precisions: list of precision values\n    recalls: list of recall values\n    \"\"\"\n    # Plot the Precision-Recall curve\n    _, ax = plt.subplots(1)\n    ax.set_title(\"Precision-Recall Curve. AP@50 = {:.3f}\".format(AP))\n    ax.set_ylim(0, 1.1)\n    ax.set_xlim(0, 1.1)\n    _ = ax.plot(recalls, precisions)\n\n\ndef plot_overlaps(gt_class_ids, pred_class_ids, pred_scores,\n                  overlaps, class_names, threshold=0.5):\n    \"\"\"Draw a grid showing how ground truth objects are classified.\n    gt_class_ids: [N] int. Ground truth class IDs\n    pred_class_id: [N] int. Predicted class IDs\n    pred_scores: [N] float. The probability scores of predicted classes\n    overlaps: [pred_boxes, gt_boxes] IoU overlaps of predictions and GT boxes.\n    class_names: list of all class names in the dataset\n    threshold: Float. The prediction probability required to predict a class\n    \"\"\"\n    gt_class_ids = gt_class_ids[gt_class_ids != 0]\n    pred_class_ids = pred_class_ids[pred_class_ids != 0]\n\n    plt.figure(figsize=(12, 10))\n    plt.imshow(overlaps, interpolation='nearest', cmap=plt.cm.Blues)\n    plt.yticks(np.arange(len(pred_class_ids)),\n               [\"{} ({:.2f})\".format(class_names[int(id)], pred_scores[i])\n                for i, id in enumerate(pred_class_ids)])\n    plt.xticks(np.arange(len(gt_class_ids)),\n               [class_names[int(id)] for id in gt_class_ids], rotation=90)\n\n    thresh = overlaps.max() / 2.\n    for i, j in itertools.product(range(overlaps.shape[0]),\n                                  range(overlaps.shape[1])):\n        text = \"\"\n        if overlaps[i, j] > threshold:\n            text = \"match\" if gt_class_ids[j] == pred_class_ids[i] else \"wrong\"\n        color = (\"white\" if overlaps[i, j] > thresh\n                 else \"black\" if overlaps[i, j] > 0\n                 else \"grey\")\n        plt.text(j, i, \"{:.3f}\\n{}\".format(overlaps[i, j], text),\n                 horizontalalignment=\"center\", verticalalignment=\"center\",\n                 fontsize=9, color=color)\n\n    plt.tight_layout()\n    plt.xlabel(\"Ground Truth\")\n    plt.ylabel(\"Predictions\")\n\n\ndef draw_boxes(image, boxes=None, refined_boxes=None,\n               masks=None, captions=None, visibilities=None,\n               title=\"\", ax=None):\n    \"\"\"Draw bounding boxes and segmentation masks with different\n    customizations.\n\n    boxes: [N, (y1, x1, y2, x2, class_id)] in image coordinates.\n    refined_boxes: Like boxes, but draw with solid lines to show\n        that they're the result of refining 'boxes'.\n    masks: [N, height, width]\n    captions: List of N titles to display on each box\n    visibilities: (optional) List of values of 0, 1, or 2. Determine how\n        prominent each bounding box should be.\n    title: An optional title to show over the image\n    ax: (optional) Matplotlib axis to draw on.\n    \"\"\"\n    # Number of boxes\n    assert boxes is not None or refined_boxes is not None\n    N = boxes.shape[0] if boxes is not None else refined_boxes.shape[0]\n\n    # Matplotlib Axis\n    if not ax:\n        _, ax = plt.subplots(1, figsize=(12, 12))\n\n    # Generate random colors\n    colors = random_colors(N)\n\n    # Show area outside image boundaries.\n    margin = image.shape[0] // 10\n    ax.set_ylim(image.shape[0] + margin, -margin)\n    ax.set_xlim(-margin, image.shape[1] + margin)\n    ax.axis('off')\n\n    ax.set_title(title)\n\n    masked_image = image.astype(np.uint32).copy()\n    for i in range(N):\n        # Box visibility\n        visibility = visibilities[i] if visibilities is not None else 1\n        if visibility == 0:\n            color = \"gray\"\n            style = \"dotted\"\n            alpha = 0.5\n        elif visibility == 1:\n            color = colors[i]\n            style = \"dotted\"\n            alpha = 1\n        elif visibility == 2:\n            color = colors[i]\n            style = \"solid\"\n            alpha = 1\n\n        # Boxes\n        if boxes is not None:\n            if not np.any(boxes[i]):\n                # Skip this instance. Has no bbox. Likely lost in cropping.\n                continue\n            y1, x1, y2, x2 = boxes[i]\n            p = patches.Rectangle((x1, y1), x2 - x1, y2 - y1, linewidth=2,\n                                  alpha=alpha, linestyle=style,\n                                  edgecolor=color, facecolor='none')\n            ax.add_patch(p)\n\n        # Refined boxes\n        if refined_boxes is not None and visibility > 0:\n            ry1, rx1, ry2, rx2 = refined_boxes[i].astype(np.int32)\n            p = patches.Rectangle((rx1, ry1), rx2 - rx1, ry2 - ry1, linewidth=2,\n                                  edgecolor=color, facecolor='none')\n            ax.add_patch(p)\n            # Connect the top-left corners of the anchor and proposal\n            if boxes is not None:\n                ax.add_line(lines.Line2D([x1, rx1], [y1, ry1], color=color))\n\n        # Captions\n        if captions is not None:\n            caption = captions[i]\n            # If there are refined boxes, display captions on them\n            if refined_boxes is not None:\n                y1, x1, y2, x2 = ry1, rx1, ry2, rx2\n            ax.text(x1, y1, caption, size=11, verticalalignment='top',\n                    color='w', backgroundcolor=\"none\",\n                    bbox={'facecolor': color, 'alpha': 0.5,\n                          'pad': 2, 'edgecolor': 'none'})\n\n        # Masks\n        if masks is not None:\n            mask = masks[:, :, i]\n            masked_image = apply_mask(masked_image, mask, color)\n            # Mask Polygon\n            # Pad to ensure proper polygons for masks that touch image edges.\n            padded_mask = np.zeros(\n                (mask.shape[0] + 2, mask.shape[1] + 2), dtype=np.uint8)\n            padded_mask[1:-1, 1:-1] = mask\n            contours = find_contours(padded_mask, 0.5)\n            for verts in contours:\n                # Subtract the padding and flip (y, x) to (x, y)\n                verts = np.fliplr(verts) - 1\n                p = Polygon(verts, facecolor=\"none\", edgecolor=color)\n                ax.add_patch(p)\n    ax.imshow(masked_image.astype(np.uint8))\n\n\ndef display_table(table):\n    \"\"\"Display values in a table format.\n    table: an iterable of rows, and each row is an iterable of values.\n    \"\"\"\n    html = \"\"\n    for row in table:\n        row_html = \"\"\n        for col in row:\n            row_html += \"<td>{:40}</td>\".format(str(col))\n        html += \"<tr>\" + row_html + \"</tr>\"\n    html = \"<table>\" + html + \"</table>\"\n    IPython.display.display(IPython.display.HTML(html))\n\n\ndef display_weight_stats(model):\n    \"\"\"Scans all the weights in the model and returns a list of tuples\n    that contain stats about each weight.\n    \"\"\"\n    layers = model.get_trainable_layers()\n    table = [[\"WEIGHT NAME\", \"SHAPE\", \"MIN\", \"MAX\", \"STD\"]]\n    for l in layers:\n        weight_values = l.get_weights()  # list of Numpy arrays\n        weight_tensors = l.weights  # list of TF tensors\n        for i, w in enumerate(weight_values):\n            weight_name = weight_tensors[i].name\n            # Detect problematic layers. Exclude biases of conv layers.\n            alert = \"\"\n            if w.min() == w.max() and not (l.__class__.__name__ == \"Conv2D\" and i == 1):\n                alert += \"<span style='color:red'>*** dead?</span>\"\n            if np.abs(w.min()) > 1000 or np.abs(w.max()) > 1000:\n                alert += \"<span style='color:red'>*** Overflow?</span>\"\n            # Add row\n            table.append([\n                weight_name + alert,\n                str(w.shape),\n                \"{:+9.4f}\".format(w.min()),\n                \"{:+10.4f}\".format(w.max()),\n                \"{:+9.4f}\".format(w.std()),\n            ])\n    display_table(table)\n"
  },
  {
    "path": "Image Processor/requirements.txt",
    "content": "numpy\nscipy\nPillow\ncython\nmatplotlib\nscikit-image\ntensorflow>=1.3.0\nkeras>=2.0.8\nopencv-python\nh5py\nimgaug\nIPython[all]"
  },
  {
    "path": "Image Processor/scratch.py",
    "content": "import math\r\nimport pickle\r\nfrom pathlib import Path\r\nfrom random import randint\r\nimport json\r\nfrom multiprocessing import Pool, Queue\r\nimport traceback\r\n\r\nimport cv2\r\nimport numpy as np\r\nfrom keras.preprocessing.image import img_to_array, load_img\r\nfrom tqdm import tqdm\r\n\r\nimport cv_tools\r\nfrom mrcnn import model as modellib\r\nfrom mrcnn import visualize\r\nfrom mrcnn.config import Config\r\n\r\nfrom mrcnn.config import Config\r\nfrom mrcnn import model as modellib\r\nfrom mrcnn import visualize\r\nimport mrcnn\r\nfrom mrcnn import utils\r\nfrom mrcnn.utils import Dataset\r\nfrom mrcnn.model import MaskRCNN\r\n\r\nimport numpy as np\r\nfrom numpy import zeros\r\nfrom numpy import asarray\r\nimport colorsys\r\nimport argparse\r\nimport imutils\r\nimport random\r\nimport cv2\r\nimport os\r\nimport time\r\n\r\nfrom matplotlib import pyplot\r\nfrom matplotlib.patches import Rectangle\r\nfrom keras.models import load_model\r\n\r\nfrom os import listdir\r\nfrom pathlib import Path\r\nimport tarfile\r\nfrom xml.etree import ElementTree\r\n\r\nfrom download_utils import download_file_from_google_drive\r\n\r\nimport os\r\nimport random\r\n\r\nimport cv2\r\nimport numpy as np\r\n\r\nimport math\r\nimport sys\r\nfrom collections import defaultdict\r\nfrom pathlib import Path\r\nfrom typing import List, Tuple\r\n\r\nimport cv2\r\nimport numpy as np"
  },
  {
    "path": "Image Processor/setup.cfg",
    "content": "[metadata]\ndescription-file = README.md\nlicense-file = LICENSE\nrequirements-file = requirements.txt"
  },
  {
    "path": "Image Processor/setup.py",
    "content": "\"\"\"\nThe build/compilations setup\n\n>> pip install -r requirements.txt\n>> python setup.py install\n\"\"\"\nimport pip\nimport logging\nimport pkg_resources\ntry:\n    from setuptools import setup\nexcept ImportError:\n    from distutils.core import setup\n\n\ndef _parse_requirements(file_path):\n    pip_ver = pkg_resources.get_distribution('pip').version\n    pip_version = list(map(int, pip_ver.split('.')[:2]))\n    if pip_version >= [6, 0]:\n        raw = pip.req.parse_requirements(file_path,\n                                         session=pip.download.PipSession())\n    else:\n        raw = pip.req.parse_requirements(file_path)\n    return [str(i.req) for i in raw]\n\n\n# parse_requirements() returns generator of pip.req.InstallRequirement objects\ntry:\n    install_reqs = _parse_requirements(\"requirements.txt\")\nexcept Exception:\n    logging.warning('Fail load requirements file, so using default ones.')\n    install_reqs = []\n\nsetup(\n    name='mask-rcnn',\n    version='2.1',\n    url='https://github.com/matterport/Mask_RCNN',\n    author='Matterport',\n    author_email='waleed.abdulla@gmail.com',\n    license='MIT',\n    description='Mask R-CNN for object detection and instance segmentation',\n    packages=[\"mrcnn\"],\n    install_requires=install_reqs,\n    include_package_data=True,\n    python_requires='>=3.4',\n    long_description=\"\"\"This is an implementation of Mask R-CNN on Python 3, Keras, and TensorFlow. \nThe model generates bounding boxes and segmentation masks for each instance of an object in the image. \nIt's based on Feature Pyramid Network (FPN) and a ResNet101 backbone.\"\"\",\n    classifiers=[\n        \"Development Status :: 5 - Production/Stable\",\n        \"Environment :: Console\",\n        \"Intended Audience :: Developers\",\n        \"Intended Audience :: Information Technology\",\n        \"Intended Audience :: Education\",\n        \"Intended Audience :: Science/Research\",\n        \"License :: OSI Approved :: MIT License\",\n        \"Natural Language :: English\",\n        \"Operating System :: OS Independent\",\n        \"Topic :: Scientific/Engineering :: Artificial Intelligence\",\n        \"Topic :: Scientific/Engineering :: Image Recognition\",\n        \"Topic :: Scientific/Engineering :: Visualization\",\n        \"Topic :: Scientific/Engineering :: Image Segmentation\",\n        'Programming Language :: Python :: 3.4',\n        'Programming Language :: Python :: 3.5',\n        'Programming Language :: Python :: 3.6',\n    ],\n    keywords=\"image instance segmentation object detection mask rcnn r-cnn tensorflow keras\",\n)\n"
  },
  {
    "path": "README.md",
    "content": "# TDPDNE\nA StyleGAN2 model to make AI generated dicks\n\n#### Website\n\n[https://thisdickpicdoesnotexist.com/](https://thisdickpicdoesnotexist.com/)\n\n#### Make your own dicks\n\n[Google Colab](https://colab.research.google.com/drive/1DoCxr2pYlxCRv6RmITtFWahVXsbTexYp?usp=sharing)\n\n#### Inspiration\n\n* [https://thispersondoesnotexist.com/](https://thispersondoesnotexist.com/)\n* Too many women asking for my dick pics, now I can send these instead\n* StyleGAN2 Paper: [https://arxiv.org/pdf/1912.04958.pdf](https://arxiv.org/pdf/1912.04958.pdf)\n* StyleGAN2 Repo: [https://github.com/NVlabs/stylegan2](https://github.com/NVlabs/stylegan2)\n\n## Model Details\n\n42,273 dick pics were scraped from Reddit that were posted on these subreddits\n\n* r/penis\n* r/cock\n* r/dicks\n* r/averagepenis\n* r/MassiveCock\n* r/tinydick\n\nThe scraping procedure was done by first [downloading all submissions](https://files.pushshift.io/reddit/submissions/) from the year 2018. These submissions were then filtered down to image submissions in the above subreddits. Since pushshift only stores the image URLs, these images were then fetched from reddit using the stored URL.\n\nA model was created with these images, but the model suffered from mode collapse. The solution was to train a custom Mask-RCNN model (in `Image Processor/Dick_Pic_Mask-RCNN_Trainer.ipynb`) to segment the penis. With this segmentation, PCA was used to find the tilt, then rotate so the penis was vertical (in `Image Processor/align_images.py`). However this results in some penises being upside down. A possible improvement could be training another Mask R-CNN to detect the head of the penis and make sure that is always at the top half of the image.\n\nThe training was done using a TPU v3-8 trained for ~9 days (25,000 KImg). Gamma was started at 100 and decreased by 25 each 10,000 KImg. The resulting model still suffers from some mode collapse as the generated dicks seen on [https://thisdickpicdoesnotexist.com/](https://thisdickpicdoesnotexist.com/) are lacking of the African American variety. This was found to be surprising as there were many coloured dicks in the dataset.\n\nThe generated dicks on [https://thisdickpicdoesnotexist.com/](https://thisdickpicdoesnotexist.com/) used a truncation_psi of 0.7.\n\n[Email me](mailto:hello@thisdickpicdoesnotexist.com) if you have any questions.\n\n## How to use\n\n### Download the dataset\n\n1. [Here](https://mega.nz/file/f91lBAzA#1wvrbxh89bJ8MAUiGjHwIZnZ97P8vzflQJaBL_ALpeM)\n\n2. Unzip the tarball and place in the root directory of the repo\n\n2. Tell all your friends you have more dick pics on your computer than them\n\n### Run The Image Preprocessor\n\n1. Train the custom Mask R-CNN model using\n\n `Image Processor/Dick_Pic_Mask-RCNN_Trainer.ipynb`\n\n2. Align the dataset and resize using\n\n `Image Processor/align_images.py`\n\n### Get a Google Compute Platform TPU instance\n\n1. Apply for [TFRC](https://www.tensorflow.org/tfrc) if you haven't already\n\n2. Start the instance\n\n3. Install python 3.7\n\n4. Set the right environment variables\n\n        export NOISY=0\n        export DEBUG=0\n        export LABEL_SIZE=0\n        export MODEL_DIR=gs://your-gcp-bucket/model\n        export BATCH_PER=4\n        export BATCH_SIZE=32\n        export RESOLUTION=512\n\n### Train the Dick-GAN\n\n1. Convert the images to TFRecords using\n\n`stylegan2-tpu/dataset_tool.py create_from_images ~/datasets/aligned_images_tfrecords_dir ~/aligned_images`\n\n2. Train the model\n\n`stylegan2-tpu/run_training.py --result-dir=gs://your-gcp-bucket/model --data-dir=dataset --dataset=aligned_images_tfrecords_dir --config=config-f --num-gpus=8 --mirror-augment=true`\n\n### Generate Dicks\n\n1. Run\n\n`stylegan2-tpu/generate_images_tpu.py --model_dir=gs://your-gcp-bucket/model --save_dir=generated_fakes --truncation_psi=0.7 --num_samples=10`"
  },
  {
    "path": "stylegan2-tpu/Dockerfile",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\nFROM tensorflow/tensorflow:1.15.0-gpu-py3\n\nRUN pip install scipy==1.3.3\nRUN pip install requests==2.22.0\nRUN pip install Pillow==6.2.1\n"
  },
  {
    "path": "stylegan2-tpu/LICENSE.txt",
    "content": "Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\r\n\r\n\r\nNvidia Source Code License-NC\r\n\r\n=======================================================================\r\n\r\n1. Definitions\r\n\r\n\"Licensor\" means any person or entity that distributes its Work.\r\n\r\n\"Software\" means the original work of authorship made available under\r\nthis License.\r\n\r\n\"Work\" means the Software and any additions to or derivative works of\r\nthe Software that are made available under this License.\r\n\r\n\"Nvidia Processors\" means any central processing unit (CPU), graphics\r\nprocessing unit (GPU), field-programmable gate array (FPGA),\r\napplication-specific integrated circuit (ASIC) or any combination\r\nthereof designed, made, sold, or provided by Nvidia or its affiliates.\r\n\r\nThe terms \"reproduce,\" \"reproduction,\" \"derivative works,\" and\r\n\"distribution\" have the meaning as provided under U.S. copyright law;\r\nprovided, however, that for the purposes of this License, derivative\r\nworks shall not include works that remain separable from, or merely\r\nlink (or bind by name) to the interfaces of, the Work.\r\n\r\nWorks, including the Software, are \"made available\" under this License\r\nby including in or with the Work either (a) a copyright notice\r\nreferencing the applicability of this License to the Work, or (b) a\r\ncopy of this License.\r\n\r\n2. License Grants\r\n\r\n    2.1 Copyright Grant. Subject to the terms and conditions of this\r\n    License, each Licensor grants to you a perpetual, worldwide,\r\n    non-exclusive, royalty-free, copyright license to reproduce,\r\n    prepare derivative works of, publicly display, publicly perform,\r\n    sublicense and distribute its Work and any resulting derivative\r\n    works in any form.\r\n\r\n3. Limitations\r\n\r\n    3.1 Redistribution. You may reproduce or distribute the Work only\r\n    if (a) you do so under this License, (b) you include a complete\r\n    copy of this License with your distribution, and (c) you retain\r\n    without modification any copyright, patent, trademark, or\r\n    attribution notices that are present in the Work.\r\n\r\n    3.2 Derivative Works. You may specify that additional or different\r\n    terms apply to the use, reproduction, and distribution of your\r\n    derivative works of the Work (\"Your Terms\") only if (a) Your Terms\r\n    provide that the use limitation in Section 3.3 applies to your\r\n    derivative works, and (b) you identify the specific derivative\r\n    works that are subject to Your Terms. Notwithstanding Your Terms,\r\n    this License (including the redistribution requirements in Section\r\n    3.1) will continue to apply to the Work itself.\r\n\r\n    3.3 Use Limitation. The Work and any derivative works thereof only\r\n    may be used or intended for use non-commercially. The Work or\r\n    derivative works thereof may be used or intended for use by Nvidia\r\n    or its affiliates commercially or non-commercially. As used herein,\r\n    \"non-commercially\" means for research or evaluation purposes only.\r\n\r\n    3.4 Patent Claims. If you bring or threaten to bring a patent claim\r\n    against any Licensor (including any claim, cross-claim or\r\n    counterclaim in a lawsuit) to enforce any patents that you allege\r\n    are infringed by any Work, then your rights under this License from\r\n    such Licensor (including the grants in Sections 2.1 and 2.2) will\r\n    terminate immediately.\r\n\r\n    3.5 Trademarks. This License does not grant any rights to use any\r\n    Licensor's or its affiliates' names, logos, or trademarks, except\r\n    as necessary to reproduce the notices described in this License.\r\n\r\n    3.6 Termination. If you violate any term of this License, then your\r\n    rights under this License (including the grants in Sections 2.1 and\r\n    2.2) will terminate immediately.\r\n\r\n4. Disclaimer of Warranty.\r\n\r\nTHE WORK IS PROVIDED \"AS IS\" WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OR CONDITIONS OF\r\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR\r\nNON-INFRINGEMENT. YOU BEAR THE RISK OF UNDERTAKING ANY ACTIVITIES UNDER\r\nTHIS LICENSE. \r\n\r\n5. Limitation of Liability.\r\n\r\nEXCEPT AS PROHIBITED BY APPLICABLE LAW, IN NO EVENT AND UNDER NO LEGAL\r\nTHEORY, WHETHER IN TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE\r\nSHALL ANY LICENSOR BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT,\r\nINDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF\r\nOR RELATED TO THIS LICENSE, THE USE OR INABILITY TO USE THE WORK\r\n(INCLUDING BUT NOT LIMITED TO LOSS OF GOODWILL, BUSINESS INTERRUPTION,\r\nLOST PROFITS OR DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY OTHER\r\nCOMMERCIAL DAMAGES OR LOSSES), EVEN IF THE LICENSOR HAS BEEN ADVISED OF\r\nTHE POSSIBILITY OF SUCH DAMAGES.\r\n\r\n=======================================================================\r\n"
  },
  {
    "path": "stylegan2-tpu/README.md",
    "content": "## StyleGAN2 &mdash; Official TensorFlow Implementation\n\n![Teaser image](./docs/stylegan2-teaser-1024x256.png)\n\n**Analyzing and Improving the Image Quality of StyleGAN**<br>\nTero Karras, Samuli Laine, Miika Aittala, Janne Hellsten, Jaakko Lehtinen, Timo Aila<br>\n\nPaper: http://arxiv.org/abs/1912.04958<br>\nVideo: https://youtu.be/c-NJtV9Jvp0<br>\n\nAbstract: *The style-based GAN architecture (StyleGAN) yields state-of-the-art results in data-driven unconditional generative image modeling. We expose and analyze several of its characteristic artifacts, and propose changes in both model architecture and training methods to address them. In particular, we redesign generator normalization, revisit progressive growing, and regularize the generator to encourage good conditioning in the mapping from latent vectors to images. In addition to improving image quality, this path length regularizer yields the additional benefit that the generator becomes significantly easier to invert. This makes it possible to reliably detect if an image is generated by a particular network. We furthermore visualize how well the generator utilizes its output resolution, and identify a capacity problem, motivating us to train larger models for additional quality improvements. Overall, our improved model redefines the state of the art in unconditional image modeling, both in terms of existing distribution quality metrics as well as perceived image quality.*\n\nFor business inquiries, please contact [researchinquiries@nvidia.com](mailto:researchinquiries@nvidia.com)<br>\nFor press and other inquiries, please contact Hector Marinez at [hmarinez@nvidia.com](mailto:hmarinez@nvidia.com)<br>\n\n| Additional material | &nbsp;\n| :--- | :----------\n| [StyleGAN2](https://drive.google.com/open?id=1QHc-yF5C3DChRwSdZKcx1w6K8JvSxQi7) | Main Google Drive folder\n| &boxvr;&nbsp; [stylegan2-paper.pdf](https://drive.google.com/open?id=1fnF-QsiQeKaxF-HbvFiGtzHF_Bf3CzJu) | High-quality version of the paper\n| &boxvr;&nbsp; [stylegan2-video.mp4](https://drive.google.com/open?id=1f_gbKW6FUUHKkUxciJ_lQx29mCq_fSBy) | High-quality version of the video\n| &boxvr;&nbsp; [images](https://drive.google.com/open?id=1Sak157_DLX84ytqHHqZaH_59HoEWzfB7) | Example images produced using our method\n| &boxv;&nbsp; &boxvr;&nbsp;  [curated-images](https://drive.google.com/open?id=1ydWb8xCHzDKMTW9kQ7sL-B1R0zATHVHp) | Hand-picked images showcasing our results\n| &boxv;&nbsp; &boxur;&nbsp;  [100k-generated-images](https://drive.google.com/open?id=1BA2OZ1GshdfFZGYZPob5QWOGBuJCdu5q) | Random images with and without truncation\n| &boxvr;&nbsp; [videos](https://drive.google.com/open?id=1yXDV96SFXoUiZKU7AyE6DyKgDpIk4wUZ) | Individual clips of the video as high-quality MP4\n| &boxur;&nbsp; [networks](https://drive.google.com/open?id=1yanUI9m4b4PWzR0eurKNq6JR1Bbfbh6L) | Pre-trained networks\n| &ensp;&ensp; &boxvr;&nbsp;  [stylegan2-ffhq-config-f.pkl](https://drive.google.com/open?id=1Mgh-jglZjgksupF0XLl0KzuOqd1LXcoE) | StyleGAN2 for <span style=\"font-variant:small-caps\">FFHQ</span> dataset at 1024&times;1024\n| &ensp;&ensp; &boxvr;&nbsp;  [stylegan2-car-config-f.pkl](https://drive.google.com/open?id=1MutzVf8XjNo6TUg03a6CUU_2Vlc0ltbV) | StyleGAN2 for <span style=\"font-variant:small-caps\">LSUN Car</span> dataset at 512&times;384\n| &ensp;&ensp; &boxvr;&nbsp;  [stylegan2-cat-config-f.pkl](https://drive.google.com/open?id=1MyowTZGvMDJCWuT7Yg2e_GnTLIzcSPCy) | StyleGAN2 for <span style=\"font-variant:small-caps\">LSUN Cat</span> dataset at 256&times;256\n| &ensp;&ensp; &boxvr;&nbsp;  [stylegan2-church-config-f.pkl](https://drive.google.com/open?id=1N3iaujGpwa6vmKCqRSHcD6GZ2HVV8h1f) | StyleGAN2 for <span style=\"font-variant:small-caps\">LSUN Church</span> dataset at 256&times;256\n| &ensp;&ensp; &boxvr;&nbsp;  [stylegan2-horse-config-f.pkl](https://drive.google.com/open?id=1N55ZtBhEyEbDn6uKBjCNAew1phD5ZAh-) | StyleGAN2 for <span style=\"font-variant:small-caps\">LSUN Horse</span> dataset at 256&times;256\n| &ensp;&ensp; &boxur;&nbsp;&#x22ef;  | Other training configurations used in the paper\n\n## Requirements\n\n* Both Linux and Windows are supported. Linux is recommended for performance and compatibility reasons.\n* 64-bit Python 3.6 installation. We recommend Anaconda3 with numpy 1.14.3 or newer.\n* TensorFlow 1.14 or 1.15 with GPU support. The code does not support TensorFlow 2.0.\n* On Windows, you need to use TensorFlow 1.14 &mdash; TensorFlow 1.15 will not work.\n* One or more high-end NVIDIA GPUs, NVIDIA drivers, CUDA 10.0 toolkit and cuDNN 7.5. To reproduce the results reported in the paper, you need an NVIDIA GPU with at least 16 GB of DRAM.\n* Docker users: use the [provided Dockerfile](./Dockerfile) to build an image with the required library dependencies.\n\nStyleGAN2 relies on custom TensorFlow ops that are compiled on the fly using [NVCC](https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html). To test that your NVCC installation is working correctly, run:\n\n```.bash\nnvcc test_nvcc.cu -o test_nvcc -run\n| CPU says hello.\n| GPU says hello.\n```\n\nOn Windows, the compilation requires Microsoft Visual Studio to be in `PATH`. We recommend installing [Visual Studio Community Edition](https://visualstudio.microsoft.com/vs/) and adding into `PATH` using `\"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat\"`.\n\n## Preparing datasets\n\nDatasets are stored as multi-resolution TFRecords, similar to the [original StyleGAN](https://github.com/NVlabs/stylegan). Each dataset consists of multiple `*.tfrecords` files stored under a common directory, e.g., `~/datasets/ffhq/ffhq-r*.tfrecords`. In the following sections, the datasets are referenced using a combination of `--dataset` and `--data-dir` arguments, e.g., `--dataset=ffhq --data-dir=~/datasets`.\n\n**FFHQ**. To download the [Flickr-Faces-HQ](https://github.com/NVlabs/ffhq-dataset) dataset as multi-resolution TFRecords, run:\n\n```.bash\npushd ~\ngit clone https://github.com/NVlabs/ffhq-dataset.git\ncd ffhq-dataset\npython download_ffhq.py --tfrecords\npopd\npython dataset_tool.py display ~/ffhq-dataset/tfrecords/ffhq\n```\n\n**LSUN**. Download the desired LSUN categories in LMDB format from the [LSUN project page](https://www.yf.io/p/lsun). To convert the data to multi-resolution TFRecords, run:\n\n```.bash\npython dataset_tool.py create_lsun_wide ~/datasets/car ~/lsun/car_lmdb --width=512 --height=384\npython dataset_tool.py create_lsun ~/datasets/cat ~/lsun/cat_lmdb --resolution=256\npython dataset_tool.py create_lsun ~/datasets/church ~/lsun/church_outdoor_train_lmdb --resolution=256\npython dataset_tool.py create_lsun ~/datasets/horse ~/lsun/horse_lmdb --resolution=256\n```\n\n**Custom**. Create custom datasets by placing all training images under a single directory. The images must be square-shaped and they must all have the same power-of-two dimensions. To convert the images to multi-resolution TFRecords, run:\n\n```.bash\npython dataset_tool.py create_from_images ~/datasets/my-custom-dataset ~/my-custom-images\npython dataset_tool.py display ~/datasets/my-custom-dataset\n```\n\n## Using pre-trained networks\n\nPre-trained networks are stored as `*.pkl` files on the [StyleGAN2 Google Drive folder](https://drive.google.com/open?id=1QHc-yF5C3DChRwSdZKcx1w6K8JvSxQi7). Below, you can either reference them directly using the syntax `gdrive:networks/<filename>.pkl`, or download them manually and reference by filename.\n\n**Generating images**:\n\n```.bash\n# Generate uncurated ffhq images (matches paper Figure 12)\npython run_generator.py generate-images --network=gdrive:networks/stylegan2-ffhq-config-f.pkl \\\n  --seeds=6600-6625 --truncation-psi=0.5\n\n# Generate curated ffhq images (matches paper Figure 11)\npython run_generator.py generate-images --network=gdrive:networks/stylegan2-ffhq-config-f.pkl \\\n  --seeds=66,230,389,1518 --truncation-psi=1.0\n\n# Generate uncurated car images\npython run_generator.py generate-images --network=gdrive:networks/stylegan2-car-config-f.pkl \\\n  --seeds=6000-6025 --truncation-psi=0.5\n\n# Example of style mixing (matches the corresponding video clip)\npython run_generator.py style-mixing-example --network=gdrive:networks/stylegan2-ffhq-config-f.pkl \\\n  --row-seeds=85,100,75,458,1500 --col-seeds=55,821,1789,293 --truncation-psi=1.0\n```\n\nThe results are placed in `results/<RUNNING_ID>/*.png`. You can change the location with `--result-dir`. For example, `--result-dir=~/my-stylegan2-results`.\n\n**Projecting images to latent space**:\n\n```.bash\n# Project generated images\npython run_projector.py project-generated-images --network=gdrive:networks/stylegan2-car-config-f.pkl \\\n  --seeds=0,1,5\n\n# Project real images\npython run_projector.py project-real-images --network=gdrive:networks/stylegan2-car-config-f.pkl \\\n  --dataset=car --data-dir=~/datasets\n```\n\nYou can import the networks in your own Python code using `pickle.load()`. For this to work, you need to include the `dnnlib` source directory in `PYTHONPATH` and create a default TensorFlow session by calling `dnnlib.tflib.init_tf()`. See [run_generator.py](./run_generator.py) and [pretrained_networks.py](./pretrained_networks.py) for examples.\n\n## Training networks\n\nTo reproduce the training runs for config F in Tables 1 and 3, run:\n\n```.bash\npython run_training.py --num-gpus=8 --data-dir=~/datasets --config=config-f \\\n  --dataset=ffhq --mirror-augment=true\npython run_training.py --num-gpus=8 --data-dir=~/datasets --config=config-f \\\n  --dataset=car --total-kimg=57000\npython run_training.py --num-gpus=8 --data-dir=~/datasets --config=config-f \\\n  --dataset=cat --total-kimg=88000\npython run_training.py --num-gpus=8 --data-dir=~/datasets --config=config-f \\\n  --dataset=church --total-kimg 88000 --gamma=100\npython run_training.py --num-gpus=8 --data-dir=~/datasets --config=config-f \\\n  --dataset=horse --total-kimg 100000 --gamma=100\n```\n\nFor other configurations, see `python run_training.py --help`.\n\nWe have verified that the results match the paper when training with 1, 2, 4, or 8 GPUs. Note that training FFHQ at 1024&times;1024 resolution requires GPU(s) with at least 16 GB of memory. The following table lists typical training times using NVIDIA DGX-1 with 8 Tesla V100 GPUs:\n\n| Configuration | Resolution      | Total kimg | 1 GPU   | 2 GPUs  | 4 GPUs  | 8 GPUs | GPU mem |\n| :------------ | :-------------: | :--------: | :-----: | :-----: | :-----: | :----: | :-----: |\n| `config-f`    | 1024&times;1024 | 25000      | 69d 23h | 36d 4h  | 18d 14h | 9d 18h | 13.3 GB |\n| `config-f`    | 1024&times;1024 | 10000      | 27d 23h | 14d 11h | 7d 10h  | 3d 22h | 13.3 GB |\n| `config-e`    | 1024&times;1024 | 25000      | 35d 11h | 18d 15h | 9d 15h  | 5d 6h  | 8.6 GB  |\n| `config-e`    | 1024&times;1024 | 10000      | 14d 4h  | 7d 11h  | 3d 20h  | 2d 3h  | 8.6 GB  |\n| `config-f`    | 256&times;256   | 25000      | 32d 13h | 16d 23h | 8d 21h  | 4d 18h | 6.4 GB  |\n| `config-f`    | 256&times;256   | 10000      | 13d 0h  | 6d 19h  | 3d 13h  | 1d 22h | 6.4 GB  |\n\nTraining curves for FFHQ config F (StyleGAN2) compared to original StyleGAN using 8 GPUs:\n\n![Training curves](./docs/stylegan2-training-curves.png)\n\nAfter training, the resulting networks can be used the same way as the official pre-trained networks:\n\n```.bash\n# Generate 1000 random images without truncation\npython run_generator.py generate-images --seeds=0-999 --truncation-psi=1.0 \\\n  --network=results/00006-stylegan2-ffhq-8gpu-config-f/networks-final.pkl\n```\n\n## Evaluation metrics\n\nTo reproduce the numbers for config F in Tables 1 and 3, run:\n\n```.bash\npython run_metrics.py --data-dir=~/datasets --network=gdrive:networks/stylegan2-ffhq-config-f.pkl \\\n  --metrics=fid50k,ppl_wend --dataset=ffhq --mirror-augment=true\npython run_metrics.py --data-dir=~/datasets --network=gdrive:networks/stylegan2-car-config-f.pkl \\\n  --metrics=fid50k,ppl2_wend --dataset=car\npython run_metrics.py --data-dir=~/datasets --network=gdrive:networks/stylegan2-cat-config-f.pkl \\\n  --metrics=fid50k,ppl2_wend --dataset=cat\npython run_metrics.py --data-dir=~/datasets --network=gdrive:networks/stylegan2-church-config-f.pkl \\\n  --metrics=fid50k,ppl2_wend --dataset=church\npython run_metrics.py --data-dir=~/datasets --network=gdrive:networks/stylegan2-horse-config-f.pkl \\\n  --metrics=fid50k,ppl2_wend --dataset=horse\n```\n\nFor other configurations, see the [StyleGAN2 Google Drive folder](https://drive.google.com/open?id=1QHc-yF5C3DChRwSdZKcx1w6K8JvSxQi7).\n\nNote that the metrics are evaluated using a different random seed each time, so the results will vary between runs. In the paper, we reported the average result of running each metric 10 times. The following table lists the available metrics along with their expected runtimes and random variation:\n\n| Metric      | FFHQ config F  | 1 GPU  | 2 GPUs  | 4 GPUs | Description |\n| :---------- | :------------: | :----: | :-----: | :----: | :---------- |\n| `fid50k`    | 2.84 &pm; 0.03 | 22 min | 14 min  | 10 min | [Fr&eacute;chet Inception Distance](https://arxiv.org/abs/1706.08500)\n| `is50k`     | 5.13 &pm; 0.02 | 23 min | 14 min  | 8 min  | [Inception Score](https://arxiv.org/abs/1606.03498)\n| `ppl_zfull` | 348.0 &pm; 3.8 | 41 min | 22 min  | 14 min | [Perceptual Path Length](https://arxiv.org/abs/1812.04948) in Z, full paths\n| `ppl_wfull` | 126.9 &pm; 0.2 | 42 min | 22 min  | 13 min | [Perceptual Path Length](https://arxiv.org/abs/1812.04948) in W, full paths\n| `ppl_zend`  | 348.6 &pm; 3.0 | 41 min | 22 min  | 14 min | [Perceptual Path Length](https://arxiv.org/abs/1812.04948) in Z, path endpoints\n| `ppl_wend`  | 129.4 &pm; 0.8 | 40 min | 23 min  | 13 min | [Perceptual Path Length](https://arxiv.org/abs/1812.04948) in W, path endpoints\n| `ppl2_wend` | 145.0 &pm; 0.5 | 41 min | 23 min  | 14 min | [Perceptual Path Length](https://arxiv.org/abs/1812.04948) without center crop\n| `ls`        | 154.2 / 4.27   | 10 hrs | 6 hrs   | 4 hrs  | [Linear Separability](https://arxiv.org/abs/1812.04948)\n| `pr50k3`    | 0.689 / 0.492  | 26 min | 17 min  | 12 min | [Precision and Recall](https://arxiv.org/abs/1904.06991)\n\nNote that some of the metrics cache dataset-specific data on the disk, and they will take somewhat longer when run for the first time.\n\n## License\n\nCopyright &copy; 2019, NVIDIA Corporation. All rights reserved.\n\nThis work is made available under the Nvidia Source Code License-NC. To view a copy of this license, visit https://nvlabs.github.io/stylegan2/license.html\n\n## Citation\n\n```\n@article{Karras2019stylegan2,\n  title   = {Analyzing and Improving the Image Quality of {StyleGAN}},\n  author  = {Tero Karras and Samuli Laine and Miika Aittala and Janne Hellsten and Jaakko Lehtinen and Timo Aila},\n  journal = {CoRR},\n  volume  = {abs/1912.04958},\n  year    = {2019},\n}\n```\n\n## Acknowledgements\n\nWe thank Ming-Yu Liu for an early review, Timo Viitanen for his help with code release, and Tero Kuosmanen for compute infrastructure.\n"
  },
  {
    "path": "stylegan2-tpu/align_mammos.py",
    "content": "import argparse, os\nimport numpy as np\nfrom PIL import Image\nfrom tqdm import tqdm\n\nparser = argparse.ArgumentParser()\nparser.add_argument('-i', '--input', type=str, required=True, help=\"Input directory of images to resize.\")\nparser.add_argument('-o', '--output', type=str, required=True, help=\"Output destination to store resized images.\")\nargs = parser.parse_args()\n\n# Artistic crop: In-frame, centered mammogram.              \ndef flipImage(image):\n    def isLeftEdgeBlank(image):\n        return image[:, -1].sum(axis=0) > image[:, 0].sum(axis=0) \n    return image if isLeftEdgeBlank(np.asarray(image)).all() else image.transpose(Image.FLIP_LEFT_RIGHT)\n\ndirectory = args.input\ntarget_directory = args.output\n\n# This is a waste of memory and compute, \n# but it's nice to have an idea on the progress of the script.\nfilescount = 0\nfor dirPath, subdirList, fileList in os.walk(directory):\n    filescount += len(list(filter(lambda x: x.endswith(\".jpeg\"), fileList)))\n\nwith tqdm(total=filescount) as pbar:\n    for subdir, dirs, files in os.walk(directory):\n        for file in files:\n            filepath = subdir + os.sep + file\n            if filepath.endswith(\".jpeg\"):\n                if \"._\" in filepath:\n                    continue\n                im = Image.open(filepath).convert('RGB')\n                img = flipImage(im)\n                img.save(target_directory + '/' + file)\n                pbar.update(1)\n\n\n"
  },
  {
    "path": "stylegan2-tpu/convert_ckpt_to_pkl.py",
    "content": "#   ~~~ aydao ~~~~ 2020 ~~~\n#\n#   Convert a StyleGAN2 network stored in ckpt files to a .pkl\n#\nimport argparse\nimport pickle\nimport numpy as np\nimport warnings\nwarnings.filterwarnings('ignore', category=FutureWarning)\nwarnings.filterwarnings('ignore', category=DeprecationWarning)\nimport tensorflow as tf\ntf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)\nimport dnnlib\nimport dnnlib.tflib as tflib\nfrom training import misc\n\ndef main():\n    parser = argparse.ArgumentParser(\n        description='Creates a pkl from a ckpt of a StyleGAN2 model using a reference pkl of a network of the same size.',\n        formatter_class=argparse.RawDescriptionHelpFormatter\n    )\n    parser.add_argument('--ckpt_model_dir', help='The directory with the ckpt files', required=True)\n    parser.add_argument('--reference_pkl', help='A reference pkl of a StyleGAN2, must have the exact same variables as ckpt (will not be overwritten)', required=True)\n    parser.add_argument('--prefix', default='')\n\n    args = parser.parse_args()\n\n    model_dir = args.ckpt_model_dir\n    name = args.reference_pkl\n\n    tflib.init_tf()\n    G, D, Gs = pickle.load(open(name, \"rb\"))\n    G.print_layers(); D.print_layers(); Gs.print_layers()\n\n    var_list = [v for v in tf.global_variables()]\n    saver = tf.train.Saver(\n      var_list=var_list,\n    )\n    ckpt = tf.train.latest_checkpoint(model_dir)\n    sess = tf.get_default_session()\n    saver.restore(sess, ckpt)\n\n    out_pkl_iteration = ckpt.split('ckpt-')[-1]\n    out_pkl = './'+args.prefix+'model.ckpt-'+out_pkl_iteration+'.pkl'\n    print('Saving %s' % out_pkl)\n    misc.save_pkl((G, D, Gs), out_pkl)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "stylegan2-tpu/convert_pkl_to_ckpt.py",
    "content": "#   ~~~ aydao ~~~~ 2020 ~~~\n#\n#   Convert a StyleGAN2 network stored in a .pkl file to ckpt files\n#\n#       Warning: it worked for my use case, not fully checked \n#\nimport argparse\nimport pickle\nimport numpy as np\nimport warnings\nwarnings.filterwarnings('ignore', category=FutureWarning)\nwarnings.filterwarnings('ignore', category=DeprecationWarning)\nimport tensorflow as tf\ntf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)\nimport dnnlib\nimport dnnlib.tflib as tflib\nfrom training import misc\n\ndef main():\n    parser = argparse.ArgumentParser(\n        description='Creates a ckpt from a pkl of a StyleGAN2 model.',\n        formatter_class=argparse.RawDescriptionHelpFormatter\n    )\n    parser.add_argument('--ckpt_model_dir', help='The directory with the ckpt files', required=True)\n    parser.add_argument('--input_pkl', help='A StyleGAN2 pkl', required=True)\n    parser.add_argument('--prefix', default='')\n\n    args = parser.parse_args()\n\n    model_dir = args.ckpt_model_dir\n    input_pkl = args.input_pkl\n    prefix = args.prefix\n\n    tflib.init_tf()\n    with tf.Session() as sess:\n        G, D, Gs = pickle.load(open(input_pkl, \"rb\"))\n        G.print_layers(); D.print_layers(); Gs.print_layers()\n        var_list = [v for v in tf.global_variables() if 'Dataset/' not in v.name]\n        saver = tf.train.Saver(\n        var_list=var_list,\n        )\n        saver.save(sess, model_dir+'/'+prefix+'model.ckpt')\n\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "stylegan2-tpu/dataset_tool.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Tool for creating multi-resolution TFRecords datasets.\"\"\"\n\n# pylint: disable=too-many-lines\nimport os\nimport sys\nimport glob\nimport argparse\nimport threading\nimport six.moves.queue as Queue # pylint: disable=import-error\nimport traceback\nimport numpy as np\nimport tensorflow as tf\nimport PIL.Image\nimport dnnlib.tflib as tflib\nfrom tqdm import tqdm\n\nfrom training import dataset\n\n#----------------------------------------------------------------------------\n\ndef error(msg):\n    print('Error: ' + msg)\n    exit(1)\n\n#----------------------------------------------------------------------------\n\nclass TFRecordExporter:\n    def __init__(self, tfrecord_dir, expected_images, print_progress=True, progress_interval=10):\n        self.tfrecord_dir       = tfrecord_dir\n        self.tfr_prefix         = os.path.join(self.tfrecord_dir, os.path.basename(self.tfrecord_dir))\n        self.expected_images    = expected_images\n        self.cur_images         = 0\n        self.shape              = None\n        self.resolution_log2    = None\n        self.tfr_writers        = []\n        self.print_progress     = print_progress\n        self.progress_interval  = progress_interval\n\n        if self.print_progress:\n            print('Creating dataset \"%s\"' % tfrecord_dir)\n        if not os.path.isdir(self.tfrecord_dir):\n            os.makedirs(self.tfrecord_dir)\n        assert os.path.isdir(self.tfrecord_dir)\n\n    def close(self):\n        if self.print_progress:\n            print('%-40s\\r' % 'Flushing data...', end='', flush=True)\n        for tfr_writer in self.tfr_writers:\n            tfr_writer.close()\n        self.tfr_writers = []\n        if self.print_progress:\n            print('%-40s\\r' % '', end='', flush=True)\n            print('Added %d images.' % self.cur_images)\n\n    def choose_shuffled_order(self): # Note: Images and labels must be added in shuffled order.\n        order = np.arange(self.expected_images)\n        np.random.RandomState(123).shuffle(order)\n        return order\n\n    def add_image(self, img):\n        if self.shape is None:\n            self.shape = img.shape\n            self.resolution_log2 = int(np.log2(self.shape[1]))\n            assert self.shape[0] in [1, 3]\n            assert self.shape[1] == self.shape[2]\n            assert self.shape[1] == 2**self.resolution_log2\n            tfr_opt = tf.python_io.TFRecordOptions(tf.python_io.TFRecordCompressionType.NONE)\n            for lod in range(self.resolution_log2 - 1):\n                tfr_file = self.tfr_prefix + '-r%02d.tfrecords' % (self.resolution_log2 - lod)\n                self.tfr_writers.append(tf.python_io.TFRecordWriter(tfr_file, tfr_opt))\n        assert img.shape == self.shape\n        for lod, tfr_writer in enumerate(self.tfr_writers):\n            if lod:\n                img = img.astype(np.float32)\n                img = (img[:, 0::2, 0::2] + img[:, 0::2, 1::2] + img[:, 1::2, 0::2] + img[:, 1::2, 1::2]) * 0.25\n            quant = np.rint(img).clip(0, 255).astype(np.uint8)\n            ex = tf.train.Example(features=tf.train.Features(feature={\n                'shape': tf.train.Feature(int64_list=tf.train.Int64List(value=quant.shape)),\n                'data': tf.train.Feature(bytes_list=tf.train.BytesList(value=[quant.tostring()]))}))\n            tfr_writer.write(ex.SerializeToString())\n        self.cur_images += 1\n\n    def add_labels(self, labels):\n        if self.print_progress:\n            print('%-40s\\r' % 'Saving labels...', end='', flush=True)\n        assert labels.shape[0] == self.cur_images\n        with open(self.tfr_prefix + '-rxx.labels', 'wb') as f:\n            np.save(f, labels.astype(np.float32))\n\n    def __enter__(self):\n        return self\n\n    def __exit__(self, *args):\n        self.close()\n\n#----------------------------------------------------------------------------\n\nclass ExceptionInfo(object):\n    def __init__(self):\n        self.value = sys.exc_info()[1]\n        self.traceback = traceback.format_exc()\n\n#----------------------------------------------------------------------------\n\nclass WorkerThread(threading.Thread):\n    def __init__(self, task_queue):\n        threading.Thread.__init__(self)\n        self.task_queue = task_queue\n\n    def run(self):\n        while True:\n            func, args, result_queue = self.task_queue.get()\n            if func is None:\n                break\n            try:\n                result = func(*args)\n            except:\n                result = ExceptionInfo()\n            result_queue.put((result, args))\n\n#----------------------------------------------------------------------------\n\nclass ThreadPool(object):\n    def __init__(self, num_threads):\n        assert num_threads >= 1\n        self.task_queue = Queue.Queue()\n        self.result_queues = dict()\n        self.num_threads = num_threads\n        for _idx in range(self.num_threads):\n            thread = WorkerThread(self.task_queue)\n            thread.daemon = True\n            thread.start()\n\n    def add_task(self, func, args=()):\n        assert hasattr(func, '__call__') # must be a function\n        if func not in self.result_queues:\n            self.result_queues[func] = Queue.Queue()\n        self.task_queue.put((func, args, self.result_queues[func]))\n\n    def get_result(self, func): # returns (result, args)\n        result, args = self.result_queues[func].get()\n        if isinstance(result, ExceptionInfo):\n            print('\\n\\nWorker thread caught an exception:\\n' + result.traceback)\n            raise result.value\n        return result, args\n\n    def finish(self):\n        for _idx in range(self.num_threads):\n            self.task_queue.put((None, (), None))\n\n    def __enter__(self): # for 'with' statement\n        return self\n\n    def __exit__(self, *excinfo):\n        self.finish()\n\n    def process_items_concurrently(self, item_iterator, process_func=lambda x: x, pre_func=lambda x: x, post_func=lambda x: x, max_items_in_flight=None):\n        if max_items_in_flight is None: max_items_in_flight = self.num_threads * 4\n        assert max_items_in_flight >= 1\n        results = []\n        retire_idx = [0]\n\n        def task_func(prepared, _idx):\n            return process_func(prepared)\n\n        def retire_result():\n            processed, (_prepared, idx) = self.get_result(task_func)\n            results[idx] = processed\n            while retire_idx[0] < len(results) and results[retire_idx[0]] is not None:\n                yield post_func(results[retire_idx[0]])\n                results[retire_idx[0]] = None\n                retire_idx[0] += 1\n\n        for idx, item in enumerate(item_iterator):\n            prepared = pre_func(item)\n            results.append(None)\n            self.add_task(func=task_func, args=(prepared, idx))\n            while retire_idx[0] < idx - max_items_in_flight + 2:\n                for res in retire_result(): yield res\n        while retire_idx[0] < len(results):\n            for res in retire_result(): yield res\n\n#----------------------------------------------------------------------------\n\ndef display(tfrecord_dir):\n    print('Loading dataset \"%s\"' % tfrecord_dir)\n    tflib.init_tf({'gpu_options.allow_growth': True})\n    dset = dataset.TFRecordDataset(tfrecord_dir, max_label_size='full', repeat=False, shuffle_mb=0)\n    tflib.init_uninitialized_vars()\n    import cv2  # pip install opencv-python\n\n    idx = 0\n    while True:\n        try:\n            images, labels = dset.get_minibatch_np(1)\n        except tf.errors.OutOfRangeError:\n            break\n        if idx == 0:\n            print('Displaying images')\n            cv2.namedWindow('dataset_tool')\n            print('Press SPACE or ENTER to advance, ESC to exit')\n        print('\\nidx = %-8d\\nlabel = %s' % (idx, labels[0].tolist()))\n        cv2.imshow('dataset_tool', images[0].transpose(1, 2, 0)[:, :, ::-1]) # CHW => HWC, RGB => BGR\n        idx += 1\n        if cv2.waitKey() == 27:\n            break\n    print('\\nDisplayed %d images.' % idx)\n\n#----------------------------------------------------------------------------\n\ndef extract(tfrecord_dir, output_dir):\n    print('Loading dataset \"%s\"' % tfrecord_dir)\n    tflib.init_tf({'gpu_options.allow_growth': True})\n    dset = dataset.TFRecordDataset(tfrecord_dir, max_label_size=0, repeat=False, shuffle_mb=0)\n    tflib.init_uninitialized_vars()\n\n    print('Extracting images to \"%s\"' % output_dir)\n    if not os.path.isdir(output_dir):\n        os.makedirs(output_dir)\n    idx = 0\n    while True:\n        if idx % 10 == 0:\n            print('%d\\r' % idx, end='', flush=True)\n        try:\n            images, _labels = dset.get_minibatch_np(1)\n        except tf.errors.OutOfRangeError:\n            break\n        if images.shape[1] == 1:\n            img = PIL.Image.fromarray(images[0][0], 'L')\n        else:\n            img = PIL.Image.fromarray(images[0].transpose(1, 2, 0), 'RGB')\n        img.save(os.path.join(output_dir, 'img%08d.png' % idx))\n        idx += 1\n    print('Extracted %d images.' % idx)\n\n#----------------------------------------------------------------------------\n\ndef compare(tfrecord_dir_a, tfrecord_dir_b, ignore_labels):\n    max_label_size = 0 if ignore_labels else 'full'\n    print('Loading dataset \"%s\"' % tfrecord_dir_a)\n    tflib.init_tf({'gpu_options.allow_growth': True})\n    dset_a = dataset.TFRecordDataset(tfrecord_dir_a, max_label_size=max_label_size, repeat=False, shuffle_mb=0)\n    print('Loading dataset \"%s\"' % tfrecord_dir_b)\n    dset_b = dataset.TFRecordDataset(tfrecord_dir_b, max_label_size=max_label_size, repeat=False, shuffle_mb=0)\n    tflib.init_uninitialized_vars()\n\n    print('Comparing datasets')\n    idx = 0\n    identical_images = 0\n    identical_labels = 0\n    while True:\n        if idx % 100 == 0:\n            print('%d\\r' % idx, end='', flush=True)\n        try:\n            images_a, labels_a = dset_a.get_minibatch_np(1)\n        except tf.errors.OutOfRangeError:\n            images_a, labels_a = None, None\n        try:\n            images_b, labels_b = dset_b.get_minibatch_np(1)\n        except tf.errors.OutOfRangeError:\n            images_b, labels_b = None, None\n        if images_a is None or images_b is None:\n            if images_a is not None or images_b is not None:\n                print('Datasets contain different number of images')\n            break\n        if images_a.shape == images_b.shape and np.all(images_a == images_b):\n            identical_images += 1\n        else:\n            print('Image %d is different' % idx)\n        if labels_a.shape == labels_b.shape and np.all(labels_a == labels_b):\n            identical_labels += 1\n        else:\n            print('Label %d is different' % idx)\n        idx += 1\n    print('Identical images: %d / %d' % (identical_images, idx))\n    if not ignore_labels:\n        print('Identical labels: %d / %d' % (identical_labels, idx))\n\n#----------------------------------------------------------------------------\n\ndef create_mnist(tfrecord_dir, mnist_dir):\n    print('Loading MNIST from \"%s\"' % mnist_dir)\n    import gzip\n    with gzip.open(os.path.join(mnist_dir, 'train-images-idx3-ubyte.gz'), 'rb') as file:\n        images = np.frombuffer(file.read(), np.uint8, offset=16)\n    with gzip.open(os.path.join(mnist_dir, 'train-labels-idx1-ubyte.gz'), 'rb') as file:\n        labels = np.frombuffer(file.read(), np.uint8, offset=8)\n    images = images.reshape(-1, 1, 28, 28)\n    images = np.pad(images, [(0,0), (0,0), (2,2), (2,2)], 'constant', constant_values=0)\n    assert images.shape == (60000, 1, 32, 32) and images.dtype == np.uint8\n    assert labels.shape == (60000,) and labels.dtype == np.uint8\n    assert np.min(images) == 0 and np.max(images) == 255\n    assert np.min(labels) == 0 and np.max(labels) == 9\n    onehot = np.zeros((labels.size, np.max(labels) + 1), dtype=np.float32)\n    onehot[np.arange(labels.size), labels] = 1.0\n\n    with TFRecordExporter(tfrecord_dir, images.shape[0]) as tfr:\n        order = tfr.choose_shuffled_order()\n        for idx in range(order.size):\n            tfr.add_image(images[order[idx]])\n        tfr.add_labels(onehot[order])\n\n#----------------------------------------------------------------------------\n\ndef create_mnistrgb(tfrecord_dir, mnist_dir, num_images=1000000, random_seed=123):\n    print('Loading MNIST from \"%s\"' % mnist_dir)\n    import gzip\n    with gzip.open(os.path.join(mnist_dir, 'train-images-idx3-ubyte.gz'), 'rb') as file:\n        images = np.frombuffer(file.read(), np.uint8, offset=16)\n    images = images.reshape(-1, 28, 28)\n    images = np.pad(images, [(0,0), (2,2), (2,2)], 'constant', constant_values=0)\n    assert images.shape == (60000, 32, 32) and images.dtype == np.uint8\n    assert np.min(images) == 0 and np.max(images) == 255\n\n    with TFRecordExporter(tfrecord_dir, num_images) as tfr:\n        rnd = np.random.RandomState(random_seed)\n        for _idx in range(num_images):\n            tfr.add_image(images[rnd.randint(images.shape[0], size=3)])\n\n#----------------------------------------------------------------------------\n\ndef create_cifar10(tfrecord_dir, cifar10_dir):\n    print('Loading CIFAR-10 from \"%s\"' % cifar10_dir)\n    import pickle\n    images = []\n    labels = []\n    for batch in range(1, 6):\n        with open(os.path.join(cifar10_dir, 'data_batch_%d' % batch), 'rb') as file:\n            data = pickle.load(file, encoding='latin1')\n        images.append(data['data'].reshape(-1, 3, 32, 32))\n        labels.append(data['labels'])\n    images = np.concatenate(images)\n    labels = np.concatenate(labels)\n    assert images.shape == (50000, 3, 32, 32) and images.dtype == np.uint8\n    assert labels.shape == (50000,) and labels.dtype == np.int32\n    assert np.min(images) == 0 and np.max(images) == 255\n    assert np.min(labels) == 0 and np.max(labels) == 9\n    onehot = np.zeros((labels.size, np.max(labels) + 1), dtype=np.float32)\n    onehot[np.arange(labels.size), labels] = 1.0\n\n    with TFRecordExporter(tfrecord_dir, images.shape[0]) as tfr:\n        order = tfr.choose_shuffled_order()\n        for idx in range(order.size):\n            tfr.add_image(images[order[idx]])\n        tfr.add_labels(onehot[order])\n\n#----------------------------------------------------------------------------\n\ndef create_cifar100(tfrecord_dir, cifar100_dir):\n    print('Loading CIFAR-100 from \"%s\"' % cifar100_dir)\n    import pickle\n    with open(os.path.join(cifar100_dir, 'train'), 'rb') as file:\n        data = pickle.load(file, encoding='latin1')\n    images = data['data'].reshape(-1, 3, 32, 32)\n    labels = np.array(data['fine_labels'])\n    assert images.shape == (50000, 3, 32, 32) and images.dtype == np.uint8\n    assert labels.shape == (50000,) and labels.dtype == np.int32\n    assert np.min(images) == 0 and np.max(images) == 255\n    assert np.min(labels) == 0 and np.max(labels) == 99\n    onehot = np.zeros((labels.size, np.max(labels) + 1), dtype=np.float32)\n    onehot[np.arange(labels.size), labels] = 1.0\n\n    with TFRecordExporter(tfrecord_dir, images.shape[0]) as tfr:\n        order = tfr.choose_shuffled_order()\n        for idx in range(order.size):\n            tfr.add_image(images[order[idx]])\n        tfr.add_labels(onehot[order])\n\n#----------------------------------------------------------------------------\n\ndef create_svhn(tfrecord_dir, svhn_dir):\n    print('Loading SVHN from \"%s\"' % svhn_dir)\n    import pickle\n    images = []\n    labels = []\n    for batch in range(1, 4):\n        with open(os.path.join(svhn_dir, 'train_%d.pkl' % batch), 'rb') as file:\n            data = pickle.load(file, encoding='latin1')\n        images.append(data[0])\n        labels.append(data[1])\n    images = np.concatenate(images)\n    labels = np.concatenate(labels)\n    assert images.shape == (73257, 3, 32, 32) and images.dtype == np.uint8\n    assert labels.shape == (73257,) and labels.dtype == np.uint8\n    assert np.min(images) == 0 and np.max(images) == 255\n    assert np.min(labels) == 0 and np.max(labels) == 9\n    onehot = np.zeros((labels.size, np.max(labels) + 1), dtype=np.float32)\n    onehot[np.arange(labels.size), labels] = 1.0\n\n    with TFRecordExporter(tfrecord_dir, images.shape[0]) as tfr:\n        order = tfr.choose_shuffled_order()\n        for idx in range(order.size):\n            tfr.add_image(images[order[idx]])\n        tfr.add_labels(onehot[order])\n\n#----------------------------------------------------------------------------\n\ndef create_lsun(tfrecord_dir, lmdb_dir, resolution=256, max_images=None):\n    print('Loading LSUN dataset from \"%s\"' % lmdb_dir)\n    import lmdb # pip install lmdb # pylint: disable=import-error\n    import cv2 # pip install opencv-python\n    import io\n    with lmdb.open(lmdb_dir, readonly=True).begin(write=False) as txn:\n        total_images = txn.stat()['entries'] # pylint: disable=no-value-for-parameter\n        if max_images is None:\n            max_images = total_images\n        with TFRecordExporter(tfrecord_dir, max_images) as tfr:\n            for _idx, (_key, value) in enumerate(txn.cursor()):\n                try:\n                    try:\n                        img = cv2.imdecode(np.fromstring(value, dtype=np.uint8), 1)\n                        if img is None:\n                            raise IOError('cv2.imdecode failed')\n                        img = img[:, :, ::-1] # BGR => RGB\n                    except IOError:\n                        img = np.asarray(PIL.Image.open(io.BytesIO(value)))\n                    crop = np.min(img.shape[:2])\n                    img = img[(img.shape[0] - crop) // 2 : (img.shape[0] + crop) // 2, (img.shape[1] - crop) // 2 : (img.shape[1] + crop) // 2]\n                    img = PIL.Image.fromarray(img, 'RGB')\n                    img = img.resize((resolution, resolution), PIL.Image.ANTIALIAS)\n                    img = np.asarray(img)\n                    img = img.transpose([2, 0, 1]) # HWC => CHW\n                    tfr.add_image(img)\n                except:\n                    print(sys.exc_info()[1])\n                if tfr.cur_images == max_images:\n                    break\n\n#----------------------------------------------------------------------------\n\ndef create_lsun_wide(tfrecord_dir, lmdb_dir, width=512, height=384, max_images=None):\n    assert width == 2 ** int(np.round(np.log2(width)))\n    assert height <= width\n    print('Loading LSUN dataset from \"%s\"' % lmdb_dir)\n    import lmdb # pip install lmdb # pylint: disable=import-error\n    import cv2 # pip install opencv-python\n    import io\n    with lmdb.open(lmdb_dir, readonly=True).begin(write=False) as txn:\n        total_images = txn.stat()['entries'] # pylint: disable=no-value-for-parameter\n        if max_images is None:\n            max_images = total_images\n        with TFRecordExporter(tfrecord_dir, max_images, print_progress=False) as tfr:\n            for idx, (_key, value) in enumerate(txn.cursor()):\n                try:\n                    try:\n                        img = cv2.imdecode(np.fromstring(value, dtype=np.uint8), 1)\n                        if img is None:\n                            raise IOError('cv2.imdecode failed')\n                        img = img[:, :, ::-1] # BGR => RGB\n                    except IOError:\n                        img = np.asarray(PIL.Image.open(io.BytesIO(value)))\n\n                    ch = int(np.round(width * img.shape[0] / img.shape[1]))\n                    if img.shape[1] < width or ch < height:\n                        continue\n\n                    img = img[(img.shape[0] - ch) // 2 : (img.shape[0] + ch) // 2]\n                    img = PIL.Image.fromarray(img, 'RGB')\n                    img = img.resize((width, height), PIL.Image.ANTIALIAS)\n                    img = np.asarray(img)\n                    img = img.transpose([2, 0, 1]) # HWC => CHW\n\n                    canvas = np.zeros([3, width, width], dtype=np.uint8)\n                    canvas[:, (width - height) // 2 : (width + height) // 2] = img\n                    tfr.add_image(canvas)\n                    print('\\r%d / %d => %d ' % (idx + 1, total_images, tfr.cur_images), end='')\n\n                except:\n                    print(sys.exc_info()[1])\n                if tfr.cur_images == max_images:\n                    break\n    print()\n\n#----------------------------------------------------------------------------\n\ndef create_celeba(tfrecord_dir, celeba_dir, cx=89, cy=121):\n    print('Loading CelebA from \"%s\"' % celeba_dir)\n    glob_pattern = os.path.join(celeba_dir, 'img_align_celeba_png', '*.png')\n    image_filenames = sorted(glob.glob(glob_pattern))\n    expected_images = 202599\n    if len(image_filenames) != expected_images:\n        error('Expected to find %d images' % expected_images)\n\n    with TFRecordExporter(tfrecord_dir, len(image_filenames)) as tfr:\n        order = tfr.choose_shuffled_order()\n        for idx in range(order.size):\n            img = np.asarray(PIL.Image.open(image_filenames[order[idx]]))\n            assert img.shape == (218, 178, 3)\n            img = img[cy - 64 : cy + 64, cx - 64 : cx + 64]\n            img = img.transpose(2, 0, 1) # HWC => CHW\n            tfr.add_image(img)\n\n#----------------------------------------------------------------------------\ndef create_from_images(tfrecord_dir, image_dir, shuffle, res_log2=7, resize=None, max_images=None):\n    print('Loading images from \"%s\"' % image_dir)\n    image_filenames = sorted(glob.glob(os.path.join(image_dir, '*')))\n    if max_images is None:\n            max_images = len(image_filenames)\n    print(f\"detected {len(image_filenames)} images ...\")\n    if len(image_filenames) == 0:\n        error('No input images found')\n    if resize == None:\n        img = np.asarray(PIL.Image.open(image_filenames[0]).convert('RGB'))\n    else:\n        img = np.asarray(PIL.Image.open(image_filenames[0]).convert('RGB').resize((resize, resize), PIL.Image.ANTIALIAS))\n    resolution = img.shape[0]\n    channels = img.shape[2] if img.ndim == 3 else 1\n    if img.shape[1] != resolution:\n        error('Input images must have the same width and height')\n    if resolution != 2 ** int(np.floor(np.log2(resolution))):\n        error('Input image resolution must be a power-of-two')\n    if channels not in [1, 3]:\n        error('Input images must be stored as RGB or grayscale')\n\n    with TFRecordExporter(tfrecord_dir, max_images) as tfr:\n        order = tfr.choose_shuffled_order() if shuffle else np.arange(len(image_filenames))\n        print(\"Adding the images to tfrecords ...\")\n        for idx in tqdm(range(order.size)):\n            if resize == None:\n                img = np.asarray(PIL.Image.open(image_filenames[order[idx]]).convert('RGB'))\n            else:\n                img = np.asarray(PIL.Image.open(image_filenames[order[idx]]).convert('RGB').resize((resize, resize), PIL.Image.ANTIALIAS))\n            if channels == 1:\n                img = img[np.newaxis, :, :] # HW => CHW\n            else:\n                img = img.transpose([2, 0, 1]) # HWC => CHW\n            tfr.add_image(img)\n            if tfr.cur_images == max_images:\n                break\n\n#----------------------------------------------------------------------------\n\ndef create_from_hdf5(tfrecord_dir, hdf5_filename, shuffle):\n    print('Loading HDF5 archive from \"%s\"' % hdf5_filename)\n    import h5py # conda install h5py\n    with h5py.File(hdf5_filename, 'r') as hdf5_file:\n        hdf5_data = max([value for key, value in hdf5_file.items() if key.startswith('data')], key=lambda lod: lod.shape[3])\n        with TFRecordExporter(tfrecord_dir, hdf5_data.shape[0]) as tfr:\n            order = tfr.choose_shuffled_order() if shuffle else np.arange(hdf5_data.shape[0])\n            for idx in range(order.size):\n                tfr.add_image(hdf5_data[order[idx]])\n            npy_filename = os.path.splitext(hdf5_filename)[0] + '-labels.npy'\n            if os.path.isfile(npy_filename):\n                tfr.add_labels(np.load(npy_filename)[order])\n\n#----------------------------------------------------------------------------\n\ndef execute_cmdline(argv):\n    prog = argv[0]\n    parser = argparse.ArgumentParser(\n        prog        = prog,\n        description = 'Tool for creating multi-resolution TFRecords datasets for StyleGAN and ProGAN.',\n        epilog      = 'Type \"%s <command> -h\" for more information.' % prog)\n\n    subparsers = parser.add_subparsers(dest='command')\n    subparsers.required = True\n    def add_command(cmd, desc, example=None):\n        epilog = 'Example: %s %s' % (prog, example) if example is not None else None\n        return subparsers.add_parser(cmd, description=desc, help=desc, epilog=epilog)\n\n    p = add_command(    'display',          'Display images in dataset.',\n                                            'display datasets/mnist')\n    p.add_argument(     'tfrecord_dir',     help='Directory containing dataset')\n\n    p = add_command(    'extract',          'Extract images from dataset.',\n                                            'extract datasets/mnist mnist-images')\n    p.add_argument(     'tfrecord_dir',     help='Directory containing dataset')\n    p.add_argument(     'output_dir',       help='Directory to extract the images into')\n\n    p = add_command(    'compare',          'Compare two datasets.',\n                                            'compare datasets/mydataset datasets/mnist')\n    p.add_argument(     'tfrecord_dir_a',   help='Directory containing first dataset')\n    p.add_argument(     'tfrecord_dir_b',   help='Directory containing second dataset')\n    p.add_argument(     '--ignore_labels',  help='Ignore labels (default: 0)', type=int, default=0)\n\n    p = add_command(    'create_mnist',     'Create dataset for MNIST.',\n                                            'create_mnist datasets/mnist ~/downloads/mnist')\n    p.add_argument(     'tfrecord_dir',     help='New dataset directory to be created')\n    p.add_argument(     'mnist_dir',        help='Directory containing MNIST')\n\n    p = add_command(    'create_mnistrgb',  'Create dataset for MNIST-RGB.',\n                                            'create_mnistrgb datasets/mnistrgb ~/downloads/mnist')\n    p.add_argument(     'tfrecord_dir',     help='New dataset directory to be created')\n    p.add_argument(     'mnist_dir',        help='Directory containing MNIST')\n    p.add_argument(     '--num_images',     help='Number of composite images to create (default: 1000000)', type=int, default=1000000)\n    p.add_argument(     '--random_seed',    help='Random seed (default: 123)', type=int, default=123)\n\n    p = add_command(    'create_cifar10',   'Create dataset for CIFAR-10.',\n                                            'create_cifar10 datasets/cifar10 ~/downloads/cifar10')\n    p.add_argument(     'tfrecord_dir',     help='New dataset directory to be created')\n    p.add_argument(     'cifar10_dir',      help='Directory containing CIFAR-10')\n\n    p = add_command(    'create_cifar100',  'Create dataset for CIFAR-100.',\n                                            'create_cifar100 datasets/cifar100 ~/downloads/cifar100')\n    p.add_argument(     'tfrecord_dir',     help='New dataset directory to be created')\n    p.add_argument(     'cifar100_dir',     help='Directory containing CIFAR-100')\n\n    p = add_command(    'create_svhn',      'Create dataset for SVHN.',\n                                            'create_svhn datasets/svhn ~/downloads/svhn')\n    p.add_argument(     'tfrecord_dir',     help='New dataset directory to be created')\n    p.add_argument(     'svhn_dir',         help='Directory containing SVHN')\n\n    p = add_command(    'create_lsun',      'Create dataset for single LSUN category.',\n                                            'create_lsun datasets/lsun-car-100k ~/downloads/lsun/car_lmdb --resolution 256 --max_images 100000')\n    p.add_argument(     'tfrecord_dir',     help='New dataset directory to be created')\n    p.add_argument(     'lmdb_dir',         help='Directory containing LMDB database')\n    p.add_argument(     '--resolution',     help='Output resolution (default: 256)', type=int, default=256)\n    p.add_argument(     '--max_images',     help='Maximum number of images (default: none)', type=int, default=None)\n\n    p = add_command(    'create_lsun_wide', 'Create LSUN dataset with non-square aspect ratio.',\n                                            'create_lsun_wide datasets/lsun-car-512x384 ~/downloads/lsun/car_lmdb --width 512 --height 384')\n    p.add_argument(     'tfrecord_dir',     help='New dataset directory to be created')\n    p.add_argument(     'lmdb_dir',         help='Directory containing LMDB database')\n    p.add_argument(     '--width',          help='Output width (default: 512)', type=int, default=512)\n    p.add_argument(     '--height',         help='Output height (default: 384)', type=int, default=384)\n    p.add_argument(     '--max_images',     help='Maximum number of images (default: none)', type=int, default=None)\n\n    p = add_command(    'create_celeba',    'Create dataset for CelebA.',\n                                            'create_celeba datasets/celeba ~/downloads/celeba')\n    p.add_argument(     'tfrecord_dir',     help='New dataset directory to be created')\n    p.add_argument(     'celeba_dir',       help='Directory containing CelebA')\n    p.add_argument(     '--cx',             help='Center X coordinate (default: 89)', type=int, default=89)\n    p.add_argument(     '--cy',             help='Center Y coordinate (default: 121)', type=int, default=121)\n\n    p = add_command(    'create_from_images', 'Create dataset from a directory full of images.',\n                                            'create_from_images datasets/mydataset myimagedir')\n    p.add_argument(     'tfrecord_dir',     help='New dataset directory to be created')\n    p.add_argument(     'image_dir',        help='Directory containing the images')\n    p.add_argument(     '--shuffle',        help='Randomize image order (default: 1)', type=int, default=1)\n    p.add_argument(     '--resize',         help=\"width/height of the image (default: None)\", type=int, default=None, required=False)\n    p.add_argument(     '--res_log2',       help=\"image width and height should be multiple of 2**res_log2 (default: 7)\", type=int, default=7)\n    p.add_argument(     '--max_images',     help='Maximum number of images (default: none)', type=int, default=None)\n\n    p = add_command(    'create_from_hdf5', 'Create dataset from legacy HDF5 archive.',\n                                            'create_from_hdf5 datasets/celebahq ~/downloads/celeba-hq-1024x1024.h5')\n    p.add_argument(     'tfrecord_dir',     help='New dataset directory to be created')\n    p.add_argument(     'hdf5_filename',    help='HDF5 archive containing the images')\n    p.add_argument(     '--shuffle',        help='Randomize image order (default: 1)', type=int, default=1)\n\n    args = parser.parse_args(argv[1:] if len(argv) > 1 else ['-h'])\n    func = globals()[args.command]\n    del args.command\n    func(**vars(args))\n\n#----------------------------------------------------------------------------\n\nif __name__ == \"__main__\":\n    execute_cmdline(sys.argv)\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/__init__.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\nfrom . import submission\n\nfrom .submission.run_context import RunContext\n\nfrom .submission.submit import SubmitTarget\nfrom .submission.submit import PathType\nfrom .submission.submit import SubmitConfig\nfrom .submission.submit import submit_run\nfrom .submission.submit import get_path_from_template\nfrom .submission.submit import convert_path\nfrom .submission.submit import make_run_dir_path\n\nfrom .util import EasyDict\n\nsubmit_config: SubmitConfig = None # Package level variable for SubmitConfig which is only valid when inside the run function.\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/submission/__init__.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\nfrom . import run_context\nfrom . import submit\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/submission/internal/__init__.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\nfrom . import local\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/submission/internal/local.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\nclass TargetOptions():\n    def __init__(self):\n        self.do_not_copy_source_files = False\n\nclass Target():\n    def __init__(self):\n        pass\n\n    def finalize_submit_config(self, submit_config, host_run_dir):\n        print ('Local submit ', end='', flush=True)\n        submit_config.run_dir = host_run_dir\n\n    def submit(self, submit_config, host_run_dir):\n        from ..submit import run_wrapper, convert_path\n        print('- run_dir: %s' % convert_path(submit_config.run_dir), flush=True)\n        return run_wrapper(submit_config)\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/submission/run_context.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Helpers for managing the run/training loop.\"\"\"\n\nimport datetime\nimport json\nimport os\nimport pprint\nimport time\nimport types\n\nfrom typing import Any\n\nfrom . import submit\n\n# Singleton RunContext\n_run_context = None\n\nclass RunContext(object):\n    \"\"\"Helper class for managing the run/training loop.\n\n    The context will hide the implementation details of a basic run/training loop.\n    It will set things up properly, tell if run should be stopped, and then cleans up.\n    User should call update periodically and use should_stop to determine if run should be stopped.\n\n    Args:\n        submit_config: The SubmitConfig that is used for the current run.\n        config_module: (deprecated) The whole config module that is used for the current run.\n    \"\"\"\n\n    def __init__(self, submit_config: submit.SubmitConfig, config_module: types.ModuleType = None):\n        global _run_context\n        # Only a single RunContext can be alive\n        assert _run_context is None\n        _run_context = self\n        self.submit_config = submit_config\n        self.should_stop_flag = False\n        self.has_closed = False\n        self.start_time = time.time()\n        self.last_update_time = time.time()\n        self.last_update_interval = 0.0\n        self.progress_monitor_file_path = None\n\n        # vestigial config_module support just prints a warning\n        if config_module is not None:\n            print(\"RunContext.config_module parameter support has been removed.\")\n\n        # write out details about the run to a text file\n        self.run_txt_data = {\"task_name\": submit_config.task_name, \"host_name\": submit_config.host_name, \"start_time\": datetime.datetime.now().isoformat(sep=\" \")}\n        with open(os.path.join(submit_config.run_dir, \"run.txt\"), \"w\") as f:\n            pprint.pprint(self.run_txt_data, stream=f, indent=4, width=200, compact=False)\n\n    def __enter__(self) -> \"RunContext\":\n        return self\n\n    def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:\n        self.close()\n\n    def update(self, loss: Any = 0, cur_epoch: Any = 0, max_epoch: Any = None) -> None:\n        \"\"\"Do general housekeeping and keep the state of the context up-to-date.\n        Should be called often enough but not in a tight loop.\"\"\"\n        assert not self.has_closed\n\n        self.last_update_interval = time.time() - self.last_update_time\n        self.last_update_time = time.time()\n\n        if os.path.exists(os.path.join(self.submit_config.run_dir, \"abort.txt\")):\n            self.should_stop_flag = True\n\n    def should_stop(self) -> bool:\n        \"\"\"Tell whether a stopping condition has been triggered one way or another.\"\"\"\n        return self.should_stop_flag\n\n    def get_time_since_start(self) -> float:\n        \"\"\"How much time has passed since the creation of the context.\"\"\"\n        return time.time() - self.start_time\n\n    def get_time_since_last_update(self) -> float:\n        \"\"\"How much time has passed since the last call to update.\"\"\"\n        return time.time() - self.last_update_time\n\n    def get_last_update_interval(self) -> float:\n        \"\"\"How much time passed between the previous two calls to update.\"\"\"\n        return self.last_update_interval\n\n    def close(self) -> None:\n        \"\"\"Close the context and clean up.\n        Should only be called once.\"\"\"\n        if not self.has_closed:\n            # update the run.txt with stopping time\n            self.run_txt_data[\"stop_time\"] = datetime.datetime.now().isoformat(sep=\" \")\n            with open(os.path.join(self.submit_config.run_dir, \"run.txt\"), \"w\") as f:\n                pprint.pprint(self.run_txt_data, stream=f, indent=4, width=200, compact=False)\n            self.has_closed = True\n\n            # detach the global singleton\n            global _run_context\n            if _run_context is self:\n                _run_context = None\n\n    @staticmethod\n    def get():\n        import dnnlib\n        if _run_context is not None:\n            return _run_context\n        return RunContext(dnnlib.submit_config)\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/submission/submit.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Submit a function to be run either locally or in a computing cluster.\"\"\"\n\nimport copy\nimport inspect\nimport os\nimport pathlib\nimport pickle\nimport platform\nimport pprint\nimport re\nimport shutil\nimport sys\nimport time\nimport traceback\nimport threading\nimport dnnlib.tflib as tflib\nimport tflex\nimport tensorflow as tf\n\nfrom enum import Enum\n\nfrom .. import util\nfrom ..util import EasyDict\n\nfrom . import internal\n\nclass SubmitTarget(Enum):\n    \"\"\"The target where the function should be run.\n\n    LOCAL: Run it locally.\n    \"\"\"\n    LOCAL = 1\n\n\nclass PathType(Enum):\n    \"\"\"Determines in which format should a path be formatted.\n\n    WINDOWS: Format with Windows style.\n    LINUX: Format with Linux/Posix style.\n    AUTO: Use current OS type to select either WINDOWS or LINUX.\n    \"\"\"\n    WINDOWS = 1\n    LINUX = 2\n    AUTO = 3\n\n\nclass PlatformExtras:\n    \"\"\"A mixed bag of values used by dnnlib heuristics.\n\n    Attributes:\n\n        data_reader_buffer_size: Used by DataReader to size internal shared memory buffers.\n        data_reader_process_count: Number of worker processes to spawn (zero for single thread operation)\n    \"\"\"\n    def __init__(self):\n        self.data_reader_buffer_size = 1<<30    # 1 GB\n        self.data_reader_process_count = 0      # single threaded default\n\n\n_user_name_override = None\n\nclass SubmitConfig(util.EasyDict):\n    \"\"\"Strongly typed config dict needed to submit runs.\n\n    Attributes:\n        run_dir_root: Path to the run dir root. Can be optionally templated with tags. Needs to always be run through get_path_from_template.\n        run_desc: Description of the run. Will be used in the run dir and task name.\n        run_dir_ignore: List of file patterns used to ignore files when copying files to the run dir.\n        run_dir_extra_files: List of (abs_path, rel_path) tuples of file paths. rel_path root will be the src directory inside the run dir.\n        submit_target: Submit target enum value. Used to select where the run is actually launched.\n        num_gpus: Number of GPUs used/requested for the run.\n        print_info: Whether to print debug information when submitting.\n        local.do_not_copy_source_files: Do not copy source files from the working directory to the run dir.\n        run_id: Automatically populated value during submit.\n        run_name: Automatically populated value during submit.\n        run_dir: Automatically populated value during submit.\n        run_func_name: Automatically populated value during submit.\n        run_func_kwargs: Automatically populated value during submit.\n        user_name: Automatically populated value during submit. Can be set by the user which will then override the automatic value.\n        task_name: Automatically populated value during submit.\n        host_name: Automatically populated value during submit.\n        platform_extras: Automatically populated values during submit.  Used by various dnnlib libraries such as the DataReader class.\n    \"\"\"\n\n    def __init__(self):\n        super().__init__()\n\n        # run (set these)\n        self.run_dir_root = \"\"  # should always be passed through get_path_from_template\n        self.run_desc = \"\"\n        self.run_dir_ignore = [\"__pycache__\", \"*.pyproj\", \"*.sln\", \"*.suo\", \".cache\", \".idea\", \".vs\", \".vscode\", \"_cudacache\"]\n        self.run_dir_extra_files = []\n\n        # submit (set these)\n        self.submit_target = SubmitTarget.LOCAL\n        self.num_gpus = 1\n        self.print_info = False\n        self.nvprof = False\n        self.local = internal.local.TargetOptions()\n        self.datasets = []\n\n        # (automatically populated)\n        self.run_id = None\n        self.run_name = None\n        self.run_dir = None\n        self.run_func_name = None\n        self.run_func_kwargs = None\n        self.user_name = None\n        self.task_name = None\n        self.host_name = \"localhost\"\n        self.platform_extras = PlatformExtras()\n\n\ndef get_path_from_template(path_template: str, path_type: PathType = PathType.AUTO) -> str:\n    \"\"\"Replace tags in the given path template and return either Windows or Linux formatted path.\"\"\"\n    if path_template.startswith('gs://'):\n      return path_template\n    # automatically select path type depending on running OS\n    if path_type == PathType.AUTO:\n        if platform.system() == \"Windows\":\n            path_type = PathType.WINDOWS\n        else:\n            path_type = PathType.LINUX\n\n    path_template = path_template.replace(\"<USERNAME>\", get_user_name())\n\n    # return correctly formatted path\n    if path_type == PathType.WINDOWS:\n        return str(pathlib.PureWindowsPath(path_template))\n    elif path_type == PathType.LINUX:\n        return str(pathlib.PurePosixPath(path_template))\n    else:\n        raise RuntimeError(\"Unknown platform\")\n\n\ndef get_template_from_path(path: str) -> str:\n    \"\"\"Convert a normal path back to its template representation.\"\"\"\n    path = path.replace(\"\\\\\", \"/\")\n    return path\n\n\ndef convert_path(path: str, path_type: PathType = PathType.AUTO) -> str:\n    \"\"\"Convert a normal path to template and the convert it back to a normal path with given path type.\"\"\"\n    path_template = get_template_from_path(path)\n    path = get_path_from_template(path_template, path_type)\n    return path\n\n\ndef set_user_name_override(name: str) -> None:\n    \"\"\"Set the global username override value.\"\"\"\n    global _user_name_override\n    _user_name_override = name\n\n\ndef get_user_name():\n    \"\"\"Get the current user name.\"\"\"\n    if _user_name_override is not None:\n        return _user_name_override\n    elif platform.system() == \"Windows\":\n        return os.getlogin()\n    else:\n        try:\n            import pwd # pylint: disable=import-error\n            return pwd.getpwuid(os.geteuid()).pw_name # pylint: disable=no-member\n        except:\n            return \"unknown\"\n\ndef make_run_dir_path(*paths):\n    \"\"\"Make a path/filename that resides under the current submit run_dir.\n\n    Args:\n        *paths: Path components to be passed to os.path.join\n\n    Returns:\n        A file/dirname rooted at submit_config.run_dir.  If there's no\n        submit_config or run_dir, the base directory is the current\n        working directory.\n\n    E.g., `os.path.join(dnnlib.submit_config.run_dir, \"output.txt\"))`\n    \"\"\"\n    import dnnlib\n    if (dnnlib.submit_config is None) or (dnnlib.submit_config.run_dir is None):\n        return os.path.join(os.getcwd(), *paths)\n    return os.path.join(dnnlib.submit_config.run_dir, *paths)\n\n\ndef _create_run_dir_local(submit_config: SubmitConfig) -> str:\n    \"\"\"Create a new run dir with increasing ID number at the start.\"\"\"\n    run_dir_root = get_path_from_template(submit_config.run_dir_root, PathType.AUTO)\n\n    if not os.path.exists(run_dir_root):\n        os.makedirs(run_dir_root)\n\n    submit_config.run_id = _get_next_run_id_local(run_dir_root)\n    submit_config.run_name = \"{0:05d}-{1}\".format(submit_config.run_id, submit_config.run_desc)\n    run_dir = os.path.join(run_dir_root, submit_config.run_name)\n\n    if os.path.exists(run_dir):\n        raise RuntimeError(\"The run dir already exists! ({0})\".format(run_dir))\n\n    os.makedirs(run_dir)\n\n    return run_dir\n\n\ndef _get_next_run_id_local(run_dir_root: str) -> int:\n    \"\"\"Reads all directory names in a given directory (non-recursive) and returns the next (increasing) run id. Assumes IDs are numbers at the start of the directory names.\"\"\"\n    dir_names = [d for d in os.listdir(run_dir_root) if os.path.isdir(os.path.join(run_dir_root, d))]\n    r = re.compile(\"^\\\\d+\")  # match one or more digits at the start of the string\n    run_id = 0\n\n    for dir_name in dir_names:\n        m = r.match(dir_name)\n\n        if m is not None:\n            i = int(m.group())\n            run_id = max(run_id, i + 1)\n\n    return run_id\n\n\ndef _populate_run_dir(submit_config: SubmitConfig, run_dir: str) -> None:\n    \"\"\"Copy all necessary files into the run dir. Assumes that the dir exists, is local, and is writable.\"\"\"\n    pickle.dump(submit_config, open(os.path.join(run_dir, \"submit_config.pkl\"), \"wb\"))\n    with open(os.path.join(run_dir, \"submit_config.txt\"), \"w\") as f:\n        pprint.pprint(submit_config, stream=f, indent=4, width=200, compact=False)\n\n    if (submit_config.submit_target == SubmitTarget.LOCAL) and submit_config.local.do_not_copy_source_files:\n        return\n\n    files = []\n\n    run_func_module_dir_path = util.get_module_dir_by_obj_name(submit_config.run_func_name)\n    assert '.' in submit_config.run_func_name\n    for _idx in range(submit_config.run_func_name.count('.') - 1):\n        run_func_module_dir_path = os.path.dirname(run_func_module_dir_path)\n    files += util.list_dir_recursively_with_ignore(run_func_module_dir_path, ignores=submit_config.run_dir_ignore, add_base_to_relative=False)\n\n    dnnlib_module_dir_path = util.get_module_dir_by_obj_name(\"dnnlib\")\n    files += util.list_dir_recursively_with_ignore(dnnlib_module_dir_path, ignores=submit_config.run_dir_ignore, add_base_to_relative=True)\n\n    files += submit_config.run_dir_extra_files\n\n    files = [(f[0], os.path.join(run_dir, \"src\", f[1])) for f in files]\n    files += [(os.path.join(dnnlib_module_dir_path, \"submission\", \"internal\", \"run.py\"), os.path.join(run_dir, \"run.py\"))]\n\n    util.copy_files_and_create_dirs(files)\n\n\n\ndef run_wrapper(submit_config: SubmitConfig) -> None:\n    \"\"\"Wrap the actual run function call for handling logging, exceptions, typing, etc.\"\"\"\n    is_local = submit_config.submit_target == SubmitTarget.LOCAL\n\n    # when running locally, redirect stderr to stdout, log stdout to a file, and force flushing\n    if is_local:\n        logger = util.Logger(file_name=os.path.join(submit_config.run_dir, \"log.txt\"), file_mode=\"w\", should_flush=True)\n    else:  # when running in a cluster, redirect stderr to stdout, and just force flushing (log writing is handled by run.sh)\n        logger = util.Logger(file_name=None, should_flush=True)\n\n    import dnnlib\n    dnnlib.submit_config = submit_config\n\n    exit_with_errcode = False\n    try:\n        print(\"dnnlib: Running {0}() on {1}...\".format(submit_config.run_func_name, submit_config.host_name))\n        start_time = time.time()\n\n        run_func_obj = util.get_obj_by_name(submit_config.run_func_name)\n        assert callable(run_func_obj)\n        def thunk():\n            sig = inspect.signature(run_func_obj)\n            if 'submit_config' in sig.parameters:\n                run_func_obj(submit_config=submit_config, **submit_config.run_func_kwargs)\n            else:\n                run_func_obj(**submit_config.run_func_kwargs)\n\n        kws = submit_config.run_func_kwargs\n        tf_config = kws['tf_config'] if 'tf_config' in kws else {}\n        if 'TPU_NAME' not in os.environ or 'NO_SWARM' in os.environ:\n            tflib.init_tf(tf_config)\n            thunk()\n        else:\n            threads = []\n            tflex.trainers = []\n            tpu_core_count = 1 if 'TPU_CORE_COUNT' not in os.environ else int(os.environ['TPU_CORE_COUNT'])\n            tpu_core_offset = 0 if 'TPU_CORE_OFFSET' not in os.environ else int(os.environ['TPU_CORE_OFFSET'])\n            for i in range(tpu_core_count):\n                def worker(i):\n                    _id = i + tpu_core_offset\n                    spec = '#%d' % _id\n                    print(spec, 'Initializing...')\n                    tflib.init_tf(tf_config)\n                    sess = tf.get_default_session()\n                    cores = tflex.get_cores()[tpu_core_offset:tpu_core_offset+tpu_core_count]\n                    sess.id = _id\n                    tflex.trainers.append(sess)\n                    if False:\n                      tflex.set_override_device(cores[i])\n                      with tf.device(cores[i]):\n                          print(spec, 'Running thunk...')\n                          thunk()\n                    else:\n                      tflex.set_override_cores(cores)\n                      print(spec, 'Running thunk...')\n                      thunk()\n                if tpu_core_count <= 1:\n                  worker(i)\n                else:\n                  thread = threading.Thread(target=worker, args=(i,))\n                  threads.append(thread)\n                  thread.start()\n            for thread in threads:\n                thread.join()\n\n        print(\"dnnlib: Finished {0}() in {1}.\".format(submit_config.run_func_name, util.format_time(time.time() - start_time)))\n    except:\n        if is_local:\n            raise\n        else:\n            traceback.print_exc()\n\n            log_src = os.path.join(submit_config.run_dir, \"log.txt\")\n            log_dst = os.path.join(get_path_from_template(submit_config.run_dir_root), \"{0}-error.txt\".format(submit_config.run_name))\n            shutil.copyfile(log_src, log_dst)\n\n            # Defer sys.exit(1) to happen after we close the logs and create a _finished.txt\n            exit_with_errcode = True\n    finally:\n        open(os.path.join(submit_config.run_dir, \"_finished.txt\"), \"w\").close()\n\n    dnnlib.RunContext.get().close()\n    dnnlib.submit_config = None\n    logger.close()\n\n    # If we hit an error, get out of the script now and signal the error\n    # to whatever process that started this script.\n    if exit_with_errcode:\n        sys.exit(1)\n\n    return submit_config\n\n\ndef submit_run(submit_config: SubmitConfig, run_func_name: str, **run_func_kwargs) -> None:\n    \"\"\"Create a run dir, gather files related to the run, copy files to the run dir, and launch the run in appropriate place.\"\"\"\n    submit_config = copy.deepcopy(submit_config)\n\n    submit_target = submit_config.submit_target\n    farm = None\n    if submit_target == SubmitTarget.LOCAL:\n        farm = internal.local.Target()\n    assert farm is not None # unknown target\n\n    # Disallow submitting jobs with zero num_gpus.\n    if (submit_config.num_gpus is None) or (submit_config.num_gpus == 0):\n        raise RuntimeError(\"submit_config.num_gpus must be set to a non-zero value\")\n\n    if submit_config.user_name is None:\n        submit_config.user_name = get_user_name()\n\n    submit_config.run_func_name = run_func_name\n    submit_config.run_func_kwargs = run_func_kwargs\n\n    #--------------------------------------------------------------------\n    # Prepare submission by populating the run dir\n    #--------------------------------------------------------------------\n    host_run_dir = _create_run_dir_local(submit_config)\n\n    submit_config.task_name = \"{0}-{1:05d}-{2}\".format(submit_config.user_name, submit_config.run_id, submit_config.run_desc)\n    docker_valid_name_regex = \"^[a-zA-Z0-9][a-zA-Z0-9_.-]+$\"\n    if not re.match(docker_valid_name_regex, submit_config.task_name):\n        raise RuntimeError(\"Invalid task name.  Probable reason: unacceptable characters in your submit_config.run_desc.  Task name must be accepted by the following regex: \" + docker_valid_name_regex + \", got \" + submit_config.task_name)\n\n    # Farm specific preparations for a submit\n    farm.finalize_submit_config(submit_config, host_run_dir)\n    _populate_run_dir(submit_config, host_run_dir)\n    return farm.submit(submit_config, host_run_dir)\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/tflib/__init__.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\nfrom . import autosummary\nfrom . import network\nfrom . import optimizer\nfrom . import tfutil\nfrom . import custom_ops\n\nfrom .tfutil import *\nfrom .network import Network\n\nfrom .optimizer import Optimizer\n\nfrom .custom_ops import get_plugin\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/tflib/autosummary.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Helper for adding automatically tracked values to Tensorboard.\n\nAutosummary creates an identity op that internally keeps track of the input\nvalues and automatically shows up in TensorBoard. The reported value\nrepresents an average over input components. The average is accumulated\nconstantly over time and flushed when save_summaries() is called.\n\nNotes:\n- The output tensor must be used as an input for something else in the\n  graph. Otherwise, the autosummary op will not get executed, and the average\n  value will not get accumulated.\n- It is perfectly fine to include autosummaries with the same name in\n  several places throughout the graph, even if they are executed concurrently.\n- It is ok to also pass in a python scalar or numpy array. In this case, it\n  is added to the average immediately.\n\"\"\"\n\nfrom collections import OrderedDict\nimport numpy as np\nimport tensorflow as tf\nimport tflex\nfrom tensorboard import summary as summary_lib\nfrom tensorboard.plugins.custom_scalar import layout_pb2\n\nfrom . import tfutil\nfrom .tfutil import TfExpression\nfrom .tfutil import TfExpressionEx\n\n# Enable \"Custom scalars\" tab in TensorBoard for advanced formatting.\n# Disabled by default to reduce tfevents file size.\nenable_custom_scalars = False\n\n_dtype = tf.float64\n_vars = OrderedDict()  # name => [var, ...]\n_immediate = OrderedDict()  # name => update_op, update_value\n_finalized = False\n_merge_op = None\n\n\ndef _create_var(name: str, value_expr: TfExpression) -> TfExpression:\n    \"\"\"Internal helper for creating autosummary accumulators.\"\"\"\n    assert not _finalized\n    name_id = name.replace(\"/\", \"_\")\n    v = tf.cast(value_expr, _dtype)\n\n    if v.shape.is_fully_defined():\n        size = np.prod(v.shape.as_list())\n        size_expr = tf.constant(size, dtype=_dtype)\n    else:\n        size = None\n        size_expr = tf.reduce_prod(tf.cast(tf.shape(v), _dtype))\n\n    if size == 1:\n        if v.shape.ndims != 0:\n            v = tf.reshape(v, [])\n        v = [size_expr, v, tf.square(v)]\n    else:\n        v = [size_expr, tf.reduce_sum(v), tf.reduce_sum(tf.square(v))]\n    v = tf.cond(tf.is_finite(v[1]), lambda: tf.stack(v), lambda: tf.zeros(3, dtype=_dtype))\n\n    with tfutil.absolute_name_scope(\"Autosummary/\" + name_id), tf.control_dependencies(None):\n        var = tf.Variable(tf.zeros(3, dtype=_dtype), trainable=False)  # [sum(1), sum(x), sum(x**2)]\n    update_op = tf.cond(tf.is_variable_initialized(var), lambda: tf.assign_add(var, v), lambda: tf.assign(var, v))\n\n    if name in _vars:\n        _vars[name].append(var)\n    else:\n        _vars[name] = [var]\n    return update_op\n\nimport os\nfrom . import tpu_summaries\n\ntpu_summary = None\n\ndef get_tpu_summary(model_dir=None):\n    global tpu_summary\n    if tpu_summary is None:\n        if model_dir is None:\n            model_dir = os.path.join(os.environ['MODEL_DIR'], 'autosummary')\n        tpu_summary = tpu_summaries.TpuSummaries(model_dir)\n    else:\n        assert model_dir is None\n    return tpu_summary\n\n# TODO(joelshor): Make this a special case of `image_reshaper`.\ndef image_grid(input_tensor, grid_shape, image_shape=(32, 32), num_channels=3):\n  \"\"\"Arrange a minibatch of images into a grid to form a single image.\n\n  Args:\n    input_tensor: Tensor. Minibatch of images to format, either 4D\n        ([batch size, height, width, num_channels]) or flattened\n        ([batch size, height * width * num_channels]).\n    grid_shape: Sequence of int. The shape of the image grid,\n        formatted as [grid_height, grid_width].\n    image_shape: Sequence of int. The shape of a single image,\n        formatted as [image_height, image_width].\n    num_channels: int. The number of channels in an image.\n\n  Returns:\n    Tensor representing a single image in which the input images have been\n    arranged into a grid.\n\n  Raises:\n    ValueError: The grid shape and minibatch size don't match, or the image\n        shape and number of channels are incompatible with the input tensor.\n  \"\"\"\n  if grid_shape[0] * grid_shape[1] != int(input_tensor.shape[0]):\n    raise ValueError(\"Grid shape %s incompatible with minibatch size %i.\" %\n                     (grid_shape, int(input_tensor.shape[0])))\n  if len(input_tensor.shape) == 2:\n    num_features = image_shape[0] * image_shape[1] * num_channels\n    if int(input_tensor.shape[1]) != num_features:\n      raise ValueError(\"Image shape and number of channels incompatible with \"\n                       \"input tensor.\")\n  elif len(input_tensor.shape) == 4:\n    if (int(input_tensor.shape[1]) != image_shape[0] or\n        int(input_tensor.shape[2]) != image_shape[1] or\n        int(input_tensor.shape[3]) != num_channels):\n      raise ValueError(\"Image shape and number of channels incompatible with \"\n                       \"input tensor. %s vs %s\" % (\n                           input_tensor.shape, (image_shape[0], image_shape[1],\n                                                num_channels)))\n  else:\n    raise ValueError(\"Unrecognized input tensor format.\")\n  height, width = grid_shape[0] * image_shape[0], grid_shape[1] * image_shape[1]\n  input_tensor = tf.reshape(\n      input_tensor, tuple(grid_shape) + tuple(image_shape) + (num_channels,))\n  input_tensor = tf.transpose(a=input_tensor, perm=[0, 1, 3, 2, 4])\n  input_tensor = tf.reshape(\n      input_tensor, [grid_shape[0], width, image_shape[0], num_channels])\n  input_tensor = tf.transpose(a=input_tensor, perm=[0, 2, 1, 3])\n  input_tensor = tf.reshape(input_tensor, [1, height, width, num_channels])\n  return input_tensor\n\nnum_replicas = None\n\ndef get_num_replicas():\n    assert num_replicas is not None\n    return num_replicas\n\ndef set_num_replicas(n):\n    global num_replicas\n    num_replicas = n\n\ndef _i(x): return tf.transpose(x, [0, 2, 3, 1])\ndef _o(x): return tf.transpose(x, [0, 3, 1, 2])\n\ndef autoimages(summary_name, images, grid_shape=None, res=None):\n    \"\"\"Called from model_fn() to add a grid of images as summary.\"\"\"\n    # convert from [batch, channels, width, height] to [batch, width, height, channels]\n    images = _i(images)\n    # All summary tensors are synced to host 0 on every step. To avoid sending\n    # more images then needed we transfer at most `sampler_per_replica` to\n    # create a 8x8 image grid.\n    batch_size_per_replica = images.shape[0].value\n    num_replicas = get_num_replicas()\n    total_num_images = batch_size_per_replica * num_replicas\n    if callable(grid_shape):\n        grid_shape = grid_shape(total_num_images)\n    if grid_shape is None:\n        w = int(os.environ['GRID_WIDTH']) if 'GRID_WIDTH' in os.environ else 3\n        h = int(os.environ['GRID_HEIGHT']) if 'GRID_HEIGHT' in os.environ else 3\n        grid_shape = (w, h)\n    sample_num_images = np.prod(grid_shape)\n    if total_num_images >= sample_num_images:\n        # This can be more than 64. We slice all_images below.\n        samples_per_replica = int(np.ceil(sample_num_images / num_replicas))\n    else:\n        samples_per_replica = batch_size_per_replica\n    if res is None:\n        res = int(os.environ['RESOLUTION']) if 'RESOLUTION' in os.environ else 64\n    num_channels = int(os.environ[\"NUM_CHANNELS\"]) if \"NUM_CHANNELS\" in os.environ else 3\n    image_shape = [res, res, num_channels]\n    sample_res = int(os.environ['GRID_RESOLUTION']) if 'GRID_RESOLUTION' in os.environ else 200\n    sample_shape = [sample_res, sample_res, num_channels]\n    tf.logging.info(\"autoimages(%s, %s): Creating %dx%d images grid at resolution %dx%d channel count %d across %d replicas\",\n                    repr(summary_name), repr(images),\n                    grid_shape[0], grid_shape[1], image_shape[0], image_shape[1], image_shape[2],\n                    num_replicas)\n    images = images[:samples_per_replica]\n\n    def _merge_images_to_grid(all_images):\n        all_images = all_images[:np.prod(grid_shape)]\n        shape = image_shape\n        if shape[0] > sample_shape[0] or shape[1] > sample_shape[1]:\n            tf.logging.info('autoimages(%s, %s): Downscaling sampled images from %dx%d to %dx%d',\n                            repr(summary_name), repr(all_images),\n                            shape[0], shape[1],\n                            sample_shape[0], sample_shape[1])\n            all_images = tf.image.resize(all_images, sample_shape[0:2], method=tf.image.ResizeMethod.AREA)\n            shape = sample_shape\n        return image_grid(\n            all_images,\n            grid_shape=grid_shape,\n            image_shape=shape[:2],\n            num_channels=shape[2])\n    get_tpu_summary().image(summary_name,\n                            images,\n                            reduce_fn=_merge_images_to_grid)\n\ndef autosummary(name: str, value: TfExpressionEx, passthru: TfExpressionEx = None, condition: TfExpressionEx = True) -> TfExpressionEx:\n    \"\"\"Create a new autosummary.\n\n    Args:\n        name:     Name to use in TensorBoard\n        value:    TensorFlow expression or python value to track\n        passthru: Optionally return this TF node without modifications but tack an autosummary update side-effect to this node.\n\n    Example use of the passthru mechanism:\n\n    n = autosummary('l2loss', loss, passthru=n)\n\n    This is a shorthand for the following code:\n\n    with tf.control_dependencies([autosummary('l2loss', loss)]):\n        n = tf.identity(n)\n    \"\"\"\n    tf.logging.info('autosummary(%s, %s)', repr(name), repr(value))\n    get_tpu_summary().scalar(name, value)\n    return value\n    tfutil.assert_tf_initialized()\n    name_id = name.replace(\"/\", \"_\")\n\n    if tfutil.is_tf_expression(value):\n        with tf.name_scope(\"summary_\" + name_id), tflex.device(value.device):\n            condition = tf.convert_to_tensor(condition, name='condition')\n            update_op = tf.cond(condition, lambda: tf.group(_create_var(name, value)), tf.no_op)\n            with tf.control_dependencies([update_op]):\n                return tf.identity(value if passthru is None else passthru)\n\n    else:  # python scalar or numpy array\n        assert not tfutil.is_tf_expression(passthru)\n        assert not tfutil.is_tf_expression(condition)\n        if condition:\n            if name not in _immediate:\n                with tfutil.absolute_name_scope(\"Autosummary/\" + name_id), tflex.device(None), tf.control_dependencies(None):\n                    update_value = tf.placeholder(_dtype)\n                    update_op = _create_var(name, update_value)\n                    _immediate[name] = update_op, update_value\n            update_op, update_value = _immediate[name]\n            tfutil.run(update_op, {update_value: value})\n        return value if passthru is None else passthru\n\n\ndef finalize_autosummaries() -> None:\n    \"\"\"Create the necessary ops to include autosummaries in TensorBoard report.\n    Note: This should be done only once per graph.\n    \"\"\"\n    global _finalized\n    tfutil.assert_tf_initialized()\n\n    if _finalized:\n        return None\n\n    _finalized = True\n    tfutil.init_uninitialized_vars([var for vars_list in _vars.values() for var in vars_list])\n\n    # Create summary ops.\n    with tflex.device(None), tf.control_dependencies(None):\n        for name, vars_list in _vars.items():\n            name_id = name.replace(\"/\", \"_\")\n            with tfutil.absolute_name_scope(\"Autosummary/\" + name_id):\n                moments = tf.add_n(vars_list)\n                moments /= moments[0]\n                with tf.control_dependencies([moments]):  # read before resetting\n                    reset_ops = [tf.assign(var, tf.zeros(3, dtype=_dtype)) for var in vars_list]\n                    with tf.name_scope(None), tf.control_dependencies(reset_ops):  # reset before reporting\n                        mean = moments[1]\n                        std = tf.sqrt(moments[2] - tf.square(moments[1]))\n                        tf.summary.scalar(name, mean)\n                        if enable_custom_scalars:\n                            tf.summary.scalar(\"xCustomScalars/\" + name + \"/margin_lo\", mean - std)\n                            tf.summary.scalar(\"xCustomScalars/\" + name + \"/margin_hi\", mean + std)\n\n    # Setup layout for custom scalars.\n    layout = None\n    if enable_custom_scalars:\n        cat_dict = OrderedDict()\n        for series_name in sorted(_vars.keys()):\n            p = series_name.split(\"/\")\n            cat = p[0] if len(p) >= 2 else \"\"\n            chart = \"/\".join(p[1:-1]) if len(p) >= 3 else p[-1]\n            if cat not in cat_dict:\n                cat_dict[cat] = OrderedDict()\n            if chart not in cat_dict[cat]:\n                cat_dict[cat][chart] = []\n            cat_dict[cat][chart].append(series_name)\n        categories = []\n        for cat_name, chart_dict in cat_dict.items():\n            charts = []\n            for chart_name, series_names in chart_dict.items():\n                series = []\n                for series_name in series_names:\n                    series.append(layout_pb2.MarginChartContent.Series(\n                        value=series_name,\n                        lower=\"xCustomScalars/\" + series_name + \"/margin_lo\",\n                        upper=\"xCustomScalars/\" + series_name + \"/margin_hi\"))\n                margin = layout_pb2.MarginChartContent(series=series)\n                charts.append(layout_pb2.Chart(title=chart_name, margin=margin))\n            categories.append(layout_pb2.Category(title=cat_name, chart=charts))\n        layout = summary_lib.custom_scalar_pb(layout_pb2.Layout(category=categories))\n    return layout\n\ndef save_summaries(file_writer, global_step=None):\n    \"\"\"Call FileWriter.add_summary() with all summaries in the default graph,\n    automatically finalizing and merging them on the first call.\n    \"\"\"\n    return\n    global _merge_op\n    tfutil.assert_tf_initialized()\n\n    if _merge_op is None:\n        layout = finalize_autosummaries()\n        if layout is not None:\n            file_writer.add_summary(layout)\n        with tflex.device(None), tf.control_dependencies(None):\n            _merge_op = tf.summary.merge_all()\n\n    if _merge_op is not None:\n        file_writer.add_summary(_merge_op.eval(), global_step)\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/tflib/custom_ops.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"TensorFlow custom ops builder.\n\"\"\"\n\nimport os\nimport re\nimport uuid\nimport hashlib\nimport tempfile\nimport shutil\nimport tensorflow as tf\nfrom tensorflow.python.client import device_lib # pylint: disable=no-name-in-module\n\n#----------------------------------------------------------------------------\n# Global options.\n\ncuda_cache_path = os.path.join(os.path.dirname(__file__), '_cudacache')\ncuda_cache_version_tag = 'v1'\ndo_not_hash_included_headers = False # Speed up compilation by assuming that headers included by the CUDA code never change. Unsafe!\nverbose = True # Print status messages to stdout.\n\ncompiler_bindir_search_path = [\n    'C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.14.26428/bin/Hostx64/x64',\n    'C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.23.28105/bin/Hostx64/x64',\n    'C:/Program Files (x86)/Microsoft Visual Studio 14.0/vc/bin',\n]\n\n#----------------------------------------------------------------------------\n# Internal helper funcs.\n\ndef _find_compiler_bindir():\n    for compiler_path in compiler_bindir_search_path:\n        if os.path.isdir(compiler_path):\n            return compiler_path\n    return None\n\ndef _get_compute_cap(device):\n    caps_str = device.physical_device_desc\n    m = re.search('compute capability: (\\\\d+).(\\\\d+)', caps_str)\n    major = m.group(1)\n    minor = m.group(2)\n    return (major, minor)\n\ndef _get_cuda_gpu_arch_string():\n    gpus = [x for x in device_lib.list_local_devices() if x.device_type == 'GPU']\n    if len(gpus) == 0:\n        raise RuntimeError('No GPU devices found')\n    (major, minor) = _get_compute_cap(gpus[0])\n    return 'sm_%s%s' % (major, minor)\n\ndef _run_cmd(cmd):\n    with os.popen(cmd) as pipe:\n        output = pipe.read()\n        status = pipe.close()\n    if status is not None:\n        raise RuntimeError('NVCC returned an error. See below for full command line and output log:\\n\\n%s\\n\\n%s' % (cmd, output))\n\ndef _prepare_nvcc_cli(opts):\n    cmd = 'nvcc ' + opts.strip()\n    cmd += ' --disable-warnings'\n    cmd += ' --include-path \"%s\"' % tf.sysconfig.get_include()\n    cmd += ' --include-path \"%s\"' % os.path.join(tf.sysconfig.get_include(), 'external', 'protobuf_archive', 'src')\n    cmd += ' --include-path \"%s\"' % os.path.join(tf.sysconfig.get_include(), 'external', 'com_google_absl')\n    cmd += ' --include-path \"%s\"' % os.path.join(tf.sysconfig.get_include(), 'external', 'eigen_archive')\n\n    compiler_bindir = _find_compiler_bindir()\n    if compiler_bindir is None:\n        # Require that _find_compiler_bindir succeeds on Windows.  Allow\n        # nvcc to use whatever is the default on Linux.\n        if os.name == 'nt':\n            raise RuntimeError('Could not find MSVC/GCC/CLANG installation on this computer. Check compiler_bindir_search_path list in \"%s\".' % __file__)\n    else:\n        cmd += ' --compiler-bindir \"%s\"' % compiler_bindir\n    cmd += ' 2>&1'\n    return cmd\n\n#----------------------------------------------------------------------------\n# Main entry point.\n\n_plugin_cache = dict()\n\ndef get_plugin(cuda_file):\n    cuda_file_base = os.path.basename(cuda_file)\n    cuda_file_name, cuda_file_ext = os.path.splitext(cuda_file_base)\n\n    # Already in cache?\n    if cuda_file in _plugin_cache:\n        return _plugin_cache[cuda_file]\n\n    # Setup plugin.\n    if verbose:\n        print('Setting up TensorFlow plugin \"%s\": ' % cuda_file_base, end='', flush=True)\n    try:\n        # Hash CUDA source.\n        md5 = hashlib.md5()\n        with open(cuda_file, 'rb') as f:\n            md5.update(f.read())\n        md5.update(b'\\n')\n\n        # Hash headers included by the CUDA code by running it through the preprocessor.\n        if not do_not_hash_included_headers:\n            if verbose:\n                print('Preprocessing... ', end='', flush=True)\n            with tempfile.TemporaryDirectory() as tmp_dir:\n                tmp_file = os.path.join(tmp_dir, cuda_file_name + '_tmp' + cuda_file_ext)\n                _run_cmd(_prepare_nvcc_cli('\"%s\" --preprocess -o \"%s\" --keep --keep-dir \"%s\"' % (cuda_file, tmp_file, tmp_dir)))\n                with open(tmp_file, 'rb') as f:\n                    bad_file_str = ('\"' + cuda_file.replace('\\\\', '/') + '\"').encode('utf-8') # __FILE__ in error check macros\n                    good_file_str = ('\"' + cuda_file_base + '\"').encode('utf-8')\n                    for ln in f:\n                        if not ln.startswith(b'# ') and not ln.startswith(b'#line '): # ignore line number pragmas\n                            ln = ln.replace(bad_file_str, good_file_str)\n                            md5.update(ln)\n                    md5.update(b'\\n')\n\n        # Select compiler options.\n        compile_opts = ''\n        if os.name == 'nt':\n            compile_opts += '\"%s\"' % os.path.join(tf.sysconfig.get_lib(), 'python', '_pywrap_tensorflow_internal.lib')\n        elif os.name == 'posix':\n            compile_opts += '\"%s\"' % os.path.join(tf.sysconfig.get_lib(), 'python', '_pywrap_tensorflow_internal.so')\n            compile_opts += ' --compiler-options \\'-fPIC -D_GLIBCXX_USE_CXX11_ABI=0\\''\n        else:\n            assert False # not Windows or Linux, w00t?\n        compile_opts += ' --gpu-architecture=%s' % _get_cuda_gpu_arch_string()\n        compile_opts += ' --use_fast_math'\n        nvcc_cmd = _prepare_nvcc_cli(compile_opts)\n\n        # Hash build configuration.\n        md5.update(('nvcc_cmd: ' + nvcc_cmd).encode('utf-8') + b'\\n')\n        md5.update(('tf.VERSION: ' + tf.VERSION).encode('utf-8') + b'\\n')\n        md5.update(('cuda_cache_version_tag: ' + cuda_cache_version_tag).encode('utf-8') + b'\\n')\n\n        # Compile if not already compiled.\n        bin_file_ext = '.dll' if os.name == 'nt' else '.so'\n        bin_file = os.path.join(cuda_cache_path, cuda_file_name + '_' + md5.hexdigest() + bin_file_ext)\n        if not os.path.isfile(bin_file):\n            if verbose:\n                print('Compiling... ', end='', flush=True)\n            with tempfile.TemporaryDirectory() as tmp_dir:\n                tmp_file = os.path.join(tmp_dir, cuda_file_name + '_tmp' + bin_file_ext)\n                _run_cmd(nvcc_cmd + ' \"%s\" --shared -o \"%s\" --keep --keep-dir \"%s\"' % (cuda_file, tmp_file, tmp_dir))\n                os.makedirs(cuda_cache_path, exist_ok=True)\n                intermediate_file = os.path.join(cuda_cache_path, cuda_file_name + '_' + uuid.uuid4().hex + '_tmp' + bin_file_ext)\n                shutil.copyfile(tmp_file, intermediate_file)\n                os.rename(intermediate_file, bin_file) # atomic\n\n        # Load.\n        if verbose:\n            print('Loading... ', end='', flush=True)\n        plugin = tf.load_op_library(bin_file)\n\n        # Add to cache.\n        _plugin_cache[cuda_file] = plugin\n        if verbose:\n            print('Done.', flush=True)\n        return plugin\n\n    except:\n        if verbose:\n            print('Failed!', flush=True)\n        raise\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/tflib/network.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Helper for managing networks.\"\"\"\n\nimport types\nimport inspect\nimport re\nimport uuid\nimport sys\nimport numpy as np\nimport tensorflow as tf\nimport tflex\nimport threading\ntflex.network_lock = threading.RLock()\n\nfrom collections import OrderedDict\nfrom typing import Any, List, Tuple, Union\n\nfrom . import tfutil\nfrom .. import util\n\nfrom .tfutil import TfExpression, TfExpressionEx\n\n_import_handlers = []  # Custom import handlers for dealing with legacy data in pickle import.\n_import_module_src = dict()  # Source code for temporary modules created during pickle import.\n\n\ndef import_handler(handler_func):\n    \"\"\"Function decorator for declaring custom import handlers.\"\"\"\n    _import_handlers.append(handler_func)\n    return handler_func\n\n\nclass Network:\n    \"\"\"Generic network abstraction.\n\n    Acts as a convenience wrapper for a parameterized network construction\n    function, providing several utility methods and convenient access to\n    the inputs/outputs/weights.\n\n    Network objects can be safely pickled and unpickled for long-term\n    archival purposes. The pickling works reliably as long as the underlying\n    network construction function is defined in a standalone Python module\n    that has no side effects or application-specific imports.\n\n    Args:\n        name: Network name. Used to select TensorFlow name and variable scopes.\n        func_name: Fully qualified name of the underlying network construction function, or a top-level function object.\n        static_kwargs: Keyword arguments to be passed in to the network construction function.\n\n    Attributes:\n        name: User-specified name, defaults to build func name if None.\n        scope: Unique TensorFlow scope containing template graph and variables, derived from the user-specified name.\n        static_kwargs: Arguments passed to the user-supplied build func.\n        components: Container for sub-networks. Passed to the build func, and retained between calls.\n        num_inputs: Number of input tensors.\n        num_outputs: Number of output tensors.\n        input_shapes: Input tensor shapes (NC or NCHW), including minibatch dimension.\n        output_shapes: Output tensor shapes (NC or NCHW), including minibatch dimension.\n        input_shape: Short-hand for input_shapes[0].\n        output_shape: Short-hand for output_shapes[0].\n        input_templates: Input placeholders in the template graph.\n        output_templates: Output tensors in the template graph.\n        input_names: Name string for each input.\n        output_names: Name string for each output.\n        own_vars: Variables defined by this network (local_name => var), excluding sub-networks.\n        vars: All variables (local_name => var).\n        trainables: All trainable variables (local_name => var).\n        var_global_to_local: Mapping from variable global names to local names.\n    \"\"\"\n\n    def __init__(self, name: str = None, scope: str = None, func_name: Any = None, reset_own_vars = False, **static_kwargs):\n        tfutil.assert_tf_initialized()\n        assert isinstance(name, str) or name is None\n        assert func_name is not None\n        assert isinstance(func_name, str) or util.is_top_level_function(func_name)\n        assert util.is_pickleable(static_kwargs)\n\n        self._init_fields()\n        self.name = name\n        self.scope = scope\n        self.static_kwargs = util.EasyDict(static_kwargs)\n\n        # Locate the user-specified network build function.\n        if util.is_top_level_function(func_name):\n            func_name = util.get_top_level_function_name(func_name)\n        module, self._build_func_name = util.get_module_from_obj_name(func_name)\n        self._build_func = util.get_obj_from_module(module, self._build_func_name)\n        assert callable(self._build_func)\n\n        # Dig up source code for the module containing the build function.\n        self._build_module_src = _import_module_src.get(module, None)\n        if self._build_module_src is None:\n            self._build_module_src = inspect.getsource(module)\n\n        # Init TensorFlow graph.\n        self._init_graph()\n        if reset_own_vars:\n            self.ensure()\n\n    def ensure(self):\n        for k, v in self.components.items():\n            v.ensure()\n        if self._need_reset:\n            self.reset_own_vars()\n            self._need_reset = False\n        return self\n\n    def _init_fields(self) -> None:\n        self.name = None\n        self.scope = None\n        self.static_kwargs = util.EasyDict()\n        self.components = util.EasyDict()\n        self.num_inputs = 0\n        self.num_outputs = 0\n        self.input_shapes = [[]]\n        self.output_shapes = [[]]\n        self.input_shape = []\n        self.output_shape = []\n        self.input_templates = []\n        self.output_templates = []\n        self.input_names = []\n        self.output_names = []\n        self.own_vars = OrderedDict()\n        self.vars = OrderedDict()\n        self.trainables = OrderedDict()\n        self.var_global_to_local = OrderedDict()\n\n        self._build_func = None  # User-supplied build function that constructs the network.\n        self._build_func_name = None  # Name of the build function.\n        self._build_module_src = None  # Full source code of the module containing the build function.\n        self._run_cache = dict()  # Cached graph data for Network.run().\n        self._need_reset = True\n\n    def _init_graph(self) -> None:\n        with tflex.network_lock:\n            self._init_graph_()\n\n    def _init_graph_(self) -> None:\n        # Collect inputs.\n        self.input_names = []\n\n        for param in inspect.signature(self._build_func).parameters.values():\n            if param.kind == param.POSITIONAL_OR_KEYWORD and param.default is param.empty:\n                self.input_names.append(param.name)\n\n        self.num_inputs = len(self.input_names)\n        assert self.num_inputs >= 1\n\n        # Choose name and scope.\n        if self.name is None:\n            self.name = self._build_func_name\n        assert re.match(\"^[A-Za-z0-9_.\\\\-]*$\", self.name)\n        if self.scope is None:\n            with tf.name_scope(None):\n                self.scope = tf.get_default_graph().unique_name(self.name, mark_as_used=True)\n\n        # Finalize build func kwargs.\n        build_kwargs = dict(self.static_kwargs)\n        build_kwargs[\"is_template_graph\"] = True\n        build_kwargs[\"components\"] = self.components\n\n        # Build template graph.\n        with tfutil.absolute_variable_scope(self.scope, reuse=False), tfutil.absolute_name_scope(self.scope):  # ignore surrounding scopes\n            assert tf.get_variable_scope().name == self.scope\n            assert tf.get_default_graph().get_name_scope() == self.scope\n            with tf.control_dependencies(None):  # ignore surrounding control dependencies\n                self.input_templates = [tf.placeholder(tf.float32, name=name) for name in self.input_names]\n                out_expr = self._build_func(*self.input_templates, **build_kwargs)\n\n        # Collect outputs.\n        assert tfutil.is_tf_expression(out_expr) or isinstance(out_expr, tuple)\n        self.output_templates = [out_expr] if tfutil.is_tf_expression(out_expr) else list(out_expr)\n        self.num_outputs = len(self.output_templates)\n        assert self.num_outputs >= 1\n        assert all(tfutil.is_tf_expression(t) for t in self.output_templates)\n\n        # Perform sanity checks.\n        if any(t.shape.ndims is None for t in self.input_templates):\n            raise ValueError(\"Network input shapes not defined. Please call x.set_shape() for each input.\")\n        if any(t.shape.ndims is None for t in self.output_templates):\n            raise ValueError(\"Network output shapes not defined. Please call x.set_shape() where applicable.\")\n        if any(not isinstance(comp, Network) for comp in self.components.values()):\n            raise ValueError(\"Components of a Network must be Networks themselves.\")\n        if len(self.components) != len(set(comp.name for comp in self.components.values())):\n            raise ValueError(\"Components of a Network must have unique names.\")\n\n        # List inputs and outputs.\n        self.input_shapes = [t.shape.as_list() for t in self.input_templates]\n        self.output_shapes = [t.shape.as_list() for t in self.output_templates]\n        self.input_shape = self.input_shapes[0]\n        self.output_shape = self.output_shapes[0]\n        self.output_names = [t.name.split(\"/\")[-1].split(\":\")[0] for t in self.output_templates]\n\n        # List variables.\n        self.own_vars = OrderedDict((var.name[len(self.scope) + 1:].split(\":\")[0], var) for var in tf.global_variables(self.scope + \"/\"))\n        self.vars = OrderedDict(self.own_vars)\n        self.vars.update((comp.name + \"/\" + name, var) for comp in self.components.values() for name, var in comp.vars.items())\n        self.trainables = OrderedDict((name, var) for name, var in self.vars.items() if var.trainable)\n        self.var_global_to_local = OrderedDict((var.name.split(\":\")[0], name) for name, var in self.vars.items())\n\n    def reset_own_vars(self) -> None:\n        \"\"\"Re-initialize all variables of this network, excluding sub-networks.\"\"\"\n        tfutil.run([var.initializer for var in self.own_vars.values()])\n\n    def reset_vars(self) -> None:\n        \"\"\"Re-initialize all variables of this network, including sub-networks.\"\"\"\n        tfutil.run([var.initializer for var in self.vars.values()])\n\n    def reset_trainables(self) -> None:\n        \"\"\"Re-initialize all trainable variables of this network, including sub-networks.\"\"\"\n        tfutil.run([var.initializer for var in self.trainables.values()])\n\n    def get_output_for(self, *in_expr: TfExpression, return_as_list: bool = False, **dynamic_kwargs) -> Union[TfExpression, List[TfExpression]]:\n        \"\"\"Construct TensorFlow expression(s) for the output(s) of this network, given the input expression(s).\"\"\"\n        assert len(in_expr) == self.num_inputs\n        assert not all(expr is None for expr in in_expr)\n\n        # Finalize build func kwargs.\n        build_kwargs = dict(self.static_kwargs)\n        build_kwargs.update(dynamic_kwargs)\n        build_kwargs[\"is_template_graph\"] = False\n        build_kwargs[\"components\"] = self.components\n\n        # Build TensorFlow graph to evaluate the network.\n        with tfutil.absolute_variable_scope(self.scope, reuse=True), tf.name_scope(self.name):\n            assert tf.get_variable_scope().name == self.scope\n            valid_inputs = [expr for expr in in_expr if expr is not None]\n            final_inputs = []\n            for expr, name, shape in zip(in_expr, self.input_names, self.input_shapes):\n                if expr is not None:\n                    expr = tf.identity(expr, name=name)\n                else:\n                    expr = tf.zeros([tf.shape(valid_inputs[0])[0]] + shape[1:], name=name)\n                final_inputs.append(expr)\n            out_expr = self._build_func(*final_inputs, **build_kwargs)\n\n        # Propagate input shapes back to the user-specified expressions.\n        for expr, final in zip(in_expr, final_inputs):\n            if isinstance(expr, tf.Tensor):\n                expr.set_shape(final.shape)\n\n        # Express outputs in the desired format.\n        assert tfutil.is_tf_expression(out_expr) or isinstance(out_expr, tuple)\n        if return_as_list:\n            out_expr = [out_expr] if tfutil.is_tf_expression(out_expr) else list(out_expr)\n        return out_expr\n\n    def get_var_local_name(self, var_or_global_name: Union[TfExpression, str]) -> str:\n        \"\"\"Get the local name of a given variable, without any surrounding name scopes.\"\"\"\n        assert tfutil.is_tf_expression(var_or_global_name) or isinstance(var_or_global_name, str)\n        global_name = var_or_global_name if isinstance(var_or_global_name, str) else var_or_global_name.name\n        return self.var_global_to_local[global_name]\n\n    def find_var(self, var_or_local_name: Union[TfExpression, str]) -> TfExpression:\n        \"\"\"Find variable by local or global name.\"\"\"\n        assert tfutil.is_tf_expression(var_or_local_name) or isinstance(var_or_local_name, str)\n        return self.vars[var_or_local_name] if isinstance(var_or_local_name, str) else var_or_local_name\n\n    def get_var(self, var_or_local_name: Union[TfExpression, str]) -> np.ndarray:\n        \"\"\"Get the value of a given variable as NumPy array.\n        Note: This method is very inefficient -- prefer to use tflib.run(list_of_vars) whenever possible.\"\"\"\n        return self.find_var(var_or_local_name).eval()\n\n    def set_var(self, var_or_local_name: Union[TfExpression, str], new_value: Union[int, float, np.ndarray]) -> None:\n        \"\"\"Set the value of a given variable based on the given NumPy array.\n        Note: This method is very inefficient -- prefer to use tflib.set_vars() whenever possible.\"\"\"\n        tfutil.set_vars({self.find_var(var_or_local_name): new_value})\n\n    def __getstate__(self) -> dict:\n        \"\"\"Pickle export.\"\"\"\n        state = dict()\n        state[\"version\"]            = 4\n        state[\"name\"]               = self.name\n        state[\"static_kwargs\"]      = dict(self.static_kwargs)\n        state[\"components\"]         = dict(self.components)\n        state[\"build_module_src\"]   = self._build_module_src\n        state[\"build_func_name\"]    = self._build_func_name\n        state[\"variables\"]          = list(zip(self.own_vars.keys(), tfutil.run(list(self.own_vars.values()))))\n        return state\n\n    def __setstate__(self, state: dict) -> None:\n        \"\"\"Pickle import.\"\"\"\n        # pylint: disable=attribute-defined-outside-init\n        tfutil.assert_tf_initialized()\n        self._init_fields()\n\n        # Execute custom import handlers.\n        for handler in _import_handlers:\n            state = handler(state)\n\n        # Set basic fields.\n        assert state[\"version\"] in [2, 3, 4]\n        self.name = state[\"name\"]\n        self.static_kwargs = util.EasyDict(state[\"static_kwargs\"])\n        self.components = util.EasyDict(state.get(\"components\", {}))\n        self._build_module_src = state[\"build_module_src\"]\n        self._build_func_name = state[\"build_func_name\"]\n\n        # Create temporary module from the imported source code.\n        module_name = \"_tflib_network_import_\" + uuid.uuid4().hex\n        module = types.ModuleType(module_name)\n        sys.modules[module_name] = module\n        _import_module_src[module] = self._build_module_src\n        exec(self._build_module_src, module.__dict__) # pylint: disable=exec-used\n\n        # Locate network build function in the temporary module.\n        self._build_func = util.get_obj_from_module(module, self._build_func_name)\n        assert callable(self._build_func)\n\n        # Init TensorFlow graph.\n        self._init_graph()\n        self.reset_own_vars()\n        tfutil.set_vars({self.find_var(name): value for name, value in state[\"variables\"]})\n\n    def clone(self, name: str = None, **new_static_kwargs) -> \"Network\":\n        \"\"\"Create a clone of this network with its own copy of the variables.\"\"\"\n        net, finalize = self.clone2(name, **new_static_kwargs)\n        finalize()\n        return net\n\n    def clone2(self, name: str = None, **new_static_kwargs) -> (\"Network\", Any):\n        \"\"\"Create a clone of this network with its own copy of the variables.\"\"\"\n        # pylint: disable=protected-access\n        net = object.__new__(Network)\n        net._init_fields()\n        net.name = name if name is not None else self.name\n        net.static_kwargs = util.EasyDict(self.static_kwargs)\n        net.static_kwargs.update(new_static_kwargs)\n        net._build_module_src = self._build_module_src\n        net._build_func_name = self._build_func_name\n        net._build_func = self._build_func\n        net._init_graph()\n        def finalize():\n            with tflex.network_lock:\n                self.ensure()\n                net.ensure()\n                net.copy_vars_from(self)\n        return net, finalize\n\n    def copy_own_vars_from(self, src_net: \"Network\") -> None:\n        \"\"\"Copy the values of all variables from the given network, excluding sub-networks.\"\"\"\n        names = [name for name in self.own_vars.keys() if name in src_net.own_vars]\n        tfutil.set_vars({self.vars[name]: src_net.vars[name] for name in names})\n\n    def copy_vars_from(self, src_net: \"Network\") -> None:\n        \"\"\"Copy the values of all variables from the given network, including sub-networks.\"\"\"\n        names = [name for name in self.vars.keys() if name in src_net.vars]\n        tfutil.set_vars({self.vars[name]: src_net.vars[name] for name in names})\n\n    def copy_trainables_from(self, src_net: \"Network\") -> None:\n        \"\"\"Copy the values of all trainable variables from the given network, including sub-networks.\"\"\"\n        names = [name for name in self.trainables.keys() if name in src_net.trainables]\n        tfutil.set_vars({self.vars[name]: src_net.vars[name] for name in names})\n\n    def convert(self, new_func_name: str, new_name: str = None, **new_static_kwargs) -> \"Network\":\n        \"\"\"Create new network with the given parameters, and copy all variables from this network.\"\"\"\n        if new_name is None:\n            new_name = self.name\n        static_kwargs = dict(self.static_kwargs)\n        static_kwargs.update(new_static_kwargs)\n        net = Network(name=new_name, func_name=new_func_name, **static_kwargs)\n        net.copy_vars_from(self)\n        return net\n\n    def setup_as_moving_average_of(self, src_net: \"Network\", beta: TfExpressionEx = 0.99, beta_nontrainable: TfExpressionEx = 0.0) -> tf.Operation:\n        \"\"\"Construct a TensorFlow op that updates the variables of this network\n        to be slightly closer to those of the given network.\"\"\"\n        with tfutil.absolute_name_scope(self.scope + \"/_MovingAvg\"):\n            ops = []\n            for name, var in self.vars.items():\n                if name in src_net.vars:\n                    cur_beta = beta if name in self.trainables else beta_nontrainable\n                    new_value = tfutil.lerp(src_net.vars[name], var, cur_beta)\n                    ops.append(var.assign(new_value))\n            return tf.group(*ops)\n\n    def run(self,\n            *in_arrays: Tuple[Union[np.ndarray, None], ...],\n            input_transform: dict = None,\n            output_transform: dict = None,\n            return_as_list: bool = False,\n            print_progress: bool = False,\n            minibatch_size: int = None,\n            num_gpus: int = 1,\n            assume_frozen: bool = False,\n            **dynamic_kwargs) -> Union[np.ndarray, Tuple[np.ndarray, ...], List[np.ndarray]]:\n        \"\"\"Run this network for the given NumPy array(s), and return the output(s) as NumPy array(s).\n\n        Args:\n            input_transform:    A dict specifying a custom transformation to be applied to the input tensor(s) before evaluating the network.\n                                The dict must contain a 'func' field that points to a top-level function. The function is called with the input\n                                TensorFlow expression(s) as positional arguments. Any remaining fields of the dict will be passed in as kwargs.\n            output_transform:   A dict specifying a custom transformation to be applied to the output tensor(s) after evaluating the network.\n                                The dict must contain a 'func' field that points to a top-level function. The function is called with the output\n                                TensorFlow expression(s) as positional arguments. Any remaining fields of the dict will be passed in as kwargs.\n            return_as_list:     True = return a list of NumPy arrays, False = return a single NumPy array, or a tuple if there are multiple outputs.\n            print_progress:     Print progress to the console? Useful for very large input arrays.\n            minibatch_size:     Maximum minibatch size to use, None = disable batching.\n            num_gpus:           Number of GPUs to use.\n            assume_frozen:      Improve multi-GPU performance by assuming that the trainable parameters will remain changed between calls.\n            dynamic_kwargs:     Additional keyword arguments to be passed into the network build function.\n        \"\"\"\n        assert len(in_arrays) == self.num_inputs\n        assert not all(arr is None for arr in in_arrays)\n        assert input_transform is None or util.is_top_level_function(input_transform[\"func\"])\n        assert output_transform is None or util.is_top_level_function(output_transform[\"func\"])\n        output_transform, dynamic_kwargs = _handle_legacy_output_transforms(output_transform, dynamic_kwargs)\n        num_items = in_arrays[0].shape[0]\n        if minibatch_size is None:\n            minibatch_size = num_items\n\n        # Construct unique hash key from all arguments that affect the TensorFlow graph.\n        key = dict(input_transform=input_transform, output_transform=output_transform, num_gpus=num_gpus, assume_frozen=assume_frozen, dynamic_kwargs=dynamic_kwargs)\n        def unwind_key(obj):\n            if isinstance(obj, dict):\n                return [(key, unwind_key(value)) for key, value in sorted(obj.items())]\n            if callable(obj):\n                return util.get_top_level_function_name(obj)\n            return obj\n        key = repr(unwind_key(key))\n\n        # Build graph.\n        if key not in self._run_cache:\n            with tfutil.absolute_name_scope(self.scope + \"/_Run\"), tf.control_dependencies(None):\n                with tflex.device(\"/cpu:0\"):\n                    in_expr = [tf.placeholder(tf.float32, name=name) for name in self.input_names]\n                    in_split = list(zip(*[tf.split(x, num_gpus) for x in in_expr]))\n\n                out_split = []\n                for gpu in range(num_gpus):\n                    with tflex.device(\"/gpu:%d\" % gpu):\n                        net_gpu = self.clone() if assume_frozen else self\n                        in_gpu = in_split[gpu]\n\n                        if input_transform is not None:\n                            in_kwargs = dict(input_transform)\n                            in_gpu = in_kwargs.pop(\"func\")(*in_gpu, **in_kwargs)\n                            in_gpu = [in_gpu] if tfutil.is_tf_expression(in_gpu) else list(in_gpu)\n\n                        assert len(in_gpu) == self.num_inputs\n                        out_gpu = net_gpu.get_output_for(*in_gpu, return_as_list=True, **dynamic_kwargs)\n\n                        if output_transform is not None:\n                            out_kwargs = dict(output_transform)\n                            out_gpu = out_kwargs.pop(\"func\")(*out_gpu, **out_kwargs)\n                            out_gpu = [out_gpu] if tfutil.is_tf_expression(out_gpu) else list(out_gpu)\n\n                        assert len(out_gpu) == self.num_outputs\n                        out_split.append(out_gpu)\n\n                with tflex.device(\"/cpu:0\"):\n                    out_expr = [tf.concat(outputs, axis=0) for outputs in zip(*out_split)]\n                    self._run_cache[key] = in_expr, out_expr\n\n        # Run minibatches.\n        in_expr, out_expr = self._run_cache[key]\n        out_arrays = [np.empty([num_items] + expr.shape.as_list()[1:], expr.dtype.name) for expr in out_expr]\n\n        for mb_begin in range(0, num_items, minibatch_size):\n            if print_progress:\n                print(\"\\r%d / %d\" % (mb_begin, num_items), end=\"\")\n\n            mb_end = min(mb_begin + minibatch_size, num_items)\n            mb_num = mb_end - mb_begin\n            mb_in = [src[mb_begin : mb_end] if src is not None else np.zeros([mb_num] + shape[1:]) for src, shape in zip(in_arrays, self.input_shapes)]\n            mb_out = tf.get_default_session().run(out_expr, dict(zip(in_expr, mb_in)))\n\n            for dst, src in zip(out_arrays, mb_out):\n                dst[mb_begin: mb_end] = src\n\n        # Done.\n        if print_progress:\n            print(\"\\r%d / %d\" % (num_items, num_items))\n\n        if not return_as_list:\n            out_arrays = out_arrays[0] if len(out_arrays) == 1 else tuple(out_arrays)\n        return out_arrays\n\n    def list_ops(self) -> List[TfExpression]:\n        include_prefix = self.scope + \"/\"\n        exclude_prefix = include_prefix + \"_\"\n        ops = tf.get_default_graph().get_operations()\n        ops = [op for op in ops if op.name.startswith(include_prefix)]\n        ops = [op for op in ops if not op.name.startswith(exclude_prefix)]\n        return ops\n\n    def list_layers(self) -> List[Tuple[str, TfExpression, List[TfExpression]]]:\n        \"\"\"Returns a list of (layer_name, output_expr, trainable_vars) tuples corresponding to\n        individual layers of the network. Mainly intended to be used for reporting.\"\"\"\n        layers = []\n\n        def recurse(scope, parent_ops, parent_vars, level):\n            # Ignore specific patterns.\n            if any(p in scope for p in [\"/Shape\", \"/strided_slice\", \"/Cast\", \"/concat\", \"/Assign\"]):\n                return\n\n            # Filter ops and vars by scope.\n            global_prefix = scope + \"/\"\n            local_prefix = global_prefix[len(self.scope) + 1:]\n            cur_ops = [op for op in parent_ops if op.name.startswith(global_prefix) or op.name == global_prefix[:-1]]\n            cur_vars = [(name, var) for name, var in parent_vars if name.startswith(local_prefix) or name == local_prefix[:-1]]\n            if not cur_ops and not cur_vars:\n                return\n\n            # Filter out all ops related to variables.\n            for var in [op for op in cur_ops if op.type.startswith(\"Variable\")]:\n                var_prefix = var.name + \"/\"\n                cur_ops = [op for op in cur_ops if not op.name.startswith(var_prefix)]\n\n            # Scope does not contain ops as immediate children => recurse deeper.\n            contains_direct_ops = any(\"/\" not in op.name[len(global_prefix):] and op.type not in [\"Identity\", \"Cast\", \"Transpose\"] for op in cur_ops)\n            if (level == 0 or not contains_direct_ops) and (len(cur_ops) + len(cur_vars)) > 1:\n                visited = set()\n                for rel_name in [op.name[len(global_prefix):] for op in cur_ops] + [name[len(local_prefix):] for name, _var in cur_vars]:\n                    token = rel_name.split(\"/\")[0]\n                    if token not in visited:\n                        recurse(global_prefix + token, cur_ops, cur_vars, level + 1)\n                        visited.add(token)\n                return\n\n            # Report layer.\n            layer_name = scope[len(self.scope) + 1:]\n            layer_output = cur_ops[-1].outputs[0] if cur_ops else cur_vars[-1][1]\n            layer_trainables = [var for _name, var in cur_vars if var.trainable]\n            layers.append((layer_name, layer_output, layer_trainables))\n\n        recurse(self.scope, self.list_ops(), list(self.vars.items()), 0)\n        return layers\n\n    def print_layers(self, title: str = None, hide_layers_with_no_params: bool = False) -> None:\n        \"\"\"Print a summary table of the network structure.\"\"\"\n        rows = [[title if title is not None else self.name, \"Params\", \"OutputShape\", \"WeightShape\"]]\n        rows += [[\"---\"] * 4]\n        total_params = 0\n\n        for layer_name, layer_output, layer_trainables in self.list_layers():\n            num_params = sum(int(np.prod(var.shape.as_list())) for var in layer_trainables)\n            weights = [var for var in layer_trainables if var.name.endswith(\"/weight:0\")]\n            weights.sort(key=lambda x: len(x.name))\n            if len(weights) == 0 and len(layer_trainables) == 1:\n                weights = layer_trainables\n            total_params += num_params\n\n            if not hide_layers_with_no_params or num_params != 0:\n                num_params_str = str(num_params) if num_params > 0 else \"-\"\n                output_shape_str = str(layer_output.shape)\n                weight_shape_str = str(weights[0].shape) if len(weights) >= 1 else \"-\"\n                rows += [[layer_name, num_params_str, output_shape_str, weight_shape_str]]\n\n        rows += [[\"---\"] * 4]\n        rows += [[\"Total\", str(total_params), \"\", \"\"]]\n\n        widths = [max(len(cell) for cell in column) for column in zip(*rows)]\n        print()\n        for row in rows:\n            print(\"  \".join(cell + \" \" * (width - len(cell)) for cell, width in zip(row, widths)))\n        print()\n\n    def setup_weight_histograms(self, title: str = None) -> None:\n        \"\"\"Construct summary ops to include histograms of all trainable parameters in TensorBoard.\"\"\"\n        if title is None:\n            title = self.name\n\n        with tf.name_scope(None), tflex.device(None), tf.control_dependencies(None):\n            for local_name, var in self.trainables.items():\n                if \"/\" in local_name:\n                    p = local_name.split(\"/\")\n                    name = title + \"_\" + p[-1] + \"/\" + \"_\".join(p[:-1])\n                else:\n                    name = title + \"_toplevel/\" + local_name\n\n                tf.summary.histogram(name, var)\n\n#----------------------------------------------------------------------------\n# Backwards-compatible emulation of legacy output transformation in Network.run().\n\n_print_legacy_warning = True\n\ndef _handle_legacy_output_transforms(output_transform, dynamic_kwargs):\n    global _print_legacy_warning\n    legacy_kwargs = [\"out_mul\", \"out_add\", \"out_shrink\", \"out_dtype\"]\n    if not any(kwarg in dynamic_kwargs for kwarg in legacy_kwargs):\n        return output_transform, dynamic_kwargs\n\n    if _print_legacy_warning:\n        _print_legacy_warning = False\n        print()\n        print(\"WARNING: Old-style output transformations in Network.run() are deprecated.\")\n        print(\"Consider using 'output_transform=dict(func=tflib.convert_images_to_uint8)'\")\n        print(\"instead of 'out_mul=127.5, out_add=127.5, out_dtype=np.uint8'.\")\n        print()\n    assert output_transform is None\n\n    new_kwargs = dict(dynamic_kwargs)\n    new_transform = {kwarg: new_kwargs.pop(kwarg) for kwarg in legacy_kwargs if kwarg in dynamic_kwargs}\n    new_transform[\"func\"] = _legacy_output_transform_func\n    return new_transform, new_kwargs\n\ndef _legacy_output_transform_func(*expr, out_mul=1.0, out_add=0.0, out_shrink=1, out_dtype=None):\n    if out_mul != 1.0:\n        expr = [x * out_mul for x in expr]\n\n    if out_add != 0.0:\n        expr = [x + out_add for x in expr]\n\n    if out_shrink > 1:\n        ksize = [1, 1, out_shrink, out_shrink]\n        expr = [tf.nn.avg_pool(x, ksize=ksize, strides=ksize, padding=\"VALID\", data_format=\"NCHW\") for x in expr]\n\n    if out_dtype is not None:\n        if tf.as_dtype(out_dtype).is_integer:\n            expr = [tf.round(x) for x in expr]\n        expr = [tf.saturate_cast(x, out_dtype) for x in expr]\n    return expr\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/tflib/ops/__init__.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n# empty\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/tflib/ops/fused_bias_act.cu",
    "content": "// Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n//\n// This work is made available under the Nvidia Source Code License-NC.\n// To view a copy of this license, visit\n// https://nvlabs.github.io/stylegan2/license.html\n\n#define EIGEN_USE_GPU\n#define __CUDA_INCLUDE_COMPILER_INTERNAL_HEADERS__\n#include \"tensorflow/core/framework/op.h\"\n#include \"tensorflow/core/framework/op_kernel.h\"\n#include \"tensorflow/core/framework/shape_inference.h\"\n#include <stdio.h>\n\nusing namespace tensorflow;\nusing namespace tensorflow::shape_inference;\n\n#define OP_CHECK_CUDA_ERROR(CTX, CUDA_CALL) do { cudaError_t err = CUDA_CALL; OP_REQUIRES(CTX, err == cudaSuccess, errors::Internal(cudaGetErrorName(err))); } while (false)\n\n//------------------------------------------------------------------------\n// CUDA kernel.\n\ntemplate <class T>\nstruct FusedBiasActKernelParams\n{\n    const T*    x;      // [sizeX]\n    const T*    b;      // [sizeB] or NULL\n    const T*    ref;    // [sizeX] or NULL\n    T*          y;      // [sizeX]\n\n    int         grad;\n    int         axis;\n    int         act;\n    float       alpha;\n    float       gain;\n\n    int         sizeX;\n    int         sizeB;\n    int         stepB;\n    int         loopX;\n};\n\ntemplate <class T>\nstatic __global__ void FusedBiasActKernel(const FusedBiasActKernelParams<T> p)\n{\n    const float expRange        = 80.0f;\n    const float halfExpRange    = 40.0f;\n    const float seluScale       = 1.0507009873554804934193349852946f;\n    const float seluAlpha       = 1.6732632423543772848170429916717f;\n\n    // Loop over elements.\n    int xi = blockIdx.x * p.loopX * blockDim.x + threadIdx.x;\n    for (int loopIdx = 0; loopIdx < p.loopX && xi < p.sizeX; loopIdx++, xi += blockDim.x)\n    {\n        // Load and apply bias.\n        float x = (float)p.x[xi];\n        if (p.b)\n            x += (float)p.b[(xi / p.stepB) % p.sizeB];\n        float ref = (p.ref) ? (float)p.ref[xi] : 0.0f;\n        if (p.gain != 0.0f & p.act != 9)\n            ref /= p.gain;\n\n        // Evaluate activation func.\n        float y;\n        switch (p.act * 10 + p.grad)\n        {\n            // linear\n            default:\n            case 10: y = x; break;\n            case 11: y = x; break;\n            case 12: y = 0.0f; break;\n\n            // relu\n            case 20: y = (x > 0.0f) ? x : 0.0f; break;\n            case 21: y = (ref > 0.0f) ? x : 0.0f; break;\n            case 22: y = 0.0f; break;\n\n            // lrelu\n            case 30: y = (x > 0.0f) ? x : x * p.alpha; break;\n            case 31: y = (ref > 0.0f) ? x : x * p.alpha; break;\n            case 32: y = 0.0f; break;\n\n            // tanh\n            case 40: { float c = expf(x); float d = 1.0f / c; y = (x < -expRange) ? -1.0f : (x > expRange) ? 1.0f : (c - d) / (c + d); } break;\n            case 41: y = x * (1.0f - ref * ref); break;\n            case 42: y = x * (1.0f - ref * ref) * (-2.0f * ref); break;\n\n            // sigmoid\n            case 50: y = (x < -expRange) ? 0.0f : 1.0f / (expf(-x) + 1.0f); break;\n            case 51: y = x * ref * (1.0f - ref); break;\n            case 52: y = x * ref * (1.0f - ref) * (1.0f - 2.0f * ref); break;\n\n            // elu\n            case 60: y = (x >= 0.0f) ? x : expf(x) - 1.0f; break;\n            case 61: y = (ref >= 0.0f) ? x : x * (ref + 1.0f); break;\n            case 62: y = (ref >= 0.0f) ? 0.0f : x * (ref + 1.0f); break;\n\n            // selu\n            case 70: y = (x >= 0.0f) ? seluScale * x : (seluScale * seluAlpha) * (expf(x) - 1.0f); break;\n            case 71: y = (ref >= 0.0f) ? x * seluScale : x * (ref + seluScale * seluAlpha); break;\n            case 72: y = (ref >= 0.0f) ? 0.0f : x * (ref + seluScale * seluAlpha); break;\n\n            // softplus\n            case 80: y = (x > expRange) ? x : logf(expf(x) + 1.0f); break;\n            case 81: y = x * (1.0f - expf(-ref)); break;\n            case 82: { float c = expf(-ref); y = x * c * (1.0f - c); } break;\n\n            // swish\n            case 90: y = (x < -expRange) ? 0.0f : x / (expf(-x) + 1.0f); break;\n            case 91: { float c = expf(ref); float d = c + 1.0f; y = (ref > halfExpRange) ? x : x * c * (ref + d) / (d * d); } break;\n            case 92: { float c = expf(ref); float d = c + 1.0f; y = (ref > halfExpRange) ? 0.0f : x * c * (ref * (2.0f - d) + 2.0f * d) / (d * d * d); } break;\n        }\n\n        // Apply gain and store.\n        p.y[xi] = (T)(y * p.gain);\n    }\n}\n\n//------------------------------------------------------------------------\n// TensorFlow op.\n\ntemplate <class T>\nstruct FusedBiasActOp : public OpKernel\n{\n    FusedBiasActKernelParams<T> m_attribs;\n\n    FusedBiasActOp(OpKernelConstruction* ctx) : OpKernel(ctx)\n    {\n        memset(&m_attribs, 0, sizeof(m_attribs));\n        OP_REQUIRES_OK(ctx, ctx->GetAttr(\"grad\", &m_attribs.grad));\n        OP_REQUIRES_OK(ctx, ctx->GetAttr(\"axis\", &m_attribs.axis));\n        OP_REQUIRES_OK(ctx, ctx->GetAttr(\"act\", &m_attribs.act));\n        OP_REQUIRES_OK(ctx, ctx->GetAttr(\"alpha\", &m_attribs.alpha));\n        OP_REQUIRES_OK(ctx, ctx->GetAttr(\"gain\", &m_attribs.gain));\n        OP_REQUIRES(ctx, m_attribs.grad >= 0, errors::InvalidArgument(\"grad must be non-negative\"));\n        OP_REQUIRES(ctx, m_attribs.axis >= 0, errors::InvalidArgument(\"axis must be non-negative\"));\n        OP_REQUIRES(ctx, m_attribs.act >= 0, errors::InvalidArgument(\"act must be non-negative\"));\n    }\n\n    void Compute(OpKernelContext* ctx)\n    {\n        FusedBiasActKernelParams<T> p = m_attribs;\n        cudaStream_t stream = ctx->eigen_device<Eigen::GpuDevice>().stream();\n\n        const Tensor& x     = ctx->input(0); // [...]\n        const Tensor& b     = ctx->input(1); // [sizeB] or [0]\n        const Tensor& ref   = ctx->input(2); // x.shape or [0]\n        p.x = x.flat<T>().data();\n        p.b = (b.NumElements()) ? b.flat<T>().data() : NULL;\n        p.ref = (ref.NumElements()) ? ref.flat<T>().data() : NULL;\n        OP_REQUIRES(ctx, b.NumElements() == 0 || m_attribs.axis < x.dims(), errors::InvalidArgument(\"axis out of bounds\"));\n        OP_REQUIRES(ctx, b.dims() == 1, errors::InvalidArgument(\"b must have rank 1\"));\n        OP_REQUIRES(ctx, b.NumElements() == 0 || b.NumElements() == x.dim_size(m_attribs.axis), errors::InvalidArgument(\"b has wrong number of elements\"));\n        OP_REQUIRES(ctx, ref.NumElements() == ((p.grad == 0) ? 0 : x.NumElements()), errors::InvalidArgument(\"ref has wrong number of elements\"));\n        OP_REQUIRES(ctx, x.NumElements() <= kint32max, errors::InvalidArgument(\"x is too large\"));\n\n        p.sizeX = (int)x.NumElements();\n        p.sizeB = (int)b.NumElements();\n        p.stepB = 1;\n        for (int i = m_attribs.axis + 1; i < x.dims(); i++)\n            p.stepB *= (int)x.dim_size(i);\n\n        Tensor* y = NULL; // x.shape\n        OP_REQUIRES_OK(ctx, ctx->allocate_output(0, x.shape(), &y));\n        p.y = y->flat<T>().data();\n\n        p.loopX = 4;\n        int blockSize = 4 * 32;\n        int gridSize = (p.sizeX - 1) / (p.loopX * blockSize) + 1;\n        void* args[] = {&p};\n        OP_CHECK_CUDA_ERROR(ctx, cudaLaunchKernel((void*)FusedBiasActKernel<T>, gridSize, blockSize, args, 0, stream));\n    }\n};\n\nREGISTER_OP(\"FusedBiasAct\")\n    .Input      (\"x: T\")\n    .Input      (\"b: T\")\n    .Input      (\"ref: T\")\n    .Output     (\"y: T\")\n    .Attr       (\"T: {float, half}\")\n    .Attr       (\"grad: int = 0\")\n    .Attr       (\"axis: int = 1\")\n    .Attr       (\"act: int = 0\")\n    .Attr       (\"alpha: float = 0.0\")\n    .Attr       (\"gain: float = 1.0\");\nREGISTER_KERNEL_BUILDER(Name(\"FusedBiasAct\").Device(DEVICE_GPU).TypeConstraint<float>(\"T\"), FusedBiasActOp<float>);\nREGISTER_KERNEL_BUILDER(Name(\"FusedBiasAct\").Device(DEVICE_GPU).TypeConstraint<Eigen::half>(\"T\"), FusedBiasActOp<Eigen::half>);\n\n//------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/tflib/ops/fused_bias_act.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Custom TensorFlow ops for efficient bias and activation.\"\"\"\n\nimport os\nimport numpy as np\nimport tensorflow as tf\nfrom .. import custom_ops\nfrom ...util import EasyDict\n\ndef _get_plugin():\n    return custom_ops.get_plugin(os.path.splitext(__file__)[0] + '.cu')\n\n#----------------------------------------------------------------------------\n\nactivation_funcs = {\n    'linear':   EasyDict(func=lambda x, **_:        x,                          def_alpha=None, def_gain=1.0,           cuda_idx=1, ref='y', zero_2nd_grad=True),\n    'relu':     EasyDict(func=lambda x, **_:        tf.nn.relu(x),              def_alpha=None, def_gain=np.sqrt(2),    cuda_idx=2, ref='y', zero_2nd_grad=True),\n    'lrelu':    EasyDict(func=lambda x, alpha, **_: tf.nn.leaky_relu(x, alpha), def_alpha=0.2,  def_gain=np.sqrt(2),    cuda_idx=3, ref='y', zero_2nd_grad=True),\n    'tanh':     EasyDict(func=lambda x, **_:        tf.nn.tanh(x),              def_alpha=None, def_gain=1.0,           cuda_idx=4, ref='y', zero_2nd_grad=False),\n    'sigmoid':  EasyDict(func=lambda x, **_:        tf.nn.sigmoid(x),           def_alpha=None, def_gain=1.0,           cuda_idx=5, ref='y', zero_2nd_grad=False),\n    'elu':      EasyDict(func=lambda x, **_:        tf.nn.elu(x),               def_alpha=None, def_gain=1.0,           cuda_idx=6, ref='y', zero_2nd_grad=False),\n    'selu':     EasyDict(func=lambda x, **_:        tf.nn.selu(x),              def_alpha=None, def_gain=1.0,           cuda_idx=7, ref='y', zero_2nd_grad=False),\n    'softplus': EasyDict(func=lambda x, **_:        tf.nn.softplus(x),          def_alpha=None, def_gain=1.0,           cuda_idx=8, ref='y', zero_2nd_grad=False),\n    'swish':    EasyDict(func=lambda x, **_:        tf.nn.sigmoid(x) * x,       def_alpha=None, def_gain=np.sqrt(2),    cuda_idx=9, ref='x', zero_2nd_grad=False),\n}\n\n#----------------------------------------------------------------------------\n\ndef fused_bias_act(x, b=None, axis=1, act='linear', alpha=None, gain=None, impl='cuda'):\n    r\"\"\"Fused bias and activation function.\n\n    Adds bias `b` to activation tensor `x`, evaluates activation function `act`,\n    and scales the result by `gain`. Each of the steps is optional. In most cases,\n    the fused op is considerably more efficient than performing the same calculation\n    using standard TensorFlow ops. It supports first and second order gradients,\n    but not third order gradients.\n\n    Args:\n        x:      Input activation tensor. Can have any shape, but if `b` is defined, the\n                dimension corresponding to `axis`, as well as the rank, must be known.\n        b:      Bias vector, or `None` to disable. Must be a 1D tensor of the same type\n                as `x`. The shape must be known, and it must match the dimension of `x`\n                corresponding to `axis`.\n        axis:   The dimension in `x` corresponding to the elements of `b`.\n                The value of `axis` is ignored if `b` is not specified.\n        act:    Name of the activation function to evaluate, or `\"linear\"` to disable.\n                Can be e.g. `\"relu\"`, `\"lrelu\"`, `\"tanh\"`, `\"sigmoid\"`, `\"swish\"`, etc.\n                See `activation_funcs` for a full list. `None` is not allowed.\n        alpha:  Shape parameter for the activation function, or `None` to use the default.\n        gain:   Scaling factor for the output tensor, or `None` to use default.\n                See `activation_funcs` for the default scaling of each activation function.\n                If unsure, consider specifying `1.0`.\n        impl:   Name of the implementation to use. Can be `\"ref\"` or `\"cuda\"` (default).\n\n    Returns:\n        Tensor of the same shape and datatype as `x`.\n    \"\"\"\n\n    impl_dict = {\n        'ref':  _fused_bias_act_ref,\n        'cuda': _fused_bias_act_ref if 'TPU_NAME' in os.environ or 'NO_NVCC' in os.environ else _fused_bias_act_cuda,\n    }\n    return impl_dict[impl](x=x, b=b, axis=axis, act=act, alpha=alpha, gain=gain)\n\n#----------------------------------------------------------------------------\n\ndef _fused_bias_act_ref(x, b, axis, act, alpha, gain):\n    \"\"\"Slow reference implementation of `fused_bias_act()` using standard TensorFlow ops.\"\"\"\n\n    # Validate arguments.\n    x = tf.convert_to_tensor(x)\n    b = tf.convert_to_tensor(b) if b is not None else tf.constant([], dtype=x.dtype)\n    act_spec = activation_funcs[act]\n    assert b.shape.rank == 1 and (b.shape[0] == 0 or b.shape[0] == x.shape[axis])\n    assert b.shape[0] == 0 or 0 <= axis < x.shape.rank\n    if alpha is None:\n        alpha = act_spec.def_alpha\n    if gain is None:\n        gain = act_spec.def_gain\n\n    # Add bias.\n    if b.shape[0] != 0:\n        x += tf.reshape(b, [-1 if i == axis else 1 for i in range(x.shape.rank)])\n\n    # Evaluate activation function.\n    x = act_spec.func(x, alpha=alpha)\n\n    # Scale by gain.\n    if gain != 1:\n        x *= gain\n    return x\n\n#----------------------------------------------------------------------------\n\ndef _fused_bias_act_cuda(x, b, axis, act, alpha, gain):\n    \"\"\"Fast CUDA implementation of `fused_bias_act()` using custom ops.\"\"\"\n\n    # Validate arguments.\n    x = tf.convert_to_tensor(x)\n    empty_tensor = tf.constant([], dtype=x.dtype)\n    b = tf.convert_to_tensor(b) if b is not None else empty_tensor\n    act_spec = activation_funcs[act]\n    assert b.shape.rank == 1 and (b.shape[0] == 0 or b.shape[0] == x.shape[axis])\n    assert b.shape[0] == 0 or 0 <= axis < x.shape.rank\n    if alpha is None:\n        alpha = act_spec.def_alpha\n    if gain is None:\n        gain = act_spec.def_gain\n\n    # Special cases.\n    if act == 'linear' and b is None and gain == 1.0:\n        return x\n    if act_spec.cuda_idx is None:\n        return _fused_bias_act_ref(x=x, b=b, axis=axis, act=act, alpha=alpha, gain=gain)\n\n    # CUDA kernel.\n    cuda_kernel = _get_plugin().fused_bias_act\n    cuda_kwargs = dict(axis=axis, act=act_spec.cuda_idx, alpha=alpha, gain=gain)\n\n    # Forward pass: y = func(x, b).\n    def func_y(x, b):\n        y = cuda_kernel(x=x, b=b, ref=empty_tensor, grad=0, **cuda_kwargs)\n        y.set_shape(x.shape)\n        return y\n\n    # Backward pass: dx, db = grad(dy, x, y)\n    def grad_dx(dy, x, y):\n        ref = {'x': x, 'y': y}[act_spec.ref]\n        dx = cuda_kernel(x=dy, b=empty_tensor, ref=ref, grad=1, **cuda_kwargs)\n        dx.set_shape(x.shape)\n        return dx\n    def grad_db(dx):\n        if b.shape[0] == 0:\n            return empty_tensor\n        db = dx\n        if axis < x.shape.rank - 1:\n            db = tf.reduce_sum(db, list(range(axis + 1, x.shape.rank)))\n        if axis > 0:\n            db = tf.reduce_sum(db, list(range(axis)))\n        db.set_shape(b.shape)\n        return db\n\n    # Second order gradients: d_dy, d_x = grad2(d_dx, d_db, x, y)\n    def grad2_d_dy(d_dx, d_db, x, y):\n        ref = {'x': x, 'y': y}[act_spec.ref]\n        d_dy = cuda_kernel(x=d_dx, b=d_db, ref=ref, grad=1, **cuda_kwargs)\n        d_dy.set_shape(x.shape)\n        return d_dy\n    def grad2_d_x(d_dx, d_db, x, y):\n        ref = {'x': x, 'y': y}[act_spec.ref]\n        d_x = cuda_kernel(x=d_dx, b=d_db, ref=ref, grad=2, **cuda_kwargs)\n        d_x.set_shape(x.shape)\n        return d_x\n\n    # Fast version for piecewise-linear activation funcs.\n    @tf.custom_gradient\n    def func_zero_2nd_grad(x, b):\n        y = func_y(x, b)\n        @tf.custom_gradient\n        def grad(dy):\n            dx = grad_dx(dy, x, y)\n            db = grad_db(dx)\n            def grad2(d_dx, d_db):\n                d_dy = grad2_d_dy(d_dx, d_db, x, y)\n                return d_dy\n            return (dx, db), grad2\n        return y, grad\n\n    # Slow version for general activation funcs.\n    @tf.custom_gradient\n    def func_nonzero_2nd_grad(x, b):\n        y = func_y(x, b)\n        def grad_wrap(dy):\n            @tf.custom_gradient\n            def grad_impl(dy, x):\n                dx = grad_dx(dy, x, y)\n                db = grad_db(dx)\n                def grad2(d_dx, d_db):\n                    d_dy = grad2_d_dy(d_dx, d_db, x, y)\n                    d_x = grad2_d_x(d_dx, d_db, x, y)\n                    return d_dy, d_x\n                return (dx, db), grad2\n            return grad_impl(dy, x)\n        return y, grad_wrap\n\n    # Which version to use?\n    if act_spec.zero_2nd_grad:\n        return func_zero_2nd_grad(x, b)\n    return func_nonzero_2nd_grad(x, b)\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/tflib/ops/upfirdn_2d.cu",
    "content": "// Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n//\n// This work is made available under the Nvidia Source Code License-NC.\n// To view a copy of this license, visit\n// https://nvlabs.github.io/stylegan2/license.html\n\n#define EIGEN_USE_GPU\n#define __CUDA_INCLUDE_COMPILER_INTERNAL_HEADERS__\n#include \"tensorflow/core/framework/op.h\"\n#include \"tensorflow/core/framework/op_kernel.h\"\n#include \"tensorflow/core/framework/shape_inference.h\"\n#include <stdio.h>\n\nusing namespace tensorflow;\nusing namespace tensorflow::shape_inference;\n\n//------------------------------------------------------------------------\n// Helpers.\n\n#define OP_CHECK_CUDA_ERROR(CTX, CUDA_CALL) do { cudaError_t err = CUDA_CALL; OP_REQUIRES(CTX, err == cudaSuccess, errors::Internal(cudaGetErrorName(err))); } while (false)\n\nstatic __host__ __device__ __forceinline__ int floorDiv(int a, int b)\n{\n    int c = a / b;\n    if (c * b > a)\n        c--;\n    return c;\n}\n\n//------------------------------------------------------------------------\n// CUDA kernel params.\n\ntemplate <class T>\nstruct UpFirDn2DKernelParams\n{\n    const T*    x;          // [majorDim, inH, inW, minorDim]\n    const T*    k;          // [kernelH, kernelW]\n    T*          y;          // [majorDim, outH, outW, minorDim]\n\n    int         upx;\n    int         upy;\n    int         downx;\n    int         downy;\n    int         padx0;\n    int         padx1;\n    int         pady0;\n    int         pady1;\n\n    int         majorDim;\n    int         inH;\n    int         inW;\n    int         minorDim;\n    int         kernelH;\n    int         kernelW;\n    int         outH;\n    int         outW;\n    int         loopMajor;\n    int         loopX;\n};\n\n//------------------------------------------------------------------------\n// General CUDA implementation for large filter kernels.\n\ntemplate <class T>\nstatic __global__ void UpFirDn2DKernel_large(const UpFirDn2DKernelParams<T> p)\n{\n    // Calculate thread index.\n    int minorIdx = blockIdx.x * blockDim.x + threadIdx.x;\n    int outY = minorIdx / p.minorDim;\n    minorIdx -= outY * p.minorDim;\n    int outXBase = blockIdx.y * p.loopX * blockDim.y + threadIdx.y;\n    int majorIdxBase = blockIdx.z * p.loopMajor;\n    if (outXBase >= p.outW || outY >= p.outH || majorIdxBase >= p.majorDim)\n        return;\n\n    // Setup Y receptive field.\n    int midY = outY * p.downy + p.upy - 1 - p.pady0;\n    int inY = min(max(floorDiv(midY, p.upy), 0), p.inH);\n    int h = min(max(floorDiv(midY + p.kernelH, p.upy), 0), p.inH) - inY;\n    int kernelY = midY + p.kernelH - (inY + 1) * p.upy;\n\n    // Loop over majorDim and outX.\n    for (int loopMajor = 0, majorIdx = majorIdxBase; loopMajor < p.loopMajor && majorIdx < p.majorDim; loopMajor++, majorIdx++)\n    for (int loopX = 0, outX = outXBase; loopX < p.loopX && outX < p.outW; loopX++, outX += blockDim.y)\n    {\n        // Setup X receptive field.\n        int midX = outX * p.downx + p.upx - 1 - p.padx0;\n        int inX = min(max(floorDiv(midX, p.upx), 0), p.inW);\n        int w = min(max(floorDiv(midX + p.kernelW, p.upx), 0), p.inW) - inX;\n        int kernelX = midX + p.kernelW - (inX + 1) * p.upx;\n\n        // Initialize pointers.\n        const T* xp = &p.x[((majorIdx * p.inH + inY) * p.inW + inX) * p.minorDim + minorIdx];\n        const T* kp = &p.k[kernelY * p.kernelW + kernelX];\n        int xpx = p.minorDim;\n        int kpx = -p.upx;\n        int xpy = p.inW * p.minorDim;\n        int kpy = -p.upy * p.kernelW;\n\n        // Inner loop.\n        float v = 0.0f;\n        for (int y = 0; y < h; y++)\n        {\n            for (int x = 0; x < w; x++)\n            {\n                v += (float)(*xp) * (float)(*kp);\n                xp += xpx;\n                kp += kpx;\n            }\n            xp += xpy - w * xpx;\n            kp += kpy - w * kpx;\n        }\n\n        // Store result.\n        p.y[((majorIdx * p.outH + outY) * p.outW + outX) * p.minorDim + minorIdx] = (T)v;\n    }\n}\n\n//------------------------------------------------------------------------\n// Specialized CUDA implementation for small filter kernels.\n\ntemplate <class T, int upx, int upy, int downx, int downy, int kernelW, int kernelH, int tileOutW, int tileOutH>\nstatic __global__ void UpFirDn2DKernel_small(const UpFirDn2DKernelParams<T> p)\n{\n    //assert(kernelW % upx == 0);\n    //assert(kernelH % upy == 0);\n    const int tileInW = ((tileOutW - 1) * downx + kernelW - 1) / upx + 1;\n    const int tileInH = ((tileOutH - 1) * downy + kernelH - 1) / upy + 1;\n    __shared__ volatile float sk[kernelH][kernelW];\n    __shared__ volatile float sx[tileInH][tileInW];\n\n    // Calculate tile index.\n    int minorIdx = blockIdx.x;\n    int tileOutY = minorIdx / p.minorDim;\n    minorIdx -= tileOutY * p.minorDim;\n    tileOutY *= tileOutH;\n    int tileOutXBase = blockIdx.y * p.loopX * tileOutW;\n    int majorIdxBase = blockIdx.z * p.loopMajor;\n    if (tileOutXBase >= p.outW | tileOutY >= p.outH | majorIdxBase >= p.majorDim)\n        return;\n\n    // Load filter kernel (flipped).\n    for (int tapIdx = threadIdx.x; tapIdx < kernelH * kernelW; tapIdx += blockDim.x)\n    {\n        int ky = tapIdx / kernelW;\n        int kx = tapIdx - ky * kernelW;\n        float v = 0.0f;\n        if (kx < p.kernelW & ky < p.kernelH)\n            v = (float)p.k[(p.kernelH - 1 - ky) * p.kernelW + (p.kernelW - 1 - kx)];\n        sk[ky][kx] = v;\n    }\n\n    // Loop over majorDim and outX.\n    for (int loopMajor = 0, majorIdx = majorIdxBase; loopMajor < p.loopMajor & majorIdx < p.majorDim; loopMajor++, majorIdx++)\n    for (int loopX = 0, tileOutX = tileOutXBase; loopX < p.loopX & tileOutX < p.outW; loopX++, tileOutX += tileOutW)\n    {\n        // Load input pixels.\n        int tileMidX = tileOutX * downx + upx - 1 - p.padx0;\n        int tileMidY = tileOutY * downy + upy - 1 - p.pady0;\n        int tileInX = floorDiv(tileMidX, upx);\n        int tileInY = floorDiv(tileMidY, upy);\n        __syncthreads();\n        for (int inIdx = threadIdx.x; inIdx < tileInH * tileInW; inIdx += blockDim.x)\n        {\n            int relInY = inIdx / tileInW;\n            int relInX = inIdx - relInY * tileInW;\n            int inX = relInX + tileInX;\n            int inY = relInY + tileInY;\n            float v = 0.0f;\n            if (inX >= 0 & inY >= 0 & inX < p.inW & inY < p.inH)\n                v = (float)p.x[((majorIdx * p.inH + inY) * p.inW + inX) * p.minorDim + minorIdx];\n            sx[relInY][relInX] = v;\n        }\n\n        // Loop over output pixels.\n        __syncthreads();\n        for (int outIdx = threadIdx.x; outIdx < tileOutH * tileOutW; outIdx += blockDim.x)\n        {\n            int relOutY = outIdx / tileOutW;\n            int relOutX = outIdx - relOutY * tileOutW;\n            int outX = relOutX + tileOutX;\n            int outY = relOutY + tileOutY;\n\n            // Setup receptive field.\n            int midX = tileMidX + relOutX * downx;\n            int midY = tileMidY + relOutY * downy;\n            int inX = floorDiv(midX, upx);\n            int inY = floorDiv(midY, upy);\n            int relInX = inX - tileInX;\n            int relInY = inY - tileInY;\n            int kernelX = (inX + 1) * upx - midX - 1; // flipped\n            int kernelY = (inY + 1) * upy - midY - 1; // flipped\n\n            // Inner loop.\n            float v = 0.0f;\n            #pragma unroll\n            for (int y = 0; y < kernelH / upy; y++)\n                #pragma unroll\n                for (int x = 0; x < kernelW / upx; x++)\n                    v += sx[relInY + y][relInX + x] * sk[kernelY + y * upy][kernelX + x * upx];\n\n            // Store result.\n            if (outX < p.outW & outY < p.outH)\n                p.y[((majorIdx * p.outH + outY) * p.outW + outX) * p.minorDim + minorIdx] = (T)v;\n        }\n    }\n}\n\n//------------------------------------------------------------------------\n// TensorFlow op.\n\ntemplate <class T>\nstruct UpFirDn2DOp : public OpKernel\n{\n    UpFirDn2DKernelParams<T> m_attribs;\n\n    UpFirDn2DOp(OpKernelConstruction* ctx) : OpKernel(ctx)\n    {\n        memset(&m_attribs, 0, sizeof(m_attribs));\n        OP_REQUIRES_OK(ctx, ctx->GetAttr(\"upx\", &m_attribs.upx));\n        OP_REQUIRES_OK(ctx, ctx->GetAttr(\"upy\", &m_attribs.upy));\n        OP_REQUIRES_OK(ctx, ctx->GetAttr(\"downx\", &m_attribs.downx));\n        OP_REQUIRES_OK(ctx, ctx->GetAttr(\"downy\", &m_attribs.downy));\n        OP_REQUIRES_OK(ctx, ctx->GetAttr(\"padx0\", &m_attribs.padx0));\n        OP_REQUIRES_OK(ctx, ctx->GetAttr(\"padx1\", &m_attribs.padx1));\n        OP_REQUIRES_OK(ctx, ctx->GetAttr(\"pady0\", &m_attribs.pady0));\n        OP_REQUIRES_OK(ctx, ctx->GetAttr(\"pady1\", &m_attribs.pady1));\n        OP_REQUIRES(ctx, m_attribs.upx >= 1 && m_attribs.upy >= 1, errors::InvalidArgument(\"upx and upy must be at least 1x1\"));\n        OP_REQUIRES(ctx, m_attribs.downx >= 1 && m_attribs.downy >= 1, errors::InvalidArgument(\"downx and downy must be at least 1x1\"));\n    }\n\n    void Compute(OpKernelContext* ctx)\n    {\n        UpFirDn2DKernelParams<T> p = m_attribs;\n        cudaStream_t stream = ctx->eigen_device<Eigen::GpuDevice>().stream();\n\n        const Tensor& x = ctx->input(0); // [majorDim, inH, inW, minorDim]\n        const Tensor& k = ctx->input(1); // [kernelH, kernelW]\n        p.x = x.flat<T>().data();\n        p.k = k.flat<T>().data();\n        OP_REQUIRES(ctx, x.dims() == 4, errors::InvalidArgument(\"input must have rank 4\"));\n        OP_REQUIRES(ctx, k.dims() == 2, errors::InvalidArgument(\"kernel must have rank 2\"));\n        OP_REQUIRES(ctx, x.NumElements() <= kint32max, errors::InvalidArgument(\"input too large\"));\n        OP_REQUIRES(ctx, k.NumElements() <= kint32max, errors::InvalidArgument(\"kernel too large\"));\n\n        p.majorDim  = (int)x.dim_size(0);\n        p.inH       = (int)x.dim_size(1);\n        p.inW       = (int)x.dim_size(2);\n        p.minorDim  = (int)x.dim_size(3);\n        p.kernelH   = (int)k.dim_size(0);\n        p.kernelW   = (int)k.dim_size(1);\n        OP_REQUIRES(ctx, p.kernelW >= 1 && p.kernelH >= 1, errors::InvalidArgument(\"kernel must be at least 1x1\"));\n\n        p.outW = (p.inW * p.upx + p.padx0 + p.padx1 - p.kernelW + p.downx) / p.downx;\n        p.outH = (p.inH * p.upy + p.pady0 + p.pady1 - p.kernelH + p.downy) / p.downy;\n        OP_REQUIRES(ctx, p.outW >= 1 && p.outH >= 1, errors::InvalidArgument(\"output must be at least 1x1\"));\n\n        Tensor* y = NULL; // [majorDim, outH, outW, minorDim]\n        TensorShape ys;\n        ys.AddDim(p.majorDim);\n        ys.AddDim(p.outH);\n        ys.AddDim(p.outW);\n        ys.AddDim(p.minorDim);\n        OP_REQUIRES_OK(ctx, ctx->allocate_output(0, ys, &y));\n        p.y = y->flat<T>().data();\n        OP_REQUIRES(ctx, y->NumElements() <= kint32max, errors::InvalidArgument(\"output too large\"));\n\n        // Choose CUDA kernel to use.\n        void* cudaKernel = (void*)UpFirDn2DKernel_large<T>;\n        int tileOutW = -1;\n        int tileOutH = -1;\n        if (p.upx == 1 && p.upy == 1 && p.downx == 1 && p.downy == 1 && p.kernelW <= 7 && p.kernelH <= 7) { cudaKernel = (void*)UpFirDn2DKernel_small<T, 1,1, 1,1, 7,7, 64,16>; tileOutW = 64; tileOutH = 16; }\n        if (p.upx == 1 && p.upy == 1 && p.downx == 1 && p.downy == 1 && p.kernelW <= 6 && p.kernelH <= 6) { cudaKernel = (void*)UpFirDn2DKernel_small<T, 1,1, 1,1, 6,6, 64,16>; tileOutW = 64; tileOutH = 16; }\n        if (p.upx == 1 && p.upy == 1 && p.downx == 1 && p.downy == 1 && p.kernelW <= 5 && p.kernelH <= 5) { cudaKernel = (void*)UpFirDn2DKernel_small<T, 1,1, 1,1, 5,5, 64,16>; tileOutW = 64; tileOutH = 16; }\n        if (p.upx == 1 && p.upy == 1 && p.downx == 1 && p.downy == 1 && p.kernelW <= 4 && p.kernelH <= 4) { cudaKernel = (void*)UpFirDn2DKernel_small<T, 1,1, 1,1, 4,4, 64,16>; tileOutW = 64; tileOutH = 16; }\n        if (p.upx == 1 && p.upy == 1 && p.downx == 1 && p.downy == 1 && p.kernelW <= 3 && p.kernelH <= 3) { cudaKernel = (void*)UpFirDn2DKernel_small<T, 1,1, 1,1, 3,3, 64,16>; tileOutW = 64; tileOutH = 16; }\n        if (p.upx == 2 && p.upy == 2 && p.downx == 1 && p.downy == 1 && p.kernelW <= 8 && p.kernelH <= 8) { cudaKernel = (void*)UpFirDn2DKernel_small<T, 2,2, 1,1, 8,8, 64,16>; tileOutW = 64; tileOutH = 16; }\n        if (p.upx == 2 && p.upy == 2 && p.downx == 1 && p.downy == 1 && p.kernelW <= 6 && p.kernelH <= 6) { cudaKernel = (void*)UpFirDn2DKernel_small<T, 2,2, 1,1, 6,6, 64,16>; tileOutW = 64; tileOutH = 16; }\n        if (p.upx == 2 && p.upy == 2 && p.downx == 1 && p.downy == 1 && p.kernelW <= 4 && p.kernelH <= 4) { cudaKernel = (void*)UpFirDn2DKernel_small<T, 2,2, 1,1, 4,4, 64,16>; tileOutW = 64; tileOutH = 16; }\n        if (p.upx == 2 && p.upy == 2 && p.downx == 1 && p.downy == 1 && p.kernelW <= 2 && p.kernelH <= 2) { cudaKernel = (void*)UpFirDn2DKernel_small<T, 2,2, 1,1, 2,2, 64,16>; tileOutW = 64; tileOutH = 16; }\n        if (p.upx == 1 && p.upy == 1 && p.downx == 2 && p.downy == 2 && p.kernelW <= 8 && p.kernelH <= 8) { cudaKernel = (void*)UpFirDn2DKernel_small<T, 1,1, 2,2, 8,8, 32,8>;  tileOutW = 32; tileOutH = 8;  }\n        if (p.upx == 1 && p.upy == 1 && p.downx == 2 && p.downy == 2 && p.kernelW <= 6 && p.kernelH <= 6) { cudaKernel = (void*)UpFirDn2DKernel_small<T, 1,1, 2,2, 6,6, 32,8>;  tileOutW = 32; tileOutH = 8;  }\n        if (p.upx == 1 && p.upy == 1 && p.downx == 2 && p.downy == 2 && p.kernelW <= 4 && p.kernelH <= 4) { cudaKernel = (void*)UpFirDn2DKernel_small<T, 1,1, 2,2, 4,4, 32,8>;  tileOutW = 32; tileOutH = 8;  }\n        if (p.upx == 1 && p.upy == 1 && p.downx == 2 && p.downy == 2 && p.kernelW <= 2 && p.kernelH <= 2) { cudaKernel = (void*)UpFirDn2DKernel_small<T, 1,1, 2,2, 2,2, 32,8>;  tileOutW = 32; tileOutH = 8;  }\n\n        // Choose launch params.\n        dim3 blockSize;\n        dim3 gridSize;\n        if (tileOutW > 0 && tileOutH > 0) // small\n        {\n            p.loopMajor = (p.majorDim - 1) / 16384 + 1;\n            p.loopX = 1;\n            blockSize = dim3(32 * 8, 1, 1);\n            gridSize = dim3(((p.outH - 1) / tileOutH + 1) * p.minorDim, (p.outW - 1) / (p.loopX * tileOutW) + 1, (p.majorDim - 1) / p.loopMajor + 1);\n        }\n        else // large\n        {\n            p.loopMajor = (p.majorDim - 1) / 16384 + 1;\n            p.loopX = 4;\n            blockSize = dim3(4, 32, 1);\n            gridSize = dim3((p.outH * p.minorDim - 1) / blockSize.x + 1, (p.outW - 1) / (p.loopX * blockSize.y) + 1, (p.majorDim - 1) / p.loopMajor + 1);\n        }\n\n        // Launch CUDA kernel.\n        void* args[] = {&p};\n        OP_CHECK_CUDA_ERROR(ctx, cudaLaunchKernel(cudaKernel, gridSize, blockSize, args, 0, stream));\n    }\n};\n\nREGISTER_OP(\"UpFirDn2D\")\n    .Input      (\"x: T\")\n    .Input      (\"k: T\")\n    .Output     (\"y: T\")\n    .Attr       (\"T: {float, half}\")\n    .Attr       (\"upx: int = 1\")\n    .Attr       (\"upy: int = 1\")\n    .Attr       (\"downx: int = 1\")\n    .Attr       (\"downy: int = 1\")\n    .Attr       (\"padx0: int = 0\")\n    .Attr       (\"padx1: int = 0\")\n    .Attr       (\"pady0: int = 0\")\n    .Attr       (\"pady1: int = 0\");\nREGISTER_KERNEL_BUILDER(Name(\"UpFirDn2D\").Device(DEVICE_GPU).TypeConstraint<float>(\"T\"), UpFirDn2DOp<float>);\nREGISTER_KERNEL_BUILDER(Name(\"UpFirDn2D\").Device(DEVICE_GPU).TypeConstraint<Eigen::half>(\"T\"), UpFirDn2DOp<Eigen::half>);\n\n//------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/tflib/ops/upfirdn_2d.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Custom TensorFlow ops for efficient resampling of 2D images.\"\"\"\n\nimport os\nimport numpy as np\nimport tensorflow as tf\nfrom .. import custom_ops\n\ndef _get_plugin():\n    return custom_ops.get_plugin(os.path.splitext(__file__)[0] + '.cu')\n\n#----------------------------------------------------------------------------\n\ndef upfirdn_2d(x, k, upx=1, upy=1, downx=1, downy=1, padx0=0, padx1=0, pady0=0, pady1=0, impl='cuda'):\n    r\"\"\"Pad, upsample, FIR filter, and downsample a batch of 2D images.\n\n    Accepts a batch of 2D images of the shape `[majorDim, inH, inW, minorDim]`\n    and performs the following operations for each image, batched across\n    `majorDim` and `minorDim`:\n\n    1. Pad the image with zeros by the specified number of pixels on each side\n       (`padx0`, `padx1`, `pady0`, `pady1`). Specifying a negative value\n       corresponds to cropping the image.\n\n    2. Upsample the image by inserting the zeros after each pixel (`upx`, `upy`).\n\n    3. Convolve the image with the specified 2D FIR filter (`k`), shrinking the\n       image so that the footprint of all output pixels lies within the input image.\n\n    4. Downsample the image by throwing away pixels (`downx`, `downy`).\n\n    This sequence of operations bears close resemblance to scipy.signal.upfirdn().\n    The fused op is considerably more efficient than performing the same calculation\n    using standard TensorFlow ops. It supports gradients of arbitrary order.\n\n    Args:\n        x:      Input tensor of the shape `[majorDim, inH, inW, minorDim]`.\n        k:      2D FIR filter of the shape `[firH, firW]`.\n        upx:    Integer upsampling factor along the X-axis (default: 1).\n        upy:    Integer upsampling factor along the Y-axis (default: 1).\n        downx:  Integer downsampling factor along the X-axis (default: 1).\n        downy:  Integer downsampling factor along the Y-axis (default: 1).\n        padx0:  Number of pixels to pad on the left side (default: 0).\n        padx1:  Number of pixels to pad on the right side (default: 0).\n        pady0:  Number of pixels to pad on the top side (default: 0).\n        pady1:  Number of pixels to pad on the bottom side (default: 0).\n        impl:   Name of the implementation to use. Can be `\"ref\"` or `\"cuda\"` (default).\n\n    Returns:\n        Tensor of the shape `[majorDim, outH, outW, minorDim]`, and same datatype as `x`.\n    \"\"\"\n\n    impl_dict = {\n        'ref':  _upfirdn_2d_ref,\n        'cuda': _upfirdn_2d_ref if 'TPU_NAME' in os.environ or 'NO_NVCC' in os.environ else _upfirdn_2d_cuda,\n    }\n    return impl_dict[impl](x=x, k=k, upx=upx, upy=upy, downx=downx, downy=downy, padx0=padx0, padx1=padx1, pady0=pady0, pady1=pady1)\n\n#----------------------------------------------------------------------------\n\ndef _upfirdn_2d_ref(x, k, upx, upy, downx, downy, padx0, padx1, pady0, pady1):\n    \"\"\"Slow reference implementation of `upfirdn_2d()` using standard TensorFlow ops.\"\"\"\n\n    x = tf.convert_to_tensor(x)\n    k = np.asarray(k, dtype=np.float32)\n    assert x.shape.rank == 4\n    inH = x.shape[1].value\n    inW = x.shape[2].value\n    minorDim = _shape(x, 3)\n    kernelH, kernelW = k.shape\n    assert inW >= 1 and inH >= 1\n    assert kernelW >= 1 and kernelH >= 1\n    assert isinstance(upx, int) and isinstance(upy, int)\n    assert isinstance(downx, int) and isinstance(downy, int)\n    assert isinstance(padx0, int) and isinstance(padx1, int)\n    assert isinstance(pady0, int) and isinstance(pady1, int)\n\n    # Upsample (insert zeros).\n    x = tf.reshape(x, [-1, inH, 1, inW, 1, minorDim])\n    x = tf.pad(x, [[0, 0], [0, 0], [0, upy - 1], [0, 0], [0, upx - 1], [0, 0]])\n    x = tf.reshape(x, [-1, inH * upy, inW * upx, minorDim])\n\n    # Pad (crop if negative).\n    x = tf.pad(x, [[0, 0], [max(pady0, 0), max(pady1, 0)], [max(padx0, 0), max(padx1, 0)], [0, 0]])\n    x = x[:, max(-pady0, 0) : x.shape[1].value - max(-pady1, 0), max(-padx0, 0) : x.shape[2].value - max(-padx1, 0), :]\n\n    # Convolve with filter.\n    x = tf.transpose(x, [0, 3, 1, 2])\n    x = tf.reshape(x, [-1, 1, inH * upy + pady0 + pady1, inW * upx + padx0 + padx1])\n    w = tf.constant(k[::-1, ::-1, np.newaxis, np.newaxis], dtype=x.dtype)\n    x = tf.nn.conv2d(x, w, strides=[1,1,1,1], padding='VALID', data_format='NCHW')\n    x = tf.reshape(x, [-1, minorDim, inH * upy + pady0 + pady1 - kernelH + 1, inW * upx + padx0 + padx1 - kernelW + 1])\n    x = tf.transpose(x, [0, 2, 3, 1])\n\n    # Downsample (throw away pixels).\n    return x[:, ::downy, ::downx, :]\n\n#----------------------------------------------------------------------------\n\ndef _upfirdn_2d_cuda(x, k, upx, upy, downx, downy, padx0, padx1, pady0, pady1):\n    \"\"\"Fast CUDA implementation of `upfirdn_2d()` using custom ops.\"\"\"\n\n    x = tf.convert_to_tensor(x)\n    k = np.asarray(k, dtype=np.float32)\n    majorDim, inH, inW, minorDim = x.shape.as_list()\n    kernelH, kernelW = k.shape\n    assert inW >= 1 and inH >= 1\n    assert kernelW >= 1 and kernelH >= 1\n    assert isinstance(upx, int) and isinstance(upy, int)\n    assert isinstance(downx, int) and isinstance(downy, int)\n    assert isinstance(padx0, int) and isinstance(padx1, int)\n    assert isinstance(pady0, int) and isinstance(pady1, int)\n\n    outW = (inW * upx + padx0 + padx1 - kernelW) // downx + 1\n    outH = (inH * upy + pady0 + pady1 - kernelH) // downy + 1\n    assert outW >= 1 and outH >= 1\n\n    kc = tf.constant(k, dtype=x.dtype)\n    gkc = tf.constant(k[::-1, ::-1], dtype=x.dtype)\n    gpadx0 = kernelW - padx0 - 1\n    gpady0 = kernelH - pady0 - 1\n    gpadx1 = inW * upx - outW * downx + padx0 - upx + 1\n    gpady1 = inH * upy - outH * downy + pady0 - upy + 1\n\n    @tf.custom_gradient\n    def func(x):\n        y = _get_plugin().up_fir_dn2d(x=x, k=kc, upx=upx, upy=upy, downx=downx, downy=downy, padx0=padx0, padx1=padx1, pady0=pady0, pady1=pady1)\n        y.set_shape([majorDim, outH, outW, minorDim])\n        @tf.custom_gradient\n        def grad(dy):\n            dx = _get_plugin().up_fir_dn2d(x=dy, k=gkc, upx=downx, upy=downy, downx=upx, downy=upy, padx0=gpadx0, padx1=gpadx1, pady0=gpady0, pady1=gpady1)\n            dx.set_shape([majorDim, inH, inW, minorDim])\n            return dx, func\n        return y, grad\n    return func(x)\n\n#----------------------------------------------------------------------------\n\ndef filter_2d(x, k, gain=1, data_format='NCHW', impl='cuda'):\n    r\"\"\"Filter a batch of 2D images with the given FIR filter.\n\n    Accepts a batch of 2D images of the shape `[N, C, H, W]` or `[N, H, W, C]`\n    and filters each image with the given filter. The filter is normalized so that\n    if the input pixels are constant, they will be scaled by the specified `gain`.\n    Pixels outside the image are assumed to be zero.\n\n    Args:\n        x:            Input tensor of the shape `[N, C, H, W]` or `[N, H, W, C]`.\n        k:            FIR filter of the shape `[firH, firW]` or `[firN]` (separable).\n        gain:         Scaling factor for signal magnitude (default: 1.0).\n        data_format:  `'NCHW'` or `'NHWC'` (default: `'NCHW'`).\n        impl:         Name of the implementation to use. Can be `\"ref\"` or `\"cuda\"` (default).\n\n    Returns:\n        Tensor of the same shape and datatype as `x`.\n    \"\"\"\n\n    k = _setup_kernel(k) * gain\n    p = k.shape[0] - 1\n    return _simple_upfirdn_2d(x, k, pad0=(p+1)//2, pad1=p//2, data_format=data_format, impl=impl)\n\n#----------------------------------------------------------------------------\n\ndef upsample_2d(x, k=None, factor=2, gain=1, data_format='NCHW', impl='cuda'):\n    r\"\"\"Upsample a batch of 2D images with the given filter.\n\n    Accepts a batch of 2D images of the shape `[N, C, H, W]` or `[N, H, W, C]`\n    and upsamples each image with the given filter. The filter is normalized so that\n    if the input pixels are constant, they will be scaled by the specified `gain`.\n    Pixels outside the image are assumed to be zero, and the filter is padded with\n    zeros so that its shape is a multiple of the upsampling factor.\n\n    Args:\n        x:            Input tensor of the shape `[N, C, H, W]` or `[N, H, W, C]`.\n        k:            FIR filter of the shape `[firH, firW]` or `[firN]` (separable).\n                      The default is `[1] * factor`, which corresponds to nearest-neighbor\n                      upsampling.\n        factor:       Integer upsampling factor (default: 2).\n        gain:         Scaling factor for signal magnitude (default: 1.0).\n        data_format:  `'NCHW'` or `'NHWC'` (default: `'NCHW'`).\n        impl:         Name of the implementation to use. Can be `\"ref\"` or `\"cuda\"` (default).\n\n    Returns:\n        Tensor of the shape `[N, C, H * factor, W * factor]` or\n        `[N, H * factor, W * factor, C]`, and same datatype as `x`.\n    \"\"\"\n\n    assert isinstance(factor, int) and factor >= 1\n    if k is None:\n        k = [1] * factor\n    k = _setup_kernel(k) * (gain * (factor ** 2))\n    p = k.shape[0] - factor\n    return _simple_upfirdn_2d(x, k, up=factor, pad0=(p+1)//2+factor-1, pad1=p//2, data_format=data_format, impl=impl)\n\n#----------------------------------------------------------------------------\n\ndef downsample_2d(x, k=None, factor=2, gain=1, data_format='NCHW', impl='cuda'):\n    r\"\"\"Downsample a batch of 2D images with the given filter.\n\n    Accepts a batch of 2D images of the shape `[N, C, H, W]` or `[N, H, W, C]`\n    and downsamples each image with the given filter. The filter is normalized so that\n    if the input pixels are constant, they will be scaled by the specified `gain`.\n    Pixels outside the image are assumed to be zero, and the filter is padded with\n    zeros so that its shape is a multiple of the downsampling factor.\n\n    Args:\n        x:            Input tensor of the shape `[N, C, H, W]` or `[N, H, W, C]`.\n        k:            FIR filter of the shape `[firH, firW]` or `[firN]` (separable).\n                      The default is `[1] * factor`, which corresponds to average pooling.\n        factor:       Integer downsampling factor (default: 2).\n        gain:         Scaling factor for signal magnitude (default: 1.0).\n        data_format:  `'NCHW'` or `'NHWC'` (default: `'NCHW'`).\n        impl:         Name of the implementation to use. Can be `\"ref\"` or `\"cuda\"` (default).\n\n    Returns:\n        Tensor of the shape `[N, C, H // factor, W // factor]` or\n        `[N, H // factor, W // factor, C]`, and same datatype as `x`.\n    \"\"\"\n\n    assert isinstance(factor, int) and factor >= 1\n    if k is None:\n        k = [1] * factor\n    k = _setup_kernel(k) * gain\n    p = k.shape[0] - factor\n    return _simple_upfirdn_2d(x, k, down=factor, pad0=(p+1)//2, pad1=p//2, data_format=data_format, impl=impl)\n\n#----------------------------------------------------------------------------\n\ndef upsample_conv_2d(x, w, k=None, factor=2, gain=1, data_format='NCHW', impl='cuda'):\n    r\"\"\"Fused `upsample_2d()` followed by `tf.nn.conv2d()`.\n\n    Padding is performed only once at the beginning, not between the operations.\n    The fused op is considerably more efficient than performing the same calculation\n    using standard TensorFlow ops. It supports gradients of arbitrary order.\n\n    Args:\n        x:            Input tensor of the shape `[N, C, H, W]` or `[N, H, W, C]`.\n        w:            Weight tensor of the shape `[filterH, filterW, inChannels, outChannels]`.\n                      Grouped convolution can be performed by `inChannels = x.shape[0] // numGroups`.\n        k:            FIR filter of the shape `[firH, firW]` or `[firN]` (separable).\n                      The default is `[1] * factor`, which corresponds to nearest-neighbor\n                      upsampling.\n        factor:       Integer upsampling factor (default: 2).\n        gain:         Scaling factor for signal magnitude (default: 1.0).\n        data_format:  `'NCHW'` or `'NHWC'` (default: `'NCHW'`).\n        impl:         Name of the implementation to use. Can be `\"ref\"` or `\"cuda\"` (default).\n\n    Returns:\n        Tensor of the shape `[N, C, H * factor, W * factor]` or\n        `[N, H * factor, W * factor, C]`, and same datatype as `x`.\n    \"\"\"\n\n    assert isinstance(factor, int) and factor >= 1\n\n    # Check weight shape.\n    w = tf.convert_to_tensor(w)\n    assert w.shape.rank == 4\n    convH = w.shape[0].value\n    convW = w.shape[1].value\n    inC = _shape(w, 2)\n    outC = _shape(w, 3)\n    assert convW == convH\n\n    # Setup filter kernel.\n    if k is None:\n        k = [1] * factor\n    k = _setup_kernel(k) * (gain * (factor ** 2))\n    p = (k.shape[0] - factor) - (convW - 1)\n\n    # Determine data dimensions.\n    if data_format == 'NCHW':\n        stride = [1, 1, factor, factor]\n        output_shape = [_shape(x, 0), outC, (_shape(x, 2) - 1) * factor + convH, (_shape(x, 3) - 1) * factor + convW]\n        num_groups = _shape(x, 1) // inC\n    else:\n        stride = [1, factor, factor, 1]\n        output_shape = [_shape(x, 0), (_shape(x, 1) - 1) * factor + convH, (_shape(x, 2) - 1) * factor + convW, outC]\n        num_groups = _shape(x, 3) // inC\n\n    # Transpose weights.\n    w = tf.reshape(w, [convH, convW, inC, num_groups, -1])\n    w = tf.transpose(w[::-1, ::-1], [0, 1, 4, 3, 2])\n    w = tf.reshape(w, [convH, convW, -1, num_groups * inC])\n\n    # Execute.\n    x = tf.nn.conv2d_transpose(x, w, output_shape=output_shape, strides=stride, padding='VALID', data_format=data_format)\n    return _simple_upfirdn_2d(x, k, pad0=(p+1)//2+factor-1, pad1=p//2+1, data_format=data_format, impl=impl)\n\n#----------------------------------------------------------------------------\n\ndef conv_downsample_2d(x, w, k=None, factor=2, gain=1, data_format='NCHW', impl='cuda'):\n    r\"\"\"Fused `tf.nn.conv2d()` followed by `downsample_2d()`.\n\n    Padding is performed only once at the beginning, not between the operations.\n    The fused op is considerably more efficient than performing the same calculation\n    using standard TensorFlow ops. It supports gradients of arbitrary order.\n\n    Args:\n        x:            Input tensor of the shape `[N, C, H, W]` or `[N, H, W, C]`.\n        w:            Weight tensor of the shape `[filterH, filterW, inChannels, outChannels]`.\n                      Grouped convolution can be performed by `inChannels = x.shape[0] // numGroups`.\n        k:            FIR filter of the shape `[firH, firW]` or `[firN]` (separable).\n                      The default is `[1] * factor`, which corresponds to average pooling.\n        factor:       Integer downsampling factor (default: 2).\n        gain:         Scaling factor for signal magnitude (default: 1.0).\n        data_format:  `'NCHW'` or `'NHWC'` (default: `'NCHW'`).\n        impl:         Name of the implementation to use. Can be `\"ref\"` or `\"cuda\"` (default).\n\n    Returns:\n        Tensor of the shape `[N, C, H // factor, W // factor]` or\n        `[N, H // factor, W // factor, C]`, and same datatype as `x`.\n    \"\"\"\n\n    assert isinstance(factor, int) and factor >= 1\n    w = tf.convert_to_tensor(w)\n    convH, convW, _inC, _outC = w.shape.as_list()\n    assert convW == convH\n    if k is None:\n        k = [1] * factor\n    k = _setup_kernel(k) * gain\n    p = (k.shape[0] - factor) + (convW - 1)\n    if data_format == 'NCHW':\n        s = [1, 1, factor, factor]\n    else:\n        s = [1, factor, factor, 1]\n    x = _simple_upfirdn_2d(x, k, pad0=(p+1)//2, pad1=p//2, data_format=data_format, impl=impl)\n    return tf.nn.conv2d(x, w, strides=s, padding='VALID', data_format=data_format)\n\n#----------------------------------------------------------------------------\n# Internal helper funcs.\n\ndef _shape(tf_expr, dim_idx):\n    if tf_expr.shape.rank is not None:\n        dim = tf_expr.shape[dim_idx].value\n        if dim is not None:\n            return dim\n    return tf.shape(tf_expr)[dim_idx]\n\ndef _setup_kernel(k):\n    k = np.asarray(k, dtype=np.float32)\n    if k.ndim == 1:\n        k = np.outer(k, k)\n    k /= np.sum(k)\n    assert k.ndim == 2\n    assert k.shape[0] == k.shape[1]\n    return k\n\ndef _simple_upfirdn_2d(x, k, up=1, down=1, pad0=0, pad1=0, data_format='NCHW', impl='cuda'):\n    assert data_format in ['NCHW', 'NHWC']\n    assert x.shape.rank == 4\n    y = x\n    if data_format == 'NCHW':\n        y = tf.reshape(y, [-1, _shape(y, 2), _shape(y, 3), 1])\n    y = upfirdn_2d(y, k, upx=up, upy=up, downx=down, downy=down, padx0=pad0, padx1=pad1, pady0=pad0, pady1=pad1, impl=impl)\n    if data_format == 'NCHW':\n        y = tf.reshape(y, [-1, _shape(x, 1), _shape(y, 1), _shape(y, 2)])\n    return y\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/tflib/optimizer.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Helper wrapper for a Tensorflow optimizer.\"\"\"\n\nimport numpy as np\nimport tensorflow as tf\nimport tflex\n\nfrom collections import OrderedDict\nfrom typing import List, Union\n\nfrom . import autosummary\nfrom . import tfutil\nfrom .. import util\n\nfrom .tfutil import TfExpression, TfExpressionEx\n\ntry:\n    # TensorFlow 1.13\n    from tensorflow.python.ops import nccl_ops\nexcept:\n    # Older TensorFlow versions\n    import tensorflow.contrib.nccl as nccl_ops\n\nfrom tensorflow.python.framework import ops as tf_ops\n\ndef all_sum_plain(g, colocate=False, *args, **kws):\n  r = []\n  for i in range(len(g)):\n    if colocate:\n      with tf_ops.colocate_with(g[i]):\n        r.append(tf.add_n(g))\n    else:\n      r.append(tf.add_n(g))\n  return r\n\ntry:\n    # TensorFlow 1.13\n    from tensorflow.python.ops import nccl_ops\nexcept:\n    # Older TensorFlow versions\n    import tensorflow.contrib.nccl as nccl_ops\n\ndef all_sum_gpu(g, *args, **kws):\n  return nccl_ops.all_sum(g, *args, **kws)\n\nfrom tensorflow.python.tpu.ops import tpu_ops\n\n#def all_sum_tpu(g, *args, **kws):\n#  g = tpu_ops.cross_replica_sum(g, *args, **kws)\n#  return [g[i] for i in range(shape_list(g)[0])]\n\ndef all_sum_tpu(g, colocate=True, *args, **kws):\n  #import pdb\n  #pdb.set_trace()\n  #r = tf.reduce_sum(g)\n  #r = tf.reduce_sum(tf.stack(g), axis=0, keepdims=True)\n  #r = tpu_ops.cross_replica_sum(g, *args, **kws)\n  #r = [r[i] for i in range(shape_list(r)[0])]\n  return all_sum_plain(g, colocate=colocate, *args, **kws)\n\ndef all_sum(cores, g, colocate=True, *args, **kws):\n  if any([':TPU:' in x for x in cores.keys()]):\n    return all_sum_tpu(g, colocate=colocate, *args, **kws)\n  elif any([':GPU:' in x for x in cores.keys()]):\n    return all_sum_gpu(g, *args, **kws)\n  else:\n    return all_sum_cpu(g, *args, **kws)\n\n\nclass Optimizer:\n    \"\"\"A Wrapper for tf.train.Optimizer.\n\n    Automatically takes care of:\n    - Gradient averaging for multi-GPU training.\n    - Gradient accumulation for arbitrarily large minibatches.\n    - Dynamic loss scaling and typecasts for FP16 training.\n    - Ignoring corrupted gradients that contain NaNs/Infs.\n    - Reporting statistics.\n    - Well-chosen default settings.\n    \"\"\"\n\n    def __init__(self,\n        name:                   str             = \"Train\",                  # Name string that will appear in TensorFlow graph.\n        tf_optimizer:           str             = \"tf.train.AdamOptimizer\", # Underlying optimizer class.\n        learning_rate:          TfExpressionEx  = 0.001,                    # Learning rate. Can vary over time.\n        minibatch_multiplier:   TfExpressionEx  = None,                     # Treat N consecutive minibatches as one by accumulating gradients.\n        share:                  \"Optimizer\"     = None,                     # Share internal state with a previously created optimizer?\n        use_loss_scaling:       bool            = False,                    # Enable dynamic loss scaling for robust mixed-precision training?\n        loss_scaling_init:      float           = 64.0,                     # Log2 of initial loss scaling factor.\n        loss_scaling_inc:       float           = 0.0005,                   # Log2 of per-minibatch loss scaling increment when there is no overflow.\n        loss_scaling_dec:       float           = 1.0,                      # Log2 of per-minibatch loss scaling decrement when there is an overflow.\n        report_mem_usage:       bool            = False,                    # Report fine-grained memory usage statistics in TensorBoard?\n        cross_shard:            bool            = False,                    # Use CrossShardOptimizer?\n        **kwargs):\n\n        # Public fields.\n        self.name                   = name\n        self.learning_rate          = learning_rate\n        self.minibatch_multiplier   = minibatch_multiplier\n        self.id                     = self.name.replace(\"/\", \".\")\n        self.scope                  = tf.get_default_graph().unique_name(self.id)\n        self.optimizer_class        = util.get_obj_by_name(tf_optimizer)\n        self.optimizer_kwargs       = dict(kwargs)\n        self.use_loss_scaling       = use_loss_scaling\n        self.loss_scaling_init      = loss_scaling_init\n        self.loss_scaling_inc       = loss_scaling_inc\n        self.loss_scaling_dec       = loss_scaling_dec\n\n        # Private fields.\n        self._updates_applied       = False\n        self._devices               = OrderedDict() # device_name => EasyDict()\n        self._shared_optimizers     = OrderedDict() # device_name => optimizer_class\n        self._gradient_shapes       = None          # [shape, ...]\n        self._report_mem_usage      = report_mem_usage\n        self._cross_shard           = cross_shard\n\n        # Validate arguments.\n        assert callable(self.optimizer_class)\n\n        # Share internal state if requested.\n        if share is not None:\n            assert isinstance(share, Optimizer)\n            assert self.optimizer_class is share.optimizer_class\n            assert self.learning_rate is share.learning_rate\n            assert self.optimizer_kwargs == share.optimizer_kwargs\n            self._shared_optimizers = share._shared_optimizers # pylint: disable=protected-access\n\n    def _get_device(self, device_name: str):\n        \"\"\"Get internal state for the given TensorFlow device.\"\"\"\n        tfutil.assert_tf_initialized()\n        if device_name in self._devices:\n            return self._devices[device_name]\n\n        # Initialize fields.\n        device = util.EasyDict()\n        device.name             = device_name\n        device.optimizer        = None          # Underlying optimizer:     optimizer_class\n        device.loss_scaling_var = None          # Log2 of loss scaling:     tf.Variable\n        device.grad_raw         = OrderedDict() # Raw gradients:            var => [grad, ...]\n        device.grad_clean       = OrderedDict() # Clean gradients:          var => grad\n        device.grad_acc_vars    = OrderedDict() # Accumulation sums:        var => tf.Variable\n        device.grad_acc_count   = None          # Accumulation counter:     tf.Variable\n        device.grad_acc         = OrderedDict() # Accumulated gradients:    var => grad\n\n        # Setup TensorFlow objects.\n        with tfutil.absolute_name_scope(self.scope + \"/Devices\"), tflex.device(device_name), tf.control_dependencies(None):\n            if device_name not in self._shared_optimizers:\n                optimizer_name = self.scope.replace(\"/\", \"_\") + \"_opt%d\" % len(self._shared_optimizers)\n                self._shared_optimizers[device_name] = self.optimizer_class(name=optimizer_name, learning_rate=self.learning_rate, **self.optimizer_kwargs)\n                if self._cross_shard or 'TPU_REPLICATED_CORE' in device_name:\n                    print('Using cross-shard optimizer for %s' % device_name)\n                    self._shared_optimizers[device_name] = tf.contrib.tpu.CrossShardOptimizer(self._shared_optimizers[device_name])\n            device.optimizer = self._shared_optimizers[device_name]\n            if self.use_loss_scaling:\n                device.loss_scaling_var = tf.Variable(np.float32(self.loss_scaling_init), trainable=False, name=\"loss_scaling_var\")\n\n        # Register device.\n        self._devices[device_name] = device\n        return device\n\n    def register_gradients(self, loss: TfExpression, trainable_vars: Union[List, dict]) -> None:\n        \"\"\"Register the gradients of the given loss function with respect to the given variables.\n        Intended to be called once per GPU.\"\"\"\n        tfutil.assert_tf_initialized()\n        assert not self._updates_applied\n        device = self._get_device(loss.device)\n\n        # Validate trainables.\n        if isinstance(trainable_vars, dict):\n            trainable_vars = list(trainable_vars.values())  # allow passing in Network.trainables as vars\n        assert isinstance(trainable_vars, list) and len(trainable_vars) >= 1\n        assert all(tfutil.is_tf_expression(expr) for expr in trainable_vars + [loss])\n        assert all(var.device == device.name for var in trainable_vars)\n\n        # Validate shapes.\n        if self._gradient_shapes is None:\n            self._gradient_shapes = [var.shape.as_list() for var in trainable_vars]\n        assert len(trainable_vars) == len(self._gradient_shapes)\n        assert all(var.shape.as_list() == var_shape for var, var_shape in zip(trainable_vars, self._gradient_shapes))\n\n        # Report memory usage if requested.\n        deps = []\n        if self._report_mem_usage:\n            self._report_mem_usage = False\n            try:\n                with tf.name_scope(self.id + '_mem'), tflex.device(device.name), tf.control_dependencies([loss]):\n                    deps.append(autosummary.autosummary(self.id + \"/mem_usage_gb\", tf.contrib.memory_stats.BytesInUse() / 2**30))\n            except tf.errors.NotFoundError:\n                pass\n\n        # Compute gradients.\n        with tf.name_scope(self.id + \"_grad\"), tflex.device(device.name), tf.control_dependencies(deps):\n            loss = self.apply_loss_scaling(tf.cast(loss, tf.float32))\n            gate = tf.train.Optimizer.GATE_NONE  # disable gating to reduce memory usage\n            grad_list = device.optimizer.compute_gradients(loss=loss, var_list=trainable_vars, gate_gradients=gate)\n\n        # Register gradients.\n        for grad, var in grad_list:\n            if var not in device.grad_raw:\n                device.grad_raw[var] = []\n            device.grad_raw[var].append(grad)\n\n    def apply_updates(self, allow_no_op: bool = False) -> tf.Operation:\n        \"\"\"Construct training op to update the registered variables based on their gradients.\"\"\"\n        tfutil.assert_tf_initialized()\n        assert not self._updates_applied\n        self._updates_applied = True\n        all_ops = []\n\n        # Check for no-op.\n        if allow_no_op and len(self._devices) == 0:\n            with tfutil.absolute_name_scope(self.scope):\n                return tf.no_op(name='TrainingOp')\n\n        # Clean up gradients.\n        for device_idx, device in enumerate(self._devices.values()):\n            with tfutil.absolute_name_scope(self.scope + \"/Clean%d\" % device_idx), tflex.device(device.name):\n                for var, grad in device.grad_raw.items():\n\n                    # Filter out disconnected gradients and convert to float32.\n                    grad = [g for g in grad if g is not None]\n                    grad = [tf.cast(g, tf.float32) for g in grad]\n\n                    # Sum within the device.\n                    if len(grad) == 0:\n                        grad = tf.zeros(var.shape)  # No gradients => zero.\n                    elif len(grad) == 1:\n                        grad = grad[0]              # Single gradient => use as is.\n                    else:\n                        grad = tf.add_n(grad)       # Multiple gradients => sum.\n\n                    # Scale as needed.\n                    scale = 1.0 / len(device.grad_raw[var]) / len(self._devices)\n                    scale = tf.constant(scale, dtype=tf.float32, name=\"scale\")\n                    if self.minibatch_multiplier is not None:\n                        scale /= tf.cast(self.minibatch_multiplier, tf.float32)\n                    scale = self.undo_loss_scaling(scale)\n                    device.grad_clean[var] = grad * scale\n\n        # Sum gradients across devices.\n        if len(self._devices) > 1:\n            with tfutil.absolute_name_scope(self.scope + \"/Broadcast\"), tflex.device(None):\n                for all_vars in zip(*[device.grad_clean.keys() for device in self._devices.values()]):\n                    if len(all_vars) > 0 and all(dim > 0 for dim in all_vars[0].shape.as_list()): # NCCL does not support zero-sized tensors.\n                        all_grads = [device.grad_clean[var] for device, var in zip(self._devices.values(), all_vars)]\n                        all_grads = all_sum(self._devices, all_grads)\n                        for device, var, grad in zip(self._devices.values(), all_vars, all_grads):\n                            device.grad_clean[var] = grad\n\n        # Apply updates separately on each device.\n        for device_idx, device in enumerate(self._devices.values()):\n            with tfutil.absolute_name_scope(self.scope + \"/Apply%d\" % device_idx), tflex.device(device.name):\n                # pylint: disable=cell-var-from-loop\n\n                # Accumulate gradients over time.\n                if self.minibatch_multiplier is None:\n                    acc_ok = tf.constant(True, name='acc_ok')\n                    device.grad_acc = OrderedDict(device.grad_clean)\n                else:\n                    # Create variables.\n                    with tf.control_dependencies(None):\n                        for var in device.grad_clean.keys():\n                            device.grad_acc_vars[var] = tf.Variable(tf.zeros(var.shape), trainable=False, name=\"grad_acc_var\")\n                        device.grad_acc_count = tf.Variable(tf.zeros([]), trainable=False, name=\"grad_acc_count\")\n\n                    # Track counter.\n                    count_cur = device.grad_acc_count + 1.0\n                    count_inc_op = lambda: tf.assign(device.grad_acc_count, count_cur)\n                    count_reset_op = lambda: tf.assign(device.grad_acc_count, tf.zeros([]))\n                    acc_ok = (count_cur >= tf.cast(self.minibatch_multiplier, tf.float32))\n                    all_ops.append(tf.cond(acc_ok, count_reset_op, count_inc_op))\n\n                    # Track gradients.\n                    for var, grad in device.grad_clean.items():\n                        acc_var = device.grad_acc_vars[var]\n                        acc_cur = acc_var + grad\n                        device.grad_acc[var] = acc_cur\n                        with tf.control_dependencies([acc_cur]):\n                            acc_inc_op = lambda: tf.assign(acc_var, acc_cur)\n                            acc_reset_op = lambda: tf.assign(acc_var, tf.zeros(var.shape))\n                            all_ops.append(tf.cond(acc_ok, acc_reset_op, acc_inc_op))\n\n                # No overflow => apply gradients.\n                all_ok = tf.reduce_all(tf.stack([acc_ok] + [tf.reduce_all(tf.is_finite(g)) for g in device.grad_acc.values()]))\n                apply_op = lambda: device.optimizer.apply_gradients([(tf.cast(grad, var.dtype), var) for var, grad in device.grad_acc.items()])\n                all_ops.append(tf.cond(all_ok, apply_op, tf.no_op))\n\n                # Adjust loss scaling.\n                if self.use_loss_scaling:\n                    ls_inc_op = lambda: tf.assign_add(device.loss_scaling_var, self.loss_scaling_inc)\n                    ls_dec_op = lambda: tf.assign_sub(device.loss_scaling_var, self.loss_scaling_dec)\n                    ls_update_op = lambda: tf.group(tf.cond(all_ok, ls_inc_op, ls_dec_op))\n                    all_ops.append(tf.cond(acc_ok, ls_update_op, tf.no_op))\n\n                # Last device => report statistics.\n                if device_idx == len(self._devices) - 1:\n                    all_ops.append(autosummary.autosummary(self.id + \"/learning_rate\", self.learning_rate))\n                    all_ops.append(autosummary.autosummary(self.id + \"/overflow_frequency\", tf.where(all_ok, 0, 1), condition=acc_ok))\n                    if self.use_loss_scaling:\n                        all_ops.append(autosummary.autosummary(self.id + \"/loss_scaling_log2\", device.loss_scaling_var))\n\n        def finalize():\n            # Initialize variables.\n            self.reset_optimizer_state()\n            if self.use_loss_scaling:\n                tfutil.init_uninitialized_vars([device.loss_scaling_var for device in self._devices.values()])\n            if self.minibatch_multiplier is not None:\n                tfutil.run([var.initializer for device in self._devices.values() for var in list(device.grad_acc_vars.values()) + [device.grad_acc_count]])\n\n        # Group everything into a single op.\n        with tfutil.absolute_name_scope(self.scope):\n            return tf.group(*all_ops, name=\"TrainingOp\"), finalize\n\n    def reset_optimizer_state(self) -> None:\n        \"\"\"Reset internal state of the underlying optimizer.\"\"\"\n        tfutil.assert_tf_initialized()\n        tfutil.run([var.initializer for device in self._devices.values() for var in device.optimizer.variables()])\n\n    def get_loss_scaling_var(self, device: str) -> Union[tf.Variable, None]:\n        \"\"\"Get or create variable representing log2 of the current dynamic loss scaling factor.\"\"\"\n        return self._get_device(device).loss_scaling_var\n\n    def apply_loss_scaling(self, value: TfExpression) -> TfExpression:\n        \"\"\"Apply dynamic loss scaling for the given expression.\"\"\"\n        assert tfutil.is_tf_expression(value)\n        if not self.use_loss_scaling:\n            return value\n        return value * tfutil.exp2(self.get_loss_scaling_var(value.device))\n\n    def undo_loss_scaling(self, value: TfExpression) -> TfExpression:\n        \"\"\"Undo the effect of dynamic loss scaling for the given expression.\"\"\"\n        assert tfutil.is_tf_expression(value)\n        if not self.use_loss_scaling:\n            return value\n        return value * tfutil.exp2(-self.get_loss_scaling_var(value.device)) # pylint: disable=invalid-unary-operand-type\n\n\nclass SimpleAdam:\n    \"\"\"Simplified version of tf.train.AdamOptimizer that behaves identically when used with dnnlib.tflib.Optimizer.\"\"\"\n\n    def __init__(self, name=\"Adam\", learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-8):\n        self.name = name\n        self.learning_rate = learning_rate\n        self.beta1 = beta1\n        self.beta2 = beta2\n        self.epsilon = epsilon\n        self.all_state_vars = []\n\n    def variables(self):\n        return self.all_state_vars\n\n    def compute_gradients(self, loss, var_list, gate_gradients=tf.train.Optimizer.GATE_NONE):\n        assert gate_gradients == tf.train.Optimizer.GATE_NONE\n        return list(zip(tf.gradients(loss, var_list), var_list))\n\n    def apply_gradients(self, grads_and_vars):\n        with tf.name_scope(self.name):\n            state_vars = []\n            update_ops = []\n\n            # Adjust learning rate to deal with startup bias.\n            with tf.control_dependencies(None):\n                b1pow_var = tf.Variable(dtype=tf.float32, initial_value=1, trainable=False)\n                b2pow_var = tf.Variable(dtype=tf.float32, initial_value=1, trainable=False)\n                state_vars += [b1pow_var, b2pow_var]\n            b1pow_new = b1pow_var * self.beta1\n            b2pow_new = b2pow_var * self.beta2\n            update_ops += [tf.assign(b1pow_var, b1pow_new), tf.assign(b2pow_var, b2pow_new)]\n            lr_new = self.learning_rate * tf.sqrt(1 - b2pow_new) / (1 - b1pow_new)\n\n            # Construct ops to update each variable.\n            for grad, var in grads_and_vars:\n                with tf.control_dependencies(None):\n                    m_var = tf.Variable(dtype=tf.float32, initial_value=tf.zeros_like(var), trainable=False)\n                    v_var = tf.Variable(dtype=tf.float32, initial_value=tf.zeros_like(var), trainable=False)\n                    state_vars += [m_var, v_var]\n                m_new = self.beta1 * m_var + (1 - self.beta1) * grad\n                v_new = self.beta2 * v_var + (1 - self.beta2) * tf.square(grad)\n                var_delta = lr_new * m_new / (tf.sqrt(v_new) + self.epsilon)\n                update_ops += [tf.assign(m_var, m_new), tf.assign(v_var, v_new), tf.assign_sub(var, var_delta)]\n\n            # Group everything together.\n            self.all_state_vars += state_vars\n            return tf.group(*update_ops)\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/tflib/tfutil.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Miscellaneous helper utils for Tensorflow.\"\"\"\n\nimport os\nimport numpy as np\nimport tensorflow as tf\nimport tflex\n\n# Silence deprecation warnings from TensorFlow 1.13 onwards\nimport logging\nlogging.getLogger('tensorflow').setLevel(logging.ERROR)\nimport tensorflow.contrib   # requires TensorFlow 1.x!\ntf.contrib = tensorflow.contrib\n\nfrom typing import Any, Iterable, List, Union\n\nTfExpression = Union[tf.Tensor, tf.Variable, tf.Operation]\n\"\"\"A type that represents a valid Tensorflow expression.\"\"\"\n\nTfExpressionEx = Union[TfExpression, int, float, np.ndarray]\n\"\"\"A type that can be converted to a valid Tensorflow expression.\"\"\"\n\n\ndef run(*args, **kwargs) -> Any:\n    \"\"\"Run the specified ops in the default session.\"\"\"\n    assert_tf_initialized()\n    return tf.get_default_session().run(*args, **kwargs)\n\n\ndef is_tf_expression(x: Any) -> bool:\n    \"\"\"Check whether the input is a valid Tensorflow expression, i.e., Tensorflow Tensor, Variable, or Operation.\"\"\"\n    return isinstance(x, (tf.Tensor, tf.Variable, tf.Operation))\n\n\ndef shape_to_list(shape: Iterable[tf.Dimension]) -> List[Union[int, None]]:\n    \"\"\"Convert a Tensorflow shape to a list of ints. Retained for backwards compatibility -- use TensorShape.as_list() in new code.\"\"\"\n    return [dim.value for dim in shape]\n\n\ndef flatten(x: TfExpressionEx) -> TfExpression:\n    \"\"\"Shortcut function for flattening a tensor.\"\"\"\n    with tf.name_scope(\"Flatten\"):\n        return tf.reshape(x, [-1])\n\n\ndef log2(x: TfExpressionEx) -> TfExpression:\n    \"\"\"Logarithm in base 2.\"\"\"\n    with tf.name_scope(\"Log2\"):\n        return tf.log(x) * np.float32(1.0 / np.log(2.0))\n\n\ndef exp2(x: TfExpressionEx) -> TfExpression:\n    \"\"\"Exponent in base 2.\"\"\"\n    with tf.name_scope(\"Exp2\"):\n        return tf.exp(x * np.float32(np.log(2.0)))\n\n\ndef lerp(a: TfExpressionEx, b: TfExpressionEx, t: TfExpressionEx) -> TfExpressionEx:\n    \"\"\"Linear interpolation.\"\"\"\n    with tf.name_scope(\"Lerp\"):\n        return a + (b - a) * t\n\n\ndef lerp_clip(a: TfExpressionEx, b: TfExpressionEx, t: TfExpressionEx) -> TfExpression:\n    \"\"\"Linear interpolation with clip.\"\"\"\n    with tf.name_scope(\"LerpClip\"):\n        return a + (b - a) * tf.clip_by_value(t, 0.0, 1.0)\n\n\ndef absolute_name_scope(scope: str) -> tf.name_scope:\n    \"\"\"Forcefully enter the specified name scope, ignoring any surrounding scopes.\"\"\"\n    return tf.name_scope(scope + \"/\")\n\n\ndef absolute_variable_scope(scope: str, **kwargs) -> tf.variable_scope:\n    \"\"\"Forcefully enter the specified variable scope, ignoring any surrounding scopes.\"\"\"\n    return tf.variable_scope(tf.VariableScope(name=scope, **kwargs), auxiliary_name_scope=False)\n\n\ndef _sanitize_tf_config(config_dict: dict = None) -> dict:\n    # Defaults.\n    cfg = dict()\n    cfg[\"rnd.np_random_seed\"]               = None      # Random seed for NumPy. None = keep as is.\n    cfg[\"rnd.tf_random_seed\"]               = \"auto\"    # Random seed for TensorFlow. 'auto' = derive from NumPy random state. None = keep as is.\n    cfg[\"env.TF_CPP_MIN_LOG_LEVEL\"]         = \"1\"       # 0 = Print all available debug info from TensorFlow. 1 = Print warnings and errors, but disable debug info.\n    cfg[\"graph_options.place_pruned_graph\"] = True      # False = Check that all ops are available on the designated device. True = Skip the check for ops that are not used.\n    cfg[\"gpu_options.allow_growth\"]         = True      # False = Allocate all GPU memory at the beginning. True = Allocate only as much GPU memory as needed.\n\n    # Remove defaults for environment variables that are already set.\n    for key in list(cfg):\n        fields = key.split(\".\")\n        if fields[0] == \"env\":\n            assert len(fields) == 2\n            if fields[1] in os.environ:\n                del cfg[key]\n\n    # User overrides.\n    if config_dict is not None:\n        cfg.update(config_dict)\n    return cfg\n\n\ndef init_tf(config_dict: dict = None) -> None:\n    \"\"\"Initialize TensorFlow session using good default settings.\"\"\"\n    # Skip if already initialized.\n    if tf.get_default_session() is not None:\n        return\n\n    # Setup config dict and random seeds.\n    cfg = _sanitize_tf_config(config_dict)\n    np_random_seed = cfg[\"rnd.np_random_seed\"]\n    if np_random_seed is not None:\n        np.random.seed(np_random_seed)\n    tf_random_seed = cfg[\"rnd.tf_random_seed\"]\n    if tf_random_seed == \"auto\":\n        tf_random_seed = np.random.randint(1 << 31)\n    if tf_random_seed is not None:\n        tf.set_random_seed(tf_random_seed)\n\n    # Setup environment variables.\n    for key, value in cfg.items():\n        fields = key.split(\".\")\n        if fields[0] == \"env\":\n            assert len(fields) == 2\n            os.environ[fields[1]] = str(value)\n\n    # Create default TensorFlow session.\n    create_session(cfg, force_as_default=True)\n\n\ndef assert_tf_initialized():\n    \"\"\"Check that TensorFlow session has been initialized.\"\"\"\n    if tf.get_default_session() is None:\n        raise RuntimeError(\"No default TensorFlow session found. Please call dnnlib.tflib.init_tf().\")\n\n\ndef create_session(config_dict: dict = None, force_as_default: bool = False) -> tf.Session:\n    \"\"\"Create tf.Session based on config dict.\"\"\"\n    # Setup TensorFlow config proto.\n    cfg = _sanitize_tf_config(config_dict)\n    config_proto = tf.ConfigProto()\n    for key, value in cfg.items():\n        fields = key.split(\".\")\n        if fields[0] not in [\"rnd\", \"env\"]:\n            obj = config_proto\n            for field in fields[:-1]:\n                obj = getattr(obj, field)\n            setattr(obj, fields[-1], value)\n\n    # Create session.\n    config_proto.allow_soft_placement = True\n    session = tflex.Session(config=config_proto)\n    if force_as_default:\n        # pylint: disable=protected-access\n        session._default_session = session.as_default()\n        session._default_session.enforce_nesting = False\n        session._default_session.__enter__()\n    return session\n\n\ndef init_uninitialized_vars(target_vars: List[tf.Variable] = None) -> None:\n    \"\"\"Initialize all tf.Variables that have not already been initialized.\n\n    Equivalent to the following, but more efficient and does not bloat the tf graph:\n    tf.variables_initializer(tf.report_uninitialized_variables()).run()\n    \"\"\"\n    assert_tf_initialized()\n    if target_vars is None:\n        target_vars = tf.global_variables()\n\n    test_vars = []\n    test_ops = []\n\n    with tf.control_dependencies(None):  # ignore surrounding control_dependencies\n        for var in target_vars:\n            assert is_tf_expression(var)\n\n            with tflex.lock:\n                try:\n                    tf.get_default_graph().get_tensor_by_name(var.name.replace(\":0\", \"/IsVariableInitialized:0\"))\n                except KeyError:\n                    # Op does not exist => variable may be uninitialized.\n                    test_vars.append(var)\n\n                    with absolute_name_scope(var.name.split(\":\")[0]):\n                        test_ops.append(tf.is_variable_initialized(var))\n\n    init_vars = [var for var, inited in zip(test_vars, run(test_ops)) if not inited]\n    run([var.initializer for var in init_vars])\n\n\ndef set_vars(var_to_value_dict: dict) -> None:\n    \"\"\"Set the values of given tf.Variables.\n\n    Equivalent to the following, but more efficient and does not bloat the tf graph:\n    tflib.run([tf.assign(var, value) for var, value in var_to_value_dict.items()]\n    \"\"\"\n    assert_tf_initialized()\n    ops = []\n    feed_dict = {}\n\n    for var, value in var_to_value_dict.items():\n        assert is_tf_expression(var)\n\n        with tflex.lock:\n            if isinstance(value, tf.Variable):\n                try:\n                    setter = tf.get_default_graph().get_tensor_by_name(var.name.replace(\":0\", \"/setter_variable:0\"))  # look for existing op\n                except KeyError:\n                    with absolute_name_scope(var.name.split(\":\")[0]):\n                        with tf.control_dependencies(None):  # ignore surrounding control_dependencies\n                            setter = tf.group(tf.assign(var, value), name=\"setter_variable\")  # create new setter\n\n                ops.append(setter)\n            else:\n                try:\n                    setter = tflex.get_default_graph().get_tensor_by_name(var.name.replace(\":0\", \"/setter:0\"))  # look for existing op\n                except KeyError:\n                    with absolute_name_scope(var.name.split(\":\")[0]):\n                        with tf.control_dependencies(None):  # ignore surrounding control_dependencies\n                            assigner = tf.assign(var, tf.placeholder(var.dtype, var.shape, \"new_value\"))\n                            setter = tf.group(assigner, name=\"setter\")  # create new setter\n\n                ops.append(setter)\n                feed_dict[assigner.op.inputs[1]] = value\n\n    run(ops, feed_dict)\n\n\ndef create_var_with_large_initial_value(initial_value: np.ndarray, *args, **kwargs):\n    \"\"\"Create tf.Variable with large initial value without bloating the tf graph.\"\"\"\n    assert_tf_initialized()\n    assert isinstance(initial_value, np.ndarray)\n    zeros = tf.zeros(initial_value.shape, initial_value.dtype)\n    var = tf.Variable(zeros, *args, **kwargs)\n    set_vars({var: initial_value})\n    return var\n\ndef create_var_with_large_initial_value2(initial_value: np.ndarray, *args, **kwargs):\n    \"\"\"Create tf.Variable with large initial value without bloating the tf graph.\"\"\"\n    assert_tf_initialized()\n    assert isinstance(initial_value, np.ndarray)\n    zeros = tf.zeros(initial_value.shape, initial_value.dtype)\n    var = tf.Variable(zeros, *args, **kwargs)\n    return var, tf.assign(var, initial_value)\n\n\n\ndef convert_images_from_uint8(images, drange=[-1,1], nhwc_to_nchw=False):\n    \"\"\"Convert a minibatch of images from uint8 to float32 with configurable dynamic range.\n    Can be used as an input transformation for Network.run().\n    \"\"\"\n    images = tf.cast(images, tf.float32)\n    if nhwc_to_nchw:\n        images = tf.transpose(images, [0, 3, 1, 2])\n    return images * ((drange[1] - drange[0]) / 255) + drange[0]\n\n\ndef convert_images_to_uint8(images, drange=[-1,1], nchw_to_nhwc=False, shrink=1):\n    \"\"\"Convert a minibatch of images from float32 to uint8 with configurable dynamic range.\n    Can be used as an output transformation for Network.run().\n    \"\"\"\n    images = tf.cast(images, tf.float32)\n    if shrink > 1:\n        ksize = [1, 1, shrink, shrink]\n        images = tf.nn.avg_pool(images, ksize=ksize, strides=ksize, padding=\"VALID\", data_format=\"NCHW\")\n    if nchw_to_nhwc:\n        images = tf.transpose(images, [0, 2, 3, 1])\n    scale = 255 / (drange[1] - drange[0])\n    images = images * scale + (0.5 - drange[0] * scale)\n    return tf.saturate_cast(images, tf.uint8)\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/tflib/tpu_summaries.py",
    "content": "# coding=utf-8\n# Copyright 2018 Google LLC & Hwalsuk Lee.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Provide a helper class for using summaries on TPU via a host call.\n\nTPUEstimator does not support writing TF summaries out of the box and TPUs can't\nperform operations that write files to disk. To monitor tensor values during\ntraining you can copy the tensors back to the CPU of the host machine via\na host call function. This small library provides a convienent API to do this.\n\nExample:\nfrom compare_gan.tpu import tpu_summaries\ndef model_fn(features, labels, params, mode):\n  summary = tpu_summries.TpuSummaries(my_model_dir)\n\n  summary.scalar(\"my_scalar_summary\", tensor1)\n  summary.scalar(\"my_counter\", tensor2, reduce_fn=tf.math.reduce_sum)\n\n  return TPUEstimatorSpec(\n      host_call=summary.get_host_call(),\n      ...)\n\nWarning: The host call function will run every step. Writing large tensors to\nsummaries can slow down your training. High ranking outfeed operations in your\nXProf profile can be an indication for this.\n\"\"\"\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport collections\n\nfrom absl import logging\nimport tensorflow as tf\n\n\nsummary = tf.contrib.summary  # TensorFlow Summary API v2.\n\n\nTpuSummaryEntry = collections.namedtuple(\n    \"TpuSummaryEntry\", \"summary_fn name tensor reduce_fn\")\n\n\nclass TpuSummaries(object):\n  \"\"\"Class to simplify TF summaries on TPU.\n\n  An instance of the class provides simple methods for writing summaries in the\n  similar way to tf.summary. The difference is that each summary entry must\n  provide a reduction function that is used to reduce the summary values from\n  all the TPU cores.\n  \"\"\"\n\n  def __init__(self, log_dir, save_summary_steps=32):\n    self._log_dir = log_dir\n    self._entries = []\n    # While False no summary entries will be added. On TPU we unroll the graph\n    # and don't want to add multiple summaries per step.\n    self.record = True\n    self._save_summary_steps = save_summary_steps\n\n  def image(self, name, tensor, reduce_fn):\n    \"\"\"Add a summary for images. Tensor must be of 4-D tensor.\"\"\"\n    if not self.record:\n      return\n    self._entries.append(\n        TpuSummaryEntry(summary.image, name, tensor, reduce_fn))\n\n  def scalar(self, name, tensor, reduce_fn=tf.math.reduce_mean):\n    \"\"\"Add a summary for a scalar tensor.\"\"\"\n    if not self.record:\n      return\n    tensor = tf.convert_to_tensor(tensor)\n    if tensor.shape.ndims == 0:\n      tensor = tf.expand_dims(tensor, 0)\n    self._entries.append(\n        TpuSummaryEntry(summary.scalar, name, tensor, reduce_fn))\n\n  def get_host_call(self):\n    \"\"\"Returns the tuple (host_call_fn, host_call_args) for TPUEstimatorSpec.\"\"\"\n    # All host_call_args must be tensors with batch dimension.\n    # All tensors are streamed to the host machine (mind the band width).\n    global_step = tf.train.get_or_create_global_step()\n    host_call_args = [tf.expand_dims(global_step, 0)]\n    host_call_args.extend([e.tensor for e in self._entries])\n    logging.info(\"host_call_args: %s\", host_call_args)\n    return (self._host_call_fn, host_call_args)\n\n  def _host_call_fn(self, step, *args):\n    \"\"\"Function that will run on the host machine.\"\"\"\n    # Host call receives values from all tensor cores (concatenate on the\n    # batch dimension). Step is the same for all cores.\n    step = step[0]\n    logging.info(\"host_call_fn: args=%s\", args)\n    with summary.create_file_writer(self._log_dir).as_default():\n      with summary.record_summaries_every_n_global_steps(\n          self._save_summary_steps, step):\n        for i, e in enumerate(self._entries):\n          value = e.reduce_fn(args[i])\n          e.summary_fn(e.name, value, step=step)\n        return summary.all_summary_ops()\n\n"
  },
  {
    "path": "stylegan2-tpu/dnnlib/util.py",
    "content": "﻿# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Miscellaneous utility classes and functions.\"\"\"\n\nimport ctypes\nimport fnmatch\nimport importlib\nimport inspect\nimport numpy as np\nimport os\nimport shutil\nimport sys\nimport types\nimport io\nimport pickle\nimport re\nimport requests\nimport html\nimport hashlib\nimport glob\nimport uuid\nimport errno\n\nfrom distutils.util import strtobool\nfrom typing import Any, List, Tuple, Union\n\n\n# Util classes\n# ------------------------------------------------------------------------------------------\n\n\nclass EasyDict(dict):\n    \"\"\"Convenience class that behaves like a dict but allows access with the attribute syntax.\"\"\"\n\n    def __getattr__(self, name: str) -> Any:\n        try:\n            return self[name]\n        except KeyError:\n            raise AttributeError(name)\n\n    def __setattr__(self, name: str, value: Any) -> None:\n        self[name] = value\n\n    def __delattr__(self, name: str) -> None:\n        del self[name]\n\n\nclass Logger(object):\n    \"\"\"Redirect stderr to stdout, optionally print stdout to a file, and optionally force flushing on both stdout and the file.\"\"\"\n\n    def __init__(self, file_name: str = None, file_mode: str = \"w\", should_flush: bool = True):\n        self.file = None\n\n        if file_name is not None:\n            self.file = open(file_name, file_mode)\n\n        self.should_flush = should_flush\n        self.stdout = sys.stdout\n        self.stderr = sys.stderr\n\n        sys.stdout = self\n        sys.stderr = self\n\n    def __enter__(self) -> \"Logger\":\n        return self\n\n    def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:\n        self.close()\n\n    def write(self, text: str) -> None:\n        \"\"\"Write text to stdout (and a file) and optionally flush.\"\"\"\n        if len(text) == 0: # workaround for a bug in VSCode debugger: sys.stdout.write(''); sys.stdout.flush() => crash\n            return\n\n        try:\n          if self.file is not None:\n              self.file.write(text)\n\n          self.stdout.write(text)\n\n          if self.should_flush:\n              self.flush()\n        except Exception as e:\n          if e.errno == errno.ENOSPC:\n            pass # fail silently when disk full\n          else:\n            raise\n\n    def flush(self) -> None:\n        \"\"\"Flush written text to both stdout and a file, if open.\"\"\"\n        try:\n          if self.file is not None:\n              self.file.flush()\n\n          self.stdout.flush()\n        except Exception as e:\n          if e.errno == errno.ENOSPC:\n            pass # fail silently when disk full\n          else:\n            raise\n\n    def close(self) -> None:\n        \"\"\"Flush, close possible files, and remove stdout/stderr mirroring.\"\"\"\n        self.flush()\n\n        try:\n          # if using multiple loggers, prevent closing in wrong order\n          if sys.stdout is self:\n              sys.stdout = self.stdout\n          if sys.stderr is self:\n              sys.stderr = self.stderr\n\n          if self.file is not None:\n              self.file.close()\n        except Exception as e:\n          if e.errno == errno.ENOSPC:\n            pass # fail silently when disk full\n          else:\n            raise\n\n\n# Small util functions\n# ------------------------------------------------------------------------------------------\n\n\ndef format_time(seconds: Union[int, float]) -> str:\n    \"\"\"Convert the seconds to human readable string with days, hours, minutes and seconds.\"\"\"\n    s = int(np.rint(seconds))\n\n    if s < 60:\n        return \"{0}s\".format(s)\n    elif s < 60 * 60:\n        return \"{0}m {1:02}s\".format(s // 60, s % 60)\n    elif s < 24 * 60 * 60:\n        return \"{0}h {1:02}m {2:02}s\".format(s // (60 * 60), (s // 60) % 60, s % 60)\n    else:\n        return \"{0}d {1:02}h {2:02}m\".format(s // (24 * 60 * 60), (s // (60 * 60)) % 24, (s // 60) % 60)\n\n\ndef ask_yes_no(question: str) -> bool:\n    \"\"\"Ask the user the question until the user inputs a valid answer.\"\"\"\n    while True:\n        try:\n            print(\"{0} [y/n]\".format(question))\n            return strtobool(input().lower())\n        except ValueError:\n            pass\n\n\ndef tuple_product(t: Tuple) -> Any:\n    \"\"\"Calculate the product of the tuple elements.\"\"\"\n    result = 1\n\n    for v in t:\n        result *= v\n\n    return result\n\n\n_str_to_ctype = {\n    \"uint8\": ctypes.c_ubyte,\n    \"uint16\": ctypes.c_uint16,\n    \"uint32\": ctypes.c_uint32,\n    \"uint64\": ctypes.c_uint64,\n    \"int8\": ctypes.c_byte,\n    \"int16\": ctypes.c_int16,\n    \"int32\": ctypes.c_int32,\n    \"int64\": ctypes.c_int64,\n    \"float32\": ctypes.c_float,\n    \"float64\": ctypes.c_double\n}\n\n\ndef get_dtype_and_ctype(type_obj: Any) -> Tuple[np.dtype, Any]:\n    \"\"\"Given a type name string (or an object having a __name__ attribute), return matching Numpy and ctypes types that have the same size in bytes.\"\"\"\n    type_str = None\n\n    if isinstance(type_obj, str):\n        type_str = type_obj\n    elif hasattr(type_obj, \"__name__\"):\n        type_str = type_obj.__name__\n    elif hasattr(type_obj, \"name\"):\n        type_str = type_obj.name\n    else:\n        raise RuntimeError(\"Cannot infer type name from input\")\n\n    assert type_str in _str_to_ctype.keys()\n\n    my_dtype = np.dtype(type_str)\n    my_ctype = _str_to_ctype[type_str]\n\n    assert my_dtype.itemsize == ctypes.sizeof(my_ctype)\n\n    return my_dtype, my_ctype\n\n\ndef is_pickleable(obj: Any) -> bool:\n    try:\n        with io.BytesIO() as stream:\n            pickle.dump(obj, stream)\n        return True\n    except:\n        return False\n\n\n# Functionality to import modules/objects by name, and call functions by name\n# ------------------------------------------------------------------------------------------\n\ndef get_module_from_obj_name(obj_name: str) -> Tuple[types.ModuleType, str]:\n    \"\"\"Searches for the underlying module behind the name to some python object.\n    Returns the module and the object name (original name with module part removed).\"\"\"\n\n    # allow convenience shorthands, substitute them by full names\n    obj_name = re.sub(\"^np.\", \"numpy.\", obj_name)\n    obj_name = re.sub(\"^tf.\", \"tensorflow.\", obj_name)\n\n    # list alternatives for (module_name, local_obj_name)\n    parts = obj_name.split(\".\")\n    name_pairs = [(\".\".join(parts[:i]), \".\".join(parts[i:])) for i in range(len(parts), 0, -1)]\n\n    # try each alternative in turn\n    for module_name, local_obj_name in name_pairs:\n        try:\n            module = importlib.import_module(module_name) # may raise ImportError\n            get_obj_from_module(module, local_obj_name) # may raise AttributeError\n            return module, local_obj_name\n        except:\n            pass\n\n    # maybe some of the modules themselves contain errors?\n    for module_name, _local_obj_name in name_pairs:\n        try:\n            importlib.import_module(module_name) # may raise ImportError\n        except ImportError:\n            if not str(sys.exc_info()[1]).startswith(\"No module named '\" + module_name + \"'\"):\n                raise\n\n    # maybe the requested attribute is missing?\n    for module_name, local_obj_name in name_pairs:\n        try:\n            module = importlib.import_module(module_name) # may raise ImportError\n            get_obj_from_module(module, local_obj_name) # may raise AttributeError\n        except ImportError:\n            pass\n\n    # we are out of luck, but we have no idea why\n    raise ImportError(obj_name)\n\n\ndef get_obj_from_module(module: types.ModuleType, obj_name: str) -> Any:\n    \"\"\"Traverses the object name and returns the last (rightmost) python object.\"\"\"\n    if obj_name == '':\n        return module\n    obj = module\n    for part in obj_name.split(\".\"):\n        obj = getattr(obj, part)\n    return obj\n\n\ndef get_obj_by_name(name: str) -> Any:\n    \"\"\"Finds the python object with the given name.\"\"\"\n    module, obj_name = get_module_from_obj_name(name)\n    return get_obj_from_module(module, obj_name)\n\n\ndef call_func_by_name(*args, func_name: str = None, **kwargs) -> Any:\n    \"\"\"Finds the python object with the given name and calls it as a function.\"\"\"\n    assert func_name is not None\n    func_obj = get_obj_by_name(func_name)\n    assert callable(func_obj)\n    return func_obj(*args, **kwargs)\n\n\ndef get_module_dir_by_obj_name(obj_name: str) -> str:\n    \"\"\"Get the directory path of the module containing the given object name.\"\"\"\n    module, _ = get_module_from_obj_name(obj_name)\n    return os.path.dirname(inspect.getfile(module))\n\n\ndef is_top_level_function(obj: Any) -> bool:\n    \"\"\"Determine whether the given object is a top-level function, i.e., defined at module scope using 'def'.\"\"\"\n    return callable(obj) and obj.__name__ in sys.modules[obj.__module__].__dict__\n\n\ndef get_top_level_function_name(obj: Any) -> str:\n    \"\"\"Return the fully-qualified name of a top-level function.\"\"\"\n    assert is_top_level_function(obj)\n    return obj.__module__ + \".\" + obj.__name__\n\n\n# File system helpers\n# ------------------------------------------------------------------------------------------\n\ndef list_dir_recursively_with_ignore(dir_path: str, ignores: List[str] = None, add_base_to_relative: bool = False) -> List[Tuple[str, str]]:\n    \"\"\"List all files recursively in a given directory while ignoring given file and directory names.\n    Returns list of tuples containing both absolute and relative paths.\"\"\"\n    assert os.path.isdir(dir_path)\n    base_name = os.path.basename(os.path.normpath(dir_path))\n\n    if ignores is None:\n        ignores = []\n\n    result = []\n\n    for root, dirs, files in os.walk(dir_path, topdown=True):\n        for ignore_ in ignores:\n            dirs_to_remove = [d for d in dirs if fnmatch.fnmatch(d, ignore_)]\n\n            # dirs need to be edited in-place\n            for d in dirs_to_remove:\n                dirs.remove(d)\n\n            files = [f for f in files if not fnmatch.fnmatch(f, ignore_)]\n\n        absolute_paths = [os.path.join(root, f) for f in files]\n        relative_paths = [os.path.relpath(p, dir_path) for p in absolute_paths]\n\n        if add_base_to_relative:\n            relative_paths = [os.path.join(base_name, p) for p in relative_paths]\n\n        assert len(absolute_paths) == len(relative_paths)\n        result += zip(absolute_paths, relative_paths)\n\n    return result\n\n\ndef copy_files_and_create_dirs(files: List[Tuple[str, str]]) -> None:\n    \"\"\"Takes in a list of tuples of (src, dst) paths and copies files.\n    Will create all necessary directories.\"\"\"\n    for file in files:\n        target_dir_name = os.path.dirname(file[1])\n\n        # will create all intermediate-level directories\n        if not os.path.exists(target_dir_name):\n            os.makedirs(target_dir_name)\n\n        shutil.copyfile(file[0], file[1])\n\n\n# URL helpers\n# ------------------------------------------------------------------------------------------\n\ndef is_url(obj: Any, allow_file_urls: bool = False) -> bool:\n    \"\"\"Determine whether the given object is a valid URL string.\"\"\"\n    if not isinstance(obj, str) or not \"://\" in obj:\n        return False\n    if allow_file_urls and obj.startswith('file:///'):\n        return True\n    try:\n        res = requests.compat.urlparse(obj)\n        if not res.scheme or not res.netloc or not \".\" in res.netloc:\n            return False\n        res = requests.compat.urlparse(requests.compat.urljoin(obj, \"/\"))\n        if not res.scheme or not res.netloc or not \".\" in res.netloc:\n            return False\n    except:\n        return False\n    return True\n\n\ndef open_url(url: str, cache_dir: str = None, num_attempts: int = 10, verbose: bool = True) -> Any:\n    \"\"\"Download the given URL and return a binary-mode file object to access the data.\"\"\"\n    assert is_url(url, allow_file_urls=True)\n    assert num_attempts >= 1\n\n    # Handle file URLs.\n    if url.startswith('file:///'):\n        return open(url[len('file:///'):], \"rb\")\n\n    # Lookup from cache.\n    url_md5 = hashlib.md5(url.encode(\"utf-8\")).hexdigest()\n    if cache_dir is not None:\n        cache_files = glob.glob(os.path.join(cache_dir, url_md5 + \"_*\"))\n        if len(cache_files) == 1:\n            return open(cache_files[0], \"rb\")\n\n    # Download.\n    url_name = None\n    url_data = None\n    with requests.Session() as session:\n        if verbose:\n            print(\"Downloading %s ...\" % url, end=\"\", flush=True)\n        for attempts_left in reversed(range(num_attempts)):\n            try:\n                with session.get(url) as res:\n                    res.raise_for_status()\n                    if len(res.content) == 0:\n                        raise IOError(\"No data received\")\n\n                    if len(res.content) < 8192:\n                        content_str = res.content.decode(\"utf-8\")\n                        if \"download_warning\" in res.headers.get(\"Set-Cookie\", \"\"):\n                            links = [html.unescape(link) for link in content_str.split('\"') if \"export=download\" in link]\n                            if len(links) == 1:\n                                url = requests.compat.urljoin(url, links[0])\n                                raise IOError(\"Google Drive virus checker nag\")\n                        if \"Google Drive - Quota exceeded\" in content_str:\n                            raise IOError(\"Google Drive download quota exceeded -- please try again later\")\n\n                    match = re.search(r'filename=\"([^\"]*)\"', res.headers.get(\"Content-Disposition\", \"\"))\n                    url_name = match[1] if match else url\n                    url_data = res.content\n                    if verbose:\n                        print(\" done\")\n                    break\n            except:\n                if not attempts_left:\n                    if verbose:\n                        print(\" failed\")\n                    raise\n                if verbose:\n                    print(\".\", end=\"\", flush=True)\n\n    # Save to cache.\n    if cache_dir is not None:\n        safe_name = re.sub(r\"[^0-9a-zA-Z-._]\", \"_\", url_name)\n        cache_file = os.path.join(cache_dir, url_md5 + \"_\" + safe_name)\n        temp_file = os.path.join(cache_dir, \"tmp_\" + uuid.uuid4().hex + \"_\" + url_md5 + \"_\" + safe_name)\n        os.makedirs(cache_dir, exist_ok=True)\n        with open(temp_file, \"wb\") as f:\n            f.write(url_data)\n        os.replace(temp_file, cache_file) # atomic\n\n    # Return data as file object.\n    return io.BytesIO(url_data)\n"
  },
  {
    "path": "stylegan2-tpu/docs/license.html",
    "content": "<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"\" xml:lang=\"\">\n<head>\n  <meta charset=\"utf-8\"/>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\"/>\n  <title>Nvidia Source Code License-NC</title>\n  <link href=\"https://fonts.googleapis.com/css?family=Helvetica+Neue\" rel=\"stylesheet\"/>\n  <style type=\"text/css\">\n\n  body {\n      font-family: 'Helvetica Neue', sans-serif;\n      color: #000000;\n      line-height: 1.5;\n  }\n\n  h1, h2, h3, h4, h5, h6 {\n      color: #92D050;\n      font-weight: normal;\n  }\n\n  h1 {\n      line-height: 1.2;\n      font-size: 2em;\n      margin-top: 1.5em;\n  }\n\n  p {\n    margin-left: 0px;\n    margin-right: 0px;\n    margin-top: 0.75em;\n    margin-bottom: 0.75em;\n  }\n\n  p.tab {\n    margin-left: 3em;\n  }\n\n  hr {\n    border: 0px;\n    height: 1px;\n    background: #CCCCCC;\n  }\n\n  @media screen and (min-width: 680px) {\n      .max-width {\n          margin: 0 100px 0 170px;\n          max-width: 640px;\n      }\n  }\n  @media screen and (min-width: 980px) {\n      .max-width {\n          margin: 0 auto;\n      }\n  }\n  </style>\n</head>\n<body class=\"max-width\">\n\n<h1>Nvidia Source Code License-NC</h1>\n\n<hr/>\n\n<h2>1. Definitions</h2>\n\n<p>&ldquo;Licensor&rdquo; means any person or entity that distributes its Work.</p>\n\n<p>&ldquo;Software&rdquo; means the original work of authorship made available under\nthis License.</p>\n\n<p>&ldquo;Work&rdquo; means the Software and any additions to or derivative works of\nthe Software that are made available under this License.</p>\n\n<p>&ldquo;Nvidia Processors&rdquo; means any central processing unit (CPU), graphics\nprocessing unit (GPU), field-programmable gate array (FPGA),\napplication-specific integrated circuit (ASIC) or any combination\nthereof designed, made, sold, or provided by Nvidia or its affiliates.</p>\n\n<p>The terms &ldquo;reproduce,&rdquo; &ldquo;reproduction,&rdquo; &ldquo;derivative works,&rdquo; and\n&ldquo;distribution&rdquo; have the meaning as provided under U.S. copyright law;\nprovided, however, that for the purposes of this License, derivative\nworks shall not include works that remain separable from, or merely\nlink (or bind by name) to the interfaces of, the Work.</p>\n\n<p>Works, including the Software, are &ldquo;made available&rdquo; under this License\nby including in or with the Work either (a) a copyright notice\nreferencing the applicability of this License to the Work, or (b) a\ncopy of this License.<p>\n\n<h2>2. License Grants</h2>\n\n<p class=\"tab\">2.1 Copyright Grant. Subject to the terms and conditions of this\nLicense, each Licensor grants to you a perpetual, worldwide,\nnon-exclusive, royalty-free, copyright license to reproduce,\nprepare derivative works of, publicly display, publicly perform,\nsublicense and distribute its Work and any resulting derivative\nworks in any form.</p>\n\n<h2>3. Limitations</h2>\n\n<p class=\"tab\">3.1 Redistribution. You may reproduce or distribute the Work only\nif (a) you do so under this License, (b) you include a complete\ncopy of this License with your distribution, and (c) you retain\nwithout modification any copyright, patent, trademark, or\nattribution notices that are present in the Work.</p>\n\n<p class=\"tab\">3.2 Derivative Works. You may specify that additional or different\nterms apply to the use, reproduction, and distribution of your\nderivative works of the Work (&ldquo;Your Terms&rdquo;) only if (a) Your Terms\nprovide that the use limitation in Section 3.3 applies to your\nderivative works, and (b) you identify the specific derivative\nworks that are subject to Your Terms. Notwithstanding Your Terms,\nthis License (including the redistribution requirements in Section\n3.1) will continue to apply to the Work itself.</p>\n\n<p class=\"tab\">3.3 Use Limitation. The Work and any derivative works thereof only\nmay be used or intended for use non-commercially. The Work or\nderivative works thereof may be used or intended for use by Nvidia\nor its affiliates commercially or non-commercially. As used herein,\n&ldquo;non-commercially&rdquo; means for research or evaluation purposes only.</p>\n\n<p class=\"tab\">3.4 Patent Claims. If you bring or threaten to bring a patent claim\nagainst any Licensor (including any claim, cross-claim or\ncounterclaim in a lawsuit) to enforce any patents that you allege\nare infringed by any Work, then your rights under this License from\nsuch Licensor (including the grants in Sections 2.1 and 2.2) will\nterminate immediately.</p>\n\n<p class=\"tab\">3.5 Trademarks. This License does not grant any rights to use any\nLicensor&rsquo;s or its affiliates&rsquo; names, logos, or trademarks, except\nas necessary to reproduce the notices described in this License.</p>\n\n<p class=\"tab\">3.6 Termination. If you violate any term of this License, then your\nrights under this License (including the grants in Sections 2.1 and\n2.2) will terminate immediately.</p>\n\n<h2>4. Disclaimer of Warranty.</h2>\n\n<p>THE WORK IS PROVIDED &ldquo;AS IS&rdquo; WITHOUT WARRANTIES OR CONDITIONS OF ANY\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OR CONDITIONS OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR\nNON-INFRINGEMENT. YOU BEAR THE RISK OF UNDERTAKING ANY ACTIVITIES UNDER\nTHIS LICENSE.</p>\n\n<h2>5. Limitation of Liability.</h2>\n\n<p>EXCEPT AS PROHIBITED BY APPLICABLE LAW, IN NO EVENT AND UNDER NO LEGAL\nTHEORY, WHETHER IN TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE\nSHALL ANY LICENSOR BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT,\nINDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF\nOR RELATED TO THIS LICENSE, THE USE OR INABILITY TO USE THE WORK\n(INCLUDING BUT NOT LIMITED TO LOSS OF GOODWILL, BUSINESS INTERRUPTION,\nLOST PROFITS OR DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY OTHER\nCOMMERCIAL DAMAGES OR LOSSES), EVEN IF THE LICENSOR HAS BEEN ADVISED OF\nTHE POSSIBILITY OF SUCH DAMAGES.</p>\n\n<hr/>\n<br/>\n\n</body>\n</html>\n"
  },
  {
    "path": "stylegan2-tpu/docs/versions.html",
    "content": "<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"\" xml:lang=\"\">\n<head>\n  <meta charset=\"utf-8\"/>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\"/>\n  <title>StyleGAN versions</title>\n  <link href=\"https://fonts.googleapis.com/css?family=Montserrat|Source+Sans+Pro\" rel=\"stylesheet\"/>\n  <style type=\"text/css\">\n\n  body {\n      font-family: 'Source Sans Pro', sans-serif;\n      color: #000000;\n      line-height: 1.5;\n  }\n\n  h1, h2, h3, h4, h5, h6 {\n      font-family: 'Montserrat', serif;\n  }\n\n  h1 {\n      line-height: 1.2;\n      font-size: 2em;\n      margin-top: 1.5em;\n  }\n\n  p {\n    margin-left: 0px;\n    margin-right: 0px;\n    margin-top: 0.75em;\n    margin-bottom: 0.75em;\n  }\n\n  @media screen and (min-width: 680px) {\n      .max-width {\n          margin: 0 100px 0 170px;\n          max-width: 640px;\n      }\n  }\n  @media screen and (min-width: 980px) {\n      .max-width {\n          margin: 0 auto;\n      }\n  }\n  </style>\n</head>\n<body class=\"max-width\">\n\n<h1>StyleGAN2</h1>\n<ul>\n    <li>Paper: <a href=\"http://arxiv.org/abs/1912.04958\">http://arxiv.org/abs/1912.04958</a></li>\n    <li>Video: <a href=\"https://youtu.be/c-NJtV9Jvp0\">https://youtu.be/c-NJtV9Jvp0</a></li>\n    <li>Code: <a href=\"https://github.com/NVlabs/stylegan2\">https://github.com/NVlabs/stylegan2</a></li>\n</ul>\n\n<h1>Original StyleGAN</h1>\n<ul>\n    <li>Paper: <a href=\"https://arxiv.org/abs/1812.04948\">https://arxiv.org/abs/1812.04948</a></li>\n    <li>Video: <a href=\"https://youtu.be/kSLJriaOumA\">https://youtu.be/kSLJriaOumA</a></li>\n    <li>Code: <a href=\"https://github.com/NVlabs/stylegan\">https://github.com/NVlabs/stylegan</a></li>\n    <li>FFHQ: <a href=\"https://github.com/NVlabs/ffhq-dataset\">https://github.com/NVlabs/ffhq-dataset</a></li>\n</ul>\n\n</body>\n</html>\n"
  },
  {
    "path": "stylegan2-tpu/encoder/__init__.py",
    "content": ""
  },
  {
    "path": "stylegan2-tpu/encoder/generator_model.py",
    "content": "import math\nimport tensorflow as tf\nimport numpy as np\nimport dnnlib.tflib as tflib\nfrom functools import partial\n\n\ndef create_stub(name, batch_size):\n    return tf.constant(0, dtype='float32', shape=(batch_size, 0))\n\n\ndef create_variable_for_generator(name, batch_size, tiled_dlatent, model_scale=18):\n    if tiled_dlatent:\n        low_dim_dlatent = tf.get_variable('learnable_dlatents',\n            shape=(batch_size, 512),\n            dtype='float32',\n            initializer=tf.initializers.random_normal())\n        return tf.tile(tf.expand_dims(low_dim_dlatent, axis=1), [1, model_scale, 1])\n    else:\n        return tf.get_variable('learnable_dlatents',\n            shape=(batch_size, model_scale, 512),\n            dtype='float32',\n            initializer=tf.initializers.random_normal())\n\n\nclass Generator:\n    def __init__(self, model, batch_size, clipping_threshold=2, tiled_dlatent=False, model_res=1024, randomize_noise=False):\n        self.batch_size = batch_size\n        self.tiled_dlatent=tiled_dlatent\n        self.model_scale = int(2*(math.log(model_res,2)-1)) # For example, 1024 -> 18\n\n        if tiled_dlatent:\n            self.initial_dlatents = np.zeros((self.batch_size, 512))\n            model.components.synthesis.run(np.zeros((self.batch_size, self.model_scale, 512)),\n                randomize_noise=randomize_noise, minibatch_size=self.batch_size,\n                custom_inputs=[partial(create_variable_for_generator, batch_size=batch_size, tiled_dlatent=True),\n                                                partial(create_stub, batch_size=batch_size)],\n                structure='fixed')\n        else:\n            self.initial_dlatents = np.zeros((self.batch_size, self.model_scale, 512))\n            model.components.synthesis.run(self.initial_dlatents,\n                randomize_noise=randomize_noise, minibatch_size=self.batch_size,\n                custom_inputs=[partial(create_variable_for_generator, batch_size=batch_size, tiled_dlatent=False, model_scale=self.model_scale),\n                                                partial(create_stub, batch_size=batch_size)],\n                structure='fixed')\n\n        self.dlatent_avg_def = model.get_var('dlatent_avg')\n        self.reset_dlatent_avg()\n        self.sess = tf.get_default_session()\n        self.graph = tf.get_default_graph()\n\n        self.dlatent_variable = next(v for v in tf.global_variables() if 'learnable_dlatents' in v.name)\n        self.set_dlatents(self.initial_dlatents)\n\n        def get_tensor(name):\n            try:\n                return self.graph.get_tensor_by_name(name)\n            except KeyError:\n                return None\n\n        self.generator_output = get_tensor('G_synthesis_1/_Run/concat:0')\n        if self.generator_output is None:\n            self.generator_output = get_tensor('G_synthesis_1/_Run/concat/concat:0')\n        if self.generator_output is None:\n            self.generator_output = get_tensor('G_synthesis_1/_Run/concat_1/concat:0')\n        # If we loaded only Gs and didn't load G or D, then scope \"G_synthesis_1\" won't exist in the graph.\n        if self.generator_output is None:\n            self.generator_output = get_tensor('G_synthesis/_Run/concat:0')\n        if self.generator_output is None:\n            self.generator_output = get_tensor('G_synthesis/_Run/concat/concat:0')\n        if self.generator_output is None:\n            self.generator_output = get_tensor('G_synthesis/_Run/concat_1/concat:0')\n        if self.generator_output is None:\n            for op in self.graph.get_operations():\n                print(op)\n            raise Exception(\"Couldn't find G_synthesis_1/_Run/concat tensor output\")\n        self.generated_image = tflib.convert_images_to_uint8(self.generator_output, nchw_to_nhwc=True, uint8_cast=False)\n        self.generated_image_uint8 = tf.saturate_cast(self.generated_image, tf.uint8)\n\n        # Implement stochastic clipping similar to what is described in https://arxiv.org/abs/1702.04782\n        # (Slightly different in that the latent space is normal gaussian here and was uniform in [-1, 1] in that paper,\n        # so we clip any vector components outside of [-2, 2]. It seems fine, but I haven't done an ablation check.)\n        clipping_mask = tf.math.logical_or(self.dlatent_variable > clipping_threshold, self.dlatent_variable < -clipping_threshold)\n        clipped_values = tf.where(clipping_mask, tf.random_normal(shape=self.dlatent_variable.shape), self.dlatent_variable)\n        self.stochastic_clip_op = tf.assign(self.dlatent_variable, clipped_values)\n\n    def reset_dlatents(self):\n        self.set_dlatents(self.initial_dlatents)\n\n    def set_dlatents(self, dlatents):\n        if self.tiled_dlatent:\n            if (dlatents.shape != (self.batch_size, 512)) and (dlatents.shape[1] != 512):\n                dlatents = np.mean(dlatents, axis=1)\n            if (dlatents.shape != (self.batch_size, 512)):\n                dlatents = np.vstack([dlatents, np.zeros((self.batch_size-dlatents.shape[0], 512))])\n            assert (dlatents.shape == (self.batch_size, 512))\n        else:\n            if (dlatents.shape[1] > self.model_scale):\n                dlatents = dlatents[:,:self.model_scale,:]\n            if (dlatents.shape != (self.batch_size, self.model_scale, 512)):\n                dlatents = np.vstack([dlatents, np.zeros((self.batch_size-dlatents.shape[0], self.model_scale, 512))])\n            assert (dlatents.shape == (self.batch_size, self.model_scale, 512))\n        self.dlatent_variable.load(dlatents, self.sess)\n\n    def stochastic_clip_dlatents(self):\n        self.sess.run(self.stochastic_clip_op)\n\n    def get_dlatents(self):\n        return self.dlatent_variable.eval(self.sess)\n\n    def get_dlatent_avg(self):\n        return self.dlatent_avg\n\n    def set_dlatent_avg(self, dlatent_avg):\n        self.dlatent_avg = dlatent_avg\n\n    def reset_dlatent_avg(self):\n        self.dlatent_avg = self.dlatent_avg_def\n\n    def generate_images(self, dlatents=None):\n        if dlatents:\n            self.set_dlatents(dlatents)\n        return self.sess.run(self.generated_image_uint8)\n"
  },
  {
    "path": "stylegan2-tpu/encoder/perceptual_model.py",
    "content": "import os\nimport bz2\nimport PIL.Image\nimport numpy as np\nimport tensorflow as tf\nfrom keras.models import Model\nfrom keras.utils import get_file\nfrom keras.applications.vgg16 import VGG16, preprocess_input\nimport keras.backend as K\nimport traceback\n\ndef load_images(images_list, image_size=256):\n    loaded_images = list()\n    for img_path in images_list:\n      img = PIL.Image.open(img_path).convert('RGB').resize((image_size,image_size),PIL.Image.LANCZOS)\n      img = np.array(img)\n      img = np.expand_dims(img, 0)\n      loaded_images.append(img)\n    loaded_images = np.vstack(loaded_images)\n    return loaded_images\n\ndef tf_custom_l1_loss(img1,img2):\n  return tf.math.reduce_mean(tf.math.abs(img2-img1), axis=None)\n\ndef tf_custom_logcosh_loss(img1,img2):\n  return tf.math.reduce_mean(tf.keras.losses.logcosh(img1,img2))\n\ndef unpack_bz2(src_path):\n    data = bz2.BZ2File(src_path).read()\n    dst_path = src_path[:-4]\n    with open(dst_path, 'wb') as fp:\n        fp.write(data)\n    return dst_path\n\nclass PerceptualModel:\n    def __init__(self, args, batch_size=1, perc_model=None, sess=None, optimizer=None):\n        self.sess = tf.get_default_session() if sess is None else sess\n        self.optimizer = optimizer\n        K.set_session(self.sess)\n        self.epsilon = 0.00000001\n        self.lr = args.lr\n        self.decay_rate = args.decay_rate\n        self.decay_steps = args.decay_steps\n        self.img_size = args.image_size\n        self.layer = args.use_vgg_layer\n        self.vgg_loss = args.use_vgg_loss\n        self.face_mask = args.face_mask\n        self.use_grabcut = args.use_grabcut\n        self.scale_mask = args.scale_mask\n        self.mask_dir = args.mask_dir\n        if (self.layer <= 0 or self.vgg_loss <= self.epsilon):\n            self.vgg_loss = None\n        self.pixel_loss = args.use_pixel_loss\n        if (self.pixel_loss <= self.epsilon):\n            self.pixel_loss = None\n        self.mssim_loss = args.use_mssim_loss\n        if (self.mssim_loss <= self.epsilon):\n            self.mssim_loss = None\n        self.lpips_loss = args.use_lpips_loss\n        if (self.lpips_loss <= self.epsilon):\n            self.lpips_loss = None\n        self.l1_penalty = args.use_l1_penalty\n        if (self.l1_penalty <= self.epsilon):\n            self.l1_penalty = None\n        self.batch_size = batch_size\n        if perc_model is not None and self.lpips_loss is not None:\n            self.perc_model = perc_model\n        else:\n            self.perc_model = None\n        self.ref_img = None\n        self.ref_weight = None\n        self.perceptual_model = None\n        self.ref_img_features = None\n        self.features_weight = None\n        self.loss = None\n\n        if self.face_mask:\n            import dlib\n            self.detector = dlib.get_frontal_face_detector()\n            LANDMARKS_MODEL_URL = 'http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2'\n            landmarks_model_path = unpack_bz2(get_file('shape_predictor_68_face_landmarks.dat.bz2',\n                                                    LANDMARKS_MODEL_URL, cache_subdir='temp'))\n            self.predictor = dlib.shape_predictor(landmarks_model_path)\n\n    def compare_images(self,img1,img2):\n        if self.perc_model is not None:\n            return self.perc_model.get_output_for(tf.transpose(img1, perm=[0,3,2,1]), tf.transpose(img2, perm=[0,3,2,1]))\n        return 0\n\n    def add_placeholder(self, var_name):\n        var_val = getattr(self, var_name)\n        setattr(self, var_name + \"_placeholder\", tf.placeholder(var_val.dtype, shape=var_val.get_shape()))\n        setattr(self, var_name + \"_op\", var_val.assign(getattr(self, var_name + \"_placeholder\")))\n\n    def assign_placeholder(self, var_name, var_val):\n        self.sess.run(getattr(self, var_name + \"_op\"), {getattr(self, var_name + \"_placeholder\"): var_val})\n\n    def build_perceptual_model(self, generator):\n        self.generator = generator\n        # Learning rate\n        self._global_step = tf.Variable(0, dtype=tf.int32, trainable=False, name=\"global_step\")\n        self._incremented_global_step = tf.assign_add(self._global_step, 1)\n        self._reset_global_step = tf.assign(self._global_step, 0)\n        self.learning_rate = tf.train.exponential_decay(self.lr, self._incremented_global_step,\n                self.decay_steps, self.decay_rate, staircase=True)\n        self.sess.run([self._reset_global_step])\n\n        self.generated_image_tensor = self.generator.generated_image\n        self.generated_image = tf.image.resize_nearest_neighbor(self.generated_image_tensor,\n                                                                  (self.img_size, self.img_size), align_corners=True)\n\n        self.ref_img = tf.get_variable('ref_img', shape=self.generated_image.shape,\n                                                dtype='float32', initializer=tf.initializers.zeros())\n        self.ref_weight = tf.get_variable('ref_weight', shape=self.generated_image.shape,\n                                               dtype='float32', initializer=tf.initializers.zeros())\n        self.add_placeholder(\"ref_img\")\n        self.add_placeholder(\"ref_weight\")\n\n        if (self.vgg_loss is not None):\n            self.vgg16 = VGG16(include_top=False, input_shape=(self.img_size, self.img_size, 3))\n            self.perceptual_model = Model(self.vgg16.input, self.vgg16.layers[self.layer].output)\n            self.generated_img_features = self.perceptual_model(preprocess_input(self.ref_weight * self.generated_image))\n            self.ref_img_features = tf.get_variable('ref_img_features', shape=self.generated_img_features.shape,\n                                                dtype='float32', initializer=tf.initializers.zeros())\n            self.features_weight = tf.get_variable('features_weight', shape=self.generated_img_features.shape,\n                                               dtype='float32', initializer=tf.initializers.zeros())\n            self.sess.run([self.features_weight.initializer, self.features_weight.initializer])\n            self.add_placeholder(\"ref_img_features\")\n            self.add_placeholder(\"features_weight\")\n\n        self.loss = 0\n        # L1 loss on VGG16 features\n        if (self.vgg_loss is not None):\n            self.loss += self.vgg_loss * tf_custom_l1_loss(self.features_weight * self.ref_img_features, self.features_weight * self.generated_img_features)\n        # + logcosh loss on image pixels\n        if (self.pixel_loss is not None):\n            self.loss += self.pixel_loss * tf_custom_logcosh_loss(self.ref_weight * self.ref_img, self.ref_weight * self.generated_image)\n        # + MS-SIM loss on image pixels\n        if (self.mssim_loss is not None):\n            self.loss += self.mssim_loss * tf.math.reduce_mean(1-tf.image.ssim_multiscale(self.ref_weight * self.ref_img, self.ref_weight * self.generated_image, 1))\n        # + extra perceptual loss on image pixels\n        if self.perc_model is not None and self.lpips_loss is not None:\n            self.loss += self.lpips_loss * tf.math.reduce_mean(self.compare_images(self.ref_weight * self.ref_img, self.ref_weight * self.generated_image))\n        # + L1 penalty on dlatent weights\n        if self.l1_penalty is not None:\n            self.loss += self.l1_penalty * 512 * tf.math.reduce_mean(tf.math.abs(self.generator.dlatent_variable[:,0]-self.generator.get_dlatent_avg()))\n\n        vars_to_optimize = self.generator.dlatent_variable\n        self.vars_to_optimize = vars_to_optimize if isinstance(vars_to_optimize, list) else [vars_to_optimize]\n        if self.optimizer is not None:\n            self.min_op = self.optimizer.minimize(self.loss, var_list=[self.vars_to_optimize])\n        else:\n            self.optimizer = tf.train.AdamOptimizer(learning_rate=self.learning_rate)\n            self.min_op = self.optimizer.minimize(self.loss, var_list=[self.vars_to_optimize])\n            self.sess.run(tf.variables_initializer(self.optimizer.variables()))\n            self.sess.run(self._reset_global_step)\n\n    def generate_face_mask(self, im):\n        from imutils import face_utils\n        import cv2\n        rects = self.detector(im, 1)\n        # loop over the face detections\n        for (j, rect) in enumerate(rects):\n            \"\"\"\n            Determine the facial landmarks for the face region, then convert the facial landmark (x, y)-coordinates to a NumPy array\n            \"\"\"\n            shape = self.predictor(im, rect)\n            shape = face_utils.shape_to_np(shape)\n\n            # we extract the face\n            vertices = cv2.convexHull(shape)\n            mask = np.zeros(im.shape[:2],np.uint8)\n            cv2.fillConvexPoly(mask, vertices, 1)\n            if self.use_grabcut:\n                bgdModel = np.zeros((1,65),np.float64)\n                fgdModel = np.zeros((1,65),np.float64)\n                rect = (0,0,im.shape[1],im.shape[2])\n                (x,y),radius = cv2.minEnclosingCircle(vertices)\n                center = (int(x),int(y))\n                radius = int(radius*self.scale_mask)\n                mask = cv2.circle(mask,center,radius,cv2.GC_PR_FGD,-1)\n                cv2.fillConvexPoly(mask, vertices, cv2.GC_FGD)\n                cv2.grabCut(im,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_MASK)\n                mask = np.where((mask==2)|(mask==0),0,1)\n            return mask\n\n    def load_images(self, images_list):\n        assert (len(images_list) != 0 and len(images_list) <= self.batch_size)\n        loaded_image = load_images(images_list, self.img_size)\n        return loaded_image\n\n    def set_reference_images(self, images_list):\n        return self.set_reference_image_data(self.load_images(images_list), images_list)\n\n    def set_reference_image_data(self, loaded_image, images_list=None):\n        if len(loaded_image.shape) < 4:\n            loaded_image = loaded_image.reshape([1] + list(loaded_image.shape))\n        self.loaded_image = loaded_image\n        self.images_list = images_list\n        self.image_features = None\n        if self.perceptual_model is not None:\n            self.image_features = self.perceptual_model.predict_on_batch(preprocess_input(self.loaded_image))\n            self.weight_mask = np.ones(self.features_weight.shape)\n\n        if self.face_mask and self.images_list is not None:\n            self.image_mask = np.zeros(self.ref_weight.shape)\n            for (i, im) in enumerate(self.loaded_image):\n                try:\n                    _, img_name = os.path.split(self.images_list[i])\n                    mask_img = os.path.join(self.mask_dir, f'{img_name}')\n                    if (os.path.isfile(mask_img)):\n                        print(\"Loading mask \" + mask_img)\n                        imask = PIL.Image.open(mask_img).convert('L')\n                        mask = np.array(imask)/255\n                        mask = np.expand_dims(mask,axis=-1)\n                    else:\n                        mask = self.generate_face_mask(im)\n                        imask = (255*mask).astype('uint8')\n                        imask = PIL.Image.fromarray(imask, 'L')\n                        print(\"Saving mask \" + mask_img)\n                        imask.save(mask_img, 'PNG')\n                        mask = np.expand_dims(mask,axis=-1)\n                    mask = np.ones(im.shape,np.float32) * mask\n                except Exception as e:\n                    print(\"Exception in mask handling for \" + mask_img)\n                    traceback.print_exc()\n                    mask = np.ones(im.shape[:2],np.uint8)\n                    mask = np.ones(im.shape,np.float32) * np.expand_dims(mask,axis=-1)\n                self.image_mask[i] = mask\n        else:\n            self.image_mask = np.ones(self.ref_weight.shape)\n\n        image_count = self.loaded_image.shape[0]\n        if image_count != self.batch_size:\n            if self.image_features is not None:\n                features_space = list(self.features_weight.shape[1:])\n                existing_features_shape = [image_count] + features_space\n                empty_features_shape = [self.batch_size - image_count] + features_space\n                existing_examples = np.ones(shape=existing_features_shape)\n                empty_examples = np.zeros(shape=empty_features_shape)\n                self.weight_mask = np.vstack([existing_examples, empty_examples])\n                self.image_features = np.vstack([self.image_features, np.zeros(empty_features_shape)])\n\n            images_space = list(self.ref_weight.shape[1:])\n            existing_images_space = [image_count] + images_space\n            empty_images_space = [self.batch_size - image_count] + images_space\n            existing_images = np.ones(shape=existing_images_space)\n            empty_images = np.zeros(shape=empty_images_space)\n            self.image_mask = self.image_mask * np.vstack([existing_images, empty_images])\n            self.loaded_image = np.vstack([self.loaded_image, np.zeros(empty_images_space)])\n\n        if self.image_features is not None:\n            self.assign_placeholder(\"features_weight\", self.weight_mask)\n            self.assign_placeholder(\"ref_img_features\", self.image_features)\n        self.assign_placeholder(\"ref_weight\", self.image_mask)\n        self.assign_placeholder(\"ref_img\", self.loaded_image)\n\n    def optimize(self, iterations=200):\n        self.fetch_ops = [self.min_op, self.loss, self.learning_rate]\n        for _ in range(iterations):\n            _, loss, lr = self.sess.run(self.fetch_ops)\n            yield {\"loss\":loss, \"lr\": lr}\n"
  },
  {
    "path": "stylegan2-tpu/ext.l",
    "content": "\n(def image-to-discord-file (img name: name kind: kind)\n  (set kind (or kind \"jpg\"))\n  (set name (or name \"test\"))\n  (let f (BytesIO)\n    (f.write (image-to-bytes img))\n    (f.seek 0)\n    (let picture (discord.File f)\n      (set picture.filename (+ name \".\" kind))\n      picture)))\n\n(def listtab (l)\n  (with r (obj)\n    (step (k v) l\n      (if (number? k)\n          (set (at r k) v)\n        (set (get r k) v)))))\n\n(def tablist (h)\n  (with r ()\n    (each (k v) h\n      (add r (list k v)))))\n\n(def assoc (key al)\n  (let-when i (first (fn (x) (hd? x key)) al)\n    (at al i)))\n\n(def alref (al key)\n  (let-when l (assoc key al)\n    (at l 1)))\n\n(def union (f xs ys)\n  (join xs (rem (fn (y) (some (fn (_) (f _ y)) xs))\n                ys)))\n\n(define-global testify (x test)\n  (if (function? x) x\n      test\n      (fn (y) (test y x))\n    (fn (y) (= x y))))\n\n(define-global find (x t)\n  (let f (testify x)\n    (each x t\n      (let y (f x)\n        (if y (return y))))))\n\n(def saveable-vars (network)\n  (map (fn ((k v)) (list (cat \"G_synthesis/\" k) v))\n       (list x for x in (synthesis.trainables.items))))\n\n;(go (chan*.send \"hi\" file: (image-to-discord-file img)))\n\n(import tflex)\n\n(define-symbol chan* tflex.message.channel)\n\n(from training import misc)\n\n(def rand-latent (seed shape)\n  (let (shape (or shape '(1 512))\n        seed (np.random.RandomState seed)\n        latent (apply seed.randn shape))\n    latent))\n\n(from pprint import pprint)\n\n(from io import StringIO)\n\n(def bytes-to-discord-file (bs name)\n  (let f (BytesIO)\n    (f.write bs)\n    (f.seek 0)\n    (let f1 (discord.File f)\n      (when (is? name)\n        (set f1.filename name))\n      f1)))\n\n(def image-to-discord-file (img name: name kind: kind)\n  (set kind (or kind \"jpg\"))\n  (set name (or name \"test\"))\n  (bytes-to-discord-file (image-to-bytes img) (+ name \".\" kind)))\n\n(def pps (x)\n  (let f (StringIO)\n    (pprint x stream: f)\n    (ellipsize (f.getvalue) 1190)))\n\n(def netrun (network latent label |**kws|)\n  (let latent (if (or (nil? latent) (isinstance latent int))\n                  (rand-latent latent)\n                  latent)\n    (network.run latent label |**kws|)))\n\n(defvar target-size* nil)\n\n(import asyncio)\n\n(def go (coro)\n  (asyncio.run_coroutine_threadsafe coro (asyncio.get_event_loop)))\n\n(def prfile (f text: text name: name chan: chan)\n  (set chan (or chan chan*))\n  (go (chan.send (or text \"\") file: f)))\n\n(def numpy-to-image-grid (result drange-net: drange-net)\n  (let (drange-net (or drange-net '(-1 1))\n        n result.shape.0\n        grid-size (get-grid-size n)\n        x (misc.create-image-grid result grid-size)\n        img (misc.convert-to-pil-image x drange-net))\n    img))\n\n(def primg (img text: text name: name)\n  (let (img (if (numpy? img) (numpy-to-image-grid img) img)\n        img (if target-size* (resize-image img target-size*) img)\n        f (image-to-discord-file img))\n    ;(set (get f 'filename) name)\n    (go (chan*.send (or text \"\") file: f))))\n\n(import os)\n;(set (get os.environ 'TPU_NAME) \"tpu-v3-32-euw4a-4\")\n\n(import dnnlib)\n(import tflex)\n(set me (dnnlib.EasyDict tflex.self))\n(from training.networks_stylegan2 import *)\n(from training import misc)\n\n(me.init)\n\n(defvar G (tflib.Network \"G\" num_channels: 3 resolution: 512 label_size: 0 func_name: \"training.networks_stylegan2.G_main\"))\n(defvar Gs (G.clone \"Gs\"))\n\n(defvar model-dir* nil)\n(defvar model-step* 0)\n\n(def checkpoint (path i network: network)\n  (global model-dir*)\n  (let (path (or path model-dir*)\n        network (or network Gs))\n    (set model-dir* path)\n    (let path (if (is? i)\n                  (os.path.join path (idx \"model-{}.ckpt\" i))\n                  (or (tf.train.latest-checkpoint path) path))\n      (me.load-checkpoint path var_list: network.trainables)\n      path)))\n\n\n(def grab (latent ckpt network: network label: label truncation_psi: psi)\n  (let network (or network Gs)\n    (when ckpt\n      (me.load-checkpoint ckpt var_list: network.trainables))\n    (primg (hd (netrun network latent label truncation_psi: (either psi 0.7))))))\n\n(def latent-grid (seed n)\n  (rand-latent (or n 9) seed: (or seed 0)))\n\n(def o (seed n)\n  (gen-images (rand-latent (or n 9) (or seed 0))))\n\n(mac see args\n  (let (args (keep (fn (x) (not (= x \"seed\"))) args)\n       (path seed n offset) args\n        a (or offset 0)\n        b `(+ ,a ,(or n 9))\n        n 100)\n    `(do (checkpoint ,(escape path))\n             (primg (gen-images (np.array (array (cut (rand-latent ,n seed: ,(or seed 0)) ,a ,b)))) text: ,(escape (cat path \" seed \" (str seed)))))))\n\n(mac seevid (path _ seed x y dur fps)\n  `(do (checkpoint ,(escape path))\n       (interpv ,(or dur 2.0) ,(or fps 'nil) ,seed ,x ,y)))\n\n(defvar latents*)\n\n(def lerp (a b t)\n  (+ a (* t (- b a))))\n\n(def lerp-latent (a b t)\n  (np.array (list (lerp a b t))))\n\n(def latent-range (a b)\n  (fn (t)\n    (lerp-latent a b t)))\n\n(def interpolator (seed x0 x1)\n  (let (seed (or seed 0)\n        latents (rand-latent 9 seed: seed)\n        a (at latents (or x0 0))\n        b (at latents (or x1 1)))\n    (latent-range a b)))\n\n(def i args\n  (interp (apply interpolator args)))\n\n(def time-percentage (duration f)\n  (fn (t)\n    (f (/ t duration))))\n\n(def then-image (latent-maker)\n  (fn (t)\n    (let latent (latent-maker t)\n      (image-to-numpy (gen-images latent)))))\n\n(def to-numpy (x)\n  (if (image? x) x (image-to-numpy x)))\n\n(def pimg (x)\n  (primg (to-numpy x)))\n\n(def interp (f n)\n  (let n (or n 10.0)\n    (step t (np.arange 0.0 (+ n 1.0) 1.0)\n      (pimg (gen-images (f (/ t n)))))))\n\n(def i (seed a b n)\n  (interp (interpolator seed a b) n))\n\n(def prfile (f text: text chan: chan name: name)\n  (set chan (or chan chan*))\n  (when name\n    (set f.filename name))\n  (go (chan.send (or text \"\") file: f)))\n\n(mac after (x rest: body)\n  `(let ((ok v) (guard ,x))\n     ,@body\n     (if ok v (throw v))))\n\n(import os)\n(import tempfile)\n\n|sys.path += [\"/home/train/.local/lib/python3.6/site-packages\"]|\n(import moviepy)\n(import moviepy.editor)\n\n(unless (%in \"gwern#1782\" me.admins)\n  (add me.admins \"gwern#1782\"))\n\n(def videobytes (make-frame duration fps)\n  (set duration (or duration 0.5))\n  (set fps (or fps 10))\n  (set vid (moviepy.editor.VideoClip make-frame duration: duration))\n  (let ((fd path) (tempfile.mkstemp)\n        path \"test\"\n        path (+ path \".mp4\"))\n    (after (do (vid.write-videofile path fps: fps codec: mp4-codec bitrate: mp4-bitrate)\n               ((idx (open path \"rb\") read)))\n      ;(os.remove path)\n      )))\n\n(def interpv (duration fps rest: args)\n  (set duration (either duration 0.5))\n  (set fps (or fps 10))\n  (set vid (videobytes (then-image (time-percentage duration (apply interpolator args))) duration fps))\n  (set res (bytes-to-discord-file vid \"interp.mp4\"))\n  (go (chan*.send file: res)))\n\n(mac check (path)\n  `(let s (me.shell '(gsutil-checkpoints ,path))\n     (go (chan*.send file: (bytes-to-discord-file (s.encode \"utf8\") \"checkpoints.txt\")))))\n\n\n|\n\ndef get_grid_size(n):\n  gw = 1\n  gh = 1\n  i = 0\n  while gw*gh < n:\n    if i % 2 == 0:\n      gw += 1\n    else:\n      gh += 1\n    i += 1\n  return (gw, gh)\n\ndef gen_images(latents, outfile=None, display=False, labels=None, randomize_noise=False, is_validation=True, network=None):\n  if network is None:\n    network = Gs\n  n = latents.shape[0]\n  grid_size = get_grid_size(n)\n  drange_net = [-1, 1]\n  with tflex.device('/gpu:0'):\n    result = network.run(latents, labels, is_validation=is_validation, randomize_noise=randomize_noise, minibatch_size=sched.minibatch_gpu)\n    img = misc.convert_to_pil_image(misc.create_image_grid(result, grid_size), drange_net)\n    if outfile is not None:\n      img.save(outfile)\n    if display:\n      f = BytesIO()\n      img.save(f, 'png')\n      IPython.display.display(IPython.display.Image(data=f.getvalue()))\n  return result\n\nimport discord\nimport tensorflow as tf\ngrid_size = [1,1]\nimage_shrink = 1\nimage_zoom = 1\nduration_sec = 5.0\nsmoothing_sec = 1.0\nmp4_fps = 20\nmp4_codec = 'libx264'\nmp4_bitrate = '5M'\nrandom_seed = 82\nminibatch_size = 8\n\nnum_frames = int(np.rint(duration_sec * mp4_fps))\nrandom_state = np.random.RandomState(random_seed)\n\n# Generate latent vectors\nshape = [num_frames, np.prod(grid_size)] + Gs.input_shape[1:] # [frame, image, channel, component]\nall_latents = random_state.randn(*shape).astype(np.float32)\nimport scipy\nall_latents = scipy.ndimage.gaussian_filter(all_latents,\n                [smoothing_sec * mp4_fps] + [0] * len(Gs.input_shape), mode='wrap')\nall_latents /= np.sqrt(np.mean(np.square(all_latents)))\n\n\ndef rand_latent(n, seed=None):\n  if seed is not None:\n    if seed < 0:\n      seed = 2*32 - seed\n    np.random.seed(seed)\n  result = np.random.randn(n, *G.input_shape[1:])\n  if seed is not None:\n    np.random.seed()\n  return result\n\nsched = dnnlib.EasyDict()\nsched.minibatch_gpu = 1\n\n\n| \n\nnil\n\n"
  },
  {
    "path": "stylegan2-tpu/generate_images_tpu.py",
    "content": "import argparse\r\nimport os\r\nimport pathlib\r\nfrom pathlib import Path\r\nfrom pprint import pprint as pp\r\n\r\nimport numpy as np\r\nimport tensorflow as tf\r\nimport tqdm\r\nfrom tqdm import tqdm\r\n\r\nimport dnnlib\r\nimport tflex\r\nfrom dnnlib import EasyDict\r\nfrom training import misc\r\nfrom training.networks_stylegan2 import *\r\n\r\ntry:\r\n    from StringIO import StringIO as BytesIO  # for Python 2\r\nexcept ImportError:\r\n    from io import BytesIO  # for Python 3\r\n\r\n\r\ndef rand_latent(n, seed=None):\r\n    if seed is not None:\r\n        if seed < 0:\r\n            seed = 2*32 - seed\r\n        np.random.seed(seed)\r\n    result = np.random.randn(n, *G.input_shape[1:])\r\n    if seed is not None:\r\n        np.random.seed()\r\n    return result\r\n\r\n\r\ndef tfinit():\r\n    tflib.run(tf.global_variables_initializer())\r\n\r\n\r\ndef load_checkpoint(path, checkpoint_num=None):\r\n    if checkpoint_num is None:\r\n        ckpt = tf.train.latest_checkpoint(path)\r\n    else:\r\n        ckpt = os.path.join(path, f'model.ckpt-{checkpoint_num}')\r\n    assert ckpt is not None\r\n    print('Loading checkpoint ' + ckpt)\r\n    saver.restore(sess, ckpt)\r\n    return ckpt\r\n\r\n\r\ndef get_checkpoint(path):\r\n    ckpt = tf.train.latest_checkpoint(path)\r\n    return ckpt\r\n\r\n\r\ndef get_grid_size(n):\r\n    gw = 1\r\n    gh = 1\r\n    i = 0\r\n    while gw*gh < n:\r\n        if i % 2 == 0:\r\n            gw += 1\r\n        else:\r\n            gh += 1\r\n        i += 1\r\n    return (gw, gh)\r\n\r\n\r\ndef gen_images(latents, truncation_psi_val, outfile=None, display=False, labels=None, randomize_noise=False, is_validation=True, network=None, numpy=False):\r\n    if outfile:\r\n        Path(outfile).parent.mkdir(exist_ok=True, parents=True)\r\n    \r\n    if network is None:\r\n        network = Gs\r\n    n = latents.shape[0]\r\n    grid_size = get_grid_size(n)\r\n    drange_net = [-1, 1]\r\n    with tflex.device('/gpu:0'):\r\n        result = network.run(latents, labels, truncation_psi_val=truncation_psi_val, is_validation=is_validation, randomize_noise=randomize_noise,\r\n                             minibatch_size=sched.minibatch_gpu)\r\n        result = result[:, 0:3, :, :]\r\n        img = misc.convert_to_pil_image(\r\n            misc.create_image_grid(result, grid_size), drange_net)\r\n        if outfile is not None:\r\n            img.save(outfile)\r\n        if display:\r\n            f = BytesIO()\r\n            img.save(f, 'png')\r\n            IPython.display.display(IPython.display.Image(data=f.getvalue()))\r\n    return result if numpy else img\r\n\r\n\r\ndef grab(save_dir, i, n=1, latents=None, **kwargs):\r\n    if latents is None:\r\n        latents = rand_latent(n, seed=i)\r\n    gw, gh = get_grid_size(latents.shape[0])\r\n    outfile = str(save_dir/str(i)) + '.png'\r\n    return gen_images(latents, outfile=outfile, **kwargs)\r\n\r\n\r\nif __name__ == '__main__':\r\n    parser = argparse.ArgumentParser(description='StyleGAN2 TPU Generator')\r\n\r\n    parser.add_argument('--model_dir', type=str, action='store',\r\n                        help='Location of the checkpoint files')\r\n    parser.add_argument('--save_dir', type=str, action='store',\r\n                        help='Location of the directory to save images in')\r\n    parser.add_argument('--truncation_psi', type=float, action='store',\r\n                        help='Truncation psi (default: %(default)s)', default=0.7)\r\n    parser.add_argument('--num_samples', type=int, action='store',\r\n                        help='Number of samples to generate (default: %(default)s)',\r\n                        default=1)\r\n    parser.add_argument('--checkpoint_num', type=int, action='store',\r\n                        help='The checkpoint to use to generate the images. The default is the latest checkpoint in model_dir', default=None)\r\n\r\n    args = parser.parse_args()\r\n\r\n    # environment variables\r\n    os.environ['TPU_NAME'] = 'dkgan-tpu'\r\n    os.environ['NOISY'] = '1'\r\n\r\n    # --- set resolution and label size here:\r\n    label_size = 0\r\n    resolution = 512\r\n    fmap_base = (int(os.environ['FMAP_BASE'])\r\n                 if 'FMAP_BASE' in os.environ else 16) << 10\r\n    num_channels = 3\r\n    channel = 3\r\n    count = 1\r\n    grid_image_size = int(\r\n        os.environ['GRID_SIZE']) if 'GRID_SIZE' in os.environ else 9\r\n    # ------------------------\r\n    print('------------------')\r\n    print('Initializing model')\r\n    print('------------------')\r\n\r\n    # set up model\r\n    dnnlib.tflib.init_tf()\r\n\r\n    sess = tf.get_default_session()\r\n    sess.list_devices()\r\n\r\n    cores = tflex.get_cores()\r\n    tflex.set_override_cores(cores)\r\n\r\n    # Options for training loop.\r\n    train = EasyDict(run_func_name='training.training_loop.training_loop')\r\n    # Options for generator network.\r\n    G_args = EasyDict(func_name='training.networks_stylegan2.G_main')\r\n    # Options for discriminator network.\r\n    D_args = EasyDict(func_name='training.networks_stylegan2.D_stylegan2')\r\n    # Options for generator optimizer.\r\n    G_opt = EasyDict(beta1=0.0, beta2=0.99, epsilon=1e-8)\r\n    # Options for discriminator optimizer.\r\n    D_opt = EasyDict(beta1=0.0, beta2=0.99, epsilon=1e-8)\r\n    # Options for generator loss.\r\n    G_loss = EasyDict(func_name='training.loss.G_logistic_ns_pathreg')\r\n    # Options for discriminator loss.\r\n    D_loss = EasyDict(func_name='training.loss.D_logistic_r1')\r\n    # Options for TrainingSchedule.\r\n    sched = EasyDict()\r\n    # Options for setup_snapshot_image_grid().\r\n    grid = EasyDict(size='8k', layout='random')\r\n    # Options for dnnlib.submit_run().\r\n    sc = dnnlib.SubmitConfig()\r\n    tf_config = {'rnd.np_random_seed': 1000}\r\n    label_dtype = np.int64\r\n    sched.minibatch_gpu = 1\r\n\r\n    if 'G' not in globals():\r\n        with tflex.device('/gpu:0'):\r\n            G = tflib.Network('G', num_channels=num_channels, resolution=resolution,\r\n                              label_size=label_size, fmap_base=fmap_base, **G_args)\r\n            G.print_layers()\r\n            Gs, Gs_finalize = G.clone2('Gs')\r\n            Gs_finalize()\r\n            D = tflib.Network('D', num_channels=num_channels, resolution=resolution,\r\n                              label_size=label_size, fmap_base=fmap_base, **D_args)\r\n            D.print_layers()\r\n\r\n    grid_size = (2, 2)\r\n    gw, gh = grid_size\r\n    gn = np.prod(grid_size)\r\n    grid_latents = rand_latent(gn, seed=-1)\r\n    grid_labels = np.zeros([gw * gh, label_size], dtype=label_dtype)\r\n\r\n    tfinit()\r\n    print('-----------------')\r\n    print('Initialized model')\r\n    print('-----------------')\r\n    # ----------------------\r\n    # Load checkpoint\r\n    print('Loading checkpoint')\r\n    saver = tf.train.Saver()\r\n\r\n    # ------------------------\r\n    model_ckpt = load_checkpoint(args.model_dir, args.checkpoint_num)\r\n    model_name = model_ckpt.split('/')[4]\r\n    model_num = model_ckpt.split('-')[-1]\r\n    print('Loaded model', model_name)\r\n\r\n    tflex.state.noisy = False\r\n    # ---------------------\r\n    \r\n    save_dir = Path(args.save_dir)/model_num\r\n    # generate samples\r\n    for i in tqdm(list(range(args.num_samples))):\r\n        grab(save_dir, i=i,\r\n             truncation_psi_val=args.truncation_psi)  # modify seed\r\n"
  },
  {
    "path": "stylegan2-tpu/mammos.py",
    "content": "import sys\nimport os\n\nsys.path += [os.path.join(os.path.dirname(os.path.abspath(__file__)), '../pymen/bin')]\n\nif 'COLAB_TPU_ADDR' in os.environ:\n  os.environ['TPU_NAME'] = 'grpc://' + os.environ['COLAB_TPU_ADDR']\n\nos.environ['NOISY'] = '1'\n# --- set resolution and label size here:\nlabel_size = int(os.environ['LABEL_SIZE'])\nresolution = int(os.environ['RESOLUTION'])\nnum_channels = int(os.environ['NUM_CHANNELS'])\nmodel_dir = os.environ['MODEL_DIR']\ncount = int(os.environ['COUNT']) if 'COUNT' in os.environ else 1\ngrid_image_size = int(os.environ['GRID_SIZE']) if 'GRID_SIZE' in os.environ else 9\nbatch_size = 1\n# ------------------------\n\n\nimport numpy as np\nimport warnings\nwarnings.filterwarnings('ignore')\nimport tqdm\nfrom training.networks_stylegan2 import *\nfrom training import misc\n\nimport dnnlib\nfrom dnnlib import EasyDict\n\nimport tensorflow as tf\nimport tflex\nimport os\nimport numpy as np\n\ntflex.self = globals()\n\ntrain     = EasyDict(run_func_name='training.training_loop.training_loop') # Options for training loop.\nG_args    = EasyDict(func_name='training.networks_stylegan2.G_main')       # Options for generator network.\nD_args    = EasyDict(func_name='training.networks_stylegan2.D_stylegan2')  # Options for discriminator network.\nG_opt     = EasyDict(beta1=0.0, beta2=0.99, epsilon=1e-8)                  # Options for generator optimizer.\nD_opt     = EasyDict(beta1=0.0, beta2=0.99, epsilon=1e-8)                  # Options for discriminator optimizer.\nG_loss    = EasyDict(func_name='training.loss.G_logistic_ns_pathreg')      # Options for generator loss.\nD_loss    = EasyDict(func_name='training.loss.D_logistic_r1')              # Options for discriminator loss.\nsched     = EasyDict()                                                     # Options for TrainingSchedule.\ngrid      = EasyDict(size='8k', layout='random')                           # Options for setup_snapshot_image_grid().\nsc        = dnnlib.SubmitConfig()                                          # Options for dnnlib.submit_run().\ntf_config = {'rnd.np_random_seed': 1000}    \nlabel_dtype = np.int64\nsched.minibatch_gpu = 1\n\ndef with_session(sess, f, *args, **kws):\n  with sess.as_default():\n    return f(*args, **kws)\n\nasync def with_session_async(sess, f, *args, **kws):\n  with sess.as_default():\n    return await f(*args, **kws)\n\ndef init(session=None, num_channels=None, resolution=None, label_size=None):\n  label_size = int(os.environ['LABEL_SIZE']) if label_size is None else label_size\n  resolution = int(os.environ['RESOLUTION']) if resolution is None else resolution\n  num_channels = int(os.environ['NUM_CHANNELS']) if num_channels is None else num_channels\n  dnnlib.tflib.init_tf()\n\n  session = tflex.get_session(session)\n  pprint(session.list_devices())\n\n  tflex.set_override_cores(tflex.get_cores())\n  with tflex.device('/gpu:0'):\n    tflex.G = tflib.Network('G', num_channels=num_channels, resolution=resolution, label_size=label_size, **G_args)\n    tflex.G.print_layers()\n    tflex.Gs, tflex.Gs_finalize = tflex.G.clone2('Gs')\n    tflex.Gs_finalize()\n    tflex.D = tflib.Network('D', num_channels=num_channels, resolution=resolution, label_size=label_size, **D_args)\n    tflex.D.print_layers()\n  tflib.run(tf.global_variables_initializer())\n  return session\n\ndef load_checkpoint(path, session=None, var_list=None):\n  if var_list is None:\n    var_list = tflex.Gs.trainables\n  ckpt = tf.train.latest_checkpoint(path) or path\n  assert ckpt is not None\n  print('Loading checkpoint ' + ckpt)\n  saver = tf.train.Saver(var_list=var_list)\n  saver.restore(tflex.get_session(session), ckpt)\n  return ckpt\n\ninit()\nload_checkpoint(model_dir)\n\nimport PIL.Image\nimport numpy as np\nimport requests\nfrom io import BytesIO\n\ndef get_images(tags, seed = 0, mu = 0, sigma = 0, truncation=None):\n    print(\"Generating mammos...\")\n\n    Gs_kwargs = dnnlib.EasyDict()\n    Gs_kwargs.output_transform = dict(func=tflib.convert_images_to_uint8, nchw_to_nhwc=True)\n    Gs_kwargs.randomize_noise = False\n    if truncation is not None:\n        Gs_kwargs.truncation_psi = truncation\n    rnd = np.random.RandomState(seed)\n\n    all_seeds = [seed] * batch_size\n    all_z = np.stack([np.random.RandomState(seed).randn(*tflex.Gs.input_shape[1:]) for seed in all_seeds]) # [minibatch, component]\n    print(all_z.shape)\n\n    drange_net = [-1, 1]\n    with tflex.device('/gpu:0'):\n      result = tflex.Gs.run(all_z, None, is_validation=True, randomize_noise=False, minibatch_size=sched.minibatch_gpu)\n      if result.shape[1] > 3:\n        final = result[:, 3, :, :]\n      else:\n        final = None\n      result = result[:, 0:3, :, :]\n      img = misc.convert_to_pil_image(misc.create_image_grid(result, (1, 1)), drange_net)\n      img.save('mammos.png')\n      return result, img\n"
  },
  {
    "path": "stylegan2-tpu/metrics/__init__.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n# empty\n"
  },
  {
    "path": "stylegan2-tpu/metrics/frechet_inception_distance.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Frechet Inception Distance (FID).\"\"\"\n\nimport os\nimport numpy as np\nimport scipy\nimport tensorflow as tf\nimport tflex\nimport dnnlib.tflib as tflib\n\nfrom metrics import metric_base\nfrom training import misc\n\n#----------------------------------------------------------------------------\n\nclass FID(metric_base.MetricBase):\n    def __init__(self, num_images, minibatch_per_gpu, **kwargs):\n        super().__init__(**kwargs)\n        self.num_images = num_images\n        self.minibatch_per_gpu = minibatch_per_gpu\n\n    def _evaluate(self, Gs, Gs_kwargs, num_gpus):\n        minibatch_size = num_gpus * self.minibatch_per_gpu\n        inception = misc.load_pkl('https://drive.google.com/uc?id=1MzTY44rLToO5APn8TZmfR7_ENSe5aZUn', 'inception_v3_features.pkl')\n        activations = np.empty([self.num_images, inception.output_shape[1]], dtype=np.float32)\n\n        # Calculate statistics for reals.\n        cache_file = self._get_cache_file_for_reals(num_images=self.num_images)\n        os.makedirs(os.path.dirname(cache_file), exist_ok=True)\n        if os.path.isfile(cache_file):\n            mu_real, sigma_real = misc.load_pkl(cache_file)\n        else:\n            for idx, images in enumerate(self._iterate_reals(minibatch_size=minibatch_size)):\n                begin = idx * minibatch_size\n                end = min(begin + minibatch_size, self.num_images)\n                activations[begin:end] = inception.run(images[:end-begin], num_gpus=num_gpus, assume_frozen=True)\n                if end == self.num_images:\n                    break\n            mu_real = np.mean(activations, axis=0)\n            sigma_real = np.cov(activations, rowvar=False)\n            misc.save_pkl((mu_real, sigma_real), cache_file)\n\n        # Construct TensorFlow graph.\n        result_expr = []\n        for gpu_idx in range(num_gpus):\n            with tflex.device('/gpu:%d' % gpu_idx):\n                Gs_clone = Gs.clone()\n                inception_clone = inception.clone()\n                latents = tf.random_normal([self.minibatch_per_gpu] + Gs_clone.input_shape[1:])\n                labels = self._get_random_labels_tf(self.minibatch_per_gpu)\n                images = Gs_clone.get_output_for(latents, labels, **Gs_kwargs)\n                images = tflib.convert_images_to_uint8(images)\n                result_expr.append(inception_clone.get_output_for(images))\n\n        # Calculate statistics for fakes.\n        for begin in range(0, self.num_images, minibatch_size):\n            self._report_progress(begin, self.num_images)\n            end = min(begin + minibatch_size, self.num_images)\n            activations[begin:end] = np.concatenate(tflib.run(result_expr), axis=0)[:end-begin]\n        mu_fake = np.mean(activations, axis=0)\n        sigma_fake = np.cov(activations, rowvar=False)\n\n        # Calculate FID.\n        m = np.square(mu_fake - mu_real).sum()\n        s, _ = scipy.linalg.sqrtm(np.dot(sigma_fake, sigma_real), disp=False) # pylint: disable=no-member\n        dist = m + np.trace(sigma_fake + sigma_real - 2*s)\n        self._report_result(np.real(dist))\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/metrics/inception_score.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Inception Score (IS).\"\"\"\n\nimport numpy as np\nimport tensorflow as tf\nimport tflex\nimport dnnlib.tflib as tflib\n\nfrom metrics import metric_base\nfrom training import misc\n\n#----------------------------------------------------------------------------\n\nclass IS(metric_base.MetricBase):\n    def __init__(self, num_images, num_splits, minibatch_per_gpu, **kwargs):\n        super().__init__(**kwargs)\n        self.num_images = num_images\n        self.num_splits = num_splits\n        self.minibatch_per_gpu = minibatch_per_gpu\n\n    def _evaluate(self, Gs, Gs_kwargs, num_gpus):\n        minibatch_size = num_gpus * self.minibatch_per_gpu\n        inception = misc.load_pkl('https://drive.google.com/uc?id=1Mz9zQnIrusm3duZB91ng_aUIePFNI6Jx', 'inception_v3_softmax.pkl')\n        activations = np.empty([self.num_images, inception.output_shape[1]], dtype=np.float32)\n\n        # Construct TensorFlow graph.\n        result_expr = []\n        for gpu_idx in range(num_gpus):\n            with tflex.device('/gpu:%d' % gpu_idx):\n                Gs_clone = Gs.clone()\n                inception_clone = inception.clone()\n                latents = tf.random_normal([self.minibatch_per_gpu] + Gs_clone.input_shape[1:])\n                labels = self._get_random_labels_tf(self.minibatch_per_gpu)\n                images = Gs_clone.get_output_for(latents, labels, **Gs_kwargs)\n                images = tflib.convert_images_to_uint8(images)\n                result_expr.append(inception_clone.get_output_for(images))\n\n        # Calculate activations for fakes.\n        for begin in range(0, self.num_images, minibatch_size):\n            self._report_progress(begin, self.num_images)\n            end = min(begin + minibatch_size, self.num_images)\n            activations[begin:end] = np.concatenate(tflib.run(result_expr), axis=0)[:end-begin]\n\n        # Calculate IS.\n        scores = []\n        for i in range(self.num_splits):\n            part = activations[i * self.num_images // self.num_splits : (i + 1) * self.num_images // self.num_splits]\n            kl = part * (np.log(part) - np.log(np.expand_dims(np.mean(part, 0), 0)))\n            kl = np.mean(np.sum(kl, 1))\n            scores.append(np.exp(kl))\n        self._report_result(np.mean(scores), suffix='_mean')\n        self._report_result(np.std(scores), suffix='_std')\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/metrics/linear_separability.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Linear Separability (LS).\"\"\"\n\nfrom collections import defaultdict\nimport numpy as np\nimport sklearn.svm\nimport tensorflow as tf\nimport tflex\nimport dnnlib.tflib as tflib\n\nfrom metrics import metric_base\nfrom training import misc\n\n#----------------------------------------------------------------------------\n\nclassifier_urls = [\n    'https://drive.google.com/uc?id=1Q5-AI6TwWhCVM7Muu4tBM7rp5nG_gmCX', # celebahq-classifier-00-male.pkl\n    'https://drive.google.com/uc?id=1Q5c6HE__ReW2W8qYAXpao68V1ryuisGo', # celebahq-classifier-01-smiling.pkl\n    'https://drive.google.com/uc?id=1Q7738mgWTljPOJQrZtSMLxzShEhrvVsU', # celebahq-classifier-02-attractive.pkl\n    'https://drive.google.com/uc?id=1QBv2Mxe7ZLvOv1YBTLq-T4DS3HjmXV0o', # celebahq-classifier-03-wavy-hair.pkl\n    'https://drive.google.com/uc?id=1QIvKTrkYpUrdA45nf7pspwAqXDwWOLhV', # celebahq-classifier-04-young.pkl\n    'https://drive.google.com/uc?id=1QJPH5rW7MbIjFUdZT7vRYfyUjNYDl4_L', # celebahq-classifier-05-5-o-clock-shadow.pkl\n    'https://drive.google.com/uc?id=1QPZXSYf6cptQnApWS_T83sqFMun3rULY', # celebahq-classifier-06-arched-eyebrows.pkl\n    'https://drive.google.com/uc?id=1QPgoAZRqINXk_PFoQ6NwMmiJfxc5d2Pg', # celebahq-classifier-07-bags-under-eyes.pkl\n    'https://drive.google.com/uc?id=1QQPQgxgI6wrMWNyxFyTLSgMVZmRr1oO7', # celebahq-classifier-08-bald.pkl\n    'https://drive.google.com/uc?id=1QcSphAmV62UrCIqhMGgcIlZfoe8hfWaF', # celebahq-classifier-09-bangs.pkl\n    'https://drive.google.com/uc?id=1QdWTVwljClTFrrrcZnPuPOR4mEuz7jGh', # celebahq-classifier-10-big-lips.pkl\n    'https://drive.google.com/uc?id=1QgvEWEtr2mS4yj1b_Y3WKe6cLWL3LYmK', # celebahq-classifier-11-big-nose.pkl\n    'https://drive.google.com/uc?id=1QidfMk9FOKgmUUIziTCeo8t-kTGwcT18', # celebahq-classifier-12-black-hair.pkl\n    'https://drive.google.com/uc?id=1QthrJt-wY31GPtV8SbnZQZ0_UEdhasHO', # celebahq-classifier-13-blond-hair.pkl\n    'https://drive.google.com/uc?id=1QvCAkXxdYT4sIwCzYDnCL9Nb5TDYUxGW', # celebahq-classifier-14-blurry.pkl\n    'https://drive.google.com/uc?id=1QvLWuwSuWI9Ln8cpxSGHIciUsnmaw8L0', # celebahq-classifier-15-brown-hair.pkl\n    'https://drive.google.com/uc?id=1QxW6THPI2fqDoiFEMaV6pWWHhKI_OoA7', # celebahq-classifier-16-bushy-eyebrows.pkl\n    'https://drive.google.com/uc?id=1R71xKw8oTW2IHyqmRDChhTBkW9wq4N9v', # celebahq-classifier-17-chubby.pkl\n    'https://drive.google.com/uc?id=1RDn_fiLfEGbTc7JjazRXuAxJpr-4Pl67', # celebahq-classifier-18-double-chin.pkl\n    'https://drive.google.com/uc?id=1RGBuwXbaz5052bM4VFvaSJaqNvVM4_cI', # celebahq-classifier-19-eyeglasses.pkl\n    'https://drive.google.com/uc?id=1RIxOiWxDpUwhB-9HzDkbkLegkd7euRU9', # celebahq-classifier-20-goatee.pkl\n    'https://drive.google.com/uc?id=1RPaNiEnJODdr-fwXhUFdoSQLFFZC7rC-', # celebahq-classifier-21-gray-hair.pkl\n    'https://drive.google.com/uc?id=1RQH8lPSwOI2K_9XQCZ2Ktz7xm46o80ep', # celebahq-classifier-22-heavy-makeup.pkl\n    'https://drive.google.com/uc?id=1RXZM61xCzlwUZKq-X7QhxOg0D2telPow', # celebahq-classifier-23-high-cheekbones.pkl\n    'https://drive.google.com/uc?id=1RgASVHW8EWMyOCiRb5fsUijFu-HfxONM', # celebahq-classifier-24-mouth-slightly-open.pkl\n    'https://drive.google.com/uc?id=1RkC8JLqLosWMaRne3DARRgolhbtg_wnr', # celebahq-classifier-25-mustache.pkl\n    'https://drive.google.com/uc?id=1RqtbtFT2EuwpGTqsTYJDyXdnDsFCPtLO', # celebahq-classifier-26-narrow-eyes.pkl\n    'https://drive.google.com/uc?id=1Rs7hU-re8bBMeRHR-fKgMbjPh-RIbrsh', # celebahq-classifier-27-no-beard.pkl\n    'https://drive.google.com/uc?id=1RynDJQWdGOAGffmkPVCrLJqy_fciPF9E', # celebahq-classifier-28-oval-face.pkl\n    'https://drive.google.com/uc?id=1S0TZ_Hdv5cb06NDaCD8NqVfKy7MuXZsN', # celebahq-classifier-29-pale-skin.pkl\n    'https://drive.google.com/uc?id=1S3JPhZH2B4gVZZYCWkxoRP11q09PjCkA', # celebahq-classifier-30-pointy-nose.pkl\n    'https://drive.google.com/uc?id=1S3pQuUz-Jiywq_euhsfezWfGkfzLZ87W', # celebahq-classifier-31-receding-hairline.pkl\n    'https://drive.google.com/uc?id=1S6nyIl_SEI3M4l748xEdTV2vymB_-lrY', # celebahq-classifier-32-rosy-cheeks.pkl\n    'https://drive.google.com/uc?id=1S9P5WCi3GYIBPVYiPTWygrYIUSIKGxbU', # celebahq-classifier-33-sideburns.pkl\n    'https://drive.google.com/uc?id=1SANviG-pp08n7AFpE9wrARzozPIlbfCH', # celebahq-classifier-34-straight-hair.pkl\n    'https://drive.google.com/uc?id=1SArgyMl6_z7P7coAuArqUC2zbmckecEY', # celebahq-classifier-35-wearing-earrings.pkl\n    'https://drive.google.com/uc?id=1SC5JjS5J-J4zXFO9Vk2ZU2DT82TZUza_', # celebahq-classifier-36-wearing-hat.pkl\n    'https://drive.google.com/uc?id=1SDAQWz03HGiu0MSOKyn7gvrp3wdIGoj-', # celebahq-classifier-37-wearing-lipstick.pkl\n    'https://drive.google.com/uc?id=1SEtrVK-TQUC0XeGkBE9y7L8VXfbchyKX', # celebahq-classifier-38-wearing-necklace.pkl\n    'https://drive.google.com/uc?id=1SF_mJIdyGINXoV-I6IAxHB_k5dxiF6M-', # celebahq-classifier-39-wearing-necktie.pkl\n]\n\n#----------------------------------------------------------------------------\n\ndef prob_normalize(p):\n    p = np.asarray(p).astype(np.float32)\n    assert len(p.shape) == 2\n    return p / np.sum(p)\n\ndef mutual_information(p):\n    p = prob_normalize(p)\n    px = np.sum(p, axis=1)\n    py = np.sum(p, axis=0)\n    result = 0.0\n    for x in range(p.shape[0]):\n        p_x = px[x]\n        for y in range(p.shape[1]):\n            p_xy = p[x][y]\n            p_y = py[y]\n            if p_xy > 0.0:\n                result += p_xy * np.log2(p_xy / (p_x * p_y)) # get bits as output\n    return result\n\ndef entropy(p):\n    p = prob_normalize(p)\n    result = 0.0\n    for x in range(p.shape[0]):\n        for y in range(p.shape[1]):\n            p_xy = p[x][y]\n            if p_xy > 0.0:\n                result -= p_xy * np.log2(p_xy)\n    return result\n\ndef conditional_entropy(p):\n    # H(Y|X) where X corresponds to axis 0, Y to axis 1\n    # i.e., How many bits of additional information are needed to where we are on axis 1 if we know where we are on axis 0?\n    p = prob_normalize(p)\n    y = np.sum(p, axis=0, keepdims=True) # marginalize to calculate H(Y)\n    return max(0.0, entropy(y) - mutual_information(p)) # can slip just below 0 due to FP inaccuracies, clean those up.\n\n#----------------------------------------------------------------------------\n\nclass LS(metric_base.MetricBase):\n    def __init__(self, num_samples, num_keep, attrib_indices, minibatch_per_gpu, **kwargs):\n        assert num_keep <= num_samples\n        super().__init__(**kwargs)\n        self.num_samples = num_samples\n        self.num_keep = num_keep\n        self.attrib_indices = attrib_indices\n        self.minibatch_per_gpu = minibatch_per_gpu\n\n    def _evaluate(self, Gs, Gs_kwargs, num_gpus):\n        minibatch_size = num_gpus * self.minibatch_per_gpu\n\n        # Construct TensorFlow graph for each GPU.\n        result_expr = []\n        for gpu_idx in range(num_gpus):\n            with tflex.device('/gpu:%d' % gpu_idx):\n                Gs_clone = Gs.clone()\n\n                # Generate images.\n                latents = tf.random_normal([self.minibatch_per_gpu] + Gs_clone.input_shape[1:])\n                labels = self._get_random_labels_tf(self.minibatch_per_gpu)\n                dlatents = Gs_clone.components.mapping.get_output_for(latents, labels, **Gs_kwargs)\n                images = Gs_clone.get_output_for(latents, None, **Gs_kwargs)\n\n                # Downsample to 256x256. The attribute classifiers were built for 256x256.\n                if images.shape[2] > 256:\n                    factor = images.shape[2] // 256\n                    images = tf.reshape(images, [-1, images.shape[1], images.shape[2] // factor, factor, images.shape[3] // factor, factor])\n                    images = tf.reduce_mean(images, axis=[3, 5])\n\n                # Run classifier for each attribute.\n                result_dict = dict(latents=latents, dlatents=dlatents[:,-1])\n                for attrib_idx in self.attrib_indices:\n                    classifier = misc.load_pkl(classifier_urls[attrib_idx])\n                    logits = classifier.get_output_for(images, None)\n                    predictions = tf.nn.softmax(tf.concat([logits, -logits], axis=1))\n                    result_dict[attrib_idx] = predictions\n                result_expr.append(result_dict)\n\n        # Sampling loop.\n        results = []\n        for begin in range(0, self.num_samples, minibatch_size):\n            self._report_progress(begin, self.num_samples)\n            results += tflib.run(result_expr)\n        results = {key: np.concatenate([value[key] for value in results], axis=0) for key in results[0].keys()}\n\n        # Calculate conditional entropy for each attribute.\n        conditional_entropies = defaultdict(list)\n        for attrib_idx in self.attrib_indices:\n            # Prune the least confident samples.\n            pruned_indices = list(range(self.num_samples))\n            pruned_indices = sorted(pruned_indices, key=lambda i: -np.max(results[attrib_idx][i]))\n            pruned_indices = pruned_indices[:self.num_keep]\n\n            # Fit SVM to the remaining samples.\n            svm_targets = np.argmax(results[attrib_idx][pruned_indices], axis=1)\n            for space in ['latents', 'dlatents']:\n                svm_inputs = results[space][pruned_indices]\n                try:\n                    svm = sklearn.svm.LinearSVC()\n                    svm.fit(svm_inputs, svm_targets)\n                    svm.score(svm_inputs, svm_targets)\n                    svm_outputs = svm.predict(svm_inputs)\n                except:\n                    svm_outputs = svm_targets # assume perfect prediction\n\n                # Calculate conditional entropy.\n                p = [[np.mean([case == (row, col) for case in zip(svm_outputs, svm_targets)]) for col in (0, 1)] for row in (0, 1)]\n                conditional_entropies[space].append(conditional_entropy(p))\n\n        # Calculate separability scores.\n        scores = {key: 2**np.sum(values) for key, values in conditional_entropies.items()}\n        self._report_result(scores['latents'], suffix='_z')\n        self._report_result(scores['dlatents'], suffix='_w')\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/metrics/metric_base.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Common definitions for GAN metrics.\"\"\"\n\nimport os\nimport time\nimport hashlib\nimport numpy as np\nimport tensorflow as tf\nimport dnnlib\nimport dnnlib.tflib as tflib\n\nfrom training import misc\nfrom training import dataset\n\n#----------------------------------------------------------------------------\n# Base class for metrics.\n\nclass MetricBase:\n    def __init__(self, name):\n        self.name = name\n        self._dataset_obj = None\n        self._progress_lo = None\n        self._progress_hi = None\n        self._progress_max = None\n        self._progress_sec = None\n        self._progress_time = None\n        self._reset()\n\n    def close(self):\n        self._reset()\n\n    def _reset(self, network_pkl=None, run_dir=None, data_dir=None, dataset_args=None, mirror_augment=None):\n        if self._dataset_obj is not None:\n            self._dataset_obj.close()\n\n        self._network_pkl = network_pkl\n        self._data_dir = data_dir\n        self._dataset_args = dataset_args\n        self._dataset_obj = None\n        self._mirror_augment = mirror_augment\n        self._eval_time = 0\n        self._results = []\n\n        if (dataset_args is None or mirror_augment is None) and run_dir is not None:\n            run_config = misc.parse_config_for_previous_run(run_dir)\n            self._dataset_args = dict(run_config['dataset'])\n            self._dataset_args['shuffle_mb'] = 0\n            self._mirror_augment = run_config['train'].get('mirror_augment', False)\n\n    def configure_progress_reports(self, plo, phi, pmax, psec=15):\n        self._progress_lo = plo\n        self._progress_hi = phi\n        self._progress_max = pmax\n        self._progress_sec = psec\n\n    def run(self, network_pkl, run_dir=None, data_dir=None, dataset_args=None, mirror_augment=None, num_gpus=1, tf_config=None, log_results=True, Gs_kwargs=dict(is_validation=True)):\n        self._reset(network_pkl=network_pkl, run_dir=run_dir, data_dir=data_dir, dataset_args=dataset_args, mirror_augment=mirror_augment)\n        time_begin = time.time()\n        with tf.Graph().as_default(), tflib.create_session(tf_config).as_default(): # pylint: disable=not-context-manager\n            self._report_progress(0, 1)\n            _G, _D, Gs = misc.load_pkl(self._network_pkl)\n            self._evaluate(Gs, Gs_kwargs=Gs_kwargs, num_gpus=num_gpus)\n            self._report_progress(1, 1)\n        self._eval_time = time.time() - time_begin # pylint: disable=attribute-defined-outside-init\n\n        if log_results:\n            if run_dir is not None:\n                log_file = os.path.join(run_dir, 'metric-%s.txt' % self.name)\n                with dnnlib.util.Logger(log_file, 'a'):\n                    print(self.get_result_str().strip())\n            else:\n                print(self.get_result_str().strip())\n\n    def get_result_str(self):\n        network_name = os.path.splitext(os.path.basename(self._network_pkl))[0]\n        if len(network_name) > 29:\n            network_name = '...' + network_name[-26:]\n        result_str = '%-30s' % network_name\n        result_str += ' time %-12s' % dnnlib.util.format_time(self._eval_time)\n        for res in self._results:\n            result_str += ' ' + self.name + res.suffix + ' '\n            result_str += res.fmt % res.value\n        return result_str\n\n    def update_autosummaries(self):\n        for res in self._results:\n            tflib.autosummary.autosummary('Metrics/' + self.name + res.suffix, res.value)\n\n    def _evaluate(self, Gs, Gs_kwargs, num_gpus):\n        raise NotImplementedError # to be overridden by subclasses\n\n    def _report_result(self, value, suffix='', fmt='%-10.4f'):\n        self._results += [dnnlib.EasyDict(value=value, suffix=suffix, fmt=fmt)]\n\n    def _report_progress(self, pcur, pmax, status_str=''):\n        if self._progress_lo is None or self._progress_hi is None or self._progress_max is None:\n            return\n        t = time.time()\n        if self._progress_sec is not None and self._progress_time is not None and t < self._progress_time + self._progress_sec:\n            return\n        self._progress_time = t\n        val = self._progress_lo + (pcur / pmax) * (self._progress_hi - self._progress_lo)\n        dnnlib.RunContext.get().update(status_str, int(val), self._progress_max)\n\n    def _get_cache_file_for_reals(self, extension='pkl', **kwargs):\n        all_args = dnnlib.EasyDict(metric_name=self.name, mirror_augment=self._mirror_augment)\n        all_args.update(self._dataset_args)\n        all_args.update(kwargs)\n        md5 = hashlib.md5(repr(sorted(all_args.items())).encode('utf-8'))\n        dataset_name = self._dataset_args.get('tfrecord_dir', None) or self._dataset_args.get('h5_file', None)\n        dataset_name = os.path.splitext(os.path.basename(dataset_name))[0]\n        return os.path.join('.stylegan2-cache', '%s-%s-%s.%s' % (md5.hexdigest(), self.name, dataset_name, extension))\n\n    def _get_dataset_obj(self):\n        if self._dataset_obj is None:\n            self._dataset_obj = dataset.load_dataset(data_dir=self._data_dir, **self._dataset_args)\n        return self._dataset_obj\n\n    def _iterate_reals(self, minibatch_size):\n        dataset_obj = self._get_dataset_obj()\n        while True:\n            images, _labels = dataset_obj.get_minibatch_np(minibatch_size)\n            if self._mirror_augment:\n                images = misc.apply_mirror_augment(images)\n            yield images\n\n    def _iterate_fakes(self, Gs, minibatch_size, num_gpus):\n        while True:\n            latents = np.random.randn(minibatch_size, *Gs.input_shape[1:])\n            fmt = dict(func=tflib.convert_images_to_uint8, nchw_to_nhwc=True)\n            images = Gs.run(latents, None, output_transform=fmt, is_validation=True, num_gpus=num_gpus, assume_frozen=True)\n            yield images\n\n    def _get_random_labels_tf(self, minibatch_size):\n        return self._get_dataset_obj().get_random_labels_tf(minibatch_size)\n\n#----------------------------------------------------------------------------\n# Group of multiple metrics.\n\nclass MetricGroup:\n    def __init__(self, metric_kwarg_list):\n        self.metrics = [dnnlib.util.call_func_by_name(**kwargs) for kwargs in metric_kwarg_list]\n\n    def run(self, *args, **kwargs):\n        for metric in self.metrics:\n            metric.run(*args, **kwargs)\n\n    def get_result_str(self):\n        return ' '.join(metric.get_result_str() for metric in self.metrics)\n\n    def update_autosummaries(self):\n        for metric in self.metrics:\n            metric.update_autosummaries()\n\n#----------------------------------------------------------------------------\n# Dummy metric for debugging purposes.\n\nclass DummyMetric(MetricBase):\n    def _evaluate(self, Gs, Gs_kwargs, num_gpus):\n        _ = Gs, Gs_kwargs, num_gpus\n        self._report_result(0.0)\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/metrics/metric_defaults.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Default metric definitions.\"\"\"\n\nfrom dnnlib import EasyDict\n\n#----------------------------------------------------------------------------\n\nmetric_defaults = EasyDict([(args.name, args) for args in [\n    EasyDict(name='fid50k',    func_name='metrics.frechet_inception_distance.FID', num_images=50000, minibatch_per_gpu=8),\n    EasyDict(name='is50k',     func_name='metrics.inception_score.IS',             num_images=50000, num_splits=10, minibatch_per_gpu=8),\n    EasyDict(name='ppl_zfull', func_name='metrics.perceptual_path_length.PPL',     num_samples=50000, epsilon=1e-4, space='z', sampling='full', crop=True, minibatch_per_gpu=4, Gs_overrides=dict(dtype='float32', mapping_dtype='float32')),\n    EasyDict(name='ppl_wfull', func_name='metrics.perceptual_path_length.PPL',     num_samples=50000, epsilon=1e-4, space='w', sampling='full', crop=True, minibatch_per_gpu=4, Gs_overrides=dict(dtype='float32', mapping_dtype='float32')),\n    EasyDict(name='ppl_zend',  func_name='metrics.perceptual_path_length.PPL',     num_samples=50000, epsilon=1e-4, space='z', sampling='end', crop=True, minibatch_per_gpu=4, Gs_overrides=dict(dtype='float32', mapping_dtype='float32')),\n    EasyDict(name='ppl_wend',  func_name='metrics.perceptual_path_length.PPL',     num_samples=50000, epsilon=1e-4, space='w', sampling='end', crop=True, minibatch_per_gpu=4, Gs_overrides=dict(dtype='float32', mapping_dtype='float32')),\n    EasyDict(name='ppl2_wend', func_name='metrics.perceptual_path_length.PPL',     num_samples=50000, epsilon=1e-4, space='w', sampling='end', crop=False, minibatch_per_gpu=4, Gs_overrides=dict(dtype='float32', mapping_dtype='float32')),\n    EasyDict(name='ls',        func_name='metrics.linear_separability.LS',         num_samples=200000, num_keep=100000, attrib_indices=range(40), minibatch_per_gpu=4),\n    EasyDict(name='pr50k3',    func_name='metrics.precision_recall.PR',            num_images=50000, nhood_size=3, minibatch_per_gpu=8, row_batch_size=10000, col_batch_size=10000),\n]])\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/metrics/perceptual_path_length.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Perceptual Path Length (PPL).\"\"\"\n\nimport numpy as np\nimport tensorflow as tf\nimport tflex\nimport dnnlib.tflib as tflib\n\nfrom metrics import metric_base\nfrom training import misc\n\n#----------------------------------------------------------------------------\n\n# Normalize batch of vectors.\ndef normalize(v):\n    return v / tf.sqrt(tf.reduce_sum(tf.square(v), axis=-1, keepdims=True))\n\n# Spherical interpolation of a batch of vectors.\ndef slerp(a, b, t):\n    a = normalize(a)\n    b = normalize(b)\n    d = tf.reduce_sum(a * b, axis=-1, keepdims=True)\n    p = t * tf.math.acos(d)\n    c = normalize(b - d * a)\n    d = a * tf.math.cos(p) + c * tf.math.sin(p)\n    return normalize(d)\n\n#----------------------------------------------------------------------------\n\nclass PPL(metric_base.MetricBase):\n    def __init__(self, num_samples, epsilon, space, sampling, crop, minibatch_per_gpu, Gs_overrides, **kwargs):\n        assert space in ['z', 'w']\n        assert sampling in ['full', 'end']\n        super().__init__(**kwargs)\n        self.num_samples = num_samples\n        self.epsilon = epsilon\n        self.space = space\n        self.sampling = sampling\n        self.crop = crop\n        self.minibatch_per_gpu = minibatch_per_gpu\n        self.Gs_overrides = Gs_overrides\n\n    def _evaluate(self, Gs, Gs_kwargs, num_gpus):\n        Gs_kwargs = dict(Gs_kwargs)\n        Gs_kwargs.update(self.Gs_overrides)\n        minibatch_size = num_gpus * self.minibatch_per_gpu\n\n        # Construct TensorFlow graph.\n        distance_expr = []\n        for gpu_idx in range(num_gpus):\n            with tflex.device('/gpu:%d' % gpu_idx):\n                Gs_clone = Gs.clone()\n                noise_vars = [var for name, var in Gs_clone.components.synthesis.vars.items() if name.startswith('noise')]\n\n                # Generate random latents and interpolation t-values.\n                lat_t01 = tf.random_normal([self.minibatch_per_gpu * 2] + Gs_clone.input_shape[1:])\n                lerp_t = tf.random_uniform([self.minibatch_per_gpu], 0.0, 1.0 if self.sampling == 'full' else 0.0)\n                labels = tf.reshape(tf.tile(self._get_random_labels_tf(self.minibatch_per_gpu), [1, 2]), [self.minibatch_per_gpu * 2, -1])\n\n                # Interpolate in W or Z.\n                if self.space == 'w':\n                    dlat_t01 = Gs_clone.components.mapping.get_output_for(lat_t01, labels, **Gs_kwargs)\n                    dlat_t01 = tf.cast(dlat_t01, tf.float32)\n                    dlat_t0, dlat_t1 = dlat_t01[0::2], dlat_t01[1::2]\n                    dlat_e0 = tflib.lerp(dlat_t0, dlat_t1, lerp_t[:, np.newaxis, np.newaxis])\n                    dlat_e1 = tflib.lerp(dlat_t0, dlat_t1, lerp_t[:, np.newaxis, np.newaxis] + self.epsilon)\n                    dlat_e01 = tf.reshape(tf.stack([dlat_e0, dlat_e1], axis=1), dlat_t01.shape)\n                else: # space == 'z'\n                    lat_t0, lat_t1 = lat_t01[0::2], lat_t01[1::2]\n                    lat_e0 = slerp(lat_t0, lat_t1, lerp_t[:, np.newaxis])\n                    lat_e1 = slerp(lat_t0, lat_t1, lerp_t[:, np.newaxis] + self.epsilon)\n                    lat_e01 = tf.reshape(tf.stack([lat_e0, lat_e1], axis=1), lat_t01.shape)\n                    dlat_e01 = Gs_clone.components.mapping.get_output_for(lat_e01, labels, **Gs_kwargs)\n\n                # Synthesize images.\n                with tf.control_dependencies([var.initializer for var in noise_vars]): # use same noise inputs for the entire minibatch\n                    images = Gs_clone.components.synthesis.get_output_for(dlat_e01, randomize_noise=False, **Gs_kwargs)\n                    images = tf.cast(images, tf.float32)\n\n                # Crop only the face region.\n                if self.crop:\n                    c = int(images.shape[2] // 8)\n                    images = images[:, :, c*3 : c*7, c*2 : c*6]\n\n                # Downsample image to 256x256 if it's larger than that. VGG was built for 224x224 images.\n                factor = images.shape[2] // 256\n                if factor > 1:\n                    images = tf.reshape(images, [-1, images.shape[1], images.shape[2] // factor, factor, images.shape[3] // factor, factor])\n                    images = tf.reduce_mean(images, axis=[3,5])\n\n                # Scale dynamic range from [-1,1] to [0,255] for VGG.\n                images = (images + 1) * (255 / 2)\n\n                # Evaluate perceptual distance.\n                img_e0, img_e1 = images[0::2], images[1::2]\n                distance_measure = misc.load_pkl('https://drive.google.com/uc?id=1N2-m9qszOeVC9Tq77WxsLnuWwOedQiD2', 'vgg16_zhang_perceptual.pkl')\n                distance_expr.append(distance_measure.get_output_for(img_e0, img_e1) * (1 / self.epsilon**2))\n\n        # Sampling loop.\n        all_distances = []\n        for begin in range(0, self.num_samples, minibatch_size):\n            self._report_progress(begin, self.num_samples)\n            all_distances += tflib.run(distance_expr)\n        all_distances = np.concatenate(all_distances, axis=0)\n\n        # Reject outliers.\n        lo = np.percentile(all_distances, 1, interpolation='lower')\n        hi = np.percentile(all_distances, 99, interpolation='higher')\n        filtered_distances = np.extract(np.logical_and(lo <= all_distances, all_distances <= hi), all_distances)\n        self._report_result(np.mean(filtered_distances))\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/metrics/precision_recall.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Precision/Recall (PR).\"\"\"\n\nimport os\nimport numpy as np\nimport tensorflow as tf\nimport tflex\nimport dnnlib\nimport dnnlib.tflib as tflib\n\nfrom metrics import metric_base\nfrom training import misc\n\n#----------------------------------------------------------------------------\n\ndef batch_pairwise_distances(U, V):\n    \"\"\" Compute pairwise distances between two batches of feature vectors.\"\"\"\n    with tf.variable_scope('pairwise_dist_block'):\n        # Squared norms of each row in U and V.\n        norm_u = tf.reduce_sum(tf.square(U), 1)\n        norm_v = tf.reduce_sum(tf.square(V), 1)\n\n        # norm_u as a row and norm_v as a column vectors.\n        norm_u = tf.reshape(norm_u, [-1, 1])\n        norm_v = tf.reshape(norm_v, [1, -1])\n\n        # Pairwise squared Euclidean distances.\n        D = tf.maximum(norm_u - 2*tf.matmul(U, V, False, True) + norm_v, 0.0)\n\n    return D\n\n#----------------------------------------------------------------------------\n\nclass DistanceBlock():\n    \"\"\"Distance block.\"\"\"\n    def __init__(self, num_features, num_gpus):\n        self.num_features = num_features\n        self.num_gpus = num_gpus\n\n        # Initialize TF graph to calculate pairwise distances.\n        with tflex.device('/cpu:0'):\n            self._features_batch1 = tf.placeholder(tf.float16, shape=[None, self.num_features])\n            self._features_batch2 = tf.placeholder(tf.float16, shape=[None, self.num_features])\n            features_split2 = tf.split(self._features_batch2, self.num_gpus, axis=0)\n            distances_split = []\n            for gpu_idx in range(self.num_gpus):\n                with tflex.device('/gpu:%d' % gpu_idx):\n                    distances_split.append(batch_pairwise_distances(self._features_batch1, features_split2[gpu_idx]))\n            self._distance_block = tf.concat(distances_split, axis=1)\n\n    def pairwise_distances(self, U, V):\n        \"\"\"Evaluate pairwise distances between two batches of feature vectors.\"\"\"\n        return self._distance_block.eval(feed_dict={self._features_batch1: U, self._features_batch2: V})\n\n#----------------------------------------------------------------------------\n\nclass ManifoldEstimator():\n    \"\"\"Finds an estimate for the manifold of given feature vectors.\"\"\"\n    def __init__(self, distance_block, features, row_batch_size, col_batch_size, nhood_sizes, clamp_to_percentile=None):\n        \"\"\"Find an estimate of the manifold of given feature vectors.\"\"\"\n        num_images = features.shape[0]\n        self.nhood_sizes = nhood_sizes\n        self.num_nhoods = len(nhood_sizes)\n        self.row_batch_size = row_batch_size\n        self.col_batch_size = col_batch_size\n        self._ref_features = features\n        self._distance_block = distance_block\n\n        # Estimate manifold of features by calculating distances to kth nearest neighbor of each sample.\n        self.D = np.zeros([num_images, self.num_nhoods], dtype=np.float16)\n        distance_batch = np.zeros([row_batch_size, num_images], dtype=np.float16)\n        seq = np.arange(max(self.nhood_sizes) + 1, dtype=np.int32)\n\n        for begin1 in range(0, num_images, row_batch_size):\n            end1 = min(begin1 + row_batch_size, num_images)\n            row_batch = features[begin1:end1]\n\n            for begin2 in range(0, num_images, col_batch_size):\n                end2 = min(begin2 + col_batch_size, num_images)\n                col_batch = features[begin2:end2]\n\n                # Compute distances between batches.\n                distance_batch[0:end1-begin1, begin2:end2] = self._distance_block.pairwise_distances(row_batch, col_batch)\n\n            # Find the kth nearest neighbor from the current batch.\n            self.D[begin1:end1, :] = np.partition(distance_batch[0:end1-begin1, :], seq, axis=1)[:, self.nhood_sizes]\n\n        if clamp_to_percentile is not None:\n            max_distances = np.percentile(self.D, clamp_to_percentile, axis=0)\n            self.D[self.D > max_distances] = 0  #max_distances  # 0\n\n    def evaluate(self, eval_features, return_realism=False, return_neighbors=False):\n        \"\"\"Evaluate if new feature vectors are in the estimated manifold.\"\"\"\n        num_eval_images = eval_features.shape[0]\n        num_ref_images = self.D.shape[0]\n        distance_batch = np.zeros([self.row_batch_size, num_ref_images], dtype=np.float16)\n        batch_predictions = np.zeros([num_eval_images, self.num_nhoods], dtype=np.int32)\n        #max_realism_score = np.zeros([num_eval_images,], dtype=np.float32)\n        realism_score = np.zeros([num_eval_images,], dtype=np.float32)\n        nearest_indices = np.zeros([num_eval_images,], dtype=np.int32)\n\n        for begin1 in range(0, num_eval_images, self.row_batch_size):\n            end1 = min(begin1 + self.row_batch_size, num_eval_images)\n            feature_batch = eval_features[begin1:end1]\n\n            for begin2 in range(0, num_ref_images, self.col_batch_size):\n                end2 = min(begin2 + self.col_batch_size, num_ref_images)\n                ref_batch = self._ref_features[begin2:end2]\n\n                distance_batch[0:end1-begin1, begin2:end2] = self._distance_block.pairwise_distances(feature_batch, ref_batch)\n\n            # From the minibatch of new feature vectors, determine if they are in the estimated manifold.\n            # If a feature vector is inside a hypersphere of some reference sample, then the new sample lies on the estimated manifold.\n            # The radii of the hyperspheres are determined from distances of neighborhood size k.\n            samples_in_manifold = distance_batch[0:end1-begin1, :, None] <= self.D\n            batch_predictions[begin1:end1] = np.any(samples_in_manifold, axis=1).astype(np.int32)\n\n            #max_realism_score[begin1:end1] = np.max(self.D[:, 0] / (distance_batch[0:end1-begin1, :] + 1e-18), axis=1)\n            #nearest_indices[begin1:end1] = np.argmax(self.D[:, 0] / (distance_batch[0:end1-begin1, :] + 1e-18), axis=1)\n            nearest_indices[begin1:end1] = np.argmin(distance_batch[0:end1-begin1, :], axis=1)\n            realism_score[begin1:end1] = self.D[nearest_indices[begin1:end1], 0] / np.min(distance_batch[0:end1-begin1, :], axis=1)\n\n        if return_realism and return_neighbors:\n            return batch_predictions, realism_score, nearest_indices\n        elif return_realism:\n            return batch_predictions, realism_score\n        elif return_neighbors:\n            return batch_predictions, nearest_indices\n\n        return batch_predictions\n\n#----------------------------------------------------------------------------\n\ndef knn_precision_recall_features(ref_features, eval_features, feature_net, nhood_sizes,\n                                  row_batch_size, col_batch_size, num_gpus):\n    \"\"\"Calculates k-NN precision and recall for two sets of feature vectors.\"\"\"\n    state = dnnlib.EasyDict()\n    #num_images = ref_features.shape[0]\n    num_features = feature_net.output_shape[1]\n    state.ref_features = ref_features\n    state.eval_features = eval_features\n\n    # Initialize DistanceBlock and ManifoldEstimators.\n    distance_block = DistanceBlock(num_features, num_gpus)\n    state.ref_manifold = ManifoldEstimator(distance_block, state.ref_features, row_batch_size, col_batch_size, nhood_sizes)\n    state.eval_manifold = ManifoldEstimator(distance_block, state.eval_features, row_batch_size, col_batch_size, nhood_sizes)\n\n    # Evaluate precision and recall using k-nearest neighbors.\n    #print('Evaluating k-NN precision and recall with %i samples...' % num_images)\n    #start = time.time()\n\n    # Precision: How many points from eval_features are in ref_features manifold.\n    state.precision, state.realism_scores, state.nearest_neighbors = state.ref_manifold.evaluate(state.eval_features, return_realism=True, return_neighbors=True)\n    state.knn_precision = state.precision.mean(axis=0)\n\n    # Recall: How many points from ref_features are in eval_features manifold.\n    state.recall = state.eval_manifold.evaluate(state.ref_features)\n    state.knn_recall = state.recall.mean(axis=0)\n\n    #elapsed_time = time.time() - start\n    #print('Done evaluation in: %gs' % elapsed_time)\n\n    return state\n\n#----------------------------------------------------------------------------\n\nclass PR(metric_base.MetricBase):\n    def __init__(self, num_images, nhood_size, minibatch_per_gpu, row_batch_size, col_batch_size, **kwargs):\n        super().__init__(**kwargs)\n        self.num_images = num_images\n        self.nhood_size = nhood_size\n        self.minibatch_per_gpu = minibatch_per_gpu\n        self.row_batch_size = row_batch_size\n        self.col_batch_size = col_batch_size\n\n    def _evaluate(self, Gs, Gs_kwargs, num_gpus):\n        minibatch_size = num_gpus * self.minibatch_per_gpu\n        feature_net = misc.load_pkl('https://drive.google.com/uc?id=1MzY4MFpZzE-mNS26pzhYlWN-4vMm2ytu', 'vgg16.pkl')\n\n        # Calculate features for reals.\n        cache_file = self._get_cache_file_for_reals(num_images=self.num_images)\n        os.makedirs(os.path.dirname(cache_file), exist_ok=True)\n        if os.path.isfile(cache_file):\n            ref_features = misc.load_pkl(cache_file)\n        else:\n            ref_features = np.empty([self.num_images, feature_net.output_shape[1]], dtype=np.float32)\n            for idx, images in enumerate(self._iterate_reals(minibatch_size=minibatch_size)):\n                begin = idx * minibatch_size\n                end = min(begin + minibatch_size, self.num_images)\n                ref_features[begin:end] = feature_net.run(images[:end-begin], num_gpus=num_gpus, assume_frozen=True)\n                if end == self.num_images:\n                    break\n            misc.save_pkl(ref_features, cache_file)\n\n        # Construct TensorFlow graph.\n        result_expr = []\n        for gpu_idx in range(num_gpus):\n            with tflex.device('/gpu:%d' % gpu_idx):\n                Gs_clone = Gs.clone()\n                feature_net_clone = feature_net.clone()\n                latents = tf.random_normal([self.minibatch_per_gpu] + Gs_clone.input_shape[1:])\n                labels = self._get_random_labels_tf(self.minibatch_per_gpu)\n                images = Gs_clone.get_output_for(latents, labels, **Gs_kwargs)\n                images = tflib.convert_images_to_uint8(images)\n                result_expr.append(feature_net_clone.get_output_for(images))\n\n        # Calculate features for fakes.\n        eval_features = np.empty([self.num_images, feature_net.output_shape[1]], dtype=np.float32)\n        for begin in range(0, self.num_images, minibatch_size):\n            self._report_progress(begin, self.num_images)\n            end = min(begin + minibatch_size, self.num_images)\n            eval_features[begin:end] = np.concatenate(tflib.run(result_expr), axis=0)[:end-begin]\n\n        # Calculate precision and recall.\n        state = knn_precision_recall_features(ref_features=ref_features, eval_features=eval_features, feature_net=feature_net,\n            nhood_sizes=[self.nhood_size], row_batch_size=self.row_batch_size, col_batch_size=self.row_batch_size, num_gpus=num_gpus)\n        self._report_result(state.knn_precision[0], suffix='_precision')\n        self._report_result(state.knn_recall[0], suffix='_recall')\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/prepare_image.py",
    "content": "#!/usr/bin/env python3\n# Copyright 2018 The TensorFlow Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport argparse\nimport datetime\nimport os\nimport shutil\nimport subprocess\nimport sys\nimport tensorflow.compat.v1 as tf\n\nclass Namespace():\n  pass\n\nme = Namespace()\n\ndef _int64_feature(value):\n  \"\"\"Wrapper for inserting int64 features into Example proto.\"\"\"\n  if not isinstance(value, list):\n    value = [value]\n  return tf.train.Feature(int64_list=tf.train.Int64List(value=value))\n\n\ndef _bytes_feature(value):\n  \"\"\"Wrapper for inserting bytes features into Example proto.\"\"\"\n  return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))\n\n\ndef _convert_to_example(filename, image_buffer, label_int, label_str, height,\n                        width):\n  \"\"\"Build an Example proto for an example.\n\n  Args:\n    filename: string, path to an image file, e.g., '/path/to/example.JPG'\n    image_buffer: string, JPEG encoding of RGB image\n    label_int: integer, identifier for ground truth (0-based)\n    label_str: string, identifier for ground truth, e.g., 'daisy'\n    height: integer, image height in pixels\n    width: integer, image width in pixels\n  Returns:\n    Example proto\n  \"\"\"\n  colorspace = 'RGB'\n  channels = 3\n  image_format = 'JPEG'\n\n  example = tf.train.Example(\n      features=tf.train.Features(\n          feature={\n              'image/height': _int64_feature(height),\n              'image/width': _int64_feature(width),\n              'image/colorspace': _bytes_feature(colorspace),\n              'image/channels': _int64_feature(channels),\n              'image/class/label': _int64_feature(label_int +\n                                                  1),  # model expects 1-based\n              'image/class/synset': _bytes_feature(label_str),\n              'image/format': _bytes_feature(image_format),\n              'image/filename': _bytes_feature(os.path.basename(filename)),\n              'image/encoded': _bytes_feature(image_buffer)\n          }))\n  return example\n\n\nclass ImageCoder(object):\n  \"\"\"Helper class that provides TensorFlow image coding utilities.\"\"\"\n\n  def __init__(self, session=None):\n    # Create a single Session to run all image coding calls.\n    session = tf.get_default_session() if session is None else session\n    self._sess = tf.Session() if session is None else session\n\n    # Initializes function that converts PNG to JPEG data.\n    self._png_data = tf.placeholder(dtype=tf.string)\n    image = tf.image.decode_png(self._png_data, channels=3)\n    self._png_to_jpeg = tf.image.encode_jpeg(image, format='rgb', quality=100)\n\n    # Initializes function that converts CMYK JPEG data to RGB JPEG data.\n    self._cmyk_data = tf.placeholder(dtype=tf.string)\n    image = tf.image.decode_jpeg(self._cmyk_data, channels=0)\n    self._cmyk_to_rgb = tf.image.encode_jpeg(image, format='rgb', quality=100)\n\n    # Initializes function that decodes RGB JPEG data.\n    self._decode_jpeg_data = tf.placeholder(dtype=tf.string)\n    self._decode_jpeg = tf.image.decode_jpeg(self._decode_jpeg_data, channels=3)\n\n  def __del__(self):\n    self._sess.close()\n\n  def png_to_jpeg(self, image_data):\n    return self._sess.run(self._png_to_jpeg,\n                          feed_dict={self._png_data: image_data})\n\n  def cmyk_to_rgb(self, image_data):\n    return self._sess.run(self._cmyk_to_rgb,\n                          feed_dict={self._cmyk_data: image_data})\n\n  def decode_jpeg(self, image_data):\n    image = self._sess.run(self._decode_jpeg,\n                           feed_dict={self._decode_jpeg_data: image_data})\n    assert len(image.shape) == 3\n    assert image.shape[2] == 3\n    return image\n\n\n# Parse individual image from a tfrecords file into TensorFlow expression.\ndef parse_tfrecord_tf(record):\n  features = tf.parse_single_example(record, features={ 'shape': tf.FixedLenFeature([3], tf.int64), 'data': tf.FixedLenFeature([], tf.string)})\n  data = tf.decode_raw(features['data'], tf.uint8)\n  return tf.reshape(data, features['shape'])\n\ndef parse_tfrecord_file(tfr_file, num_threads=8):\n  dset = tf.data.TFRecordDataset(tfr_file, compression_type='', buffer_size=buffer_mb<<20)\n  dset = dset.map(parse_tfrecord_tf, num_parallel_calls=num_threads)\n  return dset\n\ndef init_dataset(dset):\n  tf_iterator = tf.data.Iterator.from_structure(dset.output_types, dset.output_shapes)\n  tf_init_ops = tf_iterator.make_initializer(dset)\n  return tf_iterator, tf_init_ops\n\nfrom tensorflow.python.framework import errors_impl\n\ndef iterate_stylegan_records(tfr_file, session=None):\n  if session is None:\n    session = tf.get_default_session()\n  dset = parse_tfrecord_file(tfr_file)\n  it, init = init_dataset(dset)\n  session.run(init)\n  with session.graph.as_default():\n    op = tf.transpose(it.get_next(), [1, 2, 0])\n  try:\n    while True:\n      yield sess.run(op)\n  except errors_impl.OutOfRangeError:\n    pass\n\ndef _is_png(filename):\n  return filename.endswith('.png') or filename.endswith('.PNG')\n\ndef _is_png_data(image_data):\n  return image_data.startswith(b'\\x89PNG')\n\ndef _is_cmyk(filename):\n  return False # TODO\n\ndef get_coder(coder=None):\n  coder = me.coder = me.coder if hasattr(me, 'coder') else ImageCoder()\n  return coder\n\nimport requests\n\ndef getfile(path):\n  if path.startswith('http'):\n    r = requests.get(path, stream=True)\n    if r.status_code == 200:\n      return r.raw.read()\n    else:\n      raise Exception(\"Couldn't open URL: %s\" % path)\n  with tf.gfile.FastGFile(path, 'rb') as f:\n    return f.read()\n\ndef _process_image(filename, coder=None):\n  \"\"\"Process a single image file.\n\n  Args:\n    filename: string, path to an image file e.g., '/path/to/example.JPG'.\n    coder: instance of ImageCoder to provide TensorFlow image coding utils.\n  Returns:\n    image_buffer: string, JPEG encoding of RGB image.\n    height: integer, image height in pixels.\n    width: integer, image width in pixels.\n  \"\"\"\n  coder = get_coder(coder)\n  # Read the image file.\n  image_data = getfile(filename)\n  # Clean the dirty data.\n  if _is_png_data(image_data):\n    # 1 image is a PNG.\n    tf.logging.info('Converting PNG to JPEG for %s' % filename)\n    image_data = coder.png_to_jpeg(image_data)\n  elif _is_cmyk(filename):\n    # 22 JPEG images are in CMYK colorspace.\n    tf.logging.info('Converting CMYK to RGB for %s' % filename)\n    image_data = coder.cmyk_to_rgb(image_data)\n  # Decode the RGB JPEG.\n  image = coder.decode_jpeg(image_data)\n  # Check that image converted to RGB\n  assert len(image.shape) == 3\n  height = image.shape[0]\n  width = image.shape[1]\n  assert image.shape[2] == 3\n  return image_data, height, width, image\n\ndef tf_randi(*args, **kws):\n  assert len(args) > 0\n  if len(args) == 1:\n    lo, hi = [0] + [x for x in args]\n  else:\n    lo, hi = args\n  return tf.random.uniform((), minval=lo, maxval=hi, dtype=tf.int32, **kws)\n\ndef tf_rand(*args, **kws):\n  if len(args) == 0:\n    lo, hi = 0.0, 1.0\n  elif len(args) == 1:\n    lo, hi = [0] + [x for x in args]\n  else:\n    lo, hi = args\n  return tf.random.uniform((), minval=lo, maxval=hi, **kws)\n\ndef tf_biased_rand(*args, bias=1, **kws):\n  x = tf_rand(*args, **kws)\n  # simple technique to bias the result towards the center.\n  for i in range(bias-1):\n    x += tf_rand(*args, **kws)\n  dtype = kws.pop('dtype') if 'dtype' in kws else tf.float32\n  x = tf.cast(x, tf.float32) / bias\n  x = tf.cast(x, dtype)\n  return x\n\ndef tf_between(*args, bias=1, **kws):\n  if bias <= 0:\n    return tf_randi(*args, **kws)\n  else:\n    return tf_biased_rand(*args, dtype=tf.int32, bias=bias, **kws)\n  \ndef random_crop(image_bytes, scope=None, resize=None, method=tf.image.ResizeMethod.AREA, seed=None):\n  with tf.name_scope(scope, 'random_crop', [image_bytes]):\n    shape = tf.image.extract_jpeg_shape(image_bytes)\n    w = shape[0]\n    h = shape[1]\n    channels = shape[2]\n    x, y = 0, 0\n    n = 3\n    image = tf.cond(w > h,\n        lambda: tf.image.decode_and_crop_jpeg(image_bytes, tf.stack([x + tf_between(w - h, seed=seed), y, h, h]), channels=n),\n        lambda: tf.cond(h > w,\n          lambda: tf.image.decode_and_crop_jpeg(image_bytes, tf.stack([x, y + tf_between(h - w, seed=seed), w, w]), channels=n),\n          lambda: tf.image.decode_jpeg(image_bytes, channels=n)))\n    if resize:\n      image_size = [resize, resize] if isinstance(resize, int) or isinstance(resize, float) else resize\n      image = tf.image.resize([image], image_size, method=method)[0]\n    return image\n    \n    \n# with open('test.jpg', 'wb') as f: f.write(tf.get_default_session().run(tf.io.encode_jpeg(sess.run(random_crop(open(np.random.choice(list(glob('*.jpg'))), 'rb').read())))))\n\n\n\nIMAGE_SIZE = 224\nCROP_PADDING = 32\n\ndef distorted_bounding_box_crop(image_bytes,\n                                bbox,\n                                min_object_covered=0.1,\n                                aspect_ratio_range=(0.75, 1.33),\n                                area_range=(0.05, 1.0),\n                                max_attempts=100,\n                                scope=None):\n  \"\"\"Generates cropped_image using one of the bboxes randomly distorted.\n\n  See `tf.image.sample_distorted_bounding_box` for more documentation.\n\n  Args:\n    image_bytes: `Tensor` of binary image data.\n    bbox: `Tensor` of bounding boxes arranged `[1, num_boxes, coords]`\n        where each coordinate is [0, 1) and the coordinates are arranged\n        as `[ymin, xmin, ymax, xmax]`. If num_boxes is 0 then use the whole\n        image.\n    min_object_covered: An optional `float`. Defaults to `0.1`. The cropped\n        area of the image must contain at least this fraction of any bounding\n        box supplied.\n    aspect_ratio_range: An optional list of `float`s. The cropped area of the\n        image must have an aspect ratio = width / height within this range.\n    area_range: An optional list of `float`s. The cropped area of the image\n        must contain a fraction of the supplied image within in this range.\n    max_attempts: An optional `int`. Number of attempts at generating a cropped\n        region of the image of the specified constraints. After `max_attempts`\n        failures, return the entire image.\n    scope: Optional `str` for name scope.\n  Returns:\n    cropped image `Tensor`\n  \"\"\"\n  with tf.name_scope(scope, 'distorted_bounding_box_crop', [image_bytes, bbox]):\n    shape = tf.image.extract_jpeg_shape(image_bytes)\n    sample_distorted_bounding_box = tf.image.sample_distorted_bounding_box(\n        shape,\n        bounding_boxes=bbox,\n        min_object_covered=min_object_covered,\n        aspect_ratio_range=aspect_ratio_range,\n        area_range=area_range,\n        max_attempts=max_attempts,\n        use_image_if_no_bounding_boxes=True)\n    bbox_begin, bbox_size, _ = sample_distorted_bounding_box\n    # Crop the image to the specified bounding box.\n    offset_y, offset_x, _ = tf.unstack(bbox_begin)\n    target_height, target_width, _ = tf.unstack(bbox_size)\n    crop_window = tf.stack([offset_y, offset_x, target_height, target_width])\n    image = tf.image.decode_and_crop_jpeg(image_bytes, crop_window, channels=3)\n    return image\n\n\ndef _at_least_x_are_equal(a, b, x):\n  \"\"\"At least `x` of `a` and `b` `Tensors` are equal.\"\"\"\n  match = tf.equal(a, b)\n  match = tf.cast(match, tf.int32)\n  return tf.greater_equal(tf.reduce_sum(match), x)\n\ndef _decode_and_random_crop(image_bytes, image_size, resize=True, method=tf.image.ResizeMethod.AREA, aspect_ratio_range=(3. / 4, 4. / 3), area_range=(0.08, 1.0)): # AREA is much higher quality than BICUBIC\n  \"\"\"Make a random crop of image_size.\"\"\"\n  bbox = tf.constant([0.0, 0.0, 1.0, 1.0], dtype=tf.float32, shape=[1, 1, 4])\n  image = distorted_bounding_box_crop(\n      image_bytes,\n      bbox,\n      min_object_covered=0.1,\n      aspect_ratio_range=aspect_ratio_range,\n      area_range=area_range,\n      max_attempts=10,\n      scope=None)\n  original_shape = tf.image.extract_jpeg_shape(image_bytes)\n  bad = _at_least_x_are_equal(original_shape, tf.shape(image), 3)\n  if resize:\n    image = tf.cond(\n        bad,\n        lambda: _decode_and_center_crop(image_bytes, image_size, resize=resize, method=method),\n        lambda: tf.image.resize([image], [image_size, image_size], method=method)[0])\n  else:\n    image = tf.cond(\n        bad,\n        lambda: _decode_and_center_crop(image_bytes, image_size, resize=resize, method=method),\n        lambda: image)\n  return image\n\ndef _decode_and_center_crop(image_bytes, image_size, resize=True, method=tf.image.ResizeMethod.AREA): # AREA is much higher quality than BICUBIC\n  \"\"\"Crops to center of image with padding then scales image_size.\"\"\"\n  shape = tf.image.extract_jpeg_shape(image_bytes)\n  image_height = shape[0]\n  image_width = shape[1]\n  padded_center_crop_size = tf.cast(\n      ((image_size / (image_size + CROP_PADDING)) *\n       tf.cast(tf.minimum(image_height, image_width), tf.float32)),\n      tf.int32)\n  offset_height = ((image_height - padded_center_crop_size) + 1) // 2\n  offset_width = ((image_width - padded_center_crop_size) + 1) // 2\n  crop_window = tf.stack([offset_height, offset_width,\n                          padded_center_crop_size, padded_center_crop_size])\n  image = tf.image.decode_and_crop_jpeg(image_bytes, crop_window, channels=3)\n  if resize:\n    image = tf.image.resize([image], [image_size, image_size], method=method)[0]\n  return image\n\nimport os\nfrom tensorflow.compat.v1.distribute.cluster_resolver import TPUClusterResolver\n\ndef get_target(target=None):\n  if target is None and 'COLAB_TPU_ADDR' in os.environ:\n    target = os.environ['COLAB_TPU_ADDR']\n  if target is None and 'TPU_NAME' in os.environ:\n    target = os.environ['TPU_NAME']\n    if not target.startswith('grpc://'):\n      target = TPUClusterResolver(target).get_master()\n  if target is not None:\n    print('Using target %s' % target)\n  return target\n\ndef main():\n  from tensorflow.python.framework.ops import disable_eager_execution\n  disable_eager_execution()\n\n  parser = argparse.ArgumentParser()\n  parser.add_argument('infile')\n  parser.add_argument('outfile', nargs='?')\n  parser.add_argument('-r', '--resize', type=int, default=0)\n  args = me.args = parser.parse_args()\n  with tf.Session(get_target()) as sess:\n    image_data, width, height, image = _process_image(args.infile)\n    image_out = sess.run(tf.io.encode_jpeg(sess.run(random_crop(image_data, resize=args.resize))))\n    if not args.outfile:\n      args.outfile = os.path.basename(args.infile)\n      if args.outfile == args.infile:\n        print('Implicitly overwriting infile not supported; pass `%s %s` to confirm' % (args.outfile, args.outfile))\n        sys.exit(1)\n    with open(args.outfile, 'wb') as f:\n      f.write(image_out)\n\nif __name__ == '__main__':\n  main()\n\ndef convert_to_example(csvline, categories):\n  \"\"\"Parse a line of CSV file and convert to TF Record.\n\n  Args:\n    csvline: line from input CSV file\n    categories: list of labels\n  Yields:\n    serialized TF example if the label is in categories\n  \"\"\"\n  filename, label = csvline.encode('ascii', 'ignore').split(',')\n  if label in categories:\n    # ignore labels not in categories list\n    coder = ImageCoder()\n    image_buffer, height, width, image = _process_image(filename, coder)\n    del coder\n    example = _convert_to_example(filename, image_buffer,\n                                  categories.index(label), label, height, width)\n    yield example.SerializeToString()\n\ndef main2():\n  parser = argparse.ArgumentParser()\n  parser.add_argument(\n      '--train_csv',\n      # pylint: disable=line-too-long\n      help=\n      'Path to input.  Each line of input has two fields  image-file-name and label separated by a comma',\n      required=True)\n  parser.add_argument(\n      '--validation_csv',\n      # pylint: disable=line-too-long\n      help=\n      'Path to input.  Each line of input has two fields  image-file-name and label separated by a comma',\n      required=True)\n  parser.add_argument(\n      '--labels_file',\n      help='Path to file containing list of labels, one per line',\n      required=True)\n  parser.add_argument(\n      '--project_id',\n      help='ID (not name) of your project. Ignored by DirectRunner',\n      required=True)\n  parser.add_argument(\n      '--runner',\n      help='If omitted, uses DataFlowRunner if output_dir starts with gs://',\n      default=None)\n  parser.add_argument(\n      '--output_dir', help='Top-level directory for TF Records', required=True)\n\n  args = parser.parse_args()\n  arguments = args.__dict__\n\n  JOBNAME = (\n      'preprocess-images-' + datetime.datetime.now().strftime('%y%m%d-%H%M%S'))\n\n  PROJECT = arguments['project_id']\n  OUTPUT_DIR = arguments['output_dir']\n\n  # set RUNNER using command-line arg or based on output_dir path\n  on_cloud = OUTPUT_DIR.startswith('gs://')\n  if arguments['runner']:\n    RUNNER = arguments['runner']\n  else:\n    RUNNER = 'DataflowRunner' if on_cloud else 'DirectRunner'\n\n  # clean-up output directory since Beam will name files 0000-of-0004 etc.\n  # and this could cause confusion if earlier run has 0000-of-0005, for eg\n  if on_cloud:\n    try:\n      subprocess.check_call('gsutil -m rm -r {}'.format(OUTPUT_DIR).split())\n    except subprocess.CalledProcessError:\n      pass\n  else:\n    shutil.rmtree(OUTPUT_DIR, ignore_errors=True)\n    os.makedirs(OUTPUT_DIR)\n\n  # read list of labels\n  with tf.gfile.FastGFile(arguments['labels_file'], 'r') as f:\n    LABELS = [line.rstrip() for line in f]\n  print('Read in {} labels, from {} to {}'.format(\n      len(LABELS), LABELS[0], LABELS[-1]))\n  if len(LABELS) < 2:\n    print('Require at least two labels')\n    sys.exit(-1)\n\n  # set up Beam pipeline to convert images to TF Records\n  options = {\n      'staging_location': os.path.join(OUTPUT_DIR, 'tmp', 'staging'),\n      'temp_location': os.path.join(OUTPUT_DIR, 'tmp'),\n      'job_name': JOBNAME,\n      'project': PROJECT,\n      'teardown_policy': 'TEARDOWN_ALWAYS',\n      'save_main_session': True\n  }\n  opts = beam.pipeline.PipelineOptions(flags=[], **options)\n\n  with beam.Pipeline(RUNNER, options=opts) as p:\n    # BEAM tasks\n    for step in ['train', 'validation']:\n      _ = (\n          p\n          | '{}_read_csv'.format(step) >> beam.io.ReadFromText(\n              arguments['{}_csv'.format(step)])\n          | '{}_convert'.format(step) >>\n          beam.FlatMap(lambda line: convert_to_example(line, LABELS))\n          | '{}_write_tfr'.format(step) >> beam.io.tfrecordio.WriteToTFRecord(\n              os.path.join(OUTPUT_DIR, step)))\n"
  },
  {
    "path": "stylegan2-tpu/pretrained_networks.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"List of pre-trained StyleGAN2 networks located on Google Drive.\"\"\"\n\nimport pickle\nimport dnnlib\nimport dnnlib.tflib as tflib\n\n#----------------------------------------------------------------------------\n# StyleGAN2 Google Drive root: https://drive.google.com/open?id=1QHc-yF5C3DChRwSdZKcx1w6K8JvSxQi7\n\ngdrive_urls = {\n    'gdrive:networks/stylegan2-car-config-a.pkl':                           'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-car-config-a.pkl',\n    'gdrive:networks/stylegan2-car-config-b.pkl':                           'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-car-config-b.pkl',\n    'gdrive:networks/stylegan2-car-config-c.pkl':                           'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-car-config-c.pkl',\n    'gdrive:networks/stylegan2-car-config-d.pkl':                           'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-car-config-d.pkl',\n    'gdrive:networks/stylegan2-car-config-e.pkl':                           'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-car-config-e.pkl',\n    'gdrive:networks/stylegan2-car-config-f.pkl':                           'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-car-config-f.pkl',\n    'gdrive:networks/stylegan2-cat-config-a.pkl':                           'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-cat-config-a.pkl',\n    'gdrive:networks/stylegan2-cat-config-f.pkl':                           'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-cat-config-f.pkl',\n    'gdrive:networks/stylegan2-church-config-a.pkl':                        'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-church-config-a.pkl',\n    'gdrive:networks/stylegan2-church-config-f.pkl':                        'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-church-config-f.pkl',\n    'gdrive:networks/stylegan2-ffhq-config-a.pkl':                          'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-ffhq-config-a.pkl',\n    'gdrive:networks/stylegan2-ffhq-config-b.pkl':                          'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-ffhq-config-b.pkl',\n    'gdrive:networks/stylegan2-ffhq-config-c.pkl':                          'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-ffhq-config-c.pkl',\n    'gdrive:networks/stylegan2-ffhq-config-d.pkl':                          'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-ffhq-config-d.pkl',\n    'gdrive:networks/stylegan2-ffhq-config-e.pkl':                          'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-ffhq-config-e.pkl',\n    'gdrive:networks/stylegan2-ffhq-config-f.pkl':                          'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-ffhq-config-f.pkl',\n    'gdrive:networks/stylegan2-horse-config-a.pkl':                         'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-horse-config-a.pkl',\n    'gdrive:networks/stylegan2-horse-config-f.pkl':                         'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-horse-config-f.pkl',\n    'gdrive:networks/table2/stylegan2-car-config-e-Gorig-Dorig.pkl':        'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-car-config-e-Gorig-Dorig.pkl',\n    'gdrive:networks/table2/stylegan2-car-config-e-Gorig-Dresnet.pkl':      'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-car-config-e-Gorig-Dresnet.pkl',\n    'gdrive:networks/table2/stylegan2-car-config-e-Gorig-Dskip.pkl':        'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-car-config-e-Gorig-Dskip.pkl',\n    'gdrive:networks/table2/stylegan2-car-config-e-Gresnet-Dorig.pkl':      'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-car-config-e-Gresnet-Dorig.pkl',\n    'gdrive:networks/table2/stylegan2-car-config-e-Gresnet-Dresnet.pkl':    'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-car-config-e-Gresnet-Dresnet.pkl',\n    'gdrive:networks/table2/stylegan2-car-config-e-Gresnet-Dskip.pkl':      'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-car-config-e-Gresnet-Dskip.pkl',\n    'gdrive:networks/table2/stylegan2-car-config-e-Gskip-Dorig.pkl':        'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-car-config-e-Gskip-Dorig.pkl',\n    'gdrive:networks/table2/stylegan2-car-config-e-Gskip-Dresnet.pkl':      'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-car-config-e-Gskip-Dresnet.pkl',\n    'gdrive:networks/table2/stylegan2-car-config-e-Gskip-Dskip.pkl':        'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-car-config-e-Gskip-Dskip.pkl',\n    'gdrive:networks/table2/stylegan2-ffhq-config-e-Gorig-Dorig.pkl':       'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-ffhq-config-e-Gorig-Dorig.pkl',\n    'gdrive:networks/table2/stylegan2-ffhq-config-e-Gorig-Dresnet.pkl':     'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-ffhq-config-e-Gorig-Dresnet.pkl',\n    'gdrive:networks/table2/stylegan2-ffhq-config-e-Gorig-Dskip.pkl':       'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-ffhq-config-e-Gorig-Dskip.pkl',\n    'gdrive:networks/table2/stylegan2-ffhq-config-e-Gresnet-Dorig.pkl':     'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-ffhq-config-e-Gresnet-Dorig.pkl',\n    'gdrive:networks/table2/stylegan2-ffhq-config-e-Gresnet-Dresnet.pkl':   'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-ffhq-config-e-Gresnet-Dresnet.pkl',\n    'gdrive:networks/table2/stylegan2-ffhq-config-e-Gresnet-Dskip.pkl':     'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-ffhq-config-e-Gresnet-Dskip.pkl',\n    'gdrive:networks/table2/stylegan2-ffhq-config-e-Gskip-Dorig.pkl':       'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-ffhq-config-e-Gskip-Dorig.pkl',\n    'gdrive:networks/table2/stylegan2-ffhq-config-e-Gskip-Dresnet.pkl':     'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-ffhq-config-e-Gskip-Dresnet.pkl',\n    'gdrive:networks/table2/stylegan2-ffhq-config-e-Gskip-Dskip.pkl':       'http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/table2/stylegan2-ffhq-config-e-Gskip-Dskip.pkl',\n}\n\n#----------------------------------------------------------------------------\n\ndef get_path_or_url(path_or_gdrive_path):\n    return gdrive_urls.get(path_or_gdrive_path, path_or_gdrive_path)\n\n#----------------------------------------------------------------------------\n\n_cached_networks = dict()\n\ndef load_networks(path_or_gdrive_path):\n    path_or_url = get_path_or_url(path_or_gdrive_path)\n    if path_or_url in _cached_networks:\n        return _cached_networks[path_or_url]\n\n    if dnnlib.util.is_url(path_or_url):\n        stream = dnnlib.util.open_url(path_or_url, cache_dir='.stylegan2-cache')\n    else:\n        stream = open(path_or_url, 'rb')\n\n    tflib.init_tf()\n    with stream:\n        G, D, Gs = pickle.load(stream, encoding='latin1')\n    _cached_networks[path_or_url] = G, D, Gs\n    return G, D, Gs\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/projector.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\nimport numpy as np\nimport tensorflow as tf\nimport dnnlib\nimport dnnlib.tflib as tflib\n\nfrom training import misc\n\n#----------------------------------------------------------------------------\n\nclass Projector:\n    def __init__(self):\n        self.num_steps                  = 1000\n        self.dlatent_avg_samples        = 10000\n        self.initial_learning_rate      = 0.1\n        self.initial_noise_factor       = 0.05\n        self.lr_rampdown_length         = 0.25\n        self.lr_rampup_length           = 0.05\n        self.noise_ramp_length          = 0.75\n        self.regularize_noise_weight    = 1e5\n        self.verbose                    = False\n        self.clone_net                  = True\n\n        self._Gs                    = None\n        self._minibatch_size        = None\n        self._dlatent_avg           = None\n        self._dlatent_std           = None\n        self._noise_vars            = None\n        self._noise_init_op         = None\n        self._noise_normalize_op    = None\n        self._dlatents_var          = None\n        self._noise_in              = None\n        self._dlatents_expr         = None\n        self._images_expr           = None\n        self._target_images_var     = None\n        self._lpips                 = None\n        self._dist                  = None\n        self._loss                  = None\n        self._reg_sizes             = None\n        self._lrate_in              = None\n        self._opt                   = None\n        self._opt_step              = None\n        self._cur_step              = None\n\n    def _info(self, *args):\n        if self.verbose:\n            print('Projector:', *args)\n\n    def set_network(self, Gs, minibatch_size=1):\n        assert minibatch_size == 1\n        self._Gs = Gs\n        self._minibatch_size = minibatch_size\n        if self._Gs is None:\n            return\n        if self.clone_net:\n            self._Gs = self._Gs.clone()\n\n        # Find dlatent stats.\n        self._info('Finding W midpoint and stddev using %d samples...' % self.dlatent_avg_samples)\n        latent_samples = np.random.RandomState(123).randn(self.dlatent_avg_samples, *self._Gs.input_shapes[0][1:])\n        dlatent_samples = self._Gs.components.mapping.run(latent_samples, None)[:, :1, :] # [N, 1, 512]\n        self._dlatent_avg = np.mean(dlatent_samples, axis=0, keepdims=True) # [1, 1, 512]\n        self._dlatent_std = (np.sum((dlatent_samples - self._dlatent_avg) ** 2) / self.dlatent_avg_samples) ** 0.5\n        self._info('std = %g' % self._dlatent_std)\n\n        # Find noise inputs.\n        self._info('Setting up noise inputs...')\n        self._noise_vars = []\n        noise_init_ops = []\n        noise_normalize_ops = []\n        while True:\n            n = 'G_synthesis/noise%d' % len(self._noise_vars)\n            if not n in self._Gs.vars:\n                break\n            v = self._Gs.vars[n]\n            self._noise_vars.append(v)\n            noise_init_ops.append(tf.assign(v, tf.random_normal(tf.shape(v), dtype=tf.float32)))\n            noise_mean = tf.reduce_mean(v)\n            noise_std = tf.reduce_mean((v - noise_mean)**2)**0.5\n            noise_normalize_ops.append(tf.assign(v, (v - noise_mean) / noise_std))\n            self._info(n, v)\n        self._noise_init_op = tf.group(*noise_init_ops)\n        self._noise_normalize_op = tf.group(*noise_normalize_ops)\n\n        # Image output graph.\n        self._info('Building image output graph...')\n        self._dlatents_var = tf.Variable(tf.zeros([self._minibatch_size] + list(self._dlatent_avg.shape[1:])), name='dlatents_var')\n        self._noise_in = tf.placeholder(tf.float32, [], name='noise_in')\n        dlatents_noise = tf.random.normal(shape=self._dlatents_var.shape) * self._noise_in\n        self._dlatents_expr = tf.tile(self._dlatents_var + dlatents_noise, [1, self._Gs.components.synthesis.input_shape[1], 1])\n        self._images_expr = self._Gs.components.synthesis.get_output_for(self._dlatents_expr, randomize_noise=False)\n\n        # Downsample image to 256x256 if it's larger than that. VGG was built for 224x224 images.\n        proc_images_expr = (self._images_expr + 1) * (255 / 2)\n        sh = proc_images_expr.shape.as_list()\n        if sh[2] > 256:\n            factor = sh[2] // 256\n            proc_images_expr = tf.reduce_mean(tf.reshape(proc_images_expr, [-1, sh[1], sh[2] // factor, factor, sh[2] // factor, factor]), axis=[3,5])\n\n        # Loss graph.\n        self._info('Building loss graph...')\n        self._target_images_var = tf.Variable(tf.zeros(proc_images_expr.shape), name='target_images_var')\n        if self._lpips is None:\n            self._lpips = misc.load_pkl('https://drive.google.com/uc?id=1N2-m9qszOeVC9Tq77WxsLnuWwOedQiD2', 'vgg16_zhang_perceptual.pkl')\n        self._dist = self._lpips.get_output_for(proc_images_expr, self._target_images_var)\n        self._loss = tf.reduce_sum(self._dist)\n\n        # Noise regularization graph.\n        self._info('Building noise regularization graph...')\n        reg_loss = 0.0\n        for v in self._noise_vars:\n            sz = v.shape[2]\n            while True:\n                reg_loss += tf.reduce_mean(v * tf.roll(v, shift=1, axis=3))**2 + tf.reduce_mean(v * tf.roll(v, shift=1, axis=2))**2\n                if sz <= 8:\n                    break # Small enough already\n                v = tf.reshape(v, [1, 1, sz//2, 2, sz//2, 2]) # Downscale\n                v = tf.reduce_mean(v, axis=[3, 5])\n                sz = sz // 2\n        self._loss += reg_loss * self.regularize_noise_weight\n\n        # Optimizer.\n        self._info('Setting up optimizer...')\n        self._lrate_in = tf.placeholder(tf.float32, [], name='lrate_in')\n        self._opt = dnnlib.tflib.Optimizer(learning_rate=self._lrate_in)\n        self._opt.register_gradients(self._loss, [self._dlatents_var] + self._noise_vars)\n        self._opt_step = self._opt.apply_updates()\n\n    def run(self, target_images):\n        # Run to completion.\n        self.start(target_images)\n        while self._cur_step < self.num_steps:\n            self.step()\n\n        # Collect results.\n        pres = dnnlib.EasyDict()\n        pres.dlatents = self.get_dlatents()\n        pres.noises = self.get_noises()\n        pres.images = self.get_images()\n        return pres\n\n    def start(self, target_images):\n        assert self._Gs is not None\n\n        # Prepare target images.\n        self._info('Preparing target images...')\n        target_images = np.asarray(target_images, dtype='float32')\n        target_images = (target_images + 1) * (255 / 2)\n        sh = target_images.shape\n        assert sh[0] == self._minibatch_size\n        if sh[2] > self._target_images_var.shape[2]:\n            factor = sh[2] // self._target_images_var.shape[2]\n            target_images = np.reshape(target_images, [-1, sh[1], sh[2] // factor, factor, sh[3] // factor, factor]).mean((3, 5))\n\n        # Initialize optimization state.\n        self._info('Initializing optimization state...')\n        tflib.set_vars({self._target_images_var: target_images, self._dlatents_var: np.tile(self._dlatent_avg, [self._minibatch_size, 1, 1])})\n        tflib.run(self._noise_init_op)\n        self._opt.reset_optimizer_state()\n        self._cur_step = 0\n\n    def step(self):\n        assert self._cur_step is not None\n        if self._cur_step >= self.num_steps:\n            return\n        if self._cur_step == 0:\n            self._info('Running...')\n\n        # Hyperparameters.\n        t = self._cur_step / self.num_steps\n        noise_strength = self._dlatent_std * self.initial_noise_factor * max(0.0, 1.0 - t / self.noise_ramp_length) ** 2\n        lr_ramp = min(1.0, (1.0 - t) / self.lr_rampdown_length)\n        lr_ramp = 0.5 - 0.5 * np.cos(lr_ramp * np.pi)\n        lr_ramp = lr_ramp * min(1.0, t / self.lr_rampup_length)\n        learning_rate = self.initial_learning_rate * lr_ramp\n\n        # Train.\n        feed_dict = {self._noise_in: noise_strength, self._lrate_in: learning_rate}\n        _, dist_value, loss_value = tflib.run([self._opt_step, self._dist, self._loss], feed_dict)\n        tflib.run(self._noise_normalize_op)\n\n        # Print status.\n        self._cur_step += 1\n        if self._cur_step == self.num_steps or self._cur_step % 10 == 0:\n            self._info('%-8d%-12g%-12g' % (self._cur_step, dist_value, loss_value))\n        if self._cur_step == self.num_steps:\n            self._info('Done.')\n\n    def get_cur_step(self):\n        return self._cur_step\n\n    def get_dlatents(self):\n        return tflib.run(self._dlatents_expr, {self._noise_in: 0})\n\n    def get_noises(self):\n        return tflib.run(self._noise_vars)\n\n    def get_images(self):\n        return tflib.run(self._images_expr, {self._noise_in: 0})\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/random_crops.py",
    "content": "import argparse, os\nimport numpy as np\nfrom PIL import Image\nfrom random import randrange\nfrom tqdm import tqdm\n\nparser = argparse.ArgumentParser()\nparser.add_argument('-i', '--input', type=str, required=True, help=\"Input directory of images to randomly crop.\")\nparser.add_argument('-o', '--output', type=str, required=True, help=\"Output destination to store randomly-cropped images.\")\nparser.add_argument('-n', '--max_images', type=int, required=True, help=\"Max images to randomly crop\")\nargs = parser.parse_args()\n\ndef random_crop(image, target, samples, file): \n    x = image.width\n    y = image.height\n    for i in range(samples):\n        x1 = randrange(0, x - target)\n        y1 = randrange(0, y - target)\n        image.crop((x1, y1, x1 + target, y1 + target)).save(target_directory + \"/\" + str(i) + file)\n\n\ndirectory = args.input\ntarget_directory = args.output\nmax_images = args.max_images\nadded = 0\n\nwith tqdm(total=max_images) as pbar:\n    for subdir, dirs, files in os.walk(directory):\n        for file in files:\n            filepath = subdir + os.sep + file\n            if filepath.endswith(\".jpeg\") and added != max_images:\n                if \"._\" in filepath:\n                    continue\n                im = Image.open(filepath).convert('RGB')\n                random_crop(im, 512, 5, file)\n                added += 1\n                pbar.update(1)\n            else:\n                break\n"
  },
  {
    "path": "stylegan2-tpu/repl.l",
    "content": "(%block class Namespace (do))\n\n(defvar args (Namespace))\n\n(set args.batch_size 1 args.randomize_noise false args.tile_dlatents false args.clipping_threshold 2.0 args.model_res 1024 args.lr 0.02 args.decay_rate 0.9 args.decay_steps 10 args.image_size 256 args.use_vgg_layer 9 args.use_vgg_loss 0.4 args.face_mask false args.use_grabcut true args.scale_mask 1.5 args.mask_dir \"masks\" args.use_pixel_loss 1.5 args.use_mssim_loss 100 args.use_lpips_loss 100 args.use_l1_penalty 1)\n;(set args.batch_size 1 args.randomize_noise false args.tile_dlatents true args.clipping_threshold 2.0 args.model_res 1024 args.lr 0.02 args.decay_rate 0.9 args.decay_steps 10 args.image_size 256 args.use_vgg_layer 9 args.use_vgg_loss 0.4 args.face_mask false args.use_grabcut true args.scale_mask 1.5 args.mask_dir \"masks\" args.use_pixel_loss 1.5 args.use_mssim_loss 100 args.use_lpips_loss 100 args.use_l1_penalty 0)\n\n(import os)\n(import pickle)\n(import PIL.Image)\n(import numpy as np)\n(import tensorflow as tf)\n(import dnnlib)\n(import dnnlib.tflib as tflib)\n(defvar config (Namespace))\n(set config.cache_dir \"cache\")\n(import websockets)\n(import datetime)\n(import asyncio)\n;(import ganlib)\n(from encoder.generator_model import Generator)\n(from encoder.perceptual_model import PerceptualModel load_images)\n(from keras.models import load_model)\n(from importlib import reload)\n\n;(import matplotlib.pyplot as plt)\n\n(defconst URL_FFHQ \"https://drive.google.com/uc?id=1MEGjdvVpUsu1jB4zrXZN7Y4kBBOzizDQ\")\n(defconst URL_FFHQ_RES 1024)\n(defconst URL_PERC \"https://drive.google.com/uc?id=1N2-m9qszOeVC9Tq77WxsLnuWwOedQiD2\")\n(defconst URL_ANIME \"2019-04-30-stylegan-danbooru2018-portraits-02095-066083.pkl\")\n(defconst URL_ANIME \"https://drive.google.com/uc?id=1pWnrmlP1aDv3bp1evzspH4ke9RdnP4aj\")\n(defconst URL_ANIME_RES 512)\n\n(def load-generator (url)\n  (with (dnnlib.util.open_url (or url URL_FFHQ) cache_dir: config.cache_dir) as f\n    (pickle (.load f))))\n  ;(ganlib.load_model (or url URL_FFHQ)))\n\n(def load-perceptual (url)\n (with (dnnlib.util.open_url (or URL_PERC url) cache_dir: config.cache_dir) as f\n   (pickle (.load f))))\n ;(ganlib.load_perceptual (or url URL_PERC)))\n\n(def init-generator (url res)\n  (global generator_network)\n  (global discriminator_network)\n  (global Gs_network)\n  (global generator)\n  (set generator_network, discriminator_network, Gs_network (load-generator url))\n  (set generator (Generator Gs_network batch_size: 1 randomize_noise: false model_res: (or res URL_FFHQ_RES) tiled_dlatent: args.tile_dlatents))\n  generator)\n\n(defvar reference-images*\n  (list \"/drive/stylegan-server-cache/217677dfe303180f7736ca5ecf0868a3_aligned\"))\n\n(def init-perceptual (url res)\n  (global perc_model)\n  (global perceptual_model)\n  (set perc_model (load-perceptual url))\n  (set perceptual_model (PerceptualModel args perc_model: perc_model batch_size: args.batch_size))\n  (perceptual_model.build_perceptual_model generator)\n  (let img (PIL.Image.new size: '(256 256) mode: \"RGB\" color: \"black\")\n    (img.save \"/tmp/reference.png\" \"PNG\"))\n  (perceptual_model.set_reference_images (list \"/tmp/reference.png\"))\n  )\n\n;(tflib.init_tf)\n;(set sess (tf.get_default_session))\n;(init-generator)\n\n; (set vs (+ (list x for x in (perceptual_model.optimizer._get_beta_accumulators)) (list (perceptual_model.optimizer.get_slot generator.dlatent_variable x) for x in '(m v))))\n; (set state0 (list (x (.eval)) for x in vs))\n; (list (x (.load v)) for x, v in (zip vs state0))\n\n; stochastic clipping doesn't play well with facial directions!\n\n(def reinit-perceptual ()\n  (let scope (tf.get_variable_scope)\n    (with (tf.variable_scope scope reuse: tf.AUTO_REUSE)\n      (perceptual_model.build_perceptual_model generator))))\n\n(defvar ff-model* nil)\n(defvar resnet-path* \"data/finetuned_resnet.h5\")\n(defconst resnet-download-url* \"https://drive.google.com/uc?id=1aT59NFy9-bNyXjDuZOTMl0qX0jmZc6Zb\")\n\n(def init-resnet ()\n  (global ff-model*)\n  (unless (os.path.exists resnet-path*)\n    (os.makedirs (os.path.dirname resnet-path*) exist_ok: true)\n    (with (dnnlib.util.open_url resnet-download-url* cache_dir: \"cache\") as f\n      (with (open resnet-path* \"wb\") as dst\n        (dst.write (f.read)))))\n  (unless ff-model*\n    (set ff-model* (load_model resnet-path*)))\n  ff-model*)\n\n(def image? (x)\n  (isinstance x PIL.Image.Image))\n\n(def file? (x)\n  (os.path.isfile x))\n\n(def numpy? (x)\n  (isinstance x np.ndarray))\n\n(import requests)\n\n(def GET (url)\n  (requests.get url))\n\n(def convert-image (img)\n  (img.convert \"RGB\"))\n\n(def fetch-image (url)\n  (if (image? url) url\n      (file? url) (PIL.Image.open url)\n      (numpy? url) (PIL.Image.fromarray url)\n    (let resp (GET url)\n      (when (= resp.status_code 200)\n        (PIL.Image.open (BytesIO resp.content))))))\n\n(def image-to-numpy (x)\n  (if (numpy? x) x (np.array (fetch-image x))))\n\n(def bytes-to-numpy (x reshape)\n  (if (numpy? x) x\n    (let l (np.frombuffer x dtype: np.uint8 count: (# x))\n      (if (is? reshape) (l.reshape reshape) l))))\n\n(def numpy-to-image (x)\n  (if (numpy? x) (PIL.Image.fromarray x) (fetch-image x)))\n\n(def expand-image (x)\n  (let-when img (numpy-to-image x)\n    (let img (convert-image img)\n      (let-when data (image-to-numpy img)\n        (if (= (# data.shape) 3)\n            (np.expand_dims data axis: 0)\n          data)))))\n\n(def resize-image (img size)\n  (img.resize size PIL.Image.ANTIALIAS))\n\n(def image-to-target (img size)\n  (let (size (or size '(256 256))\n        img (resize-image img size))\n    (image-to-numpy (img.convert \"RGB\"))))\n\n(def thumbnail-image (img size)\n  (let img (img.copy)\n    (img.thumbnail size PIL.Image.ANTIALIAS)\n    img))\n\n(import time)\n\n(def current-time ()\n  (time.time))\n\n(mac timeit body\n  (let-unique (t1 t2 r)\n    `(let ,t1 (current-time)\n       (with ,r (do ,@body)\n         (let ,t2 (current-time)\n           (print (cat \"time: \" (- ,t2 ,t1) \" seconds\")))))))\n\n\n(from keras.applications.resnet50 import preprocess_input)\n\n(defconst default-dlatent* (np.zeros shape: (if args.tile_dlatents '(1 512) '(1 18 512))))\n\n(def estimate-dlatent (img)\n  (let result (let-when model (init-resnet)\n                (let-when data (image-to-numpy img)\n                  (model.predict (preprocess_input (np.expand_dims data axis: 0)))))\n    (if (is? result) result (default-dlatent*.copy))))\n\n;(tflib.init_tf)\n;(with (dnnlib.util.open_url URL_FFHQ, cache_dir=config.cache_dir) as f\n;  (set generator_network, discriminator_network, Gs_network (pickle.load f)))\n\n(defvar latents* (Namespace))\n\n;(set latents*.trump (np (.load \"ffhq_dataset/latent_representations/donald_trump_01.npy\"))\n;     latents*.hillary (np (.load \"ffhq_dataset/latent_representations/hillary_clinton_01.npy\")))\n\n;(step x (list \"smile\" \"gender\" \"age\")\n;  (let path (cat \"ffhq_dataset/latent_directions/\" x \".npy\")\n;    (setattr latents* x (np (.load path)))))\n\n(from glob import glob)\n(for k, v in (list (list (hd ((at (x (.split \"/\")) -1) (.split \"_direction\"))) (np (.load x))) for x in (glob \"trained_directions/*.npy\"))\n  (setattr latents* k v))\n\n(for k, v in (list (list (hd ((at (x (.split \"/\")) -1) (.split \"_direction\"))) (np (.load x))) for x in (glob \"../facetrickery/data/directions/*.npy\"))\n  (setattr latents* k v))\n\n(def file-to-bytes (path)\n  (with (open path \"rb\") as f\n    (f.read)))\n\n(import json)\n\n(def file-to-latent (path)\n  (np.array (json.loads (file-to-bytes path))))\n\n(def load-latents ()\n  (let i 0\n    (for path in (sorted (hd (list (glob \"/drive/stylegan-server-cache/*_latent\"))))\n    ;(for k, v in (list (list (hd ((at (x (.split \"/\")) -1) (.split \"_latent\"))) (np (.load x))) for x in \n      (let (name (% \"i%03d\" (inc i))\n            v (file-to-latent path))\n        (setattr latents* name v)))))\n\n(def upload-variable (variable value)\n  (variable (.load value)))\n\n(def fetch-variable (variable)\n  (variable (.eval)))\n\n(def as-latent (latent)\n  (let-when x (np.array latent dtype: np.float32)\n    (x.reshape (if args.tile_dlatents (list -1 512) (list 1 -1 512)))))\n\n(def upload-latent (latent)\n  (let x (as-latent latent)\n    (upload-variable generator.dlatent_variable x)))\n\n(def fetch-latent ()\n  (fetch-variable generator.dlatent_variable))\n\n(def upload-step (i)\n  (upload-variable perceptual_model._global_step (or i 0)))\n\n(def generate-image-array (latent)\n  ;(generator.set_dlatents latent)\n  (upload-latent latent)\n  (at (generator.generate_images) 0))\n\n(def generate-image (latent)\n    (let (img-array (generate-image-array latent)\n          img (PIL.Image.fromarray img-array \"RGB\"))\n      img))\n\n(def disk-image (latent fname)\n  (let img (generate-image latent)\n    (img (.save fname))\n    latent))\n\n(def zspace-to-wspace (dlatent)\n  (let dlatent (dlatent (.reshape '(1 -1)))\n    (Gs_network.components.mapping (.run dlatent nil minibatch_size: 1 randomize_noise: false structure: \"fixed\"))))\n\n(defvar image-path* (os.path.join \"/tmp\" \"images\"))\n(defvar error-image* (PIL.Image.new size: '(16 16) mode: \"RGB\" color: \"black\"))\n(defvar saved-image* error-image*)\n\n(def next-path (base)\n  (with i 0\n    (while (os.path.exists (% base i))\n      (inc i))))\n\n(def image-path (idx)\n  (let (fmt (os.path.join image-path* \"image_%05d.png\")\n        idx (if (is? idx) idx (next-path fmt)))\n    (% fmt idx)))\n\n(def save-image (img idx)\n  (os.makedirs image-path* exist_ok: true)\n  (let fname (image-path idx)\n    (print (cat \"Saving \" fname))\n    (img.save fname \"PNG\")\n    (global saved-image*)\n    (set saved-image* (img.resize '(256 256)))\n    img))\n\n(def calculate-latent (spec)\n  (with result (np.zeros shape: '(1 18 512))\n    (step (weight x) (pair spec)\n      (let-when latent (if (string? x) (getattr latents* x)\n                           (array? x) x)\n        (inc result (* weight latent))))))\n\n(def generate-image-from-spec (spec)\n  (let (latent (calculate-latent spec)\n        img (generate-image latent))\n    ;(save-image img idx)))\n    img))\n\n(def randf ()\n  (np.random.uniform))\n\n(def generate-random-image ()\n  (let spec (list (randf) 'trump (randf) 'hillary)\n    (generate-image-from-spec spec)))\n\n(import tempfile)\n\n(mac with-temp-dir (var rest: body)\n  `(with (tempfile.TemporaryDirectory suffix: ',(compile (cat \"-\" var))) as ,var\n     ,@body))\n\n(import PIL.Image)\n(from io import BytesIO)\n\n(def image-from-bytes (s)\n  (PIL.Image.open (BytesIO (to-bytes s))))\n\n(def image-to-bytes (img rest: args)\n  (with-temp-dir tmp-image-dir\n    (let fname (os.path.join tmp-image-dir \"image\")\n      (apply img.save fname args)\n      (with (open fname \"rb\") as f\n        (f.read)))))\n\n(def image-to-bytes (img format quality)\n  (let bs (BytesIO)\n    ;(img.save bs format: (or format \"PNG\") quality: (or quality 95))\n    (img.save bs format: (or format \"JPEG\") quality: (or quality 90))\n    (bs (.getvalue))))\n  \n(defconst regen-delay* 3)\n\n(async def handle-serve-1 (websocket path)\n  (let now (cat (datetime.datetime (.utcnow) (.isoformat)) \"Z\")\n    (await (websocket.send now))\n    (await (asyncio.sleep (* (randf) regen-delay*)))))\n\n(async def handle-serve-1 (websocket path)\n  (save-image (generate-random-image) 0)\n  (await (websocket.send (image-to-bytes saved-image*)))\n  (await (asyncio.sleep (* (randf) regen-delay*))))\n\n(defconst ellipsize-limit* 240)\n\n(def ellipsize (s limit)\n  (let n (either limit ellipsize-limit*)\n    (if (> (# s) n)\n        (cat (clip s 0 n) \"...\")\n      s)))\n\n(async def handle-serve-1 (websocket path)\n  (let x (await (websocket.recv))\n    (print (ellipsize (repr x)))\n    (save-image (generate-random-image) 0)\n    (await (websocket.send (image-to-bytes saved-image*)))))\n\n(import reader)\n\n(def image? (x)\n  (isinstance x PIL.Image.Image))\n\n(def bytes? (x)\n  (isinstance x bytes))\n\n(import inspect)\n\n(define-global awaitable? (x)\n  (inspect.isawaitable x))\n\n(async def awaitable (x)\n  (if (awaitable? x) (await x) x))\n\n(def gathered (x)\n  ;(if (awaitable? x) x ((async fn () (if (function? x) (x) x)))))\n  (if (awaitable? x) x ((async fn () x))))\n\n(def current-task ()\n  (let ((ok v) (guard (asyncio.Task.current-task)))\n    (if ok v\n      (do (asyncio.set_event_loop (asyncio.new_event_loop))\n          (asyncio.Task.current-task)))))\n\n(import threading)\n\n(def current-thread ()\n  (threading.current_thread))\n\n(defvar id-count* 1)\n(defvar id-lock* (threading.RLock))\n\n(def get-id (x)\n  (global id-count*)\n  (with id-lock*\n    (if (hasattr x \"lumen_id\")\n        (getattr x \"lumen_id\")\n        (with i (inc id-count*)\n          (setattr x \"lumen_id\" i)))))\n\n(def current-task-id ()\n  (let task (current-task)\n    (if task (get-id task) (get-id (current-thread)))))\n\n(%block class (Tagged Namespace)\n  (def __init__ (self tag rep)\n    (set self.tag tag\n         self.rep rep)\n    nil)\n  (def __repr__ (self)\n    (cat \"Tagged(\" (repr self.tag) \")\")))\n\n(def tagged? (x)\n  (and (hasattr x 'tag) (hasattr x 'rep)))\n\n(def kind (x)\n  (if (tagged? x) x.tag (type x)))\n\n(def tag (x y)\n  (if (= (kind x) y) x (Tagged y x)))\n\n(def rep (x)\n  (if (tagged? x) x.rep x))\n\n(def make-thread-cell-value (cell value)\n  (with self (tag nil 'thread-cell-value)\n    (set self.cell cell\n         self.value value\n         self.rep self)))\n\n(def thread-cell-value? (v)\n  (= (kind v) 'thread-cell-value))\n\n(import weakref)\n\n(defvar preserved-thread-cells* (list))\n(defvar preserved-thread-cell-values* (obj))\n\n(def add-preserved-thread-cell (cell)\n  (add preserved-thread-cells* (weakref.ref cell)))\n\n(def set-preserved-thread-cell-values (id vals)\n  (set (get preserved-thread-cell-values* id) vals))\n\n(def grab-preserved-thread-cell-values ()\n  (list (make-thread-cell-value cell (thread-cell-ref cell))\n        for cell in (array (map call preserved-thread-cells*))))\n\n(def get-preserved-thread-cell-values (id)\n  (has preserved-thread-cell-values* id))\n\n(def find-preserved-thread-cell-value (vals cell)\n  (step x vals\n    (when (= x.cell cell)\n      (return x.value)))\n  cell.default)\n\n(def current-preserved-thread-cell-values args\n  (if (none? args)\n      (grab-preserved-thread-cell-values)\n      (let vals (hd args)\n        (step x preserved-thread-cells*\n          (let-when x (x)\n            (let v (find-preserved-thread-cell-value vals x)\n              (thread-cell-set x v)))))))\n\n(def make-thread-cell (v preserved?)\n  (with self (tag nil 'thread-cell)\n    (set self.default v\n         self.values (obj) ; (WeakValueDictionary)\n         self.preserved preserved?\n         self.rep self)\n    (when preserved?\n      (add-preserved-thread-cell self))))\n\n(def thread-cell? (v)\n  (= (kind v) 'thread-cell))\n\n(def thread-cell-ref (v id)\n  (let id (if (is? id) id (current-task-id))\n    (if (has? v.values id)\n        (get v.values id)\n        ;v.preserved\n        ;(step x (get-preserved-thread-cell-values id)\n        ;  (when (= x.cell v)\n        ;    (return x.value)))\n      v.default)))\n\n(def thread-cell-set (cell v)\n  (unless (thread-cell? cell)\n    (error \"Expected thread-cell\"))\n  (let id (current-task-id)\n    (if (nil? v)\n        (wipe (get cell.values id))\n      (set (get cell.values id) v))))\n\n(def create-task (f)\n  (let (loop (event-loop)\n        vals (current-preserved-thread-cell-values)\n        thunk ((async fn ()\n                 (current-preserved-thread-cell-values vals)\n                 (await (gathered f))))\n        task (loop.create-task thunk))\n    task))\n\n(def schedule (f)\n  (create-task f))\n\n(define-macro thread body\n  `(schedule ((async fn () ,@body))))\n\n(defvar websocket* (make-thread-cell nil true))\n\n(def current-socket args\n  (if (none? args)\n      (thread-cell-ref websocket*)\n    (thread-cell-set websocket* (hd args))))\n\n(async def send-full-image (img format quality)\n  (let val (image-to-bytes img format quality)\n    (await ((current-socket) (.send val)))\n    img))\n\n(async def send-image (img)\n  (await (send-full-image (resize-image img '(256 256)))))\n\n(defvar data* (list))\n\n(async def repl-print (form)\n  (let ((ok v ex) (guard ((idx compiler eval) form)))\n    (if (not ok)\n        (print-exception v ex)\n        (is? v)\n        (let v (await (gathered v))\n          (do (print (ellipsize (repr v))) v)))))\n\n(async def handle-serve-1 (websocket path)\n  (let x (await (websocket.recv))\n    (if (bytes? x)\n        (do (add data* x)\n            (await (websocket.send (cat \"data*.\" (edge data*)))))\n      (let form (reader.read-string x)\n        (print (ellipsize (repr form)))\n        (let (result (await (repl-print form))\n              result (if (image? result) result error-image*)\n              ;result (result.resize '(256 256)))\n              )\n          ;(await (websocket.send (image-to-bytes result \"PNG\"))))))))\n          (await (send-full-image result)))))))\n\n(async def handle-serve (websocket path)\n  (while true\n    ;(load \"repl.l\")\n    (current-socket websocket)\n    (await (handle-serve-1 websocket path))))\n\n(defvar start-server* (websockets.serve (fn args (apply handle-serve args)) \"0.0.0.0\" 5679 max_queue: nil read_limit: (* 100 1024 1024) write_limit: (* 100 1024 1024) max_size: (* 100 1024 1024)))\n\n(defvar server* nil)\n\n(def event-loop ()\n  (asyncio (.get-event-loop)))\n\n(def serve ()\n  (global server*)\n  (set server* (or server* (asyncio (.get-event-loop) (.run-until-complete start-server*)))))\n\n(def setup (model-url perc-url model_res: res)\n  (global sess)\n  (tflib.init_tf)\n  (set sess (tf.get_default_session))\n  (init-generator model-url res)\n  (init-perceptual perc-url res)\n  (init-resnet)\n  (serve))\n\n(def run-forever ()\n  (asyncio (.get-event-loop) (.run-forever)))\n\n(import os)\n(import sys)\n(import bz2)\n(import argparse)\n(from keras.utils import get_file)\n;(from ffhq_dataset.face_alignment import image_align)\n;(from ffhq_dataset.landmarks_detector import LandmarksDetector)\n(import multiprocessing)\n\n(defconst LANDMARKS_MODEL_URL \"http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2\")\n\n(def unpack-bz2 (src-path)\n  (let (f (bz2.BZ2File src_path)\n        data (f.read)\n        dst-path (get src-path (: -4)))\n    (with (open dst-path \"wb\") as fp\n      (fp.write data))\n    dst-path))\n\n;(defvar landmarks-model-path*\n;  (unpack_bz2 (get_file \"shape_predictor_68_face_landmarks.dat.bz2\" LANDMARKS_MODEL_URL cache_subdir: \"temp\")))\n\n;(defvar landmarks-detector* (LandmarksDetector landmarks-model-path*))\n\n(def get-landmarks (img)\n  (list marks for marks in (landmarks-detector*.get-landmarks img)))\n\n(def face-align (img)\n  (let (img (numpy-to-image img)\n        marks (get-landmarks img))\n    (if (none? marks)\n        (do (print \"No face detected\")\n            (img (.resize '(1024 1024) PIL.Image.ANTIALIAS)\n                 (.convert \"RGB\")))\n      (image-align img (hd marks)))))\n\n(def fetch-downsize (url)\n  (let-when img (fetch-image url)\n    (let img (convert-image img)\n      (img.thumbnail '(1536 1536) PIL.Image.ANTIALIAS)\n      img)))\n\n(def fetch-aligned (url)\n  (face-align (fetch-downsize url)))\n\n\n"
  },
  {
    "path": "stylegan2-tpu/requirements.txt",
    "content": "absl-py==0.7.0\nastor==0.7.1\ncertifi==2018.11.29\nchardet==3.0.4\nClick==7.0\nFlask==1.0.2\nFlask-Cors==3.0.7\ngast==0.2.2\ngevent==1.4.0\ngreenlet==0.4.15\ngrpcio==1.19.0\nh5py==2.9.0\nidna==2.8\nitsdangerous==1.1.0\nJinja2==2.10\nKeras-Applications==1.0.7\nKeras-Preprocessing==1.0.9\nMarkdown==3.0.1\nMarkupSafe==1.1.1\nmock==2.0.0\nnumpy==1.16.2\npbr==5.1.2\nPillow==5.4.1\nprotobuf==3.6.1\nrequests==2.21.0\nsix==1.12.0\ntensorflow-gpu==1.15.0\ntermcolor==1.1.0\nurllib3==1.24.1\nWerkzeug==0.14.1\nwget==3.2\n"
  },
  {
    "path": "stylegan2-tpu/run_generator.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\nimport argparse\nimport numpy as np\nimport PIL.Image\nimport dnnlib\nimport dnnlib.tflib as tflib\nimport re\nimport sys\n\nimport pretrained_networks\n\n#----------------------------------------------------------------------------\n\ndef generate_images(network_pkl, seeds, truncation_psi):\n    print('Loading networks from \"%s\"...' % network_pkl)\n    _G, _D, Gs = pretrained_networks.load_networks(network_pkl)\n    noise_vars = [var for name, var in Gs.components.synthesis.vars.items() if name.startswith('noise')]\n\n    Gs_kwargs = dnnlib.EasyDict()\n    Gs_kwargs.output_transform = dict(func=tflib.convert_images_to_uint8, nchw_to_nhwc=True)\n    Gs_kwargs.randomize_noise = False\n    if truncation_psi is not None:\n        Gs_kwargs.truncation_psi = truncation_psi\n\n    for seed_idx, seed in enumerate(seeds):\n        print('Generating image for seed %d (%d/%d) ...' % (seed, seed_idx, len(seeds)))\n        rnd = np.random.RandomState(seed)\n        z = rnd.randn(1, *Gs.input_shape[1:]) # [minibatch, component]\n        tflib.set_vars({var: rnd.randn(*var.shape.as_list()) for var in noise_vars}) # [height, width]\n        images = Gs.run(z, None, **Gs_kwargs) # [minibatch, height, width, channel]\n        PIL.Image.fromarray(images[0], 'RGB').save(dnnlib.make_run_dir_path('seed%04d.png' % seed))\n\n#----------------------------------------------------------------------------\n\ndef style_mixing_example(network_pkl, row_seeds, col_seeds, truncation_psi, col_styles, minibatch_size=4):\n    print('Loading networks from \"%s\"...' % network_pkl)\n    _G, _D, Gs = pretrained_networks.load_networks(network_pkl)\n    w_avg = Gs.get_var('dlatent_avg') # [component]\n\n    Gs_syn_kwargs = dnnlib.EasyDict()\n    Gs_syn_kwargs.output_transform = dict(func=tflib.convert_images_to_uint8, nchw_to_nhwc=True)\n    Gs_syn_kwargs.randomize_noise = False\n    Gs_syn_kwargs.minibatch_size = minibatch_size\n\n    print('Generating W vectors...')\n    all_seeds = list(set(row_seeds + col_seeds))\n    all_z = np.stack([np.random.RandomState(seed).randn(*Gs.input_shape[1:]) for seed in all_seeds]) # [minibatch, component]\n    all_w = Gs.components.mapping.run(all_z, None) # [minibatch, layer, component]\n    all_w = w_avg + (all_w - w_avg) * truncation_psi # [minibatch, layer, component]\n    w_dict = {seed: w for seed, w in zip(all_seeds, list(all_w))} # [layer, component]\n\n    print('Generating images...')\n    all_images = Gs.components.synthesis.run(all_w, **Gs_syn_kwargs) # [minibatch, height, width, channel]\n    image_dict = {(seed, seed): image for seed, image in zip(all_seeds, list(all_images))}\n\n    print('Generating style-mixed images...')\n    for row_seed in row_seeds:\n        for col_seed in col_seeds:\n            w = w_dict[row_seed].copy()\n            w[col_styles] = w_dict[col_seed][col_styles]\n            image = Gs.components.synthesis.run(w[np.newaxis], **Gs_syn_kwargs)[0]\n            image_dict[(row_seed, col_seed)] = image\n\n    print('Saving images...')\n    for (row_seed, col_seed), image in image_dict.items():\n        PIL.Image.fromarray(image, 'RGB').save(dnnlib.make_run_dir_path('%d-%d.png' % (row_seed, col_seed)))\n\n    print('Saving image grid...')\n    _N, _C, H, W = Gs.output_shape\n    canvas = PIL.Image.new('RGB', (W * (len(col_seeds) + 1), H * (len(row_seeds) + 1)), 'black')\n    for row_idx, row_seed in enumerate([None] + row_seeds):\n        for col_idx, col_seed in enumerate([None] + col_seeds):\n            if row_seed is None and col_seed is None:\n                continue\n            key = (row_seed, col_seed)\n            if row_seed is None:\n                key = (col_seed, col_seed)\n            if col_seed is None:\n                key = (row_seed, row_seed)\n            canvas.paste(PIL.Image.fromarray(image_dict[key], 'RGB'), (W * col_idx, H * row_idx))\n    canvas.save(dnnlib.make_run_dir_path('grid.png'))\n\n#----------------------------------------------------------------------------\n\ndef _parse_num_range(s):\n    '''Accept either a comma separated list of numbers 'a,b,c' or a range 'a-c' and return as a list of ints.'''\n\n    range_re = re.compile(r'^(\\d+)-(\\d+)$')\n    m = range_re.match(s)\n    if m:\n        return range(int(m.group(1)), int(m.group(2))+1)\n    vals = s.split(',')\n    return [int(x) for x in vals]\n\n#----------------------------------------------------------------------------\n\n_examples = '''examples:\n\n  # Generate ffhq uncurated images (matches paper Figure 12)\n  python %(prog)s generate-images --network=gdrive:networks/stylegan2-ffhq-config-f.pkl --seeds=6600-6625 --truncation-psi=0.5\n\n  # Generate ffhq curated images (matches paper Figure 11)\n  python %(prog)s generate-images --network=gdrive:networks/stylegan2-ffhq-config-f.pkl --seeds=66,230,389,1518 --truncation-psi=1.0\n\n  # Generate uncurated car images (matches paper Figure 12)\n  python %(prog)s generate-images --network=gdrive:networks/stylegan2-car-config-f.pkl --seeds=6000-6025 --truncation-psi=0.5\n\n  # Generate style mixing example (matches style mixing video clip)\n  python %(prog)s style-mixing-example --network=gdrive:networks/stylegan2-ffhq-config-f.pkl --row-seeds=85,100,75,458,1500 --col-seeds=55,821,1789,293 --truncation-psi=1.0\n'''\n\n#----------------------------------------------------------------------------\n\ndef main():\n    parser = argparse.ArgumentParser(\n        description='''StyleGAN2 generator.\n\nRun 'python %(prog)s <subcommand> --help' for subcommand help.''',\n        epilog=_examples,\n        formatter_class=argparse.RawDescriptionHelpFormatter\n    )\n\n    subparsers = parser.add_subparsers(help='Sub-commands', dest='command')\n\n    parser_generate_images = subparsers.add_parser('generate-images', help='Generate images')\n    parser_generate_images.add_argument('--network', help='Network pickle filename', dest='network_pkl', required=True)\n    parser_generate_images.add_argument('--seeds', type=_parse_num_range, help='List of random seeds', required=True)\n    parser_generate_images.add_argument('--truncation-psi', type=float, help='Truncation psi (default: %(default)s)', default=0.5)\n    parser_generate_images.add_argument('--result-dir', help='Root directory for run results (default: %(default)s)', default='results', metavar='DIR')\n\n    parser_style_mixing_example = subparsers.add_parser('style-mixing-example', help='Generate style mixing video')\n    parser_style_mixing_example.add_argument('--network', help='Network pickle filename', dest='network_pkl', required=True)\n    parser_style_mixing_example.add_argument('--row-seeds', type=_parse_num_range, help='Random seeds to use for image rows', required=True)\n    parser_style_mixing_example.add_argument('--col-seeds', type=_parse_num_range, help='Random seeds to use for image columns', required=True)\n    parser_style_mixing_example.add_argument('--col-styles', type=_parse_num_range, help='Style layer range (default: %(default)s)', default='0-6')\n    parser_style_mixing_example.add_argument('--truncation-psi', type=float, help='Truncation psi (default: %(default)s)', default=0.5)\n    parser_style_mixing_example.add_argument('--result-dir', help='Root directory for run results (default: %(default)s)', default='results', metavar='DIR')\n\n    args = parser.parse_args()\n    kwargs = vars(args)\n    subcmd = kwargs.pop('command')\n\n    if subcmd is None:\n        print ('Error: missing subcommand.  Re-run with --help for usage.')\n        sys.exit(1)\n\n    sc = dnnlib.SubmitConfig()\n    sc.num_gpus = 1\n    sc.submit_target = dnnlib.SubmitTarget.LOCAL\n    sc.local.do_not_copy_source_files = True\n    sc.run_dir_root = kwargs.pop('result_dir')\n    sc.run_desc = subcmd\n\n    func_name_map = {\n        'generate-images': 'run_generator.generate_images',\n        'style-mixing-example': 'run_generator.style_mixing_example'\n    }\n    dnnlib.submit_run(sc, func_name_map[subcmd], **kwargs)\n\n#----------------------------------------------------------------------------\n\nif __name__ == \"__main__\":\n    main()\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/run_metrics.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\nimport argparse\nimport os\nimport sys\n\nimport dnnlib\nimport dnnlib.tflib as tflib\n\nimport pretrained_networks\nfrom metrics import metric_base\nfrom metrics.metric_defaults import metric_defaults\n\n#----------------------------------------------------------------------------\n\ndef run(network_pkl, metrics, dataset, data_dir, mirror_augment):\n    print('Evaluating metrics \"%s\" for \"%s\"...' % (','.join(metrics), network_pkl))\n    tflib.init_tf()\n    network_pkl = pretrained_networks.get_path_or_url(network_pkl)\n    dataset_args = dnnlib.EasyDict(tfrecord_dir=dataset, shuffle_mb=0)\n    num_gpus = dnnlib.submit_config.num_gpus\n    metric_group = metric_base.MetricGroup([metric_defaults[metric] for metric in metrics])\n    metric_group.run(network_pkl, data_dir=data_dir, dataset_args=dataset_args, mirror_augment=mirror_augment, num_gpus=num_gpus)\n\n#----------------------------------------------------------------------------\n\ndef _str_to_bool(v):\n    if isinstance(v, bool):\n        return v\n    if v.lower() in ('yes', 'true', 't', 'y', '1'):\n        return True\n    elif v.lower() in ('no', 'false', 'f', 'n', '0'):\n        return False\n    else:\n        raise argparse.ArgumentTypeError('Boolean value expected.')\n\n#----------------------------------------------------------------------------\n\n_examples = '''examples:\n\n  python %(prog)s --data-dir=~/datasets --network=gdrive:networks/stylegan2-ffhq-config-f.pkl --metrics=fid50k,ppl_wend --dataset=ffhq --mirror-augment=true\n\nvalid metrics:\n\n  ''' + ', '.join(sorted([x for x in metric_defaults.keys()])) + '''\n'''\n\ndef main():\n    parser = argparse.ArgumentParser(\n        description='Run StyleGAN2 metrics.',\n        epilog=_examples,\n        formatter_class=argparse.RawDescriptionHelpFormatter\n    )\n    parser.add_argument('--result-dir', help='Root directory for run results (default: %(default)s)', default='results', metavar='DIR')\n    parser.add_argument('--network', help='Network pickle filename', dest='network_pkl', required=True)\n    parser.add_argument('--metrics', help='Metrics to compute (default: %(default)s)', default='fid50k', type=lambda x: x.split(','))\n    parser.add_argument('--dataset', help='Training dataset', required=True)\n    parser.add_argument('--data-dir', help='Dataset root directory', required=True)\n    parser.add_argument('--mirror-augment', help='Mirror augment (default: %(default)s)', default=False, type=_str_to_bool, metavar='BOOL')\n    parser.add_argument('--num-gpus', help='Number of GPUs to use', type=int, default=1, metavar='N')\n\n    args = parser.parse_args()\n\n    if not os.path.exists(args.data_dir):\n        print ('Error: dataset root directory does not exist.')\n        sys.exit(1)\n\n    kwargs = vars(args)\n    sc = dnnlib.SubmitConfig()\n    sc.num_gpus = kwargs.pop('num_gpus')\n    sc.submit_target = dnnlib.SubmitTarget.LOCAL\n    sc.local.do_not_copy_source_files = True\n    sc.run_dir_root = kwargs.pop('result_dir')\n    sc.run_desc = 'run-metrics'\n    dnnlib.submit_run(sc, 'run_metrics.run', **kwargs)\n\n#----------------------------------------------------------------------------\n\nif __name__ == \"__main__\":\n    main()\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/run_projector.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\nimport argparse\nimport numpy as np\nimport dnnlib\nimport dnnlib.tflib as tflib\nimport re\nimport sys\n\nimport projector\nimport pretrained_networks\nfrom training import dataset\nfrom training import misc\n\n#----------------------------------------------------------------------------\n\ndef project_image(proj, targets, png_prefix, num_snapshots):\n    snapshot_steps = set(proj.num_steps - np.linspace(0, proj.num_steps, num_snapshots, endpoint=False, dtype=int))\n    misc.save_image_grid(targets, png_prefix + 'target.png', drange=[-1,1])\n    proj.start(targets)\n    while proj.get_cur_step() < proj.num_steps:\n        print('\\r%d / %d ... ' % (proj.get_cur_step(), proj.num_steps), end='', flush=True)\n        proj.step()\n        if proj.get_cur_step() in snapshot_steps:\n            misc.save_image_grid(proj.get_images(), png_prefix + 'step%04d.png' % proj.get_cur_step(), drange=[-1,1])\n    print('\\r%-30s\\r' % '', end='', flush=True)\n\n#----------------------------------------------------------------------------\n\ndef project_generated_images(network_pkl, seeds, num_snapshots, truncation_psi):\n    print('Loading networks from \"%s\"...' % network_pkl)\n    _G, _D, Gs = pretrained_networks.load_networks(network_pkl)\n    proj = projector.Projector()\n    proj.set_network(Gs)\n    noise_vars = [var for name, var in Gs.components.synthesis.vars.items() if name.startswith('noise')]\n\n    Gs_kwargs = dnnlib.EasyDict()\n    Gs_kwargs.randomize_noise = False\n    Gs_kwargs.truncation_psi = truncation_psi\n\n    for seed_idx, seed in enumerate(seeds):\n        print('Projecting seed %d (%d/%d) ...' % (seed, seed_idx, len(seeds)))\n        rnd = np.random.RandomState(seed)\n        z = rnd.randn(1, *Gs.input_shape[1:])\n        tflib.set_vars({var: rnd.randn(*var.shape.as_list()) for var in noise_vars})\n        images = Gs.run(z, None, **Gs_kwargs)\n        project_image(proj, targets=images, png_prefix=dnnlib.make_run_dir_path('seed%04d-' % seed), num_snapshots=num_snapshots)\n\n#----------------------------------------------------------------------------\n\ndef project_real_images(network_pkl, dataset_name, data_dir, num_images, num_snapshots):\n    print('Loading networks from \"%s\"...' % network_pkl)\n    _G, _D, Gs = pretrained_networks.load_networks(network_pkl)\n    proj = projector.Projector()\n    proj.set_network(Gs)\n\n    print('Loading images from \"%s\"...' % dataset_name)\n    dataset_obj = dataset.load_dataset(data_dir=data_dir, tfrecord_dir=dataset_name, max_label_size=0, repeat=False, shuffle_mb=0)\n    assert dataset_obj.shape == Gs.output_shape[1:]\n\n    for image_idx in range(num_images):\n        print('Projecting image %d/%d ...' % (image_idx, num_images))\n        images, _labels = dataset_obj.get_minibatch_np(1)\n        images = misc.adjust_dynamic_range(images, [0, 255], [-1, 1])\n        project_image(proj, targets=images, png_prefix=dnnlib.make_run_dir_path('image%04d-' % image_idx), num_snapshots=num_snapshots)\n\n#----------------------------------------------------------------------------\n\ndef _parse_num_range(s):\n    '''Accept either a comma separated list of numbers 'a,b,c' or a range 'a-c' and return as a list of ints.'''\n\n    range_re = re.compile(r'^(\\d+)-(\\d+)$')\n    m = range_re.match(s)\n    if m:\n        return range(int(m.group(1)), int(m.group(2))+1)\n    vals = s.split(',')\n    return [int(x) for x in vals]\n\n#----------------------------------------------------------------------------\n\n_examples = '''examples:\n\n  # Project generated images\n  python %(prog)s project-generated-images --network=gdrive:networks/stylegan2-car-config-f.pkl --seeds=0,1,5\n\n  # Project real images\n  python %(prog)s project-real-images --network=gdrive:networks/stylegan2-car-config-f.pkl --dataset=car --data-dir=~/datasets\n\n'''\n\n#----------------------------------------------------------------------------\n\ndef main():\n    parser = argparse.ArgumentParser(\n        description='''StyleGAN2 projector.\n\nRun 'python %(prog)s <subcommand> --help' for subcommand help.''',\n        epilog=_examples,\n        formatter_class=argparse.RawDescriptionHelpFormatter\n    )\n\n    subparsers = parser.add_subparsers(help='Sub-commands', dest='command')\n\n    project_generated_images_parser = subparsers.add_parser('project-generated-images', help='Project generated images')\n    project_generated_images_parser.add_argument('--network', help='Network pickle filename', dest='network_pkl', required=True)\n    project_generated_images_parser.add_argument('--seeds', type=_parse_num_range, help='List of random seeds', default=range(3))\n    project_generated_images_parser.add_argument('--num-snapshots', type=int, help='Number of snapshots (default: %(default)s)', default=5)\n    project_generated_images_parser.add_argument('--truncation-psi', type=float, help='Truncation psi (default: %(default)s)', default=1.0)\n    project_generated_images_parser.add_argument('--result-dir', help='Root directory for run results (default: %(default)s)', default='results', metavar='DIR')\n\n    project_real_images_parser = subparsers.add_parser('project-real-images', help='Project real images')\n    project_real_images_parser.add_argument('--network', help='Network pickle filename', dest='network_pkl', required=True)\n    project_real_images_parser.add_argument('--data-dir', help='Dataset root directory', required=True)\n    project_real_images_parser.add_argument('--dataset', help='Training dataset', dest='dataset_name', required=True)\n    project_real_images_parser.add_argument('--num-snapshots', type=int, help='Number of snapshots (default: %(default)s)', default=5)\n    project_real_images_parser.add_argument('--num-images', type=int, help='Number of images to project (default: %(default)s)', default=3)\n    project_real_images_parser.add_argument('--result-dir', help='Root directory for run results (default: %(default)s)', default='results', metavar='DIR')\n\n    args = parser.parse_args()\n    subcmd = args.command\n    if subcmd is None:\n        print ('Error: missing subcommand.  Re-run with --help for usage.')\n        sys.exit(1)\n\n    kwargs = vars(args)\n    sc = dnnlib.SubmitConfig()\n    sc.num_gpus = 1\n    sc.submit_target = dnnlib.SubmitTarget.LOCAL\n    sc.local.do_not_copy_source_files = True\n    sc.run_dir_root = kwargs.pop('result_dir')\n    sc.run_desc = kwargs.pop('command')\n\n    func_name_map = {\n        'project-generated-images': 'run_projector.project_generated_images',\n        'project-real-images': 'run_projector.project_real_images'\n    }\n    dnnlib.submit_run(sc, func_name_map[subcmd], **kwargs)\n\n#----------------------------------------------------------------------------\n\nif __name__ == \"__main__\":\n    main()\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/run_training.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\nimport argparse\nimport copy\nimport os\nimport sys\n\nimport dnnlib\nfrom dnnlib import EasyDict\n\nfrom metrics.metric_defaults import metric_defaults\n\nfrom tensorflow.python.platform import gfile\n\n#----------------------------------------------------------------------------\n\n_valid_configs = [\n    # Table 1\n    'config-a', # Baseline StyleGAN\n    'config-b', # + Weight demodulation\n    'config-c', # + Lazy regularization\n    'config-d', # + Path length regularization\n    'config-e', # + No growing, new G & D arch.\n    'config-f', # + Large networks (default)\n\n    # Table 2\n    'config-e-Gorig-Dorig',   'config-e-Gorig-Dresnet',   'config-e-Gorig-Dskip',\n    'config-e-Gresnet-Dorig', 'config-e-Gresnet-Dresnet', 'config-e-Gresnet-Dskip',\n    'config-e-Gskip-Dorig',   'config-e-Gskip-Dresnet',   'config-e-Gskip-Dskip',\n]\n\n#----------------------------------------------------------------------------\n\ndef run(dataset, data_dir, result_dir, config_id, num_gpus, total_kimg, gamma, mirror_augment, metrics):\n    train     = EasyDict(run_func_name='training.training_loop.training_loop') # Options for training loop.\n    G         = EasyDict(func_name='training.networks_stylegan2.G_main')       # Options for generator network.\n    D         = EasyDict(func_name='training.networks_stylegan2.D_stylegan2')  # Options for discriminator network.\n    G_opt     = EasyDict(beta1=0.0, beta2=0.99, epsilon=1e-8)                  # Options for generator optimizer.\n    D_opt     = EasyDict(beta1=0.0, beta2=0.99, epsilon=1e-8)                  # Options for discriminator optimizer.\n    G_loss    = EasyDict(func_name='training.loss.G_logistic_ns_pathreg')      # Options for generator loss.\n    D_loss    = EasyDict(func_name='training.loss.D_logistic_r1')              # Options for discriminator loss.\n    sched     = EasyDict()                                                     # Options for TrainingSchedule.\n    grid      = EasyDict(size='8k', layout='random')                           # Options for setup_snapshot_image_grid().\n    sc        = dnnlib.SubmitConfig()                                          # Options for dnnlib.submit_run().\n    tf_config = {'rnd.np_random_seed': 1000}                                   # Options for tflib.init_tf().\n\n    train.data_dir = data_dir\n    train.total_kimg = total_kimg\n    train.mirror_augment = mirror_augment\n    train.image_snapshot_ticks = train.network_snapshot_ticks = 10\n    sched.G_lrate_base = float(os.environ['G_LR']) if 'G_LR' in os.environ else 0.002\n    sched.D_lrate_base = float(os.environ['D_LR']) if 'D_LR' in os.environ else 0.002\n    sched.G_lrate_base *= float(os.environ['G_LR_MULT']) if 'G_LR_MULT' in os.environ else 1.0\n    sched.D_lrate_base *= float(os.environ['D_LR_MULT']) if 'D_LR_MULT' in os.environ else 1.0\n    G_opt.beta2 = float(os.environ['G_BETA2']) if 'G_BETA2' in os.environ else 0.99\n    D_opt.beta2 = float(os.environ['D_BETA2']) if 'D_BETA2' in os.environ else 0.99\n    print('G_lrate: %f' % sched.G_lrate_base)\n    print('D_lrate: %f' % sched.D_lrate_base)\n    print('G_beta2: %f' % G_opt.beta2)\n    print('D_beta2: %f' % D_opt.beta2)\n    sched.minibatch_size_base = int(os.environ['BATCH_SIZE']) if 'BATCH_SIZE' in os.environ else num_gpus\n    sched.minibatch_gpu_base = int(os.environ['BATCH_PER']) if 'BATCH_PER' in os.environ else 1\n    D_loss.gamma = 10\n    metrics = [metric_defaults[x] for x in metrics]\n    desc = 'stylegan2'\n\n    desc += '-' + dataset\n    resolution = int(os.environ['RESOLUTION']) if 'RESOLUTION' in os.environ else 64\n    dataset_args = EasyDict(tfrecord_dir=dataset, resolution=resolution)\n\n    assert num_gpus in [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192]\n    sc.num_gpus = num_gpus\n    desc += '-%dgpu' % num_gpus\n\n    assert config_id in _valid_configs\n    desc += '-' + config_id\n\n    # Configs A-E: Shrink networks to match original StyleGAN.\n    if config_id != 'config-f':\n        G.fmap_base = D.fmap_base = 8 << 10\n\n    if 'FMAP_BASE' in os.environ:\n      G.fmap_base = D.fmap_base = int(os.environ['FMAP_BASE']) << 10\n    else:\n      G.fmap_base = D.fmap_base = 16 << 10 # default\n\n    print('G_fmap_base: %d' % G.fmap_base)\n    print('D_fmap_base: %d' % D.fmap_base)\n\n    # Config E: Set gamma to 100 and override G & D architecture.\n    if config_id.startswith('config-e'):\n        D_loss.gamma = 100\n        if 'Gorig'   in config_id: G.architecture = 'orig'\n        if 'Gskip'   in config_id: G.architecture = 'skip' # (default)\n        if 'Gresnet' in config_id: G.architecture = 'resnet'\n        if 'Dorig'   in config_id: D.architecture = 'orig'\n        if 'Dskip'   in config_id: D.architecture = 'skip'\n        if 'Dresnet' in config_id: D.architecture = 'resnet' # (default)\n\n    # Configs A-D: Enable progressive growing and switch to networks that support it.\n    if config_id in ['config-a', 'config-b', 'config-c', 'config-d']:\n        sched.lod_initial_resolution = 8\n        sched.G_lrate_base = sched.D_lrate_base = 0.001\n        sched.G_lrate_dict = sched.D_lrate_dict = {128: 0.0015, 256: 0.002, 512: 0.003, 1024: 0.003}\n        sched.minibatch_size_base = 32 # (default)\n        sched.minibatch_size_dict = {8: 256, 16: 128, 32: 64, 64: 32}\n        sched.minibatch_gpu_base = 4 # (default)\n        sched.minibatch_gpu_dict = {8: 32, 16: 16, 32: 8, 64: 4}\n        G.synthesis_func = 'G_synthesis_stylegan_revised'\n        D.func_name = 'training.networks_stylegan2.D_stylegan'\n\n    # Configs A-C: Disable path length regularization.\n    if config_id in ['config-a', 'config-b', 'config-c']:\n        G_loss = EasyDict(func_name='training.loss.G_logistic_ns')\n\n    # Configs A-B: Disable lazy regularization.\n    if config_id in ['config-a', 'config-b']:\n        train.lazy_regularization = False\n\n    # Config A: Switch to original StyleGAN networks.\n    if config_id == 'config-a':\n        G = EasyDict(func_name='training.networks_stylegan.G_style')\n        D = EasyDict(func_name='training.networks_stylegan.D_basic')\n\n    if gamma is not None:\n        D_loss.gamma = gamma\n\n    sc.submit_target = dnnlib.SubmitTarget.LOCAL\n    sc.local.do_not_copy_source_files = True\n    kwargs = EasyDict(train)\n    kwargs.update(G_args=G, D_args=D, G_opt_args=G_opt, D_opt_args=D_opt, G_loss_args=G_loss, D_loss_args=D_loss)\n    kwargs.update(dataset_args=dataset_args, sched_args=sched, grid_args=grid, metric_arg_list=metrics, tf_config=tf_config)\n    kwargs.submit_config = copy.deepcopy(sc)\n    kwargs.submit_config.run_dir_root = result_dir\n    kwargs.submit_config.run_desc = desc\n    dnnlib.submit_run(**kwargs)\n\n#----------------------------------------------------------------------------\n\ndef _str_to_bool(v):\n    if isinstance(v, bool):\n        return v\n    if v.lower() in ('yes', 'true', 't', 'y', '1'):\n        return True\n    elif v.lower() in ('no', 'false', 'f', 'n', '0'):\n        return False\n    else:\n        raise argparse.ArgumentTypeError('Boolean value expected.')\n\ndef _parse_comma_sep(s):\n    if s is None or s.lower() == 'none' or s == '':\n        return []\n    return s.split(',')\n\n#----------------------------------------------------------------------------\n\n_examples = '''examples:\n\n  # Train StyleGAN2 using the FFHQ dataset\n  python %(prog)s --num-gpus=8 --data-dir=~/datasets --config=config-f --dataset=ffhq --mirror-augment=true\n\nvalid configs:\n\n  ''' + ', '.join(_valid_configs) + '''\n\nvalid metrics:\n\n  ''' + ', '.join(sorted([x for x in metric_defaults.keys()])) + '''\n\n'''\n\ndef main():\n    parser = argparse.ArgumentParser(\n        description='Train StyleGAN2.',\n        epilog=_examples,\n        formatter_class=argparse.RawDescriptionHelpFormatter\n    )\n    parser.add_argument('--result-dir', help='Root directory for run results (default: %(default)s)', default='results', metavar='DIR')\n    parser.add_argument('--data-dir', help='Dataset root directory', required=True)\n    parser.add_argument('--dataset', help='Training dataset', required=True)\n    parser.add_argument('--config', help='Training config (default: %(default)s)', default='config-f', required=True, dest='config_id', metavar='CONFIG')\n    parser.add_argument('--num-gpus', help='Number of GPUs (default: %(default)s)', default=1, type=int, metavar='N')\n    parser.add_argument('--total-kimg', help='Training length in thousands of images (default: %(default)s)', metavar='KIMG', default=25000, type=int)\n    parser.add_argument('--gamma', help='R1 regularization weight (default is config dependent)', default=None, type=float)\n    parser.add_argument('--mirror-augment', help='Mirror augment (default: %(default)s)', default=False, metavar='BOOL', type=_str_to_bool)\n    parser.add_argument('--metrics', help='Comma-separated list of metrics or \"none\" (default: %(default)s)', default='fid50k', type=_parse_comma_sep)\n\n    args = parser.parse_args()\n\n    if not gfile.IsDirectory(args.data_dir):\n        print ('Error: dataset root directory does not exist.')\n        sys.exit(1)\n\n    if args.config_id not in _valid_configs:\n        print ('Error: --config value must be one of: ', ', '.join(_valid_configs))\n        sys.exit(1)\n\n    for metric in args.metrics:\n        if metric not in metric_defaults:\n            print ('Error: unknown metric \\'%s\\'' % metric)\n            sys.exit(1)\n\n    run(**vars(args))\n\n#----------------------------------------------------------------------------\n\nif __name__ == \"__main__\":\n    main()\n\n#----------------------------------------------------------------------------\n\n"
  },
  {
    "path": "stylegan2-tpu/test_nvcc.cu",
    "content": "// Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\r\n//\r\n// This work is made available under the Nvidia Source Code License-NC.\r\n// To view a copy of this license, visit\r\n// https://nvlabs.github.io/stylegan2/license.html\r\n\r\n#include <cstdio>\r\n\r\nvoid checkCudaError(cudaError_t err)\r\n{\r\n    if (err != cudaSuccess)\r\n    {\r\n        printf(\"%s: %s\\n\", cudaGetErrorName(err), cudaGetErrorString(err));\r\n        exit(1);\r\n    }\r\n}\r\n\r\n__global__ void cudaKernel(void)\r\n{\r\n    printf(\"GPU says hello.\\n\");\r\n}\r\n\r\nint main(void)\r\n{\r\n    printf(\"CPU says hello.\\n\");\r\n    checkCudaError(cudaLaunchKernel((void*)cudaKernel, 1, 1, NULL, 0, NULL));\r\n    checkCudaError(cudaDeviceSynchronize());\r\n    return 0;\r\n}\r\n"
  },
  {
    "path": "stylegan2-tpu/tflex.py",
    "content": "import tensorflow as tf\nimport numpy as np\nfrom glob import glob\nimport os\nimport re\nfrom tensorflow.python import pywrap_tensorflow\nimport tqdm\nimport h5py\nimport shutil\nimport tempfile\nimport traceback\nimport time\nimport threading\n\nfrom tensorflow.python.framework import dtypes\nfrom tensorflow.python.distribute.cluster_resolver import TPUClusterResolver as BaseTPUClusterResolver\nfrom tensorflow.python.training import server_lib\nfrom tensorflow.core.protobuf import rewriter_config_pb2\nfrom tensorflow.contrib import tpu\n\nclass _DefaultState(threading.local):\n  def __init__(self, **kws):\n    super(_DefaultState, self).__init__()\n    for k, v in kws.items():\n      setattr(self, k, v)\n\n  def save(self):\n    return [(k, v) for k, v in self.__dict__.items()]\n\n  def restore(self, state):\n    for k, v in state:\n      setattr(self, k, v)\n\nlocal = _DefaultState()\nlock = threading.RLock()\n\ndef with_defaults(thunk):\n  with lock:\n    state = local.save()\n    session = tf.get_default_session() or get_default_session()\n    graph = tf.get_default_graph() or get_default_graph()\n  def f(*args, **kws):\n    with lock:\n      local.restore(state)\n    lock.acquire()\n    with session.as_default() if session else nullcontext():\n      with graph.as_default() if graph else nullcontext():\n        lock.release()\n        result = thunk(*args, **kws)\n        lock.acquire()\n    lock.release()\n    return result\n  return f\n\ndef get_default(name, required=True):\n  with lock:\n    value = getattr(local, name) if hasattr(local, name) else None\n  if required:\n    assert value is not None\n  return value\n\ndef set_default(name, value):\n  with lock:\n    setattr(local, name, value)\n\ndef ensure_default(name, value):\n  with lock:\n    current = get_default(name, required=False)\n    if current is None:\n      set_default(name, value)\n    return value\n\ndef get_default_session(required=False):\n  return get_default('session', required=required)\n\ndef get_default_graph(required=False):\n  return get_default('graph', required=required)\n\nclass Future(object):\n  def __init__(self, dependencies, thunk, *args, **kws):\n    if isinstance(dependencies, Future):\n      dependencies = [dependencies]\n    self.dependencies = [defer(_) if callable(_) else _ for _ in dependencies]\n    if thunk is None:\n      thunk = lambda: None\n    self.thunk = thunk\n    self.args = args\n    self.kws = kws\n    self.result = None\n    self.complete = False\n    self.thread = None\n    self.daemon = True\n    self.error = None\n  def run(self):\n    try:\n      self.result = self.thunk(*self.args, **self.kws)\n    except Exception as e:\n      traceback.print_exc()\n      self.error = e\n    self.complete = True\n  def run_async(self):\n    assert self.thread is None\n    def thunk():\n      [_.join() for _ in self.dependencies]\n      self.run()\n    self.thread = threading.Thread(target=with_defaults(thunk), daemon=self.daemon)\n    self.thread.start()\n  def join(self):\n    if not self.complete:\n      assert self.thread\n      while not self.complete:\n        time.sleep(1.0)\n    return self.result\n\ndef defer(thunk, *args, **kws):\n  dependencies = []\n  if 'dependencies' in kws:\n    dependencies = kws.pop('dependencies')\n  future = Future(dependencies=dependencies, thunk=thunk, *args, **kws)\n  future.run_async()\n  return future\n\ndef parallelize(xs, thunk, *args, daemon=True):\n  threads = []\n  for x in xs:\n    thread = threading.Thread(target=with_defaults(thunk), args=(x, *args), daemon=daemon)\n    thread.start()\n    threads.append(thread)\n  return threads\n\ndef parallelize_verbose(label, xs, thunk, *args, daemon=True):\n  xs = [x for x in xs]\n  with tqdm.tqdm(total=len(xs)) as pbar:\n    pbar.set_description(label)\n    def run(*args, **kws):\n      try:\n        return thunk(*args, **kws)\n      finally:\n        pbar.update(1)\n    return parallelize(xs, run, *args, daemon=daemon)\n\ndef parallelize_verbose(label, xs, thunk, *args, daemon=True, synchronous=False):\n  xs = [x for x in xs]\n  if synchronous:\n    for i in tqdm.trange(len(xs), desc=label):\n      x = xs[i]\n      thunk(x, *args)\n  else:\n    with tqdm.tqdm(total=len(xs)) as pbar:\n      pbar.set_description(label)\n      threads = parallelize(xs, thunk, *args, daemon=daemon)\n      while len(threads) > 0:\n        for i in range(len(threads)):\n          if not threads[i].is_alive():\n            pbar.update(1)\n            threads.remove(threads[i])\n            break\n        time.sleep(0.1)\n\n# http://stackoverflow.com/questions/1624883/alternative-way-to-split-a-list-into-groups-of-n\nimport itertools\ndef group(n, iterable, fillvalue=None):\n    \"group(3, 'ABCDEFG', 'x') --> ABC DEF Gxx\"\n    args = [iter(iterable)] * n\n    return itertools.zip_longest(*args, fillvalue=fillvalue)\n\ndef tuples(*args, **kws):\n  return [x for x in group(*args, **kws)]\n\nclass Namespace(object):\n  pass\n\nif 'state' not in globals():\n  state = Namespace()\n\nif not hasattr(state, 'noisy'):\n  state.noisy = 'NOISY' in os.environ\n\nif not hasattr(state, 'debug'):\n  state.debug = 'DEBUG' in os.environ\n\nif not hasattr(state, 'noisy_backtrace'):\n  state.noisy_backtrace = 'NOISY_BACKTRACE' in os.environ\n\nif not hasattr(state, 'break_next_run'):\n  state.break_next_run = False\n\ndef reroute(addr, host=None):\n  if host is None or host is False:\n    return addr\n  if addr.startswith('grpc://'):\n    return 'grpc://' + reroute(addr[len('grpc://'):], host=host)\n  if not re.match('[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+[:]8470', addr):\n    return addr\n  if not addr.endswith(':8470'):\n    return addr\n  a, b, c, d = [int(x) for x in addr.split(':')[0].split('.')]\n  if a == 10 and b in [48, 49]:\n    assert (d == 2)\n    port = b * 1000 + c\n  elif a == 10 and b in range(2, 66) and c == 0:\n    port = b * 1000 + d\n  else:\n    return addr\n  return host + ':' + str(port)\n\n\nclass TPUClusterResolver(BaseTPUClusterResolver):\n  def __init__(self, *args, host=None, **kws):\n    super(TPUClusterResolver, self).__init__(*args, **kws)\n    if host is None:\n      if 'TPU_HOST' in os.environ:\n        host = os.environ['TPU_HOST']\n    self._host = host\n\n  def master(self, *args, **kws):\n    ip = super(TPUClusterResolver, self).master(*args, **kws)\n    return reroute(ip, host=self._host)\n\n  def cluster_spec(self):\n    spec = super(TPUClusterResolver, self).cluster_spec()\n    r = dict()\n    for k, v in spec.as_dict().items():\n      r[k] = [reroute(ip, host=self._host) for ip in v]\n    return server_lib.ClusterSpec(r)\n\ndef init_tpu(name, host=None, timeout_in_ms=600 * 60 * 1000):\n  tpu_init = [tpu.initialize_system()]\n  cluster_resolver = TPUClusterResolver(name, host=host)\n  config = tf.ConfigProto(operation_timeout_in_ms=timeout_in_ms,\n                          graph_options=tf.GraphOptions(\n                            rewrite_options=rewriter_config_pb2.RewriterConfig(\n                              disable_meta_optimizer=True)),\n                          isolate_session_state=True)\n  cluster_spec = cluster_resolver.cluster_spec()\n  if cluster_spec:\n    config.cluster_def.CopyFrom(cluster_spec.as_cluster_def())\n  init_sess = tf.Session(cluster_resolver.get_master(), config=config)\n  init_sess.run(tpu_init)\n  return init_sess, cluster_resolver\n\ndef get_session(session=None):\n  if session is None:\n    session = get_default_session()\n  return session\n\ndef get_devices(session=None):\n  session = get_session(session)\n  if hasattr(session, '_cached_devices'):\n    devices = session._cached_devices\n  else:\n    devices = session._cached_devices = session.list_devices()\n  return devices\n\ndef has_gpu(session=None):\n  session = get_session(session)\n  if hasattr(session, '_has_gpu'):\n    result = session._has_gpu\n  else:\n    devices = get_devices(session=session)\n    result = session._has_gpu = len([x for x in devices if ':GPU:' in x.name]) > 0\n  return result\n\ndef has_tpu(session=None):\n  session = get_session(session)\n  if hasattr(session, '_has_tpu'):\n    result = session._has_tpu\n  else:\n    devices = get_devices(session=session)\n    result = session._has_tpu = len([x for x in devices if ':TPU:' in x.name]) > 0\n  return result\n\ndef get_cores_from_devices(devices):\n  cores = [x for x in devices if ':TPU:' in x.name]\n  if len(cores) <= 0:\n    cores = [x for x in devices if ':GPU:' in x.name]\n  if len(cores) <= 0:\n    cores = [x for x in devices if ':CPU:' in x.name]\n  return cores\n\ndef get_cores(session=None, devices=None):\n  if devices is None:\n    devices = get_devices(session=session)\n  return get_cores_from_devices(devices)\n\ndef get_cpus(session=None, devices=None):\n  if devices is None:\n    devices = get_devices(session=session)\n  cpus = [x for x in devices if ':CPU:' in x.name]\n  return cpus\n\ndef get_tpu_resolver(tpu_name='auto'):\n  # Get the TPU's location\n  if tpu_name != 'auto':\n    return TPUClusterResolver(tpu_name)\n  elif 'COLAB_TPU_ADDR' in os.environ:\n    return TPUClusterResolver()\n  elif 'TPU_NAME' in os.environ:\n    return TPUClusterResolver(os.environ['TPU_NAME'])\n\ndef pretty(x, ellipsize=120):\n  r = str(x)\n  if len(r) > ellipsize:\n    return r[0:ellipsize - 3] + '...'\n  return r\n\ndef print_backtrace():\n  try:\n    raise Exception(\"Printing traceback...\")\n  except:\n    import traceback\n    traceback.print_exc()\n\nclass Session(tf.Session):\n  def __init__(self, target='auto', graph=None, config=None, init_tpu=False, id=None):\n    if config is None:\n      timeout_in_ms = int(os.environ['TIMEOUT_IN_MS']) if 'TIMEOUT_IN_MS' in os.environ else 10 * 60 * 1000\n      config = tf.ConfigProto(operation_timeout_in_ms=timeout_in_ms,\n                              graph_options=tf.GraphOptions(\n                                rewrite_options=rewriter_config_pb2.RewriterConfig(\n                                  disable_meta_optimizer=True)),\n                              isolate_session_state=True)\n    config.isolate_session_state = True\n    resolver = get_tpu_resolver(target)\n    if resolver is not None:\n      target = resolver.get_master()\n      cluster_spec = resolver.cluster_spec()\n      if cluster_spec:\n        config.cluster_def.CopyFrom(cluster_spec.as_cluster_def())\n    elif target == 'auto':\n      target = None\n    super().__init__(target, graph=graph, config=config)\n    self.id = id\n    self._tflex_resolver = resolver\n    self._tflex_target = target\n    self._tflex_config = config\n    ensure_default('session', self)\n    ensure_default('devices', self.list_devices())\n    ensure_default('graph', self.graph)\n\n  @property\n  def _spec(self):\n    return '#%d' % self.id if self.id is not None else ''\n\n  def ensure(self):\n    if self.init_tpu:\n      print(self._spec, \"Initializing TPU...\")\n      #sess.run(tpu.initialize_system())\n      init_tpu(session=self, timeout_in_ms=20000)\n      self.init_tpu = None\n\n  def run(self, *args, **kws):\n    if state.break_next_run:\n      import pdb; pdb.set_trace()\n    if state.debug:\n      check_commands()\n    if state.noisy:\n      print(self._spec, 'Session.run', *[pretty(x) for x in args], *[pretty(k)+'='+pretty(v) for k, v in kws.items()])\n      if state.noisy_backtrace:\n        print_backtrace()\n    start = time.time()\n    result = super(Session, self).run(*args, **kws)\n    elapsed = time.time() - start\n    if state.noisy:\n      print(self._spec, 'Session.run (finished in %.2fs)' % elapsed, pretty(result), *[pretty(x) for x in args], *[pretty(k)+'='+pretty(v) for k, v in kws.items()])\n      if state.noisy_backtrace:\n        print_backtrace()\n    return result\n\n\ndef split_by_params(vs, n=20e6, f=None):\n  if f is None:\n    f = lambda x: np.prod(x.shape.as_list())\n  i = 0\n  xs = []\n  for variable in vs:\n    xs.append(variable)\n    count = f(variable)\n    i += count\n    if i >= n:\n      yield xs\n      xs = []\n      i = 0\n  yield xs\n\ndef latest_checkpoint(checkpoint_dir, latest_filename=None):\n  paths = [x for x in glob(os.path.join(checkpoint_dir, 'model-*.*')) if not x.endswith(\".tmp\")]\n  ctrs = np.array([[int(y) for y in re.findall(r'model-([0-9]+)(?:-[0-9]+)?[.](?:npy|hdf5)', x)] for x in paths]).flatten()\n  if len(ctrs) <= 0:\n    ckpt = tf.train.latest_checkpoint(checkpoint_dir, latest_filename=latest_filename)\n    return ckpt\n  ctr = ctrs.max()\n  return os.path.join(checkpoint_dir, 'model-{}').format(ctr)\n\ndef truncate_value(variable, value, reshape=True):\n  if not reshape:\n    return value\n  shape = variable.shape.as_list()\n  params = np.prod(shape)\n  params2 = np.prod(value.shape)\n  if params == params2:\n    return value\n  print('Truncating {} from shape {} to shape {}'.format(variable.name, value.shape, shape))\n  value = np.array(value)\n  value = value.reshape([-1])\n  value = value[0:params]\n  value = value.reshape(shape)\n  return value\n\nfrom tensorflow.core.protobuf import config_pb2\n\ndef initialize_tpu(session=None, timeout_in_ms=None):\n  session = session or get_default_session()\n  with session.as_default():\n    op = tpu.initialize_system()\n  options = None\n  if timeout_in_ms:\n    options=config_pb2.RunOptions(timeout_in_ms=timeout_in_ms)\n  return session.run(op, options=options)\n\ndef load(variable, value, session=None, timeout_in_ms=None):\n  session = session or get_default_session()\n  ops = variable.initializer\n  vals = dict([(variable.initializer.inputs[1], value)])\n  #for x, (k, v) in zip(variables, vals.items()):\n  #  print(x.name, x.shape.as_list(), k, v.shape)\n  options = None\n  if timeout_in_ms:\n    options=config_pb2.RunOptions(timeout_in_ms=timeout_in_ms)\n  return session.run(ops, vals, options=options)\n\ndef eval(variable, session=None, timeout_in_ms=None):\n  session = session or get_default_session()\n  options = None\n  if timeout_in_ms:\n    options=config_pb2.RunOptions(timeout_in_ms=timeout_in_ms)\n  return session.run(variable, options=options)\n\ndef grab_values(variables, reader, reshape=False):\n  for variable in variables:\n    name = variable_name(variable).split(':')[0]\n    value = reader.get_tensor(name)\n    value = truncate_value(variable, value, reshape=reshape)\n    yield variable, value\n\ndef assign_values(variables, values, session=None, timeout_in_ms=60000):\n  session = session or get_default_session()\n  variables = [x for x in variables]\n  values = [x for x in values]\n  ops = [x.initializer for x in variables]\n  vals = dict([(x.initializer.inputs[1], value.value() if isinstance(value, tf.Variable) else value) for x, value in zip(variables, values)]) # TODO: bfloat16 support\n  #for x, (k, v) in zip(variables, vals.items()):\n  #  print(x.name, x.shape.as_list(), k, v.shape)\n  options = None\n  if timeout_in_ms:\n    options=config_pb2.RunOptions(timeout_in_ms=timeout_in_ms)\n  session.run(ops, vals, options=options)\n\ndef load_snapshot(ckpt, session=None, var_list=None, reshape=False):\n  session = session or get_default_session()\n  reader = pywrap_tensorflow.NewCheckpointReader(ckpt)\n  vs = var_list or tf.trainable_variables()\n  for variables in tqdm.tqdm(list(split_by_params(vs))):\n    values = [value for variable, value in grab_values(variables, reader, reshape=reshape)]\n    assign_values(variables, values, session=session)\n\ndef get_variable(name, var_list=None):\n  name, num = name.split(':') if ':' in name else (name, '0')\n  num = int(num)\n  name = os.path.join(tf.get_variable_scope().name, name)\n  vs = var_list or tf.trainable_variables()\n  for x in vs:\n      if x.name.startswith(name + ':%d' % num):\n          return x\n\ndef load_weights(ckpt, session=None, var_list=None, reshape=False):\n  session = session or get_default_session()\n  vs = var_list or tf.trainable_variables()\n  files = list(sorted(glob(ckpt + '-*.npy')))\n  for out in tqdm.tqdm(files):\n    for name, value in np.load(out, allow_pickle=True):\n      variable = get_variable(name)\n      if variable is None:\n        print('Warning: variable %s not loaded' % name)\n      else:\n        value = truncate_value(variable, value, reshape=reshape)\n        variable.load(value, session)\n\ndef load_variables(ckpt, session=None, var_list=None, reshape=False):\n  session = session or get_default_session()\n  vs = var_list or tf.trainable_variables()\n  with h5py.File(ckpt, \"r\") as f:\n    for variables in tqdm.tqdm(list(split_by_params(vs))):\n      values = [truncate_value(x, f[variable_name(x)], reshape=reshape)  for x in variables]\n      assign_values(variables, values, session=session)\n\ndef maketree(path):\n    try:\n        os.makedirs(path)\n    except:\n        pass\n\nstate.cache_ops = {}\n\ndef cast_variables(variables, graph=None, cache_ops=None):\n  if graph is None:\n    graph = get_default_graph()\n  if cache_ops is None:\n    cache_ops = state.cache_ops\n  if graph not in cache_ops:\n    cache_ops[graph] = {}\n  cache = cache_ops[graph]\n  ops = []\n  for variable in variables:\n    if variable in cache:\n      op = cache[variable]\n    elif variable.dtype == dtypes.bfloat16_ref or variable.dtype == tf.bfloat16:\n      op = tf.cast(variable, tf.float32)\n    else:\n      op = variable\n    cache[variable] = op\n    ops.append(op)\n  return ops\n\nimport re\n\ndef variable_name(variable):\n  if re.match(r'core[0-9]+/', variable.name):\n    return variable.name.split('/', 1)[-1]\n  return variable.name\n\ndef save_variables(ckpt, session=None, var_list=None):\n    session = session or get_default_session()\n    vs = var_list or tf.trainable_variables()\n    maketree(os.path.dirname(ckpt))\n    fname = ckpt+'.tmp'\n    with h5py.File(fname, \"w\") as f:\n      for variables in tqdm.tqdm(list(split_by_params(vs))):\n        ops = cast_variables(variables)\n        values = session.run(ops)\n        for value, variable in zip(values, variables):\n          name = variable_name(variable)\n          shape = variable.shape.as_list()\n          dtype = variable.dtype\n          dset = f.create_dataset(name, shape, dtype=np.float32)\n          dset[:] = value\n    print('Writing snapshot %s' % ckpt)\n    os.rename(ckpt+'.tmp', ckpt)\n\ndef fetch_variables(session=None, var_list=None):\n    session = session or get_default_session()\n    vs = var_list or tf.trainable_variables()\n    for variables in tqdm.tqdm(list(split_by_params(vs))):\n      values = session.run(variables)\n      yield variables, values\n\ndef partition_variables(session=None, var_list=None):\n    session = session or get_default_session()\n    vs = var_list or tf.trainable_variables()\n    for variables in tqdm.tqdm(list(split_by_params(vs))):\n      yield variables\n\nclass Saver(object):\n  def __init__(\n    self,\n    var_list=None,\n    reshape=False,\n    sharded=False,\n    max_to_keep=5,\n    keep_checkpoint_every_n_hours=10000.0,\n    name=None,\n    restore_sequentially=False,\n    saver_def=None,\n    builder=None,\n    defer_build=False,\n    allow_empty=False,\n    write_version=tf.train.SaverDef.V2,\n    pad_step_number=False,\n    save_relative_paths=False,\n    filename=None):\n    self.var_list = var_list\n    self.reshape = reshape\n    self.sharded = sharded\n    self.max_to_keep = max_to_keep\n    self.keep_checkpoint_every_n_hours = keep_checkpoint_every_n_hours\n    self.name = name\n    self.restore_sequentially = restore_sequentially\n    self.saver_def = saver_def\n    self.builder = builder\n    self.defer_build = defer_build\n    self.allow_empty = allow_empty\n    self.write_version = write_version\n    self.pad_step_number = pad_step_number\n    self.save_relative_paths = save_relative_paths\n    self.filename = filename\n    self.checkpoints = []\n\n  def restore(self, sess, save_path):\n    if save_path.endswith('.ckpt'):\n      load_snapshot(save_path, session=sess, var_list=self.var_list, reshape=self.reshape)\n    elif save_path.endswith('.hdf5'):\n      load_variables(save_path, session=sess, var_list=self.var_list, reshape=self.reshape)\n    elif os.path.exists(save_path + '.npy') or os.path.exists(save_path + '-0.npy'):\n      load_weights(save_path, session=sess, var_list=self.var_list, reshape=self.reshape)\n    elif os.path.exists(save_path + '.hdf5'):\n      load_variables(save_path + '.hdf5', session=sess, var_list=self.var_list, reshape=self.reshape)\n    else:\n      raise Exception(\"Can't load checkpoint %s\" % save_path)\n\n  def save(self,\n        sess,\n        save_path,\n        global_step=None,\n        latest_filename=None,\n        meta_graph_suffix=\"meta\",\n        write_meta_graph=True,\n        write_state=True,\n        strip_default_attrs=False,\n        save_debug_info=False):\n    if global_step is not None:\n      name = '%s-%d.hdf5' % (save_path, global_step)\n    else:\n      name = '%s.hdf5' % save_path\n    save_variables(name, session=sess, var_list=self.var_list)\n    self.checkpoints.append(name)\n    if self.max_to_keep > 0:\n      while len(self.checkpoints) > self.max_to_keep:\n        fname = self.checkpoints[0]\n        if fname != name:\n          print('Truncating %s' % fname)\n          try:\n            with open(fname, \"wb\") as f:\n              pass\n          except:\n            print('Failed to truncate %s' % fname)\n        self.checkpoints = self.checkpoints[1:]\n\n  def fetch(self, sess, var_list=None):\n    if var_list == None:\n      var_list = self.var_list\n    for variables, values in fetch_variables(session=sess, var_list=var_list):\n      yield variables, values\n\n  def variables(self, sess, var_list=None):\n    if var_list == None:\n      var_list = self.var_list\n    for variables in partition_variables(session=sess, var_list=var_list):\n      yield variables\n\n  def assign(self, sess, variables, values):\n    return assign_values(variables, values, session=sess)\n\nclass Commands(object):\n  def __init__(self, path='commands'):\n    self.path = path\n    self.commands = []\n    self.args = []\n    self.keys = {}\n    self.frozen = False\n\n  def has(self, name, **keys):\n    if 'action' in keys:\n      action = keys.pop('action')\n      for name1, action1 in self.commands:\n        if name == name1 and action1 == action:\n          return True\n    else:\n      for name1, action1 in self.commands:\n        if name == name1:\n          return True\n    return False\n\n  def add(self, name, action=None):\n    if not self.has(name=name, action=action):\n      self.commands.append((name, action))\n      full = self.full_path(name)\n      maketree(full)\n\n  def full_path(self, name):\n    return os.path.join(self.path, name)\n\n  def check(self, *args, **keys):\n    if not self.frozen:\n      heartbeat()\n    ops = []\n    seen = set()\n    for name, action in self.commands:\n      full = self.full_path(name)\n      if not os.path.isdir(full):\n        if name not in seen:\n          seen.add(name)\n          ops.append(name)\n    for op in ops:\n      self.run(op, *args, **keys)\n    return ops\n\n  def run(self, op):\n    ran = False\n    for name, action in self.commands:\n      if name == op:\n        print('Running command', name, action)\n        if not ran:\n          full = self.full_path(op)\n          maketree(full)\n          ran = True\n        if action:\n          action()\n    if not ran:\n      raise Exception('Commands.execute failed: no such command: {}'.format(op))\n  \n  def run_with_args(self, op, *args, **keys):\n    with CommandArgs(*args, **keys):\n      return self.run(op)\n\ncommander = None\n\ndef commands(**keys):\n  global commander\n  if commander is None:\n    commander = Commands()\n  cmds = keys.pop('commands') if 'commands' in keys else None\n  if cmds is not None:\n    for cmd in cmds:\n      action = None\n      if isinstance(cmd, str):\n        name = cmd\n      elif len(cmd) >= 2:\n        name, action = cmd\n      elif len(cmd) >= 1:\n        name = cmd[0]\n      else:\n        continue\n      commander.add(name=name, action=action)\n  return commander\n\nclass CommandArgs(object):\n  def __init__(self, *args, **keys):\n    self.args = list(args)\n    self.keys = keys.copy()\n    self.cmdr = commands()\n\n  def __enter__(self):\n    self.args_prev = self.cmdr.args\n    self.keys_prev = self.cmdr.keys\n    self.cmdr.args = self.args\n    self.cmdr.keys = self.keys\n\n  def __exit__(self, *excinfo):\n    self.cmdr.args = self.args_prev\n    self.cmdr.keys = self.keys_prev\n\ndef check_commands():\n  try:\n    cmdr = commands()\n    return cmdr.check()\n  except:\n    traceback.print_exc()\n\ndef check_commands_with_args(*args, **keys):\n  try:\n    cmdr = commands()\n    with CommandArgs(*args, **keys):\n      return cmdr.check()\n  except:\n    traceback.print_exc()\n\ndef add_command(name, action=None, **keys):\n  cmdr = commands()\n  return cmdr.add(name=name, action=action)\n\ndef register_command(*args, **keys):\n  fn = args[0]\n  if isinstance(fn, str):\n    add_command(fn)\n  else:\n    name = fn.__qualname__\n    name = name.replace('.<locals>.', '_command_')\n    if name.endswith('_command_save'):\n      name = 'save'\n    name = name.replace('___', '/')\n    action = fn\n    print(name, action)\n    add_command(name, action)\n  return fn\n\ndef has_command(name):\n  cmdr = commands()\n  return cmdr.has(name)\n\ndef run_command(command_name):\n  cmdr = commands()\n  return cmdr.run(command_name)\n\ndef run_command_with_args(command_name, *args, **keys):\n  cmdr = commands()\n  return cmdr.run_with_args(command_name, *args, **keys)\n\ndef command_arg(x, unset=None):\n  cmdr = commands()\n  if isinstance(x, int):\n    try:\n      return cmdr.args[x]\n    except:\n      return unset\n  else:\n    if x in cmdr.keys:\n      return cmdr.keys[x]\n    return unset\n\ndef command_args():\n  cmdr = commands()\n  return cmdr.args, cmdr.keys\n\n@register_command\ndef attach_debugger():\n  import pdb\n  pdb.set_trace()\n\nfrom pprint import pprint\n\n@register_command\ndef print_status():\n  args, props = command_args()\n  for k, v in enumerate(args):\n    pprint(v)\n  for k, v in props.items():\n    pprint({k: v})\n\n\n#\n# return current UTC timestamp.\n#\ndef utc():\n    from datetime import datetime\n    d = datetime.utcnow()\n    import calendar\n    return calendar.timegm(d.utctimetuple())\n\ndef heartbeat():\n  pongfile=os.environ['PONG'] if 'PONG' in os.environ else 'pong.txt'\n  with open(pongfile, \"a+\") as f:\n    nonce = os.urandom(8).hex()\n    now=utc()\n    out=\"pid{}_time{}_nonce{}\\n\".format(os.getpid(), now, nonce)\n    #print(\"PONG! Writing {} to {}\".format(out, pongfile))\n    f.write(out)\n    f.flush()\n\nimport time\n\n@register_command\ndef freeze_forever():\n  cmdr = commands()\n  if cmdr.frozen:\n    print(\"Already frozen.\")\n    return\n  prev = cmdr.frozen\n  cmdr.frozen = True\n  print('Simulating a freeze; going into an infinite loop:')\n  prev=time.time()\n  try:\n    while not should_quit():\n      elapsed=time.time() - prev\n      print('Frozen for {}s'.format(elapsed))\n      time.sleep(1)\n      check_commands()\n  finally:\n    cmdr.frozen = prev\n\n_quit = False\n\nimport sys\n\n@register_command\ndef quit():\n  global _quit\n  if _quit:\n    print(\"Failed to quit; running sys.exit(1)\")\n    sys.exit(1)\n  else:\n    print(\"Quitting...\")\n    _quit = True\n\ndef should_quit():\n  return _quit\n\n@register_command\ndef save_and_quit():\n  global _quit\n  if has_command('save'):\n    print(\"Saving...\")\n    run_command('save')\n  quit()\n\n@register_command\ndef throw_exception():\n  raise Exception(\"This exception should be caught and logged by the tflex command system\")\n\n\nimport tensorflow as tf\nfrom contextlib import contextmanager\n\n@contextmanager\ndef nullcontext(enter_result=None):\n    yield enter_result\n\ndef set_override_device(value, session=None):\n  session = get_session(session)\n  session._override_device = value\n  return value\n\ndef has_override_device(session=None):\n  session = get_session(session)\n  return hasattr(session, '_override_device')\n\ndef get_override_device(session=None):\n  session = get_session(session)\n  if hasattr(session, '_override_device'):\n    return session._override_device\n\ndef set_override_cores(value, session=None):\n  session = get_session(session)\n  session._override_cores = value\n  return value\n\ndef has_override_cores(session=None):\n  session = get_session(session)\n  return hasattr(session, '_override_cores')\n\ndef get_override_cores(session=None):\n  session = get_session(session)\n  if hasattr(session, '_override_cores'):\n    return session._override_cores\n\ndef device_for_tpu_core(task=0, core=0, job_name=\"tpu_worker\"):\n  return \"/job:%s/task:%d/device:TPU_REPLICATED_CORE:%d\" % (job_name, task, core)\n\ndef device(name=''):\n  if has_override_device():\n    return nullcontext()\n  if has_override_cores():\n    if name is None:\n      return tf.device(name)\n    if name.startswith('/gpu:'):\n      i = int(name.split(':', 1)[-1])\n      return tf.device(get_cores()[i].name)\n    if name.startswith('/tpu:'):\n      i = int(name.split(':', 1)[-1])\n      return tf.device(device_for_tpu_core(core=i))\n    if name.startswith('/cpu:'):\n      i = int(name.split(':', 1)[-1])\n      return tf.device(get_cpus()[i].name)\n    return nullcontext()\n  if name is None:\n    return tf.device(None)\n  if 'gpu' in name:\n    if has_gpu():\n      return tf.device(name)\n  if 'cpu' in name:\n    return tf.device(name)\n  return nullcontext()\n\ndef tuples(l, n=2):\n  r = []\n  for i in range(0, len(l), n):\n    r.append(l[i:i+n])\n  return r\n\nimport hashlib\n\ndef sha256hex(x):\n  if isinstance(x, str):\n    x = x.encode('utf8')\n  return hashlib.sha224(x).hexdigest()\n\ndef sha256label(x):\n  return [int(x, 16) / 255 * 2 - 1 for x in tuples(sha256hex(x))]\n\n"
  },
  {
    "path": "stylegan2-tpu/tflex_test.py",
    "content": "import sys\nimport tflex\nimport time\n\ndef make_future(label, delay=0.0, deps=[], thunk=None, args=[]):\n  def toplevel():\n    if delay is not None and delay > 0.0:\n      time.sleep(delay)\n    nonlocal thunk, args\n    if callable(thunk):\n      thunk(*args)\n    nonlocal label\n    if callable(label):\n      label = label()\n    print('Future {}'.format(label))\n  return tflex.defer(thunk=toplevel, dependencies=deps)\n\ndef warmup():\n  make_future('warmup', 0.0).join()\n\ndef test1():\n  a = make_future('A', 0.1)\n  b = make_future('B', 0.0, deps=[a])\n  c = make_future('C', 0.0, deps=[a, b])\n  make_future('done', 0.0, deps=[a, b, c]).join()\n\ndef test2():\n  a = make_future('A', 0.1)\n  b = make_future('B', 0.0)\n  c = make_future('C', 0.2)\n  make_future('done', 0.0, deps=[a, b, c]).join()\n\ndef test3():\n  tflex.local.foo = 'foo'\n  make_future(lambda: tflex.local.foo).join()\n\ndef test4():\n  tflex.local.foo = 'foo'\n  def bar():\n    tflex.local.foo = 'bar'\n  make_future(lambda: tflex.local.foo, thunk=bar).join()\n  make_future(lambda: tflex.local.foo).join()\n\ndef test5():\n  tflex.local.foo = 'foo'\n  def baz():\n    tflex.local.foo = 'baz'\n  def bar():\n    make_future(lambda: tflex.local.foo, thunk=baz).join()\n    tflex.local.foo = 'bar'\n  make_future(lambda: tflex.local.foo, thunk=bar).join()\n  make_future(lambda: tflex.local.foo).join()\n\ndef run_test(name, thunk, *args, **kws):\n  print('Running {}'.format(name))\n  sys.stdout.flush()\n  start_time = time.time()\n  result = thunk(*args, **kws)\n  end_time = time.time()\n  print('Finished {} in {:.2f}'.format(name, end_time - start_time))\n  print('--------------------')\n\ndef run_tests():\n  run_test('warmup', warmup)\n  run_test('test1', test1)\n  run_test('test2', test2)\n  run_test('test3', test3)\n  run_test('test4', test4)\n  run_test('test5', test5)\n\nif __name__ == '__main__':\n  run_tests()\n\n"
  },
  {
    "path": "stylegan2-tpu/train_tpu.sh",
    "content": "#!/bin/bash\nsource \"$HOME/bin/activate-tf1\"\n\nset -e\n\nexport NOISY=1\nexport DEBUG=1\n\nexport TPU_NAME=grpc://0.tcp.ngrok.io:12547\ncores=8\n\n#config=\"config-a\" # StyleGAN 1\nconfig=\"config-f\" # StyleGAN 2\n\ndata_dir=gs://sgappa-multi/stylegan-encoder/datasets\ndataset=animefaces\nmirror=false\nmetrics=none\n\nexport LABEL_SIZE=0\n#export LABEL_SIZE=full # uncomment this if using labels\nexport MODEL_DIR=gs://danbooru-euw4a/test/run50-danbooru-512-conditional-subset-128\nexport BATCH_PER=4\nexport BATCH_SIZE=$(($BATCH_PER * $cores))\nexport RESOLUTION=512\n\nset -x\nexec python3 -m pdb -c continue run_training.py --data-dir \"${data_dir}\" --config=\"${config}\" --dataset=\"${dataset}\" --mirror-augment=\"${mirror}\" --metrics=\"${metrics}\" \"$@\"\n"
  },
  {
    "path": "stylegan2-tpu/training/__init__.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n# empty\n"
  },
  {
    "path": "stylegan2-tpu/training/dataset.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Multi-resolution input data pipeline.\"\"\"\n\nimport os\nimport re\nimport numpy as np\nimport tensorflow as tf\nimport tflex\nimport dnnlib\nimport dnnlib.tflib as tflib\n\nfrom tensorflow.python.platform import gfile\nfrom tensorflow.python.framework import errors_impl\n\n#----------------------------------------------------------------------------\n# Dataset class that loads data from tfrecords files.\n\nclass TFRecordDataset:\n    def __init__(self,\n        tfrecord_dir,               # Directory containing a collection of tfrecords files.\n        resolution      = None,     # Dataset resolution, None = autodetect.\n        label_file      = None,     # Relative path of the labels file, None = autodetect.\n        max_label_size  = None,     # 0 = no labels, 'full' = full labels, <int> = N first label components.\n        max_images      = None,     # Maximum number of images to use, None = use all images.\n        repeat          = True,     # Repeat dataset indefinitely?\n        shuffle_mb      = 4096,     # Shuffle data within specified window (megabytes), 0 = disable shuffling.\n        prefetch_mb     = 2048,     # Amount of data to prefetch (megabytes), 0 = disable prefetching.\n        buffer_mb       = 256,      # Read buffer size (megabytes).\n        batch_size      = None,     # Fixed batch size\n        num_threads     = 2):       # Number of concurrent threads.\n\n        if max_label_size is None:\n          if 'LABEL_SIZE' not in os.environ:\n            max_label_size = 0\n          else:\n            try:\n              max_label_size = int(os.environ['LABEL_SIZE'])\n            except:\n              max_label_size = os.environ['LABEL_SIZE']\n        assert max_label_size == 'full' or isinstance(max_label_size, int) and max_label_size >= 0\n\n        self.tfrecord_dir       = tfrecord_dir\n        self.resolution         = None\n        self.resolution_log2    = None\n        self.shape              = []        # [channels, height, width]\n        self.dtype              = 'uint8'\n        self.dynamic_range      = [0, 255]\n        self.label_file         = label_file\n        self.label_size         = None      # components\n        self.label_dtype        = None\n        self._np_labels         = None\n        self._tf_minibatch_in   = None\n        self._tf_labels_var     = None\n        self._tf_labels_dataset = None\n        self._tf_datasets       = dict()\n        self._tf_iterator       = None\n        self._tf_init_ops       = dict()\n        self._tf_minibatch_np   = None\n        self._cur_minibatch     = -1\n        self._cur_lod           = -1\n\n        # List tfrecords files and inspect their shapes.\n        assert gfile.IsDirectory(self.tfrecord_dir)\n        tfr_files = sorted(tf.io.gfile.glob(os.path.join(self.tfrecord_dir, '*.tfrecords')))\n        assert len(tfr_files) >= 1\n\n        # To avoid parsing the entire dataset looking for the max\n        # resolution, just assume that we can extract the LOD level\n        # from the tfrecords file name.\n        tfr_shapes = []\n        lod = -1\n        for tfr_file in tfr_files:\n          match = re.match('.*?([0-9]+).tfrecords', tfr_file)\n          if match:\n            level = int(match.group(1))\n            res = 2**level\n            tfr_shapes.append((3, res, res))\n\n        # Autodetect label filename.\n        if self.label_file is None:\n            guess = sorted(tf.io.gfile.glob(os.path.join(self.tfrecord_dir, '*.labels')))\n            if len(guess):\n                self.label_file = guess[0]\n        elif not tf.io.gfile.exists(self.label_file):\n            guess = os.path.join(self.tfrecord_dir, self.label_file)\n            if tf.io.gfile.exists(guess):\n                self.label_file = guess\n\n        # Determine shape and resolution.\n        max_shape = max(tfr_shapes, key=np.prod)\n        self.resolution = resolution if resolution is not None else max_shape[1]\n        self.resolution_log2 = int(np.log2(self.resolution))\n        self.shape = [max_shape[0], self.resolution, self.resolution]\n        tfr_lods = [self.resolution_log2 - int(np.log2(shape[1])) for shape in tfr_shapes]\n        assert all(shape[0] == max_shape[0] for shape in tfr_shapes)\n        assert all(shape[1] == shape[2] for shape in tfr_shapes)\n        assert all(shape[1] == self.resolution // (2**lod) for shape, lod in zip(tfr_shapes, tfr_lods))\n        assert all(lod in tfr_lods for lod in range(self.resolution_log2 - 1))\n\n        # Load labels.\n        assert max_label_size == 'full' or max_label_size >= 0\n        self._np_labels = np.zeros([1<<16, 0], dtype=np.float32)\n        if self.label_file is not None and max_label_size != 0:\n            with gfile.GFile(self.label_file, 'rb') as f:\n              self._np_labels = np.load(f)\n            assert self._np_labels.ndim == 2\n        if max_label_size != 'full' and self._np_labels.shape[1] > max_label_size:\n            self._np_labels = self._np_labels[:, :max_label_size]\n        if max_images is not None and self._np_labels.shape[0] > max_images:\n            self._np_labels = self._np_labels[:max_images]\n        self.label_size = self._np_labels.shape[1]\n        self.label_dtype = self._np_labels.dtype.name\n        self.tfr = list(zip(tfr_files, tfr_shapes, tfr_lods))\n\n        def finalize():\n          # Build TF expressions.\n          with tf.name_scope('Dataset'), tflex.device('/cpu:0'):\n              self._tf_minibatch_in = batch_size if batch_size is not None or batch_size <= 0 else tf.placeholder(tf.int64, name='minibatch_in', shape=[])\n              self._tf_labels_var, self._tf_labels_init = tflib.create_var_with_large_initial_value2(self._np_labels, name='labels_var')\n              with tf.control_dependencies([self._tf_labels_init]):\n                  self._tf_labels_dataset = tf.data.Dataset.from_tensor_slices(self._tf_labels_var)\n              for tfr_file, tfr_shape, tfr_lod in self.tfr:\n                  if tfr_lod < 0:\n                      continue\n                  dset = tf.data.TFRecordDataset(tfr_file, compression_type='', buffer_size=buffer_mb<<20)\n                  if max_images is not None:\n                      dset = dset.take(max_images)\n                  dset = dset.map(self.parse_tfrecord_tf, num_parallel_calls=num_threads)\n                  dset = tf.data.Dataset.zip((dset, self._tf_labels_dataset))\n                  bytes_per_item = np.prod(tfr_shape) * np.dtype(self.dtype).itemsize\n                  if shuffle_mb > 0:\n                      dset = dset.shuffle(((shuffle_mb << 20) - 1) // bytes_per_item + 1)\n                  if repeat:\n                      dset = dset.repeat()\n                  if prefetch_mb > 0:\n                      dset = dset.prefetch(((prefetch_mb << 20) - 1) // bytes_per_item + 1)\n                  if batch_size is None or batch_size > 0:\n                      dset = dset.batch(self._tf_minibatch_in)\n                  self._tf_datasets[tfr_lod] = dset\n              self._tf_iterator = tf.data.Iterator.from_structure(self._tf_datasets[0].output_types, self._tf_datasets[0].output_shapes)\n              self._tf_init_ops = {lod: self._tf_iterator.make_initializer(dset) if batch_size is None else tf.no_op() for lod, dset in self._tf_datasets.items()}\n        self.finalize = finalize\n\n    def close(self):\n        pass\n\n    # Use the given minibatch size and level-of-detail for the data returned by get_minibatch_tf().\n    def configure(self, minibatch_size, lod=0):\n        lod = int(np.floor(lod))\n        assert minibatch_size >= 1 and lod in self._tf_datasets\n        if self._cur_minibatch != minibatch_size or self._cur_lod != lod:\n            #self._tf_init_ops[lod].run(*[{self._tf_minibatch_in: minibatch_size}] if not isinstance(self._tf_minibatch_in, int) and self._tf_minibatch_in is not None else [])\n            self._tf_init_ops[lod].run({self._tf_minibatch_in: minibatch_size})\n            self._cur_minibatch = minibatch_size\n            self._cur_lod = lod\n\n    # Get next minibatch as TensorFlow expressions.\n    def get_minibatch_tf(self): # => images, labels\n        return self._tf_iterator.get_next()\n\n    # Get next minibatch as NumPy arrays.\n    def get_minibatch_np(self, minibatch_size, lod=0): # => images, labels\n        while True:\n            self.configure(minibatch_size, lod)\n            with tf.name_scope('Dataset'):\n                if self._tf_minibatch_np is None:\n                    self._tf_minibatch_np = self.get_minibatch_tf()\n                try:\n                    return tflib.run(self._tf_minibatch_np)\n                except errors_impl.AbortedError:\n                    import traceback\n                    traceback.print_exc()\n\n    # Get random labels as TensorFlow expression.\n    def get_random_labels_tf(self, minibatch_size): # => labels\n        with tf.name_scope('Dataset'):\n            if self.label_size > 0:\n                with tflex.device('/cpu:0'):\n                    return tf.gather(self._tf_labels_var, tf.random_uniform([minibatch_size], 0, self._np_labels.shape[0], dtype=tf.int32))\n            return tf.zeros([minibatch_size, 0], self.label_dtype)\n\n    # Get random labels as NumPy array.\n    def get_random_labels_np(self, minibatch_size): # => labels\n        if self.label_size > 0:\n            return self._np_labels[np.random.randint(self._np_labels.shape[0], size=[minibatch_size])]\n        return np.zeros([minibatch_size, 0], self.label_dtype)\n\n    # Parse individual image from a tfrecords file into TensorFlow expression.\n    @staticmethod\n    def parse_tfrecord_tf(record):\n        features = tf.parse_single_example(record, features={\n            'shape': tf.FixedLenFeature([3], tf.int64),\n            'data': tf.FixedLenFeature([], tf.string)})\n        data = tf.decode_raw(features['data'], tf.uint8)\n        return tf.reshape(data, features['shape'])\n\n    # Parse individual image from a tfrecords file into TensorFlow expression.\n    @staticmethod\n    def parse_tfrecord_tf_float(record):\n        img = TFRecordDataset.parse_tfrecord_tf(record)\n        return tf.cast(img, dtype=tf.float32)\n\n    # Parse individual image from a tfrecords file into NumPy array.\n    @staticmethod\n    def parse_tfrecord_np(record):\n        ex = tf.train.Example()\n        ex.ParseFromString(record)\n        shape = ex.features.feature['shape'].int64_list.value # pylint: disable=no-member\n        data = ex.features.feature['data'].bytes_list.value[0] # pylint: disable=no-member\n        return np.fromstring(data, np.uint8).reshape(shape)\n\n#----------------------------------------------------------------------------\n# Helper func for constructing a dataset object using the given options.\n\ndef load_dataset(class_name=None, data_dir=None, verbose=False, **kwargs):\n    kwargs = dict(kwargs)\n    if 'tfrecord_dir' in kwargs:\n        if class_name is None:\n            class_name = __name__ + '.TFRecordDataset'\n        if data_dir is not None:\n            kwargs['tfrecord_dir'] = os.path.join(data_dir, kwargs['tfrecord_dir'])\n\n    assert class_name is not None\n    if verbose:\n        print('Streaming data using %s...' % class_name)\n    dataset = dnnlib.util.get_obj_by_name(class_name)(**kwargs)\n    if verbose:\n        print('Dataset shape =', np.int32(dataset.shape).tolist())\n        print('Dynamic range =', dataset.dynamic_range)\n        print('Label size    =', dataset.label_size)\n    return dataset\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/training/imagenet_input.py",
    "content": "# Copyright 2018 The TensorFlow Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\"\"\"ImageNet preprocessing for ResNet.\"\"\"\n\nfrom absl import flags\nimport tensorflow as tf\n\n#FLAGS = flags.FLAGS\nclass Namespace:\n  pass\n\nFLAGS = Namespace()\nFLAGS.cache_decoded_image = False\n\n\ndef distorted_bounding_box_crop(image_bytes,\n                                bbox,\n                                min_object_covered=0.1,\n                                aspect_ratio_range=(0.75, 1.33),\n                                area_range=(0.05, 1.0),\n                                max_attempts=100,\n                                scope=None):\n  \"\"\"Generates cropped_image using one of the bboxes randomly distorted.\n\n  See `tf.image.sample_distorted_bounding_box` for more documentation.\n\n  Args:\n    image_bytes: `Tensor` of binary image data.\n    bbox: `Tensor` of bounding boxes arranged `[1, num_boxes, coords]`\n        where each coordinate is [0, 1) and the coordinates are arranged\n        as `[ymin, xmin, ymax, xmax]`. If num_boxes is 0 then use the whole\n        image.\n    min_object_covered: An optional `float`. Defaults to `0.1`. The cropped\n        area of the image must contain at least this fraction of any bounding\n        box supplied.\n    aspect_ratio_range: An optional list of `float`s. The cropped area of the\n        image must have an aspect ratio = width / height within this range.\n    area_range: An optional list of `float`s. The cropped area of the image\n        must contain a fraction of the supplied image within in this range.\n    max_attempts: An optional `int`. Number of attempts at generating a cropped\n        region of the image of the specified constraints. After `max_attempts`\n        failures, return the entire image.\n    scope: Optional `str` for name scope.\n  Returns:\n    cropped image `Tensor`\n  \"\"\"\n  with tf.name_scope(scope, 'distorted_bounding_box_crop', [image_bytes, bbox]):\n    if FLAGS.cache_decoded_image:\n      shape = tf.shape(image_bytes)\n    else:\n      shape = tf.image.extract_jpeg_shape(image_bytes)\n    sample_distorted_bounding_box = tf.image.sample_distorted_bounding_box(\n        shape,\n        bounding_boxes=bbox,\n        min_object_covered=min_object_covered,\n        aspect_ratio_range=aspect_ratio_range,\n        area_range=area_range,\n        max_attempts=max_attempts,\n        use_image_if_no_bounding_boxes=True)\n    bbox_begin, bbox_size, _ = sample_distorted_bounding_box\n\n    # Crop the image to the specified bounding box.\n    offset_y, offset_x, _ = tf.unstack(bbox_begin)\n    target_height, target_width, _ = tf.unstack(bbox_size)\n    crop_window = tf.stack([offset_y, offset_x, target_height, target_width])\n    if FLAGS.cache_decoded_image:\n      image = tf.image.crop_to_bounding_box(image_bytes, offset_y, offset_x,\n                                            target_height, target_width)\n    else:\n      image = tf.image.decode_and_crop_jpeg(\n          image_bytes, crop_window, channels=3)\n\n    return image\n\n\ndef _at_least_x_are_equal(a, b, x):\n  \"\"\"At least `x` of `a` and `b` `Tensors` are equal.\"\"\"\n  match = tf.equal(a, b)\n  match = tf.cast(match, tf.int32)\n  return tf.greater_equal(tf.reduce_sum(match), x)\n\n\ndef _decode_and_random_crop(image_bytes, image_size):\n  \"\"\"Make a random crop of image_size.\"\"\"\n  bbox = tf.constant([0.0, 0.0, 1.0, 1.0], dtype=tf.float32, shape=[1, 1, 4])\n  image = distorted_bounding_box_crop(\n      image_bytes,\n      bbox,\n      min_object_covered=0.1,\n      aspect_ratio_range=(3. / 4, 4. / 3.),\n      area_range=(0.08, 1.0),\n      max_attempts=10,\n      scope=None)\n  return tf.image.resize_area([image], [image_size, image_size])[0]\n\n\ndef _decode_and_center_crop_image(image_bytes, image_size, crop_padding=32):\n  \"\"\"Crops to center of image with padding then scales image_size.\"\"\"\n  image = tf.io.decode_image(image_bytes, channels=3)\n  shape = tf.shape(image)\n  #shape = tf.image.extract_jpeg_shape(image_bytes)\n  image_height = shape[0]\n  image_width = shape[1]\n  channels = shape[2]\n\n  padded_center_crop_size = tf.cast(\n      ((image_size / (image_size + crop_padding)) *\n       tf.cast(tf.minimum(image_height, image_width), tf.float32)),\n      tf.int32)\n\n  offset_height = ((image_height - padded_center_crop_size) + 1) // 2\n  offset_width = ((image_width - padded_center_crop_size) + 1) // 2\n  if 'RANDOM_CROP' in os.environ:\n    image = tf.image.random_crop(image, [padded_center_crop_size, padded_center_crop_size, channels])\n  else:\n    image = tf.image.crop_to_bounding_box(image, offset_height, offset_width, padded_center_crop_size, padded_center_crop_size)\n  image = tf.image.resize_area([image], [image_size, image_size])[0]\n\n  return image\n\ndef _decode_and_center_crop(image_bytes, image_size, crop_padding=None):\n  if 'NO_CENTER_CROP' in os.environ:\n    image = tf.io.decode_image(image_bytes, channels=3)\n    image = tf.image.resize_area([image], [image_size, image_size])[0]\n    return image\n  else:\n    if crop_padding is None and 'CROP_PADDING' in os.environ:\n      crop_padding = int(os.environ['CROP_PADDING'])\n    if crop_padding is None:\n      crop_padding = 32\n    return _decode_and_center_crop_image(image_bytes, image_size, crop_padding=crop_padding)\n\ndef _flip(image):\n  \"\"\"Random horizontal image flip.\"\"\"\n  image = tf.image.random_flip_left_right(image)\n  return image\n\n\ndef preprocess_for_train(image_bytes, use_bfloat16, image_size):\n  \"\"\"Preprocesses the given image for evaluation.\n\n  Args:\n    image_bytes: `Tensor` representing an image binary of arbitrary size.\n    use_bfloat16: `bool` for whether to use bfloat16.\n    image_size: image size.\n\n  Returns:\n    A preprocessed image `Tensor`.\n  \"\"\"\n  image = _decode_and_random_crop(image_bytes, image_size)\n  image = _flip(image)\n  image = tf.reshape(image, [image_size, image_size, 3])\n  image = tf.image.convert_image_dtype(\n      image, dtype=tf.bfloat16 if use_bfloat16 else tf.float32)\n  return image\n\n\ndef preprocess_for_eval(image_bytes, use_bfloat16, image_size):\n  \"\"\"Preprocesses the given image for evaluation.\n\n  Args:\n    image_bytes: `Tensor` representing an image binary of arbitrary size.\n    use_bfloat16: `bool` for whether to use bfloat16.\n    image_size: image size.\n\n  Returns:\n    A preprocessed image `Tensor`.\n  \"\"\"\n  image = _decode_and_center_crop(image_bytes, image_size)\n  image = tf.reshape(image, [image_size, image_size, 3])\n  image = tf.image.convert_image_dtype(\n      image, dtype=tf.bfloat16 if use_bfloat16 else tf.float32)\n  return image\n\n\ndef preprocess_image(image_bytes,\n                     image_size,\n                     is_training=False,\n                     use_bfloat16=False):\n  \"\"\"Preprocesses the given image.\n\n  Args:\n    image_bytes: `Tensor` representing an image binary of arbitrary size.\n    is_training: `bool` for whether the preprocessing is for training.\n    use_bfloat16: `bool` for whether to use bfloat16.\n    image_size: image size.\n\n  Returns:\n    A preprocessed image `Tensor` with value range of [0, 255].\n  \"\"\"\n  if is_training and False: # a bit of a weird hack; we override the training pipeline in the eval functions.\n    img = preprocess_for_train(image_bytes, use_bfloat16, image_size)\n  else:\n    img = preprocess_for_eval(image_bytes, use_bfloat16, image_size)\n  #img = tf.transpose(img, [2, 0, 1])\n  return img\n\n\n# Copyright 2018 The TensorFlow Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\"\"\"Efficient ImageNet input pipeline using tf.data.Dataset.\"\"\"\n\nimport abc\nfrom collections import namedtuple\nimport functools\nimport math\nimport os\nfrom absl import flags\nimport tensorflow as tf\n\n#FLAGS = flags.FLAGS\n\n\ndef image_serving_input_fn():\n  \"\"\"Serving input fn for raw images.\"\"\"\n\n  def _preprocess_image(image_bytes):\n    \"\"\"Preprocess a single raw image.\"\"\"\n    image = preprocess_image(\n        image_bytes=image_bytes, is_training=False)\n    return image\n\n  image_bytes_list = tf.placeholder(\n      shape=[None],\n      dtype=tf.string,\n  )\n  images = tf.map_fn(\n      _preprocess_image, image_bytes_list, back_prop=False, dtype=tf.float32)\n  return tf.estimator.export.ServingInputReceiver(\n      images, {'image_bytes': image_bytes_list})\n\n\ndef _int64_feature(value):\n  \"\"\"Wrapper for inserting int64 features into Example proto.\"\"\"\n  if not isinstance(value, list):\n    value = [value]\n  return tf.train.Feature(int64_list=tf.train.Int64List(value=value))\n\n\ndef _bytes_feature(value):\n  \"\"\"Wrapper for inserting bytes features into Example proto.\"\"\"\n  return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))\n\n\ndef _convert_to_example(image_buffer, label):\n  \"\"\"Build an Example proto for an example.\n\n  Args:\n    image_buffer: string, JPEG encoding of RGB image\n    label: integer, identifier for the ground truth for the network\n\n  Returns:\n    Example proto\n  \"\"\"\n\n  example = tf.train.Example(\n      features=tf.train.Features(\n          feature={\n              'image/class/label': _int64_feature(label),\n              'image/encoded': _bytes_feature(image_buffer)\n          }))\n  return example\n\n\nclass ImageNetTFExampleInput(object):\n  \"\"\"Base class for ImageNet input_fn generator.\n\n  Args:\n    is_training: `bool` for whether the input is for training\n    use_bfloat16: If True, use bfloat16 precision; else use float32.\n    transpose_input: 'bool' for whether to use the double transpose trick\n    num_cores: `int` for the number of TPU cores\n  \"\"\"\n  __metaclass__ = abc.ABCMeta\n\n  def __init__(self,\n               is_training,\n               use_bfloat16,\n               num_cores=8,\n               image_size=224,\n               prefetch_depth_auto_tune=False,\n               transpose_input=False):\n    self.image_preprocessing_fn = preprocess_image\n    self.is_training = is_training\n    self.use_bfloat16 = use_bfloat16\n    self.num_cores = num_cores\n    self.transpose_input = transpose_input\n    self.image_size = image_size\n    self.prefetch_depth_auto_tune = prefetch_depth_auto_tune\n\n  def set_shapes(self, batch_size, images, labels):\n    \"\"\"Statically set the batch_size dimension.\"\"\"\n    if self.transpose_input:\n      if FLAGS.train_batch_size // FLAGS.num_cores > 8:\n        shape = [None, None, None, batch_size]\n      else:\n        shape = [None, None, batch_size, None]\n      images.set_shape(images.get_shape().merge_with(tf.TensorShape(shape)))\n      images = tf.reshape(images, [-1])\n      labels.set_shape(labels.get_shape().merge_with(\n          tf.TensorShape([batch_size])))\n    else:\n      images.set_shape(images.get_shape().merge_with(\n          tf.TensorShape([batch_size, None, None, None])))\n      labels.set_shape(labels.get_shape().merge_with(\n          tf.TensorShape([batch_size])))\n\n    return images, labels\n\n  def dataset_parser(self, value):\n    \"\"\"Parses an image and its label from a serialized ResNet-50 TFExample.\n\n    Args:\n      value: serialized string containing an ImageNet TFExample.\n\n    Returns:\n      Returns a tuple of (image, label) from the TFExample.\n    \"\"\"\n    keys_to_features = {\n        'image/encoded': tf.FixedLenFeature((), tf.string, ''),\n        'image/format': tf.FixedLenFeature((), tf.string, 'jpeg'),\n        'image/class/label': tf.FixedLenFeature([], tf.int64, -1),\n        'image/class/text': tf.FixedLenFeature([], tf.string, ''),\n        'image/object/bbox/xmin': tf.VarLenFeature(dtype=tf.float32),\n        'image/object/bbox/ymin': tf.VarLenFeature(dtype=tf.float32),\n        'image/object/bbox/xmax': tf.VarLenFeature(dtype=tf.float32),\n        'image/object/bbox/ymax': tf.VarLenFeature(dtype=tf.float32),\n        'image/object/class/label': tf.VarLenFeature(dtype=tf.int64),\n    }\n\n    parsed = tf.parse_single_example(value, keys_to_features)\n    image_bytes = tf.reshape(parsed['image/encoded'], shape=[])\n\n    # Subtract one so that labels are in [0, 1000).\n    bias = int(os.environ['LABEL_BIAS']) if 'LABEL_BIAS' in os.environ else 0\n    label = tf.cast(\n        tf.reshape(parsed['image/class/label'], shape=[]), dtype=tf.int32) + bias\n\n    # Return all black images for padded data.\n    image = tf.cond(\n        label < 0, lambda: self._get_null_input(None), lambda: self.  # pylint: disable=g-long-lambda\n        image_preprocessing_fn(\n            image_bytes=image_bytes,\n            is_training=self.is_training,\n            image_size=self.image_size,\n            use_bfloat16=self.use_bfloat16))\n\n    return image, label\n\n  def dataset_parser_static(self, value):\n    \"\"\"Parses an image and its label from a serialized ResNet-50 TFExample.\n\n       This only decodes the image, which is prepared for caching.\n\n    Args:\n      value: serialized string containing an ImageNet TFExample.\n\n    Returns:\n      Returns a tuple of (image, label) from the TFExample.\n    \"\"\"\n    keys_to_features = {\n        'image/encoded': tf.FixedLenFeature((), tf.string, ''),\n        'image/format': tf.FixedLenFeature((), tf.string, 'jpeg'),\n        'image/class/label': tf.FixedLenFeature([], tf.int64, -1),\n        'image/class/text': tf.FixedLenFeature([], tf.string, ''),\n        'image/object/bbox/xmin': tf.VarLenFeature(dtype=tf.float32),\n        'image/object/bbox/ymin': tf.VarLenFeature(dtype=tf.float32),\n        'image/object/bbox/xmax': tf.VarLenFeature(dtype=tf.float32),\n        'image/object/bbox/ymax': tf.VarLenFeature(dtype=tf.float32),\n        'image/object/class/label': tf.VarLenFeature(dtype=tf.int64),\n    }\n\n    parsed = tf.parse_single_example(value, keys_to_features)\n    image_bytes = tf.reshape(parsed['image/encoded'], shape=[])\n    image_bytes = tf.io.decode_image(image_bytes, channels=3)\n\n    # Subtract one so that labels are in [0, 1000).\n    bias = int(os.environ['LABEL_BIAS']) if 'LABEL_BIAS' in os.environ else 0\n    label = tf.cast(\n        tf.reshape(parsed['image/class/label'], shape=[]), dtype=tf.int32) + bias\n    return image_bytes, label\n\n  def dataset_parser_dynamic(self, image_bytes, label):\n    return self.image_preprocessing_fn(\n        image_bytes=image_bytes,\n        is_training=self.is_training,\n        image_size=self.image_size,\n        use_bfloat16=self.use_bfloat16), label\n\n  def pad_dataset(self, dataset, num_hosts):\n    \"\"\"Pad the eval dataset so that eval can have the same batch size as training.\"\"\"\n    num_dataset_per_shard = int(\n        math.ceil(FLAGS.num_eval_images / FLAGS.eval_batch_size) *\n        FLAGS.eval_batch_size / num_hosts)\n    example_string = 'dummy_string'\n    padded_example = _convert_to_example(\n        str.encode(example_string), -1).SerializeToString()\n    padded_dataset = tf.data.Dataset.from_tensors(\n        tf.constant(padded_example, dtype=tf.string))\n    padded_dataset = padded_dataset.repeat(num_dataset_per_shard)\n\n    dataset = dataset.concatenate(padded_dataset).take(num_dataset_per_shard)\n    return dataset\n\n  @abc.abstractmethod\n  def make_source_dataset(self, index, num_hosts):\n    \"\"\"Makes dataset of serialized TFExamples.\n\n    The returned dataset will contain `tf.string` tensors, but these strings are\n    serialized `TFExample` records that will be parsed by `dataset_parser`.\n\n    If self.is_training, the dataset should be infinite.\n\n    Args:\n      index: current host index.\n      num_hosts: total number of hosts.\n\n    Returns:\n      A `tf.data.Dataset` object.\n    \"\"\"\n    return\n\n  def input_fn(self, params):\n    \"\"\"Input function which provides a single batch for train or eval.\n\n    Args:\n      params: `dict` of parameters passed from the `TPUEstimator`.\n          `params['batch_size']` is always provided and should be used as the\n          effective batch size.\n\n    Returns:\n      A `tf.data.Dataset` object.\n    \"\"\"\n    # Retrieves the batch size for the current shard. The # of shards is\n    # computed according to the input pipeline deployment. See\n    # tf.contrib.tpu.RunConfig for details.\n    batch_size = params['batch_size']\n\n    # TODO(dehao): Replace the following with params['context'].current_host\n    if 'context' in params:\n      current_host = params['context'].current_input_fn_deployment()[1]\n      num_hosts = params['context'].num_hosts\n    else:\n      if 'dataset_index' in params:\n        current_host = params['dataset_index']\n        num_hosts = params['dataset_num_shards']\n      else:\n        current_host = 0\n        num_hosts = 1\n\n    dataset = self.make_source_dataset(current_host, num_hosts)\n\n    if not self.is_training and False:\n      # Padding for eval.\n      dataset = self.pad_dataset(dataset, num_hosts)\n\n    # Use the fused map-and-batch operation.\n    #\n    # For XLA, we must used fixed shapes. Because we repeat the source training\n    # dataset indefinitely, we can use `drop_remainder=True` to get fixed-size\n    # batches without dropping any training examples.\n    #\n    # When evaluating, `drop_remainder=True` prevents accidentally evaluating\n    # the same image twice by dropping the final batch if it is less than a full\n    # batch size. As long as this validation is done with consistent batch size,\n    # exactly the same images will be used.\n    if self.is_training and FLAGS.cache_decoded_image:\n      dataset = dataset.apply(\n          tf.contrib.data.map_and_batch(\n              self.dataset_parser_dynamic,\n              batch_size=batch_size,\n              num_parallel_batches=self.num_cores,\n              drop_remainder=True))\n    else:\n      dataset = dataset.apply(\n          tf.contrib.data.map_and_batch(\n              self.dataset_parser,\n              batch_size=batch_size,\n              num_parallel_batches=self.num_cores,\n              drop_remainder=True))\n\n    # Transpose for performance on TPU\n    if self.transpose_input:\n      if FLAGS.train_batch_size // FLAGS.num_cores > 8:\n        transpose_array = [1, 2, 3, 0]\n      else:\n        transpose_array = [1, 2, 0, 3]\n      dataset = dataset.map(\n          lambda images, labels: (tf.transpose(images, transpose_array), labels\n                                 ),\n          num_parallel_calls=self.num_cores)\n\n    # Assign static batch size dimension\n    dataset = dataset.map(functools.partial(self.set_shapes, batch_size))\n\n    # Prefetch overlaps in-feed with training\n    if self.prefetch_depth_auto_tune:\n      dataset = dataset.prefetch(tf.contrib.data.AUTOTUNE)\n    else:\n      dataset = dataset.prefetch(4)\n\n    options = tf.data.Options()\n    options.experimental_threading.max_intra_op_parallelism = 1\n    options.experimental_threading.private_threadpool_size = 48\n    dataset = dataset.with_options(options)\n    return dataset\n\n\nclass ImageNetInput(ImageNetTFExampleInput):\n  \"\"\"Generates ImageNet input_fn from a series of TFRecord files.\n\n  The training data is assumed to be in TFRecord format with keys as specified\n  in the dataset_parser below, sharded across 1024 files, named sequentially:\n\n      train-00000-of-01024\n      train-00001-of-01024\n      ...\n      train-01023-of-01024\n\n  The validation data is in the same format but sharded in 128 files.\n\n  The format of the data required is created by the script at:\n      https://github.com/tensorflow/tpu/blob/master/tools/datasets/imagenet_to_gcs.py\n  \"\"\"\n\n  def __init__(self,\n               data_dir,\n               is_training=True,\n               use_bfloat16=False,\n               transpose_input=False,\n               image_size=224,\n               num_parallel_calls=64,\n               num_cores=8,\n               prefetch_depth_auto_tune=False,\n               cache=False):\n    \"\"\"Create an input from TFRecord files.\n\n    Args:\n      is_training: `bool` for whether the input is for training\n      use_bfloat16: If True, use bfloat16 precision; else use float32.\n      transpose_input: 'bool' for whether to use the double transpose trick\n      data_dir: `str` for the directory of the training and validation data;\n          if 'null' (the literal string 'null') or implicitly False\n          then construct a null pipeline, consisting of empty images\n          and blank labels.\n      image_size: size of input images\n      num_parallel_calls: concurrency level to use when reading data from disk.\n      num_cores: Number of prefetch threads\n      prefetch_depth_auto_tune: Auto-tuning prefetch depths in input pipeline\n      cache: if true, fill the dataset by repeating from its cache\n    \"\"\"\n    super(ImageNetInput, self).__init__(\n        is_training=is_training,\n        image_size=image_size,\n        use_bfloat16=use_bfloat16,\n        num_cores=num_cores,\n        prefetch_depth_auto_tune=prefetch_depth_auto_tune,\n        transpose_input=transpose_input)\n    self.data_dir = data_dir\n    if self.data_dir == 'null' or not self.data_dir:\n      self.data_dir = None\n    self.num_parallel_calls = num_parallel_calls\n    self.cache = cache\n\n  def _get_null_input(self, data):\n    \"\"\"Returns a null image (all black pixels).\n\n    Args:\n      data: element of a dataset, ignored in this method, since it produces\n          the same null image regardless of the element.\n\n    Returns:\n      a tensor representing a null image.\n    \"\"\"\n    del data  # Unused since output is constant regardless of input\n    return tf.zeros([self.image_size, self.image_size, 3], tf.bfloat16\n                    if self.use_bfloat16 else tf.float32)\n\n  def dataset_parser(self, value):\n    \"\"\"See base class.\"\"\"\n    if not self.data_dir:\n      return value, tf.constant(0, tf.int32)\n    return super(ImageNetInput, self).dataset_parser(value)\n\n  def make_source_dataset(self, index, num_hosts):\n    \"\"\"See base class.\"\"\"\n    if not self.data_dir:\n      tf.logging.info('Undefined data_dir implies null input')\n      return tf.data.Dataset.range(1).repeat().map(self._get_null_input)\n\n    # Shuffle the filenames to ensure better randomization.\n    file_patterns = [x.strip() for x in self.data_dir.split(',') if len(x.strip()) > 0]\n\n    # For multi-host training, we want each hosts to always process the same\n    # subset of files.  Each host only sees a subset of the entire dataset,\n    # allowing us to cache larger datasets in memory.\n    dataset = None\n    for pattern in file_patterns:\n      x = tf.data.Dataset.list_files(pattern, shuffle=False)\n      if dataset is None:\n        dataset = x\n      else:\n        dataset = dataset.concatenate(x)\n    dataset = dataset.shard(num_hosts, index)\n\n    if self.is_training and not self.cache:\n      # We shuffle only during training, and during training, we must produce an\n      # infinite dataset, so apply the fused shuffle_and_repeat optimized\n      # dataset transformation.\n      dataset = dataset.apply(\n        tf.contrib.data.shuffle_and_repeat(1024 * 16))\n      #dataset = dataset.repeat()\n\n    def fetch_dataset(filename):\n      buffer_size = 8 * 1024 * 1024  # 8 MiB per file\n      dataset = tf.data.TFRecordDataset(filename, buffer_size=buffer_size)\n      return dataset\n\n    # Read the data from disk in parallel\n    dataset = dataset.apply(\n        tf.contrib.data.parallel_interleave(\n            fetch_dataset, cycle_length=self.num_parallel_calls, sloppy=True))\n\n    if self.is_training and FLAGS.cache_decoded_image:\n      dataset = dataset.map(\n          self.dataset_parser_static,\n          num_parallel_calls=self.num_parallel_calls)\n\n    if self.cache:\n      dataset = dataset.cache()\n    if self.is_training:\n      # We shuffle only during training, and during training, we must produce an\n      # infinite dataset, so apply the fused shuffle_and_repeat optimized\n      # dataset transformation.\n      dataset = dataset.apply(\n          tf.contrib.data.shuffle_and_repeat(1024 * 16))\n    return dataset\n\n\n# Defines a selection of data from a Cloud Bigtable.\nBigtableSelection = namedtuple('BigtableSelection',\n                               ['project',\n                                'instance',\n                                'table',\n                                'prefix',\n                                'column_family',\n                                'column_qualifier'])\n\n\nclass ImageNetBigtableInput(ImageNetTFExampleInput):\n  \"\"\"Generates ImageNet input_fn from a Bigtable for training or evaluation.\n  \"\"\"\n\n  def __init__(self, is_training, use_bfloat16, transpose_input, selection):\n    \"\"\"Constructs an ImageNet input from a BigtableSelection.\n\n    Args:\n      is_training: `bool` for whether the input is for training\n      use_bfloat16: If True, use bfloat16 precision; else use float32.\n      transpose_input: 'bool' for whether to use the double transpose trick\n      selection: a BigtableSelection specifying a part of a Bigtable.\n    \"\"\"\n    super(ImageNetBigtableInput, self).__init__(\n        is_training=is_training,\n        use_bfloat16=use_bfloat16,\n        transpose_input=transpose_input)\n    self.selection = selection\n\n  def make_source_dataset(self, index, num_hosts):\n    \"\"\"See base class.\"\"\"\n    data = self.selection\n    client = tf.contrib.cloud.BigtableClient(data.project, data.instance)\n    table = client.table(data.table)\n    ds = table.parallel_scan_prefix(data.prefix,\n                                    columns=[(data.column_family,\n                                              data.column_qualifier)])\n    # The Bigtable datasets will have the shape (row_key, data)\n    ds_data = ds.map(lambda index, data: data)\n\n    if self.is_training:\n      ds_data = ds_data.repeat()\n\n    return ds_data\n"
  },
  {
    "path": "stylegan2-tpu/training/loss.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Loss functions.\"\"\"\n\nimport numpy as np\nimport tensorflow as tf\nimport dnnlib.tflib as tflib\nfrom dnnlib.tflib.autosummary import autosummary, autoimages\n\n#----------------------------------------------------------------------------\n# Logistic loss from the paper\n# \"Generative Adversarial Nets\", Goodfellow et al. 2014\n\ndef G_logistic(G, D, opt, training_set, minibatch_size):\n    _ = opt\n    latents = tf.random_normal([minibatch_size] + G.input_shapes[0][1:])\n    labels = training_set.get_random_labels_tf(minibatch_size)\n    fake_images_out = G.get_output_for(latents, labels, is_training=True)\n    fake_scores_out = D.get_output_for(fake_images_out, labels, is_training=True)\n    loss = -tf.nn.softplus(fake_scores_out) # log(1-sigmoid(fake_scores_out)) # pylint: disable=invalid-unary-operand-type\n    autosummary('G_logistic_00/total_loss', loss)\n    return loss, None\n\ndef G_logistic_ns(G, D, opt, training_set, minibatch_size):\n    _ = opt\n    latents = tf.random_normal([minibatch_size] + G.input_shapes[0][1:])\n    labels = training_set.get_random_labels_tf(minibatch_size)\n    fake_images_out = G.get_output_for(latents, labels, is_training=True)\n    fake_scores_out = D.get_output_for(fake_images_out, labels, is_training=True)\n    loss = tf.nn.softplus(-fake_scores_out) # -log(sigmoid(fake_scores_out))\n    autosummary('G_logistic_ns_00/total_loss', loss)\n    return loss, None\n\ndef D_logistic(G, D, opt, training_set, minibatch_size, reals, labels):\n    _ = opt, training_set\n    latents = tf.random_normal([minibatch_size] + G.input_shapes[0][1:])\n    fake_images_out = G.get_output_for(latents, labels, is_training=True)\n    real_scores_out = D.get_output_for(reals, labels, is_training=True)\n    fake_scores_out = D.get_output_for(fake_images_out, labels, is_training=True)\n    real_scores_out = autosummary('D_logistic_00/real_scores', real_scores_out)\n    fake_scores_out = autosummary('D_logistic_01/fake_scores', fake_scores_out)\n    loss = autosummary('D_logistic_00/fake_loss', tf.nn.softplus(fake_scores_out)) # -log(1-sigmoid(fake_scores_out))\n    loss += autosummary('D_logistic_01/real_loss', tf.nn.softplus(-real_scores_out)) # -log(sigmoid(real_scores_out)) # pylint: disable=invalid-unary-operand-type\n    autosummary('D_logistic_02/total_loss', loss)\n    autoimages('D_logistic/images/real', reals)\n    autoimages('D_logistic/images/fake', fake_images_out)\n    return loss, None\n\n#----------------------------------------------------------------------------\n# R1 and R2 regularizers from the paper\n# \"Which Training Methods for GANs do actually Converge?\", Mescheder et al. 2018\n\ndef D_logistic_r1(G, D, opt, training_set, minibatch_size, reals, labels, gamma=10.0):\n    _ = opt, training_set\n    latents = tf.random_normal([minibatch_size] + G.input_shapes[0][1:])\n    fake_images_out = G.get_output_for(latents, labels, is_training=True)\n    real_scores_out = D.get_output_for(reals, labels, is_training=True)\n    fake_scores_out = D.get_output_for(fake_images_out, labels, is_training=True)\n    fake_scores_out = autosummary('D_logistic_r1_00/fake_scores', fake_scores_out)\n    real_scores_out = autosummary('D_logistic_r1_01/real_scores', real_scores_out)\n    loss = autosummary('D_logistic_r1_00/fake_loss', tf.nn.softplus(fake_scores_out)) # -log(1-sigmoid(fake_scores_out))\n    loss += autosummary('D_logistic_r1_01/real_loss', tf.nn.softplus(-real_scores_out)) # -log(sigmoid(real_scores_out)) # pylint: disable=invalid-unary-operand-type\n    with tf.name_scope('GradientPenalty'):\n        real_grads = tf.gradients(tf.reduce_sum(real_scores_out), [reals])[0]\n        gradient_penalty = tf.reduce_sum(tf.square(real_grads), axis=[1,2,3])\n        gradient_penalty = autosummary('D_logistic_r1_02/gradient_penalty', gradient_penalty)\n        reg = gradient_penalty * (gamma * 0.5)\n        autosummary('D_logistic_r1_02/reg_loss', reg)\n    autosummary('D_logistic_r1_03/total_loss', loss + reg)\n    autoimages('D_logistic_r1/images/real', reals)\n    autoimages('D_logistic_r1/images/fake', fake_images_out)\n    return loss, reg\n\ndef D_logistic_r2(G, D, opt, training_set, minibatch_size, reals, labels, gamma=10.0):\n    _ = opt, training_set\n    latents = tf.random_normal([minibatch_size] + G.input_shapes[0][1:])\n    fake_images_out = G.get_output_for(latents, labels, is_training=True)\n    real_scores_out = D.get_output_for(reals, labels, is_training=True)\n    fake_scores_out = D.get_output_for(fake_images_out, labels, is_training=True)\n    fake_scores_out = autosummary('D_logistic_r2_00/fake_scores', fake_scores_out)\n    real_scores_out = autosummary('D_logistic_r2_01/real_scores', real_scores_out)\n    loss = autosummary('D_logistic_r2_00/fake_loss', tf.nn.softplus(fake_scores_out)) # -log(1-sigmoid(fake_scores_out))\n    loss += autosummary('D_logistic_r2_01/real_loss', tf.nn.softplus(-real_scores_out)) # -log(sigmoid(real_scores_out)) # pylint: disable=invalid-unary-operand-type\n    with tf.name_scope('GradientPenalty'):\n        fake_grads = tf.gradients(tf.reduce_sum(fake_scores_out), [fake_images_out])[0]\n        gradient_penalty = tf.reduce_sum(tf.square(fake_grads), axis=[1,2,3])\n        gradient_penalty = autosummary('D_logistic_r2_02/gradient_penalty', gradient_penalty)\n        reg = gradient_penalty * (gamma * 0.5)\n        autosummary('D_logistic_r2_02/reg_loss', reg)\n    autosummary('D_logistic_r2_03/total_loss', loss + reg)\n    autoimages('D_logistic_r2/images/real', reals)\n    autoimages('D_logistic_r2/images/fake', fake_images_out)\n    return loss, reg\n\n#----------------------------------------------------------------------------\n# WGAN loss from the paper\n# \"Wasserstein Generative Adversarial Networks\", Arjovsky et al. 2017\n\ndef G_wgan(G, D, opt, training_set, minibatch_size):\n    _ = opt\n    latents = tf.random_normal([minibatch_size] + G.input_shapes[0][1:])\n    labels = training_set.get_random_labels_tf(minibatch_size)\n    fake_images_out = G.get_output_for(latents, labels, is_training=True)\n    fake_scores_out = D.get_output_for(fake_images_out, labels, is_training=True)\n    loss = -fake_scores_out\n    autosummary('G_wgan_00/total_loss', loss)\n    return loss, None\n\ndef D_wgan(G, D, opt, training_set, minibatch_size, reals, labels, wgan_epsilon=0.001):\n    _ = opt, training_set\n    latents = tf.random_normal([minibatch_size] + G.input_shapes[0][1:])\n    fake_images_out = G.get_output_for(latents, labels, is_training=True)\n    real_scores_out = D.get_output_for(reals, labels, is_training=True)\n    fake_scores_out = D.get_output_for(fake_images_out, labels, is_training=True)\n    fake_scores_out = autosummary('D_wgan_00/fake_score', fake_scores_out)\n    real_scores_out = autosummary('D_wgan_01/real_score', real_scores_out)\n    loss = autosummary('D_wgan_00/fake_loss', fake_scores_out)\n    loss += autosummary('D_wgan_01/real_loss', -real_scores_out)\n    with tf.name_scope('EpsilonPenalty'):\n        epsilon_penalty = autosummary('D_wgan_02/epsilon_penalty', tf.square(real_scores_out))\n        loss += autosummary('D_wgan_02/penalty_loss', epsilon_penalty * wgan_epsilon)\n    autosummary('D_wgan_03/total_loss', loss)\n    autoimages('D_wgan/images/real', reals)\n    autoimages('D_wgan/images/fake', fake_images_out)\n    return loss, None\n\n#----------------------------------------------------------------------------\n# WGAN-GP loss from the paper\n# \"Improved Training of Wasserstein GANs\", Gulrajani et al. 2017\n\ndef D_wgan_gp(G, D, opt, training_set, minibatch_size, reals, labels, wgan_lambda=10.0, wgan_epsilon=0.001, wgan_target=1.0):\n    _ = opt, training_set\n    latents = tf.random_normal([minibatch_size] + G.input_shapes[0][1:])\n    fake_images_out = G.get_output_for(latents, labels, is_training=True)\n    real_scores_out = D.get_output_for(reals, labels, is_training=True)\n    fake_scores_out = D.get_output_for(fake_images_out, labels, is_training=True)\n    fake_scores_out = autosummary('D_wgan_gp_00/fake_scores', fake_scores_out)\n    real_scores_out = autosummary('D_wgan_gp_01/real_scores', real_scores_out)\n    loss = autosummary('D_wgan_gp_00/fake_loss', fake_scores_out)\n    loss += autosummary('D_wgan_gp_01/real_loss', -real_scores_out)\n    with tf.name_scope('EpsilonPenalty'):\n        epsilon_penalty = autosummary('D_wgan_gp_02/epsilon_penalty', tf.square(real_scores_out))\n        loss += autosummary('D_wgan_gp_02/penalty_loss', epsilon_penalty * wgan_epsilon)\n\n    with tf.name_scope('GradientPenalty'):\n        mixing_factors = tf.random_uniform([minibatch_size, 1, 1, 1], 0.0, 1.0, dtype=fake_images_out.dtype)\n        mixed_images_out = tflib.lerp(tf.cast(reals, fake_images_out.dtype), fake_images_out, mixing_factors)\n        mixed_scores_out = D.get_output_for(mixed_images_out, labels, is_training=True)\n        mixed_scores_out = autosummary('D_wgan_gp_03/mixed_scores', mixed_scores_out)\n        mixed_grads = tf.gradients(tf.reduce_sum(mixed_scores_out), [mixed_images_out])[0]\n        mixed_norms = tf.sqrt(tf.reduce_sum(tf.square(mixed_grads), axis=[1,2,3]))\n        mixed_norms = autosummary('D_wgan_gp_03/mixed_norms', mixed_norms)\n        gradient_penalty = tf.square(mixed_norms - wgan_target)\n        reg = gradient_penalty * (wgan_lambda / (wgan_target**2))\n        autosummary('D_wgan_gp_03/gradient_penalty', gradient_penalty)\n        autosummary('D_wgan_gp_03/reg_loss', reg)\n    autosummary('D_wgan_gp_04/total_loss', loss + reg)\n    autoimages('D_wgan_gp/images/real', reals)\n    autoimages('D_wgan_gp/images/fake', fake_images_out)\n    return loss, reg\n\n#----------------------------------------------------------------------------\n# Non-saturating logistic loss with path length regularizer from the paper\n# \"Analyzing and Improving the Image Quality of StyleGAN\", Karras et al. 2019\n\ndef G_logistic_ns_pathreg(G, D, opt, training_set, minibatch_size, pl_minibatch_shrink=2, pl_decay=0.01, pl_weight=2.0):\n    _ = opt\n    latents = tf.random_normal([minibatch_size] + G.input_shapes[0][1:])\n    labels = training_set.get_random_labels_tf(minibatch_size)\n    fake_images_out, fake_dlatents_out = G.get_output_for(latents, labels, is_training=True, return_dlatents=True)\n    fake_scores_out = D.get_output_for(fake_images_out, labels, is_training=True)\n    autosummary('G_logistic_ns_pathreg_00/fake_scores', fake_scores_out)\n    loss = tf.nn.softplus(-fake_scores_out) # -log(sigmoid(fake_scores_out))\n    autosummary('G_logistic_ns_pathreg_00/fake_loss', loss)\n\n    # Path length regularization.\n    with tf.name_scope('PathReg'):\n\n        # Evaluate the regularization term using a smaller minibatch to conserve memory.\n        if pl_minibatch_shrink > 1:\n            pl_minibatch = tf.maximum(1, minibatch_size // pl_minibatch_shrink)\n            pl_latents = tf.random_normal([pl_minibatch] + G.input_shapes[0][1:])\n            pl_labels = training_set.get_random_labels_tf(pl_minibatch)\n            fake_images_out, fake_dlatents_out = G.get_output_for(pl_latents, pl_labels, is_training=True, return_dlatents=True)\n\n        # Compute |J*y|.\n        pl_noise = tf.random_normal(tf.shape(fake_images_out)) / np.sqrt(np.prod(G.output_shape[2:]))\n        pl_grads = tf.gradients(tf.reduce_sum(fake_images_out * pl_noise), [fake_dlatents_out])[0]\n        pl_lengths = tf.sqrt(tf.reduce_mean(tf.reduce_sum(tf.square(pl_grads), axis=2), axis=1))\n        pl_lengths = autosummary('G_logistic_ns_pathreg_01/pl_lengths', pl_lengths)\n\n        # Track exponential moving average of |J*y|.\n        with tf.control_dependencies(None):\n            pl_mean_var = tf.Variable(name='pl_mean', trainable=False, initial_value=0.0, dtype=tf.float32)\n            autosummary('G_logistic_ns_pathreg_01/pl_mean', pl_mean_var)\n        pl_mean = pl_mean_var + autosummary('G_logistic_ns_pathreg_01/pl_mean_delta', pl_decay * (tf.reduce_mean(pl_lengths) - pl_mean_var))\n        pl_update = tf.assign(pl_mean_var, pl_mean)\n\n        # Calculate (|J*y|-a)^2.\n        with tf.control_dependencies([pl_update]):\n            pl_penalty = tf.square(pl_lengths - pl_mean)\n            pl_penalty = autosummary('G_logistic_ns_pathreg_01/pl_penalty', pl_penalty)\n\n        # Apply weight.\n        #\n        # Note: The division in pl_noise decreases the weight by num_pixels, and the reduce_mean\n        # in pl_lengths decreases it by num_affine_layers. The effective weight then becomes:\n        #\n        # gamma_pl = pl_weight / num_pixels / num_affine_layers\n        # = 2 / (r^2) / (log2(r) * 2 - 2)\n        # = 1 / (r^2 * (log2(r) - 1))\n        # = ln(2) / (r^2 * (ln(r) - ln(2))\n        #\n        reg = pl_penalty * pl_weight\n        autosummary('G_logistic_ns_pathreg_01/reg_loss', reg)\n    autosummary('G_logistic_ns_pathreg_02/total_loss', loss + reg)\n\n    return loss, reg\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/training/misc.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Miscellaneous utility functions.\"\"\"\n\nimport os\nimport pickle\nimport numpy as np\nimport PIL.Image\nimport PIL.ImageFont\nimport dnnlib\n\n#----------------------------------------------------------------------------\n# Convenience wrappers for pickle that are able to load data produced by\n# older versions of the code, and from external URLs.\n\ndef open_file_or_url(file_or_url):\n    if dnnlib.util.is_url(file_or_url):\n        return dnnlib.util.open_url(file_or_url, cache_dir='.stylegan2-cache')\n    return open(file_or_url, 'rb')\n\ndef load_pkl(file_or_url, filename=None):\n    infile = filename if filename is not None and os.path.isfile(filename) else file_or_url\n    with open_file_or_url(infile) as file:\n        return pickle.load(file, encoding='latin1')\n\ndef save_pkl(obj, filename):\n    with open(filename, 'wb') as file:\n        pickle.dump(obj, file, protocol=pickle.HIGHEST_PROTOCOL)\n\n#----------------------------------------------------------------------------\n# Image utils.\n\ndef adjust_dynamic_range(data, drange_in, drange_out):\n    if drange_in != drange_out:\n        scale = (np.float32(drange_out[1]) - np.float32(drange_out[0])) / (np.float32(drange_in[1]) - np.float32(drange_in[0]))\n        bias = (np.float32(drange_out[0]) - np.float32(drange_in[0]) * scale)\n        data = data * scale + bias\n    return data\n\ndef create_image_grid(images, grid_size=None):\n    assert images.ndim == 3 or images.ndim == 4\n    num, img_w, img_h = images.shape[0], images.shape[-1], images.shape[-2]\n\n    if grid_size is not None:\n        grid_w, grid_h = tuple(grid_size)\n    else:\n        grid_w = max(int(np.ceil(np.sqrt(num))), 1)\n        grid_h = max((num - 1) // grid_w + 1, 1)\n\n    grid = np.zeros(list(images.shape[1:-2]) + [grid_h * img_h, grid_w * img_w], dtype=images.dtype)\n    for idx in range(num):\n        x = (idx % grid_w) * img_w\n        y = (idx // grid_w) * img_h\n        grid[..., y : y + img_h, x : x + img_w] = images[idx]\n    return grid\n\ndef convert_to_pil_image(image, drange=[0,1]):\n    assert image.ndim == 2 or image.ndim == 3\n    if image.ndim == 3:\n        if image.shape[0] == 1:\n            image = image[0] # grayscale CHW => HW\n        else:\n            image = image.transpose(1, 2, 0) # CHW -> HWC\n\n    image = adjust_dynamic_range(image, drange, [0,255])\n    image = np.rint(image).clip(0, 255).astype(np.uint8)\n    fmt = 'RGB' if image.ndim == 3 else 'L'\n    return PIL.Image.fromarray(image, fmt)\n\ndef save_image_grid(images, filename, drange=[0,1], grid_size=None):\n    convert_to_pil_image(create_image_grid(images, grid_size), drange).save(filename)\n\ndef apply_mirror_augment(minibatch):\n    mask = np.random.rand(minibatch.shape[0]) < 0.5\n    minibatch = np.array(minibatch)\n    minibatch[mask] = minibatch[mask, :, :, ::-1]\n    return minibatch\n\n#----------------------------------------------------------------------------\n# Loading data from previous training runs.\n\ndef parse_config_for_previous_run(run_dir):\n    with open(os.path.join(run_dir, 'submit_config.pkl'), 'rb') as f:\n        data = pickle.load(f)\n    data = data.get('run_func_kwargs', {})\n    return dict(train=data, dataset=data.get('dataset_args', {}))\n\n#----------------------------------------------------------------------------\n# Size and contents of the image snapshot grids that are exported\n# periodically during training.\n\ndef setup_snapshot_image_grid(training_set,\n    size    = '1080p',      # '1080p' = to be viewed on 1080p display, '4k' = to be viewed on 4k display.\n    layout  = 'random'):    # 'random' = grid contents are selected randomly, 'row_per_class' = each row corresponds to one class label.\n\n    # Select size.\n    gw = 1; gh = 1\n    if size == '1080p':\n        gw = np.clip(1920 // training_set.shape[2], 3, 32)\n        gh = np.clip(1080 // training_set.shape[1], 2, 32)\n    if size == '4k':\n        gw = np.clip(3840 // training_set.shape[2], 7, 32)\n        gh = np.clip(2160 // training_set.shape[1], 4, 32)\n    if size == '8k':\n        gw = np.clip(7680 // training_set.shape[2], 7, 32)\n        gh = np.clip(4320 // training_set.shape[1], 4, 32)\n\n    # Initialize data arrays.\n    reals = np.zeros([gw * gh] + training_set.shape, dtype=training_set.dtype)\n    labels = np.zeros([gw * gh, training_set.label_size], dtype=training_set.label_dtype)\n\n    # Random layout.\n    if layout == 'random':\n        reals[:], labels[:] = training_set.get_minibatch_np(gw * gh)\n\n    # Class-conditional layouts.\n    class_layouts = dict(row_per_class=[gw,1], col_per_class=[1,gh], class4x4=[4,4])\n    if layout in class_layouts:\n        bw, bh = class_layouts[layout]\n        nw = (gw - 1) // bw + 1\n        nh = (gh - 1) // bh + 1\n        blocks = [[] for _i in range(nw * nh)]\n        for _iter in range(1000000):\n            real, label = training_set.get_minibatch_np(1)\n            idx = np.argmax(label[0])\n            while idx < len(blocks) and len(blocks[idx]) >= bw * bh:\n                idx += training_set.label_size\n            if idx < len(blocks):\n                blocks[idx].append((real, label))\n                if all(len(block) >= bw * bh for block in blocks):\n                    break\n        for i, block in enumerate(blocks):\n            for j, (real, label) in enumerate(block):\n                x = (i %  nw) * bw + j %  bw\n                y = (i // nw) * bh + j // bw\n                if x < gw and y < gh:\n                    reals[x + y * gw] = real[0]\n                    labels[x + y * gw] = label[0]\n\n    return (gw, gh), reals, labels\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/training/networks_stylegan.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Network architectures used in the StyleGAN paper.\"\"\"\n\nimport numpy as np\nimport tensorflow as tf\nimport dnnlib\nimport dnnlib.tflib as tflib\n\n# NOTE: Do not import any application-specific modules here!\n# Specify all network parameters as kwargs.\n\ndef _i(x): return tf.transpose(x, [0,2,3,1])\ndef _o(x): return tf.transpose(x, [0,3,1,2])\n\n#----------------------------------------------------------------------------\n# Primitive ops for manipulating 4D activation tensors.\n# The gradients of these are not necessary efficient or even meaningful.\n\ndef _blur2d(x, f=[1,2,1], normalize=True, flip=False, stride=1):\n    assert x.shape.ndims == 4 and all(dim.value is not None for dim in x.shape[1:])\n    assert isinstance(stride, int) and stride >= 1\n\n    # Finalize filter kernel.\n    f = np.array(f, dtype=np.float32)\n    if f.ndim == 1:\n        f = f[:, np.newaxis] * f[np.newaxis, :]\n    assert f.ndim == 2\n    if normalize:\n        f /= np.sum(f)\n    if flip:\n        f = f[::-1, ::-1]\n    f = f[:, :, np.newaxis, np.newaxis]\n    f = np.tile(f, [1, 1, int(x.shape[1]), 1])\n\n    # No-op => early exit.\n    if f.shape == (1, 1) and f[0,0] == 1:\n        return x\n\n    # Convolve using depthwise_conv2d.\n    orig_dtype = x.dtype\n    x = tf.cast(x, tf.float32)  # tf.nn.depthwise_conv2d() doesn't support fp16\n    f = tf.constant(f, dtype=x.dtype, name='filter')\n    strides = [1, stride, stride, 1]\n    x = _o(tf.nn.depthwise_conv2d(_i(x), f, strides=strides, padding='SAME', data_format='NHWC'))\n    x = tf.cast(x, orig_dtype)\n    return x\n\ndef _upscale2d(x, factor=2, gain=1):\n    assert x.shape.ndims == 4 and all(dim.value is not None for dim in x.shape[1:])\n    assert isinstance(factor, int) and factor >= 1\n\n    # Apply gain.\n    if gain != 1:\n        x *= gain\n\n    # No-op => early exit.\n    if factor == 1:\n        return x\n\n    # Upscale using tf.tile().\n    s = x.shape\n    x = tf.reshape(x, [-1, s[1], s[2], 1, s[3], 1])\n    x = tf.tile(x, [1, 1, 1, factor, 1, factor])\n    x = tf.reshape(x, [-1, s[1], s[2] * factor, s[3] * factor])\n    return x\n\ndef _downscale2d(x, factor=2, gain=1):\n    assert x.shape.ndims == 4 and all(dim.value is not None for dim in x.shape[1:])\n    assert isinstance(factor, int) and factor >= 1\n\n    # 2x2, float32 => downscale using _blur2d().\n    if factor == 2 and x.dtype == tf.float32:\n        f = [np.sqrt(gain) / factor] * factor\n        return _blur2d(x, f=f, normalize=False, stride=factor)\n\n    # Apply gain.\n    if gain != 1:\n        x *= gain\n\n    # No-op => early exit.\n    if factor == 1:\n        return x\n\n    # Large factor => downscale using tf.nn.avg_pool().\n    # NOTE: Requires tf_config['graph_options.place_pruned_graph']=True to work.\n    ksize = [1, factor, factor, 1]\n    return _o(tf.nn.avg_pool(_i(x), ksize=ksize, strides=ksize, padding='VALID', data_format='NHWC'))\n\n#----------------------------------------------------------------------------\n# High-level ops for manipulating 4D activation tensors.\n# The gradients of these are meant to be as efficient as possible.\n\ndef blur2d(x, f=[1,2,1], normalize=True):\n    with tf.variable_scope('Blur2D'):\n        @tf.custom_gradient\n        def func(x):\n            y = _blur2d(x, f, normalize)\n            @tf.custom_gradient\n            def grad(dy):\n                dx = _blur2d(dy, f, normalize, flip=True)\n                return dx, lambda ddx: _blur2d(ddx, f, normalize)\n            return y, grad\n        return func(x)\n\ndef upscale2d(x, factor=2):\n    with tf.variable_scope('Upscale2D'):\n        @tf.custom_gradient\n        def func(x):\n            y = _upscale2d(x, factor)\n            @tf.custom_gradient\n            def grad(dy):\n                dx = _downscale2d(dy, factor, gain=factor**2)\n                return dx, lambda ddx: _upscale2d(ddx, factor)\n            return y, grad\n        return func(x)\n\ndef downscale2d(x, factor=2):\n    with tf.variable_scope('Downscale2D'):\n        @tf.custom_gradient\n        def func(x):\n            y = _downscale2d(x, factor)\n            @tf.custom_gradient\n            def grad(dy):\n                dx = _upscale2d(dy, factor, gain=1/factor**2)\n                return dx, lambda ddx: _downscale2d(ddx, factor)\n            return y, grad\n        return func(x)\n\n#----------------------------------------------------------------------------\n# Get/create weight tensor for a convolutional or fully-connected layer.\n\ndef get_weight(shape, gain=np.sqrt(2), use_wscale=False, lrmul=1):\n    fan_in = np.prod(shape[:-1]) # [kernel, kernel, fmaps_in, fmaps_out] or [in, out]\n    he_std = gain / np.sqrt(fan_in) # He init\n\n    # Equalized learning rate and custom learning rate multiplier.\n    if use_wscale:\n        init_std = 1.0 / lrmul\n        runtime_coef = he_std * lrmul\n    else:\n        init_std = he_std / lrmul\n        runtime_coef = lrmul\n\n    # Create variable.\n    init = tf.initializers.random_normal(0, init_std)\n    return tf.get_variable('weight', shape=shape, initializer=init) * runtime_coef\n\n#----------------------------------------------------------------------------\n# Fully-connected layer.\n\ndef dense(x, fmaps, **kwargs):\n    if len(x.shape) > 2:\n        x = tf.reshape(x, [-1, np.prod([d.value for d in x.shape[1:]])])\n    w = get_weight([x.shape[1].value, fmaps], **kwargs)\n    w = tf.cast(w, x.dtype)\n    return tf.matmul(x, w)\n\n#----------------------------------------------------------------------------\n# Convolutional layer.\n\ndef conv2d(x, fmaps, kernel, **kwargs):\n    assert kernel >= 1 and kernel % 2 == 1\n    w = get_weight([kernel, kernel, x.shape[1].value, fmaps], **kwargs)\n    w = tf.cast(w, x.dtype)\n    return _o(tf.nn.conv2d(_i(x), w, strides=[1,1,1,1], padding='SAME', data_format='NHWC'))\n\n#----------------------------------------------------------------------------\n# Fused convolution + scaling.\n# Faster and uses less memory than performing the operations separately.\n\ndef upscale2d_conv2d(x, fmaps, kernel, fused_scale='auto', **kwargs):\n    assert kernel >= 1 and kernel % 2 == 1\n    assert fused_scale in [True, False, 'auto']\n    if fused_scale == 'auto':\n        fused_scale = min(x.shape[2:]) * 2 >= 128\n\n    # Not fused => call the individual ops directly.\n    if not fused_scale:\n        return conv2d(upscale2d(x), fmaps, kernel, **kwargs)\n\n    # Fused => perform both ops simultaneously using tf.nn.conv2d_transpose().\n    w = get_weight([kernel, kernel, x.shape[1].value, fmaps], **kwargs)\n    w = tf.transpose(w, [0, 1, 3, 2]) # [kernel, kernel, fmaps_out, fmaps_in]\n    w = tf.pad(w, [[1,1], [1,1], [0,0], [0,0]], mode='CONSTANT')\n    w = tf.add_n([w[1:, 1:], w[:-1, 1:], w[1:, :-1], w[:-1, :-1]])\n    w = tf.cast(w, x.dtype)\n    os = [tf.shape(x)[0], x.shape[2] * 2, x.shape[3] * 2, fmaps]\n    return _o(tf.nn.conv2d_transpose(_i(x), w, os, strides=[1,2,2,1], padding='SAME', data_format='NHWC'))\n\ndef conv2d_downscale2d(x, fmaps, kernel, fused_scale='auto', **kwargs):\n    assert kernel >= 1 and kernel % 2 == 1\n    assert fused_scale in [True, False, 'auto']\n    if fused_scale == 'auto':\n        fused_scale = min(x.shape[2:]) >= 128\n\n    # Not fused => call the individual ops directly.\n    if not fused_scale:\n        return downscale2d(conv2d(x, fmaps, kernel, **kwargs))\n\n    # Fused => perform both ops simultaneously using tf.nn.conv2d().\n    w = get_weight([kernel, kernel, x.shape[1].value, fmaps], **kwargs)\n    w = tf.pad(w, [[1,1], [1,1], [0,0], [0,0]], mode='CONSTANT')\n    w = tf.add_n([w[1:, 1:], w[:-1, 1:], w[1:, :-1], w[:-1, :-1]]) * 0.25\n    w = tf.cast(w, x.dtype)\n    return _o(tf.nn.conv2d(_i(x), w, strides=[1,2,2,1], padding='SAME', data_format='NHWC'))\n\n#----------------------------------------------------------------------------\n# Apply bias to the given activation tensor.\n\ndef apply_bias(x, lrmul=1):\n    b = tf.get_variable('bias', shape=[x.shape[1]], initializer=tf.initializers.zeros()) * lrmul\n    b = tf.cast(b, x.dtype)\n    if len(x.shape) == 2:\n        return x + b\n    return x + tf.reshape(b, [1, -1, 1, 1])\n\n#----------------------------------------------------------------------------\n# Leaky ReLU activation. More efficient than tf.nn.leaky_relu() and supports FP16.\n\ndef leaky_relu(x, alpha=0.2):\n    with tf.variable_scope('LeakyReLU'):\n        alpha = tf.constant(alpha, dtype=x.dtype, name='alpha')\n        @tf.custom_gradient\n        def func(x):\n            y = tf.maximum(x, x * alpha)\n            @tf.custom_gradient\n            def grad(dy):\n                dx = tf.where(y >= 0, dy, dy * alpha)\n                return dx, lambda ddx: tf.where(y >= 0, ddx, ddx * alpha)\n            return y, grad\n        return func(x)\n\n#----------------------------------------------------------------------------\n# Pixelwise feature vector normalization.\n\ndef pixel_norm(x, epsilon=1e-8):\n    with tf.variable_scope('PixelNorm'):\n        epsilon = tf.constant(epsilon, dtype=x.dtype, name='epsilon')\n        return x * tf.rsqrt(tf.reduce_mean(tf.square(x), axis=1, keepdims=True) + epsilon)\n\n#----------------------------------------------------------------------------\n# Instance normalization.\n\ndef instance_norm(x, epsilon=1e-8):\n    assert len(x.shape) == 4 # NCHW\n    with tf.variable_scope('InstanceNorm'):\n        orig_dtype = x.dtype\n        x = tf.cast(x, tf.float32)\n        x -= tf.reduce_mean(x, axis=[2,3], keepdims=True)\n        epsilon = tf.constant(epsilon, dtype=x.dtype, name='epsilon')\n        x *= tf.rsqrt(tf.reduce_mean(tf.square(x), axis=[2,3], keepdims=True) + epsilon)\n        x = tf.cast(x, orig_dtype)\n        return x\n\n#----------------------------------------------------------------------------\n# Style modulation.\n\ndef style_mod(x, dlatent, **kwargs):\n    with tf.variable_scope('StyleMod'):\n        style = apply_bias(dense(dlatent, fmaps=x.shape[1]*2, gain=1, **kwargs))\n        style = tf.reshape(style, [-1, 2, x.shape[1]] + [1] * (len(x.shape) - 2))\n        return x * (style[:,0] + 1) + style[:,1]\n\n#----------------------------------------------------------------------------\n# Noise input.\n\ndef apply_noise(x, noise_var=None, randomize_noise=True):\n    assert len(x.shape) == 4 # NCHW\n    with tf.variable_scope('Noise'):\n        if noise_var is None or randomize_noise:\n            noise = tf.random_normal([tf.shape(x)[0], 1, x.shape[2], x.shape[3]], dtype=x.dtype)\n        else:\n            noise = tf.cast(noise_var, x.dtype)\n        weight = tf.get_variable('weight', shape=[x.shape[1].value], initializer=tf.initializers.zeros())\n        return x + noise * tf.reshape(tf.cast(weight, x.dtype), [1, -1, 1, 1])\n\n#----------------------------------------------------------------------------\n# Minibatch standard deviation.\n\ndef minibatch_stddev_layer(x, group_size=4, num_new_features=1):\n    with tf.variable_scope('MinibatchStddev'):\n        group_size = tf.minimum(group_size, tf.shape(x)[0])     # Minibatch must be divisible by (or smaller than) group_size.\n        s = x.shape                                             # [NCHW]  Input shape.\n        y = tf.reshape(x, [group_size, -1, num_new_features, s[1]//num_new_features, s[2], s[3]])   # [GMncHW] Split minibatch into M groups of size G. Split channels into n channel groups c.\n        y = tf.cast(y, tf.float32)                              # [GMncHW] Cast to FP32.\n        y -= tf.reduce_mean(y, axis=0, keepdims=True)           # [GMncHW] Subtract mean over group.\n        y = tf.reduce_mean(tf.square(y), axis=0)                # [MncHW]  Calc variance over group.\n        y = tf.sqrt(y + 1e-8)                                   # [MncHW]  Calc stddev over group.\n        y = tf.reduce_mean(y, axis=[2,3,4], keepdims=True)      # [Mn111]  Take average over fmaps and pixels.\n        y = tf.reduce_mean(y, axis=[2])                         # [Mn11] Split channels into c channel groups\n        y = tf.cast(y, x.dtype)                                 # [Mn11]  Cast back to original data type.\n        y = tf.tile(y, [group_size, 1, s[2], s[3]])             # [NnHW]  Replicate over group and pixels.\n        return tf.concat([x, y], axis=1)                        # [NCHW]  Append as new fmap.\n\n#----------------------------------------------------------------------------\n# Style-based generator used in the StyleGAN paper.\n# Composed of two sub-networks (G_mapping and G_synthesis) that are defined below.\n\ndef G_style(\n    latents_in,                                     # First input: Latent vectors (Z) [minibatch, latent_size].\n    labels_in,                                      # Second input: Conditioning labels [minibatch, label_size].\n    truncation_psi          = 0.7,                  # Style strength multiplier for the truncation trick. None = disable.\n    truncation_cutoff       = 8,                    # Number of layers for which to apply the truncation trick. None = disable.\n    truncation_psi_val      = None,                 # Value for truncation_psi to use during validation.\n    truncation_cutoff_val   = None,                 # Value for truncation_cutoff to use during validation.\n    dlatent_avg_beta        = 0.995,                # Decay for tracking the moving average of W during training. None = disable.\n    style_mixing_prob       = 0.9,                  # Probability of mixing styles during training. None = disable.\n    is_training             = False,                # Network is under training? Enables and disables specific features.\n    is_validation           = False,                # Network is under validation? Chooses which value to use for truncation_psi.\n    is_template_graph       = False,                # True = template graph constructed by the Network class, False = actual evaluation.\n    components              = dnnlib.EasyDict(),    # Container for sub-networks. Retained between calls.\n    **kwargs):                                      # Arguments for sub-networks (G_mapping and G_synthesis).\n\n    # Validate arguments.\n    assert not is_training or not is_validation\n    assert isinstance(components, dnnlib.EasyDict)\n    if is_validation:\n        truncation_psi = truncation_psi_val\n        truncation_cutoff = truncation_cutoff_val\n    if is_training or (truncation_psi is not None and not tflib.is_tf_expression(truncation_psi) and truncation_psi == 1):\n        truncation_psi = None\n    if is_training or (truncation_cutoff is not None and not tflib.is_tf_expression(truncation_cutoff) and truncation_cutoff <= 0):\n        truncation_cutoff = None\n    if not is_training or (dlatent_avg_beta is not None and not tflib.is_tf_expression(dlatent_avg_beta) and dlatent_avg_beta == 1):\n        dlatent_avg_beta = None\n    if not is_training or (style_mixing_prob is not None and not tflib.is_tf_expression(style_mixing_prob) and style_mixing_prob <= 0):\n        style_mixing_prob = None\n\n    # Setup components.\n    if 'synthesis' not in components:\n        components.synthesis = tflib.Network('G_synthesis', func_name=G_synthesis, **kwargs)\n    num_layers = components.synthesis.input_shape[1]\n    dlatent_size = components.synthesis.input_shape[2]\n    if 'mapping' not in components:\n        components.mapping = tflib.Network('G_mapping', func_name=G_mapping, dlatent_broadcast=num_layers, **kwargs)\n\n    # Setup variables.\n    lod_in = tf.get_variable('lod', initializer=np.float32(0), trainable=False)\n    dlatent_avg = tf.get_variable('dlatent_avg', shape=[dlatent_size], initializer=tf.initializers.zeros(), trainable=False)\n\n    # Evaluate mapping network.\n    dlatents = components.mapping.get_output_for(latents_in, labels_in, **kwargs)\n\n    # Update moving average of W.\n    if dlatent_avg_beta is not None:\n        with tf.variable_scope('DlatentAvg'):\n            batch_avg = tf.reduce_mean(dlatents[:, 0], axis=0)\n            update_op = tf.assign(dlatent_avg, tflib.lerp(batch_avg, dlatent_avg, dlatent_avg_beta))\n            with tf.control_dependencies([update_op]):\n                dlatents = tf.identity(dlatents)\n\n    # Perform style mixing regularization.\n    if style_mixing_prob is not None:\n        with tf.name_scope('StyleMix'):\n            latents2 = tf.random_normal(tf.shape(latents_in))\n            dlatents2 = components.mapping.get_output_for(latents2, labels_in, **kwargs)\n            layer_idx = np.arange(num_layers)[np.newaxis, :, np.newaxis]\n            cur_layers = num_layers - tf.cast(lod_in, tf.int32) * 2\n            mixing_cutoff = tf.cond(\n                tf.random_uniform([], 0.0, 1.0) < style_mixing_prob,\n                lambda: tf.random_uniform([], 1, cur_layers, dtype=tf.int32),\n                lambda: cur_layers)\n            dlatents = tf.where(tf.broadcast_to(layer_idx < mixing_cutoff, tf.shape(dlatents)), dlatents, dlatents2)\n\n    # Apply truncation trick.\n    if truncation_psi is not None and truncation_cutoff is not None:\n        with tf.variable_scope('Truncation'):\n            layer_idx = np.arange(num_layers)[np.newaxis, :, np.newaxis]\n            ones = np.ones(layer_idx.shape, dtype=np.float32)\n            coefs = tf.where(layer_idx < truncation_cutoff, truncation_psi * ones, ones)\n            dlatents = tflib.lerp(dlatent_avg, dlatents, coefs)\n\n    # Evaluate synthesis network.\n    with tf.control_dependencies([tf.assign(components.synthesis.find_var('lod'), lod_in)]):\n        images_out = components.synthesis.get_output_for(dlatents, force_clean_graph=is_template_graph, **kwargs)\n    return tf.identity(images_out, name='images_out')\n\n#----------------------------------------------------------------------------\n# Mapping network used in the StyleGAN paper.\n\ndef G_mapping(\n    latents_in,                             # First input: Latent vectors (Z) [minibatch, latent_size].\n    labels_in,                              # Second input: Conditioning labels [minibatch, label_size].\n    latent_size             = 512,          # Latent vector (Z) dimensionality.\n    label_size              = 0,            # Label dimensionality, 0 if no labels.\n    dlatent_size            = 512,          # Disentangled latent (W) dimensionality.\n    dlatent_broadcast       = None,         # Output disentangled latent (W) as [minibatch, dlatent_size] or [minibatch, dlatent_broadcast, dlatent_size].\n    mapping_layers          = 8,            # Number of mapping layers.\n    mapping_fmaps           = 512,          # Number of activations in the mapping layers.\n    mapping_lrmul           = 0.01,         # Learning rate multiplier for the mapping layers.\n    mapping_nonlinearity    = 'lrelu',      # Activation function: 'relu', 'lrelu'.\n    use_wscale              = True,         # Enable equalized learning rate?\n    normalize_latents       = False,         # Normalize latent vectors (Z) before feeding them to the mapping layers?\n    dtype                   = 'float32',    # Data type to use for activations and outputs.\n    **_kwargs):                             # Ignore unrecognized keyword args.\n\n    act, gain = {'relu': (tf.nn.relu, np.sqrt(2)), 'lrelu': (leaky_relu, np.sqrt(2))}[mapping_nonlinearity]\n\n    # Inputs.\n    latents_in.set_shape([None, latent_size])\n    labels_in.set_shape([None, label_size])\n    latents_in = tf.cast(latents_in, dtype)\n    labels_in = tf.cast(labels_in, dtype)\n    x = latents_in\n\n    # Embed labels and concatenate them with latents.\n    if label_size:\n        with tf.variable_scope('LabelConcat'):\n            w = tf.get_variable('weight', shape=[label_size, latent_size], initializer=tf.initializers.random_normal())\n            y = tf.matmul(labels_in, tf.cast(w, dtype))\n            x = tf.concat([x, y], axis=1)\n\n    # Normalize latents.\n    if normalize_latents:\n        x = pixel_norm(x)\n\n    # Mapping layers.\n    for layer_idx in range(mapping_layers):\n        with tf.variable_scope('Dense%d' % layer_idx):\n            fmaps = dlatent_size if layer_idx == mapping_layers - 1 else mapping_fmaps\n            x = dense(x, fmaps=fmaps, gain=gain, use_wscale=use_wscale, lrmul=mapping_lrmul)\n            x = apply_bias(x, lrmul=mapping_lrmul)\n            x = act(x)\n\n    # Broadcast.\n    if dlatent_broadcast is not None:\n        with tf.variable_scope('Broadcast'):\n            x = tf.tile(x[:, np.newaxis], [1, dlatent_broadcast, 1])\n\n    # Output.\n    assert x.dtype == tf.as_dtype(dtype)\n    return tf.identity(x, name='dlatents_out')\n\n#----------------------------------------------------------------------------\n# Synthesis network used in the StyleGAN paper.\n\ndef G_synthesis(\n    dlatents_in,                        # Input: Disentangled latents (W) [minibatch, num_layers, dlatent_size].\n    dlatent_size        = 512,          # Disentangled latent (W) dimensionality.\n    num_channels        = 3,            # Number of output color channels.\n    resolution          = 1024,         # Output resolution.\n    fmap_base           = 8192,         # Overall multiplier for the number of feature maps.\n    fmap_decay          = 1.0,          # log2 feature map reduction when doubling the resolution.\n    fmap_max            = 512,          # Maximum number of feature maps in any layer.\n    use_styles          = True,         # Enable style inputs?\n    const_input_layer   = True,         # First layer is a learned constant?\n    use_noise           = True,         # Enable noise inputs?\n    randomize_noise     = True,         # True = randomize noise inputs every time (non-deterministic), False = read noise inputs from variables.\n    nonlinearity        = 'lrelu',      # Activation function: 'relu', 'lrelu'\n    use_wscale          = True,         # Enable equalized learning rate?\n    use_pixel_norm      = False,        # Enable pixelwise feature vector normalization?\n    use_instance_norm   = True,         # Enable instance normalization?\n    dtype               = 'float32',    # Data type to use for activations and outputs.\n    fused_scale         = 'auto',       # True = fused convolution + scaling, False = separate ops, 'auto' = decide automatically.\n    blur_filter         = [1,2,1],      # Low-pass filter to apply when resampling activations. None = no filtering.\n    structure           = 'auto',       # 'fixed' = no progressive growing, 'linear' = human-readable, 'recursive' = efficient, 'auto' = select automatically.\n    is_template_graph   = False,        # True = template graph constructed by the Network class, False = actual evaluation.\n    force_clean_graph   = False,        # True = construct a clean graph that looks nice in TensorBoard, False = default behavior.\n    **_kwargs):                         # Ignore unrecognized keyword args.\n\n    resolution_log2 = int(np.log2(resolution))\n    assert resolution == 2**resolution_log2 and resolution >= 4\n    def nf(stage): return min(int(fmap_base / (2.0 ** (stage * fmap_decay))), fmap_max)\n    def blur(x): return blur2d(x, blur_filter) if blur_filter else x\n    if is_template_graph: force_clean_graph = True\n    if force_clean_graph: randomize_noise = False\n    if structure == 'auto': structure = 'linear' if force_clean_graph else 'recursive'\n    act, gain = {'relu': (tf.nn.relu, np.sqrt(2)), 'lrelu': (leaky_relu, np.sqrt(2))}[nonlinearity]\n    num_layers = resolution_log2 * 2 - 2\n    num_styles = num_layers if use_styles else 1\n    images_out = None\n\n    # Primary inputs.\n    dlatents_in.set_shape([None, num_styles, dlatent_size])\n    dlatents_in = tf.cast(dlatents_in, dtype)\n    lod_in = tf.cast(tf.get_variable('lod', initializer=np.float32(0), trainable=False), dtype)\n\n    # Noise inputs.\n    noise_inputs = []\n    if use_noise:\n        for layer_idx in range(num_layers):\n            res = layer_idx // 2 + 2\n            shape = [1, use_noise, 2**res, 2**res]\n            noise_inputs.append(tf.get_variable('noise%d' % layer_idx, shape=shape, initializer=tf.initializers.random_normal(), trainable=False))\n\n    # Things to do at the end of each layer.\n    def layer_epilogue(x, layer_idx):\n        if use_noise:\n            x = apply_noise(x, noise_inputs[layer_idx], randomize_noise=randomize_noise)\n        x = apply_bias(x)\n        x = act(x)\n        if use_pixel_norm:\n            x = pixel_norm(x)\n        if use_instance_norm:\n            x = instance_norm(x)\n        if use_styles:\n            x = style_mod(x, dlatents_in[:, layer_idx], use_wscale=use_wscale)\n        return x\n\n    # Early layers.\n    with tf.variable_scope('4x4'):\n        if const_input_layer:\n            with tf.variable_scope('Const'):\n                x = tf.get_variable('const', shape=[1, nf(1), 4, 4], initializer=tf.initializers.ones())\n                x = layer_epilogue(tf.tile(tf.cast(x, dtype), [tf.shape(dlatents_in)[0], 1, 1, 1]), 0)\n        else:\n            with tf.variable_scope('Dense'):\n                x = dense(dlatents_in[:, 0], fmaps=nf(1)*16, gain=gain/4, use_wscale=use_wscale) # tweak gain to match the official implementation of Progressing GAN\n                x = layer_epilogue(tf.reshape(x, [-1, nf(1), 4, 4]), 0)\n        with tf.variable_scope('Conv'):\n            x = layer_epilogue(conv2d(x, fmaps=nf(1), kernel=3, gain=gain, use_wscale=use_wscale), 1)\n\n    # Building blocks for remaining layers.\n    def block(res, x): # res = 3..resolution_log2\n        with tf.variable_scope('%dx%d' % (2**res, 2**res)):\n            with tf.variable_scope('Conv0_up'):\n                x = layer_epilogue(blur(upscale2d_conv2d(x, fmaps=nf(res-1), kernel=3, gain=gain, use_wscale=use_wscale, fused_scale=fused_scale)), res*2-4)\n            with tf.variable_scope('Conv1'):\n                x = layer_epilogue(conv2d(x, fmaps=nf(res-1), kernel=3, gain=gain, use_wscale=use_wscale), res*2-3)\n            return x\n    def torgb(res, x): # res = 2..resolution_log2\n        lod = resolution_log2 - res\n        with tf.variable_scope('ToRGB_lod%d' % lod):\n            return apply_bias(conv2d(x, fmaps=num_channels, kernel=1, gain=1, use_wscale=use_wscale))\n\n    # Fixed structure: simple and efficient, but does not support progressive growing.\n    if structure == 'fixed':\n        for res in range(3, resolution_log2 + 1):\n            x = block(res, x)\n        images_out = torgb(resolution_log2, x)\n\n    # Linear structure: simple but inefficient.\n    if structure == 'linear':\n        images_out = torgb(2, x)\n        for res in range(3, resolution_log2 + 1):\n            lod = resolution_log2 - res\n            x = block(res, x)\n            img = torgb(res, x)\n            images_out = upscale2d(images_out)\n            with tf.variable_scope('Grow_lod%d' % lod):\n                images_out = tflib.lerp_clip(img, images_out, lod_in - lod)\n\n    # Recursive structure: complex but efficient.\n    if structure == 'recursive':\n        def cset(cur_lambda, new_cond, new_lambda):\n            return lambda: tf.cond(new_cond, new_lambda, cur_lambda)\n        def grow(x, res, lod):\n            y = block(res, x)\n            img = lambda: upscale2d(torgb(res, y), 2**lod)\n            img = cset(img, (lod_in > lod), lambda: upscale2d(tflib.lerp(torgb(res, y), upscale2d(torgb(res - 1, x)), lod_in - lod), 2**lod))\n            if lod > 0: img = cset(img, (lod_in < lod), lambda: grow(y, res + 1, lod - 1))\n            return img()\n        images_out = grow(x, 3, resolution_log2 - 3)\n\n    assert images_out.dtype == tf.as_dtype(dtype)\n    return tf.identity(images_out, name='images_out')\n\n#----------------------------------------------------------------------------\n# Discriminator used in the StyleGAN paper.\n\ndef D_basic(\n    images_in,                          # First input: Images [minibatch, channel, height, width].\n    labels_in,                          # Second input: Labels [minibatch, label_size].\n    num_channels        = 1,            # Number of input color channels. Overridden based on dataset.\n    resolution          = 32,           # Input resolution. Overridden based on dataset.\n    label_size          = 0,            # Dimensionality of the labels, 0 if no labels. Overridden based on dataset.\n    fmap_base           = 8192,         # Overall multiplier for the number of feature maps.\n    fmap_decay          = 1.0,          # log2 feature map reduction when doubling the resolution.\n    fmap_max            = 512,          # Maximum number of feature maps in any layer.\n    nonlinearity        = 'lrelu',      # Activation function: 'relu', 'lrelu',\n    use_wscale          = True,         # Enable equalized learning rate?\n    mbstd_group_size    = 4,            # Group size for the minibatch standard deviation layer, 0 = disable.\n    mbstd_num_features  = 1,            # Number of features for the minibatch standard deviation layer.\n    dtype               = 'float32',    # Data type to use for activations and outputs.\n    fused_scale         = 'auto',       # True = fused convolution + scaling, False = separate ops, 'auto' = decide automatically.\n    blur_filter         = [1,2,1],      # Low-pass filter to apply when resampling activations. None = no filtering.\n    structure           = 'auto',       # 'fixed' = no progressive growing, 'linear' = human-readable, 'recursive' = efficient, 'auto' = select automatically.\n    is_template_graph   = False,        # True = template graph constructed by the Network class, False = actual evaluation.\n    **_kwargs):                         # Ignore unrecognized keyword args.\n\n    resolution_log2 = int(np.log2(resolution))\n    assert resolution == 2**resolution_log2 and resolution >= 4\n    def nf(stage): return min(int(fmap_base / (2.0 ** (stage * fmap_decay))), fmap_max)\n    def blur(x): return blur2d(x, blur_filter) if blur_filter else x\n    if structure == 'auto': structure = 'linear' if is_template_graph else 'recursive'\n    act, gain = {'relu': (tf.nn.relu, np.sqrt(2)), 'lrelu': (leaky_relu, np.sqrt(2))}[nonlinearity]\n\n    images_in.set_shape([None, num_channels, resolution, resolution])\n    labels_in.set_shape([None, label_size])\n    images_in = tf.cast(images_in, dtype)\n    labels_in = tf.cast(labels_in, dtype)\n    lod_in = tf.cast(tf.get_variable('lod', initializer=np.float32(0.0), trainable=False), dtype)\n    scores_out = None\n\n    # Building blocks.\n    def fromrgb(x, res): # res = 2..resolution_log2\n        with tf.variable_scope('FromRGB_lod%d' % (resolution_log2 - res)):\n            return act(apply_bias(conv2d(x, fmaps=nf(res-1), kernel=1, gain=gain, use_wscale=use_wscale)))\n    def block(x, res): # res = 2..resolution_log2\n        with tf.variable_scope('%dx%d' % (2**res, 2**res)):\n            if res >= 3: # 8x8 and up\n                with tf.variable_scope('Conv0'):\n                    x = act(apply_bias(conv2d(x, fmaps=nf(res-1), kernel=3, gain=gain, use_wscale=use_wscale)))\n                with tf.variable_scope('Conv1_down'):\n                    x = act(apply_bias(conv2d_downscale2d(blur(x), fmaps=nf(res-2), kernel=3, gain=gain, use_wscale=use_wscale, fused_scale=fused_scale)))\n            else: # 4x4\n                if mbstd_group_size > 1:\n                    x = minibatch_stddev_layer(x, mbstd_group_size, mbstd_num_features)\n                with tf.variable_scope('Conv'):\n                    x = act(apply_bias(conv2d(x, fmaps=nf(res-1), kernel=3, gain=gain, use_wscale=use_wscale)))\n                with tf.variable_scope('Dense0'):\n                    x = act(apply_bias(dense(x, fmaps=nf(res-2), gain=gain, use_wscale=use_wscale)))\n                with tf.variable_scope('Dense1'):\n                    x = apply_bias(dense(x, fmaps=max(label_size, 1), gain=1, use_wscale=use_wscale))\n            return x\n\n    # Fixed structure: simple and efficient, but does not support progressive growing.\n    if structure == 'fixed':\n        x = fromrgb(images_in, resolution_log2)\n        for res in range(resolution_log2, 2, -1):\n            x = block(x, res)\n        scores_out = block(x, 2)\n\n    # Linear structure: simple but inefficient.\n    if structure == 'linear':\n        img = images_in\n        x = fromrgb(img, resolution_log2)\n        for res in range(resolution_log2, 2, -1):\n            lod = resolution_log2 - res\n            x = block(x, res)\n            img = downscale2d(img)\n            y = fromrgb(img, res - 1)\n            with tf.variable_scope('Grow_lod%d' % lod):\n                x = tflib.lerp_clip(x, y, lod_in - lod)\n        scores_out = block(x, 2)\n\n    # Recursive structure: complex but efficient.\n    if structure == 'recursive':\n        def cset(cur_lambda, new_cond, new_lambda):\n            return lambda: tf.cond(new_cond, new_lambda, cur_lambda)\n        def grow(res, lod):\n            x = lambda: fromrgb(downscale2d(images_in, 2**lod), res)\n            if lod > 0: x = cset(x, (lod_in < lod), lambda: grow(res + 1, lod - 1))\n            x = block(x(), res); y = lambda: x\n            if res > 2: y = cset(y, (lod_in > lod), lambda: tflib.lerp(x, fromrgb(downscale2d(images_in, 2**(lod+1)), res - 1), lod_in - lod))\n            return y()\n        scores_out = grow(2, resolution_log2 - 2)\n\n    # Label conditioning from \"Which Training Methods for GANs do actually Converge?\"\n    if label_size:\n        with tf.variable_scope('LabelSwitch'):\n            scores_out = tf.reduce_sum(scores_out * labels_in, axis=1, keepdims=True)\n\n    assert scores_out.dtype == tf.as_dtype(dtype)\n    scores_out = tf.identity(scores_out, name='scores_out')\n    return scores_out\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/training/networks_stylegan2.py",
    "content": "﻿# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Network architectures used in the StyleGAN2 paper.\"\"\"\n\nimport os\nimport numpy as np\nimport tensorflow as tf\nimport dnnlib\nimport dnnlib.tflib as tflib\nfrom dnnlib.tflib.ops.upfirdn_2d import upsample_2d, downsample_2d, upsample_conv_2d, conv_downsample_2d\nfrom dnnlib.tflib.ops.fused_bias_act import fused_bias_act\nimport functools\nfrom dnnlib.tflib.autosummary import autosummary, autoimages\n\n# NOTE: Do not import any application-specific modules here!\n# Specify all network parameters as kwargs.\n\ndef _i(x): return tf.transpose(x, [0,2,3,1])\ndef _o(x): return tf.transpose(x, [0,3,1,2])\n\n#----------------------------------------------------------------------------\n# Get/create weight tensor for a convolution or fully-connected layer.\n\ndef get_weight(shape, gain=1, use_wscale=True, lrmul=1, weight_var='weight'):\n    fan_in = np.prod(shape[:-1]) # [kernel, kernel, fmaps_in, fmaps_out] or [in, out]\n    he_std = gain / np.sqrt(fan_in) # He init\n\n    # Equalized learning rate and custom learning rate multiplier.\n    if use_wscale:\n        init_std = 1.0 / lrmul\n        runtime_coef = he_std * lrmul\n    else:\n        init_std = he_std / lrmul\n        runtime_coef = lrmul\n\n    # Create variable.\n    init = tf.initializers.random_normal(0, init_std)\n    return tf.get_variable(weight_var, shape=shape, initializer=init, use_resource=True) * runtime_coef\n\n#----------------------------------------------------------------------------\n# Fully-connected layer.\n\ndef dense_layer(x, fmaps, gain=1, use_wscale=True, lrmul=1, weight_var='weight'):\n    if len(x.shape) > 2:\n        x = tf.reshape(x, [-1, np.prod([d.value for d in x.shape[1:]])])\n    w = get_weight([x.shape[1].value, fmaps], gain=gain, use_wscale=use_wscale, lrmul=lrmul, weight_var=weight_var)\n    w = tf.cast(w, x.dtype)\n    return tf.matmul(x, w)\n\n#----------------------------------------------------------------------------\n# Convolution layer with optional upsampling or downsampling.\n\ndef conv2d_layer(x, fmaps, kernel, up=False, down=False, resample_kernel=None, gain=1, use_wscale=True, lrmul=1, weight_var='weight'):\n    assert not (up and down)\n    assert kernel >= 1 and kernel % 2 == 1\n    w = graph_spectral_norm(get_weight([kernel, kernel, x.shape[1].value, fmaps], gain=gain, use_wscale=use_wscale, lrmul=lrmul, weight_var=weight_var))\n    if up:\n        x = _o(upsample_conv_2d(_i(x), tf.cast(w, x.dtype), data_format='NHWC', k=resample_kernel))\n    elif down:\n        x = _o(conv_downsample_2d(_i(x), tf.cast(w, x.dtype), data_format='NHWC', k=resample_kernel))\n    else:\n        x = _o(tf.nn.conv2d(_i(x), tf.cast(w, x.dtype), data_format='NHWC', strides=[1,1,1,1], padding='SAME'))\n    return x\n\n#----------------------------------------------------------------------------\n# Apply bias and activation func.\n\ndef apply_bias_act(x, act='linear', alpha=None, gain=None, lrmul=1, bias_var='bias'):\n    b = tf.get_variable(bias_var, shape=[x.shape[1]], initializer=tf.initializers.zeros(), use_resource=True) * lrmul\n    return fused_bias_act(x, b=tf.cast(b, x.dtype), act=act, alpha=alpha, gain=gain)\n\n#----------------------------------------------------------------------------\n# Naive upsampling (nearest neighbor) and downsampling (average pooling).\n\ndef naive_upsample_2d(x, factor=2):\n    with tf.variable_scope('NaiveUpsample'):\n        _N, C, H, W = x.shape.as_list()\n        x = tf.reshape(x, [-1, C, H, 1, W, 1])\n        x = tf.tile(x, [1, 1, 1, factor, 1, factor])\n        return tf.reshape(x, [-1, C, H * factor, W * factor])\n\ndef naive_downsample_2d(x, factor=2):\n    with tf.variable_scope('NaiveDownsample'):\n        _N, C, H, W = x.shape.as_list()\n        x = tf.reshape(x, [-1, C, H // factor, factor, W // factor, factor])\n        return tf.reduce_mean(x, axis=[3,5])\n\n#----------------------------------------------------------------------------\n# Modulated convolution layer.\n\ndef modulated_conv2d_layer(x, y, fmaps, kernel, up=False, down=False, demodulate=True, resample_kernel=None, gain=1, use_wscale=True, lrmul=1, fused_modconv=True, weight_var='weight', mod_weight_var='mod_weight', mod_bias_var='mod_bias'):\n    assert not (up and down)\n    assert kernel >= 1 and kernel % 2 == 1\n\n    # Get weight.\n    w = graph_spectral_norm(get_weight([kernel, kernel, x.shape[1].value, fmaps], gain=gain, use_wscale=use_wscale, lrmul=lrmul, weight_var=weight_var))\n    ww = w[np.newaxis] # [BkkIO] Introduce minibatch dimension.\n\n    # Modulate.\n    s = dense_layer(y, fmaps=x.shape[1].value, weight_var=mod_weight_var) # [BI] Transform incoming W to style.\n    s = apply_bias_act(s, bias_var=mod_bias_var) + 1 # [BI] Add bias (initially 1).\n    ww *= tf.cast(s[:, np.newaxis, np.newaxis, :, np.newaxis], w.dtype) # [BkkIO] Scale input feature maps.\n\n    # Demodulate.\n    if demodulate:\n        d = tf.rsqrt(tf.reduce_sum(tf.square(ww), axis=[1,2,3]) + 1e-8) # [BO] Scaling factor.\n        ww *= d[:, np.newaxis, np.newaxis, np.newaxis, :] # [BkkIO] Scale output feature maps.\n\n    # Reshape/scale input.\n    if fused_modconv:\n        x = tf.reshape(x, [1, -1, x.shape[2], x.shape[3]]) # Fused => reshape minibatch to convolution groups.\n        w = tf.reshape(tf.transpose(ww, [1, 2, 3, 0, 4]), [ww.shape[1], ww.shape[2], ww.shape[3], -1])\n    else:\n        x *= tf.cast(s[:, :, np.newaxis, np.newaxis], x.dtype) # [BIhw] Not fused => scale input activations.\n\n    # Convolution with optional up/downsampling.\n    if up:\n        x = _o(upsample_conv_2d(_i(x), tf.cast(w, x.dtype), data_format='NHWC', k=resample_kernel))\n    elif down:\n        x = _o(conv_downsample_2d(_i(x), tf.cast(w, x.dtype), data_format='NHWC', k=resample_kernel))\n    else:\n        x = _o(tf.nn.conv2d(_i(x), tf.cast(w, x.dtype), data_format='NHWC', strides=[1,1,1,1], padding='SAME'))\n\n    # Reshape/scale output.\n    if fused_modconv:\n        x = tf.reshape(x, [-1, fmaps, x.shape[2], x.shape[3]]) # Fused => reshape convolution groups back to minibatch.\n    elif demodulate:\n        x *= tf.cast(d[:, :, np.newaxis, np.newaxis], x.dtype) # [BOhw] Not fused => scale output activations.\n    return x\n\n#----------------------------------------------------------------------------\n# Minibatch standard deviation layer.\n\ndef minibatch_stddev_layer(x, group_size=4, num_new_features=1):\n    group_size = tf.minimum(group_size, tf.shape(x)[0])     # Minibatch must be divisible by (or smaller than) group_size.\n    s = x.shape                                             # [NCHW]  Input shape.\n    y = tf.reshape(x, [group_size, -1, num_new_features, s[1]//num_new_features, s[2], s[3]])   # [GMncHW] Split minibatch into M groups of size G. Split channels into n channel groups c.\n    y = tf.cast(y, tf.float32)                              # [GMncHW] Cast to FP32.\n    y -= tf.reduce_mean(y, axis=0, keepdims=True)           # [GMncHW] Subtract mean over group.\n    y = tf.reduce_mean(tf.square(y), axis=0)                # [MncHW]  Calc variance over group.\n    y = tf.sqrt(y + 1e-8)                                   # [MncHW]  Calc stddev over group.\n    y = tf.reduce_mean(y, axis=[2,3,4], keepdims=True)      # [Mn111]  Take average over fmaps and pixels.\n    y = tf.reduce_mean(y, axis=[2])                         # [Mn11] Split channels into c channel groups\n    y = tf.cast(y, x.dtype)                                 # [Mn11]  Cast back to original data type.\n    y = tf.tile(y, [group_size, 1, s[2], s[3]])             # [NnHW]  Replicate over group and pixels.\n    return tf.concat([x, y], axis=1)                        # [NCHW]  Append as new fmap.\n\n#----------------------------------------------------------------------------\n# Main generator network.\n# Composed of two sub-networks (mapping and synthesis) that are defined below.\n# Used in configs B-F (Table 1).\n\ndef G_main(\n    latents_in,                                         # First input: Latent vectors (Z) [minibatch, latent_size].\n    labels_in,                                          # Second input: Conditioning labels [minibatch, label_size].\n    truncation_psi          = 0.5,                      # Style strength multiplier for the truncation trick. None = disable.\n    truncation_cutoff       = None,                     # Number of layers for which to apply the truncation trick. None = disable.\n    truncation_psi_val      = None,                     # Value for truncation_psi to use during validation.\n    truncation_cutoff_val   = None,                     # Value for truncation_cutoff to use during validation.\n    dlatent_avg_beta        = 0.995,                    # Decay for tracking the moving average of W during training. None = disable.\n    style_mixing_prob       = 0.9,                      # Probability of mixing styles during training. None = disable.\n    is_training             = False,                    # Network is under training? Enables and disables specific features.\n    is_validation           = False,                    # Network is under validation? Chooses which value to use for truncation_psi.\n    return_dlatents         = False,                    # Return dlatents in addition to the images?\n    is_template_graph       = False,                    # True = template graph constructed by the Network class, False = actual evaluation.\n    components              = dnnlib.EasyDict(),        # Container for sub-networks. Retained between calls.\n    mapping_func            = 'G_mapping',              # Build func name for the mapping network.\n    synthesis_func          = 'G_synthesis_stylegan2',  # Build func name for the synthesis network.\n    **kwargs):                                          # Arguments for sub-networks (mapping and synthesis).\n\n    # Validate arguments.\n    assert not is_training or not is_validation\n    assert isinstance(components, dnnlib.EasyDict)\n    if is_validation:\n        truncation_psi = truncation_psi_val\n        truncation_cutoff = truncation_cutoff_val\n    if is_training or (truncation_psi is not None and not tflib.is_tf_expression(truncation_psi) and truncation_psi == 1):\n        truncation_psi = None\n    if is_training:\n        truncation_cutoff = None\n    if not is_training or (dlatent_avg_beta is not None and not tflib.is_tf_expression(dlatent_avg_beta) and dlatent_avg_beta == 1):\n        dlatent_avg_beta = None\n    if not is_training or (style_mixing_prob is not None and not tflib.is_tf_expression(style_mixing_prob) and style_mixing_prob <= 0):\n        style_mixing_prob = None\n\n    # Setup components.\n    if 'synthesis' not in components:\n        components.synthesis = tflib.Network('G_synthesis', func_name=globals()[synthesis_func], **kwargs)\n    num_layers = components.synthesis.input_shape[1]\n    dlatent_size = components.synthesis.input_shape[2]\n    if 'mapping' not in components:\n        components.mapping = tflib.Network('G_mapping', func_name=globals()[mapping_func], dlatent_broadcast=num_layers, **kwargs)\n\n    # Setup variables.\n    lod_in = tf.get_variable('lod', initializer=np.float32(0), trainable=False, use_resource=True)\n    dlatent_avg = tf.get_variable('dlatent_avg', shape=[dlatent_size], initializer=tf.initializers.zeros(), trainable=False, use_resource=True)\n\n    # Evaluate mapping network.\n    dlatents = components.mapping.get_output_for(latents_in, labels_in, is_training=is_training, **kwargs)\n    dlatents = tf.cast(dlatents, tf.float32)\n\n    # Update moving average of W.\n    if dlatent_avg_beta is not None:\n        with tf.variable_scope('DlatentAvg'):\n            batch_avg = tf.reduce_mean(dlatents[:, 0], axis=0)\n            update_op = tf.assign(dlatent_avg, tflib.lerp(batch_avg, dlatent_avg, dlatent_avg_beta))\n            with tf.control_dependencies([update_op]):\n                dlatents = tf.identity(dlatents)\n\n    # Perform style mixing regularization.\n    if style_mixing_prob is not None:\n        with tf.variable_scope('StyleMix'):\n            latents2 = tf.random_normal(tf.shape(latents_in))\n            dlatents2 = components.mapping.get_output_for(latents2, labels_in, is_training=is_training, **kwargs)\n            dlatents2 = tf.cast(dlatents2, tf.float32)\n            layer_idx = np.arange(num_layers)[np.newaxis, :, np.newaxis]\n            cur_layers = num_layers - tf.cast(lod_in, tf.int32) * 2\n            mixing_cutoff = tf.cond(\n                tf.random_uniform([], 0.0, 1.0) < style_mixing_prob,\n                lambda: tf.random_uniform([], 1, cur_layers, dtype=tf.int32),\n                lambda: cur_layers)\n            dlatents = tf.where(tf.broadcast_to(layer_idx < mixing_cutoff, tf.shape(dlatents)), dlatents, dlatents2)\n\n    # Apply truncation trick.\n    if truncation_psi is not None:\n        with tf.variable_scope('Truncation'):\n            layer_idx = np.arange(num_layers)[np.newaxis, :, np.newaxis]\n            layer_psi = np.ones(layer_idx.shape, dtype=np.float32)\n            if truncation_cutoff is None:\n                layer_psi *= truncation_psi\n            else:\n                layer_psi = tf.where(layer_idx < truncation_cutoff, layer_psi * truncation_psi, layer_psi)\n            dlatents = tflib.lerp(dlatent_avg, dlatents, layer_psi)\n\n    # Evaluate synthesis network.\n    deps = []\n    if 'lod' in components.synthesis.vars:\n        deps.append(tf.assign(components.synthesis.vars['lod'], lod_in))\n    with tf.control_dependencies(deps):\n        images_out = components.synthesis.get_output_for(dlatents, is_training=is_training, force_clean_graph=is_template_graph, **kwargs)\n\n    # Return requested outputs.\n    images_out = tf.identity(images_out, name='images_out')\n    if return_dlatents:\n        return images_out, dlatents\n    return images_out\n\n#----------------------------------------------------------------------------\n# Mapping network.\n# Transforms the input latent code (z) to the disentangled latent code (w).\n# Used in configs B-F (Table 1).\n\ndef G_mapping(\n    latents_in,                             # First input: Latent vectors (Z) [minibatch, latent_size].\n    labels_in,                              # Second input: Conditioning labels [minibatch, label_size].\n    latent_size             = 512,          # Latent vector (Z) dimensionality.\n    label_size              = 0,            # Label dimensionality, 0 if no labels.\n    dlatent_size            = 512,          # Disentangled latent (W) dimensionality.\n    dlatent_broadcast       = None,         # Output disentangled latent (W) as [minibatch, dlatent_size] or [minibatch, dlatent_broadcast, dlatent_size].\n    mapping_layers          = 8,            # Number of mapping layers.\n    mapping_fmaps           = 512,          # Number of activations in the mapping layers.\n    mapping_lrmul           = 0.01,         # Learning rate multiplier for the mapping layers.\n    mapping_nonlinearity    = 'lrelu',      # Activation function: 'relu', 'lrelu', etc.\n    normalize_latents       = True,        # Normalize latent vectors (Z) before feeding them to the mapping layers?\n    dtype                   = 'float32',    # Data type to use for activations and outputs.\n    **_kwargs):                             # Ignore unrecognized keyword args.\n\n    act = mapping_nonlinearity\n\n    # Inputs.\n    latents_in.set_shape([None, latent_size])\n    labels_in.set_shape([None, label_size])\n    latents_in = tf.cast(latents_in, dtype)\n    labels_in = tf.cast(labels_in, dtype)\n    x = latents_in\n\n    # Embed labels and concatenate them with latents.\n    if label_size:\n        with tf.variable_scope('LabelConcat'):\n            w = tf.get_variable('weight', shape=[label_size, latent_size], initializer=tf.initializers.random_normal(), use_resource=True)\n            y = tf.matmul(labels_in, tf.cast(w, dtype))\n            x = tf.concat([x, y], axis=1)\n\n    # Normalize latents.\n    if normalize_latents:\n        with tf.variable_scope('Normalize'):\n            x *= tf.rsqrt(tf.reduce_mean(tf.square(x), axis=1, keepdims=True) + 1e-8)\n\n    # Mapping layers.\n    for layer_idx in range(mapping_layers):\n        with tf.variable_scope('Dense%d' % layer_idx):\n            fmaps = dlatent_size if layer_idx == mapping_layers - 1 else mapping_fmaps\n            x = apply_bias_act(dense_layer(x, fmaps=fmaps, lrmul=mapping_lrmul), act=act, lrmul=mapping_lrmul)\n\n    # Broadcast.\n    if dlatent_broadcast is not None:\n        with tf.variable_scope('Broadcast'):\n            x = tf.tile(x[:, np.newaxis], [1, dlatent_broadcast, 1])\n\n    # Output.\n    assert x.dtype == tf.as_dtype(dtype)\n    return tf.identity(x, name='dlatents_out')\n\n#----------------------------------------------------------------------------\n# StyleGAN synthesis network with revised architecture (Figure 2d).\n# Implements progressive growing, but no skip connections or residual nets (Figure 7).\n# Used in configs B-D (Table 1).\n\ndef G_synthesis_stylegan_revised(\n    dlatents_in,                        # Input: Disentangled latents (W) [minibatch, num_layers, dlatent_size].\n    dlatent_size        = 512,          # Disentangled latent (W) dimensionality.\n    num_channels        = 3,            # Number of output color channels.\n    resolution          = 1024,         # Output resolution.\n    fmap_base           = 16 << 10,     # Overall multiplier for the number of feature maps.\n    fmap_decay          = 1.0,          # log2 feature map reduction when doubling the resolution.\n    fmap_min            = 1,            # Minimum number of feature maps in any layer.\n    fmap_max            = 512,          # Maximum number of feature maps in any layer.\n    randomize_noise     = True,         # True = randomize noise inputs every time (non-deterministic), False = read noise inputs from variables.\n    nonlinearity        = 'lrelu',      # Activation function: 'relu', 'lrelu', etc.\n    dtype               = 'float32',    # Data type to use for activations and outputs.\n    resample_kernel     = [1,3,3,1],    # Low-pass filter to apply when resampling activations. None = no filtering.\n    fused_modconv       = True,         # Implement modulated_conv2d_layer() as a single fused op?\n    structure           = 'auto',       # 'fixed' = no progressive growing, 'linear' = human-readable, 'recursive' = efficient, 'auto' = select automatically.\n    is_template_graph   = False,        # True = template graph constructed by the Network class, False = actual evaluation.\n    force_clean_graph   = False,        # True = construct a clean graph that looks nice in TensorBoard, False = default behavior.\n    **_kwargs):                         # Ignore unrecognized keyword args.\n\n    num_channels = int(os.environ[\"NUM_CHANNELS\"]) if \"NUM_CHANNELS\" in os.environ else num_channels\n\n    resolution_log2 = int(np.log2(resolution))\n    assert resolution == 2**resolution_log2 and resolution >= 4\n    def nf(stage): return np.clip(int(fmap_base / (2.0 ** (stage * fmap_decay))), fmap_min, fmap_max)\n    if is_template_graph: force_clean_graph = True\n    if force_clean_graph: randomize_noise = False\n    if structure == 'auto': structure = 'linear' if force_clean_graph else 'recursive'\n    act = nonlinearity\n    num_layers = resolution_log2 * 2 - 2\n    images_out = None\n\n    # Primary inputs.\n    dlatents_in.set_shape([None, num_layers, dlatent_size])\n    dlatents_in = tf.cast(dlatents_in, dtype)\n    lod_in = tf.cast(tf.get_variable('lod', initializer=np.float32(0), trainable=False, use_resource=True), dtype)\n\n    # Noise inputs.\n    noise_inputs = []\n    for layer_idx in range(num_layers - 1):\n        res = (layer_idx + 5) // 2\n        shape = [1, 1, 2**res, 2**res]\n        noise_inputs.append(tf.get_variable('noise%d' % layer_idx, shape=shape, initializer=tf.initializers.random_normal(), trainable=False, use_resource=True))\n\n    # Single convolution layer with all the bells and whistles.\n    def layer(x, layer_idx, fmaps, kernel, up=False):\n        x = modulated_conv2d_layer(x, dlatents_in[:, layer_idx], fmaps=fmaps, kernel=kernel, up=up, resample_kernel=resample_kernel, fused_modconv=fused_modconv)\n        if randomize_noise:\n            noise = tf.random_normal([tf.shape(x)[0], 1, x.shape[2], x.shape[3]], dtype=x.dtype)\n        else:\n            noise = tf.cast(noise_inputs[layer_idx], x.dtype)\n        noise_strength = tf.get_variable('noise_strength', shape=[], initializer=tf.initializers.zeros(), use_resource=True)\n        x += noise * tf.cast(noise_strength, x.dtype)\n        return apply_bias_act(x, act=act)\n\n    # Early layers.\n    with tf.variable_scope('4x4'):\n        with tf.variable_scope('Const'):\n            x = tf.get_variable('const', shape=[1, nf(1), 4, 4], initializer=tf.initializers.random_normal(), use_resource=True)\n            x = tf.tile(tf.cast(x, dtype), [tf.shape(dlatents_in)[0], 1, 1, 1])\n        with tf.variable_scope('Conv'):\n            x = layer(x, layer_idx=0, fmaps=nf(1), kernel=3)\n\n    # Building blocks for remaining layers.\n    def block(res, x): # res = 3..resolution_log2\n        with tf.variable_scope('%dx%d' % (2**res, 2**res)):\n            with tf.variable_scope('Conv0_up'):\n                x = layer(x, layer_idx=res*2-5, fmaps=nf(res-1), kernel=3, up=True)\n            with tf.variable_scope('Conv1'):\n                x = layer(x, layer_idx=res*2-4, fmaps=nf(res-1), kernel=3)\n            return x\n    def torgb(res, x): # res = 2..resolution_log2\n        with tf.variable_scope('ToRGB_lod%d' % (resolution_log2 - res)):\n            return apply_bias_act(modulated_conv2d_layer(x, dlatents_in[:, res*2-3], fmaps=num_channels, kernel=1, demodulate=False, fused_modconv=fused_modconv))\n\n    # Fixed structure: simple and efficient, but does not support progressive growing.\n    if structure == 'fixed':\n        for res in range(3, resolution_log2 + 1):\n            x = block(res, x)\n        images_out = torgb(resolution_log2, x)\n\n    # Linear structure: simple but inefficient.\n    if structure == 'linear':\n        images_out = torgb(2, x)\n        for res in range(3, resolution_log2 + 1):\n            lod = resolution_log2 - res\n            x = block(res, x)\n            img = torgb(res, x)\n            with tf.variable_scope('Upsample_lod%d' % lod):\n                images_out = upsample_2d(images_out)\n            with tf.variable_scope('Grow_lod%d' % lod):\n                images_out = tflib.lerp_clip(img, images_out, lod_in - lod)\n\n    # Recursive structure: complex but efficient.\n    if structure == 'recursive':\n        def cset(cur_lambda, new_cond, new_lambda):\n            return lambda: tf.cond(new_cond, new_lambda, cur_lambda)\n        def grow(x, res, lod):\n            y = block(res, x)\n            img = lambda: naive_upsample_2d(torgb(res, y), factor=2**lod)\n            img = cset(img, (lod_in > lod), lambda: naive_upsample_2d(tflib.lerp(torgb(res, y), upsample_2d(torgb(res - 1, x)), lod_in - lod), factor=2**lod))\n            if lod > 0: img = cset(img, (lod_in < lod), lambda: grow(y, res + 1, lod - 1))\n            return img()\n        images_out = grow(x, 3, resolution_log2 - 3)\n\n    assert images_out.dtype == tf.as_dtype(dtype)\n    return tf.identity(images_out, name='images_out')\n\n#----------------------------------------------------------------------------\n# StyleGAN2 synthesis network (Figure 7).\n# Implements skip connections and residual nets (Figure 7), but no progressive growing.\n# Used in configs E-F (Table 1).\n\ndef G_synthesis_stylegan2(\n    dlatents_in,                        # Input: Disentangled latents (W) [minibatch, num_layers, dlatent_size].\n    dlatent_size        = 512,          # Disentangled latent (W) dimensionality.\n    num_channels        = 3,            # Number of output color channels.\n    resolution          = 1024,         # Output resolution.\n    fmap_base           = 16 << 10,     # Overall multiplier for the number of feature maps.\n    fmap_decay          = 1.0,          # log2 feature map reduction when doubling the resolution.\n    fmap_min            = 1,            # Minimum number of feature maps in any layer.\n    fmap_max            = 512,          # Maximum number of feature maps in any layer.\n    randomize_noise     = True,         # True = randomize noise inputs every time (non-deterministic), False = read noise inputs from variables.\n    architecture        = 'skip',       # Architecture: 'orig', 'skip', 'resnet'.\n    nonlinearity        = 'lrelu',      # Activation function: 'relu', 'lrelu', etc.\n    dtype               = 'float32',    # Data type to use for activations and outputs.\n    resample_kernel     = [1,3,3,1],    # Low-pass filter to apply when resampling activations. None = no filtering.\n    fused_modconv       = True,         # Implement modulated_conv2d_layer() as a single fused op?\n    **_kwargs):                         # Ignore unrecognized keyword args.\n\n    num_channels = int(os.environ[\"NUM_CHANNELS\"]) if \"NUM_CHANNELS\" in os.environ else num_channels\n\n    resolution_log2 = int(np.log2(resolution))\n    assert resolution == 2**resolution_log2 and resolution >= 4\n    def nf(stage): return np.clip(int(fmap_base / (2.0 ** (stage * fmap_decay))), fmap_min, fmap_max)\n    assert architecture in ['orig', 'skip', 'resnet']\n    act = nonlinearity\n    num_layers = resolution_log2 * 2 - 2\n    images_out = None\n\n    # Primary inputs.\n    dlatents_in.set_shape([None, num_layers, dlatent_size])\n    dlatents_in = tf.cast(dlatents_in, dtype)\n\n    # Noise inputs.\n    noise_inputs = []\n    for layer_idx in range(num_layers - 1):\n        res = (layer_idx + 5) // 2\n        shape = [1, 1, 2**res, 2**res]\n        noise_inputs.append(tf.get_variable('noise%d' % layer_idx, shape=shape, initializer=tf.initializers.random_normal(), trainable=False, use_resource=True))\n\n    # Single convolution layer with all the bells and whistles.\n    def layer(x, layer_idx, fmaps, kernel, up=False):\n        x = modulated_conv2d_layer(x, dlatents_in[:, layer_idx], fmaps=fmaps, kernel=kernel, up=up, resample_kernel=resample_kernel, fused_modconv=fused_modconv)\n        if randomize_noise:\n            noise = tf.random_normal([tf.shape(x)[0], 1, x.shape[2], x.shape[3]], dtype=x.dtype)\n        else:\n            noise = tf.cast(noise_inputs[layer_idx], x.dtype)\n        noise_strength = tf.get_variable('noise_strength', shape=[], initializer=tf.initializers.zeros(), use_resource=True)\n        x += noise * tf.cast(noise_strength, x.dtype)\n        return apply_bias_act(x, act=act)\n\n    # Building blocks for main layers.\n    def block(x, res): # res = 3..resolution_log2\n        t = x\n        with tf.variable_scope('Conv0_up'):\n            x = layer(x, layer_idx=res*2-5, fmaps=nf(res-1), kernel=3, up=True)\n        with tf.variable_scope('Conv1'):\n            x = layer(x, layer_idx=res*2-4, fmaps=nf(res-1), kernel=3)\n        if architecture == 'resnet':\n            with tf.variable_scope('Skip'):\n                t = conv2d_layer(t, fmaps=nf(res-1), kernel=1, up=True, resample_kernel=resample_kernel)\n                x = (x + t) * (1 / np.sqrt(2))\n        return x\n    def upsample(y):\n        with tf.variable_scope('Upsample'):\n            return upsample_2d(y, k=resample_kernel)\n    def torgb(x, y, res): # res = 2..resolution_log2\n        with tf.variable_scope('ToRGB'):\n            t = apply_bias_act(modulated_conv2d_layer(x, dlatents_in[:, res*2-3], fmaps=num_channels, kernel=1, demodulate=False, fused_modconv=fused_modconv))\n            return graph_images(t if y is None else y + t, res=2**res)\n\n    # Early layers.\n    y = None\n    with tf.variable_scope('4x4'):\n        with tf.variable_scope('Const'):\n            x = tf.get_variable('const', shape=[1, nf(1), 4, 4], initializer=tf.initializers.random_normal(), use_resource=True)\n            x = tf.tile(tf.cast(x, dtype), [tf.shape(dlatents_in)[0], 1, 1, 1])\n        with tf.variable_scope('Conv'):\n            x = layer(x, layer_idx=0, fmaps=nf(1), kernel=3)\n        if architecture == 'skip':\n            y = torgb(x, y, 2)\n\n    # Main layers.\n    for res in range(3, resolution_log2 + 1):\n        with tf.variable_scope('%dx%d' % (2**res, 2**res)):\n            x = block(x, res)\n            if 2**res == 64 and False:\n                print('Adding self-attention block to generator')\n                x = non_local_block(x, \"SelfAtten\", use_sn=True)\n            if architecture == 'skip':\n                y = upsample(y)\n            if architecture == 'skip' or res == resolution_log2:\n                y = torgb(x, y, res)\n    images_out = y\n\n    assert images_out.dtype == tf.as_dtype(dtype)\n    return tf.identity(images_out, name='images_out')\n\n#----------------------------------------------------------------------------\n# Original StyleGAN discriminator.\n# Used in configs B-D (Table 1).\n\ndef D_stylegan(\n    images_in,                          # First input: Images [minibatch, channel, height, width].\n    labels_in,                          # Second input: Labels [minibatch, label_size].\n    num_channels        = 3,            # Number of input color channels. Overridden based on dataset.\n    resolution          = 1024,         # Input resolution. Overridden based on dataset.\n    label_size          = 0,            # Dimensionality of the labels, 0 if no labels. Overridden based on dataset.\n    fmap_base           = 16 << 10,     # Overall multiplier for the number of feature maps.\n    fmap_decay          = 1.0,          # log2 feature map reduction when doubling the resolution.\n    fmap_min            = 1,            # Minimum number of feature maps in any layer.\n    fmap_max            = 512,          # Maximum number of feature maps in any layer.\n    nonlinearity        = 'lrelu',      # Activation function: 'relu', 'lrelu', etc.\n    mbstd_group_size    = 4,            # Group size for the minibatch standard deviation layer, 0 = disable.\n    mbstd_num_features  = 1,            # Number of features for the minibatch standard deviation layer.\n    dtype               = 'float32',    # Data type to use for activations and outputs.\n    resample_kernel     = [1,3,3,1],    # Low-pass filter to apply when resampling activations. None = no filtering.\n    structure           = 'auto',       # 'fixed' = no progressive growing, 'linear' = human-readable, 'recursive' = efficient, 'auto' = select automatically.\n    is_template_graph   = False,        # True = template graph constructed by the Network class, False = actual evaluation.\n    **_kwargs):                         # Ignore unrecognized keyword args.\n\n    num_channels = int(os.environ[\"NUM_CHANNELS\"]) if \"NUM_CHANNELS\" in os.environ else num_channels\n\n    resolution_log2 = int(np.log2(resolution))\n    assert resolution == 2**resolution_log2 and resolution >= 4\n    def nf(stage): return np.clip(int(fmap_base / (2.0 ** (stage * fmap_decay))), fmap_min, fmap_max)\n    if structure == 'auto': structure = 'linear' if is_template_graph else 'recursive'\n    act = nonlinearity\n\n    images_in.set_shape([None, num_channels, resolution, resolution])\n    labels_in.set_shape([None, label_size])\n    images_in = tf.cast(images_in, dtype)\n    labels_in = tf.cast(labels_in, dtype)\n    lod_in = tf.cast(tf.get_variable('lod', initializer=np.float32(0.0), trainable=False, use_resource=True), dtype)\n\n    # Building blocks for spatial layers.\n    def fromrgb(x, res): # res = 2..resolution_log2\n        with tf.variable_scope('FromRGB_lod%d' % (resolution_log2 - res)):\n            return apply_bias_act(conv2d_layer(x, fmaps=nf(res-1), kernel=1), act=act)\n    def block(x, res): # res = 2..resolution_log2\n        with tf.variable_scope('%dx%d' % (2**res, 2**res)):\n            with tf.variable_scope('Conv0'):\n                x = apply_bias_act(conv2d_layer(x, fmaps=nf(res-1), kernel=3), act=act)\n            with tf.variable_scope('Conv1_down'):\n                x = apply_bias_act(conv2d_layer(x, fmaps=nf(res-2), kernel=3, down=True, resample_kernel=resample_kernel), act=act)\n            return x\n\n    # Fixed structure: simple and efficient, but does not support progressive growing.\n    if structure == 'fixed':\n        x = fromrgb(images_in, resolution_log2)\n        for res in range(resolution_log2, 2, -1):\n            x = block(x, res)\n\n    # Linear structure: simple but inefficient.\n    if structure == 'linear':\n        img = images_in\n        x = fromrgb(img, resolution_log2)\n        for res in range(resolution_log2, 2, -1):\n            lod = resolution_log2 - res\n            x = block(x, res)\n            with tf.variable_scope('Downsample_lod%d' % lod):\n                img = downsample_2d(img)\n            y = fromrgb(img, res - 1)\n            with tf.variable_scope('Grow_lod%d' % lod):\n                x = tflib.lerp_clip(x, y, lod_in - lod)\n\n    # Recursive structure: complex but efficient.\n    if structure == 'recursive':\n        def cset(cur_lambda, new_cond, new_lambda):\n            return lambda: tf.cond(new_cond, new_lambda, cur_lambda)\n        def grow(res, lod):\n            x = lambda: fromrgb(naive_downsample_2d(images_in, factor=2**lod), res)\n            if lod > 0: x = cset(x, (lod_in < lod), lambda: grow(res + 1, lod - 1))\n            x = block(x(), res); y = lambda: x\n            y = cset(y, (lod_in > lod), lambda: tflib.lerp(x, fromrgb(naive_downsample_2d(images_in, factor=2**(lod+1)), res - 1), lod_in - lod))\n            return y()\n        x = grow(3, resolution_log2 - 3)\n\n    # Final layers at 4x4 resolution.\n    with tf.variable_scope('4x4'):\n        if mbstd_group_size > 1:\n            with tf.variable_scope('MinibatchStddev'):\n                x = minibatch_stddev_layer(x, mbstd_group_size, mbstd_num_features)\n        with tf.variable_scope('Conv'):\n            x = apply_bias_act(conv2d_layer(x, fmaps=nf(1), kernel=3), act=act)\n        with tf.variable_scope('Dense0'):\n            x = apply_bias_act(dense_layer(x, fmaps=nf(0)), act=act)\n\n    with tf.variable_scope('Output'):\n        x = apply_bias_act(dense_layer(x, fmaps=1))\n    scores_out = x\n\n    # Output.\n    assert scores_out.dtype == tf.as_dtype(dtype)\n    scores_out = tf.identity(scores_out, name='scores_out')\n    return scores_out\n\n#----------------------------------------------------------------------------\n# StyleGAN2 discriminator (Figure 7).\n# Implements skip connections and residual nets (Figure 7), but no progressive growing.\n# Used in configs E-F (Table 1).\n\ndef D_stylegan2(\n    images_in,                          # First input: Images [minibatch, channel, height, width].\n    labels_in,                          # Second input: Labels [minibatch, label_size].\n    num_channels        = 3,            # Number of input color channels. Overridden based on dataset.\n    resolution          = 1024,         # Input resolution. Overridden based on dataset.\n    label_size          = 0,            # Dimensionality of the labels, 0 if no labels. Overridden based on dataset.\n    fmap_base           = 16 << 10,     # Overall multiplier for the number of feature maps.\n    fmap_decay          = 1.0,          # log2 feature map reduction when doubling the resolution.\n    fmap_min            = 1,            # Minimum number of feature maps in any layer.\n    fmap_max            = 512,          # Maximum number of feature maps in any layer.\n    architecture        = 'resnet',     # Architecture: 'orig', 'skip', 'resnet'.\n    nonlinearity        = 'lrelu',      # Activation function: 'relu', 'lrelu', etc.\n    mbstd_group_size    = 4,            # Group size for the minibatch standard deviation layer, 0 = disable.\n    mbstd_num_features  = 1,            # Number of features for the minibatch standard deviation layer.\n    dtype               = 'float32',    # Data type to use for activations and outputs.\n    resample_kernel     = [1,3,3,1],    # Low-pass filter to apply when resampling activations. None = no filtering.\n    **_kwargs):                         # Ignore unrecognized keyword args.\n\n    num_channels = int(os.environ[\"NUM_CHANNELS\"]) if \"NUM_CHANNELS\" in os.environ else num_channels\n\n    resolution_log2 = int(np.log2(resolution))\n    assert resolution == 2**resolution_log2 and resolution >= 4\n    def nf(stage): return np.clip(int(fmap_base / (2.0 ** (stage * fmap_decay))), fmap_min, fmap_max)\n    assert architecture in ['orig', 'skip', 'resnet']\n    act = nonlinearity\n\n    images_in.set_shape([None, num_channels, resolution, resolution])\n    labels_in.set_shape([None, label_size])\n    images_in = tf.cast(images_in, dtype)\n    labels_in = tf.cast(labels_in, dtype)\n\n    # Building blocks for main layers.\n    def fromrgb(x, y, res): # res = 2..resolution_log2\n        with tf.variable_scope('FromRGB'):\n            t = apply_bias_act(conv2d_layer(y, fmaps=nf(res-1), kernel=1), act=act)\n            return t if x is None else x + t\n    def block(x, res): # res = 2..resolution_log2\n        t = x\n        with tf.variable_scope('Conv0'):\n            x = apply_bias_act(conv2d_layer(x, fmaps=nf(res-1), kernel=3), act=act)\n        with tf.variable_scope('Conv1_down'):\n            x = apply_bias_act(conv2d_layer(x, fmaps=nf(res-2), kernel=3, down=True, resample_kernel=resample_kernel), act=act)\n        if architecture == 'resnet':\n            with tf.variable_scope('Skip'):\n                t = conv2d_layer(t, fmaps=nf(res-2), kernel=1, down=True, resample_kernel=resample_kernel)\n                x = (x + t) * (1 / np.sqrt(2))\n        return x\n    def downsample(y):\n        with tf.variable_scope('Downsample'):\n            return downsample_2d(y, k=resample_kernel)\n\n    # Main layers.\n    x = None\n    y = images_in\n    for res in range(resolution_log2, 2, -1):\n        with tf.variable_scope('%dx%d' % (2**res, 2**res)):\n            if architecture == 'skip' or res == resolution_log2:\n                x = fromrgb(x, y, res)\n            if 2**res == 64 and False:\n                print('Adding self-attention block to discriminator')\n                x = non_local_block(x, \"SelfAtten\", use_sn=True)\n            x = block(x, res)\n            if architecture == 'skip':\n                y = downsample(y)\n\n    # Final layers.\n    with tf.variable_scope('4x4'):\n        if architecture == 'skip':\n            x = fromrgb(x, y, 2)\n        if mbstd_group_size > 1:\n            with tf.variable_scope('MinibatchStddev'):\n                x = minibatch_stddev_layer(x, mbstd_group_size, mbstd_num_features)\n        with tf.variable_scope('Conv'):\n            x = apply_bias_act(conv2d_layer(x, fmaps=nf(1), kernel=3), act=act)\n        with tf.variable_scope('Dense0'):\n            x = apply_bias_act(dense_layer(x, fmaps=nf(0)), act=act)\n\n    with tf.variable_scope('Output'):\n        x = apply_bias_act(dense_layer(x, fmaps=1))\n    scores_out = x\n\n    # Output.\n    assert scores_out.dtype == tf.as_dtype(dtype)\n    scores_out = tf.identity(scores_out, name='scores_out')\n    return scores_out\n\n#----------------------------------------------------------------------------\n\n\nNORMAL_INIT = \"normal\"\nTRUNCATED_INIT = \"truncated\"\nORTHOGONAL_INIT = \"orthogonal\"\nINITIALIZERS = [NORMAL_INIT, TRUNCATED_INIT, ORTHOGONAL_INIT]\n\n#@gin.configurable(\"weights\")\ndef weight_initializer(initializer=NORMAL_INIT, stddev=0.02):\n  \"\"\"Returns the initializer for the given name.\n\n  Args:\n    initializer: Name of the initalizer. Use one in INITIALIZERS.\n    stddev: Standard deviation passed to initalizer.\n\n  Returns:\n    Initializer from `tf.initializers`.\n  \"\"\"\n  if initializer == NORMAL_INIT:\n    return tf.initializers.random_normal(stddev=stddev)\n  if initializer == TRUNCATED_INIT:\n    return tf.initializers.truncated_normal(stddev=stddev)\n  if initializer == ORTHOGONAL_INIT:\n    return tf.initializers.orthogonal()\n  raise ValueError(\"Unknown weight initializer {}.\".format(initializer))\n\n#@gin.configurable(blacklist=[\"inputs\"])\ndef spectral_norm(inputs, epsilon=1e-12, singular_value=\"left\", return_normalized=True, power_iteration_rounds=1):\n  \"\"\"Performs Spectral Normalization on a weight tensor.\n\n  Details of why this is helpful for GAN's can be found in \"Spectral\n  Normalization for Generative Adversarial Networks\", Miyato T. et al., 2018.\n  [https://arxiv.org/abs/1802.05957].\n\n  Args:\n    inputs: The weight tensor to normalize.\n    epsilon: Epsilon for L2 normalization.\n    singular_value: Which first singular value to store (left or right). Use\n      \"auto\" to automatically choose the one that has fewer dimensions.\n\n  Returns:\n    The normalized weight tensor.\n  \"\"\"\n  if len(inputs.shape) < 2:\n    raise ValueError(\n        \"Spectral norm can only be applied to multi-dimensional tensors\")\n\n  # The paper says to flatten convnet kernel weights from (C_out, C_in, KH, KW)\n  # to (C_out, C_in * KH * KW). Our Conv2D kernel shape is (KH, KW, C_in, C_out)\n  # so it should be reshaped to (KH * KW * C_in, C_out), and similarly for other\n  # layers that put output channels as last dimension. This implies that w\n  # here is equivalent to w.T in the paper.\n  w = tf.reshape(inputs, (-1, inputs.shape[-1]))\n\n  # Choose whether to persist the first left or first right singular vector.\n  # As the underlying matrix is PSD, this should be equivalent, but in practice\n  # the shape of the persisted vector is different. Here one can choose whether\n  # to maintain the left or right one, or pick the one which has the smaller\n  # dimension. We use the same variable for the singular vector if we switch\n  # from normal weights to EMA weights.\n  var_name = inputs.name.replace(\"/ExponentialMovingAverage\", \"\").split(\"/\")[-1]\n  var_name = var_name.split(\":\")[0] + \"/u_var\"\n  if singular_value == \"auto\":\n    singular_value = \"left\" if w.shape[0] <= w.shape[1] else \"right\"\n  u_shape = (w.shape[0], 1) if singular_value == \"left\" else (1, w.shape[-1])\n  u_var = tf.get_variable(\n      var_name,\n      shape=u_shape,\n      dtype=w.dtype,\n      initializer=tf.random_normal_initializer(),\n      collections=[tf.GraphKeys.LOCAL_VARIABLES],\n      trainable=False, use_resource=True)\n  u = u_var\n\n  # Use power iteration method to approximate the spectral norm.\n  # The authors suggest that one round of power iteration was sufficient in the\n  # actual experiment to achieve satisfactory performance.\n  for _ in range(power_iteration_rounds):\n    if singular_value == \"left\":\n      # `v` approximates the first right singular vector of matrix `w`.\n      v = tf.math.l2_normalize(\n          tf.matmul(tf.transpose(w), u), axis=None, epsilon=epsilon)\n      u = tf.math.l2_normalize(tf.matmul(w, v), axis=None, epsilon=epsilon)\n    else:\n      v = tf.math.l2_normalize(tf.matmul(u, w, transpose_b=True),\n                               epsilon=epsilon)\n      u = tf.math.l2_normalize(tf.matmul(v, w), epsilon=epsilon)\n  # Update the approximation.\n  with tf.control_dependencies([tf.assign(u_var, u, name=\"update_u\")]):\n    u = tf.identity(u)\n  # The authors of SN-GAN chose to stop gradient propagating through u and v\n  # and we maintain that option.\n  u = tf.stop_gradient(u)\n  v = tf.stop_gradient(v)\n  if singular_value == \"left\":\n    norm_value = tf.matmul(tf.matmul(tf.transpose(u), w), v)\n  else:\n    norm_value = tf.matmul(tf.matmul(v, w), u, transpose_b=True)\n  norm_value.shape.assert_is_fully_defined()\n  norm_value.shape.assert_is_compatible_with([1, 1])\n  if return_normalized:\n    w_normalized = w / norm_value\n    # Deflate normalized weights to match the unnormalized tensor.\n    w_tensor_normalized = tf.reshape(w_normalized, inputs.shape)\n    return w_tensor_normalized\n  else:\n    return w, norm_value\n\ndef graph_name(name):\n  name = name.split(':')[0]\n  name = name.split('/strided_slice_')[0]\n  name = name.split('/Identity_')[0]\n  if name.startswith('D_loss/G/G_synthesis/'):\n    name = name.replace('D_loss/G/G_synthesis/', '')\n    return 'G_' + name\n  elif name.startswith('D_loss/D/'):\n    name = name.replace('D_loss/D/', '')\n    return 'D_' + name\n\ndef graph_spectral_norm(w):\n  w1, norm = spectral_norm(w, return_normalized=False)\n  value = norm[0][0]\n  name = graph_name(value.name)\n  if name is not None:\n    autosummary('specnorm_' + name, value)\n  else:\n    tf.logging.info('ignoring autosummary(%s, %s)', repr(value.name), repr(value))\n  if 'USE_SPECNORM' in os.environ:\n    tf.logging.info('Using spectral normalization for %s', repr(w))\n    w_normalized = w1 / norm\n    w_normalized = tf.reshape(w_normalized, w.shape)\n    return w_normalized\n  return w\n\ndef graph_images(images, res):\n    value = tf.identity(images)\n    name = graph_name(value.name)\n    if name is not None:\n      autoimages(name, value, res=res)\n    else:\n      tf.logging.info('ignoring autoimages(%s, %s)', repr(name), repr(value))\n    return images\n\ndef conv2d(inputs, output_dim, k_h, k_w, d_h, d_w, stddev=0.02, name=\"conv2d\",\n           use_sn=False, use_bias=True):\n  \"\"\"Performs 2D convolution of the input.\"\"\"\n  with tf.variable_scope(name):\n    w = tf.get_variable(\n        \"kernel\", [k_h, k_w, inputs.shape[-1].value, output_dim],\n        initializer=weight_initializer(stddev=stddev), use_resource=True)\n    if use_sn:\n      w = spectral_norm(w)\n    outputs = tf.nn.conv2d(inputs, w, strides=[1, d_h, d_w, 1], padding=\"SAME\")\n    if use_bias:\n      bias = tf.get_variable(\n          \"bias\", [output_dim], initializer=tf.constant_initializer(0.0), use_resource=True)\n      outputs += bias\n  return outputs\n\nconv1x1 = functools.partial(conv2d, k_h=1, k_w=1, d_h=1, d_w=1)\n\n\ndef non_local_block(x, name, use_sn):\n  \"\"\"Self-attention (non-local) block.\n\n  This method is used to exactly reproduce SAGAN and ignores Gin settings on\n  weight initialization and spectral normalization.\n\n\n  Args:\n    x: Input tensor of shape [batch, h, w, c].\n    name: Name of the variable scope.\n    use_sn: Apply spectral norm to the weights.\n\n  Returns:\n    A tensor of the same shape after self-attention was applied.\n  \"\"\"\n  def _spatial_flatten(inputs):\n    shape = inputs.shape\n    return tf.reshape(inputs, (-1, shape[1] * shape[2], shape[3]))\n\n  with tf.variable_scope(name):\n    h, w, num_channels = x.get_shape().as_list()[1:]\n    num_channels_attn = num_channels // 8\n    num_channels_g = num_channels // 2\n\n    # Theta path\n    theta = conv1x1(x, num_channels_attn, name=\"conv2d_theta\", use_sn=use_sn,\n                    use_bias=False)\n    theta = _spatial_flatten(theta)\n\n    # Phi path\n    phi = conv1x1(x, num_channels_attn, name=\"conv2d_phi\", use_sn=use_sn,\n                  use_bias=False)\n    phi = tf.layers.max_pooling2d(inputs=phi, pool_size=[2, 2], strides=2)\n    phi = _spatial_flatten(phi)\n\n    attn = tf.matmul(theta, phi, transpose_b=True)\n    attn = tf.nn.softmax(attn)\n\n    # G path\n    g = conv1x1(x, num_channels_g, name=\"conv2d_g\", use_sn=use_sn,\n                use_bias=False)\n    g = tf.layers.max_pooling2d(inputs=g, pool_size=[2, 2], strides=2)\n    g = _spatial_flatten(g)\n\n    attn_g = tf.matmul(attn, g)\n    attn_g = tf.reshape(attn_g, [-1, h, w, num_channels_g])\n    sigma = tf.get_variable(\"sigma\", [], initializer=tf.zeros_initializer(), use_resource=True)\n    attn_g = conv1x1(attn_g, num_channels, name=\"conv2d_attn_g\", use_sn=use_sn,\n                     use_bias=False)\n    return x + sigma * attn_g\n\n"
  },
  {
    "path": "stylegan2-tpu/training/train_runner.py",
    "content": "# Copyright 2018 The TensorFlow Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# ==============================================================================\n\"\"\"Bypass TPUEstimator for ResNet-50 Train.\"\"\"\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport math\nimport threading\nimport time\n\nfrom absl import flags\nimport tensorflow as tf\nimport tflex\n\nfrom tensorflow.contrib import tpu\nfrom tensorflow.contrib.tpu.python.tpu import tpu_function\nfrom tensorflow.core.protobuf import rewriter_config_pb2\nfrom tensorflow.python.data.util import nest as data_nest\nfrom tensorflow.python.framework import graph_io\nfrom pprint import pprint\n\nFLAGS = flags.FLAGS\n\n_INITIAL_LOSS = 1e7\n\n\ndef device_for_tpu_core(task=0, core=0):\n  job_name = FLAGS.tpu_job_name or \"tpu_worker\"\n  return \"/job:%s/task:%d/device:TPU_REPLICATED_CORE:%d\" % (job_name, task,\n                                                            core)\n\n\ndef wrap_computation_in_while_loop(op_fn, n, parallel_iterations=1):\n  \"\"\"Wraps the ops generated by `op_fn` in tf.while_loop.\"\"\"\n\n  def computation(i):\n    ops = op_fn()\n    if not isinstance(ops, list):\n      ops = [ops]\n    with tf.control_dependencies(ops):\n      return i + 1\n\n  return tf.while_loop(\n      lambda i: tf.less(i, n),\n      computation, [tf.constant(0)],\n      parallel_iterations=parallel_iterations)\n\n\ndef tpu_ordinal_fn(shard_index_in_host):\n  \"\"\"Return the TPU ordinal associated with a shard.\n\n  Required because the enqueue ops are placed on CPU.\n\n  Args:\n    shard_index_in_host: the shard index\n\n  Returns:\n    The ordinal of the TPU device the shard's infeed should be placed on.\n  \"\"\"\n  return shard_index_in_host % FLAGS.tpu_cores_per_host\n\n\nclass TrainRunner(object):\n  \"\"\"Remove init overheads in TPU Estimator via direct session.run calls.\"\"\"\n\n  def __init__(self, iterations, train_steps):\n    tf.logging.info(\"TrainRunner: constructor\")\n    self.feature_structure = {}\n    self.loss = None\n    self.infeed_queue = []\n    self.enqueue_ops = []\n    self.dataset_initializer = []\n    self.iterations = iterations\n    self.sess = None\n    self.input_sess = None\n    self.infeed_thread = None\n    if train_steps % iterations != 0:\n      train_steps = iterations * int(math.ceil(train_steps / iterations))\n    self.train_steps = train_steps\n    self.input_graph = tf.Graph()\n    self.init_graph = tf.Graph()\n    with self.init_graph.as_default():\n      tpu_init = [tpu.initialize_system()]\n    self.tpu_shutdown = tpu.shutdown_system()\n    self.cluster_resolver = tf.contrib.cluster_resolver.TPUClusterResolver(\n        FLAGS.tpu or FLAGS.master,\n        zone=FLAGS.tpu_zone,\n        project=FLAGS.gcp_project)\n    self.config = tf.ConfigProto(operation_timeout_in_ms=600 * 60 * 1000,\n                                 graph_options=tf.GraphOptions(\n                                     rewrite_options=rewriter_config_pb2.RewriterConfig(\n                                         disable_meta_optimizer=True)),\n                                 isolate_session_state=True)\n    cluster_spec = self.cluster_resolver.cluster_spec()\n    if cluster_spec:\n      self.config.cluster_def.CopyFrom(cluster_spec.as_cluster_def())\n    self.init_sess = tflex.Session(self.cluster_resolver.get_master(), config=self.config, graph=self.init_graph)\n    self.init_sess.run(tpu_init)\n\n  def device_for_host(self, task=0, cpu=0):\n    job_name = FLAGS.tpu_job_name or \"tpu_worker\"\n    return \"/job:%s/task:%d/device:CPU:%d\" % (job_name, task, cpu)\n\n  def build_enqueue_ops(self, input_fn, params, host_id):\n    \"\"\"Build enqueue operations for the input pipeline in a given host.\n\n    Args:\n      input_fn: dataset input graph generation function\n      params:  input function parameters\n      host_id:  host identifier\n    \"\"\"\n\n    iparams = {}\n    iparams[\"batch_size\"] = params[\"batch_size\"] // FLAGS.num_cores\n    iparams[\"dataset_num_shards\"] = FLAGS.num_cores // FLAGS.tpu_cores_per_host\n\n    def get_enqueue_ops_fn():\n      \"\"\"Generate the enqueue ops graph function.\"\"\"\n\n      iparams[\"dataset_index\"] = host_id\n      dataset = input_fn(iparams)\n      iterator = dataset.make_initializable_iterator()\n      self.dataset_initializer.append(iterator.initializer)\n\n      def enqueue_ops_fn():\n        \"\"\"Generate the infeed enqueue ops graph.\"\"\"\n\n        per_host_sharded_inputs = []\n        control_deps = []\n        with tf.device(self.device_for_host(task=host_id)):\n          for _ in range(FLAGS.tpu_cores_per_host):\n            with tf.control_dependencies(control_deps):\n              features, labels = iterator.get_next()\n            self.feature_structure[\"features\"] = features\n            self.feature_structure[\"labels\"] = labels\n            flattened_inputs = data_nest.flatten(self.feature_structure)\n            control_deps.extend(flattened_inputs)\n            per_host_sharded_inputs.append(flattened_inputs)\n\n          infeed = tpu.InfeedQueue(\n              number_of_tuple_elements=len(per_host_sharded_inputs[0]))\n          self.infeed_queue.append(infeed)\n          return infeed.generate_enqueue_ops(\n              per_host_sharded_inputs, tpu_ordinal_function=tpu_ordinal_fn)\n\n      return enqueue_ops_fn\n\n    with self.input_graph.as_default():\n      with tf.device(self.device_for_host(host_id)):\n        self.enqueue_ops.append(\n            wrap_computation_in_while_loop(\n                get_enqueue_ops_fn(),\n                n=self.train_steps,\n                parallel_iterations=1))\n\n  def initialize(self, input_fn, model_fn, params):\n    \"\"\"Build graphs for the TPU device and the input pipelines.\n\n    Args:\n      input_fn: Dataset input graph generation function\n      model_fn: Model definition function\n      params:  Parameters to input and model functions\n    \"\"\"\n\n    tf.logging.info(\"TrainRunner: initialize method\")\n\n    def infeed_thread_fn():\n      \"\"\"Build and infeed session.run calls in a background thread.\"\"\"\n      i = 1\n      while i < FLAGS.num_cores // FLAGS.tpu_cores_per_host:\n        self.build_enqueue_ops(input_fn, params, i)\n        i += 1\n      # Build infeed sesssion\n      self.input_sess = tflex.Session(\n          self.cluster_resolver.get_master(),\n          graph=self.input_graph,\n          config=self.config)\n      self.input_sess.run(self.dataset_initializer)\n      # Run infeed session.run calls\n      self.input_sess.run([self.enqueue_ops])\n\n    self.build_enqueue_ops(input_fn, params, 0)\n\n    def get_tpu_step(mparams):\n      \"\"\"Get the TPU graph generation function.\"\"\"\n\n      def tpu_step(loss):\n        \"\"\"Generate the TPU graph.\"\"\"\n        del loss\n        values = self.infeed_queue[0].generate_dequeue_op(tpu_device=0)\n        unflattened_inputs = data_nest.pack_sequence_as(self.feature_structure,\n                                                        values)\n        features = unflattened_inputs[\"features\"]\n        labels = unflattened_inputs[\"labels\"]\n        estimator_spec = model_fn(features, labels, tf.estimator.ModeKeys.TRAIN,\n                                  mparams)\n        loss, train_op = estimator_spec.loss, estimator_spec.train_op\n        with tf.device(device_for_tpu_core()):\n          with tf.control_dependencies([train_op]):\n            return tf.identity(loss)\n\n      return tpu_step\n\n    tpu_step = get_tpu_step(params)\n\n    @tpu_function.on_device_training_loop\n    def tpu_loop():\n      return tpu.repeat(self.iterations, tpu_step, [_INITIAL_LOSS])\n\n    (self.loss,) = tpu.shard(\n        tpu_loop,\n        inputs=[],\n        num_shards=FLAGS.num_cores,\n        outputs_from_all_shards=False,\n    )\n    initializer = tf.global_variables_initializer()\n    graph_io.write_graph(tf.Graph().as_graph_def(add_shapes=True),\n                         FLAGS.model_dir, \"graph.pbtxt\")\n\n    # Build tpu train model session and initialize graph\n    self.sess = tflex.Session(\n        self.cluster_resolver.get_master(),\n        config=self.config)\n    self.sess.run(initializer)\n\n    self.var_list = [v for v in tf.global_variables() if 'Dataset/' not in v.name]\n    pprint(self.var_list)\n    self.saver = tf.train.Saver(\n      var_list=self.var_list,\n    )\n    if FLAGS.restore_dir is not None:\n      ckpt = tf.train.latest_checkpoint(FLAGS.restore_dir)\n      assert(ckpt is not None)\n    else:\n      ckpt = tf.train.latest_checkpoint(FLAGS.model_dir)\n    #ckpt = 'gs://danbooru-euw4a/checkpoint/test3/model.ckpt-742400'\n    if ckpt is None:\n      self.cur_ex = 0\n      tf.logging.info(\"TrainRunner: Saving initial model...\")\n      self.saver.save(self.sess, FLAGS.model_dir + \"/model.ckpt-%d\" % 0)\n    else:\n      self.cur_ex = int(ckpt.split('-')[-1])\n      tf.logging.info('TrainRunner: Restoring %s' % ckpt)\n      self.saver.restore(self.sess, ckpt)\n\n    # Complete infeed graph generation and session.run calls\n    self.infeed_thread = threading.Thread(target=infeed_thread_fn)\n    self.infeed_thread.start()\n\n  def train(self, num_threads=2):\n    \"\"\"Run the Train steps on the TPU device.\n\n    Args:\n      num_threads: number of outstanding checkpointing threads\n\n    \"\"\"\n\n    def checkpoint_thread_fn(saver, sess):\n      saver.save(sess, FLAGS.model_dir + \"/model.ckpt-%d\" % (self.cur_ex))\n\n    cur_step = 0\n    thread_id = 0\n    checkpoint_threads = []\n    tf.logging.info(\"TrainRunner: step %d\", cur_step)\n    begin = time.time()\n    for i in range(num_threads):\n      checkpoint_threads.append(None)\n    while cur_step < self.train_steps:\n      start = time.time()\n      tf.logging.info(\"TrainRunner: start next %d steps\", self.iterations)\n      cur_step += self.iterations\n      self.cur_ex += self.iterations * FLAGS.train_batch_size\n      loss = self.sess.run([self.loss])\n      if cur_step % 10 == 0 and cur_step > 0:\n        if checkpoint_threads[thread_id] is not None:\n          tf.logging.info(\"TrainRunner: waiting for checkpoint thread....\")\n          checkpoint_threads[thread_id].join()\n        from pprint import pprint\n        #pprint(self.var_list)\n        #tf.logging.info(\"TrainRunner: saving checkpoint....\")\n        checkpoint_threads[thread_id] = threading.Thread(\n            target=checkpoint_thread_fn, args=(self.saver, self.sess))\n        checkpoint_threads[thread_id].start()\n        thread_id += 1\n        if thread_id >= num_threads:\n          thread_id = 0\n      end = time.time()\n      tf.logging.info(\n          \"TrainRunner: step {} kex {:.3f} loss {} step time {:.2f}s total {:.2f}s {:.2f} examples/sec\"\n          .format(cur_step, self.cur_ex / 1000.0, loss, end - start, end - begin,\n                  self.iterations * FLAGS.train_batch_size / (end - start)))\n\n    self.infeed_thread.join()\n    for i in range(num_threads):\n      if checkpoint_threads[i] is not None:\n        checkpoint_threads[i].join()\n        checkpoint_threads[i] = None\n\n  def shutdown(self):\n    self.init_sess.run(self.tpu_shutdown)\n"
  },
  {
    "path": "stylegan2-tpu/training/training_loop.py",
    "content": "# Copyright (c) 2019, NVIDIA Corporation. All rights reserved.\n#\n# This work is made available under the Nvidia Source Code License-NC.\n# To view a copy of this license, visit\n# https://nvlabs.github.io/stylegan2/license.html\n\n\"\"\"Main training script.\"\"\"\n\nimport os\nimport numpy as np\nimport tensorflow as tf\nimport tflex\nimport time\nimport dnnlib\nimport dnnlib.tflib as tflib\nimport traceback\nfrom dnnlib.tflib.autosummary import autosummary, get_tpu_summary, set_num_replicas\n\nfrom training import dataset\nfrom training import misc\nfrom metrics import metric_base\nfrom pprint import pprint\n\n#----------------------------------------------------------------------------\n# Just-in-time processing of training images before feeding them to the networks.\n\ndef process_reals(x, labels, lod, mirror_augment, drange_data, drange_net):\n    with tf.name_scope('DynamicRange'):\n        x = tf.cast(x, tf.float32)\n        x = misc.adjust_dynamic_range(x, drange_data, drange_net)\n    if mirror_augment:\n        with tf.name_scope('MirrorAugment'):\n            x = tf.where(tf.random_uniform([tf.shape(x)[0]]) < 0.5, x, tf.reverse(x, [3]))\n    assert lod == 0.0\n    if False:\n        with tf.name_scope('FadeLOD'): # Smooth crossfade between consecutive levels-of-detail.\n            s = tf.shape(x)\n            y = tf.reshape(x, [-1, s[1], s[2]//2, 2, s[3]//2, 2])\n            y = tf.reduce_mean(y, axis=[3, 5], keepdims=True)\n            y = tf.tile(y, [1, 1, 1, 2, 1, 2])\n            y = tf.reshape(y, [-1, s[1], s[2], s[3]])\n            x = tflib.lerp(x, y, lod - tf.floor(lod))\n        with tf.name_scope('UpscaleLOD'): # Upscale to match the expected input/output size of the networks.\n            s = tf.shape(x)\n            factor = tf.cast(2 ** tf.floor(lod), tf.int32)\n            x = tf.reshape(x, [-1, s[1], s[2], 1, s[3], 1])\n            x = tf.tile(x, [1, 1, 1, factor, 1, factor])\n            x = tf.reshape(x, [-1, s[1], s[2] * factor, s[3] * factor])\n    return x, labels\n\n#----------------------------------------------------------------------------\n# Evaluate time-varying training parameters.\n\ndef training_schedule(\n    cur_nimg,\n    training_set,\n    lod_initial_resolution  = None,     # Image resolution used at the beginning.\n    lod_training_kimg       = 600,      # Thousands of real images to show before doubling the resolution.\n    lod_transition_kimg     = 600,      # Thousands of real images to show when fading in new layers.\n    minibatch_size_base     = 32,       # Global minibatch size.\n    minibatch_size_dict     = {},       # Resolution-specific overrides.\n    minibatch_gpu_base      = 4,        # Number of samples processed at a time by one GPU.\n    minibatch_gpu_dict      = {},       # Resolution-specific overrides.\n    G_lrate_base            = 0.002,    # Learning rate for the generator.\n    G_lrate_dict            = {},       # Resolution-specific overrides.\n    D_lrate_base            = 0.002,    # Learning rate for the discriminator.\n    D_lrate_dict            = {},       # Resolution-specific overrides.\n    lrate_rampup_kimg       = 0,        # Duration of learning rate ramp-up.\n    tick_kimg_base          = 4,        # Default interval of progress snapshots.\n    tick_kimg_dict          = {8:28, 16:24, 32:20, 64:16, 128:12, 256:8, 512:6, 1024:4}): # Resolution-specific overrides.\n\n    # Initialize result dict.\n    s = dnnlib.EasyDict()\n    s.kimg = cur_nimg / 1000.0\n\n    # Training phase.\n    phase_dur = lod_training_kimg + lod_transition_kimg\n    phase_idx = int(np.floor(s.kimg / phase_dur)) if phase_dur > 0 else 0\n    phase_kimg = s.kimg - phase_idx * phase_dur\n\n    # Level-of-detail and resolution.\n    if lod_initial_resolution is None:\n        s.lod = 0.0\n    else:\n        s.lod = training_set.resolution_log2\n        s.lod -= np.floor(np.log2(lod_initial_resolution))\n        s.lod -= phase_idx\n        if lod_transition_kimg > 0:\n            s.lod -= max(phase_kimg - lod_training_kimg, 0.0) / lod_transition_kimg\n        s.lod = max(s.lod, 0.0)\n    s.resolution = 2 ** (training_set.resolution_log2 - int(np.floor(s.lod)))\n\n    # Minibatch size.\n    s.minibatch_size = minibatch_size_dict.get(s.resolution, minibatch_size_base)\n    s.minibatch_gpu = minibatch_gpu_dict.get(s.resolution, minibatch_gpu_base)\n\n    # Learning rate.\n    s.G_lrate = G_lrate_dict.get(s.resolution, G_lrate_base)\n    s.D_lrate = D_lrate_dict.get(s.resolution, D_lrate_base)\n    if lrate_rampup_kimg > 0:\n        rampup = min(s.kimg / lrate_rampup_kimg, 1.0)\n        s.G_lrate *= rampup\n        s.D_lrate *= rampup\n\n    # Other parameters.\n    s.tick_kimg = tick_kimg_dict.get(s.resolution, tick_kimg_base)\n    return s\n\ndef get_input_fn(training_set, batch_size):\n    zz = training_set.get_minibatch_np(batch_size)\n    features = zz[0]\n    labels = zz[1]\n    dataset = tf.data.Dataset.from_tensor_slices((features, labels))\n    def input_fn(params):\n        batch_size = params[\"batch_size\"]\n        #features = {\"x\": np.ones((8, 3), dtype=np.float32)}\n        #labels = np.ones((8, 1), dtype=np.float32)\n        return dataset.repeat().batch(batch_size, drop_remainder=True)\n    return dataset, input_fn\n\ndef get_input_fn(training_set):\n    def input_fn(params):\n        import pdb; pdb.set_trace()\n        batch_size = params[\"batch_size\"]\n        features, labels = training_set.get_minibatch_np(batch_size)\n        features = tf.cast(features, dtype=tf.float32)\n        labels = tf.cast(labels, dtype=tf.float32)\n        dataset = tf.data.Dataset.from_tensor_slices((features, labels))\n        return dataset.repeat().batch(batch_size, drop_remainder=True)\n    return input_fn\n\n\ndef set_shapes(batch_size, num_channels, resolution, label_size, images, labels, transpose_input=False):\n    \"\"\"Statically set the batch_size dimension.\"\"\"\n    #import pdb; pdb.set_trace()\n    if transpose_input:\n        #if FLAGS.train_batch_size // FLAGS.num_cores > 8:\n        if True:\n            shape = [resolution, resolution, num_channels, batch_size]\n        else:\n            shape = [resolution, resolution, batch_size, num_channels]\n        images.set_shape(images.get_shape().merge_with(tf.TensorShape(shape)))\n        images = tf.reshape(images, [-1])\n        labels.set_shape(labels.get_shape().merge_with(\n            tf.TensorShape([batch_size, label_size])))\n    else:\n        images.set_shape(images.get_shape().merge_with(\n            tf.TensorShape([batch_size, num_channels, resolution, resolution])))\n        labels.set_shape(labels.get_shape().merge_with(\n            tf.TensorShape([batch_size, label_size])))\n    return images, labels\n\nimport functools\nfrom tensorflow.python.platform import gfile\n\n\ndef tf_randi(*args, **kws):\n    assert len(args) > 0\n    if len(args) == 1:\n        lo, hi = [0] + [x for x in args]\n    else:\n        lo, hi = args\n    return tf.random.uniform((), minval=lo, maxval=hi, dtype=tf.int32, **kws)\n\n\ndef tf_rand(*args, **kws):\n    if len(args) == 0:\n        lo, hi = 0.0, 1.0\n    elif len(args) == 1:\n        lo, hi = [0] + [x for x in args]\n    else:\n        lo, hi = args\n    return tf.random.uniform((), minval=lo, maxval=hi, **kws)\n\n\ndef tf_biased_rand(*args, bias=1, **kws):\n    x = tf_rand(*args, **kws)\n    # simple technique to bias the result towards the center.\n    for i in range(bias - 1):\n        x += tf_rand(*args, **kws)\n    dtype = kws.pop('dtype') if 'dtype' in kws else tf.float32\n    x = tf.cast(x, tf.float32) / bias\n    x = tf.cast(x, dtype)\n    return x\n\n\ndef tf_between(*args, bias=1, **kws):\n    if bias <= 0:\n        return tf_randi(*args, **kws)\n    else:\n        return tf_biased_rand(*args, dtype=tf.int32, bias=bias, **kws)\n\n\ndef random_crop(image_bytes, scope=None, resize=None, method=tf.image.ResizeMethod.AREA, seed=None):\n    with tf.name_scope(scope, 'random_crop', [image_bytes]):\n        shape = tf.image.extract_jpeg_shape(image_bytes)\n        w = shape[0]\n        h = shape[1]\n        channels = shape[2]\n        x, y = 0, 0\n        n = 3\n        image = tf.cond(w > h,\n                        lambda: tf.image.decode_and_crop_jpeg(image_bytes,\n                                                              tf.stack([x + tf_between(w - h, seed=seed), y, h, h]),\n                                                              channels=n),\n                        lambda: tf.cond(h > w,\n                                        lambda: tf.image.decode_and_crop_jpeg(image_bytes, tf.stack(\n                                            [x, y + tf_between(h - w, seed=seed), w, w]), channels=n),\n                                        lambda: tf.image.decode_jpeg(image_bytes, channels=n)))\n        if resize:\n            image_size = [resize, resize] if isinstance(resize, int) or isinstance(resize, float) else resize\n            image = tf.image.resize([image], image_size, method=method)[0]\n        return image\n\ndef _decode_and_center_crop(image_bytes, image_size, crop_padding=0):\n  \"\"\"Crops to center of image with padding then scales image_size.\"\"\"\n  shape = tf.image.extract_jpeg_shape(image_bytes)\n  image_height = shape[0]\n  image_width = shape[1]\n\n  padded_center_crop_size = tf.cast(\n      ((image_size / (image_size + crop_padding)) *\n       tf.cast(tf.minimum(image_height, image_width), tf.float32)),\n      tf.int32)\n\n  offset_height = ((image_height - padded_center_crop_size) + 1) // 2\n  offset_width = ((image_width - padded_center_crop_size) + 1) // 2\n  crop_window = tf.stack([offset_height, offset_width,\n                          padded_center_crop_size, padded_center_crop_size])\n  image = tf.image.decode_and_crop_jpeg(image_bytes, crop_window, channels=3)\n  image = tf.image.resize_area([image], [image_size, image_size])[0]\n\n  return image\n\nfrom tensorflow.python.data.experimental.ops import readers\nfrom tensorflow.python.data.kernel_tests import test_base\nfrom tensorflow.python.data.ops import dataset_ops\nfrom tensorflow.python.data.util import nest\nfrom tensorflow.python.framework import constant_op\nfrom tensorflow.python.framework import dtypes\nfrom tensorflow.python.framework import errors\nfrom tensorflow.python.framework import test_util\nfrom tensorflow.python.platform import test\n\ntype_map = {\n    'int32': dtypes.int32,\n    'int64': dtypes.int64,\n    'uint32': dtypes.uint32,\n    'uint64': dtypes.uint64,\n    'float32': dtypes.float32,\n    'float64': dtypes.float64,\n    'string': dtypes.string,\n    'i32': dtypes.int32,\n    'i64': dtypes.int64,\n    'u32': dtypes.uint32,\n    'u64': dtypes.uint64,\n    'f32': dtypes.float32,\n    'f64': dtypes.float64,\n    's': dtypes.string,\n}\n\ndef parse_header(x):\n  if '=' in x:\n    name, kind = x.split('=')\n    return name, constant_op.constant([], type_map[kind])\n  return x, constant_op.constant([], dtypes.string)\n\ndef csv_dataset(path, spec=None, **kws):\n  columns = [] if spec is None else [parse_header(x) for x in spec.split(',')]\n  column_names = None if spec is None else [x[0] for x in columns]\n  column_types = None if spec is None else [x[1] for x in columns]\n  return readers.make_csv_dataset(path, batch_size=1, column_names=column_names, column_defaults=column_types, **kws)\n\ndef imagenet_dataset(path, resize=None, seed=None):\n    print('Using imagenet dataset %s' % path)\n    #dataset = csv_dataset(path, \"name,width,height,channels,format,data\", header=False, shuffle=False, sloppy=True, num_parallel_reads=16)\n    dataset = readers.make_csv_dataset(path, batch_size=1, column_names=\"name,width,height,channels,format,data\".split(','),\n                                       column_defaults=[dtypes.string], select_columns=['data'],\n                                       header=False, shuffle=True, shuffle_seed=seed, sloppy=True, num_parallel_reads=16, ignore_errors=True)\n    def parse_image(x):\n      x = x['data'][0]\n      data = tf.io.decode_base64(x)\n      #img = random_crop(data, resize=resize)\n      img = _decode_and_center_crop(data, resize)\n      img = tf.transpose(img, [2,0,1])\n      label = tf.constant([])\n      return img, label\n    dataset = dataset.map(parse_image, num_parallel_calls=tf.data.experimental.AUTOTUNE)\n    return dataset\n\nfrom . import imagenet_input\n\ndef get_input_fn(load_training_set, num_cores, mirror_augment, drange_net):\n    self = training_set = load_training_set(batch_size=0)\n\n    def input_fn(params):\n        batch_size = params[\"batch_size\"]\n        #import pdb; pdb.set_trace()\n    \n        #num_channels = tfr_shape[0]\n        #resolution = tfr_shape[1]\n        num_channels = training_set.shape[0]\n        resolution = training_set.shape[1]\n        resolution_log2 = int(np.log2(resolution))\n        label_size = training_set.label_size\n\n        def get_tfrecord_files(tfrecord_dir):\n            assert gfile.IsDirectory(tfrecord_dir)\n            tfr_files = sorted(tf.io.gfile.glob(os.path.join(tfrecord_dir, '*-r%02d.tfrecords' % resolution_log2)))\n            assert len(tfr_files) == 1\n            return tfr_files\n\n        lod_index = -1\n        for tfr_file, tfr_shape, tfr_lod in training_set.tfr:\n          if tfr_shape[1] == resolution and tfr_shape[2] == resolution:\n            lod_index = tfr_lod\n        assert lod_index >= 0\n\n        #num_cores = batch_size\n        if False:\n            training_set.finalize()\n            label_size = training_set.label_size\n            dset = training_set._tf_datasets[lod_index]\n            dset = dset.batch(batch_size)\n\n            def dataset_parser_dynamic(features, labels):\n                features, labels = process_reals(features, labels, lod=0.0, mirror_augment=mirror_augment, drange_data=training_set.dynamic_range, drange_net=drange_net)\n                return features, labels\n\n            if False:\n                dset = dset.apply(\n                    tf.contrib.data.map_and_batch(\n                        dataset_parser_dynamic,\n                        batch_size=batch_size,\n                        num_parallel_batches=tf.data.experimental.AUTOTUNE,\n                        drop_remainder=True))\n            else:\n                dset = dset.map(\n                        dataset_parser_dynamic,\n                        num_parallel_calls=tf.data.experimental.AUTOTUNE)\n\n            # Assign static batch size dimension\n            dset = dset.map(functools.partial(set_shapes, batch_size, num_channels, resolution, label_size))\n            return dset\n        elif True:\n            #dset = training_set._tf_datasets[0]\n            #dset = tf.data.TFRecordDataset(tfr_file, compression_type='', buffer_size=buffer_mb << 20)\n            if 'context' in params:\n                current_host = params['context'].current_input_fn_deployment()[1]\n                num_hosts = params['context'].num_hosts\n            else:\n                if 'dataset_index' in params:\n                    current_host = params['dataset_index']\n                    num_hosts = params['dataset_num_shards']\n                else:\n                    current_host = 0\n                    num_hosts = 1\n            set_num_replicas(params[\"context\"].num_replicas if \"context\" in params else 1)\n            def load_stylegan_tfrecord(tfr_files, to_float=False):\n                dset = tf.data.Dataset.from_tensor_slices(tfr_files)\n                dset = dset.apply(tf.data.experimental.parallel_interleave(tf.data.TFRecordDataset, cycle_length=4, sloppy=True))\n                if training_set.label_file is not None:\n                    training_set._tf_labels_var, training_set._tf_labels_init = tflib.create_var_with_large_initial_value2(training_set._np_labels, name='labels_var', trainable=False)\n                    with tf.control_dependencies([training_set._tf_labels_init]):\n                        training_set._tf_labels_dataset = tf.data.Dataset.from_tensor_slices(training_set._tf_labels_var)\n                else:\n                    training_set._tf_labels_dataset = tf.data.Dataset.from_tensor_slices(training_set._np_labels)\n                dset = dset.map(dataset.TFRecordDataset.parse_tfrecord_tf_float if to_float else dataset.TFRecordDataset.parse_tfrecord_tf, num_parallel_calls=2)\n                dset = tf.data.Dataset.zip((dset, training_set._tf_labels_dataset))\n                return dset\n            if 'IMAGENET_DATASET' in os.environ:\n                dset = imagenet_dataset(os.environ['IMAGENET_DATASET'], resize=resolution, current_host=current_host, num_hosts=num_hosts)\n            elif 'IMAGENET_TFRECORD_DATASET' in os.environ:\n                if not 'IMAGENET_UNCONDITIONAL' in os.environ:\n                    if current_host == 0:\n                        print('Setting labels')\n                        training_set._np_labels = np.array([[1.0 if i == j else 0.0 for j in range(1000)] for i in range(1000)], dtype=np.float32)\n                        #training_set._np_labels = np.array([tflex.sha256label(str(i)) for i in range(1000)], dtype=np.float32)\n                        training_set._tf_labels_var, training_set._tf_labels_init = tflib.create_var_with_large_initial_value2(\n                            training_set._np_labels, name='labels_var', trainable=False)\n                        with tf.control_dependencies([training_set._tf_labels_init]):\n                            training_set._tf_labels_dataset = tf.data.Dataset.from_tensor_slices(training_set._tf_labels_var)\n                        training_set.label_size = 1000\n                        #training_set.label_size = len(tflex.sha256label(str(0))) # 28\n                label_size = training_set.label_size\n                num_channels = int(os.environ[\"NUM_CHANNELS\"]) if \"NUM_CHANNELS\" in os.environ else 3\n                assert num_channels == 3 or num_channels == 4\n                path = os.environ['IMAGENET_TFRECORD_DATASET']\n                ini = imagenet_input.ImageNetInput(path, is_training=True, image_size=resolution, num_cores=num_hosts)\n                iparams = dict(params)\n                iparams['batch_size'] = 1\n                dset = ini.input_fn(iparams)\n                def parse_image(img, label):\n                    img = tf.transpose(img, [0, 3, 1, 2])[0]\n                    if 'IMAGENET_UNCONDITIONAL' in os.environ:\n                        label = tf.constant([])\n                        if num_channels == 4:\n                            r = resolution\n                            n = 1\n                            c = tf.reshape(tf.tile(tf.tile(tf.constant(0, dtype=tf.float32), [tf.math.ceil(r / n)])[0:r], [r]), [r, r])\n                            img = tf.concat([img, [c]], axis=0)\n                    else:\n                        #label = label[0]\n                        #label = label[0]\n                        #label = tf.gather(training_set._tf_labels_var.initialized_value(), label)\n                        if num_channels == 4:\n                            r = resolution\n                            #n = label_size #tf.size(label)\n                            n = 1\n                            c = tf.reshape(tf.tile(tf.tile(label / label_size, [tf.math.ceil(r / n)])[0:r], [r]), [r, r])\n                            img = tf.concat([img, [c]], axis=0)\n                        label = tf.one_hot(label[0], 1000)\n                    return img, label\n                dset = dset.map(parse_image, num_parallel_calls=tf.data.experimental.AUTOTUNE)\n                print('Using imagenet dataset(s) %s (host %d / %d) channels=%d label_size=%d' % (path, current_host, num_hosts, num_channels, label_size))\n                if 'STYLEGAN_TFRECORD_DATASET' in os.environ:\n                    sgpaths = os.environ['STYLEGAN_TFRECORD_DATASET']\n                    paths = [x.strip() for x in sgpaths.split(',') if len(x.strip()) > 0]\n                    for path in paths:\n                        tfr_files = get_tfrecord_files(path)\n                        dset = dset.concatenate(load_stylegan_tfrecord(tfr_files, to_float=True))\n                    print('Using stylegan dataset(s) %s (host %d / %d) channels=%d label_size=%d' % (sgpaths, current_host, num_hosts, num_channels, label_size))\n            else:\n                tfr_files = get_tfrecord_files(training_set.tfrecord_dir)\n                dset = load_stylegan_tfrecord(tfr_files)\n\n            shuffle_mb = 4096  # Shuffle data within specified window (megabytes), 0 = disable shuffling.\n            prefetch_mb = 2048  # Amount of data to prefetch (megabytes), 0 = disable prefetching.\n\n            tfr_shape = (resolution, resolution, 3)\n            bytes_per_item = np.prod(tfr_shape) * np.dtype(training_set.dtype).itemsize\n            if shuffle_mb > 0:\n                dset = dset.shuffle(((shuffle_mb << 20) - 1) // bytes_per_item + 1)\n            repeat = True\n            if repeat:\n                dset = dset.repeat()\n            if prefetch_mb > 0:\n                dset = dset.prefetch(((prefetch_mb << 20) - 1) // bytes_per_item + 1)\n            dset = dset.batch(batch_size)\n            #dset = tf.data.TFRecordDataset(tfr_file)\n\n            def dataset_parser_dynamic(features, labels):\n                #features, labels = set_shapes(batch_size, num_channels, resolution, label_size, features, labels)\n                #features, labels = set_shapes(None, num_channels, resolution, label_size, features, labels)\n                features, labels = process_reals(features, labels, lod=0.0, mirror_augment=mirror_augment, drange_data=training_set.dynamic_range, drange_net=drange_net)\n                #features = tf.cast(features, tf.float32)\n                return features, labels\n\n            #import pdb; pdb.set_trace()\n            if False:\n                dset = dset.apply(\n                    tf.contrib.data.map_and_batch(\n                        dataset_parser_dynamic,\n                        batch_size=batch_size,\n                        num_parallel_batches=tf.data.experimental.AUTOTUNE,\n                        drop_remainder=True))\n            else:\n                dset = dset.map(\n                        dataset_parser_dynamic,\n                        num_parallel_calls=tf.data.experimental.AUTOTUNE)\n            #import pdb; pdb.set_trace()\n\n            # Assign static batch size dimension\n            dset = dset.map(functools.partial(set_shapes, batch_size, num_channels, resolution, label_size))\n            #import pdb; pdb.set_trace()\n\n            # Prefetch overlaps in-feed with training\n            #if self.prefetch_depth_auto_tune:\n            if False:\n                if True:\n                    dset = dset.prefetch(tf.contrib.data.AUTOTUNE)\n                else:\n                    dset = dset.prefetch(4)\n        else:\n            #training_set.configure(batch_size)\n            features, labels = training_set.get_minibatch_tf()\n            features.set_shape((batch_size, num_channels, resolution, resolution))\n            labels.set_shape((batch_size, label_size))\n            features = tf.cast(features, dtype=tf.float32)\n            labels = tf.cast(labels, dtype=tf.float32)\n            dset = tf.data.Dataset.from_tensor_slices((features, labels))\n            dset = dset.repeat().batch(batch_size, drop_remainder=True)\n        return dset\n    return input_fn, training_set\n\n#----------------------------------------------------------------------------\n# Main training script.\n\ndef training_loop(\n    G_args                  = {},       # Options for generator network.\n    D_args                  = {},       # Options for discriminator network.\n    G_opt_args              = {},       # Options for generator optimizer.\n    D_opt_args              = {},       # Options for discriminator optimizer.\n    G_loss_args             = {},       # Options for generator loss.\n    D_loss_args             = {},       # Options for discriminator loss.\n    dataset_args            = {},       # Options for dataset.load_dataset().\n    sched_args              = {},       # Options for train.TrainingSchedule.\n    grid_args               = {},       # Options for train.setup_snapshot_image_grid().\n    metric_arg_list         = [],       # Options for MetricGroup.\n    tf_config               = {},       # Options for tflib.init_tf().\n    data_dir                = None,     # Directory to load datasets from.\n    G_smoothing_kimg        = 10.0,     # Half-life of the running average of generator weights.\n    minibatch_repeats       = 4,        # Number of minibatches to run before adjusting training parameters.\n    lazy_regularization     = False,    # Perform regularization as a separate training step?\n    G_reg_interval          = 4,        # How often the perform regularization for G? Ignored if lazy_regularization=False.\n    D_reg_interval          = 16,       # How often the perform regularization for D? Ignored if lazy_regularization=False.\n    reset_opt_for_new_lod   = True,     # Reset optimizer internal state (e.g. Adam moments) when new layers are introduced?\n    total_kimg              = 25000,    # Total length of the training, measured in thousands of real images.\n    mirror_augment          = False,    # Enable mirror augment?\n    drange_net              = [-1,1],   # Dynamic range used when feeding image data to the networks.\n    image_snapshot_ticks    = 50,       # How often to save image snapshots? None = only save 'reals.png' and 'fakes-init.png'.\n    network_snapshot_ticks  = 50,       # How often to save network snapshots? None = only save 'networks-final.pkl'.\n    save_tf_graph           = False,    # Include full TensorFlow computation graph in the tfevents file?\n    save_weight_histograms  = False,    # Include weight histograms in the tfevents file?\n    resume_pkl              = None,     # Network pickle to resume training from, None = train from scratch.\n    resume_kimg             = 0.0,      # Assumed training progress at the beginning. Affects reporting and training schedule.\n    resume_time             = 0.0,      # Assumed wallclock time at the beginning. Affects reporting.\n    resume_with_new_nets    = False):   # Construct new networks according to G_args and D_args before resuming training?\n\n    tf.logging.set_verbosity(tf.logging.INFO)\n\n    if resume_pkl is None and 'RESUME_PKL' in os.environ:\n        resume_pkl = os.environ['RESUME_PKL']\n    if resume_kimg <= 0.0 and 'RESUME_KIMG' in os.environ:\n        resume_kimg = float(os.environ['RESUME_KIMG'])\n    if resume_time <= 0.0 and 'RESUME_TIME' in os.environ:\n        resume_time = float(os.environ['RESUME_TIME'])\n\n    num_gpus = dnnlib.submit_config.num_gpus\n\n    # Load training set.\n    def load_training_set(**kws):\n        return dataset.load_dataset(data_dir=dnnlib.convert_path(data_dir), verbose=True, **dataset_args, **kws)\n    input_fn, training_set = get_input_fn(load_training_set, num_gpus, mirror_augment=mirror_augment, drange_net=drange_net)\n\n    def model_fn(features, labels, mode, params):\n        nonlocal G_opt_args, D_opt_args, sched_args, G_reg_interval, D_reg_interval, lazy_regularization, G_smoothing_kimg\n        assert mode == tf.estimator.ModeKeys.TRAIN\n        num_channels = features.shape[1].value\n        resolution = features.shape[2].value\n        label_size = labels.shape[1].value\n        G = tflib.Network('G', num_channels=num_channels, resolution=resolution, label_size=label_size, **G_args)\n        D = tflib.Network('D', num_channels=num_channels, resolution=resolution, label_size=label_size, **D_args)\n        G.print_layers(); D.print_layers()\n        Gs, Gs_finalize = G.clone2('Gs')\n        G_gpu = G\n        D_gpu = D\n        reals_read = features\n        labels_read = labels\n\n        minibatch_gpu_in = params['batch_size']\n        G_opt_args = dict(G_opt_args)\n        D_opt_args = dict(D_opt_args)\n        sched_args = dict(sched_args)\n        G_opt = tflib.Optimizer(name='TrainG', cross_shard=True, learning_rate=sched_args['G_lrate_base'], **G_opt_args)\n        D_opt = tflib.Optimizer(name='TrainD', cross_shard=True, learning_rate=sched_args['D_lrate_base'], **D_opt_args)\n        with tf.name_scope('G_loss'):\n            G_loss, G_reg = dnnlib.util.call_func_by_name(G=G_gpu, D=D_gpu, opt=G_opt, training_set=training_set,\n                                                          minibatch_size=minibatch_gpu_in, **G_loss_args)\n        with tf.name_scope('D_loss'):\n            D_loss, D_reg = dnnlib.util.call_func_by_name(G=G_gpu, D=D_gpu, opt=D_opt, training_set=training_set,\n                                                          minibatch_size=minibatch_gpu_in, reals=reals_read,\n                                                          labels=labels_read, **D_loss_args)\n\n        # Register gradients.\n        G_reg_opt = tflib.Optimizer(name='RegG', share=G_opt, cross_shard=True, learning_rate=sched_args['G_lrate_base'], **G_opt_args)\n        D_reg_opt = tflib.Optimizer(name='RegD', share=D_opt, cross_shard=True, learning_rate=sched_args['D_lrate_base'], **D_opt_args)\n        if not lazy_regularization:\n            G_reg_loss = None\n            D_reg_loss = None\n            if G_reg is not None: G_loss += G_reg\n            if D_reg is not None: D_loss += D_reg\n        else:\n            if G_reg is not None: G_reg_loss = tf.reduce_mean(G_reg * G_reg_interval)\n            if D_reg is not None: D_reg_loss = tf.reduce_mean(D_reg * D_reg_interval)\n            if G_reg is not None: G_reg_opt.register_gradients(G_reg_loss, G_gpu.trainables)\n            if D_reg is not None: D_reg_opt.register_gradients(D_reg_loss, D_gpu.trainables)\n        G_loss_op = tf.reduce_mean(G_loss)\n        D_loss_op = tf.reduce_mean(D_loss)\n        G_opt.register_gradients(G_loss_op, G_gpu.trainables)\n        D_opt.register_gradients(D_loss_op, D_gpu.trainables)\n        inc_global_step = tf.assign_add(tf.train.get_or_create_global_step(), minibatch_gpu_in, name=\"inc_global_step\")\n        G_train_op = G_opt._shared_optimizers[''].minimize(G_loss_op, var_list=G_gpu.trainables)\n        D_train_op = D_opt._shared_optimizers[''].minimize(D_loss_op, var_list=D_gpu.trainables)\n        if lazy_regularization:\n            if False:\n                G_reg_train_op = tf.cond(\n                    lambda: tf.cast(tf.mod(tf.train.get_global_step(), G_reg_interval), tf.bool),\n                    lambda: G_reg_opt._shared_optimizers[''].minimize(G_reg_loss, var_list=G_gpu.trainables),\n                    lambda: tf.no_op()) if G_reg_loss is not None else tf.no_op()\n                D_reg_train_op = tf.cond(\n                    lambda: tf.cast(tf.mod(tf.train.get_global_step(), D_reg_interval), tf.bool),\n                    lambda: D_reg_opt._shared_optimizers[''].minimize(D_reg_loss, var_list=D_gpu.trainables),\n                    lambda: tf.no_op()) if D_reg_loss is not None else tf.no_op()\n            else:\n                assert (G_reg is not None)\n                assert (D_reg is not None)\n                def G_fn():\n                    with tf.control_dependencies([tf.train.get_or_create_global_step()]):\n                        G_op = G_reg_opt._shared_optimizers[''].minimize(G_reg_loss, var_list=G_gpu.trainables)\n                        return G_op\n                def D_fn():\n                    with tf.control_dependencies([tf.train.get_or_create_global_step()]):\n                        D_op = D_reg_opt._shared_optimizers[''].minimize(D_reg_loss, var_list=D_gpu.trainables)\n                        return D_op\n                def G_else():\n                    with tf.control_dependencies([tf.train.get_or_create_global_step()]):\n                        return tf.no_op()\n                def D_else():\n                    with tf.control_dependencies([tf.train.get_or_create_global_step()]):\n                        return tf.no_op()\n                G_reg_train_op = tf.cond(lambda: tf.equal(tf.mod(tf.train.get_or_create_global_step(), G_reg_interval), tf.constant(0, tf.int64)), G_fn, G_else)\n                D_reg_train_op = tf.cond(lambda: tf.equal(tf.mod(tf.train.get_or_create_global_step(), D_reg_interval), tf.constant(0, tf.int64)), D_fn, D_else)\n        else:\n            G_reg_train_op = G_reg_opt._shared_optimizers[''].minimize(G_reg_loss, var_list=G_gpu.trainables) if G_reg_loss is not None else tf.no_op()\n            D_reg_train_op = D_reg_opt._shared_optimizers[''].minimize(D_reg_loss, var_list=D_gpu.trainables) if D_reg_loss is not None else tf.no_op()\n\n        minibatch_size_in = batch_size\n        Gs_beta              = 0.5 ** tf.div(tf.cast(minibatch_size_in, tf.float32), G_smoothing_kimg * 1000.0) if G_smoothing_kimg > 0.0 else 0.0\n        Gs_update_op = Gs.setup_as_moving_average_of(G, beta=Gs_beta)\n        loss = G_loss_op + D_loss_op\n        if G_reg_loss is not None: loss += G_reg_loss\n        if D_reg_loss is not None: loss += D_reg_loss\n        with tf.control_dependencies([inc_global_step]):\n            with tf.control_dependencies([G_train_op]):\n                with tf.control_dependencies([G_reg_train_op]):\n                    with tf.control_dependencies([D_train_op]):\n                        with tf.control_dependencies([D_reg_train_op]):\n                            with tf.control_dependencies(tf.get_collection(tf.GraphKeys.UPDATE_OPS)):\n                                train_op = tf.group(Gs_update_op, name='train_op')\n        return tf.contrib.tpu.TPUEstimatorSpec(\n            mode=mode,\n            host_call = get_tpu_summary().get_host_call(),\n            loss=loss,\n            train_op=train_op)\n\n    use_tpu = True\n    training_steps = 2048*20480\n    batch_size = sched_args.minibatch_size_base\n    pprint(sched_args)\n    model_dir=os.environ['MODEL_DIR'] if 'MODEL_DIR' in os.environ else 'gs://danbooru-euw4a/test/run30/'\n    tpu_cluster_resolver = tflex.get_tpu_resolver()\n    run_config = tf.contrib.tpu.RunConfig(\n        model_dir=model_dir,\n        #save_checkpoints_steps=100,\n        save_checkpoints_secs=600//5,\n        keep_checkpoint_max=10,\n        keep_checkpoint_every_n_hours=1,\n        cluster=tpu_cluster_resolver,\n        tpu_config=tf.contrib.tpu.TPUConfig(iterations_per_loop=256))\n\n# Uncomment for warmstarting from checkpoint\n#     ws = tf.estimator.WarmStartSettings(\n#              ckpt_to_initialize_from=\"gs://tpu-mamm/warmstart\",\n#              vars_to_warm_start=\".*\")\n\n    estimator = tf.contrib.tpu.TPUEstimator(\n        config=run_config,\n        use_tpu=use_tpu,\n        model_fn=model_fn,\n        train_batch_size=batch_size,\n#         warm_start_from=ws\n    )\n    print('Training...')\n    estimator.train(input_fn, steps=training_steps)\n    import pdb; pdb.set_trace()\n\n    grid_size, grid_reals, grid_labels = misc.setup_snapshot_image_grid(training_set, **grid_args)\n    misc.save_image_grid(grid_reals, dnnlib.make_run_dir_path('reals.png'), drange=training_set.dynamic_range, grid_size=grid_size)\n\n    # Construct or load networks.\n    with tflex.device('/gpu:0'):\n        if resume_pkl is None or resume_with_new_nets:\n            print('Constructing networks...')\n            G = tflib.Network('G', num_channels=training_set.shape[0], resolution=training_set.shape[1], label_size=training_set.label_size, **G_args)\n            D = tflib.Network('D', num_channels=training_set.shape[0], resolution=training_set.shape[1], label_size=training_set.label_size, **D_args)\n            Gs = G.clone('Gs')\n        if resume_pkl is not None:\n            print('Loading networks from \"%s\"...' % resume_pkl)\n            rG, rD, rGs = misc.load_pkl(resume_pkl)\n            if resume_with_new_nets: G.copy_vars_from(rG); D.copy_vars_from(rD); Gs.copy_vars_from(rGs)\n            else: G = rG; D = rD; Gs = rGs\n\n    # Print layers and generate initial image snapshot.\n    G.print_layers(); D.print_layers()\n    sched = training_schedule(cur_nimg=total_kimg*1000, training_set=training_set, **sched_args)\n    grid_latents = np.random.randn(np.prod(grid_size), *G.input_shape[1:])\n    #grid_fakes = Gs.run(grid_latents, grid_labels, is_validation=True, randomize_noise=False, minibatch_size=sched.minibatch_gpu)\n    #misc.save_image_grid(grid_fakes, dnnlib.make_run_dir_path('fakes_init.png'), drange=drange_net, grid_size=grid_size)\n\n    def save_image_grid(latents, grid_size, filename):\n        grid_fakes = Gs.run(latents, grid_labels, is_validation=True, randomize_noise=False, minibatch_size=sched.minibatch_gpu)\n        misc.save_image_grid(grid_fakes, filename, drange=drange_net, grid_size=grid_size)\n\n    tflex.save_image_grid = save_image_grid\n\n    def save_image_grid_command(randomize=False):\n        if randomize:\n            tflex.latents = np.random.randn(np.prod(grid_size), *G.input_shape[1:])\n        if not hasattr(tflex, 'latents'):\n            tflex.latents = grid_latents\n        if randomize or not hasattr(tflex, 'grid_filename'):\n            tflex.grid_filename = dnnlib.make_run_dir_path('grid%06d.png' % int(time.time()))\n        use_grid_size = (2, 2)\n        latents = tflex.latents[:np.prod(use_grid_size)]\n        tflex.save_image_grid(latents, use_grid_size, tflex.grid_filename)\n        print('Saved ' + tflex.grid_filename)\n\n    tflex.save_image_grid_command = save_image_grid_command\n\n    @tflex.register_command\n    def image_grid():\n        tflex.save_image_grid_command(randomize=True)\n\n    @tflex.register_command\n    def resave_image_grid():\n        tflex.save_image_grid_command(randomize=False)\n\n    # Setup training inputs.\n    print('Building TensorFlow graph...')\n    with tf.name_scope('Inputs'), tflex.device('/cpu:0'):\n        lod_in               = tf.placeholder(tf.float32, name='lod_in', shape=[])\n        lrate_in             = tf.placeholder(tf.float32, name='lrate_in', shape=[])\n        minibatch_size_in    = tf.placeholder(tf.int32, name='minibatch_size_in', shape=[])\n        minibatch_gpu_in     = tf.placeholder(tf.int32, name='minibatch_gpu_in', shape=[])\n        minibatch_multiplier = minibatch_size_in // (minibatch_gpu_in * num_gpus)\n        Gs_beta              = 0.5 ** tf.div(tf.cast(minibatch_size_in, tf.float32), G_smoothing_kimg * 1000.0) if G_smoothing_kimg > 0.0 else 0.0\n\n    # Setup optimizers.\n    G_opt_args = dict(G_opt_args)\n    D_opt_args = dict(D_opt_args)\n    for args, reg_interval in [(G_opt_args, G_reg_interval), (D_opt_args, D_reg_interval)]:\n        args['minibatch_multiplier'] = minibatch_multiplier\n        args['learning_rate'] = lrate_in\n        if lazy_regularization:\n            mb_ratio = reg_interval / (reg_interval + 1)\n            args['learning_rate'] *= mb_ratio\n            if 'beta1' in args: args['beta1'] **= mb_ratio\n            if 'beta2' in args: args['beta2'] **= mb_ratio\n    G_opt = tflib.Optimizer(name='TrainG', **G_opt_args)\n    D_opt = tflib.Optimizer(name='TrainD', **D_opt_args)\n    G_reg_opt = tflib.Optimizer(name='RegG', share=G_opt, **G_opt_args)\n    D_reg_opt = tflib.Optimizer(name='RegD', share=D_opt, **D_opt_args)\n\n    # Build training graph for each GPU.\n    data_fetch_ops = []\n    shards = {}\n    def get_shard(i):\n        with tflex.lock:\n            if i not in shards:\n                shards[i] = dnnlib.EasyDict()\n            return shards[i]\n    def make_generator(gpu):\n        me = get_shard(gpu)\n        prev = None if gpu <= 0 else get_shard(gpu - 1)\n        with tf.name_scope('GPU%d' % gpu), tflex.device('/gpu:%d' % gpu):\n            # Create GPU-specific shadow copies of G and D.\n            G_gpu, G_final = (G, None) if gpu == 0 else G.clone2(G.name + '_shadow')\n            D_gpu, D_final = (D, None) if gpu == 0 else D.clone2(D.name + '_shadow')\n        with tflex.lock:\n            me.G = G_gpu\n            me.D = D_gpu\n            me.G_final = tflex.defer(G_final, dependencies=[prev.G_final] if prev else [])\n            me.D_final = tflex.defer(D_final, dependencies=[prev.D_final] if prev else [])\n    print('Making generators...')\n    tflex.parallelize_verbose(\"Generator\", range(num_gpus), make_generator, synchronous=True)\n    if False:\n        print('Finalizing clones...')\n        def make_shadow(gpu):\n            me = get_shard(gpu)\n            me.G_final.join()\n            me.D_final.join()\n        tflex.parallelize_verbose(\"Finalize clone\", range(num_gpus), make_shadow, synchronous=False)\n\n    def make_shard(gpu):\n        nonlocal data_fetch_ops\n        me = get_shard(gpu)\n        with tf.name_scope('GPU%d' % gpu), tflex.device('/gpu:%d' % gpu):\n            # Create GPU-specific shadow copies of G and D.\n            #G_gpu = G if gpu == 0 else G.clone(G.name + '_shadow')\n            #D_gpu = D if gpu == 0 else D.clone(D.name + '_shadow')\n            G_gpu = me.G\n            D_gpu = me.D\n            me.G_final.join()\n            me.D_final.join()\n\n            tflex.break_next_run = (gpu > 0)\n\n            # Fetch training data via temporary variables.\n            with tf.name_scope('DataFetch'):\n                sched = training_schedule(cur_nimg=int(resume_kimg*1000), training_set=training_set, **sched_args)\n                reals_var = tf.Variable(name='reals', trainable=False, initial_value=tf.zeros([sched.minibatch_gpu] + training_set.shape))\n                labels_var = tf.Variable(name='labels', trainable=False, initial_value=tf.zeros([sched.minibatch_gpu, training_set.label_size]))\n                reals_write, labels_write = training_set.get_minibatch_tf()\n                reals_write, labels_write = process_reals(reals_write, labels_write, lod_in, mirror_augment, training_set.dynamic_range, drange_net)\n                reals_write = tf.concat([reals_write, reals_var[minibatch_gpu_in:]], axis=0)\n                labels_write = tf.concat([labels_write, labels_var[minibatch_gpu_in:]], axis=0)\n                data_fetch_ops += [tf.group(tf.assign(reals_var, reals_write), name=\"fetch_reals\")]\n                data_fetch_ops += [tf.group(tf.assign(labels_var, labels_write), name=\"fetch_labels\")]\n                reals_read = reals_var[:minibatch_gpu_in]\n                labels_read = labels_var[:minibatch_gpu_in]\n\n            # Evaluate loss functions.\n            lod_assign_ops = []\n            if 'lod' in G_gpu.vars: lod_assign_ops += [tf.assign(G_gpu.vars['lod'], lod_in)]\n            if 'lod' in D_gpu.vars: lod_assign_ops += [tf.assign(D_gpu.vars['lod'], lod_in)]\n            with tf.control_dependencies(lod_assign_ops):\n                with tf.name_scope('G_loss'):\n                    G_loss, G_reg = dnnlib.util.call_func_by_name(G=G_gpu, D=D_gpu, opt=G_opt, training_set=training_set, minibatch_size=minibatch_gpu_in, **G_loss_args)\n                with tf.name_scope('D_loss'):\n                    D_loss, D_reg = dnnlib.util.call_func_by_name(G=G_gpu, D=D_gpu, opt=D_opt, training_set=training_set, minibatch_size=minibatch_gpu_in, reals=reals_read, labels=labels_read, **D_loss_args)\n\n            # Register gradients.\n            if not lazy_regularization:\n                if G_reg is not None: G_loss += G_reg\n                if D_reg is not None: D_loss += D_reg\n            else:\n                if G_reg is not None: G_reg_opt.register_gradients(tf.reduce_mean(G_reg * G_reg_interval), G_gpu.trainables)\n                if D_reg is not None: D_reg_opt.register_gradients(tf.reduce_mean(D_reg * D_reg_interval), D_gpu.trainables)\n            G_opt.register_gradients(tf.reduce_mean(G_loss), G_gpu.trainables)\n            D_opt.register_gradients(tf.reduce_mean(D_loss), D_gpu.trainables)\n    print('Making shards...')\n    tflex.parallelize_verbose(\"Shard\", range(num_gpus), make_shard, synchronous=True)\n\n    # Setup training ops.\n    data_fetch_op = tf.group(*data_fetch_ops)\n    G_train_op, G_finalize = G_opt.apply_updates()\n    D_train_op, D_finalize = D_opt.apply_updates()\n    G_reg_op, G_reg_finalize = G_reg_opt.apply_updates(allow_no_op=True)\n    D_reg_op, D_reg_finalize = D_reg_opt.apply_updates(allow_no_op=True)\n    Gs_update_op = Gs.setup_as_moving_average_of(G, beta=Gs_beta)\n\n    tflex.parallelize_verbose(\"initialize optimizers\", [G_finalize, D_finalize, G_reg_finalize, D_reg_finalize], lambda f: f())\n\n    # Finalize graph.\n    if tflex.has_gpu():\n        with tflex.device('/gpu:0'):\n            try:\n                peak_gpu_mem_op = tf.contrib.memory_stats.MaxBytesInUse()\n            except tf.errors.NotFoundError:\n                peak_gpu_mem_op = tf.constant(0)\n    else:\n        peak_gpu_mem_op = None\n    tflib.init_uninitialized_vars()\n\n    print('Initializing logs...')\n    summary_log = tf.summary.FileWriter(dnnlib.make_run_dir_path())\n    if save_tf_graph:\n        summary_log.add_graph(tf.get_default_graph())\n    if save_weight_histograms:\n        G.setup_weight_histograms(); D.setup_weight_histograms()\n    metrics = metric_base.MetricGroup(metric_arg_list)\n\n    print('Training for %d kimg...\\n' % total_kimg)\n    dnnlib.RunContext.get().update('', cur_epoch=resume_kimg, max_epoch=total_kimg)\n    maintenance_time = dnnlib.RunContext.get().get_last_update_interval()\n    cur_nimg = int(resume_kimg * 1000)\n    cur_tick = -1\n    tick_start_nimg = cur_nimg\n    prev_lod = -1.0\n    running_mb_counter = 0\n    need_warmup = True\n    while cur_nimg < total_kimg * 1000:\n        if tflex.state.noisy: print('cur_nimg', cur_nimg, total_kimg)\n        if dnnlib.RunContext.get().should_stop(): break\n\n        # Choose training parameters and configure training ops.\n        sched = training_schedule(cur_nimg=cur_nimg, training_set=training_set, **sched_args)\n        assert sched.minibatch_size % (sched.minibatch_gpu * num_gpus) == 0\n        training_set.configure(sched.minibatch_gpu, sched.lod)\n        if reset_opt_for_new_lod:\n            if np.floor(sched.lod) != np.floor(prev_lod) or np.ceil(sched.lod) != np.ceil(prev_lod):\n                G_opt.reset_optimizer_state(); D_opt.reset_optimizer_state()\n        prev_lod = sched.lod\n\n        # Run training ops.\n        feed_dict = {lod_in: sched.lod, lrate_in: sched.G_lrate, minibatch_size_in: sched.minibatch_size, minibatch_gpu_in: sched.minibatch_gpu}\n        if need_warmup:\n            i = 0\n            all_ops = [[G_train_op, data_fetch_op], [G_reg_op], [D_train_op, Gs_update_op], [D_reg_op]]\n            for ops in all_ops:\n                tflex.parallelize_verbose(\"warmup %d / %d\" % (i, len(all_ops)), ops, lambda op: tflib.run(op, feed_dict))\n                i += 1\n            need_warmup = False\n        for _repeat in range(minibatch_repeats):\n            if tflex.state.noisy: print('_repeat', _repeat)\n            rounds = range(0, sched.minibatch_size, sched.minibatch_gpu * num_gpus)\n            run_G_reg = (lazy_regularization and running_mb_counter % G_reg_interval == 0)\n            run_D_reg = (lazy_regularization and running_mb_counter % D_reg_interval == 0)\n            cur_nimg += sched.minibatch_size\n            running_mb_counter += 1\n\n            # Fast path without gradient accumulation.\n            if len(rounds) == 1:\n                if tflex.state.noisy: print('G_train_op', 'fast path')\n                #tflib.run([G_train_op, data_fetch_op], feed_dict)\n                tflib.run(G_train_op, feed_dict)\n                tflib.run(data_fetch_op, feed_dict)\n                if run_G_reg:\n                    tflib.run(G_reg_op, feed_dict)\n                if tflex.state.noisy: print('D_train_op', 'fast path')\n                #tflib.run([D_train_op, Gs_update_op], feed_dict)\n                tflib.run(D_train_op, feed_dict)\n                tflib.run(Gs_update_op, feed_dict)\n                if run_D_reg:\n                    tflib.run(D_reg_op, feed_dict)\n\n            # Slow path with gradient accumulation.\n            else:\n                for _round in rounds:\n                    if tflex.state.noisy: print('G_train_op', 'slow path')\n                    tflib.run(G_train_op, feed_dict)\n                if run_G_reg:\n                    for _round in rounds:\n                        if tflex.state.noisy: print('G_reg_op', 'slow path')\n                        tflib.run(G_reg_op, feed_dict)\n                if tflex.state.noisy: print('G_update_op', 'slow path')\n                tflib.run(Gs_update_op, feed_dict)\n                for _round in rounds:\n                    if tflex.state.noisy: print('data_fetch_op', 'slow path')\n                    tflib.run(data_fetch_op, feed_dict)\n                    if tflex.state.noisy: print('D_train_op', 'slow path')\n                    tflib.run(D_train_op, feed_dict)\n                if run_D_reg:\n                    for _round in rounds:\n                        if tflex.state.noisy: print('D_reg_op', 'slow path')\n                        tflib.run(D_reg_op, feed_dict)\n\n        # Perform maintenance tasks once per tick.\n        done = (cur_nimg >= total_kimg * 1000)\n        if cur_tick < 0 or cur_nimg >= tick_start_nimg + sched.tick_kimg * 1000 or done:\n            cur_tick += 1\n            tick_kimg = (cur_nimg - tick_start_nimg) / 1000.0\n            tick_time = dnnlib.RunContext.get().get_time_since_last_update()\n\n            def report_progress_command():\n                total_time = dnnlib.RunContext.get().get_time_since_start() + resume_time\n                tick_kimg = (cur_nimg - tick_start_nimg) / 1000.0\n                tick_time = dnnlib.RunContext.get().get_time_since_last_update()\n                print('tick %-5d kimg %-8.1f lod %-5.2f minibatch %-4d time %-12s sec/tick %-7.1f sec/kimg %-7.2f maintenance %-6.1f gpumem %.1f' % (\n                    autosummary('Progress/tick', cur_tick),\n                    autosummary('Progress/kimg', cur_nimg / 1000.0),\n                    autosummary('Progress/lod', sched.lod),\n                    autosummary('Progress/minibatch', sched.minibatch_size),\n                    dnnlib.util.format_time(autosummary('Timing/total_sec', total_time)),\n                    autosummary('Timing/sec_per_tick', tick_time),\n                    autosummary('Timing/sec_per_kimg', tick_time / tick_kimg),\n                    autosummary('Timing/maintenance_sec', maintenance_time),\n                    autosummary('Resources/peak_gpu_mem_gb', (peak_gpu_mem_op.eval() if peak_gpu_mem_op is not None else 0) / 2**30)))\n                autosummary('Timing/total_hours', total_time / (60.0 * 60.0))\n                autosummary('Timing/total_days', total_time / (24.0 * 60.0 * 60.0))\n\n            if not hasattr(tflex, 'report_progress_command'):\n                tflex.report_progress_command = report_progress_command\n\n            @tflex.register_command\n            def report_progress():\n                tflex.report_progress_command()\n\n            def save_command():\n                pkl = dnnlib.make_run_dir_path('network-snapshot-%06d.pkl' % (cur_nimg // 1000))\n                misc.save_pkl((G, D, Gs), pkl)\n                metrics.run(pkl, run_dir=dnnlib.make_run_dir_path(), data_dir=dnnlib.convert_path(data_dir), num_gpus=num_gpus, tf_config=tf_config)\n\n            if not hasattr(tflex, 'save_command'):\n                tflex.save_command = save_command\n\n            @tflex.register_command\n            def save():\n                tflex.save_command()\n\n            try:\n              # Report progress.\n              tflex.report_progress_command()\n              tick_start_nimg = cur_nimg\n\n              # Save snapshots.\n              if image_snapshot_ticks is not None and (cur_tick % image_snapshot_ticks == 0 or done):\n                  def thunk(_):\n                      grid_fakes = Gs.run(grid_latents, grid_labels, is_validation=True, randomize_noise=False, minibatch_size=sched.minibatch_gpu)\n                      misc.save_image_grid(grid_fakes, dnnlib.make_run_dir_path('fakes%06d.png' % (cur_nimg // 1000)), drange=drange_net, grid_size=grid_size)\n                  tflex.parallelize([0], thunk)\n              if network_snapshot_ticks is not None and cur_tick > 0 and (cur_tick % network_snapshot_ticks == 0 or done):\n                  def thunk(_):\n                      tflex.save_command()\n                  tflex.parallelize([0], thunk)\n\n              # Update summaries and RunContext.\n              metrics.update_autosummaries()\n              tflib.autosummary.save_summaries(summary_log, cur_nimg)\n              dnnlib.RunContext.get().update('%.2f' % sched.lod, cur_epoch=cur_nimg // 1000, max_epoch=total_kimg)\n              maintenance_time = dnnlib.RunContext.get().get_last_update_interval() - tick_time\n            except:\n              traceback.print_exc()\n\n    # Save final snapshot.\n    misc.save_pkl((G, D, Gs), dnnlib.make_run_dir_path('network-final.pkl'))\n\n    # All done.\n    summary_log.close()\n    training_set.close()\n\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "stylegan2-tpu/view.py",
    "content": "import os\n\nif 'COLAB_TPU_ADDR' in os.environ:\n  os.environ['TPU_NAME'] = 'grpc://' + os.environ['COLAB_TPU_ADDR']\n\nos.environ['NOISY'] = '1'\n\n# --- set resolution and label size here:\nlabel_size = int(os.environ['LABEL_SIZE'])\nresolution = int(os.environ['RESOLUTION'])\nfmap_base = (int(os.environ['FMAP_BASE']) if 'FMAP_BASE' in os.environ else 16) << 10\nnum_channels = int(os.environ['NUM_CHANNELS'])\nmodel_dir = os.environ['MODEL_DIR']\nchannel = os.environ['CHANNEL'] if 'CHANNEL' in os.environ else 'chaos'\ncount = int(os.environ['COUNT']) if 'COUNT' in os.environ else 1\ndiscord_token = os.environ['DISCORD_TOKEN']\ngrid_image_size = int(os.environ['GRID_SIZE']) if 'GRID_SIZE' in os.environ else 9\n# ------------------------\n\nimport tqdm\nfrom pprint import pprint as pp\nfrom training.networks_stylegan2 import *\nfrom training import misc\n\nimport dnnlib\nfrom dnnlib import EasyDict\n\nimport tensorflow as tf\nimport tflex\nimport os\nimport numpy as np\n\ndnnlib.tflib.init_tf()\n\nsess = tf.get_default_session()\nsess.list_devices()\n\n\n\ncores = tflex.get_cores()\ntflex.set_override_cores(cores)\n\n#synthesis_func          = 'G_synthesis_stylegan2'\n#kwargs = {'resolution': 512}\n#synthesis = tflib.Network('G_synthesis', func_name=globals()[synthesis_func], **kwargs)\n\n#sess.reset(os.environ['TPU_NAME']) # don't do this, this breaks the session\n\ntrain     = EasyDict(run_func_name='training.training_loop.training_loop') # Options for training loop.\nG_args    = EasyDict(func_name='training.networks_stylegan2.G_main')       # Options for generator network.\nD_args    = EasyDict(func_name='training.networks_stylegan2.D_stylegan2')  # Options for discriminator network.\nG_opt     = EasyDict(beta1=0.0, beta2=0.99, epsilon=1e-8)                  # Options for generator optimizer.\nD_opt     = EasyDict(beta1=0.0, beta2=0.99, epsilon=1e-8)                  # Options for discriminator optimizer.\nG_loss    = EasyDict(func_name='training.loss.G_logistic_ns_pathreg')      # Options for generator loss.\nD_loss    = EasyDict(func_name='training.loss.D_logistic_r1')              # Options for discriminator loss.\nsched     = EasyDict()                                                     # Options for TrainingSchedule.\ngrid      = EasyDict(size='8k', layout='random')                           # Options for setup_snapshot_image_grid().\nsc        = dnnlib.SubmitConfig()                                          # Options for dnnlib.submit_run().\ntf_config = {'rnd.np_random_seed': 1000}    \nlabel_dtype = np.int64\nsched.minibatch_gpu = 1\n\nif 'G' not in globals():\n  with tflex.device('/gpu:0'):\n    G = tflib.Network('G', num_channels=num_channels, resolution=resolution, label_size=label_size, fmap_base=fmap_base, **G_args)\n    G.print_layers()\n    Gs, Gs_finalize = G.clone2('Gs')\n    Gs_finalize()\n    D = tflib.Network('D', num_channels=num_channels, resolution=resolution, label_size=label_size, fmap_base=fmap_base, **D_args)\n    D.print_layers()\n\ndef rand_latent(n, seed=None):\n  if seed is not None:\n    if seed < 0:\n      seed = 2*32 - seed\n    np.random.seed(seed)\n  result = np.random.randn(n, *G.input_shape[1:])\n  if seed is not None:\n    np.random.seed()\n  return result\n\ngrid_size = (2, 2)\ngw, gh = grid_size\ngn = np.prod(grid_size)\ngrid_latents = rand_latent(gn, seed=-1)\ngrid_labels = np.zeros([gw * gh, label_size], dtype=label_dtype)\n\ndef tfinit():\n  tflib.run(tf.global_variables_initializer())\n\ntfinit()\n\nsaver = tf.train.Saver()\n\ndef load_checkpoint(path):\n  ckpt = tf.train.latest_checkpoint(path)\n  assert ckpt is not None\n  print('Loading checkpoint ' + ckpt)\n  saver.restore(sess, ckpt)\n  return ckpt\n\n\ntflex.state.noisy = False\n\n# https://stackoverflow.com/a/18284900/9919772\ntry:\n    from StringIO import StringIO as BytesIO ## for Python 2\nexcept ImportError:\n    from io import BytesIO ## for Python 3\n#import IPython.display\nimport numpy as np\n\ndef get_grid_size(n):\n  gw = 1\n  gh = 1\n  i = 0\n  while gw*gh < n:\n    if i % 2 == 0:\n      gw += 1\n    else:\n      gh += 1\n    i += 1\n  return (gw, gh)\n\ndef gen_images(latents, outfile=None, display=False, labels=None, randomize_noise=False, is_validation=True, network=None, numpy=False):\n  if network is None:\n    network = Gs\n  n = latents.shape[0]\n  grid_size = get_grid_size(n)\n  drange_net = [-1, 1]\n  with tflex.device('/gpu:0'):\n    result = network.run(latents, labels, is_validation=is_validation, randomize_noise=randomize_noise, minibatch_size=sched.minibatch_gpu)\n    #if result.shape[1] > 3:\n    #  final = result[:, 3, :, :]\n    #else:\n    #  final = None\n    result = result[:, 0:3, :, :]\n    img = misc.convert_to_pil_image(misc.create_image_grid(result, grid_size), drange_net)\n    if outfile is not None:\n      img.save(outfile)\n    if display:\n      f = BytesIO()\n      img.save(f, 'png')\n      IPython.display.display(IPython.display.Image(data=f.getvalue()))\n  return result if numpy else img\n\n\ndef grab(name, postfix, i, n=1, latents=None, **kwargs):\n  load_checkpoint('checkpoint/'+name)\n  if latents is None:\n    latents = rand_latent(n, seed=i)\n  gw, gh = get_grid_size(latents.shape[0])\n  outfile = 'checkpoint/%s_fakes_%dx%d_%04d_%s.png' % (name, gw, gh, i, postfix)\n  if not os.path.isfile(outfile):\n    return gen_images(latents, outfile=outfile, **kwargs)\n\ndef grab_grid(i, n=1, latents=None, outfile=None, **kwargs):\n  if latents is None:\n    latents = rand_latent(n, seed=i)\n  gw, gh = get_grid_size(latents.shape[0])\n  #outfile = 'checkpoint/%s_fakes_%dx%d_%04d_%s.png' % (name, gw, gh, i, postfix)\n  return gen_images(latents, outfile=outfile, **kwargs)\n\nimport discord\nimport asyncio\n\ndef post_picture(channel_name, image, text=None, name='test', kind='png'):\n    asyncio.set_event_loop(asyncio.new_event_loop())\n    loop = asyncio.get_event_loop()\n    client = discord.Client()\n    token=discord_token\n\n    async def send_picture(channel, image, kind='png', name='test', text=None):\n        img = misc.convert_to_pil_image(image, [-1, 1])\n        f = BytesIO()\n        img.save(f, kind)\n        f.seek(0)\n        picture = discord.File(f)\n        picture.filename = name + '.' + kind\n        await channel.send(content=text, file=picture)\n\n    @client.event\n    async def on_ready():\n        print('Logged on as {0}!'.format(client.user))\n        try:\n          channel = [x for x in list(client.get_all_channels()) if channel_name in x.name]\n          assert len(channel) == 1\n          channel = channel[0]\n          print(channel)\n          await send_picture(channel, image, kind=kind, name=name, text=text)\n        finally:\n          await client.logout()\n\n    #@client.event\n    #async def on_message(message):\n    #    print('Message from {0.author}: {0.content}'.format(message))\n\n    client.run(token)\n\nall_labels = np.array([[1.0 if i == j else 0.0 for j in range(1000)] for i in range(1000)], dtype=np.float32)\nn = grid_image_size\nlabels = [all_labels[i] for i in range(n)]\nlabels2 = [all_labels[0] for i in range(n)]\n\nfor ckpt in tf.train.checkpoints_iterator(model_dir, 1.0):\n    print('posting ' + ckpt)\n    saver.restore(sess, ckpt)\n    seed = np.random.randint(10000)\n    for i in range(seed,seed + count):\n      print('------- %d -------' % i)\n      result = grab_grid(i, n=n, labels=labels, numpy=True)\n      post_picture(channel, misc.create_image_grid(result, get_grid_size(n)), \"`\" + ckpt + ' seed %d`' % i)\n\n\n"
  }
]