1. 程式人生 > >新人上手TensorFlow之TensorFlow基本概念

新人上手TensorFlow之TensorFlow基本概念

TensorFlow是Google Brain的第二代機器學習系統,2015年11月9日,作為開源軟體釋出。TensorFlow的計算用有狀態的資料流圖表示。這個庫的演算法源於Google需要指導稱為神經網路的計算機系統,類似人類學習和推理的方法,以便派生出新的應用程式承擔以前僅人類能勝任的角色和職能;TensorFlow的名字來源於這類神經網路對多維陣列執行的操作。這些多維陣列被稱為“張量(Tensor)”,但這個概念並不等同於數學概念中的‘張量’。
上面這段話摘自TensorFlow的維基百科的介紹。其中提到了TensorFlow的幾個重要的概念:Graph,Tensor。本文著重就TensorFlow中的幾個概念進行探討,主要有:
Graph、Tensor、Session 以及Variable、 constant、placeholder等概念。

1 Tensor及Tensor類

1.1 Tensor

Tensor 是TensorFlow 中的核心資料單元,可以簡單的理解為 * 多維陣列 *。 Tensor根據陣列的維度可以分為多個等級

—–示例 ——–等級(Rank)——- ———維度———-
3 a rank 0 tensor; a scalar with shape []
[1. ,2., 3.] #; this is a rank 1 tensor a vector with shape [3]
[[1., 2., 3.], [4., 5., 6.]] a rank 2 tensor a matrix with shape [2, 3]
[[[1., 2., 3.]], [[7., 8., 9.]]] a rank 3 tensor shape [2, 1, 3]

1.2 Tensor類

Tensor類表示Operation類的輸出。
A Tensor is a symbolic handle to one of the outputs of an Operation. It does not hold the values of that operation’s output, but instead provides a means of computing those values in a TensorFlow tf.Session.

我這麼理解,Tensor 就是一個多維陣列,而TF中的Tensor類封裝了Operation和Tensor(不知道對不對!)。
一般來說,我們說Tensor以及TensorFlow的API中在指定引數的型別時說的Tensor是指第一種的Tensor的概念,Tensor類的概念一般就是用在Operation的輸出上。

2 TensorFlow的計算用有狀態的資料流圖表示

2.1 資料流圖的概念

來看一張莫煩做的TensorFlow的資料流圖的示意圖:
TensorFlow資料流圖動態演示

TensorFlow中的類Graph 是一個數據流圖。包含了tf.Operation的集合和tf.Tensor的集合。
我們抽絲剝繭的理解下這句話。
首先這裡說的Graph是TensorFlow定義的一個類,定義在:tensorflow/python/framework/ops.py中。
然後,什麼是資料流圖呢?我們對比一下 控制流圖 ,來理解一下資料流圖。

—–屬性 ——–控制流圖 ——- ———資料流圖———-
有向圖 有向圖
組成元素 矩形框、判斷菱形、合併點 操作節點, 邊(輸入、輸出)
面向過程 面向物件
節點之間不傳遞資料 節點之間傳遞資料
側重點 表示出程式、應用、服務等的執行過程,及各個過程的結果資訊 表明資料是如何在系統的節點之間傳遞(Flow)的

對於資料流圖,每個節點,對應 TensorFlow中的tf.Operation類,每個節點的輸入/輸出則對應tf.Tensor類。
在圖的起始節點,會產生一系列的資料,經過一個節點的處理後,輸出到下一個節點,依次類推,直至最終的節點輸出,由此構成一張有向圖。

2.2 TensorFlow中的計算圖

需要指出的是,TF將圖的構造和執行分離成兩個獨立的部分。也就是說,我們在進行TensorFlow核心程式設計的時候,可以大體上按照兩步來走:
1. 構造計算圖(Building the computational graph)
2. 執行計算圖(Running the computational graph)

那麼如何構造,如何執行呢?
TF通過構造運算節點(Operation類)及其相互的關係建立起圖,然後利用Session類來執行建立好的圖。(A computational graph is a series of TensorFlow operations arranged into a graph of nodes. )

3 Operation類

tf.Operation類表示TensorFlow圖中的一個節點,用來執行Tensor運算。
每個節點,可以有多個輸入輸出,也可以只有輸入或者輸出。其輸入輸出都是Tensor物件。比如:

