I am new in TensorFlow. I am trying to implement the global_context extraction in this paper https://arxiv.org/abs/1506.04579, which is actually an average pooling over the whole feature map, then duplicate the 1x1 feature map back to the original size. The illustration is as below
Specifically, the expected operation is following.
input: [N, 1, 1, C] tensor, where N is the batch size and C is the number of channel
output: [N, H, W, C] tensor, where H, W is the hight and width of original feature map, and all the H * W values of output are the same as the 1x1 input.
For example,
[[1, 1, 1]
1 -> [1, 1, 1]
[1, 1, 1]]
I have no idea how to do this using TensorFlow. tf.image.resize_images requires 3 channels, and tf.pad cannot pad constant value other than zero.
tf.tile may help you
x = tf.constant([[1, 2, 3]]) # shape (1, 3)
y = tf.tile(x, [3, 1]) # shape (3, 3)
y_ = tf.tile(x, [3, 2]) # shape (3, 6)
with tf.Session() as sess:
a, b, c = sess.run([x, y, y_])
>>>a
array([[1, 2, 3]], dtype=int32)
>>>b
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]], dtype=int32)
>>>c
array([[1, 2, 3, 1, 2, 3],
[1, 2, 3, 1, 2, 3],
[1, 2, 3, 1, 2, 3]], dtype=int32)
tf.tile(input, multiples, name=None)
multiples means how many times you want to repeat in this axis
in y repeat axis0 3 times
in y_ repeat axis0 3 times, and axis1 2 times
you may need to use tf.expand_dim first
yes it accept dynamic shape
x = tf.placeholder(dtype=tf.float32, shape=[None, 4])
x_shape = tf.shape(x)
y = tf.tile(x, [3 * x_shape[0], 1])
with tf.Session() as sess:
x_ = np.array([[1, 2, 3, 4]])
a = sess.run(y, feed_dict={x:x_})
>>>a
array([[ 1., 2., 3., 4.],
[ 1., 2., 3., 4.],
[ 1., 2., 3., 4.]], dtype=float32)
Related
Using tensorflow.stack what does it mean to have axis=-1 ?
I'm using tensorflow==1.14
Using axis=-1 simply means to stack the tensors along the last axis (as per the python list indexing syntax).
Let's take a look at how this looks like using these tensors of shape (2, 2):
>>> x = tf.constant([[1, 2], [3, 4]])
>>> y = tf.constant([[5, 6], [7, 8]])
>>> z = tf.constant([[9, 10], [11, 12]])
The default behavior for tf.stack as described in the documentation is to stack the tensors along the first axis (index 0) resulting in a tensor of shape (3, 2, 2)
>>> tf.stack([x, y, z], axis=0)
<tf.Tensor: shape=(3, 2, 2), dtype=int32, numpy=
array([[[ 1, 2],
[ 3, 4]],
[[ 5, 6],
[ 7, 8]],
[[ 9, 10],
[11, 12]]], dtype=int32)>
Using axis=-1, the three tensors are stacked along the last axis instead, resulting in a tensor of shape (2, 2, 3)
>>> tf.stack([x, y, z], axis=-1)
<tf.Tensor: shape=(2, 2, 3), dtype=int32, numpy=
array([[[ 1, 5, 9],
[ 2, 6, 10]],
[[ 3, 7, 11],
[ 4, 8, 12]]], dtype=int32)>
I want to apply the operation tf.tile, e.g. tf.tile(A, [1, 1, b]) where A has shape [5,4,3]. How to generate [1, 1, 1] according to A? Then I set the [1, 1, 1]'s third element to b, where b is a placeholder.
This is my code, but it doesn't work, how to fix it?
d = tf.shape(A)
for i in range(tf.rank(A)): #wrong, tf.rank(A) as a tensor can't be here
d[i] = 1
d[2] = b
result = tf.tile(A, d)
The easiest solution is probably to use tf.one_hot to build your multiples tensor directly.
>>> b = 2
>>> tf.one_hot(indices=[b], depth=tf.rank(A), on_value=b, off_value=1)
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([1, 1, 2], dtype=int32)>
Alternatively, you can use tf.ones_like to generate a tensor of 1 with the same shape as the Tensor passed as an argument.
>>> A = tf.random.uniform((5,4,3))
>>> tf.shape(A)
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([5, 4, 3], dtype=int32)>
>>> tf.ones_like(tf.shape(A))
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([1, 1, 1], dtype=int32)>
Note that in tensorflow, you can't do item assignment on a tensor (so d[2] = b won't work for example). To generate your tensor [1,1,b] you can use tf.concat:
>>> b = 2
>>> tf.concat([tf.ones_like(tf.shape(A)[:-1]),[b]],axis=0)
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([1, 1, 2], dtype=int32)>
Is there a way to directly update the elements in tf.Variable X at indices without creating a new tensor having the same shape as X?
tf.tensor_scatter_nd_update create a new tensor hence it appears not updateing the original tf.Variable.
This operation creates a new tensor by applying sparse updates to the input tensor.
tf.Variable assign apparently needs a new tensor value which has the same shape of X to update the tf.Variable X.
assign(
value, use_locking=False, name=None, read_value=True
)
value A Tensor. The new value for this variable.
About the tf.tensor_scatter_nd_update, you're right that it returns a new tf.tensor (and not tf.Variable). But about the assign which is an attribute of tf.Variable, I think you somewhat misread the document; the value is just the new item that you want to assign in particular indices of your old variable.
AFAIK, in tensorflow all tensors are immutable like python numbers and strings; you can never update the contents of a tensor, only create a new one, source. And directly updating or manipulating of tf.tensor or tf.Variable such as numpy like item assignment is still not supported. Check the following Github issues to follow up the discussions: #33131, #14132.
In numpy, we can do an in-place item assignment that you showed in the comment box.
import numpy as np
a = np.array([1,2,3])
print(a) # [1 2 3]
a[1] = 0
print(a) # [1 0 3]
A similar result can be achieved in tf.Variable with assign attribute.
import tensorflow as tf
b = tf.Variable([1,2,3])
b.numpy() # array([1, 2, 3], dtype=int32)
b[1].assign(0)
b.numpy() # array([1, 0, 3], dtype=int32)
Later, we can convert it to tf. tensor as follows.
b_ten = tf.convert_to_tensor(b)
b_ten.numpy() # array([1, 0, 3], dtype=int32)
We can do such item assignment in tf.tensor too but we need to convert it to tf.Variable first, (I know, not very intuitive).
tensor = [[1, 1], [1, 1], [1, 1]] # tf.rank(tensor) == 2
indices = [[0, 1], [2, 0]] # num_updates == 2, index_depth == 2
updates = [5, 10] # num_updates == 2
x = tf.tensor_scatter_nd_update(tensor, indices, updates)
x
<tf.Tensor: shape=(3, 2), dtype=int32, numpy=
array([[ 1, 5],
[ 1, 1],
[10, 1]], dtype=int32)>
x = tf.Variable(x)
x
<tf.Variable 'Variable:0' shape=(3, 2) dtype=int32, numpy=
array([[ 1, 5],
[ 1, 1],
[10, 1]], dtype=int32)>
x[0].assign([5,1])
x
<tf.Variable 'Variable:0' shape=(3, 2) dtype=int32, numpy=
array([[ 5, 1],
[ 1, 1],
[10, 1]], dtype=int32)>
x = tf.convert_to_tensor(x)
x
<tf.Tensor: shape=(3, 2), dtype=int32, numpy=
array([[ 5, 1],
[ 1, 1],
[10, 1]], dtype=int32)>
I am trying to move a list of points to the origin using tensorflow the best way to do it mathematically is to find the centroid of the list of points then subtract the list of points by that centroid.
The problems: The number of rows contained in the point list is unknown until runtime.
Code so far:
import tensorflow as tf
example_point_list = tf.constant([[3., 3.], [.2, .2], [.1, .1]]) // but with any number of points
centroid = tf.reduce_mean(example_point_list, 0)
// subtract???
origin_point_list = tf.sub(example_point_list, centroid)
The problem is that subtract works on an element by element basis so I have to create a centroid tensor with the same number of rows as the point list but there are no methods that do that.
(to put it in math terms)
A = [[1, 1],
[2, 2]
[3, 3]]
B = avg(A) // [2, 2]
// step I need to do but do not know how to do it
B -> B1 // [[2, 2], [2, 2], [2, 2]]
Result = A - B1
Any help is appreciated!
Because of broadcasting, you don't need to tile the rows. In fact, it's more efficient to not tile them and subtract vector from matrix directly. In your case it would look like this
tf.reset_default_graph()
example_points = np.array([[1, 1], [2, 2], [3, 3]], dtype=np.float32)
example_point_list = tf.placeholder(tf.float32)
centroid = tf.reduce_mean(example_point_list, 0)
result = example_point_list - centroid
sess = tf.InteractiveSession()
sess.run(result, feed_dict={example_point_list: example_points})
result
array([[-1., -1.],
[ 0., 0.],
[ 1., 1.]], dtype=float32)
If you really want to tile the centroid vector explicitly, you could do it using shape operator which can get shape during runtime
tf.reset_default_graph()
example_point_list0 = np.array([[1, 1], [2, 2], [3, 3]], dtype=np.float32)
example_point_list = tf.placeholder(tf.float32)
# get number of examples from the array: [3]
num_examples = tf.slice(tf.shape(example_points), [0], [1])
# reshape [3] into 3
num_examples_flat = tf.reshape(num_examples, ())
centroid = tf.reduce_mean(example_point_list, 0)
# reshape centroid vector [2, 2] into matrix [[2, 2]]
centroid_matrix = tf.reshape(centroid, [1, -1])
# assemble 3 into vector of dimensions to tile: [3, 1]
tile_shape = tf.pack([num_examples_flat, 1])
# tile [[2, 2]] into [[2, 2], [2, 2], [2, 2]]
centroid_tiled = tf.tile(centroid_matrix, tile_shape)
sess = tf.InteractiveSession()
sess.run(centroid_tiled, feed_dict={example_point_list: example_point_list0})
result
array([[ 2., 2.],
[ 2., 2.],
[ 2., 2.]], dtype=float32)
I want to create a 2D numpy array where I want to store the coordinates of the pixels such that numpy array looks like this
[(0, 0), (0, 1), (0, 2), ...., (0, 510), (0, 511)
(1, 0), (1, 1), (1, 2), ...., (1, 510), (1, 511)
..
..
..
(511, 0), (511, 1), (511, 2), ...., (511, 510), (511, 511)]
This is a ridiculous question but I couldn't find anything yet.
Can use np.indices or np.meshgrid for more advanced indexing:
>>> data=np.indices((512,512)).swapaxes(0,2).swapaxes(0,1)
>>> data.shape
(512, 512, 2)
>>> data[5,0]
array([5, 0])
>>> data[5,25]
array([ 5, 25])
This may look odd because its really made to do something like this:
>>> a=np.ones((3,3))
>>> ind=np.indices((2,1))
>>> a[ind[0],ind[1]]=0
>>> a
array([[ 0., 1., 1.],
[ 0., 1., 1.],
[ 1., 1., 1.]])
A mgrid example:
np.mgrid[0:512,0:512].swapaxes(0,2).swapaxes(0,1)
A meshgrid example:
>>> a=np.arange(0,512)
>>> x,y=np.meshgrid(a,a)
>>> ind=np.dstack((y,x))
>>> ind.shape
(512, 512, 2)
>>> ind[5,0]
array([5, 0])
All are equivalent ways of doing this; however, meshgrid can be used to create non-uniform grids.
If you do not mind switching row/column indices you can drop the final swapaxes(0,1).
You can use np.ogrid here. Instead of storing a tuple, store it in a 3D array.
>>> t_row, t_col = np.ogrid[0:512, 0:512]
>>> a = np.zeros((512, 512, 2), dtype=np.uint8)
>>> t_row, t_col = np.ogrid[0:512, 0:512]
>>> a[t_row, t_col, 0] = t_row
>>> a[t_row, t_col, 1] = t_col
This should do the trick. Hopefully you can use this, instead of the tuple.
Chintak
The example in the question is not completely clear - either extra commas are missing or extra brakets.
This one - example ranges 3, 4 for clarity - provides the solution for the first variant and produces a 2D array in effect (as the question title suggests) - "listing" all coordinates:
>>> np.indices((3,4)).reshape(2,-1).T
array([[0, 0],
[0, 1],
[0, 2],
[0, 3],
[1, 0],
[1, 1],
[1, 2],
[1, 3],
[2, 0],
[2, 1],
[2, 2],
[2, 3]])
The other variant was already shown in another answer by using 2x .swapaxes() - but it could also be done with one np.rollaxis() (or the new np.moveaxis()) :
>>> np.rollaxis(np.indices((3,4)), 0, 2+1)
array([[[0, 0],
[0, 1],
[0, 2],
[0, 3]],
[[1, 0],
[1, 1],
[1, 2],
[1, 3]],
[[2, 0],
[2, 1],
[2, 2],
[2, 3]]])
>>> _[0,1]
array([0, 1])
This method also works the same for N-dimensional indices, e.g.:
>>> np.rollaxis(np.indices((5,6,7)), 0, 3+1)
Note: The function np.indices works indeed (C-speed) fast for big ranges.