You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

11 KiB

BPnetwork

#include <stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> #define INNODE 2 #define HIDENODE 12 #define OUTNODE 1 double StudyRate = 1.2; double threshold = 1e-4; int mostTimes = 1e6; int trainSize = 0; int testSize = 0; typedef struct Sample{ double out[30][OUTNODE]; double in[30][INNODE]; }Sample; typedef struct Node{ double value; double bias; double bias_delta; double *weight; double *weight_delta; }Node; Node inputLayer[INNODE]; Node hideLayer[HIDENODE]; Node outLayer[OUTNODE]; double Max(double a, double b){ return a > b ? a : b; } double sigmoid(double x){ double y,z; y=exp(x); z=y/(1+y); return z;

} Sample * getTrainData(const char * filename){ Sample * result = (Sample*)malloc(sizeof (Sample)); FILE * file = fopen(filename, "r"); if(file != NULL){ int count = 0; while (fscanf(file, "%lf %lf %lf", &result->in[count][0], &result->in[count][1], &result->out[count][0]) != EOF){ ++count; } trainSize = count; printf("%s The file has been successfully read!\n", filename); fclose(file); return result; } else{ fclose(file); printf("%s Encountered an error while opening the file!\n\a", filename); return NULL; } } Sample * getTestData(const char * filename){ Sample * result=(Sample*)malloc(sizeof(Sample)); FILE * file = fopen(filename, "r"); if(file!= NULL){ int count=0; while (fscanf(file, "%lf %lf", &result->in[count][0], &result->in[count][1])!=EOF){ ++count; } testSize=count; printf("%s The file has been successfully read!\n", filename); fclose(file); return result; }else{ fclose(file); printf("%s Encountered an error while opening the file!\n\a", filename); return NULL; } } void printData(Sample * data, int size){ int i; if(data==NULL){ printf("Sample is empty!"); return; } else{ for(i=0;i<testSize;i++) { printf("%f %f ",data->in[i][0],data->in[i][1]); printf("%f",data->out[i][0]); printf("\n"); } } } void init(){ srand(time(NULL)); for (int i = 0; i < INNODE; ++i) { inputLayer[i].weight = (double *)malloc(sizeof (double ) * HIDENODE); inputLayer[i].weight_delta = (double *) malloc(sizeof (double ) * HIDENODE); inputLayer[i].bias = 0.0; inputLayer[i].bias_delta = 0.0; } for (int i = 0; i < INNODE; ++i) { for (int j = 0; j < HIDENODE; ++j) { inputLayer[i].weight[j] = rand() % 10000 / (double )10000 * 2 - 1.0; inputLayer[i].weight_delta[j] = 0.0; } } for (int i = 0; i < HIDENODE; ++i) { hideLayer[i].weight = (double *)malloc(sizeof(double)OUTNODE); hideLayer[i].weight_delta =(double)malloc(sizeof(double)*OUTNODE); hideLayer[i].bias = rand() % 10000 / (double )10000 * 2 - 1.0; hideLayer[i].bias_delta = 0.0; } for (int i = 0; i < HIDENODE; ++i) { for (int j = 0; j < OUTNODE; ++j) { hideLayer[i].weight[j] = rand() % 10000 / (double )10000 * 2 - 1.0; hideLayer[i].weight_delta[j] = 0.0; } }

for (int i = 0; i < OUTNODE; ++i) {
    outLayer[i].bias = rand() % 10000 / (double )10000 * 2 - 1.0;
    outLayer[i].bias_delta = 0.0;
}

} void resetDelta(){ for (int i = 0; i < INNODE; ++i) { for (int j = 0; j < HIDENODE; ++j) { inputLayer[i].weight_delta[j] = 0.0; } }

for (int i = 0; i < HIDENODE; ++i) {
    hideLayer[i].bias_delta = 0.0;
    for (int j = 0; j < OUTNODE; ++j) {
        hideLayer[i].weight_delta[j] = 0.0;
    }
}

for (int i = 0; i < OUTNODE; ++i) {
    outLayer[i].bias_delta = 0.0;
}

} int main() { init(); Sample * trainSample = getTrainData("TrainData.txt"); for (int trainTime = 0; trainTime < mostTimes; ++trainTime) { resetDelta(); double error_max = 0.0; for (int currentTrainSample_Pos = 0; currentTrainSample_Pos < trainSize; ++currentTrainSample_Pos) { for (int inputLayer_Pos = 0; inputLayer_Pos < INNODE; ++inputLayer_Pos) { inputLayer[inputLayer_Pos].value = trainSample->in[currentTrainSample_Pos][inputLayer_Pos]; } for (int hideLayer_Pos = 0; hideLayer_Pos < HIDENODE; ++hideLayer_Pos) { double sum = 0.0; for (int inputLayer_Pos = 0; inputLayer_Pos < INNODE; ++inputLayer_Pos) { sum += inputLayer[inputLayer_Pos].value * inputLayer[inputLayer_Pos].weight[hideLayer_Pos]; }

            sum -= hideLayer[hideLayer_Pos].bias;
            hideLayer[hideLayer_Pos].value = sigmoid(sum);
        } 
        for (int outLayer_Pos = 0;  outLayer_Pos < OUTNODE ; ++outLayer_Pos) {
            double sum = 0.0;
            for (int hideLayer_Pos = 0; hideLayer_Pos < HIDENODE; ++hideLayer_Pos) {
                sum+=hideLayer[hideLayer_Pos].value * hideLayer[hideLayer_Pos].weight[outLayer_Pos];
                
            }
            sum-=outLayer[outLayer_Pos].bias;
            outLayer[outLayer_Pos].value=sigmoid(sum);
        }
        double error = 0.0;
        for (int outLayer_Pos = 0; outLayer_Pos < OUTNODE; ++outLayer_Pos) {
            double temp = fabs(outLayer[outLayer_Pos].value - trainSample->out[currentTrainSample_Pos][outLayer_Pos]);
            error += temp * temp / 2.0;
        }
        
        error_max = Max(error_max, error);
        for (int outLayer_Pos = 0; outLayer_Pos < OUTNODE; ++outLayer_Pos) {
            double bias_delta = -(trainSample->out[currentTrainSample_Pos][outLayer_Pos] - outLayer[outLayer_Pos].value)
                    * outLayer[outLayer_Pos].value * (1.0 - outLayer[outLayer_Pos].value);
            outLayer[outLayer_Pos].bias_delta += bias_delta;
        }

        for (int hideLayer_Pos = 0; hideLayer_Pos < HIDENODE; ++hideLayer_Pos) {
            for (int outLayer_Pos = 0; outLayer_Pos < OUTNODE; ++outLayer_Pos) {
                double weight_delta = (trainSample->out[currentTrainSample_Pos][outLayer_Pos] - outLayer[outLayer_Pos].value)
                                      * outLayer[outLayer_Pos].value * (1.0 - outLayer[outLayer_Pos].value)
                                      * hideLayer[hideLayer_Pos].value;
                hideLayer[hideLayer_Pos].weight_delta[outLayer_Pos] += weight_delta;
            }
        }
        for (int hideLayer_Pos = 0; hideLayer_Pos < HIDENODE; ++hideLayer_Pos) {
            double sum = 0.0;
            for (int outLayer_Pos = 0; outLayer_Pos < OUTNODE; ++outLayer_Pos) {
                sum += -(trainSample->out[currentTrainSample_Pos][outLayer_Pos] - outLayer[outLayer_Pos].value)
                       * outLayer[outLayer_Pos].value * (1.0 - outLayer[outLayer_Pos].value)
                       * hideLayer[hideLayer_Pos].weight[outLayer_Pos];
            }
            hideLayer[hideLayer_Pos].bias_delta += sum * hideLayer[hideLayer_Pos].value * (1.0 - hideLayer[hideLayer_Pos].value);
        }


        for (int inputLayer_Pos = 0; inputLayer_Pos < INNODE; ++inputLayer_Pos) {
            for (int hideLayer_Pos = 0; hideLayer_Pos < HIDENODE; ++hideLayer_Pos) {
                double sum  = 0.0;
                for (int outLayer_Pos = 0; outLayer_Pos < OUTNODE; ++outLayer_Pos) {
                    sum += (trainSample->out[currentTrainSample_Pos][outLayer_Pos] - outLayer[outLayer_Pos].value)
                           * outLayer[outLayer_Pos].value * (1.0 - outLayer[outLayer_Pos].value)
                           * hideLayer[hideLayer_Pos].weight[outLayer_Pos];
                }
                inputLayer[inputLayer_Pos].weight_delta[hideLayer_Pos] += sum * hideLayer[hideLayer_Pos].value * (1.0 - hideLayer[hideLayer_Pos].value)
                                                                          * inputLayer[inputLayer_Pos].value;
            }
        }

    }
    if(error_max < threshold){
        printf("\a Training completed!Total training count:%d,  maximum error is:%f\n", trainTime + 1, error_max);
        break;
    }
    for (int inputLayer_Pos = 0; inputLayer_Pos < INNODE; ++inputLayer_Pos) {
        for (int hideLayer_Pos = 0; hideLayer_Pos < HIDENODE; ++hideLayer_Pos) {
            inputLayer[inputLayer_Pos].weight[hideLayer_Pos] += StudyRate
                                                                * inputLayer[inputLayer_Pos].weight_delta[hideLayer_Pos] /
                                                                (double) trainSize;
        }
    }

    for (int hideLayer_Pos = 0; hideLayer_Pos < HIDENODE; ++hideLayer_Pos) {
        hideLayer[hideLayer_Pos].bias += StudyRate
                * hideLayer[hideLayer_Pos].bias_delta / (double )trainSize;
        for (int outLayer_Pos = 0; outLayer_Pos < OUTNODE; ++outLayer_Pos) {
            hideLayer[hideLayer_Pos].weight[outLayer_Pos] += StudyRate
                    * hideLayer[hideLayer_Pos].weight_delta[outLayer_Pos] / (double )trainSize;
        }
    }

    for (int outLayer_Pos = 0; outLayer_Pos < OUTNODE; ++outLayer_Pos) {
        outLayer[outLayer_Pos].bias += StudyRate
                * outLayer[outLayer_Pos].bias_delta / (double )trainSize;
    }
}
Sample * testSample = getTestData("TestData.txt");
printf("The predicted results are as follows:\n");
for (int currentTestSample_Pos = 0; currentTestSample_Pos < testSize; ++currentTestSample_Pos) {
    for (int inputLayer_Pos = 0; inputLayer_Pos < INNODE; ++inputLayer_Pos) {
        inputLayer[inputLayer_Pos].value = testSample->in[currentTestSample_Pos][inputLayer_Pos];
    }

    for (int hideLayer_Pos = 0; hideLayer_Pos < HIDENODE; ++hideLayer_Pos) {
        double sum = 0.0;
        for (int inputLayer_Pos = 0; inputLayer_Pos < INNODE; ++inputLayer_Pos) {
            sum += inputLayer[inputLayer_Pos].value * inputLayer[inputLayer_Pos].weight[hideLayer_Pos];
    }
        sum -= hideLayer[hideLayer_Pos].bias;
        hideLayer[hideLayer_Pos].value = sigmoid(sum);
    }

    for (int outLayer_Pos = 0; outLayer_Pos < OUTNODE; ++outLayer_Pos) {
        double sum = 0.0;
        for (int hideLayer_Pos = 0; hideLayer_Pos < HIDENODE; ++hideLayer_Pos) {
            sum += hideLayer[hideLayer_Pos].value * hideLayer[hideLayer_Pos].weight[outLayer_Pos];
        }
        sum -= outLayer[outLayer_Pos].bias;
        outLayer[outLayer_Pos].value = sigmoid(sum);
    }

    for (int outLayer_Pos = 0; outLayer_Pos < OUTNODE; ++outLayer_Pos) {
        testSample->out[currentTestSample_Pos][outLayer_Pos] = outLayer[outLayer_Pos].value;
    }
}
printData(testSample, testSize);
return 0;

}