{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":91844,"databundleVersionId":11361821,"sourceType":"competition"},{"sourceId":12074955,"sourceType":"datasetVersion","datasetId":7600858},{"sourceId":235777618,"sourceType":"kernelVersion"}],"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false},"papermill":{"default_parameters":{},"duration":27.447062,"end_time":"2025-03-12T14:13:11.647927","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2025-03-12T14:12:44.200865","version":"2.6.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!python -m pip install --no-index --find-links=../input/openvino-wheels -r ../input/openvino-wheels/requirements.txt -q","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:23:22.232255Z","iopub.execute_input":"2025-06-06T01:23:22.232684Z","iopub.status.idle":"2025-06-06T01:23:26.260548Z","shell.execute_reply.started":"2025-06-06T01:23:22.232649Z","shell.execute_reply":"2025-06-06T01:23:26.258770Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport gc\nimport time\nimport numpy as np\nimport pandas as pd\nimport torch\nimport torch.nn as nn\nimport timm\nimport torch.nn.functional as F\nimport torchaudio\nimport torchaudio.transforms as AT\nfrom contextlib import contextmanager\nimport concurrent.futures\nimport openvino as ov","metadata":{"papermill":{"duration":12.984639,"end_time":"2025-03-12T14:13:00.145177","exception":false,"start_time":"2025-03-12T14:12:47.160538","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:23:26.263229Z","iopub.execute_input":"2025-06-06T01:23:26.263626Z","iopub.status.idle":"2025-06-06T01:23:26.270737Z","shell.execute_reply.started":"2025-06-06T01:23:26.263569Z","shell.execute_reply":"2025-06-06T01:23:26.269640Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class_labels = sorted(os.listdir('../input/birdclef-2025/train_audio/'))\nn_mels = 192","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:23:26.271782Z","iopub.execute_input":"2025-06-06T01:23:26.272137Z","iopub.status.idle":"2025-06-06T01:23:26.296076Z","shell.execute_reply.started":"2025-06-06T01:23:26.272106Z","shell.execute_reply":"2025-06-06T01:23:26.294962Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def init_layer(layer):\n    nn.init.xavier_uniform_(layer.weight)\n\n    if hasattr(layer, \"bias\"):\n        if layer.bias is not None:\n            layer.bias.data.fill_(0.)\n\n\ndef init_bn(bn):\n    bn.bias.data.fill_(0.)\n    bn.weight.data.fill_(1.0)\n\n\ndef init_weights(model):\n    classname = model.__class__.__name__\n    if classname.find(\"Conv2d\") != -1:\n        nn.init.xavier_uniform_(model.weight, gain=np.sqrt(2))\n        model.bias.data.fill_(0)\n    elif classname.find(\"BatchNorm\") != -1:\n        model.weight.data.normal_(1.0, 0.02)\n        model.bias.data.fill_(0)\n    elif classname.find(\"GRU\") != -1:\n        for weight in model.parameters():\n            if len(weight.size()) > 1:\n                nn.init.orghogonal_(weight.data)\n    elif classname.find(\"Linear\") != -1:\n        model.weight.data.normal_(0, 0.01)\n        model.bias.data.zero_()\n\n\ndef interpolate(x, ratio):\n    \"\"\"Interpolate data in time domain. This is used to compensate the\n    resolution reduction in downsampling of a CNN.\n    Args:\n      x: (batch_size, time_steps, classes_num)\n      ratio: int, ratio to interpolate\n    Returns:\n      upsampled: (batch_size, time_steps * ratio, classes_num)\n    \"\"\"\n    (batch_size, time_steps, classes_num) = x.shape\n    upsampled = x[:, :, None, :].repeat(1, 1, ratio, 1)\n    upsampled = upsampled.reshape(batch_size, time_steps * ratio, classes_num)\n    return upsampled\n\n\ndef pad_framewise_output(framewise_output, frames_num):\n    \"\"\"Pad framewise_output to the same length as input frames. The pad value\n    is the same as the value of the last frame.\n    Args:\n      framewise_output: (batch_size, frames_num, classes_num)\n      frames_num: int, number of frames to pad\n    Outputs:\n      output: (batch_size, frames_num, classes_num)\n    \"\"\"\n    output = F.interpolate(\n        framewise_output.unsqueeze(1),\n        size=(frames_num, framewise_output.size(2)),\n        align_corners=True,\n        mode=\"bilinear\").squeeze(1)\n\n    return output\n\n\nclass AttBlockV2(nn.Module):\n    def __init__(self,\n                 in_features: int,\n                 out_features: int,\n                 activation=\"linear\"):\n        super().__init__()\n\n        self.activation = activation\n        self.att = nn.Conv1d(\n            in_channels=in_features,\n            out_channels=out_features,\n            kernel_size=1,\n            stride=1,\n            padding=0,\n            bias=True)\n        self.cla = nn.Conv1d(\n            in_channels=in_features,\n            out_channels=out_features,\n            kernel_size=1,\n            stride=1,\n            padding=0,\n            bias=True)\n\n        self.init_weights()\n\n    def init_weights(self):\n        init_layer(self.att)\n        init_layer(self.cla)\n\n    def forward(self, x):\n        # x: (n_samples, n_in, n_time)\n        norm_att = torch.softmax(torch.tanh(self.att(x)), dim=-1)\n        cla = self.nonlinear_transform(self.cla(x))\n        x = torch.sum(norm_att * cla, dim=2)\n        return x, norm_att, cla\n\n    def nonlinear_transform(self, x):\n        if self.activation == 'linear':\n            return x\n        elif self.activation == 'sigmoid':\n            return torch.sigmoid(x)\n\nclass TimmSED(nn.Module):\n    def __init__(self, base_model_name: str, pretrained=False, num_classes=24, in_channels=1, n_mels=24):\n        super().__init__()\n\n\n        self.bn0 = nn.BatchNorm2d(n_mels)\n\n        base_model = timm.create_model(\n            base_model_name, pretrained=pretrained, in_chans=in_channels)\n        layers = list(base_model.children())[:-2]\n        self.encoder = nn.Sequential(*layers)\n\n        in_features = base_model.num_features\n\n        self.fc1 = nn.Linear(in_features, in_features, bias=True)\n        self.att_block2 = AttBlockV2(\n            in_features, num_classes, activation=\"sigmoid\")\n\n        self.init_weight()\n\n    def init_weight(self):\n        init_bn(self.bn0)\n        init_layer(self.fc1)\n        \n\n    def forward(self, input_data):\n        x = input_data.transpose(2,3)\n        x = torch.cat((x,x,x),1)\n\n        frames_num = x.shape[2]\n        x = x.transpose(2, 3)\n\n        x = self.encoder(x)\n        \n        # Aggregate in frequency axis\n        x = torch.mean(x, dim=2)\n\n        x1 = F.max_pool1d(x, kernel_size=3, stride=1, padding=1)\n        x2 = F.avg_pool1d(x, kernel_size=3, stride=1, padding=1)\n        x = x1 + x2\n\n        x = x.transpose(1, 2)\n        x = F.relu_(self.fc1(x))\n        x = x.transpose(1, 2)\n\n        (clipwise_output, norm_att, segmentwise_output) = self.att_block2(x)\n        logit = torch.sum(norm_att * self.att_block2.cla(x), dim=2)\n        return logit","metadata":{"papermill":{"duration":2.175154,"end_time":"2025-03-12T14:13:02.578522","exception":false,"start_time":"2025-03-12T14:13:00.403368","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:23:26.298644Z","iopub.execute_input":"2025-06-06T01:23:26.298960Z","iopub.status.idle":"2025-06-06T01:23:26.322549Z","shell.execute_reply.started":"2025-06-06T01:23:26.298937Z","shell.execute_reply":"2025-06-06T01:23:26.321505Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"base_model_name='tf_efficientnetv2_s.in21k'\nbase_model_name2='tf_efficientnet_b0_ns'\nbase_model_name3='tf_efficientnetv2_b3.in21k'\nbase_model_name4='tf_efficientnet_b3_ns'\npretrained=False\nin_channels=3\n\nMODELS = []\nBASE_MODELS = []\nfor i in range(4):\n    MODELS.append(f'/kaggle/input/birdclef2025-noir-models/sed_new_fold_best_fold{i}.pth')\n    BASE_MODELS.append(base_model_name)\nfor i in range(2):\n    MODELS.append(f'/kaggle/input/birdclef2025-noir-models/sed_effi_b_tss_re1_fold{i}.pth')\n    BASE_MODELS.append(base_model_name2)\nfor i in range(3):\n    MODELS.append(f'/kaggle/input/birdclef2025-noir-models/sed_effiv2_b3_tss_re1_fold{i+2}.pth')\n    BASE_MODELS.append(base_model_name3)\nfor i in range(4):\n    MODELS.append(f'/kaggle/input/birdclef2025-noir-models/sed_efficient_b3_tss_re1_fold{i}.pth')\n    BASE_MODELS.append(base_model_name4)\n    \nMODELS2 = []\nBASE_MODELS2=[]\nfor i in range(4):\n    MODELS2.append(f'/kaggle/input/birdclef2025-noir-models/sed_new_fold_best_fold{i+1}.pth')\n    BASE_MODELS2.append(base_model_name)\nfor i in range(2):\n    MODELS2.append(f'/kaggle/input/birdclef2025-noir-models/sed_effi_b_tss_re1_fold{i+2}.pth')\n    BASE_MODELS2.append(base_model_name2)\nfor i in range(3):\n    MODELS2.append(f'/kaggle/input/birdclef2025-noir-models/sed_effiv2_b3_tss_re1_fold{i}.pth')\n    BASE_MODELS2.append(base_model_name3)\nfor i in range(4):\n    MODELS2.append(f'/kaggle/input/birdclef2025-noir-models/sed_efficient_b3_tss_re1_fold{i}.pth')\n    BASE_MODELS2.append(base_model_name4)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:23:26.323757Z","iopub.execute_input":"2025-06-06T01:23:26.324144Z","iopub.status.idle":"2025-06-06T01:23:26.353328Z","shell.execute_reply.started":"2025-06-06T01:23:26.324110Z","shell.execute_reply":"2025-06-06T01:23:26.352344Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(len(MODELS))\ndisplay(MODELS)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:23:26.354478Z","iopub.execute_input":"2025-06-06T01:23:26.354869Z","iopub.status.idle":"2025-06-06T01:23:26.383031Z","shell.execute_reply.started":"2025-06-06T01:23:26.354833Z","shell.execute_reply":"2025-06-06T01:23:26.381947Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(len(MODELS2))\ndisplay(MODELS2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:23:26.384424Z","iopub.execute_input":"2025-06-06T01:23:26.384962Z","iopub.status.idle":"2025-06-06T01:23:26.409674Z","shell.execute_reply.started":"2025-06-06T01:23:26.384764Z","shell.execute_reply":"2025-06-06T01:23:26.408674Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"models = []\nfor path, base_model_name in zip(MODELS, BASE_MODELS):\n    model = TimmSED(base_model_name=base_model_name,\n               pretrained=pretrained,\n               num_classes=len(class_labels),\n               in_channels=in_channels,\n               n_mels=n_mels);\n    model.load_state_dict(torch.load(path, weights_only=True, map_location=torch.device('cpu')))\n    model.eval();\n    models.append(model)\n\nmodels2 = []\nfor path,base_model_name in zip(MODELS2, BASE_MODELS2):\n    model2 = TimmSED(base_model_name=base_model_name,\n               pretrained=pretrained,\n               num_classes=len(class_labels),\n               in_channels=in_channels,\n               n_mels=n_mels);\n    model2.load_state_dict(torch.load(path, weights_only=True, map_location=torch.device('cpu')))\n    model2.eval();\n    models2.append(model2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:23:26.410571Z","iopub.execute_input":"2025-06-06T01:23:26.411224Z","iopub.status.idle":"2025-06-06T01:23:53.312827Z","shell.execute_reply.started":"2025-06-06T01:23:26.411201Z","shell.execute_reply":"2025-06-06T01:23:53.311994Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"input_sed = torch.randn(12, 1, 192, 209)\ninput_sed2 = torch.randn(11, 1, 192, 209)\n\ninput_names = [ 'input_data' ]\noutput_names = [ \"logit\" ]\n\nfor i, model in enumerate(models):\n    torch.onnx.export(model, input_sed, f\"model_{i}.onnx\", verbose=False, input_names=input_names, output_names=output_names)\n    print(f\"model_{i}.onnx\")\n    \nfor i, model in enumerate(models2):\n    torch.onnx.export(model, input_sed2, f\"model2_{i}.onnx\", verbose=False, input_names=input_names, output_names=output_names)\n    print(f\"model2_{i}.onnx\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:23:53.314073Z","iopub.execute_input":"2025-06-06T01:23:53.314363Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!mo --input_model model_0.onnx\n!mo --input_model model_1.onnx\n!mo --input_model model_2.onnx\n!mo --input_model model_3.onnx\n!mo --input_model model_4.onnx\n!mo --input_model model_5.onnx\n!mo --input_model model_6.onnx\n!mo --input_model model_7.onnx\n!mo --input_model model_8.onnx\n!mo --input_model model_9.onnx\n!mo --input_model model_10.onnx\n!mo --input_model model_11.onnx\n!mo --input_model model_12.onnx\n!mo --input_model model_13.onnx\n\n!mo --input_model model2_0.onnx\n!mo --input_model model2_1.onnx\n!mo --input_model model2_2.onnx\n!mo --input_model model2_3.onnx\n!mo --input_model model2_4.onnx\n!mo --input_model model2_5.onnx\n!mo --input_model model2_6.onnx\n!mo --input_model model2_7.onnx\n!mo --input_model model2_8.onnx\n!mo --input_model model2_9.onnx\n!mo --input_model model2_10.onnx\n!mo --input_model model2_11.onnx\n!mo --input_model model2_12.onnx\n!mo --input_model model2_13.onnx","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}