{"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":"markdown","source":"# Inference Kernel","metadata":{}},{"cell_type":"markdown","source":"## Intialization","metadata":{}},{"cell_type":"markdown","source":"### Imports","metadata":{}},{"cell_type":"code","source":"import os\nimport cv2\nimport sys\nimport time\nimport math\n\nimport random\nimport librosa\nimport warnings\nimport torchaudio\nimport torchvision\nimport numpy as np\nimport pandas as pd\nimport typing as tp\nimport IPython.display as ipd\nimport matplotlib.pyplot as plt\n\nfrom pathlib import Path\nfrom collections import Counter\n\nimport torch\nimport torch.nn as nn\nimport torch.utils.data as data\nimport torch.nn.functional as F\n\nfrom torch.utils.data import DataLoader\nfrom torch.nn.modules.utils import _pair\nfrom torch.nn import Conv2d, Module, Linear, BatchNorm2d, ReLU\n\n\npd.options.display.max_rows = 500\npd.options.display.max_columns = 500","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-06-14T02:46:39.328899Z","iopub.execute_input":"2023-06-14T02:46:39.329305Z","iopub.status.idle":"2023-06-14T02:46:43.217821Z","shell.execute_reply.started":"2023-06-14T02:46:39.329262Z","shell.execute_reply":"2023-06-14T02:46:43.216691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Utils","metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a"}},{"cell_type":"code","source":"def load_audio(path, sr):\n    clip, _ = librosa.load(path, sr=sr, mono=True, res_type=\"kaiser_fast\")\n    return clip","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-06-14T02:49:52.114847Z","iopub.execute_input":"2023-06-14T02:49:52.115408Z","iopub.status.idle":"2023-06-14T02:49:52.124746Z","shell.execute_reply.started":"2023-06-14T02:49:52.115334Z","shell.execute_reply":"2023-06-14T02:49:52.123775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_model_weights(model, weights):\n    device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n    state_dict = torch.load(weights, map_location=device)\n    model.load_state_dict(state_dict)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-06-14T02:49:53.708096Z","iopub.execute_input":"2023-06-14T02:49:53.708466Z","iopub.status.idle":"2023-06-14T02:49:53.714658Z","shell.execute_reply.started":"2023-06-14T02:49:53.708429Z","shell.execute_reply":"2023-06-14T02:49:53.713574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def seed_everything(seed):\n    \"\"\"\n    Seeds basic parameters for reproductibility of results\n    \n    Arguments:\n        seed {int} -- Number of the seed\n    \"\"\"\n    random.seed(seed)\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = True #False","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-06-14T02:46:43.245090Z","iopub.execute_input":"2023-06-14T02:46:43.245455Z","iopub.status.idle":"2023-06-14T02:46:43.254914Z","shell.execute_reply.started":"2023-06-14T02:46:43.245424Z","shell.execute_reply":"2023-06-14T02:46:43.253975Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data","metadata":{}},{"cell_type":"code","source":"SEED = 1213\nseed_everything(SEED)","metadata":{"execution":{"iopub.status.busy":"2023-06-14T02:46:43.260899Z","iopub.execute_input":"2023-06-14T02:46:43.261204Z","iopub.status.idle":"2023-06-14T02:46:43.269572Z","shell.execute_reply.started":"2023-06-14T02:46:43.261174Z","shell.execute_reply":"2023-06-14T02:46:43.268619Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ROOT = Path.cwd().parent\nINPUT_ROOT = ROOT / \"input\"\nRAW_DATA = INPUT_ROOT / \"birdsong-recognition\"\nTRAIN_AUDIO_DIR = RAW_DATA / \"train_audio\"","metadata":{"execution":{"iopub.status.busy":"2023-06-14T02:46:43.273726Z","iopub.execute_input":"2023-06-14T02:46:43.274073Z","iopub.status.idle":"2023-06-14T02:46:43.280235Z","shell.execute_reply.started":"2023-06-14T02:46:43.274043Z","shell.execute_reply":"2023-06-14T02:46:43.279028Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv(RAW_DATA / \"train.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-06-14T02:46:43.281877Z","iopub.execute_input":"2023-06-14T02:46:43.282478Z","iopub.status.idle":"2023-06-14T02:46:43.731383Z","shell.execute_reply.started":"2023-06-14T02:46:43.282436Z","shell.execute_reply":"2023-06-14T02:46:43.730317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TEST_AUDIO_DIR = RAW_DATA / \"test_audio\"\n\nif not TEST_AUDIO_DIR.exists():\n    TEST_AUDIO_DIR = INPUT_ROOT / \"birdcall-check\" / \"test_audio\"\n    test = pd.read_csv(INPUT_ROOT / \"birdcall-check\" / \"test.csv\")\nelse:\n    test = pd.read_csv(RAW_DATA / \"test.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-06-14T02:46:43.732852Z","iopub.execute_input":"2023-06-14T02:46:43.733215Z","iopub.status.idle":"2023-06-14T02:46:43.747291Z","shell.execute_reply.started":"2023-06-14T02:46:43.733172Z","shell.execute_reply":"2023-06-14T02:46:43.746038Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Parameters","metadata":{}},{"cell_type":"code","source":"CLASSES = sorted(os.listdir(TRAIN_AUDIO_DIR))\nNUM_CLASSES = len(CLASSES)\nNUM_WORKERS = 4","metadata":{"execution":{"iopub.status.busy":"2023-06-14T02:46:43.748816Z","iopub.execute_input":"2023-06-14T02:46:43.749227Z","iopub.status.idle":"2023-06-14T02:46:43.829463Z","shell.execute_reply.started":"2023-06-14T02:46:43.749182Z","shell.execute_reply":"2023-06-14T02:46:43.828646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class AudioParams:\n    sr = 32000\n    stride = 5\n    true_kernel_size = 5\n\n    img_size = None\n    \n    # Melspectrogram\n    n_mels = 128\n    fmin = 20\n    fmax = 16000","metadata":{"execution":{"iopub.status.busy":"2023-06-14T02:46:43.831892Z","iopub.execute_input":"2023-06-14T02:46:43.832199Z","iopub.status.idle":"2023-06-14T02:46:43.840621Z","shell.execute_reply.started":"2023-06-14T02:46:43.832169Z","shell.execute_reply":"2023-06-14T02:46:43.839438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Dataset","metadata":{}},{"cell_type":"code","source":"def convert_site_3(df, clip_length, params):\n    n_samples = clip_length // (params.sr * params.true_kernel_size)  # may lose the end \n    \n    audio_id = [df['audio_id'].values[0]] * n_samples\n    site = ['site_3'] * n_samples\n    seconds = [i * params.true_kernel_size for i in range(1, n_samples + 1)]\n    row_id = [f'site_3_{audio_id[0]}_{int(s)}' for s in seconds]\n    \n    new_df = pd.DataFrame(data={'site': site,\n                                'row_id': row_id,\n                                'seconds': seconds,\n                                'audio_id': audio_id\n                               })\n    \n    return new_df","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-06-14T02:46:43.842263Z","iopub.execute_input":"2023-06-14T02:46:43.842676Z","iopub.status.idle":"2023-06-14T02:46:43.853843Z","shell.execute_reply.started":"2023-06-14T02:46:43.842637Z","shell.execute_reply":"2023-06-14T02:46:43.852777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def compute_melspec(y, params):\n    melspec = librosa.feature.melspectrogram(\n        y,\n        sr=params.sr,\n        n_mels=params.n_mels,\n        fmin=params.fmin,\n        fmax=params.fmax\n    )\n    \n    melspec = librosa.power_to_db(melspec).astype(np.float32)\n    \n    return melspec","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-06-14T02:46:43.855302Z","iopub.execute_input":"2023-06-14T02:46:43.855792Z","iopub.status.idle":"2023-06-14T02:46:43.864649Z","shell.execute_reply.started":"2023-06-14T02:46:43.855752Z","shell.execute_reply":"2023-06-14T02:46:43.863785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def mono_to_color(X, eps=1e-6, mean=None, std=None):\n    X = np.stack([X, X, X], axis=-1)\n\n    # Standardize\n    mean = mean or X.mean()\n    std = std or X.std()\n    X = (X - mean) / (std + eps)\n\n    # Normalize to [0, 255]\n    _min, _max = X.min(), X.max()\n\n    if (_max - _min) > eps:\n        V = np.clip(X, _min, _max)\n        V = 255 * (V - _min) / (_max - _min)\n        V = V.astype(np.uint8)\n    else:\n        V = np.zeros_like(X, dtype=np.uint8)\n\n    return V\n\n\ndef resize(image, size=None):\n    if size is not None:\n        h, w, _ = image.shape\n        new_w, new_h = int(w * size / h), size\n        image = cv2.resize(image, (new_w, new_h))\n\n    return image\n\n\ndef normalize(image, mean=None, std=None):\n    image = image / 255.0\n    if mean is not None and std is not None:\n        image = (image - mean) / std\n    return np.moveaxis(image, 2, 0).astype(np.float32)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-06-14T02:46:43.866434Z","iopub.execute_input":"2023-06-14T02:46:43.866908Z","iopub.status.idle":"2023-06-14T02:46:43.884454Z","shell.execute_reply.started":"2023-06-14T02:46:43.866865Z","shell.execute_reply":"2023-06-14T02:46:43.883678Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class TestDataset(data.Dataset):\n    def __init__(self, df, clip, params):\n        self.df = df\n        self.clip = clip\n        self.params = params\n        \n        if df['site'].values[0] == 'site_3':\n            self.df = convert_site_3(df, len(clip), params)\n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, idx):      \n        end_seconds = int(self.df['seconds'][idx])\n        start_seconds = int(end_seconds - 5)\n\n        start_index = self.params.sr * start_seconds\n        end_index = self.params.sr * end_seconds\n\n        y = self.clip[start_index:end_index].astype(np.float32)\n\n        melspec = compute_melspec(y, self.params)\n        \n        image = mono_to_color(melspec)\n        image = resize(image, self.params.img_size)\n        image = normalize(image, mean=None, std=None)\n        \n        return image","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2023-06-14T02:46:43.888204Z","iopub.execute_input":"2023-06-14T02:46:43.888477Z","iopub.status.idle":"2023-06-14T02:46:43.902378Z","shell.execute_reply.started":"2023-06-14T02:46:43.888451Z","shell.execute_reply":"2023-06-14T02:46:43.901590Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Modeling","metadata":{}},{"cell_type":"markdown","source":"\n### Resnest\n> From https://github.com/zhanghang1989/ResNeSt","metadata":{}},{"cell_type":"code","source":"class SplAtConv2d(Module):\n    \"\"\"Split-Attention Conv2d\n    \"\"\"\n    def __init__(self, in_channels, channels, kernel_size, stride=(1, 1), padding=(0, 0),\n                 dilation=(1, 1), groups=1, bias=True,\n                 radix=2, reduction_factor=4,\n                 rectify=False, rectify_avg=False, norm_layer=None,\n                 dropblock_prob=0.0, **kwargs):\n        super(SplAtConv2d, self).__init__()\n        padding = _pair(padding)\n        self.rectify = rectify and (padding[0] > 0 or padding[1] > 0)\n        self.rectify_avg = rectify_avg\n        inter_channels = max(in_channels*radix//reduction_factor, 32)\n        self.radix = radix\n        self.cardinality = groups\n        self.channels = channels\n        self.dropblock_prob = dropblock_prob\n        if self.rectify:\n            from rfconv import RFConv2d\n            self.conv = RFConv2d(in_channels, channels*radix, kernel_size, stride, padding, dilation,\n                                 groups=groups*radix, bias=bias, average_mode=rectify_avg, **kwargs)\n        else:\n            self.conv = Conv2d(in_channels, channels*radix, kernel_size, stride, padding, dilation,\n                               groups=groups*radix, bias=bias, **kwargs)\n        self.use_bn = norm_layer is not None\n        if self.use_bn:\n            self.bn0 = norm_layer(channels*radix)\n        self.relu = ReLU(inplace=True)\n        self.fc1 = Conv2d(channels, inter_channels, 1, groups=self.cardinality)\n        if self.use_bn:\n            self.bn1 = norm_layer(inter_channels)\n        self.fc2 = Conv2d(inter_channels, channels*radix, 1, groups=self.cardinality)\n        if dropblock_prob > 0.0:\n            self.dropblock = DropBlock2D(dropblock_prob, 3)\n        self.rsoftmax = rSoftMax(radix, groups)\n\n    def forward(self, x):\n        x = self.conv(x)\n        if self.use_bn:\n            x = self.bn0(x)\n        if self.dropblock_prob > 0.0:\n            x = self.dropblock(x)\n        x = self.relu(x)\n\n        batch, rchannel = x.shape[:2]\n        if self.radix > 1:\n            if torch.__version__ < '1.5':\n                splited = torch.split(x, int(rchannel//self.radix), dim=1)\n            else:\n                splited = torch.split(x, rchannel//self.radix, dim=1)\n            gap = sum(splited) \n        else:\n            gap = x\n        gap = F.adaptive_avg_pool2d(gap, 1)\n        gap = self.fc1(gap)\n\n        if self.use_bn:\n            gap = self.bn1(gap)\n        gap = self.relu(gap)\n\n        atten = self.fc2(gap)\n        atten = self.rsoftmax(atten).view(batch, -1, 1, 1)\n\n        if self.radix > 1:\n            if torch.__version__ < '1.5':\n                attens = torch.split(atten, int(rchannel//self.radix), dim=1)\n            else:\n                attens = torch.split(atten, rchannel//self.radix, dim=1)\n            out = sum([att*split for (att, split) in zip(attens, splited)])\n        else:\n            out = atten * x\n        return out.contiguous()\n\nclass rSoftMax(nn.Module):\n    def __init__(self, radix, cardinality):\n        super().__init__()\n        self.radix = radix\n        self.cardinality = cardinality\n\n    def forward(self, x):\n        batch = x.size(0)\n        if self.radix > 1:\n            x = x.view(batch, self.cardinality, self.radix, -1).transpose(1, 2)\n            x = F.softmax(x, dim=1)\n            x = x.reshape(batch, -1)\n        else:\n            x = torch.sigmoid(x)\n        return x","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-06-14T02:46:43.904187Z","iopub.execute_input":"2023-06-14T02:46:43.904637Z","iopub.status.idle":"2023-06-14T02:46:43.946595Z","shell.execute_reply.started":"2023-06-14T02:46:43.904597Z","shell.execute_reply":"2023-06-14T02:46:43.945300Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DropBlock2D(object):\n    def __init__(self, *args, **kwargs):\n        raise NotImplementedError\n\nclass GlobalAvgPool2d(nn.Module):\n    def __init__(self):\n        \"\"\"Global average pooling over the input's spatial dimensions\"\"\"\n        super(GlobalAvgPool2d, self).__init__()\n\n    def forward(self, inputs):\n        return nn.functional.adaptive_avg_pool2d(inputs, 1).view(inputs.size(0), -1)\n\nclass Bottleneck(nn.Module):\n    \"\"\"ResNet Bottleneck\n    \"\"\"\n    # pylint: disable=unused-argument\n    expansion = 4\n    def __init__(self, inplanes, planes, stride=1, downsample=None,\n                 radix=1, cardinality=1, bottleneck_width=64,\n                 avd=False, avd_first=False, dilation=1, is_first=False,\n                 rectified_conv=False, rectify_avg=False,\n                 norm_layer=None, dropblock_prob=0.0, last_gamma=False):\n        super(Bottleneck, self).__init__()\n        group_width = int(planes * (bottleneck_width / 64.)) * cardinality\n        self.conv1 = nn.Conv2d(inplanes, group_width, kernel_size=1, bias=False)\n        self.bn1 = norm_layer(group_width)\n        self.dropblock_prob = dropblock_prob\n        self.radix = radix\n        self.avd = avd and (stride > 1 or is_first)\n        self.avd_first = avd_first\n\n        if self.avd:\n            self.avd_layer = nn.AvgPool2d(3, stride, padding=1)\n            stride = 1\n\n        if dropblock_prob > 0.0:\n            self.dropblock1 = DropBlock2D(dropblock_prob, 3)\n            if radix == 1:\n                self.dropblock2 = DropBlock2D(dropblock_prob, 3)\n            self.dropblock3 = DropBlock2D(dropblock_prob, 3)\n\n        if radix >= 1:\n            self.conv2 = SplAtConv2d(\n                group_width, group_width, kernel_size=3,\n                stride=stride, padding=dilation,\n                dilation=dilation, groups=cardinality, bias=False,\n                radix=radix, rectify=rectified_conv,\n                rectify_avg=rectify_avg,\n                norm_layer=norm_layer,\n                dropblock_prob=dropblock_prob)\n        elif rectified_conv:\n            from rfconv import RFConv2d\n            self.conv2 = RFConv2d(\n                group_width, group_width, kernel_size=3, stride=stride,\n                padding=dilation, dilation=dilation,\n                groups=cardinality, bias=False,\n                average_mode=rectify_avg)\n            self.bn2 = norm_layer(group_width)\n        else:\n            self.conv2 = nn.Conv2d(\n                group_width, group_width, kernel_size=3, stride=stride,\n                padding=dilation, dilation=dilation,\n                groups=cardinality, bias=False)\n            self.bn2 = norm_layer(group_width)\n\n        self.conv3 = nn.Conv2d(\n            group_width, planes * 4, kernel_size=1, bias=False)\n        self.bn3 = norm_layer(planes*4)\n\n        if last_gamma:\n            from torch.nn.init import zeros_\n            zeros_(self.bn3.weight)\n        self.relu = nn.ReLU(inplace=True)\n        self.downsample = downsample\n        self.dilation = dilation\n        self.stride = stride\n\n    def forward(self, x):\n        residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        if self.dropblock_prob > 0.0:\n            out = self.dropblock1(out)\n        out = self.relu(out)\n\n        if self.avd and self.avd_first:\n            out = self.avd_layer(out)\n\n        out = self.conv2(out)\n        if self.radix == 0:\n            out = self.bn2(out)\n            if self.dropblock_prob > 0.0:\n                out = self.dropblock2(out)\n            out = self.relu(out)\n\n        if self.avd and not self.avd_first:\n            out = self.avd_layer(out)\n\n        out = self.conv3(out)\n        out = self.bn3(out)\n        if self.dropblock_prob > 0.0:\n            out = self.dropblock3(out)\n\n        if self.downsample is not None:\n            residual = self.downsample(x)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\nclass ResNet(nn.Module):\n    \"\"\"ResNet Variants\n    Parameters\n    ----------\n    block : Block\n        Class for the residual block. Options are BasicBlockV1, BottleneckV1.\n    layers : list of int\n        Numbers of layers in each block\n    classes : int, default 1000\n        Number of classification classes.\n    dilated : bool, default False\n        Applying dilation strategy to pretrained ResNet yielding a stride-8 model,\n        typically used in Semantic Segmentation.\n    norm_layer : object\n        Normalization layer used in backbone network (default: :class:`mxnet.gluon.nn.BatchNorm`;\n        for Synchronized Cross-GPU BachNormalization).\n    Reference:\n        - He, Kaiming, et al. \"Deep residual learning for image recognition.\" Proceedings of the IEEE conference on computer vision and pattern recognition. 2016.\n        - Yu, Fisher, and Vladlen Koltun. \"Multi-scale context aggregation by dilated convolutions.\"\n    \"\"\"\n    # pylint: disable=unused-variable\n    def __init__(self, block, layers, radix=1, groups=1, bottleneck_width=64,\n                 num_classes=1000, dilated=False, dilation=1,\n                 deep_stem=False, stem_width=64, avg_down=False,\n                 rectified_conv=False, rectify_avg=False,\n                 avd=False, avd_first=False,\n                 final_drop=0.0, dropblock_prob=0,\n                 last_gamma=False, norm_layer=nn.BatchNorm2d):\n        self.cardinality = groups\n        self.bottleneck_width = bottleneck_width\n        # ResNet-D params\n        self.inplanes = stem_width*2 if deep_stem else 64\n        self.avg_down = avg_down\n        self.last_gamma = last_gamma\n        # ResNeSt params\n        self.radix = radix\n        self.avd = avd\n        self.avd_first = avd_first\n\n        super(ResNet, self).__init__()\n        self.rectified_conv = rectified_conv\n        self.rectify_avg = rectify_avg\n        if rectified_conv:\n            from rfconv import RFConv2d\n            conv_layer = RFConv2d\n        else:\n            conv_layer = nn.Conv2d\n        conv_kwargs = {'average_mode': rectify_avg} if rectified_conv else {}\n        if deep_stem:\n            self.conv1 = nn.Sequential(\n                conv_layer(3, stem_width, kernel_size=3, stride=2, padding=1, bias=False, **conv_kwargs),\n                norm_layer(stem_width),\n                nn.ReLU(inplace=True),\n                conv_layer(stem_width, stem_width, kernel_size=3, stride=1, padding=1, bias=False, **conv_kwargs),\n                norm_layer(stem_width),\n                nn.ReLU(inplace=True),\n                conv_layer(stem_width, stem_width*2, kernel_size=3, stride=1, padding=1, bias=False, **conv_kwargs),\n            )\n        else:\n            self.conv1 = conv_layer(3, 64, kernel_size=7, stride=2, padding=3,\n                                   bias=False, **conv_kwargs)\n        self.bn1 = norm_layer(self.inplanes)\n        self.relu = nn.ReLU(inplace=True)\n        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n        self.layer1 = self._make_layer(block, 64, layers[0], norm_layer=norm_layer, is_first=False)\n        self.layer2 = self._make_layer(block, 128, layers[1], stride=2, norm_layer=norm_layer)\n        if dilated or dilation == 4:\n            self.layer3 = self._make_layer(block, 256, layers[2], stride=1,\n                                           dilation=2, norm_layer=norm_layer,\n                                           dropblock_prob=dropblock_prob)\n            self.layer4 = self._make_layer(block, 512, layers[3], stride=1,\n                                           dilation=4, norm_layer=norm_layer,\n                                           dropblock_prob=dropblock_prob)\n        elif dilation==2:\n            self.layer3 = self._make_layer(block, 256, layers[2], stride=2,\n                                           dilation=1, norm_layer=norm_layer,\n                                           dropblock_prob=dropblock_prob)\n            self.layer4 = self._make_layer(block, 512, layers[3], stride=1,\n                                           dilation=2, norm_layer=norm_layer,\n                                           dropblock_prob=dropblock_prob)\n        else:\n            self.layer3 = self._make_layer(block, 256, layers[2], stride=2,\n                                           norm_layer=norm_layer,\n                                           dropblock_prob=dropblock_prob)\n            self.layer4 = self._make_layer(block, 512, layers[3], stride=2,\n                                           norm_layer=norm_layer,\n                                           dropblock_prob=dropblock_prob)\n        self.avgpool = GlobalAvgPool2d()\n        self.drop = nn.Dropout(final_drop) if final_drop > 0.0 else None\n        self.fc = nn.Linear(512 * block.expansion, num_classes)\n\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels\n                m.weight.data.normal_(0, math.sqrt(2. / n))\n            elif isinstance(m, norm_layer):\n                m.weight.data.fill_(1)\n                m.bias.data.zero_()\n\n    def _make_layer(self, block, planes, blocks, stride=1, dilation=1, norm_layer=None,\n                    dropblock_prob=0.0, is_first=True):\n        downsample = None\n        if stride != 1 or self.inplanes != planes * block.expansion:\n            down_layers = []\n            if self.avg_down:\n                if dilation == 1:\n                    down_layers.append(nn.AvgPool2d(kernel_size=stride, stride=stride,\n                                                    ceil_mode=True, count_include_pad=False))\n                else:\n                    down_layers.append(nn.AvgPool2d(kernel_size=1, stride=1,\n                                                    ceil_mode=True, count_include_pad=False))\n                down_layers.append(nn.Conv2d(self.inplanes, planes * block.expansion,\n                                             kernel_size=1, stride=1, bias=False))\n            else:\n                down_layers.append(nn.Conv2d(self.inplanes, planes * block.expansion,\n                                             kernel_size=1, stride=stride, bias=False))\n            down_layers.append(norm_layer(planes * block.expansion))\n            downsample = nn.Sequential(*down_layers)\n\n        layers = []\n        if dilation == 1 or dilation == 2:\n            layers.append(block(self.inplanes, planes, stride, downsample=downsample,\n                                radix=self.radix, cardinality=self.cardinality,\n                                bottleneck_width=self.bottleneck_width,\n                                avd=self.avd, avd_first=self.avd_first,\n                                dilation=1, is_first=is_first, rectified_conv=self.rectified_conv,\n                                rectify_avg=self.rectify_avg,\n                                norm_layer=norm_layer, dropblock_prob=dropblock_prob,\n                                last_gamma=self.last_gamma))\n        elif dilation == 4:\n            layers.append(block(self.inplanes, planes, stride, downsample=downsample,\n                                radix=self.radix, cardinality=self.cardinality,\n                                bottleneck_width=self.bottleneck_width,\n                                avd=self.avd, avd_first=self.avd_first,\n                                dilation=2, is_first=is_first, rectified_conv=self.rectified_conv,\n                                rectify_avg=self.rectify_avg,\n                                norm_layer=norm_layer, dropblock_prob=dropblock_prob,\n                                last_gamma=self.last_gamma))\n        else:\n            raise RuntimeError(\"=> unknown dilation size: {}\".format(dilation))\n\n        self.inplanes = planes * block.expansion\n        for i in range(1, blocks):\n            layers.append(block(self.inplanes, planes,\n                                radix=self.radix, cardinality=self.cardinality,\n                                bottleneck_width=self.bottleneck_width,\n                                avd=self.avd, avd_first=self.avd_first,\n                                dilation=dilation, rectified_conv=self.rectified_conv,\n                                rectify_avg=self.rectify_avg,\n                                norm_layer=norm_layer, dropblock_prob=dropblock_prob,\n                                last_gamma=self.last_gamma))\n\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.bn1(x)\n        x = self.relu(x)\n        x = self.maxpool(x)\n\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n\n        x = self.avgpool(x)\n        #x = x.view(x.size(0), -1)\n        x = torch.flatten(x, 1)\n        if self.drop:\n            x = self.drop(x)\n        x = self.fc(x)\n\n        return x","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-06-14T02:46:43.948871Z","iopub.execute_input":"2023-06-14T02:46:43.949553Z","iopub.status.idle":"2023-06-14T02:46:44.044190Z","shell.execute_reply.started":"2023-06-14T02:46:43.949486Z","shell.execute_reply":"2023-06-14T02:46:44.043003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"MODEL_CONFIGS = {\n    \"resnest50_fast_1s1x64d\":\n    {\n        \"num_classes\": 264,\n        \"block\": Bottleneck,\n        \"layers\": [3, 4, 6, 3],\n        \"radix\": 1,\n        \"groups\": 1,\n        \"bottleneck_width\": 64,\n        \"deep_stem\": True,\n        \"stem_width\": 32,\n        \"avg_down\": True,\n        \"avd\" : True,\n        \"avd_first\" : True\n    },\n    \"resnest101\":\n    {\n        \"num_classes\": 264,\n        \"block\": Bottleneck,\n        \"layers\": [3, 4, 23, 3],\n        \"radix\": 2,\n        \"groups\": 1,\n        \"bottleneck_width\": 64,\n        \"deep_stem\": True,\n        \"stem_width\": 64,\n        \"avg_down\": True,\n        \"avd\" : True,\n        \"avd_first\" : False\n    },\n}","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-06-14T02:46:44.048780Z","iopub.execute_input":"2023-06-14T02:46:44.049128Z","iopub.status.idle":"2023-06-14T02:46:44.061332Z","shell.execute_reply.started":"2023-06-14T02:46:44.049080Z","shell.execute_reply":"2023-06-14T02:46:44.060549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Model loader","metadata":{}},{"cell_type":"code","source":"def get_model(name):\n    if \"resnest\" in name:\n        model = ResNet(**MODEL_CONFIGS[name])\n    elif \"resnext101\" in name:\n#         model = resnext101_32x8d()\n        model = torchvision.models.resnext101_32x8d(pretrained=False)\n    elif \"resnext50\" in name:\n        model = torchvision.models.resnext50_32x4d(pretrained=False)\n    else:\n        raise NotImplementedError\n\n    nb_ft = model.fc.in_features\n    del model.fc\n    model.fc = nn.Linear(nb_ft, NUM_CLASSES)\n\n    device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n    model.to(device)\n    model.eval()\n    \n    return model","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2023-06-14T02:46:44.065335Z","iopub.execute_input":"2023-06-14T02:46:44.065786Z","iopub.status.idle":"2023-06-14T02:46:44.078258Z","shell.execute_reply.started":"2023-06-14T02:46:44.065751Z","shell.execute_reply":"2023-06-14T02:46:44.077310Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Inference","metadata":{}},{"cell_type":"markdown","source":"### Predict","metadata":{}},{"cell_type":"code","source":"def predict(model, dataset, batch_size=16):\n    model.eval()\n    preds = np.empty((0, NUM_CLASSES))\n    \n    loader = DataLoader(\n        dataset, batch_size=batch_size, shuffle=False, num_workers=NUM_WORKERS, pin_memory=True\n    )\n\n    with torch.no_grad():\n        for x in loader:\n            y_pred = model(x.cuda()).detach()\n            preds = np.concatenate([preds, torch.sigmoid(y_pred).cpu().numpy()])\n    \n    return preds","metadata":{"execution":{"iopub.status.busy":"2023-06-14T02:46:44.080938Z","iopub.execute_input":"2023-06-14T02:46:44.081670Z","iopub.status.idle":"2023-06-14T02:46:44.091584Z","shell.execute_reply.started":"2023-06-14T02:46:44.081585Z","shell.execute_reply":"2023-06-14T02:46:44.090596Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Post-process","metadata":{}},{"cell_type":"code","source":"def post_process_site_12(preds, threshold=0.5, maxpreds=3):\n    preds = preds * (preds >= threshold)   # remove preds < threshold\n\n    next_preds = np.concatenate([preds[1:], np.zeros((1, preds.shape[-1]))])   # pred corresponding to next window\n    prev_preds = np.concatenate([np.zeros((1, preds.shape[-1])), preds[:-1]])  # pred corresponding to previous window\n    \n    score = preds + 0.5 * next_preds + 0.5 * prev_preds  # Aggregating with neighbouring predictions\n    \n    n_birds = (score >= threshold).sum(-1)   # Counting birds\n    n_birds = np.clip(n_birds, 0, maxpreds)  # keep at most maxpreds birds\n    \n    labels = [np.argsort(- score[i])[:n_birds[i]] for i in range(len(preds))]  # Getting the n_birds most likely class indices\n    \n    class_labels = [\" \".join([CLASSES[l] for l in label]) for label in labels]  # Getting class names\n    \n    return class_labels","metadata":{"execution":{"iopub.status.busy":"2023-06-14T02:46:44.093256Z","iopub.execute_input":"2023-06-14T02:46:44.093688Z","iopub.status.idle":"2023-06-14T02:46:44.106999Z","shell.execute_reply.started":"2023-06-14T02:46:44.093643Z","shell.execute_reply":"2023-06-14T02:46:44.105900Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def post_process_site_3(preds, threshold=0.5, maxpreds=3):\n    preds = preds * (preds >= threshold)     # remove preds < threshold\n\n    score = np.sum(preds, 0)                 # Aggregating all the predictions\n    \n    n_birds = (score >= threshold).sum(-1)   # Counting birds\n    n_birds = np.clip(n_birds, 0, maxpreds)  # keep at most maxpreds birds\n    \n    label = np.argsort(- score)[:n_birds]    # Getting the n_birds most likely class indices\n    \n    class_labels = \" \".join([CLASSES[l] for l in label])  # Getting class names\n    \n    return class_labels","metadata":{"execution":{"iopub.status.busy":"2023-06-14T02:46:44.108809Z","iopub.execute_input":"2023-06-14T02:46:44.109583Z","iopub.status.idle":"2023-06-14T02:46:44.120466Z","shell.execute_reply.started":"2023-06-14T02:46:44.109427Z","shell.execute_reply":"2023-06-14T02:46:44.119707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def max_pred_gen(site, duration):\n    if site != \"site_3\":\n        return 3\n    else:\n        rets = [(7,2), (15, 3), (30, 5), (60, 7)]\n        \n        for ref_duration,thresh in rets:\n            if ref_duration >= duration:\n                return thresh\n        return 10","metadata":{"execution":{"iopub.status.busy":"2023-06-14T02:46:44.121941Z","iopub.execute_input":"2023-06-14T02:46:44.122651Z","iopub.status.idle":"2023-06-14T02:46:44.132058Z","shell.execute_reply.started":"2023-06-14T02:46:44.122602Z","shell.execute_reply":"2023-06-14T02:46:44.131142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def reformat_preds(preds, df, site):\n    prediction_df = pd.DataFrame({\n        \"row_id\": df['row_id'].values,\n        \"birds\": preds\n    })\n    \n    prediction_df['birds'] = prediction_df['birds'].replace([''],'nocall')\n    \n    return prediction_df","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2023-06-14T02:46:44.133938Z","iopub.execute_input":"2023-06-14T02:46:44.134406Z","iopub.status.idle":"2023-06-14T02:46:44.143939Z","shell.execute_reply.started":"2023-06-14T02:46:44.134364Z","shell.execute_reply":"2023-06-14T02:46:44.143176Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Inference","metadata":{}},{"cell_type":"code","source":"def inference(test_df, test_audio, configs, params, threshold=0.5):\n    unique_audio_id = test_df.audio_id.unique()\n    \n    models = []\n    for config in configs:\n        models_ = []\n        for weights in config[\"weights\"]:\n            model = get_model(config['name'])\n            load_model_weights(model, weights)\n            models_.append(model)\n        models.append(models_)\n        \n    print(f'\\t -> Using {len(models)} models, with {len(models[0])} weights per model.')\n        \n    pred_dfs = []\n    for audio_id in unique_audio_id :\n        \n        audio_df = test_df[test_df['audio_id'] == audio_id].reset_index(drop=True)\n        site = audio_df[\"site\"].values[0]      \n        \n        print(f'\\nMaking predictions for audio {audio_id} in {site} ')\n\n        clip = load_audio(test_audio / (audio_id + \".mp3\"), params.sr)\n        clip_duration = len(clip) // params.sr\n        \n        dataset = TestDataset(audio_df, clip, params)\n        \n        preds = []\n        for i, config in enumerate(configs):\n            for j, weights in enumerate(config[\"weights\"]):\n                pred = predict(models[i][j], dataset, batch_size=16)\n                preds.append(pred)\n        preds = np.mean(preds, 0)\n        \n        maxpreds = max_pred_gen(site, clip_duration)\n        print(f'Limiting the number of birds to {maxpreds}')\n        \n        if site == 'site_3':\n            preds_pp = post_process_site_3(preds, threshold=threshold, maxpreds=maxpreds)\n        else:\n            preds_pp = post_process_site_12(preds, threshold=threshold, maxpreds=maxpreds)\n        \n        print(\"Predicted classes :\", preds_pp)\n        \n        pred_df = reformat_preds(preds_pp, audio_df, site)\n        pred_dfs.append(pred_df)\n    \n    sub = pd.concat(pred_dfs, axis=0, sort=False).reset_index(drop=True)\n    return sub","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2023-06-14T02:46:44.145437Z","iopub.execute_input":"2023-06-14T02:46:44.146189Z","iopub.status.idle":"2023-06-14T02:46:44.165201Z","shell.execute_reply.started":"2023-06-14T02:46:44.146143Z","shell.execute_reply":"2023-06-14T02:46:44.164428Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Inferene with voting","metadata":{}},{"cell_type":"code","source":"def vote(preds, min_votes=3):\n    votes = Counter(preds)\n    return [c for c, count in votes.items() if count >= min_votes]","metadata":{"execution":{"iopub.status.busy":"2023-06-14T02:46:44.167007Z","iopub.execute_input":"2023-06-14T02:46:44.167541Z","iopub.status.idle":"2023-06-14T02:46:44.179042Z","shell.execute_reply.started":"2023-06-14T02:46:44.167476Z","shell.execute_reply":"2023-06-14T02:46:44.178222Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def inference_voting(test_df, test_audio, configs, params, threshold=0.5, min_votes=3):\n    unique_audio_id = test_df.audio_id.unique()\n    \n    models = []\n    for config in configs:\n        models_ = []\n        for weights in config[\"weights\"]:\n            model = get_model(config['name'])\n            load_model_weights(model, weights)\n            models_.append(model)\n        models.append(models_)\n        \n    print(f'\\t -> Using {len(models)} models, with {len(models[0])} weights per model.')\n        \n    pred_dfs = []\n    for audio_id in unique_audio_id :\n        \n        audio_df = test_df[test_df['audio_id'] == audio_id].reset_index(drop=True)\n        site = audio_df[\"site\"].values[0]   \n        \n        print(f'\\nMaking predictions for audio {audio_id} in {site} ')\n\n        clip = load_audio(test_audio / (audio_id + \".mp3\"), params.sr)\n        clip_duration = len(clip) // params.sr\n        \n        dataset = TestDataset(audio_df, clip, params)\n        \n        \n        all_preds = []\n        for i, config in enumerate(configs):\n            \n            preds = []\n            for j, weights in enumerate(config[\"weights\"]):\n                pred = predict(models[i][j], dataset, batch_size=16)\n                preds.append(pred)\n            preds = np.mean(preds, 0)\n\n            maxpreds = max_pred_gen(site, clip_duration)\n            print(f'Limiting the number of birds to {maxpreds}')\n\n            if site == 'site_3':\n                preds_pp = post_process_site_3(preds, threshold=threshold, maxpreds=maxpreds)\n                preds_pp = [preds_pp]\n            else:\n                preds_pp = post_process_site_12(preds, threshold=threshold, maxpreds=maxpreds)\n\n            all_preds.append(preds_pp)\n            print(\"Predicted classes :\", preds_pp)\n        \n        final_preds = []\n        for i in range(len(all_preds[0])):\n            preds = []\n            for m in range(len(all_preds)):\n                preds += all_preds[m][i].split(' ')\n                \n            final_pred = vote(preds, min_votes=min_votes)\n            final_preds.append(' '.join(final_pred))\n        \n        print(\"\\n    -> Voted classes :\", final_preds)\n        \n        pred_df = reformat_preds(final_preds, audio_df, site)\n        pred_dfs.append(pred_df)\n    \n    sub = pd.concat(pred_dfs, axis=0, sort=False).reset_index(drop=True)\n    return sub","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2023-06-14T02:46:44.180796Z","iopub.execute_input":"2023-06-14T02:46:44.181252Z","iopub.status.idle":"2023-06-14T02:46:44.204283Z","shell.execute_reply.started":"2023-06-14T02:46:44.181201Z","shell.execute_reply":"2023-06-14T02:46:44.203551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Prediction","metadata":{}},{"cell_type":"markdown","source":"### Used models","metadata":{}},{"cell_type":"code","source":"configs = []","metadata":{"execution":{"iopub.status.busy":"2023-06-14T02:46:44.205644Z","iopub.execute_input":"2023-06-14T02:46:44.205997Z","iopub.status.idle":"2023-06-14T02:46:44.218242Z","shell.execute_reply.started":"2023-06-14T02:46:44.205967Z","shell.execute_reply":"2023-06-14T02:46:44.217319Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_name = \"resnext50_32x4d\"\nweights = [f\"../input/birds-cp-2/{model_name}_extra_{i}.pt\" for i in range(5)]\n\nfor w in weights:\n    assert os.path.isfile(w), f\"Weights {w} not found\"\n    \nconfigs.append({\n    \"name\": model_name,\n    \"weights\": weights,\n})","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-06-14T02:46:44.220072Z","iopub.execute_input":"2023-06-14T02:46:44.220499Z","iopub.status.idle":"2023-06-14T02:46:44.235957Z","shell.execute_reply.started":"2023-06-14T02:46:44.220458Z","shell.execute_reply":"2023-06-14T02:46:44.235066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_name = \"resnext101_32x8d_wsl\"\nweights = [f\"../input/birds-cp-2/{model_name}_extra_{i}.pt\" for i in range(5)]\n\nfor w in weights:\n    assert os.path.isfile(w), f\"Weights {w} not found\"\n    \nconfigs.append({\n    \"name\": model_name,\n    \"weights\": weights,\n})","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-06-14T02:46:44.238027Z","iopub.execute_input":"2023-06-14T02:46:44.238377Z","iopub.status.idle":"2023-06-14T02:46:44.250463Z","shell.execute_reply.started":"2023-06-14T02:46:44.238342Z","shell.execute_reply":"2023-06-14T02:46:44.249776Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_name = \"resnest50_fast_1s1x64d\"\nweights = [f\"../input/birds-cp-1/{model_name}_conf_{i}.pt\" for i in range(5)]\n\nfor w in weights:\n    assert os.path.isfile(w), f\"Weights {w} not found\"\n    \nconfigs.append({\n    \"name\": model_name,\n    \"weights\": weights,\n})","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-06-14T02:46:44.253983Z","iopub.execute_input":"2023-06-14T02:46:44.254263Z","iopub.status.idle":"2023-06-14T02:46:44.272506Z","shell.execute_reply.started":"2023-06-14T02:46:44.254235Z","shell.execute_reply":"2023-06-14T02:46:44.271620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model_name = \"resnest50_fast_1s1x64d\"\n# weights = [f\"../input/birds-cp-1/{model_name}_mixup5_{i}.pt\" for i in range(5)]\n\n# for w in weights:\n#     assert os.path.isfile(w), f\"Weights {w} not found\"\n    \n# configs.append({\n#     \"name\": model_name,\n#     \"weights\": weights,\n# })","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-06-14T02:46:44.275770Z","iopub.execute_input":"2023-06-14T02:46:44.276078Z","iopub.status.idle":"2023-06-14T02:46:44.282499Z","shell.execute_reply.started":"2023-06-14T02:46:44.276047Z","shell.execute_reply":"2023-06-14T02:46:44.281460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"configs","metadata":{"execution":{"iopub.status.busy":"2023-06-14T02:46:44.283986Z","iopub.execute_input":"2023-06-14T02:46:44.284410Z","iopub.status.idle":"2023-06-14T02:46:44.296250Z","shell.execute_reply.started":"2023-06-14T02:46:44.284371Z","shell.execute_reply":"2023-06-14T02:46:44.295239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Running inference","metadata":{}},{"cell_type":"code","source":"threshold = 0.5\nmin_votes = 2","metadata":{"execution":{"iopub.status.busy":"2023-06-14T02:46:44.298296Z","iopub.execute_input":"2023-06-14T02:46:44.298721Z","iopub.status.idle":"2023-06-14T02:46:44.306210Z","shell.execute_reply.started":"2023-06-14T02:46:44.298680Z","shell.execute_reply":"2023-06-14T02:46:44.305288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"warnings.filterwarnings(\"ignore\")\n\n# submission = inference(test, TEST_AUDIO_DIR, configs, AudioParams, threshold=threshold)\nsubmission = inference_voting(test, TEST_AUDIO_DIR, configs, AudioParams, threshold=threshold, min_votes=min_votes)","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-06-14T02:46:44.307809Z","iopub.execute_input":"2023-06-14T02:46:44.308273Z","iopub.status.idle":"2023-06-14T02:49:51.871872Z","shell.execute_reply.started":"2023-06-14T02:46:44.308234Z","shell.execute_reply":"2023-06-14T02:49:51.870875Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Submission","metadata":{}},{"cell_type":"code","source":"submission.to_csv(\"submission.csv\", index=False)\n# submission","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-06-14T02:50:12.212253Z","iopub.execute_input":"2023-06-14T02:50:12.212687Z","iopub.status.idle":"2023-06-14T02:50:12.218849Z","shell.execute_reply.started":"2023-06-14T02:50:12.212648Z","shell.execute_reply":"2023-06-14T02:50:12.217885Z"},"trusted":true},"execution_count":null,"outputs":[]}]}