{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":59093,"databundleVersionId":7469972,"sourceType":"competition"}],"dockerImageVersionId":30648,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# importing libraries \n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt \nimport torch \nimport torch.nn as nn\nimport timm \nimport torch.optim as optim \nimport torch.nn.functional as F \nimport torchvision.transforms as transforms\n\nimport random \nimport warnings \nwarnings.filterwarnings('ignore')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-02-09T17:46:38.586760Z","iopub.execute_input":"2024-02-09T17:46:38.587627Z","iopub.status.idle":"2024-02-09T17:46:43.759194Z","shell.execute_reply.started":"2024-02-09T17:46:38.587592Z","shell.execute_reply":"2024-02-09T17:46:43.758221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# config the stable pieces in the play ground\nclass Config: \n    seed=42\n    image_transform=transforms.Resize((512,512))\n    batch_size=64\n    num_epochs=10 \n    num_folds=5 ","metadata":{"execution":{"iopub.status.busy":"2024-02-09T17:46:43.761051Z","iopub.execute_input":"2024-02-09T17:46:43.761355Z","iopub.status.idle":"2024-02-09T17:46:43.766846Z","shell.execute_reply.started":"2024-02-09T17:46:43.761329Z","shell.execute_reply":"2024-02-09T17:46:43.765636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# seed everything \n\ndef seed_everything(seed):\n    torch.backends.cudnn.deterministic=False \n    torch.backends.cudnn.benchmark=True # i think the deterministic and benchmark are inversly propotional\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    random.seed(seed)\n\nseed_everything(Config.seed)\n    ","metadata":{"execution":{"iopub.status.busy":"2024-02-09T17:46:43.768150Z","iopub.execute_input":"2024-02-09T17:46:43.768443Z","iopub.status.idle":"2024-02-09T17:46:43.785872Z","shell.execute_reply.started":"2024-02-09T17:46:43.768418Z","shell.execute_reply":"2024-02-09T17:46:43.785049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df=pd.read_csv(\"/kaggle/input/hms-harmful-brain-activity-classification/train.csv\")\ntrain_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-02-09T17:46:43.788208Z","iopub.execute_input":"2024-02-09T17:46:43.788706Z","iopub.status.idle":"2024-02-09T17:46:44.002083Z","shell.execute_reply.started":"2024-02-09T17:46:43.788670Z","shell.execute_reply":"2024-02-09T17:46:44.001009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(train_df['spectrogram_id'])),print(len(train_df['spectrogram_id'].unique()))","metadata":{"execution":{"iopub.status.busy":"2024-02-09T17:46:44.004521Z","iopub.execute_input":"2024-02-09T17:46:44.004953Z","iopub.status.idle":"2024-02-09T17:46:44.015202Z","shell.execute_reply.started":"2024-02-09T17:46:44.004896Z","shell.execute_reply":"2024-02-09T17:46:44.013986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels=list(train_df['expert_consensus'].unique())\nlabels=[label.lower() for label in labels]\nfor label in labels: \n    group=train_df[f'{label}_vote'].groupby(train_df['spectrogram_id']).sum()\n    label_vote_sum= pd.DataFrame({'spectrogram_id':group.index, f'{label}_vote_sum':group.values})\n    \n    if label=='seizure':\n        train_feats=label_vote_sum\n    else:\n        train_feats=train_feats.merge(label_vote_sum,on='spectrogram_id', how='left')\n\ntrain_feats['total_vote']=0\nfor label in labels: \n    train_feats['total_vote']+=train_feats[f'{label}_vote_sum']\nfor label in labels: \n    train_feats[f'{label}_vote']=train_feats[f'{label}_vote_sum']/train_feats['total_vote']\n\nchosen_cols=['spectrogram_id']\nfor label in labels:\n    chosen_cols+=[f'{label}_vote']\ntrain_feats=train_feats[chosen_cols]\n\ntrain_feats['path']=train_feats['spectrogram_id'].apply(lambda x: \"/kaggle/input/hms-harmful-brain-activity-classification/train_spectrograms/\"+str(x)+\".parquet\")\n\ntrain_feats.head()","metadata":{"execution":{"iopub.status.busy":"2024-02-09T17:46:44.203585Z","iopub.execute_input":"2024-02-09T17:46:44.204262Z","iopub.status.idle":"2024-02-09T17:46:44.289369Z","shell.execute_reply.started":"2024-02-09T17:46:44.204231Z","shell.execute_reply":"2024-02-09T17:46:44.288388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submissions are evaluated on the Kullback Liebler divergence between the predicted probability and the observed target.\n# defining the custom KL Loss Function \n\ndef kl_divergence(p, q):\n    epsilon=10**(-15)\n    p=torch.clip(p,epsilon,1-epsilon)\n    q=nn.functional.log_softmax(q,dim=1)\n    return torch.mean(torch.sum(p*(torch.log(p)-q),dim=1))","metadata":{"execution":{"iopub.status.busy":"2024-02-09T17:46:45.207613Z","iopub.execute_input":"2024-02-09T17:46:45.208369Z","iopub.status.idle":"2024-02-09T17:46:45.214598Z","shell.execute_reply.started":"2024-02-09T17:46:45.208337Z","shell.execute_reply":"2024-02-09T17:46:45.213459Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_batch(paths,batch_size=Config.batch_size):\n    eps=1e-6\n    batch_data=[]\n    for path in paths:\n        data=pd.read_parquet(path[0])\n        data = data.fillna(-1).values[:,1:].T\n        data=data[:,0:300]#(400,300)\n        data=np.clip(data,np.exp(-6),np.exp(10))\n        data= np.log(data)\n        data_mean=data.mean(axis=(0,1))\n        data_std=data.std(axis=(0,1))\n        data=(data-data_mean)/(data_std+eps)\n        data_tensor = torch.unsqueeze(torch.Tensor(data), dim=0)\n        data=Config.image_transform(data_tensor)\n        batch_data.append(data)\n    batch_data=torch.stack(batch_data)\n    return batch_data","metadata":{"execution":{"iopub.status.busy":"2024-02-09T17:46:45.388217Z","iopub.execute_input":"2024-02-09T17:46:45.388975Z","iopub.status.idle":"2024-02-09T17:46:45.397716Z","shell.execute_reply.started":"2024-02-09T17:46:45.388941Z","shell.execute_reply":"2024-02-09T17:46:45.396626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device='cuda' if torch.cuda.is_available() else 'cpu'\n\ntotal_idx=np.arange(len(train_feats))\nnp.random.shuffle(total_idx)\n\nfor fold in range(Config.num_folds):\n    test_idx=total_idx[fold*len(total_idx)//Config.num_folds:(fold+1)*len(total_idx)//Config.num_folds]\n    train_idx=np.array([idx for idx in total_idx if idx not in test_idx])\n    \n    model=timm.create_model('resnet34d',pretrained=False,num_classes=6,in_chans=1)\n    optimizer=optim.AdamW(model.parameters(),lr=0.001,betas=(0.5,0.999),weight_decay=0.01)\n    best_test_loss=1.0 \n    train_losses=[]\n    test_losses=[]\n    \n    print(\"starting Training\")\n    \n    for epoch in range(Config.num_epochs):\n        print(f\"epoch{epoch}:\")\n        model.to(device)\n        model.train()\n        train_loss=[]\n        random_num=np.arange(len(train_idx))\n        np.random.shuffle(random_num)\n        train_idx=train_idx[random_num]\n        for idx in range(0,len(train_idx),Config.batch_size):\n            optimizer.zero_grad()\n            train_idx1=train_idx[idx:idx+Config.batch_size]\n            train_X1_path=train_feats[['path']].iloc[train_idx1].values \n            train_X1=get_batch(train_X1_path,batch_size=Config.batch_size)\n            train_y1=train_feats[['seizure_vote','lpd_vote','gpd_vote','lrda_vote','grda_vote','other_vote']].iloc[train_idx1].values\n            train_y1=torch.Tensor(train_y1)\n            \n            train_pred=model(train_X1.to(device)).to(device)\n            \n            loss=kl_divergence(train_y1.to(device),train_pred.to(device)).to(device)\n            loss.backward()\n            optimizer.step()\n            print(f\"idx:{idx},loss:{loss}\")\n            train_loss.append(loss.detach().cpu().numpy())\n        train_loss=np.mean(np.array(train_loss))\n        print(f\"train_loss:{train_loss}\")\n        \n        test_loss=[]\n        model.eval()\n        \n        with torch.no_grad():\n            for idx in range(0,len(test_idx),Config.batch_size):\n                test_idx1=test_idx[idx:idx+Config.batch_size]\n                test_X1_path=train_feats[['path']].iloc[test_idx1].values\n                test_X1=get_batch(test_X1_path,batch_size=Config.batch_size)\n                test_y1=train_feats[['seizure_vote','lpd_vote','gpd_vote','lrda_vote','grda_vote','other_vote']].iloc[test_idx1].values\n                test_y1=torch.Tensor(test_y1)\n                test_pred=model(test_X1.to(device)).to(device)\n                loss=kl_divergence(test_y1.to(device),test_pred.to(device)).to(device)\n                test_loss.append(loss.detach().cpu().numpy())\n        test_loss=np.mean(np.array(test_loss))\n        print(f\"test_loss:{test_loss}\")\n        if test_loss<best_test_loss:\n            best_test_loss=test_loss\n            torch.save(model.to('cpu'),f\"HMS_resnet_fold{fold}.pth\")\n            \n        train_losses.append(train_loss)\n        test_losses.append(test_loss)\n        print(\"-\"*50)\n    print(f\"best_test_loss:{best_test_loss}\") \n    plt.title(\"train_losses VS test_losses\")\n    \n    epochs=[i for i in range(len(train_losses))]\n    plt.plot(epochs,train_losses,marker=\"o\",markersize=1,label=\"train_losses\")\n    plt.plot(epochs,test_losses,marker=\"x\",markersize=1,label=\"test_losses\")\n    plt.legend()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-02-09T17:46:45.574587Z","iopub.execute_input":"2024-02-09T17:46:45.575011Z","iopub.status.idle":"2024-02-09T17:47:28.184891Z","shell.execute_reply.started":"2024-02-09T17:46:45.574977Z","shell.execute_reply":"2024-02-09T17:47:28.183476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}