PyTorch
PyTorch: ニューラルネットワークの計算が出来る、深層学習フレームワーク。
PyTorchの環境を構築するためのインストールまでの手続きについてまとめた。(簡単な使いかたもいずれ書くかも)
PyTorchのインストール
pyenv + anaconda3-5.3.1 on CentOS Linux release 7.7.1908 (Core)
いつも、Linuxにはpyenvを導入し、anaconda3-5.3.1を入れて使っている。本家のページを見ると、conda
コマンドを使っても入れられるらしく、例えば
# 本家のサイトで Stable(1.5), Linux, Conda, Python, None (cudaのオプション) で表示されるコマンド
# 最新版を入れたければ、本家サイトでコマンドは生成し直した方がよい
conda install pytorch torchvision cpuonly -c pytorch
でPyTorchが入る。
但し、この手続きでPyTorchを入れると、少なくとも私の環境(CentOS Linux release 7.7.1908 (Core))では、anaconda内のipython, jupyterの環境を壊してしまう。本末転倒である。したがって、他の道を探った。
pyenv + 3.8.2 on CentOS Linux release 7.7.1908 (Core)
本家のページを見ると、pip
でも入れられるとある。それなら、という事で、簡素なpythonを入れて、そこからpip
で足していくことにした。
途中経過には興味がなく、とにかくインストールできればいい という人は、このサブセクションの最後のまとめへ。
pyenvを入れて(入れ方は'pyenv インストール'で調べれば無限に記事が見つかるので、それらを参照)、PATHを通す(無限にある記事の中に書かれている)。pyenv install --list
で調べると、手持ちのpyenvでは3.8.2が最新だったので、これを選択することに。
pyenv install 3.8.2
でインストールを試みると、**インストールができない。**エラー、ワーニング(後々ビルドし直すのもだるいので、ワーニングもコスパの許す限り対応する)を確認すると、どうもzlib
, ssl
, bzip2
, realine
, SQlite
が足りないよう。これよりも、前にgcc
, g++
, gfortran
くらいは入れていたはずだけど、他にも既に入れたアプリ/ライブラリがあったかも。(Anacondaはシステムのライブラリを参照しないから、これまでインストールには問題なかったのかな。よくわからない。)これらのライブラリ群をインストールしようとして、yum install zlib
等とすると、既にあると表示される。つまり、必要なのはzlib-dev
なのだ。これは他のライブラリについても、大方そうである。なので、
yum install zlib-* #zlib-*でzlib-dev等を入れる
yum install openssl-*
yum install bzip2-*
yum install readline-*
yum install sqlite-*
をしてから、上記のpythonインストールコマンドを入れると、無事にビルドされた。
anacondaしか使ったことなかったので、pyenvって圧縮されたバイナリを展開しているだけだと思ったけれど、ビルドしているのね。あと、*-dev
が必要という事は、静的ライブラリをビルド時にリンクしているのかもしれない。
さぁ、そういうわけで
# 本家のサイトで Stable(1.5), Linux, Pip, Python, None (cudaのオプション) で表示されるコマンド
# 最新版を入れたければ、本家サイトでコマンドは生成し直した方がよい
pip install torch==1.5.0+cpu torchvision==0.6.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
で晴れてPyTorchが入るかな と思うと、コケる。どうもctypes
が上手く読み込めない とのこと。試しにpython3
からimport ctypes
をModuleNotFoundError: No module named '_ctypes'
のエラーを吐いてこける。ctypes
って結構基本的なライブラリなので、3.8.2のビルドの所で入っていないわけはないので、何かが根本的なところがおかしそう。エラーメッセージも併せて色々調べてみると、どうもlibffi
が不足しているようである。そして、歴史は繰り返す。libffi
自体はすでにインストールされていて、必要なのはlibffi-dev
なのだ。というわけで、
yum install libffi-*
をする。実はこれだけでは問題が解決していなくて、このライブラリはpythonのビルド時にリンクされていなければいけない(早く言ってよ)。なので、pyenv uninstall 3.8.2
で消してから、pyenv install 3.8.2
で無事ctypes
がきちんとimport出来るようになる。ここまで、来ると上に書いたPyTorchのpip
でのインストールコマンドが通る。
あとは、jupyter
, matplotlib
, scipy
あたりをpip
で入れておけば大方の機能は使えるだろう。numpy
は多分PyTorchのインストール時の依存関係で入っているはず。
まとめ
と、発見的に解決してきたPyTorchインストールの道のりをつらつらと書いてきた。しかし、答えが最初から分かっていれば、
yum install zlib-* openssl-* bzip2-* readline-* sqlite-* libffi-*
pip install torch==1.5.0+cpu torchvision==0.6.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
pip install jupyter
pip install matplotlib
pip install scipy
で、PyTorchと最低限の開発環境が揃うはず。(gcc g++あたりは、まだ入れてなければ、それもyum install
しないといけないかも。)
Anacondaと食い合うのが嫌な場合は、PyTorchを使うディレクトリで、pyenv local 3.8.2
にしておけば、よい。ほかのディレクトリに移れば、globalに指定してある環境になる。
pyenv + 3.8.2 on Ubuntu 19.10
色々勘違いがあって、sudo apt install libffi-dev
だけ入れた状態でpyenv 8.3.2
をしたら、
WARNING: The Python bz2 extenWARNING: The Python bz2 extension was not compiled. Missing the bzip2 lib?sion was not compiled. Missing the bzip2 lib?
等々のエラーが出た。Ubuntuの場合は上のyum
に対応するのは
sudo apt install libbz2-dev
sudo apt install libreadline-dev
sudo apt install libsqlite3-dev
になる。これで、python 3.8.2がインストールされるので、あとはpip
でPyTorch, jupyter, matplotlib, scipyあたりを入れれば、おしまい。
参考にさせていただいたサイト:pyenvでPython3.7.0をインストールしようとしたらWARNING発生 - 自動化厨のプログラミングメモブログ│CODE-LIFE
Torch tensor
-
torch_array.shape
で形状取得 -
torch_array.size
で長さ取得
モデルの作成
隠れ層が2層のモデルの例。nn.Linear
に、活性化関数はReLU.
import torch
import torch.nn as nn
import torch.nn.functional as F
class Model_2L(nn.Module):
def __init__(self, input_size, output_size, ndim1 = 10, ndim2=10):
super(Model_2L,self).__init__()
self.n1 = ndim1
self.n2 = ndim1
self.fc1 = nn.Linear(input_size, self.n1)
self.fc2 = nn.Linear(self.n1, self.n2)
self.fc3 = nn.Linear(self.n2, output_size)
def forward(self, x):
x = self.fc1(x)
x = self.fc2(F.relu(x))
x = self.fc3(F.relu(x))
return x
model = Model_3L(input_size, output_size)
トラブルシューティング
RuntimeError: size mismatch, m1: [1 x 15], m2: [1 x 1] at /pytorch/aten/src/TH/generic/THTensorMath.cpp:41
引数のtorch tensoryの形が多分おかしい。
自分のケースではnumpy ndarrayで作ってから、torch.from_numpy
でtorch tensorに変えていて、numpy ndarrayの時点での宣言がおかしかった。具体的には(Ndim,1)で作るべきところを、(Ndim,)で作っていたため。この変換はx_array = x_array.reshape(Ndim,-1)
で実行できる。
RuntimeError: Expected object of scalar type Float but got scalar type Double for argument #2 'mat1' in call to _th_addmm
多分、入力tensorの型が32bit実数になっていなくて、64bit実数になっているが、読んだ関数が64bit実数に対応していないことが問題。
第2回 PyTorchのテンソル&データ型のチートシート:PyTorch入門 - @ITによると、
種類は豊富だが、基本的に32bitのtorch.floatかtorch.intしか使わない。
とのことらしい。多くのnumpyはデフォルトではfloat64
を使っていると思うので、宣言部分で明示的にdtype = float32
を付けるか、x_array = np.float32(x_array)
で32bit実数に変換する必要がある。