[LSTM]LSTMネットワークに基づく顔認識アルゴリズムのMATLABシミュレーション

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つの比較アルゴリズムの認識率

アルゴリズム

-15db

-10db

-5db

0db

5db

10db

15db

NN

17.5250

30.9500

45.0000

52.6000

55.4750

57.5750

57.6000

RBM

19.4000

40.4500

58.4750

67.9500

70.4000

72.2750

71.8750

RNN

20.6750

41.1500

60.0750

68.6000

72.5500

73.3500

73.3500

LSTM

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 Cyber​​netics.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つの完全なソースコードを無料で入手します

おすすめ

転載: blog.csdn.net/ccsss22/article/details/124025316