tensorflow語法學習

老司機的詩和遠方發表於2020-04-06

摘要:本文主要對tf的一些常用概念與方法進行描述。為‘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()
  • 1

其中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) 用於覆蓋梯度函式的上下文管理器
#class tf.Graph
#tensorflow執行時需要設定預設的圖
g = tf.Graph()
with g.as_default():
  # Define operations and tensors in `g`.
  c = tf.constant(30.0)
  assert c.graph is g

##也可以使用tf.get_default_graph()獲得預設圖,也可在基礎上加入節點或子圖
c = tf.constant(4.0)
assert c.graph is tf.get_default_graph()
  • 1
#tf.Graph.as_default
#以下兩段程式碼功能相同
#1、使用Graph.as_default():
g = tf.Graph()
with g.as_default():
  c = tf.constant(5.0)
  assert c.graph is g

#2、構造和設定為預設
with tf.Graph().as_default() as g:
  c = tf.constant(5.0)
  assert c.graph is g
  • 1
#tf.Graph.control_dependencies(control_inputs)
# 錯誤程式碼
def my_func(pred, tensor):
  t = tf.matmul(tensor, tensor)
  with tf.control_dependencies([pred]):
    # 乘法操作(op)沒有建立在該上下文,所以沒有被加入依賴控制
    return t

# 正確程式碼
def my_func(pred, tensor):
  with tf.control_dependencies([pred]):
    # 乘法操作(op)建立在該上下文,所以被加入依賴控制中
    #執行完pred之後再執行matmul
    return tf.matmul(tensor, tensor)
  • 1
# tf.Graph.name_scope(name)
# 一個圖中包含有一個名稱範圍的堆疊,在使用name_scope(...)之後,將壓(push)新名稱進棧中,
#並在下文中使用該名稱
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"
  • 1

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的裝置
#tf.Tensor.get_shape()
c = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
print(c.get_shape())
==> TensorShape([Dimension(2), Dimension(3)])
  • 1
#現在有個用於影像處理的tensor->image
print(image.get_shape())
==> TensorShape([Dimension(None), Dimension(None), Dimension(3)])
# 假如我們知道資料集中影像尺寸為28 x 28,那麼可以設定
image.set_shape([28, 28, 3])
print(image.get_shape())
==> TensorShape([Dimension(28), Dimension(28), Dimension(3)])
  • 1

* 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時,返回一個上下文管理器
#tf.RegisterGradient
#該裝飾器只使用於定義一個新的op型別時候,如果一個op有m個輸入,n個輸出。那麼該梯度函式應該設定原始的
#操作型別,以及n個Tensor物件(表示每一個op輸出的梯度),以及m個物件(表示每一個op輸入的偏梯度)
#以操作節點型別為'Sub'為例,兩輸入為x,y。為一個輸出x-y
@tf.RegisterGradient("Sub")
def _sub_grad(unused_op, grad):
  return grad, tf.neg(grad)
  • 1
#tf.op_scope
#定義一個名稱為my_op的python操作節點op
def my_op(a, b, c, name=None):
  with tf.op_scope([a, b, c], name, "MyOp") as scope:
    a = tf.convert_to_tensor(a, name="a")
    b = tf.convert_to_tensor(b, name="b")
    c = tf.convert_to_tensor(c, name="c")
    # Define some computation that uses `a`, `b`, and `c`.
    return foo_op(..., name=scope)
  • 1


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型別。

#讀取檔案佇列,使用reader中read的方法,返回key與value
filename_queue = tf.train.string_input_producer(["file0.csv", "file1.csv"])
reader = tf.TextLineReader()
key, value = reader.read(filename_queue)

record_defaults = [[1], [1], [1], [1], [1]]
col1, col2, col3, col4, col5 = tf.decode_csv(
    value, record_defaults=record_defaults)
features = tf.pack([col1, col2, col3, col4])

with tf.Session() as sess:
  # Start populating the filename queue.
  coord = tf.train.Coordinator()
  threads = tf.train.start_queue_runners(coord=coord)

  for i in range(1200):
    # Retrieve a single instance:
    example, label = sess.run([features, col5])

  coord.request_stop()
  coord.join(threads)
  • 1

* 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字串
#tf.parse_example的使用舉例
#輸入序列化資料如下: 
serialized = [
  features
    { feature { key: "ft" value { float_list { value: [1.0, 2.0] } } } },
  features
    { feature []},
  features
    { feature { key: "ft" value { float_list { value: [3.0] } } }
]
#那麼輸出為一個字典(dict),如下:
{"ft": SparseTensor(indices=[[0, 0], [0, 1], [2, 0]],
                    values=[1.0, 2.0, 3.0],
                    shape=(3, 2)) }
#########
#再來看一個例子,給定兩個序列化的原始輸入樣本:
[
  features {
    feature { key: "kw" value { bytes_list { value: [ "knit", "big" ] } } }
    feature { key: "gps" value { float_list { value: [] } } }
  },
  features {
    feature { key: "kw" value { bytes_list { value: [ "emmy" ] } } }
    feature { key: "dank" value { int64_list { value: [ 42 ] } } }
    feature { key: "gps" value { } }
  }
]
#相關引數如下:
example_names: ["input0", "input1"],
features: {
    "kw": VarLenFeature(tf.string),
    "dank": VarLenFeature(tf.int64),
    "gps": VarLenFeature(tf.float32),
}
#那麼有如下輸出:
{
  "kw": SparseTensor(
      indices=[[0, 0], [0, 1], [1, 0]],
      values=["knit", "big", "emmy"]
      shape=[2, 2]),
  "dank": SparseTensor(
      indices=[[1, 0]],
      values=[42],
      shape=[2, 1]),
  "gps": SparseTensor(
      indices=[],
      values=[],
      shape=[2, 0]),
}
#########
#對於兩個樣本的輸出稠密結果情況
[
  features {
    feature { key: "age" value { int64_list { value: [ 0 ] } } }
    feature { key: "gender" value { bytes_list { value: [ "f" ] } } }
   },
   features {
    feature { key: "age" value { int64_list { value: [] } } }
    feature { key: "gender" value { bytes_list { value: [ "f" ] } } }
  }
]
#我們可以使用以下引數
example_names: ["input0", "input1"],
features: {
    "age": FixedLenFeature([], dtype=tf.int64, default_value=-1),
    "gender": FixedLenFeature([], dtype=tf.string),
}
#期望的結果如下
{
  "age": [[0], [-1]],
  "gender": [["f"], ["f"]],
}
  • 1
##Example protocol buffer相關使用的例子
#將mnist的資料轉換為TFRecords檔案格式
import os
import tensorflow as tf
from tensorflow.contrib.learn.python.learn.datasets import mnist
SOURCE_URL = 'http://yann.lecun.com/exdb/mnist/'

TRAIN_IMAGES = 'train-images-idx3-ubyte.gz'  # MNIST filenames
TRAIN_LABELS = 'train-labels-idx1-ubyte.gz'
TEST_IMAGES = 't10k-images-idx3-ubyte.gz'
TEST_LABELS = 't10k-labels-idx1-ubyte.gz'

tf.app.flags.DEFINE_string('directory', '/tmp/data',
                           'Directory to download data files and write the '
                           'converted result')
tf.app.flags.DEFINE_integer('validation_size', 5000,
                            'Number of examples to separate from the training '
                            'data for the validation set.')
FLAGS = tf.app.flags.FLAGS

def _int64_feature(value):
  return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))

def _bytes_feature(value):
  return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))

def convert_to(data_set, name):
  images = data_set.images
  labels = data_set.labels
  num_examples = data_set.num_examples

  if images.shape[0] != num_examples:
    raise ValueError('Images size %d does not match label size %d.' %
                     (images.shape[0], num_examples))
  rows = images.shape[1]
  cols = images.shape[2]
  depth = images.shape[3]

  filename = os.path.join(FLAGS.directory, name + '.tfrecords')
  print('Writing', filename)
  writer = tf.python_io.TFRecordWriter(filename)
  for index in range(num_examples):
    image_raw = images[index].tostring()
    example = tf.train.Example(features=tf.train.Features(feature={
        'height': _int64_feature(rows),
        'width': _int64_feature(cols),
        'depth': _int64_feature(depth),
        'label': _int64_feature(int(labels[index])),
        'image_raw': _bytes_feature(image_raw)}))
    writer.write(example.SerializeToString())
  writer.close()

def main(argv):
  # Get the data.
  data_sets = mnist.read_data_sets(FLAGS.directory,
                                   dtype=tf.uint8,
                                   reshape=False)

  # Convert to Examples and write the result to TFRecords.
  convert_to(data_sets.train, 'train')
  convert_to(data_sets.validation, 'validation')
  convert_to(data_sets.test, 'test')

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

* 佇列(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
# 一個簡單例子,使用tf.train.shuffle_batch建立一個具有32張影像和32個標籤的batches.
image_batch, label_batch = tf.train.shuffle_batch(
      [single_image, single_label],
      batch_size=32,
      num_threads=4,
      capacity=50000,
      min_after_dequeue=10000)
  • 1
#Batching函式相關例子,以函式tf.train.shuffle_batch為例
#為training, evaluation等操作將樣本batching,以下程式碼使用隨機順序打包樣本
def read_my_file_format(filename_queue):
  reader = tf.SomeReader()
  key, record_string = reader.read(filename_queue)
  example, label = tf.some_decoder(record_string)
  processed_example = some_processing(example)
  return processed_example, label

def input_pipeline(filenames, batch_size, num_epochs=None):
  filename_queue = tf.train.string_input_producer(
      filenames, num_epochs=num_epochs, shuffle=True)
  example, label = read_my_file_format(filename_queue)
  # min_after_dequeue defines how big a buffer we will randomly sample
  #   from -- bigger means better shuffling but slower start up and more
  #   memory used.
  # capacity must be larger than min_after_dequeue and the amount larger
  #   determines the maximum we will prefetch.  Recommendation:
  #   min_after_dequeue + (num_threads + a small safety margin) * batch_size
  min_after_dequeue = 10000
  capacity = min_after_dequeue + 3 * batch_size
  example_batch, label_batch = tf.train.shuffle_batch(
      [example, label], batch_size=batch_size, capacity=capacity,
      min_after_dequeue=min_after_dequeue)
  return example_batch, label_batch
  • 1
#如果需要跟多的並行或檔案之間的樣本亂序操作,可以使用函式tf.train.shuffle_batch_join多例項化reader
def read_my_file_format(filename_queue):
  # 與上例子相同

def input_pipeline(filenames, batch_size, read_threads, num_epochs=None):
  filename_queue = tf.train.string_input_producer(
      filenames, num_epochs=num_epochs, shuffle=True)
  example_list = [read_my_file_format(filename_queue)
                  for _ in range(read_threads)]
  min_after_dequeue = 10000
  capacity = min_after_dequeue + 3 * batch_size
  example_batch, label_batch = tf.train.shuffle_batch_join(
      example_list, batch_size=batch_size, capacity=capacity,
      min_after_dequeue=min_after_dequeue)

相關文章