Reputation: 376
I have the following code snippet, written in Lua with torch, which is a custom edge detection algorithm:
xGrad1[{{},{},{},{1,width-1}}] = input:narrow(4,2,width-1) - input:narrow(4,1,width-1)
yGrad1[{{},{},{1,height-1},{}}] = input:narrow(3,2,height-1) - input:narrow(3,1,height-1)
xGrad2[{{},{},{},{2,width}}] = input:narrow(4,2,width-1) - input:narrow(4,1,width-1)
yGrad2[{{},{},{2,height},{}}] = input:narrow(3,2,height-1) - input:narrow(3,1,height-1)
local xGrad = (torch.abs(self.xGrad1) + torch.abs(self.xGrad2))/2
local yGrad = (torch.abs(self.yGrad1) + torch.abs(self.yGrad2))/2
output = torch.sum(xGrad,2)+torch.sum(yGrad,2)
As you can see, the last two dimensions of the xGrad and yGrad tensors, which represent width and height of an image, are only partially updated, e.g. in xGrad2 only the columns 2 to width-1.
Now i want to achieve the same result with Tensorflow and Python. I am not sure if my general approach is right, but i have initialized all 4 Grad-tensors as a variable and pre-filled them with zeros. Now i am struggling with these partial assigns. I tried it with Variable.assign
but have no luck.
Currently, this is my code:
input = tf.image.decode_png(tf.read_file(f), 3)
input = tf.cast(input, tf.float32)
height = tf.shape(input)[0]
width = tf.shape(input)[1]
xGrad1 = tf.Variable(tf.zeros(tf.shape(input)), validate_shape=False)
yGrad1 = tf.Variable(tf.zeros(tf.shape(input)), validate_shape=False)
xGrad2 = tf.Variable(tf.zeros(tf.shape(input)), validate_shape=False)
yGrad2 = tf.Variable(tf.zeros(tf.shape(input)), validate_shape=False)
xGrad1[:, :width-2].assign(input[:,1:width-2] - input[:,:width-2])
yGrad1[:height-2].assign(input[1:height-2] - input[:height-2])
xGrad2[:, 1:width-1].assign(input[:,1:width-2] - input[:,:width-2])
yGrad2 [1, height-1].assign(input[1:height-2] - input[:height-2])
xGrad = (tf.abs(xGrad1) + tf.abs(xGrad2)) / 2
yGrad = (tf.abs(yGrad1) + tf.abs(yGrad2)) / 2
output = tf.reduce_sum(xGrad,axis=2) + tf.reduce_sum(yGrad,axis=2)
After translating the list indices from Lua to python, i get decent results when directly outputting the calculations which are the arguments of the 4 assign-commands, but only a black image when outputting the contents of xGrad1 and so on.
I assume a problem with incompatible shapes, but i have switched validate_shapes to False, since i do not know the shape of input at session creation time, since the input image is loaded after the session starts. If someone has an idea for this as well, feel free to answer me, but for now i am only asking how to only partially assign a variable tensor.
Upvotes: 1
Views: 1321
Reputation: 1829
If you want to do a sliced assignment you have to follow something like this,
with tf.control_dependencies([xGrad1[:, :width-2].assign(input[:,1:width-2] - input[:,:width-2]), yGrad1[:height-2].assign(input[1:height-2] - input[:height-2]),xGrad2[:, 1:width-1].assign(input[:,1:width-2] - input[:,:width-2]),yGrad2 [1, height-1].assign(input[1:height-2] - input[:height-2])]): # should give the list of slice assignment here
xGrad = (tf.abs(xGrad1) + tf.abs(xGrad2)) / 2
yGrad = (tf.abs(yGrad1) + tf.abs(yGrad2)) / 2
output = tf.reduce_sum(xGrad,axis=2) + tf.reduce_sum(yGrad,axis=2)
sess = tf.Session()
with sess.as_default():
sess.run(tf.global_variables_initializer())
output= output.eval()
Here is a nice explanation of sliced assignment in Tensorflow, https://stackoverflow.com/a/43139565/6531137
Hope this helps.
Upvotes: 1