問題背景:當(dāng)數(shù)據(jù)科學(xué)從業(yè)者在線下通過TensorFlow/Keras將神經(jīng)網(wǎng)絡(luò)模型訓(xùn)練出來之后,因?yàn)榫€上使用Java進(jìn)行工程實(shí)現(xiàn)而與模型無法良好對接预烙,導(dǎo)致形成了工程和策略之間的gap坞淮。
本文主要探討嘗試了幾種可能的解決方案以及相對應(yīng)的結(jié)果和優(yōu)缺點(diǎn)茴晋。
結(jié)論優(yōu)先
- Java分布式方案:筆者嘗試的方式中,暫時沒有能有效對接TensorFlow/Keras模型和線上分布式Java Based Spark(下文中均用JBS替代)的交互模式回窘。(如有可行方式诺擅,歡迎在留言中探討)
- Python/Java分布式方案:JBS處理的中間數(shù)據(jù)通過HDFS和Pyspark/Java對接處理,通過TensorflowOnSpark/Java Tensorflow將Tensorflow模型分布式部署到集群節(jié)點(diǎn)中進(jìn)行工程化預(yù)測啡直。
- Java單節(jié)點(diǎn)方案:JBS處理的中間數(shù)據(jù)通過在單節(jié)點(diǎn)GPU上烁涌,通過Java Based Tensorflow對數(shù)據(jù)進(jìn)行處理之后返回JBS分布式處理。
- Java分布式(手動)方案:將Java Based Tensorflow手動部署到集群節(jié)點(diǎn)付枫,JBS通過調(diào)用集群節(jié)點(diǎn)程序方式通過模型預(yù)測實(shí)現(xiàn)分布式烹玉。
Java分布式方案嘗試經(jīng)驗(yàn)
1. 采用PMML文件對接策略模型和線上工程:
-
Keras:
- 方式:通過keras2pmml項(xiàng)目對keras模型轉(zhuǎn)換到pmml文件格式,然后跟java對接阐滩。
- 問題:該項(xiàng)目已經(jīng)很久沒人維護(hù)升級二打,版本停留在0.1.主要能支持一些DNN結(jié)構(gòu)模型,對RNN和CNN等更復(fù)雜的結(jié)構(gòu)模型無法進(jìn)行正確轉(zhuǎn)換掂榔,需要修改大量源代碼继效。
- 改進(jìn)方案:部分activation類型改進(jìn)方案-如何把神經(jīng)網(wǎng)絡(luò)keras模型轉(zhuǎn)PMML文件?
-
結(jié)論:對復(fù)雜神經(jīng)網(wǎng)絡(luò)模型不可行装获。
-
Tensorflow:
-
方式:采用jpmml-tensorflow項(xiàng)目瑞信,將keras模型轉(zhuǎn)換為tensorflow的savemodel類文件之后,通過github項(xiàng)目代碼進(jìn)行轉(zhuǎn)換為pmml文件穴豫。
-
如何將keras模型轉(zhuǎn)換為savemodel類:
model = keras.models.load_model("model.h5") sess = keras.backend.get_session() builder = tf.saved_model.builder.SavedModelBuilder(saved_model_dir) builder.add_meta_graph_and_variables(sess, ['serve']) builder.save()
-
- 問題:該項(xiàng)目支持的模型種類也只有DNN凡简,并不支持CNN或者RNN等更復(fù)雜的模型逼友。所以中間會報(bào)模型種類無法找到illegal的error。
-
結(jié)論:對復(fù)雜神經(jīng)網(wǎng)絡(luò)模型也不可行秤涩。
-
方式:采用jpmml-tensorflow項(xiàng)目瑞信,將keras模型轉(zhuǎn)換為tensorflow的savemodel類文件之后,通過github項(xiàng)目代碼進(jìn)行轉(zhuǎn)換為pmml文件穴豫。
-
結(jié)論:
- PMML工程方案對于復(fù)雜神經(jīng)網(wǎng)絡(luò)的支持性不完善帜乞,但對于簡單的神經(jīng)網(wǎng)絡(luò)以及其他傳統(tǒng)機(jī)器學(xué)習(xí)模型來說,PMML方式因?yàn)槠渫ㄓ眯钥鹁欤橇己玫乃惴ê凸こ蹄暯拥臉蛄骸?br>
- PMML工程方案對于復(fù)雜神經(jīng)網(wǎng)絡(luò)的支持性不完善帜乞,但對于簡單的神經(jīng)網(wǎng)絡(luò)以及其他傳統(tǒng)機(jī)器學(xué)習(xí)模型來說,PMML方式因?yàn)槠渫ㄓ眯钥鹁欤橇己玫乃惴ê凸こ蹄暯拥臉蛄骸?br>
2. Deeplearning4J方式轉(zhuǎn)換模型應(yīng)用:
-
Keras:
- 方式:采用deeplearning4j的方式黎烈,將模型文件通過deeplearning4j方式導(dǎo)入java,再通過JBS進(jìn)行預(yù)測處理匀谣。
-
問題:
- 項(xiàng)目對Keras 2.0的支持處于beta版本照棋,會對一些神經(jīng)網(wǎng)絡(luò)層出現(xiàn)bug,比如像ELU層會報(bào)錯武翎。所以使用的時候烈炭,或者去除ELU等有問題神經(jīng)網(wǎng)絡(luò)層,或者采用Keras 1.0進(jìn)行構(gòu)建網(wǎng)絡(luò)后频。
- 在進(jìn)行JBS分布式預(yù)測的時候梳庆,出現(xiàn)了一些網(wǎng)絡(luò)結(jié)構(gòu)無法解析的錯誤暖途,猜測可能是因?yàn)樵趕park集群的序列化和反序列化過程中出現(xiàn)了問題卑惜。但deeplearning4j官網(wǎng)架構(gòu)圖顯示其對于Spark的支持,所以不確定是否是使用方式問題導(dǎo)致了分布式出現(xiàn)模型結(jié)構(gòu)解析問題驻售。
-
結(jié)論:在分布式(可能是序列化過程中)結(jié)構(gòu)中露久,deeplearning4j項(xiàng)目還存在一些問題,無法與JBS正常兼容欺栗。
3. Java Based Tensorflow方式應(yīng)用模型:
-
Keras/Tensorflow:
-
步驟一:將keras模型先轉(zhuǎn)換為tensorflow靜態(tài)圖模型文件毫痕,.pb格式或者ckpt格式。(ckpt與pb的異同:Tensorflow學(xué)習(xí)筆記-模型保存與加載)
-
如何將keras模型轉(zhuǎn)換為ckpt文件類型:
model = keras.models.load_model("model.h5") sess = keras.backend.get_session() saver = tf.train.Saver() save_path = saver.save(sess, "/tmp/model.ckpt")
如何將keras模型轉(zhuǎn)換為pb文件類型:
keras模型保存為tensorflow的二進(jìn)制模型
-
步驟二: 然后通過Java Based Tensorflow讀取pb文件迟几,對數(shù)據(jù)進(jìn)行預(yù)測消请。(關(guān)于java如何調(diào)用tensorflow模型例子:TensorFlow-Java-Examples)
-
問題:
- 單機(jī)的情況下,可以采用java來調(diào)用tensorflow类腮。
- 分布式的情況下臊泰,由于tensorflow底層是cpp,所以在序列化打包和反序列的時候會出現(xiàn)問題蚜枢,導(dǎo)致分布式節(jié)點(diǎn)機(jī)器無法正常調(diào)用缸逃。
- 所以只有在單機(jī)情況下才能跟java兼容〕С椋或者分布式采用pyspark中的tensorflowonspark包或者通過預(yù)先在分布式集群節(jié)點(diǎn)中部署本地tensorflow服務(wù)需频,然后java遠(yuǎn)程調(diào)用tensorflow服務(wù)來實(shí)現(xiàn)手動分布式
-
各方案優(yōu)缺點(diǎn):
-
Pyspark/Java分布式:
- 優(yōu)點(diǎn):通過TensorflowOnSpark/Java Tensorflow可以實(shí)現(xiàn)Tensorflow在分布式集群上的工程化部署。
- 缺點(diǎn):與線上JBS交互需要通過HDFS做中間層筷凤,文件IO的效率會影響線上工程服務(wù)的速率昭殉。
-
Java單機(jī):
- 優(yōu)點(diǎn):跟線上Java工程兼容,無需HDFS的IO。
- 缺點(diǎn):需要使用GPU機(jī)器提升單機(jī)預(yù)測效率挪丢,沒有利用分布式集群莽鸭,性價(jià)比相對較低。
-
Java手動分布式:
- 優(yōu)點(diǎn):利用分布式集群資源吃靠,且跟線上工程Java兼容硫眨。
- 缺點(diǎn):手動部署集群效率太低。