{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import sys\nsys.path.append('../input/timm-pytorch-image-models/pytorch-image-models-master')\nimport timm","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-01-10T12:48:04.540953Z","iopub.execute_input":"2023-01-10T12:48:04.541609Z","iopub.status.idle":"2023-01-10T12:48:08.521404Z","shell.execute_reply.started":"2023-01-10T12:48:04.541482Z","shell.execute_reply":"2023-01-10T12:48:08.520164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torch.utils.data import DataLoader\nfrom torch.cuda.amp import autocast, GradScaler\nimport warnings\nimport sys\nimport pandas as pd\nimport os\nimport gc\nimport sys\nimport math\nimport time\nimport random\nimport shutil\nfrom pathlib import Path\nfrom contextlib import contextmanager\nfrom collections import defaultdict, Counter\n\nimport scipy as sp\nimport numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\nfrom tqdm.auto import tqdm\nfrom functools import partial\n\nimport argparse\nimport importlib\nimport torch\nimport torch.nn as nn\nfrom torch.optim import Adam, SGD, AdamW","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.526416Z","iopub.execute_input":"2023-01-10T12:48:08.527015Z","iopub.status.idle":"2023-01-10T12:48:08.551092Z","shell.execute_reply.started":"2023-01-10T12:48:08.526975Z","shell.execute_reply":"2023-01-10T12:48:08.550122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"EXP_NAME_PLAYER = 'nfl3-exp063'\nEXP_NAME_GROUND = 'nfl3-exp050'\nEXP_NAME_PLAYER_gbdt = 'train-gbdt-exp005'\nEXP_NAME_GROUND_gbdt = 'train-gbdt-g-exp001'\ncv_exp_names = [EXP_NAME_PLAYER]\ncv_g_exp_names = [EXP_NAME_GROUND]\n\nbest_th = 0.3\nbest_th_g = 0.3","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.554381Z","iopub.execute_input":"2023-01-10T12:48:08.554806Z","iopub.status.idle":"2023-01-10T12:48:08.560553Z","shell.execute_reply.started":"2023-01-10T12:48:08.554761Z","shell.execute_reply":"2023-01-10T12:48:08.559266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"recall_num = 99\nlabels_output_dir = 'train_player_labels/'\nos.makedirs(labels_output_dir, exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.565528Z","iopub.execute_input":"2023-01-10T12:48:08.565944Z","iopub.status.idle":"2023-01-10T12:48:08.571747Z","shell.execute_reply.started":"2023-01-10T12:48:08.565907Z","shell.execute_reply":"2023-01-10T12:48:08.570453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"VIDEO_OUTPUT_PATH = '/'","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.574599Z","iopub.execute_input":"2023-01-10T12:48:08.575252Z","iopub.status.idle":"2023-01-10T12:48:08.581643Z","shell.execute_reply.started":"2023-01-10T12:48:08.575216Z","shell.execute_reply":"2023-01-10T12:48:08.580491Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IS_DEBUG = False","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.583647Z","iopub.execute_input":"2023-01-10T12:48:08.584082Z","iopub.status.idle":"2023-01-10T12:48:08.593106Z","shell.execute_reply.started":"2023-01-10T12:48:08.584037Z","shell.execute_reply":"2023-01-10T12:48:08.591029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.598082Z","iopub.execute_input":"2023-01-10T12:48:08.598391Z","iopub.status.idle":"2023-01-10T12:48:08.663410Z","shell.execute_reply.started":"2023-01-10T12:48:08.598366Z","shell.execute_reply":"2023-01-10T12:48:08.662293Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 乱数固定\ndef set_seed(seed=None):\n    if seed is None:\n        seed = 42\n\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True  # A100,effnetだとFalseの方が早い\n    torch.backends.cudnn.benchmark = False","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.666315Z","iopub.execute_input":"2023-01-10T12:48:08.667564Z","iopub.status.idle":"2023-01-10T12:48:08.675124Z","shell.execute_reply.started":"2023-01-10T12:48:08.667526Z","shell.execute_reply":"2023-01-10T12:48:08.674096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"set_seed()","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.678858Z","iopub.execute_input":"2023-01-10T12:48:08.679421Z","iopub.status.idle":"2023-01-10T12:48:08.690703Z","shell.execute_reply.started":"2023-01-10T12:48:08.679386Z","shell.execute_reply":"2023-01-10T12:48:08.689574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## ファイルパス、recall設定用","metadata":{}},{"cell_type":"code","source":"class CFG:\n    comp_dataset_path = '/kaggle/input/nfl-player-contact-detection/'\n    submission_dir = './oofs/'\n    \n    recall_num = 99","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.696602Z","iopub.execute_input":"2023-01-10T12:48:08.696890Z","iopub.status.idle":"2023-01-10T12:48:08.704333Z","shell.execute_reply.started":"2023-01-10T12:48:08.696866Z","shell.execute_reply":"2023-01-10T12:48:08.702066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.makedirs(CFG.submission_dir, exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.707131Z","iopub.execute_input":"2023-01-10T12:48:08.708188Z","iopub.status.idle":"2023-01-10T12:48:08.714765Z","shell.execute_reply.started":"2023-01-10T12:48:08.708153Z","shell.execute_reply":"2023-01-10T12:48:08.713608Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 選手ペアの衝突予測用 train用のcfgをそのままコピペ","metadata":{}},{"cell_type":"code","source":"import os\n\nclass CFG_player_pair:\n\n    # ------- テンプレ -------\n    comp_name = 'nfl3'  # compのデータセットのフォルダ名\n\n    # comp_dir_path = '/home/ryosuke/Documents/kaggle/kaggle_pipeline/'  # local\n    # comp_dir_path = '/notebooks/' # paperspace\n    comp_dir_path = './'\n    comp_dataset_path = f'{comp_dir_path}datasets/{comp_name}/'\n    print(comp_dataset_path)\n\n    try:\n        exp_name = os.path.basename(__file__).split('.')[0]\n    except Exception:\n        print('running kernel')\n        exp_name = None\n\n    recall_num = 99\n    frame_window = 0\n    frame_stride = 2\n\n    # target\n    target_size = 1\n    target_col = 'contact'\n\n    # zone = 'Endzone'\n    # zone = 'Sideline'\n    zone = 'all'\n    pred_target = 'player'\n    # pred_target = 'ground'\n\n    # 画像のfile path用dfの設定 (nfl3では事前にfold追加)\n    # train_csv_path = f'train_player_labels/train_{pred_target}_label_{zone}_recall{recall_num}.csv'\n\n    # train_image_dir_path = f'train_player_bbox_3d_frame{frame_window}_bbox_mask/'\n\n    # npy\n    # train_image_dir_path = f'datasets/nfl3/train_{pred_target}_bbox_3d_recall{recall_num}_frame{frame_window}_bbox_mask/'\n    # image_file_suffix = '.npy'\n\n    # video grayscale\n    train_image_dir_path = 'datasets/nfl3/video_images_grayscale_half/train/'\n    image_file_suffix = '.jpg'\n\n    test_image_dir_path = 'test_images'\n    image_file_col = 'image_id'\n\n    # albmentation\n    size = 128\n    img_width = 1280 // 2\n    img_height = 720 // 2\n    cut_num = 64 // 2  # 画像サイズ1/2だから 64//2\n\n    is_debug = False\n\n    use_3d_model = False\n\n    # subではcache使わない\n    if exp_name is None:\n        use_video_cache = False\n    else:\n        use_video_cache = True\n\n    use_mask = True\n    # use_attention_mask = True\n    use_body_mask = False\n\n    aug_suffix = '_mask' if use_mask else ''\n    if use_body_mask:\n        aug_suffix += '_body'\n\n    mask_ch = 1 if use_mask else 0\n    if use_body_mask:\n        mask_ch += 1\n\n    frame_ch = 1 + mask_ch\n    frame_num = (frame_window * 2 + 1)\n    # train_aug_path = f'cfgs/alb_yaml/resnet18d_{size}_randomresize_shift_bri_frame{frame_window}{aug_suffix}.yaml'\n    train_aug_path = f'cfgs/alb_yaml/img_{size}_aug_heavy_frame{frame_window}{aug_suffix}.yaml'\n    aug_mean = [0] * frame_ch * frame_num\n    aug_std = [1] * frame_ch * frame_num\n    in_chans = 1 * frame_ch * frame_num\n\n    # kf\n    skf_col = 'contact'\n    # group_col = 'game_play'\n    group_col = 'game'\n    fold_type = 'gkf'\n\n    objective_cv = 'binary'  # collateとかの型を決める用\n    metric_direction = 'maximize'  # maximize\n    metrics = 'calc_auc_score'\n\n    # ------- model config --------\n\n    # model_name = 'tf_efficientnet_b0_ns'\n    # model_name = 'tf_efficientnetv2_b0'\n    # model_name = 'tf_efficientnetv2_s'\n    # model_name = 'resnet18d'\n    model_name = 'resnet50d'\n    model_3d_name = 'resnet18-3d'\n    use_grayscale = True\n\n    # ------- wandb -------\n    # wandb_note = f'{model_name}_{pred_target}_{zone} frame={frame_window} stride={frame_stride} absdiff'\n    wandb_note = f'{pred_target}_{zone} aug_heavy add noise'\n\n    # ============== training cfg =============\n\n    batch_size = 128  # 32\n    use_mixup = False\n    use_amp = True\n\n    scheduler = 'GradualWarmupSchedulerV2'\n    # scheduler = 'CosineAnnealingLR'\n    epochs = 10\n\n    # adamW warmupあり\n    warmup_factor = 10\n    # lr = 1e-3 / warmup_factor\n    lr = 1e-3 / warmup_factor\n\n    # ============== fold =============\n    n_fold = 5\n    use_holdout = False\n    use_alldata = False\n    train_folds = [0, 1, 2, 3, 4]\n\n    # ============== ほぼ固定 =============\n    pretrained = True\n    inf_weight = 'best'  # 'best'\n\n    min_lr = 1e-6\n    weight_decay = 1e-6\n    max_grad_norm = 1000\n\n    print_freq = 50\n    num_workers = 4\n\n    seed = 42\n\n    # ----- set dataset_path -----\n    if exp_name is not None:\n        print('set dataset path')\n\n        outputs_path = comp_dir_path +  \\\n            f'outputs/{comp_name}/{exp_name}/'\n\n        submission_dir = outputs_path + 'submissions/'\n        submission_path = submission_dir + f'submission_{exp_name}.csv'\n\n        model_dir = outputs_path + \\\n            f'{comp_name}-models/'\n\n        figures_dir = outputs_path + 'figures/'\n\n        log_dir = outputs_path + 'logs/'\n        log_path = log_dir + f'{exp_name}.txt'\n\n\n# よく使うモデル\n\"\"\"\nmodel_name = 'tf_efficientnet_b0_ns'\nmodel_name = 'tf_efficientnet_b3_ns'\nmodel_name = 'tf_efficientnet_b5_ns'\nmodel_name = 'resnet18d'\nmodel_name = 'swin_tiny_patch4_window7_224'\nmodel_name = 'swin_small_patch4_window7_224'\nmodel_name = 'tf_efficientnetv2_m'\nmodel_name = 'tf_efficientnetv2_l'\n# model_name = 'swin_large_patch4_window7_224'\n# model_name = 'convnext_xlarge_in22k'\nmodel_name = 'swinv2_large_window12to16_192to256_22kft1k'\n\"\"\"\n","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.718081Z","iopub.execute_input":"2023-01-10T12:48:08.719010Z","iopub.status.idle":"2023-01-10T12:48:08.747914Z","shell.execute_reply.started":"2023-01-10T12:48:08.718976Z","shell.execute_reply":"2023-01-10T12:48:08.746695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 地面とのの衝突予測用","metadata":{}},{"cell_type":"code","source":"import os\n\nclass CFG_ground:\n\n    # ------- テンプレ -------\n    comp_name = 'nfl3'  # compのデータセットのフォルダ名\n\n    # comp_dir_path = '/home/ryosuke/Documents/kaggle/kaggle_pipeline/'  # local\n    # comp_dir_path = '/notebooks/' # paperspace\n    comp_dir_path = './'\n    comp_dataset_path = f'{comp_dir_path}datasets/{comp_name}/'\n    print(comp_dataset_path)\n\n    try:\n        exp_name = os.path.basename(__file__).split('.')[0]\n    except Exception as e:\n        print('running kernel')\n        exp_name = None\n\n    recall_num = 99\n    frame_window = 0\n    frame_stride = 2\n\n    # target\n    target_size = 1\n    target_col = 'contact'\n\n    zone = 'Endzone'\n    # zone = 'Sideline'\n    # zone = 'all'\n    # pred_target = 'player'\n    pred_target = 'ground'\n\n    # 画像のfile path用dfの設定 (nfl3では事前にfold追加)\n    # train_csv_path = f'train_player_labels/train_{pred_target}_label_{zone}_recall{recall_num}.csv'\n\n    # train_image_dir_path = f'train_player_bbox_3d_frame{frame_window}_bbox_mask/'\n\n    # npy\n    # train_image_dir_path = f'datasets/nfl3/train_{pred_target}_bbox_3d_recall{recall_num}_frame{frame_window}_bbox_mask/'\n    # image_file_suffix = '.npy'\n\n    # video grayscale\n    train_image_dir_path = 'datasets/nfl3/video_images_grayscale_half/train/'\n    image_file_suffix = '.jpg'\n\n    test_image_dir_path = 'test_images'\n    image_file_col = 'image_id'\n\n    # albmentation\n    size = 128\n    img_width = 1280 // 2\n    img_height = 720 // 2\n    cut_num = 64 // 2  # 画像サイズ1/2だから //2\n\n    is_debug = False\n\n    use_3d_model = False\n\n    # subではcache使わない\n    if exp_name is None:\n        use_video_cache = False\n    else:\n        use_video_cache = True\n\n    use_mask = True\n\n    aug_suffix = '_mask' if use_mask else ''\n    mask_ch = 1 if use_mask else 0\n    frame_ch = 1 + mask_ch\n    frame_num = (frame_window * 2 + 1)\n    train_aug_path = f'cfgs/alb_yaml/resnet18d_{size}_randomresize_shift_frame{frame_window}{aug_suffix}.yaml'\n    aug_mean = [0] * frame_ch * frame_num\n    aug_std = [1] * frame_ch * frame_num\n    in_chans = 1 * frame_ch * frame_num\n\n    # kf\n    skf_col = 'contact'\n    # group_col = 'game_play'\n    group_col = 'game'\n    fold_type = 'gkf'\n\n    objective_cv = 'binary'  # collateとかの型を決める用\n    metric_direction = 'maximize'  # maximize\n    metrics = 'calc_auc_score'\n\n    # ------- model config --------\n\n    # model_name = 'tf_efficientnet_b0_ns'\n    # model_name = 'tf_efficientnetv2_b0'\n    # model_name = 'tf_efficientnetv2_s'\n    model_name = 'resnet18d'\n    model_3d_name = 'resnet18-3d'\n    use_grayscale = True\n\n    # ------- wandb -------\n    # wandb_note = f'{model_name}_{pred_target}_{zone} frame={frame_window} stride={frame_stride} absdiff'\n    wandb_note = f'{pred_target}_{zone}'\n\n    # ============== training cfg =============\n\n    batch_size = 128  # 32\n    use_mixup = False\n    use_amp = True\n\n    scheduler = 'GradualWarmupSchedulerV2'\n    # scheduler = 'CosineAnnealingLR'\n    epochs = 10\n\n    # adamW warmupあり\n    warmup_factor = 10\n    # lr = 1e-3 / warmup_factor\n    lr = 1e-3 / warmup_factor\n\n    # ============== fold =============\n    n_fold = 5\n    use_holdout = False\n    use_alldata = False\n    train_folds = [0, 1, 2, 3, 4]\n\n    # ============== ほぼ固定 =============\n    pretrained = True\n    inf_weight = 'best'  # 'best'\n\n    min_lr = 1e-6\n    weight_decay = 1e-6\n    max_grad_norm = 1000\n\n    print_freq = 50\n    num_workers = 4\n\n    seed = 42\n\n    # ----- set dataset_path -----\n    if exp_name is not None:\n        print('set dataset path')\n\n        outputs_path = comp_dir_path +  \\\n            f'outputs/{comp_name}/{exp_name}/'\n\n        submission_dir = outputs_path + 'submissions/'\n        submission_path = submission_dir + f'submission_{exp_name}.csv'\n\n        model_dir = outputs_path + \\\n            f'{comp_name}-models/'\n\n        figures_dir = outputs_path + 'figures/'\n\n        log_dir = outputs_path + 'logs/'\n        log_path = log_dir + f'{exp_name}.txt'\n\n\n# よく使うモデル\n\"\"\"\nmodel_name = 'tf_efficientnet_b0_ns'\nmodel_name = 'tf_efficientnet_b3_ns'\nmodel_name = 'tf_efficientnet_b5_ns'\nmodel_name = 'resnet18d'\nmodel_name = 'swin_tiny_patch4_window7_224'\nmodel_name = 'swin_small_patch4_window7_224'\nmodel_name = 'tf_efficientnetv2_m'\nmodel_name = 'tf_efficientnetv2_l'\n# model_name = 'swin_large_patch4_window7_224'\n# model_name = 'convnext_xlarge_in22k'\nmodel_name = 'swinv2_large_window12to16_192to256_22kft1k'\n\"\"\"\n","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.749960Z","iopub.execute_input":"2023-01-10T12:48:08.750900Z","iopub.status.idle":"2023-01-10T12:48:08.784294Z","shell.execute_reply.started":"2023-01-10T12:48:08.750846Z","shell.execute_reply":"2023-01-10T12:48:08.782481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def expand_contact_id(df):\n    \"\"\"\n    Splits out contact_id into seperate columns.\n    \"\"\"\n    df[\"game_play\"] = df[\"contact_id\"].str[:12]\n    df[\"step\"] = df[\"contact_id\"].str.split(\"_\").str[-3].astype(\"int\")\n    df[\"nfl_player_id_1\"] = df[\"contact_id\"].str.split(\"_\").str[-2]\n    df[\"nfl_player_id_2\"] = df[\"contact_id\"].str.split(\"_\").str[-1]\n    return df\n","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.785664Z","iopub.execute_input":"2023-01-10T12:48:08.786032Z","iopub.status.idle":"2023-01-10T12:48:08.794353Z","shell.execute_reply.started":"2023-01-10T12:48:08.785999Z","shell.execute_reply":"2023-01-10T12:48:08.793170Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def read_labels(comp_dataset_path):\n    if IS_DEBUG:\n        labels = pd.read_csv(comp_dataset_path + 'train_labels.csv')\n    else:\n        labels = pd.read_csv(comp_dataset_path + 'sample_submission.csv')\n        \n        labels = labels[['contact_id']]\n        labels = expand_contact_id(labels)\n\n        \n    fps = 59.94\n    snap_frame = 5 * fps\n    labels['frame'] = ((labels['step'] / 10 * fps) +\n                       snap_frame).round().astype(\"int\")\n    return labels\n\ndef read_players(comp_dataset_path):\n    if IS_DEBUG:\n        players = pd.read_csv(comp_dataset_path + 'train_player_tracking.csv')\n    else:\n        players = pd.read_csv(comp_dataset_path + 'test_player_tracking.csv')\n\n    fps = 59.94\n    snap_frame = 5 * fps\n    players['frame'] = ((players['step'] / 10 * fps) +\n                        snap_frame).round().astype(\"int\")\n    return players\n\ndef read_helmets(comp_dataset_path):\n    if IS_DEBUG:\n        helmets = pd.read_csv(comp_dataset_path + 'train_baseline_helmets.csv')\n    else:\n        helmets = pd.read_csv(comp_dataset_path + 'test_baseline_helmets.csv')\n\n    return helmets","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.796182Z","iopub.execute_input":"2023-01-10T12:48:08.797244Z","iopub.status.idle":"2023-01-10T12:48:08.814511Z","shell.execute_reply.started":"2023-01-10T12:48:08.797209Z","shell.execute_reply":"2023-01-10T12:48:08.813258Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# labels","metadata":{}},{"cell_type":"code","source":"labels = read_labels(CFG.comp_dataset_path)\n\nlabels = labels.query('nfl_player_id_2 != \"G\"').reset_index(drop=True)\n\nlabels['nfl_player_id_1'] = labels['nfl_player_id_1'].astype(int)\nlabels['nfl_player_id_2'] = labels['nfl_player_id_2'].astype(int)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:08.815857Z","iopub.execute_input":"2023-01-10T12:48:08.817725Z","iopub.status.idle":"2023-01-10T12:48:09.426181Z","shell.execute_reply.started":"2023-01-10T12:48:08.817682Z","shell.execute_reply":"2023-01-10T12:48:09.424983Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# player","metadata":{}},{"cell_type":"code","source":"players = read_players(CFG.comp_dataset_path)\nuse_cols = ['game_play', 'step']\nrename_cols = ['nfl_player_id', 'x_position', 'y_position', 'team','speed', 'direction', 'orientation',\n            'acceleration', 'sa', 'position']\nuse_cols += rename_cols\n\nplayers = players[use_cols]\n\ncolumns = dict((col, col + '_1') for col in rename_cols)\nlabels = pd.merge(labels, players.rename(columns=columns), on=['game_play', 'step', 'nfl_player_id_1'], how='left')\n\n# rename_cols = ['nfl_player_id', 'x_position', 'y_position', 'team']\ncolumns = dict((col, col + '_2') for col in rename_cols)\nlabels = pd.merge(labels, players.rename(columns=columns), on=['game_play', 'step', 'nfl_player_id_2'], how='left')\n\nlabels[\"distance\"] = np.sqrt(\n    np.square(labels[\"x_position_1\"] - labels[\"x_position_2\"])\n    + np.square(labels[\"y_position_1\"] - labels[\"y_position_2\"])\n)\n\nlabels['same_team'] = (labels['team_1'] == labels['team_2']).astype(int)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:09.427555Z","iopub.execute_input":"2023-01-10T12:48:09.427916Z","iopub.status.idle":"2023-01-10T12:48:09.571849Z","shell.execute_reply.started":"2023-01-10T12:48:09.427882Z","shell.execute_reply":"2023-01-10T12:48:09.570824Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dist_th = 1.7476226400525687\nlabels = labels.query(f'distance <= {dist_th}').reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:09.576810Z","iopub.execute_input":"2023-01-10T12:48:09.579120Z","iopub.status.idle":"2023-01-10T12:48:09.624199Z","shell.execute_reply.started":"2023-01-10T12:48:09.579081Z","shell.execute_reply":"2023-01-10T12:48:09.620873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels.to_csv(labels_output_dir + f'train_player_label_lgb_recall{recall_num}.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:09.630591Z","iopub.execute_input":"2023-01-10T12:48:09.633525Z","iopub.status.idle":"2023-01-10T12:48:09.689056Z","shell.execute_reply.started":"2023-01-10T12:48:09.633472Z","shell.execute_reply":"2023-01-10T12:48:09.687812Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# helmet","metadata":{}},{"cell_type":"code","source":"def make_player_pair_label_df(labels, zone, labels_output_dir):\n    helmets = read_helmets(CFG.comp_dataset_path)\n    \n    # helmets = interpolate_helmets(helmets)\n    \n    helmets = helmets.query('view == @zone').reset_index(drop=True)\n\n    use_cols = ['game_play','frame']\n    rename_cols = ['nfl_player_id', 'left',\t'width','top','height']\n    use_cols += rename_cols\n    helmets = helmets[use_cols]\n\n    columns = dict((col, col + '_1') for col in rename_cols)\n    labels = pd.merge(labels, helmets.rename(columns=columns), on=['game_play', 'frame', 'nfl_player_id_1'], how='left')\n\n    columns = dict((col, col + '_2') for col in rename_cols)\n    labels = pd.merge(labels, helmets.rename(columns=columns), on=['game_play', 'frame', 'nfl_player_id_2'], how='left')\n\n    print(labels.isnull().sum())\n\n    labels['video'] = labels['game_play'] + f'_{zone}.mp4'\n\n    labels.to_csv(labels_output_dir + f'train_player_label_{zone}_recall{recall_num}.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:09.690598Z","iopub.execute_input":"2023-01-10T12:48:09.692599Z","iopub.status.idle":"2023-01-10T12:48:09.703458Z","shell.execute_reply.started":"2023-01-10T12:48:09.692551Z","shell.execute_reply":"2023-01-10T12:48:09.701876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for zone in ['Endzone', 'Sideline']:\n    make_player_pair_label_df(labels, zone, labels_output_dir)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:09.705174Z","iopub.execute_input":"2023-01-10T12:48:09.705651Z","iopub.status.idle":"2023-01-10T12:48:10.028819Z","shell.execute_reply.started":"2023-01-10T12:48:09.705615Z","shell.execute_reply":"2023-01-10T12:48:10.026712Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ground","metadata":{}},{"cell_type":"code","source":"labels = read_labels(CFG.comp_dataset_path)\nlabels = labels.query('nfl_player_id_2 == \"G\"').reset_index(drop=True)\n\nlabels['nfl_player_id_1'] = labels['nfl_player_id_1'].astype(int)\n# labels['nfl_player_id_2'] = labels['nfl_player_id_2'].astype(int)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:10.030409Z","iopub.execute_input":"2023-01-10T12:48:10.031024Z","iopub.status.idle":"2023-01-10T12:48:10.587039Z","shell.execute_reply.started":"2023-01-10T12:48:10.030985Z","shell.execute_reply":"2023-01-10T12:48:10.585766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"players = read_players(CFG.comp_dataset_path)\nuse_cols = ['game_play', 'step']\n\nrename_cols = ['nfl_player_id', 'x_position', 'y_position', 'team','speed', 'direction', 'orientation',\n            'acceleration', 'sa', 'position']\nuse_cols += rename_cols\n\nplayers = players[use_cols]\n\nplayers.rename(columns={'nfl_player_id': 'nfl_player_id_1'}, inplace=True)\n\nlabels = pd.merge(labels, players, on=['game_play', 'step', 'nfl_player_id_1'], how='left')\n","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:10.590989Z","iopub.execute_input":"2023-01-10T12:48:10.591397Z","iopub.status.idle":"2023-01-10T12:48:10.645125Z","shell.execute_reply.started":"2023-01-10T12:48:10.591360Z","shell.execute_reply":"2023-01-10T12:48:10.644164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels.to_csv(labels_output_dir + f'train_ground_label_lgb_recall{recall_num}.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:10.646515Z","iopub.execute_input":"2023-01-10T12:48:10.647009Z","iopub.status.idle":"2023-01-10T12:48:10.691119Z","shell.execute_reply.started":"2023-01-10T12:48:10.646970Z","shell.execute_reply":"2023-01-10T12:48:10.687081Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_ground_df(labels, zone, labels_output_dir):\n    helmets = read_helmets(CFG.comp_dataset_path)\n    # helmets = interpolate_helmets(helmets)\n\n    helmets = helmets.query('view == @zone').reset_index(drop=True)\n\n    use_cols = ['game_play','frame']\n    rename_cols = ['nfl_player_id', 'left',\t'width','top','height']\n    use_cols += rename_cols\n    helmets = helmets[use_cols]\n\n    helmets.rename(columns={'nfl_player_id': 'nfl_player_id_1'}, inplace=True)\n    labels = pd.merge(labels, helmets, on=['game_play', 'frame', 'nfl_player_id_1'], how='left')\n\n    print(len(labels))\n    print(labels.isnull().sum())\n\n    labels['video'] = labels['game_play'] + f'_{zone}.mp4'\n\n    labels.to_csv(labels_output_dir + f'train_ground_label_{zone}_recall{recall_num}.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:10.692948Z","iopub.execute_input":"2023-01-10T12:48:10.693308Z","iopub.status.idle":"2023-01-10T12:48:10.712217Z","shell.execute_reply.started":"2023-01-10T12:48:10.693273Z","shell.execute_reply":"2023-01-10T12:48:10.705501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for zone in ['Endzone', 'Sideline']:\n    make_ground_df(labels, zone, labels_output_dir)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:10.714195Z","iopub.execute_input":"2023-01-10T12:48:10.714650Z","iopub.status.idle":"2023-01-10T12:48:10.959985Z","shell.execute_reply.started":"2023-01-10T12:48:10.714613Z","shell.execute_reply":"2023-01-10T12:48:10.958806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# video to image","metadata":{}},{"cell_type":"code","source":"import cv2","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:10.961562Z","iopub.execute_input":"2023-01-10T12:48:10.962302Z","iopub.status.idle":"2023-01-10T12:48:11.111293Z","shell.execute_reply.started":"2023-01-10T12:48:10.962264Z","shell.execute_reply":"2023-01-10T12:48:11.110300Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def video_to_image(zone, resolution='full', mode = 'train'):\n    labels = read_labels(CFG.comp_dataset_path)\n\n    labels['video'] = labels['game_play'] + f'_{zone}.mp4'\n    \n    \n    video_dir_path = CFG.comp_dataset_path + f'{mode}/'\n\n    if resolution == 'full':\n        image_output_dir = VIDEO_OUTPUT_PATH + f'video_images_grayscale/{mode}/'\n    elif resolution == 'half':\n        image_output_dir = VIDEO_OUTPUT_PATH + f'video_images_grayscale_half/{mode}/'\n\n    VIDEO_CODEC = \"MP4V\"\n    HELMET_COLOR = (0, 0, 0)\n\n    img_width = 1280\n    img_height = 720\n\n    if resolution == 'half':\n        img_width = img_width // 2\n        img_height = img_height // 2\n\n    for video_name in tqdm(labels['video'].unique()):\n        video_path = video_dir_path + video_name\n        image_output_path = image_output_dir + video_name.split('.')[0] + '/'\n        os.makedirs(image_output_path, exist_ok=True)\n\n        vidcap = cv2.VideoCapture(video_path)\n\n        \"\"\"\n        fps = vidcap.get(cv2.CAP_PROP_FPS)\n        width = int(vidcap.get(cv2.CAP_PROP_FRAME_WIDTH))\n        height = int(vidcap.get(cv2.CAP_PROP_FRAME_HEIGHT))\n        output_path = \"labeled_\" + video_name\n        tmp_output_path = \"tmp_\" + output_path\n        output_video = cv2.VideoWriter(\n            tmp_output_path, cv2.VideoWriter_fourcc(*VIDEO_CODEC), fps, (width, height)\n        )\n        \"\"\"\n\n        frame = 0\n        while True:\n            it_worked, img = vidcap.read()\n            if not it_worked:\n                break\n\n            # 最初の方のframeは使わない\n            if frame <= 240:\n                frame += 1\n                continue\n\n            img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n\n            img = cv2.resize(img, (img_width, img_height))\n\n            cv2.imwrite(image_output_path + f'frame_{frame}.jpg', img)\n\n            frame += 1\n\n        \"\"\"\n        output_video.release()\n        if os.path.exists(output_path):\n            os.remove(output_path)\n        \n        os.remove(tmp_output_path)\n        \"\"\"\n","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:11.118365Z","iopub.execute_input":"2023-01-10T12:48:11.118669Z","iopub.status.idle":"2023-01-10T12:48:11.129417Z","shell.execute_reply.started":"2023-01-10T12:48:11.118641Z","shell.execute_reply":"2023-01-10T12:48:11.128164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!free","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:11.131050Z","iopub.execute_input":"2023-01-10T12:48:11.131520Z","iopub.status.idle":"2023-01-10T12:48:12.454345Z","shell.execute_reply.started":"2023-01-10T12:48:11.131485Z","shell.execute_reply":"2023-01-10T12:48:12.453113Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for zone in ['Endzone', 'Sideline']:\n    video_to_image(zone, 'half', 'test')","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:12.456428Z","iopub.execute_input":"2023-01-10T12:48:12.456864Z","iopub.status.idle":"2023-01-10T12:48:36.097155Z","shell.execute_reply.started":"2023-01-10T12:48:12.456819Z","shell.execute_reply":"2023-01-10T12:48:36.096103Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!free","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:36.098837Z","iopub.execute_input":"2023-01-10T12:48:36.099526Z","iopub.status.idle":"2023-01-10T12:48:37.042847Z","shell.execute_reply.started":"2023-01-10T12:48:36.099487Z","shell.execute_reply":"2023-01-10T12:48:37.041594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls {VIDEO_OUTPUT_PATH}video_images_grayscale_half/test","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.294516Z","iopub.status.idle":"2023-01-10T12:48:37.296155Z","shell.execute_reply.started":"2023-01-10T12:48:37.295862Z","shell.execute_reply":"2023-01-10T12:48:37.295892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# cnn","metadata":{}},{"cell_type":"code","source":"class CustomModel(nn.Module):\n    def __init__(self, cfg, pretrained=False, target_size=None, model_name=None):\n        super().__init__()\n        self.cfg = cfg\n\n        if model_name is None:\n            model_name = cfg.model_name\n\n        self.model = timm.create_model(\n            model_name, pretrained=pretrained, num_classes=0,\n            in_chans=self.cfg.in_chans)\n\n        self.n_features = self.model.num_features\n\n        self.target_size = self.cfg.target_size if target_size is None else target_size\n\n        # nn.Dropout(0.5),\n        self.fc = nn.Sequential(\n            nn.Linear(self.n_features, self.target_size)\n        )\n\n    def feature(self, image):\n\n        feature = self.model(image)\n        return feature\n\n    def forward(self, image):\n        feature = self.feature(image)\n        output = self.fc(feature)\n        return output\n","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.297773Z","iopub.status.idle":"2023-01-10T12:48:37.298565Z","shell.execute_reply.started":"2023-01-10T12:48:37.298290Z","shell.execute_reply":"2023-01-10T12:48:37.298315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class EnsembleModel:\n    def __init__(self):\n        self.models = []\n\n    def __call__(self, x):\n        # outputs = [F.softmax(model(x) / self.cfg.test.temp, dim=1) for model in self.models]\n        outputs = [torch.sigmoid(model(x)).to('cpu').numpy()\n                   for model in self.models]\n        avg_preds = np.mean(outputs, axis=0)\n        return avg_preds\n\n    def add_model(self, model):\n        self.models.append(model)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.300064Z","iopub.status.idle":"2023-01-10T12:48:37.300861Z","shell.execute_reply.started":"2023-01-10T12:48:37.300590Z","shell.execute_reply":"2023-01-10T12:48:37.300614Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# dataset","metadata":{}},{"cell_type":"code","source":"from tqdm import tqdm\nimport glob\nimport pandas as pd\nimport random\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom torch.utils.data import DataLoader, Dataset\nimport cv2\nimport torch\nimport os\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nfrom albumentations import ImageOnlyTransform\nfrom functools import lru_cache\n\n@lru_cache(128 * 16)\ndef read_cache_image(image_path):\n    return cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)\n\ndef cut_image_from_box(image, box, cut_num, img_width, img_height):\n\n    x_center = int(box.x_center)\n    y_center = int(box.y_center)\n    # contact_id = box.contact_id\n\n    left = max(x_center - cut_num, 0)\n    right = min(left + cut_num * 2, img_width)\n    top = max(y_center - cut_num, 0)\n    bottom = min(top + cut_num * 2, img_height)\n    image = image[top:bottom, left:right]\n\n    return image\n\ndef make_player_pair_mask(box, width=1280, height=720, is_grayscale=True):\n\n    if is_grayscale:\n        mask = np.zeros((height, width, 1), np.uint8)\n    else:\n        mask = np.zeros((height, width, 3), np.uint8)\n\n    cv2.rectangle(\n        mask,\n        (box.left_1, box.top_1),\n        (box.left_1 + box.width_1, box.top_1 + box.height_1),\n        color=(255, 255, 255),\n        thickness=-1\n    )\n\n    cv2.rectangle(\n        mask,\n        (box.left_2, box.top_2),\n        (box.left_2 + box.width_2, box.top_2 + box.height_2),\n        color=(255, 255, 255),\n        thickness=-1\n    )\n\n    return mask\n\ndef make_player_ground_mask(box, width=1280, height=720, is_grayscale=True):\n\n    if is_grayscale:\n        mask = np.zeros((height, width, 1), np.uint8)\n    else:\n        mask = np.zeros((height, width, 3), np.uint8)\n\n    cv2.rectangle(\n        mask,\n        (box.left, box.top),\n        (box.left + box.width, box.top + box.height),\n        color=(255, 255, 255),\n        thickness=-1\n    )\n\n    return mask\n\ndef read_mask(box, img_width, img_height, cut_num, target):\n\n    if target == 'player':\n        mask = make_player_pair_mask(box, img_width, img_height)\n    elif target == 'ground':\n        mask = make_player_ground_mask(box, img_width, img_height)\n\n    mask_cut = cut_image_from_box(mask, box, cut_num,\n                                  img_width, img_height)\n\n    return mask_cut\n\ndef get_use_frames(frame, max_frame, frame_window, frame_stride):\n    # 使うframeを求める\n    frame_min = frame - frame_window * frame_stride\n    frame_max = frame + frame_window * frame_stride\n\n    use_frames = range(frame_min, frame_max + 1, frame_stride)\n    use_frames = [frame if frame <=\n                  max_frame else max_frame for frame in use_frames]\n    return use_frames\n","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.302365Z","iopub.status.idle":"2023-01-10T12:48:37.303163Z","shell.execute_reply.started":"2023-01-10T12:48:37.302904Z","shell.execute_reply":"2023-01-10T12:48:37.302929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustomVideoDataset(Dataset):\n    def __init__(self, df, cfg, labels=None, transform=None, use_frame_aug=False,\n                 image_dir_path=None):\n        self.df = df\n        self.cfg = cfg\n        # self.file_paths = df['file_path'].values\n        # self.labels = df[self.cfg.target_col].values\n        self.labels = labels\n        self.transform = transform\n\n        # test用に追加\n        if image_dir_path is None:\n            self.image_dir_path = self.cfg.train_image_dir_path\n        else:\n            self.image_dir_path = image_dir_path\n\n        # video cacheするときにメモリが足りなくなるから使わない\n        # self.use_frame_aug = use_frame_aug\n\n        # 現在のframe以外のmaskを作る用\n        if self.cfg.frame_window != 0:\n            helmets = read_helmets(self.cfg.comp_dataset_path)\n            bbox_cols = ['left', 'width', 'top', 'height']\n            self.video2helmets = {}\n            for (video, nfl_player_id), df in helmets.groupby(['video', 'nfl_player_id']):\n                video = video.split('.')[0]\n                self.video2helmets[f'{video}_{nfl_player_id}'] = df[[\n                    'frame'] + bbox_cols]\n\n    def __len__(self):\n        return len(self.df)\n\n    def read_image(self, idx):\n        # file_path = self.file_paths[idx]\n        box = self.df.iloc[idx]\n\n        video = box.video\n        frame = box.frame\n        max_frame = box.max_frame\n\n        # video cacheするときにメモリが足りなくなるから使わない\n        \"\"\"\n        if self.use_frame_aug:\n            frame += random.randint(-6, 6)\n            if frame > max_frame:\n                frame = max_frame\n        \"\"\"\n\n        use_frames = get_use_frames(\n            frame, max_frame, self.cfg.frame_window, self.cfg.frame_stride)\n\n        images = []\n        for use_frame in use_frames:\n            image_path = self.image_dir_path + \\\n                f'{video}/frame_{use_frame}{self.cfg.image_file_suffix}'\n\n            # image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)\n            if self.cfg.use_video_cache:\n                image = self.cfg.video_cache[image_path]\n            else:\n                image = read_cache_image(image_path)\n\n            images.append(image)\n\n        image = np.stack(images, axis=2)\n\n        image = cut_image_from_box(image, box, self.cfg.cut_num,\n                                   self.cfg.img_width, self.cfg.img_height)\n\n        return image\n\n    def __getitem__(self, idx):\n        image = self.read_image(idx)\n\n        img_width = self.cfg.img_width\n        img_height = self.cfg.img_height\n        cut_num = self.cfg.cut_num\n        box = self.df.iloc[idx]\n\n        frame = box['frame']\n        max_frame = box['max_frame']\n\n        if self.cfg.use_mask:\n            # if self.cfg.frame_window == 0:  # 2d cnn\n            mask = read_mask(box, img_width, img_height,\n                             cut_num, self.cfg.pred_target)\n\n            image = np.concatenate([image, mask], axis=2)\n\n        if self.transform:\n            image = self.transform(image=image)['image']\n\n\n        if self.labels is None:\n            return image\n\n        if self.cfg.objective_cv == 'multiclass':\n            label = torch.tensor(self.labels[idx]).long()\n        else:\n            label = torch.tensor(self.labels[idx]).float()\n\n        return image, label","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.304671Z","iopub.status.idle":"2023-01-10T12:48:37.305452Z","shell.execute_reply.started":"2023-01-10T12:48:37.305194Z","shell.execute_reply":"2023-01-10T12:48:37.305217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_val_aug(cfg):\n\n    return [\n        A.Resize(cfg.size, cfg.size),\n        A.Normalize(\n            mean=cfg.aug_mean,\n            std=cfg.aug_std,\n        ),\n        ToTensorV2(),\n    ]\n\ndef get_transforms(cfg):\n    aug = A.Compose(get_val_aug(cfg))\n\n    # print(aug)\n    return aug","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.306903Z","iopub.status.idle":"2023-01-10T12:48:37.307689Z","shell.execute_reply.started":"2023-01-10T12:48:37.307418Z","shell.execute_reply":"2023-01-10T12:48:37.307441Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_model_ensemble(model_paths, model_names, cfg):\n    base_model = EnsembleModel()\n    \n    \"\"\"\n    model_base_dir = f'/kaggle/input/{CFG.exp_name}/nfl3-models/'\n    model_dirs = [model_base_dir] * 5\n    model_names = [CFG.model_name] * 5\n    folds = [0, 1, 2, 3, 4]\n    \"\"\"\n\n    for model_path, model_name in zip(model_paths, model_names):\n        # CFG.model_name = model_name\n        \n        model = CustomModel(cfg, pretrained=False, model_name=model_name)\n        model.to(device)\n        \"\"\"\n        model_path = model_base_dir + \\\n            f'{model_name}_fold{fold}_best_{zone}{model_suffix}.pth'\n        print('load', model_path)\n        \"\"\"\n        state = torch.load(model_path)['model']\n        model.load_state_dict(state)\n        model.eval()\n\n        base_model.add_model(model)\n\n    return base_model","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.309139Z","iopub.status.idle":"2023-01-10T12:48:37.309937Z","shell.execute_reply.started":"2023-01-10T12:48:37.309662Z","shell.execute_reply":"2023-01-10T12:48:37.309687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def test_fn(test_loader, model, device):\n    preds = []\n\n    for step, (images) in tqdm(enumerate(test_loader), total=len(test_loader)):\n        images = images.to(device)\n\n        with torch.no_grad():\n            y_preds = model(images)\n            # print(y_preds.shape)\n\n        preds.append(y_preds)\n\n    predictions = np.concatenate(preds)\n\n    return predictions","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.311340Z","iopub.status.idle":"2023-01-10T12:48:37.312191Z","shell.execute_reply.started":"2023-01-10T12:48:37.311869Z","shell.execute_reply":"2023-01-10T12:48:37.311893Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 後でensemble用にCFGを修正\ndef cnn_inference(test_df, model_paths, model_names, cfg, image_dir_path):\n\n    # get filepath\n    # test_df['video'] = test_df['game_play'] + '_' + CFG.zone\n    test_df['video'] = test_df['video'].str.split('.').str[0]\n    \n    model = get_model_ensemble(model_paths, model_names, cfg)\n\n    # dataloader\n    test_dataset = CustomVideoDataset(\n        test_df, cfg, transform=get_transforms(cfg=cfg), image_dir_path=image_dir_path)\n    test_loader = DataLoader(test_dataset, batch_size=cfg.batch_size,\n                             shuffle=False, num_workers=cfg.num_workers, pin_memory=True)\n\n    preds = test_fn(test_loader, model, device)\n    \n    return preds","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.313656Z","iopub.status.idle":"2023-01-10T12:48:37.314450Z","shell.execute_reply.started":"2023-01-10T12:48:37.314195Z","shell.execute_reply":"2023-01-10T12:48:37.314220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def helmets_pair_preprocess(train_labels: pd.DataFrame, is_half: bool = False):\n    use_idxs = train_labels['left_1'].notnull(\n    ) & train_labels['left_2'].notnull()\n    train_labels = train_labels[use_idxs].reset_index(drop=True)\n\n    cols = ['left_1', 'width_1', 'top_1', 'height_1',\n            'left_2', 'width_2', 'top_2', 'height_2']\n\n    # 画像サイズを1/2にしている場合\n    if is_half:\n        train_labels[cols] /= 2\n\n    train_labels[cols] = train_labels[cols].astype(int)\n\n    train_labels['x_1'] = train_labels['left_1'] + train_labels['width_1'] / 2\n    train_labels['y_1'] = train_labels['top_1'] + train_labels['height_1'] / 2\n    train_labels['x_2'] = train_labels['left_2'] + train_labels['width_2'] / 2\n    train_labels['y_2'] = train_labels['top_2'] + train_labels['height_2'] / 2\n\n    train_labels['x_center'] = (train_labels['x_1'] + train_labels['x_2']) / 2\n    train_labels['y_center'] = (train_labels['y_1'] + train_labels['y_2']) / 2\n\n    cols = ['x_1', 'y_1', 'x_2', 'y_2', 'x_center', 'y_center']\n    train_labels[cols] = train_labels[cols].astype(int)\n    return train_labels\n\ndef helmets_ground_preprocess(train_labels: pd.DataFrame, is_half: bool = False):\n    use_idxs = train_labels['left'].notnull()\n    train_labels = train_labels[use_idxs].reset_index(drop=True)\n\n    cols = ['left', 'width', 'top', 'height']\n\n    # 画像サイズを1/2にしている場合\n    if is_half:\n        train_labels[cols] /= 2\n\n    train_labels[cols] = train_labels[cols].astype(int)\n\n    train_labels['x_center'] = train_labels['left'] + train_labels['width'] / 2\n    train_labels['y_center'] = train_labels['top'] + train_labels['height'] / 2\n\n    cols = ['x_center', 'y_center']\n    train_labels[cols] = train_labels[cols].astype(int)\n    return train_labels\n","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.315890Z","iopub.status.idle":"2023-01-10T12:48:37.316651Z","shell.execute_reply.started":"2023-01-10T12:48:37.316395Z","shell.execute_reply":"2023-01-10T12:48:37.316419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# player_id2がplayerのを予測","metadata":{}},{"cell_type":"code","source":"pred_target = 'player'\n\nfor zone in ['Endzone', 'Sideline']:\n    train_labels = pd.read_csv(labels_output_dir + f'train_{pred_target}_label_{zone}_recall{recall_num}.csv')\n\n    # ground用も追加\n    if pred_target == 'player':\n        train_labels = helmets_pair_preprocess(train_labels, is_half=True)\n    elif pred_target == 'ground':\n        train_labels = helmets_ground_preprocess(train_labels, is_half=True)\n    \n    train_labels['max_frame'] = train_labels.groupby(['video'])['frame'].transform('max')\n\n    model_base_dir = f'/kaggle/input/{EXP_NAME_PLAYER}/nfl3-models/'\n    model_suffix = f'_{pred_target}'\n    # model_name = 'resnet18d'\n    model_name = CFG_player_pair.model_name\n    \n    # exp063 一旦zoneをallに変更\n    # model_paths = [model_base_dir + f'{model_name}_fold{fold}_best_{zone}{model_suffix}.pth' for fold in range(5)]\n    model_paths = [model_base_dir + f'{model_name}_fold{fold}_best_all{model_suffix}.pth' for fold in range(5)]\n    \n    model_names = [model_name] * 5\n    \n    image_dir_path = VIDEO_OUTPUT_PATH + f'video_images_grayscale_half/test/'\n    \n    preds_cnn = cnn_inference(train_labels, model_paths, model_names, CFG_player_pair, image_dir_path)\n    train_labels['pred_0'] = preds_cnn\n    \n    plt.hist(train_labels['pred_0'])\n    plt.show()\n    train_labels.to_csv(CFG.submission_dir + f'oof_cv_{zone}{model_suffix}.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.318102Z","iopub.status.idle":"2023-01-10T12:48:37.318863Z","shell.execute_reply.started":"2023-01-10T12:48:37.318600Z","shell.execute_reply":"2023-01-10T12:48:37.318623Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# player_id2がGのを予測","metadata":{}},{"cell_type":"code","source":"pred_target = 'ground'\n\nfor zone in ['Endzone', 'Sideline']:\n    train_labels = pd.read_csv(labels_output_dir + f'train_{pred_target}_label_{zone}_recall{recall_num}.csv')\n\n    # ground用も追加\n    if pred_target == 'player':\n        train_labels = helmets_pair_preprocess(train_labels, is_half=True)\n    elif pred_target == 'ground':\n        train_labels = helmets_ground_preprocess(train_labels, is_half=True)\n    \n    train_labels['max_frame'] = train_labels.groupby(['video'])['frame'].transform('max')\n\n    model_base_dir = f'/kaggle/input/{EXP_NAME_GROUND}/nfl3-models/'\n    model_suffix = f'_{pred_target}'\n    # model_name = 'resnet18d'\n    model_name = CFG_ground.model_name\n    model_paths = [model_base_dir + f'{model_name}_fold{fold}_best_{zone}{model_suffix}.pth' for fold in range(5)]\n    model_names = [model_name] * 5\n    \n    image_dir_path = VIDEO_OUTPUT_PATH + f'video_images_grayscale_half/test/'\n    \n    preds_cnn = cnn_inference(train_labels, model_paths, model_names, CFG_ground, image_dir_path)\n    train_labels['pred_0'] = preds_cnn\n    \n    plt.hist(train_labels['pred_0'])\n    plt.show()\n    train_labels.to_csv(CFG.submission_dir + f'oof_cv_{zone}{model_suffix}.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.320310Z","iopub.status.idle":"2023-01-10T12:48:37.321111Z","shell.execute_reply.started":"2023-01-10T12:48:37.320842Z","shell.execute_reply":"2023-01-10T12:48:37.320867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# lgb","metadata":{}},{"cell_type":"code","source":"train_labels = pd.read_csv(labels_output_dir + f'train_player_label_lgb_recall{recall_num}.csv')","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.322550Z","iopub.status.idle":"2023-01-10T12:48:37.323343Z","shell.execute_reply.started":"2023-01-10T12:48:37.323084Z","shell.execute_reply":"2023-01-10T12:48:37.323107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# blocks","metadata":{}},{"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\nimport pandas as pd\nfrom typing import List\n\nclass AbstractBaseBlock:\n    \"\"\"\n    https://www.guruguru.science/competitions/16/discussions/95b7f8ec-a741-444f-933a-94c33b9e66be/\n    \"\"\"\n\n    def __init__(self) -> None:\n        pass\n\n    def fit(self, input_df: pd.DataFrame, y=None) -> pd.DataFrame:\n        # return self.transform(input_df)\n        raise NotImplementedError()\n\n    def transform(self, input_df: pd.DataFrame) -> pd.DataFrame:\n        raise NotImplementedError()\n\n\ndef run_block(input_df: pd.DataFrame, blocks: List[AbstractBaseBlock], is_fit):\n    output_df = pd.DataFrame()\n    for block in blocks:\n        name = block.__class__.__name__\n\n        if is_fit:\n            # print(f'fit: {name}')\n            _df = block.fit(input_df)\n        else:\n            # print(f'transform: {name}')\n            _df = block.transform(input_df)\n\n        # print(f'concat: {name}')\n        output_df = pd.concat([output_df, _df], axis=1)\n    return output_df\n\nclass NumericBlock(AbstractBaseBlock):\n    def __init__(self, col: str) -> None:\n        super().__init__()\n        self.col = col\n\n    def fit(self, input_df):\n        return self.transform(input_df)\n\n    def transform(self, input_df):\n        output_df = pd.DataFrame()\n        output_df[self.col] = input_df[self.col].copy()\n        return output_df\n\nclass AggBlock(AbstractBaseBlock):\n    def __init__(self, grp_col: str, target_cols: List[str], agg_cols: List[str]) -> None:\n        super().__init__()\n        self.grp_col = grp_col\n        self.target_cols = target_cols\n        self.agg_cols = agg_cols\n\n    def fit(self, input_df):\n        self.grp_df = input_df.groupby(self.grp_col)[\n            self.target_cols].agg(self.agg_cols)\n        self.grp_df.columns = [f'{self.grp_col}_' +\n                               '_'.join(c) for c in self.grp_df.columns]\n        # self.grp_df.add_prefix(f'{self.grp_col}_')\n        return self.transform(input_df)\n\n    def transform(self, input_df):\n        output_df = pd.DataFrame()\n        output_df[self.grp_col] = input_df[self.grp_col]\n        output_df = output_df.merge(self.grp_df, on=self.grp_col, how='left')\n        output_df.drop(self.grp_col, axis=1, inplace=True)\n        return output_df\n","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.324828Z","iopub.status.idle":"2023-01-10T12:48:37.325619Z","shell.execute_reply.started":"2023-01-10T12:48:37.325350Z","shell.execute_reply":"2023-01-10T12:48:37.325374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## lgb player pair","metadata":{}},{"cell_type":"code","source":"def train_test_preprocess(train, label_dir):\n\n    num_cols = ['distance', 'same_team',\n                'step']\n    cat_cols = []\n    # 過去or未来の値\n    # lag_cols = ['pred_0_cv_Endzone', 'pred_0_cv_Sideline', 'distance']\n    lag_cols = ['distance']\n    # 現在と過去の差\n    # diff_cols = ['pred_0_cv_Endzone', 'pred_0_cv_Sideline', 'distance']\n    diff_cols = ['distance']\n\n    train['game_play_player_pair'] = train['game_play'].astype(str) + \\\n        '_' + train['nfl_player_id_1'].astype(str) + \\\n        '_' + train['nfl_player_id_2'].astype(str)\n    agg_target_cols = ['distance']\n    agg_keys = ['game_play_player_pair']\n\n    use_cols = [\n        'speed', 'direction', 'orientation', 'acceleration', 'sa'\n    ]\n    for col in use_cols:\n        train[col + '_max'] = np.maximum(\n            train[col + '_1'], train[col + '_2'])\n        train[col + '_min'] = np.minimum(\n            train[col + '_1'], train[col + '_2'])\n        train[col +\n              '_abs_diff'] = abs(train[col + '_max'] - train[col + '_min'])\n        \n        num_cols += [col + '_max', col + '_min', col + '_abs_diff']\n        \n        # lag_cols += [col + '_max', col + '_min', col + '_abs_diff']\n        # diff_cols += [col + '_max', col + '_min', col + '_abs_diff']\n    \n    \n    # exp_names = ['nfl3_exp026', 'nfl3_exp047']\n    # exp_names = ['nfl3_exp050']\n    for exp_name in cv_exp_names:\n        # submission_dir = f'{CFG.comp_dir_path}outputs/{CFG.comp_name}/{exp_name}/submissions/'\n        # kernel用\n        submission_dir = CFG.submission_dir\n        for zone in ['Endzone', 'Sideline']:\n            path = submission_dir + f'oof_cv_{zone}_player.csv'\n\n            if not os.path.exists(path):\n                continue\n\n            print(path)\n            oof_cv_df = pd.read_csv(path)\n            oof_cv_df.rename(\n                columns={'pred_0': f'pred_0_cv_{zone}_{exp_name}'}, inplace=True)\n            train = pd.merge(train, oof_cv_df[['contact_id', f'pred_0_cv_{zone}_{exp_name}']], on=[\n                'contact_id'], how='left')\n            num_cols += [f'pred_0_cv_{zone}_{exp_name}']\n            lag_cols += [f'pred_0_cv_{zone}_{exp_name}']\n            diff_cols += [f'pred_0_cv_{zone}_{exp_name}']\n\n    # 'position_1', 'position_2'\n    # train['position_pair'] = train[['position_1', 'position_2']].apply(\n    #     make_position_pair, axis=1)\n\n    for zone in ['Endzone', 'Sideline']:\n\n        helmets = pd.read_csv(\n            label_dir + f'train_player_label_{zone}_recall{CFG.recall_num}.csv')\n        helmets['helmet_size_1'] = np.sqrt(\n            helmets['width_1'] * helmets['height_1'])\n        helmets['helmet_size_2'] = np.sqrt(\n            helmets['width_2'] * helmets['height_2'])\n\n        # iou\n        \"\"\"\n        bbox_cols1 = ['left_1', 'width_1', 'top_1', 'height_1']\n        bbox_cols2 = ['left_2', 'width_2', 'top_2', 'height_2']\n        helmets['iou'] = calc_iou(\n            helmets[bbox_cols1].values, helmets[bbox_cols2].values)\n        \"\"\"\n\n        merge_cols = ['contact_id']\n        rename_cols = ['left_1', 'width_1', 'top_1', 'height_1',\n                       'left_2', 'width_2', 'top_2', 'height_2',\n                       'helmet_size_1', 'helmet_size_2', ]\n\n        helmets = helmets[merge_cols + rename_cols]\n        columns = dict((col, f'{col}_{zone}') for col in rename_cols)\n        train = pd.merge(train, helmets.rename(\n            columns=columns), on=merge_cols, how='left')\n\n        for col in ['left', 'width', 'top', 'height', 'helmet_size']:\n            train[f'{col}_max_{zone}'] = np.maximum(\n                train[f'{col}_1_{zone}'], train[f'{col}_2_{zone}'])\n            train[f'{col}_min_{zone}'] = np.minimum(\n                train[f'{col}_1_{zone}'], train[f'{col}_2_{zone}'])\n            train[f'{col}_abs_diff_{zone}'] = abs(\n                train[f'{col}_max_{zone}'] - train[f'{col}_min_{zone}'])\n\n            num_cols += [f'{col}_max_{zone}',\n                         f'{col}_min_{zone}', f'{col}_abs_diff_{zone}']\n            # num_cols += [f'{col}_abs_diff_{zone}']\n            lag_cols += [f'{col}_abs_diff_{zone}']\n\n    merge_keys = ['game_play', 'step', 'nfl_player_id_1',\n                  'nfl_player_id_2']\n    diff_num = 5\n    time_feat_cols_all = sorted(set(lag_cols + diff_cols))\n    for step_diff in range(-diff_num, diff_num + 1):\n        if step_diff == 0:\n            continue\n\n        _df = train[merge_keys + time_feat_cols_all].copy()\n        _df['step'] += step_diff\n        rename_dict = dict((col, col + f'_{step_diff}')\n                           for col in time_feat_cols_all)\n        _df.rename(columns=rename_dict, inplace=True)\n        # print(_df)\n        train = pd.merge(train, _df, on=merge_keys, how='left')\n\n        # num_cols += rename_dict.values()\n        num_cols += [col + f'_{step_diff}' for col in lag_cols]\n\n        for col in diff_cols:\n            train[col + f'_{step_diff}_absdiff'] = abs(\n                train[col] - train[col + f'_{step_diff}'])\n            num_cols += [col + f'_{step_diff}_absdiff']\n\n    # ======= fold =======\n\n    # print(train.groupby(['fold', CFG.target_col]).size())\n\n    # ======= train, test 共通の処理 =======\n\n    blocks = [\n        *[NumericBlock(col) for col in num_cols],\n        # *[LabelEncodingBlock(col) for col in cat_cols],\n        # *[CountEncodingBlock(col) for col in cat_cols],\n        # *[AggBlock(col, target_cols=agg_target_cols,\n        #            agg_cols=['mean', 'min', 'max', 'std']) for col in agg_keys],\n    ]\n\n\n    train_feat = run_block(train, blocks, is_fit=False)\n\n    print('use_col len', len(train_feat.columns))\n\n    # y = train[CFG.target_col]\n    # folds = train['fold']\n\n    # return train_feat, y, folds\n    \n    return train_feat","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.327183Z","iopub.status.idle":"2023-01-10T12:48:37.327970Z","shell.execute_reply.started":"2023-01-10T12:48:37.327706Z","shell.execute_reply":"2023-01-10T12:48:37.327744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train = train_test_preprocess(train_labels, label_dir=labels_output_dir)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.329510Z","iopub.status.idle":"2023-01-10T12:48:37.330032Z","shell.execute_reply.started":"2023-01-10T12:48:37.329795Z","shell.execute_reply":"2023-01-10T12:48:37.329818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import glob\nimport lightgbm as lgb\n\ndef lgb_inference(test_df, is_ground=False):\n    \n    filepaths = []\n    if is_ground:\n        model_path = f'/kaggle/input/{EXP_NAME_GROUND_gbdt}/nfl3-models/'\n        filepaths = [model_path + f'lgb_fold_{fold}_lgb_gkf_g.txt' for fold in range(5)]\n    else:\n        model_path = f'/kaggle/input/{EXP_NAME_PLAYER_gbdt}/nfl3-models/'\n        filepaths = [model_path + f'lgb_fold_{fold}_lgb_gkf.txt' for fold in range(5)]\n    print(filepaths)\n\n    lgb_models = [lgb.Booster(model_file=filepath) for filepath in filepaths]\n\n    lgb_result = np.zeros(test_df.shape[0])\n    for model in lgb_models:\n        # Load LightGBM Model\n        lgb_result += model.predict(test_df)\n\n    lgb_result /= len(lgb_models)\n\n    # lgb_result = (lgb_result > 0.5).astype(int)\n    return lgb_result\n    ","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.331745Z","iopub.status.idle":"2023-01-10T12:48:37.332540Z","shell.execute_reply.started":"2023-01-10T12:48:37.332285Z","shell.execute_reply":"2023-01-10T12:48:37.332310Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_labels['contact'] = lgb_inference(X_train, is_ground=False)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.333958Z","iopub.status.idle":"2023-01-10T12:48:37.334725Z","shell.execute_reply.started":"2023-01-10T12:48:37.334470Z","shell.execute_reply":"2023-01-10T12:48:37.334493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.hist(train_labels['contact'])","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.336136Z","iopub.status.idle":"2023-01-10T12:48:37.336933Z","shell.execute_reply.started":"2023-01-10T12:48:37.336662Z","shell.execute_reply":"2023-01-10T12:48:37.336686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_labels.to_csv(CFG.submission_dir + 'oof_gbdt.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.338322Z","iopub.status.idle":"2023-01-10T12:48:37.339120Z","shell.execute_reply.started":"2023-01-10T12:48:37.338852Z","shell.execute_reply":"2023-01-10T12:48:37.338876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_labels = pd.read_csv(labels_output_dir + f'train_ground_label_lgb_recall{recall_num}.csv')\n","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.340500Z","iopub.status.idle":"2023-01-10T12:48:37.341288Z","shell.execute_reply.started":"2023-01-10T12:48:37.341021Z","shell.execute_reply":"2023-01-10T12:48:37.341045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## lgb ground","metadata":{}},{"cell_type":"code","source":"def train_test_preprocess(train, label_dir):\n\n    num_cols = [\n        'speed', 'direction', 'orientation', 'acceleration', 'sa',\n        'step',\n    ]\n\n    # diff_cols = ['pred_0_cv_Endzone', 'pred_0_cv_Sideline', 'distance']\n    lag_cols = [\n        'speed', 'direction', 'orientation', 'acceleration', 'sa'\n    ]\n    diff_cols = [\n        'speed', 'direction', 'orientation', 'acceleration', 'sa'\n    ]\n\n    # cnn\n    # exp_names = ['nfl3_exp050']\n    # exp_names = ['nfl3_exp026']\n    for exp_name in cv_g_exp_names:\n        # submission_dir = f'{CFG.comp_dir_path}outputs/{CFG.comp_name}/{exp_name}/submissions/'\n        # kernel用\n        submission_dir = CFG.submission_dir\n        for zone in ['Endzone', 'Sideline']:\n            path = submission_dir + f'oof_cv_{zone}_ground.csv'\n\n            if not os.path.exists(path):\n                continue\n\n            print(path)\n            oof_cv_df = pd.read_csv(path)\n            oof_cv_df.rename(\n                columns={'pred_0': f'pred_0_cv_{zone}_{exp_name}'}, inplace=True)\n            train = pd.merge(train, oof_cv_df[['contact_id', f'pred_0_cv_{zone}_{exp_name}']], on=[\n                'contact_id'], how='left')\n            num_cols += [f'pred_0_cv_{zone}_{exp_name}']\n            lag_cols += [f'pred_0_cv_{zone}_{exp_name}']\n            diff_cols += [f'pred_0_cv_{zone}_{exp_name}']\n\n    # 'position_1', 'position_2'\n    # train['position_pair'] = train[['position_1', 'position_2']].apply(\n    #     make_position_pair, axis=1)\n\n    for zone in ['Endzone', 'Sideline']:\n\n        helmets = pd.read_csv(\n            label_dir + f'train_ground_label_{zone}_recall{CFG.recall_num}.csv')\n\n        # helmets['x_center'] = helmets['left'] + helmets['width'] / 2\n        # helmets['y_center'] = helmets['top'] + helmets['height'] / 2\n        helmets['helmet_size'] = np.sqrt(\n            helmets['width'] * helmets['height'])\n\n        merge_cols = ['game_play', 'step', 'nfl_player_id_1']\n        use_cols = ['left', 'width', 'top', 'height']\n        columns = dict((col, f'{col}_{zone}') for col in use_cols)\n\n        helmets = helmets[merge_cols + use_cols]\n        train = pd.merge(train, helmets.rename(\n            columns=columns), on=merge_cols, how='left')\n\n        \"\"\"\n        train[f'helmet_{zone}_isnull'] = train[f'left_{zone}'].isnull().astype(\n            int)\n        num_cols += [f'helmet_{zone}_isnull']\n        lag_cols += [f'helmet_{zone}_isnull']\n        \"\"\"\n\n        num_cols += [f'{col}_{zone}' for col in use_cols]\n        lag_cols += [f'{col}_{zone}' for col in use_cols]\n        diff_cols += [f'{col}_{zone}' for col in use_cols]\n\n    merge_keys = ['game_play', 'step', 'nfl_player_id_1']\n    diff_num = 10\n    time_feat_cols_all = sorted(set(lag_cols + diff_cols))\n    for step_diff in range(-diff_num, diff_num + 1):\n        if step_diff == 0:\n            continue\n\n        _df = train[merge_keys + time_feat_cols_all].copy()\n        _df['step'] += step_diff\n        # _df['contact_id'] = _df['game_play'] + '_' + _df['step'].astype(\n        #     str) + '_' + _df['nfl_player_id_1'] + '_' + _df['nfl_player_id_2']\n        rename_dict = dict((col, col + f'_{step_diff}')\n                           for col in time_feat_cols_all)\n        _df.rename(columns=rename_dict, inplace=True)\n        # print(_df)\n        train = pd.merge(train, _df, on=merge_keys, how='left')\n\n        # num_cols += rename_dict.values()\n        num_cols += [col + f'_{step_diff}' for col in lag_cols]\n\n        for col in diff_cols:\n            train[col + f'_{step_diff}_absdiff'] = abs(\n                train[col] - train[col + f'_{step_diff}'])\n            num_cols += [col + f'_{step_diff}_absdiff']\n\n    # cat_cols = []\n\n\n    # ======= fold =======\n\n    # print(train.groupby(['fold', CFG.target_col]).size())\n\n    # ======= train, test 共通の処理 =======\n\n    blocks = [\n        *[NumericBlock(col) for col in num_cols],\n        # *[LabelEncodingBlock(col) for col in cat_cols],\n        # *[CountEncodingBlock(col) for col in cat_cols],\n        # *[AggBlock(col, target_cols=[\"pred_0@bert\"],\n        #            agg_cols=['mean', 'min', 'max', 'std']) for col in []],  # ['principal_maker']\n    ]\n\n    train_feat = run_block(train, blocks, is_fit=False)\n\n    print('use_col len', len(train_feat.columns))\n\n    # y = train[CFG.target_col]\n    # folds = train['fold']\n\n    # return train_feat, y, folds\n    \n    return train_feat","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.342825Z","iopub.status.idle":"2023-01-10T12:48:37.343619Z","shell.execute_reply.started":"2023-01-10T12:48:37.343363Z","shell.execute_reply":"2023-01-10T12:48:37.343387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train = train_test_preprocess(train_labels,label_dir=labels_output_dir)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.345030Z","iopub.status.idle":"2023-01-10T12:48:37.345829Z","shell.execute_reply.started":"2023-01-10T12:48:37.345556Z","shell.execute_reply":"2023-01-10T12:48:37.345580Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_labels['contact'] = lgb_inference(X_train, is_ground=True)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.347232Z","iopub.status.idle":"2023-01-10T12:48:37.348001Z","shell.execute_reply.started":"2023-01-10T12:48:37.347749Z","shell.execute_reply":"2023-01-10T12:48:37.347774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.hist(train_labels['contact'])","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.349400Z","iopub.status.idle":"2023-01-10T12:48:37.350209Z","shell.execute_reply.started":"2023-01-10T12:48:37.349940Z","shell.execute_reply":"2023-01-10T12:48:37.349964Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_labels.to_csv(CFG.submission_dir + 'oof_gbdt_g.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.351602Z","iopub.status.idle":"2023-01-10T12:48:37.352377Z","shell.execute_reply.started":"2023-01-10T12:48:37.352123Z","shell.execute_reply":"2023-01-10T12:48:37.352147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## player_pairとgroundをまとめて、submission.csvにする","metadata":{}},{"cell_type":"code","source":"if IS_DEBUG:\n    sub = pd.read_csv(CFG.comp_dataset_path + 'train_labels.csv')\nelse:\n    sub = pd.read_csv(CFG.comp_dataset_path + 'sample_submission.csv')\n\nsub = sub[['contact_id']]","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.353791Z","iopub.status.idle":"2023-01-10T12:48:37.354559Z","shell.execute_reply.started":"2023-01-10T12:48:37.354308Z","shell.execute_reply":"2023-01-10T12:48:37.354331Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.355969Z","iopub.status.idle":"2023-01-10T12:48:37.356763Z","shell.execute_reply.started":"2023-01-10T12:48:37.356492Z","shell.execute_reply":"2023-01-10T12:48:37.356515Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"oof = pd.read_csv(CFG.submission_dir + 'oof_gbdt.csv')\noof_g = pd.read_csv(CFG.submission_dir + 'oof_gbdt_g.csv')","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.358147Z","iopub.status.idle":"2023-01-10T12:48:37.358923Z","shell.execute_reply.started":"2023-01-10T12:48:37.358652Z","shell.execute_reply":"2023-01-10T12:48:37.358675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"oof_g['contact'] = (oof_g['contact'] >= best_th_g).astype(int)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.360343Z","iopub.status.idle":"2023-01-10T12:48:37.361143Z","shell.execute_reply.started":"2023-01-10T12:48:37.360884Z","shell.execute_reply":"2023-01-10T12:48:37.360909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_labels = pd.concat([oof, oof_g]).reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.362807Z","iopub.status.idle":"2023-01-10T12:48:37.363590Z","shell.execute_reply.started":"2023-01-10T12:48:37.363329Z","shell.execute_reply":"2023-01-10T12:48:37.363354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.merge(sub, train_labels[['contact_id', 'contact']], how='left', on=['contact_id'])","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.365004Z","iopub.status.idle":"2023-01-10T12:48:37.365805Z","shell.execute_reply.started":"2023-01-10T12:48:37.365527Z","shell.execute_reply":"2023-01-10T12:48:37.365551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub['contact'] = sub['contact'].fillna(0)\nsub['contact'] = (sub['contact'] >= best_th).astype(int)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.367231Z","iopub.status.idle":"2023-01-10T12:48:37.368014Z","shell.execute_reply.started":"2023-01-10T12:48:37.367763Z","shell.execute_reply":"2023-01-10T12:48:37.367787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.369422Z","iopub.status.idle":"2023-01-10T12:48:37.370228Z","shell.execute_reply.started":"2023-01-10T12:48:37.369955Z","shell.execute_reply":"2023-01-10T12:48:37.369979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.371618Z","iopub.status.idle":"2023-01-10T12:48:37.372418Z","shell.execute_reply.started":"2023-01-10T12:48:37.372160Z","shell.execute_reply":"2023-01-10T12:48:37.372184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"shutil.rmtree('train_player_labels')\nshutil.rmtree(CFG.submission_dir)","metadata":{"execution":{"iopub.status.busy":"2023-01-10T12:48:37.373847Z","iopub.status.idle":"2023-01-10T12:48:37.374640Z","shell.execute_reply.started":"2023-01-10T12:48:37.374386Z","shell.execute_reply":"2023-01-10T12:48:37.374410Z"},"trusted":true},"execution_count":null,"outputs":[]}]}