上一篇:TensorFlow常用函数(一)
1、tf.meshgrid()
2、tf.stack()、tf.vstack()、tf.hstack()
3、tf.transpose() : 对tensor进行转置
4、tf.maximum()、tf.minimum()
5、tf.image.non_max_suppression():非极大抑制算法
6、tf.gather():可以把向量中某些索引值提取出来,得到新的向量,适用于要提取的索引为不连续的情况。这个函数似乎只适合在一维的情况下使用。
7、tf.py_func():将函数包装成一个操作符
8、tf.map_fn(fn, elems):接受一个函数对象,然后用该函数对象对集合(elems)中的每一个元素分别处理:
9、tf.slice():从列表、数组、张量等对象中抽取一部分数据
10、tf.split(input,num_split,dimension):拆分tensor
11、tf.concat(values, axis,name='concat') : 连接两个tensor
12、tf.image.crop_and_resize() : RoI池化函数,该函数从输入图像里裁剪出一部分区域然后再重新缩放并返回处理后的图像。
13、tf.losses.get_regularization_losses():获取权重正则化损失,返回正则化损失列表
14、tf.add_to_collection(‘list_name’, element): 将元素element添加到列表list_name中 tf.get_collection(‘list_name’): 返回名称为list_name的列表 tf.add_n(list): 将列表元素相加并返回
15、tf.squeeze():从张量形状中移除大小为1的维度,和np.squeeze()的功能相同。
16、tf.expand_dims(Tensor, dim) : 为张量+1维。
17、tf.assign():给变量重新赋值
18、tf.app.flags:用于支持接受命令行传递参数,相当于接受argv。
19、tf.train.batch():该函数会创建一个队列,然后读取一定数量的tensor送入队列,然后每次从队列中选取batch_size个tensors组成一个新的tensors返回回来。
20、tf.train.shuffle_batch():函数类似于上面的tf.train.batch(),同样创建一个队列,主要区别是会首先把队列中的张量进行乱序处理,然后再选取其中的batch_size个张量组成一个新的张量返回。
下一篇:TensorFlow常用函数(三)
1、tf.meshgrid()
meshgrid用于从数组a和b产生网格。生成的网格矩阵A和B大小是相同的。它也可以是更高维的。用法: [A,B]=Meshgrid(a,b),生成size(b)Xsize(a)大小的矩阵A和B。它相当于a从一行重复增加到size(b)行,把b转置成一列再重复增加到size(a)列。
a=[0,5,10]
b=[0,5,15,20,25]
A,B=tf.meshgrid(a,b)
with tf.Session() as sess:
print (A.eval())
print (B.eval())
结果:
[[ 0 5 10]
[ 0 5 10]
[ 0 5 10]
[ 0 5 10]
[ 0 5 10]]
[[ 0 0 0]
[ 5 5 5]
[15 15 15]
[20 20 20]
[25 25 25]]
2、tf.stack()、tf.vstack()、tf.hstack()
a=np.array([1,2,3])
b=np.array([4,5,6])
print (np.stack([a,b],axis=1))
[[1 4]
[2 5]
[3 6]]
print (np.stack([a,b],axis=0))
[[1 2 3]
[4 5 6]]
print (np.vstack([a,b])) # 沿着行方向堆叠,增加行数,阵列必须具有相同的形状
[[1 2 3]
[4 5 6]]
print (np.hstack([a,b])) # 沿着列方向堆叠,增加列数,阵列必须具有相同的形状
[1 2 3 4 5 6]
3、tf.transpose() : 对tensor进行转置
a=tf.constant([[1,2,3],[4,5,6]])
b=tf.constant([ [[1,2,3],[4,5,6]], [[7,8,9],[10,11,12]] ])
with tf.Session() as sess:
print (tf.transpose(a,[1,0]).eval()) # 2*3-->3*2
[[1 4]
[2 5]
[3 6]]
print (tf.transpose(b,[2,0,1]).eval()) # 2*2*3-->3*2*2,先找出(1,4,7,10)然后组成2*2的形状
[[[ 1 4]
[ 7 10]]
[[ 2 5]
[ 8 11]]
[[ 3 6]
[ 9 12]]]
print (tf.transpose(b,[1,0,2]).eval()) # 2*2*3-->2*2*3,三元组看做一个整体,类似二维的转置。
[[[ 1 2 3]
[ 7 8 9]]
[[ 4 5 6]
[10 11 12]]]
4、tf.maximum()、tf.minimum()
tf.maximum:用法tf.maximum(a,b),返回的是a,b之间的最大值,
tf.minimum:用法tf.minimum(a,b),返回的是a,b之间的最小值
5、tf.image.non_max_suppression():非极大抑制算法
函数原型:tf.image.non_max_suppression(boxes,scores,max_output_size,iou_threshold=0.5,name=None)
boxes: 一个2-D浮点型Tensor,它的形状为:[num_boxes, 4].
scores: 一个1-D 浮点型,它的形状为:[num_boxes],它表示每个box的得分
max_output_size: 一个张量,代表非极大抑制后保存的boxes数量
iou_threshold: IoU的阈值
name: 操作名(可选)
6、tf.gather():可以把向量中某些索引值提取出来,得到新的向量,适用于要提取的索引为不连续的情况。这个函数似乎只适合在一维的情况下使用。
a = tf.Variable([[1,2,3,4,5], [6,7,8,9,10], [11,12,13,14,15]])
index_a = tf.Variable([0,2])
b = tf.Variable([1,2,3,4,5,6,7,8,9,10])
index_b = tf.Variable([2,4,6,8])
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(tf.gather(a, index_a)))
print(sess.run(tf.gather(b, index_b)))
输出:
[[ 1 2 3 4 5]
[11 12 13 14 15]]
[3 5 7 9]
7、tf.py_func():将函数包装成一个操作符
函数原型:py_func(function,input param,output type,stateful=True,name=None)
注意:tf.py_func在定义多输出函数时,输出变量类型需要用[ ]框起来;
tf.py_func在定义单输出函数时,输出变量类型不能再用[ ]框起来;
8、tf.map_fn(fn, elems):接受一个函数对象,然后用该函数对象对集合(elems)中的每一个元素分别处理:
def preprocessing_image(image, training):
image = ...
return image
def preprocessing_images(images, training):
images = tf.map_fn(lambda image: preprocessing_image(image, training), images)
return images
9、tf.slice():从列表、数组、张量等对象中抽取一部分数据
函数原型:tf.slice(input_, begin, size, name = None):
begin:表示从inputs的哪几个维度上的哪个元素开始抽取
size:表示在inputs的各个维度上抽取的元素个数
begin和size是两个多维列表,他们共同决定了要抽取的数据的开始和结束位置,若begin[]或size[]中出现-1,表示抽取对应维度上的所有元素。
x=[[1,2,3],[4,5,6]]
with tf.Session() as sess:
begin = [0,1] # 从x[0,1],即元素2开始抽取
size = [2,1] # 从x[0,1]开始,对x的第一个维度(行)抽取2个元素,即出[1,2,3]和[4,5,6]两行,再对这两行的每行取1个元素
print sess.run(tf.slice(x,begin,size)) # 输出[[2 5]]
10、tf.split(input,num_split,dimension):拆分tensor
dimension:意思就是输入张量的哪一个维度,如果是0就表示对第0维度进行切割。
num_split:切割的数量,如果是2就表示输入张量被切成2份,每一份是一个列表。
针对上节中a这个张量[ [ [11. 21. 31.] [41. 51. 61.] ] ]
1)第0维有一个1个元素,因此不能拆分。
2)第1维有2个元素可以拆分为2份:tf.split(a,2,1)
[array([[[11., 21., 31.]]], dtype=float32), array([[[41., 51., 61.]]], dtype=float32)]
3)第2维有3个元素可以拆分为3份:tf.split(tx,3,2)
[ array([[[11.], [41.]]], dtype=float32),
array([[[21.], [51.]]], dtype=float32),
array([[[31.], [61.]]], dtype=float32) ]
注意:拆分不影响原来tensor的维度,原来的tensor是3维的,现在也是三维的。
11、tf.concat(values, axis,name='concat') : 连接两个tensor
axis:必须是一个数,表明在哪一维上连接
values: 一个Tensor对象的列表
如果concat_dim是0,那么在某一个shape的第一个维度上连,对应到实际,就是叠放到列上
t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
tf.concat(0, [t1, t2]) == > [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]],2*3-->4*3
如果concat_dim是1,那么在某一个shape的第二个维度上连
t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
tf.concat(1, [t1, t2]) ==> [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12],2*3-->2*6
12、tf.image.crop_and_resize() : RoI池化函数,该函数从输入图像里裁剪出一部分区域然后再重新缩放并返回处理后的图像。
形参:(image, boxes, box_ind, crop_size, method="bilinear", extrapolation_value=0, name=None)
image:shape为[batch, image_height, image_width, depth]且其dtype只能为`uint8`, `int8`, `int16`, `int32`, `int64`, `half`, `float32`, `float64`其一;
boxes:一系列标注框其shape为[num_boxes, 4],每个标注框的数据对应坐标为[y1, x1, y2, x2],函数将以标注框来裁剪部分区域;
box_ind:指定引用标注框里的哪一个坐标系,其shape为[num_boxes];
crop_size:裁剪区域要缩放的大小,形如size = [crop_height, crop_width],所有裁剪区域均被缩放到此大小;
method:图像缩放所采用的插值方法,目前仅支持bilinear;
extrapolation_value:预留;
return:dtype为float32且其shape为[num_boxes, crop_height, crop_width, depth]的4-D张量,得到的是一系列定义区域统一缩放后的一批图像;
13、tf.losses.get_regularization_losses():获取权重正则化损失,返回正则化损失列表
tensorflow中对参数使用正则项分为两步:
(1). 创建一个正则方法(函数/对象)
(2). 将这个正则方法(函数/对象),应用到参数上
如何创建一个正则方法函数
1) tf.contrib.layers.l1_regularizer(scale, scope=None):返回一个用来执行L1正则化的函数,函数的签名是func(weights).
2) tf.contrib.layers.l2_regularizer(scale, scope=None):返回一个执行L2正则化的函数.
3) tf.contrib.layers.sum_regularizer(regularizer_list, scope=None):返回一个可以执行多种(个)正则化的函数.意思是,创建一个正则化方法,这个方法是多个正则化方法的混合体.regularizer_list为regulizer的列表。
在使用tf.get_variable()和tf.variable_scope()的时候,你会发现,它们俩中有regularizer形参.如果传入这个参数的话,那么variable_scope内的weights的正则化损失,或者weights的正则化损失就会被添加到GraphKeys.REGULARIZATION_LOSSES中.
regularizer = layers.l1_regularizer(0.1)
with tf.variable_scope('var', initializer=tf.random_normal_initializer(),
regularizer=regularizer):
weight = tf.get_variable('weight', shape=[8], initializer=tf.ones_initializer())
with tf.variable_scope('var2', initializer=tf.random_normal_initializer(),
regularizer=regularizer):
weight2 = tf.get_variable('weight', shape=[8], initializer=tf.ones_initializer())
regularization_loss = tf.reduce_sum(tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES))
# 或者为:
regularization_loss = tf.add_n(tf.losses.get_regularization_losses(), 'regu')
14、tf.add_to_collection(‘list_name’, element): 将元素element添加到列表list_name中
tf.get_collection(‘list_name’): 返回名称为list_name的列表
tf.add_n(list): 将列表元素相加并返回
例子:
import tensorflow as tf
tf.add_to_collection('losses', tf.constant(2.2))
tf.add_to_collection('losses', tf.constant(3.))
with tf.Session() as sess:
print(sess.run(tf.get_collection('losses')))
print(sess.run(tf.add_n(tf.get_collection('losses'))
输出:
[2.2, 3.0]
5.2
注意:
使用tf.add_n对列表元素进行相加时,列表内元素类型必须一致,否则会报错。
15、tf.squeeze():从张量形状中移除大小为1的维度,和np.squeeze()的功能相同。
函数原型:squeeze(input,axis=None,name=None,squeeze_dims=None)
axis:一个可选列表ints。默认为[]。如果指定,只能挤压列出的尺寸。维度索引从0开始。压缩非1的维度是错误的。必须在范围内[-rank(input), rank(input))。
name:操作的名称(可选)。
squeeze_dims:现在是轴的已弃用的关键字参数。
给定一个张量 input,该操作返回一个与已经移除的所有大小为1的维度具有相同类型的张量。如果您不想删除所有大小为1的维度,则可以通过指定 axis 来删除特定的大小为1的维度。
假设 't' is a tensor of shape [1, 2, 1, 3, 1, 1]
tf.shape(tf.squeeze(t))
结果:
[2, 3]
或者,要删除特定的大小为1的维度:
假设 't' is a tensor of shape [1, 2, 1, 3, 1, 1]
tf.shape(tf.squeeze(t, [2, 4]))
结果:
[1, 2, 3, 1]
16、tf.expand_dims(Tensor, dim) : 为张量+1维。
官网的例子:’t’ is a tensor of shape [2]
shape(expand_dims(t, 0)) ==> [1, 2]
shape(expand_dims(t, 1)) ==> [2, 1]
shape(expand_dims(t, -1)) ==> [2, 1]
sess = tf.InteractiveSession()
labels = [1,2,3]
x = tf.expand_dims(labels, 0)
print(sess.run(x))
x = tf.expand_dims(labels, 1)
print(sess.run(x))
#>>>[[1 2 3]]
#>>>[[1]
# [2]
# [3]]
17、tf.assign():给变量重新赋值
函数原型:tf.assign(ref, value, validate_shape=None, use_locking=None, name=None)
函数完成了将value赋值给ref的作用。其中:ref 必须是tf.Variable创建的tensor,如果ref=tf.constant()会报错!同时,shape(value)==shape(ref)。实例如下:
# 声明学习率为不可训练
learning_rate = tf.Variable(float(learning_rate), trainable=False, dtype=tf.float32)
# 学习率递减操作,这里表示每次学习率变成上一次的0.9倍
learning_rate_decay_op = learning_rate.assign(learning_rate * 0.9)
#训练过程中根据loss情况来执行学习率递减操作
if ....: #这里设置一个需要衰减学习率的条件
sess.run(learning_rate_decay_op)
18、tf.app.flags:用于支持接受命令行传递参数,相当于接受argv。
import tensorflow as tf
#第一个是参数名称,第二个参数是默认值,第三个是参数描述
tf.app.flags.DEFINE_string('str_name', 'def_v_1',"descrip1")
tf.app.flags.DEFINE_integer('int_name', 10,"descript2")
tf.app.flags.DEFINE_boolean('bool_name', False, "descript3")
FLAGS = tf.app.flags.FLAGS
#必须带参数,否则:'TypeError: main() takes no arguments (1 given)'; main的参数名随意定义,无要求
def main(_):
print(FLAGS.str_name)
print(FLAGS.int_name)
print(FLAGS.bool_name)
if __name__ == '__main__':
tf.app.run() #执行main函数
[root@AliHPC-G41-211 test]# python tt.py
def_v_1
10
False
[root@AliHPC-G41-211 test]# python tt.py --str_name test_str --int_name 99 --bool_name True
test_str
99
True
19、tf.train.batch():该函数会创建一个队列,然后读取一定数量的tensor送入队列,然后每次从队列中选取batch_size个tensors组成一个新的tensors返回回来。
函数原型:
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 :送入队列的 tensors 列表或字典. tf.train.batch 函数返回值是相同类型的 tensors.
batch_size :从队列拉取的样本的 batch size
num_threads : 使tensors入队的线程数. 如果 num_thread>1,它们将从不同文件不同位置同时读取,可以更加充分的混合训练样本。
capacity : 整数,队列容量,队列里样本元素的最大数.
enqueue_many :bool型, 如果enqueue_many参数为False,则输入参数tensors为一个形状为[x, y, z]的张量,输出为一个形状为[batch_size, x, y, z]的张量。如果enqueue_many参数为True,则输入参数tensors为一个形状为[*, x, y, z]的张量,其中所有*的数值相同,输出为一个形状为[batch_size, x, y, z]的张量
shapes :(可选)每个样本的 shape. 默认是 tensors 的shapes.
dynamic_pad : Boolean 值. 如果为True,则允许输入shapes的维度的维度是可变的,出队后会自动填补维度,以保持batch内的tensor有相同的shape。
allow_smaller_final_batch : (可选) Boolean 值. 当allow_smaller_final_batch为True时,如果队列中的张量数量不足batch_size,将会返回小于batch_size长度的张量,如果为False,剩下的张量会被丢弃。
shard_name :(可选). 如果设置了该参数,则在多个会话给定的名字时,共享队列.
name – (可选). 操作operations 的名字.
该函数的输入 tensors 是张量tensors列表或字典,且函数返回相同类型的 tensors。该函数采用队列queue 来实现.,队列的 QueueRunner 被添加到当前 Grahp 的 QUEUE_RUNNER 集合(collection) 中。如果 enqueue_many=False,则 tensor 表示单个样本.对于 shape 为 [x, y, z] 的输入 tensor,该函数输出的shape 为 [batch_size, x, y, z] 的 tensor。如果 enqueue_many=True,则 tensors 表示 batch 个样本,其中,第一维表示样本的索引,所有的 tensors 都在第一维具有相同的尺寸.对于 shape 为 [*, x, y, z] 的输入 tensor,该函数输出为shape 为 [batch_size, x, y, z] 的 tensor。capacity 参数控制着预取队列的长度,即队列容量。如果输入队列用完,则返回 tf.errors.OutofRangeError。如果 dynamic_pad=False,则必须保证 shapes 参数被传递,或 tensors 内的所有张量必须已经预定义 shapes. 否则,会出现 ValueError.如果 dynamic_pad=True,则张量的秩已知即可,但独立维度的 shape 为 None. 此时,每次入队时,维度为 None 的值的长度是可变的. 出队后,输出的 tensors 会根据当前 minibatch 内的 tensors 的最大 shape 来在右边自动补零. 对于数字 tensors,填补的值为 0;对于字符串 tensors,填补的是空字符。如果 allow_smaller_final_batch=True,当队列关闭时,如果没有足够的样本元素来填补 batch,则会返回比 batch_size 更小的 batch 值,否则会丢弃样本元素.
from PIL import Image
from scipy.misc import imread,imsave,imresize
import cv2
import numpy as np
import tensorflow as tf
def generate_data():
num = 25
label = np.asarray(range(0, num))
images = np.random.random([num, 5, 5, 3])
print('label size :{}, image size {}'.format(label.shape, images.shape))
return label, images
def get_batch_data():
label, images = generate_data()
images = tf.cast(images, tf.float32)
label = tf.cast(label, tf.int32)
input_queue = tf.train.slice_input_producer([images, label], shuffle=False)
image_batch, label_batch = tf.train.batch(input_queue, batch_size=10, num_threads=1, capacity=20)
return image_batch, label_batch
image_batch, label_batch = get_batch_data()
with tf.Session() as sess:
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess, coord)
i = 0
try:
while not coord.should_stop():
image_batch_v, label_batch_v = sess.run([image_batch, label_batch])
i += 1
for j in range(10):
print(image_batch_v.shape, label_batch_v[j])
except tf.errors.OutOfRangeError:
print("done")
finally:
coord.request_stop()
coord.join(threads)
20、tf.train.shuffle_batch():函数类似于上面的tf.train.batch(),同样创建一个队列,主要区别是会首先把队列中的张量进行乱序处理,然后再选取其中的batch_size个张量组成一个新的张量返回。
函数原型:
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
)
capacity参数依然为队列的长度,建议capacity的取值如下:
min_after_dequeue + (num_threads + a small safety margin) * batch_size
min_after_dequeue这个参数的意思是队列中,做dequeue(取数据)的操作后,线程要保证队列中至少剩下min_after_dequeue个数据。如果min_after_dequeue设置的过少,则即使shuffle为True,也达不到好的混合效果。