Trying to load Tensorflow trained model into Deeplearning4J with following error:
IllegalStateException: Invalid array shape: cannot associate an array with shape [38880] with a placeholder of shape [-1, -1, -1, 3]:shape is wrong rank or does not match on one or more dimensions
var arr: INDArray = Nd4j.create(data) //.reshape(1, -1, -1, 3);
arr = Nd4j.pile(arr, arr)
sd.associateArrayWithVariable(arr, sd.variables.get(0))
Python model was loaded like that:
# Load image using OpenCV and
# expand image dimensions to have shape: [1, None, None, 3]
# i.e. a single-column array, where each item in the column has the pixel RGB value
image = cv2.imread(PATH_TO_IMAGE)
image_expanded = np.expand_dims(image, axis=0)
Please explain any question if you know:
1) What means [1, None, None, 3] in terms of Python arrays
2) What means np.expand_dims(image, axis=0) in Python
3) Deeplearning4J reshape(1, -1, -1, 3);
You're mixing two different concepts here, TF placeholders, and imperative numpy-like reshape.
In your case, model expects 4D input tensor, with shape [-1, -1, -1, 3]. For human it can be translated to [Any, Any, Any, 3]. But you're trying to feed it with tensor with shape [38880], rank 1.
Now to your questions.
1) See above. -1 is treated as "Any".
2) This function adds 1 as dimension. i.e. if you have [38880], expand_dims at axis=0 will make it [1, 38880]
3) Nope, that's wrong. You should not use that as your shape. You have some image there, so you should specify proper dimensions your image has, i.e. [1, 800, 600, 3].
Related
The problem is, I have an indices tensor with shape [batch_size, seq_len, k] and every element in this tensor is in range [0, hidden_dim). I want to create a mask tensor with shape [batch_size, seq_len, hidden_dim] where every element indexed by the indices tensor is 1 and other elements are 0. k is smaller than hidden_dim. For example:
indices = [[[0],[1],[2]]] #batch_size=1, seq_len=3, k=1
mask = tf.zeros(shape=(1,3,3)) #batch_size=1, seq_len=3, hidden_dim = 3
How can I get a target mask tensor whose elements indicated by the indices are 1, i.e.:
target_mask = [[[1, 0, 0], [0, 1, 0], [0, 0, 1]]]
This can be accomplished using tf.one_hot, e.g.:
mask = tf.one_hot(indices, depth=hidden_dim, axis=-1) # [batch, seq_len, k, hidden_dim]
I wasn't clear on what you'd like to happen to k. tf.one_hot() will keep the axis as is, i.e. you'll get a delta distribution for each [batch-index, seq-index, k-index] tuple.
I am trying to do element-wise multiplication of two tensors of dimensions (1,5,64) and (1,5). As far as I know, in spite of their dimension mismatch, broadcasting should allow this to work. So, I use this code:
x = tf.range(0,64*5)
x = tf.reshape(x, [1,5, 64])
y = tf.range(0,5)
y = tf.reshape(y, [1, 5])
prodct = x*y
This causes this error:
InvalidArgumentError: Incompatible shapes: [1,5,64] vs. [1,5] [Op:Mul]
However If i reshape first tensor to dimension (1,64,5), then it works. Code:
x = tf.range(0,64*5)
x = tf.reshape(x, [1,64, 5])
y = tf.range(0,5)
y = tf.reshape(y, [1, 5])
prodct = x*y
I do not understand why the first code does not work.
The General Broadcasting Rules, when operating on two arrays, numpy compares their shapes element-wise. It starts with the trailing (i.e. rightmost) dimensions and works its way left. Two dimensions are compatible when
they are equal, or
one of them is 1
If these conditions are not met, a ValueError: operands could not be broadcast together exception is thrown, indicating that the arrays have incompatible shapes. The size of the resulting array is the size that is not 1 along each axis of the inputs.
tensorflow also follows the same spirit. Check the documentation for more examples and details. For your case, the rightmost dimension doesn't follow the rules and throws an error.
1, 5, 64
1, 5
But this would work as it obeys the rules.
1, 64, 5
1, 5
Code
In numpy, and in tensorflow for reference.
import numpy as np
a = np.arange(64*5).reshape(1, 64, 5)
b = np.arange(5).reshape(1,5)
(a*b).shape
(1, 64, 5)
import tensorflow as tf
x = tf.reshape(tf.range(0,64*5), [1, 64, 5])
y = tf.reshape(tf.range(0,5), [1, 5])
(x*y).shape
TensorShape([1, 64, 5])
What I need to do is to cut some slices (fix size) of a 3D-binary masks randomly.
The data is stored in a tensorflow dataset (tf.data). It does have to be this kind of data type to be able to use caching for speed up.
My source code so far:
import tensorflow as tf #version 2.2.0
mask.shape # (512,512,None,1), where (width, height, depth, channel), depth is NOT FIXED and depends on the image and therefore unknown
slice_number = 10
positive = tf.where(tf.equal(masks[:, :, :-slice_number,:],1))[:, 2] #slices with non zero values
# now we need to select slice id from positive mask slices randomly,
# which failes since the shape is always None due to the fact that image depth is unknown.
pos_id = random.randint(0, positive.shape[0])
mask = mask[:, :, positive[pos_id]:positive[pos_id] + slice_number]
How do I get the shape? Any ideas are highly appreciated
Thanks in advance!
Assuming that you want to randomly slice a fixed slice_size from a Tensor dimension with unknown depth, the following demonstrates how it can be done:
import tensorflow as tf
#tf.function
def random_slice(slice_size):
# For demonstration purposes, generate your mask with random depth
random_depth = tf.random.uniform(shape=[], dtype=tf.int32,
minval=20, maxval=50)
mask = tf.ones([512, 512, random_depth, 1], dtype=tf.int32)
print(mask) # Mask with unknown depth: Tensor("ones:0", shape=(512, 512, None, 1), dtype=int32)
depth = tf.shape(mask)[2]
print(depth) # Unknown depth: Tensor("strided_slice:0", shape=(), dtype=int32)
depth_begin = tf.random.uniform(shape=[], dtype=tf.int32,
minval=0, maxval=depth-slice_size)
print(depth_begin) # Random begin of slice based on unknown depth: Tensor("random_uniform_1:0", shape=(), dtype=int32)
mask_sliced = tf.slice(mask,
begin=[0, 0, depth_begin, 0],
size=[512, 512, slice_size, 1])
print(mask_sliced) # Random slice with known dimensions: Tensor("Slice:0", shape=(512, 512, 10, 1), dtype=int32)
return mask_sliced
mask_sliced = random_slice(slice_size=10)
print(mask_sliced) # Resolved random slice
I've been trying to implement the Spatial Pyramid Pooling (https://arxiv.org/abs/1406.4729), but I've been having a problem with the input size.
My input has shape (batch_size, None, n_feature_maps) and I have the following code:
self.y_conv_unstacked = tf.unstack(self.conv_output, axis=0)
self.y_maxpool = []
for tensor in self.y_conv_unstacked:
for size_pool in self.out_pool_size:
self.w_strd = self.w_size = math.ceil(float(tensor.get_shape()[1]) / size_pool)
self.pad_w = int(size_pool * self.w_size - tensor.get_shape()[1])
self.padded_tensor = tf.pad(tensor, tf.constant([[0, 0], [0, 0], [0, self.pad_w], [0, 0]]))
self.max_pool = tf.nn.max_pool(self.padded_tensor, ksize=[1, 1, self.w_size, 1], strides=[1, 1, self.w_strd, 1], padding='SAME')
self.spp_tensor = tf.concat([self.spp_tensor, tf.reshape(self.max_pool, [1, size_pool, self.n_fm1])], axis=1)
self.y_maxpool.append(spp_tensor)
Since the inputs in the batch have different sizes, I am unstacking them and pooling each tensor separately. However when using tensor.get_shape()[1], it returns "?". If I use tensor.get_shape().as_list()[1], it returns None.
I would like to know how I can work around this nondefined size. Is it possible to get the tensor's shape at runtime?
Edit: Using tf.shape, I get a tensor. How can I use this tensor to create the ksize, strides and paddings I need?
I would like to know how I can work around this nondefined size. Is it
possible to get the tensor's shape at runtime?
Use tf.shape() op to get the dynamic shape of a tensor instead of the x.get_shape() which returns the static shape of x.
This is explained in detail here.
In the above code replace tensor.get_shape()[1] with tf.shape(tensor)[1]
I have a tensor and an index tensor of the same rank. I want to set the values of the tensor that correspond to the indices in the index tensor to a certain scalar. How do I do this?
In other words, I'm looking for the Tensorflow equivalent of the following Numpy operation:
array[indices] = scalar
In my concrete case we're talking about a 1D tensor:
mask = tf.zeros_like(some_1D_tensor)
(e.g. mask = [0, 0, 0, 0, 0])
Let indices be a 1D tensor that contains the indices of mask that I'd like to set to the scalar value 1. So I want:
mask[indices] = 1
(e.g. for indices = [1, 3] the output should be mask == [0, 1, 0, 1, 0])
I don't know if it wasn't there before or if I just haven't seen it, but the general case equivalent of
array[indices] = scalar
is
tensor = tf.scatter_nd_update(tensor, indices, updates)
using tf.scatter_nd_update()