          logger.debug("initialize %s: (args: %s, kwargs: %s)",
                       self.__class__.__name__, args, kwargs)
          p_type = "Detector" if self._plugin_type == "detect" else "Aligner"
          logger.info("Initializing %s %s...", self.name, p_type)
          self.queue_size = kwargs["queue_size"]
          self._add_queues(kwargs["in_queue"], kwargs["out_queue"], ["predict", "post"])
          self._compile_threads()
          self.init_model()
          logger.info("Initialized %s %s with batchsize of %s", self.name, p_type, self.batchsize)
  
 
</s> remove         batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
 </s> add         batch["prediction"], batch["mtcnn_points"] = prediction, points </s> remove     def predict(self, feed):
 </s> add     def _amd_predict_with_optimized_batchsizes(self, feed, batch_size):
        """ Minimizes the amount of kernels to be compiled when using
        the ``Amd`` backend with varying batchsizes while trying to keep
        the batchsize as high as possible.

        Parameters
        ----------
        feed: numpy.ndarray or list
            The feed to be provided to the model as input. This should be a ``numpy.ndarray``
            for single inputs or a ``list`` of ``numpy.ndarrays`` for multiple inputs.
        batch_size: int
            The upper batchsize to use.
        """
        if isinstance(feed, np.ndarray):
            feed = [feed]
        items = feed[0].shape[0]
        done_items = 0
        results = list()
        while done_items < items:
            if batch_size < 4:  # Not much difference in BS < 4
                batch_size = 1
            batch_items = ((items - done_items) // batch_size) * batch_size
            if batch_items:
                pred_data = [x[done_items:done_items + batch_items] for x in feed]
                pred = self._model.predict(pred_data, batch_size=batch_size)
                done_items += batch_items
                results.append(pred)
            batch_size //= 2
        if isinstance(results[0], np.ndarray):
            return np.concatenate(results)
        return [np.concatenate(x) for x in zip(*results)]

    def predict(self, feed, batch_size=None): </s> remove         crop_number = 0
        predict_24_batch = []
        for rect in rectangles:
            crop_img = image[int(rect[1]):int(rect[3]), int(rect[0]):int(rect[2])]
            scale_img = cv2.resize(crop_img, (24, 24))  # pylint:disable=no-member
            predict_24_batch.append(scale_img)
            crop_number += 1

        predict_24_batch = np.array(predict_24_batch)
        output = self.rnet.predict(predict_24_batch)

        cls_prob = output[0]  # first 0 is to select cls, second batch number, always =0
        cls_prob = np.array(cls_prob)
        roi_prob = output[1]  # first 0 is to select roi, second batch number, always =0
        roi_prob = np.array(roi_prob)
        return filter_face_24net(cls_prob, roi_prob, rectangles, width, height, self.threshold[1])

    def detect_onet(self, image, rectangles, height, width):
 </s> add         ret = []
        # TODO: batching
        for b, rectangles in enumerate(rectangle_batch):
            if not rectangles:
                ret.append(list())
                continue
            image = images[b]
            crop_number = 0
            predict_24_batch = []
            for rect in rectangles:
                crop_img = image[int(rect[1]):int(rect[3]), int(rect[0]):int(rect[2])]
                scale_img = cv2.resize(crop_img, (24, 24))  # pylint:disable=no-member
                predict_24_batch.append(scale_img)
                crop_number += 1
            predict_24_batch = np.array(predict_24_batch)
            output = self.rnet.predict(predict_24_batch, batch_size=128)
            cls_prob = output[0]
            cls_prob = np.array(cls_prob)
            roi_prob = output[1]
            roi_prob = np.array(roi_prob)
            ret.append(filter_face_24net(
                cls_prob, roi_prob, rectangles, width, height, self.threshold[1]
            ))
        return ret

    def detect_onet(self, images, rectangle_batch, height, width): </s> remove             cls_prob = np.swapaxes(cls_prob, 0, 1)
            roi = np.swapaxes(roi, 0, 2)
            rectangle = detect_face_12net(cls_prob,
                                          roi,
                                          out_side,
                                          1 / scale,
                                          width,
                                          height,
                                          self.threshold[0])
            rectangles.extend(rectangle)
        return nms(rectangles, 0.7, 'iou')

    def detect_rnet(self, image, rectangles, height, width):
 </s> add             cls_prob = np.swapaxes(cls_prob, 1, 2)
            roi = np.swapaxes(roi, 1, 3)
            for b in range(batch_items):
                # first index 0 = cls score, 1 = one hot repr
                rectangle = detect_face_12net(cls_prob[b, ...],
                                              roi[b, ...],
                                              out_side,
                                              1 / scale,
                                              width,
                                              height,
                                              self.threshold[0])
                rectangles[b].extend(rectangle)
        return [nms(x, 0.7, 'iou') for x in rectangles]

    def detect_rnet(self, images, rectangle_batch, height, width):
        self.queue_size = 1
          logger.debug("initialize %s: (args: %s, kwargs: %s)",
                       self.__class__.__name__, args, kwargs)
          p_type = "Detector" if self._plugin_type == "detect" else "Aligner"
          logger.info("Initializing %s %s...", self.name, p_type)
        self.queue_size = 1
          self._add_queues(kwargs["in_queue"], kwargs["out_queue"], ["predict", "post"])
          self._compile_threads()
          self.init_model()
          logger.info("Initialized %s %s with batchsize of %s", self.name, p_type, self.batchsize)
  
keep keep keep keep replace keep keep keep keep keep
 Optimized mtcnn a bit + added batching (#874) 
plugins/extract/_base.py