关于bp神经网络算法的总结

学习自: https://blog.csdn.net/QKK612501/article/details/52893803
需要用以下两行代码:

#include"bpNetwork.h"
using namespace bpNetwork;

介绍:

提供 “basicNode” 类
定义:

basicNode<typename _type>(nodeType type,_type(*function)(vector<_type>,int,_type theta));

nodeType 有如下种类:
FRONT_NODE :输入节点
MID_NODE :隐藏节点(默认)
END_NODE:输出节点

function 是数据处理函数指针,
数据处理函数要有如下参数:
vector<_type> :提供数据
int :数据长度
_type :权值

头文件自带数据处理函数有:
Identity
Binary_Step
Logistic(Sigmoid)
tanh
arctan
RelU
PRelU
ElU
Softplus
转载图片
basicNode类提供以下函数:

void giveData(_type Num);

提供输入。参数:输入数据

void addSon(basicNode* sonNode,_type(*con)(_type,_type),_type w=1);

添加子节点。参数:子节点指针,连接函数指针,权值(默认为1)
连接函数参数:数据,权值
头文件目前只提供:
Identity

void func(_type(*solveDat)(vector<_type>,int,_type));

改变数据处理函数。参数:见上

void searchSon(vector<basicNode<_type>*>* hiddenPoints,vector<basicNode<_type>*>* endPoints,vector<basicNode<_type>*>* edgeStack,vector<basicNode<_type>*>* nodeStack)

搜索子节点并入vector。参数:隐藏节点vector指针,末节点vector指针,读边学习vector指针,读节点学习vector指针

void endResult(_type* res)

确定返回数据指针。参数:返回指针

void exchangeTheta(_type newTheta);
void exchangeTheta(long id,_type newTheta);
void exchangeDerta(_type newTheta);
void exchangeDerta(long id,_type newTheta);

改权值。

long long getSonNum()

获得子节点数

void saveNode(const char * __restrict__ _Filename);
void saveNode(FILE* _FilePointer);
void readNode(const char * __restrict__ _Filename);
void readNode(FILE* _FilePointer);

存储节点到文件(不完备)

头文件自带学习函数(不完备):

void faltBack(vector<_type> inputs,vector<_type> outputs,vector<basicNode<_type>*>* inputPoints,unsigned long long learnTimes,_type learnWeight,double(*resultFunction)(vector<_type>*,vector<_type>*,vector<_type>*));//double resultFunciton(vector<_type>* wantOut,vector<_type*>* factOut,vector<_type>* oldOut) return weight:positive for

参数:输入数据vector,期望输出数据vector,输入节点指针vector的指针,学习次数,学习力度,权值计算函数(参数:希望输出数据vector的指针,实际输出的指针vector的指针,测试优化前输出。返回值:正数表示劣化了,负数表示优化了)

应用

我写的小型bp神经网络
bp神经网络
源代码(C++)

#include<bits/stdc++.h>
#include"bpNetwork.h"
using namespace std;
using namespace bpNetwork;

FILE* sav;
float result,input;
int main(){
	sav=fopen("save.sav","r");
	basicNode<float>
	node1(FRONT_NODE,&Logistic),
	node2(MID_NODE,&Logistic),
	node3(MID_NODE,&Logistic),
	node4(MID_NODE,&Logistic),
	node5(MID_NODE,&Logistic),
	node6(MID_NODE,&Logistic),
	node7(MID_NODE,&Logistic),
	node8(MID_NODE,&Logistic),
	node9(MID_NODE,&Logistic),
	node10(END_NODE,&Logistic);
	node1.addSon(&node2,&Identity);
	node1.addSon(&node3,&Identity);
	node1.addSon(&node4,&Identity);
	node2.addSon(&node4,&Identity);
	node2.addSon(&node6,&Identity);
	node3.addSon(&node4,&Identity);
	node3.addSon(&node5,&Identity);
	node4.addSon(&node6,&Identity);
	node4.addSon(&node7,&Identity);
	node5.addSon(&node7,&Identity);
	node5.addSon(&node8,&Identity);
	node6.addSon(&node7,&Identity);
	node6.addSon(&node9,&Identity);
	node7.addSon(&node8,&Identity);
	node7.addSon(&node9,&Identity);
	node7.addSon(&node10,&Identity);
	node8.addSon(&node10,&Identity);
	node9.addSon(&node10,&Identity);
	node10.endResult(&result);
	scanf("%f",&input);
	node1.giveData(input);
	printf("%f",result);
}

