黃 杰
(山西大同大學(xué)計(jì)算機(jī)與網(wǎng)絡(luò)工程學(xué)院,山西大同 037009)
當(dāng)下人工智能時代,機(jī)器學(xué)習(xí)(Machine Learning)與大數(shù)據(jù)研究已經(jīng)日益成為科學(xué)研究者關(guān)注的焦點(diǎn)。傳統(tǒng)計(jì)算機(jī)算法的核心在于給定數(shù)據(jù)和運(yùn)算規(guī)律,來求解相應(yīng)的輸出結(jié)果;而機(jī)器學(xué)習(xí)的算法則基于給定的數(shù)據(jù)和其對應(yīng)的輸出結(jié)果,來探究輸入與輸出之間的運(yùn)算規(guī)律。
深度學(xué)習(xí)(Deep Learning)作為機(jī)器學(xué)習(xí)中的一類分支,是一種以人工神經(jīng)網(wǎng)絡(luò)為主要架構(gòu),對數(shù)據(jù)進(jìn)行表征學(xué)習(xí)(Feature Learning)的算法[1]。深度學(xué)習(xí)結(jié)構(gòu)多種多樣,其中深度神經(jīng)網(wǎng)絡(luò)憑借其運(yùn)用統(tǒng)計(jì)學(xué)方法從原始數(shù)據(jù)中提取高層特征,并在大量的數(shù)據(jù)中獲得輸入空間的特點(diǎn),已逐漸成為許多人工智能應(yīng)用的基礎(chǔ)。其中,在圖像識別、語音識別、自動駕駛、癌癥檢測等方面,深度神經(jīng)網(wǎng)絡(luò)已逐漸體現(xiàn)出高于人類的準(zhǔn)確率,擁有極大的發(fā)展?jié)摿Α?/p>
由于深度神經(jīng)網(wǎng)絡(luò)搭建的時間性與復(fù)雜性,傳統(tǒng)的編程語言及數(shù)據(jù)庫可能無法進(jìn)行有效的支持。TensorFlow是谷歌于2015年開源的通用高性能計(jì)算庫,其本質(zhì)是采用數(shù)據(jù)流圖(data flow graphs)進(jìn)行數(shù)據(jù)計(jì)算,目前已經(jīng)發(fā)展為一個完整的機(jī)器學(xué)習(xí)生態(tài)系統(tǒng)。其中,Keras 模型旨在通過創(chuàng)建一組圖層,使用明確的標(biāo)準(zhǔn)來構(gòu)建神經(jīng)網(wǎng)絡(luò),是目前內(nèi)置于TensorFlow最為廣泛應(yīng)用與推薦的高級API。
首先我們將從數(shù)理統(tǒng)計(jì)角度具體介紹深度神經(jīng)網(wǎng)絡(luò)的工作原理,其次對深度神經(jīng)網(wǎng)絡(luò)在“服裝圖像識別”這一具體問題的實(shí)現(xiàn)過程進(jìn)行展示,最后則是對深度神經(jīng)網(wǎng)絡(luò)這一應(yīng)用的討論與總結(jié)。
深度神經(jīng)網(wǎng)絡(luò)是一種可以使用反向傳播算法(Backpropagation,BP)進(jìn)行訓(xùn)練的判別模型[2]。反向傳播算法,也稱作“誤差反向傳播”,是一種結(jié)合了最優(yōu)化算法(如梯度下降法),對神經(jīng)網(wǎng)絡(luò)進(jìn)行訓(xùn)練的常用方法。而判別模型,顧名思義,是監(jiān)督式學(xué)習(xí)(supervised learning)中處理統(tǒng)計(jì)分類問題的一類模型,其工作原理為:從歷史數(shù)據(jù)中學(xué)習(xí)不同類別對象的特征,并提取出模型,從而在面對新的學(xué)習(xí)對象時能夠預(yù)測出其從屬于每一個類別的概率,實(shí)現(xiàn)識別與歸類。
深度神經(jīng)網(wǎng)絡(luò)的主要組成結(jié)構(gòu)為輸入層,隱層與輸出層,如圖1。
圖1 深度神經(jīng)網(wǎng)絡(luò)
如圖所示,輸入層(input layers)為輸入的數(shù)據(jù)神經(jīng)元集合;輸出層(output layers)為經(jīng)過神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)后的輸出數(shù)據(jù)神經(jīng)元的集合;隱層(hidden layers)為輸入層與輸出層之間的紐帶,是深度神經(jīng)網(wǎng)絡(luò)的主要運(yùn)算部分,其作用是模擬人腦中神經(jīng)元之間的聯(lián)系與活動,來達(dá)到學(xué)習(xí)與優(yōu)化的目的。
隱層的數(shù)量和其中包含神經(jīng)元的個數(shù)決定了該神經(jīng)網(wǎng)絡(luò)的復(fù)雜度和處理能力。一般來講,隱層數(shù)量越多,模型的學(xué)習(xí)深度越高;而神經(jīng)元個數(shù)的增加也細(xì)化了數(shù)據(jù)之間的聯(lián)結(jié),從而提高學(xué)習(xí)的精確度。值得注意的是,每一個隱層中的神經(jīng)元是沒有直接關(guān)聯(lián)的,因此每當(dāng)希望模型進(jìn)一步挖掘前一個隱層神經(jīng)元之間的關(guān)系時,我們都需要添加一個新的隱層,這也是所謂“深度”的含義。
深度神經(jīng)網(wǎng)絡(luò)概念是從早期的感知機(jī)模型拓展而來的。感知機(jī)模型定義了從若干輸入到唯一輸出的一個線性關(guān)系,如圖2。
圖2 感知機(jī)模型
即在輸入層中,每一個神經(jīng)元都有其對應(yīng)的權(quán)重,權(quán)值(ω)乘以輸入值(x)加上對應(yīng)的偏差值(b)之后,可得到上圖圓圈所代表的中間輸出結(jié)果(z),如下式所示:
接著在中間輸出結(jié)果基礎(chǔ)上添加神經(jīng)元激活函數(shù)(activation function),例如
即得到最終輸出層的輸出結(jié)果,稱為“激勵響應(yīng)”。從感知機(jī)到深度神經(jīng)網(wǎng)絡(luò)的拓展主要基于以下3點(diǎn):
1)隱層數(shù)量更多,模型表達(dá)能力得到增強(qiáng);
2)輸出層不再只有唯一輸出結(jié)果,因此模型可以更加靈活地運(yùn)用到分類、聚類、降維、回歸等問題當(dāng)中;
3)激活函數(shù)的選擇更多元化。傳統(tǒng)感知機(jī)模型中的sign 函數(shù)只能用于二元分類,處理能力有限;而深度神經(jīng)網(wǎng)絡(luò)可以處理更多非線性模型,常用的神經(jīng)元激活函數(shù)有如下幾種:
2)Tanh函數(shù):tanh(x),
3)ReLU函數(shù):max(0,x)。
機(jī)器學(xué)習(xí)理論的核心在于,每一組輸入數(shù)據(jù)得到輸出結(jié)果后,該模型都將重新對其運(yùn)算規(guī)律作出調(diào)整與優(yōu)化。為達(dá)到這一目的,深度神經(jīng)網(wǎng)絡(luò)的反向傳播算法主要包括兩個階段:激勵傳播和權(quán)重更新。
感知機(jī)模型就是激勵傳播的第一步:“前向傳播階段”,即通過輸入和初始權(quán)值來得到對應(yīng)的激勵響應(yīng)。而第二步“反向傳播階段”,則是將得到的激勵響應(yīng)和輸入值對應(yīng)的目標(biāo)輸出求差,得到輸出層和隱層間的代價函數(shù)(cost function),記為C。
第二階段,權(quán)重ωi的更新可以用隨機(jī)梯度下降法(Stochastic gradient descent)求解:
將對深度神經(jīng)網(wǎng)絡(luò)在服裝圖像識別問題中進(jìn)行應(yīng)用研究,其目的在于通過對大量服裝圖片的學(xué)習(xí),讓模型在接收到新的服裝圖片時,能夠自動識別服裝的類別,并且達(dá)到較高的準(zhǔn)確率?;赥ensorFlow計(jì)算庫在深度學(xué)習(xí)領(lǐng)域優(yōu)秀的處理能力,我們將主要運(yùn)用其中的Keras 數(shù)據(jù)包來搭建該問題的模型。
理想情況下,能夠運(yùn)用于圖像識別訓(xùn)練的數(shù)據(jù)庫應(yīng)當(dāng)具備數(shù)據(jù)量大、規(guī)格標(biāo)準(zhǔn)、分類得當(dāng)?shù)忍攸c(diǎn)。Fashion-MNIST 是和傳統(tǒng)的MNIST數(shù)據(jù)庫結(jié)構(gòu)相類似的,基于歐洲電商公司Zalando 的圖片匯總而成的28*28 灰度服裝圖像數(shù)據(jù)庫,其中包含60,000 張訓(xùn)練圖片和10,000 張測試圖片,并將全部服裝分類為10類,標(biāo)號見表1。
表1 Fashion-MNIST 圖像數(shù)據(jù)庫的服裝類別編碼
通過tensorflow.keras 命令可輕松導(dǎo)入Fashion-MNIST 數(shù)據(jù)庫,并對訓(xùn)練圖片和測試圖片分別存儲,運(yùn)行代碼如下:
其中,training_images 和training_labels 分別代表訓(xùn)練圖片和其分類編號,而test_images 和test_labels則儲存著測試圖片和對應(yīng)的編碼。為了檢測以上存儲結(jié)果,我們可以引用matplotlib 包來進(jìn)行展示,例如:
import matplotlib.pyplot as plt
plt.imshow(training_images[0])
#展示第一幅訓(xùn)練圖片的內(nèi)容#
print(training_labels[0])
print(training_images[0])
輸出結(jié)果包括:該圖片的分類編號[9],完整圖片的28*28 個灰度值列表(范圍在[0,255]之間),以及該服裝圖片原貌,為一只踝靴(見圖3)。
圖3 第一幅訓(xùn)練圖片原貌
基于使數(shù)據(jù)誤差最小化和簡化運(yùn)算的原則,我們可以對圖片的灰度值進(jìn)行正交化處理,即將所有的灰度值除以255,使其從[0,255]區(qū)間統(tǒng)一到[0,1]區(qū)間,為接下來模型的搭建做好準(zhǔn)備:
training_images=training_images/255.0
test_images=test_images/255.0。
選用平行序列的隱層作為該深度神經(jīng)網(wǎng)絡(luò)的處理核心,故引用tensorflow.keras.models.Sequential定義模型:
model=tf.keras.models.Sequential([tf.keras.layrs.
Flatten(input_shape=(28,28)),
tf.keras.layers.Dense(128,activation=tf.nn.relu),
tf.keras.layers.Dense(10,activation=tf.nn.softax)])。
來分別解析該模型包括的內(nèi)容。Flatten函數(shù)定義了模型的輸入層,通過平方運(yùn)算,將二維的28*28正方形圖片整理為1*784的一維數(shù)組,便于后續(xù)讀取和處理。
第一個Dense 函數(shù)定義了模型的隱層,其神經(jīng)元激活函數(shù)為ReLU(只輸出x>0),包含128 個神經(jīng)元。在灰度圖片中,0代表黑色,255代表白色,而在Fashion-MNIST 數(shù)據(jù)庫中,圖片的背景為全黑,而服裝部分則偏白。由ReLU 函數(shù)的性質(zhì)可知,在計(jì)算權(quán)重時,背景部分權(quán)重為0,而服裝部分權(quán)重相對較高。簡而言之,該隱層相當(dāng)于對圖片進(jìn)行了背景裁剪,只將包含該服裝的有效部分進(jìn)行處理并傳達(dá)到下一層。
第二個Dense 函數(shù)定義了模型的輸出層,其激活函數(shù)為Softmax(將序列中的最大值標(biāo)為1,其余標(biāo)記為0),包含10 個神經(jīng)元,代表10 種不同的服裝編號。在隱層預(yù)測出該服裝從屬于每一種類別的概率后,該函數(shù)可以將其中概率值最大的類別作為該圖片最后的輸出分類結(jié)果。
完成了神經(jīng)網(wǎng)絡(luò)的定義,下一步是模型的編譯,即如何對學(xué)習(xí)成果進(jìn)行優(yōu)化和監(jiān)測:
model.compile(optimizer=tf.train.AdamOptimizer(),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
其中,optimizer 代表了模型的優(yōu)化過程,Adam Optimizer 具有計(jì)算效率高,存儲空間需求小的特點(diǎn),適合對大數(shù)據(jù)量的信息進(jìn)行統(tǒng)一處理;loss 函數(shù)表示模型使用的代價函數(shù)。因?yàn)槊恳环N服裝類別都是相互獨(dú)立的,因此我們選用交叉熵來解決探究的多分類問題,相較于傳統(tǒng)線性問題中使用的MSE(mean-squared error)函數(shù)更加合適,運(yùn)算也更加簡便。同時,由于希望在運(yùn)行過程中對模型學(xué)習(xí)的準(zhǔn)確率進(jìn)行實(shí)時監(jiān)測,我們添加了accuracy 矩陣來對此進(jìn)行表達(dá)。
在機(jī)器學(xué)習(xí)問題中,學(xué)習(xí)輪數(shù)也是關(guān)乎模型最終表現(xiàn)的重要因素之一:輪數(shù)過少則精度較低,而迭代次數(shù)過多也會出現(xiàn)過度擬合的情況。選擇定義一個Callback函數(shù)來根據(jù)預(yù)測結(jié)果的精度及時調(diào)整輪數(shù),從而避免以上問題。函數(shù)定義如下:
其中epoch 代表迭代次數(shù),從logs 變量中取得每一次迭代過程中預(yù)測的精確度進(jìn)行記錄。當(dāng)準(zhǔn)確度高于90%時,則停止迭代次數(shù),輸出最后結(jié)果。
模型搭建完成后,首先我們導(dǎo)入全部的訓(xùn)練圖片進(jìn)行學(xué)習(xí):
model.fit(training_images,training_labels,ep-ochs=10,callbacks=[callbacks])
即學(xué)習(xí)輪數(shù)上限是10,在此之前若精確度高于90%則停止學(xué)習(xí)。學(xué)習(xí)過程中可以實(shí)時監(jiān)控程序運(yùn)行。在第八輪學(xué)習(xí)后,對60,000幅訓(xùn)練圖片的分類精確度達(dá)到了90.29%。且每幅圖片的學(xué)習(xí)僅需要75微秒左右,整體運(yùn)行時間控制在在35秒內(nèi),非常高效快捷。此時模型的學(xué)習(xí)階段結(jié)束。
下一步,導(dǎo)入訓(xùn)練階段沒有包括的10,000張測試圖片,檢測模型對于新圖片的識別能力:
model.evaluate(test_images,test_labels)
輸出結(jié)果顯示,在識別新圖片的過程中,該模型的預(yù)測精度達(dá)到了88.46%,略低于之前的訓(xùn)練圖片。由于測試圖片與訓(xùn)練圖片互相獨(dú)立,因此分類準(zhǔn)確度有所下降是正?,F(xiàn)象。但在一秒內(nèi)得出這樣的結(jié)果,該模型仍具有運(yùn)行速度快,準(zhǔn)確度高的特點(diǎn),其表現(xiàn)是可圈可點(diǎn)的。
取單個測試圖片來觀察模型的識別過程。例如測試圖片的第二張,模型的預(yù)測結(jié)果如下:
classifications=model.predict(test_images)
print(classifications[1])
該代碼輸出了十個小于1的數(shù)字,分別代表該圖像可能歸屬于十種不同服裝類別的概率.其中,第三個數(shù)字的量級明顯高于其他數(shù)字,為0.9978,即表示該服裝歸屬于編號[2]:套頭毛衣的概率為99.78%,遠(yuǎn)高于歸屬其他類別。由此我們有把握推斷,第二張測試圖片是一件套頭毛衣。我們通過指令可以輕松查看該圖片的原始樣貌和分類:
plt.imshow(test_images[1])
print(test_images[1])
print(test_labels[1])
分類顯示數(shù)字2,如圖4顯示,這確實(shí)是一件套頭毛衣??梢娫撃P偷念A(yù)測是準(zhǔn)確無誤的。
至此,已經(jīng)得到了一個在服裝圖像識別問題中表現(xiàn)較為良好的深度神經(jīng)網(wǎng)絡(luò),但其功能還可以進(jìn)一步優(yōu)化。在此提出兩種可能的改進(jìn)方向:增加隱層的神經(jīng)元個數(shù),以及添加新的隱層。
3.5.1 增加隱層的神經(jīng)元個數(shù)
在原始模型中,選用了128 個神經(jīng)元的隱層進(jìn)行數(shù)據(jù)處理和權(quán)重分配。如果增加神經(jīng)元的個數(shù)至1024 個,即原有個數(shù)的八倍。由訓(xùn)練與測試的結(jié)果可以看到,由于運(yùn)算量的加大,模型的運(yùn)行時間變長了,每一輪的學(xué)習(xí)時間由原來的4~5秒增加為14~16秒。但修改后的模型僅用6次迭代就達(dá)到了90%的準(zhǔn)確率,可見整體的運(yùn)行效率得到了提高。當(dāng)然,神經(jīng)元的個數(shù)也并非越多越好,在達(dá)到一定數(shù)量后,模型的效率便不再有顯著提高,而運(yùn)行時間則會出現(xiàn)過長的情況。
3.5.2 添加新隱層
添加新的隱層可以增加神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)深度。我們嘗試為原模型添加一個具有1024 個神經(jīng)元,且同樣使用ReLU 作為激活函數(shù)的隱層。在原模型中添加新的隱層后,模型運(yùn)行速度略有下降,為每次迭代9~10 s,但同樣在6 次學(xué)習(xí)后就達(dá)到了和原模型相近的準(zhǔn)確度,為88.08%。事實(shí)上,對于許多復(fù)雜的機(jī)器學(xué)習(xí)問題,在簡單神經(jīng)網(wǎng)絡(luò)的基礎(chǔ)上多添加2~4個隱層,會是一個非常行之有效的提高模型效率的辦法。
主要基于深度神經(jīng)網(wǎng)絡(luò)的圖像識別功能,以Python TensorFlow 作為平臺,實(shí)現(xiàn)了模型的搭建與運(yùn)行。通過適當(dāng)增加隱層和神經(jīng)元的數(shù)量,我們可以進(jìn)一步提高模型的預(yù)測能力;而在傳統(tǒng)深度神經(jīng)網(wǎng)絡(luò)的基礎(chǔ)上加入其他功能性的隱層(如縮小圖片尺寸,強(qiáng)調(diào)圖形重點(diǎn)等),可以獲得更加功能強(qiáng)大的神經(jīng)網(wǎng)絡(luò)模型,如卷積神經(jīng)網(wǎng)絡(luò)、深度信任網(wǎng)絡(luò)等[3],都會是未來研究的重點(diǎn)。另外,TensorFlow計(jì)算庫的使用,將復(fù)雜的數(shù)理統(tǒng)計(jì)模型集成于簡潔的代碼中,使得更龐大的神經(jīng)網(wǎng)絡(luò)的搭建成為可能。因此,Python語言及其相關(guān)數(shù)據(jù)平臺在人工智能時代的廣泛發(fā)展和應(yīng)用,必將是大勢所趨。