No BSD License  

Highlights from
Fuzzy ART and Fuzzy ARTMAP Neural Networks

Fuzzy ART and Fuzzy ARTMAP Neural Networks

by

 

22 Dec 2003 (Updated )

This package allows creation, training, and testing of ART and ARTMAP neural networks.

ARTMAP_Learn(artmap_network, data, supervisor)
function new_artmap_network = ARTMAP_Learn(artmap_network, data, supervisor)
% ARTMAP_Learn    Trains an ARTMAP network on the given input data.
%    NEW_ARTMAP_NETWORK = ARTMAP_Learn(ARTMAP_NETWORK, DATA, SUPERVISOR)
%    This function trains an ARTMAP network on the given input data. Each sample
%    of the data is presented to the network, which categorizes each sample
%    and compares that category's entry in the map field to the supervisor signal.
%    If the map field value and the supervisor signal do not match, match-tracking
%    is induced until a category is found to code the input correctly. This
%    category then learns the input vector.
%
%    The function returns a new ARTMAP network which has learned the input data
%    according to the supervisor signal. If the maximum number of categories 
%    is reached and an appropriate categorization of the input cannot be made,
%    no learning occurs. The program prints out a warning message that the 
%    maximum category limit has been reached and begins to process the next
%    input vector.
% 
%    The input parameters are as follows:
%    The ARTMAP_NETWORK is the ARTMAP network to be trained. It should be created
%    with ARTMAP_Create_Network(). The DATA is the training data to be presented
%    to the network. It is a matrix of size NumFeatures-by-NumSamples. The
%    SUPERVISOR is the correct classification for each input vector. It is a
%    matrix of size 1-by-NumSamples.
%
%    The return parameters are as follows:
%    The NEW_ARTMAP_NETWORK is a new ARTMAP network which has learned the input data.


% Make sure the user specifies the input parameters.
if(nargin ~= 3)
    error('You must specify all 3 input parameters.');
end

% Make sure that the data is appropriate for the given network.
[numFeatures, numSamples] = size(data);
if(numFeatures ~= artmap_network.numFeatures)
    error('The data does not contain the same number of features as the network.');
end

% Make sure the vigilance is within the (0, 1] range.
if((artmap_network.vigilance <= 0) | (artmap_network.vigilance > 1))
    error('The vigilance must be within the range (0, 1].');
end

% Make sure that the number of epochs is a positive integer.
if(artmap_network.numEpochs < 1)
    error('The number of epochs must be a positive integer.');
end

% Set up the return variables.
new_artmap_network = {};


% Go through the data once for every epoch.
for epochNumber = 1:artmap_network.numEpochs
        
    % This variable will allow us to keep up with the total
    % network change due to learning.
    % Initialize the number of changes to 0.
    numChanges = 0;
    
    % Classify and learn on each sample.
    for sampleNumber = 1:numSamples
        
        % Get the current data sample.
        currentData = data(:, sampleNumber);

        % Get the current supervisory signal.
        currentSupervisor = supervisor(1, sampleNumber);
    
        % Create a new category if this supervisory signal
        % has never been seen before.
        if(isempty(artmap_network.mapField) | isempty(find(artmap_network.mapField == currentSupervisor)))
            
            [resizedWeight, resizedMapField] = ARTMAP_Add_New_Category(artmap_network.weight, artmap_network.mapField);
            resizedWeight = ART_Update_Weights(currentData, resizedWeight, length(resizedMapField), artmap_network.learningRate);
            artmap_network.weight = resizedWeight;
            artmap_network.numCategories = artmap_network.numCategories + 1;
            resizedMapField(1, length(resizedMapField)) = currentSupervisor;
            artmap_network.mapField = resizedMapField;
            numChanges = numChanges + 1;
            continue;    
            
        else
        
           % Activate the categories for this sample.
            bias = artmap_network.bias;
            categoryActivation = ART_Activate_Categories(currentData, artmap_network.weight, bias);
            
            % Rank the activations in order from highest to lowest.
            % This will allow us easier access to step through the categories.
            [sortedActivations, sortedCategories] = sort(-categoryActivation);
            
            % Go through the process of locating the highest activated category
            % with the correct value in the map field for the supervisory signal.
            matchTracking = 1;
            vigilance = artmap_network.vigilance;
	
            % Go through each category in the sorted list looking for the best match.
            resonance = 0;
            match = 0;
            numSortedCategories = length(sortedCategories);
            currentSortedIndex = 1;
            while(~resonance)
                
                % Get the current category based on the sorted index.
                currentCategory = sortedCategories(currentSortedIndex);
                
                % Get the current weight vector from the sorted category list.
                currentWeightVector = artmap_network.weight(:, currentCategory);
                
                % Calculate the match given the current data sample and weight vector.
                match = ART_Calculate_Match(currentData, currentWeightVector);
                
                % Check to see if the match is less than the vigilance.
                if(match < vigilance)
                    
                    % If so, choose the next category in the sorted category list.
                    % If the current category is the last in the list, make sure that
                    % the maximum number of categories have not been reached. If the 
                    % maximum has not been reached, create a new category for the input, 
                    % update the weights, and induce resonance.
                    if(currentSortedIndex == numSortedCategories)
                        if(currentSortedIndex == artmap_network.maxNumCategories)
                            fprintf('WARNING: The maximum number of categories has been reached.\n');
                            resonance = 1;
                        else
                            [resizedWeight, resizedMapField] = ARTMAP_Add_New_Category(artmap_network.weight, artmap_network.mapField);
                            [resizedWeight, weightChange] = ART_Update_Weights(currentData, resizedWeight, currentSortedIndex + 1, artmap_network.learningRate);
                            artmap_network.weight = resizedWeight;
                            artmap_network.numCategories = artmap_network.numCategories + 1;
                            resizedMapField(1, currentSortedIndex + 1) = currentSupervisor;
                            artmap_network.mapField = resizedMapField;

                            % Increment the number of changes since we added a new category.
                            numChanges = numChanges + 1;
                            
                            resonance = 1;
                        end
                    else
                        currentSortedIndex = currentSortedIndex + 1;
                    end 
                    
                else 
                    
                    % Otherwise, check the category's value in the map field.
                    if(artmap_network.mapField(1, currentCategory) == currentSupervisor)
                        % If they're equal, the category should code the input.
                        % Therefore, we should update the weights and induce resonance.
                        [artmap_network.weight, weightChange] = ART_Update_Weights(currentData, artmap_network.weight, currentCategory, artmap_network.learningRate);

                        if(weightChange == 1)
                            numChanges = numChanges + 1;
                        end

                        resonance = 1;
                    else
                        % If they're not equal, we must find another category by
                        % inducing match-tracking. This means that we should increase
                        % the vigilance by the current match plus epsilon and then 
                        % continue through the category list until another match is
                        % found.
                        vigilance = match + 0.000001;
                        if(currentSortedIndex == numSortedCategories)
                            if(currentSortedIndex == artmap_network.maxNumCategories)
                                fprintf('WARNING: The maximum number of categories has been reached.\n');
                                resonance = 1;
                            else
                                [resizedWeight, resizedMapField] = ARTMAP_Add_New_Category(artmap_network.weight, artmap_network.mapField);
                                [resizedWeight, weightChange] = ART_Update_Weights(currentData, resizedWeight, currentSortedIndex + 1, artmap_network.learningRate);
                                artmap_network.weight = resizedWeight;
                                artmap_network.numCategories = artmap_network.numCategories + 1;
                                resizedMapField(1, currentSortedIndex + 1) = currentSupervisor;
                                artmap_network.mapField = resizedMapField;
                                
                                % Increment the number of changes since we added a new category.
                                numChanges = numChanges + 1;
                                
                                resonance = 1;
                            end
                        else
                            currentSortedIndex = currentSortedIndex + 1;
                            resonance = 0;
                        end
                    end      % if(artmap_network.mapField(1, currentCategory) == currentSupervisor)
                end      % if(match < vigilance)
            end      % while(~resonance)
        end      % if(isempty(artmap_network.mapField) | isempty(find(artmap_network.mapField == currentSupervisor)))
    end      % for sampleNumber = 1:numSamples
    
    % If the network didn't change at all during the last epoch,
    % then we've reached equilibrium. Thus, we can stop training.
    if(numChanges == 0)
        break;
    end

end      % for epochNumber = 1:artmap_network.numEpochs


fprintf('The number of epochs needed was %d\n', epochNumber);

% Fill the new network with the appropriate values.
new_artmap_network = artmap_network;

return

Contact us