{"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":"import os\nimport ast\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')\nfrom timm import create_model","metadata":{"execution":{"iopub.status.busy":"2022-04-20T08:09:53.810650Z","iopub.execute_input":"2022-04-20T08:09:53.810951Z","iopub.status.idle":"2022-04-20T08:09:57.825998Z","shell.execute_reply.started":"2022-04-20T08:09:53.810872Z","shell.execute_reply":"2022-04-20T08:09:57.825142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# loading training data","metadata":{}},{"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: eval(x))\ntrain['len_new_target'] = train['new_target'].map(lambda x: len(x))\ntrain['full_path'] = train.filename.map(lambda x: '../input/birdclef-2022/train_audio/' + str(x))","metadata":{"execution":{"iopub.status.busy":"2022-04-20T08:09:57.829663Z","iopub.execute_input":"2022-04-20T08:09:57.830237Z","iopub.status.idle":"2022-04-20T08:09:58.158309Z","shell.execute_reply.started":"2022-04-20T08:09:57.830204Z","shell.execute_reply":"2022-04-20T08:09:58.157616Z"},"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-04-20T08:09:58.159707Z","iopub.execute_input":"2022-04-20T08:09:58.159948Z","iopub.status.idle":"2022-04-20T08:09:58.192945Z","shell.execute_reply.started":"2022-04-20T08:09:58.159915Z","shell.execute_reply":"2022-04-20T08:09:58.191714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Creating dataset","metadata":{}},{"cell_type":"code","source":"SAMPLE_RATE = 32000\nNUM_SAMPLES = 22050\nN_SEC = 5\nVAL_FOLD = 0","metadata":{"execution":{"iopub.status.busy":"2022-04-20T08:09:58.194758Z","iopub.execute_input":"2022-04-20T08:09:58.195061Z","iopub.status.idle":"2022-04-20T08:09:58.199042Z","shell.execute_reply.started":"2022-04-20T08:09:58.195025Z","shell.execute_reply":"2022-04-20T08:09:58.198336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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 encodes(self, x):\n        return x.new_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):self.num_samples = num_samples\n    def encodes(self, x):\n        signal, device = x\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=32000,\n                      n_fft=1024,\n                      hop_length=512,\n                      n_mels=64):\n        \n         self.sample_rate = sample_rate\n         self.n_fft = n_fft\n         self.hop_length = hop_length\n         self.n_mels = n_mels\n         self.mel_spectrogram = torchaudio.transforms.MelSpectrogram(\n                sample_rate=self.sample_rate,\n                n_fft=self.n_fft,\n                hop_length=self.hop_length,\n                n_mels=self.n_mels\n            ) \n           \n    def encodes(self, x):\n        signal = self.mel_spectrogram(x)\n        signal = signal.repeat(3,1,1)\n        return signal\n\nclass ohe(Transform):\n    def __init__(self,targets):\n        self.mlb = MultiLabelBinarizer()\n        self.mlb.fit(targets.tolist())\n    def encodes(self, x):\n        return tensor(self.mlb.transform([x])).view(-1)","metadata":{"execution":{"iopub.status.busy":"2022-04-20T08:09:58.200598Z","iopub.execute_input":"2022-04-20T08:09:58.201135Z","iopub.status.idle":"2022-04-20T08:09:58.220739Z","shell.execute_reply.started":"2022-04-20T08:09:58.201097Z","shell.execute_reply":"2022-04-20T08:09:58.219968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_dls(val_fold):\n    splits = [train[train.kfold != val_fold].index.tolist() , train[train.kfold == val_fold].index.tolist()]\n    ","metadata":{"execution":{"iopub.status.busy":"2022-04-20T08:09:58.223406Z","iopub.execute_input":"2022-04-20T08:09:58.223626Z","iopub.status.idle":"2022-04-20T08:09:58.232987Z","shell.execute_reply.started":"2022-04-20T08:09:58.223594Z","shell.execute_reply":"2022-04-20T08:09:58.232269Z"},"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-04-20T08:09:58.234342Z","iopub.execute_input":"2022-04-20T08:09:58.234830Z","iopub.status.idle":"2022-04-20T08:09:58.242262Z","shell.execute_reply.started":"2022-04-20T08:09:58.234794Z","shell.execute_reply":"2022-04-20T08:09:58.241399Z"},"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(SAMPLE_RATE*N_SEC),right_pad_if_necessary,\n              mel_spec(SAMPLE_RATE)]\n\n    y_tfms = [get_audio_sample_label,ohe(train['new_target'])]\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-04-20T08:09:58.243795Z","iopub.execute_input":"2022-04-20T08:09:58.244046Z","iopub.status.idle":"2022-04-20T08:09:58.252306Z","shell.execute_reply.started":"2022-04-20T08:09:58.244012Z","shell.execute_reply":"2022-04-20T08:09:58.251626Z"},"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-04-20T08:09:58.253185Z","iopub.execute_input":"2022-04-20T08:09:58.253447Z","iopub.status.idle":"2022-04-20T08:10:06.595066Z","shell.execute_reply.started":"2022-04-20T08:09:58.253361Z","shell.execute_reply":"2022-04-20T08:10:06.594373Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class building_model(Module):\n    def __init__(self,num_classes:int,arch:str ='efficientnet_b0', pretrained:bool=True):\n        self.model = create_model(arch, pretrained=pretrained)\n        self.linear = nn.Linear(self.model.get_classifier().out_features, num_classes)\n       \n    def forward(self,x):\n        features = self.model(x)\n        output = self.linear(features)\n        return output","metadata":{"execution":{"iopub.status.busy":"2022-04-20T08:10:06.597288Z","iopub.execute_input":"2022-04-20T08:10:06.597496Z","iopub.status.idle":"2022-04-20T08:10:06.605508Z","shell.execute_reply.started":"2022-04-20T08:10:06.597471Z","shell.execute_reply":"2022-04-20T08:10:06.604838Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# metric","metadata":{}},{"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_pred = nn.functional.sigmoid(y_pred).cpu().numpy()\n        y_pred = np.where(y_pred > 0.5, 1, 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-04-20T08:10:06.606902Z","iopub.execute_input":"2022-04-20T08:10:06.607148Z","iopub.status.idle":"2022-04-20T08:10:06.617335Z","shell.execute_reply.started":"2022-04-20T08:10:06.607117Z","shell.execute_reply":"2022-04-20T08:10:06.616631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dls = get_dls(val_fold=0,bs=64)","metadata":{"execution":{"iopub.status.busy":"2022-04-20T08:10:06.618373Z","iopub.execute_input":"2022-04-20T08:10:06.618646Z","iopub.status.idle":"2022-04-20T08:10:06.816212Z","shell.execute_reply.started":"2022-04-20T08:10:06.618613Z","shell.execute_reply":"2022-04-20T08:10:06.815507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = building_model(num_classes=152,pretrained=False)\n#model = resnet18(num_classes=152)\nlearn = Learner(dls,model,loss_func=BCEWithLogitsLossFlat(),metrics=comp_metric)\nlearn.summary()","metadata":{"execution":{"iopub.status.busy":"2022-04-20T08:10:06.817288Z","iopub.execute_input":"2022-04-20T08:10:06.819203Z","iopub.status.idle":"2022-04-20T08:10:16.127164Z","shell.execute_reply.started":"2022-04-20T08:10:06.819172Z","shell.execute_reply":"2022-04-20T08:10:16.126379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn.lr_find()","metadata":{"execution":{"iopub.status.busy":"2022-04-20T08:10:16.129516Z","iopub.execute_input":"2022-04-20T08:10:16.129902Z","iopub.status.idle":"2022-04-20T08:15:42.062257Z","shell.execute_reply.started":"2022-04-20T08:10:16.129864Z","shell.execute_reply":"2022-04-20T08:15:42.061511Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn.fit_one_cycle(10,lr_max=1e-3)","metadata":{"execution":{"iopub.status.busy":"2022-04-20T08:15:42.063879Z","iopub.execute_input":"2022-04-20T08:15:42.064298Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn.export(fname='model.pkl')","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}