Skip to content

Instantly share code, notes, and snippets.

@sanity
Created February 18, 2020 17:59
Show Gist options
  • Save sanity/f6d327ea1c5c4abafb57c970ef2a946a to your computer and use it in GitHub Desktop.
Save sanity/f6d327ea1c5c4abafb57c970ef2a946a to your computer and use it in GitHub Desktop.
/*
The C Neural Network Toolkit - Include File
(c) 1993,1994 Ian Clarke
*/
#define train teach
struct node
{
float error,input,output,correct_output,threshold,change_in_threshold;
short type;
};
const signed short input=-1;
const signed short hidden=0;
const signed short output=1;
struct connection
{
short start,end;
float weight,change_in_weight;
};
/* Procedure prototypes */
void run_net(struct node *nodes,struct connection *conns,int n,int c);
float af(float value);
void reset_net(struct node *nodes,struct connection *conns,int n,int c);
void teach_net(struct node *nodes,struct connection *conns,int n,int c
,float learning_rate);
float derror(float,float);
void scramble_net(struct node *nodes,struct connection *conns,int n,int c);
void make_changes(struct node *nodes,struct connection *conns,int n,int c);
/* This procedure causes the energy to flow from the bottom of
the net to the top*/
void run_net(struct node nodes[],struct connection conns[],int n,int c)
{
int x;
for (x=0;x<n;x++)
{
nodes[x].input=0;
};
for (x=0;x<c;x++)
{
if ((nodes[conns[x].start].output==0)&(nodes[conns[x].start].type!=input))
{
nodes[conns[x].start].output=af(nodes[conns[x].start].input+nodes[conns[x].start].threshold);
};
nodes[conns[x].end].input+=nodes[conns[x].start].output*conns[x].weight;
nodes[conns[x].end].output=0;
};
for(x=n-1;nodes[x].type==output;x--)
{
nodes[x].output=af(nodes[x].input+nodes[x].threshold);
};
}
/* This is the function used to determine the response of a node to input*/
float af(float input)
{
float output;
output=(float) (1/(1+exp(-input)));
return output;
}
/* Reset 'change_in_weight' and 'change_in_threshold' */
void reset_net(struct node nodes[],struct connection conns[],int n,int c)
{
int counter;
for (counter=0;counter<n;counter++)
{
nodes[counter].change_in_threshold=0;
};
for (counter=0;counter<=c-1;counter++)
{
conns[counter].change_in_weight=0;
};
}
/* Teach net */
void teach_net(struct node nodes[],struct connection conns[],int n,int c,float lr)
{
int x;
for(x=0;x<n;x++)
{
nodes[x].error=0;
};
for(x=c-1;x>-1;x--)
{
if (nodes[conns[x].end].type==output)
{
nodes[conns[x].end].error=nodes[conns[x].end].correct_output-
nodes[conns[x].end].output;
};
nodes[conns[x].start].error+=conns[x].weight*
derror(nodes[conns[x].end].error,nodes[conns[x].start].output);
};
for(x=0;x<c;x++)
{
conns[x].change_in_weight+=lr*nodes[conns[x].start].output*
derror(nodes[conns[x].end].error,nodes[conns[x].end].output);
};
for(x=0;x<n;x++)
{
nodes[x].change_in_threshold+=derror(nodes[x].error,nodes[x].output);
};
}
float derror(float error,float output)
{
float otpt;
otpt=error*output*(1-output);
return otpt;
}
void make_changes(struct node nodes[],struct connection conns[],int n,int c)
{
int x;
for(x=0;x<n;x++)
{
nodes[x].threshold+=nodes[x].change_in_threshold;
};
for(x=0;x<c;x++)
{
conns[x].weight+=conns[x].change_in_weight;
};
}
void scramble_net(struct node nodes[],struct connection conns[],int n,int c)
{
int p;
for(p=0;p<n;p++)
{
nodes[p].change_in_threshold=0;
nodes[p].threshold=((int) drand48()*4)-2;
};
for(p=0;p<c;p++)
{
conns[p].change_in_weight=0;
conns[p].weight=((int) drand48()*4)-2;
};
}
/*
The C Neural Network Tool-Kit
Design
By Ian Clarke
NOTE: This is a hastily prepared guide to the use of the C Neural
Network toolkit, I expect it to be full of errors so please email me
when you find them.
Email: [email protected]
****************Intended use of the C Neural Network Toolkit*******************
The C Neural Network Tool-Kit (CNNTK) is an assortment of functions,
designed to allow any C programmer to use the power of Neural Networks in
his or her programs. The program will include detailed documentation to
allow the user to learn about neural networks, they will not even need to
know what a neural network is before they read the instruction files!
***************************Technical Specifications****************************
CNNTK is fully ANSI compatible, allowing it to be used under any operating
system with a ANSI C compiler. The type of network modelled is a
multi-layer feed-forward net, using the generalised delta, or backward
error propogation learning algorithm. The program would heavily benifit
from a maths co-processor if available(and if the compiler used can detect
and make use of it).
*********************************Background************************************
CNNTK was developed using Lattice C V5.52 on an Atari ST/Falcon computer.
Also available is a program 'The Neural Network Construction Kit', by the
same author, but currently available for the Atari ST/TT/Falcon range of
computers only.
*******************************Internal Design*********************************
The Neural Network is contained within 2 arrays.
The first array is of 'node' structures. The node structure contains
the following elements:
*float output
This element contains the output of the node in question, this will
contain the output of output nodes, and should be set to the input of
input nodes
*short type
This contains the type of the node, use the constants input, hidden or
output to set this to the correct value
*float correct_output
This should contain the correct output of a node, ie. what the node
should output. This should be set before teach_net is called.
float error
This is for the learning algorithm and need not be touched by the user
float threshold
This is the nodes threshold, and need not be touched by the user
float input
This is the input to a node, DON'T USE THIS TO SET THE INPUT OF INPUT
NODES, float output SHOULD BE USED INSTEAD
The second array is of 'connection' structures and contains
information concerning the connections.
*short start
This is the node at which the connection starts
*short end
This is the node at which the connection ends
short weight
This is the weight of the connection and need not be touched by the user
short change_in_weight
This is used by the training algorithm and need not be touched by the
user
*****************************Functions*******************************
The high level functions (in contact with the users program) are:
*NODE is a pointer to an array of node structures
*CONNECTION is a pointer to an array of connection structures
NODES is the amount of nodes
CONNECTIONS is the amount of connections
RUN_NET(*NODE,*CONNECTION,NODES,CONNECTIONS)
This function will run through one cycle of the neural network and set the
output of the output nodes( NODE[x].output ) according to the output of the
input nodes (also NODE [x].output )
TEACH_NET(*NODE,*CONNECTION,NODES,CONNECTIONS,LEARNING_RATE)
This function will adjust the weights of the connections and thresholds
of the nodes to bring the actual output( NODE[x].output ) of the output
nodes, closer to the desired output( NODE[x].correct_output )
SCRAMBLE_NET(*NODE,*CONNECTION,NODES,CONNECTIONS)
This resets connection weights and node thresholds to random values
MAKE_CHANGES(*NODE,*CONNECTION,NODES,CONNECTIONS)
This is called after one training cycle to implement the changes in
weights and thresholds which have been calculated during the training
cycle.
RESET_NET(*NODE,*CONNECTION,NODES,CONNECTIONS)
After make_changes has been called, this must be called to reset the
change_in_weight and change_in_threshold values
What follows is the general structure of a CNNTK program
1)#include "cnntk1.c" >Include C Neural Network Toolkit File
Define node and connection arrays (normally global)
2)Set up connections between nodes (by setting .start and .end values
in connection structures
3)Set types of nodes (by setting .type component of node structures to
hidden, input or output (these are defined in cnntk1.c)
4)Call scramble_net
Training Cycle>>
5)Set .output values of input nodes to first/next item of input data
6)Set .correct_output values of output nodes
7)Call run_net
8)Call teach_net
9)If not last item of input data return to 5)
10) Call make_changes to implement changes
11) If not last training cycle return to stage 5)
To run the net>
1) Set .output values of input nodes to first/next item of input data
2) Call run_net
3) Output of net will be in .output of output nodes
4) If not last item of input data return to stage 1)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment