def faceid_retina(target_image_dir: str) -> Callable:
    """The closure returns the Face ID reward function given a user ID. It uses RetinaFace to detect the face and then
    use CurricularFace to extract the face feature. As the detection capability of RetinaFace is weaker than SCRFD,
    many generated side faces cannot be detected.

    Args:
        target_image_dir (str): The directory of processed face image files (.jpg) given a user ID.
    """
    # The retinaface detection is built into the face recognition pipeline.
    face_recognition = pipeline("face_recognition", model="bubbliiiing/cv_retinafce_recognition", model_revision="v1.0.3")
    target_image_files = Path(target_image_dir).glob("*.jpg")
    target_images = [Image.open(f).convert("RGB") for f in target_image_files]

    target_embs = [face_recognition(dict(user=f))[OutputKeys.IMG_EMBEDDING] for f in target_images]  # (M, 512)
    target_mean_emb = np.mean(np.vstack(target_embs), axis=0)  # (512,)

    # Redundant parameters are for backward compatibility.
    def __call__(src_images: Union[List[Image.Image], np.array, torch.Tensor], prompts: List[str]) -> Tuple[np.array, dict]:
        src_images = _convert_images(src_images)
        src_embs = []  # (N, 512)
        for s in src_images:
            try:
                emb = face_recognition(dict(user=s))[OutputKeys.IMG_EMBEDDING][0]
            except Exception as e:  # cv2.error; TypeError.
                print("Catch Exception in the reward function faceid_retina: {}".format(e))
                emb = np.array([0] * 512)
                print("No face is detected or the size of the detected face size is not enough. Set the embedding to zero.")
            finally:
                src_embs.append(emb)
        faceid_list = np.dot(src_embs, target_mean_emb)

        return faceid_list

    return __call__
The closure returns the Face ID reward function given a user ID. It uses RetinaFace to detect the face and then
    use CurricularFace to extract the face feature. As the detection capability of RetinaFace is weaker than SCRFD,
    many generated side faces cannot be detected.

    Args:
        target_image_dir (str): The directory of processed face image files (.jpg) given a user ID.
    
scripts/train_kohya/ddpo_pytorch/rewards.py