【TensorFlow】基本概念篇

文章目录

  • Tensor(张量)
  • Variable(变量)
  • Placeholder(占位符)
  • Session(会话)
  • Operation(操作)
  • Queue(队列)
    • QueueRunner(队列管理器)
    • Coordinator(协调器:线程之间的同步)

Tensor(张量)

Tensor用于在图中进行数据传递,是Tensorflow中最基本的数据结构。

张量生成方法:

  1. 固定张量:例如,tf.zeros、tf.ones、tf.fill、tf.constant
  2. 相似张量:例如,tf.zeros_like、tf.ones_like
  3. 序列张量:例如,tf.linspace(指定区间,等间距)、tf.range(指定区域、间隔)
  4. 分布函数张量:例如,tf.random_uniform(均匀分布随机数)、tf.random_normal(正态分布随机数)、tf.truncated_normal(指定边界正态分布)。

作为tensorflow中的正态分布产生函数,tf.truncated_normal和tf.random_normal的输入参数几乎完全一致,其主要区别在于:tf.truncated_normal输出截断,截断是2倍的stddev,例如:当输入mean=0,stddev=1时,使用tf.truncated_normal的输出是不可能出现[-2,2]以外的点的,而如果shape够大的话,tf.random_normal却会产生出2.2或者2.4之类的输出。

import tensorflow as tf
row = 3.0
col = 4.0
zero_tsr = tf.zeros([row,col])
ones_tsr = tf.ones([row,col])
fill_tsr = tf.fill([3,4],20)
constant_tsr = tf.constant([1,2,3])
zeros_similar = tf.zeros_like(constant_tsr)
ones_similar = tf.ones_like(constant_tsr)
liner_tsr = tf.linspace(start=0.0,stop=2.0,num=3)
integer_seq_tsr = tf.range(start=0,limit=5,delta=1)
randunif_tsr = tf.random.uniform([3,4],minval=0,maxval=2)
randnorm_tsr = tf.random.normal([3,4],mean=0.0,stddev=1.0)
truncate_tsr = tf.truncated_normal([3,4],mean=.0,stddev=1.0)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(liner_tsr))
print(sess.run(integer_seq_tsr))
print(sess.run(randunif_tsr))
print(sess.run(truncate_tsr))

Variable(变量)

Variable一般用来表示图中各个计算参数,包括矩阵和向量等。创建变量应使用tf.Variable()函数,通过输入一个张量,返回一个变量。变量声明后需要进行初始化才能够使用。

注意:类似tf.zeros()这种张量可以不用初始化,而变量是需要初始化的

import tensorflow as tf
tensor = tf.zeros([1,2])
m_var = tf.Variable(tensor)
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
    print('tensor is',sess.run(tensor))
    sess.run(init_op) #如果不初始化,在打印变量时就会报错
    print('m_var',sess.run(m_var))

Placeholder(占位符)

placeholder用于表示输入输出数据的格式,允许传入指定类型和形状的数据,占位符仅仅声明了数据位置,告诉系统治理有一个值、向量或者矩阵等,现在还没给出具体数值。占位符会通过会话的feed_dict参数获取数据,在计算图运行时使用获取的数据进行计算,计算完毕后获取的数据就会消失。

import tensorflow as tf
x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)
z = tf.add(x,y)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(z,{x:[2,3],y:[1,-1]}))
sess.close()

Session(会话)

Session是TensorFlow中计算图的执行者,与图进行实际交互,一个会话可有多个图

Session的主要目的:

  1. 将训练数据添加到图中进行计算
  2. 修改图的结构

Session的调用方式:

  1. 明确调用会话的生成函数和关闭函数
sess = tf.Session()
sess.run(...)
sess.close #记得要释放资源
  1. 上下文管理机制自动释放所有资源,这种方式不需要再调用sess.close()来释放资源。
with tf.Session() as sess:
	sess.run(...)

Operation(操作)

operation即操作,是TensorFlow中的节点,它的输入和输出都是Tensor。
主要操作

操作组 操作
数学运算操作 Add、Sub、Mul、Div、Exp、Log、Greater、Less、Equal
数组运算操作 Concat、Slice、Split、Constant、Rank、Shape、Shuffle
矩阵运算操作 MatMul、MatrixInverse、MatrixDeterminant
神经网络构建操作 Softmax、Sigmoid、ReLU、Convolution2D、MaxPool
检查点操作 Save、Restore
队列和同步操作 Enqueue、Dequeue、MutexAcquire、MutexRelease
张量控制操作 Merge、Switch、Enter、Leave、NextIteration

Queue(队列)

Queue的主要操作:

  1. enqueue操作返回计算图中的一个Operation节点
  2. dequeue操作返回一个Tensor值

Queue类型:

  1. 按入对顺序出列:FIFOQueue,在需要读入的训练样本有序时使用。
  2. 随机队列:RandomShuffleQueue,在训练样本无序时使用。
import tensorflow as tf
q1 = tf.FIFOQueue(10,'float')
init1 = q1.enqueue_many(([1.0,2.0,3.0,4.0,5.0,6.0],))
#min_after_dequeue表示的是出队后的最小长度
q2 = tf.RandomShuffleQueue(capacity=10,min_after_dequeue=0,dtypes='float')
init2 = q2.enqueue_many(([1.0,2.0,3.0,4.0,5.0,6.0],))
with tf.Session() as sess:
    sess.run(init1)
    quelen1 = sess.run(q1.size())
    for i in range(quelen1):
        print('q',sess.run(q1.dequeue()))
    sess.run(init2)
    quelen2 = sess.run(q2.size())    
    for i in range(quelen2):
        print('random_q',sess.run(q2.dequeue()))

在RandomShuffleQueue中,我们定义了队列程度以及出队后的最小长度,当队列长度等于min_after_dequeue时,不再执行出队操作,如果此时还要求执行出队操作,就会发生阻断。同理,当队列长度等于最大值时,还要求入队操作也会发生阻断。

import tensorflow as tf
q = tf.RandomShuffleQueue(10,min_after_dequeue=2,dtypes='float')
init = q.enqueue_many(([1.0,2.0,3.0,4.0,5.0,6.0],))
#定义10s超时
run_options = tf.RunOptions(timeout_in_ms=10000)
with tf.Session() as sess:
    sess.run(init)
    quelen = sess.run(q.size())
    for i in range(quelen):
        try:
            print('q',sess.run(q.dequeue(),options=run_options))
        except tf.errors.DeadlineExceededError:
            print('time out')

QueueRunner(队列管理器)

QueueRunner即队列管理器,在Tensorflow运行时,由于涉及到硬件资源包括CPU、GPU、内存、以及读取数据时使用的其他硬件资源,因为涉及了磁盘操作,所以后者的速度将远远低于前者。因此,在实际操作中,通常使用多个线程读取数据,然后使用一个线程使用数据使用QueueRunner可管理这些读写队列的线程。

QueueRunner的使用:

  1. 创建QueueRunner需要使用方法tf.train.QueueRunner._init_ (queue,enqueue_ops),其中,queue代表指定的队列,enqueue_ops代表指定的操作,一般都是多个操作,每个操作会使用一个线程。
  2. 声明QueueRunner队列管理器后,还需要使用tf.train.QueueRunner.create_threads(sess,coord=None,daemon=False,start=False)创建线程来具体执行队列管理操作。
import tensorflow as tf
q = tf.FIFOQueue(10,'float')
counter = tf.Variable(0.0)
increment_op = tf.assign_add(counter,1.0) #
enqueue_op = q.enqueue(counter) #

qr = tf.train.QueueRunner(q,enqueue_ops=[increment_op,enqueue_op]*1)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    qr.create_threads(sess,start=True) #启动队列管理器
    for i in range(8):
        print(sess.run(q.dequeue()))

输出:

5.0
17.0
25.0
41.0
52.0
56.0
62.0
69.0
ERROR:tensorflow:Exception in QueueRunner: Session has been closed.
ERROR:tensorflow:Exception in QueueRunner: Session has been closed.

显然,输出的结果并非自然数列,这是因为计数器自增操作和入队操作在不同线程中,且不同步,可能计数器自增操作执行了很多次后,才进入一个入队操作。
另一方面,最后程序报错了,是因为主程序的出队操作和线程中的入队操作是异步的。当出队结束后,主程序结束,自动关闭了会话,都是入队线程并没有结束,所以程序报错。而如果显式的采用sess.run()和sess.close()方法,则整个程序最后会产生阻断,无法结束。

Coordinator(协调器:线程之间的同步)

为了实现线程之间的同步,使用Coordinator(协调器)来处理。
具体流程为:

  • QueueRunner(queue,ops)
  • QueueRunner.create_threads(sess,coord,deamon,start) #指定一个协调器
  • Coordinator.request_stop()通知所有的线程停止当前线程,并迭代其他线程返回结果。
  • Coordinator.join(queue_thread) #等待线程结束
import tensorflow as tf
q = tf.FIFOQueue(10,'float')
counter = tf.Variable(0.0)
increment_op = tf.assign_add(counter,1.0)
enqueue_op = q.enqueue(counter)
coord = tf.train.Coordinator()
qr = tf.train.QueueRunner(q,enqueue_ops=[increment_op,enqueue_op]*1)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    queue_thread = qr.create_threads(sess,coord=coord,start=True)#指定协调器
    for i in range(8):
        print(sess.run(q.dequeue()))
    coord.request_stop() #通知线程关闭
    coord.join(queue_thread) #等待线程结束

参考资料:

  1. https://blog.csdn.net/u014687582/article/details/78027061
  2. 《Python+TensorFlow机器学习实战》

你可能感兴趣的:(TensorFlow)