{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"!pip uninstall torch --y\n!pip uninstall torchaudio --y\n!pip install ../input/pytorch-160-with-torchvision-070/torch-1.6.0cu101-cp37-cp37m-linux_x86_64.whl\n!pip install ../input/torchaudio/torchaudio-0.6.0-cp37-cp37m-manylinux1_x86_64.whl","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install ../input/timm-wheel/*.whl","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### import libraries"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport gc\nimport time\nimport math\nimport shutil\nimport random\nimport warnings\nwarnings.filterwarnings('ignore',\".*PySoundFile\")\nimport os\nfrom joblib import delayed, Parallel\n\nimport cv2\nimport librosa\nimport audioread\nimport soundfile as sf\n\nimport numpy as np\nimport pandas as pd\n\nfrom tqdm import tqdm_notebook as tqdm\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torchaudio\nfrom torch.utils.data import DataLoader\nimport timm\n\npd.options.display.max_rows = 500\npd.options.display.max_columns = 500","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### read data"},{"metadata":{"trusted":true},"cell_type":"code","source":"RAW_DATA = \"../input/birdsong-recognition/\"\nTRAIN_AUDIO_DIR = \"../input/birdsong-recognition/train_audio/\"\nTEST_AUDIO_DIR = \"../input/birdsong-recognition/test_audio/\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = pd.read_csv(RAW_DATA + \"train.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if not os.path.exists(TEST_AUDIO_DIR):\n    print(\"Run check\")\n    TEST_AUDIO_DIR = \"../input/birdcall-check/test_audio/\"\n    test = pd.read_csv(\"../input/birdcall-check/test.csv\")\nelse:\n    print(\"run submission\")\n    test = pd.read_csv(\"../input/birdsong-recognition/test.csv\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### set parameters"},{"metadata":{},"cell_type":"markdown","source":"## Definition"},{"metadata":{},"cell_type":"markdown","source":"### Dataset\n\nFor `site_3`, I decided to use the same procedure as I did for `site_1` and `site_2`, which is, crop 5 seconds out of the clip and provide prediction on that short clip.\nThe only difference is that I crop 5 seconds short clip from start to the end of the `site_3` clip and aggeregate predictions for each short clip after I did prediction for all those short clips."},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"BIRD_CODE = {\n    'aldfly': 0, 'ameavo': 1, 'amebit': 2, 'amecro': 3, 'amegfi': 4,\n    'amekes': 5, 'amepip': 6, 'amered': 7, 'amerob': 8, 'amewig': 9,\n    'amewoo': 10, 'amtspa': 11, 'annhum': 12, 'astfly': 13, 'baisan': 14,\n    'baleag': 15, 'balori': 16, 'banswa': 17, 'barswa': 18, 'bawwar': 19,\n    'belkin1': 20, 'belspa2': 21, 'bewwre': 22, 'bkbcuc': 23, 'bkbmag1': 24,\n    'bkbwar': 25, 'bkcchi': 26, 'bkchum': 27, 'bkhgro': 28, 'bkpwar': 29,\n    'bktspa': 30, 'blkpho': 31, 'blugrb1': 32, 'blujay': 33, 'bnhcow': 34,\n    'boboli': 35, 'bongul': 36, 'brdowl': 37, 'brebla': 38, 'brespa': 39,\n    'brncre': 40, 'brnthr': 41, 'brthum': 42, 'brwhaw': 43, 'btbwar': 44,\n    'btnwar': 45, 'btywar': 46, 'buffle': 47, 'buggna': 48, 'buhvir': 49,\n    'bulori': 50, 'bushti': 51, 'buwtea': 52, 'buwwar': 53, 'cacwre': 54,\n    'calgul': 55, 'calqua': 56, 'camwar': 57, 'cangoo': 58, 'canwar': 59,\n    'canwre': 60, 'carwre': 61, 'casfin': 62, 'caster1': 63, 'casvir': 64,\n    'cedwax': 65, 'chispa': 66, 'chiswi': 67, 'chswar': 68, 'chukar': 69,\n    'clanut': 70, 'cliswa': 71, 'comgol': 72, 'comgra': 73, 'comloo': 74,\n    'commer': 75, 'comnig': 76, 'comrav': 77, 'comred': 78, 'comter': 79,\n    'comyel': 80, 'coohaw': 81, 'coshum': 82, 'cowscj1': 83, 'daejun': 84,\n    'doccor': 85, 'dowwoo': 86, 'dusfly': 87, 'eargre': 88, 'easblu': 89,\n    'easkin': 90, 'easmea': 91, 'easpho': 92, 'eastow': 93, 'eawpew': 94,\n    'eucdov': 95, 'eursta': 96, 'evegro': 97, 'fiespa': 98, 'fiscro': 99,\n    'foxspa': 100, 'gadwal': 101, 'gcrfin': 102, 'gnttow': 103, 'gnwtea': 104,\n    'gockin': 105, 'gocspa': 106, 'goleag': 107, 'grbher3': 108, 'grcfly': 109,\n    'greegr': 110, 'greroa': 111, 'greyel': 112, 'grhowl': 113, 'grnher': 114,\n    'grtgra': 115, 'grycat': 116, 'gryfly': 117, 'haiwoo': 118, 'hamfly': 119,\n    'hergul': 120, 'herthr': 121, 'hoomer': 122, 'hoowar': 123, 'horgre': 124,\n    'horlar': 125, 'houfin': 126, 'houspa': 127, 'houwre': 128, 'indbun': 129,\n    'juntit1': 130, 'killde': 131, 'labwoo': 132, 'larspa': 133, 'lazbun': 134,\n    'leabit': 135, 'leafly': 136, 'leasan': 137, 'lecthr': 138, 'lesgol': 139,\n    'lesnig': 140, 'lesyel': 141, 'lewwoo': 142, 'linspa': 143, 'lobcur': 144,\n    'lobdow': 145, 'logshr': 146, 'lotduc': 147, 'louwat': 148, 'macwar': 149,\n    'magwar': 150, 'mallar3': 151, 'marwre': 152, 'merlin': 153, 'moublu': 154,\n    'mouchi': 155, 'moudov': 156, 'norcar': 157, 'norfli': 158, 'norhar2': 159,\n    'normoc': 160, 'norpar': 161, 'norpin': 162, 'norsho': 163, 'norwat': 164,\n    'nrwswa': 165, 'nutwoo': 166, 'olsfly': 167, 'orcwar': 168, 'osprey': 169,\n    'ovenbi1': 170, 'palwar': 171, 'pasfly': 172, 'pecsan': 173, 'perfal': 174,\n    'phaino': 175, 'pibgre': 176, 'pilwoo': 177, 'pingro': 178, 'pinjay': 179,\n    'pinsis': 180, 'pinwar': 181, 'plsvir': 182, 'prawar': 183, 'purfin': 184,\n    'pygnut': 185, 'rebmer': 186, 'rebnut': 187, 'rebsap': 188, 'rebwoo': 189,\n    'redcro': 190, 'redhea': 191, 'reevir1': 192, 'renpha': 193, 'reshaw': 194,\n    'rethaw': 195, 'rewbla': 196, 'ribgul': 197, 'rinduc': 198, 'robgro': 199,\n    'rocpig': 200, 'rocwre': 201, 'rthhum': 202, 'ruckin': 203, 'rudduc': 204,\n    'rufgro': 205, 'rufhum': 206, 'rusbla': 207, 'sagspa1': 208, 'sagthr': 209,\n    'savspa': 210, 'saypho': 211, 'scatan': 212, 'scoori': 213, 'semplo': 214,\n    'semsan': 215, 'sheowl': 216, 'shshaw': 217, 'snobun': 218, 'snogoo': 219,\n    'solsan': 220, 'sonspa': 221, 'sora': 222, 'sposan': 223, 'spotow': 224,\n    'stejay': 225, 'swahaw': 226, 'swaspa': 227, 'swathr': 228, 'treswa': 229,\n    'truswa': 230, 'tuftit': 231, 'tunswa': 232, 'veery': 233, 'vesspa': 234,\n    'vigswa': 235, 'warvir': 236, 'wesblu': 237, 'wesgre': 238, 'weskin': 239,\n    'wesmea': 240, 'wessan': 241, 'westan': 242, 'wewpew': 243, 'whbnut': 244,\n    'whcspa': 245, 'whfibi': 246, 'whtspa': 247, 'whtswi': 248, 'wilfly': 249,\n    'wilsni1': 250, 'wiltur': 251, 'winwre3': 252, 'wlswar': 253, 'wooduc': 254,\n    'wooscj2': 255, 'woothr': 256, 'y00475': 257, 'yebfly': 258, 'yebsap': 259,\n    'yehbla': 260, 'yelwar': 261, 'yerwar': 262, 'yetvir': 263,'nocall':-1,\n}\n\nINV_BIRD_CODE = {v: k for k, v in BIRD_CODE.items()}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"class Dataset_Test:\n    def __init__(\n            self,\n            df,\n            data_dir,\n            sample_rate=32000,\n            duration=5,\n            waveform_transforms=None):\n        self.data_dir=data_dir\n        self.clip_frames=sample_rate*duration\n        self.df=df\n        self.sample_rate=sample_rate\n        self.duration=duration\n        self.audio_ids=df.audio_id.unique()\n    def __len__(self):\n        return len(self.audio_ids)\n\n    def __getitem__(self, idx: int):\n        audio_id=self.audio_ids[idx]\n        clip, _ = librosa.load(self.data_dir+'{}.mp3'.format(audio_id),\n                                sr=self.sample_rate,\n                                mono=True,\n                                res_type=\"kaiser_fast\")\n        clip=clip.astype(np.float32)\n        total_frames=len(clip)\n        target_df=self.df[self.df.audio_id==audio_id]\n        all_5s_clips=[]\n        row_ids=[]\n        site=target_df.site.iloc[0]\n        \n        if site=='site_3':\n            startpoints=list(range(0,total_frames,self.clip_frames))\n            if (len(startpoints)>1 and total_frames-startpoints[-1]<= 2.5*self.sample_rate ):\n                startpoints.pop(-1)\n            for start in startpoints:\n                clip_5s=clip[start:min(total_frames,start+self.clip_frames)]\n                if len(clip_5s)<self.clip_frames:\n                    pad0=(self.clip_frames-len(clip_5s))//2\n                    pad1=self.clip_frames-len(clip_5s)-pad0\n                    clip_5s=np.pad(clip_5s,[pad0,pad1],constant_values=0)\n                all_5s_clips.append(clip_5s)\n            row_ids.append(\"site_3_{}\".format(audio_id))\n        else:\n            for i in range(len(target_df)):\n                row=target_df.iloc[i]\n                end=int(row.seconds*self.sample_rate)\n                clip_5s=clip[max(0,end-self.clip_frames):min(total_frames,end)]\n                if len(clip_5s)<self.clip_frames:\n                    pad0=(self.clip_frames-len(clip_5s))//2\n                    pad1=self.clip_frames-len(clip_5s)-pad0\n                    clip_5s=np.pad(clip_5s,[pad0,pad1],constant_values=0)\n                all_5s_clips.append(clip_5s)\n                row_ids.append(\"{}_{}_{}\".format(site,audio_id,int(row.seconds)))\n        all_5s_clips=np.stack(all_5s_clips,axis=0)\n        return torch.tensor(all_5s_clips),row_ids,site","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"class Identity(nn.Module):\n    def __init__(self):\n        super().__init__()\n\n    def forward(self,x):\n        return x\n\n\nclass AttBlock(nn.Module):\n    '''\n    Input: [b,c,t//stride]\n    '''\n    def __init__(self, n_in, n_out, activation='linear', hidden=512,dropout=0):\n        super(AttBlock, self).__init__()\n        att_module = [\n            nn.Conv1d(n_in, hidden, kernel_size=1, stride=1, padding=0, bias=True),\n            nn.Tanh(),\n        ]\n        if dropout>0:\n            att_module.append(nn.Dropout(dropout))\n        att_module.append(nn.Conv1d(hidden,1,kernel_size=1,stride=1,padding=0,bias=True)) #[b,1,t]\n        self.att=nn.Sequential(*att_module)\n        self.cla = nn.Conv1d(in_channels=n_in, out_channels=n_out, kernel_size=1, stride=1, padding=0, bias=True) #[b,class,t]\n        self.nonlinear_transform=nn.Sigmoid() if activation=='sigmoid' else Identity()\n\n    def forward(self, x):\n        # x: (n_samples, n_in, n_time)\n        A=self.att(x)\n        A=torch.softmax(A,dim=-1)\n        instance_pred = self.nonlinear_transform(self.cla(x))\n        x = torch.sum(A * instance_pred, dim=2)\n        return x, A, instance_pred\n    \n\ndef interpolate(x, ratio):\n    \"\"\"Interpolate data in time domain. This is used to compensate the\n    resolution reduction in downsampling of a CNN.\n\n    Args:\n      x: (batch_size, time_steps, classes_num)\n      ratio: int, ratio to interpolate\n\n    Returns:\n      upsampled: (batch_size, time_steps * ratio, classes_num)\n    \"\"\"\n    (batch_size, time_steps, classes_num) = x.shape\n    upsampled = x[:, :, None, :].repeat(1, 1, ratio, 1)\n    upsampled = upsampled.reshape(batch_size, time_steps * ratio, classes_num)\n    return upsampled\n\n\ndef pad_framewise_output(framewise_output, frames_num):\n    \"\"\"Pad framewise_output to the same length as input frames. The pad value\n    is the same as the value of the last frame.\n\n    Args:\n      framewise_output: (batch_size, frames_num, classes_num)\n      frames_num: int, number of frames to pad\n\n    Outputs:\n      output: (batch_size, frames_num, classes_num)\n    \"\"\"\n    pad = framewise_output[:, -1:, :].repeat(1, frames_num - framewise_output.shape[1], 1)\n    \"\"\"tensor for padding\"\"\"\n\n    output = torch.cat((framewise_output, pad), dim=1)\n    \"\"\"(batch_size, frames_num, classes_num)\"\"\"\n\n    return output\n\nclass SED_Model_ATT(nn.Module):\n    def __init__(self,arch,num_class=264,dropout=0.4,dropout_att=0.25,**kwargs):\n        super().__init__()\n        self.base_model=timm.create_model(arch,pretrained=False,**kwargs)\n        feature_dim=self.base_model.classifier.in_features\n        self.interpolate_ratio=32\n        self.dropout = nn.Dropout(p=dropout)\n        self.att=AttBlock(feature_dim,num_class,activation='sigmoid',dropout=dropout_att)\n\n    def forward(self,x):\n        frames_num = x.size(3)\n \n        x=self.base_model.forward_features(x) #[b,c,Mel,T]\n        x=x.mean(dim=2)\n        x=self.dropout(x) #[b,c,T]\n\n\n        clipwise_output,att,segmentwise_output=self.att(x.float())\n        clipwise_output=torch.clamp(clipwise_output,0.0,1.0)\n\n        segmentwise_output=segmentwise_output.transpose(1,2)\n        framewise_output = interpolate(segmentwise_output, self.interpolate_ratio)\n        #print(frames_num,framewise_output.shape)\n        #framewise_output = pad_framewise_output(framewise_output, frames_num)\n\n        output_dict = {'framewise_output': framewise_output,\n                        'clipwise_output': clipwise_output,\n                       'att':att}\n        return output_dict","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def gem(x, p=3, eps=1e-6):\n    return F.avg_pool2d(x.clamp(min=eps).pow(p), (x.size(-2), x.size(-1))).pow(1. / p)\n\nclass GeM(nn.Module):\n    def __init__(self, p=3, eps=1e-6):\n        super(GeM, self).__init__()\n        self.p = nn.Parameter(torch.ones(1) * p)\n        self.eps = eps\n\n    def forward(self, x):\n        return gem(x, p=self.p, eps=self.eps)\n\n    def __repr__(self):\n        return self.__class__.__name__ + '(' + 'p=' + '{:.4f}'.format(self.p.data.tolist()[0]) + ', ' + 'eps=' + str(\n            self.eps) + ')'\n\nclass AdaptiveConcatPool2d(nn.Module):\n    def __init__(self, sz=None,gem=False):\n        super().__init__()\n        sz = sz or (1,1)\n        self.ap = GeM() if gem else nn.AdaptiveAvgPool2d(sz)\n        self.mp = nn.AdaptiveMaxPool2d(sz)\n\n    def forward(self, x):\n        return torch.cat([self.ap(x), self.mp(x)], 1).view(x.size(0),-1)\n\nclass AttMaxPool(nn.Module):\n    '''\n    Input: [b,c,t//stride]\n    '''\n    def __init__(self, n_in,hidden=512,dropout=0,drop_time=0.):\n        super().__init__()\n        att_module = [\n            nn.Conv1d(n_in, hidden, kernel_size=1, stride=1, padding=0, bias=True),\n            nn.Tanh(),\n        ]\n        if dropout>0:\n            att_module.append(nn.Dropout(dropout))\n\n        att_module.append(nn.Conv1d(hidden,1,kernel_size=1,stride=1,padding=0,bias=True)) #[b,1,t]\n        self.att=nn.Sequential(*att_module)\n        self.drop_time=drop_time\n\n    def forward(self, x):\n        # x: (n_samples, n_in, n_time)\n        mp=torch.max(x,dim=2)[0]\n        A=self.att(x)\n        A=torch.softmax(A,dim=-1)\n        if self.drop_time>0 and self.training:\n            A=nn.functional.dropout(A,p=self.drop_time,training=self.training)\n            A/=A.sum(dim=2,keepdim=True)\n            print(\"drop\")\n        x = torch.sum(A * x, dim=2)\n        x = torch.cat([x,mp],dim=1)\n        return x\n\nclass ModelWarper(nn.Module):\n    def __init__(self,arch,dropout=0.5,num_class=264):\n        super().__init__()\n        self.basemodel=timm.create_model(arch,pretrained=False)\n\n        features=self.basemodel.get_classifier().in_features\n\n        self.pooling=AdaptiveConcatPool2d()\n        self.dropout=nn.Dropout(dropout)\n        self.fc=nn.Linear(2*features,out_features=num_class)\n\n    def forward(self,x):\n        x=self.basemodel.forward_features(x)\n        x=self.pooling(x)\n        x=x.view(x.size(0),-1)\n        x=self.dropout(x)\n        x=self.fc(x)\n        return x\n    \nclass ModelWarper_Att(nn.Module):\n    def __init__(self,arch,dropout=0.5,dropout_att=0.25,num_class=264,drop_time=0,**kwargs):\n        super().__init__()\n        if arch=='PANN_res54':\n            from .pann_backbone import ResNet54\n            self.basemodel=ResNet54()\n            ckpt=torch.load(\"./model/ResNet54.pth\")\n            self.basemodel.load_state_dict(ckpt['model'],strict=False)\n            features=2048\n        else:\n            self.basemodel=timm.create_model(arch,pretrained=False,**kwargs)\n            features=self.basemodel.get_classifier().in_features\n\n        self.pooling=AttMaxPool(features,dropout=dropout_att,drop_time=drop_time)\n        self.dropout=nn.Dropout(dropout)\n        self.fc=nn.Linear(2*features,out_features=num_class)\n\n    def forward(self,x):\n        x=self.basemodel.forward_features(x)\n        #print(x.shape)\n        x=x.mean(dim=2)\n        x=self.pooling(x)\n        #x=x.view(x.size(0),-1)\n        x=self.dropout(x)\n        x=self.fc(x)\n        return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class SpecNorm(nn.Module):\n    def __init__(self,eps=1e-6):\n        super().__init__()\n        self.eps=eps\n\n    def forward(self,x):\n        b,c,m,t=x.shape\n        x=x.view(b*c,-1) #[b*c,mel*t]\n        _min = x.min(dim=1,keepdim=True)[0]\n        _max = x.max(dim=1,keepdim=True)[0]\n        x=(x-_min)/(_max-_min+self.eps)\n        #x = torch.stack([x, x, x], dim=1).view(b,3,m,t)  # ->[B,3,bins,Time]\n        return x.view(b,c,m,t)\n\nclass MelTransformer(nn.Module):\n    def __init__(self,sample_rate=32000,\n                 n_fft=[1024,1024,1024],\n                 hop_length=313,\n                 n_mels=224,\n                 f_min=20,\n                 f_max=16000,\n                 **kwargs):\n        super().__init__()\n        self.m1=torchaudio.transforms.MelSpectrogram(\n            sample_rate=sample_rate,\n            n_fft=n_fft[0],\n            hop_length=hop_length,\n            f_min=f_min,\n            f_max=f_max,\n            n_mels=n_mels,\n            **kwargs\n        )\n        self.m2=torchaudio.transforms.MelSpectrogram(\n            sample_rate=sample_rate,\n            n_fft=n_fft[1],\n            hop_length=hop_length,\n            f_min=f_min,\n            f_max=f_max,\n            n_mels=n_mels,\n            **kwargs\n        )\n        self.m3=torchaudio.transforms.MelSpectrogram(\n            sample_rate=sample_rate,\n            n_fft=n_fft[2],\n            hop_length=hop_length,\n            f_min=f_min,\n            f_max=f_max,\n            n_mels=n_mels,\n            **kwargs\n        )\n        self.amp2db=torchaudio.transforms.AmplitudeToDB()\n        self.norm=SpecNorm()\n    def forward(self,x):\n        with torch.no_grad():\n            x=torch.stack([self.m1(x),self.m2(x),self.m3(x)],dim=1) #[b,3,m,t]\n            x=self.amp2db(x)\n            x=self.norm(x)\n        return x\n\n\nimport torchaudio\nimport torch.nn.functional as F\n\ndef resize(x,size=(256,512)):\n    return F.interpolate(x,size=size,mode='bilinear')\n\ndef randomCrop(x,height=224):\n    #x [3,h,w]\n    start=np.random.randint(0,x.shape[1]-height)\n    return x[:,start:start+height,:]\n\ndef centerCrop(x,height=224):\n    #x [3,h,w]\n    start=(x.shape[1]-height)//2\n    return x[:,start:start+height,:]\n\nclass SpecAugmenter:\n    def __init__(self,resize=(256,512),crop_height=224,valid=False):\n        self.resize_size=resize\n        self.crop_height=crop_height\n        self.valid=valid\n\n    @torch.no_grad()\n    def __call__(self,specs):\n        result=[]\n        if self.resize_size:\n            if type(self.resize_size) is int:\n                specs=resize(specs,(self.resize_size,specs.shape[3]))\n            else:\n                specs=resize(specs,self.resize_size)\n        for x in specs:\n            if self.valid:\n                if self.crop_height:\n                    x=centerCrop(x,self.crop_height)\n            else:\n                if self.crop_height:\n                    x=randomCrop(x,self.crop_height)\n                if random.random()<0.5:\n                    x=torchaudio.transforms.F.mask_along_axis(x,x.shape[1]//8,0,axis=1)\n                if random.random() < 0.5:\n                    x=torchaudio.transforms.F.mask_along_axis(x,x.shape[2]//8,0,axis=2)\n            result.append(x)\n        return torch.stack(result,dim=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preprocessor=dict()\n\nmel_config = {\n        \"sample_rate\": 32000,\n        \"n_fft\": [1024,1024,1024],\n        \"hop_length\": 313,\n        \"n_mels\": 128,\n        \"f_min\": 20,\n        \"f_max\": 16000,\n        }\ntransformer = MelTransformer(**mel_config).cuda()\naugmenter=SpecAugmenter(valid=True,resize=256,crop_height=None)\n\npreprocessor['standard']={\n    'transformer':transformer,\n    'augmenter':augmenter\n}\n\n\nmel_config_2 = {\n        \"sample_rate\": 32000,\n        \"n_fft\": [1024,1024,1024],\n        \"hop_length\": 209,\n        \"n_mels\": 128,\n        \"f_min\": 20,\n        \"f_max\": 16000,\n        }\ntransformer = MelTransformer(**mel_config_2).cuda()\naugmenter=SpecAugmenter(valid=True,resize=320,crop_height=None)\npreprocessor['big']={\n    'transformer':transformer,\n    'augmenter':augmenter\n}\n\n\nmel_config_3 = {\n        \"sample_rate\": 32000,\n        \"n_fft\": [1024,1024,1024],\n        \"hop_length\": 313,\n        \"n_mels\": 96,\n        \"f_min\": 20,\n        \"f_max\": 16000,\n        }\ntransformer = MelTransformer(**mel_config_3).cuda()\naugmenter=SpecAugmenter(valid=True,resize=224,crop_height=None)\npreprocessor['small']={\n    'transformer':transformer,\n    'augmenter':augmenter\n}\n\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_configs=[\n    {\n        'arch':ModelWarper,\n        'preprocess':'standard',\n        'path':\"../input/bird-resnest50-mp3ft-5fold/resnest50d_1s4x24d_fold0_epoch9.pth\",\n        'base':\"resnest50d_1s4x24d\",\n    },\n    \n    {\n        'arch':ModelWarper,\n        'preprocess':'standard',\n        'path':\"../input/bird-resnest50-mp3ft-5fold/resnest50d_1s4x24d_fold1_epoch9.pth\",\n        'base':\"resnest50d_1s4x24d\",\n    },\n        {\n        'arch':ModelWarper,\n        'preprocess':'standard',\n        'path':\"../input/bird-resnest50-mp3ft-5fold/resnest50d_1s4x24d_fold2_epoch9.pth\",\n        'base':\"resnest50d_1s4x24d\",\n    },\n        {\n        'arch':ModelWarper,\n        'preprocess':'standard',\n        'path':\"../input/bird-resnest50-mp3ft-5fold/resnest50d_1s4x24d_fold3_epoch9.pth\",\n        'base':\"resnest50d_1s4x24d\",\n    },\n        {\n        'arch':ModelWarper,\n        'preprocess':'standard',\n        'path':\"../input/bird-resnest50-mp3ft-5fold/resnest50d_1s4x24d_fold4_epoch9.pth\",\n        'base':\"resnest50d_1s4x24d\",\n    },\n    {\n        'arch':ModelWarper,\n        'preprocess':'big',\n        'path':\"../input/birdcall-bigsize/resnest50d_1s4x24d_fold0_epoch9.pth\",\n        'base':\"resnest50d_1s4x24d\",\n    },\n    {\n        'arch':ModelWarper,\n        'preprocess':'big',\n        'path':\"../input/birdcall-bigsize/resnest50d_1s4x24d_fold1_epoch9.pth\",\n        'base':\"resnest50d_1s4x24d\",\n    },\n    {\n        'arch':ModelWarper,\n        'preprocess':'big',\n        'path':\"../input/birdcall-bigsize/resnest50d_1s4x24d_fold2_epoch9.pth\",\n        'base':\"resnest50d_1s4x24d\",\n    },\n    {\n        'arch':ModelWarper,\n        'preprocess':'big',\n        'path':\"../input/birdcall-bigsize/resnest50d_1s4x24d_fold3_epoch9.pth\",\n        'base':\"resnest50d_1s4x24d\",\n    },\n    {\n        'arch':ModelWarper,\n        'preprocess':'big',\n        'path':\"../input/birdcall-bigsize/resnest50d_1s4x24d_fold4_epoch9.pth\",\n        'base':\"resnest50d_1s4x24d\",\n    },\n        {\n        'arch':ModelWarper,\n        'preprocess':'small',\n        'path':\"../input/regnety40-224/regnety_040_fold0_epoch9.pth\",\n        'base':\"regnety_040\",\n    },\n        {\n        'arch':ModelWarper,\n        'preprocess':'small',\n        'path':\"../input/regnety40-224/regnety_040_fold1_epoch9.pth\",\n        'base':\"regnety_040\",\n    },\n        {\n        'arch':ModelWarper,\n        'preprocess':'small',\n        'path':\"../input/regnety40-224/regnety_040_fold2_epoch9.pth\",\n        'base':\"regnety_040\",\n    },\n        {\n        'arch':ModelWarper,\n        'preprocess':'small',\n        'path':\"../input/regnety40-224/regnety_040_fold3_epoch9.pth\",\n        'base':\"regnety_040\",\n    },\n]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"modellist=[]\npplist=[]\nfor config in model_configs:\n    model=config['arch'](config['base'],num_class=264)\n    print(\"Loading\",config['path'])\n    ckpt=torch.load(config['path'])['state_dict']\n    model.load_state_dict(ckpt)\n    model.cuda()\n    model.eval()\n    modellist.append(model)    \n    pplist.append(config['preprocess'])\n\nprint(len(modellist))\nprint(pplist)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.cuda.empty_cache()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!nvidia-smi","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataset=Dataset_Test(\n        test,\n        TEST_AUDIO_DIR,\n        duration=5,\n        sample_rate=32000,\n    )\ndataloader=DataLoader(dataset,batch_size=1,shuffle=False,num_workers=2,drop_last=False,pin_memory=True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Prediction loop"},{"metadata":{"trusted":true},"cell_type":"code","source":"THRESHOLD=0.5\nMAX_PRED={\n    'site_1':3,\n    'site_2':3,\n    'site_3':10\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"rows=[]\nresult=[]\nfor clips,row_ids,site in tqdm(dataloader):\n    clips=clips.cuda()[0]\n    batch_output=0.\n    specs={}\n    specs_shift1={}\n    specs_shift2={}\n    \n    shifted1=torch.zeros(clips.shape).float().cuda()  #[k,n]\n    shifted1[:,:-155]=clips[:,155:]\n    \n    shifted2=torch.zeros(clips.shape).float().cuda()  #[k,n]\n    shifted2[:,155:]=clips[:,:-155]\n    \n    with torch.no_grad():\n        for k,v in preprocessor.items():\n            spec=v['transformer'](clips)\n            spec=v['augmenter'](spec)\n            specs[k]=spec\n            specs_shift1[k]=v['augmenter'](v['transformer'](shifted1))\n            specs_shift2[k]=v['augmenter'](v['transformer'](shifted2))\n        for model,p in zip(modellist,pplist):\n            #print(specs[p].shape)\n            output = torch.sigmoid(model(specs[p]))\n            #output = output['clipwise_output']\n            output_shift1=torch.sigmoid(model(specs_shift1[p]))\n            output_shift2=torch.sigmoid(model(specs_shift2[p]))\n            \n            batch_output+=((output+output_shift1+output_shift2)/3)**0.5\n        \n        batch_output/=len(modellist)\n        #batch_output=batch_output**0.5\n        batch_output = batch_output.cpu().numpy()  #[n,264]\n        #print(output)\n        if site[0]=='site_3':\n            batch_output=np.max(batch_output,axis=0,keepdims=True) #[1,264]\n            \n        #binary_preds=output>THRESHOLD  #[n,264]\n        print(batch_output[:,0])\n        for clip_pred in batch_output:\n            binary_pred=clip_pred>THRESHOLD\n            pos_idx=np.where(binary_pred)[0]\n            pos_prob=clip_pred[pos_idx]\n            sort=np.argsort(pos_prob)[::-1]\n            pos_idx=pos_idx[sort[:min(len(sort),MAX_PRED[site[0]])]]\n            #print(pos_idx)\n            if len(pos_idx)==0:\n                result.append(\"nocall\")\n            else:\n                result.append(\" \".join([INV_BIRD_CODE[code] for code in pos_idx]))    \n    for r in row_ids:\n        rows.extend(r)\n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#result=np.concatenate(result)\nsubmission_df=pd.DataFrame(\n    {\n        \"row_id\": rows,\n        \"birds\": result\n    }\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df.to_csv(\"submission.csv\",index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}