{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":36363,"databundleVersionId":4050810,"sourceType":"competition"}],"dockerImageVersionId":30761,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install pylibjpeg\n!pip install gdcm\n!pip install pylibjpeg-libjpeg\n!pip install pillow\n!pip install transformers torch torchvision","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:23:15.219453Z","iopub.execute_input":"2024-09-18T10:23:15.220122Z","iopub.status.idle":"2024-09-18T10:24:22.390511Z","shell.execute_reply.started":"2024-09-18T10:23:15.220079Z","shell.execute_reply":"2024-09-18T10:24:22.389486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport pydicom\nfrom tqdm import tqdm\nfrom PIL import Image\nimport torch\nfrom torchvision import transforms\nfrom transformers import AutoFeatureExtractor, AutoModelForImageClassification\nfrom torch.utils.data import Dataset, DataLoader\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import classification_report, roc_auc_score","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:24:22.392599Z","iopub.execute_input":"2024-09-18T10:24:22.392961Z","iopub.status.idle":"2024-09-18T10:24:29.425946Z","shell.execute_reply.started":"2024-09-18T10:24:22.392924Z","shell.execute_reply":"2024-09-18T10:24:29.425159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# Set up paths\nBASE_PATH = '/kaggle/input/rsna-2022-cervical-spine-fracture-detection'\nTRAIN_CSV_PATH = os.path.join(BASE_PATH, 'train.csv')\nTEST_CSV_PATH = os.path.join(BASE_PATH, 'test.csv')\nTRAIN_IMAGES_PATH = os.path.join(BASE_PATH, 'train_images')\nTEST_IMAGES_PATH = os.path.join(BASE_PATH, 'test_images')\nSEGMENTATIONS_PATH = os.path.join(BASE_PATH, 'segmentations')\nBOUNDING_BOXES_PATH = os.path.join(BASE_PATH, 'train_bounding_boxes.csv')\nSAMPLE_SUBMISSION_PATH = os.path.join(BASE_PATH, 'sample_submission.csv')\n\n# Load training data\ntrain_df = pd.read_csv(TRAIN_CSV_PATH)\nprint(\"Training data shape:\", train_df.shape)\nprint(\"\\nFirst few rows of training data:\")\nprint(train_df.head())\n\n# Explore target variables\ntarget_cols = ['patient_overall'] + [f'C{i}' for i in range(1, 8)]\nprint(\"\\nDistribution of fractures:\")\nprint(train_df[target_cols].sum())\n\n# Visualize fracture distribution\nplt.figure(figsize=(12, 6))\nsns.barplot(x=target_cols, y=train_df[target_cols].sum())\nplt.title(\"Distribution of Fractures\")\nplt.ylabel(\"Count\")\nplt.xticks(rotation=45)\nplt.tight_layout()\nplt.show()\n\n# Function to load DICOM files\ndef load_dicom(path):\n    dicom = pydicom.dcmread(path)\n    return dicom.pixel_array\n\n# Explore a sample patient's scans\ndef explore_patient_scans(patient_id):\n    patient_path = os.path.join(TRAIN_IMAGES_PATH, patient_id)\n    slices = sorted([f for f in os.listdir(patient_path) if f.endswith('.dcm')])\n    print(f\"Number of slices for patient {patient_id}: {len(slices)}\")\n    \n    # Load middle slice\n    middle_slice = load_dicom(os.path.join(patient_path, slices[len(slices)//2]))\n    print(f\"Slice shape: {middle_slice.shape}\")\n    print(f\"Pixel value range: {middle_slice.min()} to {middle_slice.max()}\")\n    \n    # Visualize middle slice\n    plt.figure(figsize=(10, 10))\n    plt.imshow(middle_slice, cmap='bone')\n    plt.title(f\"Middle slice for patient {patient_id}\")\n    plt.axis('off')\n    plt.show()\n\n# Explore a few sample patients\nsample_patients = train_df['StudyInstanceUID'].sample(3).tolist()\nfor patient in sample_patients:\n    explore_patient_scans(patient)\n\n# Load and explore bounding box data\nbounding_boxes_df = pd.read_csv(BOUNDING_BOXES_PATH)\nprint(\"\\nBounding boxes data shape:\", bounding_boxes_df.shape)\nprint(\"\\nFirst few rows of bounding boxes data:\")\nprint(bounding_boxes_df.head())\n\n# Explore segmentation files\nsegmentation_files = os.listdir(SEGMENTATIONS_PATH)\nprint(f\"\\nNumber of segmentation files: {len(segmentation_files)}\")\nprint(\"Sample segmentation file names:\")\nprint(segmentation_files[:5])\n\nprint(\"\\nInitial data exploration complete!\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-09-18T10:24:29.42735Z","iopub.execute_input":"2024-09-18T10:24:29.427895Z","iopub.status.idle":"2024-09-18T10:24:31.833362Z","shell.execute_reply.started":"2024-09-18T10:24:29.427854Z","shell.execute_reply":"2024-09-18T10:24:31.832413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Hello, it works without error ","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Function to load and preprocess DICOM image\ndef load_and_preprocess_dicom(file_path):\n    dicom = pydicom.dcmread(file_path)\n    image = dicom.pixel_array\n    \n    # Normalize the image\n    image = (image - image.min()) / (image.max() - image.min())\n    image = (image * 255).astype(np.uint8)\n    \n    # Convert to RGB (most pre-trained models expect 3-channel input)\n    image = Image.fromarray(image).convert('RGB')\n    \n    return image\n\n# Load pre-trained model and feature extractor\nmodel_name = \"google/vit-base-patch16-224\"\nfeature_extractor = AutoFeatureExtractor.from_pretrained(model_name)\nmodel = AutoModelForImageClassification.from_pretrained(model_name)\n\n# Set up image transformation\ntransform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n])\n\n# Function to predict\ndef predict(image_path):\n    image = load_and_preprocess_dicom(image_path)\n    image = transform(image).unsqueeze(0)  # Add batch dimension\n    \n    with torch.no_grad():\n        inputs = feature_extractor(images=image, return_tensors=\"pt\")\n        outputs = model(**inputs)\n        logits = outputs.logits\n        predicted_class = logits.argmax(-1).item()\n    \n    return predicted_class\n\n# Example usage\nsample_image_path = os.path.join(TRAIN_IMAGES_PATH, train_df['StudyInstanceUID'].iloc[0], '1.dcm')\nprediction = predict(sample_image_path)\nprint(f\"Predicted class: {prediction}\")","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:24:31.835485Z","iopub.execute_input":"2024-09-18T10:24:31.835835Z","iopub.status.idle":"2024-09-18T10:24:46.474432Z","shell.execute_reply.started":"2024-09-18T10:24:31.835801Z","shell.execute_reply":"2024-09-18T10:24:46.473507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import logging\n\nlogging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')\n","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:24:46.475658Z","iopub.execute_input":"2024-09-18T10:24:46.476305Z","iopub.status.idle":"2024-09-18T10:24:46.484568Z","shell.execute_reply.started":"2024-09-18T10:24:46.476264Z","shell.execute_reply":"2024-09-18T10:24:46.483633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# New imports and configurations\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(f\"Using device: {device}\")","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:24:46.485768Z","iopub.execute_input":"2024-09-18T10:24:46.486073Z","iopub.status.idle":"2024-09-18T10:24:46.580505Z","shell.execute_reply.started":"2024-09-18T10:24:46.486038Z","shell.execute_reply":"2024-09-18T10:24:46.579408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Advanced data augmentation\ntrain_transform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomRotation(10),\n    transforms.RandomAffine(degrees=0, translate=(0.05, 0.05)),\n    transforms.ColorJitter(brightness=0.2, contrast=0.2),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n])\n\n# Define a separate transform for validation (without augmentation)\nval_transform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n])","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:24:46.581768Z","iopub.execute_input":"2024-09-18T10:24:46.582429Z","iopub.status.idle":"2024-09-18T10:24:46.594412Z","shell.execute_reply.started":"2024-09-18T10:24:46.582377Z","shell.execute_reply":"2024-09-18T10:24:46.59325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Add this debugging function\ndef inspect_dataframe(df, target_cols):\n    print(\"Data types of target columns:\")\n    print(df[target_cols].dtypes)\n    print(\"\\nNumber of NaN values in target columns:\")\n    print(df[target_cols].isna().sum())\n    print(\"\\nSample of target column data:\")\n    print(df[target_cols].head())\n    print(\"\\nUnique values in target columns:\")\n    for col in target_cols:\n        print(f\"{col}: {df[col].unique()}\")\n\n# Call this function before creating your datasets\ninspect_dataframe(train_df, ['patient_overall'] + [f'C{i}' for i in range(1, 8)])","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:24:46.595728Z","iopub.execute_input":"2024-09-18T10:24:46.596368Z","iopub.status.idle":"2024-09-18T10:24:46.62017Z","shell.execute_reply.started":"2024-09-18T10:24:46.596307Z","shell.execute_reply":"2024-09-18T10:24:46.618788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CervicalSpineDataset(Dataset):\n    def __init__(self, df, image_dir, transform=None):\n        self.df = df\n        self.image_dir = image_dir\n        self.transform = transform\n        self.target_cols = ['patient_overall'] + [f'C{i}' for i in range(1, 8)]\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        study_id = self.df.iloc[idx]['StudyInstanceUID']\n        study_path = os.path.join(self.image_dir, study_id)\n        slices = sorted([f for f in os.listdir(study_path) if f.endswith('.dcm')])\n        middle_slice = slices[len(slices)//2]\n        image = load_and_preprocess_dicom(os.path.join(study_path, middle_slice))\n        \n        if self.transform:\n            image = self.transform(image)\n        \n        # Convert target values to float and handle any potential non-numeric values\n        target_values = self.df.iloc[idx][self.target_cols].values\n        target_values = [float(val) if not pd.isna(val) else 0.0 for val in target_values]\n        target = torch.tensor(target_values, dtype=torch.float)\n        \n        return image, target","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:24:46.623398Z","iopub.execute_input":"2024-09-18T10:24:46.623893Z","iopub.status.idle":"2024-09-18T10:24:46.639442Z","shell.execute_reply.started":"2024-09-18T10:24:46.623842Z","shell.execute_reply":"2024-09-18T10:24:46.63842Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create datasets and dataloaders\ntrain_df, val_df = train_test_split(train_df, test_size=0.2, random_state=42)\n\ntrain_dataset = CervicalSpineDataset(train_df, TRAIN_IMAGES_PATH, transform=train_transform)\nval_dataset = CervicalSpineDataset(val_df, TRAIN_IMAGES_PATH, transform=val_transform)\n\ntrain_loader = DataLoader(train_dataset, batch_size=16, shuffle=True, num_workers=4)\nval_loader = DataLoader(val_dataset, batch_size=16, shuffle=False, num_workers=4)","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:24:46.642373Z","iopub.execute_input":"2024-09-18T10:24:46.642885Z","iopub.status.idle":"2024-09-18T10:24:46.659591Z","shell.execute_reply.started":"2024-09-18T10:24:46.642829Z","shell.execute_reply":"2024-09-18T10:24:46.6585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Model initialization\nmodel_name = \"google/vit-base-patch16-224\"\nfeature_extractor = AutoFeatureExtractor.from_pretrained(model_name)\nmodel = AutoModelForImageClassification.from_pretrained(model_name)\n","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:24:46.661792Z","iopub.execute_input":"2024-09-18T10:24:46.662182Z","iopub.status.idle":"2024-09-18T10:24:47.185081Z","shell.execute_reply.started":"2024-09-18T10:24:46.662137Z","shell.execute_reply":"2024-09-18T10:24:47.18416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Training function\ndef train_model(model, train_loader, val_loader, num_epochs=10):\n    optimizer = torch.optim.AdamW(model.parameters(), lr=2e-5)\n    criterion = torch.nn.BCEWithLogitsLoss()\n    scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=2)\n    \n    best_val_loss = float('inf')\n    for epoch in range(num_epochs):\n        model.train()\n        train_loss = 0\n        train_preds, train_targets = [], []\n        \n        for images, targets in tqdm(train_loader, desc=f\"Epoch {epoch+1}/{num_epochs} - Training\"):\n            images, targets = images.to(device), targets.to(device)\n            \n            optimizer.zero_grad()\n            outputs = model(images).logits\n            loss = criterion(outputs, targets)\n            loss.backward()\n            optimizer.step()\n            \n            train_loss += loss.item()\n            train_preds.extend(torch.sigmoid(outputs).detach().cpu().numpy())\n            train_targets.extend(targets.cpu().numpy())\n        \n        train_loss /= len(train_loader)\n        train_auc = roc_auc_score(train_targets, train_preds, average='macro')\n        \n        # Validation\n        model.eval()\n        val_loss = 0\n        val_preds, val_targets = [], []\n        with torch.no_grad():\n            for images, targets in tqdm(val_loader, desc=f\"Epoch {epoch+1}/{num_epochs} - Validation\"):\n                images, targets = images.to(device), targets.to(device)\n                outputs = model(images).logits\n                loss = criterion(outputs, targets)\n                val_loss += loss.item()\n                \n                val_preds.extend(torch.sigmoid(outputs).cpu().numpy())\n                val_targets.extend(targets.cpu().numpy())\n        \n        val_loss /= len(val_loader)\n        val_auc = roc_auc_score(val_targets, val_preds, average='macro')\n        \n        scheduler.step(val_loss)\n        \n        print(f\"Epoch {epoch+1}/{num_epochs}\")\n        print(f\"Train Loss: {train_loss:.4f}, Train AUC: {train_auc:.4f}\")\n        print(f\"Val Loss: {val_loss:.4f}, Val AUC: {val_auc:.4f}\")\n        print(classification_report(np.array(val_targets) > 0.5, np.array(val_preds) > 0.5, target_names=target_cols))\n        \n        if val_loss < best_val_loss:\n            best_val_loss = val_loss\n            torch.save(model.state_dict(), 'best_model.pth')\n            print(\"Saved best model!\")\n        \n        print(\"\\n\" + \"=\"*50 + \"\\n\")\n\n# Train the model\ntrain_model(model, train_loader, val_loader)\n","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:24:47.186352Z","iopub.execute_input":"2024-09-18T10:24:47.186632Z","iopub.status.idle":"2024-09-18T10:24:55.725264Z","shell.execute_reply.started":"2024-09-18T10:24:47.1866Z","shell.execute_reply":"2024-09-18T10:24:55.723211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load pre-trained model and modify for multi-label classification\nmodel_name = \"google/vit-base-patch16-224\"\nfeature_extractor = AutoFeatureExtractor.from_pretrained(model_name)\nmodel = AutoModelForImageClassification.from_pretrained(model_name, num_labels=8, problem_type=\"multi_label_classification\")\nmodel = model.to(device)\n\n# Training function\ndef train_model(model, train_loader, val_loader, num_epochs=5):\n    optimizer = torch.optim.AdamW(model.parameters(), lr=2e-5)\n    criterion = torch.nn.BCEWithLogitsLoss()\n    \n    for epoch in range(num_epochs):\n        model.train()\n        train_loss = 0\n        for images, targets in tqdm(train_loader, desc=f\"Epoch {epoch+1}/{num_epochs}\"):\n            images, targets = images.to(device), targets.to(device)\n            \n            optimizer.zero_grad()\n            outputs = model(images).logits\n            loss = criterion(outputs, targets)\n            loss.backward()\n            optimizer.step()\n            \n            train_loss += loss.item()\n        \n        # Validation\n        model.eval()\n        val_loss = 0\n        all_preds = []\n        all_targets = []\n        with torch.no_grad():\n            for images, targets in val_loader:\n                images, targets = images.to(device), targets.to(device)\n                outputs = model(images).logits\n                loss = criterion(outputs, targets)\n                val_loss += loss.item()\n                \n                preds = torch.sigmoid(outputs) > 0.5\n                all_preds.extend(preds.cpu().numpy())\n                all_targets.extend(targets.cpu().numpy())\n        \n        print(f\"Epoch {epoch+1}/{num_epochs}, Train Loss: {train_loss/len(train_loader):.4f}, Val Loss: {val_loss/len(val_loader):.4f}\")\n        print(classification_report(all_targets, all_preds, target_names=target_cols))\n\n","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:24:55.726504Z","iopub.status.idle":"2024-09-18T10:24:55.726967Z","shell.execute_reply.started":"2024-09-18T10:24:55.726779Z","shell.execute_reply":"2024-09-18T10:24:55.726799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train the model\ntrain_model(model, train_loader, val_loader)\n\n# Function to predict on new data\ndef predict(model, image_path):\n    image = load_and_preprocess_dicom(image_path)\n    image = transform(image).unsqueeze(0).to(device)\n    \n    model.eval()\n    with torch.no_grad():\n        outputs = model(image).logits\n        preds = torch.sigmoid(outputs) > 0.5\n    \n    return preds.squeeze().cpu().numpy()\n\n# Example usage\nsample_image_path = os.path.join(TRAIN_IMAGES_PATH, train_df['StudyInstanceUID'].iloc[0], 'some_slice.dcm')\nprediction = predict(model, sample_image_path)\nprint(f\"Predicted fractures: {[target_cols[i] for i, p in enumerate(prediction) if p]}\")\n\nprint(\"Model training and prediction pipeline complete!\")","metadata":{"execution":{"iopub.status.busy":"2024-09-18T10:24:55.728217Z","iopub.status.idle":"2024-09-18T10:24:55.728733Z","shell.execute_reply.started":"2024-09-18T10:24:55.728458Z","shell.execute_reply":"2024-09-18T10:24:55.728482Z"},"trusted":true},"execution_count":null,"outputs":[]}]}