{"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-06T10:29:41.557389Z","iopub.execute_input":"2022-05-06T10:29:41.557865Z","iopub.status.idle":"2022-05-06T10:29:57.340796Z","shell.execute_reply.started":"2022-05-06T10:29:41.557758Z","shell.execute_reply":"2022-05-06T10:29:57.339596Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport ast\nimport numpy as np\nimport warnings\nfrom sklearn import metrics\nfrom torch.utils.data import Dataset\nimport pandas as pd\nimport torchaudio\nimport glob\nfrom sklearn.model_selection import StratifiedKFold, GroupKFold\nimport os\nfrom torch.utils.data import Dataset\nimport pandas as pd\nimport torchaudio\nfrom sklearn.preprocessing import MultiLabelBinarizer\nfrom fastai.vision.all import *\nfrom typing import Optional,Tuple,List\nsys.path.append('../input/timm-pytorch-image-models/pytorch-image-models-master')\nimport timm\nfrom timm import create_model\n#new\nimport audioread\nimport librosa\nimport soundfile as sf\nfrom albumentations.core.transforms_interface import ImageOnlyTransform\nfrom torchlibrosa.stft import LogmelFilterBank, Spectrogram\nfrom torchlibrosa.augmentation import SpecAugmentation\n\nimport albumentations as A\nimport albumentations.pytorch.transforms as T\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:29:57.347269Z","iopub.execute_input":"2022-05-06T10:29:57.350038Z","iopub.status.idle":"2022-05-06T10:30:05.005967Z","shell.execute_reply.started":"2022-05-06T10:29:57.349955Z","shell.execute_reply":"2022-05-06T10:30:05.004891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class AudioParams:\n    sr = 32000\n    duration = 5\n    n_samples = sr * duration\n    # Melspectrogram\n    n_mels = 224\n    fmin = 20\n    fmax = 16000\n    hop_length = 512\n    n_fft = 2048\n    window = 'hann'\n    mode = 'train'\n    #train\n    bs = 16\n    \nparams = AudioParams\nMODE = 'train'","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:05.007940Z","iopub.execute_input":"2022-05-06T10:30:05.008297Z","iopub.status.idle":"2022-05-06T10:30:05.015033Z","shell.execute_reply.started":"2022-05-06T10:30:05.008253Z","shell.execute_reply":"2022-05-06T10:30:05.014046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# loading training data","metadata":{}},{"cell_type":"code","source":"scored_classes = [\"akiapo\",\"aniani\",\"apapan\",\"barpet\",\"crehon\",\"elepai\"\n                  ,\"ercfra\",\"hawama\",\"hawcre\",\"hawgoo\",\"hawhaw\",\"hawpet1\",\"houfin\"\n                  ,\"iiwi\",\"jabwar\",\"maupar\",\"omao\",\"puaioh\",\"skylar\",\"warwhe1\",\"yefcan\"]","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:05.018028Z","iopub.execute_input":"2022-05-06T10:30:05.018565Z","iopub.status.idle":"2022-05-06T10:30:05.029854Z","shell.execute_reply.started":"2022-05-06T10:30:05.018509Z","shell.execute_reply":"2022-05-06T10:30:05.028803Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv('../input/birdclef-2022/train_metadata.csv')\ntrain['new_target'] = train['primary_label'].map(lambda x: [x]) + train['secondary_labels'].map(lambda x: [i for i in eval(x) if i in scored_classes])\ntrain['len_new_target'] = train['new_target'].map(lambda x: len(x))\ntrain['full_path'] = train.filename.map(lambda x: '../input/birdclef2022-audio-image-dataset/' + str(x) + '.npy')\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:05.031578Z","iopub.execute_input":"2022-05-06T10:30:05.031929Z","iopub.status.idle":"2022-05-06T10:30:05.276316Z","shell.execute_reply.started":"2022-05-06T10:30:05.031880Z","shell.execute_reply":"2022-05-06T10:30:05.275214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#train = train[train.primary_label.isin(scored_classes)]\n#train.reset_index(inplace=True)","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:05.278306Z","iopub.execute_input":"2022-05-06T10:30:05.278682Z","iopub.status.idle":"2022-05-06T10:30:05.283448Z","shell.execute_reply.started":"2022-05-06T10:30:05.278637Z","shell.execute_reply":"2022-05-06T10:30:05.281908Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Fold = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)\nfor n, (trn_index, val_index) in enumerate(Fold.split(train, train['primary_label'])):\n    train.loc[val_index, 'kfold'] = int(n)\ntrain['kfold'] = train['kfold'].astype(int)","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:05.285427Z","iopub.execute_input":"2022-05-06T10:30:05.285938Z","iopub.status.idle":"2022-05-06T10:30:05.330509Z","shell.execute_reply.started":"2022-05-06T10:30:05.285893Z","shell.execute_reply":"2022-05-06T10:30:05.329490Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Creating dataset","metadata":{}},{"cell_type":"code","source":"class get_audio_sample_path(Transform):\n    def encodes(self, x):\n        return x.full_path\n    \nclass get_audio_sample_label(Transform):\n    def __init__(self,scored_classes=scored_classes):\n        self.scored_classes = scored_classes\n        self.target = []\n        \n    def encodes(self,x):\n        for _class in x.new_target:\n            if _class in self.scored_classes:\n                self.target.append(_class)\n        return self.target\n\nclass load_signal(Transform):\n    def __init__(self,device='cpu'):self.device=device\n    def encodes(self, x:str):\n        signal, sr = torchaudio.load(x)\n        return [signal,sr,self.device]\n\nclass resample_if_necessary(Transform):\n    def __init__(self,target_sample_rate):self.target_sample_rate = target_sample_rate\n    def encodes(self, x):\n        signal, sr ,device= x\n        if sr != self.target_sample_rate:\n            resampler = torchaudio.transforms.Resample(sr, self.target_sample_rate)\n            signal = resampler(signal)\n            signal = signal\n        return [signal, device]\n\nclass mix_down_if_necessary(Transform):\n    def encodes(self, x):\n        signal, device= x\n        if signal.shape[0] > 1:\n            signal = torch.mean(signal, dim=0, keepdim=True)\n        return [signal, device]\n\nclass cut_if_necessary(Transform):\n    def __init__(self,num_samples=params.n_samples):\n        self.num_samples = num_samples\n    def encodes(self, x):\n        signal, device = x\n        if MODE == 'train':\n            if signal.shape[1] > self.num_samples:\n                diff = signal.shape[1] - self.num_samples\n                start = random.randint(0,diff)\n                end = start + self.num_samples\n                signal = signal[:,start:end]\n        else:       \n            if signal.shape[1] > self.num_samples:\n                signal = signal[:, :self.num_samples]\n        return [signal, self.num_samples, device]\n\nclass right_pad_if_necessary(Transform):\n    def encodes(self, x):\n        signal, num_samples, device = x\n        length_signal = signal.shape[1]\n        if length_signal < num_samples:\n            num_missing_samples = num_samples - length_signal\n            last_dim_padding = (0, num_missing_samples)\n            signal = torch.nn.functional.pad(signal, last_dim_padding)\n        return signal\n\nclass mel_spec(Transform):\n    def __init__(self,sample_rate=params.sr,\n                      n_fft = params.n_fft,\n                      hop_length=params.hop_length,\n                      n_mels=params.n_mels,\n                      fmin = params.fmin,\n                      fmax = params.fmax,\n                      window = params.window):\n\n        self.mel_spectrogram = torchaudio.transforms.MelSpectrogram(\n                sample_rate=sample_rate,n_fft=n_fft,f_min=fmin,f_max=fmax,\n                hop_length=hop_length,n_mels=n_mels)   \n        self.db = torchaudio.transforms.AmplitudeToDB()\n        \n    def encodes(self, x):\n        melspec = self.mel_spectrogram(x)\n        melspec = self.db(melspec)\n        return melspec\n\nclass mono_to_color(Transform):\n    def __init__(self,mean=None, std=None,  eps=1e-6):\n        self.mean = mean\n        self.std = std\n        self.eps = eps\n        \n    def encodes(self,x):\n        X = x.repeat([3,1,1])\n        mean = self.mean or X.mean()\n        std = self.std or X.std()\n        X = (X - mean) / (std + self.eps)\n        _min, _max = X.min(), X.max()\n        if (_max - _min) > self.eps:\n            V = torch.clip(X, _min, _max)\n            V = 255 * (V - _min) / (_max - _min)\n            V = V.type(torch.FloatTensor)\n        else:\n            V = torch.zeros_like(X, dtype=torch.FloatTensor)\n        V = V.transpose(1,2)\n        return V\n    \nclass ohe(Transform):\n    def __init__(self,targets):\n        self.mlb = MultiLabelBinarizer()\n        self.mlb.fit(targets.tolist())\n        self.vocab = self.mlb.classes_\n    def encodes(self, x):\n        return self.mlb.transform([x]).reshape(-1).astype(np.float32)\n\nclass get_sound_images(Transform):\n    def encodes(self,x):\n        image = np.load(x) # (224, 313, 3)\n        image = albu_transforms[params.mode](image=image)['image']\n        image = image.T\n        return image","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:05.332254Z","iopub.execute_input":"2022-05-06T10:30:05.332782Z","iopub.status.idle":"2022-05-06T10:30:05.366379Z","shell.execute_reply.started":"2022-05-06T10:30:05.332739Z","shell.execute_reply":"2022-05-06T10:30:05.365151Z"},"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-06T10:30:05.370090Z","iopub.execute_input":"2022-05-06T10:30:05.370375Z","iopub.status.idle":"2022-05-06T10:30:05.386135Z","shell.execute_reply.started":"2022-05-06T10:30:05.370346Z","shell.execute_reply":"2022-05-06T10:30:05.384986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if torch.cuda.is_available():\n        device = \"cuda\"\nelse:\n        device = \"cpu\"\nprint(f\"Using {device}\")","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:05.391561Z","iopub.execute_input":"2022-05-06T10:30:05.392403Z","iopub.status.idle":"2022-05-06T10:30:05.399827Z","shell.execute_reply.started":"2022-05-06T10:30:05.392360Z","shell.execute_reply":"2022-05-06T10:30:05.398304Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_fold = 0\ndef get_dls(val_fold=0,bs=64):\n    splits = [train[train.kfold != val_fold].index.tolist() , train[train.kfold == val_fold].index.tolist()]\n    #x_tfms = [get_audio_sample_path,load_signal(device),resample_if_necessary(32000),\n    #          mix_down_if_necessary,cut_if_necessary(),right_pad_if_necessary,\n    #          mel_spec,mono_to_color]\n    x_tfms = [get_audio_sample_path,get_sound_images,ToTensor]\n    y_tfms = [get_audio_sample_label,ohe(train['new_target']),ToTensor]\n\n    dsets = Datasets(items = train ,tfms=[x_tfms, y_tfms],splits=splits)\n\n    dls = dsets.dataloaders(bs=bs)   \n    return dls","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:05.401830Z","iopub.execute_input":"2022-05-06T10:30:05.402319Z","iopub.status.idle":"2022-05-06T10:30:05.412289Z","shell.execute_reply.started":"2022-05-06T10:30:05.402275Z","shell.execute_reply":"2022-05-06T10:30:05.410883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"xb, yb = get_dls(val_fold=0,bs=64).one_batch()\nxb.shape, yb.shape","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:05.414169Z","iopub.execute_input":"2022-05-06T10:30:05.414745Z","iopub.status.idle":"2022-05-06T10:30:09.914975Z","shell.execute_reply.started":"2022-05-06T10:30:05.414699Z","shell.execute_reply":"2022-05-06T10:30:09.914048Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dls = get_dls(val_fold=0,bs=params.bs)","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:09.916751Z","iopub.execute_input":"2022-05-06T10:30:09.917250Z","iopub.status.idle":"2022-05-06T10:30:10.014834Z","shell.execute_reply.started":"2022-05-06T10:30:09.917207Z","shell.execute_reply":"2022-05-06T10:30:10.013788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Creating the model","metadata":{}},{"cell_type":"code","source":"def interpolate(x: torch.Tensor, ratio: int):\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    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","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:10.016368Z","iopub.execute_input":"2022-05-06T10:30:10.016660Z","iopub.status.idle":"2022-05-06T10:30:10.024961Z","shell.execute_reply.started":"2022-05-06T10:30:10.016620Z","shell.execute_reply":"2022-05-06T10:30:10.023998Z"},"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\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        \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)","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:10.026997Z","iopub.execute_input":"2022-05-06T10:30:10.027670Z","iopub.status.idle":"2022-05-06T10:30:10.047330Z","shell.execute_reply.started":"2022-05-06T10:30:10.027623Z","shell.execute_reply":"2022-05-06T10:30:10.045979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import random\nclass building_model(Module):\n    def __init__(self,num_classes:int,arch:str ='efficientnet_b0', pretrained:bool=False):\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        self.bn0 = nn.BatchNorm2d(params.n_mels)\n        self.base_model = create_model(arch, pretrained=pretrained)\n        self.linear = nn.Linear(self.base_model.get_classifier().out_features, num_classes)\n        self.layers = list(self.base_model.children())[:-2]\n        self.encoder = nn.Sequential(*self.layers)\n        self.in_features = self.base_model.classifier.in_features\n        self.fc1 = nn.Linear(self.in_features, self.in_features, bias=True)\n        self.fc2 = nn.Linear(num_classes,num_classes, bias=False)\n\n        self.drop_1 = nn.Dropout(0.5)\n        self.drop_2 = nn.Dropout(0.5)\n        self.att_block = AttBlockV2(self.in_features, num_classes, activation=\"sigmoid\")  \n        self.init_weight()\n        self.mode = 'train'\n    def init_weight(self):\n        init_bn(self.bn0)\n        init_layer(self.fc1)\n        \n    def change_mode(self,mode='train'):\n        self.mode = mode\n\n    def forward(self,input_data):\n        frames_num = input_data.shape[2]\n        x = input_data # (batch_size, 3, time_steps, mel_bins)\n        x = x.transpose(1, 3)\n        x = self.bn0(x)\n        x = x.transpose(1, 3)\n\n        if self.mode == 'train':\n            if random.random() < 0.75:\n                x = self.spec_augmenter(x)\n                \n        x = x.transpose(2, 3)\n        x = self.encoder(x)  \n        x = torch.mean(x, dim=3)\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        x = self.drop_1(x)\n        x = x.transpose(1, 2)\n        x = F.relu_(self.fc1(x))\n        x = x.transpose(1, 2)\n        x = self.drop_2(x)\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-06T10:30:10.049190Z","iopub.execute_input":"2022-05-06T10:30:10.049523Z","iopub.status.idle":"2022-05-06T10:30:10.072352Z","shell.execute_reply.started":"2022-05-06T10:30:10.049471Z","shell.execute_reply":"2022-05-06T10:30:10.071354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loss","metadata":{}},{"cell_type":"code","source":"# https://www.kaggle.com/c/rfcx-species-audio-detection/discussion/213075\nclass BCEFocalLoss(nn.Module):\n    def __init__(self, alpha=0.25, gamma=2.0):\n        super().__init__()\n        self.alpha = alpha\n        self.gamma = gamma\n\n    def forward(self, preds, targets):\n        bce_loss = nn.BCEWithLogitsLoss(reduction='none')(preds, targets)\n        probas = torch.sigmoid(preds)\n        loss = targets * self.alpha * \\\n            (1. - probas)**self.gamma * bce_loss + \\\n            (1. - targets) * probas**self.gamma * bce_loss\n        loss = loss.mean()\n        return loss\n\n\nclass BCEFocal2WayLoss(nn.Module):\n    def __init__(self, weights=[1, 1], class_weights=None):\n        super().__init__()\n\n        self.focal = BCEFocalLoss()\n\n        self.weights = weights\n\n    def forward(self, input, target):\n        input_ = input[\"logit\"]\n        target = target.float()\n\n        framewise_output = input[\"framewise_logit\"]\n        clipwise_output_with_max, _ = framewise_output.max(dim=1)\n\n        loss = self.focal(input_, target)\n        aux_loss = self.focal(clipwise_output_with_max, target)\n\n        return self.weights[0] * loss + self.weights[1] * aux_loss","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:10.074045Z","iopub.execute_input":"2022-05-06T10:30:10.074405Z","iopub.status.idle":"2022-05-06T10:30:10.090059Z","shell.execute_reply.started":"2022-05-06T10:30:10.074362Z","shell.execute_reply":"2022-05-06T10:30:10.089033Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def loss_fn(logits, targets):\n    loss_fct = BCEFocal2WayLoss()\n    loss = loss_fct(logits, targets)\n    return loss","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:10.091750Z","iopub.execute_input":"2022-05-06T10:30:10.092485Z","iopub.status.idle":"2022-05-06T10:30:10.104464Z","shell.execute_reply.started":"2022-05-06T10:30:10.092441Z","shell.execute_reply":"2022-05-06T10:30:10.103423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# metric","metadata":{}},{"cell_type":"code","source":"label_mask = []\nfor n,x in enumerate(dls.vocab):\n    if x in scored_classes:\n        label_mask.append(n)","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:10.106591Z","iopub.execute_input":"2022-05-06T10:30:10.106967Z","iopub.status.idle":"2022-05-06T10:30:10.117225Z","shell.execute_reply.started":"2022-05-06T10:30:10.106925Z","shell.execute_reply":"2022-05-06T10:30:10.116224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_mask","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:10.118804Z","iopub.execute_input":"2022-05-06T10:30:10.119397Z","iopub.status.idle":"2022-05-06T10:30:10.132018Z","shell.execute_reply.started":"2022-05-06T10:30:10.119340Z","shell.execute_reply":"2022-05-06T10:30:10.131072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def MetricMeter(y_pred, y_true):\n    with torch.no_grad():\n        y_true = y_true.cpu().detach().numpy()\n        y_true = y_true[:,label_mask]\n        y_pred = y_pred[\"clipwise_output\"].cpu().detach().numpy()\n        y_pred = y_pred[:,label_mask]\n        y_pred = np.where(y_pred > 0.3,1.0,0.0)\n        f1_03 = metrics.f1_score(y_true,y_pred, average=\"micro\")        \n        return f1_03","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:10.133873Z","iopub.execute_input":"2022-05-06T10:30:10.134193Z","iopub.status.idle":"2022-05-06T10:30:10.143361Z","shell.execute_reply.started":"2022-05-06T10:30:10.134151Z","shell.execute_reply":"2022-05-06T10:30:10.142208Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport sklearn.metrics\n\ndef comp_metric(y_pred, y_true, epsilon=1e-9):\n    with torch.no_grad():\n        y_true = y_true.cpu().numpy()\n        y_true = y_true[:,label_mask]\n        y_pred = y_pred[\"clipwise_output\"].cpu().numpy()\n        y_pred = y_pred[:,label_mask]\n        y_pred = np.where(y_pred > 0.3, 1.0, 0.0)\n    # Get representative confusion matrices for each label\n    mlbl_cms = sklearn.metrics.multilabel_confusion_matrix(y_true, y_pred)\n\n    # Get two scores (TP and TN SCORES)\n    tp_scores = np.array([\n        mlbl_cm[1, 1]/(epsilon+mlbl_cm[:, 1].sum()) \\\n        for mlbl_cm in mlbl_cms\n        ])\n    tn_scores = np.array([\n        mlbl_cm[0, 0]/(epsilon+mlbl_cm[:, 0].sum()) \\\n        for mlbl_cm in mlbl_cms\n        ])\n\n    # Get average\n    tp_mean = tp_scores.mean()\n    tn_mean = tn_scores.mean()\n\n    return round((tp_mean+tn_mean)/2, 8)\n","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:10.145323Z","iopub.execute_input":"2022-05-06T10:30:10.145818Z","iopub.status.idle":"2022-05-06T10:30:10.157462Z","shell.execute_reply.started":"2022-05-06T10:30:10.145759Z","shell.execute_reply":"2022-05-06T10:30:10.156219Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"target_cols = dls.vocab","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:10.159515Z","iopub.execute_input":"2022-05-06T10:30:10.159841Z","iopub.status.idle":"2022-05-06T10:30:10.171013Z","shell.execute_reply.started":"2022-05-06T10:30:10.159800Z","shell.execute_reply":"2022-05-06T10:30:10.169854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"target_cols","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:10.172539Z","iopub.execute_input":"2022-05-06T10:30:10.173121Z","iopub.status.idle":"2022-05-06T10:30:10.185467Z","shell.execute_reply.started":"2022-05-06T10:30:10.172936Z","shell.execute_reply":"2022-05-06T10:30:10.184242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class train_val_clb(Callback):\n        def after_validate(self):\n            self.learn.model.change_mode('train')\n            params.mode = 'train'\n            \n        def before_validate(self):\n            self.learn.model.change_mode('valid')\n            params.mode = 'valid'","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:10.186984Z","iopub.execute_input":"2022-05-06T10:30:10.187604Z","iopub.status.idle":"2022-05-06T10:30:10.196793Z","shell.execute_reply.started":"2022-05-06T10:30:10.187531Z","shell.execute_reply":"2022-05-06T10:30:10.195595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = building_model(num_classes=dls.vocab.shape[0],pretrained=False)\n#model = resnet18(num_classes=152)\nlearn = Learner(dls,model,loss_func=loss_fn,metrics=comp_metric,cbs=[train_val_clb])\n#learn.summary()","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:10.198770Z","iopub.execute_input":"2022-05-06T10:30:10.199303Z","iopub.status.idle":"2022-05-06T10:30:10.365716Z","shell.execute_reply.started":"2022-05-06T10:30:10.199261Z","shell.execute_reply":"2022-05-06T10:30:10.364699Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#learn.lr_find()","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:10.367504Z","iopub.execute_input":"2022-05-06T10:30:10.367944Z","iopub.status.idle":"2022-05-06T10:30:10.373289Z","shell.execute_reply.started":"2022-05-06T10:30:10.367882Z","shell.execute_reply":"2022-05-06T10:30:10.372157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn.fit_one_cycle(20,lr_max=1e-3,cbs=MixUp(0.7))","metadata":{"execution":{"iopub.status.busy":"2022-05-06T10:30:10.380127Z","iopub.execute_input":"2022-05-06T10:30:10.380850Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn.export(fname='model.pkl')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# references","metadata":{}},{"cell_type":"markdown","source":"1- https://www.kaggle.com/code/kaerunantoka/birdclef2022-audio-to-numpy-1-4/notebook\n\n2- https://www.kaggle.com/code/kaerunantoka/birdclef2022-n001-training/notebook","metadata":{}}]}