MATLAB、Python、Scilab、Julia比較ページはこちら
https://www.simulationroom999.com/blog/comparison-of-matlab-python-scilab/
はじめに
の、
MATLAB,Python,Scilab,Julia比較 第4章 その99【モーメンタム⑨】
を書き直したもの。
ニューラルネットワークの最適化アルゴリズムについて。
モーメンタムをプログラムとして実装する。
今回はScilabで実現。
モーメンタムのプログラムフロー【再掲】
まずは、プログラムフローを再掲。
- シグモイド関数の定義
- シグモイド関数の導関数の定義
- データの準備
- ネットワークの構築
- 重みとバイアスの初期化
- モーメンタム項の初期化
- 学習(4000エポック)
- 順伝播
- 誤差計算(平均二乗誤差)
- 逆伝播
- パラメータの更新(モーメンタム)
- 決定境界線の表示
今回は、Scilabで実現する。
Scilabコード
Scilabコードは以下。
// シグモイド関数の定義
function y = sigmoid(x)
y = 1 ./ (1 + exp(-x));
endfunction
// シグモイド関数の導関数の定義
function y = sigmoid_derivative(x)
y = sigmoid(x) .* (1 - sigmoid(x));
endfunction
// データの準備
X = [0 0; 0 1; 1 0; 1 1]; // 入力データ
Y = [0; 1; 1; 0]; // 出力データ
// ネットワークの構築
hidden_size = 4; // 隠れ層のユニット数
output_size = 1; // 出力層のユニット数
learning_rate = 0.5; // 学習率
momentum = 0.9; // モーメンタム
input_size = size(X, 2);
W1 = rand(input_size, hidden_size, 'normal'); // 入力層から隠れ層への重み行列
b1 = rand(1, hidden_size, 'normal'); // 隠れ層のバイアス項
W2 = rand(hidden_size, output_size, 'normal'); // 隠れ層から出力層への重み行列
b2 = rand(1, output_size, 'normal'); // 出力層のバイアス項
// モーメンタム項の初期化
vW1 = zeros(W1);
vb1 = zeros(b1);
vW2 = zeros(W2);
vb2 = zeros(b2);
// 学習
epochs = 4000; // エポック数
errors = zeros(epochs, 1); // エポックごとの誤差を保存する配列
for epoch = 1:epochs
// 順伝播
Z1 = X * W1 + ones(size(X, 1),1) * b1; // 隠れ層の入力
A1 = sigmoid(Z1); // 隠れ層の出力
Z2 = A1 * W2 + b2; // 出力層の入力
A2 = sigmoid(Z2); // 出力層の出力
// 誤差計算(平均二乗誤差)
error = (1/size(X, 1)) * sum((A2 - Y).^2);
errors(epoch) = error;
// 逆伝播
delta2 = (A2 - Y) .* sigmoid_derivative(Z2);
delta1 = (delta2 * W2') .* sigmoid_derivative(Z1);
grad_W2 = A1' * delta2;
grad_b2 = sum(delta2);
grad_W1 = X' * delta1;
grad_b1 = sum(delta1);
// パラメータの更新
vW1 = momentum * vW1 - learning_rate * grad_W1;
vb1 = momentum * vb1 - learning_rate * grad_b1;
vW2 = momentum * vW2 - learning_rate * grad_W2;
vb2 = momentum * vb2 - learning_rate * grad_b2;
W1 = W1 + vW1;
b1 = b1 + vb1;
W2 = W2 + vW2;
b2 = b2 + vb2;
end
// 決定境界線の表示
h = 0.01; // メッシュの間隔
[x1, x2] = meshgrid(min(X(:, 1)) - 0.5:h:max(X(:, 1)) + 0.5, min(X(:, 2)) - 0.5:h:max(X(:, 2)) + 0.5);
X_mesh = [x1(:) x2(:)];
hidden_layer_mesh = sigmoid(X_mesh * W1 + ones(size(X_mesh, 1), 1) * b1);
output_layer_mesh = sigmoid(hidden_layer_mesh * W2 + b2);
y_mesh = round(output_layer_mesh); // 出力を0または1に丸める
clf;
x = X_mesh(:, 1);
y = X_mesh(:, 2);
idx_boundary = find(y_mesh(1:$-1) <> y_mesh(2:$)); // 境界のインデックスを取得
boundary_x = x(idx_boundary); // 境界のx座標
boundary_y = y(idx_boundary); // 境界のy座標
scatter(boundary_x, boundary_y, 3, 'k', 'fill'); // 境界を黒でプロット
scatter(X(Y==0, 1), X(Y==0, 2), 100, 'r', 'fill');
scatter(X(Y==1, 1), X(Y==1, 2), 100, 'b', 'fill');
xlabel("X1");
ylabel("X2");
title("XOR Classification");
legend("Boundary", "Class 1", "Class 0");
xgrid; // グリッドの表示
処理結果
処理結果は以下。
分類のパターンとしては大きく2パターンあるので、それぞれを分類と誤差関数の推移を掲載。
パターン1
パターン2
まとめ
- 最適化アルゴリズム モーメンタムを用いて分類の学習をScilabで実現。
- 問題無く動作。
- 学習の収束が通常の勾配降下法よりも比較的早い。
MATLAB、Python、Scilab、Julia比較ページはこちら
Pythonで動かして学ぶ!あたらしい線形代数の教科書
Amazon.co.jp
ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装
Amazon.co.jp
ゼロからはじめるPID制御
https://amzn.to/3SvzuyR
OpenCVによる画像処理入門
https://amzn.to/498ZUgK
恋する統計学[回帰分析入門(多変量解析1)] 恋する統計学[記述統計入門]
Amazon.co.jp
Pythonによる制御工学入門
Amazon.co.jp
理工系のための数学入門 ―微分方程式・ラプラス変換・フーリエ解析
https://amzn.to/3UAunQK
コメント