BPnetwork #include #include #include #include #define INNODE 2 #define HIDENODE 10 #define OUTNODE 1 double StudyRate = 1.6; 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;iin[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; } //练习部分的源程序并为录入代码库,需要自行稍加更改就行