Tensorflow一些常用基本概念與函數
1、tensorflow的基本運作
為了快速的熟悉TensorFlow編程,下面從一段簡單的代碼開始:
import tensorflow as tf #定義‘符號’變量,也稱為占位符 a = tf.placeholder("float") b = tf.placeholder("float") y = tf.mul(a, b) #構造一個op節點 sess = tf.Session()#建立會話 #運行會話,輸入數據,並計算節點,同時打印結果 print sess.run(y, feed_dict={a: 3, b: 3}) # 任務完成, 關閉會話. sess.close()
其中tf.mul(a, b)函數便是tf的一個基本的算數運算,接下來介紹跟多的相關函數。
2、tf函數
TensorFlow 將圖形定義轉換成分布式執行的操作, 以充分利用可用的計算資源(如 CPU 或 GPU。一般你不需要顯式指定使用 CPU 還是 GPU, TensorFlow 能自動檢測。如果檢測到 GPU, TensorFlow 會盡可能地利用找到的第一個 GPU 來執行操作.
並行計算能讓代價大的算法計算加速執行,TensorFlow也在實現上對復雜操作進行了有效的改進。大部分核相關的操作都是設備相關的實現,比如GPU。本文主要涉及的相關概念或操作有以下內容:
| 操作組 | 操作 |
|---|---|
| Building Graphs | Core graph data structures,Tensor types,Utility functions |
| Inputs and Readers | Placeholders,Readers,Converting,Queues,Input pipeline |
2.1 建立圖(Building Graphs)
本節主要介紹建立tensorflow圖的相關類或函數
* 核心圖的數據結構(Core graph data structures)
tf.Graph
| 操作 | 描述 |
|---|---|
| class tf.Graph | tensorflow中的計算以圖數據流的方式表示 一個圖包含一系列表示計算單元的操作對象 以及在圖中流動的數據單元以tensor對象表現 |
| tf.Graph.__init__() | 建立一個空圖 |
| tf.Graph.as_default() | 一個將某圖設置為默認圖,並返回一個上下文管理器 如果不顯式添加一個默認圖,系統會自動設置一個全局的默認圖。 所設置的默認圖,在模塊范圍內所定義的節點都將默認加入默認圖中 |
| tf.Graph.as_graph_def (from_version=None, add_shapes=False) |
返回一個圖的序列化的GraphDef表示 序列化的GraphDef可以導入至另一個圖中(使用 import_graph_def()) 或者使用C++ Session API |
| tf.Graph.finalize() | 完成圖的構建,即將其設置為只讀模式 |
| tf.Graph.finalized | 返回True,如果圖被完成 |
| tf.Graph.control_dependencies(control_inputs) | 定義一個控制依賴,並返回一個上下文管理器 with g.control_dependencies([a, b, c]): # `d` 和 `e` 將在 `a`, `b`, 和`c`執行完之后運行. d = … e = … |
| tf.Graph.device(device_name_or_function) | 定義運行圖所使用的設備,並返回一個上下文管理器with g.device('/gpu:0'): ...with g.device('/cpu:0'): ... |
| tf.Graph.name_scope(name) | 為節點創建層次化的名稱,並返回一個上下文管理器 |
| tf.Graph.add_to_collection(name, value) | 將value以name的名稱存儲在收集器(collection)中 |
| tf.Graph.get_collection(name, scope=None) | 根據name返回一個收集器中所收集的值的列表 |
| tf.Graph.as_graph_element (obj, allow_tensor=True, allow_operation=True) |
返回一個圖中與obj相關聯的對象,為一個操作節點或者tensor數據 |
| tf.Graph.get_operation_by_name(name) | 根據名稱返回操作節點 |
| tf.Graph.get_tensor_by_name(name) | 根據名稱返回tensor數據 |
| tf.Graph.get_operations() | 返回圖中的操作節點列表 |
| tf.Graph.gradient_override_map(op_type_map) | 用於覆蓋梯度函數的上下文管理器 |
tf.Operation
| 操作 | 描述 |
|---|---|
| class tf.Operation | 代表圖中的一個節點,用於計算tensors數據 該類型將由python節點構造器產生(比如tf.matmul()) 或者Graph.create_op() 例如c = tf.matmul(a, b)創建一個Operation類 為類型為”MatMul”,輸入為’a’,’b’,輸出為’c’的操作類 |
| tf.Operation.name | 操作節點(op)的名稱 |
| tf.Operation.type | 操作節點(op)的類型,比如”MatMul” |
| tf.Operation.inputs tf.Operation.outputs |
操作節點的輸入與輸出 |
| tf.Operation.control_inputs | 操作節點的依賴 |
| tf.Operation.run(feed_dict=None, session=None) | 在會話(Session)中運行該操作 |
| tf.Operation.get_attr(name) | 獲取op的屬性值 |
tf.Tensor
| 操作 | 描述 |
|---|---|
| class tf.Tensor | 表示一個由操作節點op產生的值, TensorFlow程序使用tensor數據結構來代表所有的數據, 計算圖中, 操作間傳遞的數據都是 tensor,一個tensor是一個符號handle, 里面並沒有表示實際數據,而相當於數據流的載體 |
| tf.Tensor.dtype | tensor中數據類型 |
| tf.Tensor.name | 該tensor名稱 |
| tf.Tensor.value_index | 該tensor輸出外op的index |
| tf.Tensor.graph | 該tensor所處在的圖 |
| tf.Tensor.op | 產生該tensor的op |
| tf.Tensor.consumers() | 返回使用該tensor的op列表 |
| tf.Tensor.eval(feed_dict=None, session=None) | 在會話中求tensor的值 需要使用 with sess.as_default()或者 eval(session=sess) |
| tf.Tensor.get_shape() | 返回用於表示tensor的shape的類TensorShape |
| tf.Tensor.set_shape(shape) | 更新tensor的shape |
| tf.Tensor.device | 設置計算該tensor的設備 |
* tensor類型(Tensor types)
tf.DType
| 操作 | 描述 |
|---|---|
| class tf.DType | 數據類型主要包含 tf.float16,tf.float16,tf.float32,tf.float64, tf.bfloat16,tf.complex64,tf.complex128, tf.int8,tf.uint8,tf.uint16,tf.int16,tf.int32, tf.int64,tf.bool,tf.string |
| tf.DType.is_compatible_with(other) | 判斷other的數據類型是否將轉變為該DType |
| tf.DType.name | 數據類型名稱 |
| tf.DType.base_dtype | 返回該DType的基礎DType,而非參考的數據類型(non-reference) |
| tf.DType.as_ref | 返回一個基於DType的參考數據類型 |
| tf.DType.is_floating | 判斷是否為浮點類型 |
| tf.DType.is_complex | 判斷是否為復數 |
| tf.DType.is_integer | 判斷是否為整數 |
| tf.DType.is_unsigned | 判斷是否為無符號型數據 |
| tf.DType.as_numpy_dtype | 返回一個基於DType的numpy.dtype類型 |
| tf.DType.max tf.DType.min |
返回這種數據類型能表示的最大值及其最小值 |
| tf.as_dtype(type_value) | 返回由type_value轉變得的相應tf數據類型 |
* 通用函數(Utility functions)
| 操作 | 描述 |
|---|---|
| tf.device(device_name_or_function) | 基於默認的圖,其功能便為Graph.device() |
| tf.container(container_name) | 基於默認的圖,其功能便為Graph.container() |
| tf.name_scope(name) | 基於默認的圖,其功能便為 Graph.name_scope() |
| tf.control_dependencies(control_inputs) | 基於默認的圖,其功能便為Graph.control_dependencies() |
| tf.convert_to_tensor (value, dtype=None, name=None, as_ref=False) |
將value轉變為tensor數據類型 |
| tf.get_default_graph() | 返回返回當前線程的默認圖 |
| tf.reset_default_graph() | 清除默認圖的堆棧,並設置全局圖為默認圖 |
| tf.import_graph_def(graph_def, input_map=None, return_elements=None, name=None, op_dict=None, producer_op_list=None) |
將graph_def的圖導入到python中 |
* 圖收集(Graph collections)
| 操作 | 描述 |
|---|---|
| tf.add_to_collection(name, value) | 基於默認的圖,其功能便為Graph.add_to_collection() |
| tf.get_collection(key, scope=None) | 基於默認的圖,其功能便為Graph.get_collection() |
* 定義新操作節點(Defining new operations)
tf.RegisterGradient
| 操作 | 描述 |
|---|---|
| class tf.RegisterGradient | 返回一個用於寄存op類型的梯度函數的裝飾器 |
| tf.NoGradient(op_type) | 設置操作節點類型op_type的節點沒有指定的梯度 |
| class tf.RegisterShape | 返回一個用於寄存op類型的shape函數的裝飾器 |
| class tf.TensorShape | 表示tensor的shape |
| tf.TensorShape.merge_with(other) | 與other合並shape信息,返回一個TensorShape類 |
| tf.TensorShape.concatenate(other) | 與other的維度相連結 |
| tf.TensorShape.ndims | 返回tensor的rank |
| tf.TensorShape.dims | 返回tensor的維度 |
| tf.TensorShape.as_list() | 以list的形式返回tensor的shape |
| tf.TensorShape.is_compatible_with(other) | 判斷shape是否為兼容 TensorShape(None)與其他任何shape值兼容 |
| class tf.Dimension | |
| tf.Dimension.is_compatible_with(other) | 判斷dims是否為兼容 |
| tf.Dimension.merge_with(other) | 與other合並dims信息 |
| tf.op_scope(values, name, default_name=None) | 在python定義op時,返回一個上下文管理器 |
2.2 輸入和讀取器(Inputs and Readers)
本節主要介紹tensorflow中數據的讀入相關類或函數
* 占位符(Placeholders)
tf提供一種占位符操作,在執行時需要為其提供數據data。
| 操作 | 描述 |
|---|---|
| tf.placeholder(dtype, shape=None, name=None) | 為一個tensor插入一個占位符 eg:x = tf.placeholder(tf.float32, shape=(1024, 1024)) |
| tf.placeholder_with_default(input, shape, name=None) | 當輸出沒有fed時,input通過一個占位符op |
| tf.sparse_placeholder(dtype, shape=None, name=None) | 為一個稀疏tensor插入一個占位符 |
* 讀取器(Readers)
tf提供一系列讀取各種數據格式的類。對於多文件輸入,可以使用函數tf.train.string_input_producer,該函數將創建一個保持文件的FIFO隊列,以供reader使用。或者如果輸入的這些文件名有相雷同的字符串,也可以使用函數tf.train.match_filenames_once。
| 操作 | 描述 |
|---|---|
| class tf.ReaderBase | 不同的讀取器類型的基本類 |
| tf.ReaderBase.read(queue, name=None) | 返回下一個記錄對(key, value),queue為tf文件隊列FIFOQueue |
| tf.ReaderBase.read_up_to(queue, num_records, name=None) | 返回reader產生的num_records對(key, value) |
| tf.ReaderBase.reader_ref | 返回應用在該reader上的Op |
| tf.ReaderBase.reset(name=None) | 恢復reader為初始狀態 |
| tf.ReaderBase.restore_state(state, name=None) | 恢復reader為之前的保存狀態state |
| tf.ReaderBase.serialize_state(name=None) | 返回一個reader解碼后產生的字符串tansor |
| class tf.TextLineReader | |
| tf.TextLineReader.num_records_produced(name=None) | 返回reader已經產生的記錄(records )數目 |
| tf.TextLineReader.num_work_units_completed(name=None) | 返回該reader已經完成的處理的work數目 |
| tf.TextLineReader.read(queue, name=None) | 返回reader所產生的下一個記錄對 (key, value),該reader可以限定新產生輸出的行數 |
| tf.TextLineReader.reader_ref | 返回應用在該reader上的Op |
| tf.TextLineReader.reset(name=None) | 恢復reader為初始狀態 |
| tf.TextLineReader.restore_state(state, name=None) | 恢復reader為之前的保存狀態state |
| tf.TextLineReader.serialize_state(name=None) | 返回一個reader解碼后產生的字符串tansor |
| class tf.WholeFileReader | 一個閱讀器,讀取整個文件,返回文件名稱key,以及文件中所有的內容value,該類的方法同上,不贅述 |
| class tf.IdentityReader | 一個reader,以key和value的形式,輸出一個work隊列。該類其他方法基本同上 |
| class tf.TFRecordReader | 讀取TFRecord格式文件的reader。該類其他方法基本同上 |
| class tf.FixedLengthRecordReader | 輸出 |
* 數據轉換(Converting)
tf提供一系列方法將各種格式數據轉換為tensor表示。
| 操作 | 描述 |
|---|---|
| tf.decode_csv(records, record_defaults, field_delim=None, name=None) |
將csv轉換為tensor,與tf.TextLineReader搭配使用 |
| tf.decode_raw(bytes, out_type, little_endian=None, name=None) |
將bytes轉換為一個數字向量表示,bytes為一個字符串類型的tensor 與函數 tf.FixedLengthRecordReader搭配使用,詳見tf的CIFAR-10例子 |
選取與要輸入的文件格式相匹配的reader,並將文件隊列提供給reader的讀方法( read method)。讀方法將返回文件唯一標識的key,以及一個記錄(record)(有助於對出現一些另類的records時debug),以及一個標量的字符串值。再使用一個(或多個)解碼器(decoder) 或轉換操作(conversion ops)將字符串轉換為tensor類型。
* Example protocol buffer
提供了一些Example protocol buffers,tf所推薦的用於訓練樣本的數據格式,它們包含特征信息,詳情可見。
這是一種與前述將手上現有的各種數據類型轉換為支持的格式的方法,這種方法更容易將網絡結構與數據集融合或匹配。這種tensorflow所推薦的數據格式是一個包含tf.train.Example protocol buffers (包含特征Features域)的TFRecords文件。
1、獲取這種格式的文件方式為,首先將一般的數據格式填入Example protocol buffer中,再將 protocol buffer序列化為一個字符串,然后使用tf.python_io.TFRecordWriter類的相關方法將字符串寫入一個TFRecords文件中,參見MNIST例子,將MNIST 數據轉換為該類型數據。
2、讀取TFRecords格式文件的方法為,使用tf.TFRecordReader讀取器和tf.parse_single_example解碼器。parse_single_example操作將 example protocol buffers解碼為tensor形式。參見MNIST例子
| 操作 | 描述 |
|---|---|
| class tf.VarLenFeature | 解析變長的輸入特征feature相關配置 |
| class tf.FixedLenFeature | 解析定長的輸入特征feature相關配置 |
| class tf.FixedLenSequenceFeature | 序列項目中的稠密(dense )輸入特征的相關配置 |
| tf.parse_example(serialized, features, name=None, example_names=None) |
將一組Example protos解析為tensor的字典形式 解析serialized所給予的序列化的一些Example protos 返回一個由特征keys映射Tensor和SparseTensor值的字典 |
| tf.parse_single_example(serialized, features, name=None, example_names=None) |
解析一個單獨的Example proto,與tf.parse_example方法雷同 |
| tf.decode_json_example(json_examples, name=None) | 將JSON編碼的樣本記錄轉換為二進制protocol buffer字符串 |
* 隊列(Queues)
tensorflow提供了幾個隊列應用,用來將tf計算圖與tensors的階段流水組織到一起。隊列是使用tensorflow計算的一個強大的機制,正如其他Tensorflow的元素一樣,一個隊列也是tf圖中的一個節點(node),它是一個有狀態的node,就像一個變量:其他節點可以改變其內容。
我們來看一個簡單的例子,如下gif圖,我們將創建一個先入先出隊列(FIFOQueue)並且將值全設為0,然后我們構建一個圖以獲取隊列出來的元素,對該元素加1操作,並將結果再放入隊列末尾。漸漸地,隊列中的數字便增加。 
| 操作 | 描述 |
|---|---|
| class tf.QueueBase | 基本的隊列應用類.隊列(queue)是一種數據結構, 該結構通過多個步驟存儲tensors, 並且對tensors進行入列(enqueue)與出列(dequeue)操作 |
| tf.QueueBase.enqueue(vals, name=None) | 將一個元素編入該隊列中。如果在執行該操作時隊列已滿, 那么將會阻塞直到元素編入隊列之中 |
| tf.QueueBase.enqueue_many(vals, name=None) | 將零個或多個元素編入該隊列中 |
| tf.QueueBase.dequeue(name=None) | 將元素從隊列中移出。如果在執行該操作時隊列已空, 那么將會阻塞直到元素出列,返回出列的tensors的tuple |
| tf.QueueBase.dequeue_many(n, name=None) | 將一個或多個元素從隊列中移出 |
| tf.QueueBase.size(name=None) | 計算隊列中的元素個數 |
| tf.QueueBase.close (cancel_pending_enqueues=False, name=None) |
關閉該隊列 |
| f.QueueBase.dequeue_up_to(n, name=None) | 從該隊列中移出n個元素並將之連接 |
| tf.QueueBase.dtypes | 列出組成元素的數據類型 |
| tf.QueueBase.from_list(index, queues) | 根據queues[index]的參考隊列創建一個隊列 |
| tf.QueueBase.name | 返回最隊列下面元素的名稱 |
| tf.QueueBase.names | 返回隊列每一個組成部分的名稱 |
| class tf.FIFOQueue | 在出列時依照先入先出順序,其他方法與tf.QueueBase雷同 |
| class tf.PaddingFIFOQueue | 一個FIFOQueue ,同時根據padding支持batching變長的tensor |
| class tf.RandomShuffleQueue | 該隊列將隨機元素出列,其他方法與tf.QueueBase雷同 |
* 文件系統的處理(Dealing with the filesystem)
| 操作 | 描述 |
|---|---|
| tf.matching_files(pattern, name=None) | 返回與pattern匹配模式的文件名稱 |
| tf.read_file(filename, name=None) | 讀取並輸出輸入文件的整個內容 |
* 輸入管道(Input pipeline)
用於設置輸入預取數的管道TF函數,函數 “producer”添加一個隊列至圖中,同時一個相應用於運行隊列中子圖(subgraph)的QueueRunner
| 操作 | 描述 |
|---|---|
| tf.train.match_filenames_once(pattern, name=None) | 保存與pattern的文件列表 |
| tf.train.limit_epochs(tensor, num_epochs=None, name=None) | 返回一個num_epochs次數,然后報告OutOfRange錯誤 |
| tf.train.input_producer(input_tensor, element_shape=None, num_epochs=None, shuffle=True, seed=None, capacity=32, shared_name=None, summary_name=None, name=None) |
為一個輸入管道輸出input_tensor中的多行至一個隊列中 |
| tf.train.range_input_producer(limit, num_epochs=None, shuffle=True, seed=None, capacity=32, shared_name=None, name=None) |
產生一個從1至limit-1的整數至隊列中 |
| tf.train.slice_input_producer(tensor_list, num_epochs=None, shuffle=True, seed=None, capacity=32, shared_name=None, name=None) |
對tensor_list中的每一個tensor切片 |
| tf.train.string_input_producer(string_tensor, num_epochs=None, shuffle=True, seed=None, capacity=32, shared_name=None, name=None) |
為一個輸入管道輸出一組字符串(比如文件名)至隊列中 |
* 在輸入管道末端批量打包(Batching at the end of an input pipeline)
該相關函數增添一個隊列至圖中以將數據一樣本打包為batch。它們也會添加 一個QueueRunner,以便執行的已經被填滿隊列的子圖
| 操作 | 描述 |
|---|---|
| tf.train.batch(tensors, batch_size, num_threads=1, capacity=32, enqueue_many=False, shapes=None, dynamic_pad=False, allow_smaller_final_batch=False, shared_name=None, name=None) |
在輸入的tensors中創建一些tensor數據格式的batch, 若輸入為shape[*, x, y, z],那么輸出則為[batch_size, x, y, z] 返回一個列表或者一個具有與輸入tensors相同類型tensors的字典 |
| tf.train.batch_join(tensors_list, batch_size, capacity=32, enqueue_many=False, shapes=None, dynamic_pad=False, allow_smaller_final_batch=False, shared_name=None, name=None) |
將一個tensors的列表添加至一個隊列中以創建樣本的batches len(tensors_list)個線程將啟動, 線程i將tensors_list[i]的tensors入列 tensors_list[i1][j]與tensors_list[i2][j]有相同的類型和shape |
| tf.train.shuffle_batch(tensors, batch_size, capacity, min_after_dequeue, num_threads=1, seed=None, enqueue_many=False, shapes=None, allow_smaller_final_batch=False, shared_name=None, name=None) |
使用隨機亂序的方法創建batches tensors:用於入列的一個list或者dict capacity:一個整數,表示隊列中元素最大數目 |
| tf.train.shuffle_batch_join(tensors_list, batch_size, capacity, min_after_dequeue, seed=None, enqueue_many=False, shapes=None, allow_smaller_final_batch=False, shared_name=None, name=None) |
隨機亂序的tensors創建batches, 其中tensors_list參數為tensors元組或tensors字典的列表 len(tensors_list)個線程將啟動, 線程i將tensors_list[i]的tensors入列 tensors_list[i1][j]與tensors_list[i2][j]有相同的類型和shape |
