Error relating to conversion from list to tensor in Pytorch - pytorch

There is a variable 'tmp' (3 dimension).
tmp = [torch.tensor([1]),torch.tensor([2,3])]
type(tmp) -> <class 'list'>
type(tmp[0]) -> <class 'torch.Tensor'>
type(tmp[0][0]) -> <class 'torch.Tensor'>
I want to convert 'tmp' into torch.Tensor type.
But, when I run this code below, an error occurs.
torch.Tensor(tmp)
>> ValueError: only one element tensors can be converted to Python scalars
How can I fix this?
torch.stack cannot be effective in this case because tensors in 'tmp' are not the same shape.

Use torch.stack - All tensors need to be of the same size in the list.
>>> torch.stack(tmp)
Ex:
>>> tmp = [torch.rand(2,2),torch.rand(2,2)]
>>> tmp = torch.stack(tmp)
>>> tmp
tensor([[[0.0212, 0.1864],
[0.0070, 0.3381]],
[[0.1607, 0.9568],
[0.9093, 0.1835]]])
>>> type(tmp)
<class 'torch.Tensor'>

Related

Find the biggest of two pytorch tensor on size

How to find the biggest of two pytorch tensors on size
>>> tensor1 = torch.empty(0)
>>> tensor2 = torch.empty(1)
>>> tensor1
tensor([])
>>> tensor2
tensor([5.9555e-34])
torch.maximum is returrning the empty tensor as the biggest tensor
>>> torch.maximum(tensor1,tensor2)
tensor([])
Is there a way to find the biggest tensor among two tensors (mostly 1d), base on the number of elements in the tensor.
Why not comparing their first dimension size? To do so you can use equivalents: x.size(0), x.shape[0], and len(x). To return the tensor with longest size, you can use the built-in max function with the key argument:
>>> max((tensor1, tensor2), key=len)

Batch-wise norm of a tensor

I have a tensor t of dim n x 3. When I apply torch.linalg.norm it returns one single value. What I need is a batch-wise norm function which will return a tensor with n norms, one for each vector in t.
Thanks for your help.
It seems the most relevant documentation place is:
https://pytorch.org/docs/stable/generated/torch.linalg.norm.html
In the terminal you could try: python3 and then the following python commands:
>>> from torch import linalg as LA
>>> c = torch.tensor([[1., 2., 3.],
... [-1, 1, 4]])
>>> LA.norm(c, dim=0)
tensor([1.4142, 2.2361, 5.0000])
>>> LA.norm(c, dim=1)
tensor([3.7417, 4.2426])
Conclusion:
In your specific case you will need to do:
torch.linalg.norm(t,dim=1)

Can't reshape my numpy array for training a KNN model

I try to train a KNN model using a Local Binary Pattern (LBP) descriptor.
My data is a numpy.array of shape (67, 26) elements, but myaray.shape returns (67, ).
I tried to reshape the array like:
myarray.reshape(-1, 26)
but it resulted in the following error:
ValueError: cannot reshape array of size 67 into shape (26)**
Thanks you so much
As I'm not sure I've clearly understood your question, first I'm going to try to mock up your data:
In [101]: import numpy as np
In [102]: myarray = np.empty(shape=67, dtype=object)
In [103]: for i in range(len(myarray)):
...: myarray[i] = np.random.rand(26)
Please, run the following code:
In [104]: type(myarray)
Out[104]: numpy.ndarray
In [105]: myarray.shape
Out[105]: (67,)
In [106]: myarray.dtype
Out[106]: dtype('O')
In [107]: type(myarray[0])
Out[107]: numpy.ndarray
In [108]: myarray[0].shape
Out[108]: (26,)
If you get the same results as above, numpy.stack should do the trick as pointed out by #hpaulj in the comments:
In [109]: x = np.stack(myarray)
In [110]: type(x)
Out[110]: numpy.ndarray
In [111]: x.shape
Out[111]: (67, 26)

how to use map with tuples in a tensorflow 2 dataset?

trying to map a tuple to a tuple in a dataset in tf 2 (please see code below). my output (please see below) shows that the map function is only called once. and i can not seem to get at the tuple.
how do i get at the "a","b","c" from the input parameter which is a:
tuple Tensor("args_0:0", shape=(3,), dtype=string)
type <class 'tensorflow.python.framework.ops.Tensor'>
edit: it seems like using Dataset.from_tensor_slices produces the data all at once. this explcains why map is only called once. so i probably need to make the dataset in some other way.
from __future__ import absolute_import, division, print_function, unicode_literals
from timeit import default_timer as timer
print('import tensorflow')
start = timer()
import tensorflow as tf
end = timer()
print('Elapsed time: ' + str(end - start),"for",tf.__version__)
import numpy as np
def map1(tuple):
print("<<<")
print("tuple",tuple)
print("type",type(tuple))
print("shape",tuple.shape)
print("tuple 0",tuple[0])
print("type 0",type(tuple[0]))
print("shape 0",tuple.shape[0])
# how do i get "a","b","c" from the input parameter?
print(">>>")
return ("1","2","3")
l=[]
l.append(("a","b","c"))
l.append(("d","e","f"))
print(l)
ds=tf.data.Dataset.from_tensor_slices(l)
print("ds",ds)
print("start mapping")
result = ds.map(map1)
print("end mapping")
$ py mapds.py
import tensorflow
Elapsed time: 12.002168990751619 for 2.0.0
[('a', 'b', 'c'), ('d', 'e', 'f')]
ds <TensorSliceDataset shapes: (3,), types: tf.string>
start mapping
<<<
tuple Tensor("args_0:0", shape=(3,), dtype=string)
type <class 'tensorflow.python.framework.ops.Tensor'>
shape (3,)
tuple 0 Tensor("strided_slice:0", shape=(), dtype=string)
type 0 <class 'tensorflow.python.framework.ops.Tensor'>
shape 0 3
>>>
end mapping
The value or values returned by map function (map1) determine the structure of each element in the returned dataset. [Ref]
In your case, result is a tf dataset and there is nothing wrong in your coding.
To check whether every touple is mapped correctly you can traverse every sample of your dataset like follows:
[Updated Code]
def map1(tuple):
print(tuple[0].numpy().decode("utf-8")) # Print first element of tuple
return ("1","2","3")
l=[]
l.append(("a","b","c"))
l.append(("d","e","f"))
ds=tf.data.Dataset.from_tensor_slices(l)
ds = ds.map(lambda tpl: tf.py_function(map1, [tpl], [tf.string, tf.string, tf.string]))
for sample in ds:
print(str(sample[0].numpy().decode()), sample[1].numpy().decode(), sample[2].numpy().decode())
Output:
a
1 2 3
d
1 2 3
Hope it will help.

Getting TypeError when wrapping input().split() in int()

So I just wanted to know the reason and cause of error I am getting in order to get a better understanding of python.
Here is what I have tried.
Code snippet #1
x,y=int(input()),int(input())
print(x,y)
print(type(x))
print(type(y))
So I get the output -
4
6
4 6
<class 'int'>
<class 'int'>
I am fine with the output, but what bugs me is why I can't use it in the manner like -
Code snippet #2
x,y= int(input().split('-'))
print(x,y)
print(type(x))
print(type(y))
So here, on wrapping input().split() inside int(), it throws an error as :
TypeError: int() argument must be a string, a bytes-like object or a
number, not 'list'
My Doubt
I just want to know why I cannot wrap int() inside input().split() ? Is there an alternate way to do it? Or if it's not allowed please explain why.
From docs.python.org:
str.split() returns a list of the words in str
You can not turn a list to a int
You can try this way:
(x, y) = (int(x) for x in input().split('-'))
print(x, y)
print(type(x))
print(type(y))
Okay so if you want to take multiple inputs in a single line and also convert it into desired data type, you can use map() to achieve it.
Code snippet #3
x,y,z=map(int,input().strip().split())
print(x,y,z)
print(type(x))
print(type(y))
print(type(z))
So your output will look like this -
2 3 4
2 3 4
<class 'int'>
<class 'int'>
<class 'int'>
And as #dyukha pointed out correctly the reason you cannot wrap input().split() inside int() is because split() returns a list and we cannot cast list to int data type.

Resources