0
| 本文作者: 汪思穎 | 2018-04-28 11:54 |
雷鋒網(wǎng) AI 研習(xí)社按,日前,MXNet 作者李沐在知乎上發(fā)文,介紹他們開(kāi)發(fā)了一個(gè)記錄 MXNet 數(shù)據(jù)類(lèi)型的庫(kù),稱(chēng)作 MXBoard,記錄結(jié)果可以用 TensorBoard 來(lái)呈現(xiàn)。原文如下,雷鋒網(wǎng) AI 研習(xí)社獲其授權(quán)轉(zhuǎn)載。
寫(xiě)在前面
深度神經(jīng)網(wǎng)絡(luò)自出現(xiàn)以來(lái)就一直飽受爭(zhēng)議。從實(shí)踐角度來(lái)講,設(shè)計(jì)并訓(xùn)練出一個(gè)可用的模型非常困難,需要涉及大量的調(diào)參、修改網(wǎng)絡(luò)結(jié)構(gòu)、嘗試各種優(yōu)化算法等等;從理論角度來(lái)看,深度神經(jīng)網(wǎng)絡(luò)的數(shù)學(xué)理論證明并不完備,從而造成人們對(duì)其基本原理缺乏清晰的認(rèn)識(shí)。而數(shù)據(jù)可視化帶來(lái)的直觀(guān)效果可以很大程度上彌補(bǔ)上述的不足。比如,模型訓(xùn)練時(shí)如果能實(shí)時(shí)畫(huà)出梯度數(shù)據(jù)分布,可以很快發(fā)現(xiàn)并糾正梯度消失或者梯度爆炸的現(xiàn)象。再比如,詞嵌入(word embedding)的可視化表明文字根據(jù)語(yǔ)義在低維空間聚合成不同的流形(manifold),這也從數(shù)學(xué)上解釋了,為什么增加詞向量的維度可以更好地區(qū)分不同語(yǔ)義的聚類(lèi)(低維空間纏繞的流形在高維可以分開(kāi))。優(yōu)秀可視化工具對(duì)深度學(xué)習(xí)的份量可見(jiàn)一斑。
TensorBoard 的橫空出世給 TensorFlow 的使用者帶來(lái)了可視化的福音。我們?cè)?tīng)到過(guò)很多用戶(hù)(包括企業(yè)用戶(hù))介紹,選擇TensorFlow 是因?yàn)榭梢杂?TensorBoard。這么好的東西能否給各大深度學(xué)習(xí)框架共享呢?多虧了 TeamHG-Memex 這個(gè)組織,將 TensorFlow 中寫(xiě)數(shù)據(jù)到事件文件 (event files)的算法提取出來(lái)。自此,開(kāi)發(fā)者們只需要將這個(gè)算法嵌入到深度學(xué)習(xí)的框架中,就可以使用 TensorBoard 來(lái)可視化框架特有的數(shù)據(jù)結(jié)構(gòu)了。
正是基于這樣的基礎(chǔ),我們開(kāi)發(fā)了一個(gè)記錄 MXNet 數(shù)據(jù)類(lèi)型的庫(kù),稱(chēng)作 MXBoard,記錄結(jié)果得以用 TensorBoard 來(lái)呈現(xiàn)。安裝 MXBoard 請(qǐng)參考這里。
注:請(qǐng)安裝 MXNet 1.2.0 版本來(lái)使用 MXBoard 的全部功能。在 MXNet 1.2.0 正式發(fā)布前,請(qǐng)安裝 MXNet nightly 版本來(lái)使用 MXBoard,pip install --pre mxnet
MXBoard 快速上手指南
MXBoard 支持了 TensorBoard 中大部分的數(shù)據(jù)類(lèi)型,如下圖所示。

MXBoard API 的設(shè)計(jì)參考了 tensorboard-pytorch,所有的記錄 API 都定義在一個(gè)叫 SummaryWriter 的類(lèi)當(dāng)中,這個(gè)類(lèi)含有諸如記錄的文件地址、寫(xiě)文件的頻率、寫(xiě)文件的隊(duì)列大小等等信息,用戶(hù)可以根據(jù)需求設(shè)置。當(dāng)需要把當(dāng)前數(shù)據(jù)記錄成 TensorBoard 中某種數(shù)據(jù)類(lèi)型時(shí),用戶(hù)只要調(diào)用相應(yīng)的 API 即可。
比如,我們想畫(huà)一個(gè)正態(tài)分布標(biāo)準(zhǔn)差逐漸縮小的數(shù)據(jù)分布圖。首先定義一個(gè)寫(xiě)記錄的對(duì)象如下,它會(huì)把數(shù)據(jù)寫(xiě)入到當(dāng)前文件夾下的名為 logs 的文件夾。
from mxboard import *
sw = SummaryWriter(logdir='./logs')
接著在每個(gè)循環(huán)里,用 MXNet 的隨機(jī)正態(tài)分布算子創(chuàng)建一個(gè) NDArray,把這個(gè) NDArray 傳給寫(xiě)數(shù)據(jù)的 API add_histogram,指定畫(huà)分布圖時(shí) bin 的數(shù)量和當(dāng)前的循環(huán)數(shù)。最后,和 Python 里常用的文件寫(xiě)入器一樣,記得關(guān)閉這個(gè) SummaryWriter。
import mxnet as mx
for i in range(10):
# create a normal distribution with fixed mean and decreasing std
data = mx.nd.random.normal(loc=0, scale=10.0/(i+1), shape=(10, 3, 8, 8))
sw.add_histogram(tag='norml_dist', values=data, bins=200, global_step=i)
sw.close()
為了看到效果圖,打開(kāi)命令行窗口,進(jìn)入到當(dāng)前文件夾,鍵入如下命令以打開(kāi) TensorBoard:
tensorboard --logdir=./logs --host=127.0.0.1 --port=8888
接著在瀏覽器地址欄輸入 127.0.0.1:8888,點(diǎn)擊 HISTOGRAM,就可以看到如下效果圖了。

實(shí)戰(zhàn) MXBoard
有了使用 MXBoard 的基本概念,我們來(lái)嘗試通過(guò)可視化完成下面兩個(gè)任務(wù):
監(jiān)督模型訓(xùn)練
理解卷積神經(jīng)網(wǎng)絡(luò)的工作原理
訓(xùn)練 MNIST 模型
借用 Gluon 里訓(xùn)練 MNIST 模型的 Python 程序,用 MXBoard 記錄下交叉熵、訓(xùn)練和測(cè)試精度、參數(shù)的梯度數(shù)據(jù)分布,可以實(shí)時(shí)反映出模型訓(xùn)練的進(jìn)度。
首先定義一個(gè) SummaryWriter 的對(duì)象,
sw = SummaryWriter(logdir='./logs', flush_secs=5)
這里加了 flush_secs=5 是為了每五秒就寫(xiě)一次記錄到文件,以便在瀏覽器中及時(shí)看到結(jié)果。接著在每個(gè) mini-batch 循環(huán)結(jié)束時(shí)記錄下交叉熵,
sw.add_scalar(tag='cross_entropy', value=L.mean().asscalar(), global_step=global_step)
在每個(gè) epoch 結(jié)束時(shí)記錄下參數(shù)的梯度為 HISTOGRAM,記錄下訓(xùn)練和測(cè)試精度為 SCALAR,
grads = [i.grad() for i in net.collect_params().values()]
assert len(grads) == len(param_names)
# logging the gradients of parameters for checking convergence
for i, name in enumerate(param_names):
sw.add_histogram(tag=name, values=grads[i], global_step=epoch, bins=1000)
name, acc = metric.get()
# logging training accuracy
sw.add_scalar(tag='train_acc', value=acc, global_step=epoch)
name, val_acc = test(ctx)
# logging the validation accuracy
sw.add_scalar(tag='valid_acc', value=val_acc, global_step=epoch)
然后運(yùn)行 Python 程序,并運(yùn)行 TensorBoard,就可以在瀏覽器中看到以下效果了。小伙伴們可以嘗試著用 MXBoard 監(jiān)督訓(xùn)練更復(fù)雜神經(jīng)網(wǎng)絡(luò)。更多本實(shí)例的代碼和解說(shuō)請(qǐng)點(diǎn)擊這里。


可視化卷積層的 filters 和 feature maps
將卷積層的 filters 和 feature maps 當(dāng)成圖片可視化有兩個(gè)意義:
特征平滑規(guī)律的 filters 是模型訓(xùn)練良好的標(biāo)志之一,未收斂或過(guò)擬合模型的卷積層 filters 會(huì)出現(xiàn)很多 noise。
觀(guān)察 filters 和 feature maps 的圖片,特別是第一層卷積的圖片可以總結(jié)出該層所關(guān)注的圖片特征,這有助于我們理解卷積神經(jīng)網(wǎng)絡(luò)的工作原理。
這里將 MXNet Model Zoo 中三個(gè) CNN 模型,Inception-BN,Resnet-152,和 VGG16 的 filters 當(dāng)成圖像輸出到 TensorBoard,并將這三組 filters 作用于一張黑天鵝的圖片(來(lái)自驗(yàn)證數(shù)據(jù)集 val_256_q90.rec)上觀(guān)察 feature maps。
Inception-BN

