1
votes

I have a deep network using Keras and I need to apply cropping on the output of one layer and then send to the next layer. for this aim, I write the following code as a lambda layer:

def cropping_fillzero(img, rate=0.6): # Q = percentage
    residual_shape = img.get_shape().as_list()
    h, w = residual_shape[1:3]
    blacked_pixels = int((rate) * (h*w))
    ratio = int(np.floor(np.sqrt(blacked_pixels)))
#    width = int(np.ceil(np.sqrt(blacked_pixels)))

    x = np.random.randint(0, w - ratio)
    y = np.random.randint(0, h - ratio)
    cropingImg = img[y:y+ratio, x:x+ratio].assign(tf.zeros([ratio, ratio]))

    return cropingImg

decoded_noise = layers.Lambda(cropping_fillzero, arguments={'rate':residual_cropRate}, name='residual_cropout_attack')(bncv11)

but it produces the following error and I do not know why?!

Traceback (most recent call last):

File "", line 1, in runfile('E:/code_v28-7-19/CIFAR_los4x4convolvedw_5_cropAttack_RandomSize_Pad.py', wdir='E:/code_v28-7-19')

File "D:\software\Anaconda3\envs\py36\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 704, in runfile execfile(filename, namespace)

File "D:\software\Anaconda3\envs\py36\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 108, in execfile exec(compile(f.read(), filename, 'exec'), namespace)

File "E:/code_v28-7-19/CIFAR_los4x4convolvedw_5_cropAttack_RandomSize_Pad.py", line 143, in decoded_noise = layers.Lambda(cropping_fillzero, arguments={'rate':residual_cropRate}, name='residual_cropout_attack')(bncv11)

File "D:\software\Anaconda3\envs\py36\lib\site-packages\keras\engine\base_layer.py", line 457, in call output = self.call(inputs, **kwargs)

File "D:\software\Anaconda3\envs\py36\lib\site-packages\keras\layers\core.py", line 687, in call return self.function(inputs, **arguments)

File "E:/code_v28-7-19/CIFAR_los4x4convolvedw_5_cropAttack_RandomSize_Pad.py", line 48, in cropping_fillzero cropingImg = img[y:y+ratio, x:x+ratio].assign(tf.zeros([ratio, ratio]))

File "D:\software\Anaconda3\envs\py36\lib\site-packages\tensorflow\python\ops\array_ops.py", line 700, in assign raise ValueError("Sliced assignment is only supported for variables")

ValueError: Sliced assignment is only supported for variables

could you please tell me how can I solve this error? Thank you

2
Do you expect images to be variable size? There are a lot of things that need to be fixed there. You can't have numpy, it will not be random as you expect.Daniel Möller
Maybe this is helpfulJos
my input is a tensor, not an image, this is only a name. sorry, I could not understand your answer! img is the output of the prior layer and is a tensor. could you please explain more.david
The error message states (vaguely) that sliced assignment (img[y:y=ratio,x:x+ratio].assign(...)) is only supported for Tensorflow Variable objects, not for Tensor objects.Jos

2 Answers

0
votes

h, w = residual_shape[1:3]

I'm not entirely sure what you're trying to do here, but Python interprets this as 'return between the 2nd element and the 4th'. Maybe you mean residual_shape[1], residual_shape[3]?

0
votes
cropingImg = img[y:y+ratio, x:x+ratio].assign(tf.zeros([ratio, ratio]))

You are trying to use slice notation on a tensor. Slice notation may only be used on variables, as the error message says. In order to get the actual variable, try loading the previous layer output using tf.identity():

self.output = your_layer
self.output = tf.identity(self.output, name='output')
output = graph.get_tensor_by_name('output:0')