How to remove specific value in tensor? - pytorch

If I have the tensor like this,
tensor([[2, 5, 4, 2, 1, 1, 1, 1, 5],
[4, 0, 1, 5, 0, 3, 5, 1, 4],
[1, 1, 7, 2, 1, 5, 1, 1, 1],
[5, 5, 5, 3, 0, 4, 3, 1, 1],
[1, 1, 1, 1, 5, 3, 2, 7, 3],
[6, 6, 1, 1, 1, 1, 1, 1, 1]])
I wanted to remove value '1' as many as i can
so desired tensor is like this
tensor([[2., 5., 4., 2., 5., 1., 1.],
[4., 0., 5., 0., 3., 5., 4.],
[7., 2., 5., 1., 1., 1., 1.],
[5., 5., 5., 3., 0., 4., 3.],
[5., 3., 2., 7., 3., 1., 1.],
[6., 6., 1., 1., 1., 1., 1.]])
how to make original tensor to desired tensor effectively?
I tried like this way,
>>> not_one = torch.sum(t!=1, dim=-1)
>>> max_l = not_one.max()
>>> not_one
tensor([5, 7, 3, 7, 5, 2])
>>> max_l
tensor(7)
>>> desired_tensor = torch.ones(t.size(0), max_l)
>>> for i, tt in enumerate(t):
... desired_tensor[i, :not_one[i]] = tt[tt != 1]
...
>>> desired_tensor
tensor([[2., 5., 4., 2., 5., 1., 1.],
[4., 0., 5., 0., 3., 5., 4.],
[7., 2., 5., 1., 1., 1., 1.],
[5., 5., 5., 3., 0., 4., 3.],
[5., 3., 2., 7., 3., 1., 1.],
[6., 6., 1., 1., 1., 1., 1.]])

Related

Numpy: Generate matrix recursively

Is there a smart way to recursively generate matrices with increasing sizes in numpy?
I do have a generator matrix which is
g = np.array([[1, 0], [1, 1]])
And in every further iteration, the size of both axes doubles, making a new matrix of the format:
[g_{n-1}, 0], [g_{n-1}, g_{n-1}]
which means that the new version would be:
g = np.array([[1, 0, 0, 0], [1, 1, 0, 0], [1, 0, 1, 0], [1, 1, 1, 1]])
Is there an easy way to obtain something like that?
I could also generate a matrix of size (len(g)*2, len(g)*2) and try to fill it manually in two for-loops, but that seems extremely annoying.
Is there a better way?
PS: For those of you curious about it, the matrix is the generator matrix for polar codes.
IIUC, one way using numpy.block:
g = np.array([[1, 0], [1, 1]])
g = np.block([[g, np.zeros(g.shape)], [g, g]])
Output (iteration 1):
array([[1., 0., 0., 0.],
[1., 1., 0., 0.],
[1., 0., 1., 0.],
[1., 1., 1., 1.]])
Output (iteration 2):
array([[1., 0., 0., 0., 0., 0., 0., 0.],
[1., 1., 0., 0., 0., 0., 0., 0.],
[1., 0., 1., 0., 0., 0., 0., 0.],
[1., 1., 1., 1., 0., 0., 0., 0.],
[1., 0., 0., 0., 1., 0., 0., 0.],
[1., 1., 0., 0., 1., 1., 0., 0.],
[1., 0., 1., 0., 1., 0., 1., 0.],
[1., 1., 1., 1., 1., 1., 1., 1.]])
I don't see a straight-forward way to generate g_n, but you can reduce the two for-loops to one (along n) with:
# another sample
g = np.array([[1, 0], [2, 3]])
g = (np.array([[g,np.zeros_like(g)],[g, g]])
.swapaxes(1,2).reshape(2*g.shape[0], 2*g.shape[1])
)
Output:
array([[1, 0, 0, 0],
[2, 3, 0, 0],
[1, 0, 1, 0],
[2, 3, 2, 3]])

Concatenate torch tensor at a certain index

