- 人間はスパゲティコードの管理が苦手
- 研究プロジェクトでは、生データから情報を抽出するプログラムを書くことが多い
- データは明確な仕様に従っていない
- 例:
- ニュース記事から企業と役員を識別
- 公共調達契約をサービス種別ごとにラベリング
- エンジニア同士のメッセージからプログラムコードを識別
メッセージ内のプログラムコード検出
- コードレビュー中に、メッセージがプログラムコードを参照しているかを検出する問題に取り組む
- 例のメッセージ:
- LGTM with render_ipa_alloc()
- If the FTPSACK flag is set, then use a prespecified value
- AFAICT there is nothing else to check (unless you can think of something)
- Actually, debug_error() doesn’t return NULL, so we should use IS_ERROR() here
- This fails to build on aarch64 even though it works without issue on amd64
- I’ve added if (err) goto cleanup; but the code still leaks
決定ルールのアイデア
- 単純なルールを使ってプログラムコードと一般的な英語を区別するアプローチ
- ルール:
- 括弧が続く単語はコードである
- すべて大文字の単語はコードである
- 英語以外の単語はコードである
- 各ルールの長所と短所:
- ルール1: 単純だが、明白な肯定例を見落とす
- ルール2: 大文字の略語をプログラムコードとして誤分類する
- ルール3: エンジニアリング用語をプログラムコードとして誤分類する
手書きのアルゴリズム
- 単純なアルゴリズムでも十分うまく機能すると判断
- メッセージがコードを含むかどうかを2段階で判定:
- 前処理: メッセージをトークン列に変換
- 推論: トークン列にルールを適用して、コードを含むかどうかを判定
- Pythonで実装した例:
from dataclasses import dataclass
Token = str
@dataclass
class State:
previous_was_identifier: bool = False
previous_was_open_paren: bool = False
previous_previous_was_identifier: bool = False
seen_code: bool = False
def contains_code(tokens: Iterable[Token]) -> bool:
state = State()
for token in tokens:
state = process(state, token)
return state.seen_code
def process(state: State, token: Token) -> State:
if state.seen_code:
return state
if (token == "close_paren" and state.previous_was_open_paren and state.previous_previous_was_identifier):
state.seen_code = True
return state
state.previous_previous_was_identifier = state.previous_was_identifier
state.previous_was_identifier = token in ("all_caps_identifier", "underscore_identifier", "misc_identifier")
state.previous_was_open_paren = token == "open_paren"
return state
ニューラルネットワークの助け
- 状態機械としての
contains_codeとprocessはRNNとしてエンコードできる
- RNNを使ってより良いアルゴリズムを見つけられる
一般的なアイデア
- RNNは条件付き確率を近似する
- 各トークンごとに状態ベクトルを計算
- 最終状態に基づいてメッセージを分類
数学から見たPythonコード
- RNNがルール1をどのようにエンコードするかを説明
- 各トークンを二値ベクトルで表現
- 隠れ状態を計算してルールを適用
ネットワークの訓練
- RNNを訓練するために活性化関数をReLUに変更
- PyTorchを使って訓練可能
より効率的な実装を持つアーキテクチャ
- Elman RNNのような、PyTorchで提供されるアーキテクチャを使用
- Elman RNNでは各隠れレイヤーが前のレイヤーと現在のレイヤーの両方を入力として使う
より安定した勾配を持つアーキテクチャ
- 長いメッセージでは勾配が0に近づき、問題が発生する
- GRUやLSTMのようなアーキテクチャのほうがより良い性能を示す可能性がある
データ中心の規律
- RNNはスパゲティコードをよりうまく扱う
- データ中心の規律を強制することで問題を明確にする
GN⁺の見解
- この記事は、RNNを使って複雑な問題を解く方法をうまく説明している
- RNNを使うとコードの保守がしやすくなる
- PyTorchのようなツールを使って効率的に実装できる
- GRUやLSTMのようなアーキテクチャを検討する必要がある
- データ中心のアプローチが問題解決に有用である
1件のコメント
Hacker Newsの意見
この記事では、テストや訓練データについてあまり触れられていない
この記事は、実用的な作業を行うためのニューラルネットワークの構築方法として読むと興味深い
ニューラルネットワークには普遍近似定理(Universal Approximation Theorem)が存在する
この記事はRNNに関する深い数学的概念を扱っているが、興味深いアイデアを提供している
RNNがトランスフォーマーに完全に置き換えられたのか気になっているという意見がある
遺伝的プログラミング(Genetic Programming)を見てみる価値がある
この記事はRNNを学習経験として扱い、PyTorchのRNNと比較している
RNNは任意の計算を実行できるが、実用的ではない
ニューラルネットワークがますますコードのように見えてくるだろうという意見がある