{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":10418,"databundleVersionId":862236,"sourceType":"competition"},{"sourceId":249057,"sourceType":"modelInstanceVersion","modelInstanceId":212881,"modelId":234519}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport os\nimport cv2\nimport pandas as pd\nimport matplotlib.pyplot as plt \nimport seaborn as sns\nimport random\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:18.630238Z","iopub.execute_input":"2025-02-07T07:04:18.630763Z","iopub.status.idle":"2025-02-07T07:04:18.635305Z","shell.execute_reply.started":"2025-02-07T07:04:18.630735Z","shell.execute_reply":"2025-02-07T07:04:18.634137Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_link = '/kaggle/input/human-protein-atlas-image-classification/train'\ntest_link = '/kaggle/input/human-protein-atlas-image-classification/test'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:18.636545Z","iopub.execute_input":"2025-02-07T07:04:18.636842Z","iopub.status.idle":"2025-02-07T07:04:18.646705Z","shell.execute_reply.started":"2025-02-07T07:04:18.636809Z","shell.execute_reply":"2025-02-07T07:04:18.646077Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Understanding the data","metadata":{}},{"cell_type":"code","source":"protein_type =[\n    (0, \"Nucleoplasm\"),\n    (1, \"Nuclear membrane\"),\n    (2, \"Nucleoli\"),\n    (3, \"Nucleoli fibrillar center\"),\n    (4, \"Nuclear speckles\"),\n    (5, \"Nuclear bodies\"),\n    (6, \"Endoplasmic reticulum\"),\n    (7, \"Golgi apparatus\"),\n    (8, \"Peroxisomes\"),\n    (9, \"Endosomes\"),\n    (10, \"Lysosomes\"),\n    (11, \"Intermediate filaments\"),\n    (12, \"Actin filaments\"),\n    (13, \"Focal adhesion sites\"),\n    (14, \"Microtubules\"),\n    (15, \"Microtubule ends\"),\n    (16, \"Cytokinetic bridge\"),\n    (17, \"Mitotic spindle\"),\n    (18, \"Microtubule organizing center\"),\n    (19, \"Centrosome\"),\n    (20, \"Lipid droplets\"),\n    (21, \"Plasma membrane\"),\n    (22, \"Cell junctions\"),\n    (23, \"Mitochondria\"),\n    (24, \"Aggresome\"),\n    (25, \"Cytosol\"),\n    (26, \"Cytoplasmic bodies\"),\n    (27, \"Rods & rings\")\n]\nprotein_dict = {name: index for index, name in protein_type}\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:18.648451Z","iopub.execute_input":"2025-02-07T07:04:18.648702Z","iopub.status.idle":"2025-02-07T07:04:18.657690Z","shell.execute_reply.started":"2025-02-07T07:04:18.648682Z","shell.execute_reply":"2025-02-07T07:04:18.657052Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"protein_dict","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:18.658562Z","iopub.execute_input":"2025-02-07T07:04:18.658782Z","iopub.status.idle":"2025-02-07T07:04:18.671613Z","shell.execute_reply.started":"2025-02-07T07:04:18.658764Z","shell.execute_reply":"2025-02-07T07:04:18.670897Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"traincsv = '/kaggle/input/human-protein-atlas-image-classification/train.csv'\ndtrain = pd.read_csv(traincsv)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:18.672496Z","iopub.execute_input":"2025-02-07T07:04:18.672808Z","iopub.status.idle":"2025-02-07T07:04:18.732183Z","shell.execute_reply.started":"2025-02-07T07:04:18.672778Z","shell.execute_reply":"2025-02-07T07:04:18.731312Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dtrain.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:18.733706Z","iopub.execute_input":"2025-02-07T07:04:18.733896Z","iopub.status.idle":"2025-02-07T07:04:18.746217Z","shell.execute_reply.started":"2025-02-07T07:04:18.733880Z","shell.execute_reply":"2025-02-07T07:04:18.745216Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"protein_target = []\nfor e in dtrain['Target']:\n\n    temp = []\n    for ec in e.split():\n        \n        ec = int(ec)    #because it was stored in string\n        for k,v in protein_dict.items():\n            if v == ec:\n                temp.append(k)\n    protein_target.append(','.join(temp)) #writing like Golgi apparatus, Nuclear membrane, Nucleoli, Nucleoplasm\n\ndtrain['Target_Protein'] = protein_target\n   ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:18.747516Z","iopub.execute_input":"2025-02-07T07:04:18.747724Z","iopub.status.idle":"2025-02-07T07:04:18.924373Z","shell.execute_reply.started":"2025-02-07T07:04:18.747706Z","shell.execute_reply":"2025-02-07T07:04:18.923651Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dtrain.head(10)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:18.925240Z","iopub.execute_input":"2025-02-07T07:04:18.925559Z","iopub.status.idle":"2025-02-07T07:04:18.933784Z","shell.execute_reply.started":"2025-02-07T07:04:18.925525Z","shell.execute_reply":"2025-02-07T07:04:18.933095Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(dtrain.columns)\nprint(len(dtrain.columns))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:18.934686Z","iopub.execute_input":"2025-02-07T07:04:18.935052Z","iopub.status.idle":"2025-02-07T07:04:18.946790Z","shell.execute_reply.started":"2025-02-07T07:04:18.934988Z","shell.execute_reply":"2025-02-07T07:04:18.945790Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#writing the columns with protein type in the same order with protein_dict\nfor col in protein_dict.keys():\n    dtrain[col] = 0","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:18.947639Z","iopub.execute_input":"2025-02-07T07:04:18.947904Z","iopub.status.idle":"2025-02-07T07:04:18.967517Z","shell.execute_reply.started":"2025-02-07T07:04:18.947880Z","shell.execute_reply":"2025-02-07T07:04:18.966874Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#here we can see columns as the number of protein types. also i need to make them initialize with zero that refers not existing\ndtrain.head(10)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:18.970175Z","iopub.execute_input":"2025-02-07T07:04:18.970402Z","iopub.status.idle":"2025-02-07T07:04:18.992531Z","shell.execute_reply.started":"2025-02-07T07:04:18.970383Z","shell.execute_reply":"2025-02-07T07:04:18.991615Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#lets fill them acc to targets. if it exists, the one existed is 1, the rest is 0s.\nfor index,targets in enumerate(dtrain['Target_Protein']):\n    targets = targets.split(',')\n    for each in targets:\n        dtrain.loc[index,each] = 1","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:18.993802Z","iopub.execute_input":"2025-02-07T07:04:18.993983Z","iopub.status.idle":"2025-02-07T07:04:22.145813Z","shell.execute_reply.started":"2025-02-07T07:04:18.993967Z","shell.execute_reply":"2025-02-07T07:04:22.145047Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dtrain.head(10)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:22.146597Z","iopub.execute_input":"2025-02-07T07:04:22.146837Z","iopub.status.idle":"2025-02-07T07:04:22.166677Z","shell.execute_reply.started":"2025-02-07T07:04:22.146820Z","shell.execute_reply":"2025-02-07T07:04:22.165660Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"protein_col = dtrain.columns\nprotein_col=protein_col.drop(['Id','Target','Target_Protein'])\nnumber_of_protein = dtrain[protein_col].sum().to_dict()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:22.167678Z","iopub.execute_input":"2025-02-07T07:04:22.168015Z","iopub.status.idle":"2025-02-07T07:04:22.187578Z","shell.execute_reply.started":"2025-02-07T07:04:22.167978Z","shell.execute_reply":"2025-02-07T07:04:22.186849Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pd_protein_number =pd.DataFrame(number_of_protein.items(),columns=['Protein','Number'])\npd_protein_number.head(5)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:22.188476Z","iopub.execute_input":"2025-02-07T07:04:22.188744Z","iopub.status.idle":"2025-02-07T07:04:22.199449Z","shell.execute_reply.started":"2025-02-07T07:04:22.188717Z","shell.execute_reply":"2025-02-07T07:04:22.198711Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cnt = 0\nfor s in pd_protein_number['Number']:\n    cnt +=s \nprint(cnt)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:22.200297Z","iopub.execute_input":"2025-02-07T07:04:22.200545Z","iopub.status.idle":"2025-02-07T07:04:22.210871Z","shell.execute_reply.started":"2025-02-07T07:04:22.200514Z","shell.execute_reply":"2025-02-07T07:04:22.210017Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pd_protein_number_sorted=pd_protein_number.sort_values(by='Number',ascending = False)\npd_protein_number_sorted.head(5)\n\npd_protein_number_sorted['Percentage'] = round(pd_protein_number_sorted['Number']/dtrain.shape[0]*100,2)\n\n#plotting it with percentage:\nplt.figure(figsize = (8,6))\n\nsns.barplot(x='Protein',y='Percentage',data= pd_protein_number_sorted)\nplt.xticks(rotation=90)\nplt.title('Sum of Each Protein')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:22.211695Z","iopub.execute_input":"2025-02-07T07:04:22.211922Z","iopub.status.idle":"2025-02-07T07:04:22.675419Z","shell.execute_reply.started":"2025-02-07T07:04:22.211903Z","shell.execute_reply":"2025-02-07T07:04:22.674371Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pd_protein_number_sorted.head(10)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:22.676449Z","iopub.execute_input":"2025-02-07T07:04:22.676777Z","iopub.status.idle":"2025-02-07T07:04:22.686606Z","shell.execute_reply.started":"2025-02-07T07:04:22.676743Z","shell.execute_reply":"2025-02-07T07:04:22.685749Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> Keynotes: We can see easily that the data was not distributed fairly. In order to make the model introduce the low number of protein, I need to make data augmentation so that the image with low number protein is augmented.","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"no_target = []\ntarget_list = dtrain['Target']\nfor target in target_list:\n    no_target.append(len(target.split()))\ndtrain['No_of_Protein'] = no_target","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:22.687572Z","iopub.execute_input":"2025-02-07T07:04:22.687916Z","iopub.status.idle":"2025-02-07T07:04:22.714050Z","shell.execute_reply.started":"2025-02-07T07:04:22.687892Z","shell.execute_reply":"2025-02-07T07:04:22.713447Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"a=dtrain['No_of_Protein'].value_counts().reset_index()\n\nplt.figure(figsize=(6,4))\nsns.barplot(x='No_of_Protein',y='count',data= a)\nplt.title('How Many Proteins Are in Each Group')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:22.714782Z","iopub.execute_input":"2025-02-07T07:04:22.714987Z","iopub.status.idle":"2025-02-07T07:04:22.951349Z","shell.execute_reply.started":"2025-02-07T07:04:22.714969Z","shell.execute_reply":"2025-02-07T07:04:22.950656Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#fetching the images from train folder:\ntrain_files = []\ntrain_link = '/kaggle/input/human-protein-atlas-image-classification/train'\n\nfor dirname, _, filenames in os.walk(train_link):\n    for filename in filenames:\n        filename=(os.path.join(dirname, filename))\n        train_files.append(filename)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:04:22.952172Z","iopub.execute_input":"2025-02-07T07:04:22.952393Z","iopub.status.idle":"2025-02-07T07:06:46.408144Z","shell.execute_reply.started":"2025-02-07T07:04:22.952374Z","shell.execute_reply":"2025-02-07T07:06:46.407454Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print('the number of image in train folder: ',len(train_files))\nprint('the number of id in train.csv',len(dtrain['Id']))\nprint('example:',train_files[0])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:06:46.408964Z","iopub.execute_input":"2025-02-07T07:06:46.409299Z","iopub.status.idle":"2025-02-07T07:06:46.415849Z","shell.execute_reply.started":"2025-02-07T07:06:46.409271Z","shell.execute_reply":"2025-02-07T07:06:46.415129Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#fetching the images from test folder:\ntest_link = '/kaggle/input/human-protein-atlas-image-classification/test' \ntestcsv = '/kaggle/input/human-protein-atlas-image-classification/sample_submission.csv'\ntest_files = []\n\ndtest = pd.read_csv(testcsv)\n\nfor dirname, _, filenames in os.walk(test_link):\n    for filename in filenames:\n        filename=(os.path.join(dirname, filename))\n        test_files.append(filename)\n\nprint('the number of image in test folder: ',len(test_files))\nprint('the number of id in test.csv',len(dtest['Id']))\nprint('example:',test_files[0])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:06:46.416616Z","iopub.execute_input":"2025-02-07T07:06:46.417133Z","iopub.status.idle":"2025-02-07T07:07:38.554225Z","shell.execute_reply.started":"2025-02-07T07:06:46.417099Z","shell.execute_reply":"2025-02-07T07:07:38.553523Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dtest['Id']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:38.554943Z","iopub.execute_input":"2025-02-07T07:07:38.555223Z","iopub.status.idle":"2025-02-07T07:07:38.561760Z","shell.execute_reply.started":"2025-02-07T07:07:38.555201Z","shell.execute_reply":"2025-02-07T07:07:38.560798Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"11702*4","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:38.562753Z","iopub.execute_input":"2025-02-07T07:07:38.563058Z","iopub.status.idle":"2025-02-07T07:07:38.575891Z","shell.execute_reply.started":"2025-02-07T07:07:38.563028Z","shell.execute_reply":"2025-02-07T07:07:38.575238Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Important that test_files includes only image names. In dataset and dataloader, _green,_blue,_yellow and _red part will be merged there, not here!**\n\n> Total images in test folder is 46808\n> \n> Total image name in test_files is 11702\n> \n> I am on the correct way now.","metadata":{}},{"cell_type":"markdown","source":"## Co-Occurence of Data\n\nprotein_col = Index(['Nucleoplasm', 'Nuclear membrane', 'Nucleoli',\n       'Nucleoli fibrillar center', 'Nuclear speckles', 'Nuclear bodies',\n       'Endoplasmic reticulum', 'Golgi apparatus', 'Peroxisomes', 'Endosomes',\n       'Lysosomes', 'Intermediate filaments', 'Actin filaments',\n       'Focal adhesion sites', 'Microtubules', 'Microtubule ends',\n       'Cytokinetic bridge', 'Mitotic spindle',\n       'Microtubule organizing center', 'Centrosome', 'Lipid droplets',\n       'Plasma membrane', 'Cell junctions', 'Mitochondria', 'Aggresome',\n       'Cytosol', 'Cytoplasmic bodies', 'Rods & rings'],\n      dtype='object')","metadata":{}},{"cell_type":"code","source":"protein_df = dtrain[protein_col]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:38.585359Z","iopub.execute_input":"2025-02-07T07:07:38.585561Z","iopub.status.idle":"2025-02-07T07:07:38.597657Z","shell.execute_reply.started":"2025-02-07T07:07:38.585544Z","shell.execute_reply":"2025-02-07T07:07:38.596821Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"protein_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:38.600217Z","iopub.execute_input":"2025-02-07T07:07:38.600437Z","iopub.status.idle":"2025-02-07T07:07:38.652963Z","shell.execute_reply.started":"2025-02-07T07:07:38.600419Z","shell.execute_reply":"2025-02-07T07:07:38.652288Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Calculate co-occurrence matrix\nco_occurrence = np.dot(protein_df.T, protein_df) #generic dot operations by numpy, but it is generic summary. i need ot make it normalize by protein_df.values.sum()\nco_occurence_norm = co_occurrence/( protein_df.values.sum())\nco_occ_df = pd.DataFrame(co_occurrence,index = protein_col, columns = protein_col)\n\n\nplt.figure(figsize=(12,12))\nsns.heatmap(co_occ_df,annot=False,cmap = 'crest') #fmt=\".1f\"\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:38.653719Z","iopub.execute_input":"2025-02-07T07:07:38.653913Z","iopub.status.idle":"2025-02-07T07:07:39.285315Z","shell.execute_reply.started":"2025-02-07T07:07:38.653897Z","shell.execute_reply":"2025-02-07T07:07:39.284463Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**WHY Protein_1 vs Protein_1 is not 1 or max,here is the answer:**\n\n> Takeaways: **the cells in diagonal** are expected to be 1. But the heatmap above also shows the density. If you can see protein_x in x axis and the same protein in y axis, some cell is light green while some is dark green. It shows that dark green refers how intense the protein is and vice versa. You can see the example below: A is more often than B. That's why, co-occurence matrix shows A intersection is 5 while B intersection is 4.","metadata":{}},{"cell_type":"code","source":"data = {\n    'Protein_A': [1, 1, 1, 1, 1],\n    'Protein_B': [0, 1, 1, 1, 1],\n    'Protein_C': [1, 0, 1, 0, 0]}\ndf = pd.DataFrame(data)\nprint(df.head(5))\n\n# Calculate co-occurrence matrix\ntry_1 = np.dot(df.T, df)\nco_try_1 = pd.DataFrame(try_1, index=df.columns, columns=df.columns)\n\nprint(co_try_1)","metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:39.286196Z","iopub.execute_input":"2025-02-07T07:07:39.286444Z","iopub.status.idle":"2025-02-07T07:07:39.294682Z","shell.execute_reply.started":"2025-02-07T07:07:39.286422Z","shell.execute_reply":"2025-02-07T07:07:39.293738Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Showing some images with labels:","metadata":{}},{"cell_type":"code","source":"color_arr = ['_red.png','_green.png','_blue.png','_yellow.png'] #Sequence: RGBY\ntmp = 0\ncnt_nmb = 7\nfig, ax = plt.subplots(cnt_nmb,cnt_nmb,figsize = (20,16))\n\nfor i in range(cnt_nmb):\n    for j in range(cnt_nmb):\n        tmp = random.randint(0, dtrain.shape[0])\n        img_name = dtrain['Id'][tmp]\n        title = 'Class:'+ dtrain['Target'][tmp]\n        link = os.path.join(train_link,img_name)\n        each_image = [] # will store 4 channels here\n        \n        for idx,c in enumerate (color_arr):\n            c_link = link + c\n            #print(c_link)\n            a = cv2.imread(c_link)\n            a = cv2.cvtColor(a,cv2.COLOR_BGR2GRAY)  #in order to put them into RGB sequence of final image\n            each_image.append(a)\n            \n        each_image= np.array(each_image)\n        k = each_image.transpose()\n        ax[i][j].imshow(k[:,:,:3])\n        ax[i][j].axis('off')\n        title = title\n        ax[i][j].set_title(title)   \n\n        tmp +=1 #classic counter that will give an index to dtrain \n    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:39.295510Z","iopub.execute_input":"2025-02-07T07:07:39.295804Z","iopub.status.idle":"2025-02-07T07:07:46.899439Z","shell.execute_reply.started":"2025-02-07T07:07:39.295772Z","shell.execute_reply":"2025-02-07T07:07:46.898028Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"np.clip(value,min,max):\n* Any value less than 0 is set to 0, and any value greater than 255 is set to 255.\n* \n![image.png](attachment:d3ec3bf3-065a-443e-aeef-fdd77f7323dc.png)","metadata":{},"attachments":{"d3ec3bf3-065a-443e-aeef-fdd77f7323dc.png":{"image/png":"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"}}},{"cell_type":"code","source":"fig,ax = plt.subplots(4,4,figsize = (16,16))\n\nfor i in range(4):\n    cnt = random.randint(0,dtrain.shape[0])\n    img_linked = os.path.join(train_link,dtrain['Id'][cnt])\n\n    for j, c in enumerate(color_arr):\n        img_link = img_linked + c  #_color will add to the end\n        #print('sss',img_link)\n        img = cv2.imread(img_link)\n        imaj = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)\n        imaj = imaj.copy()\n        \n        if c == '_red.png':\n            imaj[:,:,0] = np.clip(imaj[:,:,0]*2,0,255)\n            imaj[:,:,1] = 0 #GREEN -- 0\n            imaj[:,:,2] = 0 #BLUE -- 0     \n\n        elif c == '_green.png':\n            imaj[:,:,0] = 0 #RED -- 0\n            imaj[:,:,1] = np.clip(imaj[:,:,1]*2,0,255)\n            imaj[:,:,2] = 0 #BLUE -- 0     \n\n        elif c == '_blue.png':\n            imaj[:,:,0] = 0 #RED -- 0\n            imaj[:,:,1] = 0 #GREEN -- 0\n            imaj[:,:,2] = np.clip(imaj[:,:,2]*2,0,255)\n\n        else:  #YELLOW -- RED and GREEN\n            imaj[:,:,0] = np.clip(imaj[:,:,0]*2,0,255)\n            imaj[:,:,1] = np.clip(imaj[:,:,1]*2,0,255)\n            imaj[:,:,2] = 0 #BLUE -- 0\n\n        #black_mask:\n        black_mask_out = (imaj[:,:,0] == 0) & (imaj[:,:,1] == 0) & (imaj[:,:,2] == 0)\n        #make black white:\n        imaj[black_mask_out] = [255,255,255] #SET THEM 255,255,255 WHICH IS WHITE\n\n        ax[i][j].axis('off')     \n        ax[i][j].imshow(imaj)\n        ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:46.900619Z","iopub.execute_input":"2025-02-07T07:07:46.900840Z","iopub.status.idle":"2025-02-07T07:07:48.974753Z","shell.execute_reply.started":"2025-02-07T07:07:46.900823Z","shell.execute_reply":"2025-02-07T07:07:48.973442Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig,ax = plt.subplots(4,4,figsize = (16,16))\n\nfor i in range(4):\n    cnt = random.randint(0,dtest.shape[0])\n    img_linked = os.path.join(test_link,dtest['Id'][cnt])\n\n    for j, c in enumerate(color_arr):\n        img_link = img_linked + c  #_color will add to the end\n        #print('sss',img_link)\n        img = cv2.imread(img_link)\n        imaj = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)\n        imaj = imaj.copy()\n        \n        if c == '_red.png':\n            imaj[:,:,0] = np.clip(imaj[:,:,0]*2,0,255)\n            imaj[:,:,1] = 0 #GREEN -- 0\n            imaj[:,:,2] = 0 #BLUE -- 0     \n\n        elif c == '_green.png':\n            imaj[:,:,0] = 0 #RED -- 0\n            imaj[:,:,1] = np.clip(imaj[:,:,1]*2,0,255)\n            imaj[:,:,2] = 0 #BLUE -- 0     \n\n        elif c == '_blue.png':\n            imaj[:,:,0] = 0 #RED -- 0\n            imaj[:,:,1] = 0 #GREEN -- 0\n            imaj[:,:,2] = np.clip(imaj[:,:,2]*2,0,255)\n\n        else:  #YELLOW -- RED and GREEN\n            imaj[:,:,0] = np.clip(imaj[:,:,0]*2,0,255)\n            imaj[:,:,1] = np.clip(imaj[:,:,1]*2,0,255)\n            imaj[:,:,2] = 0 #BLUE -- 0\n\n        #black_mask:\n        black_mask_out = (imaj[:,:,0] == 0) & (imaj[:,:,1] == 0) & (imaj[:,:,2] == 0)\n        #make black white:\n        imaj[black_mask_out] = [255,255,255] #SET THEM 255,255,255 WHICH IS WHITE\n\n        ax[i][j].axis('off')     \n        ax[i][j].imshow(imaj)\n        ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:48.976223Z","iopub.execute_input":"2025-02-07T07:07:48.976625Z","iopub.status.idle":"2025-02-07T07:07:50.857215Z","shell.execute_reply.started":"2025-02-07T07:07:48.976586Z","shell.execute_reply":"2025-02-07T07:07:50.856270Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Important note:** each id has 4 different images like red,green,yellow,blue ","metadata":{}},{"cell_type":"code","source":"#drop the no_of_protein from the data, because it is no needed here anymore.\ndtrain=dtrain.drop(['No_of_Protein'],axis = 1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:50.858099Z","iopub.execute_input":"2025-02-07T07:07:50.858377Z","iopub.status.idle":"2025-02-07T07:07:50.867386Z","shell.execute_reply.started":"2025-02-07T07:07:50.858355Z","shell.execute_reply":"2025-02-07T07:07:50.866403Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dtrain.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:50.868113Z","iopub.execute_input":"2025-02-07T07:07:50.868374Z","iopub.status.idle":"2025-02-07T07:07:50.887341Z","shell.execute_reply.started":"2025-02-07T07:07:50.868351Z","shell.execute_reply":"2025-02-07T07:07:50.886430Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Data Processing","metadata":{}},{"cell_type":"markdown","source":"*Important Info*: \n- X, Y, Z and C. X and Y will be the two sides of a two dimensional image. \n- Z will be the third side of a three dimensional image. In this dataset there are no three dimensional images, so Z will always be 1. \n- C will be the number of channels per image field of view. In this dataset there are always four channels. The order of channels in the numpy array is important. \n- The channel order should be: [red, green, blue, yellow]","metadata":{}},{"cell_type":"code","source":"'''\n\nThis is example, i need to tranform this as function so i can use both train and test\n\nmerged_image[:, :, 0] → Red\nmerged_image[:, :, 1] → Green\nmerged_image[:, :, 2] → Blue\nmerged_image[:, :, 3] → Yellow\n\n\nimg = os.path.join(train_link,'96ac3ccc-bbae-11e8-b2ba-ac1f6b6435d0')\nimg_red = img+'_red.png'\nimg_green = img+'_green.png'\nimg_blue = img+'_blue.png'\nimg_yellow = img+'_yellow.png'\n\narr_red = cv2.imread(img_red,cv2.IMREAD_GRAYSCALE)  # Read as grayscale)\narr_green = cv2.imread(img_green,cv2.IMREAD_GRAYSCALE)  # Read as grayscale))\narr_blue = cv2.imread(img_blue,cv2.IMREAD_GRAYSCALE)  # Read as grayscale))\narr_yellow = cv2.imread(img_yellow,cv2.IMREAD_GRAYSCALE)  # Read as grayscale))\n\nmerged_image = np.stack((arr_red,arr_green,arr_blue,arr_yellow))\n\nprint(merged_image.shape)\ntranspose_image = np.transpose(merged_image, (1, 2, 0))\nprint(transpose_image.shape)\nimage_final = transpose_image[:, :, np.newaxis, :] \nprint(image_final.shape)\n\n------------------------------------------------------------------------------------------------\noutput: \n\n(4, 512, 512)\n(512, 512, 4)\n(512, 512, 1, 4)\n------------------------------------------------------------------------------------------------\n'''\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:50.888362Z","iopub.execute_input":"2025-02-07T07:07:50.888621Z","iopub.status.idle":"2025-02-07T07:07:50.896144Z","shell.execute_reply.started":"2025-02-07T07:07:50.888571Z","shell.execute_reply":"2025-02-07T07:07:50.895109Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"'''\n\nimg = os.path.join(train_link,'96ac3ccc-bbae-11e8-b2ba-ac1f6b6435d0')\nimg_red = img+'_red.png'\nimg_green = img+'_green.png'\nimg_blue = img+'_blue.png'\nimg_yellow = img+'_yellow.png'\n\narr_red = cv2.imread(img_red,cv2.IMREAD_GRAYSCALE)  # Read as grayscale)\narr_green = cv2.imread(img_green,cv2.IMREAD_GRAYSCALE)  # Read as grayscale))\narr_blue = cv2.imread(img_blue,cv2.IMREAD_GRAYSCALE)  # Read as grayscale))\narr_yellow = cv2.imread(img_yellow,cv2.IMREAD_GRAYSCALE)  # Read as grayscale))\n\n\nnumpy_array = np.stack((arr_red, arr_green, arr_blue, arr_yellow), axis=0)  # Shape: (4, H, W)\ntensor = torch.from_numpy(numpy_array)\ntensor = tensor.to('cuda')\nprint(tensor.shape)\nnew_tensor = tensor.unsqueeze(0)  # Adds a new axis at position 0\nprint(new_tensor.shape)\nreorder_new_tensor = new_tensor.permute(2,3,1,0)\nprint(reorder_new_tensor.shape)\n\n\n------------------------OUTPUT --------------------------\ntorch.Size([4, 512, 512])\ntorch.Size([1, 4, 512, 512])\ntorch.Size([512, 512, 4, 1]) THIS IS WHAT EXPECTED!\n------------------------OUTPUT --------------------------\n\n'''","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:50.897185Z","iopub.execute_input":"2025-02-07T07:07:50.897502Z","iopub.status.idle":"2025-02-07T07:07:50.909897Z","shell.execute_reply.started":"2025-02-07T07:07:50.897468Z","shell.execute_reply":"2025-02-07T07:07:50.908861Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#here, the output is one hot encoding\n\ncolumn = dtrain.columns \ny_column =column.drop(['Id','Target','Target_Protein'])\nprint(len(y_column))\n\nlabel = dtrain[y_column].values\nprint(label.shape)\ny = label","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:50.910819Z","iopub.execute_input":"2025-02-07T07:07:50.911421Z","iopub.status.idle":"2025-02-07T07:07:50.932861Z","shell.execute_reply.started":"2025-02-07T07:07:50.911388Z","shell.execute_reply":"2025-02-07T07:07:50.932078Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:50.933668Z","iopub.execute_input":"2025-02-07T07:07:50.933884Z","iopub.status.idle":"2025-02-07T07:07:50.939116Z","shell.execute_reply.started":"2025-02-07T07:07:50.933866Z","shell.execute_reply":"2025-02-07T07:07:50.938312Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print('the first protein is:',y[0])\nprint('the second protein is:',y[1])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:50.940045Z","iopub.execute_input":"2025-02-07T07:07:50.940294Z","iopub.status.idle":"2025-02-07T07:07:50.951524Z","shell.execute_reply.started":"2025-02-07T07:07:50.940271Z","shell.execute_reply":"2025-02-07T07:07:50.950763Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"When compare to output.head and y[0] and y[1], you can see that i got reached out the label of each image in one hot encoding successfully.","metadata":{}},{"cell_type":"code","source":"#before putting them into torch, just make sure the shape is okay for each other\n\nprint('y:',y.shape)\nprint('x',dtrain.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:50.952424Z","iopub.execute_input":"2025-02-07T07:07:50.952682Z","iopub.status.idle":"2025-02-07T07:07:50.962861Z","shell.execute_reply.started":"2025-02-07T07:07:50.952650Z","shell.execute_reply":"2025-02-07T07:07:50.962057Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dtrain['Id'][0:10]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:50.963721Z","iopub.execute_input":"2025-02-07T07:07:50.963916Z","iopub.status.idle":"2025-02-07T07:07:50.975110Z","shell.execute_reply.started":"2025-02-07T07:07:50.963899Z","shell.execute_reply":"2025-02-07T07:07:50.974280Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y[0:10]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:50.975996Z","iopub.execute_input":"2025-02-07T07:07:50.976328Z","iopub.status.idle":"2025-02-07T07:07:50.986421Z","shell.execute_reply.started":"2025-02-07T07:07:50.976296Z","shell.execute_reply":"2025-02-07T07:07:50.985683Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# i need to split train and val, otherwise i cannot see val loss!\nfrom sklearn.model_selection import train_test_split\n\n\nx_train,x_val, y_train, y_val = train_test_split(dtrain['Id'].values,y,test_size=0.30, random_state=42)\n\nprint(f'X_train shape: {x_train.shape}')  # Expected: (24857, 1)\nprint(f'X_val shape: {x_val.shape}')      # Expected: (6215, 1)\nprint(f'y_train shape: {y_train.shape}')  # Expected: (24857, 28)\nprint(f'y_val shape: {y_val.shape}')      # Expected: (6215, 28)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:50.987207Z","iopub.execute_input":"2025-02-07T07:07:50.987581Z","iopub.status.idle":"2025-02-07T07:07:51.339196Z","shell.execute_reply.started":"2025-02-07T07:07:50.987546Z","shell.execute_reply":"2025-02-07T07:07:51.338377Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_train[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:51.340049Z","iopub.execute_input":"2025-02-07T07:07:51.340355Z","iopub.status.idle":"2025-02-07T07:07:51.345286Z","shell.execute_reply.started":"2025-02-07T07:07:51.340325Z","shell.execute_reply":"2025-02-07T07:07:51.344589Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_train[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:51.346114Z","iopub.execute_input":"2025-02-07T07:07:51.346383Z","iopub.status.idle":"2025-02-07T07:07:51.361043Z","shell.execute_reply.started":"2025-02-07T07:07:51.346355Z","shell.execute_reply":"2025-02-07T07:07:51.360317Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_val[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:51.361733Z","iopub.execute_input":"2025-02-07T07:07:51.361984Z","iopub.status.idle":"2025-02-07T07:07:51.373555Z","shell.execute_reply.started":"2025-02-07T07:07:51.361964Z","shell.execute_reply":"2025-02-07T07:07:51.372647Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_val[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:51.374459Z","iopub.execute_input":"2025-02-07T07:07:51.374720Z","iopub.status.idle":"2025-02-07T07:07:51.385103Z","shell.execute_reply.started":"2025-02-07T07:07:51.374700Z","shell.execute_reply":"2025-02-07T07:07:51.384266Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**One more note:**\n\n* the number of image in train folder is 124,288.\n* they are merged by 4 channels so each element of input should have 4 channels.\n* At the end torch number of input should be 31072 as well","metadata":{}},{"cell_type":"markdown","source":"## Data Augmentation\n\n\nI noticed that the previous model easily miss out some images to predict. In order to boost the model, i decided to make the train data to increase the varients. \n\n> https://pytorch.org/vision/main/transforms.html\n","metadata":{}},{"cell_type":"code","source":"# Image Classification\nimport torch\nfrom torchvision.transforms import v2\n\n#train to augment\ntrain_transforms = v2.Compose([\n    v2.ToImage(),  # Ensures compatibility with tensors and PIL images\n    v2.RandomResizedCrop(size=(512, 512),scale=(0.8, 1.0), antialias=True),\n    v2.RandomHorizontalFlip(p=0.5),\n    #v2.RandomVerticalFlip(p=0.5),\n    v2.RandomRotation(degrees=(-30, 30),fill=(0, 0, 0, 0)),   # Transparency\n    v2.ToDtype(torch.float32, scale=True), # Converts to float32 and scales to [0,1] right before normalization\n    #v2.Normalize(mean=[0.485, 0.456, 0.406,0.5], std=[0.229, 0.224, 0.225,0.25]),\n])\n#val to only normalize\nval_transforms = v2.Compose([\n    v2.ToImage(),  # Ensures compatibility with tensors and PIL images\n    v2.RandomResizedCrop(size=(512, 512), antialias=True),\n    v2.ToDtype(torch.float32, scale=True), # Converts to float32 and scales to [0,1] right before normalization\n    #v2.Normalize(mean=[0.485, 0.456, 0.406,0.5], std=[0.229, 0.224, 0.225,0.25]),\n])\n\n#val to only normalize\ntest_transforms = v2.Compose([\n    v2.ToImage(),  # Ensures compatibility with tensors and PIL images\n    v2.RandomResizedCrop(size=(512, 512), antialias=True),\n    v2.ToDtype(torch.float32, scale=True), # Converts to float32 and scales to [0,1] right before normalization\n    #v2.Normalize(mean=[0.485, 0.456, 0.406,0.5], std=[0.229, 0.224, 0.225,0.25]),\n])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:51.385940Z","iopub.execute_input":"2025-02-07T07:07:51.386267Z","iopub.status.idle":"2025-02-07T07:07:55.437507Z","shell.execute_reply.started":"2025-02-07T07:07:51.386234Z","shell.execute_reply":"2025-02-07T07:07:55.436574Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"'''\n### WeightedRandomSampler \n\nThere are notes that was written in pytorch form,\n\n> https://discuss.pytorch.org/t/targeted-image-augmentation/215621\n>\n> https://discuss.pytorch.org/t/how-to-handle-imbalanced-classes/11264/2\n> \n> https://medium.com/@zergtant/improving-control-and-reproducibility-of-pytorch-dataloader-with-sampler-instead-of-shuffle-7f795490256e\n\nIn the implementation, with the help of this open source code: https://gist.github.com/angeligareta/83d9024c5e72ac9ebc34c9f0b073c64c and https://discuss.pytorch.org/t/how-to-handle-imbalanced-classes/11264/2\n\n'''","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:55.438369Z","iopub.execute_input":"2025-02-07T07:07:55.438825Z","iopub.status.idle":"2025-02-07T07:07:55.443930Z","shell.execute_reply.started":"2025-02-07T07:07:55.438803Z","shell.execute_reply":"2025-02-07T07:07:55.443186Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"\n","metadata":{}},{"cell_type":"markdown","source":"## Pytorch for dataset and dataloader","metadata":{}},{"cell_type":"code","source":"import torch\nfrom torch.utils.data import Dataset, DataLoader\n\nclass ProteinDataset(Dataset):\n    def __init__(self,link,ids,label=None,transform = None):\n        self.link=link\n        self.ids = ids\n        self.label = label\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.ids)\n\n    def __getitem__(self,idx):\n        each_id = self.ids[idx]\n        each_label = self.label[idx] if self.label is not None else None\n        img_path = os.path.join(self.link,each_id)\n        \n        arr_red = cv2.imread((img_path+'_red.png'),cv2.IMREAD_GRAYSCALE)\n        arr_blue = cv2.imread((img_path+'_blue.png'),cv2.IMREAD_GRAYSCALE)\n        arr_green = cv2.imread((img_path+'_green.png'),cv2.IMREAD_GRAYSCALE)\n        arr_yellow = cv2.imread((img_path+'_yellow.png'),cv2.IMREAD_GRAYSCALE)\n\n        numpy_array = np.stack((arr_red, arr_green, arr_blue, arr_yellow), axis=0)  # Shape: (4, H, W)\n        tensor = torch.from_numpy(numpy_array)\n\n        if self.transform: # Apply transformations\n            transformed_tensor = self.transform(tensor)\n            tensor = transformed_tensor\n        \n        #new_tensor = tensor.unsqueeze(0)  # Adds a new axis at position 0\n        #print(tensor.shape)\n        #reorder_new_tensor = new_tensor.permute(2,3,0,1) #fixed as 2,3,0,1\n        #print(tensor.shape)\n        #tensor = tensor.permute(0,3,2,1) #16,4,512,512\n\n        if each_label is not None:\n            return tensor, torch.tensor(each_label) # you need to make the output in torch tensor as well\n        else:\n            return tensor","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:35:29.011718Z","iopub.execute_input":"2025-02-07T09:35:29.012050Z","iopub.status.idle":"2025-02-07T09:35:29.018902Z","shell.execute_reply.started":"2025-02-07T09:35:29.011996Z","shell.execute_reply":"2025-02-07T09:35:29.017905Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dataset = ProteinDataset(train_link,x_train,y_train,transform=train_transforms)\nval_dataset = ProteinDataset(train_link,x_val,y_val,transform=val_transforms)\ntest_dataset = ProteinDataset(test_link,dtest['Id'],transform=test_transforms)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:35:31.386596Z","iopub.execute_input":"2025-02-07T09:35:31.386915Z","iopub.status.idle":"2025-02-07T09:35:31.391493Z","shell.execute_reply.started":"2025-02-07T09:35:31.386886Z","shell.execute_reply":"2025-02-07T09:35:31.390467Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dataloader = DataLoader(train_dataset, batch_size= 16,shuffle = True,drop_last=True,num_workers =0)\nval_dataloader = DataLoader(val_dataset, batch_size= 16,shuffle = False,drop_last=True,num_workers = 2)\ntest_dataloader = DataLoader(test_dataset, batch_size= 16,shuffle = False,drop_last=False,num_workers = 2) ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:35:33.163044Z","iopub.execute_input":"2025-02-07T09:35:33.163351Z","iopub.status.idle":"2025-02-07T09:35:33.167850Z","shell.execute_reply.started":"2025-02-07T09:35:33.163327Z","shell.execute_reply":"2025-02-07T09:35:33.167118Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"'''\nimport torch\n\n# Initialize mean & std accumulation\nmean_sum = torch.zeros(4)  # Assuming 4 channels\nstd_sum = torch.zeros(4)\nnum_samples = 0\n\n# Iterate over the dataloader\nfor images, _ in iter(train_dataloader):\n    batch_size = images.size(0)  # Number of images in batch\n\n    # Fix shape: Remove redundant dimension (1) but keep channels last\n    images = images.squeeze(3)  # Now shape is [16, 512, 512, 4]\n\n    # Compute per-channel mean & std for this batch\n    batch_mean, batch_std = torch.std_mean(images, dim=[0, 1, 2])  \n\n    # Accumulate weighted sum\n    mean_sum += batch_mean * batch_size\n    std_sum += batch_std * batch_size\n    print(mean_sum)\n    num_samples += batch_size\n\n# Normalize by total number of images\nmean_final = mean_sum / num_samples\nstd_final = std_sum / num_samples\n\nprint(f\"Mean per channel: {mean_final.tolist()}\")\nprint(f\"Std per channel: {std_final.tolist()}\")\n'''","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:07:55.483426Z","iopub.execute_input":"2025-02-07T07:07:55.483695Z","iopub.status.idle":"2025-02-07T07:07:55.497455Z","shell.execute_reply.started":"2025-02-07T07:07:55.483668Z","shell.execute_reply":"2025-02-07T07:07:55.496787Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for image,label in iter(train_dataloader):\n    print('batch of image shapes: ',image.shape)\n    print('batch of label shapes:',label.shape)\n    break","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:35:35.878085Z","iopub.execute_input":"2025-02-07T09:35:35.878385Z","iopub.status.idle":"2025-02-07T09:35:36.422147Z","shell.execute_reply.started":"2025-02-07T09:35:35.878365Z","shell.execute_reply":"2025-02-07T09:35:36.421203Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for image,label in iter(val_dataloader):\n    print('batch of image shapes: ',image.shape)\n    print('batch of label shapes:',label.shape)\n    break","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:35:42.827532Z","iopub.execute_input":"2025-02-07T09:35:42.827811Z","iopub.status.idle":"2025-02-07T09:35:44.008498Z","shell.execute_reply.started":"2025-02-07T09:35:42.827790Z","shell.execute_reply":"2025-02-07T09:35:44.007448Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for image in iter(test_dataloader):\n    print('batch of image shapes: ',image.shape)\n    break","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:35:46.039846Z","iopub.execute_input":"2025-02-07T09:35:46.040181Z","iopub.status.idle":"2025-02-07T09:35:47.097116Z","shell.execute_reply.started":"2025-02-07T09:35:46.040152Z","shell.execute_reply":"2025-02-07T09:35:47.096239Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#train data after augmentation\nfig, ax = plt.subplots(2,2,figsize = (10,8))\n\nfor image,_ in iter(train_dataloader):\n    print('batch of image shapes: ',image.shape)\n    print(image[0].shape)\n    reorder_new_tensor = image[6].squeeze(2)\n    print(reorder_new_tensor.shape)\n    for i in range(2):\n        for j in  range(2):\n            ax[i][j].imshow(reorder_new_tensor[2*i+j,:,:])\n    break","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:36:22.153428Z","iopub.execute_input":"2025-02-07T09:36:22.153723Z","iopub.status.idle":"2025-02-07T09:36:23.449311Z","shell.execute_reply.started":"2025-02-07T09:36:22.153701Z","shell.execute_reply":"2025-02-07T09:36:23.448337Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#val data after augmentation (no real augmantation)\n\nfig, ax = plt.subplots(2,2,figsize = (10,8))\n\nfor image,_ in iter(train_dataloader):\n    print('batch of image shapes: ',image.shape)\n    print(image[0].shape)\n    reorder_new_tensor = image[10].squeeze(2)\n    print(reorder_new_tensor.shape)\n    for i in range(2):\n        for j in  range(2):\n            ax[i][j].imshow(reorder_new_tensor[2*i+j,:,:])\n    break","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:36:36.275377Z","iopub.execute_input":"2025-02-07T09:36:36.275711Z","iopub.status.idle":"2025-02-07T09:36:37.665862Z","shell.execute_reply.started":"2025-02-07T09:36:36.275683Z","shell.execute_reply":"2025-02-07T09:36:37.664824Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, ax = plt.subplots(2,2,figsize = (10,8))\n\nfor image in iter(test_dataloader):\n    print('batch of image shapes: ',image.shape)\n    print(image[0].shape)\n    reorder_new_tensor = image[6].squeeze(2)\n    print(reorder_new_tensor.shape)\n    for i in range(2):\n        for j in  range(2):\n            ax[i][j].imshow(reorder_new_tensor[2*i+j,:,:])\n    break","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:36:43.684255Z","iopub.execute_input":"2025-02-07T09:36:43.684558Z","iopub.status.idle":"2025-02-07T09:36:46.160902Z","shell.execute_reply.started":"2025-02-07T09:36:43.684536Z","shell.execute_reply":"2025-02-07T09:36:46.159914Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Focal Loss\n\nAt the beginning, I was thinking that WeightedRandomSampler could work for me but I noticed that tuning of the rare components and also the common components is very challenging for me. After that, I decided to change my direction using FOCAL LOSS so that the model would focus on rare data by looking at the LOSS WHICH IS EXPLAINED IN DETAIL BELOW.\n\n**What I understand from Focal Loss:**\n* This example is basically cross entropy problem. But if I could apply BCE directly for my model in training phase, the BCE loss would reflect the same and equal effect on each protein no matter how much the protein reveals. This can be problematic because the BCE loss from common protein can manipulate the model. Also BCE loss for rear protein does not have any advantages.\n\n* CHATGPT Comment:  In a more balanced (or \"stable\") dataset, where class frequencies are similar and you don't have severe imbalance, standard BCE (Binary Cross Entropy) would likely work well. The primary motivation for using focal loss is to mitigate the negative effects of class imbalance by reducing the contribution of easy, abundant examples and focusing more on the hard, rare ones.\n\n* Focal Loss make sure that focuses on the rare samples. How it works like: that focal loss down-weights easy examples (from the common classes) so that the learning process emphasizes the rare or difficult ones. But the important key is that down weighting will be taken place without any manuel inputs except for gamma and alpha parameters (no manual per-sample weighting is required)\n\n> Matematical Formulation;\n> \n![image.png](attachment:c091c318-ca2f-4767-a9cc-19ec552700e2.png)","metadata":{},"attachments":{"c091c318-ca2f-4767-a9cc-19ec552700e2.png":{"image/png":"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vE2Z3maz5ebmJqZlY9npcDiysrJat27dqVOn0tLSeoldu91eVlZWUVFRUlKSnZ3tcDhi1ZLw9XS4G+EjCIAACIAACCSXwC3TeTabLSsry2KxdO7ceXTt0a1bN6vVmpub63Q6e/Xq5XA4MjIy7jQ8MjIyLBYLSwcKKY0aNWrp0qWDBg3Kz8+vl1jJy8srLy9fvHjx9OnTi4qKGi80xQYncGKz2TIyMhRFqaioaNeuXQIlxMqSmZl53333vfTSS08//XS7du3qJSKtVqvT6Zw7d+78+fM7deqUlZUVq5aErye336M0EAABEAABEEgHArdG5+Xm5hYWFvbv33/u3LkbNmw4ePDgvn371q1bN2vWrIEDB3q93rffftvhcEyePHn+/Plz5syZOXOmx+OZP3/+C/8+nnvuuTlz5owfP75r166kSEjSDRw4cN++fRs3buzSpUsCUaWCgoKXXnrp6NGjkyZNKigoqJfWSVjBxJ/RZrO1adNm5syZr7766po1a6ZOnZqAj1Gry83Nveuuu5YvX7537163211fiWy32wsKCp555pkvv/xyyZIl7dq1a0hENqqF6XA3wkcQAAEQAAEQSC6BW6DzLBZLq1atJkyYsG/fvuvXr3/xxReLFy9+5ZVX3nnnnV27dn3++efhcHjHjh0Oh+P111/fvHlzTU3N//7v/169enXHjh2bNm365JNPPvvss1Ao9Pe//z0cDk+bNo2jRx07dty0adPRo0fvv//+xOZe7XZ7aWnphg0bDh06NGLECEVR6hsRjKpRknXRarXeddddq1evvnTp0t/+9rdVq1YlMDetN8ZutyuKsmDBgm+++Wb+/PklJSVilFSfPuoVi8VSWlr68ssvHzly5LnnnnM4HMlFl9x+j9JAAARAAARAIB0INLXOI0kxZcqUEydOXL9+fdmyZffcc8/vf//7Fi1a5OTkuFyuY8eORSKRzz77TFGUO++802w2V1ZWRiKR1atXt23b9r/+679+97vfZWRkqKq6du3as2fPPvfcc5mZmXa7vaioaMaMGRcvXnz99detVmvCIiM3N3fMmDEnT5788MMPO3TokPS4VFSRFP9FUmDLli374Ycfli9fnhSdl5ubO2TIkGAwuH379j59+mRmZsZvj5gyIyOjf//+O3bs2LNnz+DBg7Ozs8VPG3ieDncjfAQBEAABEACB5BJoap2XlZU1bNiwvXv3/uUvf/nggw86dOiQmZlJk482my0/P3/69OlXr14lnZeXl5eZmbl169ZIJLJu3brOnTvn5OSUlZV16tTJZrMNHTo0GAwuXry4ZcuWNputffv2gUDg9OnTgwcPFmczaQMpLbaz2WyW2sNYBZaWllZWVp49e3bEiBGJxQUbqGkMsttstrKysrfeequmpkbSebS6kfZn6B0kDhaLxWazcUpKlpWVtWjRogsXLrz44outW7fm2WrCRaKZ1j5S9ljmWa3WsrKyRYsWnT9/fuHChTk5ObFSJnA9uf0epYEACIAACIBAOhBoUp1nt9utVuurr75aU1NTXV395JNPtmjRQhzybTZbeXn5kSNHtm/fTpGqrKws1nkVFRUtWrQYMWLE22+//eCDD953333r1q178803W7Zs6XA4+vfvf+7cuUAgIMoLKrCioqKsrMxms5WWlnbu3Lljx46FhYWsZkQD6DwrK8vr9V66dOm1114rLy83SKnP29hXSOe9/fbbos6z2Wx2u728vLxHjx49e/bs0KGDoihsNn3atm3brl27du7cuaysrG3btr169erWrRvtqy0tLd2yZcvJkycHDx6ckZHBLrRq1apz587t27en5XedOnWiHbUGO1TuvPPORx555PTp05s3b7777rvZBi4z4ZN0uBvhIwiAAAiAAAgkl0CT6jyLxdK7d+/PPvvsl19++eqrr1wuFy+to+HfZrO1atVq5cqVH374oajzfv75Z7/f37Nnz7y8vJkzZ3711VfTp09v1arVM888M3369IyMjLKyshdeeOHKlStvvfUWKwmbzeZ0OhcuXLhx48ZZs2b169dvypQpH3744YoVKx555BGDHbUWi2XKlCnnz5//5JNP7r333qhTtxwapAChwV99aI0tTOBEr/NsNltJSUn//v1fe+21ysrKQCDw9ttvjxw5sri42FZ75Ofnq6q6cOHCjz/+2O/3z5s3b8GCBV999dWBAwdGjRplt9sffPDB48eP79ixo0+fPqSSrVZrmzZtpkyZsnHjxldffXXgwIFjx45dsWLFunXrpk6d2rZt21iWZ2dnDx06dP/+/UeOHBk1apSouWNlifN6cvs9SgMBEAABEACBdCDQpDovJydnzJgxBw8e/Nvf/rZjx46oS7jy8/O7d++uqioN/xTP++mnnz7//PNFixa99NJLe/bsOXPmzLRp0+68887s2sNqtbZv337FihVXrlx5/vnnWTfYbLYlS5Z8/vnnVVVVly5d+vbbbz///PP3339/3759p0+fnjFjBr0Q2G63U8SLM1qtVpfLdeLEib179/bq1UsvVhRFadu27b333ntfXUfXrl3/qVxjST2aFDb+y1bRiV7nKYoybdq006dP79+//5lnnpk6deru3bvPnDkzZ86cwsLC3NzcYcOGHTp06OLFi+++++6qVau+//77K1eubNiw4dSpU1OmTMnLy3v22WfPnz+/fv16ErU0Rfvkk0/u2bNn7969V65cOXPmzOHDh1esWPHpp59ev3594cKFBQUFZLaELicnR1XVrVu3njp1auLEiZKOl3yp17/pcDfCRxAAARAAARBILoEm1XnZ2dlPPfVUVVUV6bwhQ4ZEXapPK8lIBJDO+/HHH69fv/7tt9+eOnXq+vXr586dmzp1Kk3XkuBwOp2ffPLJpUuXpk6dynqod+/eu3fvfu655zZs2HDjxo0tW7b06NHjd7/73eTJk69du1ZZWdm5c2eKIJaXlxcVFbHssNlsffr0+fLLL48fP96/f3/JSIp1zZkz5/Tp0+fPnz8X+6iurj569OjYsWOj7mxwOBxFRUXFhkdhYaG000LSeQ6HY8iQIcePHz937pzL5bLZbH/4wx9Gjx595MiRU6dOPf744+Xl5cuXL79x48ayZcv+8z//s6SkZO/evd99990LL7wwaNAgu92elZW1YMGCy5cvL1++/J577qGXVN93330rVqxYv379vHnzrl69WlVVNXr06KysrIceeuj8+fPHjh1r27at3W5v1apVeXk5NQHRy83N7dy588qVKy9cuDBnzpyojjPnep0kt9+jNBAAARAAARBIBwJNqvNycnIeeOCB/fv3//rrrzt37oyq8xwOR0lJSatWrUgE8Pq8NWvWOJ3O//iP/5g2bdrBgwdnzJjRokWLDh06jBkzpkuXLuXl5Zs2bQqHw08++SRltFqto0aN+uijj8aPH79t27arV6/OmzevqKiosLDwhRdeqKmp2bt374ABA0pLS71e77Fjx8aMGcNRN5vNpqrql19+eerUqYEDB0o6Ly8vjyJe9DMeBn8zMzOzsrKirlFzOBx33333tGnTno19zJ49+6mnnurUqZP4lhNJ5+Xl5b3xxhs//PDDnj17OnXqlFt79OnTZ+vWrT///PPixYsHDRq0adOmmpqapUuX3nnnnW3btt23b99PP/1Eezjsdnt2dvaf/vSny5cvv/nmm06n02Kx5OTk3H///cuWLXv99dcXL15cU1OzatWqFi1aFBYWjhs3LhwOnzt3bvTo0VardcmSJUeOHOnXrx+HPEnnrVq1KhwOz58/HzovHR4i8BEEQAAEQCBlCTSpzrNarV26dNm4cePNmzcPHTpEISIxqEMiZtWqVZ9++qm4Po/3295xxx1PPvnktm3bpk2b9vvf//7hhx8+cOCA2+1u3bq1pPPy8vLopyMeeeSR48ePnzp16oEHHmjRokXXrl1Xrlz5008/UTyvQ4cOn3322dGjR1VV1eu8CxcuRBWjeXl5DocjP75D3PxLztrt9uLi4vHjx+/bty8Y+zh48OBnn3328MMPi7Ofep23cePGSCRSWVnZsWNHisbRzOkvv/zy8ccfjxo1yuv1fv/99x9//LGiKB06dPjyyy8vX7789NNP5+fn5+XliTqvQ4cOpCntdntGRkbPnj23b99+5cqVF154ISsrq7i42Ov13rhx49ixY+3bt8/Pz9+5c+eBAwd69uwp6byVK1deu3Zt0aJF4q4OsaETOE/ZWwiGgQAIgAAIgEDKEmhSnZeXl9eyZcvnnnvu8uXLV69enTp1qqQD6PceKisrly9fTvKI43n0XhX6DVzaA1FeXr5w4cKdO3cOGjSobdu2pPOeeuopUUNkZWVRddu3b1dVlbbr7t+//8cff1y8eLHZbO7Ro0coFNq8ebPFYmFBRvG8YDBYVVWln7clkdepUye32z158uRJsY8pU6aMGzeuoqJCDMixebQukLZKGPxl9UkZ9TpvzZo1P//8844dOyjyl5ubSzrv5s2b69atu/vuu/v27XvkyJGrV6/u2rVr3759ly9fXrp0KZvBOu+tt95inZeXl5eVlTV8+PATJ06EQqFHH300Ozu7rKzsk08+iUQin376aVFR0YMPPnjixIkNGzZ07tyZHaR43urVqy9cuDBr1izE81L2zodhIAACIAAC6UCgqXVebm5u7969Kysrb968+c9Amqii7HZ7YWHhY489dvjw4WnTpsXSeSRQsrOzVVX99NNPt2/ffu+997Zt23b16tVXrlyZP38+K5i8vLyMjIzly5d///337777bqdOnf7whz9MmDDh0qVLhw4dev7555cuXUoL/r755ptt27YNGzaM8lqt1sGDB3/99df00xocrKJPKRo3atSoFStWrDE81q5d+/7770fdbiIaWa9zSec5HI4FCxZcv37966+/7tKlS25ubk5OzuDBg3ft2vX9998///zzpaWl8+fP37Vr17hx48aPH+92u/v27SvWmJOTM2fOnOrq6g0bNvDmYpvNVlBQMGPGjKtXr+7cubNnz552u71///4nT568dOnS008/vW7duqqqqmvXrp08efLzzz/v27cvUcrNze3evfvGjRvPnz8/c+ZM6Lx0eIjARxAAARAAgZQl0NQ6Ly8vLycnZ+zYsQcOHPj5558/+eSTfv36tWzZkt5dMmTIkJ07d65YsYJEXm5ursViCQQCNG/bsWPHf+q2nNqjX79+69evv3bt2nvvvXfHHXe0bdv2jTfeuH79+pIlS1jEWK3WHj167Ny5MxKJvP/+++3bt+/WrduWLVuuXLnypz/9yWq13nPPPcuXLz979uzUqVPz8/N5x4PFYnn44YdPnjwZCAS6d+8e9b0qiqIUxndwsWxYQ06sVmtxcfEbb7xRU1PzzjvvWK3WioqK3bt3X7t2bc6cOcXFxf/v//2/yZMnnzt3bt++fUOGDCksLJw/f351dfX27duXL1++YsWKZcuWTZ06tby8nF6Dl5ubO3HixLNnz27fvr13794k1ywWS6dOnd59991IJLJ79+6ePXsWFha+8847NTU1a9euLSws/KcLq1at+vbbbx9//PHS0lL2KDs7+/7779+2bVtVVdVjjz2mX9rIKet7krK3EAwDARAAARAAgZQlcAt0Hs1XDhgwYMOGDTU1NZcuXdqxY8eqVau2bdsWCoU++OCDNm3aUJpt27ZdunTpl19++cc//nHz5s2rV69evHgxHA5fu3btp59++p//+R+afr3jjjuKi4snTZpUXV394Ycf8lt8LRbLo48+evz48evXr1+8ePHrr78+c+bMiRMnZs2aVVBQkJOT07Vr161bt3799df9+vWjGWESH7m5uXPnzj1//jxvTYgqSozfh8KfRs2b2EWLxdK5c+eqqqqbN2/+/e9/j0QiVVVV/3wFzNChQzdv3nzhwoXDhw8fOHAgHA5/9tlnw4YNo53Lw4YNO3r06K+//vpL7fHXv/71hx9+OHny5LRp0woLCy0WS9++fffv33/w4MEBAwbQWsDs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pk6det999zkcjsLCwjZt2ki+cL3U2QoKCpKra8mk7t27P/HEE7169crNzeUa4znJzc0dPHjwY489VlFRQV09nlwJpEnwpkc2EAABEACBtCGQZJ3ncDhKSkra1h5tag86F/+WlZXl5+fT+N22bVtO1qZNm1atWomjvjjyWSyWadOmffXVV6+88spdd91VX51ntVoXLVp06NChiRMnNurQK9rc9OcFBQWvvPJKVVXVhAkTiouLbTYbO1tYWFhSUpJAKDTpXlit1nbt2r388svHjx+fPn06l2+z2QYOHPjFF19cv3795s2bBw4c6NOnz5gxY9atW/fEE09kZmZySjpxOBzFxcXt2rV77LHHpkyZUl5enqwQpsVi6du376ZNmyorKwcPHpydnS1Vbfxvdnb22LFj9+7d+8EHH9x3330Wi8U4fcKfps1jCo6CAAiAAAgkSCCZOs9ms7Vt23bZsmU//fTTzZs3f/31119++eVn4fjLX/7yj3/849SpU4MHD54wYUI4HKZkv/7661/+8pcrV65s2LAhKytLP+zl5uY+9NBDBw8eXLt27b333puTk6NPY3zFZrOVlZWtWLHiq6++Gjt2bH1HbuPCU+RTRVGmT59+9uzZhQsXlpSU2Gw2h8ORX3u0bt36+eefX758+aBBgxKgl3QHSeq9//77x44de/DBB0ncWyyW9evXV1ZWDhgwYPz48fv27XvxxRfffPPNJUuW3HvvvVJQzWazlZaWvvrqqzU1NX/9618vXrz4yCOPJDDHqnfNZrO1a9du1apVhw4deuihhzIyMvRp6rzSsmXLiRMnHj58eMmSJW3atKnX15I6C+cECd70yAYCIAACIJA2BJKp82j4sdvtRUVFixcvrqmpCYVCTqeTJtccDseECROOHj165syZsWPHZmRk5OTkTJw48caNGxcvXvR4PJmZmVGDefbaY+3atcePHx82bFhUIcgjn8FJdnb26NGjv/zyy48//rh3796pIHcMrE3gozZt2nz55Zf79+8vKyuz2WxWq/W+++5buHDhjh07zp8/f/PmzT179owYMSJFNK7dbr/33nurqqoqKyup3Tt37rx48eJ77rknLy8vIyNj7ty5n3zyydatW8eMGaMP5hEfh8OhquqJEyfOnz8/duzYpOi8rKysZ555JhQKvf76606nM7FonNVqLS8vf/fdd48cOTJ+/PhY9ifQymKWtHlMwVEQAAEQAIEECTSWznvttddqamqOHz/eqlUrnj3Mzs5+9tlnv/766/Hjx7ds2TIjI+OJJ564ceNGOByeO3durLEwNzfX7XafPHly3bp1Xbt2leI64rBnfE4hPZ/Pd/bs2alTp7Zs2dI4fTP61G63FxQUvPDCC5cuXVq0aBGtZrNard26dVu0aNE777zz0UcfhcPh/fv3p47Oo1V6y5cvr66unjZtGk258rRydnb2U089FQwG165d27Nnz1iinL5UHD169Ny5c0nReVartVOnTlu2bDl27NioUaMaookzMzPHjRv3zTffbNy4sUuXLonpReNOmOBNj2wgAAIgAAJpQ6CJdF5BQcHAgQPbtGkzYsSIzz///LXXXmvfvv0dd9zxxBNPfP/99ydPnpwwYUKsMTUjI+Pdd9+9cOHCrFmzSktLSTXm5eXZbDaLxWK1WingZ6k9+NOoA2RmZubUqVNPnTq1Zs2aTp06NcbQG7XeOC/a7XbygpyKMxetwCsqKtq2bdvp06cfeOABVkuKohQVFVkslueee+7KlSuNqvOsVis1BzeNxWKJGqAlv0iiTZs27dKlSytXrpSW1mVnZ48bN2737t2TJk0y2G9rt9sLCwuPHDki6TzqG7m1h75LEOfc3FzibLFYcnJyqDPk5OSMHz/+xIkTH330UY8ePVhf0kZgi8VCpYnOxmqmnJyc+++/f9u2bUeOHHn00UcTjkPHKj8vLy9tHlNwFARAAARAIEECTaHzLBZLr169Nm7cOHny5D59+rz11lsLFizo0KGDqPPcbndUnWez2SoqKnbt2nX8+PEBAwZwMM9qtd5///0vv/zylClTWrVq1a5du3nz5r322mvGq+azsrJGjx594MCB/fv3jxw5MmqNBsNq431kt9tzc3M7d+78/PPPv/XWW5MnT6YFdqRI6pR9iqIMGjToxIkTu3fvLi0tFdWV3W6/8847PR7P1atXG0/n2Wy2Rx55ZPHixWPGjMnNze3Xr9+iRYvmz59fUVFhsDTNbrffddddoVDo0KFDpaWlIt6srKypU6f6/f7hw4cbNFNUnZeRkdGzZ88FCxZs2rTJ5/MNHTqUVBoJYrvdXlFRMW/evKVLl86aNatTp06LFy/eunWrx+MpKSnJyMhYtGjRhQsXXn311fLycjI+NzfX6XTOnDlzwYIFvXr1slqtjz/++BtvvDFp0iRFUUSzxXOLxdKhQ4d33nnnwoULzz33XGPEjxO86ZENBEAABEAgbQg0rs47duyYzWb73e9+N3Xq1Kqqqjlz5rRt27asrKx169b5+fk0b0vxvFg6z2q1ulyukydP7ty5s1u3bqTzsrKyBg8evG7duq9rjz179uzYsWPXrl1ffPFFVVXVjBkzYmmLnJycvn37btu2LRQKRd3CmZeXZ7FYWrZseWddR8uWLXNycqQolDjMx39us9lat27t8/lOnjz5+eefb9q0KRQK7dy58/7772/fvv2kSZNGjx7N09/6YknrTJky5erVq6tXr9avUWvZsmWj6rz8/PyHH3543759X3zxxYkTJz799NMvv/yysrLy6NGjO3fuHDp0KKtzyXiaSf+n5j5z5szw4cNFzXTnnXe+9NJLH3744f33389BNSk76TYpnpeTkzNnzpyvv/66srLypZdeWrduXVVV1dtvv925c+esrKxWrVpNnDjx4MGDR48e3bx585EjR06ePBkIBC5fvrx///7y8nKz2bx69eqLFy8+/PDDZLbFYnE6nQsWLDh48GAwGDxy5MjmzZuDweCnn34aCoVWrlxZVFSkN4yuZGVlzZw58/Lly0uWLEE8L20eqnAUBEAABFKIQOPqvBs3bnzzzTenTp26VnvMnj27VatWPPlloPMojkV/Z8yYcfHixc2bN9PiPJvN1qpVq4ULF3700Uc+n+/cuXMXLlx46aWXOnToMGzYsHPnzu3fv79bt24OhyM3N5fUGMe3LBZLp06d1qxZ8+233z7zzDP6EAtJlr179x4zPL755puDBw/OmTMn1mZMi8VCk4YGf2kG0GazOZ1Ov99P05edO3e+++67ly5dev369WXLlo0fP76ysnLy5Mm05I48ys3NFfUlvTPv1Vdf/e67795+++2G6Lz4zWZlY7fb//kC6jVr1mzZsmX58uU1NTVVVVVPPfXUXXfd5fV6L168uHLlyi5duuTk5GRnZ2dkZIhz5dSU69evv3LlyoQJE3i62WaztW/f/sMPP/T5fMYrMsV43iOPPGKxWCZNmnTy5MkvvvhixIgRxcXF3bp1W7lyJcXniouLu3fv/sUXX5w/f3727NkVFRUvv/zyDz/8sG/fvsmTJ9Pyvs6dO+/cufPs2bO84ycrK2vUqFGVlZUbNmyorKz86aefNm3a1K9fv/vuu6+ysvLy5cvTp08vKCiwWq0tW7bMysrizpaXl9eyZcvx48d/++2369evv/vuu2N9/WCY9T1JoQcJTAEBEAABEEhJAo2r886cOTNq1KiRI0d+8MEHZ8+enT17Nm0FpfHMQOcVFBT06tWL1pbNnj374sWL69atq6ioICHSvXv3NWvWLF++/MUXX7x69erOnTt79+6dnZ2tqurZs2erq6sff/zxvLy8kSNHrlq16o9//GNJSQmNvhaLpWPHjitWrKiurvZ4PHqd53A4ysvLBw4cONTwGDZs2ODBg2NNSlqt1j59+gwfPnxEjGPkyJGDBw/u2LFjbm5umzZtXnrppe+++27fvn3l5eXk4Pjx4y9evHj48OF169bt2LFj2LBhFGUcPXr08uXLpcVepPNef/31a9euvfLKKwnrPKvVqqpqnWZLesVut5eWln711Vcvvvjixo0ba2pqVqxY0b59+xYtWng8nitXrgSDwYEDBxYVFT3zzDNvv/32wIEDObxHedesWXPt2rWZM2ey5bm5ucOHD9+9e/fUqVONf8JE1HkPP/xwRUXFli1bampqlixZ0r59++zs7MzMzOnTp1+5cuXAgQNDhw7t16/fpUuXQqGQy+Wy2WzTp0//7rvvzpw543K5iouLrVZr79699+7dGwqFhgwZQvPFGRkZEydO3Lp1q9frDQaD1dXVs2bNys7OLiwsXL9+/c8///zee+8VFBR07drV5/N5PJ527dqxnsvIyHjqqafOnj27ZcuW7t27ixq3vpIuavqUfKTAKBAAARAAgRQi0Lg679ixYzQ/O2bMmIMHD86bN69169a8Lj6WzlMUZdSoUZs2bRo+fLjNZps1a1Z1dfXatWtp54Tdbm/VqlW3bt1Gjhz53nvvfffdd8uWLcvNzS0qKpowYcLly5fPnTv36KOP2u32RYsWVVdXP/3007TWjeZkSeddvXr1hRdeuPPOO/XDJwVm6pq2/dfnseZtu3fv/uGHH9I88hfRjj179mzfvn3mzJl/+MMfKioqDh8+XFNT8+abb5KwsNvto0ePPnny5NmzZ7/55ps///nPd999d3Z2duvWrd96663jx49PnjxZjCOSzluyZMm1a9e8Xi+rJXYtnnlbh8PRs2fP9evXR7P3/79GZk+bNk3aGa0oyoABA/r163fgwIErV67MmDGjpKTEbDbTu3V2796tqmqPHj22bt36Twk1ZMgQnoclnbd27dobN24sXLiQLbfb7e3ataNpa+4t7I54Iuq8MWPGjB49+tixY999953H46FvFPQeu3A4fOnSpenTp3fv3v306dPnzp178sknaVPOjRs3qqqqOnToQGv4evXqtWfPnuPHj7POs1qtTqdTVdWnn366urr6wIED9FFRUdH+/ft//PHHpUuXKooyefLkb7/99s9//nP79u0lnXf+/Pldu3b169ePBa7oQkPOU+hBAlNAAARAAARSkkDj6jx6rwq9S2zWrFmDBg0Sf+cqqs6jV4TQEisK4M2ePbu6ulrcIUt7C/r27fvFF19cvHhx9uzZd9xxR9u2/x97Zx4sSVWm/fxzIj5lJrGh977dnWwDGDaaIIqK4JKMDLYwMDmKyCpEDS5M4CAUgyMMSyeizdpWAw3Ili5siuWGglgwQjtotezxRUM+AAAgAElEQVRIKjSNypgxMRETYcT8lR99H3x852RVVt61q+59Kogmb+ZZ3vd3tifPOZn5piuvvPKVV1555JFH9t5775133vnuu+9+7LHHDjrooKVLl3I+79XpqBtuuAFv7CvP561atWrPPff8m7/5m7WDfkccccSBBx7IEd2O1mvWrDn66KOP7f/76Ec/+pGPfOSQQw5ZvXr1ySef/MILLzz99NONRgOaZuXKlWvXrn31vWu///3vf/KTn6xdu3blypU777zzIYcccu+99/7whz884ogjFixYwKVb6Lwrr7xy69at69ato1qiSTV13n777XfMMcf0t/pYmP3ud7/bmZfCQyTHHHPMM8880+12DznkkLGxsf333/+ee+7J8/wrX/nKvvvue/TRR2/evPkrX/nK3nvvzecqOJ+3bdu2z372s9bysbGxpUuX9sRLv5z9eR/96EdPPPHEbrf78ssv445ixYoVCxcu/MQnPpFl2W9+85t//ud/fuMb33j99df/7ne/+9GPfnThhRc++OCDL7zwwuc//3l8iBYTsQ888MDPf/5z+0DP0qVL995774suuujll19O0zQY/x111FHPPvvs1q1bzzzzzAULFlxxxRW8waDZms8byk5PRomACIjAPCIwszrvscce23PPPSFf3vSmNzk71hcuXHjyySdv27Zty5YtfA5jxfjvhhtu+OlPf7r77rsvW7bsU5/61HPPPXfXXXe94x3v4IzIrrvueuyxxz7xxBOPPvroRz7ykV133XXNmjX33XffK6+8cuONN55yyimXXXbZ008//cQTT2zYsOGoo47ac889sdvv7W9/+y233PLcc8+dddZZZZ23evXqgw8++Etf+tLGjRuv7f+77rrrNmzYcNJJJ1GyWPExNja2ZMmSxYN+S5Ys2Xfffc8666yXXnpp8+bN0HOrVq1atmzZ+973vp/+9Kfbtm0799xzV69evffee59++um33XbbE0888fjjj7darbVr19pZsb322uuSSy556aWXrr76aquWYFUdnYeXodQxe/ny5ZSY9DoIgs9//vPbtm2799573/jGNy5cuPCEE074+c9/nmXZ+vXrzz777Hvuuef555/vdDqf//znuYLJ/XkvvvjiJz7xCe7PY7IDD+x83nHHHXfYYYc99NBD//mf/7lu3TrMq73hDW84/fTTX3jhhS1btpx00klvectbNm3adN99911wwQXr1q370pe+dMIJJ7z69QtkhIe7v/e97z311FNHHnkkpy2XLVv27ne/++tf//qLL754ySWXLFiwYK+99rrooot+97vfPfroo5/5zGfWrVu3efPmX/3qV1/72tdOPfVUTlpjf94zzzxz5513zsQr9OZRRyVXRUAEREAEJkVgmnXeypUrFy1atHTp0nXr1v3ud797/PHH3/Wud+26666LFi2yb1NbvXr10qVLX//61x9//PEvv/zy448//vGPf/x1r3vdggUL9txzz0996lOPP/74gw8+iP15J5544hNPPHH//fcfeuih0HljY2O77777v/zLv7z88ss//vGPDzvssIULF3784x9/8cUXN2/efMQRRxxzzDG33Xbbiy+++I1vfOPss89+3/veh3nEZcuWHXLIIXfdddcTTzxx+umn29VPjPSrV69+y1ve8g//8A/HVf4+9rGPffSjHz300EOdmS0kUvPflStXrl69+phjjnnuued+8YtfYJZul112OeCAA9avX//CCy/8+te/PvHEE4844oiDDz547dq1aZo+//zzt91228knn/ze976XWeNFdOecc87WrVvTNLUzpmNjY4sWLfqLv/iLM88884UXXnjggQcOP/zw173udUuWLClrtZpml4PBkdtvv/0Pf/jDV7/6VRTuhg0btm3b9rWvfe3v/u7vTj/99IceeujJJ5/88pe/fPzxx7/tbW/DjBe+Xfad73zn2WefPe644+zztuVcymdWrlwJLf3II488/fTTxxxzzMqVK6+++upXXnnlzjvv3H///V//+tevXr36sssu+/3vf3/77bevWbPmkEMO+e53v/vAAw+ceeaZ559//jnnnHP00Ufvt99+ixYt4lv6vv71r2dZ1mg0MMm3atUqPN+9efPm3/zmN81mc6eddnr729/+wAMPvPTSSxdeeGEURevXr8+y7P777//c5z535JFH8i2PCxcuPOOMM55//vlrr7129913r16DLjs48MykmrwiiYAIiIAIzCMC06nzsIB4/PHHX3755Y8++ugf//jH//7v/7733ntf3Tp20kkncfBbtWrV0qVL165du27duu9973t//OMf/+u//usHP/jBpZdeeuWVV95+++1bt2793//93x/+8Id77rnnihUrDjrooAcffPCxxx573/veh5dTLFu27B3veMdNN930hz/84amnntq0adNFF1308MMPP/TQQyeffPKKFSuWLl160UUXPffcc2ecccayZcuWLFmCddslS5YcddRR999//49//ON+X4aoORu3ePFiKq2B43G/AMuXL99vv/2uv/763/zmN7fffvs555xzwQUX3HbbbXfeeSc27X3rW9+655571q5du3z58i996Uu/+MUvTjnllP/3//6f3Rq4cuXKIAg+9KEPPf300z/4wQ/44AKeWv30pz+9bt26V5XN//zP/2zbtu2OO+645JJLjjvuuJ4zkf3sHHh+v/32e+ihh37/+99v2bLlggsuuOKKK7Zs2XL33Xe/uody2bJlhx566Le+9a0f/ehHhx9++F/+5V9abm9729seffTRhx9++IADDpiQ9MRM3nHHHXf55ZfjE7f33HNPo9H4wAc+cPPNN//yl7/cuHHjWWeddc0112zevPk73/nO3//93y9YsGD//ffftGnTK6+88uyzzz49/vvFL36RpuknPvEJ6ONdd931iiuueP755y+55BI8UYF9e6eeemqWZb/97W+/973vNZvNW2+99amnnrr88ssPPPDApUuXnnbaac8888z69et32223XXfdFZVtbGzsr//6ry+77LJnnnnm3HPPXbBgwUCMEw0wjzoquSoCIiACIjApAtOv80477bSNGzdu2LDhyiuvvOqqqzaO/xqNhn0D3JIlS44++ugNGzZs3LjxqvFfq9W67rrrNm3adMMNN2zYsOGKK64444wzdtttt5UrVy5ZsgQrrSeffDJEzJIlS9auXfvDH/7whRdeuPfee2+77bY77rjj6quv/shHPgJJ9+o3te66664tW7a85z3vWbNmzV577QUNscsuu/zjP/7jli1bbr755gMPPNAKjokOsdMSfuXKlbvtttuhhx568cUX3zn+u/XWW9evX4/tfTfccMPdd9+dJMlb3/rWKIq+853v3H///R/+8If32GOP8suQ99577wceeGDLli0HH3wwnB0bG3vLW95y9tlnX3vtteB8zTXXXHvttV/+8pdPOeWUadR5eG7mmfHfdddd941vfOOOO+5IkiSKIrxb5OSTT968efPNN9/8jne8Y99998UaOoTaySef/Ktf/eq2226DNqpPFbOYp5xyCqvQxo0bzzzzTKy8n3vuubfeeuvdd9/9jW9844tf/OIHP/jBVatWrV69+sgjj7zzzjt/9rOfbdq0acOGDa1W6957733ppZeefvrpY489dvfdd1+8ePE//dM/Pfnkk7fccgv2CaxYsWLNmjWXXnrptm3bHn744Vardffdd996662f+cxn8Hz02NjYVVdd9dxzz5122mlhGO6zzz6YmFy6dOn73//+b37zm5s3bz7xxBP1/rxJdVCKJAIiIAIiMCUC06nzsC9+8eLFbxj/7Tz+w7HzXjEs7S1YsOANb3iDDWb/5KLqkiVLzjrrrKeffvq6665761vfunTp0gULFpxwwglPPvnko48+evzxx69Zs+bd7373ihUruKHqgAMO+I//+I977733oIMOOuuss975zndi/9luu+12xRVX/PKXv/zsZz+Lr6XVFxYzFHLlypVLly5dtGjRqw/eHnbYYfvtt98uu+yCV829+c1vPvjgg8fGxhYsWHDSSSc98sgjN95448c+9rHTTz/dfhoE2HfffffLL7/817/+9XnnnQd9DJcXLlzoFMeCBQsWL14MLTh1pzCbeP7557/88svf//738Y46PCAMzb3rrruec845v/zlLy+88MIPfvCDn/70pw844ICxsbEVK1bsvffeGzZseO655z75yU9Owh6s29K7N7zhDYsWLcJDITvvvPOaNWve//7341mZxYsXL1u27K1vfWur1fr1r3994YUX7rLLLjvvvDNm+K666qrf/va3N9xww6tPaWD28fvf//7DDz981FFHLRn/HXrooXfeeedLL720bt06vHtl33333WWXXbj6/O1vf/tnP/vZ4Ycf/qpGPOaYY/B896JFiyBw0zTFE0VTp+2kMKWmr8giIAIiIALzgMA06zxnHJqWP8fGxt72trd985vffPjhh7EHa8899/y3f/u3bdu2ffe73z3iiCPGxsaWLVvGCaEgCI488sgnn3wSczm333471NLChQuPPvroH/3oR3feeSfetzct5k1XInhzHh/VXLVq1YoVK+DXokWLTj/99Mcee+yWW275whe+sHHjxg984AN8JAUGBEFw+OGHP/roo+12G28JmS7DKtKBVj7wwAPTNH3llVc2bdr06sIoPtHL4thll10uuOCCLVu2tFqtyy677Itf/CLfMPfe9773wQcfbLfb++23X0Uuk7sEetwVildkX3/99b/61a8uueSSvfbaa9GiRXhbzcUXX7x169YNGzbgVSyLFy/+3Oc+9/jjj//rv/7r7rvvvnz58hNOOGHz5s3PPvvsWWedFQSB8yDwihUrHhz/nXfeeV/96lePO+64PfbYY9myZXvvvffll1++efPmT37yk7wDmZwv/WLNgw5KLoqACIiACEyJwAjovFWrVuH5zU6n8+oL5D74wQ+eccYZP/7xj7dt2/bggw+ee+65fH4Tw+Hq1atfnU+69tprv/a1r910003HHXfcXnvttWzZsj322OPyyy9/+OGHP/WpT3ETW78RdKjOL1u27AMf+ECr1brnnnuuvvrqY445hg/b0k5sIzvnnHO63e4555yD72fw6gwdAPXFF1+Mt9bdddddn/nMZ/hWamS6ePHi44477tZbb73jjjsuvfRSKOyxsbE3velNV1xxxc9//vOPf/zjVt3OkKmYdzzqqKNww3DJJZfgaZsvfOELjzzyyLe//e0PfehDmAddvnz5O9/5zlffy/2DH/zgYx/72Kvnb7311izLnnrqqY0bN374wx92FPbY2NjFF1/89a9//fbbbz/jjDPwxZfly5efeuqpP/nJT66//voDDzzQiTJdPk6p6SuyCIiACIjAPCAwGjpv1apVixYtOvvss++///7rr7/+1beHvLqj66abbrrtttsuv/zyww47zNlpNzY2tueeex5xxBFvfOMb8Zm13Xbb7cwzz7z//vsvu+yy/ffff4bG3ekav510Vq9evWTJkjVr1kRR9KY3valicmjlypUbNmzAxGf5BStOslP8E286XLt27Y033njLLbfcdNNNt99++4UXXujsHeTrqfGBE7zLcI899jjhhBP+/d//HSuhU7SkZnRI4be//e1f/OIX77vvvh+P/+67774kSd71rnetWLGCc5ALFy7827/923vuuefuu+++8sorb7zxxptvvvmWW2654YYbTjvttLLIXrFixWGHHYY14rGxseXLl7/nPe9J0/Suu+46/PDDy6/vqWnwwGDzoIOSiyIgAiIgAlMiMDI6b2xsbK+99jrvvPOuuuqqQw455K/+6q92Hf8tWrSo52wQ3paHN1m8urJ2yCGHbNiw4bzzzttvv/3K4/TAAXUYAkBAVL+bY+XKlW9+85uvueaaSy+9dM2aNdWBp8Wp5cuXL1y4EGVR/sArs1ixYoVdQj3wwAOvueaaiy++mK+wZsiZPsA+zgXmV65Cq1ev3mWXXfDBlWOPPfb1r389HFy4cGHPyoPKxnq4aNGiM888c+PGjVEU7brrrpPYelgTwpSaviKLgAiIgAjMAwIjo/PwtAFe5MsBteZwiCcSFi9evGTJklmQPvWtmomQY2Nj8JSzUzORyxTThJEz8QjqFA1j9NWrVy9fvhzvfZyoUMNjRmX5yMSn62AedFByUQREQAREYEoERknnTdfoqHREYG4QmFLTV2QREAEREIF5QEA6b26M+PJiPhKYBx2UXBQBERABEZgSAem8+agP5PPcIDClpq/IIiACIiAC84CAdN7cGPHlxXwkMA86KLkoAiIgAiIwJQLSefNRH8jnuUFgSk1fkUVABERABOYBAem8uTHiy4v5SGAedFByUQREQAREYEoEpPPmoz6Qz3ODwJSaviKLgAiIgAjMAwLSeXNjxJcX85HAPOig5KIIiIAIiMCUCEjnzUd9IJ/nBoEpNX1FFgEREAERmAcEpPPmxogvL+YjgXnQQclFERABERCBKRGQzpuP+kA+zw0CU2r6iiwCIiACIjAPCEjnzY0RX17MRwLzoIOSiyIgAiIgAlMiIJ03H/WBfJ4bBKbU9BVZBERABERgHhCQzpsbI768mI8E5kEHJRdFQAREQASmREA6bz7qA/k8NwhMqekrsgiIgAiIwDwgIJ03N0Z8eTEfCcyDDkouioAIiIAITImAdN581AfyeW4QmFLTV2QREAEREIF5QEA6b26M+PJiPhKYBx2U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AREQAREQAREQgZoEpPNqglIwERABERABERABERgxAtJ5I1ZgMlcEREAEREAEREAEahKQzqsJSsFEQAREQAREQAREYMQISOeNWIHJXBEQAREQAREQARGoSUA6ryYoBRMBERABERABERCBESMgnTdiBSZzRUAEREAEREAERKAmAem8mqAUTAREQAREQAREQARGjIB03ogVmMwVAREQAREQAREQgZoEpPNqglIwERABERABERABERgxAtJ5I1ZgMlcEREAEREAEREAEahKQzqsJSsFEQAREQAREQAREYMQISOeNWIHJXBEQAREQAREQARGoSUA6ryYoBRMBERABERABERCBESMgnTdiBSZzRUAEREAEREAERKAmAem8mqAUTAREQAREQAREQARGjIB03ogVmMwVAREQAREQAREQgZoEpPNqglIwERABERABERABERgxAtJ5I1ZgMlcEREAEREAEREAEahKQzqsJSsFEQAREQAREQAREYMQISOeNWIHJXBEQAREQAREQARGoSUA6ryYoBRMBERABERABERCBESNQW+etX18cdFDhedv/22mnIo6Lxx4bal+3bt1u5/LlVUY+9th2dw46qCqMromACIiACIiACIjAaBKop/Pi+DWFB51Htbdp0/B6feaZ221ev36AhXDtjjsGBNNlERABERABERABERg1AjV0HgST5xXnn/+ad489Vuyzz3YVVT1btmNZ7LTTdgu3bh1gxaZN24PF8WvB7ruvOOyw4swzB8TSZREQAREQAREQAREYegI1dN7y5f9HCcGl++7bvtx50EF/Xr09//zXxB/0H6XSHXdsj37QQcWmTX9Wh5s2FVBUmBo89dTXQE0ocFFsl55QnE6mUG9ckF2/fvsarudt13D4YRpvp5222w8bcJ6i9r77Xgup/4mACIiACIiACIjAaBIYpPO2bn1NBlUv0UKf7bRTceqp2/+DqMJiKC9B7eHSTju9tnmOKm0qgcuZQq5Ba27dul0LHnbYa47ccceftR2cwr5DGLBp03bD9tln8ETgaJa3rBYBERABERABEZg/BAbpPKg0zyu4g+3UU1+bycN8Hua98JQGN8NBOUFmMQWE5PwZJ/wg9SYRuCJTGMCFZpQn5u3uuOM1zce1Wszt0Z75U/jyVAREQAREQAREYE4TGKTzyvN5fOqWsgmAzj9/u36yVx3pRo5OxJ6isE5grNv2zBRpUpsiNeSLqb7ly/88Y2cn/5ivDkRABERABERABERgxAkM0nlFsf1hC/ukAhym/oOWwqroPvts3zB3xx2v7ZmbaZ1XkWmFzoM7VgJK5414JZb5IiACIiACIiACPQnU0HmQQc7zthBSfN7WmaLruRTL/J3Ak57Pc9KxmVboPM/bvoPQ/qAXoUr1vK0lo2MREAEREAEREIFRJlBD5xXF9teOQFTZf3faafszs/hhkmyffba/kWT58teew5jp+byKTE89dbvBMIDFA+Ptii0uWVFIUUvXGF0HIiACIiACIiACIjBSBOrpvKLY/sJh6KGe38O4777X1mp32mm7urIroXwOg1ycebhJz+dVZLp+/Xadx7eoIGsnX8cevGlPz9sSiw5EQAREQAREQARGnEBtnTdafmL74E47/dlqKL999vnzGRxBhvJNe+5l/S0CIiACIiACIiACo0pgjuo8rjXztX89nyZhML4RZlTLUXaLgAiIgAiIgAiIgEtg7uo8vKgPE3V8aZ+j57Zufe11zS4W/S0CIiACIiACIiACI09g7uq8otj+mIh9f0q5sLZu3R7gscfKV3RGBERABERABERABEadwJzWeaNeOLJfBERABERABERABKZAQDpvCvAUVQREQAREQAREQASGmIB03hAXjkwTAREQAREQAREQgSkQkM6bAjxFFQEREAEREAEREIEhJiCdN8SFI9NEQAREQAREQAREYAoEpPOmAE9RRUAEREAEREAERGCICQzQeWEYep7XaDToQrvd9sZ/7XabJ5vNpud5YRgWRRFFked5nU6HV4fkoNVqBUHgeV4QBEmS1LGq2+2CgOcNAFUntZ5hgKtsT5IknudFUdQz1lCdRH0YwhKfNKWhrcPVHnU6HZRFdbA6V6cxqTrZzaswI9S051W5yFkRmKsEBsiXVqsFYUT/Iek8z2s2mzwJMdRqtYZW56VpiiGQ/5alFd3hAfwKw7BOYMaa0IF03oRwVQSe9PBZjjijOq+cXYVTE7o0jeJsGpOakAuzE3jH3pnMXAWYHXrKRQREYLQIDNB53W4XfWKWZXAMU2JW/GVZhjDdbndodR7MhlyDePV9f2BRzcJ4IJ03sBRqBpj08FmOKJ0nnVez1k0iWLm+TSIRRREBERCBmgQG6LyiKKCQ0jQtigKSLhz/eZ4H8YepsiAIkCXG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XCzaQvM5/tooLOh2u42Speaz1upYBERABERABERghAgM1nmQd1g3hKoLgsD3fUwUYSLKEWGO/1YD5XkO4QiRYTfVOYk4oqT6qpOjo2CcpBi4fN6JaC23x0jBnrHHVucxr34HE8rRJoIZ0ziO0zSlI1zw9TzP933MeuKgbJWTNdUhDriGazPVsQiIgAiIgAiIwAgRGKzzsEAJcYaxn5vhuFGPOoOv4UX48rotppcYzJKqVnLO1aIoIFO4BGx3mGGKi0oFwoVLwMyUZvOMI32seoMBnOXiIq9dt+WCb7V5zI7BOPVYJ8c8zx3LuYrNdMAZ/3L92oll19aLooBH2CnIksWTJQPfiWM90rEIiIAIiIAIiMCQEBis87iixycSuHOOood7woIgaDabkFmcRiprF8gpzDlxSs9Rco4oYaZRFEHbYaLRH3+2F4KGFvI5jCiK7LKmA93Jolp11XkOw+q8CvOsGRXKks9hhGHIJ1GwME2VGcdxs9kcf3TEp/tFUZCAPen4C2goMphEjHykGmXHZ2Ws5ToWAREQAREQAREYcgK1dB4lC5zh7BEnzIqiwHtVuCZL9cZnUaGB0jTFjFE0/kN46MVqnYcnWDEFRTmVJAllHF8sAiP5cpYoihx9wyIpn69QXZjxqn6vCg2jDf3Mow3VOeK9KvAaihYPYUDJkR7f58L5vKIoEMtqccdfvsyFeyIppvlcCAqFM4I0WwciIAIiIAIiIALDT6CWzptGNyBrKFYc5TGNGSmpSRCgzmMBTSIRRREBERABERABERgSArOt8zAFFccx3hWCZUH7Ut8h4TLfzODcnud5mr2bb6Uvf0VABERABOYqgdnWeVmWxXGMJUXP8/ByOM0e7fDqxYlVvgJwh5skA0RABERABERABKZIYLZ13hTNVXQREAEREAEREAEREIGaBKTzaoJSMBEQAREQAREQAREYMQLSeSNWYDJXBERABERABERABGoSkM6rCUrBREAEREAEREAERGDECEjnjViByVwREAEREAEREAERqElAOq8mKAUTAREQAREQAREQgREjIJ03YgUmc0VABERABERABESgJgHpvJqgFEwEREAEREAEREAERoyAdN6IFZjMFQEREAEREAEREIGaBKTzaoJSMBEQAREQAREQAREYMQLSeSNWYDJXBERABERABERABGoSkM6rCUrBREAEREAEREAERGDECEjnjViByVwREAEREAEREAERqElAOq8mKAUTAREQAREQAREQgREjIJ03YgUmc0VABERABERABESgJgHpvJqgFEwEREAEREAEREAERoyAdN6IFZjMFQEREAEREAEREIGaBKTzaoJSMBEQAREQAREQAREYMQLSeSNWYDJXBERABERABERABGoSkM6rCUrBREAEREAEREAERGDECEjnjViByVwREAEREAEREAERqElAOq8mKAUTAREQAREQAREQgREjIJ03YgUmc0VABERABERABESgJgHpvJqgFEwEREAEREAEREAERoyAdN6IFZjMFQEREAEREAEREIGaBKTzaoJSMBEQAREQAREQAREYMQKDdV4URV7pF0XRMDgKuzqdzjAY08+GLMviOIapcRx3u91+IdvtdhiGdUL2S2GHn+90OnDB9/1Go5HneT+TkiQJgoDODnkh9vNC50VABERABERgmAlI5w0oHcjcJEkGhOt/mWoGmsb3/Z7qp91uI0AQBL7ve57XL2T/rKZ0pdPpwIBJp5JlGVLgv/3uB5IkQZgwDMkny7JJZ62IIiACIiACIiACZQJ1dV6/Abuc4myegVaoMxXU7XbjOJ6EXJuizkvTlIotz3NomlarVaaEabA4jouiyPMc+TYajXLIGTozdZ3XaDQ8z0NV6Xa7KJ2e85dwlhzw5yRKZ4ZQKFkREAEREAERmBsEpqTzms2m53mQJkVRQJo0m00olWazyamaMAzb7TaQYS4nGf8hQBRF3W6Xq5a+76dpWg6MWS4ExtWyznNWAykyOIHEMyw/yhHY7/s+BQcu8V8rKKmKeBUHjIv0sWJLRCDWUzQjOrPA9F4QBLSzKApHHhVFASbdbjfP80ajwYnAOI7Ls4awOYqidrsN8kEQoFzIB2Y4FjpX6TKthZHIfRLqDX6x0K3LOhYBERABERABEZg0gbo6j0O7lSOcoGq325i4CsMQ8gLKIAiCJEkwzcNVSFzyx3+QVp7nQXZwFa9fYKoTOGyNKYoCKsrJFKuB7Xbb932aZ3khEVylPdAcURRBuwRBYPVlURTdbjfq9XPEChKk+CMWawCO4ZoT0vP+TwG1Wi3P88IwRBSrBSEowzBMkgSZOlqtKAroPHgURRHUled5WZalaco/oyiCWKeRaZr28nW7OmeYoiic4oAZ1VOSURTBcUphm6CORUAE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JiCd986lI99EQAREQAREQARE4HkC0nnPs1NMERABERABERABEXhnAtJ571w68k0EREAEREAEREAEnicgnfc8O8UUAREQAREQAREQgXcmIJ33zqUj30RABERABERABETgeQLSec+zU0wREAEREAEREAEReGcCv6Dz3JfE35nO077xo+eFXShgfBgGbCNhd3h7Ol1FFAEREAEREAEREAESkM4jipcd5BuYcqdRlwZ39sTOS3bPKxdSf4qACIiACIiACIjAowSk8x4ldj983/cxRu4kO45jCIF7zNv4VVVZCQjZZwPoWAREQAREQAREQASeJnBH57W3H603TRNCoILB5sq4erZzMzZ4nue5qqqmaVJKdt52XdcYY9d1TAIH2DQagglfq8feRJjirKqK+4IXNkHPk7ZfXa+qap5nly7+PNvWGntyz/PM/d1zz10GU0rbtnGL9MPkeLLve7sbPc/rQAREQAREQAREQASeIHBH543jGGOE3X3fQwhVVU3ThDNd17Vtm1Li/OO+7xBJ1CsQW3VdT9MEcUaddybyUkohBLyvtizLPM/x9mvbdrn96tsPPjyRNIbWIFJzqQcxNwzDtm3runZdF2NEFFwCgWVZMFBHGvAHzrsN0SFbGcAdANqZPy6w/hQBERABERABERCBiwTu6DyMRUEMTdNU13Xf99B2KaUYI1SOe7HMxoLO4xAgh7sKIg9SyU5oNk1D4QhZGcL/eX496XVd3fwpdaqFhR217RnOrnI8j1frunaS7gmdB7MhhL7vLSimogMREAEREAEREAEReILAHZ2XUoK2Syl1Xdf3/TzP0FhQJ9AlIQQ3MMYRLOg861nTNFVVxRipF+1VHDM6/uQQIP60Nq8nTTkVzA9TydaBpmmsxKQwTSnBgt3vvGmar+s8pL5tm5Oz1isdi4AIiIAIiIAIiMCjBO7rPLx4h9E7TLzGGOd5tgN718UWZRPmQ+1rdtb179N5NpXD46/rPKdKr7+fl+vIQw91UgREQAREQAREQASuELiv8yBTqPYwsNd1HV65Qxp3J0+tK5RBbdvadak2zHWddz1pzNvaccdxHN3QXUrp7rzt3fG8i+ttc3+k82wd0LEIiIAIiIAIiMAXCdzXeZi6tatip2nCule+TGYXQ+ATwXydzs6xwlfqvH3fsaKCdpiZ6zrv0aS5zBbLO/JZV4gtrMPYti1f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Swf4IhRCzvNcXodR1/Vy++GWSW2H0SD8iSUOFEaWBWRrCAH3Xb6tj2W2XN5RGNCC/HWrfZlEOdeWQEHnQbZipg/vz9nknJF8rItC06oKzDhjHYOVKVhwg/wSfiH7zCmXTVDB4K3Nfd9dTWCUfEbe6jzUtH3ft22DsrEKjMcY6LLrMDDiZQMgRQ6LrutqS3bfd65sQBigxvMGluawnsCUJXllPA8DeFhtY1fG2FI4cw/z1xg7R2a5+B1R2MQsWB2LgAiIgAiIgCVwSedhyIFaCoM9XIgAc7wj8j7NZPiZDKgoK1Awc0pFQgUJGWdlDa1R2FVV5db/Qq4xOd7FGZcHUGnuTmk/kJF/WASihxZSShAWnO+zl1JKdCPPtSVQ0Hm4hC+PAEjTNJStzshFnbfvO969g57m5Cy+R4O3xNq2BZ8rOo8GKbAKNYGInPNW583zzJIdx9FecnlMKfG7KhygpRtMiyIJuWPJuu/j4KkAa2OBCGOTXxzP4+4mbdvyuYjQUJpnFQ8VADTwhRdUNihUV3ttfnUsAiIgAiIgAiBwSecJ1iGBpmmc2D0MppP/TQJOy/43ISjXIiACIiACv0tAOu8Z/vxYWj7I94w5xfmLBKTz/mKpKk8iIAIi8GEEpPOeKTDMANp35J+xojh/moB03p8uXmVOBERABD6DgHTeZ5STvBQBERABERABERCBRwlI5z1KTOFFQAREQAREQARE4DMISOd9RjnJSxEQAREQAREQARF4lIB03qPEFF4EREAEREAEREAEPoOAdN5nlJO8FAEREAEREAEREIFHCUjnPUpM4UVABERABERABETgMwhI531GOclLERABERABERABEXiUgHTeo8QUXgREQAREQAREQAQ+g4B03meUk7wUAREQAREQAREQgUcJSOc9SkzhRUAEREAEREAEROAzCEjnfUY5yUsREAEREAEREAEReJSAdN6jxBReBERABERABERABD6DgHTeZ5STvBQBERABERABERCBRwlI5z1KTOFFQAREQAREQARE4DMISOd9RjnJSxEQAREQAREQARF4lIB03qPEFF4EREAEREAEREAEPoOAdN5nlJO8FAEREAEREAEREIFHCfw/kk+ts4Ciw5oAAAAASUVORK5CYII="}}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\n'''\n    how torch.sigmoid works:\n    y_true = torch.tensor([0,1,0,1,1,1])\n    torch.sigmoid(y_true)\n    tensor([0.5000, 0.7311, 0.5000, 0.7311, 0.7311, 0.7311])\n'''","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.622235Z","iopub.execute_input":"2025-02-07T07:08:10.622490Z","iopub.status.idle":"2025-02-07T07:08:10.628076Z","shell.execute_reply.started":"2025-02-07T07:08:10.622466Z","shell.execute_reply":"2025-02-07T07:08:10.627156Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class FocalLoss(nn.Module):\n  \n    def __init__ (self,alpha=0.25, gamma=2.0, reduction='mean'):\n        \"\"\"\n        Args:\n            label (Tensor): y  --> torch.Size([batch_size, 28])\n            pred (Tensor): output --> torch.Size([batch_size, 28])\n        Returns:\n            Tensor\n        \"\"\"\n        super(FocalLoss, self).__init__()\n        self.alpha = alpha\n        self.gamma = gamma\n        self.reduction = reduction\n\n    def forward(self, preds, labels):\n            \n        labels = labels.float()\n        preds = preds.float()\n    \n        #Convert the labels to probabilities with sigmoid function\n        probs = torch.sigmoid(preds)\n        #If label is 1, select probability from probs. If not, then get 1-probs\n        p_t = torch.where(labels  == 1, probs, 1 - probs)\n        modulating_factor = (1 - p_t) ** self.gamma\n\n        #'When labels is 1, the weight is alpha'\n        #'When labels is 0, the weight is 1-alpha'\n        if isinstance(self.alpha, (float, int)):\n            alpha_factor = labels * self.alpha + (1 - labels) * (1 - self.alpha)\n        else:\n            # Assuming alpha is a tensor with shape (num_classes,). We need to expand it to match targets.\n            self.alpha = self.alpha.view(1, -1)\n            alpha_factor = labels * self.alpha +  (1 - labels) * (1 - self.alpha)\n\n        # Compute binary cross entropy loss without reduction.\n        ce_loss = F.binary_cross_entropy_with_logits(preds, labels, reduction='none')\n\n        # Combine the factors to get focal loss:\n        focal_loss_val = alpha_factor * modulating_factor * ce_loss\n    \n        # Apply the specified reduction.\n        if self.reduction == 'mean':\n            return focal_loss_val.mean()\n        elif self.reduction == 'sum':\n            return focal_loss_val.sum()\n        else:\n            return focal_loss_val\n\n        return focal_loss_val\n\n# Example usage:\ny_true = torch.tensor([[0, 0, 0, 1, 1, 1],\n                       [0, 0, 1, 1, 1, 1]])\ny_pred = torch.tensor([[0.2, -0.5, 1.0, 0.7, 0.3, -1.2],\n                       [0.1, 0.0, 1.2, 0.5, -0.2, 0.3]])\n    \nprint(FocalLoss()(y_pred, y_true))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:26:30.467500Z","iopub.execute_input":"2025-02-07T09:26:30.467883Z","iopub.status.idle":"2025-02-07T09:26:30.478366Z","shell.execute_reply.started":"2025-02-07T09:26:30.467848Z","shell.execute_reply":"2025-02-07T09:26:30.477474Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#this is the cross chech function that located in the main model. In training process, i needed to make sure my focal loss I wrote working as competible with the function from torchvision \nimport torch\nfrom torchvision.ops import sigmoid_focal_loss\n\nloss = sigmoid_focal_loss(y_pred.float(), y_true.float(), alpha=0.25, gamma=2.0, reduction='mean')\nprint(\"Focal Loss:\", loss.item())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:26:33.756492Z","iopub.execute_input":"2025-02-07T09:26:33.756771Z","iopub.status.idle":"2025-02-07T09:26:33.762620Z","shell.execute_reply.started":"2025-02-07T09:26:33.756748Z","shell.execute_reply":"2025-02-07T09:26:33.761847Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"stopper!","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.670867Z","iopub.execute_input":"2025-02-07T07:08:10.671191Z","iopub.status.idle":"2025-02-07T07:08:10.687712Z","shell.execute_reply.started":"2025-02-07T07:08:10.671172Z","shell.execute_reply":"2025-02-07T07:08:10.685785Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**The Focal loss i created is validated with sigmoid_focal_loss methods that comes from torchvision.  It is matching right now!**","metadata":{}},{"cell_type":"markdown","source":"Keynote: If the train or validation data has remaining data that caused by not divided by batch size equally, then use drop_last = True","metadata":{}},{"cell_type":"markdown","source":"# Start defining the model ","metadata":{}},{"cell_type":"markdown","source":"## Starting wih Basic Model with Pytorch","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nfrom torchvision import models\n\nclass SimpleCNN(nn.Module):\n    def __init__(self,num_classes =None):\n        super(SimpleCNN,self).__init__()\n\n        self.features = nn.Sequential(\n            nn.Conv2d(4,64,kernel_size=3,stride=2,padding =1),\n            nn.BatchNorm2d(64),\n            nn.ReLU(),\n\n            nn.Conv2d(64,128,kernel_size=3,padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size = 2),\n            nn.Dropout(0.3),\n\n            nn.Conv2d(128,256,kernel_size = 5, padding = 1),\n            nn.BatchNorm2d(256),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size = 2),\n            nn.Dropout(0.5)\n        )\n\n        self.adaptive = nn.Sequential(\n            nn.AdaptiveAvgPool2d((1,1)) #Global Average Pooling\n        )\n\n        self.classifier = nn.Sequential(\n            nn.Flatten(),\n            nn.Linear(256,128),\n            nn.Dropout(0.3),\n            nn.ReLU(),\n            nn.Linear(128,num_classes)\n        )\n\n    def forward(self,x):\n        x = self.features(x)\n        x = self.adaptive(x)\n        x = self.classifier(x)\n        return x","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T10:45:07.131631Z","iopub.execute_input":"2025-02-07T10:45:07.131916Z","iopub.status.idle":"2025-02-07T10:45:07.138663Z","shell.execute_reply.started":"2025-02-07T10:45:07.131892Z","shell.execute_reply":"2025-02-07T10:45:07.137662Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = SimpleCNN(num_classes = 28)\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nmodel = model.to(device)\nprint(model)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T10:45:10.761841Z","iopub.execute_input":"2025-02-07T10:45:10.762294Z","iopub.status.idle":"2025-02-07T10:45:10.781509Z","shell.execute_reply.started":"2025-02-07T10:45:10.762242Z","shell.execute_reply":"2025-02-07T10:45:10.780574Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torchsummary import summary\nsummary(model,input_size = (4,512,512),batch_size = 16)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T10:02:46.985562Z","iopub.execute_input":"2025-02-07T10:02:46.985838Z","iopub.status.idle":"2025-02-07T10:02:47.013796Z","shell.execute_reply.started":"2025-02-07T10:02:46.985816Z","shell.execute_reply":"2025-02-07T10:02:47.013087Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pip install torch-lr-finder","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:37:10.593476Z","iopub.execute_input":"2025-02-07T09:37:10.593798Z","iopub.status.idle":"2025-02-07T09:37:13.964657Z","shell.execute_reply.started":"2025-02-07T09:37:10.593767Z","shell.execute_reply":"2025-02-07T09:37:13.963771Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torch_lr_finder import LRFinder\n\n#Finding best LR:\n\n#Set an initial value for LR\noptimizer = torch.optim.Adam(resnet.parameters(), lr=1e-6, weight_decay=1e-5)\ncriterion = FocalLoss(alpha = 0.25,gamma = 2.0, reduction = 'mean')\n#create LR_FINDER\nlr_finder = LRFinder(model,optimizer,criterion,device= 'cuda')\nlr_finder.range_test(train_dataloader,end_lr =1,num_iter = 200) #from 1e-7 to 1 by 100 iteration\n\nlr_finder.plot()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:57:43.820329Z","iopub.execute_input":"2025-02-07T09:57:43.820696Z","iopub.status.idle":"2025-02-07T10:00:45.266544Z","shell.execute_reply.started":"2025-02-07T09:57:43.820663Z","shell.execute_reply":"2025-02-07T10:00:45.265744Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import roc_auc_score\nfrom sklearn.metrics import f1_score\n#for overall performance graph\ntrain_loss_list = []\nmicro_f1_list = []\nval_loss_list = []\nnum_epoch = 5\nresnet = model\noptimizer = torch.optim.Adam(resnet.parameters(), lr=1e-3, weight_decay=1e-4)\ncriterion = FocalLoss(alpha=0.25, gamma=2.0, reduction='mean')\n\nfor epoch in range(num_epoch):\n    #Initiate the parameters\n    \n    total = 0   #calculation param\n    \n    running_loss = 0.0      #calculation parameter for train\n    running_test_loss = 0.0 #calculation parameter for test\n    train_total_samples = 0.0\n\n    f1_micro = 0 \n    f1_micro_total = 0\n\n    resnet.train() #Set the model as training mode\n    print('********  EPOCH NO {} ******** '.format(epoch))\n   \n    num_batches = 0\n  #------------------ Train the Model ------------------\n    for inputs,labels in train_dataloader:\n        \n        batch_size = inputs.size(0)         # e.g., 16\n        num_classes = labels.size(1)        # e.g., 28\n\n        #Remove the 3rd dimension of image which is Z.\n        #inputs = inputs.permute(0,3,2,1)             # Shape: [16,512,512,4] to [16,4,512,512]\n        \n        #inputs = inputs.squeeze(3).permute(0,3,2,1)  # Shape: [16, 512, 512,1,4] to [16,4,512,512]\n        inputs = inputs.to(torch.float).to(device, non_blocking=True)\n        labels = labels.to(torch.float).to(device, non_blocking=True)\n        #print(inputs.shape) #torch.Size([8, 4, 512, 512])\n        #print(labels.shape) #torch.Size([8, 28])\n\n        optimizer.zero_grad()\n        outputs = resnet(inputs)\n\n        #Loss Calculation\n        loss = criterion(outputs,labels) #pred,target\n\n        loss.backward()  #it is valid only for train (backpropagation)\n        optimizer.step() #it is valid only for train (backpropagation)\n        running_loss += loss.item() * batch_size \n        train_total_samples +=  batch_size   \n        #print(running_loss / train_total_samples) #control\n        \n        probs = torch.sigmoid(outputs)\n        thresholded_outputs  = (probs > 0.5).float()\n        \n\n\n        #F1 Score:\n        f1_micro = f1_score(labels.cpu().numpy().flatten(), thresholded_outputs.cpu().numpy().flatten(), average='micro')\n        f1_micro_total += f1_micro \n\n        \n        num_batches +=1 \n    \n    # Calculate average loss and accuracy for the epoch\n    epoch_loss = running_loss / train_total_samples\n    train_loss_list.append(epoch_loss)\n    print(f\"Train Epoch {epoch + 1}/{num_epoch}: Train Loss: {epoch_loss:.4f} \")\n    micro_per_class = f1_micro_total/num_batches\n    micro_f1_list.append(micro_per_class)\n    print(f\"Train Epoch {epoch + 1}/{num_epoch}: F1Micro: {micro_per_class:.4f} \")\n    \n\n    resnet.eval()  # Set the model to evaluation mode\n    val_running_loss = 0.0\n    val_total_samples = 0\n    \n    with torch.no_grad():  # Disable gradient computation for validation\n        for inputs,labels in val_dataloader:\n            batch_size = inputs.size(0)         # e.g., 16\n            num_classes = labels.size(1)        # e.g., 28\n           \n            #inputs = inputs.squeeze(3).permute(0,3,2,1)  # Shape: [16, 512, 512,4]\n            inputs = inputs.to(torch.float).to(device)\n\n            labels = labels.to(torch.float).to(device)\n\n            # Forward pass\n            outputs = resnet(inputs)\n            loss = criterion(outputs,labels) #pred,target\n\n            # Accumulate validation loss\n            val_running_loss += loss.item()* batch_size\n            val_total_samples += batch_size\n           \n\n    # Calculate average validation loss and accuracy\n    val_loss = val_running_loss / val_total_samples\n    val_loss_list.append(val_loss)\n\n    print(f\"Validation Epoch{epoch}/{num_epoch}: Validation Loss: {val_loss:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T10:45:18.673106Z","iopub.execute_input":"2025-02-07T10:45:18.673408Z","iopub.status.idle":"2025-02-07T12:40:00.533451Z","shell.execute_reply.started":"2025-02-07T10:45:18.673387Z","shell.execute_reply":"2025-02-07T12:40:00.532191Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Start with Resnet50:","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nfrom torchvision import models\n\n# Load a pre-trained ResNet model\nresnet = models.resnet50(weights=None)\n\n# Freeze all layers initially\n#for param in resnet.parameters():\n#    param.requires_grad = False\n\n# Replace the final fully connected layer\nnum_classes = 28  # Example: for a 4-class classification problem\nresnet.fc = nn.Sequential(\n    nn.Linear(2048, 512),\n    nn.BatchNorm1d(512),\n    nn.ReLU(),\n    nn.Dropout(0.5),  # Optional: Helps prevent overfitting\n    nn.Linear(512, 128),\n    nn.BatchNorm1d(128),\n    nn.ReLU(),\n    nn.Dropout(0.3),  # Optional: Helps prevent overfitting\n    nn.Linear(128, num_classes)\n)\n\n# Unfreeze upper layers (optional)\n#for param in resnet.layer4.parameters():  # Unfreeze the last residual block\n#    param.requires_grad = True\n\nprint(resnet)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.688223Z","iopub.status.idle":"2025-02-07T07:08:10.688496Z","shell.execute_reply":"2025-02-07T07:08:10.688390Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for name,param in resnet.named_parameters():\n  print(f'Layer: {name}')\n  print(f' - Shape: {param.shape}')\n  print(f' - Requires Grad: {param.requires_grad}')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.689413Z","iopub.status.idle":"2025-02-07T07:08:10.689789Z","shell.execute_reply":"2025-02-07T07:08:10.689630Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import gc\ngc.collect()\ntorch.cuda.empty_cache()\ntorch.manual_seed(42)\ntorch.cuda.manual_seed(42)\n\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nresnet = resnet.to(device)\n\nif torch.cuda.is_available(): #if GPU is working\n    print('GPU is active',torch.cuda.get_device_name(0))\n    #move the model to GPU\nelse:\n    print('GPU is not available')\n\noptimizer = torch.optim.Adam(resnet.parameters(), lr=5e-3, weight_decay=1e-5)\n\n#early stop setup\npatience = 5\nbest_loss = float('inf') #set it as infinite value\nepochs_no_improve = 0    #counts if it is no improvements\nearly_stop = True       #trigger\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.690619Z","iopub.status.idle":"2025-02-07T07:08:10.691062Z","shell.execute_reply":"2025-02-07T07:08:10.690835Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**IMPORTANT**\n\nThe resnet50 is designed with 3 channels image, now i need to make it 4 otherwise,\n\n**RuntimeError: Given groups=1, weight of size [64, 3, 7, 7], expected input[16, 4, 512, 512] to have 3 channels, but got 4 channels instead**\n","metadata":{}},{"cell_type":"code","source":"''' (EXAMPLE)\n(conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n  (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n  (relu): ReLU(inplace=True)\n  (maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)\n'''\n\nresnet.conv1 = nn.Conv2d(4,64,kernel_size=7,\n                      stride = 2,\n                      padding = 3,\n                      bias = False)\n\nresnet = resnet.to(device)\nprint(resnet)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.692178Z","iopub.status.idle":"2025-02-07T07:08:10.692671Z","shell.execute_reply":"2025-02-07T07:08:10.692472Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pip install torchsummary ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.693891Z","iopub.status.idle":"2025-02-07T07:08:10.694279Z","shell.execute_reply":"2025-02-07T07:08:10.694115Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torchsummary import summary\nsummary(resnet,input_size = (4,512,512),batch_size = 16)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.695394Z","iopub.status.idle":"2025-02-07T07:08:10.695716Z","shell.execute_reply":"2025-02-07T07:08:10.695558Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import roc_auc_score\nfrom sklearn.metrics import f1_score\n\n#for overall performance graph\ntrain_loss_list = []\nmicro_f1_list = []\nval_loss_list = []\n\nnum_epoch = 5\ncriterion = FocalLoss(alpha=0.25, gamma=2.0, reduction='mean')\n\nfor epoch in range(num_epoch):\n    #Initiate the parameters\n    \n    total = 0   #calculation param\n    \n    running_loss = 0.0      #calculation parameter for train\n    running_test_loss = 0.0 #calculation parameter for test\n    train_total_samples = 0.0\n\n    f1_micro = 0 \n    f1_micro_total = 0\n\n    resnet.train() #Set the model as training mode\n    print('********  EPOCH NO {} ******** '.format(epoch))\n   \n    num_batches = 0\n  #------------------ Train the Model ------------------\n    for inputs,labels in train_dataloader:\n        #print(f\"Total number of batches in train_dataloader: {len(train_dataloader)}\")\n        \n        batch_size = inputs.size(0)         # e.g., 16\n        num_classes = labels.size(1)        # e.g., 28\n\n        #Remove the 3rd dimension of image which is Z.\n        inputs = inputs.squeeze(3).permute(0,3,2,1)  # Shape: [16, 512, 512,1,4] to [16,4,512,512]\n        inputs = inputs.to(torch.float).to(device)\n        labels = labels.to(torch.float).to(device)\n        #print(inputs.shape) #torch.Size([8, 4, 512, 512])\n        #print(labels.shape) #torch.Size([8, 28])\n\n        optimizer.zero_grad()\n        outputs = resnet(inputs)\n\n        #Loss Calculation\n        loss = criterion(outputs,labels) #pred,target\n        #print('Loss:')\n        #print(loss)\n        #loss_checker = sigmoid_focal_loss(outputs.float(), labels.float(), alpha=0.25, gamma=2.0, reduction='sum')\n        #print(\"Focal Loss_Checker:\", loss_checker.item())\n\n        loss.backward()  #it is valid only for train (backpropagation)\n        optimizer.step() #it is valid only for train (backpropagation)\n        running_loss += loss.item() * batch_size \n        train_total_samples +=  batch_size   \n        #print(running_loss / train_total_samples) #control\n        \n        probs = torch.sigmoid(outputs)\n        thresholded_outputs  = (probs > 0.5).float()\n        \n        #print('predicted:',thresholded_outputs[0]) # 0,0,1,...etc....\n        #print('actual:',labels[0])\n        #print('outputs:')\n        #print(outputs)\n\n        #F1 Score:\n        f1_micro = f1_score(labels.cpu().numpy().flatten(), thresholded_outputs.cpu().numpy().flatten(), average='micro')\n        f1_micro_total += f1_micro \n        #print('f1_control',f1_micro_total/num_batches)\n        \n        num_batches +=1 \n    \n    # Calculate average loss and accuracy for the epoch\n    epoch_loss = running_loss / train_total_samples\n    train_loss_list.append(epoch_loss)\n    print(f\"Train Epoch {epoch + 1}/{num_epoch}: Train Loss: {epoch_loss:.4f} \")\n    micro_per_class = f1_micro_total/num_batches\n    micro_f1_list.append(micro_per_class)\n    print(f\"Train Epoch {epoch + 1}/{num_epoch}: F1Micro: {micro_per_class:.4f} \")\n    \n\n    resnet.eval()  # Set the model to evaluation mode\n    val_running_loss = 0.0\n    val_total_samples = 0\n    \n    with torch.no_grad():  # Disable gradient computation for validation\n        for inputs,labels in val_dataloader:\n            batch_size = inputs.size(0)         # e.g., 16\n            num_classes = labels.size(1)        # e.g., 28\n           \n            inputs = inputs.squeeze(3).permute(0,3,2,1)  # Shape: [16, 512, 512,4]\n            inputs = inputs.to(torch.float).to(device)\n\n            labels = labels.to(torch.float).to(device)\n\n            # Forward pass\n            outputs = resnet(inputs)\n            loss = criterion(outputs,labels) #pred,target\n\n            # Accumulate validation loss\n            val_running_loss += loss.item()* batch_size\n            val_total_samples += batch_size\n           \n\n    # Calculate average validation loss and accuracy\n    val_loss = val_running_loss / val_total_samples\n    val_loss_list.append(val_loss)\n\n    print(f\"Validation Epoch{epoch}/{num_epoch}: Validation Loss: {val_loss:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.697238Z","iopub.status.idle":"2025-02-07T07:08:10.697507Z","shell.execute_reply":"2025-02-07T07:08:10.697402Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Model Changing Decision:\n\nI noticed that resnet50 with unfreeze/freeze parameters are working heavy and also prone to be overfitted. The trainable parameters 24m which is more than the need of this problem (I am assuming for sure!). Also, I can see this by looking at the results as below:\n\n![image.png](attachment:b8beac99-6ddb-4e5f-a3ad-b5f1fa39be1a.png)\n\nNow I want to change the model with more basic structure and less parameters.","metadata":{},"attachments":{"b8beac99-6ddb-4e5f-a3ad-b5f1fa39be1a.png":{"image/png":"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"}}},{"cell_type":"markdown","source":"just so an example:\n\n>(conv1): Conv2d(4, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n>\n>(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n>\n>(relu): ReLU(inplace=True)\n>\n>(maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)\n>\n>(layer1): Sequential(","metadata":{}},{"cell_type":"code","source":"'''\nBuilt by Keras Based CNN Model\n\nimport tensorflow as tf\nimport keras\nfrom keras import layers\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Activation\nfrom tensorflow.keras.layers import Input\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import Conv2D\nfrom tensorflow.keras.layers import MaxPooling2D\nfrom tensorflow.keras.layers import Flatten\nfrom tensorflow.keras.layers import Dropout\nfrom tensorflow.keras.layers import Dense\nfrom tensorflow.keras.layers import BatchNormalization\n\n# creating CNN model:\n\ncnn_model = Sequential()\n\n#train dataloader gives --> torch.Size([16, 512, 512, 1, 4])\n# with torch squeeze, i would expect -->  [16,4,512,512]\n#Conv_InputLayer\ncnn_model.add(Input(shape=(4,512,512))) #keras automatically understand the batch size that comes from torch tensor\ncnn_model.add(Conv2D(32,kernel_size=(3,3), strides = (2,2),padding ='same'))\ncnn_model.add(Activation('relu'))\ncnn_model.add(BatchNormalization())\n\n#------------------basic detail/feature (kernel_size=(small,small))\n#Conv_layer1\ncnn_model.add(Conv2D(32,kernel_size=(3,3),padding ='same'))\ncnn_model.add(Activation('relu'))\ncnn_model.add(BatchNormalization())\ncnn_model.add(Dropout(0.2))\n#Conv_layer2\ncnn_model.add(Conv2D(32,kernel_size = (3,3),padding='same'))\ncnn_model.add(Activation('relu'))\ncnn_model.add(BatchNormalization())\ncnn_model.add(Dropout(0.2))\n\n#------------------Medium detail/feature (kernel_size=(medium,medium))\n#Conv_layer3\ncnn_model.add(Conv2D(64,kernel_size=(5,5),padding ='same'))\ncnn_model.add(Activation('relu'))\ncnn_model.add(BatchNormalization())\ncnn_model.add(MaxPooling2D(pool_size = (2,2)))\ncnn_model.add(Dropout(0,3))\n\n#Conv_layer4\ncnn_model.add(Conv2D(64,kernel_size=(5,5),padding ='same'))\ncnn_model.add(Activation('relu'))\ncnn_model.add(BatchNormalization())\ncnn_model.add(Dropout(0,3))\n\n#------------------Hard detail/feature (kernel_size=(big,big))\n#Conv_layer5\ncnn_model.add(Conv2D(128,kernel_size=(5,5),padding ='same'))\ncnn_model.add(Activation('relu'))\ncnn_model.add(BatchNormalization())\ncnn_model.add(MaxPooling2D(pool_size = (2,2)))\ncnn_model.add(Dropout(0.5))\n\n#Conv_layer6\ncnn_model.add(Conv2D(128,kernel_size=(5,7),padding ='same'))\ncnn_model.add(Activation('relu'))\ncnn_model.add(BatchNormalization())\ncnn_model.add(MaxPooling2D(pool_size = (2,2)))\ncnn_model.add(Dropout(0.5))\n\n#Conv_layer7\ncnn_model.add(Conv2D(128,kernel_size=(7,5),padding ='same'))\ncnn_model.add(Activation('relu'))\ncnn_model.add(BatchNormalization())\ncnn_model.add(MaxPooling2D(pool_size = (2,2)))\ncnn_model.add(Dropout(0.5))\n\ncnn_model.add(Flatten())\n\n#FC_Layer_1\ncnn_model.add(Dense(128))\ncnn_model.add(BatchNormalization())\ncnn_model.add(Activation('relu'))\ncnn_model.add(Dropout(0.5))\n#FC_Layer_2\ncnn_model.add(Dense(64))\ncnn_model.add(BatchNormalization())\ncnn_model.add(Activation('relu'))\ncnn_model.add(Dropout(0.5))\n#FC_Layer_3\ncnn_model.add(Dense(28))\ncnn_model.add(Activation('softmax')) #probability\n\n\n'''","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.698420Z","iopub.status.idle":"2025-02-07T07:08:10.698682Z","shell.execute_reply":"2025-02-07T07:08:10.698560Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\n# Check for GPU\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\nclass MyCNN(nn.Module):\n    def __init__(self, num_classes=28):\n        super(MyCNN, self).__init__()\n        \n        # Conv Input Layer (More Filters)\n        self.conv1 = nn.Conv2d(in_channels=4, out_channels=64, kernel_size=3, stride=2, padding=1)\n        self.bn1 = nn.BatchNorm2d(64)\n        \n        # Basic Detail Features\n        self.conv2 = nn.Conv2d(64, 64, kernel_size=3, padding=1)\n        self.bn2 = nn.BatchNorm2d(64)\n        self.drop2 = nn.Dropout(0.1)\n\n        self.residual3 = nn.Conv2d(64,128,kernel_size = 1, stride=1)\n        \n        self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)\n        self.bn3 = nn.BatchNorm2d(128)\n        self.drop3 = nn.Dropout(0.1)\n        \n        # Medium Detail Features\n        self.conv4 = nn.Conv2d(128, 128, kernel_size=5, padding=2)\n        self.bn4 = nn.BatchNorm2d(128)\n        self.pool4 = nn.MaxPool2d(kernel_size=2)\n        self.drop4 = nn.Dropout(0.2)\n\n        self.conv5 = nn.Conv2d(128, 128, kernel_size=5, padding=2)\n        self.bn5 = nn.BatchNorm2d(128)\n        self.drop5 = nn.Dropout(0.3)\n\n        self.residual6 = nn.Conv2d(128,256,kernel_size = 1, stride=1)\n        \n        # Hard Detail Features\n        self.conv6 = nn.Conv2d(128, 256, kernel_size=5, padding=2)\n        self.bn6 = nn.BatchNorm2d(256)\n        #self.pool6 = nn.MaxPool2d(kernel_size=2)\n        self.drop6 = nn.Dropout(0.4)\n\n        self.conv7 = nn.Conv2d(256, 256, kernel_size=(5,7), padding=(2,3))\n        self.bn7 = nn.BatchNorm2d(256)\n        self.pool7 = nn.MaxPool2d(kernel_size=2)\n        self.drop7 = nn.Dropout(0.3)\n\n        self.conv8 = nn.Conv2d(256, 256, kernel_size=(7,5), padding=(3,2))\n        self.bn8 = nn.BatchNorm2d(256)\n        self.pool8 = nn.MaxPool2d(kernel_size=2)\n        self.drop8 = nn.Dropout(0.3)\n\n        # Adaptive pooling to handle dynamic input sizes\n        self.global_pool = nn.AdaptiveAvgPool2d((1, 1))\n\n        # Fully Connected Layers (Increased Size)\n        self.fc1 = nn.Linear(256, 256)\n        self.bn_fc1 = nn.BatchNorm1d(256)\n        self.drop_fc1 = nn.Dropout(0.3)\n\n        self.fc2 = nn.Linear(256, 128)\n        self.bn_fc2 = nn.BatchNorm1d(128)\n        self.drop_fc2 = nn.Dropout(0.2)\n\n        self.fc3 = nn.Linear(128, num_classes)\n\n    def forward(self, x):\n        x = x.to(device)  # Ensure input is moved to GPU\n        x = F.relu(self.bn1(self.conv1(x)))\n\n        x = F.relu(self.bn2(self.conv2(x)))\n        x = self.drop2(x)\n\n        residual = x  # Store original input BEFORE conv3\n        x = F.relu(self.bn3(self.conv3(x)))\n        x = self.drop3(x)\n        # If residual shape doesn't match, apply 1x1 conv to match channels\n        if residual.shape[1] != x.shape[1]:  # Check if channels differ\n            residual =  self.residual3(residual)  # Match channels 64 → 128\n        x = x + residual  # Now both tensors have 128 channels\n\n        \n        x = x + residual  # Add skip connection\n\n        x = F.relu(self.bn4(self.conv4(x)))\n        x = self.pool4(x)\n        x = self.drop4(x)\n\n        x = F.relu(self.bn5(self.conv5(x)))\n        x = self.drop5(x)\n\n        residual =  x  # Store original input BEFORE conv3\n        x = F.relu(self.bn6(self.conv6(x)))\n        #x = self.pool6(x)\n        x = self.drop6(x)\n        if residual.shape[1] != x.shape[1]:  # Check if channels differ\n            residual = self.residual6(residual)  # Match channels 128 → 256\n        x = x + residual  # Skip connection\n\n        x = F.relu(self.bn7(self.conv7(x)))\n        x = self.pool7(x)\n        x = self.drop7(x)\n\n        x = F.relu(self.bn8(self.conv8(x)))\n        x = self.pool8(x)\n        x = self.drop8(x)\n\n        # Global Pooling\n        x = self.global_pool(x)\n        \n        # Flatten\n        x = torch.flatten(x, start_dim=1)\n\n        # Fully Connected Layers\n        x = F.relu(self.bn_fc1(self.fc1(x)))\n        x = self.drop_fc1(x)\n\n        x = F.relu(self.bn_fc2(self.fc2(x)))\n        x = self.drop_fc2(x)\n\n        x = self.fc3(x)  # No activation since softmax is handled by loss function\n\n        return x\n\n# Move model to GPU\nmodel = MyCNN(num_classes=28).to(device)\nprint(model)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.699892Z","iopub.status.idle":"2025-02-07T07:08:10.700327Z","shell.execute_reply":"2025-02-07T07:08:10.700134Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torchsummary import summary\n\nresnet = MyCNN(num_classes=28).to(device)\nsummary(resnet,input_size = (4,512,512),batch_size = 16)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.701269Z","iopub.status.idle":"2025-02-07T07:08:10.701535Z","shell.execute_reply":"2025-02-07T07:08:10.701429Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import roc_auc_score\nfrom sklearn.metrics import f1_score\n#for overall performance graph\ntrain_loss_list = []\nmicro_f1_list = []\nval_loss_list = []\nnum_epoch = 5\noptimizer = torch.optim.Adam(resnet.parameters(), lr=1e-4, weight_decay=1e-5)\nresnet = model\ncriterion = FocalLoss(alpha=0.25, gamma=2.0, reduction='mean')\n\nfor epoch in range(num_epoch):\n    #Initiate the parameters\n    \n    total = 0   #calculation param\n    \n    running_loss = 0.0      #calculation parameter for train\n    running_test_loss = 0.0 #calculation parameter for test\n    train_total_samples = 0.0\n\n    f1_micro = 0 \n    f1_micro_total = 0\n\n    resnet.train() #Set the model as training mode\n    print('********  EPOCH NO {} ******** '.format(epoch))\n   \n    num_batches = 0\n  #------------------ Train the Model ------------------\n    for inputs,labels in train_dataloader:\n        #print(f\"Total number of batches in train_dataloader: {len(train_dataloader)}\")\n        \n        batch_size = inputs.size(0)         # e.g., 16\n        num_classes = labels.size(1)        # e.g., 28\n\n        #Remove the 3rd dimension of image which is Z.\n        inputs = inputs.squeeze(3).permute(0,3,2,1)  # Shape: [16, 512, 512,1,4] to [16,4,512,512]\n        inputs = inputs.to(torch.float).to(device, non_blocking=True)\n        labels = labels.to(torch.float).to(device, non_blocking=True)\n        #print(inputs.shape) #torch.Size([8, 4, 512, 512])\n        #print(labels.shape) #torch.Size([8, 28])\n\n        optimizer.zero_grad()\n        outputs = resnet(inputs)\n\n        #Loss Calculation\n        loss = criterion(outputs,labels) #pred,target\n        #print('Loss:')\n        #print(loss)\n        #loss_checker = sigmoid_focal_loss(outputs.float(), labels.float(), alpha=0.25, gamma=2.0, reduction='sum')\n        #print(\"Focal Loss_Checker:\", loss_checker.item())\n\n        loss.backward()  #it is valid only for train (backpropagation)\n        optimizer.step() #it is valid only for train (backpropagation)\n        running_loss += loss.item() * batch_size \n        train_total_samples +=  batch_size   \n        #print(running_loss / train_total_samples) #control\n        \n        probs = torch.sigmoid(outputs)\n        thresholded_outputs  = (probs > 0.5).float()\n        \n        #print('predicted:',thresholded_outputs[0]) # 0,0,1,...etc....\n        #print('actual:',labels[0])\n        #print('outputs:')\n        #print(outputs)\n\n        #F1 Score:\n        f1_micro = f1_score(labels.cpu().numpy().flatten(), thresholded_outputs.cpu().numpy().flatten(), average='micro')\n        f1_micro_total += f1_micro \n        #print('f1_control',f1_micro_total/num_batches)\n        \n        num_batches +=1 \n    \n    # Calculate average loss and accuracy for the epoch\n    epoch_loss = running_loss / train_total_samples\n    train_loss_list.append(epoch_loss)\n    print(f\"Train Epoch {epoch + 1}/{num_epoch}: Train Loss: {epoch_loss:.4f} \")\n    micro_per_class = f1_micro_total/num_batches\n    micro_f1_list.append(micro_per_class)\n    print(f\"Train Epoch {epoch + 1}/{num_epoch}: F1Micro: {micro_per_class:.4f} \")\n    \n\n    resnet.eval()  # Set the model to evaluation mode\n    val_running_loss = 0.0\n    val_total_samples = 0\n    \n    with torch.no_grad():  # Disable gradient computation for validation\n        for inputs,labels in val_dataloader:\n            batch_size = inputs.size(0)         # e.g., 16\n            num_classes = labels.size(1)        # e.g., 28\n           \n            inputs = inputs.squeeze(3).permute(0,3,2,1)  # Shape: [16, 512, 512,4]\n            inputs = inputs.to(torch.float).to(device)\n\n            labels = labels.to(torch.float).to(device)\n\n            # Forward pass\n            outputs = resnet(inputs)\n            loss = criterion(outputs,labels) #pred,target\n\n            # Accumulate validation loss\n            val_running_loss += loss.item()* batch_size\n            val_total_samples += batch_size\n           \n\n    # Calculate average validation loss and accuracy\n    val_loss = val_running_loss / val_total_samples\n    val_loss_list.append(val_loss)\n\n    print(f\"Validation Epoch{epoch}/{num_epoch}: Validation Loss: {val_loss:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.702443Z","iopub.status.idle":"2025-02-07T07:08:10.702749Z","shell.execute_reply":"2025-02-07T07:08:10.702637Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Saving the model","metadata":{}},{"cell_type":"code","source":"# Save the entire model\nmodel_path = '/kaggle/working/full_model.pth'\ntorch.save(resnet, model_path)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.703388Z","iopub.status.idle":"2025-02-07T07:08:10.703665Z","shell.execute_reply":"2025-02-07T07:08:10.703536Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Testing the model","metadata":{}},{"cell_type":"code","source":"resnet = model  # pay attention which model will assign here!\nresnet.eval()  # Set the model to evaluation mode\npredictions = []\n\nwith torch.no_grad():  # Disable gradient computation for validation\n    for inputs in test_dataloader:\n        #batch_size = inputs.size(0)         # e.g., 16\n        #inputs = inputs.squeeze(3).permute(0,3,2,1)  # Shape: [16, 512, 512,4]\n        inputs = inputs.to(torch.float).to(device)\n\n        outputs = resnet(inputs)\n        probs = torch.sigmoid(outputs)\n        thresholded_outputs  = (probs > 0.35).float()\n        predictions.append(thresholded_outputs.cpu().numpy())\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T12:46:08.880429Z","iopub.execute_input":"2025-02-07T12:46:08.880718Z","iopub.status.idle":"2025-02-07T12:51:43.286283Z","shell.execute_reply.started":"2025-02-07T12:46:08.880694Z","shell.execute_reply":"2025-02-07T12:51:43.285315Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predf = np.concatenate(predictions)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T13:01:47.013208Z","iopub.execute_input":"2025-02-07T13:01:47.013562Z","iopub.status.idle":"2025-02-07T13:01:47.019448Z","shell.execute_reply.started":"2025-02-07T13:01:47.013538Z","shell.execute_reply":"2025-02-07T13:01:47.018543Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predf[:10]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.706823Z","iopub.status.idle":"2025-02-07T07:08:10.707208Z","shell.execute_reply":"2025-02-07T07:08:10.707088Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predc = []\n\nfor each in predf:\n    tmp=[]\n    for idx in range(len(each)):\n        if each[idx] ==1:\n            tmp.append(idx)\n    predc.append(tmp)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T13:01:49.496366Z","iopub.execute_input":"2025-02-07T13:01:49.496638Z","iopub.status.idle":"2025-02-07T13:01:50.097748Z","shell.execute_reply.started":"2025-02-07T13:01:49.496617Z","shell.execute_reply":"2025-02-07T13:01:50.097080Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predc[:10]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T13:01:52.340705Z","iopub.execute_input":"2025-02-07T13:01:52.340980Z","iopub.status.idle":"2025-02-07T13:01:52.346615Z","shell.execute_reply.started":"2025-02-07T13:01:52.340959Z","shell.execute_reply":"2025-02-07T13:01:52.345850Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Submitting the test data","metadata":{}},{"cell_type":"code","source":"temporary_predc = predc\nnew_arr = []\nfor each in temporary_predc:\n    if isinstance(each,list):  # if the prediction is packed in list,then search deeper.\n        if len(each) == 0:     #if the prediction is not existed.\n            new_arr.append('') #save empty\n        elif len(each) == 1:\n            new_arr.append(str(each[0])) #save the only one value into new array \n        else:\n            tmp = []\n            for idx in range(len(each)): #search each element then pack it into list\n                tmp.append(str(each[idx]))\n            new_arr.append(' '.join(tmp)) #form the list as str [1,3,5] to str(1,3,5) then save it\n    else:\n        new_arr.append(each) # if the prediction is out of list, then save the row value.\n        ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T13:01:57.426580Z","iopub.execute_input":"2025-02-07T13:01:57.426864Z","iopub.status.idle":"2025-02-07T13:01:57.446850Z","shell.execute_reply.started":"2025-02-07T13:01:57.426842Z","shell.execute_reply":"2025-02-07T13:01:57.445868Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dtest = pd.read_csv('/kaggle/input/human-protein-atlas-image-classification/sample_submission.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T13:02:03.480564Z","iopub.execute_input":"2025-02-07T13:02:03.480837Z","iopub.status.idle":"2025-02-07T13:02:03.499909Z","shell.execute_reply.started":"2025-02-07T13:02:03.480815Z","shell.execute_reply":"2025-02-07T13:02:03.499131Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"new_arr[:10]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:08:10.712857Z","iopub.status.idle":"2025-02-07T07:08:10.713296Z","shell.execute_reply":"2025-02-07T07:08:10.713082Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dtest['Predicted'] = new_arr","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T13:02:06.718248Z","iopub.execute_input":"2025-02-07T13:02:06.718550Z","iopub.status.idle":"2025-02-07T13:02:06.723732Z","shell.execute_reply.started":"2025-02-07T13:02:06.718524Z","shell.execute_reply":"2025-02-07T13:02:06.722854Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dtest.to_csv('/kaggle/working/prediction_r.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T13:02:09.238917Z","iopub.execute_input":"2025-02-07T13:02:09.239259Z","iopub.status.idle":"2025-02-07T13:02:09.266014Z","shell.execute_reply.started":"2025-02-07T13:02:09.239230Z","shell.execute_reply":"2025-02-07T13:02:09.265172Z"}},"outputs":[],"execution_count":null}]}