I am looking to Concatenate 2 torch tensors at a certain index. As an example, I want to add b after a[1].
a = torch.Tensor([1, 2, 3, 4, 5])
b = torch.Tensor([6, 7, 8, 9, 10])
The desired output is
torch.Tensor([1, 2, 6, 7, 8, 9, 10, 3, 4, 5])
I tried torch.cat, but I can only have
tensor([ 6., 7., 8., 9., 10., 1., 2., 3., 4., 5.])
tensor([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
you will need to split the first tensor and concatenate the second in between
torch.cat([a[:2], b, a[2:]])
output will be like
tensor([ 1., 2., 6., 7., 8., 9., 10., 3., 4., 5.])

How to multiply torch[N,1] and torch[1,N]?

I'd like to calculate a matrix (shape[N,N]) by multiplying 2 torch vectors A(shape[N,1]) and B=A'(shape[1,N]).
When I use torch.matmul or torch.mm, I got errors or A'A(shape[1,1]).
If A is denoted as
A = [a_1, a_2, ..., a_N]', I want to calculate a matrix C whose (i,j)element is
for i in range(N):
for j in range(N):
C(i,j) = a_i * a_j
I'd like to calculate this quickly. Do you have any ideas?
thank you for your help!
If I understood you correctly you can do something like this :
A = torch.randint(0,5,(5,))
C = (A.view(1, -1) * A.view(-1, 1)).to(torch.float)
it produces :
tensor([[ 1., 4., 3., 3., 0.],
[ 4., 16., 12., 12., 0.],
[ 3., 12., 9., 9., 0.],
[ 3., 12., 9., 9., 0.],
[ 0., 0., 0., 0., 0.]])
which is equivalent to writting :
D = torch.zeros((5,5))
for i in range(5):
for j in range(5):
D[i][j] = A[i] * A[j]
which results in :
tensor([[ 1., 4., 3., 3., 0.],
[ 4., 16., 12., 12., 0.],
[ 3., 12., 9., 9., 0.],
[ 3., 12., 9., 9., 0.],
[ 0., 0., 0., 0., 0.]])
You could simply do the following:
import torch
A = torch.randint(0, 5, (3, 2))
B = torch.randint(0, 5, (2, 3))
A:
tensor([[1, 3],
[2, 1],
[1, 3]])
B:
tensor([[1, 0, 3],
[3, 4, 1]])
C = A # B # python 3.5+
C:
tensor([[10, 12, 6],
[ 5, 4, 7],
[10, 12, 6]])

keras and nlp - when to use .texts_to_matrix instead of .texts_to_sequences?

Keras offers a couple of helper functions to process text:
texts_to_sequences and texts_to_matrix
It seems that most people use texts_to_sequences, but it is unclear to me why one is picked over the other and under what conditions you might want to use texts_to_matrix.
texts_to_matrix is easy to understand. It will convert texts to a matrix with columns refering to words and cells carrying number of occurrence or presence. Such a design will be useful for direct application of ML algorithms (logistic regression, decision tree, etc.)
texts_to_sequence will create lists that are collection of integers representing words. Certain functions like Keras-embeddings require this format for preprocessing.
Consider the example below.
txt = ['Python is great and useful', 'Python is easy to learn', 'Python is easy to implement']
txt = pd.Series(txt)
tok = Tokenizer(num_words=10)
tok.fit_on_texts(txt)
mat_texts = tok.texts_to_matrix(txt, mode='count')
mat_texts
Output:
array([[0., 1., 1., 0., 0., 1., 1., 1., 0., 0.],
[0., 1., 1., 1., 1., 0., 0., 0., 1., 0.],
[0., 1., 1., 1., 1., 0., 0., 0., 0., 1.]])
tok.get_config()['word_index']
Output:
'{"python": 1, "is": 2, "easy": 3, "to": 4, "great": 5, "and": 6, "useful": 7, "learn": 8, "implement": 9}'
mat_texts_seq = tok.texts_to_sequences(txt)
mat_texts_seq
Output:-
[[1, 2, 5, 6, 7], [1, 2, 3, 4, 8], [1, 2, 3, 4, 9]]

Image composition based on "pattern matrix"

I want to stitch together c rgb images in numpy resulting into a larger image. Images are represented as numpy arrays. I however, do have the following constraints:
I do want to stitch together c rgb images in shape n * m = c, stored in a dictionary, here an example of a dictionary containing 21 images:
c_images = { 5:numpy.array[[x,y,3]], 1:numpy.array[[x,y,3]], ... 21:numpy.array[[x,y,3]]}
I have a "pattern" matrix of size n * m = c, in which each the indexes of the images 0...c are scattered randomly. A randomly generated "pattern matrix" of size n = 3, m = 7, c = 21looks like the following
P_matrix = [[14, 3, 19, 5, 16, 18, 0],
[17, 1, 13, 7, 6, 15, 11],
[4, 9, 10, 12, 8, 20, 2 ]]
What would be the best way to use the pattern matrix, to compose a larger numpy array, based on c images ?
Maybe np.block can help you. Not all the images have to be the same size but they need to fit together. First some example data:
import numpy as np
n, m = 3, 4
img_size = np.array([3, 3])
img_list = [np.zeros(img_size)+i for i in range(n*m)]
# [array([[1., 1., 1.], array([[2., 2., 2.], ...array([[12., 12., 12.],
# [1., 1., 1.], [2., 2., 2.], [12., 12., 12.],
# [1., 1., 1.]]), [2., 2., 2.]]),, [12., 12., 12.]])
rnd_idx = np.random.permutation(range(n*m)).reshape((n, m))
# array([[ 9, 10, 0, 4],
# [ 3, 11, 6, 5],
# [ 2, 8, 7, 1]])
Than you need to create a nested list of your images based on the given pattern, np.block does the rest for you:
img_list_nested = [[img_list[col] for col in rows] for rows in rnd_idx]
img = np.block(img_list_nested)
# array([[ 9., 9., 9., 10., 10., 10., 0., 0., 0., 4., 4., 4.],
# [ 9., 9., 9., 10., 10., 10., 0., 0., 0., 4., 4., 4.],
# [ 9., 9., 9., 10., 10., 10., 0., 0., 0., 4., 4., 4.],
# [ 3., 3., 3., 11., 11., 11., 6., 6., 6., 5., 5., 5.],
# [ 3., 3., 3., 11., 11., 11., 6., 6., 6., 5., 5., 5.],
# [ 3., 3., 3., 11., 11., 11., 6., 6., 6., 5., 5., 5.],
# [ 2., 2., 2., 8., 8., 8., 7., 7., 7., 1., 1., 1.],
# [ 2., 2., 2., 8., 8., 8., 7., 7., 7., 1., 1., 1.],
# [ 2., 2., 2., 8., 8., 8., 7., 7., 7., 1., 1., 1.]])

Resources