手把手教你玩轉谷歌TensorFlow

峻峰飛陽發表於2018-08-15

AI並不是一門簡單的學科,AI演算法的開發和除錯並沒有一個統一的、整合了大量API方便呼叫的平臺和語言,目前的人工智慧開發平臺仍然處於一種半蠻荒的狀態。許多功能需要自己親自去搭建和實現。

不過幸運的是,這個領域受到了足夠多的重視,因此許多巨頭都針對它開發了自己的平臺,這其中就包括谷歌的Tensorflow。谷歌DeepMind在AI領域的造詣已經人盡皆知,其推出的這款開發語言平臺也不禁引人遐想,那麼,Tensorflow到底適合如何拿來做開發?能不能為你的研究或者產品帶來更好的機會?

本期公開課我們邀請到了科技公司Nielsen的機器學習實驗室的負責人李加波博士,他帶領的團隊利用基於Tensorflow自己改進的演算法成功運用在了公司的精準廣告推送業務中。在產業界的十多年中,李博士始終堅持學術研究與產業應用相結合,長期保持與學術界的緊密合作,並將學術成果引入到軟體創新中。

嘉賓介紹,李加波,目前任職於美國科技公司Nielsen的 Machine Learning Lab, 負責領導基於深度學習智慧產品的研發,主要利用Tensorflow框架搭建新型的深度神經網路,利用GPU訓練各種使用者分類模型,並將這些模型運用於精準廣告推送中。在去年加入Nielsen之前曾任職於生物,製藥和金融等科技軟體公司,包括Accelrys, 薛定諤(Schrödinger)及TD Ameritrade。

李博士在工業界的十多年中始終堅持學術研究與工業應用相結合,長期保持與學術界的緊密合作,並將學術成果引入直接到軟體創新中。目前任中山大學藥學院客座教授,指導博士生的研究課題,並開設了Advanced Lectures on Algorithms and High Performance Computing (演算法與高效能運算程式設計) 高階研討班。另外在國際期刊發表科學論文六十多篇。李博士對各種複雜科學計算演算法問題有極致的追求,併發明瞭一系列不同學科的優秀演算法。

▎為什麼一開始選擇Tensorflow作為首選平臺?

最開始對於選取何種深度學習平臺並不確定,而且那時Tensorflow還尚未問世。當時的考慮主要是該平臺的成熟程度,支援的程式語言,GPU的支援和效率,搭建神經網路的使用的方便程度,上手難易,平臺的後續發展,開發的生態環境,平臺的效率等因素。儘管我們收集了一些評比資料,要在諸多因素的權衡之中做出選擇並非易事,而且逐個去試也不現實。不久之後,Tensorflow從Google開源,我們毫不猶豫地選定了它。

其一,TF有我們要求的所有功能(C++/Python語言支援,GPU,等)。更重要的是我們相信由Google推出的平臺會很快為大家接受並迅速形成對應的開發生態圈和活躍的後續更新發展。後來的事實也證實了我們的料想。下面表格比較了幾種流行的平臺,資料來源於今年二月份在arXiv釋出的論文。

那時候,Caffe和Theano還是最活躍的開源開發社群,但到目前Tensorflow已有最多的開發者。見下表:

總體來講,TF給我的感覺不錯,我相信Google產品的後發優勢。

▎Tensorflow的優點和缺點是什麼?

總的來說,Tensorflow提供的API對搭建神經網路有了足夠的自由度。對於損失函式的構造也很直接,TF框架能自動計算任意構建的損失函式的導數。對模型引數的訓練也提供了最新的一些演算法可供選擇。TF使用者論壇也很活躍,有疑難問題也很快能從中得到幫助。

當然也有一些不足之處。例如如果要構造任意連線的神經網路,TF沒有提高直接的工具,但有一個通過向量轉置的變通的辦法來實現,但代價是訓練和打分都十分的緩慢。

另一個不足之處是,對於實時的應用(需要對單個輸入一個個單獨計算打分),效率很低。例如,將一千個輸入記錄作為一個批處理交給TF打分要比分一千次每次計算一個記錄要快100倍。這意味著後者(實時應用)比其前者的效率低了兩個數量級。

▎它和ResNet的區別?兩個版本差別在哪裡?

何愷明去年底提出的152層超深度的殘差網路贏得了2015年度ImageNet競賽的冠軍,隨後論文發表在arXiv上("Deep Residual Learning for Image Recognition", by Kaiming He, Xiangyu Zhang, Shaoqing Ren, and Jian Sun. (Dec. 10 2015) http://arxiv.org/abs/1512.03385)。

今年七月同樣在arXiv 上發表續集("Identity Mappings in Deep Residual Networks", by Kaiming He, Xiangyu Zhang, Shaoqing Ren, and Jian Sun. (July, 2016) http://arxiv.org/abs/1603.05027v3)。 這裡姑且叫前者ResNet I, 後者 ResNet II。殘差網路的出發點很簡單,簡潔性正是大受歡迎的原因。

起核心思想包含三個要素:資訊通路捷徑,殘差單元,殘差單元輸出與資訊通路的合併。數學表達為:

其中F為殘差單元的操作,h(x) = x. ResNet I 與 ResNet II的差異在於其中的f 函式。如f是非線性變換,則為ResNet I, 如果f 為恆等變換則為ResNet II,見下圖:

Figure 2a. The tensor flow chart of ResNet I.

Figure 2b. The tensor flow chart of ResNet II. 

總結:ResNet I在資訊合併後緊接非線性變換,而ResNet II則數非線性變換後在合併。

▎為何要在Tensorflow上搭建一個自己的基於 ResNet思想的網路?

首先,沒有一個現成的網路構架能完全合乎我們問題的解決方案,這是實際需要。同時,要得到最好結果,必須對最新的研究成果廣泛吸收,加以創新。對於為何在應用中要採用ResNet的思想我們得從理解ResNet為何能有效開始。儘管愷明有一點解釋,但這裡我給出不同角度的一個理解。一個神經網路模型的精確度受兩個競爭因素的影響:網路複雜度越高,模型的表達力越強,逼近最佳結果的潛力也越高。

另一面,複雜度越高,從高維引數空間通過SGD方法尋求最佳解的困難也越大。可以將SGD優化類比從山上沿著山路下到山底谷的過程, 如圖(圖片來自網上):

Figure 3. Stochastic Gradient Descendent (SGD)  method 

可以這樣理解:可以將優化問題理解為從山上凹凸不平的山路中尋找一條到達山谷的途徑,山路崎嶇,充滿陷阱。只是相對於神經網路模型而言是在一個超高維(數百萬維對於三維)的山上,而山路的崎嶇複雜和陷阱的數量遠超三維空間的情形。要成功下到山谷(或接近山谷),下山途中要儘量避免誤入歧途,掉入陷阱,萬一掉入也有機會逃去陷阱。ResNet的結構是在原有的網路基礎上新增了一個資訊通路捷徑,從而可以向前跨越數層網路在一些特定層與原來的輸出匯合,並作為下一個殘差單元的輸入。從數學直覺上看,這應該是勢能面變得平坦一些,即使下山掉入陷阱,從中逃逸的機會也大些。

一旦理解了ResNet的思想就可以在其它網路構架中利用,而這個在Tensorflow上很容易實現。

Tensorflow提供的Python API可直接用於網路的搭建。這些API非常直觀,可以將網路結構的數學表達直接翻譯成對應tf函式的呼叫(例如tf.nn.matmul, tf.nn.relu, tn.nn.l2_loss  for L2 regularization,and  tf.reduce_sum for L1 regularization)。由於TF能對任意損失函式自動計算導數,因此可以設計任何形式的損失函式和任意的網路結構,非常靈活。

ResNet 的引入,讓我們可以建立超深度的神經網路而不必太擔心訓練模型中的收斂性的問題。即使對於不太深的網路,ResNet 仍可以改進收斂和改善精度。

▎Tensorflow使用中需注意的問題?

在使用Tensorflow上與其它框架沒有特別的地方。不過有些問題對於神經網路的訓練帶有普遍性。

首先,訓練神經網路往往有許多巨集觀控制引數,包括網路結構的深度,寬度,學習速率的選擇及動態調節,正則化(Regularization)的型別和強度,迭代次數等。這些沒有一個簡單的標準怎樣選區,通常只能通過不斷試錯才能找到最佳答案。模型中的引數初始化也很關鍵, 如選擇不當,迭代會停滯不前。例如,如果優化陷入停滯不前,簡單的解決辦法就是對全體起始引數進行縮放。

Figure 4. Convergence is very sensitive to both learning rate and model initialization.

前一個圖開始學習速率為0.002,模型訓練收斂正常。第二個圖開始學習速率為0.02,完全不收斂(欲速則不達)。

▎如何基於Tensorflow搭建新的神經網路架構?

在Tensorflow上搭建神經網路還是比較直接的,因為Tensorflow 提供了十分豐富的API (Python和C++),和搭建神經網路的各個元件,包括卷積網路構件,各種優化方法,各種損失函式的組合,正則化控制等。因此許多軟體開發都可以基於Tensorflow提供的Python應用介面進行,因此在研發中可以快速實驗不同的構架。

然而,也正是因為使用Python介面,對於特定應用這有可能成為效率的瓶頸。我目前還沒有深入到C++底層修改Tensorflow。但從長遠看進入底層的擴充套件是必要的,特別是對特定應用進行效率優化。 例如,對於一個實時應用來說,要求能夠對於每一個單獨的輸入快速響應,返回結果。我們發現,雖然Tensorflow GPU版本能夠高速批處理打分(batch scoring),如果同樣的數量單獨一個個處理,效率可能會慢兩個數量級,這對於實時應用是個問題。解決之道可以單獨編寫一個高效率的打分函式,而不必依賴Tensorflow。

▎之前你提到你們搭建的網路架構不同於卷積神經網路,所以採用了ResNet的思想。ReNet思想是指?

這個問題要這樣看:殘差網路(ResNet) 和卷積神經網路( ConvNet) 之間是平行概念,互不排斥。

ResNet的基本思想可以和卷積神經網路結合,也可和其它任何型別的神經網路結合。ResNet的核心思想是在不改變網路表達力和複雜度的情形下改變損失函式勢能面的狀況,從而使優化到最佳點的途徑變得順利些。

▎如何根據自己需求開發深度學習產品?

這個問題很大,有些籠統。總的來說,並非所有應用都需要用深度學習。能用簡單模型解決的問題絕不用複雜的深度模型。例如如果問題能用線性模型就能得到很好的結果,那麼用深度神經網路就沒必要,因為簡單模型的效率要高很多。但如果問題是高度非線性,而且各個變數之間存在強烈耦合,那麼這時用神經網路可能是一個好的選擇。但即使如此,也要從簡單的網路開始入手,例如3-6層網路,然後逐漸增加層數,仔細觀察是否有改進空間。由於SGD優化結果帶有一定的誤差和不確定性,每次Tensorflow優化的結果會有g一定的差別,因此觀測增加層數是否改進模型精度時要小心,要重複多次運算,取平均值,然後做比較。這樣做對於樣本數較少時尤為重要。

▎如何根據自己需求在深度學習中做演算法創新?

這個問題很大,應該問Jeff Hinton 或Yan LeCun 等大牛。但一些通常的創新思維方式還是值得借鑑的。我認為,首先要對問題有透徹的理解。例如我門希望對卷積神經網路是怎樣工作的,近幾年不斷改進的演算法是如何提高模型精度的有深入的認識,不僅如此,我們還要對反方向的研究結果有所理解。例如,Szegedy 等人的研究表明,在一個能被DNN模型完全正確識別的圖片(如獅子)加入人眼難以擦覺的噪聲,然後再讓計算機識別,會認為是一個完全不同的類別。

還有最近Yoshinski 的研究表明利用一訓練好的DNN模型可以從完全無規的電視機雪花噪聲圖片(完全沒有任何意義),通過對圖象優化使得DNN以很高的置信度(99.99%)認為是某個特定動物(如熊貓或啄木鳥等)而得到的影象仍然如同一片噪聲,完全看不出任何有意義的模樣。  

如果我們能從數學上理解這些現象那麼我們必將產生更新的思想,引導我們嘗試新的網路結構,從而發現更有效,更精確,更魯棒的演算法來。但是,對於這些問題我們目前還了解得不透,而恰恰是因為這樣,還有許多創新空間等待我們發現。另外,目前關於影象識別的大多數演算法幾乎都是基於卷積神經網路。是否有其它途徑,使得我們即使利用較少的樣本也可以訓練出很好的模型,如同人類認知能力一樣?這值得我們深思!

▎怎麼根據自己的需求改進神經網路?

怎樣跟據自己需求改進網路架構這個問題比較泛。大致講要根據自身應用問題的特殊性調整。例如,卷積神經網路主要用於影象識別,因為影象中的每個畫素都與其鄰近畫素關連,而全部的這種關聯,空間關係決定了一個影象的表徵。卷積神經網路的設計就是為了提取這些特徵,並通過大量例子訓練模型。

而有些問題,其變數之間的相互作用關係不明確,無法套用卷積神經網路。這時可以採用全連線網路,或根據已知或猜測到的相互作用關係建立網路連線(這樣可大大減少引數量)。實際應用中還涉及模型的效率(速度)問題。 如果一個神經網路過大,無論是訓練還是用於打分都會較慢,如需提速,必須減少模型的大小。

▎如何利用GPU加速?請舉例說明。

對於Tensorflow,其GPU加速已在其核心構架的底層已經實現了。對於所有關神經網路運算都有對應的GPU版本,因此從開發者的角度看,Tensorflow 實際上已將開發者從GPU程式設計的痛苦中解救出來了。因此,利用GPU加速變成了僅僅是一個安裝的問題。

如果你有GPU機器,裝載支援GPU的Tensorflow版本即可。CPU/GPU版本從API的角度是透明的,同樣的PYTHON程式碼可以在CPU/GPU兩個版本上執行。

不過安裝GPU版本時有一點要注意:Tensorflow預設要求GPU卡的運算能力為3.5或以上。如果你的GPU的運算能力為3.0(相當普遍),那麼預設安裝會有問題。這時要從原始碼進行編譯安裝,並且要在編譯時的計算能力選項引數設為3.0。目前Amazon雲端計算提供的GPU還是3.0,所以在Amazon 上安裝Tensorflow 要從原始碼開始編譯安裝。Tensorflow支援多GPU,但相應的程式碼要修改,因為要對任務的分配進行程式設計。我們比較了一個32核CPU與一個單片GPU機上Tensorflow 執行的速度做個比較。GPU機器大約是32核CPU機器速度的4倍。 

▎你是如何多年堅持科研並將成果引入到軟體創新中的?

多年堅持將學術成果引入到軟體創新中需要有很大的熱情。

我一直保持著學術研究的興趣,尤其是與實際應用相關的問題, 其目的就是要將突破性研究成果融入到新產品的開發之中。 例如,2006獲得了公司獎勵的學術休假,使得我有幾個月自由科研的機會,也正是在此期間發明了愷撒(CAESAR)演算法,提高了三維分子結構模擬的效率達十倍以上,並作為藥物分子設計的一個核心模組廣泛應用於各大製藥公司的藥物研發中。從2008年以來開始與中山大學,除了給國內的研究生遠端授課外,每年也回國一兩次講學,並指導研究生的課題。

另一成功案例:WEGA(三維幾何形狀比較的高斯權重)演算法。

工業應用:藥物分子的計算機輔助設計問題痛點:超大規模分子庫三維數十億個分子形狀的比較計算量巨大而費時。合作研究:與中山大學藥學院合作,組建了一個攻關團度,包括博導和其學生。解決方案:分三步:1)新演算法,2)GPU加速, 3)GPU叢集的大規模並行。

研究成果:

1)演算法方面,提出了比較分子三維形狀的WEGA(高斯權重)演算法,大大提高了計算精度同時保留了計算的簡潔性和高效率。2)指導中大博士生開發了利用GPU加速的GWEGA,使得單片GPU即可提高近100倍的加速。3 )利用廣州超算中心的GPU叢集實現了大規模GPU並行,將TB數量級的超大規模分子庫的三維結構檢索移植到GPU叢集中,實現了1億次/秒的高通量藥物分子虛擬篩選,比國際競爭對手快了近兩個數量級。這一成果我們申請了中國和國際專利。

難點:這個專案的難點是GPU程式設計。GPU程式設計的門檻較高,尤其是要達到高效率,特別是要達到近100倍的加速,對程式設計技巧有苛刻的要求。為此,外特地為中東研究生開設了GPU程式設計課,讓學生很快入門,進而對GPU架構有深入的理解,關鍵地方和學生一同探討,對每行程式碼逐條分析優化,將效率推行極致。這個過程不僅培養了學生,同時也使難題得以解決。

▎群友提問:除了影象之外,對於其它有一定相互關聯性的訊號,是否都可以借鑑卷積網路,比如一些時間上有一定關聯的訊號的機器學習?

可以,但比較麻煩,因為你不知道怎樣歸類,對於音訊完全可以,時間和頻率構成二維影象。

相關文章