{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":70203,"databundleVersionId":8068726,"sourceType":"competition"},{"sourceId":9242018,"sourceType":"datasetVersion","datasetId":5590593},{"sourceId":193863923,"sourceType":"kernelVersion"},{"sourceId":194105330,"sourceType":"kernelVersion"}],"dockerImageVersionId":30761,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install fastbook","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-08-26T09:36:07.539687Z","iopub.execute_input":"2024-08-26T09:36:07.540835Z","iopub.status.idle":"2024-08-26T09:36:26.406754Z","shell.execute_reply.started":"2024-08-26T09:36:07.540786Z","shell.execute_reply":"2024-08-26T09:36:26.405125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Convert sound of bird to spectrogram\nfrom fastai.vision.all import Path, get_files\nimport soundfile as sf\nimport librosa as lb\nimport librosa.display as lbd\nfrom IPython.display import Audio\nfrom soundfile import SoundFile\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport random\nimport os\nimport pandas as pd \nfrom fastbook import *\nfrom IPython.display import Image, display, Audio, Markdown\nimport plotly.express as px","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:26.410003Z","iopub.execute_input":"2024-08-26T09:36:26.410544Z","iopub.status.idle":"2024-08-26T09:36:26.425325Z","shell.execute_reply.started":"2024-08-26T09:36:26.410482Z","shell.execute_reply":"2024-08-26T09:36:26.423967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Config:\n    sampling_rate = 32000\n    duration = 5\n    fmin = 0\n    fmax = None\n    audios_path = Path(\"../input/birdclef-2024/train_audio\")\n    out_dir_train = Path(\"../input/birdcleff24-stage-1/specs/train\")\n    out_dir_valid = Path(\"../input/birdcleff24-stage-1/specs/valid\")","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:26.427227Z","iopub.execute_input":"2024-08-26T09:36:26.427719Z","iopub.status.idle":"2024-08-26T09:36:26.442920Z","shell.execute_reply.started":"2024-08-26T09:36:26.427667Z","shell.execute_reply":"2024-08-26T09:36:26.441675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_audio_info(filepath):\n    \"\"\"Get some properties from  an audio file\"\"\"\n    with SoundFile(filepath) as f:\n        sr = f.samplerate\n        frames = f.frames\n        duration = float(frames)/sr\n    return {\"frames\": frames, \"sr\": sr, \"duration\": duration}","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:26.446588Z","iopub.execute_input":"2024-08-26T09:36:26.447145Z","iopub.status.idle":"2024-08-26T09:36:26.459609Z","shell.execute_reply.started":"2024-08-26T09:36:26.447080Z","shell.execute_reply":"2024-08-26T09:36:26.458481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def compute_melspec(y, sr, n_mels, fmin, fmax):\n    melspec = lb.feature.melspectrogram(\n        y=y, sr=sr, n_mels=n_mels, fmin=fmin, fmax=fmax,\n    )\n\n    melspec = lb.power_to_db(melspec).astype(np.float32)\n    return melspec","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:26.461192Z","iopub.execute_input":"2024-08-26T09:36:26.461651Z","iopub.status.idle":"2024-08-26T09:36:26.473090Z","shell.execute_reply.started":"2024-08-26T09:36:26.461599Z","shell.execute_reply":"2024-08-26T09:36:26.471782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def mono_to_color(X, eps=1e-6, mean=None, std=None):\n    mean = mean or X.mean()\n    std = std or X.std()\n    X = (X - mean) / (std + eps)\n\n    _min, _max = X.min(), X.max()\n\n    if (_max - _min) > eps:\n        V = np.clip(X, _min, _max)\n        V = 255 * (V - _min) / (_max - _min)\n        V = V.astype(np.uint8)\n    else:\n        V = np.zeros_like(X, dtype=np.uint8)\n\n    return V","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:26.474719Z","iopub.execute_input":"2024-08-26T09:36:26.476260Z","iopub.status.idle":"2024-08-26T09:36:26.487476Z","shell.execute_reply.started":"2024-08-26T09:36:26.476203Z","shell.execute_reply":"2024-08-26T09:36:26.486264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sr, n_mels, fmin, fmax  = Config.sampling_rate, 128, Config.fmin, Config.fmax\ndef audio_to_image(audio):\n    melspec = compute_melspec(audio, sr=sr, n_mels = n_mels, fmin=fmin, fmax=fmax)\n    image = mono_to_color(melspec)\n    return image","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:26.489049Z","iopub.execute_input":"2024-08-26T09:36:26.489513Z","iopub.status.idle":"2024-08-26T09:36:26.499139Z","shell.execute_reply.started":"2024-08-26T09:36:26.489462Z","shell.execute_reply":"2024-08-26T09:36:26.497930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\naudio_files = get_files(\"../input/birdclef-2024/train_audio\", extensions=\".ogg\")\nprint(f\"Found {len(audio_files)} audio files\")","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:26.500630Z","iopub.execute_input":"2024-08-26T09:36:26.501077Z","iopub.status.idle":"2024-08-26T09:36:26.916326Z","shell.execute_reply.started":"2024-08-26T09:36:26.501036Z","shell.execute_reply":"2024-08-26T09:36:26.915190Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# take a random sample\naudio_path = random.choice(audio_files)\ninfo = get_audio_info(audio_path)\nprint(info)\n\n# Convert to spectrogram\naudio, sr = sf.read(audio_path)\nimg = audio_to_image(audio)\n\n# show spectrogra\nplt.imshow(img)\nplt.show()\n\n# play audio\ny, sr = lb.load(audio_path)\nAudio(y, rate=sr)","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:26.918164Z","iopub.execute_input":"2024-08-26T09:36:26.918529Z","iopub.status.idle":"2024-08-26T09:36:27.456454Z","shell.execute_reply.started":"2024-08-26T09:36:26.918490Z","shell.execute_reply":"2024-08-26T09:36:27.454248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# take a random sample\naudio_path = random.choice(audio_files)\ninfo = get_audio_info(audio_path)\nprint(info)\n\n# Convert to spectrogram\naudio, sr = sf.read(audio_path)\nimg = audio_to_image(audio)\n\n# show spectrogra\nplt.imshow(img)\nplt.show()\n\n# play audio\ny, sr = lb.load(audio_path)\nAudio(y, rate=sr)","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:27.461953Z","iopub.execute_input":"2024-08-26T09:36:27.462779Z","iopub.status.idle":"2024-08-26T09:36:27.905254Z","shell.execute_reply.started":"2024-08-26T09:36:27.462726Z","shell.execute_reply":"2024-08-26T09:36:27.904031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Training","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport torch\nimport os\nimport pytorch_lightning as pl\nfrom torch.utils.data import Dataset, DataLoader\nfrom sklearn import model_selection\nimport torchvision.transforms as transforms\nimport torchvision.io \nimport librosa\nfrom PIL import Image\nimport albumentations as alb\nimport torch.multiprocessing as mp\nimport warnings\n\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:27.906848Z","iopub.execute_input":"2024-08-26T09:36:27.907356Z","iopub.status.idle":"2024-08-26T09:36:27.916474Z","shell.execute_reply.started":"2024-08-26T09:36:27.907302Z","shell.execute_reply":"2024-08-26T09:36:27.915333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from pytorch_lightning.callbacks import ModelCheckpoint, BackboneFinetuning, EarlyStopping","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:27.918070Z","iopub.execute_input":"2024-08-26T09:36:27.919101Z","iopub.status.idle":"2024-08-26T09:36:27.929021Z","shell.execute_reply.started":"2024-08-26T09:36:27.919045Z","shell.execute_reply":"2024-08-26T09:36:27.927676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Config:\n    use_aug = False\n    num_classes = 264\n    batch_size = 64\n    epochs = 12\n    PRECISION = 16    \n    PATIENCE = 8    \n    seed = 2023\n    model = \"tf_efficientnet_b0_ns\"\n    pretrained = True            \n    weight_decay = 1e-3\n    use_mixup = True\n    mixup_alpha = 0.2   \n    DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')    \n\n    \n    train_images = \"../input/birdcleff24-stage-1/specs/train\"\n    valid_images = \"../input/birdcleff24-stage-1/specs/valid\"\n    train_path = \"../input/birdcleff24-stage-1/train.csv\"\n    valid_path = \"../input/birdcleff24-stage-1/valid.csv\"\n    \n    \n    SR = 32000\n    DURATION = 5\n    MAX_READ_SAMPLES = 5\n    LR = 5e-4","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:27.930445Z","iopub.execute_input":"2024-08-26T09:36:27.930910Z","iopub.status.idle":"2024-08-26T09:36:27.942267Z","shell.execute_reply.started":"2024-08-26T09:36:27.930840Z","shell.execute_reply":"2024-08-26T09:36:27.941087Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pl.seed_everything(Config.seed, workers=True)","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:27.943690Z","iopub.execute_input":"2024-08-26T09:36:27.944701Z","iopub.status.idle":"2024-08-26T09:36:27.959215Z","shell.execute_reply.started":"2024-08-26T09:36:27.944643Z","shell.execute_reply":"2024-08-26T09:36:27.958074Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def config_to_dict(cfg):\n    return dict((name, getattr(cfg, name)) for name in dir(cfg) if not name.startswith('__'))","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:27.961004Z","iopub.execute_input":"2024-08-26T09:36:27.961508Z","iopub.status.idle":"2024-08-26T09:36:27.968854Z","shell.execute_reply.started":"2024-08-26T09:36:27.961448Z","shell.execute_reply":"2024-08-26T09:36:27.967705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv(Config.train_path)\ndf_valid = pd.read_csv(Config.valid_path)\ndf_train.head()","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:27.970469Z","iopub.execute_input":"2024-08-26T09:36:27.970971Z","iopub.status.idle":"2024-08-26T09:36:28.173025Z","shell.execute_reply.started":"2024-08-26T09:36:27.970909Z","shell.execute_reply":"2024-08-26T09:36:28.171831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Config.num_classes = len(df_train.primary_label.unique())","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:28.174908Z","iopub.execute_input":"2024-08-26T09:36:28.175413Z","iopub.status.idle":"2024-08-26T09:36:28.183387Z","shell.execute_reply.started":"2024-08-26T09:36:28.175358Z","shell.execute_reply":"2024-08-26T09:36:28.181953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.concat([df_train, pd.get_dummies(df_train['primary_label'])], axis=1)\ndf_valid = pd.concat([df_valid, pd.get_dummies(df_valid['primary_label'])], axis=1)","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:28.185018Z","iopub.execute_input":"2024-08-26T09:36:28.185517Z","iopub.status.idle":"2024-08-26T09:36:28.207462Z","shell.execute_reply.started":"2024-08-26T09:36:28.185460Z","shell.execute_reply":"2024-08-26T09:36:28.206076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"birds = list(df_train.primary_label.unique())\nmissing_birds = list(set(list(df_train.primary_label.unique())).difference(list(df_valid.primary_label.unique())))","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:28.208828Z","iopub.execute_input":"2024-08-26T09:36:28.209256Z","iopub.status.idle":"2024-08-26T09:36:28.220972Z","shell.execute_reply.started":"2024-08-26T09:36:28.209214Z","shell.execute_reply":"2024-08-26T09:36:28.219515Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"non_missing_birds = list(set(list(df_train.primary_label.unique())).difference(missing_birds))","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:28.222321Z","iopub.execute_input":"2024-08-26T09:36:28.222740Z","iopub.status.idle":"2024-08-26T09:36:28.231793Z","shell.execute_reply.started":"2024-08-26T09:36:28.222697Z","shell.execute_reply":"2024-08-26T09:36:28.230649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(non_missing_birds)","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:28.233326Z","iopub.execute_input":"2024-08-26T09:36:28.233781Z","iopub.status.idle":"2024-08-26T09:36:28.245173Z","shell.execute_reply.started":"2024-08-26T09:36:28.233730Z","shell.execute_reply":"2024-08-26T09:36:28.243957Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_valid[missing_birds] = 0\ndf_valid = df_valid[df_train.columns] ## Fix order","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:28.246766Z","iopub.execute_input":"2024-08-26T09:36:28.247783Z","iopub.status.idle":"2024-08-26T09:36:28.257403Z","shell.execute_reply.started":"2024-08-26T09:36:28.247728Z","shell.execute_reply":"2024-08-26T09:36:28.256171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import albumentations as A\ndef get_train_transform():\n    return A.Compose([\n        A.HorizontalFlip(p=0.5),\n        A.OneOf([\n                A.Cutout(max_h_size=5, max_w_size=16),\n                A.CoarseDropout(max_holes=4),\n            ], p=0.5),\n    ])","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:28.259113Z","iopub.execute_input":"2024-08-26T09:36:28.259717Z","iopub.status.idle":"2024-08-26T09:36:28.268585Z","shell.execute_reply.started":"2024-08-26T09:36:28.259662Z","shell.execute_reply":"2024-08-26T09:36:28.266950Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class BirdDataset(torch.utils.data.Dataset):\n\n    def __init__(self, df, sr = Config.SR, duration = Config.DURATION, augmentations = None, train = True):\n\n        self.df = df\n        self.sr = sr \n        self.train = train\n        self.duration = duration\n        self.augmentations = augmentations\n        if train:\n            self.img_dir = Config.train_images\n        else:\n            self.img_dir = Config.valid_images\n\n    def __len__(self):\n        return len(self.df)\n\n    @staticmethod\n    def normalize(image):\n        image = image / 255.0\n        #image = torch.stack([image, image, image])\n        return image\n\n    def __getitem__(self, idx):\n        row = self.df.iloc[idx]\n        impath = os.path.join(self.img_dir, f\"{row.filename.split('.')[0]}.npy\")\n        \n        if not os.path.exists(impath):\n            print(f\"File not found: {impath}\")\n            return None, None\n\n        image = np.load(str(impath))[:Config.MAX_READ_SAMPLES]\n        \n        if self.train:\n            image = image[np.random.choice(len(image))]\n        else:\n            image = image[0]\n            \n        image = torch.tensor(image).float()\n\n        if self.augmentations:\n            image = self.augmentations(image.unsqueeze(0)).squeeze()\n            \n        image = torch.stack([image, image, image])\n        image = self.normalize(image)\n\n        return image, torch.tensor(row[17:]).float()","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:28.270750Z","iopub.execute_input":"2024-08-26T09:36:28.271244Z","iopub.status.idle":"2024-08-26T09:36:28.287072Z","shell.execute_reply.started":"2024-08-26T09:36:28.271190Z","shell.execute_reply":"2024-08-26T09:36:28.285787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_fold_dls(df_train, df_valid):\n\n    ds_train = BirdDataset(\n        df_train, \n        sr = Config.SR,\n        duration = Config.DURATION,\n        augmentations = None,\n        train = True\n    )\n    ds_val = BirdDataset(\n        df_valid, \n        sr = Config.SR,\n        duration = Config.DURATION,\n        augmentations = None,\n        train = False\n    )\n    dl_train = DataLoader(ds_train, batch_size=Config.batch_size , shuffle=True, num_workers = 2)    \n    dl_val = DataLoader(ds_val, batch_size=Config.batch_size, num_workers = 2)\n    return dl_train, dl_val, ds_train, ds_val","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:28.288669Z","iopub.execute_input":"2024-08-26T09:36:28.289171Z","iopub.status.idle":"2024-08-26T09:36:28.303608Z","shell.execute_reply.started":"2024-08-26T09:36:28.289111Z","shell.execute_reply":"2024-08-26T09:36:28.302396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\n\n# Load the .npy file\nfile_path = \"../input/birdcleff24-stage-1/specs/train/asbfly/XC175797.npy\"\ndata = np.load(file_path)\n\n# Display the shape of the data to understand its dimensions\nprint(f\"Data Shape: {data.shape}\")\n\n# If the data is a 2D array (single image), display it directly\nif data.ndim == 2:\n    plt.imshow(data, cmap='viridis')\n    plt.title(\"Spectrogram\")\n    plt.colorbar()\n    plt.show()\n    \n# If the data is a 3D array (multiple images stacked), display the first image\nelif data.ndim == 3:\n    plt.imshow(data[0], cmap='viridis')  # Displaying the first image in the stack\n    plt.title(\"Spectrogram - First Image in Stack\")\n    plt.colorbar()\n    plt.show()\nelse:\n    print(\"The data has an unexpected shape, unable to display.\")\n","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:28.305539Z","iopub.execute_input":"2024-08-26T09:36:28.306065Z","iopub.status.idle":"2024-08-26T09:36:28.724746Z","shell.execute_reply.started":"2024-08-26T09:36:28.306002Z","shell.execute_reply":"2024-08-26T09:36:28.723555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_batch(img_ds, num_items, num_rows, num_cols, predict_arr=None):\n    fig = plt.figure(figsize=(12, 6))    \n    img_index = np.random.randint(0, len(img_ds)-1, num_items)\n    for index, img_index in enumerate(img_index):  # list first 9 images\n        img, lb = img_ds[img_index]        \n        ax = fig.add_subplot(num_rows, num_cols, index + 1, xticks=[], yticks=[])\n        if isinstance(img, torch.Tensor):\n            img = img.detach().numpy()\n        if isinstance(img, np.ndarray):\n            img = img.transpose(1, 2, 0)\n            ax.imshow(img)        \n            \n        title = f\"Spec\"\n        ax.set_title(title)  ","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:28.726362Z","iopub.execute_input":"2024-08-26T09:36:28.726751Z","iopub.status.idle":"2024-08-26T09:36:28.736185Z","shell.execute_reply.started":"2024-08-26T09:36:28.726712Z","shell.execute_reply":"2024-08-26T09:36:28.734712Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dl_train, dl_val, ds_train, ds_val = get_fold_dls(df_train, df_valid)\nshow_batch(ds_val, 8, 2, 4)","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:28.743012Z","iopub.execute_input":"2024-08-26T09:36:28.743455Z","iopub.status.idle":"2024-08-26T09:36:29.986132Z","shell.execute_reply.started":"2024-08-26T09:36:28.743408Z","shell.execute_reply":"2024-08-26T09:36:29.985010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torch.optim.lr_scheduler import CosineAnnealingLR, CosineAnnealingWarmRestarts, ReduceLROnPlateau, OneCycleLR\n\ndef get_optimizer(lr, params):\n    model_optimizer = torch.optim.Adam(\n            filter(lambda p: p.requires_grad, params), \n            lr=lr,\n            weight_decay=Config.weight_decay\n        )\n    interval = \"epoch\"\n    \n    lr_scheduler = CosineAnnealingWarmRestarts(\n                            model_optimizer, \n                            T_0=Config.epochs, \n                            T_mult=1, \n                            eta_min=1e-6, \n                            last_epoch=-1\n                        )\n\n    return {\n        \"optimizer\": model_optimizer, \n        \"lr_scheduler\": {\n            \"scheduler\": lr_scheduler,\n            \"interval\": interval,\n            \"monitor\": \"val_loss\",\n            \"frequency\": 1\n        }\n    }","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:29.987470Z","iopub.execute_input":"2024-08-26T09:36:29.987845Z","iopub.status.idle":"2024-08-26T09:36:29.996789Z","shell.execute_reply.started":"2024-08-26T09:36:29.987805Z","shell.execute_reply":"2024-08-26T09:36:29.995436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install torchtoolbox\nfrom torchtoolbox.tools import mixup_data, mixup_criterion\nimport torch.nn as nn\nfrom torch.nn.functional import cross_entropy\nimport torchmetrics\nimport timm","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:29.998625Z","iopub.execute_input":"2024-08-26T09:36:29.999363Z","iopub.status.idle":"2024-08-26T09:36:46.146233Z","shell.execute_reply.started":"2024-08-26T09:36:29.999294Z","shell.execute_reply":"2024-08-26T09:36:46.144639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sklearn.metrics\n\ndef padded_cmap(solution, submission, padding_factor=5):\n    solution = solution#.drop(['row_id'], axis=1, errors='ignore')\n    submission = submission#.drop(['row_id'], axis=1, errors='ignore')\n    new_rows = []\n    for i in range(padding_factor):\n        new_rows.append([1 for i in range(len(solution.columns))])\n    new_rows = pd.DataFrame(new_rows)\n    new_rows.columns = solution.columns\n    padded_solution = pd.concat([solution, new_rows]).reset_index(drop=True).copy()\n    padded_submission = pd.concat([submission, new_rows]).reset_index(drop=True).copy()\n    score = sklearn.metrics.average_precision_score(\n        padded_solution.values,\n        padded_submission.values,\n        average='macro',\n    )\n    return score\n\ndef map_score(solution, submission):\n    solution = solution#.drop(['row_id'], axis=1, errors='ignore')\n    submission = submission#.drop(['row_id'], axis=1, errors='ignore')\n    score = sklearn.metrics.average_precision_score(\n        solution.values,\n        submission.values,\n        average='micro',\n    )\n    return score","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:46.148731Z","iopub.execute_input":"2024-08-26T09:36:46.149300Z","iopub.status.idle":"2024-08-26T09:36:46.164357Z","shell.execute_reply.started":"2024-08-26T09:36:46.149240Z","shell.execute_reply":"2024-08-26T09:36:46.162897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dummy = df_valid[birds].copy()\ndummy[birds] = np.random.rand(dummy.shape[0],dummy.shape[1])","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:46.166124Z","iopub.execute_input":"2024-08-26T09:36:46.166678Z","iopub.status.idle":"2024-08-26T09:36:46.236292Z","shell.execute_reply.started":"2024-08-26T09:36:46.166581Z","shell.execute_reply":"2024-08-26T09:36:46.235112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"padded_cmap(df_valid[birds], dummy[birds], padding_factor = 5)","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:46.238001Z","iopub.execute_input":"2024-08-26T09:36:46.238602Z","iopub.status.idle":"2024-08-26T09:36:47.854378Z","shell.execute_reply.started":"2024-08-26T09:36:46.238537Z","shell.execute_reply":"2024-08-26T09:36:47.853114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"padded_cmap(df_valid[birds], dummy[birds], padding_factor = 1)","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:47.858053Z","iopub.execute_input":"2024-08-26T09:36:47.858430Z","iopub.status.idle":"2024-08-26T09:36:49.407432Z","shell.execute_reply.started":"2024-08-26T09:36:47.858391Z","shell.execute_reply":"2024-08-26T09:36:49.406108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Config.num_classes","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:49.409427Z","iopub.execute_input":"2024-08-26T09:36:49.409933Z","iopub.status.idle":"2024-08-26T09:36:49.424132Z","shell.execute_reply.started":"2024-08-26T09:36:49.409853Z","shell.execute_reply":"2024-08-26T09:36:49.422665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class BirdClefModel(pl.LightningModule):\n    def __init__(self, model_name=Config.model, num_classes = Config.num_classes, pretrained = Config.pretrained):\n        super().__init__()\n        self.num_classes = num_classes\n\n        self.backbone = timm.create_model(model_name, pretrained=pretrained)\n\n        if 'res' in model_name:\n            self.in_features = self.backbone.fc.in_features\n            self.backbone.fc = nn.Linear(self.in_features, num_classes)\n        elif 'dense' in model_name:\n            self.in_features = self.backbone.classifier.in_features\n            self.backbone.classifier = nn.Linear(self.in_features, num_classes)\n        elif 'efficientnet' in model_name:\n            self.in_features = self.backbone.classifier.in_features\n            self.backbone.classifier = nn.Sequential(\n                nn.Linear(self.in_features, num_classes)\n            )\n        \n        self.loss_function = nn.BCEWithLogitsLoss() \n\n    def forward(self,images):\n        logits = self.backbone(images)\n        return logits\n        \n    def configure_optimizers(self):\n        return get_optimizer(lr=Config.LR, params=self.parameters())\n\n    def train_with_mixup(self, X, y):\n        X, y_a, y_b, lam = mixup_data(X, y, alpha=Config.mixup_alpha)\n        y_pred = self(X)\n        loss_mixup = mixup_criterion(cross_entropy, y_pred, y_a, y_b, lam)\n        return loss_mixup\n\n    def training_step(self, batch, batch_idx):\n        image, target = batch        \n        if Config.use_mixup:\n            loss = self.train_with_mixup(image, target)\n        else:\n            y_pred = self(image)\n            loss = self.loss_function(y_pred,target)\n\n        self.log(\"train_loss\", loss, on_step=True, on_epoch=True, prog_bar=True)\n        return loss        \n\n    def validation_step(self, batch, batch_idx):\n        image, target = batch     \n        y_pred = self(image)\n        val_loss = self.loss_function(y_pred, target)\n        self.log(\"val_loss\", val_loss, on_step=True, on_epoch=True, logger=True, prog_bar=True)\n        \n        return {\"val_loss\": val_loss, \"logits\": y_pred, \"targets\": target}\n    \n    def train_dataloader(self):\n        return self._train_dataloader \n    \n    def validation_dataloader(self):\n        return self._validation_dataloader\n    \n    def on_validation_batch_end(self, outputs, batch, batch_idx, dataloader_idx=0):\n        if batch_idx == 0:\n            self._logits = []\n            self._targets = []\n            self._val_loss = []\n\n        self._logits.append(outputs[\"logits\"])\n        self._targets.append(outputs[\"targets\"])\n        self._val_loss.append(outputs[\"val_loss\"])\n\n    def on_validation_epoch_end(self):\n        output_val = torch.cat(self._logits, dim=0).sigmoid().cpu().detach().numpy()\n        target_val = torch.cat(self._targets, dim=0).cpu().detach().numpy()\n        avg_loss = torch.stack(self._val_loss).mean()\n\n        # print(output_val.shape)\n        val_df = pd.DataFrame(target_val, columns = birds)\n        pred_df = pd.DataFrame(output_val, columns = birds)\n        \n        avg_score = padded_cmap(val_df, pred_df, padding_factor = 5)\n        avg_score2 = padded_cmap(val_df, pred_df, padding_factor = 3)\n        avg_score3 = sklearn.metrics.label_ranking_average_precision_score(target_val,output_val)\n        \n#         competition_metrics(output_val,target_val)\n        print(f'epoch {self.current_epoch} validation loss {avg_loss}')\n        print(f'epoch {self.current_epoch} validation C-MAP score pad 5 {avg_score}')\n        print(f'epoch {self.current_epoch} validation C-MAP score pad 3 {avg_score2}')\n        print(f'epoch {self.current_epoch} validation AP score {avg_score3}')\n        \n        \n        val_df.to_pickle('val_df.pkl')\n        pred_df.to_pickle('pred_df.pkl')\n        \n        \n        return {'val_loss': avg_loss,'val_cmap':avg_score}","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:49.426239Z","iopub.execute_input":"2024-08-26T09:36:49.426964Z","iopub.status.idle":"2024-08-26T09:36:49.461636Z","shell.execute_reply.started":"2024-08-26T09:36:49.426904Z","shell.execute_reply":"2024-08-26T09:36:49.460305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\n\n# Create a new directory\nos.makedirs(\"../working/exp1\", exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:49.464632Z","iopub.execute_input":"2024-08-26T09:36:49.466300Z","iopub.status.idle":"2024-08-26T09:36:49.476378Z","shell.execute_reply.started":"2024-08-26T09:36:49.466239Z","shell.execute_reply":"2024-08-26T09:36:49.475298Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from pytorch_lightning.loggers import WandbLogger\nimport gc\n\ndef run_training():\n    print(f\"Running training...\")\n    logger = None\n    \n    \n    dl_train, dl_val, ds_train, ds_val = get_fold_dls(df_train, df_valid)\n    \n    audio_model = BirdClefModel()\n\n    early_stop_callback = EarlyStopping(monitor=\"val_loss\", min_delta=0.00, patience=Config.PATIENCE, verbose= True, mode=\"min\")\n    checkpoint_callback = ModelCheckpoint(monitor='val_loss',\n                                      dirpath= \"../working/exp1/\",\n                                      save_top_k=1,\n                                      save_last= True,\n                                      save_weights_only=True,\n                                      filename= f'./{Config.model}_loss',\n                                      verbose= True,\n                                      mode='min')\n    \n    callbacks_to_use = [checkpoint_callback,early_stop_callback]\n\n\n    trainer = pl.Trainer(\n        val_check_interval=0.5,\n        deterministic=True,\n        max_epochs=Config.epochs,\n        logger=logger,\n        callbacks=callbacks_to_use,\n        precision=Config.PRECISION, accelerator=\"gpu\" \n    )\n\n    print(\"Running trainer.fit\")\n    trainer.fit(audio_model, train_dataloaders = dl_train, val_dataloaders = dl_val)                \n\n    gc.collect()\n    torch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:49.479349Z","iopub.execute_input":"2024-08-26T09:36:49.480199Z","iopub.status.idle":"2024-08-26T09:36:49.494068Z","shell.execute_reply.started":"2024-08-26T09:36:49.480143Z","shell.execute_reply":"2024-08-26T09:36:49.492692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"run_training()","metadata":{"execution":{"iopub.status.busy":"2024-08-26T09:36:49.495729Z","iopub.execute_input":"2024-08-26T09:36:49.497206Z","iopub.status.idle":"2024-08-26T09:36:50.126236Z","shell.execute_reply.started":"2024-08-26T09:36:49.497152Z","shell.execute_reply":"2024-08-26T09:36:50.121942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}