Apache Ignite上的TensorFlow

任何深度學習都是從數據開始的,這是關鍵點。沒有數據,就沒法訓練模型,也沒法評估模型質量,更沒法作出預測,所以,數據源很是重要。在作研究、構建新的神經網絡架構、以及作實驗時,會習慣於使用最簡單的本地數據源,一般是不一樣格式的文件,這種方法確實很是有效。但有時須要更加接近於生產環境,那麼簡化和加速生產數據的反饋,以及可以處理大數據就變得很是重要,這時就須要Apache Ignite大展身手了。html

Apache Ignite是之內存爲中心的分佈式數據庫、緩存,也是事務性、分析性和流式負載的處理平臺,能夠實現PB級的內存級速度。藉助Ignite和TensorFlow之間的現有集成,能夠將Ignite用做神經網絡訓練和推理的數據源,也能夠將其用做分佈式訓練的檢查點存儲和集羣管理器。java

分佈式內存數據源

做爲之內存爲中心的分佈式數據庫,Ignite能夠提供快速數據訪問,擺脫硬盤的限制,在分佈式集羣中存儲和處理須要的全部數據,能夠經過使用Ignite Dataset來利用Ignite的這些優點。node

注意Ignite不僅是數據庫或數據倉庫與TensorFlow之間ETL管道中的一個步驟,它仍是一個HTAP(混合事務/分析處理)系統。經過選擇Ignite和TensorFlow,能夠得到一個可以處理事務和分析的單一系統,同時還能夠得到將操做型和歷史型數據用於神經網絡訓練和推理的能力。python

下面的測試結果代表,Ignite很是適合用於單節點數據存儲場景。若是存儲和客戶端位於同一節點,則經過使用Ignite,能夠實現每秒超過850MB的吞吐量,若是存儲位於與客戶端相關的遠程節點,則吞吐量約爲每秒800MB。git

當存在一個本地Ignite節點時Ignite Dataset的吞吐量。執行該基準測試時使用的是2個Xeon E5–2609 v4 1.7GHz處理器,配備 16GB內存和每秒10Gb的網絡(1MB的行和20MB 的頁面大小)github

另外一個測試顯示Ignite Dataset如何與分佈式Ignite集羣協做。這是Ignite做爲HTAP系統的默認用例,它可以在每秒10Gb的網絡集羣上爲單個客戶端實現每秒超過1GB的讀取吞吐量。sql

分佈式Ignite集羣具有不一樣數量的節點(從1到9)時Ignite Dataset的吞吐量。執行該測試時使用的是2個Xeon E5–2609 v4 1.7GHz處理器,配備16GB內存和每秒10Gb的網絡(1MB的行和20MB的頁面大小)docker

測試後的用例以下:Ignite緩存(以及第一組測試中數量不一樣的分區和第二組測試中的2048個分區)由10000個大小爲1MB的行填充,而後TensorFlow客戶端使用Ignite Dataset讀取全部數據。全部節點均爲2個Xeon E5–2609 v4 1.7GHz處理器,配備16GB內存和每秒10Gb的網絡鏈接,每一個節點都使用默認配置運行Ignite。數據庫

能夠很輕鬆地將Ignite同時用做支持SQL接口的傳統數據庫和TensorFlow數據源。apache

apache-ignite/bin/ignite.sh
apache-ignite/bin/sqlline.sh -u "jdbc:ignite:thin://localhost:10800/"
CREATE TABLE KITTEN_CACHE (ID LONG PRIMARY KEY, NAME VARCHAR);
INSERT INTO KITTEN_CACHE VALUES (1, 'WARM KITTY');
INSERT INTO KITTEN_CACHE VALUES (2, 'SOFT KITTY');
INSERT INTO KITTEN_CACHE VALUES (3, 'LITTLE BALL OF FUR');
import tensorflow as tf
from tensorflow.contrib.ignite import IgniteDataset
tf.enable_eager_execution()

dataset = IgniteDataset(cache_name="SQL_PUBLIC_KITTEN_CACHE")

for element in dataset:
 print(element)
{'key': 1, 'val': {'NAME': b'WARM KITTY'}}
{'key': 2, 'val': {'NAME': b'SOFT KITTY'}}
{'key': 3, 'val': {'NAME': b'LITTLE BALL OF FUR'}}

結構化對象

使用Ignite能夠存儲任何類型的對象,這些對象能夠具有任何層次結構。Ignite Dataset有處理此類對象的能力。

import tensorflow as tf
from tensorflow.contrib.ignite import IgniteDataset
tf.enable_eager_execution()

dataset = IgniteDataset(cache_name="IMAGES")

for element in dataset.take(1):
 print(element)
{
   'key': 'kitten.png',
   'val': {
       'metadata': {
           'file_name': b'kitten.png',
           'label': b'little ball of fur',
           width: 800,
           height: 600
       },
       'pixels': [0, 0, 0, 0, ..., 0]
   }
}

若是使用Ignite Dataset,則神經網絡訓練和其它計算所需的轉換均可以做爲tf.data管道的一部分來完成。

import tensorflow as tf
from tensorflow.contrib.ignite import IgniteDataset
tf.enable_eager_execution()

dataset = IgniteDataset(cache_name="IMAGES").map(lambda obj: obj['val']['pixels'])

for element in dataset:
 print(element)
[0, 0, 0, 0, ..., 0]

分佈式訓練

