📄 cbpnlayer.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 + -