Initial import

git-svn-id: http://moon:8086/svn/software/trunk/libsrc/nn@1 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
2014-07-19 07:44:42 +00:00
commit 82fbd5d19d
7 changed files with 1797 additions and 0 deletions
Executable
+909
View File
@@ -0,0 +1,909 @@
/**********************************************************************
* nnet.c
*
* (C) 2000 J. Ahrensfeld
*
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "nnfile.h"
#include "nntypes.h"
#include "nnet.h"
/**********************************************************************/
//#define COOL_FEEDFORWARD
//#define COOL_BACKPROP
/**********************************************************************/
char *unitStr[] =
{
"Bias", "Input", "Hidden", "Output"
};
/**********************************************************************/
UINT32 NetInit(struct _sNNET *pObj, NETFILE *pNetData, UINT32 netID)
{
UINT32 i, j, k, layCnt, numUnits;
pObj->nUnits = 0;
pObj->ID = netID;
pObj->pUnit = NULL;
pObj->pLayer = NULL;
pObj->nLayers = 0;
pObj->sse = 0.0;
pObj->pInputID = 0;
pObj->pHiddenID = 0;
pObj->pOutputID = 0;
pObj->nIn = 0;
pObj->nOut = 0;
pObj->nHidden = 0;
pObj->nnType = pNetData->nntype;
pObj->initwrange = pNetData->initwrange;
pObj->nLayers = 2 + pNetData->nHiddenLayers;
pObj->pLayer = (LAYER*)nnMalloc(pObj->pLayer, pObj->nLayers*sizeof(LAYER));
layCnt = 0;
srand(12345);
rand((UINT16)time(NULL));
/* Init Units */
NetAddUnit(pObj, UTYPE_BIAS, 0); /* Bias Unit has index 0 */
for(i=0; i < (UINT32)pNetData->LInfo[0].nNeurons; i++)
NetAddUnit(pObj, UTYPE_INPUT, 0); /* Input Units */
for(layCnt++; layCnt < pObj->nLayers-1; layCnt++)
for(i=0; i < (UINT32)pNetData->LInfo[layCnt].nNeurons; i++)
NetAddUnit(pObj, UTYPE_HIDDEN, pNetData->LInfo[layCnt].NeuronType);/* Hidden Units */
for(i=0; i < (UINT32)pNetData->LInfo[layCnt].nNeurons; i++)
NetAddUnit(pObj, UTYPE_OUTPUT, pNetData->LInfo[layCnt].NeuronType); /* Output Units */
j = 0;
for(i=0; i < pObj->nLayers; i++)
{
numUnits = pNetData->LInfo[i].nNeurons;
if (i==0)
numUnits++; // +1 for bias unit
LayerInit(&pObj->pLayer[i], &pObj->pUnit[j], numUnits, i);
j += numUnits;
}
for(k=0; k < pObj->nUnits; k++)
{
pObj->pUnit[k].ppRecurr = (FLOAT64**)realloc(pObj->pUnit[k].ppRecurr, pObj->nUnits*sizeof(FLOAT64*));
pObj->pUnit[k].ppRecurrOld = (FLOAT64**)realloc(pObj->pUnit[k].ppRecurrOld, pObj->nUnits*sizeof(FLOAT64*));
for (i=0; i < pObj->nUnits; i++)
{
pObj->pUnit[k].ppRecurr[i] = (FLOAT64*)malloc(pObj->nUnits*sizeof(FLOAT64));
pObj->pUnit[k].ppRecurrOld[i] = (FLOAT64*)malloc(pObj->nUnits*sizeof(FLOAT64));
memset(pObj->pUnit[k].ppRecurr[i], 0, (pObj->nUnits)*sizeof(FLOAT64));
memset(pObj->pUnit[k].ppRecurrOld[i], 0, (pObj->nUnits)*sizeof(FLOAT64));
}
}
return EXIT_SUCCESS;
}
UINT32 NetWire(struct _sNNET *pObj, UINT32 nnType)
{
UINT32 layer, i, j, firstUnitInLayer_i, firstUnitInLayer_j;
switch(nnType)
{
case NNTYPE_MLP:
/* Wire bias unit */
layer=0;
for(j=pObj->pLayer[layer].nUnits; j < pObj->nUnits; j++)
NetAddConnection(pObj,0, j);
/* Wire input units */
firstUnitInLayer_i = 1;
for (i=0; i < pObj->pLayer[layer].nUnits-1; i++)
{
firstUnitInLayer_j = pObj->pLayer[layer+1].ppUnit[0]->globalUnitID;
for(j=0; j < pObj->pLayer[layer+1].nUnits; j++)
{
NetAddConnection(pObj,i+firstUnitInLayer_i, j+firstUnitInLayer_j);
}
}
/* Wire hidden units */
layer++;
for (layer; layer < pObj->nLayers-1; layer++)
{
firstUnitInLayer_i = pObj->pLayer[layer].ppUnit[0]->globalUnitID;
for (i=0; i < pObj->pLayer[layer].nUnits; i++)
{
firstUnitInLayer_j = pObj->pLayer[layer+1].ppUnit[0]->globalUnitID;
for(j=0; j < pObj->pLayer[layer+1].nUnits; j++)
{
NetAddConnection(pObj,i+firstUnitInLayer_i, j+firstUnitInLayer_j);
}
}
}
break;
case NNTYPE_RECURRENT:
/* Wire bias unit */
/* Wire input units */
firstUnitInLayer_i = 1;
for (i=0; i < pObj->pLayer[0].nUnits; i++)
{
for(j=pObj->pLayer[0].nUnits; j < pObj->nUnits; j++)
{
NetAddConnection(pObj,i, j);
}
}
/* Wire hidden units */
for (i=pObj->pLayer[0].nUnits; i < pObj->nUnits; i++)
{
for(j=pObj->pLayer[0].nUnits; j < pObj->nUnits; j++)
{
NetAddConnection(pObj,i, j);
}
}
break;
default:
break;
}
return EXIT_SUCCESS;
}
UINT32 NetFree(struct _sNNET *pObj)
{
UINT32 i;
for (i=0; i < pObj->nUnits; i++)
UnitFree(&pObj->pUnit[i]);
for (i=0; i < pObj->nLayers; i++)
LayerFree(&pObj->pLayer[i]);
nnFree(pObj->pUnit);
nnFree(pObj->pLayer);
return EXIT_SUCCESS;
}
UINT32 NetAddUnit(struct _sNNET *pObj, UINT32 unitType, UINT32 FType)
{
UINT32 uid;
uid = pObj->nUnits;
pObj->pUnit = (UNIT*)realloc(pObj->pUnit, (uid+1)*sizeof(UNIT));
switch(unitType)
{
case UTYPE_INPUT:
pObj->pInputID = (UINT32*)realloc(pObj->pInputID, (pObj->nIn+1)*sizeof(UINT32));
pObj->pInputID[pObj->nIn] = uid;
pObj->nIn++;
break;
case UTYPE_HIDDEN:
pObj->pHiddenID = (UINT32*)realloc(pObj->pHiddenID, (pObj->nHidden+1)*sizeof(UINT32));
pObj->pHiddenID[pObj->nHidden] = uid;
pObj->nHidden++;
break;
case UTYPE_OUTPUT:
pObj->pOutputID = (UINT32*)realloc(pObj->pOutputID, (pObj->nOut+1)*sizeof(UINT32));
pObj->pOutputID[pObj->nOut] = uid;
pObj->nOut++;
break;
}
UnitInit(&pObj->pUnit[uid], unitType, FType, uid);
pObj->nUnits++;
return uid;
}
void NetPrint(struct _sNNET *pObj)
{
UINT32 layer, i, j, id, nAxonTo, firstUnitInLayer_i;
printf("Connection Table\n");
/* Wire hidden units */
for (layer=0; layer < pObj->nLayers; layer++)
{
firstUnitInLayer_i = pObj->pLayer[layer].ppUnit[0]->globalUnitID;
printf("*** LAYER %d ***\n",layer);
for (i=0; i < pObj->pLayer[layer].nUnits; i++)
{
id = pObj->pUnit[i+firstUnitInLayer_i].globalUnitID;
nAxonTo = pObj->pUnit[id].nAxonTo;
if (!nAxonTo)
continue;
printf("Axon of %s unit %d.%d (ID #%d) connected to \n",unitStr[pObj->pUnit[id].UType],pObj->pUnit[id].layerID,pObj->pUnit[id].unitID, id);
for (j=0; j < nAxonTo; j++)
{
id = pObj->pUnit[i+firstUnitInLayer_i].pAxonTo[j].unitID;
printf("%s unit %d.%d (ID #%d)\n",unitStr[pObj->pUnit[id].UType],pObj->pUnit[id].layerID,pObj->pUnit[id].unitID,id);
}
}
}
printf("\n");
}
UINT32 LayerInit(struct _sLAYER *pObj, struct _sUNIT *pUnit, UINT32 nUnits, UINT32 LayID)
{
UINT32 i;
pObj->ID = LayID;
pObj->nUnits = nUnits;
pObj->ppUnit = (UNIT**) malloc(pObj->nUnits*sizeof(UNIT*));
for(i=0; i < pObj->nUnits; i++)
{
pUnit[i].layerID = LayID;
pUnit[i].unitID = i;
pObj->ppUnit[i] = &pUnit[i];
}
return EXIT_SUCCESS;
}
UINT32 LayerFree(struct _sLAYER *pObj)
{
free(pObj->ppUnit);
return EXIT_SUCCESS;
}
UINT32 UnitInit(struct _sUNIT *pObj, UINT32 type, UINT32 FType, UINT32 ID)
{
pObj->globalUnitID = ID;
pObj->layerID = 0;
pObj->unitID = 0;
pObj->UType = type;
pObj->nAxonTo = 0;
pObj->nWeights = 0;
pObj->pAxonFrom = (UINT32*)malloc(sizeof(UINT32));
pObj->pAxonTo = (WTINFO*)malloc(sizeof(WTINFO));
pObj->pWeight = (FLOAT64*)malloc(sizeof(FLOAT64));
pObj->pSlope = (FLOAT64*)malloc(sizeof(FLOAT64));
pObj->pdWeight = (FLOAT64*)malloc(sizeof(FLOAT64));
pObj->ppRecurr = (FLOAT64**)malloc(sizeof(FLOAT64*));
*pObj->ppRecurr = (FLOAT64*)malloc(sizeof(FLOAT64));
pObj->ppRecurrOld = (FLOAT64**)malloc(sizeof(FLOAT64*));
*pObj->ppRecurrOld = (FLOAT64*)malloc(sizeof(FLOAT64));
*pObj->pAxonFrom = UNIT_ID_INPUT;
pObj->pAxonTo->unitID = UNIT_ID_OUTPUT;
*pObj->pWeight = 1.0;
*pObj->pSlope = 0.0;
*pObj->pdWeight = 0.0;
**pObj->ppRecurr = 0.12345;
**pObj->ppRecurrOld = 0.12345;
pObj->net = 0.0;
pObj->error = 0.0;
pObj->delta = 0.0;
pObj->axon = 0.0;
pObj->lastAxon = 0.0;
pObj->F = 0;
pObj->Fd = 0;
pObj->FType = 0;
if (type==UTYPE_BIAS)
{
pObj->axon = 1.0;
pObj->lastAxon = pObj->axon;
return EXIT_SUCCESS;
}
if (type == UTYPE_INPUT)
return EXIT_SUCCESS;
UnitSetFunc(pObj, FType);
return EXIT_SUCCESS;
}
UINT32 UnitSetFunc(struct _sUNIT *pObj, UINT32 FuncType)
{
switch(FuncType)
{
case Lin:
pObj->F = Linear;
pObj->Fd = dLinear;
pObj->FType = Lin;
break;
case Tanh:
pObj->F = Tanh2;
pObj->Fd = dTanh;
pObj->FType = Tanh;
break;
case ASig:
pObj->F = ASigmoid;
pObj->Fd = dSigmoid;
pObj->FType = ASig;
break;
case SSig:
pObj->F = SSigmoid;
pObj->Fd = dSSigmoid;
pObj->FType = SSig;
break;
case Sig:
pObj->F = Sigmoid;
pObj->Fd = dSigmoid;
pObj->FType = Sig;
break;
case FSig:
pObj->F = FSigmoid;
pObj->Fd = dFSigmoid;
pObj->FType = FSig;
break;
default:
pObj->F = Sigmoid;
pObj->Fd = dSigmoid;
pObj->FType = Sig;
break;
}
return EXIT_SUCCESS;
}
UINT32 NetAddConnection(struct _sNNET *pObj, UINT32 ID_i, UINT32 ID_j)
{
UINT32 *pFrom = NULL, i, k;
FLOAT64 *pWeight = NULL, *pdWeight = NULL;
WTINFO *pTo = NULL;
UNIT *pUnit_i, *pUnit_j;
if (ID_j==0 || ID_j >= pObj->nUnits)
return EXIT_FAILURE;
if (ID_i >= pObj->nUnits)
return EXIT_FAILURE;
pUnit_i = &pObj->pUnit[ID_i];
pUnit_j = &pObj->pUnit[ID_j];
for(i=0; i < pUnit_i->nAxonTo; i++)
{
if (pUnit_i->pAxonTo[i].unitID == ID_j)
{
printf("Axon of unit #%d already connected to unit #%d\n",ID_i,ID_j);
return EXIT_FAILURE;
}
}
/* Unit j */
pUnit_j->pAxonFrom = realloc(pUnit_j->pAxonFrom, (pUnit_j->nWeights + 1)*sizeof(UINT32));
pUnit_j->pWeight = realloc(pUnit_j->pWeight,(pUnit_j->nWeights + 1)*sizeof(FLOAT64));
pUnit_j->pSlope = realloc(pUnit_j->pSlope,(pUnit_j->nWeights + 1)*sizeof(FLOAT64));
pUnit_j->pdWeight = realloc(pUnit_j->pdWeight,(pUnit_j->nWeights + 1)*sizeof(FLOAT64));
pUnit_j->pAxonFrom[pUnit_j->nWeights] = pUnit_i->globalUnitID;
pUnit_j->pWeight[pUnit_j->nWeights] = 2.0*(0.5 - (FLOAT64)rand()/(FLOAT64)RAND_MAX)*pObj->initwrange;
pUnit_j->pdWeight[pUnit_j->nWeights] = 0.0;
pUnit_j->pSlope[pUnit_j->nWeights] = 0.0;
/* Unit i */
pUnit_i->pAxonTo = realloc(pUnit_i->pAxonTo, (pUnit_i->nAxonTo + 1)*sizeof(WTINFO));
pUnit_i->pAxonTo[pUnit_i->nAxonTo].unitID = pUnit_j->globalUnitID;
pUnit_i->pAxonTo[pUnit_i->nAxonTo].weightID = pUnit_j->nWeights;
pUnit_i->nAxonTo++;
pUnit_j->nWeights++;
return EXIT_SUCCESS;
}
UINT32 NetRTRLFeedForward(struct _sNNET *pObj, FLOAT64 *pIn, FLOAT64 *pOut)
{
UINT32 k, i, id;
UNIT * pUnit_i, *pUnit_k;
// Input units (one pattern per training interval)
for (k=0; k < pObj->nIn; k++)
{
id = pObj->pInputID[k];
pObj->pUnit[id].axon = pIn[k];
}
// ************* FEED FORWARD *********************
// Calc net(t+1)
// Hidden Units (update every time step)
for (k=0; k < pObj->nHidden; k++)
{
id = pObj->pHiddenID[k];
pUnit_k = &pObj->pUnit[id];
pUnit_k->net =0.0;
for (i =0; i < pUnit_k->nWeights; i++)
{
pUnit_i = &pObj->pUnit[pUnit_k->pAxonFrom[i]];
pUnit_k->net += pUnit_k->pWeight[i]*pUnit_i->axon;
}
}
// Output units (update every time step)
for (k=0; k < pObj->nOut; k++)
{
id = pObj->pOutputID[k];
pUnit_k = &pObj->pUnit[id];
pUnit_k->net =0.0;
for (i =0; i < pUnit_k->nWeights; i++)
{
pUnit_i = &pObj->pUnit[pUnit_k->pAxonFrom[i]];
pUnit_k->net += pUnit_k->pWeight[i]*pUnit_i->axon;
}
}
/// Axon(t+1)
for (k=0; k < pObj->nUnits; k++)
{
pObj->pUnit[k].lastAxon = pObj->pUnit[k].axon;
if (pObj->pUnit[k].F)
{
pObj->pUnit[k].axon = pObj->pUnit[k].F(pObj->pUnit[k].net);
}
}
for (k=0; k < pObj->nOut; k++)
{
pUnit_k = &pObj->pUnit[pObj->pOutputID[k]];
pOut[k] = pUnit_k->axon;
}
return EXIT_SUCCESS;
}
UINT32 NetRTRL(struct _sNNET *pObj, FLOAT64 *pIn, FLOAT64 *pOut, FLOAT64 *pTarget, FLOAT64 alpha, FLOAT64 eta, UINT32 nPattern, UINT32 trainInterval)
{
UINT32 j, k, i, t, id, p, n, uid_i, uid_j;
UNIT * pUnit_i, *pUnit_j, *pUnit_k, *pUnit_n;
FLOAT64 sum, err;
pObj->sse = 0;
for (p=0; p < nPattern; p++)
{
// Input units (one pattern per training interval)
NetRTRLFeedForward(pObj, &pIn[p*pObj->nIn], &pOut[p*pObj->nOut]);
// delta(t)
for (j=0; j < pObj->nUnits; j++)
{
uid_j = j;
pUnit_j = &pObj->pUnit[uid_j];
for (i=0; i < pObj->nUnits; i++)
{
uid_i = i;
pUnit_i = &pObj->pUnit[uid_i];
for (k=0; k < pObj->nUnits; k++)
{
pUnit_k = &pObj->pUnit[k];
sum = 0.0;
for (n=0; n < pUnit_k->nWeights; n++)
{
pUnit_n = &pObj->pUnit[pUnit_k->pAxonFrom[n]];
sum += pUnit_k->pWeight[n]*pUnit_n->ppRecurrOld[uid_i][uid_j];
}
if (pUnit_k->Fd)
{
if (uid_i == k)
pUnit_k->ppRecurr[uid_i][uid_j] = pUnit_k->Fd(pUnit_k->axon)*(sum+pUnit_j->lastAxon);
else
pUnit_k->ppRecurr[uid_i][uid_j] = pUnit_k->Fd(pUnit_k->axon)*sum;
}
}
}
}
for (k=0; k < pObj->nUnits; k++)
for (i=0; i < pObj->nUnits; i++)
for (j=0; j < pObj->nUnits; j++)
pObj->pUnit[k].ppRecurrOld[i][j] = pObj->pUnit[k].ppRecurr[i][j];
// dW(t)
for (k=0; k < pObj->nOut; k++)
{
pUnit_k = &pObj->pUnit[pObj->pOutputID[k]];
err = pTarget[p*pObj->nOut+k] - pUnit_k->axon;
pUnit_k->error = err;
// pUnit_k->error = log10(fabs((1 + err)/(1 - err)));
// err = log10(fabs((1 + err)/(1 - err)));
pObj->sse += err*err;
for (i=0; i < pObj->nUnits; i++)
{
uid_i = i;
pUnit_i = &pObj->pUnit[i];
for (j=0; j < pUnit_i->nWeights; j++)
{
uid_j = pUnit_i->pAxonFrom[j];
pUnit_j = &pObj->pUnit[uid_j];
pUnit_i->pdWeight[j] += alpha*err*pUnit_k->ppRecurr[uid_i][uid_j] + (1.0-alpha)*pUnit_i->pdWeight[j];
}
}
}
// After training interval adjust Hidden and Output Units
for (i=0; i < pObj->nUnits; i++)
{
pUnit_i = &pObj->pUnit[i];
for (j=0; j < pUnit_i->nWeights; j++)
{
pUnit_i->pWeight[j] += eta*pUnit_i->pdWeight[j];
pUnit_i->pdWeight[j] = 0;
}
}
}
pObj->sse *= 0.5;
return EXIT_SUCCESS;
}
UINT32 NetTrain(struct _sNNET *pObj, FLOAT64 *pIn, FLOAT64 *pOut, FLOAT64 *pTarget, FLOAT64 eta, FLOAT64 alpha, UINT32 len)
{
UINT32 j, k, i, p, n;
UNIT *pUnit_j, *pUnit_k;
FLOAT64 slope;
n=0;
pObj->sse =0.0;
for (p=0; p < len; p++)
{
NetFeedForward(pObj, &pIn[p*(pObj->nIn)], &pOut[n]);
NetBackPropErr(pObj, &pIn[p*(pObj->nIn)], &pTarget[n]);
/* Adjust Hidden and Output Units */
for (k=pObj->nIn+1; k < pObj->nUnits; k++)
{
pUnit_k = &pObj->pUnit[k];
slope = 0.0;
for (i =0; i < pUnit_k->nWeights; i++)
{
j = pUnit_k->pAxonFrom[i];
pUnit_j = &pObj->pUnit[j];
pUnit_k->pdWeight[i] = alpha*pUnit_j->axon*pUnit_k->delta + (1.0-alpha)*pUnit_k->pdWeight[i];
pUnit_k->pWeight[i] += eta*pUnit_k->pdWeight[i];
}
}
n++;
}
pObj->sse *= 0.5;
return EXIT_SUCCESS;
}
UINT32 NetTrain2(struct _sNNET *pObj, FLOAT64 *pIn, FLOAT64 *pOut, FLOAT64 *pError, FLOAT64 eta, FLOAT64 alpha, UINT32 len)
{
UINT32 j, k, i, p, n;
UNIT *pUnit_j, *pUnit_k;
n=0;
for (p=0; p < len; p++)
{
NetBackPropErr2(pObj, &pIn[p*(pObj->nIn)], &pError[n]);
/* Adjust Hidden and Output Units */
for (k=pObj->nIn+1; k < pObj->nUnits; k++)
{
pUnit_k = &pObj->pUnit[k];
for (i =0; i < pUnit_k->nWeights; i++)
{
j = pUnit_k->pAxonFrom[i];
pUnit_j = &pObj->pUnit[j];
pUnit_k->pdWeight[i] = eta*pUnit_j->axon*pUnit_k->delta;
pUnit_k->pWeight[i] += alpha*pUnit_k->pdWeight[i];
}
}
n++;
}
return EXIT_SUCCESS;
}
UINT32 NetFeedForward(struct _sNNET *pObj, FLOAT64 *pIn, FLOAT64 *pOut)
{
UINT32 j, k, m, i;
UNIT *pUnit_j, *pUnit_k, **ppU;
m=0;
/* Input Layer */
for (k=1; k < pObj->nIn+1; k++)
{
pUnit_k = &pObj->pUnit[k];
pUnit_k->axon = pIn[m++];
}
#ifndef COOL_FEEDFORWARD
/* Input, Hidden and Output Layers */
for (k=pObj->pLayer[0].nUnits; k < pObj->nUnits; k++)
{
pUnit_k = &pObj->pUnit[k];
pUnit_k->net =0.0;
for (i =0; i < pUnit_k->nWeights; i++)
{
j = pUnit_k->pAxonFrom[i];
pUnit_j = &pObj->pUnit[j];
pUnit_k->net += pUnit_k->pWeight[i]*pUnit_j->axon;
}
pUnit_k->axon = pUnit_k->F(pUnit_k->net);
}
#else
#pragma message ("nnet.c: Using cool feed forward computing.")
/********************************************************/
/* TEST: don't care for layer organization */
/********************************************************/
for (i=0; i < pObj->nUnits; i++)
pObj->pUnit[i].net = 0.0;
for (j=0; j < pObj->nUnits; j++)
{
pUnit_j = &pObj->pUnit[j];
if (pUnit_j->F)
pUnit_j->axon = pUnit_j->F(pUnit_j->net);
for (i=0; i < pUnit_j->nAxonTo; i++)
{
k = pUnit_j->pAxonTo[i].unitID;
wid = pUnit_j->pAxonTo[i].weightID;
pUnit_k = &pObj->pUnit[k];
pUnit_k->net += pUnit_k->pWeight[wid]*pUnit_j->axon;
}
}
#endif
/********************************************************/
ppU = pObj->pLayer[pObj->nLayers-1].ppUnit;
for (j = 0; j < pObj->nOut; j++)
{
pOut[j] = (*ppU)->axon;
ppU++;
}
return EXIT_SUCCESS;
}
UINT32 NetBackPropErr(struct _sNNET *pObj, FLOAT64 *pIn, FLOAT64 *pTarget)
{
UINT32 j, k, i, target, numLayers, layer;
UNIT **ppUnit_j, **ppUnit_k, *pUnit_j, *pUnit_k;
FLOAT64 err;
numLayers = pObj->nLayers;
/* Zero Errors of all units */
for (j = pObj->pLayer[0].nUnits; j < pObj->nUnits; j++)
{
pObj->pUnit[j].error = 0;
}
/* Calc Error Output Layer */
target=0;
ppUnit_j = pObj->pLayer[numLayers-1].ppUnit;
for (j=0; j < pObj->pLayer[numLayers-1].nUnits; j++)
{
pUnit_j = *(ppUnit_j++);
err = pTarget[target++] - pUnit_j->axon;
pUnit_j->error = log10(fabs((1 + err)/(1 - err)));
pUnit_j->delta = pUnit_j->error*pUnit_j->Fd(pUnit_j->axon);
pObj->sse += err*err;
}
#ifndef COOL_BACKPROP
/* Calc Error Hidden Layer */
for (layer = numLayers-1; layer > 1; layer--)
{
ppUnit_k = pObj->pLayer[layer].ppUnit;
for (k =0; k < pObj->pLayer[layer].nUnits; k++)
{
pUnit_k = *(ppUnit_k++);
for (i=1; i < pUnit_k->nWeights; i++)
{
j = pUnit_k->pAxonFrom[i];
pUnit_j = &pObj->pUnit[j];
if (pUnit_j->UType == UTYPE_HIDDEN)
{
pUnit_k->pSlope[j] += pUnit_k->delta*pUnit_k->axon;
pUnit_j->error += pUnit_k->pWeight[i]*pUnit_k->delta;
pUnit_j->delta = pUnit_j->error*pUnit_j->Fd(pUnit_j->axon);
}
}
}
}
#else
#pragma message ("nnet.c: Using cool error back propagation.")
#error ("nnet.c: Implement cool error back propagation.")
#endif
return EXIT_SUCCESS;
}
UINT32 NetBackPropErr2(struct _sNNET *pObj, FLOAT64 *pIn, FLOAT64 *pError)
{
UINT32 j, k, i, error, numLayers, layer;
UNIT **ppUnit_j, **ppUnit_k, *pUnit_j, *pUnit_k;
FLOAT64 err;
numLayers = pObj->nLayers;
/* Zero Errors of all units */
for (j = pObj->pLayer[0].nUnits; j < pObj->nUnits; j++)
{
pObj->pUnit[j].error = 0;
}
/* Calc Error Output Layer */
pObj->sse =0.0;
error=0;
ppUnit_j = pObj->pLayer[numLayers-1].ppUnit;
for (j=0; j < pObj->pLayer[numLayers-1].nUnits; j++)
{
pUnit_j = *(ppUnit_j++);
err = pError[error++];
pUnit_j->error = log10(fabs((1 + err)/(1 - err)));
pUnit_j->delta = pUnit_j->error*pUnit_j->Fd(pUnit_j->axon);
pObj->sse += err*err;
}
/* Calc Error Hidden Layer */
for (layer = numLayers-1; layer > 1; layer--)
{
ppUnit_k = pObj->pLayer[layer].ppUnit;
for (k =0; k < pObj->pLayer[layer].nUnits; k++)
{
pUnit_k = *(ppUnit_k++);
for (i=1; i < pUnit_k->nWeights; i++)
{
j = pUnit_k->pAxonFrom[i];
pUnit_j = &pObj->pUnit[j];
pUnit_j->error += pUnit_k->pWeight[i]*pUnit_k->delta;
pUnit_j->delta = pUnit_j->error*pUnit_j->Fd(pUnit_j->axon);
}
}
}
return EXIT_SUCCESS;
}
UINT32 NetWeightUpd(struct _sNNET *pObj, FLOAT64 *pIn, UINT32 len)
{
return EXIT_SUCCESS;
}
UINT32 UnitFree(struct _sUNIT *pObj)
{
return EXIT_SUCCESS;
}
void* nnMalloc(void *pBuffer, UINT32 size)
{
if (pBuffer == NULL)
pBuffer = malloc(size);
else
pBuffer = NULL;
return pBuffer;
}
void* nnFree(void *pBuffer)
{
if (pBuffer != NULL)
free(pBuffer);
pBuffer = NULL;
return pBuffer;
}
/*************************************************************************/
#define K_SIGM 1.0
#define K_TANH 1.0
FLOAT64 Sigmoid(FLOAT64 x)
{
return 1.0 / (1.0 + exp(-K_SIGM*x));
}
FLOAT64 dSigmoid(FLOAT64 x)
{
return x*(1.0-x);
}
FLOAT64 Linear(FLOAT64 x)
{
return x;
}
FLOAT64 dLinear(FLOAT64 x)
{
return 1;
}
FLOAT64 Tanh2(FLOAT64 x)
{
FLOAT64 e1 = exp(2*K_TANH*x);
e1 = (e1-1.0)/(e1+1.0);
return e1;
}
FLOAT64 dTanh2(FLOAT64 x)
{
FLOAT64 e1 = exp(2*K_TANH*x);
FLOAT64 e11 = e1+1.0;
return 4*K_TANH*e1 / (e11*e11);
}
FLOAT64 ASigmoid(FLOAT64 x)
{
return 1.0 / (1.0 + exp(-K_SIGM*x));
}
FLOAT64 SSigmoid(FLOAT64 x)
{
return - 0.5 + 1.0 / (1.0 + exp(-x));
}
FLOAT64 dSSigmoid(FLOAT64 x)
{
FLOAT64 e1 = exp(K_SIGM*x);
FLOAT64 e11 = 1.0 + e1;
return K_SIGM*e1 / (e11*e11);
}
FLOAT64 FSigmoid(FLOAT64 x)
{
FLOAT64 kx = K_SIGM*x;
return kx / (1.0 + fabs(kx));
}
FLOAT64 dFSigmoid(FLOAT64 x)
{
return fabs(x*(1.0-x));
}
FLOAT64 dTanh(FLOAT64 x)
{
return 1.0-x*x;
}
FLOAT64 NullFunc(FLOAT64 x)
{
return 0;
}
/**************************************************************************/
Executable
+113
View File
@@ -0,0 +1,113 @@
/**********************************************************************
* nnet.h
*
* (C) 2000 J. Ahrensfeld
*
**********************************************************************/
#ifndef NNET_H
#define NNET_H
#define UTYPE_BIAS 0
#define UTYPE_INPUT 1
#define UTYPE_HIDDEN 2
#define UTYPE_OUTPUT 3
#define UNIT_ID_INPUT (-UTYPE_INPUT)
#define UNIT_ID_OUTPUT (-UTYPE_OUTPUT)
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
#ifndef M_E
#define M_E 2.71828182845904523536028747135266
#endif
enum
{
NNTYPE_MLP = 0,
NNTYPE_RECURRENT
};
/**********************************************************************/
typedef struct _sWTINFO
{
UINT32 unitID, weightID;
} WTINFO;
typedef struct _sUNIT
{
UINT32 nWeights, nAxonTo, *pAxonFrom, UType, FType, globalUnitID, layerID, unitID;
WTINFO *pAxonTo;
FLOAT64 axon, lastAxon, *pWeight, *pdWeight, net, error, delta, *pSlope;
FLOAT64 (*F)(FLOAT64); /* Zeiger auf Aktivierungsfunktion */
FLOAT64 (*Fd)(FLOAT64); /* Zeiger auf Ableitungsfunktion */
FLOAT64 **ppRecurr, **ppRecurrOld;
} UNIT;
typedef struct _sLAYER
{
UINT32 nUnits, ID;
UNIT **ppUnit;
} LAYER;
typedef struct _sNNET
{
UINT32 nLayers, nUnits, nnType, ID, nIn, nOut, nHidden;
struct _sLAYER *pLayer;
struct _sUNIT *pUnit;
UINT32 *pInputID, *pHiddenID, *pOutputID;
FLOAT64 sse, initwrange;
} NNET;
enum
{
Null, Lin, Tanh, ASig, Sig, SSig, FSig
};
UINT32 NetInit(struct _sNNET *pObj, struct _sNETFILE *pNetData, UINT32 netID);
UINT32 NetAddUnit(struct _sNNET *pObj, UINT32 unitType, UINT32 FType);
UINT32 NetAddConnection(struct _sNNET *pObj, UINT32 ID_i, UINT32 ID_j);
UINT32 NetFeedForward(struct _sNNET *pObj, FLOAT64 *pIn, FLOAT64 *pOut);
UINT32 NetBackPropErr(struct _sNNET *pObj, FLOAT64 *pIn, FLOAT64 *pTarget);
UINT32 NetBackPropErr2(struct _sNNET *pObj, FLOAT64 *pIn, FLOAT64 *pError);
UINT32 NetWeightUpd(struct _sNNET *pObj, FLOAT64 *pIn, UINT32 len);
UINT32 NetTrain(struct _sNNET *pObj, FLOAT64 *pIn, FLOAT64 *pOut, FLOAT64 *pTarget, FLOAT64 eta, FLOAT64 alpha, UINT32 len);
UINT32 NetTrain2(struct _sNNET *pObj, FLOAT64 *pIn, FLOAT64 *pOut, FLOAT64 *pError, FLOAT64 eta, FLOAT64 alpha, UINT32 len);
UINT32 NetRTRL(struct _sNNET *pObj, FLOAT64 *pIn, FLOAT64 *pOut, FLOAT64 *pTarget, FLOAT64 eta, FLOAT64 alpha, UINT32 nPattern, UINT32 trainInterval);
UINT32 NetWire(struct _sNNET *pObj, UINT32 nnType);
UINT32 NetFree(struct _sNNET *pObj);
void NetPrint(struct _sNNET *pObj);
UINT32 LayerInit(struct _sLAYER *pObj, struct _sUNIT *pUnit, UINT32 nUnits, UINT32 LayID);
UINT32 LayerFree(struct _sLAYER *pObj);
UINT32 UnitInit(struct _sUNIT *pObj, UINT32 type, UINT32 FType, UINT32 ID);
UINT32 UnitSetFunc(struct _sUNIT *pObj, UINT32 FuncType);
UINT32 UnitFree(struct _sUNIT *pObj);
/* Wrapper functions */
void* nnMalloc(void *pBuffer, UINT32 size);
void* nnFree(void *pBuffer);
/* Activation Functions */
FLOAT64 Func(FLOAT64 x);
FLOAT64 dFunc(FLOAT64 x);
FLOAT64 Linear(FLOAT64 x);
FLOAT64 dLinear(FLOAT64 x);
FLOAT64 Tanh2(FLOAT64 x);
FLOAT64 dTanh2(FLOAT64 x);
FLOAT64 ASigmoid(FLOAT64 x);
FLOAT64 SSigmoid(FLOAT64 x);
FLOAT64 dSSigmoid(FLOAT64 x);
FLOAT64 Sigmoid(FLOAT64 x);
FLOAT64 dSigmoid(FLOAT64 x);
FLOAT64 FSigmoid(FLOAT64 x);
FLOAT64 dFSigmoid(FLOAT64 x);
FLOAT64 dTanh(FLOAT64 x);
FLOAT64 NullFunc(FLOAT64 x);
#endif
Executable
+440
View File
@@ -0,0 +1,440 @@
/**********************************************************************
* netfile.c
*
* (C) 2000 J. Ahrensfeld
*
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nntypes.h"
#include "nnet.h"
#include "nnfile.h"
/**********************************************************************/
#define VERSION "0.1"
#define MAX_TOKENS 15
#define MAX_NEURON_TYPES 6
/**********************************************************************/
char *pszNNtypeList[] =
{
"MLP", "RECURRENT", 0
};
char *pszTokenList[]=
{
"NINPUTS","NOUTPUTS","NHIDDENLAYERS","NHIDDENNEURONS","HIDDENTYPE","OUTPUTTYPE",
"TRAINING","LEARNINGRATE","MOMENTUM","ERRORTHRESHOLD","MAXEPOCHS","REPORTUPDATE",
"MAXPATTERNS", "INITWEIGHTRANGE", "NNTYPE", 0
};
char *pszNeuronTypeList[]=
{
"NULL", "LINEAR", "TANH", "ASIGMOID", "SIGMOID", "SSIGMOID", "FSIGMOID", 0
};
enum Token
{
NINPUTS, NOUTPUTS, NHIDDENLAYERS, NHIDDENNEURONS, HIDDENTYPE, OUTPUTTYPE,
TRAINING, LEARNINGRATE, MOMENTUM, ERRORTHRESHOLD, MAXEPOCHS, REPORTUPDATE,
MAXPATTERNS, INITWEIGHTRANGE, NNTYPE, NOTFOUND
};
/**********************************************************************/
int ReadNextToken(FILE *pFile, char *pToken)
{
int i, res=EXIT_FAILURE;
while(!feof(pFile))
{
fscanf(pFile,"%s",pToken);
if((pToken[0]=='#') || (pToken[0] < '0'))
continue;
res = EXIT_SUCCESS;
for (i=0; pToken[i]; i++)
pToken[i]=toupper(pToken[i]);
break;
}
return res;
}
int ReadValue(FILE *pFile, char* szValue)
{
int i;
szValue[0] = 0;
fscanf(pFile,"%s",szValue);
for (i=0; szValue[i]; i++)
szValue[i]=toupper(szValue[i]);
return 0;
}
int Seek(FILE *pFile, char **pTokenList, int nMaxToken, int *RetToken)
{
char szToken[256];
int nToken=0, res = EXIT_FAILURE, status=EXIT_SUCCESS;
*RetToken = NOTFOUND;
while ((status == EXIT_SUCCESS) && (*RetToken == NOTFOUND))
{
status=ReadNextToken(pFile,szToken);
for (nToken=0; nToken < nMaxToken; nToken++)
{
if(strcmp(szToken,pszTokenList[nToken]))
continue;
//cout << "Token(" << nToken << "): " << szToken << endl;
*RetToken = nToken;
res = EXIT_SUCCESS;
break;
}
}
return res;
}
int ReadNetFile(char* szFileName, NETFILE *NetData)
{
char szValue[80], szToken[256];
FILE *pFile;
UINT32 pos;
NETFILE net;
UINT32 Token, t, status, i, error;
UINT32 layer, neurons, neuronType;
UINT32 size, p;
/***************************************************************************/
// INIT
net.nInputs = 0;
net.nOutputs = 0;
net.nHiddenLayers = 0;
net.nHiddenNeurons = 0;
net.nTrainingSets = 0;
net.LearningRate = 0.4;
net.Momentum = 0.8;
net.ErrorThreshold = 0;
net.MaxEpochs = 25000;
net.reportUpd = 100;
net.maxPatterns = 1000000;
net.initwrange = 1.0;
net.nntype = NNTYPE_MLP;
/***************************************************************************/
error = EXIT_FAILURE;
while(1)
{
/***************************************************************************/
/* Datei oeffnen */
/***************************************************************************/
printf("Lese Datei %s\n",szFileName);
pFile = fopen(szFileName,"r");
if (pFile==NULL)
{
printf("Die Datei %s konnte nicht geöffnet werden.\n",szFileName);
break;
}
/***************************************************************************/
/* Erwarte "net"-Identifier */
/***************************************************************************/
ReadNextToken(pFile, szToken);
pos = ftell(pFile);
if (!strcmp(szToken,"NET"))
printf("%s\n",szToken);
else
{
printf("ERROR: Missing NET-identifier\n");
break;
}
/***************************************************************************/
/* Inputs, Outputs, Layer */
/***************************************************************************/
pos=fseek(pFile, 0, SEEK_SET);
status = 0;
Token = NOTFOUND;
while ((net.nInputs*net.nOutputs*net.nHiddenLayers)==0 && !status)
{
status=Seek(pFile,pszTokenList, MAX_TOKENS, &Token);
switch (Token)
{
case NNTYPE:
net.nntype = NNTYPE_MLP;
ReadValue(pFile, szValue);
i=0;
while(pszNNtypeList[i])
{
if(!strcmp(szValue, pszNNtypeList[i]))
{
net.nntype = i;
break;
}
i++;
}
printf("Neural Net type is %s\n",pszNNtypeList[net.nntype]);
break;
case NINPUTS:
ReadValue(pFile, szValue);
net.nInputs = atoi(szValue);
printf("nInputs = %d\n",net.nInputs);
break;
case NOUTPUTS:
ReadValue(pFile, szValue);
net.nOutputs = atoi(szValue);
printf("nOutputs = %d\n",net.nOutputs);
break;
case NHIDDENLAYERS:
ReadValue(pFile, szValue);
net.nHiddenLayers = atoi(szValue);
printf("nHiddenLayers = %d\n",net.nHiddenLayers);
break;
default:
break;
}
}
if(status == EXIT_FAILURE)
{
printf("Invalid file Inputs, Outputs, Layer!\n");
break;
}
/***************************************************************************/
/* Layer Organization */
/***************************************************************************/
pos=fseek(pFile, 0, SEEK_SET);
t = 0;
status = 0;
Token = NOTFOUND;
while (t < net.nHiddenLayers && !status )
{
status = Seek(pFile,pszTokenList, MAX_TOKENS, &Token);
if ((Token != NHIDDENNEURONS) && !feof(pFile))
continue;
{
ReadValue(pFile, szValue);
layer = atoi(szValue);
ReadValue(pFile, szValue);
neurons = atoi(szValue);
printf("HiddenLayer[%d]: %d Neurons\n",layer,neurons);
net.LInfo[layer].nNeurons = neurons;
net.nHiddenNeurons += neurons;
t++;
}
}
printf("Total number of Hidden Neurons = %d\n",net.nHiddenNeurons);
if(status == EXIT_FAILURE)
{
printf("Invalid Layer Organization!\n");
break;
}
/***************************************************************************/
/* NeuronType */
/***************************************************************************/
pos=fseek(pFile, 0, SEEK_SET);
for (layer=0; layer <net.nHiddenLayers; layer++)
net.LInfo[layer].NeuronType = Tanh;
while (!feof(pFile))
{
status=0;
Token = NOTFOUND;
status=Seek(pFile,pszTokenList, MAX_TOKENS, &Token);
switch (Token)
{
case HIDDENTYPE:
ReadValue(pFile, szValue);
layer = atoi(szValue);
ReadValue(pFile, szValue);
for (neuronType=0; neuronType < MAX_NEURON_TYPES; neuronType++)
{
if(!strcmp(szValue,pszNeuronTypeList[neuronType]))
break;
}
if (neuronType==MAX_NEURON_TYPES)
neuronType = Sig;
printf("HiddenType[%d] = %s (%d)\n",layer,szValue,neuronType);
net.LInfo[layer].NeuronType = neuronType;
break;
case OUTPUTTYPE:
ReadValue(pFile, szValue);
for (net.OutType=0; net.OutType < MAX_NEURON_TYPES; net.OutType++)
{
if(!strcmp(szValue,pszNeuronTypeList[net.OutType]))
break;
}
if (net.OutType==MAX_NEURON_TYPES)
net.OutType = Tanh;
printf("Output Type = %s (%d)\n",szValue,net.OutType);
break;
}
}
net.LInfo[0].NeuronType = 0;
net.LInfo[0].nNeurons = net.nInputs;
net.LInfo[net.nHiddenLayers+1].NeuronType = net.OutType;
net.LInfo[net.nHiddenLayers+1].nNeurons = net.nOutputs;
/***************************************************************************/
/* Parameter */
/***************************************************************************/
pos=fseek(pFile, 0, SEEK_SET);
while (!feof(pFile))
{
status=0;
Token = NOTFOUND;
status=Seek(pFile,pszTokenList, MAX_TOKENS, &Token);
switch(Token)
{
case LEARNINGRATE:
ReadValue(pFile, szValue);
net.LearningRate = atof(szValue);
printf("Learning Rate = %g\n",net.LearningRate);
break;
case MOMENTUM:
ReadValue(pFile, szValue);
net.Momentum = atof(szValue);
printf("Momentum = %g\n",net.Momentum);
break;
case ERRORTHRESHOLD:
ReadValue(pFile, szValue);
net.ErrorThreshold = atof(szValue);
printf("Error Threshold = %g\n",net.ErrorThreshold);
break;
case MAXEPOCHS:
ReadValue(pFile, szValue);
net.MaxEpochs = atoi(szValue);
printf("Max. Epochs = %d\n",net.MaxEpochs);
break;
case REPORTUPDATE:
ReadValue(pFile, szValue);
net.reportUpd = atoi(szValue);
printf("Report every %d epoch\n",net.reportUpd);
break;
case MAXPATTERNS:
ReadValue(pFile, szValue);
net.maxPatterns = atoi(szValue);
printf("Read max. %d patterns\n",net.maxPatterns);
break;
case INITWEIGHTRANGE:
ReadValue(pFile, szValue);
net.initwrange = (double)atof(szValue);
printf("Init weight range = +/- %2.2g\n",net.initwrange);
break;
default:
break;
}
}
/***************************************************************************/
/* Training Data */
/***************************************************************************/
pos=fseek(pFile, 0, SEEK_SET);
status=0;
Token = NOTFOUND;
while (Token != TRAINING && !status )
status=Seek(pFile,pszTokenList, MAX_TOKENS, &Token);
if(status == EXIT_FAILURE)
{
printf("No Training Data found.\n");
break;
}
status = 0;
/* Count number of Patterns */
while (!status)
{
for (i=0; i < net.nInputs; i++)
status=ReadValue(pFile, szValue);
if (szValue[0] < ' ') break;
for (i=0; i < net.nOutputs; i++)
status=ReadValue(pFile, szValue);
if (szValue[0] < ' ') break;
net.nTrainingSets++;
}
if(net.nTrainingSets == 0)
{
printf("Missing Training Data!\n");
break;
}
if(net.maxPatterns < net.nTrainingSets)
net.nTrainingSets = net.maxPatterns;
/* Alloc mem */
size = net.nInputs*net.nTrainingSets;
net.pInput = (FLOAT64*)malloc(size*sizeof(FLOAT64));
size = net.nOutputs*net.nTrainingSets;
net.pTarget = (FLOAT64*)malloc(size*sizeof(FLOAT64));
/* Read training data */
pos=fseek(pFile, 0, SEEK_SET);
status=0;
Token = NOTFOUND;
while (Token != TRAINING && !status )
status=Seek(pFile,pszTokenList, MAX_TOKENS, &Token);
for (p=0; p < net.nTrainingSets; p++)
{
for (i=0; i < net.nInputs; i++)
{
status=ReadValue(pFile, szValue);
net.pInput[i+p*net.nInputs]= atof(szValue);
}
if (szValue[0] < ' ') break;
for (i=0; i < net.nOutputs; i++)
{
status=ReadValue(pFile, szValue);
net.pTarget[i+p*net.nOutputs]= atof(szValue);
}
if (szValue[0] < ' ') break;
}
error = EXIT_SUCCESS;
break;
}
printf("Number of Training Sets = %d\n",net.nTrainingSets);
/******************************************************************************/
fclose(pFile);
*NetData = net;
return error;
}
/******************************************************************************/
Executable
+37
View File
@@ -0,0 +1,37 @@
/**********************************************************************
* netfile.h
*
* (C) 2000 J. Ahrensfeld
*
**********************************************************************/
#ifndef NNFILE_H
#define NNFILE_H
#include "nntypes.h"
typedef struct _sLayerInfo
{
int nNeurons, NeuronType;
} LayerInfo;
typedef struct _sNETFILE
{
UINT32 nInputs, nOutputs, nHiddenNeurons, nHiddenLayers, nTrainingSets, OutType;
UINT32 MaxEpochs, reportUpd, maxPatterns, nntype;
LayerInfo LInfo[64];
double *pInput;
double *pTarget;
double LearningRate, Momentum, ErrorThreshold, initwrange;
} NETFILE;
int ReadNetFile(char* szFileName, NETFILE *NInfo);
#endif /* NNFILE_H */
Executable
+245
View File
@@ -0,0 +1,245 @@
/**********************************************************************
* nntiff.c
*
* (C) 2000 J. Ahrensfeld
*
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "nntypes.h"
#include "nnet.h"
#include "nntiff.h"
#include "tiffio.h"
#define TIFF_FILENAME "test"
#define TIFF_PASS_WIDTH 200
#define TIFF_PASS_HEIGHT 200
#define TIFF_NUM_FRAMES 1
/**********************************************************************/
UINT32 CpyChar2Dbl(double *pDoubleArr, UINT8 *pCharArr, UINT32 nChars)
{
UINT32 i;
for (i=0; i <nChars; i++)
pDoubleArr[i] = (double)pCharArr[i];
return i;
}
UINT32 CpyDbl2Char(UINT8 *pCharArr, double *pDoubleArr, UINT32 nDoubles)
{
UINT32 i;
for (i=0; i <nDoubles; i++)
pCharArr[i] = (UINT8)(fabs(pDoubleArr[i])*0xFF);
return i;
}
double dmax(double v1, double v2)
{
if (v1 > v2)
return v1;
else
return v2;
}
void Normalize(double *pBuffer, double normVal, UINT32 len)
{
UINT32 i;
double maxVal = normVal;
for (i=0; i <len; i++)
maxVal = dmax(maxVal, pBuffer[i]);
for (i=0; i <len; i++)
pBuffer[i] = normVal * pBuffer[i] / maxVal;
}
void SwapRowCol(UINT8 *pBuffer, UINT32 width, UINT32 height)
{
UINT32 row, col;
UINT8 *pNewBuf = (UINT8*)_TIFFmalloc(width*height);
for (row=0; row <height; row++)
{
for (col=0; col <width; col++)
pNewBuf[width*col+row] = pBuffer[col+row*width];
}
_TIFFmemcpy(pBuffer, pNewBuf, width*height);
_TIFFfree(pNewBuf);
}
void ViewAlign(UINT8 **ppBuffer, UINT32 width, UINT32 height)
{
UINT8 temp;
UINT32 col, row;
UINT8 *pTemp = (UINT8*)_TIFFmalloc(width);
for (row=0; row <height; row++)
{
for (col=0; col <width/2; col++)
{
temp = ppBuffer[row][col];
ppBuffer[row][col] = ppBuffer[row][col+width/2];
ppBuffer[row][col+width/2] = temp;
}
}
for (row=0; row <height/2; row++)
{
_TIFFmemcpy(pTemp, ppBuffer[row+height/2], width);
_TIFFmemcpy(ppBuffer[row+height/2], ppBuffer[row], width);
_TIFFmemcpy(ppBuffer[row], pTemp, width);
}
ppBuffer[height/2][width/2] /= 2;
_TIFFfree(pTemp);
}
UINT32 TiffOutInit(TIFFOUT *pObj)
{
pObj->frameCnt=0;
return EXIT_SUCCESS;
}
UINT32 TiffOut(TIFFOUT *pObj, NNET *pNet)
{
TIFF *pTifOut;
ttag_t config, nBits, nSamples, photometric;
UINT8 *pLineBuf;
UINT32 width, height, tx, ty;
INT32 status, ci;
char tiffName[100], framenum[8];
FLOAT64 *pIn, *pOut, xVal, yVal;
pLineBuf = NULL;
pLineBuf = (char*)_TIFFmalloc(TIFF_PASS_WIDTH*sizeof(UINT8));
pIn = (double*) malloc(pNet->nIn*sizeof(double));
pOut = (double*) malloc(TIFF_PASS_HEIGHT*pNet->nOut*sizeof(double));
if (pNet->nIn == 2)
{
photometric = PHOTOMETRIC_MINISBLACK;
width = 200;
height = 200;
config = PLANARCONFIG_CONTIG;
nBits = 8;
nSamples = 1;
sprintf(framenum,"%4d",pObj->frameCnt);
ci=0;
while (framenum[ci])
{
if(framenum[ci]==0x20)
framenum[ci]=0x30;
ci++;
}
sprintf(tiffName,"%s%s.tiff",TIFF_FILENAME,framenum);
pTifOut = TIFFOpen(tiffName,"w");
status = TIFFSetField(pTifOut, TIFFTAG_IMAGEWIDTH, TIFF_PASS_WIDTH);
status = TIFFSetField(pTifOut, TIFFTAG_IMAGELENGTH, TIFF_PASS_HEIGHT);
status = TIFFSetField(pTifOut, TIFFTAG_PLANARCONFIG, config);
status = TIFFSetField(pTifOut, TIFFTAG_PHOTOMETRIC, photometric);
status = TIFFSetField(pTifOut, TIFFTAG_BITSPERSAMPLE, nBits);
status = TIFFSetField(pTifOut, TIFFTAG_SAMPLESPERPIXEL, nSamples);
status = TIFFSetField(pTifOut, TIFFTAG_ORIENTATION, 1);
}
for (ty=0; ty < TIFF_PASS_HEIGHT; ty++)
{
yVal = (FLOAT64)ty / TIFF_PASS_WIDTH;
for (tx=0; tx < TIFF_PASS_WIDTH; tx++)
{
xVal = (FLOAT64)tx / TIFF_PASS_WIDTH;
pIn[0] = xVal;
pIn[1] = yVal;
NetFeedForward(pNet, pIn, &pOut[tx]);
}
Normalize(pOut, 1.0, TIFF_PASS_WIDTH);
CpyDbl2Char(pLineBuf, pOut, TIFF_PASS_WIDTH);
status = TIFFWriteScanline(pTifOut, pLineBuf, ty, 0);
}
printf("Write frame %d\n",pObj->frameCnt++);
TIFFClose(pTifOut);
if (pLineBuf)
_TIFFfree(pLineBuf);
if (pIn)
free(pIn);
if (pOut)
free(pOut);
return EXIT_SUCCESS;
}
Executable
+13
View File
@@ -0,0 +1,13 @@
/**********************************************************************
* nntiff.h
*
* (C) 2000 J. Ahrensfeld
*
**********************************************************************/
typedef struct _sTIFFOUT
{
UINT32 frameCnt;
} TIFFOUT;
UINT32 TiffOutInit(TIFFOUT *pObj);
UINT32 TiffOut(TIFFOUT *pObj, NNET *pNet);
Executable
+40
View File
@@ -0,0 +1,40 @@
/**********************************************************************
* nntypes.h
*
* (C) 2000 J. Ahrensfeld
*
**********************************************************************/
#ifndef _NNTYPES_H
#define _NNTYPES_H
#if defined(_WIN32) || defined(WIN32)
/* Win32 data types */
#include <windows.h>
#define INT8 char
#define INT16 short
#define INT32 long
#define UINT8 unsigned char
#define UINT16 unsigned short
#define UINT32 unsigned long
/* INT and UINT are defined in windef.h */
#define FLOAT32 float
#define FLOAT64 double
#elif defined(__linux__)
#if defined(__i386__)
/* linux x86 data types */
#define INT8 char
#define INT16 short
#define INT32 long
#define UINT8 unsigned char
#define UINT16 unsigned short
#define UINT32 unsigned long
#define INT int
#define UINT unsigned int
#define FLOAT32 float
#define FLOAT64 double
#endif
#endif
#endif