Reshape and conccatente arrays in 4D to 3D - python-3.x

l'm working with 4D arrays in numpy. l would like to append the data in forth dimension as follow :
1)
inputs :
data_1_1=dim(2,4,130,10)
data_1_2=dim(2,4,130,10)
expected output :
data_1=dim(2,4,130,20)
2) reduce 4D array to 3D array
inputs :
data_2_1=dim(3,5,130,20)
expected output :
data_2_1=dim(15,130,20)
Sorry for my newbie question.
Thank you for your help
What l have tried ?
1)
data_1= np.concatenate((data_1_1[...,np.newaxis],data_1_2[...,np.newaxis]),axis=2)
l'm wondering if this solution do the right job. since l would like to concatenate on the last dimension. In which order it's done ?
Is is correct ?
2) For this case l don't have any idea

For the first part you need to say you want a specific axis to work on:
>>>x=np.arange(2*4*130*10).reshape(2,4,130,10)
>>>np.concatenate((x,x),axis=3).shape
(2, 4, 130, 20)
and for the second part, sounds like you want a reshape
>>>y=np.arange(3*5*130*20).reshape(3,5,130,20)
>>> y.reshape(15,130,20).shape
(15, 130, 20)
The numpy terms you need to acquaint yourself with are axis and shape - a good read on these will help you a lot.

Related

Place two 2D matrices (numpy arrays) one after other on chennel for CNN input

I am trying to create the data for my CNN network. Desired input shape for my CNN network is 36 X 36 X 2. This means, I have two different 2D matrices with the size of 36 X 36.
Using these two matrices, I want to get a output of 36 X 36 X 2.
I have tried above code.
arr1 = np.random.rand(36,36)
arr2 = np.random.rand(36,36)
res = np.stack((arr1, arr2), axis=2)
Output should look like as matrices in the image:
I want my input shape as described in the picture. first matrix should be arr1, second matrix should be arr2 and both matrix should be placed one after other.
However, I am quite confused with the result I got from res. It shows me the shape (36, 36, 2), but when I print the res, then I am not able to see my first matrix and second matrix properly. I see elements from my first matrix arr1 is inside other matrix.
I am not sure if this process gives me a correct output or I am doing anything wrong.

combining non-uniform size 2D arrays into a 3D array in python?

I've searched on stackoverflow but could not find an answer to this specific question. Sorry if it is a naive question, I am a newbie to python. I have three 2d arrays of shapes
Shape of arr_X = (1,8), Shape of arr_Y = (1,8), & Shape of
arr_Z = (5,8).
From these 2D arrays I want to make one 3D array of shape (5, 8, 8).
Can anyone help me to form the 3D array?

How to create a tensor by accessing specific values at given indices of a 2 X 2 tensor in pytorch?

Suppose
mat = torch.rand((5,7)) and I want to get values from 1st dimension (here, 7) by passing the indices, say idxs=[0,4,2,3,6]. The way I am able to do it now is by doing mat[[0,1,2,3,4],idxs]. I expected mat[:,idxs] to work, but it didn't. Is the first option the only way or is there a better way?
torch.gather is what you are looking for:
torch.gather(mat, 1, torch.tensor(idxs)[:, None])

Permutate over output of CNN to return smallest loss and rearange output

Lets say i am detecting dogs on images.
Output of my CNN is
Dense(24,activation="relu")
Which means i want to detect up to 6 dogs ( each dogs should be represented by xmin,ymin,xmax,ymax = 4 values , 4 * 6 = 24 )
Now lets say i have two dogs on pictures and their positions are ( bounding box )
dog1 = { xmin: 50, ymin:50, xmax:150,ymax:150}
dog2 = { xmin: 300,ymin:300,xmax:400,ymax:400}
Now tha label for this picture would look something like
( 50, 50, 150, 150, 300, 300, 400 ,400 , 0 ,0, 0 ... 16 zeros )
Now what if my CNN outputs something like
( 290, 285, 350 , 350, 60 , 40 , 120 ,110 ... 0 ... )
AS you can see the first bounding box that CNN outputs is closer to the bounding box of second dog and vice verse.
How should i deal with this?
I can create my own MSE function and output the smallest value e.g
def custom_mse(y_true, y_pred):
tmp = 10000000000
a = list(itertools.permutations(y_pred))
for i in range(0, len(a)):
t = K.mean(K.square(a[i] - y_true), axis=-1)
if t < tmp :
tmp = t
return tmp
But this would results only in "best" loss but the weights would get modified wrongly.
How can i modify output of CNN ( permutate or rearrange elements ) so this would work?
I hope i explained it clearly.
Thanks for help.
Your issue lies in on what object you calculate the loss.
Tensorflow/Keras/Almost any other library, uses its own objects in order to find derivatives and define the calculation graph.
Therefore, if you need to do anything with the graph, you must do it using a defined op or define your own op using the given methods and objects. Tensorflow also allows to wrap regular python functions and make it as ops on tensors.
As for your problem, create a 2d output array of dims [4,num_of_objects] and use tensorflow operations to reorder the second dimension before calculating loss. See full lists here. Split it according to second dimension, iterate combinations, use tf.min to find the minimum loss, and optimize only the minimum loss. Experimented with that approach, it works, also with bounding boxes.
EDIT: Noted that you perform your experiments and calculation with Keras, use Tensorflow backend and work only on tensors, do NOT retreive data from graph to numpy/list objects. Use only tensors.
Good luck!

Finding the centre of multiple lines using least squares approach in Python

I have a series of lines which roughly (but not exactly) intersect at some point.
I need to find the point which minimises the distance between each line in the centre. I have been trying to follow this methodology:
Nearest point to intersecting lines in 2D
When I create my script in Python to perform this function I get the incorrect answer:
Here is my code, I was wondering if anyone could suggest what I am doing wrong? Or an easier way of going about this. Each line is defined by two points x1 and x2.
def directionalv(x1,x2):
point1=np.array(x1) #point1 and point2 define my line
point2=np.array(x2)
ortho= np.array([[0,-1],[1,0]]) #see wikipedia article
subtract=point2-point1
length=np.linalg.norm(subtract)
fraction = np.divide(subtract,length)
n1=ortho.dot(fraction)
num1=n1.dot(n1.transpose())
num = num1*(point1)
denom=n1.dot(n1.transpose())
return [num,denom]
n1l1=directionalv(x1,x2)
n1l2=directionalv(x3,x4)
n1l3=directionalv(x5,x6)
n1l4=directionalv(x7,x8)
n1l5=directionalv(x9,x10)
numerall=n1l1[0]+n1l2[0]+n1l3[0]+n1l4[0]+n1l5[0] #sum of (n.n^t)pi from wikipedia article
denomall=n1l1[1]+n1l2[1]+n1l3[1]+n1l4[1]+n1l5[1] #sum of n.n^t
point=(numerall/denomall)
My points are as follows
Line1 consists of points x1= [615, 396] and x2 = [616, 880]
Line 2, x3 = [799, 449] x4= [449, 799]
Line 3, x5 = [396, 637] x6 = [880, 636]
Line 4, x7 = [618, 396] x8 = [618, 880]
Line 5, x9 = [483, 456] x10 = [777, 875]
Any help would be really appreciated!
Thank you for your time.
Could it simply be the fact that you should define in Python the matrix as 2 vectors (understand is a column of the matrix, not row!
see: How to define two-dimensional array in python ), you'll then should define the ortho matrix like this:
ortho= np.array([[0,1],[-1,0]])
Otherwise, what does the following means?
numerall=n1l1[0]+n1l2[0]+n1l3[0]+n1l4[0]+n1l5[0] #sum of (n.n^t)pi from wikipedia article
denomall=n1l1[1]+n1l2[1]+n1l3[1]+n1l4[1]+n1l5[1] #sum of n.n^t
point=(numerall/denomall)
I do not understand your interpretation of the transposition of a Matrix; and the inverse of a matrix does not equals to a division.
Use an existing Python library like Numpy to do the computing instead of implementing it yourself. See: https://docs.scipy.org/doc/numpy-1.10.4/reference/generated/numpy.matrix.html

Resources