How to multiply a matrix by a vector in PyTorch - pytorch

I'm playing around with PyTorch with the aim of learning it, and I have a very dumb question: how can I multiply a matrix by a single vector?
Here's what I've tried:
>>> import torch
>>> a = torch.rand(4,4)
>>> a
0.3162 0.4434 0.9318 0.8752
0.0129 0.8609 0.6402 0.2396
0.5720 0.7262 0.7443 0.0425
0.4561 0.1725 0.4390 0.8770
[torch.FloatTensor of size 4x4]
>>> b = torch.rand(4)
>>> b
0.1813
0.7090
0.0329
0.7591
[torch.FloatTensor of size 4]
>>> a.mm(b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: invalid argument 2: dimension 1 out of range of 1D tensor at /Users/soumith/code/builder/wheel/pytorch-src/torch/lib/TH/generic/THTensor.c:24
>>> a.mm(b.t())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: t() expects a 2D tensor, but self is 1D
>>> b.mm(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: matrices expected, got 1D, 2D tensors at /Users/soumith/code/builder/wheel/pytorch-src/torch/lib/TH/generic/THTensorMath.c:1288
>>> b.t().mm(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: t() expects a 2D tensor, but self is 1D
On the other hand, if I do
>>> b = torch.rand(4,2)
then my first attempt, a.mm(b), works fine. So the problem is just that I'm multiplying a vector rather than a matrix --- but how can I do this?

You're looking for
torch.mv(a,b)
Note that for the future, you may also find torch.matmul() useful. torch.matmul() infers the dimensionality of your arguments and accordingly performs either dot products between vectors, matrix-vector or vector-matrix multiplication, matrix multiplication or batch matrix multiplication for higher order tensors.

This is a self-answer to supplement #mexmex's correct and useful answer.
In PyTorch, unlike numpy, 1D Tensors are not interchangeable with 1xN or Nx1 tensors. If I replace
>>> b = torch.rand(4)
with
>>> b = torch.rand((4,1))
then I will have a column vector, and matrix multiplication with mm will work as expected.
But this is not necessary, because as #mexmex points out there is an mv function for matrix-vector multiplication, as well as a matmul function that dispatches the appropriate function depending on the dimensions of its input.

Related

TypeError: 'tuple' object is not callable when converting a list to tuple as return value

I want to convert the final list as tuple. However i am receiving an error.How can i get rid of this?
li= [(19343160,),(39343169,)]
def render_list_sql(li):
l = []
for index, tuple in enumerate(li):
idd = str(tuple[0])
l.append(idd)
return tuple(l)
print(render_list_sql(li))
Expected value to be returned is:
(19343160,39343169)
Error
Traceback (most recent call last):
File "test.py", line 20, in <module>
print(render_list_sql(list))
File "test.py", line 14, in render_list_sql
return tuple(l)
TypeError: 'tuple' object is not callable
As commented, don't use names for variables that mean other things to Python. This is called "shadowing" and you lose the meaning of the original name.
Example:
>>> tuple # This is the class used to create tuples.
<class 'tuple'>
>>> for index,tuple in enumerate([1,2,3]): # This is similar to your code
... print(index,tuple)
...
0 1
1 2
2 3
>>> tuple # tuple is no longer a class, but an instance of an integer.
3
>>> tuple([1,2,3]) # so this fails
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: 'int' object is not callable
>>> 3([1,2,3]) # You are basically doing this:
<interactive input>:1: SyntaxWarning: 'int' object is not callable; perhaps you missed a comma?
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: 'int' object is not callable
So don't do that:
li = [(19343160,),(39343169,)] # don't reassign list
def render_list_sql(li):
l = []
for index, tup in enumerate(li): # don't reassign tuple
idd = str(tup[0])
l.append(idd)
return tuple(l) # now this will work
print(render_list_sql(li))
Output:
('19343160', '39343169')
FYI, a shorter version using a generator:
li = [(19343160,),(39343169,)]
tup = tuple(str(i[0]) for i in li)
print(tup)

Why does nn.CrossEntropyLoss throw "TypeError: iteration over a 0-d tensor" when I verify inputs to be non-0-dimensional?

I am using PyTorch version 1.5.0.
When I pass an input torch tensor of size [8,21,400,400] with a target of size [8,400,400], the program raises a TypeError: iteration over a 0-d tensor. However, the dimensions of the arguments are 4 and 3 respectively.
What could be causing this error?
The traceback points to torch\tensor.py's iter function.
Traceback (most recent call last):
File "train.py", line 108, in <module>
loss, accuracy = lossLayer(pred2, targetBatch)
File "C:\Users\PC\anaconda3\lib\site-packages\torch\tensor.py", line 462, in __iter__
raise TypeError('iteration over a 0-d tensor')
TypeError: iteration over a 0-d tensor
You get the error because nn.CrossEntropyLoss just returns one torch.Tensor, not a pair (it doesn't return accuracy). And this tensor is 0-dimensional, i.e. one number (unless you don't override reduction argument to 'none' to get per-element loss). So when you try to assign its value to two variables loss, accuracy python tries to iterate over this tensor variable, hence the error message. Simply use loss = lossLayer(pred2, targetBatch).

Input data error using interpolate.splrep

I defined the two arrays:
x = array([ 0. , 50. , 55.5, 57.5, 55.5, 50. , 0. ])
y = array([ 2.5, 2.5, 4.7, 10. , 15.3, 17.5, 17.5])
Then I interpolate with the command:
import numpy as np
from scipy import interpolate
tck = interpolate.splrep(x, y)
This give me the error message:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3/dist-packages/scipy/interpolate/fitpack.py", line 289, in splrep
res = _impl.splrep(x, y, w, xb, xe, k, task, s, t, full_output, per, quiet)
File "/usr/lib/python3/dist-packages/scipy/interpolate/_fitpack_impl.py", line 515, in splrep
raise _iermess[ier][1](_iermess[ier][0])
ValueError: Error on input data
Why are the input data not correct? Where is the problem?
Welcome to Stack Overflow!
I'm not familiar with SciPy but I went to look at its documentation and in its description of function scipy.interpolate.splrep(). There a sentence that says:
The user is responsible for assuring that the values of x are unique. Otherwise, splrep will not return sensible results.
But you have many of the same values in your x array. Maybe that's why you have an error message?

Problem in reshaping numpy array of large size

I have a numpy array with following dimensions :
(1611216, 2)
I tried reshaping it to (804, 2004)
using :
df = np.reshape(df, (804, 2004))
but it gives an error :
Traceback (most recent call last):
File "Z:/Seismic/Geophysical/99_Personal/Abhishake/RMS_Machine_learning/RMS_data_analysis.py", line 19, in <module>
df = np.reshape(df, (804, 2004))
File "C:\python36\lib\site-packages\numpy\core\fromnumeric.py", line 232, in reshape
return _wrapfunc(a, 'reshape', newshape, order=order)
File "C:\python36\lib\site-packages\numpy\core\fromnumeric.py", line 57, in _wrapfunc
return getattr(obj, method)(*args, **kwds)
ValueError: cannot reshape array of size 3222432 into shape (804,2004)
df = np.reshape(df, (804, 2004))
but it gives an error :
Traceback (most recent call last):
File "Z:/Seismic/Geophysical/99_Personal/Abhishake/RMS_Machine_learning/RMS_data_analysis.py", line 19, in
df = np.reshape(df, (804, 2004))
File "C:\python36\lib\site-packages\numpy\core\fromnumeric.py", line 232, in reshape
return _wrapfunc(a, 'reshape', newshape, order=order)
File "C:\python36\lib\site-packages\numpy\core\fromnumeric.py", line 57, in _wrapfunc
return getattr(obj, method)(*args, **kwds)
ValueError: cannot reshape array of size 3222432 into shape (804,2004)
You cannot reshape (1611216, 2) numpy array into (804, 2004).
It is because 1611216 x 2 = 3,222,432 and 804 x 2004 = 1,611,216. The difference in size of the two array is very large. I think you have to come up with another set of dimensions for your numpy array and that would depend on how you want to use your array.
Hint : (1608, 2004) will be a valid reshape.

TypeError: len() of unsized object when comparing and I cannot make sense of it

I am trying to select sensors by placing a box around their geographic coordinates:
In [1]: lat_min, lat_max = lats(data)
lon_min, lon_max = lons(data)
print(np.around(np.array([lat_min, lat_max, lon_min, lon_max]), 5))
Out[1]: [ 32.87248 33.10181 -94.37297 -94.21224]
In [2]: select_sens = sens[(lat_min<=sens['LATITUDE']) & (sens['LATITUDE']<=lat_max) &
(lon_min<=sens['LONGITUDE']) & (sens['LONGITUDE']<=lon_max)].copy()
Out[2]: ---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-12-7881f6717415> in <module>()
4 lon_min, lon_max = lons(data)
5 select_sens = sens[(lat_min<=sens['LATITUDE']) & (sens['LATITUDE']<=lat_max) &
----> 6 (lon_min<=sens['LONGITUDE']) & (sens['LONGITUDE']<=lon_max)].copy()
7 sens_data = data[data['ID'].isin(select_sens['ID'])].copy()
8 sens_data.describe()
/home/kartik/miniconda3/lib/python3.5/site-packages/pandas/core/ops.py in wrapper(self, other, axis)
703 return NotImplemented
704 elif isinstance(other, (np.ndarray, pd.Index)):
--> 705 if len(self) != len(other):
706 raise ValueError('Lengths must match to compare')
707 return self._constructor(na_op(self.values, np.asarray(other)),
TypeError: len() of unsized object
Of course, sens is a pandas DataFrame. Even when I use .where() it raises the same error. I am completely stumped, because it is a simple comparison that shouldn't raise any errors. Even the data types match:
In [3]: sens.dtypes
Out[3]: ID object
COUNTRY object
STATE object
COUNTY object
LENGTH float64
NUMBER object
NAME object
LATITUDE float64
LONGITUDE float64
dtype: object
So what is going on?!?
-----EDIT------
As per Ethan Furman's answer, I made the following changes:
In [2]: select_sens = sens[([lat_min]<=sens['LATITUDE']) & (sens['LATITUDE']<=[lat_max]) &
([lon_min]<=sens['LONGITUDE']) & (sens['LONGITUDE']<=[lon_max])].copy()
And (drumroll) it worked... But why?
I'm not familiar with NumPy nor Pandas, but the error is saying that one of the objects in the comparison if len(self) != len(other) does not have a __len__ method and therefore has no length.
Try doing print(sens_data) to see if you get a similar error.
I found a similar issue and think the problem may be related to the Python version you are using.
I wrote my code in Spyder
Python 3.6.1 |Anaconda 4.4.0 (64-bit)
but then passed it to someone using Spyder but
Python 3.5.2 |Anaconda 4.2.0 (64-bit)
I had one numpy.float64 object (as far as i understand, similar to lat_min, lat_max, lon_min and lon_max in your code) MinWD.MinWD[i]
In [92]: type(MinWD.MinWD[i])
Out[92]: numpy.float64
and a Pandas data frame WatDemandCur with one column called Percentages
In [96]: type(WatDemandCur)
Out[96]: pandas.core.frame.DataFrame
In [98]: type(WatDemandCur['Percentages'])
Out[98]: pandas.core.series.Series
and i wanted to do the following comparison
In [99]: MinWD.MinWD[i]==WatDemandCur.Percentages
There was no problem with this line when running the code in my machine (Python 3.6.1)
But my friend got something similar to you in (Python 3.5.2)
MinWD.MinWD[i]==WatDemandCur.Percentages
Traceback (most recent call last):
File "<ipython-input-99-3e762b849176>", line 1, in <module>
MinWD.MinWD[i]==WatDemandCur.Percentages
File "C:\Program Files\Anaconda3\lib\site-packages\pandas\core\ops.py", line 741, in wrapper
if len(self) != len(other):
TypeError: len() of unsized object
My solution to his problem was to change the code to
[MinWD.MinWD[i]==x for x in WatDemandCur.Percentages]
and it worked in both versions!
With this and your evidence, i would assume that it is not possible to compare numpy.float64 and perhaps numpy.integers objects with Pandas Series, and this could be partly related to the fact that the former have no len function.
Just for curiosity, i did some tests with float and integer objects (please tell the difference with numpy.float64 object)
In [122]: Temp=1
In [123]: Temp2=1.0
In [124]: type(Temp)
Out[124]: int
In [125]: type(Temp2)
Out[125]: float
In [126]: len(Temp)
Traceback (most recent call last):
File "<ipython-input-126-dc80ab11ca9c>", line 1, in <module>
len(Temp)
TypeError: object of type 'int' has no len()
In [127]: len(Temp2)
Traceback (most recent call last):
File "<ipython-input-127-a1b836f351d2>", line 1, in <module>
len(Temp2)
TypeError: object of type 'float' has no len()
Temp==WatDemandCur.Percentages
Temp2==WatDemandCur.Percentages
Both worked!
Conclusions
In another python version your code should work!
The problem with the comparison is specific for numpy.floats and perhaps numpy.integers
When you include [] or when I create the list with my solution, the type of object is changed from a numpy.float to a list, and in this way it works fine.
Although the problem seems to be related to the fact that numpy.float64 objects have no len function, floats and integers, which do not have a len function either, do work.
Hope some of this works for you or someone else facing a similar issue.

Resources