How to reshape and change the rank of a numpy array? - numpy

if I have a numpy array of shape
(16, 224, 224, 6)
how can I reshape it to
(224, 224, 6*16)
so that all elements are still in the new shape?
P.S.:I need a numpy answer and not an answere derived from pytorch please :)

I believe you can use transpose and reshape:
a.transpose([1,2,3,0]).reshape(244,244,-1)

Probably the most elegant and easy to understand way is to use einops:
from einops import rearrange
a = rearrange(a, 'b w h c -> w h (b c)')
Plus this code works on Numpy, Pytorch, Jax and Tensorflow without changes.

Related

What does the .numpy() function do?

I tried searching for the documentation online but I can't find anything that gives me an answer. What does .numpy() function do? The example code given is:
y_true = []
for X_batch, y_batch in mnist_test:
y_true.append(y_batch.numpy()[0].tolist())
Both in Pytorch and Tensorflow, the .numpy() method is pretty much straightforward. It converts a tensor object into an numpy.ndarray object. This implicitly means that the converted tensor will be now processed on the CPU.
Ever getting a problem understanding some PyTorch function you may ask help().
import torch
t = torch.tensor([1,2,3])
help(t.numpy)
Out:
Help on built-in function numpy:
numpy(...) method of torch.Tensor instance
numpy() -> numpy.ndarray
Returns :attr:`self` tensor as a NumPy :class:`ndarray`. This tensor and the
returned :class:`ndarray` share the same underlying storage. Changes to
:attr:`self` tensor will be reflected in the :class:`ndarray` and vice versa.
This numpy() function is the converter form torch.Tensor to numpy array.
If we look at this code below, we see a simple example where the .numpy() convert Tensors to numpy arrays automatically.
import numpy as np
ndarray = np.ones([3, 3])
print("TensorFlow operations convert numpy arrays to Tensors automatically")
tensor = tf.multiply(ndarray, 42)
print(tensor)
print("And NumPy operations convert Tensors to numpy arrays automatically")
print(np.add(tensor, 1))
print("The .numpy() method explicitly converts a Tensor to a numpy array")
print(tensor.numpy())
In the 2nd last line of code, we see that the tensorflow officials declared it as the converter of Tensor to a numpy array.
You may check it out here

Reshaping a numpy vector

I am really new to numpy. I have a numpy vector that when I run y.shape returns (4000,). Is there a way, I can have it return (4000, 1)?
np.reshape(y,(4000,1))
Reshape function can be used to do this

Unpackbits only in TF

I am looking for a way to unpack bits in TF in the same way I can do this with np.unpackbits. So revert the operation like:
import numpy as np
import tensorflow as tf
original = np.random.choice(a=[1, 0], size=(100))
data = np.packbits(original.astype(np.bool), axis=None)
X = tf.constant(data)
Assuming I have access only to X, how to convert it to original in TF. Of course I can use numpy, but this will move data from TF to python and then back to TF.
Few thoughts I had in mind (have not implemented any of them):
use tf.map_fn
use tf.contrib.lookup
For both of them the ideas is to map each number to a vector, concat all the vectors, reshape, remove unneeded elements.
Both of the approaches seems more complicated that they should be. Does anyone has an efficient way (in terms of speed) how to achieve numpy's unpackbits in tensorflow?
Perhaps something like this:
import tensorflow as tf
x = tf.constant((1, 2, 7, 0, 255), dtype=tf.uint8)
b = tf.constant((128, 64, 32, 16, 8, 4, 2, 1), dtype=tf.uint8)
unpacked = tf.reshape(tf.mod(tf.to_int32(x[:,None] // b), 2), [-1])
unpacked is in int32 due to tf.mod not accepting bytes, you may want to cast it to uint8 again.
Tensorflow 1.3 will have bitwise operations, so this last line could be replaced with
unpacked = tf.reshape(tf.bitwise.bitwise_and(x, b), [-1])
which will hopefully be faster (and the result in uint8).

Advanced indexing in Tensorflow

I have two tensors with shapes
voxels :: (4, 64, 64, 64)
indices :: (4096, 3)
Here voxels has dtype float32, while indices are integers between 0 and 63.
I would like to index the voxels, creating a tensor tensor output:
output :: 4, 4096
Such that the following constraint holds
output[i,j] = voxels[i, indices[j,0], indices[j,1]. indices[j,2]]
How can I do this in tensorflow?
There is some talk of more advanced slicing here, but it's not clear that the suggestions there apply, or that the gradients have been implemented.
For reference, if the above tensors were numpy arrays, the following code does what I want:
output = voxels[:, indices[:,0],indices[:,1],indices[:,2]]
gather_nd is indeed a possibility, but gradients are not yet implemented. However, it is also possible to use a trick involving gather, by flattening the tensor and re-computing appropriate indices.
I believe gather_nd does what you want, though I don't think the gradients have been implemented.

Slicing by tensor with indices

I have a tensor tf.shape(X) == [M, N, N] and a set of indices tf.shape(IDX) == [N, N]. How can I form a tensor tf.shape(Y) = [N, N], which equals to the slice of X using indices IDX in the first dimension? I.e.
Y[i, j] = X[IDX[i, j], i, j] for all i,j = 1..N.
I have tried to play with tf.gather_nd but with no result :(
Update 10-12-2016:
As of tensorflow version 0.11 and up one can index into tensors in the same way as numpy.
a = tf.Variable([9,10,11])
b = tf.constant([[1,2,3,4],[5,6,7,8]])
a = b[0,1:]
Gradients are also supported on the indexing.
What did you try already?
It seems like there's a bug with tf.gather_nd that I reported.
Here's the response
Support for partial indices in gather_nd (fewer indices than dimensions) was added quite recently. You are you using a version of TensorFlow where each index tensor must have exactly the number of tensor dimensions. The code should work at HEAD.
so by version 0.10 or above gather_nd should work like you want.
However this below works
import tensorflow as tf
x = tf.constant([[1,1,1,1],[1,2,3,4]],shape=(2,4))
indices = [[0,0],[0,1]]
y = tf.gather_nd(x,indices)
so it seems like you need the full index description at the moment, not just slice 0. You also try tf.pack.
You can also track the progress of indexing tensors in tensorflow here:
https://github.com/tensorflow/tensorflow/issues/206