PyTorch : python 深層学習ライブラリ

記事を共有する:

1. PyTorchとは [概要]

PyTorchとは,前身のTorchライブラリをPython言語でリニューアルした,ディープラーニング向けの機械学習フレームワークである.オープンソースである(修正BSDライセンス).2021年現在,最も使われている機械学習ライブラリの1つであり,2016年に登場した.

コンピュータビジョン向けモデルや,自然言語処理向けモデルを始め,ディープラーニングのさまざまな応用研究の成果が,昨今PyTorchで研究されている.研究者が最新の論文のコードを,PyTorchを用いたソフトウェアで公開するのも業界で標準的となっている.他の深層学習フレームワークやライブラリでも,HuggingFaceのTransformerや,OpenMMLab,軽量高速ライブラリのPyTorch lightning・Catalyst など,において基盤としてPyTorchが用いられている.このように,良く使われるフレームワークもPyTorchを基盤としてきたという意味で,PyTorchはデファクトスタンダードな深層学習向けフレームワークであると言える.

※ 2022年3月追記:研究成果発表向けには,しばらく「PyTorch一強 + Google社勢はTensorflow」という状況が続いていたが,2021年以降はGoogleの「JAX」ベースの深層学習フレームワークで構築したコードで成果発表されることが増えてきている状況.詳しくは下記関連ページを参照.

2. PyTorch の歴史

2.1. Torch (Lua言語) 時代

2002年 Lua言語で開発された「Torch」が,Ronan Collobert やSamy Bengio (Yosua Bengio の兄弟)などによりIDIAP Research Institue から登場した.それが時を経てバージョンアップを重ね,Torch ver.7 (Torch7) の頃に,深層学習ブームの中で使用されはじめた.

Torchは N次元テンソルと線形代数を簡便に取り扱うことができる.自動微分に対応しており,Forward関数に順伝播時の挙動さえコーディングすれば,逆伝播の各層の微分値を明示的に記述しないでよく,自動で微分してその値を勝手に逆伝播してくれる.最適化においても, nn.StochasticGradient (network, criterion) というインターフェースとなっており,アルゴリズムの種類とそこで用いるロス関数(criterion)を選ぶだけで,学習アルゴリズムの実行自体はライブラリにお任せできる.

当時まで使われていた(低レベル記述が多くなりがちな)Caffe や Theanoなどと比べると,上記のように簡潔にプロトタイピングができて助かる.更には,スクリプト言語の Lua(JIT)を用いて,インタラクティブに色々と試せる点でも優れていた.

参考:CVPR2015 Tutorial: Deep Learning with Torch: the 60-minute blitz (Jupyternotebook)

現在のPyTorchと比べると,nn.Sequential にConvやReluなどの各層を部品として追加し,ニューラルネットを簡単に構築できるところまではTorchも変わらなかった.しかし Lua言語 のライブラリであることもあり,関数の連続でコードを書いていくCライクな手続き方プログラミング設計であり,独自に層やネットワークなどを定義する際に,オブジェクト指向を用いて(再利用に便利で簡潔な) コードを書きづらい面があった.

2.2. PyTorch の登場

当時 Python が機械学習でデファクトスタンダードのプログラミング言語になってきていたことから,「Torchの利点を残したまま,Torchを改善したPythonのライブラリを作ろう」という機運になった.これにより,Python First であるTorch後継ライブラリとして,PyTorchが開発され始めた.

PyTorchでは,ネットワーク全体を nn.module を継承したクラスとしてつくり,そのクラスの内のforward関数内に準伝搬時の各層の手続きを書く.前身のTorchでは当時よく使われていたCaffeなどよりは快適なものの,オブジェクト指向化がまだ中途半端であった.それがPyTorchでは,Keras や Chainer のように,オブジェクト指向で書けて,なおかつ簡潔で短いコードを書きやすいライブラリに改善されたので,一気に人気を獲得することになる.

PyTorch は1.0がリリースされて以降,その便利さや開発体制の強さなどもあって,多くのAI系最先端研究が,PyTorchでコードを公開されることが普通になっていった.そして,他のフレームワークの研究成果コードがどんどん減って,PyTorchの研究成果コードの割合が高くなっていった結果,現在ではPyTorchの人気は不動のものになっている.

関連記事:【Q & A 記事】なぜ Python はディープラーニング・機械学習向けの人気プログラミング言語になったのか

ちなみに,日本独自の状況であったが,PFN社が当時開発していたChainerが,TorchがDeep Learningで使われていた時期に日本では流行しており,日本のビジョン界ではChainer使用者も一大勢力であった.PyTorchより先に,PyTorch的な「簡潔で(隠ぺい度が高めのオブジェクト群を用いて)短い行数でコードを書けるフレームワーク」をChainerは提供しており,日本語資料やWeb記事の多さから,国内ではlua torch版は流行しなかった.

3. PyTorchの特徴的な機能

3.1 Numpy-likeなテンソル

Pythonなのでnumpyと行き来ができて,なおかつ numpy-likeなインターフェースでテンソルを操作できる torch.Tensor が提供されている.スライスやインデクシング,数学演算などがGPU最適化がされており,GPU上でそれらの各操作が高速に実行される.

ただしnumpyと比べるとインターフェース名・引数名などに幾つか相違点があり,Numpy に慣れている人でも,スラスラとPyTorchのテンソルを操るためにはそれらの相違点を暗記する必要が出てくる)

3.2 PyTorch の Tape-Based Autograd (自動微分)

PyTorchでは,define-by-run方式によるネットワークグラフ構築と自動微分が提供されている (詳細は githubレポジトリのトップで図解されている「Dynamic Neural Networks: Tape-Based Autograd」を参照).PyTorchのTape-based Autogradは,TorchのAutogradや,autogradライブラリ,Chainer などからインスパイアされた設計である.

これにより,PyTorchでは各層を選び層間のforward動作さえ記述すれば,逆伝播時の微分値はヘッド側から逆順にグラフを構築しながら自動微分される.まず自動微分なので,過去のライブラリのように各層の微分値を(ただしく)記述する必要がない.

また,define-and-run方式の計算グラフ(例:TensorFlowのtf.Graph)だと,学習の毎ループで先にグラフ構造の定義が必要でその分だけ記述量の増えたコードになる.しかし,PyTorchのdefine-by-runでは,勝手に毎フレームの計算グラフ構造の変化に対応した自動微分計算が行われるので,グラフの変化をコードで記述しないで済み,非常に簡潔なコードで済む.

3.3 最小限の抽象化:簡潔に記述でき,拡張も楽に行える.

2節でも述べたとおり,前身のTorchでは,関数型の手続き型言語的なネットワーク構築の書き方を強いられ抽象化の面での設計がまだ微妙であったの.そこで,PyTorchでは抽象化具合の洗練化も行われた.

PyTorchはほどよい最小限の抽象化がクラス設計においてなされており,ただ単に記述がしやすいだけでなく,独自拡張も容易に行いやすいライブラリ設計になっている.競合のTensorflowのようなLow-levelな関数の実行が少なくて済むPytorchは,短い記述量で済ませやすい.

PyTorchでは,元から用意されているクラス群を使うと,ネットワーク構造の記述や学習・テストの手続きループを短時間で楽に記述できる.また,サブ機能だけ微妙に別クラスに抽出していたりもしていないおかげで,凝ったことをしないうちは,簡潔な最低限のコード記述だけで済む.

抽象化が最小限であるので,独自の層クラス,ネットワーク構造,ロス関数も設計しやすい.PyTorch Lightning などの高速化・効率化・更なる簡潔記述化などを目的としたラッパーライブラリが複数登場しているのも,PyTorchが抽象化を控えめにしている設計に起因している.

References

参照外部リンク

関連記事