国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Tensorflow 代碼解析(三)

worldligang / 2595人閱讀

摘要:所有操作都是節點形式表示的,包括計算節點和非計算節點。采用回合通信機制,類似生產者消費者的消息信箱。解析器將協議內存塊解析為張量,放入隊列中,其中命名和類型要與寫入的一致。目前就職于騰訊事業部,從事神經機器翻譯工作。

4. ?TF – Kernels模塊

TF中包含大量Op算子,這些算子組成Graph的節點集合。這些算子對Tensor實現相應的運算操作。圖 4 1列出了TF中的Op算子的分類和舉例。

圖 4 1 TensorFlow核心庫中的部分運算

4.1 ? OpKernels 簡介

OpKernel類(core/framework/op_kernel.h)是所有Op類的基類。繼承OpKernel還可以自定義新的Op類。用的較多的Op如(MatMul, ?Conv2D, ?SoftMax, ?AvgPooling, Argmax等)。

所有Op包含注冊(Register Op)和實現(正向計算、梯度定義)兩部分。

所有Op類的實現需要overide抽象基函數 void Compute(OpKernelContext* context),實現自身Op功能。用戶可以根據需要自定義新的Op操作,參考[12]。

TF中所有Op操作的屬性定義和描述都在 ops/ops.pbtxt。如下Add操作,定義了輸入參數x、y,輸出參數z。

4.2 UnaryOp & BinaryOp

UnaryOp和BinaryOp定義了簡單的一元操作和二元操作,類定義在/core/kernels/ cwise_ops.h文件,類實現在/core/kernels/cwise_op_*.cc類型的文件中,如cwise_op_sin.cc文件。

一元操作全稱為Coefficient-wise unary operations,一元運算有abs, sqrt, exp, sin, cos,conj(共軛)等。如abs的基本定義:

二元操作全稱為Coefficient-wise binary operations,二元運算有add,sub, div, mul,mod等。如sum的基本定義:

4.3 MatMul

4.3.1 Python相關部分

在Python腳本中定義matmul運算:

根據Ops名稱MatMul從Ops庫中找出對應Ops類型

創建ops節點

創建ops節點并指定相關屬性和設備分配

4.3.2 C++相關部分

Python腳本通過swig調用進入C接口API文件core/client/tensor_c_api.cc,調用TF_NewNode函數生成節點,同時還需要指定輸入變量,TF_AddInput函數設置first輸入變量,TF_AddInputList函數設置other輸入變量。這里op_type為MatMul,first輸入變量為a,other輸入變量為b。

創建節點根據節點類型從注冊的Ops工廠中生成,即TF通過工廠模式把一系列Ops注冊到Ops工廠中。其中MatMul的注冊函數為如下

4.3.3 MatMul正向計算

MatMul的實現部分在core/kernels/matmul_op.cc文件中,類MatMulOp繼承于OpKernel,成員函數Compute完成計算操作。

MatMul的測試用例core/kernels/matmul_op_test.cc文件,要調試這個測試用例,可通過如下方式:

在TF中MatMul實現了CPU和GPU兩個版本,其中CPU版本使用Eigen庫,GPU版本使用cuBLAS庫。

CPU版的MatMul使用Eigen庫,調用方式如下:

簡而言之就是調用eigen的constract函數。

GPU版的MatMul使用cuBLAS庫,準確而言是基于cuBLAS的stream_executor庫。Stream executor是google開發的開源并行計算庫,調用方式如下:

其中stream類似于設備句柄,可以調用stream executor中的cuda模塊完成運算。

4.3.4 MatMul梯度計算

MatMul的梯度計算本質上也是一種kernel ops,描述為MatMulGrad。MatMulgrad操作是定義在grad_ops工廠中,類似于ops工廠。定義方式如下:

MatmulGrad由FDH(Function Define Helper)完成定義,

其中attr_adj_x="transpose_a" ax0=false, ax1=true, attr_adj_y= "transpose_b", ay0=true, ay1=false, *g屬于FunctionDef類,包含MatMul的梯度定義。

從FDH定義中可以看出MatMulGrad本質上還是MatMul操作。在矩陣求導運算中:

MatMulGrad的測試用例core/ops/math_grad_test.cc文件,要調試這個測試用例,可通過如下方式:

4.4 Conv2d

關于conv2d的python調用部分和C++創建部分可參考MatMul中的描述。

4.4.1 Conv2d正向計算部分

TF中conv2d接口如下所示,簡單易用:

