I wondered if there was any way too loop over Ragged Tensors, similarly to tf.map_fn. My Ragged Tensor has a different amount of rows but contains 4 points which I would like to retrieve.
The input looks as follows:
ragged_tensor[0] equals (100, 4)
ragged_tensor[1] equals (50, 4)
For now I can retrieve all of the points by looping over the first tensor inside the RaggedTensor:
test = tf.map_fn(lambda box: tf.image.crop_to_bounding_box(img, box[0], box[1], box[2], box[3]), tf.cast(boxes, tf.int32), dtype=tf.float32)
Does anyone have any experience with this, or might give me some tips&tricks? All help is appreciated.
This is one way to get the whole array of points:
points = tf.reshape(ragged_tensor.flat_values, [-1, 4])
Related
I have a convolutional autoencoder model. While an autoencoder typically focuses on reconstructing the input without using any label information, I want to use the class label to perform class conditional scaling/shifting after convolutions. I am curious if utilizing the label in this way might help produce better reconstructions.
num_filters = 32
input_img = layers.Input(shape=(28, 28, 1)) # input image
label = layers.Input(shape=(10,)) # label
# separate scale value for each of the filter dimensions
scale = layers.Dense(num_filters, activation=None)(label)
# conv_0 produces something of shape (None,14,14,32)
conv_0 = layers.Conv2D(num_filters, (3, 3), strides=2, activation=None, padding='same')(input_img)
# TODO: Need help here. Multiply conv_0 by scale along each of the filter dimensions.
# This still outputs something of shape (None,14,14,32)
# Essentially each 14x14x1 has it's own scalar multiplier
In the example above, the output of the convolutional layer is (14,14,32) and the scale layer is of shape (32,). I want the convolutional output to be multiplied by the corresponding scale value along each filter dimension. For example, if these were numpy arrays I could do something like conv_0[:, :, i] * scale[i] for i in range(32).
I looked at tf.keras.layers.Multiply which can be found here, but based on the documentation I believe that takes in tensors of the same size as input. How do I work around this?
You don't have to loop. Simply do the following by making two tensors broadcast-compatible,
out = layers.Multiply()([conv_0, tf.expand_dims(tf.expand_dims(scale,axis=1), axis=1)])
I dont know if i actually understood what you are trying to achieve but i did a quick numpy test. I believe it should hold in tensorflow also:
conv_0 = np.ones([14, 14, 32])
scale = np.array([ i + 1 for i in range(32)])
result = conv_0 * scale
check whether channel-wise slices actually scaled element-wise in this case by the element found at index 1 in scale, which is 2
conv_0_slice_1 = conv_0[:, :, 1]
result_slice_1 = result[:, :, 1]
I have a Tensor tensor of shape (?, 1082) and I want to slice this Tensor into n subparts in a for-loop but I want to keep the original shape, including the unknown dimension ?.
Example:
lst = []
for n in range(15):
sub_tensor = tensor[n] # this will reduce the first dimension
print(sub_tensor.get_shape())
Print output I'm looking for:
(?, 1082)
(?, 1082)
etc.
How can this be achieved in TensorFlow?
Considering that your problem can have many constraints, I can think of at least 3 solutions.
You can use tf.split. I'll use tf.placeholder, but it's applicable to tensors and variables as well.
p = tf.placeholder(shape=[None,10], dtype=tf.int32)
s1, s2 = tf.split(value=p, num_or_size_splits=2, axis=1)
However, this approach can become unfeasible if number of splits required is large. Note that it can split None axis as well.
for n in range(15):
sub_tensor = tensor[n, :]
s = tf.slice(p, [0,2], [-1, 2])
Slice can be used for multidimensional tensors, but it' pretty tricky to use. And you can use tf.Tensor.getitem method, almost as you described in your question. It acts similar to NumPy. So this should do the job:
for n in range(10):
print(p[n, :])
However, usage of these methods heavily depend on your particular application. Hope this helps.
Hello question regarding reshaping an array.
I have an array train_x (2D) which content is (103,784)
In this case 103 is the amount of examples.
784 is the input of my neural network.
Now I want to reshape from 2D to 4D
I use the following command:
train_x = np.reshape(train_x, (103, 28, 28, 1))
Is it correct that in this case 103 is still the amount of training examples and that in this case my input 784 is devided into a matrix of 28x28? 1 in this case is my channel, not using RGB (otherwhise the channel should be 3).
If my assumption is not correct please can somebody advice how to reshape from 2D to 4D to archive the above? tnx
Your assumption is correct. The NumPy doc about reshape states:
You can think of reshaping as first raveling the array (using the given index order), then inserting the elements from the raveled array into the new array using the same kind of index ordering as was used for the raveling.
train_x with shape (103, 784) would ravel to:
[img_0[0], ..., img_0[783], img_1[0], ..., img_1[783], ..., img_102[0], img_102[783]]
Which is then reshaped to 103 images of 28x28x1 with the reshape command from your question, as intended.
You should make sure that the flat 784 values have been raveled in the same order that you are using to unravel them, row-major or column-major. If you are unsure, a quick sanity check would be to plot one of the images after reshaping.
Alternatively, you can use the following.
train_X = X_train.reshape(X_train.shape[0],28,28,1)
provided X-train has shape of (103,784)
I have a variable a of dimension (1, 5) which I want to 'tile' as many times as the size of my mini-batch. For example, if the mini-batch size is 32 then I want to construct a tensor c of dimension (32, 5) where each row has values the same as the original (1, 5) variable a.
But I only know the mini-batch size at run time: it's the size of dimension 0 of a placeholder b: tf.shape(b)[0]
Here's my code to construct c:
a = tf.Variable(np.random.uniform(size=(1,5)))
b = tf.placeholder(shape=[None, 12], dtype=tf.float32)
batch_size = tf.shape(b)[0]
c = tf.tile(a, tf.pack([batch_size, 1]))
This runs fine. Howeverc.get_shape() returns (?, ?). I don't understand why this doesn't return (?, 5) instead.
This is causing an issue later in my code when I construct a matrix variable W with number of columns c.get_shape()[1] which I expect to return 5 rather than ?.
Any help would be appreciated. Thanks.
[EDIT: This was fixed in a commit to TensorFlow on August 10, 2016.]
This is a known limitation of TensorFlow's shape inference: when the multiples argument to tf.tile() is a computed value (such as the result of tf.pack() here), and its value is not trivially computable at graph construction time (in this case, because it depends on a tf.placeholder(), which has no value until it is fed), the current shape inference will throw its hands up and declare that the shape is unknown (but with the same rank as the input, a).
The current workaround is to use Tensor.set_shape(), which allows you as the programmer to provide additional shape information when you know more than the shape inference does. For example, you could do:
a = tf.Variable(np.random.uniform(size=(1, 5)))
b = tf.placeholder(shape=[None, 12], dtype=tf.float32)
batch_size = tf.shape(b)[0]
c = tf.tile(a, tf.pack([batch_size, 1]))
c.set_shape([None, a.get_shape()[1]]) # or `c.set_shape([None, 5])`
However, we recently added some features that make it possible to propagate partially computed values that may be used as shapes, and this can be adapted to aid the shape function for tf.tile(). I have created a GitHub issue to track this, and I have a fix being tested right now.
I need to convert a list of tensors of dimensionality N to a new tensor with dimensionality N+1 so that the new dimension would be the right most dimension.
For example if x and y would be tensors of shape (4,3) both then I am trying to create a new tensor z of shape (4,3,2) by forming z and setting tensor x as the 0th element along the third dimension and setting tensor y as the 1st element along the third dimension. In pseudocode:
z = tf.fromList([x,y],3)
What's the best way to do that in Tensorflow. I was unable to figure it out from the documentation of TF 0.7.1.
If I'm reading you correctly, you want to interleave the data of the two tensors.
You want to tf.pack() them together, which would form a tensor of shape [2, 4, 3] and then tf.transpose([1, 2, 0]) that resulting tensor to get to the interleaving you want.
dga's method works, but tf.pack() has been removed from TensorFlow V1.0 onwards.
You can use tf.stack() to achieve the same.
Docs: https://www.tensorflow.org/api_docs/python/tf/stack