I'm working with Python 3.5.1 on a computer having CentOS Linux 7.3.1611 (Core) operating system.
I'm trying to use PyTorch and I'm getting started with this tutorial.
Unfortunately, the #4 line of the example creates troubles:
>>> torch.Tensor(5, 3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'torch' has no attribute 'Tensor'
I cannot understand this error... of course in Torch the 'torch' does have an attribute 'Tensor'. The same command works in Torch.
How can I solve this problem?
The Python binary that you are running does not have torch
installed. It does have a directory named torch
on the module search path, and it is treated as a namespace package:
$ pwd
/some/path
$ python3 -c 'import torch; print(torch); print(torch.__path__)'
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'torch'
$ mkdir torch
$ python3 -c 'import torch; print(torch); print(torch.__path__)'
<module 'torch' (namespace)>
_NamespacePath(['/some/path/torch'])
Any directory without a __init__.py
file present in it, located on your module search path, will be treated as a namespace, provided no other Python modules or packages by that name are found anywhere else along the search path.
This means that if torch
was installed for your Python binary, it doesn't matter if there is a local torch
directory:
$ ls -ld torch/
drwxr-xr-x 2 mjpieters users 68 Nov 23 13:57 torch/
$ mkdir -p additional_path/torch/
$ touch additional_path/torch/__init__.py
$ PYTHONPATH="./additional_path" python3 -c 'import os.path as p, sys; print(*(t for t in (p.join(e, "torch") for e in sys.path) if p.exists(t)), sep="\n")'
torch
/some/path/additional_path/torch
$ PYTHONPATH="./additional_path" python3 -c 'import torch; print(torch); print(torch.__path__)'
<module 'torch' from '/some/path/additional_path/torch/__init__.py'>
['/some/path/additional_path/torch']
The above shows that sys.path
lists the torch
directory first, followed by additional_path/torch
, but the latter is loaded as the torch
module when you try to import it. That's because Python gives priority to top-level modules and packages before loading a namespace package.
You need to install torch correctly for your current Python binary, see the project homepage; when using pip
you may want to use the Python binary with the -m
switch instead:
python3.5 -m pip install http://download.pytorch.org/whl/cu80/torch-0.2.0.post3-cp35-cp35m-manylinux1_x86_64.whl
python3.5 -m pip install torchvision
So replace the pip3
the homepage instructions use with python3.5 -m pip
; python3.5
can also be the full path to your Python binary.
Do use the correct download.pytorch.org
URL for the latest version.
You don't have to move the directory aside, but if you do want to and don't know where it is located, use print(torch.__path__)
as I've shown above.
Again, note that if you do have an __init__.py
file in a local torch
directory, it becomes a regular package and it'll mask packages installed by pip
into the normal site-packages
location. If you have such a package, or a local torch.py
single-file module, you need to rename those. The diagnostic information looks different in that case:
$ pwd
/some/path
$ python3 -c 'import torch; print(torch); print(torch.__path__)'
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'torch'
$ mkdir torch
$ touch torch/__init__.py # make it a package
$ python3 -c 'import torch; print(torch); print(torch.__path__)'
<module 'torch' from '/some/path/torch/__init__.py'>
['/some/path/torch']
$ rm -rf torch/
$ touch torch.py # make it a module
$ python3 -c 'import torch; print(torch); print(torch.__file__)'
<module 'torch' from '/some/path/torch.py'>
/some/path/torch.py
Note the differences; a namespace package, above, uses <module 'name' (namespace)>
, while a regular package uses )
, while a plain module uses
`.
Such packages and modules (not namespace packages) are found first and stop the search. If the found package or module is not the one you wanted, you need to move them aside or rename them.