如何在tensorflow中判断tensor(张量)的值

   众所周知,在tensorflow程序中,tensor只是占位符,在会话层没有run出tensor的值之前,我们是无法获知tensor的值的(不过笔者听说tensorflow要改良这一机制,将tensor转化为可以判断值的数据结构-flag:2017.11.13)。也就是说,下面的逻辑是无法实现的:

#a is a 1-D tensor, b is a 1-D tensor too.
if a == b:
    #take some actions...
else:
    #take some other actions...

   可是,我们在程序中有可能需要根据tensor的值作出判断,以采取不同的操作。笔者就曾经遇到过这种问题,笔者在构造一个网络时,网络的输入为两个tensor,在这里分别称为a和b,需要根据b的值对a采取不同的操作。可是,在程序中是无法通过逻辑语句去判断tensor b的值的。那么,我们应该怎么办呢?

   对于这个问题,tensorflow官方已经为我们提供了一个能满足功能的接口,即tf.cond,如下图所示。


   tf.cond函数7个参数,其中有2个参数已经被弃用(fn1和fn2,这两个参数的功能被true_fn和false_fn取代),剩余的5个参数中,常用的是前三个,第一个参数pred是一个判断条件,返回一个True或者False的Tensor,程序会根据pred去执行true_fn或者false_fn。

   可以请大家看看tensorflow官方提供的样例,如下图所示。


   不过,笔者想提醒大家注意两点:

   1. tf.cond函数接收的true_fn和false_fn是不带参数的,那么,对于这两个函数的实现,对于逻辑简单的情况,可以采用匿名函数的形式,即lamda表达式,如下所示:

z = tf.multiply(a, b)
result = tf.cond(x < y, lambda: tf.add(x, z), lambda: tf.square(y))

    如果对于复杂一些的情况,由于函数true_fn和false_fn并不接受参数的输入,那么,我们可以使用嵌套函数的做法。因为嵌套函数引用的变量可以从被嵌套的函数中查找。比如,笔者就是这样做的:

def main():
    img = tf.placeholder(tf.float32, shape = [1, 256, 256, 3], name = "image")
    flag = tf.placeholder(tf.int32, shape = (), name = "switch")
	
    def true_proc():
        result = img/2.
        return result
		
    def false_proc():
	result = img/3.
	return result
		
    standard = tf.constant(value = 1, dtype = tf.int32)
    img_proc_result = tf.cond(pred = tf.equal(flag, standard), true_fn = true_proc, false_fn = false_proc)
    在上面的代码中,根据flag的值会做出不同的操作。而笔者定义的true_proc和false_proc中,对img中的每个值分别进行了除以2.0和3.0的操作。使用嵌套函数,将true_proc函数和false_proc函数嵌套在main函数里面,可以使得在main函数中定义的img这个tensor的作用域完全覆盖true_proc和false_proc。这样,我们在使用tf.cond的时候,调用true_fn与false_fn的时候,就可以不传入任何参数。

   2. 对于true_fn和false_fn的返回值,要求必须返回值的数量(非零)与数据类型完全相同,这样做的原因是,tensorflow的会话层(tf.Session())在进行run操作之前,是需要建立数据流图的(Graph),在数据流图建立之后,所有数据的类型与维度就已经被确定并在显存/内存中占好了位置。而tf.cond函数的返回值会被加入数据流图之中,而tf.cond的返回值依赖于true_fn或者false_fn。因此,无论执行true_fn还是false_fn,两者返回值的数量与数据类型必须保持一致。



   除了上面讲解的tf.cond进行判值,还可以在tf.py_func中将tensor转化成numpy array进行判值,该方法比较高效。详情请参见下方链接中文末的例子:

   https://blog.csdn.net/jiongnima/article/details/80555387

   

   欢迎阅读笔者后续博客,各位读者朋友的支持与鼓励是我最大的动力!


written by jiong

宝剑锋从磨砺出,梅花香自苦寒来

  • 12
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值