⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bp.cpp

📁 简单的bp算法 用c实现的 用于股票预测很实用
💻 CPP
字号:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>

const int N = 20;              //学习样本个数
const int IN = 1;              //输入层神经元数目
const int HN = 50;             //隐层神经元数目
const int OUT = 1;             //输出层神经元数目
const double MAX = 0x7fff;
const double EPS = 0.00001;

double P[IN]; //单个样本输入数据
double T[OUT]; //单个样本教师数据
double W[HN][IN];//输入层至隐层权值
double V[OUT][HN];//隐层至输出层权值
double HIN[HN]; //隐层的输入
double OIN[OUT];//输出层的输入
double HOUT[HN];//隐层的输出             
double OOUT[OUT];//输出层的输出
double HLIMIT[HN];//隐层的阈值
double OLIMIT[OUT];//输出层的阈值
double ERROR[N];//第m个样本的总误差
double ALPHA;//输出层至隐层的学习效率
double BETA;//隐层至输入层学习效率
double YITA;
double ERROROH[OUT];
double ERRORHI[HN];
double OLDW[HN];
double OLDV[OUT];
int    NOW;
double BEFORE;
//定义一个放学习样本的结构
struct DATA
{
	double input[IN];
	double teach[OUT];
};

struct DATA TrainingData[N];
///////////////////////////
//初始化权、阈值子程序/////
///////////////////////////
void Initial()
{
	NOW = 0;
	ALPHA = 0.6;
	BETA = 0.6;
	YITA = 0.6;
	srand((unsigned int)time(NULL));
	double sign;
	int i, j;
	//初始化输入-隐层权值矩阵
	for(i = 0; i < HN; ++i)
	{
		for(j = 0; j < IN; ++j)
		{
			sign = pow(-1, rand()%2);
			W[i][j] = sign * rand() / MAX;
		}
	}
	//初始化隐层-输出权值矩阵
	for(i = 0; i < OUT; ++i)
	{
		for(j = 0; j < HN; ++j)
		{
			sign = pow(-1, rand()%2);
			V[i][j] = sign * rand() / MAX; 
		}
	}
	//初始化隐层阈值
	for(i = 0; i < HN; ++i)
	{
		sign = pow(-1, rand()%2);
		HLIMIT[i] = sign * rand() / MAX;
	}
	//初始化输出层阈值
	for(j = 0; j < OUT; ++j)
	{
		sign = pow(-1, rand()%2);
		OLIMIT[i] = sign * rand() / MAX;
	}
}

//得到第m个样本数据
void GetOneData(const int m)
{
	int i;
	for(i = 0; i < IN; ++i)
	{
		P[i] = TrainingData[m].input[i];
		T[i] = TrainingData[m].teach[i];
	}
}

//得到净输入、输出,采用sigmoid函数
void Calculate()
{
	int i, j; 
	double total;
	//计算隐层输出
	for(i = 0; i < HN; ++i)
	{
		total = 0;
		for(j = 0; j < IN; ++j)
		{
			total += W[i][j] * P[j];
		}
		HIN[i]  = total - HLIMIT[i];
		HOUT[i] = 1.0 / (1.0 + exp(-HIN[i]));
	}
	//计算输出层输出
	for(i = 0; i < OUT; ++i)
	{
		total = 0;
		for(j = 0; j < HN; ++j)
		{
			total += V[i][j] * HOUT[j];
		}
		OIN[i] = total - OLIMIT[i];
		OOUT[i] = 1.0 / (1.0 + exp(-OIN[i]));
	}
}

//计算输出-隐层误差
void ErrorOutToHide(const int m)
{
	int i;
	double *Abs_Error = new double [OUT];
	double Sqr_Error = 0;
	for(i = 0; i < OUT; ++i)
	{
		Abs_Error[i] = (T[i] - OOUT[i]);
		Sqr_Error += Abs_Error[i] * Abs_Error[i];
		ERROROH[i] = Abs_Error[i] * OOUT[i] * (1 - OOUT[i]);
	}
	ERROR[m] = Sqr_Error / 2.0;
	delete [OUT]Abs_Error;
}

//计算隐层-输入误差
void ErrorHideToIn()
{
	int i, j;
	double total;
	for(i = 0; i < HN; ++i)
	{
		total = 0;
		for(j = 0; j < OUT; ++j)
		{
			total += ERROROH[j] * V[j][i];
		}
		ERRORHI[i] = total * HOUT[i] * (1 - HOUT[i]);
	}
}

void GetOldError()
{
	int i;
	for(i = 0; i < HN; ++i)
		OLDW[i] = ALPHA * ERRORHI[i];
	for(i = 0; i < OUT; ++i)
		OLDV[i] = BETA * ERROROH[i];
}


//输出层至隐层权值、阈值调整
void UpdateV()
{
	int i, j; 
	if(NOW == 1)
	{
		for(i = 0; i < OUT; ++i)
		{
			for(j = 0; j < HN; ++j)
			{
				V[i][j] += BETA * ERROROH[i] * HOUT[j];
			}
			OLIMIT[i] += BETA * ERROROH[i];
		}
	}
	else
	{
		for(i = 0; i < OUT; ++i)
		{
			for(j = 0; j < HN; ++j)
			{
				V[i][j] += (1 - YITA) * BETA * ERROROH[i] * HOUT[j] + YITA * OLDV[i];
			}
			OLIMIT[i] += BETA * ERROROH[i];
		}
	}
}

void UpdateW()
{
	int i, j; 
	if(NOW == 1)
	{
		for(i = 0; i < HN; ++i)
		{
			for(j = 0; j < IN; ++j)
			{
				W[i][j] += ALPHA * ERRORHI[i] * P[j];
			}
			HLIMIT[i] += ALPHA * ERRORHI[i];
		}
	}
	else
	{
		for(i = 0; i < HN; ++i)
		{
			for(j = 0; j < IN; ++j)
			{
				W[i][j] += (1 - YITA) * ALPHA * ERRORHI[i] * P[j] + YITA * OLDW[i];
			}
			HLIMIT[i] += ALPHA * ERRORHI[i] ;
		}
	}
}

//计算N个样本全局误差,用于判断收敛
bool GetGlobalError()
{
	int i;
	double GlobalError = 0;
	for(i = 0; i < N; ++i)
		GlobalError += ERROR[i];
	if(GlobalError < EPS)return true;
	return false;
}

//读取训练数据
void GetData()
{
	int i, j, k;
	for(i = 0; i < N; ++i)
	{
		for(j = 0; j < IN; ++j)
		{
			scanf("%lf", &TrainingData[i].input[j]);
		}
		for(k = 0; k < OUT; ++k)
		{
			scanf("%lf", &TrainingData[i].teach[k]);
		}
	}
}
///////////////////////////////////////////////////////
//测试所用函数为y = sin(x)
void GenerateData()
{
//	freopen("TrainingData.txt","w",stdout);
	srand((unsigned int)time(NULL));
	int i;
	double x;
	for(i = 0; i < N; i++)
	{
		x = (double)rand() / MAX;
//		printf("%lf %lf\n", x, sin(x));
	}
}

void GetTest()
{
	freopen("in.txt","r", stdin);
	double x;
	while(scanf("%lf\n", &x)!=EOF)
	{
		P[0] = x;
		Calculate();
		printf("\n%lf %lf\n", sin(x), OOUT[0]);
	}
}
//////////////////////////////////////////////////////////////////////////

int main()
{
	FILE *stream;
	int i, j, k;
	const int MAXGENERATION = 10000;
//	GenerateData();
	stream = freopen("TrainingData.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
	GetData();
	Initial();
	do 
	{
		++NOW;
//		printf("第%d次迭代\n", NOW);
		for(i = 0; i < N; ++i)
		{
			GetOneData(i);
			Calculate();
			GetOldError();
			ErrorOutToHide(i);
			ErrorHideToIn();
			UpdateW();
			UpdateV();
		}
	} while((!GetGlobalError()) && (NOW != MAXGENERATION));
	GetTest();
	return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -