tensorflow語法筆記


1、如何理解 tf.reduce_max或者 tf.reduce_mean中對Tensor和高維矩陣的坐標軸axis的選擇的操作

tf.reduce_mean( input_tensor, axis=None, keepdims=None, name=None, reduction_indices=None, keep_dims=None )
x = tf.constant([[1., 1.], [2., 2.]]) tf.reduce_mean(x) # 1.5
tf.reduce_mean(x, 0)  # [1.5, 1.5]
tf.reduce_mean(x, 1)  # [1., 2.]

  從上計算結果中也可以看到,如果axis為None,默認將所有的維度都降1,最后剩下個0維的數子。

  一個不是很簡單,但是很好理解的方法是:你的輸入矩陣的shape是(2,3,4),那么當axis=0時,就是在第一個dimension上進行求均值,最后得到的結果的shape就是去掉第一個dimension后的shape,也就是(3,4)。所以,我們例子中的x是shape為(2,2),axis=0時,剩下第二個維度--列,所以沿着第一個維度方向上--行對所有列求均值。

 

2、Tensorflow里的eval()是什么意思

  今天看到一個用法

with tf.Session() as sess:
    print(tf.nn.embedding_lookup(wordVectors,firstSentence).eval().shape)

  一般tensorflow不都是要在Session里run一下才能執行嗎,這里怎么直接print出來了,還多了一個eval()。

  經查,eval() 其實就是tf.Tensor的Session.run() 的另外一種寫法。但是要注意的是,eval()只能用於tf.Tensor類對象,也就是有輸出的Operation。對於沒有輸出的Operation, 可以用.run()或者Session.run()。Session.run()沒有這個限制。所以上述其實也可以等效地表示為

with tf.Session() as sess:
    print(sess.run(tf.nn.embedding_lookup(wordVectors,firstSentence)).shape)

 

 3、tf.InteractiveSession()與tf.Session()

  • tf.InteractiveSession():它能讓你在運行圖的時候,插入一些計算圖,這些計算圖是由某些操作(operations)構成的。這對於工作在交互式環境中的人們來說非常便利,比如使用IPython。
  • tf.Session():需要在啟動session之前構建整個計算圖,然后啟動該計算圖。
  意思就是在我們使用tf.InteractiveSession()來構建會話的時候,我們可以先構建一個session然后再定義操作(operation),如果我們使用tf.Session()來構建會話我們需要在會話構建之前定義好全部的操作(operation)然后再構建會話。
 

 4、tf.app.flags.FLAGS和 tf.app.run()

  <1> tf.app.flags.FLAGS

  tf.app.flags.FLAGS源碼其實是調用的argparse庫,而argparse也就是一個方便用戶添加命令行的python庫。

  • tf.app.flags.DEFINE_xxx():添加命令行的optional argument(可選參數)
  • tf.app.flags.FLAGS:可以從對應的命令行參數取出參數。

舉個栗子:

新建 tf_app_flag.py 文件,並輸入如下代碼,代碼的功能是創建幾個命令行參數,然后把命令行參數輸出顯示

import tensorflow  as tf
FLAGS=tf.app.flags.FLAGS
tf.app.flags.DEFINE_float('flag_float', 0.01, 'input a float')
tf.app.flags.DEFINE_integer( 'flag_int', 400, 'input a int')
tf.app.flags.DEFINE_boolean( 'flag_bool', True, 'input a bool')
tf.app.flags.DEFINE_string('flag_string', 'yes', 'input a string')
 
print(FLAGS.flag_float)
print(FLAGS.flag_int)
print(FLAGS.flag_bool)
print(FLAGS.flag_string)

  1> 在命令行中查看幫助信息,在命令行輸入 python3 tf_app_flag.py -h

➜  learn python3 tf_app_flag.py -h
usage: tf_app_flag.py [-h] [--flag_float FLAG_FLOAT] [--flag_int FLAG_INT]
                      [--flag_bool [FLAG_BOOL]] [--noflag_bool]
                      [--flag_string FLAG_STRING]

optional arguments:
  -h, --help            show this help message and exit
  --flag_float FLAG_FLOAT
                        input a float --flag_int FLAG_INT   input a int --flag_bool [FLAG_BOOL]
                        input a bool --noflag_bool
  --flag_string FLAG_STRING
                        input a string

注意紅色字體信息,這個就是我們用DEFINE_XXX添加命令行參數時的第三個參數

  2> 直接運行

➜  learn python3 tf_app_flag.py   
0.01
400
True
yes

  3> 帶參數運行

➜  learn python3 tf_app_flag.py --flag_float 0.24 --flag_int 3 --flag_bool False --flag_string 'lalala, I got it'
0.24
3
False
lalala, I got it

   <2> tf.app.run()

該函數一般都是出現在這種代碼中:

if __name__ == '__main__':
    tf.app.run()

從源碼開始分析,源碼如下:

flags_passthrough=f._parse_flags(args=args)這里的parse_flags就是我們tf.app.flags源碼中用來解析命令行參數的函數。所以這一行就是解析參數的功能;

下面兩行代碼也就是tf.app.run的核心意思:執行程序中main函數,並解析命令行參數!

  • 如果你的代碼中的入口函數不叫main(),而是一個其他名字的函數,如test(),則你應該這樣寫入口tf.app.run(test())

5、RNN、LSTM訓練代碼輸入輸出,維度分析

 

  當前層各個參數含義:

     

  Tensorflow 中RNN單個時刻計算流程:

 

Tensorflow 中 lstm 單個時刻計算流程:

注:上面計算[H,X] * W后和B維度不同, 如何相加,解釋如下;

  1. tensorflow代碼中,用的這個 nn_ops.bias_add(gate_inputs, self._bias),這個函數的計算方法是,讓每個 batch 的輸出值,都加上這個 B;
  2. 所以維度不同可以相加:【batch_size,Hidden_size】,【Hidden_size】,見函數演示:nn_ops.bias_add

6、gensim word2vec的輸入必須是list of list格式,即[ [ ] ]。  

7、Graph和Session 

  Graph 

  一個TensorFlow的運算,被表示為一個數據流的圖。 一幅圖中包含一些操作(Operation)對象,這些對象是計算節點。前面說過的Tensor對象,則是表示在不同的操作(operation)間的數據節點

  你一旦開始你的任務,就已經有一個默認的圖已經創建好了。而且可以通過調用tf.get_default_graph()來訪問到。 添加一個操作到默認的圖里面,只要簡單的調用一個定義了新操作的函數就行。比如下面的例子展示的:

import tensorflow as tf
import numpy as np

c=tf.constant(value=1)
#print(assert c.graph is tf.get_default_graph())
print(c.graph)
print(tf.get_default_graph())

另外一種典型的用法就是要使用到Graph.as_default() 的上下文管理器( context manager),它能夠在這個上下文里面覆蓋默認的圖。如下例

import tensorflow as tf
c=tf.constant(value=1)
print('c: \n', c.graph)
print('default: \n', tf.get_default_graph())

g1 = tf.Graph()
print('g1: \n', g1)
with g1.as_default():
    c1 = tf.constant(4.0)
    print('c1: \n', c1.graph)
 
g2 = tf.Graph()
print('g2: \n', g2)
with g2.as_default():
    c2 = tf.constant(20.0)
    print('c2: \n', c2.graph)

e=tf.constant(value=15)
print('e: \n', e.graph)

結果:

c: 
 <tensorflow.python.framework.ops.Graph object at 0x7fe8d8667048>
default: 
 <tensorflow.python.framework.ops.Graph object at 0x7fe8d8667048>
g1: 
 <tensorflow.python.framework.ops.Graph object at 0x7fe875d5af60>
c1: 
 <tensorflow.python.framework.ops.Graph object at 0x7fe875d5af60>
g2: 
 <tensorflow.python.framework.ops.Graph object at 0x7fe875d5af28>
c2: 
 <tensorflow.python.framework.ops.Graph object at 0x7fe875d5af28>
e: 
 <tensorflow.python.framework.ops.Graph object at 0x7fe8d8667048>
View Code

  上面的例子里面創創建了一個新的圖g1,然后把g1設為默認,那么接下來的操作不是在默認的圖中,而是在g1中了。你也可以認為現在g1這個圖就是新的默認的圖了。 然后又創建新的圖g2,做同樣的操作。要注意的是,最后一個量e不是定義在with語句里面的,也就是說,e會包含在最開始的那個圖中。也就是說,要在某個graph里面定義量,要在with語句的范圍里面定義。
從結果的graph ID可以驗證以上說法

  一個Graph的實例支持任意多數量通過名字區分的的“collections”。 為了方便,當構建一個大的圖的時候,collection能夠存儲很多類似的對象。比如 tf.Variable就使用了一個collection(tf.GraphKeys.GLOBAL_VARIABLES),包含了所有在圖創建過程中的變量。 也可以通過之指定新名稱定義其他的collection。

7.1 Graph屬性

  • building_function:Returns True iff this graph represents a function.
  • finalized:返回True,要是這個圖被終止了
  • graph_def_versions:The GraphDef version information of this graph.
  • seed:The graph-level random seed of this graph.
  • version:Returns a version number that increases as ops are added to the graph.

7.2 graph函數

__init__()

作用:創建一個新的,空的圖

add_to_collection(name,value)

作用:存放值在給定名稱的collection里面(因為collection不是sets,所以有可能一個值會添加很多次) 
參數: 
name: The key for the collection. The GraphKeys class contains many standard names for collections. 
value: 添加到collection中的值

as_default()

 

作用: 
返回一個上下文管理器,使得這個Graph對象成為當前默認的graph.當你想在一個進程里面創建多個圖的時候,就應該使用這個函數.為了方便起見,一個全局的圖對象被默認提供,要是你沒有顯式創建一個新的圖的話,所有的操作(ops)都會被添加到這個默認的圖里面來. 
通過with關鍵字和這個方法,來讓這個代碼塊內創建的從操作(ops)添加到這個新的圖里面. 
默認的是當前線程的”property”,如果你創建了一個新的線程而且想使用這個默認的圖,你應該顯式添加一個g.as_default(): 在這個線程函數里面. 
下面是兩種寫法示例:
# 1. Using Graph.as_default():
g = tf.Graph()
with g.as_default():
  c = tf.constant(5.0)
  assert c.graph is g

# 2. Constructing and making default:
with tf.Graph().as_default() as g:
  c = tf.constant(5.0)
  assert c.graph is g

device(*args,**kwds)

作用: 
返回一個上下文管理器(context manager)指定新創建的操作(ops)默認使用的設備。 
參數: 
device_name_or_function::在這個上下文下面使用的設備名稱或者函數。這個參數可以十一個設備名稱字符串,或者十一個設備函數,或者是None。
with g.device('/gpu:0'):
  # All operations constructed in this context will be placed
  # on GPU 0.
  with g.device(None):
    # All operations constructed in this context will have no
    # assigned device.

# Defines a function from `Operation` to device string.
def matmul_on_gpu(n):
  if n.type == "MatMul":
    return "/gpu:0"
  else:
    return "/cpu:0"

with g.device(matmul_on_gpu):
  # All operations of type "MatMul" constructed in this context
  # will be placed on GPU 0; all other operations will be placed
  # on CPU 0.
View Code

name_scope(*args,**kwds) 

Returns a context manager that creates hierarchical names for operations.

with tf.Graph().as_default() as g:
  c = tf.constant(5.0, name="c")
  assert c.op.name == "c"
  c_1 = tf.constant(6.0, name="c")
  assert c_1.op.name == "c_1"

  # Creates a scope called "nested"
  with g.name_scope("nested") as scope:
    nested_c = tf.constant(10.0, name="c")
    assert nested_c.op.name == "nested/c"

    # Creates a nested scope called "inner".
    with g.name_scope("inner"):
      nested_inner_c = tf.constant(20.0, name="c")
      assert nested_inner_c.op.name == "nested/inner/c"

    # Create a nested scope called "inner_1".
    with g.name_scope("inner"):
      nested_inner_1_c = tf.constant(30.0, name="c")
      assert nested_inner_1_c.op.name == "nested/inner_1/c"

      # Treats `scope` as an absolute name scope, and
      # switches to the "nested/" scope.
      with g.name_scope(scope):
        nested_d = tf.constant(40.0, name="d")
        assert nested_d.op.name == "nested/d"

        with g.name_scope(""):
          e = tf.constant(50.0, name="e")
          assert e.op.name == "e"
View Code

 

Session

運行TensorFLow操作(operations)的類,一個Seesion包含了操作對象執行的環境. 
一個例子:

import tensorflow as tf

#build graph
a=tf.constant(2.)
b=tf.constant(5.)
c=a*b

#construct session
sess=tf.Session()

#Evaluate the tensor `c`
print(sess.run(c))

#close session
sess.close()
View Code

上面最后一句close()是因為session一般都擁有很多的資源,要是session不再可用的話,就要調用close()函數來釋放這些資源。 
簡單一點的話,也可以用上下文管理器,比如參照下面的方式:

# Using the `close()` method.
sess = tf.Session()
sess.run(...)
sess.close()

# Using the context manager.
with tf.Session() as sess:
  sess.run(...)
View Code

7.3 Session屬性

  • graph:“投放”到session中的圖 
  • graph_def:圖的描述 
  • sess_str

7.4 Session主要函數

tf.Session.__init__(target=”, graph=None, config=None)

作用: 
這是session的構造函數,創建一個新的tensorflow的session

參數: 
target:(可選)連接的執行引擎,默認是使用in-process引擎,分布式TensorFLow有更多的例子。 
graph: (可選)投放進的計算圖(graph),要是沒有指定的話,那么默認的圖就會被投放到這個session。要是你在同一個進程里面用了很多的圖,你將為各個圖使用不用的session,但是每一個graph都能夠在多個session中使用。在這種情況下,經常顯式的傳遞graph參數到session的構造里面。 
config: (可選) A ConfigProto protocol buffer with configuration options for the session.

tf.Session.run(fetches, feed_dict=None, options=None, run_metadata=None)

作用: 
運行操作估算(計算)tensor。 
參數: 
fetches: 一個單獨的圖的元素,或者一個圖的元素的列表。或者一個字典,這個字典的值是剛剛所說的一個圖的元素(元素列表)(見下面第四部分的例子)。圖的元素可以是一個操作(那么fetch回來的值將是None);一個tensor(反回的值將是將是表示這個tensor值的numpy ndarray對象);一個sparsetensor(稀疏tensor);一個get_tensor_handle的操作;一個表示tensor或者操作名稱的string 
feed_dict: 一個字典,為之前“占位”的元素“喂”給值。(具體見第四部分的例子。) 

返回值: 
如果你的fetchs參數傳入的圖的一個元素,那么返回一個單獨的值,要是是圖的一個元素列表,那么返回就是一個列表,要是你傳入的是一個字典,那么返回的也是一個字典,這個字典的鍵和你傳入的字典的鍵是一樣的。函數返回的值和你傳進去的fetch參數的形狀是一樣的,只是里面的元素是相應的值而已了。
 a = tf.constant([10, 20])
   b = tf.constant([1.0, 2.0])
   # 'fetches' can be a singleton
   v = session.run(a)
   # v is the numpy array [10, 20]
   # 'fetches' can be a list.
   v = session.run([a, b])
   # v a Python list with 2 numpy arrays: the numpy array [10, 20] and the
   # 1-D array [1.0, 2.0]
   # 'fetches' can be arbitrary lists, tuples, namedtuple, dicts:
   MyData = collections.namedtuple('MyData', ['a', 'b'])
   v = session.run({'k1': MyData(a, b), 'k2': [b, a]})
   # v is a dict with
   # v['k1'] is a MyData namedtuple with 'a' the numpy array [10, 20] and
   # 'b' the numpy array [1.0, 2.0]
   # v['k2'] is a list with the numpy array [1.0, 2.0] and the numpy array
   # [10, 20].
View Code

tf.Session.close()

as_default() 
作用:返回一個上下文管理器,使得這個對象成為當前默認的session/使用with關鍵字然后可以在with關鍵字代碼塊中執行tf.Operation.run和 tf.Tensor.eval ,都是默認在當前session下面執行。

c = tf.constant(..)
sess = tf.Session()

with sess.as_default():
  assert tf.get_default_session() is sess
  print(c.eval())
View Code

 

8、tf.identity的意義以及用例

  下面程序的功能是,做5次循環,每次循環給x加1,賦值給y,然后打印出來,所以我們預期達到的效果是輸出2,3,4,5,6。

x = tf.Variable(1.0)
y = tf.Variable(0.0)

#返回一個op,表示給變量x加1的操作
x_plus_1 = tf.assign_add(x, 1)

#control_dependencies的意義是,在執行with包含的內容(在這里就是 y = x)前,
#先執行control_dependencies參數中的內容(在這里就是 x_plus_1),這里的解釋不准確,先接着看。。。
with tf.control_dependencies([x_plus_1]):
    y = x
init = tf.initialize_all_variables()

with tf.Session() as session:
    init.run()
    for i in xrange(5):
        print(y.eval())#相當於sess.run(y),按照我們的預期,由於control_dependencies的作用,所以應該執行print前都會先執行x_plus_1,但是這種情況會出問題
View Code

這個打印的是1,1,1,1,1 。可以看到,沒有達到我們預期的效果,y只被賦值了一次。

如果改成這樣:

x = tf.Variable(1.0)
y = tf.Variable(0.0)
x_plus_1 = tf.assign_add(x, 1)

with tf.control_dependencies([x_plus_1]):
    y = tf.identity(x)       #  修改部分
init = tf.initialize_all_variables()

with tf.Session() as session:
    init.run()
    for i in xrange(5):
        print(y.eval())
View Code

這時候打印的是2,3,4,5,6

解釋:對於control_dependencies這個管理器,只有當里面的操作是一個op時,才會生效,也就是先執行傳入的參數op,再執行里面的op。而y=x僅僅是tensor的一個簡單賦值,不是定義的op,所以在圖中不會形成一個節點,這樣該管理器就失效了。tf.identity是返回一個一模一樣新的tensor的op,這會增加一個新節點到gragh中,這時control_dependencies就會生效,所以第二種情況的輸出符合預期。

 

9、TensorFlow  顯卡內存使用管理

  在使用TensorFlow gpu 跑程序時常會遇到顯卡內存不足的問題,這時有以下幾個方法可供參考

  1、如果是模型訓練,減小batch size;

  2、如果開了多個進程 ,減小個數

  3、可用以下代碼限制顯卡使用占比

gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.6) #gpu資源的占比,顯存×0.6
with tf.Session(config=tf.ConfigProto(log_device_placement=False,gpu_options=gpu_options)) as sess:

  4、也可以設置

config.gpu_options.allow_growth = True #開始不會給tensorflow全部gpu資源 而是按需增加

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM