[LSTM] Simulación MATLAB del algoritmo de reconocimiento facial basado en la red LSTM

1. Versión de software

matlab2021a

2. Conocimiento teórico de este algoritmo

    El modelo de memoria a largo plazo LSTM fue propuesto por primera vez por Hochreiter et al., en 1997, y su principio fundamental es almacenar información durante mucho tiempo a través de una estructura neuronal especial. La estructura básica del modelo de red LSTM se muestra en la siguiente figura:

Figura 1 Estructura básica de la red LSTM

    Como puede verse en el diagrama de estructura de la Figura 1, la estructura de la red LSMT incluye tres partes: la capa de entrada, el módulo de memoria y la capa de salida. El módulo de memoria consta de la puerta de entrada, la puerta de olvido y la puerta de salida. El modelo LSTM controla las operaciones de lectura y escritura de todas las neuronas de la red neuronal a través de estas tres puertas de control.

    El principio básico del modelo LSTM es suprimir el defecto del gradiente de fuga de la red neuronal RNN a través de múltiples puertas de control. El modelo LSTM puede guardar la información del gradiente durante mucho tiempo y prolongar el tiempo de procesamiento de la señal. Por lo tanto, el modelo LSTM es adecuado para procesar señales de varias frecuencias y señales mixtas de alta y baja frecuencia. La puerta de entrada, la puerta de olvido y la puerta de salida en la unidad de memoria en el modelo LSTM forman una unidad de suma no lineal a través de la unidad de control. La función de activación de la puerta de entrada, la puerta de olvido y la puerta de salida es la función sigmoide, a través de la cual se pueden cambiar los estados "abierto" y "cerrado" de la puerta de control.

    La siguiente figura muestra la estructura interna del módulo de memoria en el modelo LSTM:

 

Figura 2 La estructura interna de la unidad de memoria de la red LSTM

    Como se puede ver en el diagrama de estructura de la Figura 2, el principio de funcionamiento de la unidad de memoria de LSTM es que cuando la puerta de entrada entra en el estado "encendido", la unidad de memoria lee la información externa y cuando la puerta de entrada entra el estado "apagado", la información externa no puede entrar en la unidad de memoria. De manera similar, la puerta de olvido y la puerta de salida tienen funciones de control similares. El modelo LSTM almacena información de varios gradientes en la unidad de memoria durante mucho tiempo a través de estas tres puertas de control. Cuando la unidad de memoria almacena información durante mucho tiempo, su puerta de olvido está en estado "abierto" y la puerta de entrada está en estado "cerrado".

    Cuando la puerta de entrada entra en el estado "abierto", la unidad de memoria comienza a recibir y almacenar información externa. Cuando la puerta de entrada entra en el estado "cerrado", la unidad de memoria suspende la recepción de información externa y, al mismo tiempo, la puerta de salida entra en el estado "abierto", y la información almacenada en la unidad de memoria se transmite a la siguiente capa. La función de la puerta del olvido es restablecer el estado de las neuronas cuando sea necesario.

    Para el proceso de propagación directa del modelo de red LSTM, los principios matemáticos involucrados son los siguientes:

 

 2. El proceso de cálculo de la puerta de olvido es el siguiente:

       

 3. El proceso de cálculo de la unidad de memoria es el siguiente:

 4. El proceso de cálculo de la puerta de salida es el siguiente:

 5. El proceso de cálculo de salida de la unidad de memoria es el siguiente:

Para el proceso de retropropagación del modelo de red LSTM, los principios matemáticos involucrados son los siguientes:

 6. El proceso de cálculo de la puerta de entrada es el siguiente:

    El diagrama de flujo del algoritmo general del algoritmo de reconocimiento visual basado en la red LSTM se muestra en la siguiente figura:

                                

 

Figura 3 Diagrama de flujo del algoritmo de reconocimiento visual basado en la red LSTM

De acuerdo con el diagrama de flujo del algoritmo de la Figura 3, los pasos del algoritmo de reconocimiento visual basado en la red LSTM que se estudiarán en este artículo son:

    Paso 1: Recopilación de imágenes, este trabajo toma la imagen del rostro como objeto de investigación.

    Paso 2: Preprocesamiento de imágenes, de acuerdo con el contenido de la Sección 2 de este capítulo, preprocesar la imagen visual a reconocer para obtener una imagen más clara.

    Paso 3: Segmentación de imágenes, la imagen se segmenta y el tamaño del segmento se determina de acuerdo con la relación entre el objetivo de reconocimiento de la imagen recopilada y el tamaño general de la escena, y la imagen original se segmenta en subimágenes de diferentes tamaños.

    Paso 4: Extraer elementos geométricos de subgráficos, obtener los elementos geométricos contenidos en cada subgráfico a través del método de extracción de bordes y formar información de oraciones a partir de cada elemento geométrico.

    Paso 5: Ingrese la información de la oración en la red LSTM. Este paso también es el enlace principal. El proceso de reconocimiento de la red LSTM se presenta a continuación. Primero, la información de la oración se ingresa en la red LSTM a través de la capa de entrada de LSTM. El diagrama de estructura básica se muestra en la siguiente figura:

Figura 3 Diagrama de estructura de reconocimiento basado en la red LSTM

    Aquí, se supone que la información de características de entrada y el resultado de salida de LSTM en un momento determinado son suma, la entrada y salida en su módulo de memoria son suma, y ​​la suma representa la salida de la función de activación de la neurona LSTM y la salida de la capa oculta Todo el proceso de entrenamiento de LSTM es:

3. Código central


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. Pasos de operación y conclusión de la simulación.

    A través del algoritmo de reconocimiento de red LSTM de este documento, se reconocen los rostros recopilados con diferentes tamaños de interferencia y la curva de precisión del reconocimiento se muestra en la siguiente figura:

 

    A partir de los resultados de la simulación en la Figura 2, se puede ver que con la reducción de la interferencia en las imágenes recopiladas, el algoritmo de reconocimiento LSTM estudiado en este documento tiene la mejor precisión de reconocimiento.La red neuronal RNN y la red neuronal profunda basada en convolución tienen la misma tasa de reconocimiento El rendimiento de la tasa de reconocimiento de la red neuronal es obviamente pobre. La tasa de reconocimiento específica se muestra en la siguiente tabla:

Tabla 1 Tasas de reconocimiento de cuatro algoritmos de comparación

algoritmo

-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. Referencias

[01] Mi Liangchuan, Yang Zifu, Li Desheng, etc. Sistema automático de control de visión de robot [J] Computadora de control industrial 2003.3.

[02]Or1ando,Fla.Técnicas de procesamiento de imágenes digitales.Academic Pr,Inc.1984

[03]K.Fukushima.Un modelo de red neuronal para la atención selectiva en el reconocimiento de patrones visuales. Cibernética biológica [J] octubre de 1986-55 (1): 5-15.

[04]Entrenamiento óptimo de THCidebrandt de clasificadores de correlación lineal con umbral [J]. Redes neuronales de transacciones IEEE.1991‑2(6):577-588.

[05]Van Ooyen B.Nienhuis Pattern Recognition in the Neocognitron Is Enhanced by Neural Adaption[J].Biological Cybernetics.1993,70:47-53.

[06]Bao Qing Li BaoXinLi. Construyendo clasificadores de patrones utilizando redes neuronales convolucionales[J]. Neural.Networks‑vol.5(3): 3081-3085.

[07]ES ackinger‑,B boser,Y lecun‑,L jaclel. Aplicación del chip de red neuronal ANNA al reconocimiento de caracteres de alta velocidad[J]. Transacciones IEEE en redes neuronales 1992.3:498-505.

A05-40

6. Cómo obtener el código fuente completo

Método 1: Póngase en contacto con el bloguero a través de WeChat o QQ

Método 2: suscríbase al tutorial de MATLAB/FPGA, obtenga el caso del tutorial y 2 códigos fuente completos de forma gratuita

Supongo que te gusta

Origin blog.csdn.net/ccsss22/article/details/124025316
Recomendado
Clasificación