parent
7792cb45cc
commit
4475cfa93b
@ -1,2 +1,272 @@
|
||||
# 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;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in new issue