{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":71549,"databundleVersionId":8561470,"sourceType":"competition"},{"sourceId":115426,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":96956,"modelId":121141},{"sourceId":118892,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":99976,"modelId":124147}],"dockerImageVersionId":30762,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\n\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torchvision import models \nimport torchvision.transforms as T\nfrom torch.utils.data import Dataset, DataLoader\nimport torch.nn.functional as F\n\nimport pydicom\nfrom PIL import Image,ImageOps\nimport random\nfrom sklearn.preprocessing import LabelEncoder, label_binarize\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import roc_auc_score ,accuracy_score,classification_report,roc_curve,auc\nfrom sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay,accuracy_score\n\nimport matplotlib.pyplot as plt\nimport cv2\nfrom skimage.measure import regionprops, label\nimport time\n\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-09-18T07:02:09.395985Z","iopub.execute_input":"2024-09-18T07:02:09.396321Z","iopub.status.idle":"2024-09-18T07:02:15.528394Z","shell.execute_reply.started":"2024-09-18T07:02:09.396286Z","shell.execute_reply":"2024-09-18T07:02:15.527334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install segmentation-models-pytorch","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#file path\nbase_path = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification'\n\n#train path\ntrain_label = os.path.join(base_path,'train_label_coordinates.csv')\ntrain_series = os.path.join(base_path,'train_series_descriptions.csv')\ntrain_ = os.path.join(base_path,'train.csv')\nimg_train_path = os.path.join(base_path,'train_images')\n\n#test path\ntest_series=os.path.join(base_path,'test_series_descriptions.csv')\nimg_test_path = os.path.join(base_path,'test_images')","metadata":{"execution":{"iopub.status.busy":"2024-09-18T07:02:15.530109Z","iopub.execute_input":"2024-09-18T07:02:15.531264Z","iopub.status.idle":"2024-09-18T07:02:15.537002Z","shell.execute_reply.started":"2024-09-18T07:02:15.531215Z","shell.execute_reply":"2024-09-18T07:02:15.536169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def reconstruct_df(df):\n    series = ['Sagittal T2/STIR', 'Sagittal T1', 'Axial T2']\n    conditions = ['spinal_canal_stenosis', 'neural_foraminal_narrowing', 'subarticular_stenosis']\n    df_name=[pd.DataFrame(),pd.DataFrame(),pd.DataFrame()]\n    \n    for i,(se, cond) in enumerate(zip(series, conditions)):\n        filtered_df = df[df['series_description'] == se] # Filter the dataframe based on 'series_description'\n\n        # Select columns to keep\n        columns_to_keep = filtered_df.columns[:8].tolist()\n        columns_to_keep += [col for col in filtered_df.columns[8:] if cond in col]\n\n        #filter and update\n        filtered_df = filtered_df[columns_to_keep] \n        df_name[i] = filtered_df\n    \n    return df_name[0],df_name[1],df_name[2]\n\n\ndef xy_spinal_neural(df):\n    # Required levels and associated columns\n    required_levels = ['L1/L2', 'L2/L3', 'L3/L4', 'L4/L5', 'L5/S1']\n\n    ## filterout data which having both level\n    df_filtered = df.groupby(['study_id','series_id','instance_number']).filter(\n    lambda group: set(required_levels).issubset(group['level'].unique()))\n\n    # make localize \n    grouped = df_filtered.groupby(['study_id', 'series_id', 'instance_number'])\n    result_rows = []\n    for (study_id, series_id, instance_number), group in grouped:\n        # Create a dictionary to store the data for this group\n        row_data = {'study_id': study_id, 'series_id': series_id, 'instance_number': instance_number}\n    \n        # Check if all other columns have the same value in the group, if so, keep them\n        for col in group.columns:\n            if col not in ['level', 'x', 'y']:  # Exclude 'level', 'x', and 'y' columns\n                if group[col].nunique() == 1:  # Check if all values in this column are the same\n                    row_data[col] = group[col].iloc[0]  # Take the unique value\n\n\n        # Extract x and y coordinates for each required level\n        for level in required_levels:\n            level_data = group[group['level'] == level]\n            if not level_data.empty:\n                row_data[f'x_level_{level.lower().replace(\"/\", \"_\")}'] = level_data['x'].values[0]\n                row_data[f'y_level_{level.lower().replace(\"/\", \"_\")}'] = level_data['y'].values[0]\n\n        # Add the row data to the result_rows list\n        result_rows.append(row_data)\n\n    # Convert the result_rows list to a DataFrame\n    result = pd.DataFrame(result_rows)\n    return result\n\n\ndef xy_subarticular(df):\n    # Required levels and associated columns\n    require_condition=['Right Subarticular Stenosis','Left Subarticular Stenosis']\n\n    ## filterout data which having both level\n    df_filtered = df.groupby(['study_id','series_id','instance_number','level']).filter(\n    lambda group: set(require_condition).issubset(group['condition'].unique()))\n\n    # make localize \n    grouped = df_filtered.groupby(['study_id', 'series_id', 'instance_number','level'])\n    result_rows = []\n    for (study_id, series_id, instance_number,level), group in grouped:\n        # Create a dictionary to store the data for this group\n        row_data = {'study_id': study_id, 'series_id': series_id, 'instance_number': instance_number,'level':level}\n    \n        # Check if all other columns have the same value in the group, if so, keep them\n        for col in group.columns:\n            if col not in ['series_description','condition','x', 'y']:  # Exclude 'level', 'x', and 'y' columns\n                if group[col].nunique() == 1:  # Check if all values in this column are the same\n                    row_data[col] = group[col].iloc[0]  # Take the unique value\n\n        # Extract x and y coordinates for each required level\n        for condition in require_condition:\n            condition_data = group[group['condition'] == condition]\n            if not condition_data.empty:\n                row_data[f'x_level_{condition.split(\" \")[0]}'] = condition_data['x'].values[0]\n                row_data[f'y_level_{condition.split(\" \")[0]}'] = condition_data['y'].values[0]\n\n        # Add the row data to the result_rows list\n        result_rows.append(row_data)\n\n    # Convert the result_rows list to a DataFrame\n    df_result = pd.DataFrame(result_rows)\n    \n    #dummy varables\n    columns_to_encode = 'level'\n    df_encoded = pd.get_dummies(df_result[columns_to_encode], columns=columns_to_encode, prefix=columns_to_encode)\n    df_encoded = df_encoded.astype(float)# Convert boolean True/False to 1.0/0.0\n    df_result['level_array'] = df_encoded.values.tolist()\n    #result=pd.concat([df_result,df_encoded],axis=1)\n    df_result = df_result.drop(columns=columns_to_encode)\n    \n    return df_result","metadata":{"execution":{"iopub.status.busy":"2024-09-18T07:02:22.021110Z","iopub.execute_input":"2024-09-18T07:02:22.021508Z","iopub.status.idle":"2024-09-18T07:02:22.042027Z","shell.execute_reply.started":"2024-09-18T07:02:22.021469Z","shell.execute_reply":"2024-09-18T07:02:22.040981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"###mask crop\nfrom skimage.measure import regionprops, label\n\ndef crop_image_using_multiclass_mask(original_image, mask):\n    # Convert tensor to NumPy array\n    original_image_np = np.squeeze(original_image) # Remove channel dimension\n    ori_image_pil = Image.fromarray(original_image_np)\n   \n    # Get unique class labels from the mask\n    unique_labels = np.unique(mask)\n    \n    cropped_images = {label: [] for label in unique_labels if label != 0}  # Exclude background (label 0)\n\n    # Iterate through each unique label (except background)\n    for label in unique_labels:\n        if label == 0:\n            continue\n\n        # Find regions with the current label\n        labeled_mask = (mask_np == label).astype(int)\n        regions = regionprops(labeled_mask)\n\n        # Crop the image using the bounding boxes from the mask regions\n        for region in regions:\n            minr, minc, maxr, maxc = region.bbox\n            #print(region.bbox)\n            y,x = (minr+ maxr)/2 , (minc+maxc)/2\n            size_half = 32 // 2\n            x_start, x_end = max(0, x - size_half), min(ori_image_pil.width, x + size_half)\n            y_start, y_end = max(0, y - size_half), min(ori_image_pil.height, y + size_half)\n            cropped_img = ori_image_pil.crop((x_start, y_start, x_end, y_end))\n            cropped_img=np.array(cropped_img)\n            cropped_images[label].append(cropped_img)\n\n    return cropped_images\n\n\n# Example usage\nimg, label=spinal_lo_dataset[1]\noriginal_image_np = np.array(img)  # Assuming img is a PIL Image or a numpy array\nmask_np = outputs[1]  # Assuming outputs is a tensor or numpy array\n\ncropped_images = crop_image_using_multiclass_mask(original_image_np, mask_np)\n","metadata":{"execution":{"iopub.status.busy":"2024-09-18T07:12:29.960695Z","iopub.execute_input":"2024-09-18T07:12:29.961762Z","iopub.status.idle":"2024-09-18T07:12:29.995691Z","shell.execute_reply.started":"2024-09-18T07:12:29.961707Z","shell.execute_reply":"2024-09-18T07:12:29.994737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"####################### data file proccess ####################","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv(train_)\nseries_df = pd.read_csv(train_series)\nlabel_df = pd.read_csv(train_label)\ndf = pd.merge(label_df, series_df , on=['study_id','series_id'])\ndf = pd.merge(df,train_df,on = 'study_id')\ndf_spinal, df_neural,df_subarticular = reconstruct_df(df)\n\n#spinal\ndf_spinal_xy =xy_spinal_neural(df_spinal)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"spinal_train_df, spinal_val_df=train_test_split(df_spinal_xy,test_size=0.3,random_state=208)\nprint(f\"size for train:{len(spinal_train_df)}\")\nprint(f\"size for validation:{len(spinal_val_df)}\")","metadata":{"execution":{"iopub.status.busy":"2024-09-18T07:22:10.471404Z","iopub.execute_input":"2024-09-18T07:22:10.471826Z","iopub.status.idle":"2024-09-18T07:22:10.481037Z","shell.execute_reply.started":"2024-09-18T07:22:10.471785Z","shell.execute_reply":"2024-09-18T07:22:10.479753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def data_process_spinal(df):\n    location_level  = [col for col in df.columns if '_level_' in col]\n    condition_columns = [col for col in df.columns if col.startswith('spinal_canal_stenosis_')]\n\n    # Melt the DataFrame to create a row for each condition\n    df_melted = pd.melt(df, id_vars=['study_id', 'series_id', 'instance_number', 'series_description'], \n                        value_vars=condition_columns, \n                        var_name='condition', value_name='severity')\n    df_melted[['d', 'level']] = df_melted['condition'].str.split('_', n=3, expand=True).iloc[:, [0, 3]]\n    df_melted=df_melted.drop(columns=['d'])\n    \n    df_location=df.copy()\n    df_location = df.drop(columns=condition_columns)\n    df_location=df_location.drop(columns=['series_description', 'condition'])\n    \n    # Merge the DataFrames on common columns\n    merged_df = pd.merge(df_melted, df_location, on=['study_id', 'series_id', 'instance_number'], how='left')\n\n    # Function to extract x and y based on the level\n    def get_coordinates(row):\n        level = row['level']\n        if level == 'l1_l2':\n            return row['x_level_l1_l2'], row['y_level_l1_l2']\n        elif level == 'l2_l3':\n            return row['x_level_l2_l3'], row['y_level_l2_l3']\n        elif level == 'l3_l4':\n            return row['x_level_l3_l4'], row['y_level_l3_l4']\n        elif level == 'l4_l5':\n            return row['x_level_l4_l5'], row['y_level_l4_l5']\n        elif level == 'l5_s1':\n            return row['x_level_l5_s1'], row['y_level_l5_s1']\n        else:\n            return None, None\n\n    # Apply the function to create x and y columns\n    merged_df[['x', 'y']] = merged_df.apply(get_coordinates, axis=1, result_type='expand')\n    merged_df = merged_df.sort_values(by=['study_id', 'series_id', 'instance_number'])\n    df_final=merged_df.drop(columns=location_level)\n    \n    # dummy variables on severity\n    dummy_var=pd.get_dummies(df_final['severity'],columns=['severity'])\n    dummy_var=dummy_var[['Normal/Mild','Moderate','Severe']]\n    dummy_var=dummy_var.astype('float')\n    df_final['label_array']=dummy_var.values.tolist()\n    \n    # create image_id columns\n    df_final['image_id'] = [f\"{row['study_id']}_{row['series_id']}_{row['instance_number']}\" for _, row in df_final.iterrows()]\n    \n    # Map the \"level\" column to create \"level_id\"\n    level_mapping = {\n    'l1_l2': 1,\n    'l2_l3': 2,\n    'l3_l4': 3,\n    'l4_l5': 4,\n    'l5_s1': 5\n    }\n    df_final['level_id'] = df_final['level'].map(level_mapping)\n\n    return df_final","metadata":{"execution":{"iopub.status.busy":"2024-09-18T07:37:28.701145Z","iopub.execute_input":"2024-09-18T07:37:28.702007Z","iopub.status.idle":"2024-09-18T07:37:28.715733Z","shell.execute_reply.started":"2024-09-18T07:37:28.701961Z","shell.execute_reply":"2024-09-18T07:37:28.714639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"spinal_train=data_process_spinal(spinal_train_df)\nspinal_val=data_process_spinal(spinal_val_df)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T07:37:30.851830Z","iopub.execute_input":"2024-09-18T07:37:30.852466Z","iopub.status.idle":"2024-09-18T07:37:31.702992Z","shell.execute_reply.started":"2024-09-18T07:37:30.852424Z","shell.execute_reply":"2024-09-18T07:37:31.702114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"spinal_train.head()","metadata":{"execution":{"iopub.status.busy":"2024-09-18T07:37:31.704735Z","iopub.execute_input":"2024-09-18T07:37:31.705518Z","iopub.status.idle":"2024-09-18T07:37:31.722064Z","shell.execute_reply.started":"2024-09-18T07:37:31.705469Z","shell.execute_reply":"2024-09-18T07:37:31.721084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_severity_value(spinal_train, spinal_val):\n    # Create the subplots\n    f, ax = plt.subplots(1, 2, figsize=(10, 5))\n\n    # Plot 1: Severity distribution in spinal_train\n    severity_counts = spinal_train['severity'].value_counts()\n    bars = ax[0].bar(severity_counts.index, severity_counts.values)\n    ax[0].set_xlabel('Severity')\n    ax[0].set_ylabel('Frequency')\n    ax[0].set_title('Distribution of Severity in spinal_train')\n    for bar in bars:\n        height = bar.get_height()\n        ax[0].text(bar.get_x() + bar.get_width() / 2, height, f'{height}', ha='center', va='bottom')\n\n    # Plot 2: Severity distribution in spinal_ori2\n    severity_counts = spinal_val['severity'].value_counts()\n    bars = ax[1].bar(severity_counts.index, severity_counts.values)\n    ax[1].set_xlabel('Severity')\n    ax[1].set_ylabel('Frequency')\n    ax[1].set_title('Distribution of Severity in spinal_ori2')\n    for bar in bars:\n        height = bar.get_height()\n        ax[1].text(bar.get_x() + bar.get_width() / 2, height, f'{height}', ha='center', va='bottom')\n\n    plt.tight_layout()\n    plt.show()\n    \nplot_severity_value(spinal_train, spinal_val)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T07:37:36.790113Z","iopub.execute_input":"2024-09-18T07:37:36.790966Z","iopub.status.idle":"2024-09-18T07:37:37.247630Z","shell.execute_reply.started":"2024-09-18T07:37:36.790928Z","shell.execute_reply":"2024-09-18T07:37:37.246701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Group by both 'severity' and 'level' and count the occurrences\n#severity_level_counts = spinal_lo2.groupby(['severity', 'level']).size().reset_index(name='count')\n\n# Display the grouped counts\n#print(severity_level_counts)\n\ndef group_by_counts(df_train,df_ori2): \n    # Group by both 'severity' and 'level' and count the occurrences\n    severity_level_counts = df_train.groupby(['severity', 'level']).size().reset_index(name='count')\n    # Display the grouped counts\n    print('train_set: \\n',severity_level_counts)\n    print('*' *30)\n\n    severity_level_counts = df_ori2.groupby(['severity', 'level']).size().reset_index(name='count')\n    # Display the grouped counts\n    print('ori2_set: \\n',severity_level_counts)\n    print('*' *30)\n\ngroup_by_counts(spinal_train,spinal_val)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T07:37:45.798787Z","iopub.execute_input":"2024-09-18T07:37:45.799175Z","iopub.status.idle":"2024-09-18T07:37:45.817830Z","shell.execute_reply.started":"2024-09-18T07:37:45.799136Z","shell.execute_reply":"2024-09-18T07:37:45.816946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def data_balance(df,spinal_ori2,n_normal=50,train=False):\n    normal = df[df['severity']=='Normal/Mild']\\\n    .groupby('level')\\\n    .apply(lambda x : x.sample(n=min(n_normal,len(x)), random_state =42))\\\n    .reset_index(drop=True)\n    \n    moderate = df[df['severity']=='Moderate']\n    severe = df[df['severity']=='Severe']\n    \n    if train is True:\n        severe_ori2 = spinal_ori2[spinal_ori2['severity']=='Severe']\n        #severe_lo2 = spinal_lo2[spinal_lo2['severity']=='Severe']\n        df_severe=pd.concat([severe,severe_ori2])\n        #df_severe_duplicated = pd.concat([df_severe,df_severe,df_severe], ignore_index=True)\n        train_set = pd.concat([normal,moderate,df_severe])#df_severe_duplicated])\n        final_set = train_set.sort_values(['study_id','series_id','instance_number']).reset_index(drop=True)\n        return final_set\n    else:\n        train_set = pd.concat([normal,moderate,severe])\n        final_set = train_set.sort_values(['study_id','series_id','instance_number']).reset_index(drop=True)\n        return final_set","metadata":{"execution":{"iopub.status.busy":"2024-09-18T07:37:48.770961Z","iopub.execute_input":"2024-09-18T07:37:48.771914Z","iopub.status.idle":"2024-09-18T07:37:48.781043Z","shell.execute_reply.started":"2024-09-18T07:37:48.771870Z","shell.execute_reply":"2024-09-18T07:37:48.779796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_set=data_balance(spinal_train,spinal_val,n_normal=120,train=True)\nval_set=data_balance(spinal_val,spinal_val,n_normal=40,train=False)\n\nprint(train_set.shape)\nprint(val_set.shape)\n\nplot_severity_value(train_set,val_set)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:34:23.881136Z","iopub.execute_input":"2024-09-18T10:34:23.881550Z","iopub.status.idle":"2024-09-18T10:34:24.299448Z","shell.execute_reply.started":"2024-09-18T10:34:23.881511Z","shell.execute_reply":"2024-09-18T10:34:24.298517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_set.head(5)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T07:38:51.133235Z","iopub.execute_input":"2024-09-18T07:38:51.133990Z","iopub.status.idle":"2024-09-18T07:38:51.150726Z","shell.execute_reply.started":"2024-09-18T07:38:51.133949Z","shell.execute_reply":"2024-09-18T07:38:51.149795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class spinal_lo_Dataset(Dataset):\n    def __init__(self, df, image_dir, transform=None):\n        self.df = df\n        self.img_dir = image_dir\n        self.transform = transform\n\n        # Default transform if none provided\n        if self.transform is None:\n            self.transform = T.Compose([\n                T.Resize((256, 256)),\n                T.ToTensor()\n            ])\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        # Get the image and mask for the given index\n        image, image_id = self.get_images(idx)\n\n        # Apply transformations to the image (if any)\n        image = self.transform(image)\n\n        # Ensure image and mask are of type float32 for model compatibility\n        image = torch.tensor(image, dtype=torch.float32)\n        \n        return image, image_id\n\n    def get_images(self, idx):\n        # Fetch the row for the given index\n        row = self.df.iloc[idx]\n\n        # Load DICOM image\n        dicom_path = os.path.join(self.img_dir, str(row['study_id']), str(row['series_id']), f\"{str(row['instance_number'])}.dcm\")\n        dicom = pydicom.dcmread(dicom_path)\n        image = dicom.pixel_array\n\n        # Normalize the image to the range 0-255 and convert it to RGB\n        image_normalized = np.interp(image, (0, 1810), (0, 255)).astype(np.uint8)  #(n,n)\n        rgb_image_pil = Image.fromarray(image_normalized)\n        \n        # Image_id\n        image_id = row['image_id']\n\n        return rgb_image_pil, image_id\n","metadata":{"execution":{"iopub.status.busy":"2024-09-18T07:53:50.911855Z","iopub.execute_input":"2024-09-18T07:53:50.912256Z","iopub.status.idle":"2024-09-18T07:53:50.923960Z","shell.execute_reply.started":"2024-09-18T07:53:50.912218Z","shell.execute_reply":"2024-09-18T07:53:50.923031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"spinal_train_dataset= spinal_lo_Dataset(train_set,img_train_path,transform=None)\nspinal_val_dataset= spinal_lo_Dataset(val_set,img_train_path,transform=None)\n\nspinal_train_loader = DataLoader(spinal_train_dataset,batch_size=32,shuffle=False,num_workers=5,pin_memory=True )\nspinal_val_loader=DataLoader(spinal_val_dataset,batch_size=32,shuffle=False,num_workers=5,pin_memory=True)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T08:13:15.502788Z","iopub.execute_input":"2024-09-18T08:13:15.503197Z","iopub.status.idle":"2024-09-18T08:13:15.510141Z","shell.execute_reply.started":"2024-09-18T08:13:15.503157Z","shell.execute_reply":"2024-09-18T08:13:15.508966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#################### Unet Mask #####################\nimport segmentation_models_pytorch as smp\n# Define the model: U-Net with a VGG16 backbone\nspinal_vgg16 = smp.Unet(\n    encoder_name=\"vgg16\",           # Choose the backbone VGG16\n    encoder_weights=\"imagenet\",     # Use pre-trained weights from ImageNet\n    in_channels=1,                  # Input channel size (e.g., 1 for grayscale, 3 for RGB)\n    classes=6                       # Number of output classes (e.g., 5 spinal levels + background)\n)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T08:01:50.953008Z","iopub.execute_input":"2024-09-18T08:01:50.953714Z","iopub.status.idle":"2024-09-18T08:01:53.591526Z","shell.execute_reply.started":"2024-09-18T08:01:50.953679Z","shell.execute_reply":"2024-09-18T08:01:53.590472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def model_loc(model, data_loader):\n    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n    model.to(device)\n    print(f\"Device: {device}\")\n    \n    coor_outputs = []\n    images_id = []\n    \n    model.eval()\n    \n    with torch.no_grad():\n        for images, image_id in data_loader:\n            images = images.to(device)\n            \n            outputs = model(images)\n            _, preds = torch.max(outputs, 1)\n            \n            coor_outputs.append(preds.cpu().numpy())  # Append NumPy arrays\n            images_id.extend(image_id)  # Convert tensor to list if necessary\n    \n    # Concatenate predictions\n    coor_outputs = np.concatenate(coor_outputs, axis=0)\n    \n    # Check dimensions before creating DataFrame\n    #print(f'images_id length: {len(images_id)}')\n    #print(f'coor_outputs shape: {coor_outputs.shape}')\n    \n    # Create DataFrame\n    df_output = pd.DataFrame({\n        'image_id': images_id,\n        'mask': list(coor_outputs)  # Ensure mask column is properly formatted\n    })\n    \n    return df_output\n","metadata":{"execution":{"iopub.status.busy":"2024-09-18T08:13:28.431013Z","iopub.execute_input":"2024-09-18T08:13:28.431922Z","iopub.status.idle":"2024-09-18T08:13:28.439991Z","shell.execute_reply.started":"2024-09-18T08:13:28.431877Z","shell.execute_reply":"2024-09-18T08:13:28.438977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_coor = unet_vgg16\nmodel_coor.load_state_dict(torch.load('/kaggle/input/unet_spinal/pytorch/default/1/lo_last_vgg16.pth'))\ndf_mask_train = model_loc(model_coor,spinal_train_loader)\ndf_mask_val = model_loc(model_coor,spinal_val_loader)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T08:13:28.736896Z","iopub.execute_input":"2024-09-18T08:13:28.737449Z","iopub.status.idle":"2024-09-18T08:13:43.722733Z","shell.execute_reply.started":"2024-09-18T08:13:28.737412Z","shell.execute_reply":"2024-09-18T08:13:43.721566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def model_plot(test_dataset, output):\n    f, ax = plt.subplots(1, 2, figsize=(13,8 ))\n    \n    img, _= test_dataset\n    image = img.permute(1, 2, 0)\n    #height, weight = image.shape[:2]\n\n    # Original image with label scatter plot\n    ax[0].imshow(image, cmap='gray')\n    #ax[0].imshow(mask, cmap='jet', alpha=0.5)\n        \n    # Model prediction\n    ax[1].imshow(image, cmap='gray')\n    ax[1].imshow(output,cmap='jet',alpha=0.5)\n\n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-09-18T08:13:52.290693Z","iopub.execute_input":"2024-09-18T08:13:52.291102Z","iopub.status.idle":"2024-09-18T08:13:52.298192Z","shell.execute_reply.started":"2024-09-18T08:13:52.291065Z","shell.execute_reply":"2024-09-18T08:13:52.297186Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_plot(spinal_val_dataset[1], df_mask_val['mask'][1])","metadata":{"execution":{"iopub.status.busy":"2024-09-18T08:13:52.596816Z","iopub.execute_input":"2024-09-18T08:13:52.597495Z","iopub.status.idle":"2024-09-18T08:13:53.451582Z","shell.execute_reply.started":"2024-09-18T08:13:52.597457Z","shell.execute_reply":"2024-09-18T08:13:53.450707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport torch\nfrom PIL import Image\n\n\ndef crop_image_using_multiclass_mask(original_image, mask):\n    # Convert tensor to NumPy array\n    original_image_np = np.squeeze(original_image) # Remove channel dimension\n    ori_image_pil = Image.fromarray(original_image_np)\n   \n    # Get unique class labels from the mask\n    unique_labels = np.unique(mask)\n    \n    cropped_images = {label: [] for label in unique_labels if label != 0}  # Exclude background (label 0)\n\n    # Iterate through each unique label (except background)\n    for label in unique_labels:\n        if label == 0:\n            continue\n\n        # Find regions with the current label\n        labeled_mask = (mask == label).astype(int)\n        #print(labeled_mask)\n        regions = regionprops(labeled_mask)\n        #print(regions)\n\n        # Crop the image using the bounding boxes from the mask regions\n        for region in regions:\n            minr, minc, maxr, maxc = region.bbox\n            #print(region.bbox)\n            y,x = (minr+ maxr)/2 , (minc+maxc)/2\n            size_half = 32 // 2\n            x_start, x_end = max(0, x - size_half), min(ori_image_pil.width, x + size_half)\n            y_start, y_end = max(0, y - size_half), min(ori_image_pil.height, y + size_half)\n            cropped_img = ori_image_pil.crop((x_start, y_start, x_end, y_end))\n            cropped_img=np.array(cropped_img)\n            cropped_images[label].append(cropped_img)\n\n    return cropped_images\n\n\n# Example usage\nimg, label=spinal_val_dataset[1]\noriginal_image_np = np.array(img)  # Assuming img is a PIL Image or a numpy array\nmask_np = df_mask_val['mask'][1]  # Assuming outputs is a tensor or numpy array\n\ncropped_images = crop_image_using_multiclass_mask(original_image_np, mask_np)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T08:53:06.960512Z","iopub.execute_input":"2024-09-18T08:53:06.961294Z","iopub.status.idle":"2024-09-18T08:53:06.990890Z","shell.execute_reply.started":"2024-09-18T08:53:06.961253Z","shell.execute_reply":"2024-09-18T08:53:06.989959Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class SpinalSevereDataset(Dataset):\n    def __init__(self, df, image_dir, Unet_mask_df, transform=None):\n        self.df = df\n        self.img_dir = image_dir\n        self.transform = transform\n        self.Unet_mask_df = Unet_mask_df\n        \n        # Initialize transformation if not provided\n        if self.transform is None:\n            self.transform = T.Compose([\n                T.Resize((32, 32)),  # Ensure the final size is handled correctly\n                T.ToTensor(),\n                # T.Normalize(norm_mean, norm_std)  # Uncomment if normalization is needed\n            ])\n    \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, idx):\n        # Get the image and label for the given index\n        image, label = self.get_image_label(idx)\n        \n        # Apply transformations\n        image = self.transform(image)\n        \n        image = torch.tensor(image, dtype=torch.float32)\n        label = torch.tensor(label, dtype=torch.long)\n        \n        return image, label\n    \n    def get_image_label(self, idx):\n        row = self.df.iloc[idx]\n        mask_id = row['image_id']\n        mask_row = self.Unet_mask_df[self.Unet_mask_df['image_id'] == mask_id].iloc[0]\n        \n        dicom_path = os.path.join(self.img_dir, str(row['study_id']), str(row['series_id']), f\"{str(row['instance_number'])}.dcm\")\n        dicom = pydicom.dcmread(dicom_path)\n        image = dicom.pixel_array\n        \n        # Normalize the image\n        image_normalized = np.interp(image, (0, 1810), (0, 255)).astype(np.uint8)\n        \n        # Convert to PIL Image\n        rgb_image_pil = Image.fromarray(image_normalized)\n        \n        # Resize the image using PIL\n        rgb_image_pil = rgb_image_pil.resize((256, 256), Image.BILINEAR)\n        \n        # Get cropped image\n        cropped_image = self.crop_mask(row, mask_row, rgb_image_pil)\n        \n        # Get label\n        label = row['label_array'].index(1)\n        \n        return cropped_image, label\n    \n    def crop_mask(self, row, mask_row, ori_image_pil):\n        level = row['level_id']\n        mask_np = mask_row['mask']\n        labeled_mask = (mask_np == level).astype(int)\n        regions = regionprops(labeled_mask)\n        \n        # Initialize cropped image with zeros\n        cropped_img = np.zeros((32, 32), dtype=np.uint8)\n        \n        # Crop the image using the bounding boxes from the mask regions\n        for region in regions:\n            minr, minc, maxr, maxc = region.bbox\n            y, x = (minr + maxr) / 2, (minc + maxc) / 2\n            size_half = 32 // 2\n            x_start, x_end = max(0, x - size_half), min(ori_image_pil.width, x + size_half)\n            y_start, y_end = max(0, y - size_half), min(ori_image_pil.height, y + size_half)\n            cropped_pil_img = ori_image_pil.crop((x_start, y_start, x_end, y_end))\n            cropped_img = np.array(cropped_pil_img)\n        \n        # Ensure the image is a PIL Image if more transformations are needed\n        return Image.fromarray(cropped_img)\n","metadata":{"execution":{"iopub.status.busy":"2024-09-18T09:38:05.425174Z","iopub.execute_input":"2024-09-18T09:38:05.425581Z","iopub.status.idle":"2024-09-18T09:38:05.441834Z","shell.execute_reply.started":"2024-09-18T09:38:05.425540Z","shell.execute_reply":"2024-09-18T09:38:05.440941Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = SpinalSevereDataset(train_set, img_train_path, df_mask_train,transform=None)\nval_dataset = SpinalSevereDataset(val_set, img_train_path, df_mask_val, transform=None)\n\ntrain_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=32, shuffle=False)\n","metadata":{"execution":{"iopub.status.busy":"2024-09-18T09:38:08.236460Z","iopub.execute_input":"2024-09-18T09:38:08.237461Z","iopub.status.idle":"2024-09-18T09:38:08.243474Z","shell.execute_reply.started":"2024-09-18T09:38:08.237416Z","shell.execute_reply":"2024-09-18T09:38:08.242490Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img,a = val_dataset[1]\nimage = img.permute(1, 2, 0)\nprint(a)\nplt.imshow(image)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T09:38:08.535507Z","iopub.execute_input":"2024-09-18T09:38:08.535823Z","iopub.status.idle":"2024-09-18T09:38:08.826548Z","shell.execute_reply.started":"2024-09-18T09:38:08.535790Z","shell.execute_reply":"2024-09-18T09:38:08.825616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2024-09-09T05:24:47.320883Z","iopub.execute_input":"2024-09-09T05:24:47.321638Z","iopub.status.idle":"2024-09-09T05:24:47.32906Z","shell.execute_reply.started":"2024-09-09T05:24:47.321598Z","shell.execute_reply":"2024-09-09T05:24:47.328057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_and_evaluate(model,train_loader,val_loader,optimizer,scheduler,num_epochs=10):\n    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n    model.to(device)\n    print(device)\n    \n    criterion = nn.CrossEntropyLoss(reduction='mean')\n    optimizer = optimizer\n    scheduler = scheduler\n    \n    train_loss_set,val_loss_set = [],[]\n    acc_train_set,acc_val_set=[],[]\n    best_test_loss = float('inf')\n    \n    train_start = time.time()\n    for epoch in range(num_epochs):\n        model.train()\n        total_loss = 0.0 \n        #train_acc_sum =0.0\n        all_train_labels,all_train_outputs=[],[]\n        for inputs, labels in train_loader:\n            inputs, labels = inputs.to(device), labels.to(device)\n            optimizer.zero_grad()\n            outputs = model(inputs)\n            loss = criterion(outputs,labels)\n            loss.backward()\n            optimizer.step()\n            \n            # record result\n            total_loss += loss.item()\n            all_train_labels.extend(labels.cpu().detach().numpy())\n            outputs=outputs.argmax(dim=1)\n            all_train_outputs.extend(outputs.cpu().detach().numpy())\n            \n        average_train_loss = total_loss / len(train_loader) \n        train_accuracy=accuracy_score(all_train_labels,all_train_outputs)* 100\n        train_loss_set.append(average_train_loss)\n        acc_train_set.append(train_accuracy)\n        scheduler.step()\n        \n        #model for validation with val loader\n        model.eval()\n        total_loss = 0.0\n        correct = 0\n        total = 0\n        with torch.no_grad():\n            for inputs, targets in val_loader:\n                inputs, targets = inputs.to(device), targets.to(device)\n                outputs = model(inputs)\n                loss = criterion(outputs, targets)\n                total_loss += loss.item()\n                _, predicted = outputs.max(1)\n                correct += predicted.eq(targets).sum().item()\n                total += targets.size(0)\n\n        val_avg_loss = total_loss / len(val_loader)\n        val_accuracy = correct / total * 100\n        val_loss_set.append(val_avg_loss)\n        acc_val_set.append(val_accuracy)\n    \n\n        \n        current_lr = optimizer.param_groups[0]['lr']\n        #average_test_loss = average_val1_loss + average_val2_loss\n        if average_train_loss < best_test_loss:\n            best_test_loss = average_train_loss\n            torch.save(model.state_dict(),f'best_movile_spinal.pth')\n            print(f'best loss::{best_test_loss}')\n        print(\n            f'Epoch {epoch+1}/{num_epochs}: \\t '\n            f'Lr: {current_lr},\\t '\n            f'train loss: {average_train_loss:.4f},\\t '\n            f'train acc: {train_accuracy:.2f}% , \\t'\n            f'val loss: {val_avg_loss:.4f}, \\t '\n            f'val acc: {val_accuracy:.2f}% , \\t '\n        )\n        print('-'*80)\n            \n    train_end = time.time()\n    time_used = train_end-train_start\n    print(f'Time used for Training:{time_used} sec ')\n    print('-'* 80)\n    \n    train_history_df=pd.DataFrame({\n        'train_loss': train_loss_set,\n        'train_accuracy': acc_train_set ,\n        'val_loss': val_loss_set ,\n        'val_accuracy': acc_val_set ,\n    })\n    \n    torch.save(model.state_dict(),f'last_mobile_spinal.pth')\n    return model,train_history_df\n\n","metadata":{"execution":{"iopub.status.busy":"2024-09-18T09:58:26.508045Z","iopub.execute_input":"2024-09-18T09:58:26.508490Z","iopub.status.idle":"2024-09-18T09:58:26.525585Z","shell.execute_reply.started":"2024-09-18T09:58:26.508448Z","shell.execute_reply":"2024-09-18T09:58:26.524607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_history(train_loss_history,val_loss_history,):\n    epochs= range(1,len(train_loss_history)+1)\n    plt.plot(epochs,train_loss_history,label=\"Train Loss\")\n    plt.plot(epochs,val_loss_history,label=\"val1 Loss\")\n    #plt.plot(epochs,val2_loss_history,label=\"val2 Loss\")\n    plt.xlabel('Epochs')\n    plt.ylabel('loss')\n    plt.title(\"train loss on model spinal\")\n    plt.legend()\n    plt.tight_layout()\n    plt.show()\n\n\ndef evaluation_model(model, test_loader):\n    device= torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n    model.to(device)\n    print(device)\n    model.eval()\n\n    all_test_labels = []\n    all_test_outputs = []\n\n    with torch.no_grad():\n        for inputs, labels in test_loader:\n            inputs, labels = inputs.to(device), labels.to(device)\n\n            # Get model outputs (logits)\n            outputs = model(inputs)\n\n            # Convert logits to probabilities using softmax\n            preds = F.softmax(outputs, dim=1)\n\n            # Collect labels and predicted probabilities\n            all_test_labels.extend(labels.cpu().numpy())\n            all_test_outputs.extend(preds.detach().cpu().numpy())\n\n    # Convert to numpy arrays\n    all_test_labels = np.array(all_test_labels)\n    all_test_outputs = np.array(all_test_outputs)\n\n    # Number of classes\n    n_classes = all_test_outputs.shape[1]\n\n    # Initialize dictionaries for ROC curve metrics\n    fpr = dict()\n    tpr = dict()\n    roc_auc = dict()\n\n    # Compute ROC curve and AUC for each class\n    for i in range(n_classes):\n        fpr[i], tpr[i], _ = roc_curve(all_test_labels == i, all_test_outputs[:, i])\n        roc_auc[i] = auc(fpr[i], tpr[i])\n\n    # Plot ROC curves for each class\n    plt.figure(figsize=(12, 6))\n    for i in range(n_classes):\n        plt.plot(fpr[i], tpr[i], label=f'Class {i} (AUC = {roc_auc[i]:.2f})')\n\n    plt.plot([0, 1], [0, 1], color='gray', linestyle='--')\n    plt.xlabel('False Positive Rate')\n    plt.ylabel('True Positive Rate')\n    plt.title('Multiclass ROC Curve')\n    plt.legend(loc=\"lower right\")\n    plt.show()\n\n    # Classification Report\n    report = classification_report(all_test_labels, np.argmax(all_test_outputs, axis=1), target_names=[f'Class {i}' for i in range(n_classes)])\n    print(\"Classification Report:\")\n    print(report)\n\n    # Confusion Matrix\n    cm = confusion_matrix(all_test_labels, np.argmax(all_test_outputs, axis=1))\n    disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=[f'Class {i}' for i in range(n_classes)])\n    \n    # Plot Confusion Matrix\n    plt.figure(figsize=(8, 6))\n    disp.plot(cmap=plt.cm.Blues)\n    plt.title('Confusion Matrix')\n    plt.show()\n    ","metadata":{"execution":{"iopub.status.busy":"2024-09-18T09:58:28.138088Z","iopub.execute_input":"2024-09-18T09:58:28.138869Z","iopub.status.idle":"2024-09-18T09:58:28.154648Z","shell.execute_reply.started":"2024-09-18T09:58:28.138827Z","shell.execute_reply":"2024-09-18T09:58:28.153718Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"######################################## MODEL FOR SEVERITY CLASSIFICATION ###################################################","metadata":{"execution":{"iopub.status.busy":"2024-09-07T12:59:59.927571Z","iopub.execute_input":"2024-09-07T12:59:59.928496Z","iopub.status.idle":"2024-09-07T12:59:59.932856Z","shell.execute_reply.started":"2024-09-07T12:59:59.928454Z","shell.execute_reply":"2024-09-07T12:59:59.931887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class spinal_mobile(nn.Module):\n    def __init__(self, num_classes=3):\n        super(spinal_mobile, self).__init__()\n        # Load the pretrained MobileNetV2 model\n        self.mobilenet_v2 = models.mobilenet_v2(pretrained=True)\n        \n        # Modify the first convolutional layer to accept 1 channel instead of 3\n        in_channels = self.mobilenet_v2.features[0][0].in_channels\n        out_channels = self.mobilenet_v2.features[0][0].out_channels\n        kernel_size = self.mobilenet_v2.features[0][0].kernel_size\n        stride = self.mobilenet_v2.features[0][0].stride\n        padding = self.mobilenet_v2.features[0][0].padding\n        \n        self.pool = nn.AdaptiveAvgPool2d(1)\n        \n        # Replace the first conv layer\n        self.mobilenet_v2.features[0][0] = nn.Conv2d(1, out_channels, kernel_size, stride, padding, bias=False)\n        \n        # Reinitialize the weights for the new conv layer\n        nn.init.kaiming_normal_(self.mobilenet_v2.features[0][0].weight, mode='fan_out', nonlinearity='relu')\n        \n        # Adjust the fully connected layer according to your specific needs\n        self.mobilenet_v2.classifier[1] = nn.Linear(self.mobilenet_v2.classifier[1].in_features, num_classes)\n    \n    def forward(self, x):\n        x = self.mobilenet_v2.features(x)\n        x = self.pool(x)\n        x = torch.flatten(x, 1)\n        x = self.mobilenet_v2.classifier(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2024-09-18T09:35:53.566879Z","iopub.execute_input":"2024-09-18T09:35:53.567888Z","iopub.status.idle":"2024-09-18T09:35:53.580610Z","shell.execute_reply.started":"2024-09-18T09:35:53.567832Z","shell.execute_reply":"2024-09-18T09:35:53.579487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = spinal_mobile(num_classes=3)  # Example with 10 classes\noptimizer=torch.optim.AdamW(model.parameters(), lr=0.001)\nscheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)\nmodel,df_loss_history= train_and_evaluate(model,train_loader,val_loader,optimizer,scheduler,num_epochs=20)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:12:04.166411Z","iopub.execute_input":"2024-09-18T10:12:04.166820Z","iopub.status.idle":"2024-09-18T10:22:46.335089Z","shell.execute_reply.started":"2024-09-18T10:12:04.166782Z","shell.execute_reply":"2024-09-18T10:22:46.334148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_history(df_loss_history['train_loss'],df_loss_history['val_loss'])","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:28:22.481194Z","iopub.execute_input":"2024-09-18T10:28:22.481895Z","iopub.status.idle":"2024-09-18T10:28:22.852044Z","shell.execute_reply.started":"2024-09-18T10:28:22.481855Z","shell.execute_reply":"2024-09-18T10:28:22.851073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#torch.save(model_best.state_dict(),f'spinal_moblt.pth')","metadata":{"execution":{"iopub.status.busy":"2024-08-30T12:42:58.887087Z","iopub.execute_input":"2024-08-30T12:42:58.888012Z","iopub.status.idle":"2024-08-30T12:42:58.936128Z","shell.execute_reply.started":"2024-08-30T12:42:58.887967Z","shell.execute_reply":"2024-08-30T12:42:58.935402Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"evaluation_model(model, val_loader)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:28:33.153717Z","iopub.execute_input":"2024-09-18T10:28:33.154627Z","iopub.status.idle":"2024-09-18T10:28:42.203795Z","shell.execute_reply.started":"2024-09-18T10:28:33.154585Z","shell.execute_reply":"2024-09-18T10:28:42.202874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"evaluation_model(model, train_loader)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:28:42.205685Z","iopub.execute_input":"2024-09-18T10:28:42.206248Z","iopub.status.idle":"2024-09-18T10:29:06.818455Z","shell.execute_reply.started":"2024-09-18T10:28:42.206200Z","shell.execute_reply":"2024-09-18T10:29:06.817615Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Display all images from val2_dataset on a grid\ndef show_all_val2_dataset(val2_dataset):\n    num_images = len(val2_dataset)\n    cols = 8  # Define the number of columns you want\n    rows = (num_images // cols) + (1 if num_images % cols != 0 else 0)  # Calculate number of rows\n\n    fig, axes = plt.subplots(rows, cols, figsize=(15, rows * 2))\n\n    # Flatten axes array for easy iteration\n    axes = axes.flatten()\n\n    for i in range(num_images):\n        img, label = val2_dataset[i]\n\n        # Convert tensor image to NumPy array if necessary\n        if isinstance(img, torch.Tensor):\n            img = img.permute(1, 2, 0).numpy()  # Adjust shape from (C, H, W) to (H, W, C)\n\n        # Show image on the subplot\n        axes[i].imshow(img)\n        axes[i].set_title(f'Label: {label}')\n        axes[i].axis('off')\n\n    # Turn off remaining empty subplots\n    for j in range(i+1, len(axes)):\n        axes[j].axis('off')\n\n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:30:04.757721Z","iopub.execute_input":"2024-09-18T10:30:04.758644Z","iopub.status.idle":"2024-09-18T10:30:04.766506Z","shell.execute_reply.started":"2024-09-18T10:30:04.758594Z","shell.execute_reply":"2024-09-18T10:30:04.765562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Show all images from the val2_dataset\nshow_all_val2_dataset(train_dataset)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:30:59.309173Z","iopub.execute_input":"2024-09-18T10:30:59.309484Z","iopub.status.idle":"2024-09-18T10:32:46.454065Z","shell.execute_reply.started":"2024-09-18T10:30:59.309451Z","shell.execute_reply":"2024-09-18T10:32:46.452423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_all_val2_dataset(val_dataset)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:30:22.209482Z","iopub.execute_input":"2024-09-18T10:30:22.210337Z","iopub.status.idle":"2024-09-18T10:30:59.307641Z","shell.execute_reply.started":"2024-09-18T10:30:22.210285Z","shell.execute_reply":"2024-09-18T10:30:59.306455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}