Neural Networks
Sigmoid Activation Function
入力とパラメータの内積を、シグモイド関数を通して 0 < a < 1
の範囲に変換するモデルを、 Sigmoid (Logistic) activation function と呼ぶ。
バイアス項 Bias unit として、x(0) = 1
で固定し、theta(0)
をオフセット値とする。入力値 x
を (0|1)
に制限すると、theta
の値に応じて AND / OR の論理回路を実現できる。
X = [0 0; 0 1; 1 0; 1 1];
X = [ones(length(X), 1), X]; % [1 0 0; 1 0 1; 1 1 0; 1 1 1]
theta1 = [-30; 20; 20]; % AND gate
z1 = X * theta1; % [-30; -10; -10; 10]
h1 = sigmoid(z1); % [0; 0; 0; 1]
theta2 = [-10; 20; 20]; % OR gate
z2 = X * theta2; % [-10; 10; 10; 30]
h2 = sigmoid(z2); % [0; 1; 1; 1]
Forward Propagation
Activation function を複数レイヤーに定義し、各レイヤーの出力を次のレイヤーへの入力とすることで、より複雑な論理回路を実現できる。このモデルは、神経回路のシミュレーションを元にしており、ニューラルネットワーク Neural network と呼ばれる。
L1 | L2 | L3 | L4
------------------------------------------
[+1]-+ [+1]-+ [+1]-+
| | |
[x(1)]-+->[a2(1)]-+->[a3(1)]-+->[a4(1)]-> h(x)
| | |
[x(2)]-+->[a2(2)]-+->[a3(2)]-+
| |
+->[a2(3)]-+
- 入力
x
のバイアス項としてx(0) = 1
とする。 - Layer1: 3つの入力
x
から、3つの出力a2
を算出する。バイアス項としてa2(0) = 1
とする。 - Layer2: Layer1 の4つの出力
a2
を入力とし、2つの出力a3
を算出する。バイアス項としてa3(0) = 1
とする。 - Layer3: Layer2 の3つの出力
a3
を入力とし、1つの出力a4
を算出する。 - 最終レイヤーの出力
a4(1)
が、予測値h(x)
となる。
Layer2 の2入力に NAND / OR ゲート、Layer3 の1入力に AND ゲートを置くことで、XOR ゲートとして機能する。
Theta1 = [30 -20 -20; -10 20 20]; % [{NAND}; {OR}]
Theta2 = [-30 20 20]; % [{AND}]
X = [0 0; 0 1; 1 0; 1 1];
X = [ones(length(X), 1), X]; % [1 0 0; 1 0 1; 1 1 0; 1 1 1]
z1 = X * Theta1'; % [30 -10; 10 10; 10 10; -10 30]
a2 = sigmoid(z1); % [1 0; 1 1; 1 1; 0 1]
a2 = [ones(length(a2), 1), a2]; % [1 1 0; 1 1 1; 1 1 1; 1 0 1]
z2 = a2 * Theta2'; % [-10; 10; 10; -10]
a3 = sigmoid(z2); % [0; 1; 1; 0]
このように、複数レイヤーの入出力を介して、前方に伝播させていく方法を Forward propagation と呼ぶ。
Multi-class Classification
3つ以上に分類するには、出力レイヤーのユニットを、分類の数だけ用意すればよい。
L1 | L2 | L3 |
--------------------------------
[+1]-+ [+1]-+
| |
[x(1)]-+->[a2(1)]-+->[a3(1)]
| |
[x(2)]-+->[a2(2)]-+->[a3(2)]
| |
+->[a2(3)]-+->[a3(3)]
| |
+->[a2(4)]-+
出力レイヤーのベクトルを a3
、正解値を y
としたとき、a3(y)
のフラグが立つと考える。
y = 1 if a3 = [1; 0; 0]
y = 2 if a3 = [0; 1; 0]
y = 3 if a3 = [0; 0; 1]
分類数を K
とすると、コスト関数は各出力の誤差平均を求めればよい。
Cost Function
ニューラルネットワークのコスト関数は、ロジスティック回帰と同様であるが、予測値を求めるには Forward propagation で各レイヤーを通して算出する必要がある。
Theta1 = [-30 10 10 10; -10 20 20 20; 20 -10 -10 -10; -20 10 10 10];
Theta2 = [10 -20 -20 -10 -10; -10 10 10 0 10; 20 -20 -20 -10 -10];
X = [0 0 0; 0 0 1; 0 1 0; 1 1 1];
m = size(X, 1);
a1 = X; % 4 x 3
a1 = [ones(m, 1) a1]; % 4 x 4
z2 = a1 * Theta1'; % 4 x 4
a2 = sigmoid(z2);
a2 = [ones(size(a2, 1), 1) a2]; % 4 x 5
z3 = a2 * Theta2'; % 4 x 3
h = sigmoid(z3);
Regularization を行なう場合は、各レイヤーにパラメータがある点に注意する。バイアス項は除外する。
t1 = Theta1;
t2 = Theta2;
t1(:, 1) = 0;
t2(:, 1) = 0;
lambda = 0.1;
J = J + (sum(sum(t1 .^ 2)) + sum(sum(t2 .^ 2))) * lambda / (2 * m);
Sigmoid Gradient Function
ネイピア数 e
を底とする指数の微分は (e^x)' = e^x
であることを利用して、シグモイド関数 g(z)
を微分すると g'(z) = g(z) * (1 - g(z))
となる。
Backpropagation
ニューラルネットワークの各ユニットのパラメータ(ニューロンの重み)を求めるには、ロジスティック回帰と同様に最急降下法を用いる。各ユニットの偏微分を求めるためには、最終出力の誤差から各レイヤーを逆に伝播して算出する必要がある。この方法を、誤差逆伝播法 Backpropagation と呼ぶ。
出力レイヤーの誤差は、予測値ベクトルから正解値ベクトルを引いたものになる。
中間レイヤーの誤差は以下の式で求められる。各パラメータ自身が次のレイヤーに伝播させてしまった誤差を算出すると考えればよい。バイアス項は含めなくてよい。
入力レイヤーの誤差は存在しないので算出する必要はない。
ユニットの入力 a(l)
に、直後のレイヤーの誤差を掛け合わせたものが、各パラメータの偏微分となる。
Regularization を行なう場合は、各パラメータ毎にペナルティを与えればよい。コスト関数と同様に、バイアス項は除外する。
Numerical Gradient
Backpropagation を正しく行なえているかどうかは、一つのパラメータのみ極小値で増減させて、二つのコスト関数を適用した差分が Backpropagation で得た偏微分とほぼ相違ないこと(1e-9 以下が目安)をチェックすればよい。
function grad = numericalGradient(J, theta)
m = length(theta);
grad = zeros(m, 1);
E = 0.01; % epsilon;
for i = 1:m
theta1 = theta; theta1(i) = theta1(i) + E;
theta2 = theta; theta2(i) = theta2(i) - E;
grad(i) = (J(theta1) - J(theta2)) / (2 * E);
end
end
すべてのパラメータに対してコスト関数を適用するため、非常に処理時間がかかる。あくまで Backpropagation が正しくおこなえているかのチェックのみで、実際の学習処理に含めてはならない。
Symmetry Breaking
ニューラルネットワークにおいては、レイヤーの出力として、次のレイヤーの各ユニットへ同じ入力が与えられる。このため入力に対するパラメータ(重み)が同じ値の場合、同一レイヤー内の全てのユニットの出力が同じ値になってしまう。
- 初期パラメータを全て 0 にすると、バイアス項のみが伝播する。
- 初期パラメータを全て 1 にすると、全てのユニットの出力が、前ユニット出力の総和のシグモイド値になる。
このため Backpropagation を開始する際の初期パラメータは、ランダムである必要がある。-ε .. ε
の範囲でランダムに設定するとよい。
E = 0.01 % epsilon
Theta1 = rand(3, 4) * (2 * E) - E; % initialize to 3 x 4 random matrix
Theta2 = rand(3, 5) * (2 * E) - E; % initialize to 3 x 5 random matrix