📄 art_ext.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //for filename
#include "art_def.h"
#include "art_int.h"
/**
* \fn int InitNet(netPTR net, int net_type,
int componentA, int styleA, int num_inputs,
int componentB, int styleB, int num_outputs)
* \brief initializes network values
* Given network parameters, initializes network values and allocates spaces
* \param net A pointer to a network of type netTYPE
* \param set A pointer to a set of patterns of type setTYPE
* \param net_type ART or ARTMAP
* \param componentA ART_TYPE_ART1 or ART_TYPE_FUZZYART
* For net_type ART, this is the type of ART
* network that is created.
* For net_type ARTMAP, this the the ArtA network
* used for ArtMap input vectors.
* \param styleA ART_STYLE_NONE or ART_STYLE_COMPLIMENT
* \param componentB ART_TYPE_ART1, ART_TYPE_FUZZYART or ART_TYPE_NONE
* for net-type ARTMAP, this the the ArtB network
* used for ArtMap input vectors.
* \param styleB ART_STYLE_NONE or ART_STYLE_COMPLIMENT
* \retval 0 Network successfuly Initialized
* \retval 1 Invalid Network Type
* \retval 2 Invalid Art Component
* \retval 3 Invalid Style Type
* \retval 4 Invalid number or inputs or outputs (<=0)
* \retval 5 Network was already initialized
* \retval 6 Memory Allocation Failure (out of memory)
* \retval 7 When net NULL
*/
int InitNet(netPTR net, int net_type,
int componentA, int styleA, int num_inputs,
int componentB, int styleB, int num_outputs)
{
if (net==NULL)
{
return 7;
}
/**< Check if already initialized */
if ((net->initB) == TRUE)
{
return 5;
}
/**< Check styles */
if ((styleA != ART_STYLE_NONE)&&(styleA != ART_STYLE_COMPLIMENT))
{
return 3;
}
/**< Check input size */
if (num_inputs <= 0)
{
return 4;
}
net->checkB = FALSE; /**< Hasn't been tested against the set */
net->doneB = FALSE; /**< Training hasn't occured */
net->type = net_type;
net->num_inputs = num_inputs;
net->num_patterns = 0; /**< No training yet, so all zero */
net->num_epochs = 0;
if (net_type == ART)
{
/**< First check validity of Art type */
if ((componentA != ART_TYPE_ART1)&&(componentA != ART_TYPE_FUZZYART))
{
return 2;
}
net->num_outputs = 0;
if (InitArt(&net->art, componentA, styleA, num_inputs))
{
return 6;
}
net->initB = TRUE; /**< The network has been initialized */
return 0;
}
else if (net_type == ARTMAP)
{
/**< Check output size */
if (num_outputs <= 0)
{
return 4;
}
/**< Check validity of Art types */
if (((componentA != ART_TYPE_ART1)&&(componentA != ART_TYPE_FUZZYART))||
((componentB != ART_TYPE_ART1)&&(componentB != ART_TYPE_FUZZYART)&&(componentB != ART_TYPE_NONE)))
{
return 2;
}
/**< Check styles */
if ((styleB != ART_STYLE_NONE)&&(styleB != ART_STYLE_COMPLIMENT))
{
return 3;
}
net->num_outputs = num_outputs;
if (InitMap(&net->map, componentA, styleA, componentB, styleB, num_inputs, num_outputs))
{
return 6;
}
net->initB = TRUE; /**< The network has been initialized */
return 0;
}
else
{
/**< Wrong network type */
return 1;
}
}
/**
* \fn int InitSet(setPTR set, int num_inputs, int type_inputs, int num_outputs, int type_outputs)
* \brief Initialize values for a new pattern set
* \param set A pointer to a set of patterns of type setTYPE
* \param num_inputs Number of input values
* \param type_inputs NODE_ANALOG or NODE_BINARY
* \param num_outputs Number of output values
* \param type_outputs NODE_ANALOG, NODE_BINARY or NODE_NONE
* \retval 0 Set successfuly Initialized
* \retval 1 Initialization Failure - Invalid Set Types
* \retval 2 Output type NODE_NONE specified with non-zero number of outputs
* \retval 3 Memory Allocation Failure (out of memory)
* \retval 4 When set is NULL
*/
int InitSet(setPTR set, int num_inputs, int type_inputs, int num_outputs, int type_outputs)
{
int i;
if (set == NULL)
{
return 4;
}
/**< First check that types are valid */
if ((type_inputs != NODE_ANALOG)&&(type_inputs != NODE_BINARY))
{
return 1;
}
if ((type_outputs != NODE_ANALOG)&&(type_outputs != NODE_BINARY)&&(type_outputs != NODE_NONE))
{
return 1;
}
/**< If type_output is NODE_NONE, num_outputs should be 0 */
if ((type_outputs == NODE_NONE)&&(num_outputs != 0))
{
return 2;
}
set->max_num_patterns = 50; /**< Allocate space for 50 patterns */
set->num_patterns = 0; /**< No patterns to start with */
set->num_inputs = num_inputs;
set->type_inputs = type_inputs;
set->style_inputs = NODE_NONE; /**< Not compliment coded until load */
set->num_outputs = num_outputs;
set->type_outputs = type_outputs;
set->style_outputs = NODE_NONE; /**< Not compliment coded until load */
/**< Allocate space for patterns */
set->pattern = (patTYPE *)malloc((size_t)(set->max_num_patterns * sizeof(patTYPE)));
if (set->pattern == NULL)
{
return 3;
}
/**< Allocate space for input/output vectors patterns */
for (i = 0; i < set->max_num_patterns; i++)
{
set->pattern[i].input = (float *)malloc((size_t)(set->num_inputs * sizeof(float)));
if (set->pattern[i].input == NULL)
{
free(set->pattern);
set->pattern = NULL;
return 3;
}
/**< If there are output patterns, allocate space */
if (set->type_outputs != NODE_NONE)
{
set->pattern[i].output = (float *)malloc((size_t)(set->num_outputs * sizeof(float)));
if (set->pattern[i].output == NULL)
{
int j;
for (j = 0; j < i; j++)
{
if (set->pattern[j].input != NULL)
{
free(set->pattern[j].input);
set->pattern[j].input = NULL;
}
if (set->pattern[j].output != NULL)
{
free(set->pattern[j].output);
set->pattern[j].output = NULL;
}
}
free(set->pattern);
set->pattern = NULL;
return 3;
}
}
}
set->initB = TRUE; /**< The set has been initialized */
set->checkB = FALSE; /**< The set has not been checked against the network */
return 0;
}
/**
* \fn int TrainSet(netPTR net, setPTR set, int max_epoch)
* \brief Trains the network on the pattern set
* Given a pointer to a network, and a pointer to a pattern set,
* trains the network on the pattern set.
* \param net A pointer to an initialized netowrk of type netTYPE
* \param set A pointer to a set of patterns of type setTYPE
* \param max_epoch Maximum number of training epochs
* \retval 0 When successful
* \retval 1 When the set wasn't initialized first or NULL
* \retval 2 When the network wasn't initialized first or NULL
* \retval 3 NODE_ANALOG inputs given to NODE_BINARY network
* \retval 4 Input Size Incompatible
* \retval 5 Output Size Incompatible
* \retval 6 No output patterns for ARTMAP network
* \retval 7 Memory Allocation Failure (out of memory)
*/
int TrainSet(netPTR net, setPTR set, int max_epoch)
{
int epoch; /**< Number of times passed through training set */
int pat; /**< Counters */
int oldA_used; /**< Old number of ArtA nodes used */
int oldB_used; /**< Old number of ArtB nodes used */
/**< Check that set was initialized first */
if ((set == NULL)||(set->initB != TRUE))
{
return 1;
}
/**< Check that network was initialized first */
if ((net==NULL)||(net->initB!=TRUE))
{
return 2;
}
/**< Check to see if the net and set were tested for compatibility */
if ((net->checkB==FALSE)||(set->checkB==FALSE))
{
if (CheckNetSet(net,set)) /**< If not check compatibilty */
{
//todo: shoud return a value directly.
return (CheckNetSet(net,set)); /**< If there was an error return it */
}
}
/**< ========= If everything in order, then train the network ============ */
/**< --------------- If network is a plain Art network ------------------- */
if (net->type == ART)
{
/**< Initialize Variables */
oldA_used = net->art.nodes_used;
net->art.num_reset = 0; /**< To ensure at least on epoch */
epoch = 0;
net->doneB = FALSE; /**< Network isn't done with training */
/**< Do another Epoch if there were any resets */
while ((!(net->doneB))&&(epoch!=max_epoch))
{
epoch++;
net->art.num_reset = 0;
oldA_used = net->art.nodes_used;
/**< Train each pattern in the set checking for mem. allocation errs */
for (pat = 0; pat < set->num_patterns; pat++)
{
ActivateArt(&net->art, set->pattern[pat].input);
if (TrainArtPat(&net->art, set->pattern[pat].input))
{
net = NULL;
return 7;
}
}
/**< Check in no more resents, if so then done training */
if ((net->art.num_reset == 0)&&(oldA_used == net->art.nodes_used))
{
net->doneB = TRUE;
}
}
/**< Update network statistics based on new training */
net->num_patterns += set->num_patterns;
net->num_epochs += epoch;
}
/**< ------------------ If network is an ArtMap network ------------------ */
else if (net->type == ARTMAP)
{
/**< Initialize Variables */
oldA_used = net->map.artA.nodes_used;
oldB_used = net->map.artB.nodes_used;
epoch = 0;
net->doneB = FALSE; /**< Network isn't done with training */
/**< Do another Epoch when not done or hit max number of epochs */
while ((!(net->doneB))&&(epoch != max_epoch))
{
epoch++;
/**< Reset Counters */
net->map.num_mismatch = 0;
net->map.artA.num_reset = 0;
net->map.artB.num_reset = 0;
/**< Update Size */
oldA_used = net->map.artA.nodes_used;
oldB_used = net->map.artB.nodes_used;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -