繁体   English   中英

运行tf.where并获取TypeError:不允许将tf.Tensor作为Python bool使用

[英]Running tf.where and getting TypeError: Using a `tf.Tensor` as a Python `bool` is not allowed

关于我要实现的目标的一些背景知识:我正在尝试将HOG特征提取器的实现实现为keras Lambda层。 虽然我在Tensorflow方面确实有少量经验,但是编写这种复杂的内容略高于我的专业水平。 不用说,我有几个问题。

只是很容易理解我的模型是什么,这里是结构,其中x_convy_conv是我的实现中唯一具有可训练参数的部分。

# Model 
inputs = Input(shape(128, 128)
x_conv = conv2d(1, (3,3), strides=1, padding="same", kernel_initializer=init_prewitt_x)(inputs)
y_conv = conv2d(1, (3,3), strides=1, padding="same", kernel_initializer=init_prewitt_y)(inputs)
conv_stacked = keras.layers.Concatenate(axis=-1)([x_conv, y_conv])
x = Lambda(hog_layer, output_shape=hoglayer_output_shape)(conv_stacked)

我用来测试hog_layer超参数,初始化程序和假批处理是

# Defining Initializers
prewitt_x = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]])
prewitt_y = prewitt_x.T 

def init_prewitt_x(shape, dtype=None):
return K.convert_to_tensor(prewitt_x)

def init_prewitt_y(shape, dtype=None):
    return K.convert_to_tensor(prewitt_y)

# Defining Values
bins = 8         # number of gaps
w = 360/bins     # gap size
centers = np.arange(0, 360, w)+0.5*w

cell_size = 8
block_size = 2
batch_size = 20

fake_batch = np.random.rand(20, 128, 128, 2)

给我带来麻烦的部分是hog_layer 图层中没有可训练的参数,只有一系列张量变换。 它也不是完整的HOG特征提取器-批次选择和规范化过程尚未实现。 下面显示的内容将x_convy_conv的堆叠输出y_conv并返回(或至少它将在工作后返回),具有以下形状的数组(批,图像高度/单元数,图像宽度/单元数,直方图中的bin) )。 就这个:

