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

📄 bpclassification.cpp

📁 这是我自己编程的BP算法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		{
			W_HIDE_TO_OUTPUT[i][j]=(float)(rand() % 1000)/1000-0.5f;//随机生成
		}
	}
}

void TEST_Init_Weight_Difference(float W_INPUT_TO_HIDE[][NUM_NODE_HIDE_LAYER],float W_HIDE_TO_OUTPUT[][NUM_NODE_OUTPUT_LAYER],BP_Node* bpNode)
{
	int i,j;

	printf("输入层到隐藏层 权值(随机) 显示:\n");
	for(i=0;i<NUM_NODE_INPUT_LAYER;i++)
	{
		for(j=0;j<NUM_NODE_HIDE_LAYER;j++)
		{
			printf("%.3f\t",W_INPUT_TO_HIDE[i][j]);
		}
		printf("\n");
	}

	printf("隐含层到输出层 权值(随机) 显示:\n");
	for(i=0;i<NUM_NODE_HIDE_LAYER;i++)
	{
		for(j=0;j<NUM_NODE_OUTPUT_LAYER;j++)
		{
			printf("%.3f\t",W_HIDE_TO_OUTPUT[i][j]);
		}
		printf("\n");
	}

	printf("BP网各节点:\n");
	for(i=0;i<NUM_NODE_TOTAL;i++)
	{
		printf("节点 %d :",i);
		printf("数据-> %f\t 偏差: %.3f\t 教师值: %f\n",bpNode[i].data,bpNode[i].difference,bpNode[i].expect);
	}
}

void Input_Single_Train_Data_To_Input_Layer(TrainData singleTrainData)
{
	int i;
	for(i=0;i<NUM_NODE_INPUT_LAYER;i++)
	{
		bpNode[i].data=singleTrainData.feature[i];
	}
}

void Input_Teacher_Data_To_Output_Layer(TrainData singleTrainData)
{
	int i;
	i=0;

	if(singleTrainData.nClass==0) //当前样本属于第0类
	{
		bpNode[INDEX_START_OUTPUT_LAYER].expect=1.0f;
		bpNode[INDEX_START_OUTPUT_LAYER+1].expect=0.0f;
		bpNode[INDEX_START_OUTPUT_LAYER+2].expect=0.0f;
	}
	else if(singleTrainData.nClass==1)
	{
		bpNode[INDEX_START_OUTPUT_LAYER].expect=0.0f;
		bpNode[INDEX_START_OUTPUT_LAYER+1].expect=1.0f;
		bpNode[INDEX_START_OUTPUT_LAYER+2].expect=0.0f;
	}
	else if(singleTrainData.nClass==2)
	{
		bpNode[INDEX_START_OUTPUT_LAYER].expect=0.0f;
		bpNode[INDEX_START_OUTPUT_LAYER+1].expect=0.0f;
		bpNode[INDEX_START_OUTPUT_LAYER+2].expect=1.0f;
	}
	else //出错
	{
		bpNode[INDEX_START_OUTPUT_LAYER].expect=-1.0f;
		bpNode[INDEX_START_OUTPUT_LAYER+1].expect=-1.0f;
		bpNode[INDEX_START_OUTPUT_LAYER+2].expect=-1.0f;
	}
}

void Print_Input_Output_Layer_Before_Train()
{
	int i=0;
	//输出INPUT_LAYER各节点的值
	printf("当前学习样本输入BP网,启动学习之前相关数据 显示:\n");
	printf("输入层 显示:\n");
	for(i=0;i<NUM_NODE_INPUT_LAYER;i++)
	{
		printf("节点 %d :",i);
		printf("数据-> %f\t 偏差: %.3f\t 教师值: %f\n",bpNode[i].data,bpNode[i].difference,bpNode[i].expect);
	}
	//输出OUTPUT_LAYER各节点的值
	printf("输出层 显示:\n");
	for(i=INDEX_START_OUTPUT_LAYER;i<NUM_NODE_TOTAL;i++)
	{
		printf("节点 %d :",i);
		printf("数据-> %f\t 偏差: %.3f\t 教师值: %f\n",bpNode[i].data,bpNode[i].difference,bpNode[i].expect);
	}
}

void Train()
{
	int i;
	i=0;
	for(i=0;i<NUM_CLASS*NUM_TRAIN_PER_CLASS;i++)
	{
		//先将每个学习样本分发到BP网的INPUT_LAYER
		Input_Single_Train_Data_To_Input_Layer(train[i]);
		//更改BP网OUTPUT_LAYER的教师值
		Input_Teacher_Data_To_Output_Layer(train[i]);
		//DEBUG
		Print_Input_Output_Layer_Before_Train();
		//DEBUG
		prePropagation();//向前传播
		while(!isStop(train[i]))
		{
			Update_Weight_Difference();
			NUM_CURRENT_ITERATE++;
			prePropagation();
		}
	}
}

