neural-networks.io

neural-networks.io

Exemple de classification automatique

 

# Définition du problème

Dans cet exemple, nous considérons un jeu de données où chaque vecteur d'entrée \( X = ( x , y) \) est associé à une classe A(+1) ou B(-1). La figure suivante illustre ce problème de classification:

 

# Architecture du réseau

L'architecture du réseau sans couche caché est la suivante:

Comme nous souhaitons distinguer la classe A de la classe B, nous devons utiliser une fonction d'activation capable de séparer ces classes. Dans cet exemple, c'est la fonction tangente hyperbolique qui a été choisie:

Ce choix est motivé par le fait que cette fonction retourne une valeur comprise entre -1 et +1. La sortie du réseau peut être interprétée de deux façons. En terme de classes binaires (A ou B) ou en terme de probablités.

 
# Interpretation binaire

Pour déterminer si un échantillon appartient à la classe A ou B, nous pouvons utiliser la règle suivante: lorque la sortie est positive, l'échantillon appartient à la classe A, sinon à la classe B. Mathématiquement, cela revient à ajouter cette fonction à la sortie du réseau:

 
# Interpretation probabiliste

La seconde option pour interpréter la sortie du réseau est de la considérer comme une probabilité d'appartenir à la classe A ou B. Quand la sortie est égale à +1, la probablité de l'échantillon d'appartenir à la classe A ou B est respectivement donnée par un et zéro. L'équation suivante généralise ce concept et convertit la sortie du réseau en probabilités:

Probabilité d'appartenir à la classe A : $$ p_A = \frac{o+1}{2} $$ Probabilité d'appartenir à la classe B : $$ p_B = \frac{1-o}{2} $$ Notons que la somme des probabilité est toujours égale à 1 ( \( p_A + p_B = 1 \) ).
 

# Resultats

La figure suivante montre comment l'espace est divisé en deux classes après l'apprentissage:

La figure suivante donne une vue d'ensemble des résultats d'apprentissage.

 

# Source code

Cliquez sur l'un des langages suivants pour afficher le code source de cette classification :

%% Single layer classifier
close all;
clear all;
clc;

%% Parameters
% Dataset size
N=1000;
% Learning rate
Eta=0.003;




%% Dataset
% Generate dataset for each class [ X , Y , class (+1 or -1) ]

% Class A (+1)

% ~ 98% good classification
classA = mvnrnd ([2, 2] , [5 1.5; 1.5 1] ,N/2) ;
%% Uncomment the following line to create a 100% good classification
%classA = mvnrnd ([2, 4] , [5 1.5; 1.5 1] ,N/2) ;
classA= [classA , ones(N/2,1) ];

% class B (-1)

classB = mvnrnd ([2,-2] , [3,0;0,0.5] ,N/2);
classB= [classB , -ones(N/2,1) ];

% Merge classes for creating the dataset
dataset=[ classA ; classB ];
% Shuffle dataset
dataset=dataset(randperm(length(dataset)),:);




%% Initialize weight
W=[0;0;0];

%% Trainig loop
for i = 1:size(dataset,1)
    % Forward
    S=W'*[dataset(i,1:2),1]';
    Y=tanh (S);
    
    % Expected output
    Y_=dataset(i,3);
    
    % Update weights
    W=W+Eta*(Y_ - Y)*[dataset(i,1:2),1]'*(1-tanh(S)*tanh(S));
end


%% Display

% Get boundaries (for display)
Xmin=min(dataset(:,1));
Xmax=max(dataset(:,1));
Ymin=min(dataset(:,2));
Ymax=max(dataset(:,2));

%% Output
[X,Y] = meshgrid(Xmin:0.1:Xmax,Ymin:0.1:Ymax);
Z = tanh ( X*W(1) + Y*W(2) + W(3) );
surf(X,Y,Z,'facecolor','texture')
hold on;



%% Display dataset
plot3 (classA(:,1),classA(:,2),4+classA(:,3),'.r'); hold on;
plot3 (classB(:,1),classB(:,2),4+classB(:,3),'.b');
grid on;
axis square equal;




%% Test on training set
good=0;
for i = 1:size(dataset,1)
    % Compute network output
    Y=tanh (W'*[dataset(i,1:2),1]');
    
    % Compare to the expected output
    if (sign(Y)==dataset(i,3))
        % Good classification (green circle)
        good=good+1;
        plot3 (dataset(i,1),dataset(i,2),8+sign(Y),'og');
    else
        % Wrong classification (black cross)
        plot3 (dataset(i,1),dataset(i,2),8+sign(Y),'xk');            
    end
end

% Axis labels and colormap
colormap(jet);
colorbar
shading interp;
xlabel ('X');
ylabel ('Y');
% Uncomment for a top view
%view(0,90);

% Compute success ratio 
badly_classified = 1-good/N

Output :

badly_classified =

    0.0060