1.ソフトウェアバージョン
matlab2021a
2.このアルゴリズムの理論的知識
長期記憶モデルLSTMは、1997年にHochreiter et al。によって最初に提案されました。その主な原理は、特殊なニューロン構造を介して情報を長期間保存することです。LSTMネットワークモデルの基本構造を次の図に示します。
図1LSTMネットワークの基本構造
図1の構造図からわかるように、LSMTネットワーク構造には、入力層、メモリモジュール、出力層の3つの部分があります。メモリモジュールは、入力ゲート、忘れゲート、出力ゲートで構成されています。LSTMモデルは、これら3つの制御ゲートを介してニューラルネットワーク内のすべてのニューロンの読み取りおよび書き込み操作を制御します。
LSTMモデルの基本原理は、複数の制御ゲートを介してRNNニューラルネットワークの勾配消失の欠陥を抑制することです。LSTMモデルは、勾配情報を長期間保存し、信号の処理時間を長くすることができるため、さまざまな周波数の信号や高周波数と低周波数の混合信号の処理に適しています。LSTMモデルのメモリユニットの入力ゲート、忘却ゲート、および出力ゲートは、制御ユニットを介して非線形合計ユニットを形成します。入力ゲート、忘却ゲート、出力ゲートの活性化関数はシグモイド関数であり、これにより制御ゲートの「開」状態と「閉」状態を変更できます。
次の図は、LSTMモデルのメモリモジュールの内部構造を示しています。
図2LSTMネットワークのメモリユニットの内部構造
図2の構造図からわかるように、LSTMのメモリユニットの動作原理は、入力ゲートが「オン」状態になると外部情報がメモリユニットによって読み取られ、入力ゲートが入ると読み取られるというものです。 「オフ」状態の場合、外部情報は入力できません。メモリユニット。同様に、忘却ゲートと出力ゲートは同様の制御機能を備えています。LSTMモデルは、これら3つの制御ゲートを介してさまざまな勾配情報をメモリユニットに長期間保存します。メモリユニットが情報を長期間保存すると、その忘却ゲートは「開」状態になり、入力ゲートは「閉」状態になります。
入力ゲートが「開」状態になると、メモリユニットは外部情報の受信と保存を開始します。入力ゲートが「閉」状態になると、メモリユニットは外部情報の受信を一時停止すると同時に、出力ゲートは「開」状態になり、メモリユニットに格納されている情報は次の層に送信されます。忘却ゲートの機能は、必要に応じてニューロンの状態をリセットすることです。
LSTMネットワークモデルの順方向伝播プロセスの場合、関係する数学的原理は次のとおりです。
2.忘却ゲートの計算プロセスは次のとおりです。
3.メモリユニットの計算プロセスは次のとおりです。
4.出力ゲートの計算プロセスは次のとおりです。
5.メモリユニットの出力計算プロセスは次のとおりです。
LSTMネットワークモデルのバックプロパゲーションプロセスの場合、関連する数学的原理は次のとおりです。
6.入力ゲートの計算プロセスは次のとおりです。
LSTMネットワークに基づく視覚認識アルゴリズムの全体的なアルゴリズムフローチャートを次の図に示します。
図3LSTMネットワークに基づく視覚認識アルゴリズムのフローチャート
図3のアルゴリズムのフローチャートによると、このホワイトペーパーで検討するLSTMネットワークに基づく視覚認識アルゴリズムの手順は次のとおりです。
ステップ1:画像収集、この論文は研究対象として顔画像を取ります。
ステップ2:この章のセクション2の内容に従って、画像の前処理を行い、認識される視覚画像を前処理して、より鮮明な画像を取得します。
ステップ3:画像のセグメンテーション、画像のセグメント化、収集された画像の認識ターゲットとシーン全体のサイズの関係に基づいてセグメントサイズが決定され、元の画像が異なるサイズのサブ画像にセグメント化されます。
ステップ4:サブグラフの幾何学的要素を抽出し、エッジ抽出法によって各サブグラフに含まれる幾何学的要素を取得し、各幾何学的要素から文情報を形成します。
ステップ5:文情報をLSTMネットワークに入力します。このステップはコアリンクでもあります。LSTMネットワークの認識プロセスを以下に紹介します。まず、文情報がLSTMの入力層を介してLSTMネットワークに入力されます。基本的な構造図を次の図に示します。
図3LSTMネットワークに基づく認識構造図
ここでは、ある時点でのLSTMの入力特徴情報と出力結果を合計し、そのメモリモジュールの入力と出力を合計し、その合計がLSTMニューロンの活性化関数の出力と出力を表すと仮定します。 LSTMトレーニングプロセス全体は次のとおりです。
3.コアコード
function nn = func_LSTM(train_x,train_y,test_x,test_y);
binary_dim = 8;
largest_number = 2^binary_dim - 1;
binary = cell(largest_number, 1);
for i = 1:largest_number + 1
binary{i} = dec2bin(i-1, binary_dim);
int2binary{i} = binary{i};
end
%input variables
alpha = 0.000001;
input_dim = 2;
hidden_dim = 32;
output_dim = 1;
%initialize neural network weights
%in_gate = sigmoid(X(t) * U_i + H(t-1) * W_i)
U_i = 2 * rand(input_dim, hidden_dim) - 1;
W_i = 2 * rand(hidden_dim, hidden_dim) - 1;
U_i_update = zeros(size(U_i));
W_i_update = zeros(size(W_i));
%forget_gate = sigmoid(X(t) * U_f + H(t-1) * W_f)
U_f = 2 * rand(input_dim, hidden_dim) - 1;
W_f = 2 * rand(hidden_dim, hidden_dim) - 1;
U_f_update = zeros(size(U_f));
W_f_update = zeros(size(W_f));
%out_gate = sigmoid(X(t) * U_o + H(t-1) * W_o)
U_o = 2 * rand(input_dim, hidden_dim) - 1;
W_o = 2 * rand(hidden_dim, hidden_dim) - 1;
U_o_update = zeros(size(U_o));
W_o_update = zeros(size(W_o));
%g_gate = tanh(X(t) * U_g + H(t-1) * W_g)
U_g = 2 * rand(input_dim, hidden_dim) - 1;
W_g = 2 * rand(hidden_dim, hidden_dim) - 1;
U_g_update = zeros(size(U_g));
W_g_update = zeros(size(W_g));
out_para = 2 * zeros(hidden_dim, output_dim) ;
out_para_update = zeros(size(out_para));
% C(t) = C(t-1) .* forget_gate + g_gate .* in_gate
% S(t) = tanh(C(t)) .* out_gate
% Out = sigmoid(S(t) * out_para)
%train
iter = 9999; % training iterations
for j = 1:iter
% generate a simple addition problem (a + b = c)
a_int = randi(round(largest_number/2)); % int version
a = int2binary{a_int+1}; % binary encoding
b_int = randi(floor(largest_number/2)); % int version
b = int2binary{b_int+1}; % binary encoding
% true answer
c_int = a_int + b_int; % int version
c = int2binary{c_int+1}; % binary encoding
% where we'll store our best guess (binary encoded)
d = zeros(size(c));
% total error
overallError = 0;
% difference in output layer, i.e., (target - out)
output_deltas = [];
% values of hidden layer, i.e., S(t)
hidden_layer_values = [];
cell_gate_values = [];
% initialize S(0) as a zero-vector
hidden_layer_values = [hidden_layer_values; zeros(1, hidden_dim)];
cell_gate_values = [cell_gate_values; zeros(1, hidden_dim)];
% initialize memory gate
% hidden layer
H = [];
H = [H; zeros(1, hidden_dim)];
% cell gate
C = [];
C = [C; zeros(1, hidden_dim)];
% in gate
I = [];
% forget gate
F = [];
% out gate
O = [];
% g gate
G = [];
% start to process a sequence, i.e., a forward pass
% Note: the output of a LSTM cell is the hidden_layer, and you need to
for position = 0:binary_dim-1
% X ------> input, size: 1 x input_dim
X = [a(binary_dim - position)-'0' b(binary_dim - position)-'0'];
% y ------> label, size: 1 x output_dim
y = [c(binary_dim - position)-'0']';
% use equations (1)-(7) in a forward pass. here we do not use bias
in_gate = sigmoid(X * U_i + H(end, :) * W_i); % equation (1)
forget_gate = sigmoid(X * U_f + H(end, :) * W_f); % equation (2)
out_gate = sigmoid(X * U_o + H(end, :) * W_o); % equation (3)
g_gate = tanh(X * U_g + H(end, :) * W_g); % equation (4)
C_t = C(end, :) .* forget_gate + g_gate .* in_gate; % equation (5)
H_t = tanh(C_t) .* out_gate; % equation (6)
% store these memory gates
I = [I; in_gate];
F = [F; forget_gate];
O = [O; out_gate];
G = [G; g_gate];
C = [C; C_t];
H = [H; H_t];
% compute predict output
pred_out = sigmoid(H_t * out_para);
% compute error in output layer
output_error = y - pred_out;
% compute difference in output layer using derivative
% output_diff = output_error * sigmoid_output_to_derivative(pred_out);
output_deltas = [output_deltas; output_error];
% compute total error
overallError = overallError + abs(output_error(1));
% decode estimate so we can print it out
d(binary_dim - position) = round(pred_out);
end
% from the last LSTM cell, you need a initial hidden layer difference
future_H_diff = zeros(1, hidden_dim);
% stare back-propagation, i.e., a backward pass
% the goal is to compute differences and use them to update weights
% start from the last LSTM cell
for position = 0:binary_dim-1
X = [a(position+1)-'0' b(position+1)-'0'];
% hidden layer
H_t = H(end-position, :); % H(t)
% previous hidden layer
H_t_1 = H(end-position-1, :); % H(t-1)
C_t = C(end-position, :); % C(t)
C_t_1 = C(end-position-1, :); % C(t-1)
O_t = O(end-position, :);
F_t = F(end-position, :);
G_t = G(end-position, :);
I_t = I(end-position, :);
% output layer difference
output_diff = output_deltas(end-position, :);
% H_t_diff = (future_H_diff * (W_i' + W_o' + W_f' + W_g') + output_diff * out_para') ...
% .* sigmoid_output_to_derivative(H_t);
% H_t_diff = output_diff * (out_para') .* sigmoid_output_to_derivative(H_t);
H_t_diff = output_diff * (out_para') .* sigmoid_output_to_derivative(H_t);
% out_para_diff = output_diff * (H_t) * sigmoid_output_to_derivative(out_para);
out_para_diff = (H_t') * output_diff;
% out_gate diference
O_t_diff = H_t_diff .* tanh(C_t) .* sigmoid_output_to_derivative(O_t);
% C_t difference
C_t_diff = H_t_diff .* O_t .* tan_h_output_to_derivative(C_t);
% forget_gate_diffeence
F_t_diff = C_t_diff .* C_t_1 .* sigmoid_output_to_derivative(F_t);
% in_gate difference
I_t_diff = C_t_diff .* G_t .* sigmoid_output_to_derivative(I_t);
% g_gate difference
G_t_diff = C_t_diff .* I_t .* tan_h_output_to_derivative(G_t);
% differences of U_i and W_i
U_i_diff = X' * I_t_diff .* sigmoid_output_to_derivative(U_i);
W_i_diff = (H_t_1)' * I_t_diff .* sigmoid_output_to_derivative(W_i);
% differences of U_o and W_o
U_o_diff = X' * O_t_diff .* sigmoid_output_to_derivative(U_o);
W_o_diff = (H_t_1)' * O_t_diff .* sigmoid_output_to_derivative(W_o);
% differences of U_o and W_o
U_f_diff = X' * F_t_diff .* sigmoid_output_to_derivative(U_f);
W_f_diff = (H_t_1)' * F_t_diff .* sigmoid_output_to_derivative(W_f);
% differences of U_o and W_o
U_g_diff = X' * G_t_diff .* tan_h_output_to_derivative(U_g);
W_g_diff = (H_t_1)' * G_t_diff .* tan_h_output_to_derivative(W_g);
% update
U_i_update = U_i_update + U_i_diff;
W_i_update = W_i_update + W_i_diff;
U_o_update = U_o_update + U_o_diff;
W_o_update = W_o_update + W_o_diff;
U_f_update = U_f_update + U_f_diff;
W_f_update = W_f_update + W_f_diff;
U_g_update = U_g_update + U_g_diff;
W_g_update = W_g_update + W_g_diff;
out_para_update = out_para_update + out_para_diff;
end
U_i = U_i + U_i_update * alpha;
W_i = W_i + W_i_update * alpha;
U_o = U_o + U_o_update * alpha;
W_o = W_o + W_o_update * alpha;
U_f = U_f + U_f_update * alpha;
W_f = W_f + W_f_update * alpha;
U_g = U_g + U_g_update * alpha;
W_g = W_g + W_g_update * alpha;
out_para = out_para + out_para_update * alpha;
U_i_update = U_i_update * 0;
W_i_update = W_i_update * 0;
U_o_update = U_o_update * 0;
W_o_update = W_o_update * 0;
U_f_update = U_f_update * 0;
W_f_update = W_f_update * 0;
U_g_update = U_g_update * 0;
W_g_update = W_g_update * 0;
out_para_update = out_para_update * 0;
end
nn = newgrnn(train_x',train_y(:,1)',mean(mean(abs(out_para)))/2);
4.操作手順とシミュレーションの結論
この論文のLSTMネットワーク認識アルゴリズムにより、異なる干渉サイズで収集された顔が認識され、認識精度曲線が次の図に示されています。
図2のシミュレーション結果から、収集された画像への干渉が減少することで、この論文で研究されたLSTM認識アルゴリズムが最高の認識精度を持っていることがわかります。RNNニューラルネットワークと畳み込みベースのディープニューラルネットワーク認識率は同じです。ニューラルネットワークの認識率のパフォーマンスは明らかに劣っています。具体的な認識率を次の表に示します。
表14つの比較アルゴリズムの認識率
17.5250 |
30.9500 |
45.0000 |
52.6000 |
55.4750 |
57.5750 |
57.6000 |
|
19.4000 |
40.4500 |
58.4750 |
67.9500 |
70.4000 |
72.2750 |
71.8750 |
|
20.6750 |
41.1500 |
60.0750 |
68.6000 |
72.5500 |
73.3500 |
73.3500 |
|
23.1000 |
46.3500 |
65.0250 |
72.9500 |
75.6000 |
76.1000 |
76.3250 |
5.参考文献
[01] Mi Liangchuan、Yang Zifu、LiDeshengなど。自動ロボットビジョン制御システム[J]。産業用制御コンピューター。2003.3。
[02] Or1ando、Fla.Digital Image Processing Techniques.Academic Pr、Inc.1984
[03]K.Fukushima。視覚パターン認識における選択的注意のためのニューラルネットワークモデル。生物学的サイバネティックス[J]1986年10月‑55(1):5-15。
[04]しきい値線形相関分類器のTHHidebrandt最適トレーニング[J]。IEEE Transaction Neural Networks.1991‑2(6):577-588。
[05]ネオコグニトロンにおけるVanOoyenB.Nienhuisパターン認識は、神経適応によって改善されます[J] .Biological Cybernetics.1993,70:47-53。
[06] Bao QingLiBaoXinLi。畳み込みニューラルネットワークを使用したパターン分類器の構築[J]。Neural.Networks‑vol.5(3):3081-3085。
[07] ES ackinger‑、B boser、Y lecun‑、Ljaclel。ANNAニューラルネットワークチップの高速文字認識への応用[J]。ニューラルネットワーク上のIEEEトランザクション1992.3:498-505。
A05-40
6.完全なソースコードを入手する方法
方法1:WeChatまたはQQ経由でブロガーに連絡する
方法2:MATLAB / FPGAチュートリアルを購読し、チュートリアルケースと2つの完全なソースコードを無料で入手します