{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":23870,"databundleVersionId":1781260,"sourceType":"competition"}],"dockerImageVersionId":30043,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Data Loading","metadata":{"papermill":{"duration":0.021363,"end_time":"2020-12-14T19:52:40.311302","exception":false,"start_time":"2020-12-14T19:52:40.289939","status":"completed"},"tags":[]}},{"cell_type":"code","source":"!python -V","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T00:05:09.560078Z","iopub.execute_input":"2025-05-08T00:05:09.560419Z","iopub.status.idle":"2025-05-08T00:05:10.618458Z","shell.execute_reply.started":"2025-05-08T00:05:09.56037Z","shell.execute_reply":"2025-05-08T00:05:10.61756Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\nimport pandas as pd\n\nfrom matplotlib import pyplot as plt\nimport seaborn as sns","metadata":{"execution":{"iopub.status.busy":"2025-05-07T23:21:16.110533Z","iopub.execute_input":"2025-05-07T23:21:16.110849Z","iopub.status.idle":"2025-05-07T23:21:16.114253Z","shell.execute_reply.started":"2025-05-07T23:21:16.110822Z","shell.execute_reply":"2025-05-07T23:21:16.113576Z"},"papermill":{"duration":1.015612,"end_time":"2020-12-14T19:52:41.346578","exception":false,"start_time":"2020-12-14T19:52:40.330966","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"os.listdir('../input/ranzcr-clip-catheter-line-classification')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T23:21:16.120585Z","iopub.execute_input":"2025-05-07T23:21:16.120823Z","iopub.status.idle":"2025-05-07T23:21:16.12585Z","shell.execute_reply.started":"2025-05-07T23:21:16.120801Z","shell.execute_reply":"2025-05-07T23:21:16.125099Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train = pd.read_csv('../input/ranzcr-clip-catheter-line-classification/train.csv')\ntest = pd.read_csv('../input/ranzcr-clip-catheter-line-classification/sample_submission.csv')\ndisplay(train.head())\ndisplay(test.head())","metadata":{"execution":{"iopub.status.busy":"2025-05-07T23:21:16.136555Z","iopub.execute_input":"2025-05-07T23:21:16.136762Z","iopub.status.idle":"2025-05-07T23:21:16.233111Z","shell.execute_reply.started":"2025-05-07T23:21:16.136742Z","shell.execute_reply":"2025-05-07T23:21:16.232228Z"},"papermill":{"duration":0.084553,"end_time":"2020-12-14T19:52:41.45243","exception":false,"start_time":"2020-12-14T19:52:41.367877","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Quick EDA","metadata":{}},{"cell_type":"code","source":"train['PatientID'].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T23:21:16.235115Z","iopub.execute_input":"2025-05-07T23:21:16.235492Z","iopub.status.idle":"2025-05-07T23:21:16.24674Z","shell.execute_reply.started":"2025-05-07T23:21:16.235454Z","shell.execute_reply":"2025-05-07T23:21:16.245978Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"target_cols = ['ETT - Abnormal', 'ETT - Borderline', 'ETT - Normal', 'NGT - Abnormal', \n               'NGT - Borderline', 'NGT - Incompletely Imaged', 'NGT - Normal', 'CVC - Abnormal',\n               'CVC - Borderline', 'CVC - Normal', 'Swan Ganz Catheter Present']\nfor c in target_cols:\n    plt.hist(train[c].values)\n    plt.title(f'target: {c}')\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T23:21:16.247868Z","iopub.execute_input":"2025-05-07T23:21:16.248121Z","iopub.status.idle":"2025-05-07T23:21:17.534981Z","shell.execute_reply.started":"2025-05-07T23:21:16.248098Z","shell.execute_reply":"2025-05-07T23:21:17.534207Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"View the basic information of the TFRecord file：\nFirst of all, we can read the original records of some TFRecord files to see what information is contained in each record. This can help us understand the format and structure of the data.","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\n\n# Read TFRecord file\ntfrecord_file = '/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/00-1881.tfrec'\nraw_dataset = tf.data.TFRecordDataset(tfrecord_file)\n\n# Define parsing function to print field names\ndef parse_example(proto):\n    # Parse a simple Example\n    parsed_features = tf.io.parse_single_example(proto, {\n        'image': tf.io.FixedLenFeature([], tf.string)  # Parse only the image field\n    })\n    print(parsed_features.keys())\n    print(parsed_features)  # Print each record's fields\n    parsed_features['image'] = tf.io.decode_jpeg(parsed_features['image'])  # Decode image\n    return parsed_features\n\n# View the fields of the first few records\nfor raw_record in raw_dataset.take(5):\n    parse_example(raw_record)  # Print without returning data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T23:39:54.239499Z","iopub.execute_input":"2025-05-07T23:39:54.239801Z","iopub.status.idle":"2025-05-07T23:39:54.51318Z","shell.execute_reply.started":"2025-05-07T23:39:54.239777Z","shell.execute_reply":"2025-05-07T23:39:54.511961Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Parse image function\ndef parse_example(proto):\n    # Parse the image field\n    parsed_features = tf.io.parse_single_example(proto, {\n        'image': tf.io.FixedLenFeature([], tf.string),  # Parse the image\n    })\n    \n    # Decode the image\n    parsed_features['image'] = tf.io.decode_jpeg(parsed_features['image'])\n    return parsed_features['image']\n\n# View the images of the first few records\nfor raw_record in raw_dataset.take(5):\n    image = parse_example(raw_record)\n    print(f\"Image shape: {image.shape}\")\n    print(f\"Image dtype: {image.dtype}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T23:21:17.823488Z","iopub.execute_input":"2025-05-07T23:21:17.823811Z","iopub.status.idle":"2025-05-07T23:21:17.86463Z","shell.execute_reply.started":"2025-05-07T23:21:17.82378Z","shell.execute_reply":"2025-05-07T23:21:17.86383Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# View feature names of a single sample\nfor raw_record in raw_dataset.take(1):\n    parsed = tf.io.parse_single_example(raw_record, {\n        'image': tf.io.FixedLenFeature([], tf.string),  # Parse the image field\n    })\n    print(parsed.keys())  # Output the field names present in the sample","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T23:21:17.866826Z","iopub.execute_input":"2025-05-07T23:21:17.867048Z","iopub.status.idle":"2025-05-07T23:21:17.879478Z","shell.execute_reply.started":"2025-05-07T23:21:17.867027Z","shell.execute_reply":"2025-05-07T23:21:17.878843Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nfor raw_record in raw_dataset.take(5):\n    image = parse_example(raw_record)\n    plt.imshow(image.numpy().reshape(1024, 1024), cmap='gray')  # Display the image\n    plt.axis('off')  # Remove axes\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T23:21:17.880525Z","iopub.execute_input":"2025-05-07T23:21:17.880749Z","iopub.status.idle":"2025-05-07T23:21:18.572749Z","shell.execute_reply.started":"2025-05-07T23:21:17.880726Z","shell.execute_reply":"2025-05-07T23:21:18.57202Z"},"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Calculate the total number of records\nrecord_count = 0\nfor _ in raw_dataset:\n    record_count += 1\nprint(f\"Total records in all TFRecord files: {record_count}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T23:21:18.573738Z","iopub.execute_input":"2025-05-07T23:21:18.573948Z","iopub.status.idle":"2025-05-07T23:21:18.827526Z","shell.execute_reply.started":"2025-05-07T23:21:18.573927Z","shell.execute_reply":"2025-05-07T23:21:18.826602Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"It should be noted here that the 16th one, namely 15-1881, has only 1868 pictures","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\n\n# Generate file paths from 00-1881.tfrec to 15-1881.tfrec\ntfrecord_files = [f\"/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/{str(i).zfill(2)}-1881.tfrec\" for i in range(16)]\n\n# Iterate through each TFRecord file and count the number of records\nfor file in tfrecord_files:\n    dataset = tf.data.TFRecordDataset(file)\n    \n    # Count the number of records in the current file\n    record_count = sum(1 for _ in dataset)\n    \n    print(f\"File {file} contains {record_count} records.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T23:21:18.828786Z","iopub.execute_input":"2025-05-07T23:21:18.829128Z","iopub.status.idle":"2025-05-07T23:21:23.20812Z","shell.execute_reply.started":"2025-05-07T23:21:18.829089Z","shell.execute_reply":"2025-05-07T23:21:23.207229Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n# Generate file paths from 00-1881.tfrec to 04-1881.tfrec\ntfrecord_files = [f\"/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/{str(i).zfill(2)}-1881.tfrec\" for i in range(5)]\n\ndef parse_example(proto):\n    # Define the parsing process, assuming 'image' is the image field\n    parsed_features = tf.io.parse_single_example(proto, {\n        'image': tf.io.FixedLenFeature([], tf.string)  # Image field\n    })\n    image = tf.io.decode_jpeg(parsed_features['image'])  # Decode JPEG image\n    return image\n\n# Iterate through each TFRecord file and extract images\nfor file in tfrecord_files:\n    dataset = tf.data.TFRecordDataset(file)\n    print(f\"Processing {file}...\")\n    \n    for i, raw_record in enumerate(dataset):\n        image = parse_example(raw_record)\n        \n        # Get image shape and type\n        print(f\"Image {i+1}:\")\n        print(f\"  Shape: {image.shape}\")\n        print(f\"  Dtype: {image.dtype}\")\n        \n        # Display pixel value distribution\n        pixel_values = image.numpy().flatten()\n        plt.figure(figsize=(10, 4))\n        \n        # Plot histogram\n        plt.subplot(1, 2, 1)\n        plt.hist(pixel_values, bins=50, color='gray', alpha=0.7)\n        plt.title(f\"Pixel Value Distribution for Image {i+1}\")\n        plt.xlabel('Pixel Value')\n        plt.ylabel('Frequency')\n\n        # Show image\n        plt.subplot(1, 2, 2)\n        plt.imshow(np.squeeze(image.numpy()), cmap='gray')\n        plt.title(f\"Image {i+1}\")\n        plt.axis('off')\n        \n        plt.show()\n\n        if i >= 4:  # Limit to analyzing the first 5 images for efficiency\n            break","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T23:21:23.209291Z","iopub.execute_input":"2025-05-07T23:21:23.209564Z","iopub.status.idle":"2025-05-07T23:21:30.830165Z","shell.execute_reply.started":"2025-05-07T23:21:23.209538Z","shell.execute_reply":"2025-05-07T23:21:30.829314Z"},"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for raw_record in raw_dataset.take(1):\n    example = tf.train.Example()\n    example.ParseFromString(raw_record.numpy())\n    print(example)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T23:21:30.831624Z","iopub.execute_input":"2025-05-07T23:21:30.831987Z","iopub.status.idle":"2025-05-07T23:21:30.902137Z","shell.execute_reply.started":"2025-05-07T23:21:30.831949Z","shell.execute_reply":"2025-05-07T23:21:30.901383Z"},"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom PIL import Image\nimport io\nimport matplotlib.pyplot as plt\n\n# Define the structured fields of interest\nlabel_keys = [\n    \"CVC - Abnormal\", \"CVC - Borderline\", \"CVC - Normal\",\n    \"ETT - Abnormal\", \"ETT - Borderline\", \"ETT - Normal\",\n    \"NGT - Abnormal\", \"NGT - Borderline\", \"NGT - Incompletely Imaged\", \"NGT - Normal\",\n    \"Swan Ganz Catheter Present\"\n]\n\n# Read the dataset\nraw_dataset = tf.data.TFRecordDataset(\"/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/01-1881.tfrec\")\n\nfor raw_record in raw_dataset.take(6):  # Extract only a few samples\n    example = tf.train.Example()\n    example.ParseFromString(raw_record.numpy())\n\n    # Extract image data\n    image_bytes = example.features.feature[\"image\"].bytes_list.value[0]\n    image = Image.open(io.BytesIO(image_bytes))\n\n    # Extract labels\n    labels = {key: example.features.feature[key].int64_list.value[0] for key in label_keys}\n    \n    # Display image and labels\n    plt.imshow(image)\n    plt.axis(\"off\")\n    plt.title(\"Labels: \" + \", \".join(f\"{k}:{v}\" for k, v in labels.items() if v != 0))\n    plt.show()\n\n    print(\"StudyInstanceUID:\", example.features.feature[\"StudyInstanceUID\"].bytes_list.value[0].decode())\n    print(\"All extracted labels:\", labels)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T23:21:30.903599Z","iopub.execute_input":"2025-05-07T23:21:30.903823Z","iopub.status.idle":"2025-05-07T23:21:31.686491Z","shell.execute_reply.started":"2025-05-07T23:21:30.903799Z","shell.execute_reply":"2025-05-07T23:21:31.6857Z"},"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nimport pandas as pd\nfrom PIL import Image\nimport io\nimport numpy as np\n\ndef load_tfrecord_to_dataframe(file_pattern, label_keys):\n    # Create an empty list to store data\n    data = []\n\n    # Read TFRecord file\n    raw_dataset = tf.data.TFRecordDataset(file_pattern)\n\n    # Iterate through TFRecord file\n    for raw_record in raw_dataset.batch(16):  # Limit the number of records read at a time\n        for record in raw_record:\n            example = tf.train.Example()\n            example.ParseFromString(record.numpy())\n\n            # Extract StudyInstanceUID\n            study_instance_uid = example.features.feature[\"StudyInstanceUID\"].bytes_list.value[0].decode()\n\n            # Extract image data\n            image_bytes = example.features.feature[\"image\"].bytes_list.value[0]\n            image = Image.open(io.BytesIO(image_bytes))\n            \n            # Resize image to 64x64\n            image = image.resize((64, 64), Image.ANTIALIAS)\n            image_array = np.array(image)  # Convert to array\n\n            # Extract labels\n            labels = {key: example.features.feature[key].int64_list.value[0] for key in label_keys}\n\n            # Combine StudyInstanceUID, labels, and image into a dictionary\n            record = {\"StudyInstanceUID\": study_instance_uid, **labels, \"image\": image_array}\n            \n            # Add to data list\n            data.append(record)\n\n    # Convert data to DataFrame\n    df = pd.DataFrame(data)\n    return df\n\n# Define structured fields of interest\nlabel_keys = [\n    \"CVC - Abnormal\", \"CVC - Borderline\", \"CVC - Normal\",\n    \"ETT - Abnormal\", \"ETT - Borderline\", \"ETT - Normal\",\n    \"NGT - Abnormal\", \"NGT - Borderline\", \"NGT - Incompletely Imaged\", \"NGT - Normal\",\n    \"Swan Ganz Catheter Present\"\n]\n\n# Use the function to load data\nfile_pattern = \"/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/00-1881.tfrec\"\ndf = load_tfrecord_to_dataframe(file_pattern, label_keys)\n\n# Display the first few rows\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T06:28:05.686069Z","iopub.execute_input":"2025-05-08T06:28:05.686461Z","iopub.status.idle":"2025-05-08T06:28:41.693279Z","shell.execute_reply.started":"2025-05-08T06:28:05.686424Z","shell.execute_reply":"2025-05-08T06:28:41.692229Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Assume you want to display the first image\nimage_data = df['image'][0]  # Get the first image array\n\n# Display the image\nplt.imshow(image_data, cmap='gray')  # Use appropriate color mapping\nplt.axis('off')  # Hide axes\nplt.title(f\"StudyInstanceUID: {df['StudyInstanceUID'][0]}\")  # Show UID\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T05:44:47.996559Z","iopub.execute_input":"2025-05-08T05:44:47.996888Z","iopub.status.idle":"2025-05-08T05:44:48.062312Z","shell.execute_reply.started":"2025-05-08T05:44:47.996858Z","shell.execute_reply":"2025-05-08T05:44:48.061515Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load data using functions\nfile_pattern = \"/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/01-1881.tfrec\"\ndf1 = load_tfrecord_to_dataframe(file_pattern, label_keys)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T05:44:51.071016Z","iopub.execute_input":"2025-05-08T05:44:51.071324Z","iopub.status.idle":"2025-05-08T05:45:18.914892Z","shell.execute_reply.started":"2025-05-08T05:44:51.071288Z","shell.execute_reply":"2025-05-08T05:45:18.91412Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load df1 by merging multiple TFRecord files\ndf1 = pd.DataFrame()  # Initialize an empty DataFrame\n\nfor i in range(1, 9):  # From 01 to 08\n    file_pattern = f\"/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/0{i}-1881.tfrec\"\n    temp_df = load_tfrecord_to_dataframe(file_pattern, label_keys)\n    df1 = pd.concat([df1, temp_df], ignore_index=True)  # Merge DataFrames\n\n# Print results to confirm\nprint(f\"Loaded df1 with {len(df1)} records.\")\nprint(df1.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T06:40:10.049532Z","iopub.execute_input":"2025-05-08T06:40:10.04988Z","iopub.status.idle":"2025-05-08T06:42:46.095708Z","shell.execute_reply.started":"2025-05-08T06:40:10.049851Z","shell.execute_reply":"2025-05-08T06:42:46.094388Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df[df['Swan Ganz Catheter Present'] == 1]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T02:49:23.572761Z","iopub.execute_input":"2025-05-08T02:49:23.573036Z","iopub.status.idle":"2025-05-08T02:49:23.589524Z","shell.execute_reply.started":"2025-05-08T02:49:23.57301Z","shell.execute_reply":"2025-05-08T02:49:23.588426Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Initialize an empty list for data\ndata = []\n\n# Iterate through TFRecord files\nfor raw_record in raw_dataset:\n    example = tf.train.Example()\n    example.ParseFromString(raw_record.numpy())\n\n    # Extract labels\n    labels = {key: example.features.feature[key].int64_list.value[0] for key in label_keys}\n    \n    # Add labels to the data list\n    data.append(labels)\n\n# Convert labels to DataFrame\ndf = pd.DataFrame(data)\n\n# Calculate frequency of each label\nlabel_frequencies = df.sum()\n\n# Plot histogram\nplt.figure(figsize=(12, 6))\nlabel_frequencies.plot(kind='bar', color='skyblue', edgecolor='black')\nplt.title('Frequency of Label Categories')\nplt.xlabel('Label Categories')\nplt.ylabel('Frequency')\nplt.xticks(rotation=45, ha='right')\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T23:21:53.182062Z","iopub.execute_input":"2025-05-07T23:21:53.182278Z","iopub.status.idle":"2025-05-07T23:21:53.943462Z","shell.execute_reply.started":"2025-05-07T23:21:53.182257Z","shell.execute_reply":"2025-05-07T23:21:53.942709Z"},"jupyter":{"outputs_hidden":true},"collapsed":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# May cause a merge error\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\n# Calculate the frequency of each tag\nlabel_frequencies = df.sum()\n\n# Draw a pie chart\nplt.figure(figsize=(8, 8))\nplt.pie(label_frequencies, labels=label_frequencies.index, autopct='%1.1f%%', startangle=140) colors=plt.cm.Paired.colors)\nplt.title('Label Categories Frequency Distribution')\nplt.axis('equal') # makes the pie chart circular\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T23:21:53.944498Z","iopub.execute_input":"2025-05-07T23:21:53.944716Z","iopub.status.idle":"2025-05-07T23:21:54.052716Z","shell.execute_reply.started":"2025-05-07T23:21:53.944694Z","shell.execute_reply":"2025-05-07T23:21:54.051986Z"},"jupyter":{"outputs_hidden":true},"collapsed":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"import pandas as pd\n\n# Read Data\ntrain_df = pd.read_csv(\"/kaggle/input/ranzcr-clip-catheter-line-classification/train.csv\")\nannotations_df = pd.read_csv(\"/kaggle/input/ranzcr-clip-catheter-line-classification/train_annotations.csv\")\n\n# Merge annotations_df and train_df\nmerged_df = pd.merge(annotations_df, train_df, on='StudyInstanceUID', how='left')\n\n# Merge df and merged_df, and only retain the rows existing in df\nmerged_df1 = pd.merge(df[['StudyInstanceUID', 'image']], merged_df, on='StudyInstanceUID', how='inner')\n\n# Merge df1 and merged_df, and only retain the rows existing in df1\n\nmerged_df2 = pd.merge(df1[['StudyInstanceUID', 'image']], merged_df, on='StudyInstanceUID', how='inner')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T06:37:01.311324Z","iopub.execute_input":"2025-05-08T06:37:01.311659Z","iopub.status.idle":"2025-05-08T06:37:01.612736Z","shell.execute_reply.started":"2025-05-08T06:37:01.31163Z","shell.execute_reply":"2025-05-08T06:37:01.611844Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(merged_df1.isnull().sum())\nprint(merged_df2.isnull().sum())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T06:09:48.949367Z","iopub.execute_input":"2025-05-08T06:09:48.949703Z","iopub.status.idle":"2025-05-08T06:09:48.959597Z","shell.execute_reply.started":"2025-05-08T06:09:48.949672Z","shell.execute_reply":"2025-05-08T06:09:48.958756Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"merged_df1.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T06:12:48.409387Z","iopub.execute_input":"2025-05-08T06:12:48.409703Z","iopub.status.idle":"2025-05-08T06:12:48.709641Z","shell.execute_reply.started":"2025-05-08T06:12:48.40967Z","shell.execute_reply":"2025-05-08T06:12:48.708857Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"merged_df1 = pd.merge(df[['StudyInstanceUID', 'image']], merged_df, on='StudyInstanceUID', how='inner')\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"merged_df1.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T06:43:22.327059Z","iopub.execute_input":"2025-05-08T06:43:22.327414Z","iopub.status.idle":"2025-05-08T06:43:22.671541Z","shell.execute_reply.started":"2025-05-08T06:43:22.327383Z","shell.execute_reply":"2025-05-08T06:43:22.670586Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(f\"Number of rows in merged_df1: {merged_df1.shape[0]}\")\nprint(f\"Number of rows in merged_df2: {merged_df2.shape[0]}\")\n\n# Check which ids did not merge successfully\nmissing_ids_df1 = df[~df['StudyInstanceUID'].isin(merged_df1['StudyInstanceUID'])]\nmissing_ids_df2 = df1[~df1['StudyInstanceUID'].isin(merged_df2['StudyInstanceUID'])]\n\nprint(\"Missing IDs in merged_df1:\")\nprint(missing_ids_df1)\n\nprint(\"Missing IDs in merged_df2:\")\nprint(missing_ids_df2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T06:27:50.515278Z","iopub.execute_input":"2025-05-08T06:27:50.515532Z","iopub.status.idle":"2025-05-08T06:27:50.548532Z","shell.execute_reply.started":"2025-05-08T06:27:50.515505Z","shell.execute_reply":"2025-05-08T06:27:50.547275Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport cv2\nimport matplotlib.pyplot as plt\n\n# Assume you already have image data\nimage_data = df['image'][0]  # Get the first image array\nimage_with_boxes = image_data.copy()  # Create a copy for drawing\n\n# Original coordinate data\ncoordinates = [\n    [1487, 1279], [1477, 1168], [1472, 1052], [1464, 924],\n    [1453, 827], [1443, 755], [1434, 640], [1404, 514],\n    [1387, 497], [1360, 541], [1290, 617], [1228, 696],\n    [1179, 776], [1116, 880], [1065, 963], [1031, 999]\n]\n\n# Scaling factor\nscale_factor = 64 / 2048  # Scale from 2048 to 64\n\n# Scale coordinates and draw\nfor point in coordinates:\n    scaled_point = [int(point[0] * scale_factor), int(point[1] * scale_factor)]\n    cv2.circle(image_with_boxes, tuple(scaled_point), radius=1, color=(0, 0, 0), thickness=-1)  # Black dots\n\n# Display the image\nplt.imshow(image_with_boxes, cmap='gray')  # Use appropriate color mapping\nplt.axis('off')  # Hide axes\nplt.title(\"Image with Points\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T03:55:49.409117Z","iopub.execute_input":"2025-05-08T03:55:49.409404Z","iopub.status.idle":"2025-05-08T03:55:49.454626Z","shell.execute_reply.started":"2025-05-08T03:55:49.409379Z","shell.execute_reply":"2025-05-08T03:55:49.453955Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Check for mismatches between two DataFrames\nimport pandas as pd\n\n# Assume df1 and df2 are your two DataFrames\ncolumns_to_check = [\n    \"ETT - Abnormal\", \"ETT - Borderline\", \"ETT - Normal\",\n    \"NGT - Abnormal\", \"NGT - Borderline\", \"NGT - Incompletely Imaged\", \"NGT - Normal\",\n    \"CVC - Abnormal\", \"CVC - Borderline\", \"CVC - Normal\",\n    \"Swan Ganz Catheter Present\"\n]\n\n# Merge the two DataFrames\nmerged_df = pd.merge(df[columns_to_check], df1[columns_to_check], left_index=True, right_index=True, suffixes=('_df1', '_df2'))\n\n# Check for inconsistent values\ninconsistent_rows = merged_df[merged_df.filter(like='_df1').ne(merged_df.filter(like='_df2')).any(axis=1)]\n\n# Output inconsistent rows\nprint(inconsistent_rows)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T02:56:34.272189Z","iopub.execute_input":"2025-05-08T02:56:34.272534Z","iopub.status.idle":"2025-05-08T02:56:34.29504Z","shell.execute_reply.started":"2025-05-08T02:56:34.272509Z","shell.execute_reply":"2025-05-08T02:56:34.294011Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Train","metadata":{}},{"cell_type":"markdown","source":"---\n","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import IterableDataset, DataLoader\nfrom PIL import Image\nimport io\nimport numpy as np\nfrom torch.utils.data import Dataset\n\n\n# 1. Define IterableDataset to load data on-demand\nclass TFRecordMultimodalDataset(Dataset):\n    def __init__(self, tfrecord_pattern, label_keys, final_df, image_size=(64, 64)):\n        self.tfrecord_files = tf.io.gfile.glob(tfrecord_pattern)\n        self.raw_dataset = list(tf.data.TFRecordDataset(self.tfrecord_files))\n        self.label_keys = label_keys\n        self.final_df = final_df\n        self.image_size = image_size\n\n    def __len__(self):\n        return len(self.raw_dataset)\n\n    def __getitem__(self, idx):\n        record = self.raw_dataset[idx]\n        example = tf.train.Example()\n        example.ParseFromString(record.numpy())\n\n        # Decode image\n        image_bytes = example.features.feature[\"image\"].bytes_list.value[0]\n        image = Image.open(io.BytesIO(image_bytes)).resize(self.image_size).convert(\"RGB\")\n        image = np.array(image).astype(np.float32) / 255.0\n        image = torch.tensor(image).permute(2, 0, 1)\n\n        # Get UID and label\n        uid = example.features.feature[\"StudyInstanceUID\"].bytes_list.value[0].decode()\n        labels_df = self.final_df[self.final_df[\"StudyInstanceUID\"] == uid]\n        if labels_df.empty:\n            label = torch.tensor(0)  # Default label (not recommended for long-term use)\n        else:\n            label = torch.tensor(labels_df.iloc[0][self.label_keys[0]])  # Use first label for testing\n\n        return image, label\n\nclass TFRecordIterableMultimodal(IterableDataset):\n    def __init__(self, tfrecord_pattern, final_df, label_keys, image_size=(64, 64)):\n        self.files = tf.io.gfile.glob(tfrecord_pattern)\n        self.final_df = final_df.set_index('StudyInstanceUID')\n        self.label_keys = label_keys\n        self.image_size = image_size\n\n    def _parse_and_preprocess(self, raw_record):\n        ex = tf.train.Example()\n        ex.ParseFromString(raw_record.numpy())\n        uid = ex.features.feature[\"StudyInstanceUID\"].bytes_list.value[0].decode()\n        \n        try:\n            row = self.final_df.loc[uid]\n        except KeyError:\n            return None\n    \n        image_bytes = ex.features.feature[\"image\"].bytes_list.value[0]\n        image = Image.open(io.BytesIO(image_bytes)).resize(self.image_size).convert(\"RGB\")\n        image = np.array(image).astype(np.float32) / 255.0\n        image = torch.tensor(image).permute(2, 0, 1)\n    \n        label = row[self.label_keys[0]]\n        return image, label\n\n    def __iter__(self):\n        # tf.data pipeline\n        ds = tf.data.TFRecordDataset(self.files)\n        for raw in ds:\n            item = self._parse_and_preprocess(raw)\n            if item is not None:\n                yield item","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T06:05:17.780172Z","iopub.execute_input":"2025-05-08T06:05:17.780445Z","iopub.status.idle":"2025-05-08T06:05:17.796952Z","shell.execute_reply.started":"2025-05-08T06:05:17.780422Z","shell.execute_reply":"2025-05-08T06:05:17.796156Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Define the label keys\nlabel_keys = [\n    'ETT - Abnormal_x', 'ETT - Borderline_x', 'ETT - Normal_x',\n    'NGT - Abnormal_x', 'NGT - Borderline_x', 'NGT - Incompletely Imaged_x', 'NGT - Normal_x',\n    'CVC - Abnormal_x', 'CVC - Borderline_x', 'CVC - Normal_x',\n    'Swan Ganz Catheter Present_x', 'PatientID',\n    'CVC - Abnormal_y', 'CVC - Borderline_y', 'CVC - Normal_y',\n    'ETT - Abnormal_y', 'ETT - Borderline_y', 'ETT - Normal_y',\n    'NGT - Abnormal_y', 'NGT - Borderline_y', 'NGT - Incompletely Imaged_y', 'NGT - Normal_y',\n    'Swan Ganz Catheter Present_y', 'label', 'data'\n]\n\n# Create datasets for training and validation\ndataset = TFRecordIterableMultimodal(\n    \"/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/00-1881.tfrec\",\n    merged_df1,\n    label_keys,\n    image_size=(64, 64)  # Use 64x64 for now\n)\n\ndataset_val = TFRecordIterableMultimodal(\n    \"/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/01-1881.tfrec\",\n    merged_df2,\n    label_keys,\n    image_size=(64, 64)  # Use 64x64 for now\n)\n\n# Create data loaders\nloader = DataLoader(\n    dataset,\n    batch_size=8,  # Reduce batch size\n    num_workers=0,  # Avoid issues with multi-threading\n    pin_memory=True,\n)\n\nval_loader = DataLoader(\n    dataset_val,\n    batch_size=8,  # Reduce batch size\n    pin_memory=True,\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T06:05:19.32488Z","iopub.execute_input":"2025-05-08T06:05:19.325176Z","iopub.status.idle":"2025-05-08T06:05:19.339313Z","shell.execute_reply.started":"2025-05-08T06:05:19.325151Z","shell.execute_reply":"2025-05-08T06:05:19.338613Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Fetch a single batch of data\nfor imgs, labels in loader:\n    print(f\"📷 Image size: {imgs.shape}\")      # Expected shape: (batch_size, 3, 64, 64)\n    print(f\"🏷️ Labels: {labels}\")               # e.g. tensor([0, 1, 0, ...])\n    print(f\"🏷️ Label type: {labels.dtype}\")     # Should be torch.long\n    break","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T05:53:25.42836Z","iopub.execute_input":"2025-05-08T05:53:25.428692Z","iopub.status.idle":"2025-05-08T05:53:25.509287Z","shell.execute_reply.started":"2025-05-08T05:53:25.42866Z","shell.execute_reply":"2025-05-08T05:53:25.507894Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nimport time\nimport numpy as np\n\n# Minimal model\nclass TinyNet(nn.Module):\n    def __init__(self, num_classes=2):\n        super().__init__()\n        self.conv = nn.Conv2d(3, 4, kernel_size=3, padding=1)\n        self.pool = nn.AdaptiveAvgPool2d(1)\n        self.fc = nn.Linear(4, num_classes)\n\n    def forward(self, x):\n        x = torch.relu(self.conv(x))\n        x = self.pool(x).view(x.size(0), -1)\n        return self.fc(x)\n\n#-----------------------------------------------------------------\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel = TinyNet(num_classes=2).to(device)\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=1e-3)\n\n# Training loop\nepochs = 3\nstart_total = time.time()\n# Initialize counters\ntotal_correct = 0\ntotal_samples = 0\n\nfor epoch in range(epochs):\n    model.train()\n    total_loss = 0.0\n    start_epoch = time.time()\n    batch_count = 0\n\n    for imgs, labels in loader:\n        imgs = imgs.to(device)\n        labels = labels.to(device)\n\n        outputs = model(imgs)\n        loss = criterion(outputs, labels)\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        total_loss += loss.item()\n        batch_count += 1\n\n        # Accuracy calculation\n        _, predicted = torch.max(outputs, 1)\n        total_correct += (predicted == labels).sum().item()\n        total_samples += labels.size(0)\n\n    average_loss = total_loss / batch_count if batch_count > 0 else 0\n    accuracy = total_correct / total_samples if total_samples > 0 else 0\n\n    end_epoch = time.time()\n    print(f\"Epoch {epoch+1:02d}  loss = {average_loss:.4f}  accuracy = {accuracy:.4f} \"\n          f\"| time: {end_epoch - start_epoch:.1f}s\")\n\nend_total = time.time()\nprint(f\"✅ Training completed in {end_total - start_total:.1f} seconds.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T05:56:22.143264Z","iopub.execute_input":"2025-05-08T05:56:22.143559Z","iopub.status.idle":"2025-05-08T05:56:22.220326Z","shell.execute_reply.started":"2025-05-08T05:56:22.143533Z","shell.execute_reply":"2025-05-08T05:56:22.218935Z"},"jupyter":{"outputs_hidden":true,"source_hidden":true},"collapsed":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nimport time\nimport numpy as np\n\n# Minimal model\nclass TinyNet(nn.Module):\n    def __init__(self, num_classes=2):\n        super().__init__()\n        self.conv = nn.Conv2d(3, 4, kernel_size=3, padding=1)\n        self.pool = nn.AdaptiveAvgPool2d(1)\n        self.fc = nn.Linear(4, num_classes)\n\n    def forward(self, x):\n        x = torch.relu(self.conv(x))\n        x = self.pool(x).view(x.size(0), -1)\n        return self.fc(x)\n\n#-----------------------------------------------------------------\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel = TinyNet(num_classes=2).to(device)\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=1e-3)\n\n# Training loop\nepochs = 3\nstart_total = time.time()\nfor epoch in range(epochs):\n    model.train()\n    total_loss = 0.0\n    total_correct = 0\n    total_samples = 0\n    start_epoch = time.time()\n    batch_count = 0  # Counter\n\n    for imgs, labels in loader:\n        imgs = imgs.to(device)\n        labels = labels.to(device)\n\n        outputs = model(imgs)\n        loss = criterion(outputs, labels)\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        total_loss += loss.item()\n        total_correct += (outputs.argmax(1) == labels).sum().item()\n        total_samples += labels.size(0)\n        batch_count += 1  # Increment counter for each batch\n\n    # Calculate training accuracy\n    average_loss = total_loss / batch_count if batch_count > 0 else 0\n    accuracy = total_correct / total_samples if total_samples > 0 else 0\n\n    print(f\"Epoch {epoch+1:02d}  loss = {average_loss:.4f}  accuracy = {accuracy:.4f} | time: {time.time() - start_epoch:.1f}s\")\n\n    # Validation step\n    model.eval()\n    val_loss = 0.0\n    val_correct = 0\n    val_samples = 0\n    val_batch_count = 0  # Counter\n\n    with torch.no_grad():\n        for val_imgs, val_labels in val_loader:\n            val_imgs = val_imgs.to(device)\n            val_labels = val_labels.to(device)\n\n            val_outputs = model(val_imgs)\n            val_loss += criterion(val_outputs, val_labels).item()\n            val_correct += (val_outputs.argmax(1) == val_labels).sum().item()\n            val_samples += val_labels.size(0)\n            val_batch_count += 1  # Increment counter for each validation batch\n\n    average_val_loss = val_loss / val_batch_count if val_batch_count > 0 else 0\n    val_accuracy = val_correct / val_samples if val_samples > 0 else 0\n    print(f\"Validation loss = {average_val_loss:.4f}  accuracy = {val_accuracy:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T05:52:45.37868Z","iopub.execute_input":"2025-05-08T05:52:45.378982Z","iopub.status.idle":"2025-05-08T05:52:45.418058Z","shell.execute_reply.started":"2025-05-08T05:52:45.378959Z","shell.execute_reply":"2025-05-08T05:52:45.416219Z"},"jupyter":{"outputs_hidden":true,"source_hidden":true},"collapsed":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#pip install torchvision\n!pip show torch torchvision","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T00:10:16.014653Z","iopub.execute_input":"2025-05-08T00:10:16.014983Z","iopub.status.idle":"2025-05-08T00:10:21.041914Z","shell.execute_reply.started":"2025-05-08T00:10:16.014947Z","shell.execute_reply":"2025-05-08T00:10:21.041088Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader\nfrom torchvision import models\nimport time\n\n# Prepare data and model\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n# Create dataset\nlabel_key = [\n    'ETT - Abnormal_x', 'ETT - Borderline_x', 'ETT - Normal_x', \n    'NGT - Abnormal_x', 'NGT - Borderline_x', 'NGT - Incompletely Imaged_x', \n    'NGT - Normal_x', 'CVC - Abnormal_x', 'CVC - Borderline_x', \n    'CVC - Normal_x', 'Swan Ganz Catheter Present_x', 'PatientID', \n    'CVC - Abnormal_y', 'CVC - Borderline_y', 'CVC - Normal_y', \n    'ETT - Abnormal_y', 'ETT - Borderline_y', 'ETT - Normal_y', \n    'NGT - Abnormal_y', 'NGT - Borderline_y', 'NGT - Incompletely Imaged_y', \n    'NGT - Normal_y', 'Swan Ganz Catheter Present_y', 'label', 'data'\n]\n\ndataset = TFRecordIterableMultimodal(\n    \"/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/01-1881.tfrec\",\n    final_df, \n    label_key,\n    image_size=(224, 224)  # Ensure consistency with model input\n)\n\nloader = DataLoader(\n    dataset,\n    batch_size=8,    # Batch size\n    num_workers=0,   # Set to 0 to avoid freezing\n    pin_memory=True\n)\n\n# Select model\nmodel_name = \"resnet18\"\nif model_name == \"resnet18\":\n    model = models.resnet18(pretrained=True)\n    model.fc = nn.Linear(model.fc.in_features, len(label_key) - 2)  # Modify output layer\nelif model_name == \"efficientnet_b0\":\n    model = models.efficientnet_b0(pretrained=True)\n    model.classifier[1] = nn.Linear(model.classifier[1].in_features, len(label_key) - 2)\nelif model_name == \"mobilenet_v2\":\n    model = models.mobilenet_v2(pretrained=True)\n    model.classifier[1] = nn.Linear(model.classifier[1].in_features, len(label_key) - 2)\n\nmodel = model.to(device)\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=1e-3)\n\n# Training loop\nepochs = 10\nstart_total = time.time()\nfor epoch in range(epochs):\n    model.train()\n    total_loss = 0.0\n    total_correct = 0\n    total_samples = 0  # For accuracy calculation\n    start_epoch = time.time()\n    batch_count = 0  # Batch counter\n\n    for imgs, labels in loader:\n        imgs = imgs.to(device)\n        labels = labels.to(device)\n\n        outputs = model(imgs)\n        loss = criterion(outputs, labels)\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        total_loss += loss.item()\n\n        # Calculate accuracy\n        _, predicted = torch.max(outputs, 1)\n        total_correct += (predicted == labels).sum().item()\n        total_samples += labels.size(0)  # Accumulate sample count\n\n        batch_count += 1  # Increment counter\n\n    end_epoch = time.time()\n    average_loss = total_loss / batch_count if batch_count > 0 else 0  # Calculate average loss\n    accuracy = total_correct / total_samples if total_samples > 0 else 0  # Calculate accuracy\n    \n    print(f\"Epoch {epoch+1:02d}  loss = {average_loss:.4f}  accuracy = {accuracy:.4f} \"\n          f\"| time: {end_epoch - start_epoch:.1f}s\")\n\nend_total = time.time()\nprint(f\"✅ Training completed in {end_total - start_total:.1f} seconds.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T05:37:13.560792Z","iopub.execute_input":"2025-05-08T05:37:13.561114Z","iopub.status.idle":"2025-05-08T05:37:19.449966Z","shell.execute_reply.started":"2025-05-08T05:37:13.561079Z","shell.execute_reply":"2025-05-08T05:37:19.449267Z"},"jupyter":{"outputs_hidden":true,"source_hidden":true},"collapsed":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader\nfrom torchvision import models\nimport time\n\n# Prepare data and model\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n# Create dataset\nlabel_key = [\n    'ETT - Abnormal_x', 'ETT - Borderline_x', 'ETT - Normal_x', \n    'NGT - Abnormal_x', 'NGT - Borderline_x', 'NGT - Incompletely Imaged_x', \n    'NGT - Normal_x', 'CVC - Abnormal_x', 'CVC - Borderline_x', \n    'CVC - Normal_x', 'Swan Ganz Catheter Present_x', 'PatientID', \n    'CVC - Abnormal_y', 'CVC - Borderline_y', 'CVC - Normal_y', \n    'ETT - Abnormal_y', 'ETT - Borderline_y', 'ETT - Normal_y', \n    'NGT - Abnormal_y', 'NGT - Borderline_y', 'NGT - Incompletely Imaged_y', \n    'NGT - Normal_y', 'Swan Ganz Catheter Present_y', 'label', 'data'\n]\n\ndataset = TFRecordIterableMultimodal(\n    \"/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/01-1881.tfrec\",\n    final_df, \n    label_key,\n    image_size=(224, 224)  # Ensure consistency with model input\n)\n\nloader = DataLoader(\n    dataset,\n    batch_size=8,    # Batch size\n    num_workers=0,   # Set to 0 to avoid freezing\n    pin_memory=True\n)\n\n# Select model\nmodel_name = \"mobilenet_v2\"\nif model_name == \"resnet18\":\n    model = models.resnet18(pretrained=True)\n    model.fc = nn.Linear(model.fc.in_features, len(label_key) - 2)  # Modify output layer\nelif model_name == \"efficientnet_b0\":\n    model = models.efficientnet_b0(pretrained=True)\n    model.classifier[1] = nn.Linear(model.classifier[1].in_features, len(label_key) - 2)\nelif model_name == \"mobilenet_v2\":\n    model = models.mobilenet_v2(pretrained=True)\n    model.classifier[1] = nn.Linear(model.classifier[1].in_features, len(label_key) - 2)\n\nmodel = model.to(device)\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=1e-3)\n\n# Training loop\nepochs = 10\nstart_total = time.time()\nfor epoch in range(epochs):\n    model.train()\n    total_loss = 0.0\n    total_correct = 0\n    total_samples = 0  # For accuracy calculation\n    start_epoch = time.time()\n    batch_count = 0  # Batch counter\n\n    for imgs, labels in loader:\n        imgs = imgs.to(device)\n        labels = labels.to(device)\n\n        outputs = model(imgs)\n        loss = criterion(outputs, labels)\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        total_loss += loss.item()\n\n        # Calculate accuracy\n        _, predicted = torch.max(outputs, 1)\n        total_correct += (predicted == labels).sum().item()\n        total_samples += labels.size(0)  # Accumulate sample count\n\n        batch_count += 1  # Increment counter\n\n    end_epoch = time.time()\n    average_loss = total_loss / batch_count if batch_count > 0 else 0  # Calculate average loss\n    accuracy = total_correct / total_samples if total_samples > 0 else 0  # Calculate accuracy\n    \n    print(f\"Epoch {epoch+1:02d}  loss = {average_loss:.4f}  accuracy = {accuracy:.4f} \"\n          f\"| time: {end_epoch - start_epoch:.1f}s\")\n\nend_total = time.time()\nprint(f\"✅ Training completed in {end_total - start_total:.1f} seconds.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T00:33:34.485395Z","iopub.execute_input":"2025-05-08T00:33:34.485711Z","iopub.status.idle":"2025-05-08T00:38:50.494565Z","shell.execute_reply.started":"2025-05-08T00:33:34.485686Z","shell.execute_reply":"2025-05-08T00:38:50.493648Z"},"jupyter":{"outputs_hidden":true,"source_hidden":true},"collapsed":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Check what models can still be run","metadata":{}},{"cell_type":"code","source":"import torchvision.models as models\n\navailable_models = dir(models)\nprint([model for model in available_models if not model.startswith('__')])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T00:40:22.936691Z","iopub.execute_input":"2025-05-08T00:40:22.937008Z","iopub.status.idle":"2025-05-08T00:40:22.942152Z","shell.execute_reply.started":"2025-05-08T00:40:22.93698Z","shell.execute_reply":"2025-05-08T00:40:22.941311Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# mobilenet_v2\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader\nfrom torchvision import models\nimport time\n\n# 准备数据、模型\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n# 创建数据集\nlabel_key = [\n    'ETT - Abnormal_x', 'ETT - Borderline_x', 'ETT - Normal_x', \n    'NGT - Abnormal_x', 'NGT - Borderline_x', 'NGT - Incompletely Imaged_x', \n    'NGT - Normal_x', 'CVC - Abnormal_x', 'CVC - Borderline_x', \n    'CVC - Normal_x', 'Swan Ganz Catheter Present_x', 'PatientID', \n    'CVC - Abnormal_y', 'CVC - Borderline_y', 'CVC - Normal_y', \n    'ETT - Abnormal_y', 'ETT - Borderline_y', 'ETT - Normal_y', \n    'NGT - Abnormal_y', 'NGT - Borderline_y', 'NGT - Incompletely Imaged_y', \n    'NGT - Normal_y', 'Swan Ganz Catheter Present_y', 'label', 'data'\n]\n\ndataset = TFRecordIterableMultimodal(\n    \"/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/01-1881.tfrec\",\n    final_df, \n    label_key,\n    image_size=(224, 224)  # 确保与模型输入一致\n)\n\nloader = DataLoader(\n    dataset,\n    batch_size=8,    # 批次大小\n    num_workers=0,   # 设置为0以避免卡死\n    pin_memory=True\n)\n\n# 选择模型\nmodel_name = \"resnet101\"  # 你可以替换为其他模型，如：resnet152, densenet161, densenet169, densenet201, vgg16, vgg19, inception_v3\nif model_name == \"resnet101\":\n    model = models.resnet101(pretrained=True)\n    model.fc = nn.Linear(model.fc.in_features, len(label_key) - 2)  # 修改输出层\nelif model_name == \"resnet152\":\n    model = models.resnet152(pretrained=True)\n    model.fc = nn.Linear(model.fc.in_features, len(label_key) - 2)\nelif model_name == \"densenet161\":\n    model = models.densenet161(pretrained=True)\n    model.classifier = nn.Linear(model.classifier.in_features, len(label_key) - 2)  # 修改输出层\nelif model_name == \"densenet169\":\n    model = models.densenet169(pretrained=True)\n    model.classifier = nn.Linear(model.classifier.in_features, len(label_key) - 2)\nelif model_name == \"densenet201\":\n    model = models.densenet201(pretrained=True)\n    model.classifier = nn.Linear(model.classifier.in_features, len(label_key) - 2)\nelif model_name == \"vgg16\":\n    model = models.vgg16(pretrained=True)\n    model.classifier[6] = nn.Linear(model.classifier[6].in_features, len(label_key) - 2)  # 修改输出层\nelif model_name == \"vgg19\":\n    model = models.vgg19(pretrained=True)\n    model.classifier[6] = nn.Linear(model.classifier[6].in_features, len(label_key) - 2)  # 修改输出层\nelif model_name == \"inception_v3\":\n    model = models.inception_v3(pretrained=True, aux_logits=False)\n    model.fc = nn.Linear(model.fc.in_features, len(label_key) - 2)  # 修改输出层\n\nmodel = model.to(device)\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=1e-3)\n\n# 训练循环\nepochs = 10\nstart_total = time.time()\nfor epoch in range(epochs):\n    model.train()\n    total_loss = 0.0\n    total_correct = 0\n    total_samples = 0  # 用于计算准确率\n    start_epoch = time.time()\n    batch_count = 0  # 批次数计数器\n\n    for imgs, labels in loader:\n        imgs = imgs.to(device)\n        labels = labels.to(device)\n\n        outputs = model(imgs)\n        loss = criterion(outputs, labels)\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        total_loss += loss.item()\n\n        # 计算准确率\n        _, predicted = torch.max(outputs, 1)\n        total_correct += (predicted == labels).sum().item()\n        total_samples += labels.size(0)  # 累加当前批次的样本数量\n\n        batch_count += 1  # 计数器加一\n\n    end_epoch = time.time()\n    average_loss = total_loss / batch_count if batch_count > 0 else 0  # 计算平均损失\n    accuracy = total_correct / total_samples if total_samples > 0 else 0  # 计算准确率\n    \n    print(f\"Epoch {epoch+1:02d}  loss = {average_loss:.4f}  accuracy = {accuracy:.4f} \"\n          f\"| time: {end_epoch - start_epoch:.1f}s\")\n\nend_total = time.time()\nprint(f\"✅ Training completed in {end_total - start_total:.1f} seconds.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T00:45:26.423113Z","iopub.execute_input":"2025-05-08T00:45:26.423472Z","iopub.status.idle":"2025-05-08T00:50:31.030807Z","shell.execute_reply.started":"2025-05-08T00:45:26.423432Z","shell.execute_reply":"2025-05-08T00:50:31.027969Z"},"collapsed":true,"jupyter":{"source_hidden":true,"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# resnet152\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader\nfrom torchvision import models\nimport time\n\n# 准备数据、模型\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n# 创建数据集\nlabel_key = [\n    'ETT - Abnormal_x', 'ETT - Borderline_x', 'ETT - Normal_x', \n    'NGT - Abnormal_x', 'NGT - Borderline_x', 'NGT - Incompletely Imaged_x', \n    'NGT - Normal_x', 'CVC - Abnormal_x', 'CVC - Borderline_x', \n    'CVC - Normal_x', 'Swan Ganz Catheter Present_x', 'PatientID', \n    'CVC - Abnormal_y', 'CVC - Borderline_y', 'CVC - Normal_y', \n    'ETT - Abnormal_y', 'ETT - Borderline_y', 'ETT - Normal_y', \n    'NGT - Abnormal_y', 'NGT - Borderline_y', 'NGT - Incompletely Imaged_y', \n    'NGT - Normal_y', 'Swan Ganz Catheter Present_y', 'label', 'data'\n]\n\ndataset = TFRecordIterableMultimodal(\n    \"/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/01-1881.tfrec\",\n    final_df, \n    label_key,\n    image_size=(224, 224)  # 确保与模型输入一致\n)\n\nloader = DataLoader(\n    dataset,\n    batch_size=8,    # 批次大小\n    num_workers=0,   # 设置为0以避免卡死\n    pin_memory=True\n)\n\n# 选择模型\nmodel_name = \"resnet101\"  # 你可以替换为其他模型，如：resnet152, densenet161, densenet169, densenet201, vgg16, vgg19, inception_v3\nif model_name == \"resnet101\":\n    model = models.resnet101(pretrained=True)\n    model.fc = nn.Linear(model.fc.in_features, len(label_key) - 2)  # 修改输出层\nelif model_name == \"resnet152\":\n    model = models.resnet152(pretrained=True)\n    model.fc = nn.Linear(model.fc.in_features, len(label_key) - 2)\nelif model_name == \"densenet161\":\n    model = models.densenet161(pretrained=True)\n    model.classifier = nn.Linear(model.classifier.in_features, len(label_key) - 2)  # 修改输出层\nelif model_name == \"densenet169\":\n    model = models.densenet169(pretrained=True)\n    model.classifier = nn.Linear(model.classifier.in_features, len(label_key) - 2)\nelif model_name == \"densenet201\":\n    model = models.densenet201(pretrained=True)\n    model.classifier = nn.Linear(model.classifier.in_features, len(label_key) - 2)\nelif model_name == \"vgg16\":\n    model = models.vgg16(pretrained=True)\n    model.classifier[6] = nn.Linear(model.classifier[6].in_features, len(label_key) - 2)  # 修改输出层\nelif model_name == \"vgg19\":\n    model = models.vgg19(pretrained=True)\n    model.classifier[6] = nn.Linear(model.classifier[6].in_features, len(label_key) - 2)  # 修改输出层\nelif model_name == \"inception_v3\":\n    model = models.inception_v3(pretrained=True, aux_logits=False)\n    model.fc = nn.Linear(model.fc.in_features, len(label_key) - 2)  # 修改输出层\n\nmodel = model.to(device)\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=1e-3)\n\n# 训练循环\nepochs = 3\nstart_total = time.time()\nfor epoch in range(epochs):\n    model.train()\n    total_loss = 0.0\n    total_correct = 0\n    total_samples = 0  # 用于计算准确率\n    start_epoch = time.time()\n    batch_count = 0  # 批次数计数器\n\n    for imgs, labels in loader:\n        imgs = imgs.to(device)\n        labels = labels.to(device)\n\n        outputs = model(imgs)\n        loss = criterion(outputs, labels)\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        total_loss += loss.item()\n\n        # 计算准确率\n        _, predicted = torch.max(outputs, 1)\n        total_correct += (predicted == labels).sum().item()\n        total_samples += labels.size(0)  # 累加当前批次的样本数量\n\n        batch_count += 1  # 计数器加一\n\n    end_epoch = time.time()\n    average_loss = total_loss / batch_count if batch_count > 0 else 0  # 计算平均损失\n    accuracy = total_correct / total_samples if total_samples > 0 else 0  # 计算准确率\n    \n    print(f\"Epoch {epoch+1:02d}  loss = {average_loss:.4f}  accuracy = {accuracy:.4f} \"\n          f\"| time: {end_epoch - start_epoch:.1f}s\")\n\nend_total = time.time()\nprint(f\"✅ Training completed in {end_total - start_total:.1f} seconds.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T00:50:35.469463Z","iopub.execute_input":"2025-05-08T00:50:35.469809Z","iopub.status.idle":"2025-05-08T00:54:02.695817Z","shell.execute_reply.started":"2025-05-08T00:50:35.469771Z","shell.execute_reply":"2025-05-08T00:54:02.694018Z"},"jupyter":{"source_hidden":true,"outputs_hidden":true},"collapsed":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.applications import VGG16","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T00:59:06.34456Z","iopub.execute_input":"2025-05-08T00:59:06.344865Z","iopub.status.idle":"2025-05-08T00:59:06.348639Z","shell.execute_reply.started":"2025-05-08T00:59:06.34484Z","shell.execute_reply":"2025-05-08T00:59:06.34767Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nimport torchvision.models as models\nimport time\n\n# Simple dataset: randomly generate images and labels\nclass DummyDataset(Dataset):\n    def __init__(self, size=200):  # Increase dataset size to improve training effect\n        self.size = size\n\n    def __len__(self):\n        return self.size\n\n    def __getitem__(self, idx):\n        image = torch.rand(3, 224, 224)  # Fake image, adjusted for VGG16 input size\n        label = torch.randint(0, 2, (1,)).item()  # 0 or 1\n        return image, label\n\n# Prepare data and model\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n# Create dataset and data loader\ndataset = DummyDataset(size=200)  # You can adjust the size as needed\nloader = DataLoader(dataset, batch_size=8, shuffle=True, num_workers=0)\n\n# Prepare VGG16 model\nmodel = models.vgg16(pretrained=True)  # Load pretrained VGG16 model\nmodel.classifier[6] = nn.Linear(model.classifier[6].in_features, 2)  # Modify output layer\nmodel = model.to(device)  # Move model to GPU\n\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=1e-3)\n\n# Training loop\nepochs = 10\nstart_total = time.time()\nfor epoch in range(epochs):\n    model.train()\n    total_loss = 0.0\n    total_correct = 0  # Track correct predictions\n    total_samples = 0  # Track total samples\n    start_epoch = time.time()\n    batch_count = 0  # Counter\n\n    for imgs, labels in loader:\n        imgs = imgs.to(device)\n        labels = labels.to(device)\n\n        outputs = model(imgs)\n        loss = criterion(outputs, labels)\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        total_loss += loss.item()\n\n        # Calculate accuracy\n        _, predicted = torch.max(outputs, 1)\n        total_correct += (predicted == labels).sum().item()\n        total_samples += labels.size(0)  # Accumulate current batch sample count\n\n        batch_count += 1  # Increment counter\n\n    end_epoch = time.time()\n    average_loss = total_loss / batch_count if batch_count > 0 else 0  # Calculate average loss\n    accuracy = total_correct / total_samples if total_samples > 0 else 0  # Calculate accuracy\n\n    print(f\"Epoch {epoch+1:02d}  loss = {average_loss:.4f}  accuracy = {accuracy:.4f} \"\n          f\"| time: {end_epoch - start_epoch:.1f}s\")\n\nend_total = time.time()\nprint(f\"✅ Training completed in {end_total - start_total:.1f} seconds.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T01:03:09.224111Z","iopub.execute_input":"2025-05-08T01:03:09.224413Z","iopub.status.idle":"2025-05-08T01:04:32.706444Z","shell.execute_reply.started":"2025-05-08T01:03:09.224378Z","shell.execute_reply":"2025-05-08T01:04:32.704453Z"},"collapsed":true,"jupyter":{"outputs_hidden":true,"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nimport torchvision.models as models\nimport time\n\n# Simple dataset: randomly generate images and labels\nclass DummyDataset(Dataset):\n    def __init__(self, size=200):  # Increase dataset size to improve training effect\n        self.size = size\n\n    def __len__(self):\n        return self.size\n\n    def __getitem__(self, idx):\n        image = torch.rand(3, 224, 224)  # Fake image, adjusted for VGG16 input size\n        label = torch.randint(0, 2, (1,)).item()  # 0 or 1\n        return image, label\n\n# Prepare data and model\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n# Create dataset and data loader\ndataset = DummyDataset(size=200)  # You can adjust the size as needed\nloader = DataLoader(dataset, batch_size=8, shuffle=True, num_workers=0)\n\n# Prepare VGG16 model\nmodel = models.vgg16(pretrained=True)  # Load pretrained VGG16 model\nmodel.classifier[6] = nn.Linear(model.classifier[6].in_features, 2)  # Modify output layer\nmodel = model.to(device)  # Move model to GPU\n\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=1e-4)  # Lower learning rate\n\n# Training loop\nepochs = 3\nstart_total = time.time()\nfor epoch in range(epochs):\n    model.train()\n    total_loss = 0.0\n    total_correct = 0  # Track correct predictions\n    total_samples = 0  # Track total samples\n    start_epoch = time.time()\n    batch_count = 0  # Counter\n\n    for imgs, labels in loader:\n        imgs = imgs.to(device)\n        labels = labels.to(device)\n\n        outputs = model(imgs)\n        loss = criterion(outputs, labels)\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        total_loss += loss.item()\n\n        # Calculate accuracy\n        _, predicted = torch.max(outputs, 1)\n        total_correct += (predicted == labels).sum().item()\n        total_samples += labels.size(0)  # Accumulate current batch sample count\n\n        batch_count += 1  # Increment counter\n\n    end_epoch = time.time()\n    average_loss = total_loss / batch_count if batch_count > 0 else 0  # Calculate average loss\n    accuracy = total_correct / total_samples if total_samples > 0 else 0  # Calculate accuracy\n\n    print(f\"Epoch {epoch+1:02d}  loss = {average_loss:.4f}  accuracy = {accuracy:.4f} \"\n          f\"| time: {end_epoch - start_epoch:.1f}s\")\n\nend_total = time.time()\nprint(f\"✅ Training completed in {end_total - start_total:.1f} seconds.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T01:04:50.310518Z","iopub.execute_input":"2025-05-08T01:04:50.310851Z","iopub.status.idle":"2025-05-08T01:12:32.922111Z","shell.execute_reply.started":"2025-05-08T01:04:50.310823Z","shell.execute_reply":"2025-05-08T01:12:32.921162Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Prepare test dataset and data loader\ntest_dataset = TFRecordIterableMultimodal(\n    \"/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/02-1881.tfrec\",\n    final_df, \n    label_key,\n    image_size=(224, 224)  # Ensure input size matches model requirements\n)\n\ntest_loader = DataLoader(\n    test_dataset,\n    batch_size=8,    # Further reduce batch size\n    pin_memory=True,\n)\n\n# Testing loop\nmodel.eval()  # Set model to evaluation mode\ntotal_correct = 0\ntotal_samples = 0\n\nwith torch.no_grad():  # No need to compute gradients\n    for imgs, labels in test_loader:\n        imgs = imgs.to(device)\n        labels = labels.to(device)\n\n        outputs = model(imgs)\n        _, predicted = torch.max(outputs, 1)\n        total_correct += (predicted == labels).sum().item()\n        total_samples += labels.size(0)\n\n# Calculate and print test accuracy\ntest_accuracy = total_correct / total_samples if total_samples > 0 else 0\nprint(f\"Test accuracy: {test_accuracy:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T01:13:15.740283Z","iopub.execute_input":"2025-05-08T01:13:15.740627Z","iopub.status.idle":"2025-05-08T01:13:45.331201Z","shell.execute_reply.started":"2025-05-08T01:13:15.740596Z","shell.execute_reply":"2025-05-08T01:13:45.330247Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torchvision.transforms as transforms\nimport matplotlib.pyplot as plt\n\n# Assume TFRecordIterableMultimodal is defined and the model is loaded\n# Load the test dataset\nlabel_key_test = ['data', 'label']\ntest_dataset = TFRecordIterableMultimodal(\n    \"/kaggle/input/ranzcr-clip-catheter-line-classification/train_tfrecords/02-1881.tfrec\",\n    final_df, \n    label_key_test,\n    image_size=(224, 224)\n)\n\n# Create data loader\ntest_loader = DataLoader(\n    test_dataset,\n    batch_size=1,  # Set to 1 for single sample retrieval\n    pin_memory=True,\n)\n\n# Get a single sample from the test dataset\nfor imgs, labels in test_loader:\n    imgs = imgs.to(device)  # Move to device\n    labels = labels.to(device)\n\n    # Predict using the model\n    model.eval()  # Set to evaluation mode\n    with torch.no_grad():\n        outputs = model(imgs)\n        print(\"Raw model outputs:\", outputs)  # Print raw outputs\n        _, predicted = torch.max(outputs, 1)\n    \n    # Prepare image for display\n    sample_image = imgs.squeeze(0).cpu().numpy()  # Move to CPU and remove batch dimension\n    sample_image = sample_image.transpose(1, 2, 0)  # Convert to HWC format\n    \n    # Show the image\n    plt.imshow(sample_image)\n    plt.axis('off')  # Hide axes\n    plt.title(f\"Predicted: {predicted.item()}, Actual: {labels.item()}\")\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T01:29:58.306807Z","iopub.execute_input":"2025-05-08T01:29:58.307162Z","iopub.status.idle":"2025-05-08T01:30:00.497917Z","shell.execute_reply.started":"2025-05-08T01:29:58.307132Z","shell.execute_reply":"2025-05-08T01:30:00.495778Z"},"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"label_key","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T01:22:03.083288Z","iopub.execute_input":"2025-05-08T01:22:03.083622Z","iopub.status.idle":"2025-05-08T01:22:03.088776Z","shell.execute_reply.started":"2025-05-08T01:22:03.083597Z","shell.execute_reply":"2025-05-08T01:22:03.087957Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"---\n","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader\n\nclass SimpleCNN(nn.Module):\n    def __init__(self, num_classes=10):\n        super(SimpleCNN, self).__init__()\n        self.conv1 = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1)\n        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1)\n        self.fc1 = nn.Linear(32 * 16 * 16, 128)  # 64x64 input size\n        self.fc2 = nn.Linear(128, num_classes)\n        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)\n\n    def forward(self, x):\n        x = self.pool(F.relu(self.conv1(x)))\n        x = self.pool(F.relu(self.conv2(x)))\n        x = x.view(-1, 32 * 16 * 16)  # Flatten the tensor\n        x = F.relu(self.fc1(x))\n        x = self.fc2(x)\n        return x\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nmodel = SimpleCNN(num_classes=10).to(device)\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)\n\nnum_epochs = 1  \n\nfor epoch in range(num_epochs):\n    model.train()\n    for images, labels in loader:\n        images, labels = images.to(device), labels.to(device)\n        \n        optimizer.zero_grad()\n        outputs = model(images)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n    \n    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')\n\nmodel.eval()\nwith torch.no_grad():\n    total = 0\n    correct = 0\n    for images, labels in val_loader:\n        images, labels = images.to(device), labels.to(device)\n        outputs = model(images)\n        _, predicted = torch.max(outputs.data, 1)\n        total += labels.size(0)\n        correct += (predicted == labels).sum().item()\n\n    print(f'Accuracy: {100 * correct / total:.2f}%')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T06:05:23.394703Z","iopub.execute_input":"2025-05-08T06:05:23.394985Z","iopub.status.idle":"2025-05-08T06:05:33.223421Z","shell.execute_reply.started":"2025-05-08T06:05:23.394961Z","shell.execute_reply":"2025-05-08T06:05:33.222428Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(f\"Number of rows in merged_df2: {merged_df2.shape[0]}\")\nprint(merged_df2.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-08T06:08:03.505555Z","iopub.execute_input":"2025-05-08T06:08:03.505853Z","iopub.status.idle":"2025-05-08T06:08:03.511002Z","shell.execute_reply.started":"2025-05-08T06:08:03.505828Z","shell.execute_reply":"2025-05-08T06:08:03.510241Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}