def hog_layer(conv_stacked_batch):
    #Finding the value of the last axis
    axis = tf.size(tf.shape(conv_stacked_batch))-1 # Ask if considers batch_dim!!!!

    #Splitting along axis to x_conv and y_conv
    x_grad, y_grad = tf.split(conv_stacked_batch,2, axis=axis)

    # Defining Empty Vote Array for shape (batch_size, img height, img width, bins)
    votes_array = tf.zeros((batch_size, tf.shape(x_grad)[1], tf.shape(x_grad)[2], bins)) 

    def hog_layer_img(votes_array, img_nb,x_grad, y_grad):
        #Calculating magnitudes
        mags = tf.sqrt(tf.pow(x_grad[img_nb, :, :], 2)+tf.pow(y_grad[img_nb, :, :], 2))

        #Calculating angles from 0 to 360 degrees
        angles = 180*(tf.atan2(y_grad[img_nb, :, :], x_grad[img_nb, :, :]) + np.pi)/np.pi 

        # Defining the function that generates all votes for each bin number
        def create_vote_array(votes_array, angles, mags, bin_nb):
            # The Else function is for all bins expect for the last bin
            # Voting for angles that lie in the last bin act differently (see bellow)

            # For angles in bin number (bin_nb=j), where bin j has boundries center[i] to center[i+1]
            # where bin j has boundries center[i] to center[i+1]
            # unless bin j is the last bin, then the boutreis are from the last center to the first center
            # If the bins=8, the center would be:
            # [ 22.5,   67.5,  112.5,  157.5,  202.5,  247.5,  292.5,  337.5]

            # Read --else-- comments first for explanation 
            if bin_nb == bins-1:
                # Since it is hard to express in python that an angle 0 = angle 360, we do this instead
                # Adding 360 to where the center and the angles are not both on the same side of the 0/360 boundary
                # This satisfies vote_j + vote_j+1 = mag
                votes_top_j = tf.where(centers[-1] < angles, tf.multiply(mags, (centers[0]-angle_array+360)/w), tf.zeros(tf.shape(angles)))
                votes_top_j1 = tf.where(centers[-1] < angles, tf.multiply(mags, (angle_array-centers[bin_nb])/w), tf.zeros(tf.shape(angles)))

                votes_bot_j = tf.where(centers[0] > angles, tf.multiply(mags, (centers[0]-angle_array)/w), tf.zeros(tf.shape(angles)))
                votes_bot_j1 = tf.where(centers[0] > angles, tf.multiply(mags, (360+angle_array-centers[bin_nb])/w), tf.zeros(tf.shape(angles)))


                votes_j = tf.add(votes_top_j, votes_bot_j)
                votes_j1 = tf.add(votes_top_j1, votes_bot_j1)

                votes_array[:, :, bin_nb] += votes_j
                votes_array[:, :, 0] += votes_j1

            # finds all angles in bin j
            # for those not in bin j, element = 0
            else:
                # Calculates votes for bin j for angles that are in bin j
                votes_j = tf.where((centers[bin_nb]) < angles < centers[bin_nb+1], tf.multiply(mags, (centers[bin_nb+1]-angles)/w), tf.zeros(tf.shape(angles)))

                #Calculates votes for bin j+1 for angles that are in bin j
                votes_j1 = tf.where((centers[bin_nb]) < angles < centers[bin_nb+1], tf.multiply(mags, (angle_array-centers[bin_nb])/w), tf.zeros(tf.shape(angles)))

                #Adds votes the bin jth and j+1th layer on axis=2 of voting array                            
                votes_array[img_nb, :, :, bin_nb] = tf.add(votes_array[img_nb, :, :, bin_nb], votes_j)
                votes_array[img_nb, :, :, bin_nb+1] = tf.add(votes_array[img_nb, :, :, bin_nb+1], votes_j1)

            return votes_array
            #Bin Level

        # Interating through each bin to generate votes                           
        for i in range(bins):
            votes_array = create_vote_array(votes_array, angles, mags, i)

        return votes_array
        # Image Level                            

    # Performing hog_layer_img function on each imgage in the batch
    for img_nb in range(batch_size):
        votes_array = hog_layer_img(votes_array, img_nb, x_grad, y_grad)

    # For each cell, calculating the average vote at each bin level (or depth)
    # We multiply each element by the number of pixels in the cell, giving the sum of the votes for each bin level   
    # Result is array that keeps the spatial infomation of the cells
    # and the last dimetion (with depth bins) is the cell histogram                            
    cell_array = (cell_size**2)*tf.nn.avg_pool(votes_array, ksize=(1, cell_size, cell_size, bins), strides=(1, cell_size, cell_size, 1))

    return cell_array
    # Batch Level

如您可能看到的那样,存在一些问题。 最明显的一个是缺少所有的tf.constanttf.Variable 原因是 我还没有到,b。 我没有足够经验的人对我的张量流能力(我主要使用Keras)没有足够的信心去做。

现在运行它,我得到错误:

TypeError: Using a `tf.Tensor` as a Python `bool` is not allowed. Use `if t 
is not None:` instead of `if t:` to test if a tensor is defined, and use 
TensorFlow ops such as tf.cond to execute subgraphs conditioned on the value 
of a tensor.

从线

else:
   # Calculates votes for bin j for angles that are in bin j
   votes_j = tf.where((centers[bin_nb]) < angles < centers[bin_nb+1], tf.multiply(mags, (centers[bin_nb+1]-angles)/w), tf.zeros(tf.shape(angles)))

我想要做的是针对位于指定范围内的每个角度(位于bin i内的所有角度),我计算出对bin i(下一行中bin i + 1)的“投票”。 对于不在指定范围内的那些,它将返回零。 我这样做是为了保持与大小数组(或mags )相同的形状,以便于进行简单的元素乘法。 我敢肯定有更好的方法可以做到这一点,但我想不到。

另一个主要问题来自此操作:

votes_array[img_nb, :, :, bin_nb] = tf.add(votes_array[img_nb, :, :, bin_nb], votes_j)

我知道这不适用于张量,但我不知道等效的操作。 其他在线示例则无济于事。

任何帮助将不胜感激! 提前致谢!

当你写:

(centers[bin_nb]) < angles < centers[bin_nb+1]

Python解释:

(centers[bin_nb]) < angles and angles < centers[bin_nb+1]

但是,无论左右手两边and是张量,而张量不能被用作布尔值。 您想要的是成员逻辑,并且可以通过以下方式获得:

((centers[bin_nb]) < angles) & (angles < centers[bin_nb+1])

至于对变量的赋值操作,这应该是一个单独的问题,但是基本上,您必须自己构建张量。 您可以将片段放入列表中,然后使用tf.concat和/或tf.stack来构建完整的张量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM