{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"vscode":{"interpreter":{"hash":"f7241b2af102f7e024509099765066b36197b195077f7bfac6e5bc041ba17c8c"}},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":70203,"databundleVersionId":8068726,"sourceType":"competition"},{"sourceId":8108072,"sourceType":"datasetVersion","datasetId":4789213},{"sourceId":8460492,"sourceType":"datasetVersion","datasetId":4988031},{"sourceId":8499494,"sourceType":"datasetVersion","datasetId":4783443},{"sourceId":8501307,"sourceType":"datasetVersion","datasetId":5073622},{"sourceId":8573293,"sourceType":"datasetVersion","datasetId":5126502},{"sourceId":8625476,"sourceType":"datasetVersion","datasetId":5163904},{"sourceId":8648409,"sourceType":"datasetVersion","datasetId":5180170},{"sourceId":8650354,"sourceType":"datasetVersion","datasetId":4784404},{"sourceId":172595154,"sourceType":"kernelVersion"},{"sourceId":176719083,"sourceType":"kernelVersion"},{"sourceId":182269965,"sourceType":"kernelVersion"},{"sourceId":182511991,"sourceType":"kernelVersion"},{"sourceId":182514035,"sourceType":"kernelVersion"}],"dockerImageVersionId":30684,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"### Imports","metadata":{}},{"cell_type":"code","source":"import os\nimport gc\nimport sys\nimport glob\nimport json\nimport torch\nimport joblib\nimport shutil\nimport librosa\nimport warnings\nimport numpy as np\nimport pandas as pd\nimport torch.nn.functional as F\nimport matplotlib.pyplot as plt\n\nfrom pathlib import Path\nfrom tqdm.notebook import tqdm\nfrom scipy.special import expit\nfrom scipy.stats import rankdata\nfrom types import SimpleNamespace\n\nwarnings.simplefilter(action=\"ignore\", category=UserWarning)\ntorch.set_num_threads(os.cpu_count())","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-06-10T06:41:56.157654Z","iopub.execute_input":"2024-06-10T06:41:56.15802Z","iopub.status.idle":"2024-06-10T06:42:02.086672Z","shell.execute_reply.started":"2024-06-10T06:41:56.157983Z","shell.execute_reply":"2024-06-10T06:42:02.085681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sys.path.append('/kaggle/input/birdclef-2024-code/src')\n\nfrom util.logger import Config\nfrom util.metrics import macro_auc\nfrom util.torch import load_model_weights\n\nfrom data.preparation import prepare_data, prepare_folds\nfrom params import CLASSES\nfrom model_zoo.models import define_model\n\nfrom inference.predict import load_sample, infer_onnx, infer_sample","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-06-10T06:44:51.569974Z","iopub.execute_input":"2024-06-10T06:44:51.570653Z","iopub.status.idle":"2024-06-10T06:44:56.904078Z","shell.execute_reply.started":"2024-06-10T06:44:51.570616Z","shell.execute_reply":"2024-06-10T06:44:56.902618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -qqq /kaggle/input/onnxruntime/humanfriendly-10.0-py2.py3-none-any.whl --no-index --find-links /kaggle/input/onnxruntime\n!pip install -qqq /kaggle/input/onnxruntime/coloredlogs-15.0.1-py2.py3-none-any.whl --no-index --find-links /kaggle/input/onnxruntime\n!pip install -qqq /kaggle/input/onnxruntime/onnxruntime-1.17.3-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl --no-index --find-links /kaggle/input/onnxruntime\n# !python -m pip install -qqq --no-index --find-links=/kaggle/input/openvino -r /kaggle/input/openvino/requirements.txt\n\nimport onnx\nimport onnxruntime as ort","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-06-10T06:44:56.906422Z","iopub.execute_input":"2024-06-10T06:44:56.906797Z","iopub.status.idle":"2024-06-10T06:45:42.628222Z","shell.execute_reply.started":"2024-06-10T06:44:56.906765Z","shell.execute_reply":"2024-06-10T06:45:42.626742Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import timm\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport matplotlib.pyplot as plt\nimport torchaudio.transforms as T\n\n\nclass BirdModel(nn.Module):\n    def __init__(self, cfg, pretrained: bool = True):\n        super(BirdModel, self).__init__()\n        self.cfg = cfg\n        self.mel = T.MelSpectrogram(\n            sample_rate=cfg.sr, n_fft=cfg.n_fft, win_length=cfg.win_length, \n            hop_length= cfg.hop_length, f_min=cfg.fmin, f_max=cfg.fmax, \n            n_mels=cfg.n_mels, mel_scale='htk', power=2.0)\n        self.A2DB = T.AmplitudeToDB(stype=\"power\")\n        self.backbone = timm.create_model(\n            cfg.backbone,\n            pretrained=pretrained,\n            drop_rate = 0.1,\n            #drop_path_rate = 0.2,\n            num_classes=cfg.num_labels, \n            #global_pool=''\n        )\n        #if cfg.gem_pooling == \"gem\":\n        #    self.backbone.head.global_pool = GeM(p_trainable=args.p_trainable)\n        \n        self.logits = None\n         \n    def forward(self, x):\n        x = self.get_image(x)\n        x = self.backbone(x)\n        return x\n\n    def encoder(self, x):\n        return self.backbone(x)\n    \n    def get_image(self, x):\n        with torch.no_grad():\n            x = x / torch.std(x, 1, keepdim=True)\n            x = self.mel(x)\n            x = self.A2DB(x)\n            x = (x - 40) / 80\n            x = x.unsqueeze(1)\n            pos = torch.linspace(0., 1., x.size(2)).to(x.device)\n            pos = pos.unsqueeze(0).unsqueeze(0).unsqueeze(-1)\n            pos = pos.expand(x.size(0), 1, x.size(2), x.size(3))\n            x = torch.cat([x, x, pos], 1)\n        return x\n    \n\ndef load_checkpoint(fold, seed, cfg):\n    if cfg.pretrained_path:\n        checkpoint_path = cfg.pretrained_path\n    else:\n        checkpoint_path = cfg.checkpoint_path\n    \n    save_path = checkpoint_path / ('%s_%d_%d.pt' % (cfg.fname, fold, seed, ))\n    print('\\n-> Loading weights from', save_path, \"\\n\")\n    \n    checkpoint = torch.load(save_path, map_location='cpu')\n    model = BirdModel(cfg, pretrained=False).to(cfg.device)\n    model.load_state_dict(checkpoint['model'], strict=True)\n    model.eval()\n    model.n_channels = 3\n    model.zero_grad()\n    return model\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-06-10T06:45:42.630211Z","iopub.execute_input":"2024-06-10T06:45:42.631273Z","iopub.status.idle":"2024-06-10T06:45:42.650103Z","shell.execute_reply.started":"2024-06-10T06:45:42.631222Z","shell.execute_reply":"2024-06-10T06:45:42.648978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Params","metadata":{}},{"cell_type":"code","source":"DATA_PATH = \"/kaggle/input/birdclef-2024/test_soundscapes/\"\n\nLIM = None\nif len(os.listdir(DATA_PATH)) < 5:\n    DATA_PATH = \"/kaggle/input/birdclef-2024/unlabeled_soundscapes/\"\n    LIM = 3\n#     LIM = 1100\n#     LIM = 3","metadata":{"execution":{"iopub.status.busy":"2024-06-10T06:45:42.653687Z","iopub.execute_input":"2024-06-10T06:45:42.654801Z","iopub.status.idle":"2024-06-10T06:45:42.668443Z","shell.execute_reply.started":"2024-06-10T06:45:42.654764Z","shell.execute_reply":"2024-06-10T06:45:42.66731Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 48\nUSE_FP16 = False\nNUM_WORKERS = 4\n\nDEVICE = \"cpu\" \n\nDURATION = 5\nSR = 32000\n\nUSE_PP = True\nSMOOTH = True\nSEPARATE = True\nRANK_AVG = False\n\n# ONNX_FOLDER = \"/kaggle/input/birdclef-2024-onnx-safe/\"\nONNX_FOLDER = \"/kaggle/input/birdclef-2024-onnx-risky/\"\n\n\nassert len(ONNX_FOLDER), \"UPDATE ONNX\"","metadata":{"execution":{"iopub.status.busy":"2024-06-10T06:45:42.669804Z","iopub.execute_input":"2024-06-10T06:45:42.670208Z","iopub.status.idle":"2024-06-10T06:45:42.676849Z","shell.execute_reply.started":"2024-06-10T06:45:42.670179Z","shell.execute_reply":"2024-06-10T06:45:42.675806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Data","metadata":{}},{"cell_type":"code","source":"df = pd.DataFrame({\"path\": glob.glob(DATA_PATH + \"*\")})\ndf[\"id\"] = df[\"path\"].apply(lambda x: x.split(\"/\")[-1].rsplit('.', 1)[0])\n\nif LIM:\n#     df = df[df[\"id\"].isin([\"1000170626\", \"1001358022\"])].reset_index(drop=True)\n\n    df = df.head(LIM * 2)\n    df[\"duration\"] = df[\"path\"].apply(lambda x: librosa.get_duration(path=x))\n    df = df[df[\"duration\"] == 240].reset_index(drop=True)\n    df = df.head(LIM)\n        \ndisplay(df.head())","metadata":{"execution":{"iopub.status.busy":"2024-06-10T06:45:42.678351Z","iopub.execute_input":"2024-06-10T06:45:42.678764Z","iopub.status.idle":"2024-06-10T06:45:48.963601Z","shell.execute_reply.started":"2024-06-10T06:45:42.678726Z","shell.execute_reply":"2024-06-10T06:45:48.962457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Models Dieter","metadata":{}},{"cell_type":"code","source":"cfg = SimpleNamespace(**{})\ncfg.num_folds = 5\n\ncfg.fname = 'bird_003'\ncfg.seed = 4000\n\ncfg.input_path = Path('../input')\ncfg.comp_data_path = cfg.input_path / 'birdclef-2024'\ncfg.save_path = Path('../checkpoints')\ncfg.soundscape_path = cfg.comp_data_path / 'unlabeled_soundscapes'\ncfg.test_path = cfg.comp_data_path / 'test_soundscapes'\ncfg.checkpoint_path = Path('/kaggle/input/bc-weights-ch-pl-13/CH_pl_13/checkpoints/bird_003/exp_0/')\n\ncfg.logger_file = False\n\n# image size\ncfg.image_height = 224\ncfg.image_width = 224\n\n# audio\ncfg.duration = 5\ncfg.sr = 32000\ncfg.fmin = 90\ncfg.fmax = 14000\ncfg.n_fft = 1024 + 512\ncfg.n_mels = cfg.image_height\ncfg.win_length = 1024\ncfg.hop_length = int((cfg.duration * cfg.sr - cfg.win_length + cfg.n_fft) / (cfg.image_width)) + 1 \n\n# training HP\ncfg.num_epochs = 3\ncfg.train_batch_size = 1\ncfg.valid_batch_size = 64\ncfg.onnx_batch_size = 48\ncfg.workers = 0\ncfg.grad_norm = 0.0\ncfg.grad_norm_type = 2\ncfg.device = \"cpu\"\ncfg.accumulate = 1\n\n# optimizer\ncfg.lr = 7e-5\ncfg.decay = 0.01\ncfg.opt_beta1 = 0.9\ncfg.opt_beta2 = 0.999\ncfg.opt_eps = 1e-8\ncfg.optimizer = 'AdamW'\ncfg.no_decay = False\n\n# scheduler\ncfg.pct_start = 0.1\ncfg.max_lr = 3e-3\ncfg.final_div_factor = 100\n\n# augmentations\ncfg.resample_train = 10\n\n# logging\ncfg.local_rank = 0\ncfg.verbose=True\n\n# model\ncfg.backbone = 'efficientvit_b0.r224_in1k'\ncfg.gem_pooling = False\ncfg.bce = True\n\n# tasks hp\ncfg.train_model = True\ncfg.pl = None\ncfg.pretrained_path = None \n\ncfg.num_rows = 48\n\ntrain = pd.read_csv(cfg.comp_data_path / 'train_metadata.csv')\ntrain['species'] = [filename.split('/')[0] for filename in train.filename]\n\ncfg.labels = np.array(sorted(train.species.unique()))\ncfg.num_labels = len(cfg.labels)\ncfg.targets = {v : i for i, v in enumerate(cfg.labels)}\n\ncfg.logger = None","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-06-10T06:45:48.965202Z","iopub.execute_input":"2024-06-10T06:45:48.965952Z","iopub.status.idle":"2024-06-10T06:45:49.182298Z","shell.execute_reply.started":"2024-06-10T06:45:48.965909Z","shell.execute_reply":"2024-06-10T06:45:49.181142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nN_FOLDS_DIETER = 5\nmodels_dieter = [(load_checkpoint(fold, cfg.seed + fold, cfg), \"onnx\") for fold in range(N_FOLDS_DIETER)]\n\ninput_tensor = torch.randn(cfg.onnx_batch_size, 3, cfg.image_height, cfg.image_width)  # input shape\ncfg.input_names = ['x']\ncfg.output_names = ['output']\n\nsessions_dieter = []\nfor (i, (model, _)) in enumerate(models_dieter):\n    model.eval()\n    model.zero_grad()\n    model.half().float()\n\n    if not ONNX_FOLDER:\n        torch.onnx.export(model.backbone, input_tensor, f\"model_dieter_{i}.onnx\", verbose=False, input_names=cfg.input_names, output_names=cfg.output_names)\n\n    onnx_model = onnx.load(ONNX_FOLDER + f\"model_dieter_{i}.onnx\")\n    onnx.checker.check_model(onnx_model)\n    ort_session = ort.InferenceSession(ONNX_FOLDER + f\"model_dieter_{i}.onnx\")\n    print(f'\\n-> Loaded ONNX model {ONNX_FOLDER}model_dieter_{i}.onnx\\n')\n    sessions_dieter.append(ort_session)","metadata":{"execution":{"iopub.status.busy":"2024-06-10T06:45:49.183699Z","iopub.execute_input":"2024-06-10T06:45:49.18404Z","iopub.status.idle":"2024-06-10T06:45:51.372552Z","shell.execute_reply.started":"2024-06-10T06:45:49.184006Z","shell.execute_reply":"2024-06-10T06:45:51.371083Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Models CPMP","metadata":{}},{"cell_type":"markdown","source":"### Safe - 253","metadata":{}},{"cell_type":"code","source":"# cfg = SimpleNamespace(**{})\n# cfg.num_folds = 5\n\n# cfg.fname = 'bird_003'\n# cfg.seed = 0\n\n# cfg.input_path = Path('../input')\n# cfg.comp_data_path = cfg.input_path / 'birdclef-2024'\n# cfg.save_path = Path('../checkpoints')\n# cfg.soundscape_path = cfg.comp_data_path / 'unlabeled_soundscapes'\n# cfg.test_path = cfg.comp_data_path / 'test_soundscapes'\n# cfg.checkpoint_path = Path('/kaggle/input/cpmp-birdclef-253')\n\n# cfg.logger_file = False\n\n# # image size\n# cfg.image_height = 224\n# cfg.image_width = 224\n\n# # audio\n# cfg.duration = 5\n# cfg.sr = 32000\n# cfg.fmin = 90\n# cfg.fmax = 14000\n# cfg.n_fft = 1536\n# cfg.n_mels = cfg.image_height\n# cfg.win_length = 1024\n# cfg.hop_length = int((cfg.duration * cfg.sr - cfg.win_length + cfg.n_fft) / (cfg.image_width)) + 1 \n\n# # training HP\n# cfg.num_epochs = 3\n# cfg.train_batch_size = 1\n# cfg.valid_batch_size = 64\n# cfg.onnx_batch_size = 48\n# cfg.workers = 0\n# cfg.grad_norm = 0.0\n# cfg.grad_norm_type = 2\n# cfg.device = \"cpu\"\n# cfg.accumulate = 1\n\n# # optimizer\n# cfg.lr = 7e-5\n# cfg.decay = 0.01\n# cfg.opt_beta1 = 0.9\n# cfg.opt_beta2 = 0.999\n# cfg.opt_eps = 1e-8\n# cfg.optimizer = 'AdamW'\n# cfg.no_decay = False\n\n# # scheduler\n# cfg.pct_start = 0.1\n# cfg.max_lr = 3e-3\n# cfg.final_div_factor = 100\n\n# # augmentations\n# cfg.resample_train = 10\n\n# # logging\n# cfg.local_rank = 0\n# cfg.verbose=True\n\n# # model\n# cfg.backbone = 'efficientvit_b0.r224_in1k'\n# cfg.gem_pooling = False\n# cfg.bce = True\n\n# # tasks hp\n# cfg.train_model = True\n# cfg.pl = None\n# cfg.pretrained_path = None \n\n# cfg.num_rows = 48\n\n# train = pd.read_csv(cfg.comp_data_path / 'train_metadata.csv')\n# train['species'] = [filename.split('/')[0] for filename in train.filename]\n# cfg.labels = np.array(sorted(train.species.unique()))\n# cfg.num_labels = len(cfg.labels)\n# cfg.targets = {v : i for i,v in enumerate(cfg.labels)}\n\n# cfg.logger = None","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Risky - 237","metadata":{}},{"cell_type":"code","source":"cfg = SimpleNamespace(**{})\ncfg.num_folds = 5\n\ncfg.fname = 'bird_003'\ncfg.seed = 2029\n\ncfg.input_path = Path('../input')\ncfg.comp_data_path = cfg.input_path / 'birdclef-2024'\ncfg.save_path = Path('../checkpoints')\ncfg.soundscape_path = cfg.comp_data_path / 'unlabeled_soundscapes'\ncfg.test_path = cfg.comp_data_path / 'test_soundscapes'\ncfg.checkpoint_path = Path('/kaggle/input/cpmp-birdclef-237')\n\ncfg.logger_file = False\n\n# image size\ncfg.image_height = 224\ncfg.image_width = 224\n\n# audio\ncfg.duration = 5\ncfg.sr = 32000\ncfg.fmin = 90\ncfg.fmax = 14000\ncfg.n_fft = 1536\ncfg.n_mels = cfg.image_height\ncfg.win_length = 1024\ncfg.hop_length = int((cfg.duration * cfg.sr - cfg.win_length + cfg.n_fft) / (cfg.image_width)) + 1 \n\n# training HP\ncfg.num_epochs = 3\ncfg.train_batch_size = 1\ncfg.valid_batch_size = 64\ncfg.onnx_batch_size = 48\ncfg.workers = 0\ncfg.grad_norm = 0.0\ncfg.grad_norm_type = 2\ncfg.device = \"cpu\"\ncfg.accumulate = 1\n\n# optimizer\ncfg.lr = 7e-5\ncfg.decay = 0.01\ncfg.opt_beta1 = 0.9\ncfg.opt_beta2 = 0.999\ncfg.opt_eps = 1e-8\ncfg.optimizer = 'AdamW'\ncfg.no_decay = False\n\n# scheduler\ncfg.pct_start = 0.1\ncfg.max_lr = 3e-3\ncfg.final_div_factor = 100\n\n# augmentations\ncfg.resample_train = 10\n\n# logging\ncfg.local_rank = 0\ncfg.verbose=True\n\n# model\ncfg.backbone = 'efficientvit_b0.r224_in1k'\ncfg.gem_pooling = False\ncfg.bce = True\n\n# tasks hp\ncfg.train_model = True\ncfg.pl = None\ncfg.pretrained_path = None \n\ncfg.num_rows = 48\n\ntrain = pd.read_csv(cfg.comp_data_path / 'train_metadata.csv')\ntrain['species'] = [filename.split('/')[0] for filename in train.filename]\ncfg.labels = np.array(sorted(train.species.unique()))\ncfg.num_labels = len(cfg.labels)\ncfg.targets = {v : i for i,v in enumerate(cfg.labels)}\n\ncfg.logger = None","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nN_FOLDS_CPMP = 5\n\nmodels_cpmp = [(load_checkpoint(fold, cfg.seed + fold, cfg), \"onnx\") for fold in range(N_FOLDS_CPMP)]\n\ninput_tensor = torch.randn(cfg.onnx_batch_size, 3, cfg.image_height, cfg.image_width)  # input shape\ncfg.input_names = ['x']\ncfg.output_names = ['output']\n\nsessions_cpmp = []\nfor (i, (model, _)) in enumerate(models_cpmp):\n    model.eval()\n    model.zero_grad()\n    model.half().float()\n\n    if not ONNX_FOLDER:\n        torch.onnx.export(\n            model.backbone,\n            input_tensor,\n            f\"model_cpmp_{i}.onnx\",\n            verbose=False,\n            input_names=cfg.input_names,\n            output_names=cfg.output_names\n        )\n    onnx_model = onnx.load(ONNX_FOLDER + f\"model_cpmp_{i}.onnx\")\n    onnx.checker.check_model(onnx_model)\n    ort_session = ort.InferenceSession(ONNX_FOLDER + f\"model_cpmp_{i}.onnx\")\n    print(f'\\n-> Loaded ONNX model {ONNX_FOLDER}model_cpmp_{i}.onnx\\n')\n    sessions_cpmp.append(ort_session)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Models Theo","metadata":{}},{"cell_type":"code","source":"N_FOLDS_MNASNET = 2\nN_FOLDS_EFFVIT = 2\nN_FOLDS_THEO = N_FOLDS_MNASNET + N_FOLDS_EFFVIT\n\nEXP_FOLDERS = [\n    (\"/kaggle/input/birdclef-2024-weights-1/2024-06-09_10/\", [f\"fullfit_{i}\" for i in range(N_FOLDS_EFFVIT)], \"onnx\"),  # AVES efficientvit_b0\n    (\"/kaggle/input/birdclef-2024-weights-1/2024-06-09_11/\", [f\"fullfit_{i}\" for i in range(N_FOLDS_MNASNET)], \"onnx\"),  # AVES mnasnet\n\n]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n\nmodels = []\nfor e in EXP_FOLDERS:\n    exp_folder, folds, runtime = e\n    config = Config(json.load(open(exp_folder + \"config.json\", \"r\")))\n    \n    for fold in folds:\n        weights = exp_folder + f\"{config.name}_{fold}.pt\"\n\n        model = define_model(\n            config.name,\n            config.melspec_config,\n            head=config.head,\n            aug_config=config.aug_config,\n            num_classes=config.num_classes,\n            n_channels=config.n_channels,\n            drop_rate=config.drop_rate,\n            drop_path_rate=config.drop_path_rate,\n            norm=config.norm if hasattr(config, \"norm\") else \"min_max\",\n            top_db=config.top_db if hasattr(config, \"top_db\") else None,\n            #exportable=config.exportable,\n            verbose=True,\n            pretrained=False\n        )\n        model = model.to(DEVICE).eval()\n        model.zero_grad()\n\n        model = load_model_weights(model, weights, verbose=config.local_rank == 0)\n        model.half().float()\n        models.append((model, runtime))\n\nsessions = []\ninput_names = ['x']\noutput_names = ['output']\n\ninput_tensor = torch.randn(\n    BATCH_SIZE,\n    config.n_channels,\n    config.melspec_config['n_mels'],\n    313 if config.melspec_config['hop_length'] == 512 else 224\n)\n\nfor i, (model, runtime) in enumerate(models):\n    if not ONNX_FOLDER:\n        torch.onnx.export(\n            model.encoder.cpu(),\n            input_tensor,\n            f\"model_{i}.onnx\",\n            verbose=False,\n            input_names=input_names,\n            output_names=output_names,\n        )\n    onnx_model = onnx.load(ONNX_FOLDER + f\"model_{i}.onnx\")\n    onnx.checker.check_model(onnx_model)\n    ort_session = ort.InferenceSession(ONNX_FOLDER + f\"model_{i}.onnx\")\n\n    if runtime == \"onnx\":\n        sessions.append(ort_session)\n        print(f'\\n-> Loaded ONNX model {ONNX_FOLDER}model_{i}.onnx\\n')\n    else:\n        raise NotImplementedError","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Inference\n- 5x CPMP + 5x Christof + 6x Theo : 15' / 100 samples\n- 4x CPMP + 4x Christof + 4x Theo : 11'30 / 100 samples","metadata":{}},{"cell_type":"code","source":"def infer_sample(wave, models, sessions, device=\"cpu\", use_fp16=False):\n    if isinstance(wave, str):\n        wave = load_sample(wave)\n\n    preds = []\n    with torch.no_grad():\n        with torch.cuda.amp.autocast(enabled=False):\n            # Use Theo's model to compute melspec - this requires to have them in the first model position\n            melspec = models[0][0].ft_extractor(wave.to(device))[0].unsqueeze(1)\n\n        pos = (\n            torch.linspace(0.0, 1.0, melspec.size(2))\n            .to(melspec.device)\n            .view(1, 1, -1, 1)\n        )\n        pos = pos.expand(melspec.size(0), 1, melspec.size(2), melspec.size(3))\n        x3 = torch.cat([melspec, melspec, pos], 1)\n\n        for (model, runtime), session in zip(models, sessions):\n            if model.n_channels == 3:\n                x = x3\n            else:\n                x = melspec\n\n            if runtime == \"onnx\":\n                fts = infer_onnx(session, x)\n            else:\n                raise NotImplementedError\n\n            if model.logits is not None:\n                if isinstance(fts, np.ndarray):\n                    fts = torch.from_numpy(fts)\n                with torch.cuda.amp.autocast(enabled=use_fp16):\n                    y_pred = model.get_logits(fts)\n            else:\n                y_pred = fts\n\n            if isinstance(y_pred, torch.Tensor):\n                y_pred = y_pred.detach().cpu().numpy()\n\n            preds.append(y_pred)\n    return np.array(preds)   # n_models x 48 x 182","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"try:\n    batches = np.array_split(np.arange(len(df)), len(df) / 100)\nexcept:\n    batches = [np.arange(len(df))]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\ninference_rows = []\ninference_rows_dict = {\"cpmp\": [], \"theo\": [], \"dieter\": []}\n\nfor i, batch in enumerate(batches):\n    print(f\"-> Batch {i + 1}/{len(batches)}\")\n    df_batch = df.iloc[batch].reset_index(drop=True)\n\n    waves = joblib.Parallel(n_jobs=os.cpu_count())(\n        joblib.delayed(load_sample)(\n            path,\n            evaluate=False,\n            sr=SR,\n            duration=DURATION,\n            normalize=config.wav_norm if hasattr(config, \"wav_norm\") else \"librosa\"\n        )\n        for path in tqdm(df_batch[\"path\"].values)\n    )\n\n    # Requires one of Theo's model to be the first element of the list for spectrogram computing\n    all_preds = [\n        infer_sample(\n            wave,\n            models + models_dieter + models_cpmp,\n            sessions + sessions_dieter + sessions_cpmp,\n            device=DEVICE,\n            use_fp16=USE_FP16,\n        )\n        for wave in tqdm(waves)\n    ]\n\n    del waves\n    gc.collect()\n\n    for idx in range(len(df_batch)):\n        y_pred = all_preds[idx]  # N_MODELS x 48 x 182\n        \n        if USE_PP:\n            if SEPARATE:  # PP p\n                y_pred_dieter = y_pred[N_FOLDS_THEO: N_FOLDS_THEO + N_FOLDS_DIETER]\n                y_pred_cpmp = y_pred[N_FOLDS_THEO + N_FOLDS_DIETER:]\n                y_pred_theo = y_pred[:N_FOLDS_THEO]\n                \n                # CPMP\n                #preds_max = np.max(y_pred_cpmp, 0)  # 48 x 182\n                #y_pred_cpmp = np.array([(pred + preds_max + pred.mean() - preds_max.mean()) / 2.0 for pred in y_pred_cpmp])\n                \n                preds_cpmp = y_pred_cpmp.mean(0)  # 48 x 182\n                max_preds = preds_cpmp.max(0, keepdims=True)  # 1 x 182\n                max_preds = max_preds + (preds_cpmp.mean() - max_preds.mean())\n                preds_cpmp = preds_cpmp + 0.8 * max_preds\n                #preds_cpmp = expit(preds_cpmp)\n                \n                if 0 and SMOOTH:\n                    for i in range(preds_cpmp.shape[1]):\n                        p = np.pad(preds_cpmp[:, i], (2, 2), mode=\"edge\")\n                        preds_cpmp[:, i] = np.convolve(p, np.array([0.1, 0.2, 0.4, 0.2, 0.1]), mode=\"valid\")\n\n                # Dieter\n                preds_dieter = y_pred_dieter.mean(0)  # 48 x 182\n                max_preds = preds_dieter.max(0, keepdims=True)  # 1 x 182\n                max_preds = max_preds + (preds_dieter.mean() - max_preds.mean())\n                preds_dieter = preds_dieter + 0.8 * max_preds\n                #preds_dieter = expit(preds_dieter)\n                \n                if 0 and SMOOTH:\n                    for i in range(preds_dieter.shape[1]):\n                        p = np.pad(preds_dieter[:, i], (2, 2), mode=\"edge\")\n                        preds_dieter[:, i] = np.convolve(p, np.array([0.1, 0.2, 0.4, 0.2, 0.1]), mode=\"valid\")\n                \n                # Theo\n                preds_theo = y_pred_theo.mean(0)  # 48 x 182  -  Average logits before PP ?\n                max_preds = preds_theo.max(0, keepdims=True)  # 1 x 182\n                max_preds = max_preds + (preds_theo.mean() - max_preds.mean())\n                preds_theo = preds_theo + 0.8 * max_preds\n                #preds_theo = expit(preds_theo)\n                \n                if 0 and SMOOTH:\n                    for i in range(preds_theo.shape[1]):\n                        p = np.pad(preds_theo[:, i], (2, 2), mode=\"edge\")\n                        preds_theo[:, i] = np.convolve(p, np.array([0.1, 0.2, 0.4, 0.2, 0.1]), mode=\"valid\")\n                        \n                # Save\n                preds = (preds_cpmp + preds_dieter + preds_theo) / 3\n                preds = expit(preds)\n                if SMOOTH:\n                    # Sliding window smoothing\n                    for i in range(preds.shape[1]):\n                        p = np.pad(preds[:, i], (2, 2), mode=\"edge\")\n                        preds[:, i] = np.convolve(p, np.array([0.1, 0.2, 0.4, 0.2, 0.1]), mode=\"valid\")\n                \n                preds_dict = {\"cpmp\": preds_cpmp, \"dieter\": preds_dieter, \"theo\": preds_theo}\n                \n                \n            else:  # Average then PP\n                \n                preds = y_pred.mean(0)  # 48 x 182  -  Average logits before PP ?\n                max_preds = preds.max(0, keepdims=True)  # 1 x 182\n                max_preds = max_preds + (preds.mean() - max_preds.mean())\n                preds = preds + 0.0 * max_preds\n                preds = expit(preds)\n\n                if 0 and SMOOTH:\n                    # Sliding window smoothing\n                    for i in range(preds.shape[1]):\n                        p = np.pad(preds[:, i], (2, 2), mode=\"edge\")\n                        preds[:, i] = np.convolve(p, np.array([0.1, 0.2, 0.4, 0.2, 0.1]), mode=\"valid\")\n\n        else:\n            preds = expit(y_pred).mean(0)  # Average probas\n\n        for t, pred in enumerate(preds):\n            predictions = dict([(l, p) for l, p in zip(CLASSES, pred)])\n            inference_rows.append(\n                {\"row_id\": f\"{df_batch.id[idx]}_{(t + 1) * 5}\"} | predictions\n            )\n        \n        if SEPARATE:\n            for k in preds_dict:\n                for t, pred in enumerate(preds_dict[k]):\n                    predictions = dict([(l, p) for l, p in zip(CLASSES, pred)])\n                    inference_rows_dict[k].append(\n                        {\"row_id\": f\"{df_batch.id[idx]}_{(t + 1) * 5}\"} | predictions\n                    )\n\n    del all_preds\n    gc.collect()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.DataFrame(inference_rows)\n\nif RANK_AVG and SEPARATE:\n    sub_theo = pd.DataFrame(inference_rows_dict[\"theo\"])\n    sub_cpmp = pd.DataFrame(inference_rows_dict[\"cpmp\"])\n    sub_dieter = pd.DataFrame(inference_rows_dict[\"dieter\"])\n\n    for c in CLASSES:\n        pred_theo = (rankdata(sub_theo[c]) - 1) / (len(sub) - 1)\n        pred_cpmp = (rankdata(sub_cpmp[c]) - 1) / (len(sub) - 1)\n        pred_dieter = (rankdata(sub_dieter[c]) - 1) / (len(sub) - 1)\n\n        sub[c] = (pred_theo + pred_cpmp + pred_dieter) / 3","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.to_csv('submission.csv', index=False)\ndisplay(sub)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Done ! ","metadata":{}}]}