實現部分在core/kernels/conv_ops.cc文件中,類Conv2DOp繼承于抽象基類OpKernel。

Conv2DOp的測試用例core/kernels/eigen_spatial_convolutions_test.cc文件,要調試這個測試用例,可通過如下方式:

Conv2DOp的成員函數Compute完成計算操作。

為方便描述,假設tf.nn.conv2d中input參數的shape為[batch, in_rows, in_cols, in_depth],filter參數的shape為[filter_rows, filter_cols, in_depth, out_depth]。

首先,計算卷積運算后輸出tensor的shape。

? ?若padding=VALID,output_size = (input_size - filter_size + stride) / stride;

? ?若padding=SAME,output_size = (input_size + stride - 1) / stride;

其次,根據計算結果給輸出tensor分配內存。

然后,開始卷積計算。Conv2DOp實現了CPU和GPU兩種模式下的卷積運算。同時,還需要注意input tensor的輸入格式,通常有NHWC和NCHW兩種格式。在TF中,Conv2d-CPU模式下目前僅支持NHWC格式,即[Number, Height, Weight, Channel]格式。Conv2d-GPU模式下以NCHW為主,但支持將NHWC轉換為NCHW求解。C++中多維數組是row-major順序存儲的,而Eigen默認是col-major順序的,則C++中[N, H, W, C]相當于Eigen中的[C, W, H, N],即dimention order是相反的,需要特別注意。

Conv2d-CPU模式下調用Eigen庫函數。

Eigen庫中卷積函數的詳細代碼參見圖 4 2。

圖 4 2 Eigen卷積運算的定義

? ?Tensor:: extract_image_patches () 為卷積或池化操作抽取與kernel size一致的image patches。該函數的定義在eigen3/unsupported/Eigen/CXX11/src/Tensor/ TensorBase.h中,參考該目錄下ReadME.md。

? ?Tensor:: extract_image_patches () 的輸出與input tensor的data layout有關。設input tensor為ColMajor格式[NHWC],則image patches輸出為[batch, filter_index, filter_rows, filter_cols, in_depth],并reshape為[batch * filter_index, filter_rows * filter_cols * in_depth],而kernels維度為[filter_rows * filter_cols * in_depth, out_depth],然后kernels矩陣乘image patches得到輸出矩陣[batch * filter_index, out_depth],并reshape為[batch, out_rows, out_cols, out_depth]。

Conv2d-GPU模式下調用基于cuDNN的stream_executor庫。若input tensor為NHWC格式的,則先轉換為NCHW格式

調用cudnn庫實現卷積運算:

計算完成后再轉換成HHWC格式的

4.4.2 Conv2d梯度計算部分

Conv2D梯度計算公式,假設output=Conv2d(input, filter),則

Conv2D梯度計算的測試用例core/kernels/eigen_backward_spatial_convolutions_test.cc文件,要調試這個測試用例,可通過如下方式:

Conv2d的梯度計算函數描述為Conv2DGrad。Conv2DGrad操作定義在grad_ops工廠中。注冊方式如下:

Conv2DGrad由FDH(Function Define Helper)完成定義,參見圖 4 3。

圖 4 3 Conv2DGrad的函數定義

Conv2DGrad梯度函數定義中依賴Conv2DBackpropInput和Conv2DBackpropFilter兩種Ops,二者均定義在kernels/conv_grad_ops.cc文件中。

Conv2DBackpropInputOp和Conv2DBackpropFilterOp的實現分為GPU和CPU版本。

Conv2D運算的GPU版實現定義在類Conv2DSlowBackpropInputOp和類Conv2DSlowBackprop FilterOp 中。

Conv2D運算的CPU版有兩種實現形式,分別為custom模式和fast模式。Custom模式基于賈揚清在caffe中的思路實現,相關類是Conv2DCustomBackpropInputOp和Conv2DCustomBackpropFilterOp。Fast模式基于Eigen計算庫,由于在GPU下會出現nvcc編譯超時,目前僅適用于CPU環境,相關類是Conv2DFastBackpropInputOp和Conv2DFastBackpropFilterOp

根據Conv2DGrad的函數定義,從代碼分析Conv2D-GPU版的實現代碼,即分析Conv2DBackpropInput和Conv2DBackpropFilter的實現方式。

Conv2DSlowBackpropInputOp的成員函數Compute完成計算操作。

Compute實現部分調用stream executor的相關函數,需要先獲取庫的stream句柄,再調用卷積梯度函數。

stream executor在卷積梯度運算部分仍然是借助cudnn庫實現的。

