{"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":"markdown","source":"+ [Training a winning model](https://www.kaggle.com/theoviel/training-a-winning-model/notebook?scriptVersionId=42814701)","metadata":{}},{"cell_type":"markdown","source":"## Libraries","metadata":{}},{"cell_type":"markdown","source":"+ v3 pin memory True テスト","metadata":{}},{"cell_type":"code","source":"!pip install ../input/torchlibrosa/torchlibrosa-0.0.5-py3-none-any.whl","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:30.530265Z","iopub.execute_input":"2021-06-01T11:50:30.530813Z","iopub.status.idle":"2021-06-01T11:50:57.768407Z","shell.execute_reply.started":"2021-06-01T11:50:30.530754Z","shell.execute_reply":"2021-06-01T11:50:57.766782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\n#sys.path.append('../input/pytorch-image-models/pytorch-image-models-master')\n#sys.path.append('../input/pytorchimagemodels')\nsys.path.append('../input/timm-pytorch-image-models/pytorch-image-models-master')\n\nimport os\nimport math\nimport time\nimport random\n\nimport numpy as np\nimport pandas as pd\nfrom matplotlib import pyplot as plt\nimport seaborn as sns\nimport soundfile as sf\nfrom pathlib import Path\nfrom contextlib import contextmanager\nfrom collections import Counter\nfrom typing import Optional\nimport logging\nfrom IPython.display import Audio, IFrame, display # jupyterで再生につかう\n\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.metrics import f1_score\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.optim import Adam, SGD\nimport torchvision.models as models\nfrom torch.nn.parameter import Parameter\nfrom torch.utils.data import DataLoader, Dataset\nfrom torch.optim.lr_scheduler import CosineAnnealingWarmRestarts, CosineAnnealingLR, ReduceLROnPlateau\n\nfrom torchlibrosa.stft import LogmelFilterBank, Spectrogram\nfrom torchlibrosa.augmentation import SpecAugmentation\n\nimport timm\nimport warnings \nfrom tqdm import tqdm\n\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:57.77331Z","iopub.execute_input":"2021-06-01T11:50:57.773726Z","iopub.status.idle":"2021-06-01T11:50:57.788933Z","shell.execute_reply.started":"2021-06-01T11:50:57.773695Z","shell.execute_reply":"2021-06-01T11:50:57.787695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"OUTPUT_DIR = './'\nif not os.path.exists(OUTPUT_DIR):\n    os.makedirs(OUTPUT_DIR)\n\ntrain = pd.read_csv('../input/birdclef-2021/train_metadata.csv')\ntest = pd.read_csv('../input/birdclef-2021/test.csv')\ntrain = train[['primary_label', 'filename']]","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:57.790553Z","iopub.execute_input":"2021-06-01T11:50:57.791227Z","iopub.status.idle":"2021-06-01T11:50:58.044908Z","shell.execute_reply.started":"2021-06-01T11:50:57.79118Z","shell.execute_reply":"2021-06-01T11:50:58.043869Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## CFG","metadata":{}},{"cell_type":"code","source":"TARGETS = [\n        'acafly', 'acowoo', 'aldfly', 'ameavo', 'amecro',\n        'amegfi', 'amekes', 'amepip', 'amered', 'amerob',\n        'amewig', 'amtspa', 'andsol1', 'annhum', 'astfly',\n        'azaspi1', 'babwar', 'baleag', 'balori', 'banana',\n        'banswa', 'banwre1', 'barant1', 'barswa', 'batpig1',\n        'bawswa1', 'bawwar', 'baywre1', 'bbwduc', 'bcnher',\n        'belkin1', 'belvir', 'bewwre', 'bkbmag1', 'bkbplo',\n        'bkbwar', 'bkcchi', 'bkhgro', 'bkmtou1', 'bknsti', 'blbgra1',\n        'blbthr1', 'blcjay1', 'blctan1', 'blhpar1', 'blkpho',\n        'blsspa1', 'blugrb1', 'blujay', 'bncfly', 'bnhcow', 'bobfly1',\n        'bongul', 'botgra', 'brbmot1', 'brbsol1', 'brcvir1', 'brebla',\n        'brncre', 'brnjay', 'brnthr', 'brratt1', 'brwhaw', 'brwpar1',\n        'btbwar', 'btnwar', 'btywar', 'bucmot2', 'buggna', 'bugtan',\n        'buhvir', 'bulori', 'burwar1', 'bushti', 'butsal1', 'buwtea',\n        'cacgoo1', 'cacwre', 'calqua', 'caltow', 'cangoo', 'canwar',\n        'carchi', 'carwre', 'casfin', 'caskin', 'caster1', 'casvir',\n        'categr', 'ccbfin', 'cedwax', 'chbant1', 'chbchi', 'chbwre1',\n        'chcant2', 'chispa', 'chswar', 'cinfly2', 'clanut', 'clcrob',\n        'cliswa', 'cobtan1', 'cocwoo1', 'cogdov', 'colcha1', 'coltro1',\n        'comgol', 'comgra', 'comloo', 'commer', 'compau', 'compot1',\n        'comrav', 'comyel', 'coohaw', 'cotfly1', 'cowscj1', 'cregua1',\n        'creoro1', 'crfpar', 'cubthr', 'daejun', 'dowwoo', 'ducfly', 'dusfly',\n        'easblu', 'easkin', 'easmea', 'easpho', 'eastow', 'eawpew', 'eletro',\n        'eucdov', 'eursta', 'fepowl', 'fiespa', 'flrtan1', 'foxspa', 'gadwal',\n        'gamqua', 'gartro1', 'gbbgul', 'gbwwre1', 'gcrwar', 'gilwoo',\n        'gnttow', 'gnwtea', 'gocfly1', 'gockin', 'gocspa', 'goftyr1',\n        'gohque1', 'goowoo1', 'grasal1', 'grbani', 'grbher3', 'grcfly',\n        'greegr', 'grekis', 'grepew', 'grethr1', 'gretin1', 'greyel',\n        'grhcha1', 'grhowl', 'grnher', 'grnjay', 'grtgra', 'grycat',\n        'gryhaw2', 'gwfgoo', 'haiwoo', 'heptan', 'hergul', 'herthr',\n        'herwar', 'higmot1', 'hofwoo1', 'houfin', 'houspa', 'houwre',\n        'hutvir', 'incdov', 'indbun', 'kebtou1', 'killde', 'labwoo', 'larspa',\n        'laufal1', 'laugul', 'lazbun', 'leafly', 'leasan', 'lesgol', 'lesgre1',\n        'lesvio1', 'linspa', 'linwoo1', 'littin1', 'lobdow', 'lobgna5', 'logshr',\n        'lotduc', 'lotman1', 'lucwar', 'macwar', 'magwar', 'mallar3', 'marwre',\n        'mastro1', 'meapar', 'melbla1', 'monoro1', 'mouchi', 'moudov', 'mouela1',\n        'mouqua', 'mouwar', 'mutswa', 'naswar', 'norcar', 'norfli', 'normoc', 'norpar',\n        'norsho', 'norwat', 'nrwswa', 'nutwoo', 'oaktit', 'obnthr1', 'ocbfly1',\n        'oliwoo1', 'olsfly', 'orbeup1', 'orbspa1', 'orcpar', 'orcwar', 'orfpar',\n        'osprey', 'ovenbi1', 'pabspi1', 'paltan1', 'palwar', 'pasfly', 'pavpig2',\n        'phivir', 'pibgre', 'pilwoo', 'pinsis', 'pirfly1', 'plawre1', 'plaxen1',\n        'plsvir', 'plupig2', 'prowar', 'purfin', 'purgal2', 'putfru1', 'pygnut',\n        'rawwre1', 'rcatan1', 'rebnut', 'rebsap', 'rebwoo', 'redcro', 'reevir1',\n        'rehbar1', 'relpar', 'reshaw', 'rethaw', 'rewbla', 'ribgul', 'rinkin1',\n        'roahaw', 'robgro', 'rocpig', 'rotbec', 'royter1', 'rthhum', 'rtlhum',\n        'ruboro1', 'rubpep1', 'rubrob', 'rubwre1', 'ruckin', 'rucspa1', 'rucwar',\n        'rucwar1', 'rudpig', 'rudtur', 'rufhum', 'rugdov', 'rumfly1', 'runwre1',\n        'rutjac1', 'saffin', 'sancra', 'sander', 'savspa', 'saypho', 'scamac1',\n        'scatan', 'scbwre1', 'scptyr1', 'scrtan1', 'semplo', 'shicow', 'sibtan2',\n        'sinwre1', 'sltred', 'smbani', 'snogoo', 'sobtyr1', 'socfly1', 'solsan',\n        'sonspa', 'soulap1', 'sposan', 'spotow', 'spvear1', 'squcuc1', 'stbori',\n        'stejay', 'sthant1', 'sthwoo1', 'strcuc1', 'strfly1', 'strsal1', 'stvhum2',\n        'subfly', 'sumtan', 'swaspa', 'swathr', 'tenwar', 'thbeup1', 'thbkin',\n        'thswar1', 'towsol', 'treswa', 'trogna1', 'trokin', 'tromoc', 'tropar',\n        'tropew1', 'tuftit', 'tunswa', 'veery', 'verdin', 'vigswa', 'warvir',\n        'wbwwre1', 'webwoo1', 'wegspa1', 'wesant1', 'wesblu', 'weskin', 'wesmea',\n        'westan', 'wewpew', 'whbman1', 'whbnut', 'whcpar', 'whcsee1', 'whcspa',\n        'whevir', 'whfpar1', 'whimbr', 'whiwre1', 'whtdov', 'whtspa', 'whwbec1',\n        'whwdov', 'wilfly', 'willet1', 'wilsni1', 'wiltur', 'wlswar', 'wooduc',\n        'woothr', 'wrenti', 'y00475', 'yebcha', 'yebela1', 'yebfly', 'yebori1',\n        'yebsap', 'yebsee1', 'yefgra1', 'yegvir', 'yehbla', 'yehcar1', 'yelgro',\n        'yelwar', 'yeofly1', 'yerwar', 'yeteup1', 'yetvir']","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-06-01T11:50:58.046809Z","iopub.execute_input":"2021-06-01T11:50:58.047374Z","iopub.status.idle":"2021-06-01T11:50:58.070145Z","shell.execute_reply.started":"2021-06-01T11:50:58.047331Z","shell.execute_reply":"2021-06-01T11:50:58.068911Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    seed = 29\n    target_col = 'primary_label'\n    train_datadir = Path(\"../input/birdclef-2021/train_short_audio\")\n    period = 5\n    img_size = 224\n    target_size = len(TARGETS)\n    # Audio cfg\n    n_mels = 128\n    fmin = 20\n    fmax = 16000\n    n_fft = 2048\n    hop_length = 512\n    sample_rate = 32000\n    # model\n    pretrained = True\n    in_channels = 1","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.076249Z","iopub.execute_input":"2021-06-01T11:50:58.076995Z","iopub.status.idle":"2021-06-01T11:50:58.088219Z","shell.execute_reply.started":"2021-06-01T11:50:58.076953Z","shell.execute_reply":"2021-06-01T11:50:58.086996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Utils","metadata":{}},{"cell_type":"code","source":"def set_seed(seed=42):\n    random.seed(seed)\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\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@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\nlogger = get_logger(\"main.log\")\nset_seed(seed=CFG.seed)","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.09314Z","iopub.execute_input":"2021-06-01T11:50:58.093889Z","iopub.status.idle":"2021-06-01T11:50:58.111432Z","shell.execute_reply.started":"2021-06-01T11:50:58.093853Z","shell.execute_reply":"2021-06-01T11:50:58.109502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data loading","metadata":{}},{"cell_type":"code","source":"TAEGET_SR = 32000\nTEST = (len(list(Path(\"../input/birdclef-2021/test_soundscapes/\").glob(\"*.ogg\"))) != 0)\nTARGET_PATH = None\nif TEST:\n    print(f'TEST mode')\n    DATADIR = Path(\"../input/birdclef-2021/test_soundscapes/\")\nelse:\n    print(f'TRAIN mode')\n    DATADIR = Path(\"../input/birdclef-2021/train_soundscapes/\")\n    TARGET_PATH = Path(\"../input/birdclef-2021/train_soundscape_labels.csv\")","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.114053Z","iopub.execute_input":"2021-06-01T11:50:58.114847Z","iopub.status.idle":"2021-06-01T11:50:58.127853Z","shell.execute_reply.started":"2021-06-01T11:50:58.114781Z","shell.execute_reply":"2021-06-01T11:50:58.125471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_audios = list(DATADIR.glob(\"*.ogg\"))\nall_audio_ids = [\"_\".join(audio_id.name.split(\"_\")[:2]) for audio_id in all_audios]\nsubmission_df = pd.DataFrame({\n    \"row_id\": all_audio_ids\n})\nsubmission_df","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.130374Z","iopub.execute_input":"2021-06-01T11:50:58.130725Z","iopub.status.idle":"2021-06-01T11:50:58.152758Z","shell.execute_reply.started":"2021-06-01T11:50:58.130694Z","shell.execute_reply":"2021-06-01T11:50:58.151683Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Dataset","metadata":{}},{"cell_type":"code","source":"class TestDataset(Dataset):\n    def __init__(self, df: pd.DataFrame, clip: np.ndarray,\n                 waveform_transforms=None):\n        self.df = df\n        self.clip = clip\n        self.waveform_transforms=waveform_transforms\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        start_index = SR * start_seconds\n        end_index = SR * end_seconds\n        \n        y = self.clip[start_index:end_index].astype(np.float32)\n        \n        y = np.nan_to_num(y)\n\n        if self.waveform_transforms:\n            y = self.waveform_transforms(y)\n\n        y = np.nan_to_num(y)\n        \n        return y, row_id","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.155133Z","iopub.execute_input":"2021-06-01T11:50:58.155624Z","iopub.status.idle":"2021-06-01T11:50:58.16571Z","shell.execute_reply.started":"2021-06-01T11:50:58.155565Z","shell.execute_reply":"2021-06-01T11:50:58.163784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Torchaudio utils\nhttps://www.kaggle.com/vladimirsydor/4-th-place-solution-inference-and-training-tips","metadata":{}},{"cell_type":"code","source":"def compute_deltas(\n        specgram: torch.Tensor,\n        win_length: int = 5,\n        mode: str = \"replicate\"\n) -> torch.Tensor:\n    r\"\"\"Compute delta coefficients of a tensor, usually a spectrogram:\n\n    .. math::\n       d_t = \\frac{\\sum_{n=1}^{\\text{N}} n (c_{t+n} - c_{t-n})}{2 \\sum_{n=1}^{\\text{N}} n^2}\n\n    where :math:`d_t` is the deltas at time :math:`t`,\n    :math:`c_t` is the spectrogram coeffcients at time :math:`t`,\n    :math:`N` is ``(win_length-1)//2``.\n\n    Args:\n        specgram (Tensor): Tensor of audio of dimension (..., freq, time)\n        win_length (int, optional): The window length used for computing delta (Default: ``5``)\n        mode (str, optional): Mode parameter passed to padding (Default: ``\"replicate\"``)\n\n    Returns:\n        Tensor: Tensor of deltas of dimension (..., freq, time)\n\n    Example\n        >>> specgram = torch.randn(1, 40, 1000)\n        >>> delta = compute_deltas(specgram)\n        >>> delta2 = compute_deltas(delta)\n    \"\"\"\n    device = specgram.device\n    dtype = specgram.dtype\n\n    # pack batch\n    shape = specgram.size()\n    specgram = specgram.reshape(1, -1, shape[-1])\n\n    assert win_length >= 3\n\n    n = (win_length - 1) // 2\n\n    # twice sum of integer squared\n    denom = n * (n + 1) * (2 * n + 1) / 3\n\n    specgram = torch.nn.functional.pad(specgram, (n, n), mode=mode)\n\n    kernel = torch.arange(-n, n + 1, 1, device=device, dtype=dtype).repeat(specgram.shape[1], 1, 1)\n\n    output = torch.nn.functional.conv1d(specgram, kernel, groups=specgram.shape[1]) / denom\n\n    # unpack batch\n    output = output.reshape(shape)\n\n    return output\n\ndef make_delta(input_tensor: torch.Tensor):\n    input_tensor = input_tensor.transpose(3,2)\n    input_tensor = compute_deltas(input_tensor)\n    input_tensor = input_tensor.transpose(3,2)\n    return input_tensor","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.168065Z","iopub.execute_input":"2021-06-01T11:50:58.168827Z","iopub.status.idle":"2021-06-01T11:50:58.183745Z","shell.execute_reply.started":"2021-06-01T11:50:58.168763Z","shell.execute_reply":"2021-06-01T11:50:58.181894Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model","metadata":{}},{"cell_type":"code","source":"class CustomModel(nn.Module):\n    def __init__(self, model_name=\"\", pretrained=False, in_channels=1,spec_aggreagation: str='repeat3'):\n        super().__init__()\n        \n        # Spectrogram extractor\n        self.spectrogram_extractor = Spectrogram(n_fft=CFG.n_fft, hop_length=CFG.hop_length,\n                                                 win_length=CFG.n_fft, window=\"hann\", center=True, pad_mode=\"reflect\",\n                                                 freeze_parameters=True)\n\n        # Logmel feature extractor\n        self.logmel_extractor = LogmelFilterBank(sr=CFG.sample_rate, n_fft=CFG.n_fft,\n                                                 n_mels=CFG.n_mels, fmin=CFG.fmin, fmax=CFG.fmax, ref=1.0, amin=1e-10, top_db=None,\n                                                 freeze_parameters=True)\n\n        # Spec augmenter\n        self.spec_augmenter = SpecAugmentation(time_drop_width=64, time_stripes_num=2,\n                                               freq_drop_width=8, freq_stripes_num=2)\n        self.bn0 = nn.BatchNorm2d(CFG.n_mels)\n        \n        self.spec_aggreagation = spec_aggreagation\n\n        self.model = timm.create_model(model_name, pretrained=pretrained,in_chans=in_channels)\n        \n        if 'rexnet' in model_name:\n            n_features = self.model.head.fc.in_features\n            self.model.head.fc = nn.Linear(n_features, CFG.target_size)\n        elif ('efficientnet' in model_name) or ('densenet' in model_name):\n            n_features = self.model.classifier.in_features\n            self.model.classifier = nn.Linear(n_features, CFG.target_size)\n        elif ('resnet' in model_name) or ('resnext' in model_name)or ('resnest' in model_name):\n            n_features = self.model.fc.in_features\n            self.model.fc = nn.Linear(n_features, CFG.target_size)\n        else:\n            raise NotImplementedError\n            \n\n    def forward(self, input):\n        \"\"\"\n        Input: (batch_size, data_length)\n        \"\"\"\n        x = self.spectrogram_extractor(input)# output:(batch_size, 1(channel), time_steps, freq_bins)\n        x = self.logmel_extractor(x)# output:(batch_size, 1(channel), time_steps, mel_bins)\n        x = x.transpose(1, 3)\n        x = self.bn0(x)\n        x = x.transpose(1, 3)\n        if self.training:\n            x = self.spec_augmenter(x)\n        # 1channel => 3channel\n        if self.spec_aggreagation == 'repeat3':\n            x = torch.cat([x,x,x], dim=1)\n        elif self.spec_aggreagation == 'deltas':\n            delta_1 = make_delta(x)\n            delta_2 = make_delta(delta_1)\n            x = torch.cat([x,delta_1,delta_2], dim=1)\n\n        #x = x.transpose(2, 3)\n        # (batch_size, channels, freq, frames)\n\n        x = self.model(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.186402Z","iopub.execute_input":"2021-06-01T11:50:58.187221Z","iopub.status.idle":"2021-06-01T11:50:58.205474Z","shell.execute_reply.started":"2021-06-01T11:50:58.187159Z","shell.execute_reply":"2021-06-01T11:50:58.204436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def prediction_for_clip(test_df: pd.DataFrame,\n                        clip: np.ndarray,\n                        model):\n    \"\"\"\n    [input]test_df:audiofile一個分のdataframe\n           clip:音声データ\n           model:モデルのインスタンス\n           threshold:\n           \n    [output]preds:ndarray(120,397)\n    \n    \"\"\"\n    model.eval()\n    preds = np.empty((0, len(TARGETS)))\n    dataset = TestDataset(df=test_df,\n                          clip=clip,\n                          waveform_transforms=None)\n    loader = DataLoader(dataset, batch_size=120, shuffle=False)\n    \n    for image, row_id in loader:\n        row_id = row_id[0]\n        image = image.to(device)\n        with torch.no_grad():\n            y_pred = model(image)\n            preds = np.concatenate([preds, torch.sigmoid(y_pred).cpu().numpy()])\n        \n    return preds","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.208047Z","iopub.execute_input":"2021-06-01T11:50:58.208709Z","iopub.status.idle":"2021-06-01T11:50:58.221779Z","shell.execute_reply.started":"2021-06-01T11:50:58.208664Z","shell.execute_reply":"2021-06-01T11:50:58.220548Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_model(model_name, pretrained=False, in_channels=3, spec_aggreagation='repeat3'):\n    # if 'efficientnet' in model_name:\n    #     model = CustomEfficientNet(model_name=model_name, pretrained=pretrained, in_channels=in_channels)\n    # elif 'rexnet' in model_name:\n    #     model = CustomRexNet(model_name=model_name, pretrained=pretrained, in_channels=in_channels)\n    # else:\n    #     raise NotImplementedError\n    model = CustomModel(model_name=model_name,\n                        pretrained=pretrained,\n                        in_channels=in_channels,\n                        spec_aggreagation=spec_aggreagation)\n    device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n    model.to(device)\n    model.eval()\n    \n    return model\n\ndef load_model_weights(model, weights):\n    device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n    state_dict = torch.load(weights, map_location=device)\n    model.load_state_dict(state_dict[\"model\"])","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.224864Z","iopub.execute_input":"2021-06-01T11:50:58.225929Z","iopub.status.idle":"2021-06-01T11:50:58.235327Z","shell.execute_reply.started":"2021-06-01T11:50:58.225771Z","shell.execute_reply":"2021-06-01T11:50:58.234381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Inferene with voting","metadata":{}},{"cell_type":"markdown","source":"# ppNo3","metadata":{}},{"cell_type":"code","source":"def make_location_list(target_list):\n    location_list = np.zeros(len(TARGETS))\n    for i in range(len(TARGETS)):\n        if TARGETS[i] in target_list:\n            location_list[i] = 1\n    return location_list\n\ncol_name_list = pd.read_csv(\"../input/bird2location-list/col_list.csv\")[\"bird\"].values.tolist()\ncor_name_list = pd.read_csv(\"../input/bird2location-list/cor_list.csv\")[\"bird\"].values.tolist()\nsne_name_list = pd.read_csv(\"../input/bird2location-list/sne_list.csv\")[\"bird\"].values.tolist()\nssw_name_list = pd.read_csv(\"../input/bird2location-list/ssw_list.csv\")[\"bird\"].values.tolist()\n\nCOL_list = make_location_list(col_name_list)\nCOR_list = make_location_list(cor_name_list)\nSNE_list = make_location_list(sne_name_list)\nSSW_list = make_location_list(ssw_name_list)","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.237527Z","iopub.execute_input":"2021-06-01T11:50:58.238245Z","iopub.status.idle":"2021-06-01T11:50:58.268038Z","shell.execute_reply.started":"2021-06-01T11:50:58.238106Z","shell.execute_reply":"2021-06-01T11:50:58.266962Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ppNo2,4,6,7","metadata":{}},{"cell_type":"code","source":"def get_adjust_score(score, optim_thresh):\n    # ppNo6\n    tmp = np.copy(score)\n    for i in range(len(tmp)):\n        tmp[i,:] = tmp[i,:] - optim_thresh# ppNo4\n    sum_score = np.sum(tmp>0, axis=0)#(397,)\n    adjust_score = np.zeros(397)\n    #print(max_score.shape, adjust_score.shape)\n    adjust_score[sum_score>10] = 0.1\n\n    return adjust_score\n\ndef post_process_site_12(preds, target_list, optim_thresh, maxpreds=3):\n    \"\"\"\n    input: preds(120, 397)\n    \"\"\"\n    #preds = preds * (preds >= threshold)   # remove preds < threshold\n\n    next_preds = np.concatenate([preds[1:], np.zeros((1, preds.shape[-1]))])   # pred corresponding to next window\n    prev_preds = np.concatenate([np.zeros((1, preds.shape[-1])), preds[:-1]])  # pred corresponding to previous window\n    n_n_preds = np.concatenate([preds[2:], np.zeros((2, preds.shape[-1]))])   # ppNo1\n    p_p_preds = np.concatenate([np.zeros((2, preds.shape[-1])), preds[:-2]])  # ppNo1\n    n_n_n_preds = np.concatenate([preds[3:], np.zeros((3, preds.shape[-1]))])   # ppNo1\n    p_p_p_preds = np.concatenate([np.zeros((3, preds.shape[-1])), preds[:-3]])  # ppNo1\n    \n    score = preds + 0.5 * (next_preds + prev_preds + n_n_preds + p_p_preds + n_n_n_preds + p_p_p_preds)# ppNo1\n    \n    score[:, target_list==0] = 0# ppNo2\n    \n    # ppNo6\n    adjust_score = get_adjust_score(score[:40], optim_thresh)\n    adjust_score2 = get_adjust_score(score[40:80], optim_thresh)\n    adjust_score3 = get_adjust_score(score[80:], optim_thresh)\n    \n    for i in range(len(score)):\n        if i < 40:\n            score[i,:] = score[i,:] - optim_thresh + adjust_score# ppNo4,6\n        elif i < 80:\n            score[i,:] = score[i,:] - optim_thresh + adjust_score2# ppNo4,6\n        else:\n            score[i,:] = score[i,:] - optim_thresh + adjust_score3# ppNo4,6\n            \n    # ppNo7\n    birdcall_one = -1*np.ones(score.shape)\n    birdcall_one[score>0] = 1\n    \n    for i in range(birdcall_one.shape[1]): # each species\n        sum_ = 0\n        target_species = birdcall_one[:,i]\n        if np.sum(target_species[target_species==1]) >= 6:# speed up\n            for j in range(birdcall_one.shape[0]): # each time\n                if j == 0: # zero time\n                    if birdcall_one[j,i] == 1:\n                        begin = j\n                        sum_ += 1\n                else:\n                    if birdcall_one[j-1,i] * birdcall_one[j,i] > 0:#birdcall -> birdcall or nocall -> nocall\n                        if birdcall_one[j,i] > 0:#birdcall -> birdcall\n                            sum_ += 1\n                    else: #birdcall_one[j,i] * birdcall_one[j,i] < 0:\n                        if birdcall_one[j,i] < 0:#birdcall -> nocall\n                            if sum_ >= 6:\n                                score[begin,i] = -1\n                                score[begin+1,i] = -1\n                                score[j-1,i] = -1\n                                score[j,i] = -1\n                            sum_ = 0\n                        else: #nocall -> birdcall\n                            begin = j\n                            sum_ += 1\n    \n    n_birds = (score >= 0).sum(-1)   # Counting birds\n    n_birds = np.clip(n_birds, 0, maxpreds)  # keep at most maxpreds birds\n    \n    labels = [np.argsort(- score[i])[:n_birds[i]] for i in range(len(preds))]  # Getting the n_birds most likely class indices\n    \n    class_labels = [\" \".join([TARGETS[l] for l in label]) for label in labels]  # Getting class names\n    \n    return class_labels","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.271327Z","iopub.execute_input":"2021-06-01T11:50:58.271596Z","iopub.status.idle":"2021-06-01T11:50:58.295223Z","shell.execute_reply.started":"2021-06-01T11:50:58.271568Z","shell.execute_reply":"2021-06-01T11:50:58.293189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def vote(preds, min_votes=3):\n    votes = Counter(preds)\n    return [c for c, count in votes.items() if count >= min_votes]","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.297482Z","iopub.execute_input":"2021-06-01T11:50:58.298582Z","iopub.status.idle":"2021-06-01T11:50:58.307992Z","shell.execute_reply.started":"2021-06-01T11:50:58.298533Z","shell.execute_reply":"2021-06-01T11:50:58.305215Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def reformat_preds(preds, df):\n    prediction_df = pd.DataFrame({\n        'row_id': df['row_id'].values,\n        'birds': preds\n    })\n    \n    prediction_df['birds'] = prediction_df['birds'].replace([''],'nocall')\n    \n    return prediction_df","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.311349Z","iopub.execute_input":"2021-06-01T11:50:58.311817Z","iopub.status.idle":"2021-06-01T11:50:58.319257Z","shell.execute_reply.started":"2021-06-01T11:50:58.311768Z","shell.execute_reply":"2021-06-01T11:50:58.3178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def inference_voting(test_audios,configs, models, optim_thresh, min_votes=3):\n    pred_dfs = []\n    for audio_path in tqdm(test_audios):\n        clip, _ = sf.read(audio_path)\n            \n        # 1clip分のdfを作成\n        seconds = []\n        row_ids = []\n        for second in range(5, 605, 5):\n            row_id = \"_\".join(audio_path.name.split(\"_\")[:2]) + f\"_{second}\"\n            seconds.append(second)\n            row_ids.append(row_id)\n\n        #ppNo2\n        site = \"ALL\"\n        if \"SSW\" in row_ids[0]:\n            site = \"SSW\"\n            target_list = np.copy(SSW_list)\n        elif \"COR\" in row_ids[0]:\n            site = \"COR\"\n            target_list = np.copy(COR_list)\n        elif \"COL\" in row_ids[0]:\n            site = \"COL\"\n            target_list = np.copy(COL_list)\n        else:\n            target_list = np.copy(SNE_list)\n        \n        test_df = pd.DataFrame({\n            \"row_id\": row_ids,\n            \"seconds\": seconds\n        })\n        all_preds = []\n        for i in range(len(models)): # モデルの種類\n            preds =[]\n            for model in models[i]: # fold分\n                pred = prediction_for_clip(test_df, clip, model)\n                #120行*397クラスの予測が帰ってくる\n                preds.append(pred)\n            preds = np.mean(preds, 0)\n            \n            # postprocess\n            #preds_pp = post_process_site_12(preds, target_list, optim_thresh[i])\n            if (site == \"COR\") or (site == \"SSW\"):\n                preds_pp = post_process_site_12(preds, target_list, config.TEYO.models[i][\"optim_thresh\"][site][0])\n            elif (site == \"COL\"):\n                preds_pp = post_process_site_12(preds, target_list, config.TEYO.models[i][\"optim_thresh\"][\"COR\"][0])\n            else:\n                preds_pp = post_process_site_12(preds, target_list, config.TEYO.models[i][\"optim_thresh\"][\"ALL\"][0])\n            all_preds.append(preds_pp)\n            #print(\"Predicted classes :\", preds_pp)\n            \n        final_preds = []\n        #print(f\"{len(all_preds[0])},{len(all_preds)}\")\n        for i in range(len(all_preds[0])): # 120\n            preds = []\n            for m in range(len(all_preds)): # モデル種数\n                preds += all_preds[m][i].split(' ')\n                \n            final_pred = vote(preds, min_votes=min_votes)\n            final_preds.append(' '.join(final_pred))\n        #print(\"\\n    -> Voted classes :\", final_preds)\n        pred_df = reformat_preds(final_preds, test_df)\n        pred_dfs.append(pred_df)\n    \n    sub = pd.concat(pred_dfs, axis=0, sort=False).reset_index(drop=True)\n    return sub","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.322008Z","iopub.execute_input":"2021-06-01T11:50:58.322511Z","iopub.status.idle":"2021-06-01T11:50:58.340459Z","shell.execute_reply.started":"2021-06-01T11:50:58.322465Z","shell.execute_reply":"2021-06-01T11:50:58.338475Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class config:\n    INPUT_ROOT = \"/kaggle/input/birdclef-2021\"\n    WORK_ROOT = \"/kaggle/working\"\n    SAMPLE_RATE = 32000\n    SEED = 416\n    SITE_LST = [\"COL\", \"COR\", \"SNE\", \"SSW\"]\n    N_LABELS = 397\n        \n    class TEYO:\n        n_mels = 128\n        fmin = 20\n        fmax = 16000\n        n_fft = 2048\n        hop_length = 512\n        models = [\n            {\"name\": 'rexnet_200',\n             \"weights\": [f'../input/bird2021/exp13_rexnet200_last/rexnet_200_fold{i}_last.pth' for i in range(5)],\n             \"spec_aggreagation\":'deltas',\n             \"optim_thresh\": \"../input/bird2021/exp13_rexnet200_last/ex13_rexnet_last_optim_thresh.pkl\"},\n            \n            {\"name\": 'rexnet_200',\n             \"weights\": [f'../input/bird2021/exp17_rexnet_200_loss/rexnet_200_fold{i}_best_loss.pth' for i in range(5)],\n             \"spec_aggreagation\":'deltas',\n             \"optim_thresh\":  \"../input/bird2021/exp17_rexnet_200_loss/ex17_rexnet_loss_optim_thresh.pkl\"},\n            \n            {\"name\": 'rexnet_200',\n             \"weights\": [f'../input/bird2021/exp23_rexnet200/rexnet_200_fold{i}_best_f1.pth' for i in range(2)],\n             \"spec_aggreagation\":'deltas',\n             \"optim_thresh\":  \"../input/bird2021/exp23_rexnet200/ex23_rexnet_f1_optim_thresh.pkl\"},\n            \n            {\"name\": 'densenet161',\n             \"weights\": [f'../input/bird2021/exp23_dense161_f1/densenet161_fold{i}_best_f1.pth' for i in range(5)],\n             \"spec_aggreagation\":'deltas',\n             \"optim_thresh\" : \"../input/bird2021/exp23_dense161_loss/ex23_dense161_loss_optim_thresh.pkl\"},\n    # \n            # {\"name\": 'tf_efficientnetv2_s',\n            #  \"weights\": [f'../input/bird2021/exp19_effnetv2f1/tf_efficientnetv2_s_fold{i}_best_f1.pth' for i in range(5)],\n            #  \"spec_aggreagation\":'deltas',\n            #  \"optim_thresh\": \"../input/bird2021/exp19_effnetv2f1/ex19_effv2_f1_optim_thresh.pkl\"},\n            # \n            # {\"name\": 'resnext50_32x4d',\n            #  \"weights\": [f'../input/bird2021/exp17_resnext_f1/resnext50_32x4d_fold{i}_best_f1.pth' for i in range(4)],\n            #  \"spec_aggreagation\":'deltas',\n            #  \"optim_thresh\" : \"../input/bird2021/exp17_resnext_f1/ex17_resnext_f1_optim_thresh.pkl\"},\n    # \n            {\"name\": 'resnest50d',\n             \"weights\": [f'../input/bird2021/exp17_resnest_f1/resnest50d_fold{i}_best_f1.pth' for i in range(4)],\n             \"spec_aggreagation\":'deltas',\n             \"optim_thresh\": \"../input/bird2021/exp17_resnest_f1/ex17_resnest_f1_optim_thresh.pkl\"},\n        ]\nimport cloudpickle\nfor i in range(len(config.TEYO.models)):\n    path = config.TEYO.models[i][\"optim_thresh\"]\n    with open(path, \"rb\") as f:\n        config.TEYO.models[i][\"optim_thresh\"] = cloudpickle.loads(f.read())\n    for site in [\"SSW\", \"COR\", \"ALL\"]:\n        config.TEYO.models[i][\"optim_thresh\"][site][0][265] = config.TEYO.models[i][\"optim_thresh\"][site][0][265] - 0.4#reevir1\n        config.TEYO.models[i][\"optim_thresh\"][site][0][286] = config.TEYO.models[i][\"optim_thresh\"][site][0][286] - 0.2#rucwar\n        config.TEYO.models[i][\"optim_thresh\"][site][0][315] = config.TEYO.models[i][\"optim_thresh\"][site][0][315] - 0.4#sonspa\n        config.TEYO.models[i][\"optim_thresh\"][site][0][130] = config.TEYO.models[i][\"optim_thresh\"][site][0][130] - 0.2#eawpew\n        config.TEYO.models[i][\"optim_thresh\"][site][0][168] = config.TEYO.models[i][\"optim_thresh\"][site][0][168] - 0.2#grycat\n        config.TEYO.models[i][\"optim_thresh\"][site][0][357] = config.TEYO.models[i][\"optim_thresh\"][site][0][357] - 0.2#westan\n        config.TEYO.models[i][\"optim_thresh\"][site][0][148] = config.TEYO.models[i][\"optim_thresh\"][site][0][148] - 0.2#gockin\n        config.TEYO.models[i][\"optim_thresh\"][site][0][216] = config.TEYO.models[i][\"optim_thresh\"][site][0][216] - 0.2#mouqua\n        config.TEYO.models[i][\"optim_thresh\"][site][0][213] = config.TEYO.models[i][\"optim_thresh\"][site][0][213] - 0.2#mouchi\n        config.TEYO.models[i][\"optim_thresh\"][site][0][58]  = config.TEYO.models[i][\"optim_thresh\"][site][0][58] - 0.2#brncre","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.343405Z","iopub.execute_input":"2021-06-01T11:50:58.344117Z","iopub.status.idle":"2021-06-01T11:50:58.403735Z","shell.execute_reply.started":"2021-06-01T11:50:58.344071Z","shell.execute_reply":"2021-06-01T11:50:58.40283Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"models = []\nfor _conf in config.TEYO.models:\n    print(_conf['name'])\n    models_ = []\n    for weights in _conf['weights']:\n        model = get_model(model_name=_conf['name'], spec_aggreagation=_conf['spec_aggreagation'])\n        load_model_weights(model, weights)\n        model.eval()\n        models_.append(model)\n    models.append(models_)","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:50:58.40547Z","iopub.execute_input":"2021-06-01T11:50:58.406172Z","iopub.status.idle":"2021-06-01T11:52:06.056251Z","shell.execute_reply.started":"2021-06-01T11:50:58.406127Z","shell.execute_reply":"2021-06-01T11:52:06.055006Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# prediction","metadata":{}},{"cell_type":"code","source":"optim_thresh = np.load(\"../input/birdclef-infer-ppno2-3-4-6-7-rex200s-serchth/optim_thresh.npy\")","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:52:06.058679Z","iopub.execute_input":"2021-06-01T11:52:06.059097Z","iopub.status.idle":"2021-06-01T11:52:06.069045Z","shell.execute_reply.started":"2021-06-01T11:52:06.059054Z","shell.execute_reply":"2021-06-01T11:52:06.067923Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(models)","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:52:06.070781Z","iopub.execute_input":"2021-06-01T11:52:06.071307Z","iopub.status.idle":"2021-06-01T11:52:06.08115Z","shell.execute_reply.started":"2021-06-01T11:52:06.071273Z","shell.execute_reply":"2021-06-01T11:52:06.079376Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"min_votes = 3\nsubmission = inference_voting(test_audios=all_audios,\n                              configs=config,\n                              models=models,\n                              optim_thresh = optim_thresh,\n                              min_votes=min_votes)","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:52:06.083434Z","iopub.execute_input":"2021-06-01T11:52:06.084052Z","iopub.status.idle":"2021-06-01T11:56:20.293653Z","shell.execute_reply.started":"2021-06-01T11:52:06.084004Z","shell.execute_reply":"2021-06-01T11:56:20.292005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:56:20.296282Z","iopub.execute_input":"2021-06-01T11:56:20.296923Z","iopub.status.idle":"2021-06-01T11:56:20.311903Z","shell.execute_reply.started":"2021-06-01T11:56:20.296877Z","shell.execute_reply":"2021-06-01T11:56:20.310502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv(\"submission.csv\", index=False)\n# submission","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:56:20.313938Z","iopub.execute_input":"2021-06-01T11:56:20.314867Z","iopub.status.idle":"2021-06-01T11:56:20.331318Z","shell.execute_reply.started":"2021-06-01T11:56:20.314787Z","shell.execute_reply":"2021-06-01T11:56:20.330309Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_metrics(s_true, s_pred):\n    s_true = set(s_true.split())\n    s_pred = set(s_pred.split())\n    n, n_true, n_pred = len(s_true.intersection(s_pred)), len(s_true), len(s_pred)\n    \n    prec = n/n_pred\n    rec = n/n_true\n    f1 = 2*prec*rec/(prec + rec) if prec + rec else 0\n    \n    return {\"f1\": f1, \"prec\": prec, \"rec\": rec, \"n_true\": n_true, \"n_pred\": n_pred, \"n\": n}\n    \n\nsub = pd.read_csv(\"./submission.csv\")\nif TARGET_PATH:\n    sub_target = pd.read_csv(TARGET_PATH)\n    sub_target = sub_target.merge(sub, how=\"left\", on=\"row_id\")\n    print(sub_target[\"birds_x\"].notnull().sum(), sub_target[\"birds_x\"].notnull().sum())\n    assert sub_target[\"birds_x\"].notnull().all()\n    assert sub_target[\"birds_y\"].notnull().all()\n    \n    df_metrics = pd.DataFrame([get_metrics(s_true, s_pred) for s_true, s_pred in zip(sub_target.birds_x, sub_target.birds_y)])\n    \n    print(df_metrics.mean())","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:56:20.33347Z","iopub.execute_input":"2021-06-01T11:56:20.334004Z","iopub.status.idle":"2021-06-01T11:56:20.383933Z","shell.execute_reply.started":"2021-06-01T11:56:20.333945Z","shell.execute_reply":"2021-06-01T11:56:20.382481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.save(\"optim_thresh.npy\", optim_thresh)","metadata":{"execution":{"iopub.status.busy":"2021-06-01T11:56:20.386042Z","iopub.execute_input":"2021-06-01T11:56:20.386492Z","iopub.status.idle":"2021-06-01T11:56:20.392556Z","shell.execute_reply.started":"2021-06-01T11:56:20.38645Z","shell.execute_reply":"2021-06-01T11:56:20.3912Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### ","metadata":{}}]}