TensorFlow常用函数总结(二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/MOU_IT/article/details/82083984

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个样本

 函数原型: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,则 batch 操作是非确定的.
    capacity – 整数,队列容量,队列里样本元素的最大数.
    enqueue_many – tensors 内的每个 tensor 是否是单个样本.
    shapes – (可选)每个样本的 shape. 默认是 tensors 的shapes.
    dynamic_pad – Boolean 值. 输入 shapes 的变量维度. 出队后会自动填补维度,以保持batch内 shapes 一致.
    allow_smaller_final_batch – (可选) Boolean 值. 如果队列中样本不足 batch,允许最后的 batch 样本数小于 batch_size.
    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 参数控制着预取队列的长度(how long the prefetching is allowed to grow the queues),队列容量.如果输入队列用完,则返回 tf.errors.OutofRangeError.如果 dynamic_pad=False,则必须保证 shapes 参数被传递,或 tensors 内的所有张量必须已经预定义 shapes. 否则,会出现 ValueError.如果 dynamic_pad=True,则张量的秩已知即可,但独立维度的 shape 为 None. 此时,每次入队时,维度为 None 的值的长度是可变的. 出队后,输出的 tensors 会根据当前 minibatch 内的 tensors 的最大 shape 来在右边自动补零. 对于数字 tensors,填补的值为 0;对于字符串 tensors,填补的是空字符. 可见 PaddingFIF0Queue.如果 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)

猜你喜欢

转载自blog.csdn.net/MOU_IT/article/details/82083984