胡繼禮,闞紅星
(安徽中醫(yī)藥大學(xué)醫(yī)藥信息工程學(xué)院,安徽合肥230012)
卷積神經(jīng)網(wǎng)絡(luò)[1](Convolutional Neural Network,CNN)由Hinton 教授于2006年提出,它是一種前饋神經(jīng)網(wǎng)絡(luò),深度學(xué)習(xí)[2]卷積神經(jīng)網(wǎng)絡(luò)通過(guò)建立多層神經(jīng)網(wǎng)絡(luò)來(lái)模仿人腦對(duì)圖像進(jìn)行解釋和分析,可以發(fā)現(xiàn)更深層次的數(shù)據(jù)分布式特征表示。目前在工業(yè)、生物醫(yī)療、智能制造等多個(gè)領(lǐng)域采用深度學(xué)習(xí)技術(shù),已經(jīng)取得了令人矚目的成果,谷歌通過(guò)分析病人眼球的視網(wǎng)膜圖像,可以預(yù)測(cè)一個(gè)人的血壓、年齡和吸煙狀況[3]。中醫(yī)體質(zhì)學(xué)[4],是以中醫(yī)理論為指導(dǎo),以生命個(gè)體的人作為研究出發(fā)點(diǎn),旨在研究人體不同體質(zhì)構(gòu)成的特點(diǎn)對(duì)疾病演變過(guò)程造成的影響,從而指導(dǎo)疾病的預(yù)防、診治、康復(fù)與養(yǎng)生的一門學(xué)科。舌象的變化可以直觀靈敏地反映人的各個(gè)器官的新陳代謝的變化,通過(guò)對(duì)舌象的分析來(lái)探究人體的陰陽(yáng)盛衰、虛實(shí)寒熱,具有很大的參考價(jià)值。目前關(guān)于舌象的處理[5-7],大部分是surf特征提取技術(shù),但這些研究存在局限性:(1)他們使用的舌象都是過(guò)于理想化的舌象樣本數(shù)據(jù),沒(méi)有復(fù)雜背景;(2)底層特征沒(méi)有高層語(yǔ)義的特征信息,大部分是直接從原始圖片中直接進(jìn)行像素提取,不能作為特征識(shí)別的可靠依據(jù)。本文在TensorFlow[8]平臺(tái)下構(gòu)建舌象圖像識(shí)別分類模型,將卷積神經(jīng)網(wǎng)絡(luò)圖像處理技術(shù)引入到中醫(yī)體質(zhì)辨識(shí)系統(tǒng),實(shí)現(xiàn)中醫(yī)體質(zhì)辨識(shí)的客觀化,從而為中醫(yī)體質(zhì)辨識(shí)提供新的研究思路和手段,輔助醫(yī)生對(duì)體質(zhì)進(jìn)行快速診斷,提高醫(yī)生的工作效率。
卷積神經(jīng)網(wǎng)絡(luò)[9-11]的每一層通常會(huì)包含卷積層、池化(Pooling)層、修正線性單元(ReLU)層或激活層,在每一層中一般會(huì)定義一個(gè)權(quán)值矩陣與圖像的像素點(diǎn)進(jìn)行卷積。卷積層的目的是用來(lái)濾波,以便更有效地查看圖像區(qū)域的特征,前一層的卷積運(yùn)算結(jié)果經(jīng)過(guò)激活函數(shù)運(yùn)算會(huì)輸出成為下一層的神經(jīng)元,以便構(gòu)成下一層對(duì)應(yīng)某一特征的特征圖。在經(jīng)過(guò)多輪的卷積、ReLU、池化后,會(huì)檢測(cè)出圖像的高級(jí)特征。網(wǎng)絡(luò)最后進(jìn)行全連接,這一層主要處理由卷積層、也可能是ReLU層或是池化層的輸出內(nèi)容,最后輸出一個(gè)N維向量,N一般代表分類的數(shù)量。由于卷積神經(jīng)網(wǎng)絡(luò)比普通神經(jīng)網(wǎng)絡(luò)增加了卷積層、池化、降采樣層,非常適合視覺(jué)處理和圖像識(shí)別分類處理領(lǐng)域,卷積層一方面可以很好地提取相鄰圖像像素之間的共同特性,另一方面能減少訓(xùn)練過(guò)程中產(chǎn)生的神經(jīng)網(wǎng)絡(luò)參數(shù)數(shù)量。
圖1所示為卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu),一般從輸入層input輸入圖像,卷積層與輸入層相連,中間層由卷積層和降采樣層相互交替連接,每進(jìn)行一次卷積運(yùn)算,就會(huì)進(jìn)行一次下采樣,然后再進(jìn)行卷積。經(jīng)過(guò)這樣多次的卷積與下采樣后,再進(jìn)行全連接,最終得到整個(gè)網(wǎng)絡(luò)的output[12]。
圖1 卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)
在進(jìn)行分類時(shí),輸出層使用帶有標(biāo)簽的目標(biāo)信息,采用softmax函數(shù)進(jìn)行網(wǎng)絡(luò)收斂計(jì)算,特征映射結(jié)構(gòu)一般采用sigmoid函數(shù)作為卷積網(wǎng)絡(luò)的激活函數(shù),sigmoid是使用范圍最廣的一類激活函數(shù),在物理意義上最為接近生物神經(jīng)元,使得特征映射具有位移不變性。為降低CPU和GPU運(yùn)算的復(fù)雜度,通常卷積神經(jīng)網(wǎng)絡(luò)會(huì)共享神經(jīng)元的權(quán)重,用不同的卷積核去提取不同的特征,可以有效地減少訓(xùn)練過(guò)程復(fù)雜度和參數(shù)數(shù)量。在進(jìn)行卷積時(shí),不同的卷積核進(jìn)行卷積可提取前一層特征圖的不同特征,這些不同特征的特征圖一起作為下一層子采樣的輸入數(shù)據(jù)。例如第l層卷積中的第j個(gè)神經(jīng)元可表示為
其中f()表示激活函數(shù),b為偏置量,k代表卷積核,M代表輸入層感受野。通常一個(gè)卷積層會(huì)由多個(gè)特征圖構(gòu)成,并且相互共享權(quán)值,以便降低卷積網(wǎng)絡(luò)中的參數(shù)數(shù)量。一般在卷積層之后進(jìn)行子采樣層,也叫池化層,子采樣層一般選取多個(gè)像素的平均值或最大值,將多個(gè)像素值壓縮為一個(gè)進(jìn)行特征提取,達(dá)到減少數(shù)據(jù)規(guī)模,降低網(wǎng)絡(luò)分辨率的目的。由子采樣計(jì)算神經(jīng)元的公式為
公式中的pooling()表示池化函數(shù),β表示加權(quán)因子。卷積神經(jīng)網(wǎng)絡(luò)訓(xùn)練過(guò)程一般分為前向和后向傳播兩個(gè)階段,在前向傳播階段,輸入層逐層向前傳播信息,通過(guò)各種卷積層和完全連接層,最后到達(dá)輸出層,網(wǎng)絡(luò)在此過(guò)程執(zhí)行的計(jì)算公式為
其中,fi()代表第i層的激活函數(shù),ωi代表第i層卷積核的權(quán)值向量,第i層卷積網(wǎng)絡(luò)的輸出記為yi。在卷積神經(jīng)網(wǎng)絡(luò)的后向傳播過(guò)程中,先計(jì)算標(biāo)簽信息和實(shí)際輸出差值,再按照極小化誤差的方法,采用隨機(jī)梯度下降法反向傳播調(diào)整卷積神經(jīng)網(wǎng)絡(luò)各層的權(quán)值。卷積神經(jīng)網(wǎng)絡(luò)能夠?qū)崿F(xiàn)自動(dòng)特征學(xué)習(xí),和傳統(tǒng)識(shí)別算法相比,其模型構(gòu)建復(fù)雜度低、權(quán)值數(shù)量少、可實(shí)現(xiàn)權(quán)值共享[13-14],并且可避免復(fù)雜的手動(dòng)提取特征和重建數(shù)據(jù)過(guò)程,在應(yīng)用到大規(guī)模的圖像識(shí)別分類時(shí)具有較大優(yōu)勢(shì)。
中醫(yī)根據(jù)舌象的不同特征,將人體的體質(zhì)類型分為9種,體質(zhì)類型和舌苔癥狀對(duì)照見(jiàn)表1所示。將CNN卷積神經(jīng)網(wǎng)絡(luò)技術(shù)引入到舌象分類數(shù)據(jù)處理中,可自動(dòng)對(duì)舌象進(jìn)行特征提取。根據(jù)其數(shù)據(jù)的特點(diǎn)和性能需求,實(shí)驗(yàn)選用MobileNets[15]模型進(jìn)行分類訓(xùn)練,然后將訓(xùn)練后的模型文件用于舌象的分類,從而輔助醫(yī)生進(jìn)行體質(zhì)類型診斷。
表1 體質(zhì)舌象對(duì)照表
本文的舌象數(shù)據(jù)來(lái)源于某中醫(yī)藥大學(xué)附院。根據(jù)病人的舌診信息,圖片已經(jīng)進(jìn)行了標(biāo)注。本文選取了陰虛和陽(yáng)虛中的部分圖片集作為實(shí)驗(yàn)訓(xùn)練數(shù)據(jù),每個(gè)分類下面有2 000張圖片。由于原始的舌象圖片分辨率為2 592×1 728 px,過(guò)大,訓(xùn)練會(huì)耗費(fèi)大量的CPU資源和內(nèi)存資源,并且很容易造成內(nèi)存OOM,所以首先使用python的第三方包PIL(Python Imaging Library)對(duì)原始圖片進(jìn)行縮放處理,將分辨率降低到600 px。處理后舌象數(shù)據(jù)集如圖2所示
圖2 舌象數(shù)據(jù)集圖
以Tensorflow1.4版作為卷積神經(jīng)網(wǎng)絡(luò)訓(xùn)練工具。TensorFlow是Google公司于2015年開(kāi)發(fā),它是一個(gè)開(kāi)源的深度學(xué)習(xí)框架。Tensorflow通過(guò)計(jì)算圖graph形式先描繪出一個(gè)交互操作圖的方式,圖中的節(jié)點(diǎn)op代表數(shù)學(xué)運(yùn)算,而圖中的邊則代表在這些節(jié)點(diǎn)之間傳遞的張量(即多維數(shù)組),費(fèi)時(shí)的矩陣運(yùn)算在Python語(yǔ)言外部進(jìn)行,這種靈活的架構(gòu)可以高效地構(gòu)建深層神經(jīng)網(wǎng)絡(luò)。在使用TensorFlow進(jìn)行編程時(shí),開(kāi)發(fā)者一般需要使用import導(dǎo)入需要使用的第三方函數(shù)庫(kù),因自身并不包含所有的運(yùn)算函數(shù),比如處理圖形的函數(shù)庫(kù)PIL,處理科學(xué)計(jì)算的函數(shù)庫(kù)NumPy,當(dāng)需要使用NumPy函數(shù)庫(kù)時(shí),通常采用“import numpy as np”命令調(diào)用NumPy的科學(xué)計(jì)算函數(shù)。
實(shí)驗(yàn)環(huán)境和主要配置參數(shù)如下:在MacOS操作系統(tǒng)中運(yùn)行TensorFlow1.4進(jìn)行實(shí)驗(yàn),處理器3.1 GHz Intel Core i5,內(nèi)存 16 GB 2 133 MHz LPDDR3,顯卡 Intel Iris Plus Graphics 650 1 536 MB,磁盤SSD 256 G。
(1)創(chuàng)建項(xiàng)目文件夾tf_files,創(chuàng)建命令如下:
cd~
mikdir-p pythonsrc/tf_files
(2)創(chuàng)建舌象數(shù)據(jù)集文件夾及其子文件夾
首先在項(xiàng)目文件夾tf_files下創(chuàng)建tongue_photos文件夾,然后再創(chuàng)建兩個(gè)子文件夾yinxu(陰虛)和qixu(氣虛),再分別將收集到的具有不同體質(zhì)特征的舌象圖片放入其中,比如將具有陰虛和氣虛體質(zhì)特征的舌象圖片分別放入相應(yīng)的文件夾用于后面的圖像分類識(shí)別,創(chuàng)建好的目錄截圖如圖3所示。
圖3 文件夾目錄圖
(3)創(chuàng)建遷移訓(xùn)練代碼retain.py
該段代碼源自Tensorflow examples中的image_retraining示例代碼,通過(guò)curl命令下載獲取。命令如下:
curl–O代碼地址
其中代碼地址為:https://raw.githubusercontent.com/tensorflow/tensorflow/r1.4/tensorflow/examples/label_image/label_image.py
(4)執(zhí)行訓(xùn)練腳本
在命令行窗口執(zhí)行python retain.py即可執(zhí)行遷移訓(xùn)練,后面需要跟上一些必要參數(shù)進(jìn)行訓(xùn)練,執(zhí)行如下命令:
python retrain.py
--image_dir~/pythonsrc/tf_files/tongue_photos/
--output_graph=retrained_graph.pb
--output_labels=retrained_labels.txt
--learning_rate=0.0001
--testing_percentage=20
--validation_percentage=20
--train_batch_size=32
--validation_batch_size=-1
--flip_left_right True
--random_scale=30
--random_brightness=30
--eval_step_interval=100
--how_manytraining_steps=600
--architecture mobilenet_1.0_224
--summaries_dir=training_summaries/basic
--bottleneck_dir=bottlenecks
該訓(xùn)練腳本基于MobileNets模型進(jìn)行訓(xùn)練,MobileNets模型不僅實(shí)現(xiàn)了70.5%的精度,而且生成的模型大小只有18 MB,占用資源率低,非常適合在移動(dòng)手機(jī)端運(yùn)行和應(yīng)用。其中--how_many_training_steps用于指定訓(xùn)練的迭代次數(shù),--architecture用于指定使用哪種訓(xùn)練模型。本實(shí)驗(yàn)參數(shù)值設(shè)置為mobilenet_1.0_224,其中1.0是模型的相對(duì)大小,可以采用1.0,0.75,0.50或0.25,推薦使用1.0作為初始設(shè)置,較小的型號(hào)雖然運(yùn)行速度會(huì)更快,但精確度會(huì)降低;224是指輸入圖像分辨率,可以使用128,160,192或224像素,更高分辨率的圖像需要更多的訓(xùn)練和處理時(shí)間,但是會(huì)有更好的分類精度,這里推薦224作為初始設(shè)置。其他參數(shù)的含義可以通過(guò)運(yùn)行“python retrain.py–h”腳本查看。
(5)利用TensorBoard查看訓(xùn)練過(guò)程
TensoFlow提供了非常方便的可視化工具TensorBoard(a suite of visualization tools),可以幫助開(kāi)發(fā)者方便理解、調(diào)試和優(yōu)化TensorFlow程序。打開(kāi)TensorBoard可以對(duì)訓(xùn)練進(jìn)行可視化查看,執(zhí)行如下命令啟動(dòng)TensorBoard:
tensorboard--logdir tf_files/training_summaries&
啟動(dòng)后,打開(kāi)瀏覽器,在地址欄輸入http://localhost:6006/,回車后即可看到可視化的訓(xùn)練界面,單擊SCALARS可以查看訓(xùn)練精度(如圖4)和交叉熵(如圖5)的變化。在訓(xùn)練過(guò)程中,會(huì)產(chǎn)生一系列步進(jìn)輸出,每個(gè)輸出會(huì)顯示訓(xùn)練的準(zhǔn)確性、驗(yàn)證精度和交叉熵:其中震蕩變化的折線表示在當(dāng)前批次訓(xùn)練中帶有正確標(biāo)簽分類的訓(xùn)練精度;另一條變化平滑的線代表驗(yàn)證準(zhǔn)確性,不同集合隨機(jī)選擇的圖像組的精度,被正確標(biāo)記的圖像的百分比;交叉熵代表?yè)p失函數(shù),較低的數(shù)字在這里表示更好的分類精度。
圖4 訓(xùn)練精度變化圖
圖5 交叉熵變化圖
訓(xùn)練完成后,會(huì)在當(dāng)前文件夾生成兩個(gè)文件,tf_files/retrained_graph.pb是模型文件,包含了在舌象類別上進(jìn)行遷移訓(xùn)練的最后一層的模型版本,tf_files/retrained_labels.txt是標(biāo)簽文本文件,包含了舌象分類識(shí)別的標(biāo)簽名稱,即qixu(氣虛)和yinxu(陰虛)。
(1)下載labelimage源碼
curl-O代碼地址:https://raw.githubusercontent.com/tensorflow/tensorflow/r1.4/tensorflow/examples/label_image/label_image.py
(2)準(zhǔn)備一張舌象圖片test.jpg,然后執(zhí)行如下命令:
python label_image.py
--graph=retrained_graph.pb
--labels=retrained_labels.txt
--image=test.jpg
--input_layer=input
--output_layer=final_result
--input_mean=128
--input_std=128
--input_width=224
--input_height=224
注意:因?yàn)樯弦徊缴赡P蜁r(shí)指定了參數(shù)architecture為mobilenet_1.0_224,圖像分辨率是224,所以這一步也必須指定輸入的寬度和高度分辨率為224,即input_width和input_height為224,運(yùn)行結(jié)果如圖6所示,最后顯示氣虛(qixu)的概率為1.0,陰虛(yinxu)的概率為2.387 58e-14。
圖6 檢測(cè)結(jié)果圖
本文將深度學(xué)習(xí)卷積神經(jīng)網(wǎng)絡(luò)運(yùn)用到中醫(yī)舌象識(shí)別分類中,利用TensorFlow機(jī)器學(xué)習(xí)軟件平臺(tái)搭建舌象分類MobileNets模型,對(duì)舌象圖像數(shù)據(jù)進(jìn)行數(shù)據(jù)預(yù)處理后進(jìn)行訓(xùn)練,可以得到較好的識(shí)別精度和計(jì)算效率,分析中醫(yī)體質(zhì)與舌象之間的關(guān)系,用以發(fā)現(xiàn)中醫(yī)舌診的規(guī)則和模式,從而輔助醫(yī)生對(duì)病人體質(zhì)進(jìn)行診斷。將機(jī)器學(xué)習(xí)卷積神經(jīng)網(wǎng)絡(luò)技術(shù)引入到舌象識(shí)別分類中,為中醫(yī)的舌象診斷提供了一種新的方法和手段。