學(xué)深度學(xué)習(xí):從功能連接到疾病分類(lèi)的完整實(shí)戰(zhàn)指南)
神經(jīng)影像與醫(yī)學(xué)深度學(xué)習(xí)的結(jié)合近幾年幾乎是計(jì)算機(jī)視覺(jué)和醫(yī)學(xué)圖像分析領(lǐng)域里最熱門(mén)的方向之一。無(wú)論是阿爾茨海默癥早期診斷、精神分裂癥生物標(biāo)志物挖掘還是腦機(jī)接口中的腦狀態(tài)解碼fMRI功能磁共振成像數(shù)據(jù)都扮演著核心角色。但很多剛接觸這個(gè)方向的同學(xué)會(huì)遇到同一個(gè)問(wèn)題自然圖像那套深度學(xué)習(xí)流程遷移到腦影像上似乎沒(méi)那么好用了。數(shù)據(jù)維度不對(duì)、樣本量太小、預(yù)處理流程復(fù)雜、模型可解釋性要求高處處都是坎。這篇文章會(huì)圍繞醫(yī)學(xué)深度學(xué)習(xí)在神經(jīng)影像中的應(yīng)用展開(kāi)重點(diǎn)針對(duì) fMRI 數(shù)據(jù)講清楚核心概念、科研應(yīng)用場(chǎng)景、完整的工具鏈與學(xué)習(xí)路徑并提供一個(gè)可以照著跑的實(shí)戰(zhàn)案例幫助初學(xué)者少走彎路。文章適合以下幾類(lèi)讀者醫(yī)學(xué)影像相關(guān)的碩士研究生、博士研究生尤其是剛接觸神經(jīng)影像分析的同學(xué)想從自然圖像 CV 轉(zhuǎn)向醫(yī)學(xué)圖像方向的算法工程師對(duì)腦科學(xué)、人工智能交叉方向感興趣但不知道從哪下手的初學(xué)者已經(jīng)在做結(jié)構(gòu)像 MRI 分析想擴(kuò)展到 fMRI 功能像分析的研究者。讀完這篇文章你會(huì)掌握 fMRI 數(shù)據(jù)的基本結(jié)構(gòu)、主流分析流程、深度學(xué)習(xí)建模的常見(jiàn)思路以及一套從零開(kāi)始的完整學(xué)習(xí)路線(xiàn)。1. 為什么神經(jīng)科學(xué) AI 被稱(chēng)為黃金賽道1.1 從醫(yī)學(xué)深度學(xué)習(xí)說(shuō)起醫(yī)學(xué)深度學(xué)習(xí)是深度學(xué)習(xí)技術(shù)在醫(yī)療健康領(lǐng)域的應(yīng)用總稱(chēng)覆蓋醫(yī)學(xué)影像診斷、病理切片分析、電子病歷挖掘、藥物發(fā)現(xiàn)、基因組學(xué)等多個(gè)子方向。其中醫(yī)學(xué)影像因?yàn)閿?shù)據(jù)形態(tài)相對(duì)規(guī)整、任務(wù)目標(biāo)明確成為落地最活躍的領(lǐng)域。常見(jiàn)的醫(yī)學(xué)影像模態(tài)包括CT計(jì)算機(jī)斷層掃描主要看解剖結(jié)構(gòu)MRI磁共振成像結(jié)構(gòu)像看解剖功能像看腦活動(dòng)超聲實(shí)時(shí)性強(qiáng)常用于腹部和心血管檢查病理切片超高分辨率二維圖像需要特殊處理眼底照視網(wǎng)膜成像用于糖尿病視網(wǎng)膜病變篩查。在所有這些模態(tài)中fMRI 是比較特殊的一種。它并不是一張靜態(tài)圖片而是包含空間結(jié)構(gòu)和時(shí)間序列的四維數(shù)據(jù)。這意味著深度學(xué)習(xí)模型要同時(shí)捕捉空間模式和時(shí)間動(dòng)態(tài)建模難度要比普通二維圖像高一個(gè)檔次。1.2 為什么神經(jīng)影像方向值得投入神經(jīng)影像 AI 之所以被很多人稱(chēng)為“黃金賽道”主要是因?yàn)橐韵聨c(diǎn)第一臨床需求真實(shí)且迫切。神經(jīng)系統(tǒng)疾病包括阿爾茨海默癥、帕金森病、精神分裂癥、抑郁癥、自閉癥譜系障礙等往往缺乏客觀(guān)的生物學(xué)診斷指標(biāo)。醫(yī)生主要依賴(lài)量表評(píng)估和行為觀(guān)察主觀(guān)性較強(qiáng)。如果模型能從 fMRI 數(shù)據(jù)中找到穩(wěn)定的腦活動(dòng)模式差異就有希望成為輔助診斷的生物標(biāo)志物。這種需求是剛性的。第二數(shù)據(jù)有獨(dú)特的學(xué)術(shù)價(jià)值。腦是人體最復(fù)雜的器官fMRI 數(shù)據(jù)記錄了大腦在任務(wù)刺激或靜息狀態(tài)下的血氧水平依賴(lài)信號(hào)BOLD 信號(hào)本質(zhì)上是一種高維時(shí)空數(shù)據(jù)。通過(guò)對(duì) fMRI 的建模研究者不僅能做分類(lèi)預(yù)測(cè)還能反過(guò)來(lái)探索“哪個(gè)腦區(qū)和哪個(gè)腦區(qū)之間的連接模式發(fā)生了改變”這種可解釋性分析對(duì)腦科學(xué)基礎(chǔ)研究非常有價(jià)值。第三交叉學(xué)科壁壘帶來(lái)的稀缺性。既懂深度學(xué)習(xí)又懂神經(jīng)影像的人目前仍然相對(duì)稀缺。純做算法的同學(xué)不熟悉腦結(jié)構(gòu)純做臨床的同學(xué)不熟悉深度學(xué)習(xí)。能夠把兩邊銜接起來(lái)的人在科研合作、項(xiàng)目落地、論文產(chǎn)出上都有明顯優(yōu)勢(shì)。1.3 常見(jiàn)應(yīng)用場(chǎng)景神經(jīng)影像 AI 的實(shí)際應(yīng)用場(chǎng)景非常豐富以下是幾個(gè)典型的任務(wù)疾病分類(lèi)根據(jù) fMRI 數(shù)據(jù)判斷被試屬于患者組還是健康對(duì)照組例如精神分裂癥分類(lèi)、阿爾茨海默癥識(shí)別。腦齡預(yù)測(cè)利用結(jié)構(gòu)像或功能像預(yù)測(cè)被試的“腦齡”腦齡與真實(shí)年齡的差距可以作為腦健康程度的指標(biāo)。認(rèn)知狀態(tài)解碼從任務(wù)態(tài) fMRI 中預(yù)測(cè)被試正在進(jìn)行的認(rèn)知活動(dòng)例如看的是貓還是狗或者正在回憶什么內(nèi)容。功能連接分析不直接做分類(lèi)而是通過(guò)功能連接矩陣比較兩組被試的腦網(wǎng)絡(luò)差異屬于更偏統(tǒng)計(jì)分析的方向。影像基因組學(xué)結(jié)合 fMRI 與基因數(shù)據(jù)分析腦活動(dòng)模式與遺傳變異之間的關(guān)聯(lián)。這些場(chǎng)景中深度學(xué)習(xí)主要承擔(dān)兩種角色一種是端到端的預(yù)測(cè)模型直接吃原始 fMRI 或預(yù)處理后的數(shù)據(jù)做分類(lèi)另一種是特征提取器將深度學(xué)習(xí)得到的表征與傳統(tǒng)的統(tǒng)計(jì)分析結(jié)合。2. fMRI 數(shù)據(jù)的核心概念在動(dòng)手寫(xiě)代碼之前先把 fMRI 數(shù)據(jù)本身搞清楚。很多人一開(kāi)始就直接跑深度學(xué)習(xí)模型結(jié)果模型不收斂、效果差回頭才發(fā)現(xiàn)連數(shù)據(jù)長(zhǎng)什么樣都沒(méi)弄明白。2.1 BOLD 信號(hào)與 fMRI 成像原理fMRI 的全稱(chēng)是 functional Magnetic Resonance Imaging即功能磁共振成像。它測(cè)量的并不是神經(jīng)元放電本身而是血氧水平依賴(lài)信號(hào)也就是 BOLD 信號(hào)。其基本原理是當(dāng)某個(gè)腦區(qū)活躍時(shí)局部腦血流量增加含氧血紅蛋白與脫氧血紅蛋白的比例發(fā)生變化。脫氧血紅蛋白是順磁性的會(huì)擾動(dòng)局部磁場(chǎng)從而影響 MRI 信號(hào)強(qiáng)度。通過(guò)對(duì)這種信號(hào)的連續(xù)采集可以間接反映神經(jīng)活動(dòng)的時(shí)間變化。需要特別注意的是BOLD 信號(hào)是一種間接且滯后的測(cè)量信號(hào)時(shí)間分辨率有限通常每隔 1 到 3 秒采集一個(gè)全腦 volume。因此fMRI 并不是“實(shí)時(shí)記錄神經(jīng)元活動(dòng)”而是通過(guò)血流動(dòng)力學(xué)響應(yīng)間接推斷神經(jīng)活動(dòng)。2.2 4D 數(shù)據(jù)空間維度和時(shí)間維度一次標(biāo)準(zhǔn)的 fMRI 掃描得到的數(shù)據(jù)通常是一個(gè)四維數(shù)組X冠狀位方向的空間維度Y矢狀位方向的空間維度Z軸位方向的空間維度T時(shí)間幀數(shù)。舉個(gè)例子一個(gè)常見(jiàn)的 fMRI 掃描參數(shù)可能是61 × 73 × 61的空間分辨率TR重復(fù)時(shí)間為 2 秒共掃描 120 個(gè)時(shí)間點(diǎn)。那么數(shù)據(jù)結(jié)構(gòu)就是61 × 73 × 61 × 120其中前三個(gè)維度構(gòu)成一個(gè)大腦的三維體積第四維是時(shí)間序列。理解這一點(diǎn)非常關(guān)鍵因?yàn)楹芏嗌疃葘W(xué)習(xí)模型的設(shè)計(jì)都圍繞這四個(gè)維度展開(kāi)如果忽略時(shí)間維度把每個(gè) volume 當(dāng)作獨(dú)立樣本就退化為 3D CNN 分類(lèi)問(wèn)題如果保留時(shí)間維度可以用 4D CNN、CNN RNN 或 Transformer 處理如果先提取每個(gè)腦區(qū)的平均信號(hào)序列再算腦區(qū)之間的相關(guān)性就得到功能連接矩陣可以用 2D CNN 或圖神經(jīng)網(wǎng)絡(luò)。2.3 fMRI 與結(jié)構(gòu)像 MRI 的區(qū)別剛?cè)腴T(mén)的人容易把 fMRI 和結(jié)構(gòu)性 MRI 混在一起。實(shí)際上它們的區(qū)別非常明顯維度結(jié)構(gòu)像 MRI功能像 fMRI數(shù)據(jù)形態(tài)3D 單張圖像3D 時(shí)間的 4D 序列主要信息解剖結(jié)構(gòu)、組織類(lèi)型血氧信號(hào)的時(shí)間變化空間分辨率較高可達(dá) 1mm 各向同性較低常見(jiàn) 2-3mm時(shí)間分辨率無(wú)較低TR 通常為 1-3 秒典型任務(wù)腫瘤分割、腦區(qū)分割功能連接分類(lèi)、腦狀態(tài)解碼有些研究還會(huì)把結(jié)構(gòu)像和功能像一起作為多模態(tài)輸入比如 Alzheimer’s 分類(lèi)中把 T1 結(jié)構(gòu)像和靜息態(tài) fMRI 結(jié)合。這樣能互補(bǔ)信息但多模態(tài)的數(shù)據(jù)預(yù)處理和模型融合復(fù)雜度也更高。2.4 靜息態(tài) fMRI 和任務(wù)態(tài) fMRIfMRI 數(shù)據(jù)根據(jù)采集時(shí)被試的狀態(tài)可以分成兩大類(lèi)靜息態(tài) fMRIrs-fMRI被試不執(zhí)行任何任務(wù)閉眼放松休息大腦處于自發(fā)的低頻活動(dòng)狀態(tài)。這種數(shù)據(jù)最常用于疾病分類(lèi)研究因?yàn)樗恍枰獜?fù)雜的任務(wù)設(shè)計(jì)臨床采集方便跨中心的標(biāo)準(zhǔn)化程度相對(duì)較高。任務(wù)態(tài) fMRItask-fMRI被試在掃描過(guò)程中執(zhí)行特定任務(wù)例如手指敲擊、圖片觀(guān)看、記憶編碼等。任務(wù)態(tài)數(shù)據(jù)更適合研究特定認(rèn)知功能對(duì)應(yīng)的腦區(qū)激活模式但不同實(shí)驗(yàn)范式的設(shè)計(jì)差異很大跨研究比較困難。對(duì)于入門(mén)者通常建議從靜息態(tài) fMRI 開(kāi)始因?yàn)樗鞒滔鄬?duì)固定公開(kāi)數(shù)據(jù)集也更多。3. 神經(jīng)影像 AI 的科研應(yīng)用全景這一部分把目前主流的研究方向梳理一遍。每個(gè)方向看似都是“分類(lèi)”或“回歸”但實(shí)際技術(shù)方案差別很大。3.1 基于功能連接的疾病分類(lèi)這是靜息態(tài) fMRI 中最主流的研究范式。思路分三步走將大腦按照標(biāo)準(zhǔn)圖譜劃分成若干個(gè)感興趣區(qū)ROI常用的圖譜包括 AAL、Desikan-Killiany、Gordon 等提取每個(gè) ROI 的平均 BOLD 時(shí)間序列計(jì)算 ROI 兩兩之間的皮爾遜相關(guān)系數(shù)得到一個(gè)N × N的功能連接矩陣以功能連接矩陣作為特征訓(xùn)練分類(lèi)器或者將矩陣當(dāng)作圖像輸入卷積網(wǎng)絡(luò)。這種做法的優(yōu)勢(shì)在于特征維度大幅降低從原始的百萬(wàn)級(jí)體素降到幾百維或幾千維緩解了樣本量不足的問(wèn)題。同時(shí)功能連接矩陣具有明確的神經(jīng)生物學(xué)意義實(shí)驗(yàn)結(jié)果更容易解釋。3.2 基于體素/灰質(zhì)體積的淺層分類(lèi)如果做結(jié)構(gòu)像分析可以計(jì)算每個(gè)體素或每個(gè)腦區(qū)的灰質(zhì)體積然后使用 SVM、邏輯回歸等傳統(tǒng)機(jī)器學(xué)習(xí)方法分類(lèi)。這種方法在 Alzheimers 分類(lèi)中非常經(jīng)典優(yōu)點(diǎn)是簡(jiǎn)單、穩(wěn)健、可解釋性強(qiáng)。但要注意這種方法對(duì)圖像配準(zhǔn)的精度要求極高。不同被試的大腦形狀不同必須先把所有圖像配準(zhǔn)到同一個(gè)標(biāo)準(zhǔn)空間比如 MNI 空間才能保證同一個(gè)體素在不同被試之間對(duì)應(yīng)的是同一個(gè)解剖位置。3.3 端到端深度模型隨著深度學(xué)習(xí)的發(fā)展越來(lái)越多研究嘗試讓模型直接吃預(yù)處理后的 fMRI 數(shù)據(jù)跳過(guò)人工特征工程。典型方案3D CNN把每個(gè)時(shí)間點(diǎn)的 brain volume 當(dāng)作 3D 圖像輸入。4D CNN / RNN 組合先用 3D CNN 提取空間特征再用 RNN 或 LSTM 建模時(shí)間動(dòng)態(tài)。Transformer把腦區(qū)時(shí)間序列當(dāng)作 token 序列用自注意力機(jī)制建模腦區(qū)間的長(zhǎng)程依賴(lài)關(guān)系。圖神經(jīng)網(wǎng)絡(luò)GNN將大腦建模為圖節(jié)點(diǎn)是 ROI邊是功能連接強(qiáng)度或結(jié)構(gòu)連接在圖級(jí)別做分類(lèi)。這些方法在論文里效果往往不錯(cuò)但在實(shí)際應(yīng)用中需要面對(duì)樣本量小、過(guò)擬合嚴(yán)重、可解釋性差等問(wèn)題。3.4 腦齡預(yù)測(cè)腦齡預(yù)測(cè)是另一個(gè)熱門(mén)的研究方向。研究者使用深度學(xué)習(xí)模型從 T1 結(jié)構(gòu)像或功能連接特征中預(yù)測(cè)被試的年齡然后計(jì)算“預(yù)測(cè)腦齡減去真實(shí)年齡”的差值即 PADPredicted Age Difference。如果某個(gè)人群的 PAD 顯著大于 0說(shuō)明其大腦看起來(lái)比同齡人更老可能與神經(jīng)退行性疾病相關(guān)。腦齡預(yù)測(cè)已經(jīng)被應(yīng)用于輕度認(rèn)知障礙、精神分裂癥、艾滋病相關(guān)神經(jīng)認(rèn)知障礙等多種疾病研究。這個(gè)方向的技術(shù)核心不是分類(lèi)精度而是回歸模型的準(zhǔn)確性和泛化能力。3.5 多中心數(shù)據(jù)的泛化問(wèn)題在真實(shí)科研項(xiàng)目中很少只用單中心數(shù)據(jù)。比如 ABIDE 數(shù)據(jù)集就包含來(lái)自 17 個(gè)不同采集中心的數(shù)據(jù)不同中心的掃描儀型號(hào)、采集參數(shù)、被試群體都有差異。模型在一個(gè)中心上訓(xùn)練效果好到另一個(gè)中心上性能可能明顯下降。這就是所謂的“跨站點(diǎn)泛化問(wèn)題”。目前在多中心 fMRI 研究中處理方式包括使用 ComBat 等工具進(jìn)行數(shù)據(jù)協(xié)調(diào)使用域適應(yīng)或域泛化方法把中心信息作為協(xié)變量加入模型采用更穩(wěn)健的預(yù)處理流程盡量減少采集參數(shù)對(duì)數(shù)據(jù)的影響。這一點(diǎn)需要從項(xiàng)目一開(kāi)始就考慮等后面發(fā)現(xiàn)泛化不行再回頭處理會(huì)浪費(fèi)大量時(shí)間和算力。4. 環(huán)境準(zhǔn)備與工具鏈4.1 操作系統(tǒng)與硬件神經(jīng)影像分析和深度學(xué)習(xí)訓(xùn)練通常在 Linux 環(huán)境下進(jìn)行推薦 Ubuntu 20.04 或 22.04。GPU 是必需的尤其是端到端深度學(xué)習(xí)模型顯存建議至少 8GB 以上如果做傳統(tǒng)機(jī)器學(xué)習(xí)或功能連接分類(lèi)CPU 也可以應(yīng)付只是速度慢一些。Windows 也能跑大部分 Python 庫(kù)但在神經(jīng)影像工具鏈的兼容性上不如 Linux。這里還是最推薦 Linux。4.2 Python 環(huán)境建議使用conda管理 Python 環(huán)境Python 版本選擇 3.9 或 3.10 即可。這里給出一個(gè)示例建環(huán)境命令conda create -n neuroai python3.10 conda activate neuroai注意具體庫(kù)的兼容性會(huì)隨版本變化如果安裝過(guò)程遇到問(wèn)題優(yōu)先查看對(duì)應(yīng)庫(kù)的官方文檔確認(rèn) Python 版本支持情況。4.3 核心 Python 庫(kù)神經(jīng)影像研究需要安裝以下幾類(lèi)庫(kù)。醫(yī)學(xué)圖像讀取與處理# 讀取 nii.gz 格式的神經(jīng)影像數(shù)據(jù) import nibabel as nib img nib.load(sub-01_T1w.nii.gz) data img.get_fdata() print(data.shape)nibabel是幾乎所有神經(jīng)影像分析工作的基礎(chǔ)庫(kù)支持 NIfTI、GIFTI、CIFTI 等格式。拿到數(shù)據(jù)后第一件事通常是打印數(shù)據(jù)形狀確認(rèn)是 3D 還是 4D。影像預(yù)處理和可視化nilearn是專(zhuān)門(mén)為神經(jīng)影像機(jī)器學(xué)習(xí)設(shè)計(jì)的 Python 庫(kù)封裝了預(yù)處理、圖譜提取、功能連接計(jì)算、可視化等常用功能非常適合入門(mén)。from nilearn import plotting, datasets # 加載示例數(shù)據(jù) haxby_dataset datasets.fetch_haxby() # 顯示一個(gè)統(tǒng)計(jì)圖 plotting.plot_stat_map(example_stat.nii.gz)流程化預(yù)處理fMRIPrep是當(dāng)前 fMRI 預(yù)處理的主流工具自動(dòng)完成頭動(dòng)校正、時(shí)間層校正、配準(zhǔn)、歸一化等步驟。它運(yùn)行在 Docker 或 Singularity 容器中輸出處理后的數(shù)據(jù)以及豐富的質(zhì)量報(bào)告。深度學(xué)習(xí)框架PyTorch 在醫(yī)學(xué)影像領(lǐng)域的使用率遠(yuǎn)高于其他框架主要原因是生態(tài)豐富、動(dòng)態(tài)圖靈活、社區(qū)資料多。安裝命令pip install torch torchvision如果要用圖神經(jīng)網(wǎng)絡(luò)還需要安裝torch-geometric安裝方式與其支持的 CUDA 版本有關(guān)建議參考官網(wǎng)。4.4 常用公開(kāi)數(shù)據(jù)集在科研中數(shù)據(jù)質(zhì)量直接決定實(shí)驗(yàn)效果。以下是幾個(gè)常用的公開(kāi) fMRI 數(shù)據(jù)集ABIDE自閉癥譜系障礙靜息態(tài) fMRI 數(shù)據(jù)集包含 17 個(gè)中心的數(shù)據(jù)適合做跨中心分類(lèi)實(shí)驗(yàn)。HCP人類(lèi)連接組計(jì)劃包含高質(zhì)量的任務(wù)態(tài)和靜息態(tài) fMRI數(shù)據(jù)量大、質(zhì)量高適合做認(rèn)知解碼和分析方法研究。ADNI阿爾茨海默癥神經(jīng)影像計(jì)劃包含 MRI、PET、臨床數(shù)據(jù)適合做疾病進(jìn)展預(yù)測(cè)和生物標(biāo)志物挖掘。UK Biobank大規(guī)模生物樣本庫(kù)包含數(shù)萬(wàn)人的腦影像數(shù)據(jù)適合做腦齡預(yù)測(cè)和大規(guī)模統(tǒng)計(jì)分析。COBRE精神分裂癥 fMRI 數(shù)據(jù)集規(guī)模適中適合快速驗(yàn)證模型。每個(gè)數(shù)據(jù)集都有自己的倫理授權(quán)協(xié)議和使用限制下載前務(wù)必查看對(duì)應(yīng)官網(wǎng)的 Terms of Use。4.5 目錄結(jié)構(gòu)規(guī)劃一個(gè)規(guī)范的 fMRI 深度學(xué)習(xí)項(xiàng)目目錄結(jié)構(gòu)可以參考下面neuro_project/ ├── data/ │ ├── raw/ # 原始 NIfTI 數(shù)據(jù) │ ├── processed/ # 預(yù)處理后數(shù)據(jù) │ └── derivatives/ # fMRIPrep 輸出 ├── src/ │ ├── preprocessing.py │ ├── build_connectome.py │ ├── dataset.py │ ├── model.py │ └── train.py ├── config/ │ └── config.yaml ├── results/ │ ├── models/ │ └── logs/ └── README.md從一開(kāi)始就保持目錄清晰能避免后期寫(xiě)論文時(shí)到處找數(shù)據(jù)文件的問(wèn)題。5. 核心處理方法與代碼示例這一節(jié)列出 fMRI 分析中最常用的幾個(gè)環(huán)節(jié)每段代碼都可以直接參考使用。5.1 數(shù)據(jù)加載與基礎(chǔ)檢查拿到 fMRI 數(shù)據(jù)后第一步永遠(yuǎn)是檢查數(shù)據(jù)的基本屬性包括形狀、體素大小、TR 等。import nibabel as nib func_path path/to/sub-01_task-rest_bold.nii.gz func_img nib.load(func_path) # 4D 數(shù)據(jù)形狀: (x, y, z, time) data func_img.get_fdata() print(4D shape:, data.shape) # 獲取體素大小 zooms func_img.header.get_zooms() print(voxel sizes:, zooms) # 獲取 TR tr func_img.header[pixdim][4] print(TR:, tr)這里有一個(gè)新手常犯的錯(cuò)誤直接用get_fdata()讀取 4D 數(shù)據(jù)并傳入 PyTorch卻忘了數(shù)據(jù)存儲(chǔ)的數(shù)據(jù)類(lèi)型可能是float64顯存占用是float32的兩倍。建議讀取后轉(zhuǎn)換為float32data func_img.get_fdata(dtypefloat32)5.2 掩膜提取與時(shí)間序列提取fMRI 數(shù)據(jù)包含大量非腦組織體素直接全腦計(jì)算會(huì)引入大量噪聲。通常需要先使用腦掩膜brain mask或圖譜把數(shù)據(jù)限定在灰質(zhì)或特定 ROI 內(nèi)。nilearn提供了非常方便的接口from nilearn.input_data import NiftiLabelsMasker, NiftiMasker # 使用標(biāo)準(zhǔn)圖譜 AAL提取每個(gè) ROI 的平均時(shí)間序列 masker NiftiLabelsMasker( labels_imgpath/to/aal.nii.gz, standardizeTrue, memorycache, verbose1 ) # 輸入 4D 數(shù)據(jù)輸出 2D 數(shù)組形狀為 (時(shí)間點(diǎn)數(shù), ROI數(shù)) time_series masker.fit_transform(path/to/sub-01_task-rest_bold.nii.gz) print(time_series.shape)NiftiLabelsMasker是最常用的工具之一它自動(dòng)完成配準(zhǔn)、重采樣、ROI 信號(hào)提取、標(biāo)準(zhǔn)化等步驟。輸出的time_series每一列代表一個(gè)腦區(qū)在不同時(shí)間點(diǎn)上的平均信號(hào)。5.3 功能連接矩陣的構(gòu)建拿到 ROI 時(shí)間序列后下一步通常就是計(jì)算功能連接矩陣import numpy as np # 計(jì)算 Pearson 相關(guān)系數(shù)矩陣 connectome np.corrcoef(time_series.T) # 對(duì)角線(xiàn)置零去除自相關(guān) np.fill_diagonal(connectome, 0) print(Connectome shape:, connectome.shape)這個(gè)連接矩陣就是后續(xù)分類(lèi)的輸入特征。可以把矩陣下表存儲(chǔ)為.npy或.csv文件供傳統(tǒng)機(jī)器學(xué)習(xí)使用也可以轉(zhuǎn)成 PyTorch Tensor 輸入圖神經(jīng)網(wǎng)絡(luò)。5.4 簡(jiǎn)單 SVM 分類(lèi)基線(xiàn)在做深度學(xué)習(xí)之前強(qiáng)烈建議先跑一個(gè)簡(jiǎn)單的 SVM 基線(xiàn)。一方面能檢驗(yàn)特征是否有效另一方面深度學(xué)習(xí)的效果必須超過(guò)基線(xiàn)才有意義。from sklearn.model_selection import cross_val_score from sklearn.svm import SVC import numpy as np # X: 上三角連接矩陣展平后的特征 # y: 標(biāo)簽數(shù)組, 0/1 # 取上三角避免對(duì)稱(chēng)矩陣的重復(fù)信息 triu_idx np.triu_indices_from(connectome, k1) X connectome[triu_idx].reshape(1, -1) clf SVC(kernellinear, C1.0) scores cross_val_score(clf, X, y, cv5, scoringaccuracy) print(fCV accuracy: {scores.mean():.3f} ± {scores.std():.3f})在 ABIDE 數(shù)據(jù)集上線(xiàn)性 SVM 的分類(lèi)準(zhǔn)確率通常在 60% 到 70% 左右具體取決于預(yù)處理和特征選擇。要超過(guò)這個(gè)基線(xiàn)深度學(xué)習(xí)模型必須能提取到 SVM 學(xué)不到的更復(fù)雜的特征。5.5 簡(jiǎn)單 2D CNN 分類(lèi)模型當(dāng)功能連接矩陣的維度不高時(shí)一種常見(jiàn)的做法是直接把它當(dāng)作單通道圖像輸入 2D CNN。盡管它并不是真正的“自然圖像”但 CNN 能捕捉到相鄰 ROI 之間的局部相關(guān)性模式。import torch import torch.nn as nn class ConnectomeCNN(nn.Module): def __init__(self, n_regions116, n_classes2): super().__init__() self.conv1 nn.Conv2d(1, 32, kernel_size3, padding1) self.conv2 nn.Conv2d(32, 64, kernel_size3, padding1) self.pool nn.MaxPool2d(2) self.flatten nn.Flatten() # 動(dòng)態(tài)計(jì)算全連接層輸入維度 dummy torch.zeros(1, 1, n_regions, n_regions) flat_dim self._get_flat_dim(dummy) self.fc nn.Linear(flat_dim, n_classes) def _get_flat_dim(self, x): x self.pool(torch.relu(self.conv1(x))) x self.pool(torch.relu(self.conv2(x))) return self.flatten(x).shape[1] def forward(self, x): x torch.relu(self.conv1(x)) x self.pool(x) x torch.relu(self.conv2(x)) x self.pool(x) x self.flatten(x) return self.fc(x)這段代碼是核心片段需要配合數(shù)據(jù)加載和訓(xùn)練腳本使用。n_regions需要與圖譜的 ROI 數(shù)量一致。5.6 時(shí)空序列建模的 RNN 方案如果不想丟失時(shí)間信息可以把 ROI 時(shí)間序列直接輸入循環(huán)神經(jīng)網(wǎng)絡(luò)。此時(shí)每個(gè)時(shí)間點(diǎn)的輸入是一個(gè)腦區(qū)信號(hào)向量import torch.nn as nn class RNNClassifier(nn.Module): def __init__(self, n_regions116, hidden_size64, n_classes2): super().__init__() self.lstm nn.LSTM( input_sizen_regions, hidden_sizehidden_size, batch_firstTrue, bidirectionalTrue ) self.fc nn.Linear(hidden_size * 2, n_classes) def forward(self, x): # x 形狀: (batch, T, n_regions) out, _ self.lstm(x) # 取最后一個(gè)時(shí)間步的輸出 last_out out[:, -1, :] return self.fc(last_out)這種模型的任務(wù)理解是每個(gè)時(shí)間點(diǎn)各腦區(qū)的活動(dòng)模式經(jīng)過(guò) LSTM 編碼后最后匯總成整個(gè)掃描序列的表示再做分類(lèi)。6. 完整實(shí)戰(zhàn)基于 ABIDE 的 ASD 分類(lèi)接下來(lái)用一個(gè)相對(duì)完整的項(xiàng)目把上面所有環(huán)節(jié)串起來(lái)。由于 ABIDE 原始數(shù)據(jù)下載需要申請(qǐng)這里提供一套代碼框架你可以根據(jù)自己的數(shù)據(jù)目錄調(diào)整路徑。6.1 數(shù)據(jù)準(zhǔn)備假設(shè)你已經(jīng)下載了 ABIDE 預(yù)處理的靜息態(tài) fMRI 數(shù)據(jù)每個(gè)被試的文件名格式為sub-50001_task-rest_bold.nii.gz同時(shí)準(zhǔn)備一個(gè)labels.csv包含兩列subject_id和label。subject_id,label 50001,0 50002,1 50003,1 ...標(biāo)簽為 0 表示健康對(duì)照1 表示 ASD 患者。6.2 批量提取功能連接矩陣先把每個(gè)被試的 fMRI 數(shù)據(jù)經(jīng)過(guò)圖譜分割和時(shí)間序列提取得到對(duì)應(yīng)的功能連接矩陣。import os import glob import numpy as np import pandas as pd from nilearn.input_data import NiftiLabelsMasker def build_connectomes(func_dir, labels_file, atlas_path, output_dir): os.makedirs(output_dir, exist_okTrue) labels_df pd.read_csv(labels_file) masker NiftiLabelsMasker( labels_imgatlas_path, standardizeTrue, memorycache, memory_level2, n_jobs2 ) for _, row in labels_df.iterrows(): sub_id row[subject_id] func_path os.path.join(func_dir, fsub-{sub_id}_task-rest_bold.nii.gz) if not os.path.exists(func_path): print(fMissing: {func_path}) continue # 提取 ROI 時(shí)間序列 ts masker.fit_transform(func_path) # 計(jì)算功能連接矩陣 conn np.corrcoef(ts.T) np.fill_diagonal(conn, 0) # 保存 save_path os.path.join(output_dir, fsub-{sub_id}_connectome.npy) np.save(save_path, conn) print(fFinished: {sub_id}, shape{conn.shape}) print(All connectomes are saved.)這段代碼的核心邏輯就是循環(huán)每個(gè)被試做序列提取、計(jì)算相關(guān)矩陣、保存。實(shí)際運(yùn)行時(shí)間取決于數(shù)據(jù)量和機(jī)器性能幾百個(gè)被試一般需要幾十分鐘到數(shù)小時(shí)。6.3 訓(xùn)練數(shù)據(jù)切分把功能連接矩陣和標(biāo)簽組裝成 PyTorch 的數(shù)據(jù)集import torch from torch.utils.data import Dataset, DataLoader class ConnectomeDataset(Dataset): def __init__(self, conn_dir, labels_file, n_regions116): labels_df pd.read_csv(labels_file) self.conn_paths [] self.labels [] for _, row in labels_df.iterrows(): sub_id row[subject_id] label int(row[label]) conn_path os.path.join(conn_dir, fsub-{sub_id}_connectome.npy) if os.path.exists(conn_path): self.conn_paths.append(conn_path) self.labels.append(label) self.n_regions n_regions def __len__(self): return len(self.conn_paths) def __getitem__(self, idx): conn np.load(self.conn_paths[idx]).astype(np.float32) # 加一個(gè)通道維度: (1, N, N) x torch.from_numpy(conn).unsqueeze(0) y torch.tensor(self.labels[idx], dtypetorch.long) return x, y注意這里的數(shù)據(jù)集假設(shè)每個(gè) connectome 矩陣都是按同一個(gè)圖譜順序排列的。不同圖譜中 ROI 的編號(hào)順序會(huì)影響矩陣結(jié)構(gòu)實(shí)驗(yàn)時(shí)必須保持一致。6.4 訓(xùn)練循環(huán)基礎(chǔ)訓(xùn)練循環(huán)如下import torch.optim as optim def train_one_epoch(model, dataloader, optimizer, criterion, device): model.train() total_loss 0 correct 0 total 0 for x, y in dataloader: x, y x.to(device), y.to(device) optimizer.zero_grad() out model(x) loss criterion(out, y) loss.backward() optimizer.step() total_loss loss.item() * x.size(0) pred out.argmax(dim1) correct (pred y).sum().item() total y.size(0) return total_loss / total, correct / total device torch.device(cuda if torch.cuda.is_available() else cpu) model ConnectomeCNN(n_regions116, n_classes2).to(device) optimizer optim.Adam(model.parameters(), lr1e-4) criterion nn.CrossEntropyLoss() for epoch in range(30): loss, acc train_one_epoch(model, train_loader, optimizer, criterion, device) print(fEpoch {epoch1}: loss{loss:.4f}, acc{acc:.4f})6.5 預(yù)期結(jié)果與說(shuō)明在 ABIDE 數(shù)據(jù)集上最后的分類(lèi)準(zhǔn)確率通常不會(huì)像自然圖像那樣輕松達(dá)到 90% 以上。如果預(yù)處理合適、樣本量充足二分類(lèi)準(zhǔn)確率在 65% 到 75% 之間已經(jīng)算是正常范圍。影響結(jié)果的變量很多樣本量、站點(diǎn)差異、圖譜選擇、是否做特征選擇、訓(xùn)練集和測(cè)試集的劃分方式等。因此當(dāng)模型準(zhǔn)確率不高時(shí)不要急著堆模型結(jié)構(gòu)首先檢查數(shù)據(jù)處理流程和數(shù)據(jù)劃分是否合理然后對(duì)比 SVM 基線(xiàn)接著再考慮是否引入更復(fù)雜的網(wǎng)絡(luò)。7. 常見(jiàn)問(wèn)題與排查思路7.1 典型問(wèn)題速查表問(wèn)題現(xiàn)象常見(jiàn)原因解決思路數(shù)據(jù)讀取后形狀不對(duì)NIfTI 數(shù)據(jù)可能是 3D也可能是 4D可能是按最后一維排列時(shí)間幀用nibabel.squeeze處理單例維度打印原始形狀并核對(duì)模型訓(xùn)練不收斂學(xué)習(xí)率過(guò)大、輸入數(shù)據(jù)未標(biāo)準(zhǔn)化、標(biāo)簽不平衡降低學(xué)習(xí)率檢查數(shù)據(jù)均值方差使用加權(quán)損失函數(shù)訓(xùn)練集準(zhǔn)確率高測(cè)試集很低樣本量小導(dǎo)致過(guò)擬合使用交叉驗(yàn)證、數(shù)據(jù)增強(qiáng)、Dropout、L2 正則化不同數(shù)據(jù)中心的同一類(lèi)別效果差距大跨站點(diǎn)數(shù)據(jù)分布差異使用數(shù)據(jù)協(xié)調(diào)工具按站點(diǎn)分層切分考慮域適應(yīng)方法功能連接矩陣中有 NaN某些 ROI 時(shí)間序列方差為 0或是掩膜外區(qū)域檢查 ROI 掩膜與功能數(shù)據(jù)的對(duì)齊情況對(duì)異常 ROI 進(jìn)行過(guò)濾顯存不足4D 數(shù)據(jù)直接輸入模型導(dǎo)致內(nèi)存爆炸先降維為功能連接矩陣或縮小 batch size圖譜與數(shù)據(jù)不對(duì)齊沒(méi)有做配準(zhǔn)或重采樣使用NiftiLabelsMasker前確認(rèn)圖譜與功能數(shù)據(jù)空間一致7.2 數(shù)據(jù)加載問(wèn)題神經(jīng)影像數(shù)據(jù)的格式非常多常見(jiàn)的有.nii、.nii.gz、.dcmDICOM等。.nii.gz是最推薦的格式。如果你拿到的是 DICOM 文件夾需要先使用dcm2niix或dcm2nii轉(zhuǎn)換。轉(zhuǎn)換示例dcm2niix -o output_dir -f %s_%d input_dicom_dir轉(zhuǎn)換完成后再檢查文件名和方向信息不要假設(shè)所有 DICOM 轉(zhuǎn)出來(lái)都是正確方向的。7.3 fMRIPrep 運(yùn)行失敗fMRIPrep 運(yùn)行依賴(lài) Docker 或 Singularity常見(jiàn)的失敗原因是鏡像下載失敗、環(huán)境變量未配置、內(nèi)存不足。排查步驟確認(rèn) Docker/Singularity 服務(wù)正常運(yùn)行檢查磁盤(pán)空間是否充足fMRIPrep 輸出數(shù)據(jù)量通常很大查看日志尾部找到具體報(bào)錯(cuò)信息如果內(nèi)存不足可以增加內(nèi)存或減少并行任務(wù)數(shù)。不建議在家用電腦上直接跑 fMRIPrep規(guī)范做法是在服務(wù)器上運(yùn)行或者使用預(yù)處理過(guò)的公開(kāi)數(shù)據(jù)。7.4 樣本不平衡問(wèn)題神經(jīng)影像研究中患者組和對(duì)照組的人數(shù)經(jīng)常不平衡有些類(lèi)別可能只有幾十個(gè)樣本。常見(jiàn)緩解辦法使用類(lèi)別權(quán)重比如CrossEntropyLoss(weighttorch.tensor([1.0, 2.0]))對(duì)少數(shù)類(lèi)做過(guò)采樣或者對(duì)多數(shù)類(lèi)做欠采樣使用評(píng)價(jià)指標(biāo) F1-score、AUC 而不是準(zhǔn)確率在論文中同時(shí)報(bào)告 sensitivity 和 specificity。不要為了提升 accuracy 而試圖通過(guò)刪除樣本改變真實(shí)分布這樣會(huì)導(dǎo)致結(jié)果不客觀(guān)。7.5 數(shù)據(jù)泄露問(wèn)題這是科研中最容易出問(wèn)題的地方。數(shù)據(jù)泄露指的是訓(xùn)練集和測(cè)試集之間存在信息重疊導(dǎo)致評(píng)估結(jié)果虛高。在 fMRI 項(xiàng)目中最容易發(fā)生數(shù)據(jù)泄露的方式同一個(gè)被試的多次掃描分別出現(xiàn)在訓(xùn)練集和測(cè)試集沒(méi)有按站點(diǎn)切分導(dǎo)致測(cè)試集中的數(shù)據(jù)分布與訓(xùn)練集高度相似特征選擇時(shí)使用了全數(shù)據(jù)集的信息數(shù)據(jù)標(biāo)準(zhǔn)化時(shí)使用全數(shù)據(jù)集的均值和方差計(jì)算。最穩(wěn)妥的做法是在進(jìn)入任何特征工程或模型訓(xùn)練之前先把訓(xùn)練集、驗(yàn)證集和測(cè)試集按被試級(jí)別分離并且盡量按站點(diǎn)分層采。8. 神經(jīng)影像深度學(xué)習(xí)的最佳實(shí)踐8.1 數(shù)據(jù)隱私與倫理合規(guī)醫(yī)學(xué)數(shù)據(jù)涉及患者隱私使用公開(kāi)數(shù)據(jù)集時(shí)必須遵守?cái)?shù)據(jù)使用協(xié)議不能隨意二次分發(fā)。如果在醫(yī)院或合作單位拿到真實(shí)患者數(shù)據(jù)需要經(jīng)過(guò)倫理審批并做到去除所有可識(shí)別信息數(shù)據(jù)加密存儲(chǔ)不在公共代碼倉(cāng)庫(kù)提交患者數(shù)據(jù)路徑論文發(fā)表時(shí)注意被試人數(shù)的可識(shí)別風(fēng)險(xiǎn)。這一點(diǎn)沒(méi)有商量余地。即使是“研究用不發(fā)表”也不能非法獲取或傳播患者數(shù)據(jù)。8.2 可復(fù)現(xiàn)性管理神經(jīng)影像分析很容易出現(xiàn)“結(jié)果不可復(fù)現(xiàn)”的問(wèn)題主要原因是環(huán)境依賴(lài)復(fù)雜、預(yù)處理參數(shù)多樣、隨機(jī)種子未固定。推薦做法使用conda或 Docker 固定環(huán)境版本在代碼中固定隨機(jī)種子記錄所有預(yù)處理參數(shù)將中間產(chǎn)物命名規(guī)范帶日期或版本號(hào)代碼和配置放到 GitHub 時(shí)不要忽略 GPU 型號(hào)和 CUDA 版本的差異。8.3 模型選擇與比較深度學(xué)習(xí)模型并非唯一選擇也不是越復(fù)雜越好。在醫(yī)學(xué)影像領(lǐng)域一個(gè)關(guān)鍵原則是模型復(fù)雜度和樣本量必須匹配。樣本量在 100 到 500 時(shí)傳統(tǒng)機(jī)器學(xué)習(xí)配合功能連接特征往往比端到端深度學(xué)習(xí)效果更穩(wěn)定樣本量達(dá)到幾千甚至幾萬(wàn)時(shí)深度學(xué)習(xí)模型才能發(fā)揮優(yōu)勢(shì)。因此如果項(xiàng)目樣本量不大優(yōu)先從線(xiàn)性模型和 SVM 開(kāi)始深度學(xué)習(xí)作為更強(qiáng)大的方案進(jìn)行比較。8.4 可視化與可解釋性醫(yī)學(xué)領(lǐng)域?qū)山忉屝砸筝^高審稿人也很難接受一個(gè)完全黑箱的分類(lèi)器。常用的可解釋性分析手段使用 Grad-CAM 查看模型關(guān)注哪些腦區(qū)對(duì)功能連接特征進(jìn)行置換重要性分析對(duì)比患者組與對(duì)照組的功能連接差異使用 t 檢驗(yàn)并做 FDR 校正使用稀疏模型Lasso、稀疏邏輯回歸直接得到有意義的特征權(quán)重。可解釋性分析不僅能增加論文的說(shuō)服力也能幫助你發(fā)現(xiàn)模型的潛在問(wèn)題例如模型可能學(xué)到了站點(diǎn)偽跡而不是真實(shí)疾病信號(hào)。8.5 計(jì)算資源與訓(xùn)練效率醫(yī)學(xué)影像項(xiàng)目的特點(diǎn)是數(shù)據(jù)大、樣本少、訓(xùn)練時(shí)間短。一臺(tái)普通的 24GB 顯存 GPU 就足以支撐絕大多數(shù)實(shí)驗(yàn)。真正耗時(shí)的往往是預(yù)處理比如 fMRIPrep 和配準(zhǔn)任務(wù)多、I/O 頻繁。效率方面的建議預(yù)處理只做一次不要每次訓(xùn)練前重復(fù)運(yùn)行將中間數(shù)據(jù)保存為.npy或.npy格式避免每次讀取 NIfTI 的解析開(kāi)銷(xiāo)使用DataLoader時(shí)設(shè)置num_workers默認(rèn)值很低時(shí)需要調(diào)整如果數(shù)據(jù)太大先做 ROI 級(jí)摘要再進(jìn)模型。9. 從零開(kāi)始的完整學(xué)習(xí)路徑對(duì)于零基礎(chǔ)想切入神經(jīng)影像 AI 的同學(xué)學(xué)習(xí)路徑比具體某個(gè)工具更重要。這里給出一個(gè)分階段的學(xué)習(xí)路線(xiàn)。階段一掌握 Python 與深度學(xué)習(xí)基礎(chǔ)約 1-2 個(gè)月不需要完全精通但至少能熟練Numpy 數(shù)組操作切片、廣播、矩陣運(yùn)算PyTorch 基礎(chǔ)Tensor、Dataset、DataLoader、模型定義、訓(xùn)練循環(huán)CNN 的基本原理卷積、池化、全連接、反向傳播經(jīng)典模型結(jié)構(gòu)ResNet、VGG 的基本組成。推薦的練習(xí)題目不是醫(yī)療圖像分類(lèi)而是先跑熟 CIFAR-10 或 MNIST把訓(xùn)練一整套模型的流程搞清楚。階段二熟悉神經(jīng)影像數(shù)據(jù)與工具約 1-2 個(gè)月這個(gè)階段目標(biāo)是從零加載一個(gè) fMRI 數(shù)據(jù)并完成最基本的分析和可視化。需要掌握NIfTI 數(shù)據(jù)格式和 4D 數(shù)據(jù)的概念nibabel 讀取數(shù)據(jù)的基本操作nilearn 中NiftiMasker、NiftiLabelsMasker和NiftiSpheresMasker的用法如何用plotting.plot_connectome可視化功能連接功能連接和 ROI 分析的基本概念??梢詤⒖?nilearn 官方教程中關(guān)于靜息態(tài) fMRI 的分析部分把每個(gè) example 手動(dòng)跑一遍。階段三跑通一個(gè)完整的疾病分類(lèi)項(xiàng)目約 2 個(gè)月選擇一個(gè)公開(kāi)數(shù)據(jù)集比如 ABIDE 或 COBRE做一遍從數(shù)據(jù)下載、預(yù)處理、特征提取、SVM 分類(lèi)、深度學(xué)習(xí)模型到結(jié)果分析的全流程。注意不要在這個(gè)階段過(guò)度糾結(jié)于刷性能先跑通整個(gè)流程是最重要的。完成一個(gè)端到端的小項(xiàng)目后你對(duì)整個(gè)領(lǐng)域的理解會(huì)有一個(gè)質(zhì)變。階段四深入研究和選題長(zhǎng)期在掌握了基本流程之后可以結(jié)合自己的領(lǐng)域背景選擇細(xì)分方向如果擅長(zhǎng)算法可以研究跨站點(diǎn)泛化、自監(jiān)督預(yù)訓(xùn)練、圖神經(jīng)網(wǎng)絡(luò)等方向如果熟悉臨床可以針對(duì)某一種疾病做深度分析如果想做工程落地可以研究體素級(jí)模型和多模態(tài)融合如果重統(tǒng)計(jì)可以深入學(xué)習(xí)功能連接分析和因果分析。持續(xù)關(guān)注神經(jīng)影像領(lǐng)域的頂級(jí)會(huì)議和期刊例如 OHBMOrganization for Human Brain Mapping、MICCAI、NeuroImage、Human Brain Mapping 等。復(fù)現(xiàn)優(yōu)秀的論文代碼是快速提升研究水平的最有效方式。寫(xiě)在最后神經(jīng)影像 AI 不是最容易的方向但確實(shí)是一個(gè)值得投入的方向。它既有真實(shí)臨床需求的牽引又有腦科學(xué)問(wèn)題的深度同時(shí)臨床上的人才缺口也相對(duì)大。入門(mén)最大的障礙不是難度而是資料分散、流程不規(guī)范帶來(lái)的挫敗感。通過(guò)這篇教程建議先跑通 ABIDE 或 COBRE 的一個(gè)小型分類(lèi)實(shí)驗(yàn)把數(shù)據(jù)處理流程和模型建立過(guò)程完整走一遍再逐步深入新的方法。腦影像數(shù)據(jù)是 4D 時(shí)空數(shù)據(jù)與普通 CV 有本質(zhì)區(qū)別學(xué)會(huì)處理這種數(shù)據(jù)本身也是一種很有遷移價(jià)值的技能。如果教程中哪一步還不清楚建議在真實(shí)數(shù)據(jù)上多試幾次很多問(wèn)題會(huì)自己在動(dòng)手過(guò)程中浮現(xiàn)出來(lái)。