{"cells":[{"metadata":{},"cell_type":"markdown","source":"# https://www.kaggle.com/fffrrt/all-in-one-rfcx-baseline-for-beginners"},{"metadata":{},"cell_type":"markdown","source":"# TODO\n\n* [X] K-fold\n* [ ] Ensembles\n* [ ] More data\n* [X] Input data preparation\n* [ ] Data Augmentation\n* [ ] LWRAP\n* [ ] Logging to the file."},{"metadata":{},"cell_type":"markdown","source":"* I'm normalizing the samples globally, with respect to the entire training set.\n* https://www.kaggle.com/c/rfcx-species-audio-detection/discussion/207624\n* Check if there are any other labels in the current range (t_min-t_max)"},{"metadata":{"trusted":true},"cell_type":"code","source":"save_to_disk = 0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport csv\nimport time\nimport pickle\nfrom pathlib import Path\nfrom tqdm import tqdm\nimport librosa\n\nfrom PIL import Image\n\nimport numpy as np\nimport pandas as pd\nimport cv2\nfrom skimage.transform import resize\n\nimport matplotlib.pyplot as plt\n\nfrom IPython.display import FileLink # , Image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!mkdir ../working/bmps","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"BASE_TRAIN_PATH = \"../input/rfcx-species-audio-detection/train/\"\nBASE_TEST_PATH = \"../input/rfcx-species-audio-detection/test/\"\n\nBASE_BMP_DIR = \"../working/bmps/\"\nfft = 2048\nhop = 512\nsr = 48000\nlength = 10 * sr\n\nfmin = 24000\nfmax = 0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_tp_fn = \"../input/rfcx-species-audio-detection/train_tp.csv\"\ndf_tr_tp = pd.read_csv(train_tp_fn)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fmin, fmax = df_tr_tp.f_min.min(), df_tr_tp.f_max.max()\nfmin, fmax","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fmin = int(fmin * 0.9)\nfmax = int(fmax * 1.1)\nfmin, fmax","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"total_rows = len(df_tr_tp)\ntotal_rows","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def normalize_melspec(X: np.ndarray):\n    eps = 1e-6\n    mean = X.mean()\n    X = X - mean\n    std = X.std()\n    Xstd = X / (std + eps)\n    norm_min, norm_max = Xstd.min(), Xstd.max()\n    if (norm_max - norm_min) > eps:\n        V = Xstd\n        V[V < norm_min] = norm_min\n        V[V > norm_max] = norm_max\n        V = 255 * (V - norm_min) / (norm_max - norm_min)\n        V = V.astype(np.uint8)\n    else:\n        # Just zero\n        V = np.zeros_like(Xstd, dtype=np.uint8)\n    return V\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n# melspec = librosa.feature.melspectrogram(\n#     y_batch, sr=sr, **self.melspectrogram_parameters)\n# pcen = librosa.pcen(melspec, sr=sr, **self.pcen_parameters)\n# clean_mel = librosa.power_to_db(melspec ** 1.5)\n# melspec = librosa.power_to_db(melspec)\n\n# norm_melspec = normalize_melspec(melspec)\n# norm_pcen = normalize_melspec(pcen)\n# norm_clean_mel = normalize_melspec(clean_mel)\n# image = np.stack([norm_melspec, norm_pcen, norm_clean_mel], axis=-1)\n# height, width, _ = image.shape\n# image = cv2.resize(image, (int(width * 224 / height), 224))\n# image = np.moveaxis(image, 2, 0)\n# image = (image / 255.0).astype(np.float32)\n\n# images.append(image)\n# images = np.asarray(images).astype(np.float32)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pcen_parameters = {\n    \"gain\": 0.98,\n    \"bias\": 2,\n    \"power\": 0.5,\n    \"time_constant\": 0.4,\n    \"eps\": 0.000001\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for row in df_tr_tp.itertuples():\n\n    wav, sr = librosa.load(f\"{BASE_TRAIN_PATH}{row.recording_id}.flac\", sr=None)\n    \n    t_min = float(row.t_min) * sr\n    t_max = float(row.t_max) * sr\n    \n    center = np.round((t_min + t_max) / 2)\n    beginning = center - length / 2\n    if beginning < 0:\n        beginning = 0\n        \n    ending = beginning + length\n    if ending > len(wav):\n        ending = len(wav)\n        beginning = ending - length\n        \n    slic = wav[int(beginning): int(ending)]\n    mel_spec = librosa.feature.melspectrogram(slic, sr=sr, fmin=fmin, fmax=fmax, n_mels=128)\n    pcen = librosa.pcen(mel_spec, sr=sr, **pcen_parameters)\n    clean_mel = librosa.power_to_db(mel_spec ** 1.5)\n#     mel_spec = librosa.power_to_db(mel_spec)\n    norm_mel_spec = normalize_melspec(mel_spec)\n    norm_pcen = normalize_melspec(pcen)\n    norm_clean_mel = normalize_melspec(clean_mel)\n    image = np.stack([norm_mel_spec, norm_pcen, norm_clean_mel], axis=-1)\n    height, width, _ = image.shape\n    image = cv2.resize(image, (int(width * 224 / height), 224))\n#     image = (image).astype(np.float32)\n#     mel_spec = resize(mel_spec, (224, 400))\n#     mel_spec = mel_spec - np.min(mel_spec)\n#     mel_spec = mel_spec / np.max(mel_spec)\n#     mel_spec = mel_spec * 255\n#     mel_spec = np.round(mel_spec)\n#     mel_spec = mel_spec.astype(\"uint8\")\n#     print(mel_spec.shape)\n#     mel_spec = np.asarray(mel_spec)\n# #     break\n    bmp = Image.fromarray(image)\n    \n    bmp.save(f\"{BASE_BMP_DIR}{row.recording_id}_{row.species_id}_{str(int(center))}.bmp\")\n    if row.Index % 100 == 0 and row.Index > 0:\n        print(f\"Processed {str(row.Index)} train examples from {total_rows}\")\n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport random\nimport torch\n\nnum_birds = 24\nbatch_size = 16\nSEED = 42\n\ndef set_seed(seed):\n    random.seed(seed)\n    np.random.seed(seed)\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n    \nset_seed(SEED)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from torch.utils.data import Dataset, DataLoader\n\n\nclass RainforestDataset(Dataset):\n    \n    def __init__(self, filelist):\n        \n        self.filelist = filelist\n        self.labels = []\n        for file in filelist:\n            label = int(file.split('_')[1])\n            label_array = np.zeros(num_birds, dtype=np.single)\n            label_array[label] = 1.0\n            self.labels.append(label_array)\n            \n    \n    def __len__(self):\n        return len(self.labels)\n    \n    \n    def __getitem__(self, idx):\n        \n        current_filename = self.filelist[idx]\n        img = Image.open(current_filename)\n        mel_spec = np.array(img)\n        img.close()\n        \n#         image = np.moveaxis(image, 2, 0)\n#         image = (image / 255.0).astype(np.float32)\n\n#         images.append(image)\n#         images = np.asarray(images).astype(np.float32)\n        mel_spec = np.moveaxis(mel_spec, 2, 0)\n        mel_spec = (mel_spec / 255.0).astype(np.float32)\n#         mel_spec = mel_spec / 255.0\n#         mel_spec = np.stack((mel_spec, mel_spec, mel_spec))\n        return mel_spec, self.labels[idx]\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"file_list = []\nlabel_list = []\nfor file in Path(BASE_BMP_DIR).iterdir():\n    \n    file_list.append(file.as_posix())\n    label = str(file).split('_')[1]\n    label_list.append(label)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# {\n#     \"0\": {\n#         \"train_idx\": [1, 2, 3],\n#         \"valid_idx\": [4, 5, 6]\n#     },\n#     \"1\": {\n#         \"train_idx\": [2, 3, 5],\n#         \"valid_idx\": [1, 4, 6]\n#     },\n#     ...\n# }","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import StratifiedKFold\n\n# TODO: Make n_splits is defined as constant at the beginning of the notebook.\nskf = StratifiedKFold(n_splits=5, shuffle=True, random_state=SEED)\nfold_indices = {}\n\nfor fold_id, (train_idx, valid_idx) in enumerate(skf.split(file_list, label_list)):\n    \n    fold_indices[fold_id] = {}\n    fold_indices[fold_id][\"train_idx\"] = np.take(file_list, train_idx)\n    fold_indices[fold_id][\"valid_idx\"] = np.take(file_list, valid_idx)\n    \n    # if fold_id == 0:\n    #     train_files = np.take(file_list, train_idx)\n    #     valid_files = np.take(file_list, valid_idx)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# dataset = RainforestDataset(fold_indices[0][\"train_idx\"])\n# data_loader = DataLoader(dataset, batch_size=2, shuffle=False)\n\n# for data, target in data_loader:\n#     print()\n#     break","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install resnest > /dev/null","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch.nn as nn\nfrom resnest.torch import resnest50","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"N_EPOCHS = 60\n\nDEVICE = \"cuda\" if torch.cuda.is_available() else \"cpu\"\nDEVICE","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def save_losses_plot(experiment_dir, fold_id, train_losses, valid_losses):\n    \n    plt.plot(train_losses, label=f\"fold_{fold_id}_train_loss\")\n    plt.plot(valid_losses, label=f\"fold_{fold_id}_valid_loss\")\n    plt.legend(loc=\"best\")\n    plt.savefig(experiment_dir / f\"fold_{fold_id}_losses.png\")\n    plt.close()\n    # plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train_fold(experiment_dir, fold_id, model, loss_fn, optimizer, scheduler, train_data_loader, valid_data_loader):\n    \n    # TODO: Calculate the correct counts.\n    best_corrects = 0\n    best_val_loss = float(\"inf\")\n    train_losses = []\n    valid_losses = []\n    \n    train_corrects = []\n    valid_corrects = []\n    \n    train_start_time = time.time()\n\n    for epoch in range(N_EPOCHS):\n\n        train_loss = []\n        valid_loss = []\n        # train_corr = []\n\n        single_train_epoch_start = time.time()\n        # Single epoch train.\n        for idx, (data, target) in enumerate(train_data_loader):\n\n            data = data.float() # float64 to float32\n            data = data.to(DEVICE)\n            target = target.to(DEVICE)\n\n            optimizer.zero_grad()\n            output = model(data)\n            loss = loss_fn(output, target)\n            loss.backward()\n            optimizer.step()\n#             # Stats.\n#             _, answers = torch.max(output, 1)\n#             _, targets = torch.max(target, 1)\n#             corrects = 0\n            \n#             for i in range(0, len(answers)):\n#                 if answers[i] == targets[i]:\n#                     corrects = corrects + 1\n#             train_corrects.append(corrects)\n            \n            train_loss.append(loss.item())\n\n        current_train_loss = sum(train_loss) / len(train_loss)\n        train_losses.append(current_train_loss)\n        total_valid_ = 0\n        # Validation.\n        with torch.no_grad():\n            \n            valid_corrects = []\n            \n            for idx, (data, target) in enumerate(valid_data_loader):\n\n                data = data.float()\n                data = data.to(DEVICE)\n                target = target.to(DEVICE)\n\n                output = model(data)\n                loss = loss_fn(output, target)\n                valid_loss.append(loss.item())\n                # Stats.\n                _, answers = torch.max(output, 1)\n                _, targets = torch.max(target, 1)\n                corrects = 0\n\n                for i in range(0, len(answers)):\n                    if answers[i] == targets[i]:\n                        corrects = corrects + 1\n                valid_corrects.append(corrects)\n                total_valid_ += len(answers)\n                \n        current_valid_loss = sum(valid_loss) / len(valid_loss)\n        valid_losses.append(current_valid_loss)\n        \n        took_single_epoch_train = time.time() - single_train_epoch_start\n        \n        for g in optimizer.param_groups:\n            lr = g[\"lr\"]\n            \n        print(f\"{epoch+1}/{N_EPOCHS}. Train_loss: {current_train_loss:.5f} Valid_loss: {current_valid_loss:.5f} LR: {str(lr)} Took: {took_single_epoch_train:.3f} secs.\")\n        \n        if current_valid_loss < best_val_loss:\n\n            print(f\"Loss improved from {best_val_loss:.5f} to {current_valid_loss:.5f}. Saving the model...\")\n            torch.save(model, experiment_dir / f\"best_model_fold_{fold_id}.pth\")\n            best_val_loss = current_valid_loss\n        \n        if sum(valid_corrects) > best_corrects:\n            print(f\"Correct count increased from {best_corrects} to {sum(valid_corrects)} out of {total_valid_}. Saving the model...\")\n            torch.save(model, experiment_dir / f\"correct_best_model_fold_{fold_id}.pth\")\n            best_corrects = sum(valid_corrects)\n            \n        # Scheduler update.\n        scheduler.step()\n\n        # print(\"=\" * 50)\n\n    total_train_time_in_sc = time.time() - train_start_time\n    print(f\"Training fold {fold_id} took {total_train_time_in_sc:.3f} secs.\")\n    \n    return train_losses, valid_losses\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def generate_resnest_50(pretrained):\n    model = resnest50(pretrained=True)\n\n    model.fc = nn.Sequential(\n        nn.Linear(2048, 1024),\n        nn.ReLU(),\n        nn.Dropout(p=0.3),\n        nn.Linear(1024, 1024),\n        nn.ReLU(),\n        nn.Dropout(p=0.3),\n        nn.Linear(1024, num_birds)\n    )\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train():\n    \n    N_FOLDS = 5\n    EXPERIMENT_DIR = Path(\"resnest50_v2_image_features_updated_adam_e_60_d_0.3\")\n    EXPERIMENT_DIR.mkdir()\n    set_seed(SEED)\n    \n\n    for fold_id in range(N_FOLDS):\n        \n        print(f\"{'=' * 20} Training fold: {fold_id} {'=' * 20}\")\n        \n        train_files = fold_indices[fold_id][\"train_idx\"]\n        valid_files = fold_indices[fold_id][\"valid_idx\"]\n        train_dataset = RainforestDataset(train_files)\n        valid_dataset = RainforestDataset(valid_files)\n\n        train_data_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\n        valid_data_loader = DataLoader(valid_dataset, batch_size=batch_size, shuffle=False)\n        \n        model = generate_resnest_50(pretrained=True)\n#         optimizer = torch.optim.SGD(model.parameters(), \n#                             lr=0.01, weight_decay=0.0001, momentum=0.9)\n#         scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.4)\n        \n        optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n        scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=10)\n    \n        pos_weights = torch.ones(num_birds)\n        pos_weights = pos_weights * num_birds\n        loss_fn = nn.BCEWithLogitsLoss() # pos_weight=pos_weights\n            \n        model = model.to(DEVICE)\n        loss_fn = loss_fn.to(DEVICE)\n        # (fold_id, model, loss_fn, optimizer, scheduler, train_data_loader, valid_data_loader):\n        fold_train_losses, fold_valid_losses = train_fold(EXPERIMENT_DIR, fold_id, model, loss_fn, optimizer, scheduler, train_data_loader, valid_data_loader)\n        \n        # Saving the loss history to file.\n        with open(EXPERIMENT_DIR / f\"fold_{fold_id}_train_losses.pkl\", \"wb\") as f:\n            pickle.dump(fold_train_losses, f)\n        \n        with open(EXPERIMENT_DIR / f\"fold_{fold_id}_valid_losses.pkl\", \"wb\") as f:\n            pickle.dump(fold_valid_losses, f)\n        \n        save_losses_plot(EXPERIMENT_DIR, fold_id, fold_train_losses, fold_valid_losses)\n        \n        print(f\"{'=' * 20} DONE Training fold: {fold_id} {'=' * 20}\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from IPython.display import Image as ImageDisplay","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ImageDisplay(\"resnest50_v2_image_features_updated_adam_e_60_d_0.3/fold_0_losses.png\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ImageDisplay(\"resnest50_v2_image_features_updated_adam_e_60_d_0.3/fold_1_losses.png\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ImageDisplay(\"resnest50_v2_image_features_updated_adam_e_60_d_0.3/fold_2_losses.png\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ImageDisplay(\"resnest50_v2_image_features_updated_adam_e_60_d_0.3/fold_3_losses.png\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ImageDisplay(\"resnest50_v2_image_features_updated_adam_e_60_d_0.3/fold_4_losses.png\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls resnest50_v2_image_features_updated_adam_e_60_d_0.3/","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!zip -r resnest50_v2_image_features_updated_adam_e_60_d_0.3.zip resnest50_v2_image_features_updated_adam_e_60_d_0.3","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"FileLink(\"resnest50_v2_image_features_updated_adam_e_60_d_0.3.zip\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# # TODO: Calculate the correct counts.\n# best_corrects = 0\n# best_val_loss = float(\"inf\")\n# train_losses = []\n# valid_losses = []\n\n# train_start_time = time.time()\n# print(f\"{'='*10} Training started {'='*10}\")\n# for epoch in range(N_EPOCHS):\n    \n#     train_loss = []\n#     valid_loss = []\n#     # train_corr = []\n    \n#     single_train_epoch_start = time.time()\n#     # Single epoch train.\n#     for idx, (data, target) in enumerate(train_data_loader):\n\n#         data = data.float() # float64 to float32\n#         data = data.to(DEVICE)\n#         target = target.to(DEVICE)\n        \n#         optimizer.zero_grad()\n#         output = model(data)\n#         loss = loss_fn(output, target)\n#         loss.backward()\n#         optimizer.step()\n#         # _, answers = torch.max(output, 1)\n#         # _, targets = torch.max(target, 1)\n#         train_loss.append(loss.item())\n    \n#     current_train_loss = sum(train_loss) / len(train_loss)\n#     train_losses.append(current_train_loss)\n#     took_single_epoch_train = time.time() - single_train_epoch_start\n    \n#     for g in optimizer.param_groups:\n#         lr = g[\"lr\"]\n#         print(f\"Epoch: {epoch} training done. LR: {str(lr)} Loss: {current_train_loss:.5f} Took: {took_single_epoch_train:.3f} secs.\")\n    \n#     single_valid_start = time.time()\n#     # Validation.\n#     with torch.no_grad():\n        \n#         for idx, (data, target) in enumerate(valid_data_loader):\n            \n#             data = data.float()\n#             data = data.to(DEVICE)\n#             target = target.to(DEVICE)\n            \n#             output = model(data)\n#             loss = loss_fn(output, target)\n#             valid_loss.append(loss.item())\n            \n#     current_valid_loss = sum(valid_loss) / len(valid_loss)\n#     valid_losses.append(current_valid_loss)\n#     took_single_epoch_valid = time.time() - single_valid_start\n#     print(f\"Epoch: {epoch} validation done. LR: {str(lr)} Valid Loss: {current_valid_loss:.5f} Took: {took_single_epoch_valid:.3f} secs.\")\n    \n#     if current_valid_loss < best_val_loss:\n        \n#         print(f\"Loss improved from {best_val_loss:.5f} to {current_valid_loss:.5f}. Saving the model...\")\n#         torch.save(model, \"best_model.pth\")\n#         best_val_loss = current_valid_loss\n            \n#     # Scheduler update.\n#     scheduler.step()\n    \n#     print(\"=\" * 50)\n    \n# total_train_time_in_sc = time.time() - train_start_time\n# print(f\"{'='*10} Training ended {'='*10}\")\n# print(f\"Training took {total_train_time_in_sc} secs.\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def load_test_file(filename):\n    \n    wav, sr = librosa.load(filename, sr=None)\n    segments = len(wav) / length\n    segments = int(np.ceil(segments))\n    \n    mel_array = []\n    \n    for i in range(segments):\n        \n        if (i + 1) * length > len(wav):\n            slic = wav[len(wav) - length: len(wav)]\n        else:\n            slic = wav[i * length: (i+1) * length]\n            \n        mel_spec = librosa.feature.melspectrogram(slic, sr=sr, fmin=fmin, fmax=fmax, n_mels=128)\n        pcen = librosa.pcen(mel_spec, sr=sr, **pcen_parameters)\n        clean_mel = librosa.power_to_db(mel_spec ** 1.5)\n        norm_mel_spec = normalize_melspec(mel_spec)\n        norm_pcen = normalize_melspec(pcen)\n        norm_clean_mel = normalize_melspec(clean_mel)\n        image = np.stack([norm_mel_spec, norm_pcen, norm_clean_mel], axis=-1)\n        height, width, _ = image.shape\n        image = cv2.resize(image, (int(width * 224 / height), 224))\n        \n        image = np.moveaxis(image, 2, 0)\n        image = (image / 255.0).astype(np.float32)\n        mel_array.append(image)\n        #         mel_spec = librosa.feature.melspectrogram(slic, n_fft=fft, \n#                                                   hop_length=hop, sr=sr, \n#                                                   fmin=fmin, fmax=fmax, power=1.5)\n#         mel_spec = resize(mel_spec, (224, 400))\n#         mel_spec = mel_spec - np.min(mel_spec)\n#         mel_spec = mel_spec / np.max(mel_spec)\n#         mel_spec = np.stack((mel_spec, mel_spec, mel_spec))\n#         mel_array.append(mel_spec)\n\n    return mel_array\n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# torch.save(model, \"last_epoch.pth\")\n\n# model = resnest50(pretrained=True)\n\n# model.fc = nn.Sequential(\n#     nn.Linear(2048, 1024),\n#     nn.ReLU(),\n#     nn.Dropout(p=0.2),\n#     nn.Linear(1024, 1024),\n#     nn.ReLU(),\n#     nn.Dropout(p=0.2),\n#     nn.Linear(1024, num_birds)\n# )\n\n# model = torch.load(\"../working/best_model.pth\")\n# model.eval()\n# model.cuda()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# with open(\"submission.csv\", \"w\", newline=\"\") as f:\n#     pass\n\ncolumns = ['recording_id','s0','s1','s2','s3','s4','s5','s6','s7','s8','s9','s10','s11',\n                               's12','s13','s14','s15','s16','s17','s18','s19','s20','s21','s22','s23']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"k_fold_models = []\n\nfor fold_id in range(5):\n    \n    # model = generate_resnest_50(False)\n    model = torch.load(f\"../working/resnest50_v2_image_features_updated_adam_e_60_d_0.3/best_model_fold_{fold_id}.pth\")\n    model.eval()\n    model.to(DEVICE)\n    k_fold_models.append(model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"k_fold_models_correct = []\n\nfor fold_id in range(5):\n    \n    # model = generate_resnest_50(False)\n    model = torch.load(f\"../working/resnest50_v2_image_features_updated_adam_e_60_d_0.3/correct_best_model_fold_{fold_id}.pth\")\n    model.eval()\n    model.to(DEVICE)\n    k_fold_models_correct.append(model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_files = list(Path(BASE_TEST_PATH).iterdir())\nsubmission_rows = []\ntotal_test_files = len(test_files)\nsubmission_rows2 = []\n\nfor idx, test_file in enumerate(tqdm(test_files)):\n    \n    data = load_test_file(test_file.as_posix())\n    data = torch.tensor(data)\n    data = data.float()\n    data = data.to(DEVICE)\n    \n    prediction = None\n    # Making the predictions with the kfold models.\n    for model in k_fold_models:\n\n        output = model(data)\n        maxed_output = torch.max(output, dim=0)[0]\n        maxed_output = maxed_output.cpu().detach()\n        if prediction is None:\n            prediction = maxed_output\n        else:\n            prediction += maxed_output\n        \n    prediction2 = None\n    for model in k_fold_models_correct:\n        output = model(data)\n        maxed_output = torch.max(output, dim=0)[0]\n        maxed_output = maxed_output.cpu().detach()\n        if prediction2 is None:\n            prediction2 = maxed_output\n        else:\n            prediction2 += maxed_output\n            \n    \n    file_id = test_file.name.split(\".\")[0]\n    current_row = [file_id]\n    for pred in prediction:\n        current_row.append(pred.item())\n    \n    submission_rows.append(current_row)\n    \n    \n    current_row2 = [file_id]\n    for pred in prediction2:\n        current_row2.append(pred.item())\n    \n    submission_rows2.append(current_row2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pd.DataFrame(submission_rows, columns=columns).to_csv(\"submission.csv\", index=False)\nFileLink(\"submission.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from IPython.display import FileLink","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"FileLink(\"submission.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pd.DataFrame(submission_rows2, columns=columns).to_csv(\"submission.csv\", index=False)\nFileLink(\"submission.csv\")","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":{"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":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"TEST_AUDIO_ROOT = Path(\"../input/rfcx-species-audio-detection/test\")\nTEST_MFCC_ROOT = \"../input/kkiller-rfcx-test-mfcc-1-0400/test_mfcc_d10_s10_sr32000\"\n\ndata = pd.DataFrame({\n    \"recording_id\": [path.stem for path in Path(TEST_AUDIO_ROOT).glob(\"*.flac\")],\n})\ndata[\"mfcc_root\"] = TEST_MFCC_ROOT\nprint(data.shape)\ndata.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"TEST_MFCC_ROOTs = [\n    \"../input/kkiller-rfcx-test-mfcc-0000-0400/test_mfcc_d10_s2_sr32000_0000_0400\",\n    \"../input/kkiller-rfcx-test-mfcc-0400-0800/test_mfcc_d10_s2_sr32000_0400_0800\",\n    \"../input/kkiller-rfcx-test-mfcc-0800-1200/test_mfcc_d10_s2_sr32000_0800_1200\",\n    \"../input/kkiller-rfcx-test-mfcc-1200-1600/test_mfcc_d10_s2_sr32000_1200_1600\",\n    \"../input/kkiller-rfcx-test-mfcc-1600-2000/test_mfcc_d10_s2_sr32000_1600_2000\",\n]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mfccs = []\nfor mfcc_root in TEST_MFCC_ROOTs:\n    mfccs += [(mfcc.stem, mfcc.parent.as_posix()) for mfcc in Path(mfcc_root).glob(\"*.npy\")]\nmfccs = pd.DataFrame(mfccs, columns = [\"recording_id\", 'mfcc_root'])\n\ndata = data[[\"recording_id\"]].merge(mfccs, on=\"recording_id\")\nprint(data.shape)\ndata.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"NUM_CLASSES = 24\nSR = 32_000\nDURATION =  10\nSTRIDE = 5\n\n\n# Neural Net\nTEST_BATCH_SIZE = 5\nTEST_NUM_WORKERS = 2\n\nUSE_PRE_COMPUTED_MFCC = True","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class SimpleRFCXDataset(Dataset):\n    def __init__(self, data):\n        self.data = data\n        \n    def __getitem__(self, idx):\n        row = self.data.iloc[idx]\n        record_id_path = Path(row.mfcc_root).joinpath(row.recording_id).with_suffix(\".npy\")\n        image = np.load(record_id_path)\n        return image\n    \n    def __len__(self):\n        return len(self.data)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_data = SimpleRFCXDataset(data) if (USE_PRE_COMPUTED_MFCC and TEST_MFCC_ROOT) else RFCXDataset(data=data, sr=SR)\ntest_loader = DataLoader(test_data, batch_size=TEST_BATCH_SIZE, num_workers=TEST_NUM_WORKERS)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import gc\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds = []\n# net.eval()\nwith torch.no_grad():\n    for xb in  tqdm(test_loader):\n        bsize, nframes = xb.shape[:2]\n        xb = xb.to(DEVICE).view(bsize*nframes, *xb.shape[2:])\n\n        pred = 0.\n        for net in k_fold_models:\n            o = net(xb)\n            o = torch.sigmoid(o)\n            o = o.view(bsize, nframes, *o.shape[1:]).max(1).values\n            o = o.detach().cpu().numpy()\n\n            pred += o\n        \n        pred /= len(k_fold_models)\n        \n        preds.append(pred)\npreds = np.vstack(preds)\npreds.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub = pd.DataFrame(preds, columns=[f\"s{i}\" for i in range(24)])\nsub[\"recording_id\"] = data[\"recording_id\"].values[:len(sub)]\nsub = sub[[\"recording_id\"] + [f\"s{i}\" for i in range(24)]]\nprint(sub.shape)\nsub.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub[\"recording_id\"] = data[\"recording_id\"].values[:len(sub)]\nsub = sub[[\"recording_id\"] + [f\"s{i}\" for i in range(24)]]\nprint(sub.shape)\nsub.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub.to_csv(\"submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"FileLink(\"submission.csv\")","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}