def evaluate(self, img_ids=None):
        """
        Args:
            img_ids: a list of image IDs to evaluate on. Default to None for the whole dataset
        """

        if self._distributed:
            comm.synchronize()
            def gather(x, move=False):
                x = comm.gather(x)
                x = list(itertools.chain(*x))
                if move:
                    x = [xx.to(self._gen_captions[0].device) for xx in x]
                return x
            gen_captions = gather(self._gen_captions)
            image_ids = gather(self._image_ids)
            if not comm.is_main_process():
                return {}
        else:
            gen_captions = self._gen_captions
            image_ids = self._image_ids

        assert len(gen_captions) == len(image_ids)
        pred_captions = [{"image_id": image_id, "caption": gen_caption} for image_id, gen_caption in zip(image_ids, gen_captions)]
        pred_pth = os.path.join(self._output_dir, 'results.json')
        json.dump(pred_captions, open(pred_pth, "w"))

        gt_captions = self._gt_json
        pred_captions = gt_captions.loadRes(pred_pth)

        cocoEval = COCOEvalCap(gt_captions, pred_captions)
        cocoEval.params['image_id'] = pred_captions.getImgIds()
        cocoEval.evaluate()
        return cocoEval.eval

        Args:
            img_ids: a list of image IDs to evaluate on. Default to None for the whole dataset
        
datasets/evaluation/captioning_evaluation.py