Define-by-Run (G検定)

Define-by-Run

1. 定義と概要

Define-by-Runとは、ネットワークの計算手順(計算グラフ。計算の手順を、データが流れる道筋として図のように表したもの)を動的に構築していく方式です。実際にデータを流して順伝播(入力から出力へ向けて計算を進める処理)を実行するのと同時に、その都度グラフが組み上がっていきます。この動的な組み立て方から、Define-by-Runは動的計算グラフ方式とも呼ばれます。

具体例としてはPyTorch(研究や実務で広く使われているディープラーニングフレームワークの一つで、Define-by-Runの代表例とされる)が挙げられ、モデルの構造をPythonのコードで直接記述しながら動かせるのが特徴です。対になる概念はDefine-and-Run(あらかじめ計算グラフの全体を定義してから、そこにデータを流し込んで実行する静的な方式で、詳しい仕組みは別記事に譲ります)で、両者は深層学習フレームワークの設計思想を分ける対比軸として扱われます。

従来の深層学習フレームワークの多くは、まずネットワークの構造を静的に定義し、そのあとでデータを流し込んで計算を実行するDefine-and-Run方式を採用していました。しかし、この方式は入力の系列の長さがそろわない自然言語処理(人間の言葉をコンピュータに処理させる技術分野)のモデルや、条件によって処理を分岐させたいモデルの記述には不向きという点が課題でした。

こうした背景の中、2015年6月にChainer(日本のPreferred Networksが公開したディープラーニングフレームワークで、Define-by-Runの考え方とともに登場しました)がこの設計思想を提唱しました。ネットワークの構造をPythonの通常のプログラムのように書きながら、データを流すたびに計算グラフを動的に構築する仕組みで、その後「PyTorch」などの後発フレームワークにも影響を与えたとされています。「Chainer」というフレームワーク自体の詳しい経緯は別記事に譲ります。

2. 試験対策ポイント

まず整理しておきたいのは、Define-by-RunとDefine-and-Runの違いを、計算グラフを構築するタイミングとデータを流す実行のタイミングの前後関係として捉える視点です。Define-by-Runは構築と実行が同時に進むのに対し、Define-and-Runは先に構築してから実行するという順序をとります。この順序の違いこそが、両者を分ける対比構造です。

Define-by-Runの主なメリットは、次の3点です。ひとつは、入力データに応じて処理内容を変えられる柔軟性で、条件分岐や系列の長さがそろわないデータにも対応しやすくなります。ふたつめは、PythonのIf文やFor文といった制御構文を、そのままネットワークの記述に使えます。みっつめは、print文や標準のデバッガ(プログラムを実行しながら内部の値や処理の流れを確認するためのツール)を使って、計算の途中経過を確認できるデバッグのしやすさです。この3点が、方式の利点を語るときの柱になります。

一方で、計算グラフをその都度作るため、事前にグラフ全体を見渡した最適化がしにくいという制約があります。Define-and-Run方式は先に全体像が定まっているぶん、こうした最適化をかけやすいとされ、両者の利点と制約の対比は取り違えやすい点です。

フレームワークの固有名詞は、どちらの方式と結びつくかという対応関係で押さえておきたいところです。

フレームワーク 方式との関係
Chainer 2015年6月にDefine-by-Runの設計思想をいち早く提唱
PyTorch Define-by-Runの代表例として挙げられる
TensorFlow(Googleが開発した深層学習フレームワーク)の1系 Define-and-Run方式が中心
TensorFlowの2以降 Eager Execution(命令を出すたびに計算をすぐ実行する動作モード)が既定になり、動的な実行に近づいたとされる

提唱したフレームワーク、代表例として挙がるフレームワーク、そして採用する方式がバージョンによって変わったフレームワークという3つの区分で覚えておくと、名前だけを見たときにも取り違えにくくなります。

3. 関連概念との比較・相違点

Define-and-Runとの最大の違いは、計算グラフを構築するタイミングと、データを流して実行するタイミングの前後関係です。Define-by-Runはデータを流しながら同時に計算グラフを組み立てていくのに対し、Define-and-Runは先にネットワークの構造を丸ごと定義してから、そこへデータを流し込んで実行します。

この順序の違いが生むのが、柔軟性を取るか事前最適化のしやすさを取るかという設計上のトレードオフです。Define-and-Run自体の詳しい仕組みには、ここでは立ち入りません。

計算グラフとの関係にも触れておきます。Define-by-Runは、計算グラフを「いつ・どのように構築するか」という方式を示す言葉であり、計算グラフそのものがどんな構成要素からなるかという定義には、ここでは立ち入りません。ここであわせて押さえておきたいのは、Define-by-Runが計算グラフという仕組みの上に成り立つ、実行方式の呼び名だという位置づけです。

4. ビジネス・実務での活用シナリオ

研究開発の現場では、新しいネットワーク構造を検証する際に、条件分岐を含む複雑なモデルをコードとして書き換えながら、その都度実行して結果を確かめられます。試作と検証を繰り返すサイクルを短いスパンで回せる点は、手探りの多い研究フェーズにおける実利的な効果です。

自然言語処理の分野では、文の長さがそろわない系列データを扱うモデルとの相性のよさが生きます。入力ごとに異なる形の計算グラフを柔軟に構築できるため、可変長のデータをそのまま扱う実装がしやすくなります。

教育や小規模チームでの開発においても有効です。通常のPythonのデバッガでモデル内部の計算過程を一行ずつ確認できるため、深層学習の学習を始めたばかりの技術者でも、不具合の原因がどこにあるかを追いやすいという意義があります。

5. 要点まとめ

  • Define-by-Runは、データを流しながら計算グラフをその都度構築していく動的な方式で、先に定義しきるDefine-and-Runと対になる概念です。
  • 「Chainer」がDefine-by-Runを提唱し、「PyTorch」が代表例として挙げられます。TensorFlowもバージョン2以降は「Eager Execution」が既定になり、動的な実行に近づきました。
  • 柔軟な処理・Pythonの制御構文の活用・デバッグのしやすさが利点で、事前の最適化がしにくい点は制約にあたります。

6. 確認問題

問1Define-by-Runは、データを流しながら実行するのと同時に計算グラフを構築していく方式である。

解答・解説をみる

○ 正しい

計算グラフの構築と順伝播の実行が同時に進む点が、Define-by-Runの定義そのものです。対になるDefine-and-Runでは、この順序が逆になります。

問2Define-by-Runでは、PythonのIf文やFor文といった通常の制御構文をそのままネットワークの記述に利用できる。

解答・解説をみる

○ 正しい

計算グラフを実行時に動的に組み立てるため、Pythonの制御構文をそのまま使って条件分岐やループを表現できます。デバッグのしやすさと並ぶ、この方式の特徴です。

問3Define-by-Runは、あらかじめ計算グラフの全体を定義してから、そこにデータを流し込んで実行する方式である。

解答・解説をみる

× 誤り

これはDefine-and-Runの説明です。正しくは、データを流しながら同時に計算グラフを構築するのがDefine-by-Runで、構築と実行の順序が逆になっている点が取り違えやすいところです。