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

📄 cbpnlayer.cpp

📁 BP神经网络程序
💻 CPP
字号:
///////////////////////////////
////cbpnlayer.cpp
//
#include "StdAfx.h"
#include "BPNLayer.h"
IMPLEMENT_SERIAL(CBPNLayer, CObject, 1 )

CBPNLayer::CBPNLayer()
{
//empty
	m_iLayerNum=0;
	m_ntTranslateFunction=NEURON_LIM;
	m_dStudyRate=0;
	m_dMomentum=0;
	m_piLayerCapture=0;
	m_ppnBPnet=0;
	m_pdDerivTempA=0;//使临时指针为空指针
	m_pdDerivTempB=0;//
}

CBPNLayer::CBPNLayer(int LayerNum,int *pLayerCapture,NEURONTYPE TranslateFunctionType
					 ,double StudyRate,double Momentum)
{
	m_iLayerNum=LayerNum-1;            //LayerNum包括输入层,m_iLayerNum不包括输入层
	m_piLayerCapture=pLayerCapture;    //每层包含的神经元个数数组指针
	m_ntTranslateFunction=TranslateFunctionType;
	m_dStudyRate=StudyRate;
	m_dMomentum=Momentum;//动量因子
	m_ppnBPnet=new CNeuCell**[m_iLayerNum];//创建神经元二重指针
	m_pdDerivTempA=0;//使临时指针为空指针
	m_pdDerivTempB=0;//
	for (int i=0;i<m_iLayerNum;i++)//创建神经元对象
	{
		m_ppnBPnet[i]=new CNeuCell*[*(m_piLayerCapture+i+1)];//先创建神经元层指针
		for (int j=0;j<*(m_piLayerCapture+i+1);j++)
		{
			*(m_ppnBPnet[i]+j)=new CNeuCell;
			(*(m_ppnBPnet[i]+j))->SetNeuCell(0,m_ntTranslateFunction,*(m_piLayerCapture+i));
		}
		
	}
}

CBPNLayer::~CBPNLayer()
{
	for (int i=0;i<m_iLayerNum;i++)
	{
		delete [] m_ppnBPnet[i];	
	}
	if (m_ppnBPnet)
	{
		delete [] m_ppnBPnet;
	}	
	if (m_pdDerivTempA)
	{
		delete [] m_pdDerivTempA;
	}
	if (m_pdDerivTempB)
	{
		delete [] m_pdDerivTempB;
	}
	
}

void CBPNLayer::SetBPNet(int LayerNum,int *pLayerCapture,NEURONTYPE TranslateFunctionType
						 ,double StudyRate,double Momentum)
{
	for (int i=0;i<m_iLayerNum;i++)
	{
		delete [] m_ppnBPnet[i];
	}
	if (m_ppnBPnet)
	{
		delete [] m_ppnBPnet;
	}
	
	if (m_pdDerivTempA)
	{
		delete [] m_pdDerivTempA;
	}
	if (m_pdDerivTempB)
	{
		delete [] m_pdDerivTempB;
	}
	
	m_iLayerNum=LayerNum-1;            //LayerNum包括输入层,m_iLayerNum不包括输入层
	m_piLayerCapture=pLayerCapture;    //每层包含的神经元个数数组指针
	m_ntTranslateFunction=TranslateFunctionType;
	m_dStudyRate=StudyRate;
	m_dMomentum=Momentum;
	m_ppnBPnet=new CNeuCell**[m_iLayerNum];//创建神经元二重指针
	m_pdDerivTempA=0;//使临时指针为空指针
	m_pdDerivTempB=0;//
	for (int i=0;i<m_iLayerNum;i++)//创建神经元对象
	{
		m_ppnBPnet[i]=new CNeuCell*[*(m_piLayerCapture+i+1)];//先创建神经元层指针
		for (int j=0;j<*(m_piLayerCapture+i+1);j++)
		{
			*(m_ppnBPnet[i]+j)=new CNeuCell;
			(*(m_ppnBPnet[i]+j))->SetNeuCell(0,m_ntTranslateFunction,*(m_piLayerCapture+i));
		}
		
	}
}

void CBPNLayer::SetStudyRate(double StudyRate)
{
	m_dStudyRate=StudyRate;
}
void CBPNLayer::SetMomentum(double Momentum)
{
	m_dMomentum=Momentum;
}
void CBPNLayer::SetNeuronWeight(int LayerNum,int NueronSequence,int NodeSequence,double InputData)
{
	(*(m_ppnBPnet[LayerNum-1]+NueronSequence))->InputW(NueronSequence,InputData);
}
void CBPNLayer::Input(double *dInput,double *ResualtExpect)
{
	m_pdInput=dInput;
	m_pdResualtExpect=ResualtExpect;
	for (int i=0;i<*(m_piLayerCapture+1);i++)//将输入值输入第一层的每个神经元
	{
		for (int j=0;j<*(m_piLayerCapture);j++)
		{
			(*(m_ppnBPnet[0]+i))->InputV(j,*(m_pdInput+j));
		}
	}
}

void CBPNLayer::Run()
{
	double AddTemp=0; //用以存放计算δ时的中间变量
//////////////////////////////////////////////////////////////////////////
//前向计算
	for (int i=1;i<m_iLayerNum;i++)//从第二层开始,每层接受第一层的输出,i为层C序号
	{
		for (int j=0;j<*(m_piLayerCapture+i+1);j++)//j为i层神经元C序号
		{	
			for (int k=0;k<*(m_piLayerCapture+i);k++)//k为i上一层神经元c序号
			{
				(*(m_ppnBPnet[i]+j))->InputV(k,(*(m_ppnBPnet[i-1]+k))->Output(1));
			}	
		}
	}
	
	/////////////////////////////////////////////////////////////////
	m_pdDerivTempA=new double[*(m_piLayerCapture+m_iLayerNum)];//分配内存,建立最后一层δ数组
	for (int i=0;i<*(m_piLayerCapture+m_iLayerNum);i++)//得到最后一层每个神经元的δ值并存入数组
	{
		(*(m_ppnBPnet[m_iLayerNum-1]+i))->Output(1);
		m_pdDerivTempA[i]=((*(m_ppnBPnet[m_iLayerNum-1]+i))->Output()-m_pdResualtExpect[i])
			*(*(m_ppnBPnet[m_iLayerNum-1]+i))->GetDeriv();
		for (int j=0;j<*(m_piLayerCapture+m_iLayerNum-1);j++)
		{
			(*(m_ppnBPnet[m_iLayerNum-1]+i))->InputW(j,(*(m_ppnBPnet[m_iLayerNum-1]+i))->GetW(j)-
				m_dStudyRate*m_pdDerivTempA[i]*((*m_ppnBPnet[m_iLayerNum-1]+i))->GetV(j)+
				m_dMomentum*(*(m_ppnBPnet[m_iLayerNum-1]+i))->GetDivW(j));			
		}
	}

	for (int i=m_iLayerNum-2;i>=0;i--)//调整除最后一层的神经元权值,循环从到数第二层到第一层
	{                                 //i为C层数
		if (m_pdDerivTempA)//判断现在权值在哪个临时数组中存放
		{
			m_pdDerivTempB=new double[*(m_piLayerCapture+i+1)];//创建另一临时数组
			
			//for (int j=*(m_piLayerCapture+i+1);j>=0;j--)   //j为i层C神经元序号
			for (int j=0;j<*(m_piLayerCapture+i+1);j++) 
			{	
				for (int k=0;k<*(m_piLayerCapture+i+2);k++)  //k为i+1层神经元序号
				{
					AddTemp+=m_pdDerivTempA[k] * (*(m_ppnBPnet[i+1]+k))->GetW(j);//得到神经元δ中的阶和
				}
				m_pdDerivTempB[j]=AddTemp*((*(m_ppnBPnet[i]+j))->GetDeriv());//得到δ值
				AddTemp=0;
				//for (int k=*(m_piLayerCapture+i);k>=0;k--)//k为本层神经元C序号
				for (int k=0;k<*(m_piLayerCapture+i);k++)
				{
					(*(m_ppnBPnet[i]+j))->InputW(k,(*(m_ppnBPnet[i]+j))->GetW(k)-m_dStudyRate
						*m_pdDerivTempB[j]*(*(m_ppnBPnet[i]+j))->GetV(k)+m_dMomentum*
						(*(m_ppnBPnet[i]+j))->GetDivW(k));//调整权值
				}	
			}
			delete [] m_pdDerivTempA;//释放上一层δ数组
			m_pdDerivTempA=0;//置零
		}
		else
		{
			m_pdDerivTempA=new double[*(m_piLayerCapture+i+1)];//创建另一临时数组
			
			//for (int j=*(m_piLayerCapture+i+1);j>=0;j--)   //j为i层C神经元序号
			for (int j=0;j<*(m_piLayerCapture+i+1);j++) 
			{	
				for (int k=0;k<*(m_piLayerCapture+i+2);k++)  //k为i+1层神经元序号
				{
					AddTemp+=m_pdDerivTempB[k] * (*(m_ppnBPnet[i+1]+k))->GetW(j);//得到神经元δ中的阶和
				}
				m_pdDerivTempA[j]=AddTemp*(*(m_ppnBPnet[i]+j))->GetDeriv();//得到δ值
				AddTemp=0;
				//for (int k=*(m_piLayerCapture+i);k>=0;k--)//k为本层神经元C序号
				for (int k=0;k<*(m_piLayerCapture+i);k++)
				{
					(*(m_ppnBPnet[i]+j))->InputW(k,(*(m_ppnBPnet[i]+j))->GetW(k)-m_dStudyRate
						*m_pdDerivTempA[j]*(*(m_ppnBPnet[i]+j))->GetV(k)+m_dMomentum*
						(*(m_ppnBPnet[i]+j))->GetDivW(k));//调整权值
				}	
			}
			delete [] m_pdDerivTempB;//释放上一层δ数组
			m_pdDerivTempB=0;//置零
			
		}
	}
	if (m_pdDerivTempA)
	{
		delete [] m_pdDerivTempA;
		m_pdDerivTempA=0;
	}
	if (m_pdDerivTempB)
	{
		delete [] m_pdDerivTempB;
		m_pdDerivTempB=0;
	}
}

