I trying to understand how Tensorflow work.
I have this code going trying to perform 2D convolution on an input image of size (5,5).
But it seems that it is only performing convolution in 1D instead of 2D.
Here is the code:
iX = iY = 5
kX = kY = 3
image = np.ones((iY,iX)).reshape((iY,iX,1))
kernel = np.ones((kY,kX)).reshape((kY,kX,1,1))
bias = np.array([0.0])
i = layers.Input(shape=(iY,iX,1))#l_input
x = layers.Conv2D(1, (kY,kX), strides=1, padding="same", activation='linear',weights=[kernel,bias])(i)#l_conv2d(i)
model = keras.Model(i, x)
model(image).numpy()
Actual output:
[2, 3, 3, 3, 2]
[2, 3, 3, 3, 2]
[2, 3, 3, 3, 2]
[2, 3, 3, 3, 2]
[2, 3, 3, 3, 2]
Expected output:
[4, 6, 6, 6, 4]
[6, 9, 9, 9, 6]
[6, 9, 9, 9, 6]
[6, 9, 9, 9, 6]
[4, 6, 6, 6, 4]
What am I doing wrong ?
You have mentioned padding='same' that's why you are getting output having the same shape as the input image 5x5x1x1 it is in the format Height X Width X Channel X No_of_filters. padding='same' parameter add additional padding values to the image to get the desired output volume shape. you can use padding='valid' to avoid padding.
You have missed batch dimension as well while providing an image to the model:
iX = iY = 9
kX = kY = 3
no_of_filter = 2
image = np.ones((iY,iX)).reshape((1,iY,iX,1))
kernel = np.ones((kY,kX,no_of_filter)).reshape((kY,kX,1,no_of_filter))
bias = np.array([0.0 for _ in range(no_of_filter)])
i = layers.Input(shape=(iY,iX,1))#l_input
x = layers.Conv2D(no_of_filter, (kY,kX), strides=1, padding="valid", activation='linear',weights=[kernel,bias])(i) #l_conv2d(i)
model = keras.Model(i, x)
model.summary()
model(image).numpy().shape
Related
Given a batch of images of shape (batch, c, h, w), I want to reshape it into (-1, depth, c, h, w) such that the i-th "chunk" of size d contains frames i -> i+d. Basically, using .view(-1, d, c, h, w) would reshape the tensor into d-size chunks where the index of the first image would be a multiple of d, which isnt what I want.
Scalar example:
if the original tensor is something like:
[1,2,3,4,5,6,7,8,9,10,11,12] and d is 2;
view() would return : [[1,2],[3,4],[5,6],[7,8],[9,10],[11,12]];
however, I want to get:
[[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,9],[9,10],[10,11],[11,12]]
I wrote this function to do so:
def chunk_slicing(data, depth):
output = []
for i in range(data.shape[0] - depth+1):
temp = data[i:i+depth]
output.append(temp)
return torch.Tensor(np.array([t.numpy() for t in output]))
However I need a function that is useable as part of a PyTorch model as this function causes this error :
RuntimeError: Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.
IIUC, You need torch.Tensor.unfold.
import torch
x = torch.arange(1, 13)
x.unfold(dimension = 0,size = 2, step = 1)
tensor([[ 1, 2],
[ 2, 3],
[ 3, 4],
[ 4, 5],
[ 5, 6],
[ 6, 7],
[ 7, 8],
[ 8, 9],
[ 9, 10],
[10, 11],
[11, 12]])
Another example with size = 3 and step = 2.
>>> torch.arange(1, 10).unfold(dimension = 0,size = 3, step = 2)
tensor([[1, 2, 3], # window with size = 3
# step : ---1--2---
[3, 4, 5], # 'step = 2' so start from 3
[5, 6, 7],
[7, 8, 9]])
I'm new in python, I was looking into a code which is similar to as follows,
import numpy as np
a = np.ones([1,1,5,5], dtype='int64')
b = np.ones([11], dtype='float64')
x = b[a]
print (x.shape)
# (1, 1, 5, 5)
I looked into the python numpy documentation I didn't find anything related to such case. I'm not sure what's going on here and I don't know where to look.
Edit
The actual code
def gausslabel(length=180, stride=2):
gaussian_pdf = signal.gaussian(length+1, 3)
label = np.reshape(np.arange(stride/2, length, stride), [1,1,-1,1])
y = np.reshape(np.arange(stride/2, length, stride), [1,1,1,-1])
delta = np.array(np.abs(label - y), dtype=int)
delta = np.minimum(delta, length-delta)+length/2
return gaussian_pdf[delta]
I guess that this code is trying to demonstrate that if you index an array with an array, the result is an array with the same shape as the indexing array (in this case a) and not the indexed array (i.e. b)
But it's confusing because b is full of 1s. Rather try this with a b full of different numbers:
>> a = np.ones([1,1,5,5], dtype='int64')
>> b = np.arange(11) + 3
array([ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
>>> b[a]
array([[[[4, 4, 4, 4, 4],
[4, 4, 4, 4, 4],
[4, 4, 4, 4, 4],
[4, 4, 4, 4, 4],
[4, 4, 4, 4, 4]]]])
because a is an array of 1s, the only element of b that is indexed is b[1] which equals 4. The shape of the result though is the shape of a, the array used as the index.
I'm trying to solve KNN using tensorflow. After I get the K neighbours for N vectors, I have a N by K tensor. Now, for each vector in N, I need to use tf.unique_with_counts to find the majority vote. However, I cannot iterate in a tensor and I cannot run tf.unique_with_counts with a multi-dimensional tensor. It keeps giving me InvalidArgumentError (see above for traceback): unique expects a 1D vector.
Example:
def knnVote():
'''
KNN using majority vote
'''
#nearest indices
A = tf.constant([1, 1, 2, 4, 4, 4, 7, 8, 8])
print(A.shape)
nearest_k_y, idx, votes = tf.unique_with_counts(A)
print("y", nearest_k_y.eval())
print("idx", idx.eval())
print("votes", votes.eval())
majority = tf.argmax(votes)
predict_res = tf.gather(nearest_k_y, majority)
print("majority", majority.eval())
print("predict", predict_res.eval())
return predict_res
Result:
y [1 2 4 7 8]
idx [0 0 1 2 2 2 3 4 4]
votes [2 1 3 1 2]
majority 2
predict 4
But how can I extend this to N by D input A, such as the case when A = tf.constant([[1, 1, 2, 4, 4, 4, 7, 8, 8],
[2, 2, 3, 3, 3, 4, 4, 5, 6]])
You can use tf.while_loop to iterate over A rows and process each row independently. This requires a little bit of dark magic with shape_invariants (to accumulate the results) and careful processing in a loop body. But it becomes more or less clear after you stare at it for some time.
Here's a code:
def multidimensionalKnnVote():
A = tf.constant([
[1, 1, 2, 4, 4, 4, 7, 8, 8],
[2, 2, 3, 3, 3, 4, 4, 5, 6],
])
def cond(i, all_idxs, all_vals):
return i < A.shape[0]
def body(i, all_idxs, all_vals):
nearest_k_y, idx, votes = tf.unique_with_counts(A[i])
majority_idx = tf.argmax(votes)
majority_val = nearest_k_y[majority_idx]
majority_idx = tf.reshape(majority_idx, shape=(1,))
majority_val = tf.reshape(majority_val, shape=(1,))
new_idxs = tf.cond(tf.equal(i, 0),
lambda: majority_idx,
lambda: tf.concat([all_idxs, majority_idx], axis=0))
new_vals = tf.cond(tf.equal(i, 0),
lambda: majority_val,
lambda: tf.concat([all_vals, majority_val], axis=0))
return i + 1, new_idxs, new_vals
# This means: starting from 0, apply the `body`, while the `cond` is true.
# Note that `shape_invariants` allow the 2nd and 3rd tensors to grow.
i0 = tf.constant(0)
idx0 = tf.constant(0, shape=(1,), dtype=tf.int64)
val0 = tf.constant(0, shape=(1,), dtype=tf.int32)
_, idxs, vals = tf.while_loop(cond, body,
loop_vars=(i0, idx0, val0),
shape_invariants=(i0.shape, tf.TensorShape([None]), tf.TensorShape([None])))
print('majority:', idxs.eval())
print('predict:', vals.eval())
you can use tf.map_fn to apply a function to each row of a matrix variable
def knnVote(A):
nearest_k_y, idx, votes = tf.unique_with_counts(A)
majority = tf.argmax(votes)
predict_res = tf.gather(nearest_k_y, majority)
return predict_res
sess = tf.Session()
with sess.as_default():
B = tf.constant([[1, 1, 2, 4, 4, 4, 7, 8, 8],
[2, 2, 3, 3, 3, 4, 4, 5, 6]])
C = tf.map_fn(knnVote, B)
print(C.eval())
Given a network with two or more placeholders of varying dimensionality e.g.
x1 = tf.placeholder(tf.int32, [None, seq_len])
x2 = tf.placeholder(tf.int32, [None, seq_len])
xn = tf.placeholder(tf.int32, [None, None, seq_len]
The first dimension in each placeholder corresponds to the minibatch size. seq_len is the length of the inputs. The second dimension is like a list of inputs that I need to process together with x1 and x2 for each index in the minibatch. How can I group these tensors to operate on them by batch index?
For example
x1 = [[1, 2, 3], [4, 5, 6]]
x2 = [[7, 8, 9], [8, 7, 6]]
xn = [[[1, 5, 2], [7, 2, 8], [3, 2, 5]], [[8, 9, 8]]]
I need to keep x1[0] i.e. [1, 2, 3], x2[0] i.e. [7, 8, 9], and xn[0] i.e. [[1, 5, 2], [7, 2, 8], [3, 2, 5]] together, because I need to perform matrix operations between x1[i] and each element in xn[i] for all i.
Notice that the dimensionality of xn is jagged.
Still not sure if I understand your question. If I understand correctly, your challenge comes from the jagged nature of the dimensionality of xn. I have the below way to "unrolling" along batch index. The result is an array with a size of batch_size; each element in the array is a Tensor. Of course you can perform other operations for all these individual tensors before evaluating them.
I have to use tf.scan to perform the operation for each element of xn[i] because its first dimension is dynamic. There might exist better solutions though.
x1 = np.array([[1, 2, 3]])
xn = np.array([[[1, 5, 2], [7, 2, 8], [3, 2, 5]]])
batch_size = x1.shape[0]
result = []
for batch_idx in range(batch_size):
x1_i = x1[batch_idx]
xn_i = xn[batch_idx]
result.append(tf.scan(fn=lambda a, x: x * x1_i, elems=xn_i, initializer=x1_i))
with tf.Session() as sess:
print sess.run([result[0]])
# result, this is x1[0] multiply each element in xn[0] for all i (element-wise).
# free free to plug in your own matrix operations in the `fn` arg of `tf.scan`.
[array([[ 1, 10, 6],
[ 7, 4, 24],
[ 3, 4, 15]])]
I have a 1-D tensor with N elements which is generated by interlacing 2 1-D vectors with N/2 elements. How can I do this with TensorFlow?
For example, I want to generate [0, 1, 2, 3, 4, 5, 6, 7] from [0, 2, 4, 6] and [1, 3, 5, 7].
I hope there could be a 1-line solution.
Thanks!!
You can stack a and b as columns, then reshape it to 1d:
tf.reshape(tf.stack([a, b], axis=-1), [-1])
a = tf.constant([0, 2, 4, 6])
b = tf.constant([1, 3, 5, 7])
sess = tf.InteractiveSession()
interlace = tf.reshape(tf.stack([a, b], axis=-1), [-1])
print(sess.run(interlace))
# [0 1 2 3 4 5 6 7]