📄 int.c
字号:
/* *********************************************************** */
/* file int.c: Contains the network evaluation and weight */
/* adjustment procedures for the integer versions */
/* bp and sbp. */
/* */
/* Copyright (c) 1993 by Donald R. Tveter */
/* */
/* *********************************************************** */
#ifdef INTEGER
#include "ibp.h"
#else
#include "rbp.h"
#endif
extern char deriv, whittled, wtlimithit, zeroderiv;
extern char outstr[OUTSTRSIZE];
extern WTTYPE alpha, decay, eta, eta2, etamax, kappa, qpeta;
extern WTTYPE qpnoise, mu, noise, theta1, theta2, toler;
extern WTTYPE rpaccel, rpdecay, rpinitial, rpdeltamax, rpdeltamin;
extern WTTYPE ssaccel, ssdecay, sseta, ssetamax, ssmo;
extern char qpslope;
extern LAYER *last, *start;
extern INT32 totaldiff;
extern REAL qpdecayh, qpdecayo;
extern REAL unscale();
#ifdef LOOKUP
extern WTTYPE sigmoid[];
#endif
void forward() /* computes unit activations */
{
register INT32 sum;
register WTNODE *w;
register UNIT *predu, *u;
LAYER *layer;
register INT32 x, intpart;
register short fract, val;
char actfun;
WTTYPE D;
int denom;
double rsum;
layer = start->next;
while (layer != NULL)
{
actfun = layer->activation;
D = layer->D;
u = (UNIT *) layer->units;
while (u != NULL)
{
sum = 0;
w = (WTNODE *) u->wtlist;
while (w != NULL)
{
predu = (UNIT *) w->backunit;
#ifdef SYMMETRIC
sum = sum + (INT32) *(w->weight) * predu->oj / 1024;
#else
sum = sum + (INT32) w->weight * predu->oj / 1024;
#endif
w = w->next;
};
sum = D * sum / 1024;
#ifdef LOOKUP
if (actfun == 's')
{
if (sum >= 0)
{
if (sum >= 7808)
{
u->oj = 1024;
zeroderiv = 1;
}
else u->oj = sigmoid[sum];
}
else
{
if (sum <= -7808)
{
u->oj = 0;
zeroderiv = 1;
}
else u->oj = 1024 - sigmoid[-sum];
};
}
#else
if (actfun == 's')
{
rsum = ((double) sum) / 1024.0;
rsum = 1.0 / (1.0 + exp(-rsum));
u->oj = (WTTYPE) (rsum * 1024.0 + 0.5);
}
#endif
else if (actfun == 'l') u->oj = sum;
u = u->next;
};
layer = layer->next;
};
}
short backoutput() /* computes weight changes from the output layer */
{
register short deltaj, temp2, temp3, D;
register INT32 temp;
register UNIT *bunit, *u;
register WTNODE *w;
register short adiff, notclose;
PATLIST *pl;
PATNODE *target;
char actfun;
actfun = last->activation;
D = last->D;
notclose = last->unitcount;
u = (UNIT *) last->units;
pl = last->currentpat[TRAIN];
target = pl->pats;
while (u != NULL)
{
temp3 = u->oj;
temp2 = target->val - temp3;
target++;
if (temp2 > 0) adiff = temp2; else adiff = -temp2;
if (adiff < toler) notclose = notclose - 1;
totaldiff = totaldiff + adiff;
if (deriv == 'd') deltaj = temp2;
else if (deriv == 'f')
switch (actfun) {
case 'l': deltaj = temp2 + 102;
break;
case 's': temp = (INT32) temp2 *
((INT32) 104448 + (INT32) temp3 * ((short)(1024 - temp3)));
if (temp > 0) deltaj = (INT32) (temp + 524288) >> 20;
else deltaj = -((INT32) (524288 - temp) >> 20);
break;}
else /* the derivative in the original formula */
switch (actfun) {
case 'l': deltaj = temp2;
break;
case 's': temp = (INT32) temp2 *
((INT32) temp3 * ((short)(1024 - temp3)));
if (temp > 0) deltaj = (INT32) (temp + 524288) >> 20;
else deltaj = -((INT32) (524288 - temp) >> 20);
break;}
w = (WTNODE *) u->wtlist;
#ifdef SYMMETRIC
while (w->next != NULL) /* skips threshold unit at end */
#else
while (w != NULL)
#endif
{
bunit = (UNIT *) w->backunit;
#ifdef SYMMETRIC
*(w->total) = *(w->total) + (INT32) deltaj * bunit->oj;
#else
w->total = w->total + (INT32) deltaj * bunit->oj;
if (bunit->layernumber > 1)
bunit->error = bunit->error + (INT32) deltaj * w->weight;
#endif
w = w->next;
};
u = u->next;
};
return(notclose);
}
#ifndef SYMMETRIC
void backinner() /* Computes slopes and passes back */
{ /* errors from hidden layers. */
register short deltaj, temp3;
register INT32 temp;
register WTTYPE D;
register UNIT *bunit, *u;
register WTNODE *w;
char actfun;
LAYER *layer;
layer = last->backlayer;
while (layer->backlayer != NULL)
{
actfun = layer->activation;
D = layer->D;
u = (UNIT *) layer->units;
while (u != NULL)
{
temp3 = u->oj;
switch (actfun) {
case 'l': deltaj = u->error;
break;
case 's': temp = (INT32) ((short)(((INT32) temp3 *
((short)(1024-temp3))+512) >> 10)) * u->error;
if (temp > 0) deltaj = (INT32) (temp + 524288) >> 20;
else deltaj = -((INT32) (524288 - temp) >> 20);
break;}
w = (WTNODE *) u->wtlist;
while (w != NULL)
{
bunit = (UNIT *) w->backunit;
w->total = w->total + (INT32) deltaj * bunit->oj;
if (bunit->layernumber > 1)
bunit->error = bunit->error + (INT32) deltaj * w->weight;
w = w->next;
};
u = u->next;
};
layer = layer->backlayer;
};
}
#endif
void periodic_update() /* update weights for the original method */
{ /* and the differential step size algorithm */
register short reta, ralpha;
register INT32 temp;
register short temp2;
register UNIT *u;
register WTNODE *w;
LAYER *layer;
ralpha = alpha;
layer = last;
while (layer->backlayer != NULL)
{
if (layer == last) reta = eta; else reta = eta2;
u = (UNIT *) layer->units;
while (u != NULL)
{
w = (WTNODE *) u->wtlist;
while (w != NULL)
{
if (w->inuse)
{
#ifdef SYMMETRIC
if (((UNIT *) w->backunit)->unitnumber > u->unitnumber)
{
if (*(w->total) > 0) temp = (INT32) ((INT32)(*(w->total) + 512) >> 10) * reta
+ (INT32) ralpha * *(w->olddw);
else temp = (INT32) -(((INT32) 512 - *(w->total)) >> 10) * reta
+ (INT32) ralpha * *(w->olddw);
if (temp > 0) temp2 = (INT32) (temp + 512) >> 10;
else temp2 = -(((INT32) 512 - temp) >> 10);
*(w->olddw) = temp2;
temp = (INT32) *(w->weight) + temp2;
if (temp > MAXSHORT)
{
wtlimithit = 1;
*(w->weight) = MAXSHORT;
}
else if (temp < MINSHORT)
{
wtlimithit = 1;
*(w->weight) = MINSHORT;
}
else *(w->weight) = temp;
};
#else
if (w->total > 0)
temp = (INT32) (((INT32) w->total + 512) >> 10) * reta + (INT32) ralpha * w->olddw;
else
temp = (INT32) -(((INT32) 512 - w->total) >> 10) * reta + (INT32) ralpha * w->olddw;
if (temp > 0) temp2 = (INT32) (temp + 512) >> 10;
else temp2 = -(((INT32) 512 - temp) >> 10);
w->olddw = temp2;
temp = (INT32) w->weight + temp2;
if (temp > MAXSHORT)
{
wtlimithit = 1;
w->weight = MAXSHORT;
}
else if (temp < MINSHORT)
{
wtlimithit = 1;
w->weight = MINSHORT;
}
else w->weight = temp;
#endif
};
w = w->next;
};
u = u->next;
};
layer = layer->backlayer;
};
}
#ifndef SYMMETRIC
void dbd_update() /* the delta-bar-delta method for weight updates */
{
register short rkappa, temp2, dbarm1, rdecay;
register INT32 temp;
register UNIT *u;
register WTNODE *w;
LAYER *layer;
/* w->olddw is used for delta-bar minus 1 */
rkappa = kappa;
rdecay = decay;
layer = last;
while (layer->backlayer != NULL)
{
u = (UNIT *) layer->units;
while (u != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -