Tensor用于在图中进行数据传递,是Tensorflow中最基本的数据结构。
张量生成方法:
作为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一般用来表示图中各个计算参数,包括矩阵和向量等。创建变量应使用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用于表示输入输出数据的格式,允许传入指定类型和形状的数据,占位符仅仅声明了数据位置,告诉系统治理有一个值、向量或者矩阵等,现在还没给出具体数值。占位符会通过会话的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是TensorFlow中计算图的执行者,与图进行实际交互,一个会话可有多个图。
Session的主要目的:
Session的调用方式:
sess = tf.Session()
sess.run(...)
sess.close #记得要释放资源
with tf.Session() as sess:
sess.run(...)
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类型:
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即队列管理器,在Tensorflow运行时,由于涉及到硬件资源包括CPU、GPU、内存、以及读取数据时使用的其他硬件资源,因为涉及了磁盘操作,所以后者的速度将远远低于前者。因此,在实际操作中,通常使用多个线程读取数据,然后使用一个线程使用数据。使用QueueRunner可管理这些读写队列的线程。
QueueRunner的使用:
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(协调器)来处理。
具体流程为:
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) #等待线程结束
参考资料: