毛亞青,王 亮,胡俊峰
(徐州醫科大學 醫學信息與工程學院,江蘇 徐州 221000)
目前,醫學影像數據約占醫院內部總數據的70%[1],它們來源于不同設備、對應不同人體組織器官和多種病癥,這些海量的醫學圖像資源為醫學圖像的存儲、檢索帶來了存儲體量大、檢索效率低等問題。如何對海量醫學圖像信息進行高效檢索,從海量數據中快速并準確地搜索出滿足要求的圖像是目前所要解決的重要問題。然而,現階段國內外關于醫學圖像檢索技術的研究[2-5]依然存在三大問題:1)主要在單機環境下進行,大規模醫學影像數據的檢索使得該串行模式的醫學圖像檢索技術已出現進程瓶頸;2)當前醫學圖像檢索中主要采用對圖像依次進行遍歷的方式,而沒有很好的索引機制來做索引,也增大了檢索系統的負荷;3)傳統的圖像檢索模式大多基于已有的數據進行定時離線構建索引,對于新增的圖像檢索存在時效性差的問題。
為了解決醫學圖像檢索過程中的效率問題,本課題擬采用基于Flink的分布式技術提高這些海量醫學圖像的檢索實時性,針對海量醫學圖像檢索系統中圖像特征索引方式、圖像存儲以及圖像檢索的問題,建立一個高效的醫學圖像檢索平臺,實現醫學圖像分布式檢索,提高圖像處理的實時性以及圖像檢索準確率,從而更好地輔助醫生便捷獲取和利用醫學圖像資源。
從狹義上來說,Hadoop[2-6]是一個由Apache基金會所維護的分布式系統基礎架構,旨在解決海量數據的存儲和計算問題。而從廣義上來說,Hadoop通常指的是它所構建的Hadoop生態,包括Hadoop核心技術,以及基于Hadoop平臺所部署的大數據開源組件和產品,如HBase、Hive、Spark、Flink、Pig、ZooKeeper、Kafka、Flume、Phoenix、Sqoop等。這些組件藉由Hadoop平臺,實現大數據場景下的數據存儲、數據倉庫、分布式計算、數據分析、實時計算、數據傳輸等不同需求,從而構成Hadoop生態。
Hadoop的核心技術:HDFS、MapReduce、HBase被譽為Hadoop的三駕馬車,更為企業生產應用帶來了高可靠、高容錯和高效率等特性。HDFS是分布式文件系統(Hadoop Distributed File System),其底層維護著多個數據副本,即使Hadoop某個計算或存儲節點出現故障也不會導致數據的丟失,所以即使部署在成本低廉的服務器上也能同樣保障其可靠性和容錯性。MapReduce是Hadoop中并行計算編程的基本模型,能夠將任務并行分配給多個節點同時工作,從而加快任務處理的速度。HBase是一個可伸縮、分布式、面向列的數據庫,和傳統關系數據庫不同,HBase提供了對大規模數據的隨機、實時讀寫訪問,同時,HBase中保存的數據可以使用MapReduce來處理,它將數據存儲和并行計算完美地結合在一起。
Apache Flink是一個框架和分布式處理引擎,用于對無界和有界數據流進行有狀態計算。Flink被設計在所有常見的集群環境中運行,以內存執行速度和任意規模來執行計算。Flink基于Flink流式執行模型(Streaming execution model),能夠支持流處理和批處理兩種應用類型。流處理和批處理所提供的服務等級協議完全不相同,流處理一般需要支持低延遲、Exactly-once保證,而批處理需要支持高吞吐、高效處理,所以在實現的時候通常是分別給出兩套實現方法,或者通過一個獨立的開源框架來實現其中每一種處理方案。如:實現批處理的開源方案MapReduce、Spark;實現流處理的開源方案Storm;微批處理方案Spark Streaming。
與傳統方案不同,Flink在實現流處理和批處理時,將二者統一起來:Flink是完全支持流處理,也就是說作為流處理看待時輸入數據流是無界的;批處理被作為一種特殊的流處理,即有界的數據流。這種批、流一體的架構使得Flink在執行計算時具有極低的延遲。
為了實現海量醫學圖像的實時檢索和高效存儲,設計基于Flink的海量醫學圖像并行檢索系統總體架構共包括:數據采集層、數據存儲層、資源管理層、數據計算層和應用層。
如圖1所示為醫學圖像檢索系統架構圖,具體如下。

圖1 系統總體架構圖
1)數據采集層:
系統的數據源主要包括:用戶通過Web界面上傳醫學圖像、通過API批量導入的醫學圖像和系統操作日志流。對于實時產生的數據首先放入Kafka消息隊列進行緩沖中以供后續計算,通過Zookeeper組件對Kafka服務器消費生產速度進行同步。此外,還可以通過ETL導入數據作為系統的數據源。
2)數據存儲層:
系統的數據存儲根據數據類型和應用場景分為基礎業務庫、醫學圖像存儲庫、圖像特征索引庫和內存數據庫。其中,基礎業務庫通過MySQL存放系統的結構化信息,如:人員列表、組織架構、圖像基礎信息等。醫學圖像存儲庫通過Hadoop平臺的HDFS進行存儲,圖像ID對應MySQL中的圖像基礎信息表的記錄。同時,該ID圖像的特征索引存儲在HBase數據庫中。此外,服務器將經常訪問的數據緩存在內存數據庫Redis中,從而提高訪問速度和計算效率。
3)資源管理層:
系統通過由Yarn進行資源管理,負責在有數據計算請求時根據集群狀況分配計算資源和計算節點,從而提供MapReduce、Spark、Flink等組件的計算環境。
4)數據計算層:
系統首先對于用戶輸入的醫學圖像通過Flink進行特征提取,根據圖像上傳形式分為實時計算和離線批量計算兩種;進而對圖像進行特征量化編碼便于檢索,特征編碼存儲在HBase中,并由Phoenix進行HBase中數據的查詢計算;在用戶需要檢索時通過醫學圖像并行檢索比對特征相似度計算返回檢索結果。
5)應用層:
系統通過Web的形式提供用戶交互界面,實現對醫學圖像的存儲管理、醫學圖像檢索操作、用戶管理、系統管理和日志管理等。
醫學圖像檢索系統主要設計包括系統管理模塊、用戶管理模塊和圖像管理模塊三部分。其中,系統管理模塊包括系統管理、日志管理、異常報警;用戶管理模塊包括用戶注冊、用戶登錄、個人信息管理;圖像管理模塊包括圖像上傳、圖像批量導入、圖像查看和圖像檢索檢索。具體功能如圖2所示。

圖2 系統功能結構圖
系統集群網絡架構共包括前端集群、后端業務集群和數據計算集群,醫學圖像并行檢索系統網絡架構如圖3所示。

圖3 系統集群網絡架構圖
系統主要采用前端界面和后端業務分離的思想,在提高各個模塊的內聚性的同時降低各模塊之間的耦合性。在前端集群中,由Nginx負責請求的反向代理和負載均衡,根據用戶操作分別指向靜態文件服務器或Web服務器,實現網頁相關界面的顯示與交互。前端集群通過遠程調用的方式與后端業務集群進行通信,實現相關業務操作、MySQL數據庫交互操作、數據計算與結果緩存到Redis等操作。對于后端業務操作中的數據計算環節則由數據計算集群負責,如:實時圖像上傳、批量圖像導入、特征提取模型計算、特征編碼模型計算等。
在數據計算集群中部署了Hadoop平臺(HDFS、HBase、Yarn)以及Flink、Kafka、Zookeeper等組件。其中HDFS負責進行底層數據的存儲,具體由HDFS的DataNode進行文件分片多備份存放,由NameNode進行元數據管理和文件操作管理,同時通過Zookeeper注冊兩個NameNode并實時監控狀態,防止一方故障立即切換到另一個,從而保證NameNode的高可用性。HBase負責對醫學圖像和特征編碼進行存儲,由HMaster管理多個RegionServer進行數據維護和查詢,底層由HDFS進行存儲。對于實時計算部分通過Kafka Broker接受Kafka生產者生產的實時消息,再通過Kafka消費者Flink進行處理計算,其中Kafka的生產、消費進度由Zookeeper進行記錄。Flink不僅提供實時計算,同時提供離線批量計算,其計算過程通過Yarn申請計算資源,具體由ResourceManager管理資源并分配到NodeManager上進行計算。
系統在接收到Web端的醫學圖像上傳請求后,首先在MySQL業務庫中創建圖像記錄,然后服務器后臺將圖像文件的字節碼對應業務庫中的圖像ID存儲到HBase中,實現海量醫學圖像數據的存儲。在圖像經過特征提取和編碼后,將編碼后的圖像特征對應圖像ID存儲到HBase中,在圖像檢索的過程中通過Phoenix進行查詢。
對于海量文件的存儲,通常的方案是通過HDFS進行分布式存儲。HDFS系統在存儲過程中將文件切分成多個block多副本存儲在多個節點上,從而保障文件的可用性和拓展性,默認每個block的大小為128 MB。然而,HDFS通過NameNode加載每個文件的元數據信息,一般上傳圖像文件的尺寸都較小,在大量這種小文件的存儲情況下,其每個小文件都會占用一個block,造成HDFS產生大量的文件元數據信息。這些元數據信息會給NameNode的內存和計算帶來很重的負擔,從而降低系統的存儲效率。為了解決HDFS在小文件存儲方面的問題,通常的做法是先將很多小文件合并成一個大文件再保存到HDFS,同時為這些小文件建立索引,以便進行快速存取,如Hadoop自帶的HAR文件和SequenceFile方案。但是這兩種方案均需要用戶編寫程序定時進行小文件的統一合并,且不支持文件追加和修改,并不適合醫學圖像實時上傳、頻繁更新業務庫的場景。因此,系統將圖像文件通過字節碼的形式直接存儲在HBase中,從而避免HDFS存儲過多的小文件、影響效率的情況。
系統利用HBase存儲醫學圖像文件數據和特征編碼等數據,進而通過Phoenix進行結構化查詢。HBase作為分布式數據庫,通過多個Region對數據進行存儲,在實時查詢方面具有很強的優勢。然而默認情況下HBase的表結構分區只有一個,在寫入讀取時會增大單節點的負擔,沒有發揮集群的優勢。此外,一條記錄由它的RowKey唯一標志,并決定該條記錄存儲于哪個分區。因此,在設置多個分區后也需要考慮分區的分配策略,即進行合理的RowKey設計,從而對數據進行均勻分布,防止出現數據熱點問題。
在本系統的HBase存儲設計部分共包括創建表、預分區、RowKey設計等環節,包括:
1)創建圖像存儲表,設計兩個列族MD(image data)、MI(image info)分別存放圖像的字節碼和圖像信息(圖像id、圖像特征碼等),在創建表的同時進行預分區操作,設計共9個分區,指定每個分區的RowKey范圍,建表語句如下:
create2′'image_info′, {NAME => ′MD′}, {NAME => ’MI’}, SPLITS => [′0000|′, ′0001|′, ′0002|′, ′0003|′, ′0004|′, ′0005|′, ′0006|′, ′0007|′, ′0008|′]
2)根據預分區設計,在向HBase中插入數據時需要對RowKey進行相應的格式約束,即在保證RowKey唯一性的同時確保其前綴格式為“000x|”。本系統首先根據醫學圖像在業務庫的唯一ID通過MD5加密生成Hash值;然后獲取RowKey前綴:將得到的Hash值轉成Long型,并根據預分區數對9取余,其中字符’a’~’f’替換為’10’~’15’;再取Hash值的后八位作為RowKey的后綴,拼接前綴作為最終的Row Key。
傳統樹結構索引方法存儲空間占用過大,且隨著維度的增長空間代價成倍變大,因此需要通過對原始數據進行哈希編碼壓縮以節省空間。目前對哈希編碼的研究主要包括數據無關哈希和數據驅動哈希:數據無關哈希方法以局部敏感哈希[7]為代表,在不考慮數據分布的情況下將原始空間中的數據投影到超平面獲取相應編碼。數據驅動哈希方法主要通過判別數據結構及分布信息來自動學習哈希函數,代表方法有譜哈希[8]、迭代量化[9]、乘積量化[10]、笛卡爾K均值[11]及組合量化[12]等。與其他編碼方法相比,乘積量化模型能夠有效解決聚類中心數量膨脹問題,進而提升大規模圖像檢索過程中的數據存儲效率。
系統根據應用場景分為批量導入圖像時的特征量化以及用戶在實時上傳圖像時的特征量化。
1)批量導入圖像特征量化:
系統實現醫學圖像的批量導入功能,用于歷史或外部圖像的離線導入場景。其過程如下:
(1)將圖像信息記錄到業務庫并將圖像字節碼和圖像id存儲在HBase中;
(2)通過DeepLearning4J調用預訓練的深度卷積神經網絡VGG-16模型提取圖像特征;
(3)使用乘積量化編碼模型對提取的圖像特征進行量化編碼;
(4)將圖像特征編碼存儲到HBase中。
2)實時圖像特征量化:
在多用戶同時在線的場景中,為保證用戶在上傳圖像后能被其他用戶同步到以供檢索,設計實時圖像檢索模塊,對增量上傳的圖像進行實時特征提取和特征量化編碼,從而實現系統的時效性。其實現過程包括:
(1)通過命令行創建Kafka消息訂閱的topic,表示一條圖像上傳的實時記錄,設計topic名為imageupload,定義副本數2個,分區數9個。
bin/kafka-topics.sh --zookeeper node01:2181 --create --replication-factor 3 --partitions 9 --topic imageupload
(2)Web服務響應用戶的上傳請求,首先將圖像基本信息存入MySQL庫中;接著創建Kafka的生產者,由Kafka生產者將圖像上傳消息類進行序列化,包括圖像的基本信息及圖像文件字節碼;然后,通過KafkaProducer類發送到imageupload的topic中;同時,利用回調函數監測是否發送成功,異常則觸發報警。因為系統對圖像上傳順序的要求不高,因此Kafka的消息按照輪詢的方式進行存放在每個分區中。
(3)創建Flink on Yarn任務實現Kafka的消費者進行實時處理。Flink任務實現記錄圖像信息到業務庫、提取圖像特征、存儲圖像字節碼和圖像特征編碼到HBase中。
在醫學圖像并行檢索的Flink任務執行過程中,對于輸入查詢的醫學圖像,本文首先利用CNN模型進行深度特征提取,然后對哈希編碼后的特征向量采用非對稱距離度量進行距離計算,最終輸出距離最近的相似醫學圖像。利用非對稱距離度量的優勢在于能夠避免直接計算查詢醫學圖像深度特征向量與數據庫中每個向量的歐式距離,從而減少查詢時間、提高檢索效率。
圖4是醫學圖像并行檢索過程的示意圖。通過事先計算深度特征哈希數據庫中每個聚類中心與其子向量的距離建立檢索查找表;對于需要查詢的醫學圖像深度特征向量q,計算其與數據庫中聚類中心xi′的距離,即為該向量與其他圖像向量之間的非對稱距離;通過比較q與聚類中心的距離找出最近的聚類c,設距離為l;最后,遍歷查找表將c聚類中每個向量與聚類中心的距離與l相加,即獲得q與該聚類中所有向量的距離,篩選距離排序獲得最近似的特征向量并返回對應的醫學圖像。

圖4 醫學圖像并行檢索過程
為了實現醫學圖像特征提取模型的高效訓練和并行檢索模型的分布式執行,本文將模型訓練和集群應用兩部分實驗分在不同的環境中執行。其中,模型訓練過程環境選用GPU型號為Tesla K80、12 GB內存的Google云服務器,并采用Python 3.6和Tensorflow 1.7的深度學習框架。集群應用環境選用1個主節點和3個計算節點,各節點配置情況如表1所示。

表1 分布式節點配置情況
服務器集群采用4個節點(node00~node03)并采用CDH進行部署管理,包括HDFS、Yarn、Zookeeper、Kafka、HBase等組件的部署、監控管理。此外,還部署了Flink計算組件、MySQL主備節點、Redis內存數據庫等,具體組件子服務的分配狀況如表2所示。

表2 服務器集群組件分配情況
實驗數據集選用由美國國立衛生研究院臨床中心(NIHCC)的團隊開發的醫學圖像數據集DeepLesion[13],是來自4 427個患者的多類別、病灶級別標注臨床醫療CT圖像開放數據集。該數據庫中目前已有32 735張CT圖像及病變信息,去除重復記錄后共有已標記的病變圖像9 624個,包括:肺(2 370)、腹部(2 119)、縱隔(1 640)、肝臟(1 257)、骨盆(843)、軟組織(660)、腎(488)和骨(247)共8種損傷類型。
本文實現的醫學圖像檢索方法在DeepLesion數據集上進行醫學圖像特征提取和分布式并行檢索。根據給定醫學圖像實現數據集中相同病灶、相似損傷的其他醫學圖像的檢索,從而有效地輔助醫療診斷過程。
為了驗證基于Flink的醫學圖像檢索系統的圖像檢索效率,本文分別使用MapReduce、Spark和Flink三種分布式計算組件實現并行檢索環節,并對比不同組件在不同圖像數據量下進行醫學圖像檢索的時間。
各組件檢索時間對比如圖5所示。在使用3種組件時,并行檢索的時間均隨著數據量的增大而增加。其中MapReduce效果相對更差,且使用時間增長也較快。Spark和Flink使用時間相差不多,總體來說Flink的處理效果更好,且隨著處理數據量的增加,Flink的計算效率明顯更優于Spark。因此,使用Flink進行分布式圖像檢索的計算更具優勢。