做爲機器學習框架,TensorFlow能夠爲分佈式神經網絡訓練、推理及其它計算提供原生支持。分佈式神經網絡訓練的主要理念是可以在每一個數據分區(基於水平分區)上計算損失函數的梯度(例如偏差的平方),而後對梯度求和,以得出整個數據集的損失函數梯度。藉助這種能力,能夠在數據所在的節點上計算梯度,減小梯度,最後更新模型參數。這樣就無需在節點間傳輸數據,從而避免了網絡瓶頸。

Ignite在分佈式集羣中使用水平分區存儲數據。在建立Ignite緩存(或基於SQL的表)時,能夠指定將要在此對數據進行分區的分區數量。例如,若是一個Ignite集羣由100臺機器組成,而後建立了一個有1000個分區的緩存,則每臺機器將要維護10個數據分區。

Ignite Dataset能夠利用分佈式神經網絡訓練(使用TensorFlow)和Ignite分區二者的能力。Ignite Dataset是一個能夠在遠程工做節點上執行的計算圖操做。遠程工做節點能夠經過爲工做節點進程設置相應的環境變量(例如IGNITE_DATASET_HOSTIGNITE_DATASET_PORTIGNITE_DATASET_PART)來替換Ignite Dataset的參數(例如主機、端口或分區)。使用這種替換方法,能夠爲每一個工做節點分配一個特定分區,以使一個工做節點只處理一個分區,同時能夠與單個數據集透明協做。

import tensorflow as tf
from tensorflow.contrib.ignite import IgniteDataset

dataset = IgniteDataset("IMAGES")

# Compute gradients locally on every worker node.
gradients = []
for i in range(5):
 with tf.device("/job:WORKER/task:%d" % i):
   device_iterator = tf.compat.v1.data.make_one_shot_iterator(dataset)
   device_next_obj = device_iterator.get_next()
   gradient = compute_gradient(device_next_obj)
   gradients.append(gradient)

# Aggregate them on master node.
result_gradient = tf.reduce_sum(gradients)

with tf.Session("grpc://localhost:10000") as sess:
 print(sess.run(result_gradient))

藉助Ignite,還可使用TensorFlow的高級Estimator API來進行分佈式訓練。此功能以所謂的TensorFlow分佈式訓練的獨立客戶端模式爲基礎,Ignite在其中發揮數據源和集羣管理器的做用。

檢查點存儲

除數據庫功能外,Ignite還有一個名爲IGFS的分佈式文件系統。IGFS 能夠提供與Hadoop HDFS相似的功能,但僅限於內存。事實上除了自有API外,IGFS還實現了Hadoop的FileSystem API,能夠透明地部署到Hadoop或Spark環境中。Ignite上的TensorFlow支持IGFS與TensorFlow集成,該集成基於TensorFlow端的自定義文件系統插件和Ignite端的IGFS原生API,它有許多使用場景,好比:

  • 能夠將狀態檢查點保存到IGFS中,以得到可靠性和容錯性;
  • 訓練過程能夠經過將事件文件寫入TensorBoard監視的目錄來與TensorBoard通訊。即便TensorBoard在不一樣的進程或機器中運行,IGFS也能夠正常運行。

TensorFlow在1.13版本中發佈了此功能,並將在TensorFlow 2.0中做爲tensorflow/io的一部分發布。

SSL鏈接

經過Ignite,可使用SSL和認證機制來保護數據傳輸通道。Ignite Dataset同時支持有認證和無認證的SSL鏈接,具體信息請參見Ignite的SSL/TLS文檔。

import tensorflow as tf
from tensorflow.contrib.ignite import IgniteDataset
tf.enable_eager_execution()

dataset = IgniteDataset(cache_name="IMAGES",
                       certfile="client.pem",
                       cert_password="password",
                       username="ignite",
                       password="ignite")

Windows支持

Ignite Dataset徹底兼容Windows系統,能夠在Windows和Linux/MacOS系統上將其用做TensorFlow的一部分。

試用

下面的示例很是有助於入門。

Ignite Dataset

要試用Ignite Dataset,最簡單的方法是運行裝有Ignite和加載好的MNIST數據的Docker容器,而後使用Ignite Dataset與其交互。能夠在Docker Hub:dmitrievanthony/ignite-with-mnist上找到此容器,而後執行以下命令啓動容器:

docker run -it -p 10800:10800 dmitrievanthony/ignite-with-mnist

而後能夠按照以下方法進行使用:

IGFS

TensorFlow的IGFS支持於TensorFlow 1.13中發佈,並將在TensorFlow 2.0中做爲tensorflow/io的一部分發布。如要經過TensorFlow試用IGFS,最簡單的方法是運行一個裝有Ignite和IGFS的Docker容器,而後使用TensorFlow的tf.gfile與之交互。能夠在Docker Hub:dmitrievanthony/ignite-with-igfs上找到此容器,而後執行以下命令啓動容器:

docker run -it -p 10500:10500 dmitrievanthony/ignite-with-igfs

而後能夠按照以下方法進行使用:

import tensorflow as tf
import tensorflow.contrib.ignite.python.ops.igfs_ops

with tf.gfile.Open("igfs:///hello.txt", mode='w') as w:
 w.write("Hello, world!")

with tf.gfile.Open("igfs:///hello.txt", mode='r') as r:
 print(r.read())
Hello, world!

限制

目前,Ignite Dataset要求緩存中的全部對象都具備相同的結構(同類型對象),而且緩存中至少包含一個檢索模式所需的對象。另外一個限制與結構化對象有關,Ignite Dataset不支持UUID、Map和多是對象結構組成部分的對象數組。

即將發佈的TensorFlow 2.0

TensorFlow 2.0中會將此功能拆分到tensorflow/io模塊,這樣會更靈活。這些示例將略有改動,後續的文檔和示例都會更新。

相關文章
相關標籤/搜索