代码

(我写的)头文件:bpNetwork.h

/*
   Copyright (c) 2019 BooleanWar project,all rights reserved.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in
   all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/
#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
#include<math.h>
#include<pthread.h>
using namespace std;
/************************************************************************************************************************/
namespace bpNetwork{
#define FUNC(e,f,p) e(*f)(p)
typedef int nodeType;
#define FRONT_NODE 0
#define MID_NODE 1
#define END_NODE 2

double arctan(double x)
{
	int i;
	double r,e,f,sqr;
	sqr=x*x;
	r=0; e=x; i=1;
	while(e/i>1e-15)
	{
		f=e/i;
		r=(i%4==1)? r+f : r-f;
		e=e*sqr; i+=2;
	}
	return r;
}
/************************************************************************************************************************/
//connection function
template <typename _type>
_type Identity(_type DATA,_type weight){
	return DATA*weight;
}
//solve Data Functions 
template <typename _type>
_type Identity(vector<_type>DATA,int vectorLen,_type THETA)
{
	_type res=DATA[0];
	for(int i=1;i<vectorLen;i++)
		res=res+DATA[i];
	res=res*THETA;
	return res;
}

template <typename _type>
_type Binary_Step(vector<_type>DATA,int vectorLen,_type THETA)
{
	_type res=DATA[0];
	for(int i=1;i<vectorLen;i++)
		res=res+DATA[i];
	res=res*THETA;
	return res>=0?1:0;
}

template <typename _type>
_type Logistic(vector<_type>DATA,int vectorLen,_type THETA)
{
	_type res=DATA[0];
	for(int i=1;i<vectorLen;i++)
		res=res+DATA[i];
	res=res*THETA;
	return 1/(1+pow(M_E,res));
}

template <typename _type>
_type Sigmoid(vector<_type>DATA,int vectorLen,_type THETA)
{
	_type res=DATA[0];
	for(int i=1;i<vectorLen;i++)
		res=res+DATA[i];
	res=res*THETA;
	return 1/(1+pow(2.7182818,res));
}

template <typename _type>
_type tanh(vector<_type>DATA,int vectorLen,_type THETA)
{
	_type res=DATA[0];
	for(int i=1;i<vectorLen;i++)
		res=res+DATA[i];
	res=res*THETA;
	return tanh(res);
}

template <typename _type>
_type arctan(vector<_type>DATA,int vectorLen,_type THETA)
{
	_type res=DATA[0];
	for(int i=1;i<vectorLen;i++)
		res=res+DATA[i];
	res=res*THETA;
	return arctan(res);
}

template <typename _type>
_type RelU(vector<_type>DATA,int vectorLen,_type THETA)
{
	_type res=DATA[0];
	for(int i=1;i<vectorLen;i++)
		res=res+DATA[i];
	res=res*THETA;
	return res>=0?res:0;
}

template <typename _type>
_type PRelU(vector<_type>DATA,int vectorLen,_type THETA)
{
	_type res=DATA[0];
	for(int i=1;i<vectorLen;i++)
		res=res+DATA[i];
	return res>=0?res*THETA:res;
}

template <typename _type>
_type ElU(vector<_type>DATA,int vectorLen,_type THETA)
{
	_type res=DATA[0];
	for(int i=1;i<vectorLen;i++)
		res=res+DATA[i];
	return res>=0?res*THETA:res;
}

template <typename _type>
_type Softplus(vector<_type>DATA,int vectorLen,_type THETA)
{
	_type res=DATA[0];
	for(int i=1;i<vectorLen;i++)
		res=res+DATA[i];
	return log(1+pow(M_E,res));
}
/************************************************************************************************************************/
//other public functions
template<typename _type>
	class basicNode{
	public:
		basicNode(nodeType type=MID_NODE,_type(*function)(vector<_type>,int,_type)=NULL):fatherNum(NULL),sonNum(NULL),type(type),theta(NULL),solveData(function),dataPoint(0),singleWeight(1){}

		void giveData(_type Num){
			_type dat;
			data.push_back(Num);
			dataPoint++;
			if(dataPoint>=fatherNum)
				if(type==MID_NODE||type==FRONT_NODE){
					dat=solveData(data,fatherNum,singleWeight);
					for(int i=0;i<sonNum;i++){
						(*sons[i]).giveData((*connections[i])(dat,weight[i]));//wrong grammer
					}
					resetData();
				}
				else
				{
					(*result)=solveData(data,fatherNum,singleWeight);
				}
		}

		void addSon(basicNode* sonNode,_type(*con)(_type,_type),_type w=1){
			sons.push_back(sonNode);
			connections.push_back(con);
			weight.push_back(w);
			sonNum++;
			(*sonNode)._addFa(this);
		}

		void _addFa(basicNode* fatherNode){
			fathers.push_back(fatherNode);
			fatherNum++;
		}
		
		void func(_type(*solveDat)(vector<_type>,int,_type)){
			solveData=solveDat; 
		}
		
		void searchSon(vector<basicNode<_type>*>* hiddenPoints,vector<basicNode<_type>*>* endPoints,vector<basicNode<_type>*>* edgeStack,vector<basicNode<_type>*>* nodeStack){
			(*nodeStack).push_back(this);
			for(int i=0;i<sonNum;i++){
				switch((*sons[i]).type){
					case FRONT_NODE:
					case MID_NODE:
						(*edgeStack).push_back(this);
						for(int j=0;j<(*hiddenPoints).length();j++)
							if((*hiddenPoints)[j]==sons[j])return;
						(*hiddenPoints).push_back(sons[i]);
						(*sons[i]).search(hiddenPoints,endPoints);
						break;
					case END_NODE:
						for(int i=0;i<(*endPoints).length();i++)
							if((*endPoints)[i]==sons[i])return;
						(*endPoints).push_back(sons[i]);						
						break;
				}
			}
		}
		
		void endResult(_type* res){
			result=res;
		}
		void exchangeTheta(_type newTheta){
			theta=newTheta;
		}
		void exchangeTheta(long id,_type newTheta){
			weight[id]=newTheta;
		}
		void exchangeDerta(_type newTheta){
			theta=newTheta+theta;
		}
		void exchangeDerta(long id,_type newTheta){
			weight[id]=newTheta+weight[id];
		}
		long long getSonNum(){
			return sonNum;
		}
/************************************************************************************************************************/
//save Node functions
		void saveNode(const char * __restrict__ _Filename){
		FILE* standard=stdout;
		freopen(_Filename,"w",stdout);
		cout<<"Node Theta:"<<theta<<endl;
		stdout=standard;
		}
		void saveNode(FILE* _FilePointer){
		FILE* standard=stdout;
		stdout=_FilePointer;
		cout<<"Node Theta:"<<theta<<endl;
		stdout=standard;
		}
/************************************************************************************************************************/
//read Node functions
		void readNode(const char * __restrict__ _Filename){
		FILE* standard=stdin;
		freopen(_Filename,"r",stdin);
		scanf("Node Theta:");
		cin>>theta;
		scanf("\n");
		stdin=standard;
		} 
		void readNode(FILE* _FilePointer){
		FILE* standard=stdin;
		stdin=_FilePointer;
		scanf("Node Theta:");
		cin>>theta;
		scanf("\n");
		stdin=standard;
		} 
/************************************************************************************************************************/
	private://private defines
		nodeType type;									
		_type* result;										
		vector<basicNode*>sons;								
		vector<basicNode*>fathers;							
		vector<_type(*)(_type,_type)>connections;					
		vector<_type>data;									
		vector<_type>weight;
		_type(*solveData)(vector<_type>,int,_type);
		long long fatherNum;
		long long sonNum;
		int dataPoint;
		_type singleWeight;									
		_type theta;								
/************************************************************************************************************************/
//private functions
		void resetData(){
			data.clear();
			dataPoint=0;
		}
	};
/************************************************************************************************************************/
//global functions
template<typename _type>
	void faltBack(vector<_type> inputs,vector<_type> outputs,vector<basicNode<_type>*>* inputPointsPointer,unsigned long long learnTimes,_type learnWeight,double(*resultFunction)(vector<_type>*,vector<_type>*,vector<_type>*)){//double resultFunciton(vector<_type>* wantOut,vector<_type*>* factOut,vector<_type>* oldOut) return weight:positive for
		vector<basicNode<_type>*> inputPoints=*inputPointsPointer;
		vector<basicNode<_type>*> hiddenPoints;
		vector<basicNode<_type>*> endPoints;
		vector<basicNode<_type>*> exchangeEdge;
		vector<basicNode<_type>*> exchangeNode;
		vector<_type*> outputsPoints;
		vector<_type> outputsPast;
		_type derta;
		int weight;
		bool lastIsNegative=false;
		for(long long i=0;i<inputPoints.length();i++)
		{
			exchangeEdge.push_back(inputPoints[i]);
			exchangeNode.push_back(inputPoints[i]);
			(*inputPoints)[i].searchSon(&hiddenPoints,&endPoints,&exchangeEdge,&exchangeNode);
		}//search nodes
		for(long long i=0;i<outputs.length();i++){
			endPoints.push_back(new _type);
			(*endPoints).endResult(outputsPoints[i]);
		}//set return points
		for(long long i=0;i<inputPoints.length();i++)
			(*inputPoints).giveData(inputs[i]);
		//input
		for(long long i=0;i<endPoints.length();i++)
			outputsPast.push_back(*endPoints[i]);
		//set outputs
		for(long long i=0;i=learnTimes;i++){
			//study
			for(long long j=0;j<exchangeEdge.length();j++)
				//start&mid nodes
				for(long long k=0;k<(*exchangeEdge[j]).getSonNum;k++)
				{
					//for each edge
					weight=1;
reset:				for(long long i=0;i<endPoints.length();i++)
						outputsPast[i]=*endPoints[i];
					//reset old output
					(*exchangeEdge[j]).exchangeDerta(k,learnWeight*weight);
					//reset weight
					for(long long i=0;i<inputPoints.length();i++)
						(*inputPoints).giveData(inputs[i]);
					//input
					if(resultFunction(&outputs,&endPoints,&outputsPast)>0){
						weight*=-1;
						if(lastIsNegative)
							weight*=0.5;
						else lastIsNegative=true;
					}
					else lastIsNegative=false;
					//change weight
					if(weight>=0.01||weight<=-0.01)
						goto reset;
					//loop
				}
			for(long long j=0;j<exchangeNode.length();j++){
					weight=1;
					//set weight
reset2:				for(long long i=0;i<endPoints.length();i++)
						outputsPast[i]=*endPoints[i];
					//reset old output
					(*exchangeEdge[j]).exchangeDerta(k,learnWeight*weight);
					//change weight
					for(long long i=0;i<inputPoints.length();i++)
						(*inputPoints).giveData(inputs[i]);
					//input
					if(resultFunction(&outputs,&endPoints,&outputsPast)>0){
						weight*=-1;
						if(lastIsNegative)
							weight*=0.5;
						else lastIsNegative=true;
					}
					else lastIsNegative=false;
					//change weight
					if(weight>=0.01||weight<=-0.01)
						goto reset2;
					//loop
			}
		}
	for(long long i=0;i<outputs.length();i++){
		delete endPoints[i];
	//free memory
}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值