void prePropagation()
{//功能:向前传播,计算每个隐含层和输出层的各个节点的输出
	int i=0;
	int j=0;

	//处理INPUT_LAYER的输出,其输出即为其data值
	for(i=INDEX_START_INPUT_LAYER;i<INDEX_START_HIDE_LAYER+NUM_NODE_INPUT_LAYER;i++)
	{
		bpNode[i].output=bpNode[i].data;
	}

	//处理HIDE_LAYER的输入与输出
	for(i=INDEX_START_HIDE_LAYER;i<INDEX_START_HIDE_LAYER+NUM_NODE_HIDE_LAYER;i++)
	{
		for(j=INDEX_START_INPUT_LAYER;j<INDEX_START_INPUT_LAYER+NUM_NODE_INPUT_LAYER;j++)
		{
			bpNode[i].input+=(bpNode[j].output*W_INPUT_TO_HIDE[j][i]);
		}
		bpNode[i].input+=bpNode[i].difference;//HIDE_LAYER当前节点的纯输入
		bpNode[i].output=(float)(1/(1+exp(bpNode[i].input)));//HIDE_LAYER当前节点的纯输出
	}

	//处理OUTPUT_LAYER的输入与输出
	for(i=INDEX_START_OUTPUT_LAYER;i<INDEX_START_OUTPUT_LAYER+NUM_NODE_OUTPUT_LAYER;i++)
	{
		for(j=INDEX_START_HIDE_LAYER;j<INDEX_START_HIDE_LAYER+NUM_NODE_HIDE_LAYER;j++)
		{
			bpNode[i].input+=(bpNode[j].output*W_HIDE_TO_OUTPUT[j][i]);
		}
		bpNode[i].input+=bpNode[j].difference;
		bpNode[i].output=(float)(1/(1+exp(bpNode[i].input)));
	}


}

void CalcErr()
{//从OUTPUT_LAYER-->HIDE_LAYER依次计算各节点的
	int i,j;
	i=0;
	j=0;

	//OUTPUT_LAYER各节点的误差
	for(i=INDEX_START_OUTPUT_LAYER;i<INDEX_START_OUTPUT_LAYER+NUM_NODE_OUTPUT_LAYER;i++)
	{
		bpNode[i].err=bpNode[i].output*(1-bpNode[i].output)*(bpNode[i].expect-bpNode[i].output);
	}

	//HIDE_LAYER各节点的误差
	for(i=INDEX_START_HIDE_LAYER;i<INDEX_START_HIDE_LAYER+NUM_NODE_HIDE_LAYER;i++)
	{
		for(j=INDEX_START_OUTPUT_LAYER;j<INDEX_START_OUTPUT_LAYER+NUM_NODE_OUTPUT_LAYER;j++)
		{
			bpNode[i].err+=(bpNode[j].err*W_HIDE_TO_OUTPUT[i][j]);
		}
		bpNode[i].err=bpNode[i].output*(1-bpNode[i].output)*bpNode[i].err;
	}
}

void Update_Weight_Difference()
{
	int i,j;
	i=0;
	j=0;

	//更新权值时要逆向
	//更新OUTPUT_LAYER到HIDE_LAYER之间的权值
	for(i=INDEX_START_OUTPUT_LAYER;i<INDEX_START_OUTPUT_LAYER+NUM_NODE_OUTPUT_LAYER;i++)
	{
		for(j=INDEX_START_HIDE_LAYER;j<INDEX_START_HIDE_LAYER+NUM_NODE_HIDE_LAYER;j++)
		{//这里映射的概念
			int tempJ=j-NUM_NODE_INPUT_LAYER;
			int tempI=i-NUM_NODE_INPUT_LAYER-NUM_NODE_HIDE_LAYER;
			W_HIDE_TO_OUTPUT[tempJ][tempI]=W_HIDE_TO_OUTPUT[tempJ][tempI]+(float)TRAIN_RATE*bpNode[i].err*bpNode[j].output;
		}
	}

	//更新INPUT_LAYER到HIDE_LAYER之间的权值
	for(i=INDEX_START_INPUT_LAYER;i<INDEX_START_INPUT_LAYER+NUM_NODE_INPUT_LAYER;i++)
	{
		for(j=INDEX_START_HIDE_LAYER;j<INDEX_START_HIDE_LAYER+NUM_NODE_HIDE_LAYER;j++)
		{
			int tempI=i;
			int tempJ=j-NUM_NODE_INPUT_LAYER;
			W_INPUT_TO_HIDE[tempJ][tempI]=W_INPUT_TO_HIDE[tempJ][tempI]+(float)TRAIN_RATE*bpNode[i].err*bpNode[j].output;
		}
	}

	//更新偏差,逆向
	//更新OUTPUT_LAYER各节点的偏差	
	for(i=INDEX_START_OUTPUT_LAYER;i<INDEX_START_OUTPUT_LAYER+NUM_NODE_OUTPUT_LAYER;i++)
	{
		bpNode[i].difference=bpNode[i].difference+(float)TRAIN_RATE*bpNode[i].err;
	}
	//更新HIDE_LAYER各节点的偏差
	for(i=INDEX_START_HIDE_LAYER;i<INDEX_START_HIDE_LAYER+NUM_NODE_HIDE_LAYER;i++)
	{
		bpNode[i].difference=bpNode[i].difference+(float)TRAIN_RATE*bpNode[i].err;
	}
}

bool isStop(TrainData current_Train_Data)
{//功能:判断迭代是否需要停止
	
	bool result;
	float diff;
	result=false;
	diff=0.0f;

	if(NUM_CURRENT_ITERATE==NUM_MAX_ITERATE)
	{
		return true;
	}

	//BP网络输出与教师值的偏差是否满足要求
	if(current_Train_Data.nClass==0)
	{
		diff=(float)fabs(bpNode[INDEX_START_OUTPUT_LAYER].expect-(float)fabs(bpNode[INDEX_START_OUTPUT_LAYER].output));
	}
	else if(current_Train_Data.nClass==1)
	{
		diff=(float)fabs(bpNode[INDEX_START_OUTPUT_LAYER+1].expect-(float)fabs(bpNode[INDEX_START_OUTPUT_LAYER+1].output));
	}
	else if(current_Train_Data.nClass==2)
	{
		diff=(float)fabs(bpNode[INDEX_START_OUTPUT_LAYER+2].expect-(float)fabs(bpNode[INDEX_START_OUTPUT_LAYER+2].output));
	}
	result=(diff<=THRESHOLD);
	return result;
}

void printTrainResult()
{
	int i=0;
	//INPUT_LAYER
	printf("训练结束后:\n");
	printf("--------------------------\n");
	printf("输入层 显示:\n");
	for(i=INDEX_START_INPUT_LAYER;i<INDEX_START_INPUT_LAYER+NUM_NODE_INPUT_LAYER;i++)
	{
		printf("Data: %.3f\t Diff:%.3f\t Expect:%.3f\t Err:%.3f\t Input:%f\t Output:%f\n",bpNode[i].data,bpNode[i].difference,bpNode[i].err,bpNode[i].expect,bpNode[i].input,bpNode[i].output);
	}

	printf("隐含层 显示:\n");
	for(i=INDEX_START_HIDE_LAYER;i<INDEX_START_HIDE_LAYER+NUM_NODE_HIDE_LAYER;i++)
	{
		printf("Data: %.3f\t Diff:%.3f\t Expect:%.3f\t Err:%.3f\t Input:%f\t Output:%f\n",bpNode[i].data,bpNode[i].difference,bpNode[i].err,bpNode[i].expect,bpNode[i].input,bpNode[i].output);
	}

	printf("输出层 显示:\n");
	for(i=INDEX_START_OUTPUT_LAYER;i<INDEX_START_OUTPUT_LAYER+NUM_NODE_OUTPUT_LAYER;i++)
	{
		printf("Data: %.3f\t Diff:%.3f\t Expect:%.3f\t Err:%.3f\t Input:%f\t Output:%f\n",bpNode[i].data,bpNode[i].difference,bpNode[i].err,bpNode[i].expect,bpNode[i].input,bpNode[i].output);
	}
}
void Test()
{
	int i=0;
	int j=0;
	bool classA=false;
	bool classB=false;
	bool classC=false;
	for(i=0;i<NUM_CLASS*NUM_TEST_PER_CLASS;i++)
	{
		for(j=INDEX_START_OUTPUT_LAYER;j<INDEX_START_OUTPUT_LAYER+NUM_NODE_OUTPUT_LAYER;j++)
		{
			bpNode[i].output=0.0f;
		}
		Input_Single_Train_Data_To_Input_Layer(train[i]);
		prePropagation();

		//依据OUTPUT_LAYER的各节点的值来修改test[i]
		classA=((float)fabs(bpNode[INDEX_START_OUTPUT_LAYER].expect-(float)fabs(bpNode[INDEX_START_OUTPUT_LAYER].output))<=THRESHOLD);
		classB=((float)fabs(bpNode[INDEX_START_OUTPUT_LAYER+1].expect-(float)fabs(bpNode[INDEX_START_OUTPUT_LAYER+1].output))<=THRESHOLD);
		classC=((float)fabs(bpNode[INDEX_START_OUTPUT_LAYER+2].expect-(float)fabs(bpNode[INDEX_START_OUTPUT_LAYER+2].output))<=THRESHOLD);
		
		if(classA)
		{
			test[i].result=0;
		}
		if(classB)
		{
			test[i].result=1;
		}
		if(classC)
		{
			test[i].result=2;
		}
		
		if(test[i].nClass==test[i].result)
		{
			test[i].Right=true;
		}
		else
		{
			test[i].Right=false;
		}
	}
}

void PrintTestResult()
{
	int i=0;
	printf("-----------------------\n");
	for(i=0;i<NUM_CLASS*NUM_TEST_PER_CLASS;i++)
	{
		printf("测试样本编号: %d \t",i);
		printf("实际结果: %d\t 测试结果: %d\n",test[i].nClass,test[i].result);
	}
}

⌨️ 快捷键说明

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