c = tf.matmul(a, b)
這裡生成了一個型別為“MatMul”的Operation, 輸入時a和b, 輸出是c。

3.1 TensorFlow內建的運算操作

參考TensorFlow的API:https://devdocs.io/tensorflow~python/math_ops
給個示例:

#tensorflow 內建的運算操作示例
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
import tensorflow as tf
import numpy as np

#算術操作符
'''
tf.add
tf.subtract
tf.multiply
tf.scalar_mul
tf.div
tf.divide
tf.truediv
tf.floordiv
tf.realdiv
tf.truncatediv
tf.floor_div
tf.truncatemod
tf.floormod
tf.mod
tf.cross
'''
sess = tf.Session()


a = np.array([1,2],dtype = np.float32)
b = np.array([2,1])
#aa = tf.add_n([a,b])
#print(sess.run(aa))
c = tf.add(a,b)
print(sess.run(c))

d = tf.constant(1.0)
e = tf.Variable(2.0)
aa = tf.add_n([d,e])

f = tf.add(d,e)
sess.run(tf.global_variables_initializer())
print('aa:',sess.run(aa))
print(sess.run(f))

h = 1
i = 2
j = tf.add(h,i)
print(sess.run(j))
l = tf.Variable(b, dtype = tf.float32)
k = tf.scalar_mul(i, l)
sess.run(tf.global_variables_initializer())
print(sess.run(k))
sess.close()

執行結果:

[ 3.  3.]
aa: 3.0
3.0
3
[ 4.  2.]

3.2 如何通過Operation來構建圖

4 Session類

4. Variable類

4.1 Variable的概念

A variable maintains state in the graph across calls to run(). You add a variable to the graph by constructing an instance of the class Variable.

The Variable() constructor requires an initial value for the variable, which can be a Tensor of any type and shape. The initial value defines the type and shape of the variable. After construction, the type and shape of the variable are fixed. The value can be changed using one of the assign methods.

If you want to change the shape of a variable later you have to use an assign Op with validate_shape=False.

Just like any Tensor, variables created with Variable() can be used as inputs for other Ops in the graph. Additionally, all the operators overloaded for the Tensor class are carried over to variables, so you can also add nodes to the graph by just doing arithmetic on variables.

4.2 Variable的初始化函式:

__init__(
    initial_value=None,
    trainable=True,
    collections=None,
    validate_shape=True,
    caching_device=None,
    name=None,
    variable_def=None,
    dtype=None,
    expected_shape=None,
    import_scope=None
)

看一下主要引數的含義:
- * initial_value:* A Tensor, or Python object convertible to a Tensor, which is the initial value for the Variable. The initial value must have a shape specified unless validate_shape is set to False. Can also be a callable with no argument that returns the initial value when called. In that case, dtype must be specified. (Note that initializer functions from init_ops.py must first be bound to a shape before being used here.)
- validate_shape: If False, allows the variable to be initialized with a value of unknown shape. If True, the default, the shape of initial_value must be known.
- name: Optional name for the variable. Defaults to ‘Variable’ and gets uniquified automatically.
- dtype: If set, initial_value will be converted to the given type. If None, either the datatype will be kept (if initial_value is a Tensor), or convert_to_tensor will decide.

4.3 如何使用Variable:

  1. 生成Variable的方法:

    Create a variable.
    w = tf.Variable(initial-value, name=optional-name)


初始化的initial—value 可以是任意資料型別的任意維度的Tensor。變數的資料型別和維度就根據這個初始值而定,而且不能改變。變數的值可以通過 tf.assign()函式來改變。如果想改變其維度,就要在生成variable的時候,將 validate_shape置false,並通過tf.assign()函式來重新賦值。
  1. Variable的使用:
    可以作為任何圖中節點的輸入引數。而且,可以通過直接對Variable進行運算將其新增到圖中。

  2. 在執行圖之前,要先初始化Variable。
    初始化Variable的方法有兩種:
    1) 單個初始化:

#Launch the graph in a session.
with tf.Session() as sess:
    # Run the variable initializer.
    sess.run(w.initializer)
    # ...you now can run ops that use the value of 'w'...
2)  全域性初始化:
# Add an Op to initialize global variables.
init_op = tf.global_variables_initializer()

# Launch the graph in a session.
with tf.Session() as sess:
    # Run the Op that initializes global variables.
    sess.run(init_op)
    # ...you can now run any Op that uses variable values...