バックプロパゲーション

バックプロパゲーション（）または誤差逆伝播法（ごさぎゃくでんぱほう）はニューラルネットワークの学習アルゴリズムである。

概要 
バックプロパゲーションは数理モデルであるニューラルネットワークの重みを層の数に関わらず更新できる（学習できる）アルゴリズムである。ディープラーニングの主な学習手法として利用される。

そのアルゴリズムは次の通りである：

 ニューラルネットワークに学習のためのサンプルを与える。
 ネットワークの出力を求め、出力層における誤差を求める。その誤差を用い、各出力ニューロンについて誤差を計算する。
 個々のニューロンの期待される出力値と倍率 (scaling factor)、要求された出力と実際の出力の差を計算する。これを局所誤差と言う。
 各ニューロンの重みを局所誤差が小さくなるよう調整する。
 より大きな重みで接続された前段のニューロンに対して、局所誤差の責任があると判定する。
 そのように判定された前段のニューロンのさらに前段のニューロン群について同様の処理を行う。

アルゴリズム名が示唆するように、エラー（および学習）は出力ノードから後方のノードへと伝播する。技術的に言えば、バックプロパゲーションはネットワーク上の変更可能な重みについて、誤差の傾斜を計算するものである。この傾斜はほとんどの場合、誤差を最小にする単純なアルゴリズムである確率的最急降下法で使われる。「バックプロパゲーション」という用語はより一般的な意味でも使われ、傾斜を求める手順と確率的最急降下法も含めた全体を示す。バックプロパゲーションは通常すばやく収束して、対象ネットワークの誤差の局所解(区間を限定したときの極小値、極値参照)を探し出す。人工ニューロン(または「ノード」)で使われる活性化関数は可微分でなければならない。また、ガウス・ニュートン法とも密接に関連する。

バックプロパゲーションのアルゴリズムは何度か再発見されており、逆積算モードにおける自動微分という汎用技法の特殊ケースと見ることもできる。

数理最適化問題の一種であるため、バッチ学習・オンライン学習のいずれかが採用される。典型的には確率的勾配降下法を用いたミニバッチ学習が行われる。

目的 
ネットワーク  に対する誤差関数  を定義したとき、現在の重み  における  の傾きすなわち偏微分値  がわかれば、最適化手法である勾配法を用いて誤差  が小さくなるように  を更新（=学習）できる。学習アルゴリズムであるバックプロパゲーションの目的はこの勾配値を得て重みを学習することである。

テクニック 
バックプロパゲーションを用いて（深層）ニューラルネットワークモデルを素早く・最適解へ収束させるために様々なテクニックが提唱されている。

標準的なテクニックをヤン・ルカンらが1998年にまとめていて、2010年に Xavier Glorot らが追証・発展させている。以下に要約する。詳細はそれぞれの論文を参照。

 オンライン学習において訓練データが一周したら毎回シャッフルし直す
 入力は、平均を0にし、主成分分析により線形相関を取り除き、分散が1になるように線形変換する。面倒だったら主成分分析は省略しても良い。
 目標値（出力）は活性化関数を通す場合は、二次導関数が最大になる範囲内を使用するべきである。 の場合は −1〜1 で、tanh(x) の場合は  〜  = −0.65848 〜 0.65848 である。
 初期値: 各層で平均0分散1、かつ連続一様分布
 入力ベース:  by ヤン・ルカン
 入出力ベース:  by Xavier Glorot
 勾配法: 様々なパラメータ更新法が提案され利用されている（確率的勾配降下法#変種を参考）。
 活性化関数
 原点を通過すなわち 
 例:、、逆に標準シグモイド関数は f(0) = 0.5 のため不適切
 入出力範囲 
 例: 
 ReLU（ランプ関数、アナログ閾素子（））: 経験的に良い性能

高速化

GPU 
行列の掛け算はGPGPUが得意としており、高速に計算できる。PythonではTheanoなどのライブラリおよびそれを間接的に使用してる機械学習のライブラリなどがある。

CPUによる並列化 
CPUのメニーコアやSIMDを有効活用する簡単な方法は行列演算ライブラリを使用する方法である。行列演算ライブラリとしては、例えばインテルのCPU向けではIntel Math Kernel Libraryなどがある。

バックプロパゲーションは完了までに非常に時間のかかる反復処理である。マルチコアのコンピュータでマルチスレッド技法を使えば、収斂までにかかる時間を大幅に短縮することができる。バッチ学習を行う場合、マルチスレッドでバックプロパゲーションのアルゴリズムを実行するのが比較的簡単である。

訓練データをそれぞれのスレッド毎に同程度の大きさに分割して割り当てる。それぞれのスレッドで順方向と逆方向のプロパゲーションを行う。重みとしきい値のデルタをスレッド毎に合計していく。反復の周回毎に全スレッドを一時停止させて、重みとしきい値のデルタを合計し、ニューラルネットワークに適用する。これを反復毎に繰り返す。このようなバックプロパゲーションのマルチスレッド技法がEncog Neural Network Frameworkで使われている。

歴史 
バックプロパゲーションに相当（連鎖律+勾配法）するニューラルネットワーク学習手法は何度も再発見されてきた。

 1960年, B. Widrow & M.E. Hoff, Jr. :  Widrow-Hoff法（デルタルール）、隠れ層のない2層のニューラルネットワークでの出力誤差からの確率的勾配降下法
 1967年, 甘利俊一: 隠れ層のあるニューラルネットワーク
 1969年, & : 多段動的システム最適化手法として提案
 1974年, : ニューラルネットワークにおける応用を示唆
 1986年, デビッド・ラメルハート、ジェフリー・ヒントン、: backwards propagation of errors（後方への誤差伝播）の略からバックプロパゲーションの名で再発明、以後定着

21世紀におけるディープラーニングではバックプロパゲーションが学習法としてよく用いられる。

限界 
 損失超平面が極小値 () を持ちうるため、勾配降下で広域最適解 () に収束する保証がない (Remelhart, 1986)
 一カ所でも勾配消失を起こすとそれより下層は学習が進まなくなるため、層数が増えるほど勾配消失を起こす確率が増大していく
 勾配が0に近い部分が存在する活性化関数を使っていると勾配消失を起こしやすい

脚注

外部リンク 
ニューラルネットワーク入門（岩田彰）
 Chapter 7 The backpropagation algorithm of Neural Networks - A Systematic Introduction by Raul Rojas (ISBN 978-3540605058)
Implementation of BackPropagation in C#
Implementation of BackPropagation in Ruby
Backpropagation Algorithm Explained In Simple English: Along with a sample implementation in Microsoft.NET
Quick explanation of the backpropagation algorithm
Graphical explanation of the backpropagation algorithm
Concise explanation of the backpropagation algorithm using math notation
Backpropagation for mathematicians
Implementation of BackPropagation in C++
Implementation of BackPropagation in Java
Implementation of BackPropagation in Python
Implementation of BackPropagation in PHP
Backpropagation neural network tutorial at the Wikiversity

機械学習アルゴリズム
人工ニューラルネットワーク
教師あり学習