{"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":"!pip install ../input/torchlibrosa/torchlibrosa-0.0.5-py3-none-any.whl > /dev/null","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:43:35.947766Z","iopub.execute_input":"2022-05-17T12:43:35.948083Z","iopub.status.idle":"2022-05-17T12:44:04.589717Z","shell.execute_reply.started":"2022-05-17T12:43:35.947993Z","shell.execute_reply":"2022-05-17T12:44:04.588761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\nimport audioread\nimport logging\nimport os\nimport sys\nsys.path.append('../input/pytorch-image-models/pytorch-image-models-master')\nimport random\nimport time\nimport warnings\n\nimport librosa\nimport numpy as np\nimport pandas as pd\nimport soundfile as sf\nimport timm\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.utils.data as torchdata\n\nfrom contextlib import contextmanager\nfrom pathlib import Path\nfrom typing import List\nfrom typing import Optional\nfrom sklearn import metrics\nfrom sklearn.model_selection import StratifiedKFold, GroupKFold\n\nfrom albumentations.core.transforms_interface import ImageOnlyTransform\nfrom torchlibrosa.stft import LogmelFilterBank, Spectrogram\nfrom torchlibrosa.augmentation import SpecAugmentation\nfrom tqdm import tqdm\n\nimport albumentations as A\nimport albumentations.pytorch.transforms as T\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:44:04.592789Z","iopub.execute_input":"2022-05-17T12:44:04.593048Z","iopub.status.idle":"2022-05-17T12:44:10.983391Z","shell.execute_reply.started":"2022-05-17T12:44:04.593012Z","shell.execute_reply":"2022-05-17T12:44:10.982611Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def set_seed(seed: int = 42):\n    random.seed(seed)\n    np.random.seed(seed)\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)  # type: ignore\n    torch.backends.cudnn.deterministic = True  # type: ignore\n    torch.backends.cudnn.benchmark = True  # type: ignore\n    \n    \ndef get_logger(out_file=None):\n    logger = logging.getLogger()\n    formatter = logging.Formatter(\"%(asctime)s - %(levelname)s - %(message)s\")\n    logger.handlers = []\n    logger.setLevel(logging.INFO)\n\n    handler = logging.StreamHandler()\n    handler.setFormatter(formatter)\n    handler.setLevel(logging.INFO)\n    logger.addHandler(handler)\n\n    if out_file is not None:\n        fh = logging.FileHandler(out_file)\n        fh.setFormatter(formatter)\n        fh.setLevel(logging.INFO)\n        logger.addHandler(fh)\n    logger.info(\"logger set up\")\n    return logger\n    \n    \n@contextmanager\ndef timer(name: str, logger: Optional[logging.Logger] = None):\n    t0 = time.time()\n    msg = f\"[{name}] start\"\n    if logger is None:\n        print(msg)\n    else:\n        logger.info(msg)\n    yield\n\n    msg = f\"[{name}] done in {time.time() - t0:.2f} s\"\n    if logger is None:\n        print(msg)\n    else:\n        logger.info(msg)\n\n\ndef get_device() -> torch.device:\n    return torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n\ndevice = get_device()\nlogger = get_logger(\"main.log\")\nset_seed(42)","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:44:10.984898Z","iopub.execute_input":"2022-05-17T12:44:10.985147Z","iopub.status.idle":"2022-05-17T12:44:11.064478Z","shell.execute_reply.started":"2022-05-17T12:44:10.985113Z","shell.execute_reply":"2022-05-17T12:44:11.063717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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: torch.Tensor, ratio: int):\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: torch.Tensor, frames_num: int):\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\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\n\nclass TimmSED(nn.Module):\n    def __init__(self, base_model_name: str, pretrained=False, num_classes=24, in_channels=1):\n        super().__init__()\n\n        self.spec_augmenter = SpecAugmentation(time_drop_width=64//2, time_stripes_num=2,\n                                               freq_drop_width=8//2, freq_stripes_num=2)\n\n        self.bn0 = nn.BatchNorm2d(CFG.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        if hasattr(base_model, \"fc\"):\n            in_features = base_model.fc.in_features\n        else:\n            in_features = base_model.classifier.in_features\n\n        self.fc1 = nn.Linear(in_features, in_features, bias=True)\n        self.att_block = 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 # (batch_size, 3, time_steps, mel_bins)\n\n        frames_num = x.shape[2]\n\n        x = x.transpose(1, 3)\n        x = self.bn0(x)\n        x = x.transpose(1, 3)\n\n        if self.training:\n            if random.random() < 0.25:\n                x = self.spec_augmenter(x)\n\n        x = x.transpose(2, 3)\n\n        x = self.encoder(x)\n        \n        # Aggregate in frequency axis\n        x = torch.mean(x, dim=3)\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 = F.dropout(x, p=0.5, training=self.training)\n        x = x.transpose(1, 2)\n        x = F.relu_(self.fc1(x))\n        x = x.transpose(1, 2)\n        x = F.dropout(x, p=0.5, training=self.training)\n\n        (clipwise_output, norm_att, segmentwise_output) = self.att_block(x)\n        logit = torch.sum(norm_att * self.att_block.cla(x), dim=2)\n        segmentwise_logit = self.att_block.cla(x).transpose(1, 2)\n        segmentwise_output = segmentwise_output.transpose(1, 2)\n\n        interpolate_ratio = frames_num // segmentwise_output.size(1)\n\n        # Get framewise output\n        framewise_output = interpolate(segmentwise_output,\n                                       interpolate_ratio)\n        framewise_output = pad_framewise_output(framewise_output, frames_num)\n\n        framewise_logit = interpolate(segmentwise_logit, interpolate_ratio)\n        framewise_logit = pad_framewise_output(framewise_logit, frames_num)\n\n        output_dict = {\n            'framewise_output': framewise_output,\n            'clipwise_output': clipwise_output,\n            'logit': logit,\n            'framewise_logit': framewise_logit,\n        }\n\n        return output_dict","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:44:11.068247Z","iopub.execute_input":"2022-05-17T12:44:11.06844Z","iopub.status.idle":"2022-05-17T12:44:11.103248Z","shell.execute_reply.started":"2022-05-17T12:44:11.068417Z","shell.execute_reply":"2022-05-17T12:44:11.102429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mean = (0.485, 0.456, 0.406) # RGB\nstd = (0.229, 0.224, 0.225) # RGB\n\nalbu_transforms = {\n    'train' : A.Compose([\n            A.HorizontalFlip(p=0.5),\n            A.OneOf([\n                A.Cutout(max_h_size=5, max_w_size=16),\n                A.CoarseDropout(max_holes=4),\n            ], p=0.5),\n            A.Normalize(mean, std),\n    ]),\n    'valid' : A.Compose([\n            A.Normalize(mean, std),\n    ]),\n}","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:44:11.10496Z","iopub.execute_input":"2022-05-17T12:44:11.105805Z","iopub.status.idle":"2022-05-17T12:44:11.118188Z","shell.execute_reply.started":"2022-05-17T12:44:11.105766Z","shell.execute_reply":"2022-05-17T12:44:11.117406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    EXP_ID = '018' \n\n    ######################\n    # Globals #\n    ######################\n    seed = 42\n    epochs = 5\n    train = True\n    folds = [0, 1, 2, 3, 4]\n    img_size = 224\n    main_metric = \"epoch_f1_at_03\"\n    minimize_metric = False\n\n    ######################\n    # Dataset #\n    ######################\n    transforms = {\n        \"train\": [{\"name\": \"Normalize\"}],\n        \"valid\": [{\"name\": \"Normalize\"}]\n    }\n    period = 5\n    n_mels = 224\n    fmin = 20\n    fmax = 16000\n    n_fft = 2048\n    hop_length = 512\n    sample_rate = 32000\n    melspectrogram_parameters = {\n        \"n_mels\": 224,\n        \"fmin\": 20,\n        \"fmax\": 16000\n    }\n\n    target_columns = 'afrsil1 akekee akepa1 akiapo akikik amewig aniani apapan arcter \\\n                      barpet bcnher belkin1 bkbplo bknsti bkwpet blkfra blknod bongul \\\n                      brant brnboo brnnod brnowl brtcur bubsan buffle bulpet burpar buwtea \\\n                      cacgoo1 calqua cangoo canvas caster1 categr chbsan chemun chukar cintea \\\n                      comgal1 commyn compea comsan comwax coopet crehon dunlin elepai ercfra eurwig \\\n                      fragul gadwal gamqua glwgul gnwtea golphe grbher3 grefri gresca gryfra gwfgoo \\\n                      hawama hawcoo hawcre hawgoo hawhaw hawpet1 hoomer houfin houspa hudgod iiwi incter1 \\\n                      jabwar japqua kalphe kauama laugul layalb lcspet leasan leater1 lessca lesyel lobdow lotjae \\\n                      madpet magpet1 mallar3 masboo mauala maupar merlin mitpar moudov norcar norhar2 normoc norpin \\\n                      norsho nutman oahama omao osprey pagplo palila parjae pecsan peflov perfal pibgre pomjae puaioh \\\n                      reccar redava redjun redpha1 refboo rempar rettro ribgul rinduc rinphe rocpig rorpar rudtur ruff \\\n                      saffin sander semplo sheowl shtsan skylar snogoo sooshe sooter1 sopsku1 sora spodov sposan \\\n                      towsol wantat1 warwhe1 wesmea wessan wetshe whfibi whiter whttro wiltur yebcar yefcan zebdov'.split()\n\n    ######################\n    # Loaders #\n    ######################\n    loader_params = {\n        \"train\": {\n            \"batch_size\": 16, \n            \"num_workers\": 0,\n            \"shuffle\": True\n        },\n        \"valid\": {\n            \"batch_size\": 32,\n            \"num_workers\": 0,\n            \"shuffle\": False\n        }\n    }\n\n    ######################\n    # Model #\n    ######################\n    base_model_name = \"tf_efficientnet_b0_ns\"\n    pooling = \"max\"\n    pretrained = False\n    num_classes = 152\n    in_channels = 3\n\n    N_FOLDS = 5\n    LR = 1e-3\n    T_max=10\n    min_lr=1e-6","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:44:11.119852Z","iopub.execute_input":"2022-05-17T12:44:11.120474Z","iopub.status.idle":"2022-05-17T12:44:11.131738Z","shell.execute_reply.started":"2022-05-17T12:44:11.120435Z","shell.execute_reply":"2022-05-17T12:44:11.13107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"AUDIO_PATH = '../input/birdclef-2022/train_audio'\nCLASSES = sorted(os.listdir(AUDIO_PATH))\nNUM_CLASSES = len(CLASSES)\nclass AudioParams:\n    \"\"\"\n    Parameters used for the audio data\n    \"\"\"\n    sr = 32000\n    duration = 5\n    # Melspectrogram\n    n_mels = 224\n    fmin = 20\n    fmax = 16000","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:44:11.133319Z","iopub.execute_input":"2022-05-17T12:44:11.133744Z","iopub.status.idle":"2022-05-17T12:44:11.158541Z","shell.execute_reply.started":"2022-05-17T12:44:11.133707Z","shell.execute_reply":"2022-05-17T12:44:11.157857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def compute_melspec(y, params):\n    \"\"\"\n    Computes a mel-spectrogram and puts it at decibel scale\n    Arguments:\n        y {np array} -- signal\n        params {AudioParams} -- Parameters to use for the spectrogram. Expected to have the attributes sr, n_mels, f_min, f_max\n    Returns:\n        np array -- Mel-spectrogram\n    \"\"\"\n    melspec = librosa.feature.melspectrogram(\n        y=y, sr=params.sr, n_mels=params.n_mels, fmin=params.fmin, fmax=params.fmax,\n    )\n\n    melspec = librosa.power_to_db(melspec).astype(np.float32)\n    return melspec\n\n\ndef mono_to_color(X, eps=1e-6, mean=None, std=None):\n    \"\"\"\n    Converts a one channel array to a 3 channel one in [0, 255]\n    Arguments:\n        X {numpy array [H x W]} -- 2D array to convert\n    Keyword Arguments:\n        eps {float} -- To avoid dividing by 0 (default: {1e-6})\n        mean {None or np array} -- Mean for normalization (default: {None})\n        std {None or np array} -- Std for normalization (default: {None})\n    Returns:\n        numpy array [3 x H x W] -- RGB numpy array\n    \"\"\"\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","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:44:11.159955Z","iopub.execute_input":"2022-05-17T12:44:11.160313Z","iopub.status.idle":"2022-05-17T12:44:11.171782Z","shell.execute_reply.started":"2022-05-17T12:44:11.160275Z","shell.execute_reply":"2022-05-17T12:44:11.171059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class TestDataset(torchdata.Dataset):\n    def __init__(self, df: pd.DataFrame, clip: np.ndarray):\n        self.df = df\n        # self.clip = clip\n        self.clip = np.concatenate([clip, clip, clip])\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx: int):\n        SR = 32000\n        sample = self.df.loc[idx, :]\n        row_id = sample.row_id\n\n        end_seconds = int(sample.seconds)\n        start_seconds = int(end_seconds - 5)\n        \n        # end_index = int(SR * (end_seconds + (self.train_period - 5) / 2) + len(self.clip) // 3)\n        # start_index = int(SR * (start_seconds - (self.train_period - 5) / 2) + len(self.clip) // 3)\n        \n        # y = self.clip[start_index:end_index].astype(np.float32)\n        image = self.clip[SR*start_seconds:SR*end_seconds].astype(np.float32)\n        image = np.nan_to_num(image)\n        \n        image = compute_melspec(image, AudioParams)\n        image = mono_to_color(image)\n        image = image.astype(np.uint8)\n\n        image = albu_transforms['valid'](image=image)['image'].T\n            \n        return {\n            \"image\": image,\n            \"row_id\": row_id,\n        }","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:44:11.173614Z","iopub.execute_input":"2022-05-17T12:44:11.173858Z","iopub.status.idle":"2022-05-17T12:44:11.184492Z","shell.execute_reply.started":"2022-05-17T12:44:11.173834Z","shell.execute_reply":"2022-05-17T12:44:11.183702Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_paths = [\n    \n    \n#     ['tf_efficientnet_b0_ns', '../input/birdcall-models/exp_4/tf_efficientnet_b0_ns/fold-0.bin'], #0.70\n    ['tf_efficientnet_b0_ns', '../input/birdclef2022-use-2nd-label-f0/fold-0.bin'], #0.71\n    ['tf_efficientnet_b0_ns', '../input/birdcall-models/exp_5/tf_efficientnet_b0_ns/fold-0.bin'], #exp_5\n#     ['resnest50d_1s4x24d', '../input/birdcall-models/exp_5/resnest50d_1s4x24d/fold-0.bin'], #exp_5\n    ['mixnet_m', '../input/birdcall-models/exp_5/mixnet_m/fold-0.bin'], #exp_5\n#     ['resnext50d_32x4d', '../input/birdcall-models/exp_5/resnext50d_32x4d/fold-0.bin'], #exp_5\n# # #     ['ecaresnet26t', '../input/birdcall-models/exp_5/ecaresnet26t/fold-0.bin'], 0.6658 \n    \n    ['tf_efficientnet_b0_ns', '../input/birdcall-models/exp_9/tf_efficientnet_b0_ns/fold-0.bin'], #exp_9\n#     ['mixnet_m', '../input/birdcall-models/exp_9/mixnet_m/fold-0.bin'], #exp_9\n#     ['resnest50d_1s4x24d', '../input/birdcall-models/exp_9/resnest50d_1s4x24d/fold-0.bin'], #exp_9\n#     ['ecaresnet26t', '../input/birdcall-models/exp_9/ecaresnet26t/fold-0.bin'],#exp_9\n    ['efficientnet_b0', '../input/birdcall-models/exp_9/efficientnet_b0/fold-0.bin'],#exp_9\n    ['tf_efficientnetv2_m', '../input/birdcall-models/exp_9/tf_efficientnetv2_m/fold-0.bin'],#exp_9\n    ['tf_efficientnetv2_s', '../input/birdcall-models/exp_9/tf_efficientnetv2_s/fold-0.bin'],#exp_9\n     ['tf_efficientnet_b1_ns', '../input/birdcall-models/tf_efficientnet_b1_ns/fold-0.bin'],#exp_9\n     ['tf_efficientnet_b2_ns', '../input/birdcall-models/tf_efficientnet_b2_ns/fold-0.bin'],#exp_9\n#      ['tf_efficientnetv2_s', '../input/birdcall-models/exp_9/tf_efficientnetv2_s/fold-0.bin'],#exp_9\n]\n\nmodels = []\nfor p in model_paths:\n    base_model_name = p[0]\n    model_path = p[1]\n    print(base_model_name)\n    model = TimmSED(\n# #         base_model_name=CFG.base_model_name,\n        base_model_name=base_model_name,\n        pretrained=CFG.pretrained,\n        num_classes=CFG.num_classes,\n        in_channels=CFG.in_channels)\n    \n    model.to(device)\n    model.load_state_dict(torch.load(model_path))\n    model.eval()\n    models.append(model)\n    \nprint()","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:44:11.187616Z","iopub.execute_input":"2022-05-17T12:44:11.187875Z","iopub.status.idle":"2022-05-17T12:44:24.571583Z","shell.execute_reply.started":"2022-05-17T12:44:11.187845Z","shell.execute_reply":"2022-05-17T12:44:24.570792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TARGET_SR = 32000\nDATADIR = Path(\"../input/birdclef-2022/test_soundscapes/\")","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:44:24.572878Z","iopub.execute_input":"2022-05-17T12:44:24.573136Z","iopub.status.idle":"2022-05-17T12:44:24.577376Z","shell.execute_reply.started":"2022-05-17T12:44:24.573098Z","shell.execute_reply":"2022-05-17T12:44:24.576655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_audios = list(DATADIR.glob(\"*.ogg\"))\nsample_submission = pd.read_csv('../input/birdclef-2022/sample_submission.csv')\nsample_submission","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:44:24.578712Z","iopub.execute_input":"2022-05-17T12:44:24.579495Z","iopub.status.idle":"2022-05-17T12:44:24.613432Z","shell.execute_reply.started":"2022-05-17T12:44:24.579455Z","shell.execute_reply":"2022-05-17T12:44:24.612785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def prediction_for_clip(test_df: pd.DataFrame, \n                        clip: np.ndarray, \n                        models, \n                        threshold=0.05, \n                        threshold_long=None):\n\n    dataset = TestDataset(df=test_df, \n                          clip=clip,)\n    loader = torchdata.DataLoader(dataset, batch_size=1, shuffle=False)\n    device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n    \n#     [model.eval() for model in models]\n    prediction_dict = {}\n    for data in tqdm(loader):\n        row_id = data['row_id'][0]\n        image = data['image'].to(device)\n\n        with torch.no_grad():\n            probas = []\n            probas_long = []\n            for model in models:\n                with torch.cuda.amp.autocast():\n                    output = model(image)\n                probas.append(output['clipwise_output'].detach().cpu().numpy().reshape(-1))\n                # probas_long.append(clipwise_pred_long.detach().cpu().numpy().reshape(-1))\n            probas = np.array(probas)\n            # probas_long = np.array(probas_long)\n#             probas = np.array([model(image)[1].detach().cpu().numpy().reshape(-1) for model in models])\n        if threshold_long is None:\n            events = probas.mean(0) >= threshold\n        else:\n            events = ((probas.mean(0) >= threshold).astype(int) \\\n                      + (probas_long.mean(0) >= threshold_long).astype(int)) >= 2\n        labels = np.argwhere(events).reshape(-1).tolist()\n#         labels = labels[:2]\n        if len(labels) == 0:\n            prediction_dict[str(row_id)] = \"nocall\"\n        else:\n            labels_str_list = list(map(lambda x: CFG.target_columns[x], labels))\n            label_string = \" \".join(labels_str_list)\n            prediction_dict[str(row_id)] = label_string\n    return prediction_dict","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:45:14.137378Z","iopub.execute_input":"2022-05-17T12:45:14.138227Z","iopub.status.idle":"2022-05-17T12:45:14.150414Z","shell.execute_reply.started":"2022-05-17T12:45:14.138181Z","shell.execute_reply":"2022-05-17T12:45:14.149542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def prediction(test_audios,\n               threshold=0.06, \n               threshold_long=None):\n    \n    # models = [model]\n    warnings.filterwarnings(\"ignore\")\n    prediction_dicts = {}\n    for audio_path in test_audios:\n        with timer(f\"Loading {str(audio_path)}\", logger):\n            clip, _ = sf.read(audio_path, always_2d=True)\n            clip = np.mean(clip, 1)\n            \n        seconds = []\n        row_ids = []\n        for second in range(5, 65, 5):\n            row_id = \"_\".join(audio_path.name.split(\".\")[:-1]) + f\"_{second}\"\n            seconds.append(second)\n            row_ids.append(row_id)\n        print(row_ids)\n        test_df = pd.DataFrame({\n            \"row_id\": row_ids,\n            \"seconds\": seconds\n        })\n        with timer(f\"Prediction on {audio_path}\", logger):\n            prediction_dict = prediction_for_clip(test_df,\n                                                  clip=clip,\n                                                  models=models,\n                                                  threshold=threshold, threshold_long=threshold_long)\n#         row_id = list(prediction_dict.keys())\n#         birds = list(prediction_dict.values())\n#         prediction_df = pd.DataFrame({\n#             \"row_id\": row_id,\n#             \"birds\": birds\n#         })\n#         prediction_dfs.append(prediction_df)\n#     prediction_df = pd.concat(prediction_dfs, axis=0, sort=False).reset_index(drop=True)\n        prediction_dicts.update(prediction_dict)\n    return prediction_dicts","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:45:14.905118Z","iopub.execute_input":"2022-05-17T12:45:14.905648Z","iopub.status.idle":"2022-05-17T12:45:14.914971Z","shell.execute_reply.started":"2022-05-17T12:45:14.905614Z","shell.execute_reply":"2022-05-17T12:45:14.914092Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"threshold = 0.04\nthreshold_long = None\n\nprediction_dicts = prediction(test_audios=all_audios,\n           threshold=threshold, \n           threshold_long=threshold_long)\nprint(prediction_dicts)\n\nfor i in range(len(sample_submission)):\n    sample = sample_submission.row_id[i]\n    key = sample.split(\"_\")[0] + \"_\" + sample.split(\"_\")[1] + \"_\" + sample.split(\"_\")[3]\n    target_bird = sample.split(\"_\")[2]\n    print(key, target_bird)\n    if key in prediction_dicts:\n        sample_submission.iat[i, 1] = (target_bird in prediction_dicts[key])\nsample_submission.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:45:15.657008Z","iopub.execute_input":"2022-05-17T12:45:15.657279Z","iopub.status.idle":"2022-05-17T12:45:19.608185Z","shell.execute_reply.started":"2022-05-17T12:45:15.65725Z","shell.execute_reply":"2022-05-17T12:45:19.60722Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_submission","metadata":{"execution":{"iopub.status.busy":"2022-05-17T12:45:22.960151Z","iopub.execute_input":"2022-05-17T12:45:22.96047Z","iopub.status.idle":"2022-05-17T12:45:22.969657Z","shell.execute_reply.started":"2022-05-17T12:45:22.960435Z","shell.execute_reply":"2022-05-17T12:45:22.9688Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}