PyTorch : 深層学習ライブラリ

1. 概要

PyTorch は,前身のTorchライブラリをPython言語でリニューアルした,ディープラーニング向けの機械学習オープンソースライブラリである (修正BSDライセンス).2021年現在,最も使われている機械学習ライブラリの1つで,FacebookのAI Research Lab (FAIR)が主に開発を主導している.

コンピュータビジョン向けCNNや自然言語処理を始め,ディープラーニングのさまざまな応用が昨今PyTorchで研究されており,研究者が最新の論文に対応するコードを,PyTorchを用いたソフトウェアで公開するのが標準的となっている.

関連ページ:Deep Learning Library の主要なもの一覧 | CVML エキスパートガイド

2 PyTorch の歴史

2.1. Torch (Lua言語) 時代

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

Torchは N次元テンソルと線形代数を簡便に取り扱うことができる.autogradに対応していて,各層の微分値を明示的に記述しないでよい.最適化でも, 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 はディープラーニング・機械学習向けの人気プログラミング言語になったのか | CVML エキスパートガイド

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

参照外部リンク