void CBPNLayer::Expend()
{
	for (int i=1;i<m_iLayerNum;i++)//从第二层开始,每层接受第一层的输出,i为层C序号
	{
		for (int j=0;j<*(m_piLayerCapture+i+1);j++)//j为i层神经元C序号
		{	
			for (int k=0;k<*(m_piLayerCapture+i);k++)//k为i上一层神经元c序号
			{
				(*(m_ppnBPnet[i]+j))->InputV(k,(*(m_ppnBPnet[i-1]+k))->Output(1));
			}	
		}
	}
}

double CBPNLayer::GetNeuronValue(int LayerNum,int NueronSequence)//输入层 为0层,第一个神经元编号为0
{
		return (*(m_ppnBPnet[LayerNum-1]+NueronSequence))->Output();
}
double CBPNLayer::GetNeuronWeight(int LayerNum,int NueronSequence,int NodeSequence)//输入层 为0层,第一个神经元编号为0
{
	if (LayerNum==0)
	{
		return 1;
	}
	else
	return (*(m_ppnBPnet[LayerNum-1]+NueronSequence))->GetW(NodeSequence);
}

double CBPNLayer::GetResualt(int OutputNumth)
{		
	return (*(m_ppnBPnet[m_iLayerNum-1]+OutputNumth))->Output();
}

void CBPNLayer::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		ar<<m_dStudyRate<<m_iLayerNum<<m_ntTranslateFunction<<m_dMomentum;
		for (int i=0;i<m_iLayerNum+1;i++)
		{
			ar<<m_piLayerCapture[i];
		}
		for (int i=0;i<m_piLayerCapture[0];i++)
		{
			ar<<m_pdInput[i];
		}
		for (int i=0;i<m_piLayerCapture[m_iLayerNum];i++)
		{
			ar<<m_pdResualtExpect[i];
		}
		
		for (int i=0;i<m_iLayerNum;i++)
		{
			for (int j=0;j<m_piLayerCapture[i+1];j++)
			{
				ar<<(*(*(m_ppnBPnet+i)+j));
			}
		}
		
	}
	else
	{
		ar>>m_dStudyRate>>m_iLayerNum>>m_ntTranslateFunction>>m_dMomentum;
		m_piLayerCapture=new int[m_iLayerNum+1];
		for (int i=0;i<m_iLayerNum+1;i++)
		{
			ar>>m_piLayerCapture[i];
		}
		m_pdInput=new double[m_piLayerCapture[0]];
		for (int i=0;i<m_piLayerCapture[0];i++)
		{
			ar>>m_pdInput[i];
		}
		m_pdResualtExpect=new double[m_piLayerCapture[m_iLayerNum]];
		for (int i=0;i<m_piLayerCapture[m_iLayerNum];i++)
		{
			ar>>m_pdResualtExpect[i];
		}
		m_ppnBPnet=new CNeuCell**[m_iLayerNum];
		for (int i=0;i<m_iLayerNum;i++)//创建神经元对象
		{
			m_ppnBPnet[i]=new CNeuCell*[*(m_piLayerCapture+i+1)];
			for (int j=0;j<*(m_piLayerCapture+i+1);j++)
			{
				ar>>(*(*(m_ppnBPnet+i)+j));
			}	
		}
	}
}

⌨️ 快捷键说明

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