{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceType":"competition","sourceId":13451,"datasetId":654585,"databundleVersionId":1188070},{"sourceType":"datasetVersion","sourceId":7911864,"datasetId":4648135,"databundleVersionId":8019594}],"dockerImageVersionId":30587,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n!pip install opencv-python\nfrom torch.utils.data import Dataset\nfrom torch.utils.data import DataLoader\nimport torchvision.transforms as transforms\nimport torch.optim as optim\nimport torchvision.models as models\nimport torch.nn as nn\n\nimport re\nimport pydicom as dcm\nimport torch\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\nfrom PIL import Image\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\nimport cv2\nimport os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-03-22T09:03:48.136314Z","iopub.execute_input":"2024-03-22T09:03:48.136723Z","iopub.status.idle":"2024-03-22T09:04:25.120697Z","shell.execute_reply.started":"2024-03-22T09:03:48.136691Z","shell.execute_reply":"2024-03-22T09:04:25.119845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 设置超参数\nBATCH_SIZE=16\nEPOCH=2\nLR=0.01\nlog_interval=10\nonly_train_fc=True\nval_interval=1\nMAX_EPOCH=100","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:04:25.122379Z","iopub.execute_input":"2024-03-22T09:04:25.122791Z","iopub.status.idle":"2024-03-22T09:04:25.127471Z","shell.execute_reply.started":"2024-03-22T09:04:25.122763Z","shell.execute_reply":"2024-03-22T09:04:25.126602Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 处理输入","metadata":{}},{"cell_type":"code","source":"import pandas as pd\n\ndir_path=\"/kaggle/input/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection\"\ntrain_path=os.path.join(dir_path,\"stage_2_train\")\ncsv_train_path=os.path.join(dir_path,\"stage_2_train.csv\")\ncsv_data=pd.read_csv(csv_train_path).drop_duplicates(subset=[\"ID\"])","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:04:25.128724Z","iopub.execute_input":"2024-03-22T09:04:25.129071Z","iopub.status.idle":"2024-03-22T09:04:32.372318Z","shell.execute_reply.started":"2024-03-22T09:04:25.129037Z","shell.execute_reply":"2024-03-22T09:04:32.371223Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"csv_cascade_data=pd.concat([csv_data[\"ID\"].str.rsplit('_',n=1,expand=True),csv_data.Label],axis=1)\ncsv_load_data=csv_cascade_data.set_index([0,1]).unstack(level=-1)[\"Label\"]","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:04:32.37388Z","iopub.execute_input":"2024-03-22T09:04:32.374222Z","iopub.status.idle":"2024-03-22T09:04:49.661848Z","shell.execute_reply.started":"2024-03-22T09:04:32.374194Z","shell.execute_reply":"2024-03-22T09:04:49.660843Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"desired_order = ['epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural', 'any']\ncsv_load_data=csv_load_data.reindex(columns=desired_order)","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:04:49.66532Z","iopub.execute_input":"2024-03-22T09:04:49.666203Z","iopub.status.idle":"2024-03-22T09:04:49.679026Z","shell.execute_reply.started":"2024-03-22T09:04:49.666159Z","shell.execute_reply":"2024-03-22T09:04:49.678099Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"csv_load_data","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:04:49.680161Z","iopub.execute_input":"2024-03-22T09:04:49.680449Z","iopub.status.idle":"2024-03-22T09:04:49.707592Z","shell.execute_reply.started":"2024-03-22T09:04:49.680425Z","shell.execute_reply":"2024-03-22T09:04:49.706757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 数据分布\ndata = csv_load_data.sum().to_dict()\nlabels = list(data.keys())\nvalues = list(data.values())\nplt.figure(figsize=(10, 6))\nplt.bar(labels, values, color='skyblue')\nplt.title('Counts of Hemorrhage Sub-types')\nplt.xlabel('Hemorrhage Sub-types')\nplt.ylabel('Count')\nplt.xticks(rotation=45, ha='right')\nplt.tight_layout()\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:04:49.70868Z","iopub.execute_input":"2024-03-22T09:04:49.708913Z","iopub.status.idle":"2024-03-22T09:04:50.097053Z","shell.execute_reply.started":"2024-03-22T09:04:49.708891Z","shell.execute_reply":"2024-03-22T09:04:50.096213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 划分训练集和验证集\ntrain_size=700000\ncsv_train=csv_load_data.iloc[:train_size]\ncsv_valid=csv_load_data.iloc[train_size:]","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:04:50.098223Z","iopub.execute_input":"2024-03-22T09:04:50.098771Z","iopub.status.idle":"2024-03-22T09:04:50.103932Z","shell.execute_reply.started":"2024-03-22T09:04:50.098733Z","shell.execute_reply":"2024-03-22T09:04:50.103093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def to_img(img_path):\n    dcm_img=dcm.dcmread(img_path)\n    img=dcm_img.pixel_array\n    slope=dcm_img.RescaleSlope\n    intercept=dcm_img.RescaleIntercept\n    img=img*slope+intercept\n    return img","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:04:50.105022Z","iopub.execute_input":"2024-03-22T09:04:50.105323Z","iopub.status.idle":"2024-03-22T09:04:50.11595Z","shell.execute_reply.started":"2024-03-22T09:04:50.105298Z","shell.execute_reply":"2024-03-22T09:04:50.115118Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 图像可视化\nt=os.listdir(train_path)\nimg=to_img(os.path.join(train_path,t[0]))\nplt.imshow(img, cmap=plt.cm.bone)","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:04:50.116939Z","iopub.execute_input":"2024-03-22T09:04:50.11719Z","iopub.status.idle":"2024-03-22T09:04:58.040001Z","shell.execute_reply.started":"2024-03-22T09:04:50.117167Z","shell.execute_reply":"2024-03-22T09:04:58.039017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dcm_img=dcm.dcmread(os.path.join(train_path,t[0]))\nprint(dcm_img)","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:04:58.041416Z","iopub.execute_input":"2024-03-22T09:04:58.042065Z","iopub.status.idle":"2024-03-22T09:04:58.052476Z","shell.execute_reply.started":"2024-03-22T09:04:58.042036Z","shell.execute_reply":"2024-03-22T09:04:58.051472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 加载数据","metadata":{}},{"cell_type":"code","source":"class ICTDataset(torch.utils.data.Dataset):\n    def __init__(self,data_dir,patients,labels=None,transform=None):\n        self.data_dir=data_dir\n        self.patients=patients\n        self.labels=labels\n        self.transform=transform\n\n    def __getitem__(self,index):\n        img=to_img(os.path.join(self.data_dir,self.patients[index]+\".dcm\"))\n        img=cv2.resize(img, (512,512))\n        # Z-score将数据归一化到[mean，std]\n        target_mean = 0.5\n        target_std = 0.2\n        cur_mean=np.mean(img)\n        cur_std=np.std(img)\n        epsilon = 1e-6  \n        cur_std = np.maximum(cur_std, epsilon)\n        scale_factor = target_std / cur_std\n        img = (img - cur_mean) * scale_factor + target_mean\n\n        img_rgb=np.zeros((3,*img.shape))\n        for i in range(3):\n            img_rgb[i,:,:]=img\n        if self.transform:\n            img_rgb=self.transform(img_rgb)\n        img_rgb=img_rgb.astype(np.float32)\n        if self.labels is not None:\n            label=self.labels[index]\n            label=label.astype(np.float32)\n            return img_rgb,label\n        else:\n            return img_rgb\n        \n    def __len__(self):\n        return len(self.patients)\n#         return 1800","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:07:13.371469Z","iopub.execute_input":"2024-03-22T09:07:13.371837Z","iopub.status.idle":"2024-03-22T09:07:13.382274Z","shell.execute_reply.started":"2024-03-22T09:07:13.371805Z","shell.execute_reply":"2024-03-22T09:07:13.381212Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset=ICTDataset(train_path,csv_train.index,csv_train.values)\nvalid_dataset=ICTDataset(train_path,csv_valid.index,csv_valid.values)\ntrain_loader=DataLoader(dataset=train_dataset,batch_size=BATCH_SIZE,shuffle=True,pin_memory=True)\nvalid_loader=DataLoader(dataset=valid_dataset,batch_size=BATCH_SIZE,pin_memory=True)","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:07:13.723906Z","iopub.execute_input":"2024-03-22T09:07:13.72451Z","iopub.status.idle":"2024-03-22T09:07:13.730092Z","shell.execute_reply.started":"2024-03-22T09:07:13.724472Z","shell.execute_reply":"2024-03-22T09:07:13.729163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 查看数据是否加载成功\nimg,label=train_dataset[0]\nprint(img.shape)\nprint(label)\nprint(np.min(img))\nprint(np.max(img))\n# plt.imshow(img)\nfor img,label in train_loader:\n    print(img.shape)\n    print(label.shape)\n    break","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:07:14.153518Z","iopub.execute_input":"2024-03-22T09:07:14.154191Z","iopub.status.idle":"2024-03-22T09:07:14.926204Z","shell.execute_reply.started":"2024-03-22T09:07:14.154159Z","shell.execute_reply":"2024-03-22T09:07:14.925235Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 搭建网络","metadata":{}},{"cell_type":"code","source":"!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:07:18.222962Z","iopub.execute_input":"2024-03-22T09:07:18.223571Z","iopub.status.idle":"2024-03-22T09:07:19.324138Z","shell.execute_reply.started":"2024-03-22T09:07:18.223536Z","shell.execute_reply":"2024-03-22T09:07:19.32314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 网络问题无法直接加载\n# net = models.resnet50(weights=models.ResNet50_Weights.DEFAULT)\n\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nnet = models.resnet50()\ncheckpoint =torch.load(\"/kaggle/input/raw-resnet50/resnet50-0676ba61.pth\")\nnet.load_state_dict(checkpoint)\n\nif only_train_fc:\n    for param in net.parameters():\n        param.requires_grad_=False\n\nnum_features=net.fc.in_features\nnet.fc = nn.Sequential(\n    nn.Linear(num_features, 256),\n    nn.ReLU(),\n    nn.Dropout(0.5),\n    nn.Linear(256, 6),\n    nn.Sigmoid()\n)\nfor param in net.fc.parameters():\n    param.requies_grad=True\nnet=net.to(device)","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:07:19.326253Z","iopub.execute_input":"2024-03-22T09:07:19.326634Z","iopub.status.idle":"2024-03-22T09:07:19.917926Z","shell.execute_reply.started":"2024-03-22T09:07:19.3266Z","shell.execute_reply":"2024-03-22T09:07:19.917157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustomBCELoss(nn.modules.loss._WeightedLoss):\n    def __init__(self, weight=None, weights=torch.tensor([0.3, 0.15, 0.15, 0.15, 0.15, 0.1]), size_average=None,\n                 reduce=None, reduction='sum', alpha=2, beta=0.5):\n        super().__init__(weight, size_average, reduce, reduction)\n        self.alpha = alpha\n        self.beta = beta\n        self.weights = weights\n\n    def forward(self, input, target):\n        loss = self.alpha * target * torch.log(input) + self.beta * (1 - target) * torch.log(1 - input)\n        if self.reduction == 'mean':\n            return -torch.mean(loss)\n        elif self.reduction == 'sum':\n            loss_sum=torch.sum(loss*self.weights,axis=1)\n            return -torch.mean(loss_sum)\n        else:\n            return -loss\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torchvision.models as models\nfrom torchinfo import summary\n\n# 定义模型\n# net=LeNetSequetial(classes=6)\n# net.initialize_weights()\n# criterion=nn.BCELoss()\ncriterion=CustomBCELoss()\noptimizer=optim.SGD(net.parameters(),lr=LR,momentum=0.9)\nscheduler=torch.optim.lr_scheduler.StepLR(optimizer,step_size=10,gamma=0.1)\ntrain_curve=list()\nvalid_curve=list()\niter_count=0\n","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:07:19.919362Z","iopub.execute_input":"2024-03-22T09:07:19.919684Z","iopub.status.idle":"2024-03-22T09:07:19.928712Z","shell.execute_reply.started":"2024-03-22T09:07:19.919656Z","shell.execute_reply":"2024-03-22T09:07:19.927979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for epoch in range(EPOCH):\n    loss_mean=0.\n    correct=0.\n    net.train()\n    flag=1\n    for i,data in enumerate(train_loader):\n        iter_count+=1\n        inputs,labels=data\n        inputs=inputs.to(device)\n        labels=labels.to(device)\n        outputs=net(inputs)\n#         if flag==1:\n#             print(summary(net, inputs.shape, device=\"cpu\"))\n#             flag=0\n        optimizer.zero_grad()\n        loss=criterion(outputs,labels)\n        loss.backward()\n        optimizer.step()\n        threshold=0.5\n        binary_predictions = (outputs > threshold).int()\n        correct = (binary_predictions == labels).float().mean()\n        loss_mean+=loss.item()\n        train_curve.append(loss.item())\n        if (i+1)%log_interval==0:\n            loss_mean=loss_mean/log_interval\n            print(\"Training:Epoch[{:0>3}/{:0>3}] Iteration[{:0>3}/{:0>3}] Loss:{:.4} Acc:{:.2%}\".format(\n                epoch,EPOCH,i+1,len(train_loader),loss_mean,correct))\n            loss_mean=0.\n            \n    scheduler.step()\n    if(epoch+1)%val_interval==0:\n        correct_val=0.\n        loss_val=0.\n        net.eval()\n        with torch.no_grad():\n            for j,data in enumerate(valid_loader):\n                inputs,labels = data\n                inputs=inputs.to(device)\n                labels=labels.to(device)\n                outputs=net(inputs)\n                loss=criterion(outputs,labels)\n                threshold=0.5\n                binary_predictions = (outputs > threshold).int()\n                correct_val = (binary_predictions == labels).float().mean()\n                loss_val+=loss.item()\n            valid_curve.append(loss_val/valid_loader.__len__())\n            print(\"Valid:\\t Epoch[{:0>3}/{:0>3}] Iteration[{:0>3}/{:0>3}] Loss: {:.4f} Acc:{:.2f}\".format(\n                epoch,MAX_EPOCH,j+1,len(valid_loader),loss_val,correct_val))\n            torch.save(net,os.path.join(\"/kaggle/working\",f\"model_name{correct_val:.2f}.pth\"))\n\ntrain_x=range(len(train_curve))\ntrain_y=train_curve\ntrain_iters=len(train_loader)\nvalid_x=np.arange(1,len(valid_curve)+1)*train_iters*val_interval\nvalid_y=valid_curve\nplt.plot(train_x,train_y,label='Train')\nplt.plot(valid_x,valid_y,label='Valid')\nplt.legend(loc='upper right')\nplt.ylabel('loss value')\nplt.xlabel('Iteration')\nplt.show()\ntorch.save(net,os.path.join(\"/kaggle/working\",\"model_name.pth\"))","metadata":{"execution":{"iopub.status.busy":"2024-03-22T09:17:43.27634Z","iopub.execute_input":"2024-03-22T09:17:43.277002Z","iopub.status.idle":"2024-03-22T10:47:57.400363Z","shell.execute_reply.started":"2024-03-22T09:17:43.27697Z","shell.execute_reply":"2024-03-22T10:47:57.399023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.save(net,os.path.join(\"/kaggle/working\",\"model_name.pth\"))","metadata":{"execution":{"iopub.status.busy":"2024-03-22T10:48:18.562832Z","iopub.execute_input":"2024-03-22T10:48:18.563202Z","iopub.status.idle":"2024-03-22T10:48:18.748364Z","shell.execute_reply.started":"2024-03-22T10:48:18.563169Z","shell.execute_reply":"2024-03-22T10:48:18.747601Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"csv_test_path=os.path.join(dir_path,\"stage_2_sample_submission.csv\")\ntest_path=os.path.join(dir_path,\"stage_2_test\")\nsample_submission = pd.read_csv(csv_test_path)\ntest_ids = sample_submission.ID.str.rsplit(\"_\", n=1, expand=True)[0].unique()\n","metadata":{"execution":{"iopub.status.busy":"2024-03-22T10:48:31.258887Z","iopub.execute_input":"2024-03-22T10:48:31.259483Z","iopub.status.idle":"2024-03-22T10:48:34.846873Z","shell.execute_reply.started":"2024-03-22T10:48:31.259444Z","shell.execute_reply":"2024-03-22T10:48:34.846034Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataset=ICTDataset(test_path,test_ids)\ntest_loader=DataLoader(dataset=test_dataset,batch_size=BATCH_SIZE)","metadata":{"execution":{"iopub.status.busy":"2024-03-22T10:48:34.84837Z","iopub.execute_input":"2024-03-22T10:48:34.848673Z","iopub.status.idle":"2024-03-22T10:48:34.853262Z","shell.execute_reply.started":"2024-03-22T10:48:34.848646Z","shell.execute_reply":"2024-03-22T10:48:34.852363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_model=torch.load(\"/kaggle/working/model_name.pth\")\nnet.eval()\nresults=np.empty((0,6))\nwith torch.no_grad():\n    for i,data in enumerate(test_loader):\n        inputs=data\n        inputs=inputs.to(device)\n        outputs=pred_model(inputs)\n        results=np.vstack((results,outputs.cpu()))","metadata":{"execution":{"iopub.status.busy":"2024-03-22T10:48:34.85441Z","iopub.execute_input":"2024-03-22T10:48:34.854676Z","iopub.status.idle":"2024-03-22T12:42:23.248437Z","shell.execute_reply.started":"2024-03-22T10:48:34.854652Z","shell.execute_reply":"2024-03-22T12:42:23.247418Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_submission.Label=results.reshape(-1)\nsample_submission.to_csv('submission2.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-03-22T12:42:23.28742Z","iopub.execute_input":"2024-03-22T12:42:23.287657Z","iopub.status.idle":"2024-03-22T12:42:24.734898Z","shell.execute_reply.started":"2024-03-22T12:42:23.287635Z","shell.execute_reply":"2024-03-22T12:42:24.733583Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}