{"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 timm\nimport os\n#os.chdir('/kaggle/input/timmmaster/')\n!cp -r ../input/timm-pytorch-image-models /kaggle/working/\n!pip install /kaggle/working/timm-pytorch-image-models/pytorch-image-models-master/","metadata":{"execution":{"iopub.status.busy":"2022-03-30T11:29:52.7101Z","iopub.execute_input":"2022-03-30T11:29:52.710558Z","iopub.status.idle":"2022-03-30T11:30:23.871293Z","shell.execute_reply.started":"2022-03-30T11:29:52.710511Z","shell.execute_reply":"2022-03-30T11:30:23.869878Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import gc\nimport cv2\nimport math\nimport copy\nimport time\nimport random\n\n# For data manipulation\nimport numpy as np\nimport pandas as pd\n\nfrom pathlib import Path\n# Pytorch Imports\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torch.optim import lr_scheduler\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch.cuda import amp\n\n# Audio \nimport torchaudio\nfrom torchaudio.transforms import MelSpectrogram, Resample,AmplitudeToDB\n\n# Utils\nimport joblib\nfrom tqdm import tqdm\nfrom collections import defaultdict\n\n# Sklearn Imports\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.metrics import f1_score\n\n# For Image Models\nimport timm\n\n# For colored terminal text\nfrom colorama import Fore, Back, Style\nb_ = Fore.BLUE\nsr_ = Style.RESET_ALL\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\n# For descriptive error messages\nos.environ['CUDA_LAUNCH_BLOCKING'] = \"1\"","metadata":{"execution":{"iopub.status.busy":"2022-03-30T11:30:23.874573Z","iopub.execute_input":"2022-03-30T11:30:23.874903Z","iopub.status.idle":"2022-03-30T11:30:23.886207Z","shell.execute_reply.started":"2022-03-30T11:30:23.874867Z","shell.execute_reply":"2022-03-30T11:30:23.884949Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Testing Configuration","metadata":{}},{"cell_type":"code","source":"class CONFIG:\n    num_class = 152\n    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')\n    model_name = 'tf_efficientnet_b0_ns'\n    embedding_size = 768\n    #Audio Specific\n    sample_rate = 32000\n    max_time = 5\n    n_mels = 224\n    n_fft = 1024\n    period = 30\n    \n    target_columns = [\n        \"afrsil1\",\n        \"akekee\",\n        \"akepa1\",\n        \"akiapo\",\n        \"akikik\",\n        \"amewig\",\n        \"aniani\",\n        \"apapan\",\n        \"arcter\",\n        \"barpet\",\n        \"bcnher\",\n        \"belkin1\",\n        \"bkbplo\",\n        \"bknsti\",\n        \"bkwpet\",\n        \"blkfra\",\n        \"blknod\",\n        \"bongul\",\n        \"brant\",\n        \"brnboo\",\n        \"brnnod\",\n        \"brnowl\",\n        \"brtcur\",\n        \"bubsan\",\n        \"buffle\",\n        \"bulpet\",\n        \"burpar\",\n        \"buwtea\",\n        \"cacgoo1\",\n        \"calqua\",\n        \"cangoo\",\n        \"canvas\",\n        \"caster1\",\n        \"categr\",\n        \"chbsan\",\n        \"chemun\",\n        \"chukar\",\n        \"cintea\",\n        \"comgal1\",\n        \"commyn\",\n        \"compea\",\n        \"comsan\",\n        \"comwax\",\n        \"coopet\",\n        \"crehon\",\n        \"dunlin\",\n        \"elepai\",\n        \"ercfra\",\n        \"eurwig\",\n        \"fragul\",\n        \"gadwal\",\n        \"gamqua\",\n        \"glwgul\",\n        \"gnwtea\",\n        \"golphe\",\n        \"grbher3\",\n        \"grefri\",\n        \"gresca\",\n        \"gryfra\",\n        \"gwfgoo\",\n        \"hawama\",\n        \"hawcoo\",\n        \"hawcre\",\n        \"hawgoo\",\n        \"hawhaw\",\n        \"hawpet1\",\n        \"hoomer\",\n        \"houfin\",\n        \"houspa\",\n        \"hudgod\",\n        \"iiwi\",\n        \"incter1\",\n        \"jabwar\",\n        \"japqua\",\n        \"kalphe\",\n        \"kauama\",\n        \"laugul\",\n        \"layalb\",\n        \"lcspet\",\n        \"leasan\",\n        \"leater1\",\n        \"lessca\",\n        \"lesyel\",\n        \"lobdow\",\n        \"lotjae\",\n        \"madpet\",\n        \"magpet1\",\n        \"mallar3\",\n        \"masboo\",\n        \"mauala\",\n        \"maupar\",\n        \"merlin\",\n        \"mitpar\",\n        \"moudov\",\n        \"norcar\",\n        \"norhar2\",\n        \"normoc\",\n        \"norpin\",\n        \"norsho\",\n        \"nutman\",\n        \"oahama\",\n        \"omao\",\n        \"osprey\",\n        \"pagplo\",\n        \"palila\",\n        \"parjae\",\n        \"pecsan\",\n        \"peflov\",\n        \"perfal\",\n        \"pibgre\",\n        \"pomjae\",\n        \"puaioh\",\n        \"reccar\",\n        \"redava\",\n        \"redjun\",\n        \"redpha1\",\n        \"refboo\",\n        \"rempar\",\n        \"rettro\",\n        \"ribgul\",\n        \"rinduc\",\n        \"rinphe\",\n        \"rocpig\",\n        \"rorpar\",\n        \"rudtur\",\n        \"ruff\",\n        \"saffin\",\n        \"sander\",\n        \"semplo\",\n        \"sheowl\",\n        \"shtsan\",\n        \"skylar\",\n        \"snogoo\",\n        \"sooshe\",\n        \"sooter1\",\n        \"sopsku1\",\n        \"sora\",\n        \"spodov\",\n        \"sposan\",\n        \"towsol\",\n        \"wantat1\",\n        \"warwhe1\",\n        \"wesmea\",\n        \"wessan\",\n        \"wetshe\",\n        \"whfibi\",\n        \"whiter\",\n        \"whttro\",\n        \"wiltur\",\n        \"yebcar\",\n        \"yefcan\",\n        \"zebdov\",\n        ]\n    bird2id = {b:i for i,b in enumerate(target_columns)}\n    id2bird = {i:b for i,b in enumerate(target_columns)}\n    scored_birds = [\"akiapo\", \"aniani\", \"apapan\", \"barpet\", \"crehon\", \"elepai\", \"ercfra\", \"hawama\", \"hawcre\", \"hawgoo\", \"hawhaw\", \"hawpet1\", \"houfin\", \"iiwi\", \"jabwar\", \"maupar\", \"omao\", \"puaioh\", \"skylar\", \"warwhe1\", \"yefcan\"]","metadata":{"execution":{"iopub.status.busy":"2022-03-30T11:30:23.887943Z","iopub.execute_input":"2022-03-30T11:30:23.888248Z","iopub.status.idle":"2022-03-30T11:30:23.91417Z","shell.execute_reply.started":"2022-03-30T11:30:23.888212Z","shell.execute_reply":"2022-03-30T11:30:23.913078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model used for prediction\n\n#GeM pooling\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 self.gem(x, p=self.p, eps=self.eps)\n        \n    def gem(self, 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        \n    def __repr__(self):\n        return self.__class__.__name__ + \\\n                '(' + 'p=' + '{:.4f}'.format(self.p.data.tolist()[0]) + \\\n                ', ' + 'eps=' + str(self.eps) + ')'\n#model\nclass BirdCLEFModel(nn.Module):\n    def __init__(self, model_name, embedding_size, pretrained=False):\n        super(BirdCLEFModel, self).__init__()\n        self.model = timm.create_model(model_name, pretrained=pretrained)\n        in_features = self.model.classifier.in_features\n        self.model.classifier = nn.Identity()\n        self.model.global_pool = nn.Identity()\n        self.pooling = GeM()\n        self.embedding = nn.Linear(in_features, embedding_size)\n        self.fc = nn.Linear(embedding_size, CONFIG.num_class)\n\n    def forward(self, images):\n        features = self.model(images)\n        pooled_features = self.pooling(features).flatten(1)\n        embedding = self.embedding(pooled_features)\n        output = self.fc(embedding)\n        return output\n    \nmodel = BirdCLEFModel(CONFIG.model_name,CONFIG.embedding_size)\nmodel.to(CONFIG.device)","metadata":{"execution":{"iopub.status.busy":"2022-03-30T11:30:23.916514Z","iopub.execute_input":"2022-03-30T11:30:23.91681Z","iopub.status.idle":"2022-03-30T11:30:24.099142Z","shell.execute_reply.started":"2022-03-30T11:30:23.916777Z","shell.execute_reply":"2022-03-30T11:30:24.098207Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#create dataset for test\nclass test_dataset(Dataset):\n\n    def __init__(self,df,clip,target_sample_rate = 32000):\n        self.df = df\n        self.clip = torch.mean(clip,axis = 0)\n        self.SR = target_sample_rate\n        self.num_samples = CONFIG.max_time*self.SR\n\n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, idx: int):\n        sample = self.df.loc[idx, :]\n        row_id = sample.row_id\n\n        end = int(sample.seconds)\n        start = int(end - 5)\n\n        start_index = int(self.SR*start)\n        end_index = int(self.SR*end)\n\n        sample = self.clip[start_index:end_index]\n        \n        if sample.shape[0] > self.num_samples:\n            sample = self.crop_audio(sample)\n        if sample.shape[0] < self.num_samples:\n            sample = self.pad_audio(sample)\n        \n        sample = torch.nan_to_num(sample)\n        mel_spectrogram = MelSpectrogram(sample_rate=self.SR,\n                                        n_mels = CONFIG.n_mels,\n                                        n_fft = CONFIG.n_fft)\n        mel = mel_spectrogram(sample)\n        image = torch.stack([mel,mel,mel])\n        max_val = torch.abs(image).max()\n        image = image / max_val\n        return image,row_id,end\n    \n\n    def pad_audio(self, audio):\n        pad_length = self.num_samples - audio.shape[0]\n        last_dim_padding = (0, pad_length)\n        audio = F.pad(audio, last_dim_padding) #奇怪的pad方式增加了\n        return audio\n        \n    def crop_audio(self, audio):\n        return audio[:self.num_samples] \n\n# \ndef prediction_for_clip(test_df,clip,model):\n    dataset = test_dataset(df = test_df,clip = clip)\n    loader = DataLoader(dataset,batch_size = 1,shuffle = False)\n\n    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n\n    prediction_dict = {'row_id':[],'target':[]}\n    for image , row_id,seconds in tqdm(loader):\n        image = image.to(device)\n        outputs = model(image)\n        '''\n        _,pred = torch.max(outputs,1)\n\n        birdcode = CONFIG.id2bird[int(pred.cpu().item())]\n        #print(birdcode)\n        #deal with format-----\n        row_id = row_id[0]\n        seconds = seconds.item()\n        #---------------------\n        for bird in CONFIG.scored_birds:\n            judge = False\n            if bird == birdcode:\n                judge = True\n            id = row_id + '_' + bird + '_' + str(seconds)\n\n            prediction_dict['row_id'].append(id)\n            prediction_dict['target'].append(judge)\n        '''\n        pred = torch.sigmoid(outputs)[0]\n        row_id = row_id[0]\n        seconds = seconds.item()\n        for bird in CONFIG.scored_birds:\n            judge = False\n            if pred[int(CONFIG.bird2id[bird])] >= 0.05:\n                judge = True\n            id = row_id + '_' + bird + '_'+str(seconds)\n                \n            prediction_dict['row_id'].append(id)\n            prediction_dict['target'].append(judge)\n            \n    return prediction_dict","metadata":{"execution":{"iopub.status.busy":"2022-03-30T11:30:24.100636Z","iopub.execute_input":"2022-03-30T11:30:24.101105Z","iopub.status.idle":"2022-03-30T11:30:24.118816Z","shell.execute_reply.started":"2022-03-30T11:30:24.101058Z","shell.execute_reply":"2022-03-30T11:30:24.117993Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Prediction part","metadata":{}},{"cell_type":"code","source":"from torch.nn.modules.batchnorm import _BatchNorm\n\ndef prepare_model_for_inference(model,path):\n    if not torch.cuda.is_available():\n        ckpt = torch.load(path,map_location = 'cpu')\n    else:\n        ckpt = torch.load(path,map_location = {'cuda:7':'cuda:0'})\n    model.load_state_dict(ckpt)\n    model.eval()\n\n    return model\n\ndef prediction(test_audios,model,threshold = 0.05, threshold_long = None):\n    #假设这里的model已经完成了load\n    prediction_dicts = {'row_id':[],'target':[]}\n    for audio_path in test_audios:\n        clip,_ = torchaudio.load(audio_path)\n        seconds = []\n        row_ids = []\n\n        for second in range(5,65,5):\n            row_id = audio_path.name.split('.')[:-1][0]\n            #row_id = \"_\".join(audio_path.name.split('.'[:-1])+f\"_{second}\")\n            seconds.append(second)\n            row_ids.append(row_id)\n        \n        test_df = pd.DataFrame(\n            {\n                \"row_id\":row_ids,\n                \"seconds\":seconds\n            }\n        )\n        prediction_dict = prediction_for_clip(test_df,clip,model)\n        prediction_dicts['row_id'].extend(prediction_dict['row_id'])\n        prediction_dicts['target'].extend(prediction_dict['target'])\n    \n    return prediction_dicts","metadata":{"execution":{"iopub.status.busy":"2022-03-30T11:30:24.120203Z","iopub.execute_input":"2022-03-30T11:30:24.120473Z","iopub.status.idle":"2022-03-30T11:30:24.141576Z","shell.execute_reply.started":"2022-03-30T11:30:24.120445Z","shell.execute_reply":"2022-03-30T11:30:24.14054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#os.chdir('/kaggle/working/')\n#test_audio_dir = '../input/birdclef-2022/test_soundscapes/'\n#file_list = [[f.split('.')][0] for f in sorted(os.listdir(test_audio))]\ntorch.cuda.empty_cache()\ntest_audio_dir = Path('../input/birdclef-2022/test_soundscapes/')\nall_audios = list(test_audio_dir.glob(\"*.ogg\"))\n\nmodel = prepare_model_for_inference(model,'../input/trained-model1/F10.4293_epoch120.bin')\npred = prediction(all_audios,model)\nresult = pd.DataFrame(pred,columns = ['row_id','target'])\nprint(result.head())\nresult.to_csv(\"submission.csv\",index = False)\ntorch.cuda.empty_cache()\n","metadata":{"execution":{"iopub.status.busy":"2022-03-30T11:30:24.145134Z","iopub.execute_input":"2022-03-30T11:30:24.145678Z","iopub.status.idle":"2022-03-30T11:30:25.367798Z","shell.execute_reply.started":"2022-03-30T11:30:24.145628Z","shell.execute_reply":"2022-03-30T11:30:25.365494Z"},"trusted":true},"execution_count":null,"outputs":[]}]}