#define PATTERN 8
#define LROWS 5
#define LCOLS 4
#define KROWS 2
#define KCOLS 5
#define ran() ((rand() % 10000) / 10000.0 / 5) - 0.1
float x[PATTERN][LCOLS] = { {0.0, 0.0, 0.0, -1.0}, {0.0, 0.0, 1.0, -1.0},
{0.0, 1.0, 0.0, -1.0}, {0.0, 1.0, 1.0, -1.0},
{1.0, 0.0, 0.0, -1.0}, {1.0, 0.0, 1.0, -1.0},
{1.0, 1.0, 0.0, -1.0}, {1.0, 1.0, 1.0, -1.0} };
float d[PATTERN][KROWS] = { {0.0, 0.0}, {0.0, 1.0}, {0.0, 1.0}, {1.0, 0.0},
{0.0, 1.0}, {1.0, 0.0}, {1.0, 0.0}, {1.0, 1.0} };
float w_l[LROWS][LCOLS], w_k[KROWS][KCOLS];
float NET_l[LCOLS], z[LROWS];
float NET_k[KROWS], OUT[KROWS];
float delta_OUT[KROWS], delta_z[LROWS];
char c;
float n = 0.0; /* n initialize */
float N = 0.0; /* lambda initialize */
float EMIN = 0.0; /* Emin initialize */
float wx = 0.0, wz = 0.0, charge = 0.0, delta_w = 0.0, E = 0.0;
int i = 0, j = 0, k = 0, l = 0, m = 0;
int number = 0; /* TRAIN number initialize */
void Forward_Pass(void);
void Backward_Pass(void);
void Amend_Weight(void);
void Input_x(void);
void Print_Weight(void);
void Initialize_Weight(void);
void Delta_Rule(void);
void main(void)
{
do {
printf(" Welcome to Backpropagation !\n");
printf(" --- Perform Full Adder ---\n");
printf(" Input E_min : ");
scanf("%f", &EMIN);
printf(" Input n(learning ratio) : ");
scanf("%f", &n);
printf(" Input N(lambda) : ");
scanf("%f", &N);
printf(" Input Maxium learning number : ");
scanf("%d", &number);
printf(" Perform Backpropagation [Y/N] : ");
} while ((c = getche()) != 'y');
Initialize_Weight(); /* weight initialize */
for (l = 0; l < number; l++)
{
for (k = 0; k < PATTERN; k++)
{
Forward_Pass();
Backward_Pass();
Delta_Rule();
Amend_Weight();
}
if(E < EMIN) break;
E = 0.;
}
Input_x();
}
void Forward_Pass()
{
/* l */
/* Z = f(NE T ) = f( sigma W1 */
/* i i i */
for (i = 0; i < LROWS; i++) NET_l[i] = 0.0;
for (i = 0; i < LROWS; i++)
{
for (j = 0; j < LCOLS; j++)
{
wx = w_l[i][j] * x[k][j];
NET_l[i] = wx + NET_l[i];
}
z[i] = 1.0 / (1.0 + exp(-N * NET_l[i]));
}
z[LROWS - 1] = -1.0; /* z[4] = -1 */
for (i = 0; i < KROWS; i++) NET_k[i] = 0.0;
for (i = 0; i < KROWS; i++)
{
for (j = 0; j < KCOLS; j++)
{
wz = w_k[i][j] * z[j];
NET_k[i] = wz + NET_k[i];
}
OUT[i] = 1.0 / (1.0 + exp(-N * NET_k[i]));
}
}
void Backward_Pass()
{
charge = 0.0;
for(i = 0; i < KROWS; i++)
{
charge = ((d[k][i] - OUT[i]) * (d[k][i] - OUT[i])) + charge;
}
E = ((1.0 / 2.0) * charge) + E;
}
void Delta_Rule()
{
/* OUTPUT layer */
for(i = 0; i < KROWS; i++)
{
delta_OUT[i] = (d[k][i] - OUT[i]) * (1.0 - OUT[i]) * OUT[i];
}
/* hidden layer */
for(i = 0; i < KCOLS; i++)
{
delta_w = 0.0;
for(m = 0; m < KROWS; m++)
{
delta_w = (delta_OUT[m] * w_k[m][i]) + delta_w;
}
delta_z[i] = z[i] * (1.0 - z[i]) * delta_w;
}
}
void Amend_Weight()
{
for(i = 0; i < KROWS; i++)
{
for(j = 0; j < KCOLS; j++)
{
w_k[i][j] = w_k[i][j] + (n * delta_OUT[i] * z[j]);
}
}
for(i = 0; i < KROWS; i++)
{
for(j = 0; j < KCOLS; j++)
{
w_l[i][j] = w_l[i][j] + (n * delta_z[i] * x[k][j]);
}
}
}
void Input_x()
{
float temp;
do {
printf("E_min = %f \tn = %f \t N = %f\n", EMIN, n, N);
printf("training number = %d, E = %f\n", l, E);
Print_Weight();
printf("\n\n");
printf("--- x[0] = Carry in, x[1] = input 1, x[2] = input 2 --- \n");
for(i = 0; i < 3; i++)
{
printf("Input x[%d] of the pattern X :", i);
scanf("%f", &temp);
x[8][i] = temp;
}
x[8][3] = -1.;
Forward_Pass();
printf("\n");
for(i = 0; i < KROWS; i++)
{
printf("OUT[%d] = %f \t", i, OUT[i]);
}
printf("\n--- Where, OUT[0] = Carry out, OUT[1] = Sum ---\n");
printf("\n\nAnother Input ? [y/n] : ");
} while ((c = getche()) != 'n');
}
void Print_Weight()
{
printf("\n\n");
printf("[Amended Weight at l layer]");
for(i = 0; i < LROWS; i++)
{
printf("\n");
for(j = 0; j < LCOLS; j++)
{
printf(" %+.3f", w_l[i][j]);
}
}
printf("\n\n");
printf("[Amended Weight at k layer]");
for(i = 0; i < KROWS; i++)
{
printf("\n");
for(i = 0; i < KROWS; i++)
{
for(j = 0; j < KCOLS; j++)
{
printf(" %+.3f", w_k[i][j]);
}
printf("\n");
}
}
}
void Initialize_Weight()
{
int i, j;
time_t t;
srand((unsigned) time(&t));
for(i = 0; i < LROWS; i++)
for(j = 0; j < LCOLS; j++)
{
w_l[i][j] = ran();
}
for(i = 0; i < KROWS; i++)
for(j = 0; j < KCOLS; j++)
{
w_k[i][j] = ran();
}
}