做者: 陳迪豪,就任小米科技,深度學習工程師,TensorFlow代碼提交者。git
TensorFlow深度學習框架
Google不只是大數據和雲計算的領導者,在機器學習和深度學習上也有很好的實踐和積累,在2015年年末開源了內部使用的深度學習框架TensorFlow。github
與Caffe、Theano、Torch、MXNet等框架相比,TensorFlow在Github上Fork數和Star數都是最多的,並且在圖形分類、音頻處理、推薦系統和天然語言處理等場景下都有豐富的應用。最近流行的Keras框架底層默認使用TensorFlow,著名的斯坦福CS231n課程使用TensorFlow做爲授課和做業的編程語言,國內外多本TensorFlow書籍已經在籌備或者發售中,AlphaGo開發團隊Deepmind也計劃將神經網絡應用遷移到TensorFlow中,這無不印證了TensorFlow在業界的流行程度。算法
TensorFlow不只在Github開放了源代碼,在《TensorFlow: Large-Scale Machine Learning on Heterogeneous Distributed Systems》論文中也介紹了系統框架的設計與實現,其中測試過200節點規模的訓練集羣也是其餘分佈式深度學習框架所不能媲美的。Google還在《Wide & Deep Learning for Recommender Systems》和《The YouTube Video Recommendation System》論文中介紹了Google Play應用商店和YouTube視頻推薦的算法模型,還提供了基於TensorFlow的代碼實例,使用TensorFlow任何人均可以在ImageNet或Kaggle競賽中獲得接近State of the art的好成績。編程
TensorFlow從入門到應用
絕不誇張得說,TensorFlow的流行讓深度學習門檻變得愈來愈低,只要你有Python和機器學習基礎,入門和使用神經網絡模型變得很是簡單。TensorFlow支持Python和C++兩種編程語言,再複雜的多層神經網絡模型均可以用Python來實現,若是業務使用其餘編程也不用擔憂,使用跨語言的gRPC或者HTTP服務也能夠訪問使用TensorFlow訓練好的智能模型。服務器
那使用Python如何編寫TensorFlow應用呢?從入門到應用究竟有多難呢?網絡
下面咱們編寫了一個Hello world應用,輸出字符串和進行簡單的運算。多線程
從這段簡單的代碼能夠了解到TensorFlow的使用很是方便,經過Python標準庫的形式導入,不須要啓動額外的服務。第一次接觸TensorFlow可能比較疑惑,這段邏輯Python也能夠實現,爲何要使用tf.constant()和tf.Session()呢?其實TensorFlow經過Graph和Session來定義運行的模型和訓練,這在複雜的模型和分佈式訓練上有很是大好處,將在文章的後續部分介紹到。架構
前面的Hello world應用並無訓練模型,接下來介紹一個邏輯迴歸問題與模型。咱們使用numpy構建一組線性關係的數據,經過TensorFlow實現的隨機梯度算法,在訓練足夠長的時間後能夠自動求解函數中的斜率和截距。app
上面的代碼能夠在tensorflow_examples項目中找到,通過訓練,咱們看到輸出的斜率w約爲2,截距b約爲10,與咱們構建的數據之間的關聯關係十分吻合!注意在TensorFlow代碼中並無實現最小二乘法等算法,也沒有if-else來控制代碼邏輯,徹底是由數據驅動而且根據梯度降低算法動態調整Loss值學習出來的。這樣咱們即便換了其餘數據集,甚至換成圖像分類等其餘領域的問題,無需修改代碼也能夠由機器自動學習,這也是神經網絡和TensorFlow強大的地方。
前面的模型只有w和b兩個變量,若是數據處於非線性關係就難以獲得很好的結果,所以咱們建議使用深層神經網絡,這也是TensorFlow設計重點就要解決的深度學習模型。咱們知道Google在2014年憑藉Inception模型贏下了ImageNet全球競賽,裏面代碼就是基於TensorFlow實現的,下面是較爲複雜的模型定義代碼。
使用TensorFlow已經封裝好的全鏈接網絡、卷積神經網絡、RNN和LSTM,咱們已經能夠組合出各類網絡模型,實現Inception這樣的多層神經網絡如拼湊Lego同樣簡單。但在選擇優化算法、生成TFRecords、導出模型文件和支持分佈式訓練上,這裏有比較多的細節,接下來咱們將在一篇文章的篇幅內介紹全部TensorFlow相關的核心使用技巧。
TensorFlow核心使用技巧
爲了介紹TensorFlow的各類用法,咱們將使用deep_recommend_system這個開源項目,它實現了TFRecords、QueueRunner、Checkpoint、TensorBoard、Inference、GPU支持、分佈式訓練和多層神經網絡模型等特性,並且能夠輕易拓展實現Wide and deep等模型,在實際的項目開發中能夠直接下載使用。
1. 準備訓練數據
通常TensorFlow應用代碼包含Graph的定義和Session的運行,代碼量不大能夠封裝到一個文件中,如cancer_classifier.py文件。訓練前須要準備樣本數據和測試數據,通常數據文件是空格或者逗號分隔的CSV文件,但TensorFlow建議使用二進制的TFRecords格式,這樣能夠支持QueuRunner和Coordinator進行多線程數據讀取,而且能夠經過batch size和epoch參數來控制訓練時單次batch的大小和對樣本文件迭代訓練多少輪。若是直接讀取CSV文件,須要在代碼中記錄下一次讀取數據的指針,並且在樣本沒法所有加載到內存時使用很是不便。
在data目錄,項目已經提供了CSV與TFRecords格式轉換工具convert_cancer_to_tfrecords.py,參考這個腳本你就能夠parse任意格式的CSV文件,轉成TensorFlow支持的TFRecords格式。不管是大數據仍是小數據,經過簡單的腳本工具就能夠直接對接TensorFlow,項目中還提供print_cancer_tfrecords.py腳原本調用API直接讀取TFRecords文件的內容。
2. 接受命令行參數
有了TFRecords,咱們就能夠編寫代碼來訓練神經網絡模型了,但衆所周知,深度學習有過多的Hyperparameter須要調優,咱們就優化算法、模型層數和不一樣模型都須要不斷調整,這時候使用命令行參數是很是方便的。
TensorFlow底層使用了python-gflags項目,而後封裝成tf.app.flags接口,使用起來很是簡單和直觀,在實際項目中通常會提早定義命令行參數,尤爲在後面將會提到的Cloud Machine Learning服務中,經過參數來簡化Hyperparameter的調優。
3. 定義神經網絡模型
準備完數據和參數,最重要的仍是要定義好網絡模型,定義模型參數能夠很簡單,建立多個Variable便可,也能夠作得比較複雜,例如使用使用tf.variable_scope()和tf.get_variables()接口。爲了保證每一個Variable都有獨特的名字,並且能都輕易地修改隱層節點數和網絡層數,咱們建議參考項目中的代碼,尤爲在定義Variables時注意要綁定CPU,TensorFlow默認使用GPU可能致使參數更新過慢。
上述代碼在生產環境也十分常見,不管是訓練、實現inference仍是驗證模型正確率和auc時都會用到。項目中還基於此代碼實現了Wide and deep模型,在Google Play應用商店的推薦業務有普遍應用,這也是適用於廣泛的推薦系統,將傳統的邏輯迴歸模型和深度學習的神經網絡模型有機結合在一塊兒。
4. 使用不一樣的優化算法
定義好網絡模型,咱們須要以爲使用哪一種Optimizer去優化模型參數,是應該選擇Sgd、Rmsprop仍是選擇Adagrad、Ftrl呢?對於不一樣場景和數據集沒有固定的答案,最好的方式就是實踐,經過前面定義的命令行參數咱們能夠很方便得使用不一樣優化算法來訓練模型。
在生產實踐中,不一樣優化算法在訓練結果、訓練速度上都有很大差別,過分優化網絡參數可能效果沒有使用其餘優化算法來得有效,所以選用正確的優化算法也是Hyperparameter調優中很重要的一步,經過在TensorFlow代碼中加入這段邏輯也能夠很好地實現對應的功能。
5. Online learning與Continuous learning
不少機器學習廠商都會宣稱本身的產品支持Online learning,其實這只是TensorFlow的一個基本的功能,就是支持在線數據不斷優化模型。TensorFlow能夠經過tf.train.Saver()來保存模型和恢復模型參數,使用Python加載模型文件後,可不斷接受在線請求的數據,更新模型參數後經過Saver保存成checkpoint,用於下一次優化或者線上服務。
而Continuous training是指訓練即便被中斷,也能繼續上一次的訓練結果繼續優化模型,在TensorFlow中也是經過Saver和checkpoint文件來實現。在deep_recommend_system項目默認能從上一次訓練中繼續優化模型,也能夠在命令行中指定train_from_scratch,不只不用擔憂訓練進程被中斷,也能夠一邊訓練一邊作inference提供線上服務。
6. 使用TensorBoard優化參數
TensorFlow還集成了一個功能強大的圖形化工具,也便是TensorBoard,通常只須要在代碼中加入咱們關心的訓練指標,TensorBoard就會自動根據這些參數繪圖,經過可視化的方式來了解模型訓練的狀況。
tf.scalar_summary(‘loss’, loss)
tf.scalar_summary(‘accuracy’, accuracy)
tf.scalar_summary(‘auc’, auc_op)
7. 分佈式TensorFlow應用
最後不得不介紹TensorFlow強大的分佈式計算功能,傳統的計算框架如Caffe,原生不支持分佈式訓練,在數據量巨大的狀況下每每沒法經過增長機器scale out。TensorFlow承載了Google各個業務PB級的數據,在設計之初就考慮到分佈式計算的需求,經過gRPC、Protobuf等高性能庫實現了神經網絡模型的分佈式計算。
實現分佈式TensorFlow應用並不難,構建Graph代碼與單機版相同,咱們實現了一個分佈式的cancer_classifier.py例子,經過下面的命令就能夠啓動多ps多worker的訓練集羣。
1
2
3
4
5
6
7
|
cancer_classifier.py --ps_hosts=127.0.0.1:2222,127.0.0.1:2223 --worker_hosts=127.0.0.1:2224,127.0.0.1:2225 --job_name=ps --task_index=0
cancer_classifier.py --ps_hosts=127.0.0.1:2222,127.0.0.1:2223 --worker_hosts=127.0.0.1:2224,127.0.0.1:2225 --job_name=ps --task_index=1
cancer_classifier.py --ps_hosts=127.0.0.1:2222,127.0.0.1:2223 --worker_hosts=127.0.0.1:2224,127.0.0.1:2225 --job_name=worker --task_index=0
cancer_classifier.py --ps_hosts=127.0.0.1:2222,127.0.0.1:2223 --worker_hosts=127.0.0.1:2224,127.0.0.1:2225 --job_name=worker --task_index=1
|
在深刻閱讀代碼前,咱們須要瞭解分佈式TensorFlow中ps、worker、in-graph、between-graph、synchronous training和asynchronous training的概念。首先ps是整個訓練集羣的參數服務器,保存模型的Variable,worker是計算模型梯度的節點,獲得的梯度向量會交付給ps更新模型。in-graph與between-graph對應,但二者均可以實現同步訓練和異步訓練,in-graph指整個集羣由一個client來構建graph,而且由這個client來提交graph到集羣中,其餘worker只負責處理梯度計算的任務,而between-graph指的是一個集羣中多個worker能夠建立多個graph,但因爲worker運行的代碼相同所以構建的graph也相同,而且參數都保存到相同的ps中保證訓練同一個模型,這樣多個worker均可以構建graph和讀取訓練數據,適合大數據場景。同步訓練和異步訓練差別在於,同步訓練每次更新梯度須要阻塞等待全部worker的結果,而異步訓練不會有阻塞,訓練的效率更高,在大數據和分佈式的場景下通常使用異步訓練。
8. Cloud Machine Learning
前面已經介紹了TensorFlow相關的所有內容,細心的網友可能已經發現,TensorFlow功能強大,但究其本質仍是一個library,用戶除了編寫TensorFlow應用代碼還須要在物理機上起服務,而且手動指定訓練數據和模型文件的目錄,維護成本比較大,並且機器之間不可共享。
縱觀大數據處理和資源調度行業,Hadoop生態儼然成爲了業界的標準,經過MapReduce或Spark接口來處理數據,用戶經過API提交任務後由Yarn進行統一的資源分配和調度,不只讓分佈式計算成爲可能,也經過資源共享和統一調度平的臺極大地提升了服務器的利用率。很遺憾TensorFlow定義是深度學習框架,並不包含集羣資源管理等功能,但開源TensorFlow之後,Google很快公佈了Google Cloud ML服務,咱們從Alpha版本開始已是Cloud ML的早期用戶,深深體會到雲端訓練深度學習的便利性。經過Google Cloud ML服務,咱們能夠把TensorFlow應用代碼直接提交到雲端運行,甚至能夠把訓練好的模型直接部署在雲上,經過API就能夠直接訪問,也得益於TensorFlow良好的設計,咱們基於Kubernetes和TensorFlow serving實現了Cloud Machine Learning服務,架構設計和使用接口都與Google Cloud ML相似。
TensorFlow是很好深度學習框架,對於我的開發者、科研人員已經企業都是值得投資的技術方向,而Cloud Machine Learning能夠解決用戶在環境初始化、訓練任務管理以及神經網絡模型的在線服務上的管理和調度問題。目前Google Cloud ML已經支持automatically hyperparameter tunning,參數調優將來也將成爲計算問題而不是技術問題,即便有的開發者使用MXNet或者其餘,而不是TensorFlow,咱們也願意與更多深度學習用戶和平臺開發者交流,促進社區的發展。
最後總結
總結一下,本文主要介紹TensorFlow深度學習框架的學習與應用,經過deep_recommend_system項目介紹了下面使用TensorFlow的8個核心要點,也歡迎你們下載源碼試用和反饋。
1. 準備訓練數據
2. 接受命令行參數
3. 定義神經網絡模型
4. 使用不一樣的優化算法
5. Online learning與Continuous learning
6. 使用TensorBoard優化參數
7. 分佈式TensorFlow應用
8. Cloud Machine Learning
我是TensorFlow和Kubernetes項目的開發者,seagull和deep_recommend_system項目的做者,郵箱是tobeg3oogle@gmail.com,歡迎與深度學習用戶和愛好者交流與學習。