[
  {
    "path": ".gitignore",
    "content": "*.pyc\ncaffe_converter\n.idea\n"
  },
  {
    "path": "README.md",
    "content": "# MTCNN_face_detection_and_alignment\n\n## About\n\n  This is a python/mxnet implementation of [Zhang](https://kpzhang93.github.io/)'s work **<Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Neural Networks>**. it's fast and accurate,  see [link](https://github.com/kpzhang93/MTCNN_face_detection_alignment). \n\n  It should have **almost** the same output with the original work,  for mxnet fans and those can't afford matlab :)\n\n[中文blog](https://pangyupo.github.io/2016/10/22/mxnet-mtcnn/)\n\n## Requirement\t  \n\n- opencv \n\n  ​\tI use cv2 for image io and resize(much faster than skimage), the input image's channel is acutally BGR\n\n- mxnet \n\n  ​\t**please update to the newest version, we need 'full' mode in Pooling operation**\n\nOnly tested on Linux and Mac\n\n## Test\n\nrun:\n\n ``python main.py`` \n\nyou can change `ctx` to `mx.gpu(0)` for faster detection\n\n--- update 20161028 ---\n\nby setting ``num_worker=4``  ``accurate_landmark=False`` we can reduce the detection time by 1/4-1/3, the bboxes are still the same, but we skip the last landmark fine-tune stage( mtcnn_v1 ). \n\n--- update 20161207 ---\n\nadd function `extract_face_chips`, examples:\n\n![1](http://7vikw0.com1.z0.glb.clouddn.com/chip_0.png)\n![2](http://7vikw0.com1.z0.glb.clouddn.com/chip_3.png)\n![3](http://7vikw0.com1.z0.glb.clouddn.com/chip_2.png)\n![4](http://7vikw0.com1.z0.glb.clouddn.com/chip_1.png)\n\nsee `mtcnn_detector.py` for the details about the parameters. this function use [dlib](http://dlib.net/)'s align strategy, which works well on profile images :) \n## Results\n\n![big4](http://7xsc78.com1.z0.glb.clouddn.com/face_mtcnn.png)\n\n\n\n## License\n\nMIT LICENSE\n\n\n\n## Reference\n\nK. Zhang and Z. Zhang and Z. Li and Y. Qiao Joint,  Face Detection and Alignment Using Multitask Cascaded Convolutional Networks, IEEE Signal Processing Letters\n"
  },
  {
    "path": "helper.py",
    "content": "# coding: utf-8\n# YuanYang\nimport math\nimport cv2\nimport numpy as np\n\n\ndef nms(boxes, overlap_threshold, mode='Union'):\n    \"\"\"\n        non max suppression\n\n    Parameters:\n    ----------\n        box: numpy array n x 5\n            input bbox array\n        overlap_threshold: float number\n            threshold of overlap\n        mode: float number\n            how to compute overlap ratio, 'Union' or 'Min'\n    Returns:\n    -------\n        index array of the selected bbox\n    \"\"\"\n    # if there are no boxes, return an empty list\n    if len(boxes) == 0:\n        return []\n\n    # if the bounding boxes integers, convert them to floats\n    if boxes.dtype.kind == \"i\":\n        boxes = boxes.astype(\"float\")\n\n    # initialize the list of picked indexes\n    pick = []\n\n    # grab the coordinates of the bounding boxes\n    x1, y1, x2, y2, score = [boxes[:, i] for i in range(5)]\n\n    area = (x2 - x1 + 1) * (y2 - y1 + 1)\n    idxs = np.argsort(score)\n\n    # keep looping while some indexes still remain in the indexes list\n    while len(idxs) > 0:\n        # grab the last index in the indexes list and add the index value to the list of picked indexes\n        last = len(idxs) - 1\n        i = idxs[last]\n        pick.append(i)\n\n        xx1 = np.maximum(x1[i], x1[idxs[:last]])\n        yy1 = np.maximum(y1[i], y1[idxs[:last]])\n        xx2 = np.minimum(x2[i], x2[idxs[:last]])\n        yy2 = np.minimum(y2[i], y2[idxs[:last]])\n\n        # compute the width and height of the bounding box\n        w = np.maximum(0, xx2 - xx1 + 1)\n        h = np.maximum(0, yy2 - yy1 + 1)\n\n        inter = w * h\n        if mode == 'Min':\n            overlap = inter / np.minimum(area[i], area[idxs[:last]])\n        else:\n            overlap = inter / (area[i] + area[idxs[:last]] - inter)\n\n        # delete all indexes from the index list that have\n        idxs = np.delete(idxs, np.concatenate(([last],\n                                               np.where(overlap > overlap_threshold)[0])))\n\n    return pick\n\ndef adjust_input(in_data):\n    \"\"\"\n        adjust the input from (h, w, c) to ( 1, c, h, w) for network input\n\n    Parameters:\n    ----------\n        in_data: numpy array of shape (h, w, c)\n            input data\n    Returns:\n    -------\n        out_data: numpy array of shape (1, c, h, w)\n            reshaped array\n    \"\"\"\n    if in_data.dtype is not np.dtype('float32'):\n        out_data = in_data.astype(np.float32)\n    else:\n        out_data = in_data\n\n    out_data = out_data.transpose((2,0,1))\n    out_data = np.expand_dims(out_data, 0)\n    out_data = (out_data - 127.5)*0.0078125\n    return out_data\n\ndef generate_bbox(map, reg, scale, threshold):\n     \"\"\"\n         generate bbox from feature map\n     Parameters:\n     ----------\n         map: numpy array , n x m x 1\n             detect score for each position\n         reg: numpy array , n x m x 4\n             bbox\n         scale: float number\n             scale of this detection\n         threshold: float number\n             detect threshold\n     Returns:\n     -------\n         bbox array\n     \"\"\"\n     stride = 2\n     cellsize = 12\n\n     t_index = np.where(map>threshold)\n\n     # find nothing\n     if t_index[0].size == 0:\n         return np.array([])\n\n     dx1, dy1, dx2, dy2 = [reg[0, i, t_index[0], t_index[1]] for i in range(4)]\n\n     reg = np.array([dx1, dy1, dx2, dy2])\n     score = map[t_index[0], t_index[1]]\n     boundingbox = np.vstack([np.round((stride*t_index[1]+1)/scale),\n                              np.round((stride*t_index[0]+1)/scale),\n                              np.round((stride*t_index[1]+1+cellsize)/scale),\n                              np.round((stride*t_index[0]+1+cellsize)/scale),\n                              score,\n                              reg])\n\n     return boundingbox.T\n\n\ndef detect_first_stage(img, net, scale, threshold):\n    \"\"\"\n        run PNet for first stage\n    \n    Parameters:\n    ----------\n        img: numpy array, bgr order\n            input image\n        scale: float number\n            how much should the input image scale\n        net: PNet\n            worker\n    Returns:\n    -------\n        total_boxes : bboxes\n    \"\"\"\n    height, width, _ = img.shape\n    hs = int(math.ceil(height * scale))\n    ws = int(math.ceil(width * scale))\n    \n    im_data = cv2.resize(img, (ws,hs))\n    \n    # adjust for the network input\n    input_buf = adjust_input(im_data)\n    output = net.predict(input_buf)\n    boxes = generate_bbox(output[1][0,1,:,:], output[0], scale, threshold)\n\n    if boxes.size == 0:\n        return None\n\n    # nms\n    pick = nms(boxes[:,0:5], 0.5, mode='Union')\n    boxes = boxes[pick]\n    return boxes\n\ndef detect_first_stage_warpper( args ):\n    return detect_first_stage(*args)\n"
  },
  {
    "path": "main.py",
    "content": "# coding: utf-8\nimport mxnet as mx\nfrom mtcnn_detector import MtcnnDetector\nimport cv2\nimport os\nimport time\n\ndetector = MtcnnDetector(model_folder='model', ctx=mx.cpu(0), num_worker = 4 , accurate_landmark = False)\n\n\nimg = cv2.imread('test2.jpg')\n\n# run detector\nresults = detector.detect_face(img)\n\nif results is not None:\n\n    total_boxes = results[0]\n    points = results[1]\n    \n    # extract aligned face chips\n    chips = detector.extract_image_chips(img, points, 144, 0.37)\n    for i, chip in enumerate(chips):\n        cv2.imshow('chip_'+str(i), chip)\n        cv2.imwrite('chip_'+str(i)+'.png', chip)\n\n    draw = img.copy()\n    for b in total_boxes:\n        cv2.rectangle(draw, (int(b[0]), int(b[1])), (int(b[2]), int(b[3])), (255, 255, 255))\n\n    for p in points:\n        for i in range(5):\n            cv2.circle(draw, (p[i], p[i + 5]), 1, (0, 0, 255), 2)\n\n    cv2.imshow(\"detection result\", draw)\n    cv2.waitKey(0)\n\n# --------------\n# test on camera\n# --------------\n'''\ncamera = cv2.VideoCapture(0)\nwhile True:\n    grab, frame = camera.read()\n    img = cv2.resize(frame, (320,180))\n\n    t1 = time.time()\n    results = detector.detect_face(img)\n    print 'time: ',time.time() - t1\n\n    if results is None:\n        continue\n\n    total_boxes = results[0]\n    points = results[1]\n\n    draw = img.copy()\n    for b in total_boxes:\n        cv2.rectangle(draw, (int(b[0]), int(b[1])), (int(b[2]), int(b[3])), (255, 255, 255))\n\n    for p in points:\n        for i in range(5):\n            cv2.circle(draw, (p[i], p[i + 5]), 1, (255, 0, 0), 2)\n    cv2.imshow(\"detection result\", draw)\n    cv2.waitKey(30)\n'''\n"
  },
  {
    "path": "model/det1-symbol.json",
    "content": "{\n  \"nodes\": [\n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"data\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"10\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv1\", \n      \"inputs\": [[0, 0], [1, 0], [2, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu1_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu1\", \n      \"inputs\": [[3, 0], [4, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(2,2)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool1\", \n      \"inputs\": [[5, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"16\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv2\", \n      \"inputs\": [[6, 0], [7, 0], [8, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu2_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu2\", \n      \"inputs\": [[9, 0], [10, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"32\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv3\", \n      \"inputs\": [[11, 0], [12, 0], [13, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu3_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu3\", \n      \"inputs\": [[14, 0], [15, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv4_2_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv4_2_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(1,1)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"4\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv4_2\", \n      \"inputs\": [[16, 0], [17, 0], [18, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv4_1_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv4_1_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(1,1)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"2\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv4_1\", \n      \"inputs\": [[16, 0], [20, 0], [21, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"SoftmaxActivation\", \n      \"param\": {\"mode\": \"channel\"}, \n      \"name\": \"prob1\", \n      \"inputs\": [[22, 0]], \n      \"backward_source_id\": -1\n    }\n  ], \n  \"arg_nodes\": [\n    0, \n    1, \n    2, \n    4, \n    7, \n    8, \n    10, \n    12, \n    13, \n    15, \n    17, \n    18, \n    20, \n    21\n  ], \n  \"heads\": [[19, 0], [23, 0]]\n}"
  },
  {
    "path": "model/det1.prototxt",
    "content": "name: \"PNet\"\ninput: \"data\"\ninput_dim: 1\ninput_dim: 3\ninput_dim: 12\ninput_dim: 12\n\nlayer {\n  name: \"conv1\"\n  type: \"Convolution\"\n  bottom: \"data\"\n  top: \"conv1\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 0\n  }\n  convolution_param {\n    num_output: 10\n    kernel_size: 3\n    stride: 1\n    weight_filler {\n      type: \"xavier\"\n    }\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"PReLU1\"\n  type: \"PReLU\"\n  bottom: \"conv1\"\n  top: \"conv1\"\n}\nlayer {\n  name: \"pool1\"\n  type: \"Pooling\"\n  bottom: \"conv1\"\n  top: \"pool1\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 2\n    stride: 2\n  }\n}\n\nlayer {\n  name: \"conv2\"\n  type: \"Convolution\"\n  bottom: \"pool1\"\n  top: \"conv2\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 0\n  }\n  convolution_param {\n    num_output: 16\n    kernel_size: 3\n    stride: 1\n     weight_filler {\n      type: \"xavier\"\n    }\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"PReLU2\"\n  type: \"PReLU\"\n  bottom: \"conv2\"\n  top: \"conv2\"\n}\n\nlayer {\n  name: \"conv3\"\n  type: \"Convolution\"\n  bottom: \"conv2\"\n  top: \"conv3\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 0\n  }\n  convolution_param {\n    num_output: 32\n    kernel_size: 3\n    stride: 1\n     weight_filler {\n      type: \"xavier\"\n    }\n    bias_filler {\n\t  type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"PReLU3\"\n  type: \"PReLU\"\n  bottom: \"conv3\"\n  top: \"conv3\"\n}\n\n\nlayer {\n  name: \"conv4-1\"\n  type: \"Convolution\"\n  bottom: \"conv3\"\n  top: \"conv4-1\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 0\n  }\n  convolution_param {\n    num_output: 2\n    kernel_size: 1\n    stride: 1\n     weight_filler {\n      type: \"xavier\"\n    }\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\n\nlayer {\n  name: \"conv4-2\"\n  type: \"Convolution\"\n  bottom: \"conv3\"\n  top: \"conv4-2\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 0\n  }\n  convolution_param {\n    num_output: 4\n    kernel_size: 1\n    stride: 1\n     weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"prob1\"\n  type: \"Softmax\"\n  bottom: \"conv4-1\"\n  top: \"prob1\"\n}\n"
  },
  {
    "path": "model/det2-symbol.json",
    "content": "{\n  \"nodes\": [\n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"data\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"28\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv1\", \n      \"inputs\": [[0, 0], [1, 0], [2, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu1_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu1\", \n      \"inputs\": [[3, 0], [4, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(3,3)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool1\", \n      \"inputs\": [[5, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"48\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv2\", \n      \"inputs\": [[6, 0], [7, 0], [8, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu2_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu2\", \n      \"inputs\": [[9, 0], [10, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(3,3)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool2\", \n      \"inputs\": [[11, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(2,2)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"64\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv3\", \n      \"inputs\": [[12, 0], [13, 0], [14, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu3_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu3\", \n      \"inputs\": [[15, 0], [16, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv4_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv4_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"128\"\n      }, \n      \"name\": \"conv4\", \n      \"inputs\": [[17, 0], [18, 0], [19, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu4_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu4\", \n      \"inputs\": [[20, 0], [21, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv5_2_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv5_2_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"4\"\n      }, \n      \"name\": \"conv5_2\", \n      \"inputs\": [[22, 0], [23, 0], [24, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv5_1_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv5_1_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"2\"\n      }, \n      \"name\": \"conv5_1\", \n      \"inputs\": [[22, 0], [26, 0], [27, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prob1_label\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"SoftmaxOutput\", \n      \"param\": {\n        \"grad_scale\": \"1\", \n        \"ignore_label\": \"-1\", \n        \"multi_output\": \"False\", \n        \"normalization\": \"null\", \n        \"use_ignore\": \"False\"\n      }, \n      \"name\": \"prob1\", \n      \"inputs\": [[28, 0], [29, 0]], \n      \"backward_source_id\": -1\n    }\n  ], \n  \"arg_nodes\": [\n    0, \n    1, \n    2, \n    4, \n    7, \n    8, \n    10, \n    13, \n    14, \n    16, \n    18, \n    19, \n    21, \n    23, \n    24, \n    26, \n    27, \n    29\n  ], \n  \"heads\": [[25, 0], [30, 0]]\n}"
  },
  {
    "path": "model/det2.prototxt",
    "content": "name: \"RNet\"\ninput: \"data\"\ninput_dim: 1\ninput_dim: 3\ninput_dim: 24\ninput_dim: 24\n\n\n##########################\n######################\nlayer {\n  name: \"conv1\"\n  type: \"Convolution\"\n  bottom: \"data\"\n  top: \"conv1\"\n  param {\n    lr_mult: 0\n    decay_mult: 0\n  }\n  param {\n    lr_mult: 0\n    decay_mult: 0\n  }\n  convolution_param {\n    num_output: 28\n    kernel_size: 3\n    stride: 1\n     weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"prelu1\"\n  type: \"PReLU\"\n  bottom: \"conv1\"\n  top: \"conv1\"\n  propagate_down: true\n}\nlayer {\n  name: \"pool1\"\n  type: \"Pooling\"\n  bottom: \"conv1\"\n  top: \"pool1\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 3\n    stride: 2\n  }\n}\n\nlayer {\n  name: \"conv2\"\n  type: \"Convolution\"\n  bottom: \"pool1\"\n  top: \"conv2\"\n  param {\n    lr_mult: 0\n    decay_mult: 0\n  }\n  param {\n    lr_mult: 0\n    decay_mult: 0\n  }\n  convolution_param {\n    num_output: 48\n    kernel_size: 3\n    stride: 1\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"prelu2\"\n  type: \"PReLU\"\n  bottom: \"conv2\"\n  top: \"conv2\"\n  propagate_down: true\n}\nlayer {\n  name: \"pool2\"\n  type: \"Pooling\"\n  bottom: \"conv2\"\n  top: \"pool2\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 3\n    stride: 2\n  }\n}\n####################################\n\n##################################\nlayer {\n  name: \"conv3\"\n  type: \"Convolution\"\n  bottom: \"pool2\"\n  top: \"conv3\"\n  param {\n    lr_mult: 0\n    decay_mult: 0\n  }\n  param {\n    lr_mult: 0\n    decay_mult: 0\n  }\n  convolution_param {\n    num_output: 64\n    kernel_size: 2\n    stride: 1\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"prelu3\"\n  type: \"PReLU\"\n  bottom: \"conv3\"\n  top: \"conv3\"\n  propagate_down: true\n}\n###############################\n\n###############################\n\nlayer {\n  name: \"conv4\"\n  type: \"InnerProduct\"\n  bottom: \"conv3\"\n  top: \"conv4\"\n  param {\n    lr_mult: 0\n    decay_mult: 0\n  }\n  param {\n    lr_mult: 0\n    decay_mult: 0\n  }\n  inner_product_param {\n    num_output: 128\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"prelu4\"\n  type: \"PReLU\"\n  bottom: \"conv4\"\n  top: \"conv4\"\n}\n\nlayer {\n  name: \"conv5-1\"\n  type: \"InnerProduct\"\n  bottom: \"conv4\"\n  top: \"conv5-1\"\n  param {\n    lr_mult: 0\n    decay_mult: 0\n  }\n  param {\n    lr_mult: 0\n    decay_mult: 0\n  }\n  inner_product_param {\n    num_output: 2\n    #kernel_size: 1\n    #stride: 1\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"conv5-2\"\n  type: \"InnerProduct\"\n  bottom: \"conv4\"\n  top: \"conv5-2\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n    num_output: 4\n    #kernel_size: 1\n    #stride: 1\n     weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"prob1\"\n  type: \"Softmax\"\n  bottom: \"conv5-1\"\n  top: \"prob1\"\n}"
  },
  {
    "path": "model/det3-symbol.json",
    "content": "{\n  \"nodes\": [\n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"data\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"32\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv1\", \n      \"inputs\": [[0, 0], [1, 0], [2, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu1_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu1\", \n      \"inputs\": [[3, 0], [4, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(3,3)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool1\", \n      \"inputs\": [[5, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"64\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv2\", \n      \"inputs\": [[6, 0], [7, 0], [8, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu2_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu2\", \n      \"inputs\": [[9, 0], [10, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(3,3)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool2\", \n      \"inputs\": [[11, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"64\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv3\", \n      \"inputs\": [[12, 0], [13, 0], [14, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu3_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu3\", \n      \"inputs\": [[15, 0], [16, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(2,2)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool3\", \n      \"inputs\": [[17, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv4_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv4_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(2,2)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"128\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv4\", \n      \"inputs\": [[18, 0], [19, 0], [20, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu4_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu4\", \n      \"inputs\": [[21, 0], [22, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv5_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv5_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"256\"\n      }, \n      \"name\": \"conv5\", \n      \"inputs\": [[23, 0], [24, 0], [25, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu5_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu5\", \n      \"inputs\": [[26, 0], [27, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv6_3_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv6_3_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"10\"\n      }, \n      \"name\": \"conv6_3\", \n      \"inputs\": [[28, 0], [29, 0], [30, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv6_2_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv6_2_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"4\"\n      }, \n      \"name\": \"conv6_2\", \n      \"inputs\": [[28, 0], [32, 0], [33, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv6_1_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv6_1_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"2\"\n      }, \n      \"name\": \"conv6_1\", \n      \"inputs\": [[28, 0], [35, 0], [36, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prob1_label\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"SoftmaxOutput\", \n      \"param\": {\n        \"grad_scale\": \"1\", \n        \"ignore_label\": \"-1\", \n        \"multi_output\": \"False\", \n        \"normalization\": \"null\", \n        \"use_ignore\": \"False\"\n      }, \n      \"name\": \"prob1\", \n      \"inputs\": [[37, 0], [38, 0]], \n      \"backward_source_id\": -1\n    }\n  ], \n  \"arg_nodes\": [\n    0, \n    1, \n    2, \n    4, \n    7, \n    8, \n    10, \n    13, \n    14, \n    16, \n    19, \n    20, \n    22, \n    24, \n    25, \n    27, \n    29, \n    30, \n    32, \n    33, \n    35, \n    36, \n    38\n  ], \n  \"heads\": [[31, 0], [34, 0], [39, 0]]\n}"
  },
  {
    "path": "model/det3.prototxt",
    "content": "name: \"ONet\"\ninput: \"data\"\ninput_dim: 1\ninput_dim: 3\ninput_dim: 48\ninput_dim: 48\n##################################\nlayer {\n  name: \"conv1\"\n  type: \"Convolution\"\n  bottom: \"data\"\n  top: \"conv1\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 32\n    kernel_size: 3\n    stride: 1\n     weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"prelu1\"\n  type: \"PReLU\"\n  bottom: \"conv1\"\n  top: \"conv1\"\n}\nlayer {\n  name: \"pool1\"\n  type: \"Pooling\"\n  bottom: \"conv1\"\n  top: \"pool1\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 3\n    stride: 2\n  }\n}\nlayer {\n  name: \"conv2\"\n  type: \"Convolution\"\n  bottom: \"pool1\"\n  top: \"conv2\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 64\n    kernel_size: 3\n    stride: 1\n     weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\n\nlayer {\n  name: \"prelu2\"\n  type: \"PReLU\"\n  bottom: \"conv2\"\n  top: \"conv2\"\n}\nlayer {\n  name: \"pool2\"\n  type: \"Pooling\"\n  bottom: \"conv2\"\n  top: \"pool2\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 3\n    stride: 2\n  }\n}\n\nlayer {\n  name: \"conv3\"\n  type: \"Convolution\"\n  bottom: \"pool2\"\n  top: \"conv3\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n\tnum_output: 64\n\tkernel_size: 3\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"prelu3\"\n  type: \"PReLU\"\n  bottom: \"conv3\"\n  top: \"conv3\"\n}\nlayer {\n  name: \"pool3\"\n  type: \"Pooling\"\n  bottom: \"conv3\"\n  top: \"pool3\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 2\n    stride: 2\n  }\n}\nlayer {\n  name: \"conv4\"\n  type: \"Convolution\"\n  bottom: \"pool3\"\n  top: \"conv4\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n\tnum_output: 128\n\tkernel_size: 2\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"prelu4\"\n  type: \"PReLU\"\n  bottom: \"conv4\"\n  top: \"conv4\"\n}\n\n\nlayer {\n  name: \"conv5\"\n  type: \"InnerProduct\"\n  bottom: \"conv4\"\n  top: \"conv5\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n\t#kernel_size: 3\n\tnum_output: 256\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\n\nlayer {\n  name: \"drop5\"\n  type: \"Dropout\"\n  bottom: \"conv5\"\n  top: \"conv5\"\n  dropout_param {\n    dropout_ratio: 0.25\n  }\n}\nlayer {\n  name: \"prelu5\"\n  type: \"PReLU\"\n  bottom: \"conv5\"\n  top: \"conv5\"\n}\n\n\nlayer {\n  name: \"conv6-1\"\n  type: \"InnerProduct\"\n  bottom: \"conv5\"\n  top: \"conv6-1\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n    #kernel_size: 1\n\tnum_output: 2\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"conv6-2\"\n  type: \"InnerProduct\"\n  bottom: \"conv5\"\n  top: \"conv6-2\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n  \t#kernel_size: 1\n\tnum_output: 4\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"conv6-3\"\n  type: \"InnerProduct\"\n  bottom: \"conv5\"\n  top: \"conv6-3\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n  \t#kernel_size: 1\n\tnum_output: 10\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\nlayer {\n  name: \"prob1\"\n  type: \"Softmax\"\n  bottom: \"conv6-1\"\n  top: \"prob1\"\n}\n"
  },
  {
    "path": "model/det4-symbol.json",
    "content": "{\n  \"nodes\": [\n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"data\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"SliceChannel\", \n      \"param\": {\n        \"axis\": \"1\", \n        \"num_outputs\": \"5\", \n        \"squeeze_axis\": \"False\"\n      }, \n      \"name\": \"slice\", \n      \"inputs\": [[0, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_1_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_1_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"28\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv1_1\", \n      \"inputs\": [[1, 0], [2, 0], [3, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu1_1_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu1_1\", \n      \"inputs\": [[4, 0], [5, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(3,3)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool1_1\", \n      \"inputs\": [[6, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_1_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_1_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"48\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv2_1\", \n      \"inputs\": [[7, 0], [8, 0], [9, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu2_1_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu2_1\", \n      \"inputs\": [[10, 0], [11, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(3,3)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool2_1\", \n      \"inputs\": [[12, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_1_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_1_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(2,2)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"64\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv3_1\", \n      \"inputs\": [[13, 0], [14, 0], [15, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu3_1_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu3_1\", \n      \"inputs\": [[16, 0], [17, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_2_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_2_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"28\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv1_2\", \n      \"inputs\": [[1, 1], [19, 0], [20, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu1_2_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu1_2\", \n      \"inputs\": [[21, 0], [22, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(3,3)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool1_2\", \n      \"inputs\": [[23, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_2_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_2_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"48\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv2_2\", \n      \"inputs\": [[24, 0], [25, 0], [26, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu2_2_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu2_2\", \n      \"inputs\": [[27, 0], [28, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(3,3)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool2_2\", \n      \"inputs\": [[29, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_2_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_2_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(2,2)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"64\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv3_2\", \n      \"inputs\": [[30, 0], [31, 0], [32, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu3_2_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu3_2\", \n      \"inputs\": [[33, 0], [34, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_3_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_3_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"28\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv1_3\", \n      \"inputs\": [[1, 2], [36, 0], [37, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu1_3_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu1_3\", \n      \"inputs\": [[38, 0], [39, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(3,3)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool1_3\", \n      \"inputs\": [[40, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_3_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_3_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"48\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv2_3\", \n      \"inputs\": [[41, 0], [42, 0], [43, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu2_3_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu2_3\", \n      \"inputs\": [[44, 0], [45, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(3,3)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool2_3\", \n      \"inputs\": [[46, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_3_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_3_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(2,2)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"64\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv3_3\", \n      \"inputs\": [[47, 0], [48, 0], [49, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu3_3_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu3_3\", \n      \"inputs\": [[50, 0], [51, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_4_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_4_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"28\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv1_4\", \n      \"inputs\": [[1, 3], [53, 0], [54, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu1_4_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu1_4\", \n      \"inputs\": [[55, 0], [56, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(3,3)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool1_4\", \n      \"inputs\": [[57, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_4_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_4_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"48\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv2_4\", \n      \"inputs\": [[58, 0], [59, 0], [60, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu2_4_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu2_4\", \n      \"inputs\": [[61, 0], [62, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(3,3)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool2_4\", \n      \"inputs\": [[63, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_4_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_4_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(2,2)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"64\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv3_4\", \n      \"inputs\": [[64, 0], [65, 0], [66, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu3_4_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu3_4\", \n      \"inputs\": [[67, 0], [68, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_5_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv1_5_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"28\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv1_5\", \n      \"inputs\": [[1, 4], [70, 0], [71, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu1_5_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu1_5\", \n      \"inputs\": [[72, 0], [73, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(3,3)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool1_5\", \n      \"inputs\": [[74, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_5_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv2_5_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(3,3)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"48\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv2_5\", \n      \"inputs\": [[75, 0], [76, 0], [77, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu2_5_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu2_5\", \n      \"inputs\": [[78, 0], [79, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Pooling\", \n      \"param\": {\n        \"global_pool\": \"False\", \n        \"kernel\": \"(3,3)\", \n        \"pad\": \"(0,0)\", \n        \"pool_type\": \"max\", \n        \"pooling_convention\": \"full\", \n        \"stride\": \"(2,2)\"\n      }, \n      \"name\": \"pool2_5\", \n      \"inputs\": [[80, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_5_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"conv3_5_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Convolution\", \n      \"param\": {\n        \"cudnn_off\": \"False\", \n        \"cudnn_tune\": \"off\", \n        \"dilate\": \"(1,1)\", \n        \"kernel\": \"(2,2)\", \n        \"no_bias\": \"False\", \n        \"num_filter\": \"64\", \n        \"num_group\": \"1\", \n        \"pad\": \"(0,0)\", \n        \"stride\": \"(1,1)\", \n        \"workspace\": \"1024\"\n      }, \n      \"name\": \"conv3_5\", \n      \"inputs\": [[81, 0], [82, 0], [83, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu3_5_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu3_5\", \n      \"inputs\": [[84, 0], [85, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"Concat\", \n      \"param\": {\n        \"dim\": \"1\", \n        \"num_args\": \"5\"\n      }, \n      \"name\": \"concat\", \n      \"inputs\": [[18, 0], [35, 0], [52, 0], [69, 0], [86, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc4_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc4_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"256\"\n      }, \n      \"name\": \"fc4\", \n      \"inputs\": [[87, 0], [88, 0], [89, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu4_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu4\", \n      \"inputs\": [[90, 0], [91, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc4_1_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc4_1_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"64\"\n      }, \n      \"name\": \"fc4_1\", \n      \"inputs\": [[92, 0], [93, 0], [94, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu4_1_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu4_1\", \n      \"inputs\": [[95, 0], [96, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc5_1_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc5_1_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"2\"\n      }, \n      \"name\": \"fc5_1\", \n      \"inputs\": [[97, 0], [98, 0], [99, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc4_2_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc4_2_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"64\"\n      }, \n      \"name\": \"fc4_2\", \n      \"inputs\": [[92, 0], [101, 0], [102, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu4_2_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu4_2\", \n      \"inputs\": [[103, 0], [104, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc5_2_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc5_2_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"2\"\n      }, \n      \"name\": \"fc5_2\", \n      \"inputs\": [[105, 0], [106, 0], [107, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc4_3_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc4_3_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"64\"\n      }, \n      \"name\": \"fc4_3\", \n      \"inputs\": [[92, 0], [109, 0], [110, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu4_3_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu4_3\", \n      \"inputs\": [[111, 0], [112, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc5_3_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc5_3_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"2\"\n      }, \n      \"name\": \"fc5_3\", \n      \"inputs\": [[113, 0], [114, 0], [115, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc4_4_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc4_4_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"64\"\n      }, \n      \"name\": \"fc4_4\", \n      \"inputs\": [[92, 0], [117, 0], [118, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu4_4_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu4_4\", \n      \"inputs\": [[119, 0], [120, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc5_4_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc5_4_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"2\"\n      }, \n      \"name\": \"fc5_4\", \n      \"inputs\": [[121, 0], [122, 0], [123, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc4_5_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc4_5_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"64\"\n      }, \n      \"name\": \"fc4_5\", \n      \"inputs\": [[92, 0], [125, 0], [126, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"prelu4_5_gamma\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"LeakyReLU\", \n      \"param\": {\n        \"act_type\": \"prelu\", \n        \"lower_bound\": \"0.125\", \n        \"slope\": \"0.25\", \n        \"upper_bound\": \"0.334\"\n      }, \n      \"name\": \"prelu4_5\", \n      \"inputs\": [[127, 0], [128, 0]], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc5_5_weight\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"null\", \n      \"param\": {}, \n      \"name\": \"fc5_5_bias\", \n      \"inputs\": [], \n      \"backward_source_id\": -1\n    }, \n    {\n      \"op\": \"FullyConnected\", \n      \"param\": {\n        \"no_bias\": \"False\", \n        \"num_hidden\": \"2\"\n      }, \n      \"name\": \"fc5_5\", \n      \"inputs\": [[129, 0], [130, 0], [131, 0]], \n      \"backward_source_id\": -1\n    }\n  ], \n  \"arg_nodes\": [\n    0, \n    2, \n    3, \n    5, \n    8, \n    9, \n    11, \n    14, \n    15, \n    17, \n    19, \n    20, \n    22, \n    25, \n    26, \n    28, \n    31, \n    32, \n    34, \n    36, \n    37, \n    39, \n    42, \n    43, \n    45, \n    48, \n    49, \n    51, \n    53, \n    54, \n    56, \n    59, \n    60, \n    62, \n    65, \n    66, \n    68, \n    70, \n    71, \n    73, \n    76, \n    77, \n    79, \n    82, \n    83, \n    85, \n    88, \n    89, \n    91, \n    93, \n    94, \n    96, \n    98, \n    99, \n    101, \n    102, \n    104, \n    106, \n    107, \n    109, \n    110, \n    112, \n    114, \n    115, \n    117, \n    118, \n    120, \n    122, \n    123, \n    125, \n    126, \n    128, \n    130, \n    131\n  ], \n  \"heads\": [[100, 0], [108, 0], [116, 0], [124, 0], [132, 0]]\n}"
  },
  {
    "path": "model/det4.prototxt",
    "content": "name: \"LNet\"\ninput: \"data\"\ninput_dim: 1\ninput_dim: 15\ninput_dim: 24\ninput_dim: 24\n\nlayer {\n  name: \"slicer_data\"\n  type: \"Slice\"\n  bottom: \"data\"\n  top: \"data241\"\n  top: \"data242\"\n  top: \"data243\"\n  top: \"data244\"\n  top: \"data245\"\n  slice_param {\n    axis: 1\n    slice_point: 3\n    slice_point: 6\n    slice_point: 9\n    slice_point: 12\n  }\n}\nlayer {\n  name: \"conv1_1\"\n  type: \"Convolution\"\n  bottom: \"data241\"\n  top: \"conv1_1\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 28\n    kernel_size: 3\n    stride: 1\n     weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu1_1\"\n  type: \"PReLU\"\n  bottom: \"conv1_1\"\n  top: \"conv1_1\"\n\n}\nlayer {\n  name: \"pool1_1\"\n  type: \"Pooling\"\n  bottom: \"conv1_1\"\n  top: \"pool1_1\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 3\n    stride: 2\n  }\n}\n\nlayer {\n  name: \"conv2_1\"\n  type: \"Convolution\"\n  bottom: \"pool1_1\"\n  top: \"conv2_1\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 48\n    kernel_size: 3\n    stride: 1\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu2_1\"\n  type: \"PReLU\"\n  bottom: \"conv2_1\"\n  top: \"conv2_1\"\n}\nlayer {\n  name: \"pool2_1\"\n  type: \"Pooling\"\n  bottom: \"conv2_1\"\n  top: \"pool2_1\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 3\n    stride: 2\n  }\n  \n}\nlayer {\n  name: \"conv3_1\"\n  type: \"Convolution\"\n  bottom: \"pool2_1\"\n  top: \"conv3_1\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 64\n    kernel_size: 2\n    stride: 1\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu3_1\"\n  type: \"PReLU\"\n  bottom: \"conv3_1\"\n  top: \"conv3_1\"\n}\n##########################\nlayer {\n  name: \"conv1_2\"\n  type: \"Convolution\"\n  bottom: \"data242\"\n  top: \"conv1_2\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 28\n    kernel_size: 3\n    stride: 1\n     weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu1_2\"\n  type: \"PReLU\"\n  bottom: \"conv1_2\"\n  top: \"conv1_2\"\n\n}\nlayer {\n  name: \"pool1_2\"\n  type: \"Pooling\"\n  bottom: \"conv1_2\"\n  top: \"pool1_2\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 3\n    stride: 2\n  }\n}\n\nlayer {\n  name: \"conv2_2\"\n  type: \"Convolution\"\n  bottom: \"pool1_2\"\n  top: \"conv2_2\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 48\n    kernel_size: 3\n    stride: 1\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu2_2\"\n  type: \"PReLU\"\n  bottom: \"conv2_2\"\n  top: \"conv2_2\"\n}\nlayer {\n  name: \"pool2_2\"\n  type: \"Pooling\"\n  bottom: \"conv2_2\"\n  top: \"pool2_2\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 3\n    stride: 2\n  }\n  \n}\nlayer {\n  name: \"conv3_2\"\n  type: \"Convolution\"\n  bottom: \"pool2_2\"\n  top: \"conv3_2\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 64\n    kernel_size: 2\n    stride: 1\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu3_2\"\n  type: \"PReLU\"\n  bottom: \"conv3_2\"\n  top: \"conv3_2\"\n}\n##########################\n##########################\nlayer {\n  name: \"conv1_3\"\n  type: \"Convolution\"\n  bottom: \"data243\"\n  top: \"conv1_3\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 28\n    kernel_size: 3\n    stride: 1\n     weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu1_3\"\n  type: \"PReLU\"\n  bottom: \"conv1_3\"\n  top: \"conv1_3\"\n\n}\nlayer {\n  name: \"pool1_3\"\n  type: \"Pooling\"\n  bottom: \"conv1_3\"\n  top: \"pool1_3\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 3\n    stride: 2\n  }\n}\n\nlayer {\n  name: \"conv2_3\"\n  type: \"Convolution\"\n  bottom: \"pool1_3\"\n  top: \"conv2_3\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 48\n    kernel_size: 3\n    stride: 1\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu2_3\"\n  type: \"PReLU\"\n  bottom: \"conv2_3\"\n  top: \"conv2_3\"\n}\nlayer {\n  name: \"pool2_3\"\n  type: \"Pooling\"\n  bottom: \"conv2_3\"\n  top: \"pool2_3\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 3\n    stride: 2\n  }\n  \n}\nlayer {\n  name: \"conv3_3\"\n  type: \"Convolution\"\n  bottom: \"pool2_3\"\n  top: \"conv3_3\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 64\n    kernel_size: 2\n    stride: 1\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu3_3\"\n  type: \"PReLU\"\n  bottom: \"conv3_3\"\n  top: \"conv3_3\"\n}\n##########################\n##########################\nlayer {\n  name: \"conv1_4\"\n  type: \"Convolution\"\n  bottom: \"data244\"\n  top: \"conv1_4\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 28\n    kernel_size: 3\n    stride: 1\n     weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu1_4\"\n  type: \"PReLU\"\n  bottom: \"conv1_4\"\n  top: \"conv1_4\"\n\n}\nlayer {\n  name: \"pool1_4\"\n  type: \"Pooling\"\n  bottom: \"conv1_4\"\n  top: \"pool1_4\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 3\n    stride: 2\n  }\n}\n\nlayer {\n  name: \"conv2_4\"\n  type: \"Convolution\"\n  bottom: \"pool1_4\"\n  top: \"conv2_4\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 48\n    kernel_size: 3\n    stride: 1\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu2_4\"\n  type: \"PReLU\"\n  bottom: \"conv2_4\"\n  top: \"conv2_4\"\n}\nlayer {\n  name: \"pool2_4\"\n  type: \"Pooling\"\n  bottom: \"conv2_4\"\n  top: \"pool2_4\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 3\n    stride: 2\n  }\n  \n}\nlayer {\n  name: \"conv3_4\"\n  type: \"Convolution\"\n  bottom: \"pool2_4\"\n  top: \"conv3_4\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 64\n    kernel_size: 2\n    stride: 1\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu3_4\"\n  type: \"PReLU\"\n  bottom: \"conv3_4\"\n  top: \"conv3_4\"\n}\n##########################\n##########################\nlayer {\n  name: \"conv1_5\"\n  type: \"Convolution\"\n  bottom: \"data245\"\n  top: \"conv1_5\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 28\n    kernel_size: 3\n    stride: 1\n     weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu1_5\"\n  type: \"PReLU\"\n  bottom: \"conv1_5\"\n  top: \"conv1_5\"\n\n}\nlayer {\n  name: \"pool1_5\"\n  type: \"Pooling\"\n  bottom: \"conv1_5\"\n  top: \"pool1_5\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 3\n    stride: 2\n  }\n}\n\nlayer {\n  name: \"conv2_5\"\n  type: \"Convolution\"\n  bottom: \"pool1_5\"\n  top: \"conv2_5\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 48\n    kernel_size: 3\n    stride: 1\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu2_5\"\n  type: \"PReLU\"\n  bottom: \"conv2_5\"\n  top: \"conv2_5\"\n}\nlayer {\n  name: \"pool2_5\"\n  type: \"Pooling\"\n  bottom: \"conv2_5\"\n  top: \"pool2_5\"\n  pooling_param {\n    pool: MAX\n    kernel_size: 3\n    stride: 2\n  }\n  \n}\nlayer {\n  name: \"conv3_5\"\n  type: \"Convolution\"\n  bottom: \"pool2_5\"\n  top: \"conv3_5\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  convolution_param {\n    num_output: 64\n    kernel_size: 2\n    stride: 1\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu3_5\"\n  type: \"PReLU\"\n  bottom: \"conv3_5\"\n  top: \"conv3_5\"\n}\n##########################\nlayer { \n\tname: \"concat\" \n\tbottom: \"conv3_1\" \n\tbottom: \"conv3_2\" \n\tbottom: \"conv3_3\" \n\tbottom: \"conv3_4\" \n\tbottom: \"conv3_5\" \n\ttop: \"conv3\" \n\ttype: \"Concat\" \n\tconcat_param { \n\t\taxis: 1 \n\t} \n}\n##########################\nlayer {\n  name: \"fc4\"\n  type: \"InnerProduct\"\n  bottom: \"conv3\"\n  top: \"fc4\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n    num_output: 256\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu4\"\n  type: \"PReLU\"\n  bottom: \"fc4\"\n  top: \"fc4\"\n}\n############################\nlayer {\n  name: \"fc4_1\"\n  type: \"InnerProduct\"\n  bottom: \"fc4\"\n  top: \"fc4_1\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n    num_output: 64\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu4_1\"\n  type: \"PReLU\"\n  bottom: \"fc4_1\"\n  top: \"fc4_1\"\n}\nlayer {\n  name: \"fc5_1\"\n  type: \"InnerProduct\"\n  bottom: \"fc4_1\"\n  top: \"fc5_1\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n    num_output: 2\n    weight_filler {\n      type: \"xavier\"\n\t  #type: \"constant\"\n      #value: 0\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\n\n\n#########################\nlayer {\n  name: \"fc4_2\"\n  type: \"InnerProduct\"\n  bottom: \"fc4\"\n  top: \"fc4_2\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n    num_output: 64\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu4_2\"\n  type: \"PReLU\"\n  bottom: \"fc4_2\"\n  top: \"fc4_2\"\n}\nlayer {\n  name: \"fc5_2\"\n  type: \"InnerProduct\"\n  bottom: \"fc4_2\"\n  top: \"fc5_2\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n    num_output: 2\n    weight_filler {\n      type: \"xavier\"\n\t  #type: \"constant\"\n      #value: 0\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\n\n#########################\nlayer {\n  name: \"fc4_3\"\n  type: \"InnerProduct\"\n  bottom: \"fc4\"\n  top: \"fc4_3\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n    num_output: 64\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu4_3\"\n  type: \"PReLU\"\n  bottom: \"fc4_3\"\n  top: \"fc4_3\"\n}\nlayer {\n  name: \"fc5_3\"\n  type: \"InnerProduct\"\n  bottom: \"fc4_3\"\n  top: \"fc5_3\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n    num_output: 2\n    weight_filler {\n      type: \"xavier\"\n\t  #type: \"constant\"\n      #value: 0\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\n\n#########################\nlayer {\n  name: \"fc4_4\"\n  type: \"InnerProduct\"\n  bottom: \"fc4\"\n  top: \"fc4_4\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n    num_output: 64\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu4_4\"\n  type: \"PReLU\"\n  bottom: \"fc4_4\"\n  top: \"fc4_4\"\n}\nlayer {\n  name: \"fc5_4\"\n  type: \"InnerProduct\"\n  bottom: \"fc4_4\"\n  top: \"fc5_4\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n    num_output: 2\n    weight_filler {\n      type: \"xavier\"\n\t  #type: \"constant\"\n      #value: 0\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\n\n#########################\nlayer {\n  name: \"fc4_5\"\n  type: \"InnerProduct\"\n  bottom: \"fc4\"\n  top: \"fc4_5\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n    num_output: 64\n    weight_filler {\n      type: \"xavier\"\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n  \n}\nlayer {\n  name: \"prelu4_5\"\n  type: \"PReLU\"\n  bottom: \"fc4_5\"\n  top: \"fc4_5\"\n}\nlayer {\n  name: \"fc5_5\"\n  type: \"InnerProduct\"\n  bottom: \"fc4_5\"\n  top: \"fc5_5\"\n  param {\n    lr_mult: 1\n    decay_mult: 1\n  }\n  param {\n    lr_mult: 2\n    decay_mult: 1\n  }\n  inner_product_param {\n    num_output: 2\n    weight_filler {\n      type: \"xavier\"\n\t  #type: \"constant\"\n      #value: 0\n\t}\n    bias_filler {\n      type: \"constant\"\n      value: 0\n    }\n  }\n}\n\n#########################\n\n"
  },
  {
    "path": "mtcnn_detector.py",
    "content": "# coding: utf-8\nimport os\nimport mxnet as mx\nimport numpy as np\nimport math\nimport cv2\nfrom multiprocessing import Pool\nfrom itertools import repeat\nfrom itertools import izip\nfrom helper import nms, adjust_input, generate_bbox, detect_first_stage_warpper\n\nclass MtcnnDetector(object):\n    \"\"\"\n        Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Neural Networks\n        see https://github.com/kpzhang93/MTCNN_face_detection_alignment\n        this is a mxnet version\n    \"\"\"\n    def __init__(self,\n                 model_folder='.',\n                 minsize = 20,\n                 threshold = [0.6, 0.7, 0.8],\n                 factor = 0.709,\n                 num_worker = 1,\n                 accurate_landmark = False,\n                 ctx=mx.cpu()):\n        \"\"\"\n            Initialize the detector\n\n            Parameters:\n            ----------\n                model_folder : string\n                    path for the models\n                minsize : float number\n                    minimal face to detect\n                threshold : float number\n                    detect threshold for 3 stages\n                factor: float number\n                    scale factor for image pyramid\n                num_worker: int number\n                    number of processes we use for first stage\n                accurate_landmark: bool\n                    use accurate landmark localization or not\n\n        \"\"\"\n        self.num_worker = num_worker\n        self.accurate_landmark = accurate_landmark\n\n        # load 4 models from folder\n        models = ['det1', 'det2', 'det3','det4']\n        models = [ os.path.join(model_folder, f) for f in models]\n        \n        self.PNets = []\n        for i in range(num_worker):\n            workner_net = mx.model.FeedForward.load(models[0], 1, ctx=ctx)\n            self.PNets.append(workner_net)\n\n        self.Pool = Pool(num_worker)\n\n        self.RNet = mx.model.FeedForward.load(models[1], 1, ctx=ctx)\n        self.ONet = mx.model.FeedForward.load(models[2], 1, ctx=ctx)\n        self.LNet = mx.model.FeedForward.load(models[3], 1, ctx=ctx)\n\n        self.minsize   = float(minsize)\n        self.factor    = float(factor)\n        self.threshold = threshold\n\n\n    def convert_to_square(self, bbox):\n        \"\"\"\n            convert bbox to square\n\n        Parameters:\n        ----------\n            bbox: numpy array , shape n x 5\n                input bbox\n\n        Returns:\n        -------\n            square bbox\n        \"\"\"\n        square_bbox = bbox.copy()\n\n        h = bbox[:, 3] - bbox[:, 1] + 1\n        w = bbox[:, 2] - bbox[:, 0] + 1\n        max_side = np.maximum(h,w)\n        square_bbox[:, 0] = bbox[:, 0] + w*0.5 - max_side*0.5\n        square_bbox[:, 1] = bbox[:, 1] + h*0.5 - max_side*0.5\n        square_bbox[:, 2] = square_bbox[:, 0] + max_side - 1\n        square_bbox[:, 3] = square_bbox[:, 1] + max_side - 1\n        return square_bbox\n\n    def calibrate_box(self, bbox, reg):\n        \"\"\"\n            calibrate bboxes\n\n        Parameters:\n        ----------\n            bbox: numpy array, shape n x 5\n                input bboxes\n            reg:  numpy array, shape n x 4\n                bboxex adjustment\n\n        Returns:\n        -------\n            bboxes after refinement\n\n        \"\"\"\n        w = bbox[:, 2] - bbox[:, 0] + 1\n        w = np.expand_dims(w, 1)\n        h = bbox[:, 3] - bbox[:, 1] + 1\n        h = np.expand_dims(h, 1)\n        reg_m = np.hstack([w, h, w, h])\n        aug = reg_m * reg\n        bbox[:, 0:4] = bbox[:, 0:4] + aug\n        return bbox\n\n \n    def pad(self, bboxes, w, h):\n        \"\"\"\n            pad the the bboxes, alse restrict the size of it\n\n        Parameters:\n        ----------\n            bboxes: numpy array, n x 5\n                input bboxes\n            w: float number\n                width of the input image\n            h: float number\n                height of the input image\n        Returns :\n        ------s\n            dy, dx : numpy array, n x 1\n                start point of the bbox in target image\n            edy, edx : numpy array, n x 1\n                end point of the bbox in target image\n            y, x : numpy array, n x 1\n                start point of the bbox in original image\n            ex, ex : numpy array, n x 1\n                end point of the bbox in original image\n            tmph, tmpw: numpy array, n x 1\n                height and width of the bbox\n\n        \"\"\"\n        tmpw, tmph = bboxes[:, 2] - bboxes[:, 0] + 1,  bboxes[:, 3] - bboxes[:, 1] + 1\n        num_box = bboxes.shape[0]\n\n        dx , dy= np.zeros((num_box, )), np.zeros((num_box, ))\n        edx, edy  = tmpw.copy()-1, tmph.copy()-1\n\n        x, y, ex, ey = bboxes[:, 0], bboxes[:, 1], bboxes[:, 2], bboxes[:, 3]\n\n        tmp_index = np.where(ex > w-1)\n        edx[tmp_index] = tmpw[tmp_index] + w - 2 - ex[tmp_index]\n        ex[tmp_index] = w - 1\n\n        tmp_index = np.where(ey > h-1)\n        edy[tmp_index] = tmph[tmp_index] + h - 2 - ey[tmp_index]\n        ey[tmp_index] = h - 1\n\n        tmp_index = np.where(x < 0)\n        dx[tmp_index] = 0 - x[tmp_index]\n        x[tmp_index] = 0\n\n        tmp_index = np.where(y < 0)\n        dy[tmp_index] = 0 - y[tmp_index]\n        y[tmp_index] = 0\n\n        return_list = [dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph]\n        return_list = [item.astype(np.int32) for item in return_list]\n\n        return  return_list\n\n    def slice_index(self, number):\n        \"\"\"\n            slice the index into (n,n,m), m < n\n        Parameters:\n        ----------\n            number: int number\n                number\n        \"\"\"\n        def chunks(l, n):\n            \"\"\"Yield successive n-sized chunks from l.\"\"\"\n            for i in range(0, len(l), n):\n                yield l[i:i + n]\n        num_list = range(number)\n        return list(chunks(num_list, self.num_worker))\n        \n\n    def detect_face(self, img):\n        \"\"\"\n            detect face over img\n        Parameters:\n        ----------\n            img: numpy array, bgr order of shape (1, 3, n, m)\n                input image\n        Retures:\n        -------\n            bboxes: numpy array, n x 5 (x1,y2,x2,y2,score)\n                bboxes\n            points: numpy array, n x 10 (x1, x2 ... x5, y1, y2 ..y5)\n                landmarks\n        \"\"\"\n\n        # check input\n        MIN_DET_SIZE = 12\n\n        if img is None:\n            return None\n\n        # only works for color image\n        if len(img.shape) != 3:\n            return None\n\n        # detected boxes\n        total_boxes = []\n\n        height, width, _ = img.shape\n        minl = min( height, width)\n\n        # get all the valid scales\n        scales = []\n        m = MIN_DET_SIZE/self.minsize\n        minl *= m\n        factor_count = 0\n        while minl > MIN_DET_SIZE:\n            scales.append(m*self.factor**factor_count)\n            minl *= self.factor\n            factor_count += 1\n\n        #############################################\n        # first stage\n        #############################################\n        #for scale in scales:\n        #    return_boxes = self.detect_first_stage(img, scale, 0)\n        #    if return_boxes is not None:\n        #        total_boxes.append(return_boxes)\n        \n        sliced_index = self.slice_index(len(scales))\n        total_boxes = []\n        for batch in sliced_index:\n            local_boxes = self.Pool.map( detect_first_stage_warpper, \\\n                    izip(repeat(img), self.PNets[:len(batch)], [scales[i] for i in batch], repeat(self.threshold[0])) )\n            total_boxes.extend(local_boxes)\n        \n        # remove the Nones \n        total_boxes = [ i for i in total_boxes if i is not None]\n\n        if len(total_boxes) == 0:\n            return None\n        \n        total_boxes = np.vstack(total_boxes)\n\n        if total_boxes.size == 0:\n            return None\n\n        # merge the detection from first stage\n        pick = nms(total_boxes[:, 0:5], 0.7, 'Union')\n        total_boxes = total_boxes[pick]\n\n        bbw = total_boxes[:, 2] - total_boxes[:, 0] + 1\n        bbh = total_boxes[:, 3] - total_boxes[:, 1] + 1\n\n        # refine the bboxes\n        total_boxes = np.vstack([total_boxes[:, 0]+total_boxes[:, 5] * bbw,\n                                 total_boxes[:, 1]+total_boxes[:, 6] * bbh,\n                                 total_boxes[:, 2]+total_boxes[:, 7] * bbw,\n                                 total_boxes[:, 3]+total_boxes[:, 8] * bbh,\n                                 total_boxes[:, 4]\n                                 ])\n\n        total_boxes = total_boxes.T\n        total_boxes = self.convert_to_square(total_boxes)\n        total_boxes[:, 0:4] = np.round(total_boxes[:, 0:4])\n\n        #############################################\n        # second stage\n        #############################################\n        num_box = total_boxes.shape[0]\n\n        # pad the bbox\n        [dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph] = self.pad(total_boxes, width, height)\n        # (3, 24, 24) is the input shape for RNet\n        input_buf = np.zeros((num_box, 3, 24, 24), dtype=np.float32)\n\n        for i in range(num_box):\n            tmp = np.zeros((tmph[i], tmpw[i], 3), dtype=np.uint8)\n            tmp[dy[i]:edy[i]+1, dx[i]:edx[i]+1, :] = img[y[i]:ey[i]+1, x[i]:ex[i]+1, :]\n            input_buf[i, :, :, :] = adjust_input(cv2.resize(tmp, (24, 24)))\n\n        output = self.RNet.predict(input_buf)\n\n        # filter the total_boxes with threshold\n        passed = np.where(output[1][:, 1] > self.threshold[1])\n        total_boxes = total_boxes[passed]\n\n        if total_boxes.size == 0:\n            return None\n\n        total_boxes[:, 4] = output[1][passed, 1].reshape((-1,))\n        reg = output[0][passed]\n\n        # nms\n        pick = nms(total_boxes, 0.7, 'Union')\n        total_boxes = total_boxes[pick]\n        total_boxes = self.calibrate_box(total_boxes, reg[pick])\n        total_boxes = self.convert_to_square(total_boxes)\n        total_boxes[:, 0:4] = np.round(total_boxes[:, 0:4])\n\n        #############################################\n        # third stage\n        #############################################\n        num_box = total_boxes.shape[0]\n\n        # pad the bbox\n        [dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph] = self.pad(total_boxes, width, height)\n        # (3, 48, 48) is the input shape for ONet\n        input_buf = np.zeros((num_box, 3, 48, 48), dtype=np.float32)\n\n        for i in range(num_box):\n            tmp = np.zeros((tmph[i], tmpw[i], 3), dtype=np.float32)\n            tmp[dy[i]:edy[i]+1, dx[i]:edx[i]+1, :] = img[y[i]:ey[i]+1, x[i]:ex[i]+1, :]\n            input_buf[i, :, :, :] = adjust_input(cv2.resize(tmp, (48, 48)))\n\n        output = self.ONet.predict(input_buf)\n\n        # filter the total_boxes with threshold\n        passed = np.where(output[2][:, 1] > self.threshold[2])\n        total_boxes = total_boxes[passed]\n\n        if total_boxes.size == 0:\n            return None\n\n        total_boxes[:, 4] = output[2][passed, 1].reshape((-1,))\n        reg = output[1][passed]\n        points = output[0][passed]\n\n        # compute landmark points\n        bbw = total_boxes[:, 2] - total_boxes[:, 0] + 1\n        bbh = total_boxes[:, 3] - total_boxes[:, 1] + 1\n        points[:, 0:5] = np.expand_dims(total_boxes[:, 0], 1) + np.expand_dims(bbw, 1) * points[:, 0:5]\n        points[:, 5:10] = np.expand_dims(total_boxes[:, 1], 1) + np.expand_dims(bbh, 1) * points[:, 5:10]\n\n        # nms\n        total_boxes = self.calibrate_box(total_boxes, reg)\n        pick = nms(total_boxes, 0.7, 'Min')\n        total_boxes = total_boxes[pick]\n        points = points[pick]\n        \n        if not self.accurate_landmark:\n            return total_boxes, points\n\n        #############################################\n        # extended stage\n        #############################################\n        num_box = total_boxes.shape[0]\n        patchw = np.maximum(total_boxes[:, 2]-total_boxes[:, 0]+1, total_boxes[:, 3]-total_boxes[:, 1]+1)\n        patchw = np.round(patchw*0.25)\n\n        # make it even\n        patchw[np.where(np.mod(patchw,2) == 1)] += 1\n\n        input_buf = np.zeros((num_box, 15, 24, 24), dtype=np.float32)\n        for i in range(5):\n            x, y = points[:, i], points[:, i+5]\n            x, y = np.round(x-0.5*patchw), np.round(y-0.5*patchw)\n            [dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph] = self.pad(np.vstack([x, y, x+patchw-1, y+patchw-1]).T,\n                                                                    width,\n                                                                    height)\n            for j in range(num_box):\n                tmpim = np.zeros((tmpw[j], tmpw[j], 3), dtype=np.float32)\n                tmpim[dy[j]:edy[j]+1, dx[j]:edx[j]+1, :] = img[y[j]:ey[j]+1, x[j]:ex[j]+1, :]\n                input_buf[j, i*3:i*3+3, :, :] = adjust_input(cv2.resize(tmpim, (24, 24)))\n\n        output = self.LNet.predict(input_buf)\n\n        pointx = np.zeros((num_box, 5))\n        pointy = np.zeros((num_box, 5))\n\n        for k in range(5):\n            # do not make a large movement\n            tmp_index = np.where(np.abs(output[k]-0.5) > 0.35)\n            output[k][tmp_index[0]] = 0.5\n\n            pointx[:, k] = np.round(points[:, k] - 0.5*patchw) + output[k][:, 0]*patchw\n            pointy[:, k] = np.round(points[:, k+5] - 0.5*patchw) + output[k][:, 1]*patchw\n\n        points = np.hstack([pointx, pointy])\n        points = points.astype(np.int32)\n\n        return total_boxes, points\n\n    def list2colmatrix(self, pts_list):\n        \"\"\"\n            convert list to column matrix\n        Parameters:\n        ----------\n            pts_list:\n                input list\n        Retures:\n        -------\n            colMat: \n\n        \"\"\"\n        assert len(pts_list) > 0\n        colMat = []\n        for i in range(len(pts_list)):\n            colMat.append(pts_list[i][0])\n            colMat.append(pts_list[i][1])\n        colMat = np.matrix(colMat).transpose()\n        return colMat\n\n    def find_tfrom_between_shapes(self, from_shape, to_shape):\n        \"\"\"\n            find transform between shapes\n        Parameters:\n        ----------\n            from_shape: \n            to_shape: \n        Retures:\n        -------\n            tran_m:\n            tran_b:\n        \"\"\"\n        assert from_shape.shape[0] == to_shape.shape[0] and from_shape.shape[0] % 2 == 0\n\n        sigma_from = 0.0\n        sigma_to = 0.0\n        cov = np.matrix([[0.0, 0.0], [0.0, 0.0]])\n\n        # compute the mean and cov\n        from_shape_points = from_shape.reshape(from_shape.shape[0]/2, 2)\n        to_shape_points = to_shape.reshape(to_shape.shape[0]/2, 2)\n        mean_from = from_shape_points.mean(axis=0)\n        mean_to = to_shape_points.mean(axis=0)\n\n        for i in range(from_shape_points.shape[0]):\n            temp_dis = np.linalg.norm(from_shape_points[i] - mean_from)\n            sigma_from += temp_dis * temp_dis\n            temp_dis = np.linalg.norm(to_shape_points[i] - mean_to)\n            sigma_to += temp_dis * temp_dis\n            cov += (to_shape_points[i].transpose() - mean_to.transpose()) * (from_shape_points[i] - mean_from)\n\n        sigma_from = sigma_from / to_shape_points.shape[0]\n        sigma_to = sigma_to / to_shape_points.shape[0]\n        cov = cov / to_shape_points.shape[0]\n\n        # compute the affine matrix\n        s = np.matrix([[1.0, 0.0], [0.0, 1.0]])\n        u, d, vt = np.linalg.svd(cov)\n\n        if np.linalg.det(cov) < 0:\n            if d[1] < d[0]:\n                s[1, 1] = -1\n            else:\n                s[0, 0] = -1\n        r = u * s * vt\n        c = 1.0\n        if sigma_from != 0:\n            c = 1.0 / sigma_from * np.trace(np.diag(d) * s)\n\n        tran_b = mean_to.transpose() - c * r * mean_from.transpose()\n        tran_m = c * r\n\n        return tran_m, tran_b\n\n    def extract_image_chips(self, img, points, desired_size=256, padding=0):\n        \"\"\"\n            crop and align face\n        Parameters:\n        ----------\n            img: numpy array, bgr order of shape (1, 3, n, m)\n                input image\n            points: numpy array, n x 10 (x1, x2 ... x5, y1, y2 ..y5)\n            desired_size: default 256\n            padding: default 0\n        Retures:\n        -------\n            crop_imgs: list, n\n                cropped and aligned faces \n        \"\"\"\n        crop_imgs = []\n        for p in points:\n            shape  =[]\n            for k in range(len(p)/2):\n                shape.append(p[k])\n                shape.append(p[k+5])\n\n            if padding > 0:\n                padding = padding\n            else:\n                padding = 0\n            # average positions of face points\n            mean_face_shape_x = [0.224152, 0.75610125, 0.490127, 0.254149, 0.726104]\n            mean_face_shape_y = [0.2119465, 0.2119465, 0.628106, 0.780233, 0.780233]\n\n            from_points = []\n            to_points = []\n\n            for i in range(len(shape)/2):\n                x = (padding + mean_face_shape_x[i]) / (2 * padding + 1) * desired_size\n                y = (padding + mean_face_shape_y[i]) / (2 * padding + 1) * desired_size\n                to_points.append([x, y])\n                from_points.append([shape[2*i], shape[2*i+1]])\n\n            # convert the points to Mat\n            from_mat = self.list2colmatrix(from_points)\n            to_mat = self.list2colmatrix(to_points)\n\n            # compute the similar transfrom\n            tran_m, tran_b = self.find_tfrom_between_shapes(from_mat, to_mat)\n\n            probe_vec = np.matrix([1.0, 0.0]).transpose()\n            probe_vec = tran_m * probe_vec\n\n            scale = np.linalg.norm(probe_vec)\n            angle = 180.0 / math.pi * math.atan2(probe_vec[1, 0], probe_vec[0, 0])\n\n            from_center = [(shape[0]+shape[2])/2.0, (shape[1]+shape[3])/2.0]\n            to_center = [0, 0]\n            to_center[1] = desired_size * 0.4\n            to_center[0] = desired_size * 0.5\n\n            ex = to_center[0] - from_center[0]\n            ey = to_center[1] - from_center[1]\n\n            rot_mat = cv2.getRotationMatrix2D((from_center[0], from_center[1]), -1*angle, scale)\n            rot_mat[0][2] += ex\n            rot_mat[1][2] += ey\n\n            chips = cv2.warpAffine(img, rot_mat, (desired_size, desired_size))\n            crop_imgs.append(chips)\n\n        return crop_imgs\n\n"
  }
]