Resnet-152

VGG16

可以看出三個(gè)模型的 filters 都表現(xiàn)出良好的光滑性和規(guī)律性,彩色 filters 負(fù)責(zé)提取原始圖片前景和背景的局部特征,灰白圖片負(fù)責(zé)提取圖片中物體的輪廓特征。復(fù)現(xiàn)代碼和解釋請(qǐng)點(diǎn)擊這里。
可視化圖片的 embedding
最后這個(gè)例子比較有趣。Embedding 在自然語(yǔ)言處理中是一個(gè)常用的概念,它是真實(shí)世界中物體在高維向量空間中的表示。我們也可以借用此概念到卷積神經(jīng)網(wǎng)絡(luò)中。卷積神經(jīng)網(wǎng)絡(luò)最后一個(gè)全連接層的輸出可以看成是一個(gè) batch_size 行、num_labels 列的矩陣,每一行作為一個(gè) num_labels 維的向量就是對(duì)應(yīng)輸入圖片的 embedding。本質(zhì)上這個(gè) embedding 就是卷積神經(jīng)網(wǎng)絡(luò)對(duì)圖片的編碼,softmax 層通過(guò)此編碼來(lái)判斷圖片所屬類(lèi)別。當(dāng)理解了圖片 embedding 的概念后,我們就可以把一個(gè)圖片集的所有 embedding 通過(guò)沒(méi)有 softmax 層的卷積神經(jīng)網(wǎng)絡(luò)求出來(lái),調(diào)用 MXBoard 的 add_embedding API,從而來(lái)觀(guān)察他們?cè)诙S或者三維空間中的聚合效應(yīng),即同類(lèi)別圖片應(yīng)該聚合在一起。
這里我們從上一個(gè)例子里的驗(yàn)證數(shù)據(jù)集中隨機(jī)選取了 2304 張圖片,用 Resnet-152 模型算出了它們的 embeddings,用 MXBoard 寫(xiě)入事件文件,并由 TensorBoard 讀取,效果如下。

這里2304張圖片的 embeddings 默認(rèn)由 PCA 算法壓縮到了三維空間,不過(guò)圖片聚合效應(yīng)似乎不是那么明顯,這是因?yàn)?PCA 算法不能保持原始物體之間的空間關(guān)系。因此,我們選用 TensorBoard 界面上提供的 t-SNE 算法,重新對(duì) embeddings 進(jìn)行降維操作,這是個(gè)動(dòng)態(tài)的過(guò)程。

隨著 t-SNE 算法的收斂,可以很明顯地看到圖片集在三維空間中被分成了幾類(lèi)。

最后我們來(lái)驗(yàn)證一下圖片分類(lèi)是否正確。在 TensorBoard GUI的右上角輸入“dog”,所有打了“dog”標(biāo)記的圖片將被高亮。拖動(dòng)并放大至高亮圖片處,可以看到很多狗的圖片,這表明預(yù)訓(xùn)練的 Resnet-152 模型是準(zhǔn)確的。

全部代碼和具體說(shuō)明請(qǐng)點(diǎn)這里。
后記
通過(guò)實(shí)戰(zhàn) MXBoard,我們可以看到,可視化工具在監(jiān)督訓(xùn)練模型和解釋深度學(xué)習(xí)原理方面的強(qiáng)大作用。MXBoard 給 MXNet 提供了一個(gè)在科研和生產(chǎn)環(huán)境中簡(jiǎn)單、易用、集中的可視化方案。當(dāng)所有的代碼在后臺(tái)運(yùn)行時(shí),你需要的只是一個(gè)瀏覽器。
看了這么多,聰明的你是不是有很多精彩的可視化點(diǎn)子躍躍欲試呢?點(diǎn)擊文末鏈接分享炫酷圖片,讓 MXNet 動(dòng)起來(lái)。
特別感謝鄭子豪在項(xiàng)目開(kāi)發(fā)時(shí)提供的技術(shù)支持。
雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見(jiàn)轉(zhuǎn)載須知。