4.4.3 MaxPooling計算部分

在很多圖像分類和識別問題中都用到了池化運算,池化操作主要有較大池化(max pooling)和均值池化(avg pooling),本章節主要介紹較大池化的實現方法。調用TF接口可以很容易實現池化操作。

Eigen庫中較大池化的詳細描述如下:

其中較大池化運算主要分為兩步,第一步中extract_image_patch為池化操作抽取與kernel size一致的image patches,第二步計算每個image patch的較大值。

4.5 SendOp & RecvOp

TF所有操作都是節點形式表示的,包括計算節點和非計算節點。在跨設備通信中,發送節點(SendOp)和接收節點(RecvOp)為不同設備的兩個相鄰節點完成完成數據通信操作。Send和Recv通過TCP或RDMA來傳輸數據。

TF采用Rendezvous(回合)通信機制,Rendezvous類似生產者/消費者的消息信箱。引用TF描述如下:

TF的消息傳遞屬于采用“發送不阻塞/接收阻塞”機制,實現場景有LocalRendezvous

(本地消息傳遞)、RpcRemoteRendezvous (分布式消息傳遞)。除此之外還有IntraProcessRendezvous用于本地不同設備間通信。

TF會在不同設備的兩個相鄰節點之間添加Send和Recv節點,通過Send和Recv之間進行通信來達到op之間通信的效果,如圖 4 4右子圖所示。圖中還涉及到一個優化問題,即a->b和a->c需要建立兩組send/recv連接的,但兩組連接是可以共用的,所以合并成一組連接。

圖 4 4 Graph跨設備通信

Send和Recv分別對應OpKernel中的SendOp和RecvOp兩個類(kernels/sendrecv_ops.h)。

SendOp的計算函數。

SendOp作為發送方需要先獲取封裝ctx消息,然后借助Rendezvous模塊發送給接收方。

RecvOp的計算函數如下。

RecvOp作為接收方借助Rendezvous模塊獲取ctx消息。

其中parsed變量是類ParsedKey的實例。圖 5?5是Rendezvous封裝的ParsedKey消息實體示例。

4.6 ReaderOp & QueueOp

4.6.1 TF數據讀取

TF系統定義了三種數據讀取方式[13]:

? ?供給數據(Feeding): 在TensorFlow程序運行的每一步, 通過feed_dict來供給數據。

? ?從文件讀取數據: 在TensorFlow圖的起始, 讓一個輸入管線(piplines)從文件中讀取數據放入隊列,通過QueueRunner供給數據,其中隊列可以實現多線程異步計算。

? ?預加載數據: 在TensorFlow圖中定義常量或變量來保存所有數據,如Mnist數據集(僅適用于數據量比較小的情況)。

除了以上三種數據讀取方式外,TF還支持用戶自定義數據讀取方式,即繼承ReaderOpKernel類創建新的輸入讀取類[14]。本章節主要講述通過piplines方式讀取數據的方法。

Piplines利用隊列實現異步計算

從piplines讀取數據也有兩種方式:一種是讀取所有樣本文件路徑名轉換成string tensor,使用input_producer將tensor亂序(shuffle)或slice(切片)處理放入隊列中;另一種是將數據轉化為TF標準輸入格式,即使用TFRecordWriter將樣本數據寫入tfrecords文件中,再使用TFRecordReader將tfrecords文件讀取到隊列中。

圖 4 6描述了piplines讀取數據的第一種方式,這些流程通過節點和邊串聯起來,成為graph數據流的一部分。

從左向右, 第一步 是載入文件列表,使用convert_to_tensor函數將文件列表轉化為tensor,如cifar10數據集中的image_files_tensor和label_tensor。

第二步是使用input_producer將image_files_tensor和label_tensor放入圖中的文件隊列中,這里的input_producer作用就是將樣本放入隊列節點中,有string_input_producer、range_input_producer和slice_input_producer三種,其中slice_input_producer的切片功能支持亂序,其他兩種需要借助tf.train.shuffle_batch函數作亂序處理,有關三種方式的具體描述可參考tensorflow/python/training/input.py注釋說明。

第三步是使用tf.read_file()讀取隊列中的文件數據到內存中,使用解碼器如tf.image.decode_jpeg()解碼成[height, width, channels]格式的數據。

最后就是使用batch函數將樣本數據處理成一批批的樣本,然后使用session執行訓練。

圖 4 6 使用piplines讀取數據

4.6.2 TFRecords使用

