list python 转tensor_TensorFlow 中的几个关键概念:Tensor,Operation,Graph,Session
前言:TensorFlow是一種符號式編程框架,首先要構造一個圖(graph),然后在這個圖上做運算。打個比方,graph就像一條生產線,session就像生產者。生產線具有一系列的加工步驟(加減乘除等運算),生產者把原料投進去,就能得到產品。不同生產者都可以使用這條生產線,只要他們的加工步驟是一樣的就行。同樣的,一個graph可以供多個session使用,而一個session不一定需要使用graph的全部,可以只使用其中的一部分。
一、Tensorflow的工作流程
- 根據需求,創建計算圖Graph
- 開啟會話Session,讀取數據運行Graph
- 獲取結果
二、TensorFlow 幾個關鍵概念:Tensor,Operation,Graph,Session
1.Tensor(數據節點)
(1)Tensor定義
在 TensorFlow 中,所有在節點之間傳遞的數據都為 Tensor 對象。
Tensor定義: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本身是不存儲數據的,創建一個Tensor實際就是聲明了一個數據節點。只有開啟Session進行運算的時候,才會獲取到數據。
(2)Tensor的階
如下圖所示,Rank為0、1、2時分別稱為標量、向量和矩陣,Rank為3時是3階張量,Rank大于3時是N階張量。這些標量、向量、矩陣和張量里的元素可以是數組,可以是tensor或者其他python基本數據類型。當所有元素類型一致且均為tensor(數組)時,則可將Rank的階數當做tensor(數組)的階數。通常我們討論的數據類型是指元素的數據類型。
(3)Tensor的幾個重要屬性
shape:類似于Numpy中ndarray.shape,比方說一個2行3列的二維矩陣,他的形狀就是2行3列。
dtype:類似于Numpy中ndarray.dtype,常用的類型有:
tf.uint8: 8-bit unsigned integer.
tf.int32: 32-bit signed integer.
tf.int64: 64-bit signed integer.
tf.String: String.
tf.float32: 32-bit single-precision floating-point.
tf.float64: 64-bit double-precision floating-point.
name:每個Tensor都必須有name屬性。在創建Tensor時,如果用戶沒有指定name,Tensorflow會自動設置;在同一張Graph中,不會有Tensor重名,當用戶設定的name重名時,Tensorlfow會自動加入后綴進行區分。
(4)幾種Tensor
- 常量Tensor:值不能改變,最常見的常量創建方式為tf.constant(value, dtype=None, shape=None, name="Const", verify_shape=False),其中value不可少,verify_shape表示常量的形狀是否可以被更改,默認不可更改。初此之外還有以下常量的創建方法:
# 產生全 0 的張量
tensor_a = tf.zeros(shape=[3,4], dtype=tf.float32, name=None)
a = tf.zeros_like(tensor_a, dtype=None, name=None)#tensor_a with all elements set to zero.
# 產生全 1 的張量
tensor_b = tf.ones(shape=[3,4], dtype=tf.float32, name=None)
b = tf.ones_like(tensor_b, dtype=None, name=None)
# Creates a tensor of shape and fills it with value
#tf.fill(dims, value, name=None)
tf.fill([2, 3], 9) ==> [[9, 9, 9][9, 9, 9]]
# 產生常量 Tensor, value 值可為 python 標準數據類型、Numpy 等
tf.constant(-1.0, shape=[2, 3]) => [[-1., -1., -1.] # Note: 注意 shape 的用法(廣播機制) [-1., -1., -1.]]
tf.constant([1,2,3,4,5,6], shape=[2,3]) => [[1, 2, 3][4, 5, 6]]注意:常量tensor無需初始化,可以直接獲取tensor的值。
但仍然遵循tensorflow的運行機制,即數據只會在session中流動,
即無論是初始化賦值還是取出tensor的值都必須在session中執行- 變量Tensor:值可以改變,可訓練。在神經網絡中,變量一般可作為儲存權重和其他信息的矩陣,而常量可作為儲存超參數或其他結構信息的變量。變量的創建方法如下(變量的創建均需要指定shape,且shape要以list或tuple的形式傳入):
tf.Variable(initial_value, dtype=None, name=None, trainable=True,collections=None,validate_shape=True)
# 參數
initial_value:A Tensor或Python對象可轉換為a Tensor.變量的初始值.必須具有指定的形狀,除非 validate_shape設置為False.
trainable:如果True,默認值也將該變量添加到圖形集合GraphKeys.TRAINABLE_VARIABLES,該集合用作Optimizer類要使用的變量的默認列表
collections:圖表集合鍵列表,新變量添加到這些集合中.默認為[GraphKeys.VARIABLES]
validate_shape:如果False允許使用未知形狀的值初始化變量,如果True,默認形狀initial_value必須提供.
name:變量的可選名稱,默認'Variable'并自動獲取#必須初始化變量(將初始值initial_value傳給tensor)后才能取出tensor的值,常見的初始化方法如下:"""變量初始化:全局變量初始化(其實全局變量初始化方法就是將初始值通過變量的assign方法向變量分配值)將一個變量的值賦值給另一個變量;運行變量的初始化函數variable.initializer();restore恢復變量值"""#1.全局變量初始化:tf.global_variables_initializer()
import tensorflow as tfweights = tf.Variable(tf.random_normal([784, 200], stddev=0.35), name="weights")
biases = tf.Variable(tf.zeros([200]), name="biases")# 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)print(weights.eval(),biases.eval())#初始化成功才能取出tensor的值#2.將一個變量的值賦值給另一個變量:initialized_value()
import tensorflow as tfw = tf.Variable(tf.ones(shape=[3]), name='w')
w2 = tf.Variable(w.initialized_value(), name='w2')#用已經初始化的w的值作為w2的初始值
w_twice = tf.Variable(w.initialized_value() * 2, name='w_twice')with tf.Session() as sess:sess.run(tf.global_variables_initializer())#注意這里必須使用全局變量初始化。w,w2,w_twice都只是計算圖中的一個opprint(w.eval(), w2.eval(), w_twice.eval())#初始化成功才能取出tensor的值#3.運行變量的初始化函數:variable.initializer()
import tensorflow as tfw = tf.Variable(tf.ones(shape=[3]), name='w')
with tf.Session() as sess:sess.run(w.initializer)#僅僅初始化w本身,等價于w.initializer.run()print(w.eval())#4.restore恢復變量值
import tensorflow as tf#首先恢復graph
saver = tf.train.import_meta_graph('./checkpoints/model.ckpt-999.meta')
with tf.Session() as sess:#恢復最新保存的權重saver.restore(sess, tf.train.latest_checkpoint('./checkpoints'))#指定一個權重恢復saver.restore(sess, './checkpoints/model.ckpt-999')#注意不要加文件后綴名tf.get_variable(name,shape=None,dtype=None,initializer=None,trainable=True,regularizer=None,collections=None,caching_device=None,partitioner=None,validate_shape=True,use_resource=None,custom_getter=None)Note:
name 參數必須要指定;shape也必須指定。 #在使用模型之前,必須初始化變量,初始化的方法跟上面一樣,這里再介紹參數initializer的幾種常用初始化方式
#(這里的initializer初始化之后并沒有實際的數據,當開啟session時,才將相應的初始化數據傳給tensor)
#(1)初始化initializer為常量
init = tf.constant_initializer([[1,2],[23,2]])
init_zeros = tf.zeros_initializer()
init_ones = tf.ones_initializer()
x = tf.get_variable(initializer=init, name='x', shape=[2,2])init_op = tf.global_variables_initializer()
with tf.Session() as sess:sess.run(init_op)print(x.eval())#(2)初始化為initializer為 標準/截斷 正態分布
init_random = tf.random_normal_initializer(mean=0.0, stddev=1.0, seed=None, dtype=tf.float32)
init_truncated = tf.truncated_normal_initializer(mean=0.0, stddev=1.0, seed=None, dtype=tf.float32)
y = tf.get_variable(initializer=init_random, name='y', shape=[10])
init_op = tf.global_variables_initializer()
with tf.Session() as sess:sess.run(init_op)print(y.eval())#(3)初始化initializer為均勻分布
init_uniform = tf.random_uniform_initializer(minval=0, maxval=10, seed=None, dtype=tf.float32)
z = tf.get_variable(initializer=init_uniform, name='z', shape=[10])
init_op = tf.global_variables_initializer()
with tf.Session() as sess:sess.run(init_op)print(z.eval())補充:tf.Variable()與tf.get_variable()的區別
(1)變量共享
使用tf.Variable()時,如果系統檢測到命名相同,系統會自動加后綴,不支持變量共享。
使用tf.get_variable(),如果系統檢測到命名相同,且參數reuse=True,那么直接共享之前的變量值,支持變量共享import tensorflow as tfwith tf.variable_scope('scope1'):w1 = tf.Variable(1, name='w1')w2 = tf.get_variable(initializer=2.0, name='w2')with tf.variable_scope('scope1', reuse=True):w1_p = tf.Variable(5, name='w1_P')w2_p = tf.get_variable(initializer=3.0, name='w2')init = tf.global_variables_initializer()
with tf.Session() as sess:sess.run(init)print(w1.eval())print(w2.eval())print(w1_p.eval())print(w2_p.eval())print(w1.name, w1_p.name)
print(w2.name, w2_p.name)assert w1 != w1_p
assert w2 == w2_p(2)tf.variable_scope()可以對所有op加上前綴,指明作用域空間;而tf.name_scope()不能給tf.get_variable()變量指明作用域空間
import tensorflow as tfwith tf.name_scope('scope1'):w0 = tf.constant(1, name='w0')w1 = tf.Variable(1, name='w1')w2 = tf.get_variable(initializer=2.0, name='w2')with tf.variable_scope('scope2'):w0_p = tf.constant(2, name='w0_p')w1_p = tf.Variable(5, name='w1_P')w2_p = tf.get_variable(initializer=3.0, name='w2_p')print(w0.name, w1.name, w2.name)
print(w0_p.name, w1_p.name, w2_p.name)- 占位符 placeholder: tf.placeholder(dtype=tf.float32, shape = [2,3],name='b')
為什么要使用tf.placeholder?
因為每一個tensor在graph上都是一個op。當我們將train數據分成一個個minibatch然后傳入網絡進行訓練時,每一個minibatch都將是一個op,這樣的話,一副graph上的op未免太多,也會產生巨大的開銷;于是就有了tf.placeholder,我們每次可以將 一個minibatch傳入到x = tf.placeholder(tf.float32,[None,32])上,下一次傳入的x都替換掉上一次傳入的x,這樣就對于所有傳入的minibatch x就只會產生一個op,不會產生其他多余的op,進而減少了graph的開銷。
import tensorflow as tf
a = tf.placeholder(tf.float32, shape=[3]) # a是一個3維向量
b = tf.constant([5, 5, 5], tf.float32)
c = a + b
with tf.Session() as sess:print(sess.run(c, feed_dict = {a: [1, 2, 3]})) # 把[1, 2, 3]灌到a里去
注意:占位符不需要初始化。可以把feed_dict看作它特有的一種初始化方式SparseTensor(稀疏張量):定義時只需要定義非0的數,其他的數會自動填充。
#Example: The sparse tensor
tf.SparseTensor(values=[1, 2], indices=[[0, 0], [1, 2]], dense_shape=[3, 4])#represents the dense tensor
[[1, 0, 0, 0][0, 0, 2, 0][0, 0, 0, 0]]2.Operation(計算節點)
將多個Tensor連接在一起,形成新的Tensor。例如tf.add、tf.mul等操作。tensor在graph上也是一個Operation(簡稱op)。但凡是op,都需要通過session運行之后,才能得到結果。
3.Graph(數據節點+計算節點)
Graph就是由一系列op構成的。具體來說就是由W、b、x等數據節點及Add、MatMul等計算節點共同構成一個Graph。
在Tensorflow中,始終存在一個默認的Graph。如果要將Operation添加到默認Graph中,只需要調用定義Operation的函數(例如tf.add())。如果我們需要定義多個Graph,則需要在with語句中調用Graph.as_default()方法將某個graph設置成默認Graph,于是with語句塊中調用的Operation或Tensor將會添加到該Graph中。
import tensorflow as tf#定義一個圖:只有一個圖時,這個圖就是默認圖,所有操作都自動添加到這個圖中
g = tf.Graph()#tensorflow會默認給我們建立一個graph,這句話可以省略
a = tf.constant(2)#將Operation添加到默認Graph中,只需要調用定義Operation的函數print(a.graph)
print(tf.get_default_graph())#通過調用tf.get_default_graph()訪問默認創建的圖的位置#定義多個圖:需要聲明某個操作是定義在哪個圖中的
g1 = tf.Graph()
g2 = tf.Graph()
#將某個graph設置成默認Graph,with語句塊中調用的Operation或Tensor將會添加到該Graph中
with g1.as_default():x = tf.constant(2)y = tf.constant(3)z = tf.add(x, y)print(x.graph, y.graph, z.graph)print(tf.get_default_graph())with g2.as_default():v = tf.constant(4)u = tf.add(2, v)print(v.graph, u.graph)print(tf.get_default_graph())#e不是定義在with語句里面的,e會包含在tensorflow默認創建的圖中。也就是說e與a在同一個圖中
e=tf.constant(value=15)
print(e.graph)如果在創建Session時沒有指定Graph,則該Session會加載默認Graph。如果創建了多個Graph,則需要創建不同的Session來加載每個Graph,而每個Graph則可以加載在多個Session中進行計算。
import tensorflow as tf
g1 = tf.Graph()
with g1.as_default():c1 = tf.constant([1.0])
with tf.Graph().as_default() as g2:c2 = tf.constant([2.0])with tf.Session(graph=g1) as sess1:print(sess1.run(c1))
with tf.Session(graph=g2) as sess2:print(sess2.run(c2))# result:
# [ 1.0 ]
# [ 2.0 ]
#如果將上面例子的sess1.run(c1)和sess2.run(c2)中的c1和c2交換一下位置,運行會報錯。
# 因為sess1加載的g1中沒有c2這個Tensor,同樣地,sess2加載的g2中也沒有c1這個Tensor。4.Session(對Graph進行計算)
Tensorflow先構造Graph,然后開啟session在這個Graph上做運算。Graph是由一系列op組成。但凡是op,都需要通過session運行之后,才能得到結果。Session的作用就是執行Operation(Tensor也可以看作一種Operation)。
執行Operation有兩種方式:
- 調用Session.run()方法: 該方法的定義如下所示,參數fetches便是一個或者多個Operation或者Tensor。
tf.Session.run(fetches, feed_dict=None)- 調用Tensor.eval()方法: 這個方法接收參數session,用于指定在哪個session中計算。該參數默認為None,表示在默認session中計算。設置默認session有兩種方式:
#設置默認session的方式一
import tensorflow as tfa = tf.constant([1.0, 2.0])
b = tf.constant([3.0, 4.0])
c = tf.add(a, b)with tf.Session():#with語句塊中的語句print(c.eval())#設置默認session的方式二
import tensorflow as tfa = tf.constant([1.0, 2.0])
b = tf.constant([3.0, 4.0])
c = tf.add(a, b)sess = tf.Session()
with sess.as_default():print(c.eval())
sess.close()session.run()與tensor.eval()都是開啟對Graph的計算,下面比較一下兩者:
首先,tensor.eval()只適用于tensor。而session.run()不僅適用于tensor,還可用于沒有輸出的op。對于tensor,調用session.run()與tensor.eval()是等價的。
import tensorflow as tf
t = tf.constant(42.0)
sess = tf.Session()
#calling t.eval() is equivalent to calling tf.get_default_session().run(t).
with sess.as_default(): # or `with sess:` to close on exitassert sess is tf.get_default_session()assert t.eval() == sess.run(t)
sess.close()其次,你可以使用session.run()在同一步驟中獲取許多張量的值,而tensor.eval()卻只能一次獲得一個張量的值。
import tensorflow as tft = tf.constant(42.0)
u = tf.constant(37.0)
tu = tf.add(t, u)
ut = tf.add(u, t)sess = tf.Session()
with sess.as_default():tu.eval() # runs one steput.eval() # runs one stepsess.run([tu, ut]) # evaluates both tensors in a single step
sess.close()參考:
Tensorflow 中eval()和sess.run()的關系
Tensorflow中 Graph和Session的關系
TensorFlow進階(三)---變量的創建、初始化 - 時間&煮雨~ - 博客園
Tensorflow學習筆記2:About Session, Graph, Operation and Tensor
TensorFlow學習筆記1:graph、session和op - Jiax - 博客園
TensorFlow學習(三):Graph和Session - 謝小小XH - CSDN博客
總結
以上是生活随笔為你收集整理的list python 转tensor_TensorFlow 中的几个关键概念:Tensor,Operation,Graph,Session的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 生成批量缩率图_Windows系统实战之
- 下一篇: 求一个韩国好听的女孩名字!