【PaddlePaddle】data()使用及分析

【PaddlePaddle】data()分析及使用

官方文檔

本文爲作者對官方文檔的解讀+自己在平時開發練習中的一些總結,但總得一切以官方爲準

背景&簡介

深度學習中第一大問題就是用於計算模型的數據量實在是過於龐大,且類型複雜。如果只用一般的列表、數組、向量這樣的數據結構進行計算的話,肯定是不行的。因此在深度學習中,主流的學習框架一般用Tensor(張量)來表示數據,這是一個不定維度的多維數組。
在Paddlepaddle中,Tensor類型被返回爲類型名爲Variable的變量。一般來說,二者是一個概念
data()方法就是用於創建tensor(variable)的方法。
data()方法在PaddlePaddle下有兩處接口,在開發中基本用法一致。

layers

先看下layers下的data()

paddle.fluid.layers.data(name, shape, append_batch_size=True, dtype='float32', lod_level=0, type=VarType.LOD_TENSOR, stop_gradient=True)

(一直不知道爲什麼Python的許多庫不可以像Java一樣在IDE中查看UML圖)
data是layers類中的一個成員方法,主要作用是構建一個類型爲Variable的算子,該算子在計算圖中是一個全局變量。
但同時,請注意官方文檔中有如下說明:
不推薦使用 paddle.fluid.layers.data ,因其在之後的版本中會被刪除。請使用 paddle.fluid.data 。
paddle.fluid.layers.data 在組網期間會設置創建的變量維度(shape)和數據類型(dtype),但不會檢查輸入數據的維度和數據類型是否符合要求。 paddle.fluid.data 會在運行過程中由Executor/ParallelExecutor檢查輸入數據的維度。

也就是說,在layers類中的data()方法可能存在一定的安全隱患,因此不推薦從這裏引用

參數解釋

  • name (str)- 被創建的變量的名字 。
  • shape (list)- 聲明維度信息的list。如果 append_batch_size 爲True且內部沒有維度值爲-1,則應將其視爲每個樣本的形狀。 否則,應將其視爲batch數據的形狀。
  • append_batch_size (bool)
    • 1.如果爲True,則在維度(shape)的開頭插入-1。 例如,如果shape=[1],則輸出shape爲[-1,1]。可用於設置運行期間不同batch大小。
    • 2.如果維度(shape)包含-1,比如shape=[-1,1]。 append_batch_size會強制變爲爲False(表示無效),因爲PaddlePaddle不能在shape上設置一個以上的未知數。
  • dtype (np.dtype|VarType|str)- 數據類型,支持bool,float16,float32,float64,int8,int16,int32,int64,uint8(機器學習中一般用float32)。
  • type (VarType)- 輸出類型,支持VarType.LOD_TENSOR,VarType.SELECTED_ROWS,VarType.NCCL_ID。默認爲VarType.LOD_TENSOR。
  • lod_level (int)- LoD層。0表示輸入數據不是一個序列。默認值爲0。
  • stop_gradient (bool)- 提示是否應該停止計算梯度,默認值爲True。
  • 返回:全局變量,可進行數據訪問
  • 返回類型:Variable(Tensor張量)

再看下fluid下的data()

fluid

作用和layers下的一致,在參數設定上稍有不同

  • name (str)- 被創建的變量的名字,具體用法請參見 Name 。
  • shape (list|tuple)- 聲明維度信息的list或tuple。
  • dtype (np.dtype|VarType|str,可選)- 數據類型,支持bool,float16,float32,float64,int8,int16,int32,int64,uint8。默認值爲float32。
  • lod_level (int,可選)- LoDTensor變量的LoD level數,LoD level是PaddlePaddle的高級特性,一般任務中不會需要更改此默認值,關於LoD level的詳細適用場景和用法請見 LoDTensor 。默認值爲0。

示例

在此需要補充的是,只有新版本的Paddlepaddle才能在fulid下直接使用data()方法,筆者的電腦中paddlepaddle版本爲1.5.1,有點低了,因此就存在這一問題

import paddle.fluid as fluid
data = fluid.layers.data(name='test', shape=[5], dtype='float32')
print(type(data)) #<class 'paddle.fluid.framework.Variable'>

再如

# 用data作算子做一個簡單的損失函數計算
import paddle.fluid as fluid
x = fluid.layers.data(name='x', shape=[1, 3, 5, 7, 9], dtype='float32')
x_predict = fluid.layers.data(name='x_predict', shape=[2, 4, 6, 7, 8])
result = fluid.layers.square_error_cost(x,x_predict)
print(result) # 輸出的是維度信息

輸出

name: "square_error_cost_0.tmp_1"
type {
  type: LOD_TENSOR
  lod_tensor {
    tensor {
      data_type: FP32
      dims: -1
      dims: 1
      dims: 3
      dims: 5
      dims: 7
      dims: 9
    }
    lod_level: 0
  }
}
persistable: false

<class 'paddle.fluid.framework.Variable'>

補充:對Tensor賦值

那麼有一個問題來了:我作好了對Tensor(Variable)的定義,那麼我該怎麼進行賦值呢?
Paddlepaddle官方曾解答過這一問題
“Fluid中,爲Variable賦值的方法如下,主要邏輯就fluid.global_scope().find_var()找到模型結構中對應節點,然後通過get_tensor()方法獲得對應的tensor對象,接着就可以使用set()方法對其進行賦值。”
fluid.global_scope()本身作用是獲取類型爲Scope的全局/默認作用域實例。
find_val()起到找對應節點的作用。
例如下面的代碼段:

import paddle.fluid as fluid
import numpy as np
List_1 = [1, 5, 9, 13, 17]
arr = np.array(List_1, dtype='int')
fluid.global_scope().var("data").get_tensor().set(arr, fluid.CPUPlace())
data = np.array(fluid.global_scope().find_var("data").get_tensor())
print(data)# [ 1  5  9 13 17]

最終返回了ndarray類型的一個向量

總結

深度學習中最常用的數據結構是Tensor,在paddlepaddle中也叫Variable,用data()方法來初始化這一算子的各種屬性。
對於Tensor的賦值要先在數組中找對應節點,再用get_tensor()將其轉化爲張量。
另外,一切以官方文檔及版本更新爲主

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章