Dividing 3D tensor into Batches

I have a tensor of shape (50,50,2). That is filled with values of a grid in (x,y). Like this.

r =0.5
#Sample 3D space
min = -10
max = 10
complexnum = 50j

#Sample 3D space
X,Y  = np.mgrid[min:max:complexnum,min:max:complexnum,] * r

T = np.sin(3*X) * np.sin(3*Y)

XY = np.concatenate((X.reshape((X.shape[0],X.shape[0],1)),Y.reshape((X.shape[0],X.shape[0],1))),2)
XY = torch.from_numpy(XY.astype(np.float32)).to(device)
T = T.reshape((T.shape[0],T.shape[0],1))
T = torch.from_numpy(T.astype(np.float32)).to(device)

I created a Neural Network that can take the XY as input and T as an output. In that is creating a function f(x,y). Now I need to create a way to train that NN using batches. The total amount of samples should be 2500 = 50 x 50. I want to divide the XY and T tensor into batches. I have tried DataLoader and creating a data set class with no luck. Is there a way I can achieve this? Are my Tensor shapes correct?

Sorry for this very basic question, I have been struggling to work with higher dimensions.

Are the questions badly explained? I would have guessed someone would reply by now.

If the total number of samples should be 2500, you should use this shape in dim0 via:

XY = XY.view(-1, 2) # should have shape [2500, 2] now
T = T.view(-1, 1) # should have shape [2500, 1] now

Afterwards you can pass these tensors to a TensorDataset and this dataset to a DataLoader.
Let me know, if you get stuck.

Another question, If I want to transform that grid into a list of the points of (x,y). Would I do the same? I found that if I do XY.view(-1, 2) I will have reaping (x,y) pairs.

Thank you for your reply. Maybe I didn’t understand the whole problem myself before explaining. But now I do. So what I want to create batches of parts of the grid. If you think of it as an image is divided into subsets of the images, then randomly sample each of them to create new sub-images filled with random samples of those subdivisions.

So for example I want to make batches of shape [12,12,2] and [12,12,1] that have random samples of the data set. I think I would have to create and slice it in my own way. I tried to find something similar but I could find anything like it.

For now, I have done something similar to what you have told me to do.

Thank you for the reply, if you do know how I could start doing this it could improve my current code.

I’m not sure if I fully understand your use case, but would you like to create windows or patches from a larger image?
E.g. given an input image of [channels=3, height=224, width=224], would you like to create multiple smaller patches in e.g. [channels=3, height=12, width=12] using a sliding window approach?
If so, then you should use tensor.unfold to create these patches.

Here is an example.

1 Like

Yeah, I think I haven’t mastered how to properly use grids.

I’m trying to train a NN that can learn f(x,y), so for each pair of x,y there is a value associated with it.

This specific function:

T = np.sin(3*X) * np.sin(3*Y)

I wanted to do this example first to try and see if I can do it before using it for more complicated inputs such as images. That is why I tried to use np.mgrid to produce sample (x,y) uniformly and use it as my training set. Could you think of any way I could do it more easily?

Yes, exactly to later use as mini-batches in the training. And if you are confused of why I’m trying to do this for. I’m working on a new algorithm for academic purposes .

I think you are using a valid approach.
Are you concerned about the ordering of the data after the reshape?
If so, you could print some data and check, if the shape is expected.

After my view operation, the [50, 50] numpy array would be flattened to [2500, 1], so that each “point” is a sample now.

Yeah, that is one of my concerns. Since I want to train a NN to a specific image I wanted to see if I could just use a grid structure to train the network and try not to flatten it.

Since I wanted to cut it into overlapping quadrants, and somehow is been quite difficult to do it in a 1d array. Haha, I’m just trying to avoid redoing my whole code.