![](/img/trans.png)
[英]Tensorflow Typeerror: Using a `tf.Tensor` as a Python `bool` is not allowed.
[英]Running tf.where and getting TypeError: Using a `tf.Tensor` as a Python `bool` is not allowed
关于我要实现的目标的一些背景知识:我正在尝试将HOG特征提取器的此实现实现为keras Lambda层。 虽然我在Tensorflow方面确实有少量经验,但是编写这种复杂的内容略高于我的专业水平。 不用说,我有几个问题。
只是很容易理解我的模型是什么,这里是结构,其中x_conv
和y_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_conv
和y_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.constant
和tf.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.