2024年認證杯SPSSPRO杯數學建模
B題 神經外科手術的定位與導航
原題再現:
??人的大腦結構非常復雜,內部交織密布著神經和血管,所以在大腦內做手術具有非常高的精細和復雜程度。例如神經外科的腫瘤切除手術或血腫清除手術,通常需要將顱骨打開一個(或幾個)圓形窗口,將病變部位暴露在術野中。但當病變部位較深時,就必須將上方的腦組織進行一定程度的牽拉、移位。這種牽拉和移位的幅度不能太大,而且具有損傷腦組織的風險。所以醫生需要仔細設計手術方案,才能在盡量減小損傷的前提下完成手術目標。現在有CT或核磁共振等成像手段可以對顱內區域進行準確的透視和三維定位。但是在打開顱骨后,由于打開部位的顱骨約束作用消失,而且腦組織是柔軟的,所以腦組織會產生一定程度的變形、移位,甚至在一定程度上膨出,以至于病變部位的位置發生了改變。如果想要在術中實時進行透視和定位,需要復雜的設備,術者也需經過特殊的訓練,這都使得此類手術尚未完全普及。所以我們需要設計一個合理的數學模型,較為精細地預測手術部位在開顱后的位置改變情況。我們一定能夠取得的數據是:
??1. 術前的CT成像結果,這包含了顱腔的三維形狀以及手術部位在三維空間中的位置(在建模時可自行尋找并使用典型的顱腦CT成像數據);
??2. 術前的顱內壓;
??3. 在顱骨上打開的窗口的大小以及位置;
??4. 開顱后在顱骨窗口處可觀察到的腦組織膨出高度(通常以mm計);
??5. 在術前可以測量得到的其他生理指標。
??請你和你的團隊建立合理的數學模型以解決下列問題。
??第二階段問題:
??1. 假設患者的大腦中有一硬質占位性病變,我們通過術前的CT成像結果可以準確地知道它的位置。在術中可以測得顱內壓。請盡可能精細地計算該占位性病變在開顱后的位移情況。
??2. 假設患者的大腦中有一血腫區域(內容物為液態血液)。我們通過術前的CT成像結果可以準確地知道它的位置。在術中可以測得顱內壓。請盡可能精細地計算該血腫在開顱后的位移和可能的形變情況。
整體求解過程概述(摘要)
??神經外科手術,特別是涉及腦內深部病灶的手術,如腫瘤切除或血腫清除,面臨著極高的技術挑戰。這類手術要求在保護正常腦組織不受損傷的同時,精準定位并處理病灶。然而,開顱操作會導致顱內壓變化,進而使腦組織發生難以預測的位移,影響術中病變位置的準確性,增加了手術難度和風險。為應對這一挑戰,本文旨在通過綜合考慮CT 圖像、手術切口位置、腦組織力學特性、顱內壓變化等因素,通過構建人工智能模型預測開顱后腦組織的位移情況。本文沒有使用傳統的有限元方法建模,有限元建模計算資源需求高、時間消耗長、非專業用戶友好性極差,限制了其在臨床環境中的廣泛應用。而基于遷移學習的預訓練-微調模型解決了這些問題,通過預先訓練的模型共享參數后進行微調,極大的降低了運算資源以及數據需求量,對小樣本問題友好;不需要豐富專業知識進行復雜物理建模分析,更好地服務于臨床決策和手術規劃。
??我們分析了人工智能在醫學圖像領域的工作以及預測可行性,根據上述思想設計了通用醫學影像預訓練-微調模型,首先通過特征工程對105個特征進行處理,使用person相關系進行分析,通過向預訓練模塊輸入顱腦等器官CT影像數據,使模型學習醫學影像通用信息,共享預訓練模塊學習到的通用參數,再向模型輸入少量腫瘤位移前后影像信息以及臨床文本信息進行微調,使模型學習到更有針對性的細節信息。最后通過神經網絡,輸出目標轉移到大腦某區域位置概率。
??問題一,首先利用獲取的CT圖像獲取占位性病變的精確尺寸、位置、形狀以及與周圍腦組織的關系,進行三維重建。對物理屬性參數,如腦組織物理特性,粘彈性、顱內壓、骨窗大小等特性進行分析,模擬硬質占位性病變位移范圍,劃定顱腦范圍作為計算的輸入參數。最后,通過醫學影像預訓練-微調模型預測位移概率。
??問題二,血腫與問題一中的硬質占位性病變不同,可以簡單理解為固體與液體的區別,我們通過分析液體動力學、固體力學以及腦組織的非線性彈性行為,分析了血腫在開顱手術后的位移和形變。根據腦組織的力學屬性和血腫的流體力學屬性設計了新的損失函數。通過修改微調信息,來預測血腫在開顱后的位移和形變。
??最后,理想的神經外科手術導航系統應具備以下特點:提供高分辨率的實時影像引導,能夠適應腦組織的動態變化,擁有精確的術中定位能力,并且便于外科醫生操作,減少手術時間和并發癥。隨著計算機科學、圖像處理技術、機器學習以及生物力學模型的不斷進步,未來的神經外科手術有望實現更加個性化、精準的治療方案,提高手術成功率并降低患者風險。
問題分析:
??在分析本題的過程中我們注意到,整個腦部組織及其他人體特征的多樣性。首先在題目中提到的數據,如表一所示。
??針對數據問題:在Github的醫學影像數據集集錦倉庫1中,我們獲得了具有各類模態以及各類器官約20個方向的80+個數據集。通過篩選選擇了105個與本問題相關的參數,并且根據腦組的粘彈性等物理特性,開顱位置、大小以及膨出高度進行了數據模擬。
??針對問題一:在各類器官影像數據量大,而相關腫瘤開顱位移影像數據量稀少的情況下,我們將顱內組織位置通過使用遷移學習的思路,利用人工智能的方法對硬質占位性病變在開顱后的位移情況進行預測。首先采取遷移學習中經典的預訓練-微調模型,通過向預訓練模塊輸入大量各種器官的CT影像數據,使預訓練模塊學習與CT影像相關的大量通用信息;其次,根據(Schirmer,Gieseetal.2019)的文章我們將全腦劃分為10個不同的位置,我們將少量的包含腫瘤位移前后信息的三維數據以及文本信息數據,輸入到模型中進行微調;最后,模型輸出硬質占位性病變轉移位置的概率,通過聯合損失函數,留一交叉驗證對測試數據進行驗證,用ACC、F1分數、HausdorffDistance(豪斯多夫距離)對模型進行評估。
??針對問題二:據腦組織的力學屬性和血腫的流體力學屬性,我們在問題一的基礎上,仍然使用遷移學習進行預訓練微調的方法,進行血腫位移和形變預測。在預訓練模塊不需要做任何改動,直接調用預訓練模塊的通用參數即可,對于微調模塊,我們根據血腫的特性,通過分析液體動力學、固體力學以及腦組織的非線性彈性行為,設計了新的綜合損失函數。最后通過模型預測血腫在開顱大致的位移和形變。根據已有的有限數據,我們可以通過計算機視覺模型來輔助判斷出病變的類型。腦組織具有獨特的生物力學特性,其中包括各向異性和粘彈性[1],這些特性對腦部病變的診斷和研究至關重要。各向異性指的是腦組織在不同方向上的力學性能不同,而粘彈性則描述了腦組織在應力作用下的變形行為及其時間依賴性。通過對這些生物力學特性的分析和計算,我們可以粗略估計出腫瘤的位置偏移。
??為了進一步提升預測的準確性和模型的泛化能力,我們采用遷移學習的方法。遷移學習是一種將已有知識應用到新的但相關問題上的技術。具體來說,我們使用目前已有關于出血性腦卒中的研究成果作為遷移學習的基礎數據。這些研究成果包括大量的原始數據,這些數據經過充分的標注和分析,能夠為我們的模型提供強大的先驗知識基礎。通過使用這些出血性腦卒中的原始數據,我們能夠訓練一個初始模型,該模型可以實現對血腫及水腫位置的預測。在此基礎上,我們進一步將腦中病變及生理數據輸入該模型,并對其進行微調。這一過程稱為模型的微調(fine-tuning),旨在使模型更好地適應新的特定任務,從而提高其預測精度。通過這種方式,我們能夠實現對病變位移的準確預測,為臨床診斷和治療提供有力的輔助工具。這一系列步驟展示了計算機視覺技術在醫學影像分析中的巨大潛力,特別是在復雜腦部病變的診斷和治療方面。
模型假設:
??? 假設獲取的全部數據是準確無誤的;
??? 假設腦組織的特性符合粘彈性這一材料屬性的各項指標;
??? 假設顱骨內各個關聯組織之間無相對運動;
??? 假設正常腦組織和病變組織均質地均勻;
??? 假設忽略腦中的微觀結構;
??? 假設開顱過程是理想情況,一切操作均符合相關規范要求。
完整論文縮略圖
全部論文及代碼請見下方“ 只會建模 QQ名片” 點擊QQ名片即可
部分程序代碼:
import os
import torch
import torchvision as tv
import torchvision.transforms as transforms
import torch.nn as nn
import torch.optim as optim
import argparse
import skimage.data
import skimage.io
import skimage.transform
import numpy as np
import matplotlib.pyplot as plt
import torchvision.models as models
from PIL import Image
import cv2#提取某一層網絡特征圖
class FeatureExtractor(nn.Module):def __init__(self, submodule, extracted_layers):super(FeatureExtractor, self).__init__()self.submodule = submoduleself.extracted_layers = extracted_layersdef forward(self, x):outputs = {}for name, module in self.submodule._modules.items():if "fc" in name:x = x.view(x.size(0), -1)x = module(x)print(name)if (self.extracted_layers is None) or (name in self.extracted_layers and 'fc' not in name):outputs[name] = x# print(outputs)return outputsdef get_picture(pic_name, transform):img = skimage.io.imread(pic_name)img = skimage.transform.resize(img, (256, 256)) #讀入圖片時將圖片resize成(256,256)的img = np.asarray(img, dtype=np.float32)return transform(img)def make_dirs(path):if os.path.exists(path) is False:os.makedirs(path)pic_dir = 'dataset/brain/train/1700.jpg'
transform = transforms.ToTensor()
img = get_picture(pic_dir, transform)
# 插入維度
img = img.unsqueeze(0)device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
img = img.to(device)net = models.resnet101(pretrained=True).to(device)dst = './feautures'
therd_size = 256myexactor = FeatureExtractor(submodule=net, extracted_layers=None)
output = myexactor(img)
#output是dict
#dict_keys(['conv1', 'bn1', 'relu', 'maxpool', 'layer1', 'layer2', 'layer3', 'layer4', 'avgpool', 'fc'])for idx,val in enumerate(output.items()):k,v = valfeatures = v[0]iter_range = features.shape[0]for i in range(iter_range):# plt.imshow(features.data.cpu().numpy()[i,:,:],cmap='jet')if 'fc' in k: #不可視化fc層continuefeature = features.data.cpu().numpy()feature_img = feature[i, :, :]feature_img = np.asarray(feature_img * 255, dtype=np.uint8)dst_path = os.path.join(dst, str(idx)+'-'+k)make_dirs(dst_path)feature_img = cv2.applyColorMap(feature_img, cv2.COLORMAP_JET)if feature_img.shape[0] < therd_size:tmp_file = os.path.join(dst_path, str(i) + '_' + str(therd_size) + '.png')tmp_img = feature_img.copy()tmp_img = cv2.resize(tmp_img, (therd_size, therd_size), interpolation=cv2.INTER_NEAREST)cv2.imwrite(tmp_file, tmp_img)dst_file = os.path.join(dst_path, str(i) + '.png')cv2.imwrite(dst_file, feature_img)