TFRecords是TF支持的標準文件格式,這種格式允許將任意的數據轉換為TFRecords支持的文件格式。TFRecords方法需要兩步:第一步是使用TFRecordWriter將樣本數據寫入tfrecords文件中,第二步是使用TFRecordReader將tfrecords文件讀取到隊列中。

圖 4 7是TFRecords文件寫入的簡單示例。tf.train.Example將數據填入到Example協議內存塊(protocol buffer),將協議內存塊序列化為一個字符串,通過TFRecordWriter寫入到TFRecords文件,圖中定義了label和image_raw兩個feature。Example協議內存塊的定義請參考文件core/example/example.proto。

圖 4 7 TFRecordWriter寫入數據示例

圖 4 8是TFRecords文件讀取的簡單示例。tf.parse_single_example解析器將Example協議內存塊解析為張量,放入example隊列中,其中features命名和類型要與Example寫入的一致。

圖 4 8 TFRecrodReader讀取數據示例

4.6.3 ReaderOps分析

ReaderOpsKernel類封裝了數據讀取的入口函數Compute,通過繼承ReaderOpsKernel類可實現各種自定義的數據讀取方法。圖 4 9是ReaderOp相關的UML視圖。

圖 4 9 ReaderOp相關的UML視圖

ReaderOpKernel子類必須重新定義成員函數SetReaderFactory實現對應的數據讀取邏輯。TFRecordReaderOp的讀取方法定義在TFRecordReader類中。

其中offset的計算方式。

作者簡介:

姚健,畢業于中科院計算所網絡數據實驗室,畢業后就職于360天眼實驗室,主要從事深度學習和增強學習相關研究工作。目前就職于騰訊MIG事業部,從事神經機器翻譯工作。聯系方式: yao_62995@163.com

歡迎加入本站公開興趣群

商業智能與數據分析群

興趣范圍包括各種讓數據產生價值的辦法,實際應用案例分享與討論,分析工具,ETL工具,數據倉庫,數據挖掘工具,報表系統等全方位知識

QQ群:81035754

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/4498.html

相關文章

  • Tensorflow代碼解析(二)

    摘要:為了進一步了解的邏輯,圖對和進行了展開分析。另外,在命名空間中還隱式聲明了控制依賴操作,這在章節控制流中相關說明。簡述是高效易用的開源庫,有效支持線性代數,矩陣和矢量運算,數值分析及其相關的算法。返回其中一塊給用戶,并將該內存塊標識為占用。 3. TF 代碼分析初步3.1 TF總體概述為了對TF有整體描述,本章節將選取TF白皮書[1]中的示例展開說明,如圖 3 1所示是一個簡單線性模型的TF...

    zhigoo 評論0 收藏0
  • TensorFlow學習筆記(10):讀取文件

    摘要:簡介讀取數據共有三種方法當運行每步計算的時候,從獲取數據。數據直接預加載到的中,再把傳入運行。在中定義好文件讀取的運算節點,把傳入運行時,執行讀取文件的運算,這樣可以避免在和執行環境之間反復傳遞數據。本文講解的代碼。 簡介 TensorFlow讀取數據共有三種方法: Feeding:當TensorFlow運行每步計算的時候,從Python獲取數據。在Graph的設計階段,用place...

    Neilyo 評論0 收藏0
  • TensorFlow 刪除 YAML 支持,建議 JSON 作為替補方案!

    摘要:據公告稱,和的包裝庫使用了不安全的函數來反序列化編碼的機器學習模型。簡單來看,序列化將對象轉換為字節流。據悉,本次漏洞影響與版本,的到版本均受影響。作為解決方案,在宣布棄用之后,團隊建議開發者以替代序列化,或使用序列化作為替代。 ...

    BlackFlagBin 評論0 收藏0
  • 以靜制動的TensorFlow Fold動態計算圖介紹

    摘要:近日它們交鋒的戰場就是動態計算圖,誰能在這場戰爭中取得優勢,誰就把握住了未來用戶的流向。所以動態框架對虛擬計算圖的構建速度有較高的要求。動態計算圖問題之一的多結構輸入問題的高效計 隨著深度學習的發展,深度學習框架之間競爭也日益激烈,新老框架紛紛各顯神通,想要在廣大DeepLearner的服務器上占據一席之地。近日它們交鋒的戰場就是動態計算圖,誰能在這場戰爭中取得優勢,誰就把握住了未來用戶的流...

    waltr 評論0 收藏0

發表評論

0條評論

worldligang

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<