圖5 各組件檢索時間對比圖
進入醫學圖像檢索系統,用戶首先通過用戶名、密碼、驗證碼的方式進行登陸。如果忘記密碼可以通過郵箱找回密碼。具體操作如圖6所示。

圖6 系統用戶登陸界面
同時,新用戶進入系統可以通過注冊賬號,填寫用戶名、姓名、郵箱、設置密碼等表單信息進行新用戶的申請。具體操作如圖7所示。

圖7 新用戶賬號注冊界面
進入桌面化的系統界面后選擇打開桌面上的應用進行操作,系統根據權限不同提供醫學圖像管理、用戶信息管理、日志管理、系統狀態管理、多媒體應用等應用。
在醫學圖像管理模塊,用戶通過醫學圖像上傳應用對圖像信息、圖像描述、圖像文件進行填寫,圖像上傳后存儲在HBase平臺中。具體操作如圖8所示。

圖8 醫學圖像上傳應用操作界面
用戶可以通過醫學圖像列表應用查看醫學圖像記錄,可以根據圖像類型、開始時間和結束時間進行簡單篩選。具體操作如圖9所示。

圖9 醫學圖像列表應用操作界面
在醫學圖像檢索應用中,用戶可以通過以圖搜圖的方式對醫學圖像庫中已有的圖像進行檢索,檢索結果按相似度從小到大進行排序。具體操作如圖10所示。

圖10 醫學圖像檢索應用操作界面
針對海量醫學圖像存儲、檢索的效率問題,本文設計并實現一種基于Flink的醫學圖像檢索系統。系統利用Flink批流一體的架構提高并行檢索效率,實現實時圖像編碼、批量圖像上傳編碼和圖像并行檢索。圖像檢索過程使用深度卷積神經網絡模型提取圖像特征并利用乘積量化編碼模型進行特征編碼。同時,通過Web應用作為用戶操作入口,系統通過HBase存儲醫學圖像數據和圖像特征編碼數據。實驗結果表明,本系統具有更好的檢索效率表現,滿足實際應用需求。