📄 backpropagation.cpp
字号:
return -1.0;
}
return m_XYMaxMin[2][varIndex-1];
}
}
//
/*
* 函数名称:SetExamMax()
* 函数介绍:设置样本最大值
* 输入参数:varIndex -参数序号
value -最大值
isX -是否输入参数
* 输出参数:
* 返回值 :true -成功
*/
bool CBackPropagation::SetExamMax(int varIndex, double value, int isX )
{
if (!m_XYMaxMin[0] || !m_XYMaxMin[2])
{
return false;
}
if (isX)
{
if (varIndex<1 || varIndex>m_InNodesNum)
{
return false;
}
m_XYMaxMin[0][varIndex-1] = value;
}
else
{
if (varIndex<1 || varIndex>m_OutNodesNum)
{
return false;
}
m_XYMaxMin[2][varIndex-1] = value;
}
return true;
}
/*
* 函数名称:GetExamMin()
* 函数介绍:获得样本最小值
* 输入参数:varIndex -参数序号
isX -是否输入参数
* 输出参数:
* 返回值 :最小值
*/
double CBackPropagation::GetExamMin(int varIndex, int isX)
{
if (!m_XYMaxMin[1] || !m_XYMaxMin[3])
{
return -1.0;
}
if (isX)
{
if (varIndex<1 || varIndex>m_InNodesNum)
{
return -1.0;
}
return m_XYMaxMin[1][varIndex-1];
}
else
{
if (varIndex<1 || varIndex>m_OutNodesNum)
{
return -1.0;
}
return m_XYMaxMin[3][varIndex-1];
}
}
/*
* 函数名称:SetExamMax()
* 函数介绍:设置样本最小值
* 输入参数:varIndex -参数序号
value -最小值
isX -是否输入参数
* 输出参数:
* 返回值 :true -成功
*/
bool CBackPropagation::SetExamMin(int varIndex, double value, int isX)
{
if (!m_XYMaxMin[1] || !m_XYMaxMin[3])
{
return false;
}
if (isX)
{
if (varIndex<1 || varIndex>m_InNodesNum)
{
return false;
}
m_XYMaxMin[1][varIndex-1] = value;
}
else
{
if (varIndex<1 || varIndex>m_OutNodesNum)
{
return false;
}
m_XYMaxMin[3][varIndex-1] = value;
}
return true;
}
/*
* 函数名称:UnitaryOper()
* 函数介绍:样本归一化
* 输入参数:
* 输出参数:
* 返回值 :true -成功
*/
bool CBackPropagation::UnitaryOper(void)
{
//释放归一化样本存储区
//FreeUnitMem();
//
////分配输入样本
//m_XUnitary = new double* [m_ExamplesNum];
//for (int nLoop=0; nLoop<m_ExamplesNum; nLoop++)
//{
// m_XUnitary[nLoop] = new double[m_InNodesNum];
//}
//
////分配输出样本
//m_YUnitary = new double* [m_ExamplesNum];
//for (int nLoop=0; nLoop<m_ExamplesNum; nLoop++)
//{
// m_YUnitary[nLoop] = new double[m_OutNodesNum];
//}
//
////网络输出
//m_YOutPut = new double* [m_ExamplesNum];
//for (int nLoop=0; nLoop<m_ExamplesNum; nLoop++)
//{
// m_YOutPut[nLoop] = new double[m_OutNodesNum];
//}
//
//归一化
int nI=0;
int nJ=0;
for (nI=0; nI<m_ExamplesNum; nI++)
{
for (nJ=0; nJ<m_InNodesNum; nJ++)
{
m_XUnitary[nI][nJ] = (m_XExamples[nI][nJ] - m_XYMaxMin[1][nJ]) / ( m_XYMaxMin[0][nJ] - m_XYMaxMin[1][nJ]);
}
for (nJ=0; nJ<m_OutNodesNum; nJ++)
{
m_YUnitary[nI][nJ] = (m_YExamples[nI][nJ] - m_XYMaxMin[3][nJ]) / ( m_XYMaxMin[2][nJ] - m_XYMaxMin[3][nJ]);
}
}
return true;
}
/*
* 函数名称:TranFunction()
* 函数介绍:传递函数
* 输入参数:x -输入值
* 输出参数:
* 返回值 :函数值
*/
double CBackPropagation::TranFunction(double x)
{
return 1.0 / (1+exp(-x));
//return (1-exp(-x)) / (1+exp(-x));
}
/*
* 函数名称:TranDFunction()
* 函数介绍:传递导函数
* 输入参数:x -输入值
* 输出参数:
* 返回值 :函数值
*/
double CBackPropagation::TranDFunction(double x)
{
double temp;
temp = 1.0 / (1+exp(-x));
return temp * (1-temp);
//return 2*exp(-x)/((1+exp(-x))*(1+exp(-x)));
}
/*
* 函数名称:Forward()
* 函数介绍:前馈
* 输入参数:
* 输出参数:
* 返回值 :true -成功
*/
bool CBackPropagation::Forward(int examIndex)
{
double sum = 0.0;
int nJ=0;
int nK=0;
int nL=0;
for(nJ=0; nJ<m_InNodesNum; nJ++)
{
m_BPNodes[0][nJ].val = m_XUnitary[examIndex][nJ];
}
for(nJ=0; nJ<(m_HidLayersNum+1); nJ++)
{
for(nK=0; nK<m_HideNodesNum[nJ+1]; nK++)
{
sum = 0.0;
for(nL=0; nL<m_HideNodesNum[nJ]; nL++)
{
sum += m_BPNodes[nJ][nL].val * m_Weight[nJ][nL][nK];
}
m_BPNodes[nJ+1][nK].net = sum;
m_BPNodes[nJ+1][nK].val = TranFunction(sum);
}
}
for(nJ=0; nJ<m_OutNodesNum; nJ++)
{
m_YOutPut[examIndex][nJ] = m_BPNodes[m_HidLayersNum+1][nJ].val;
}
return true;
}
/*
* 函数名称:Feedback()
* 函数介绍:反馈
* 输入参数:examIndex -样本编号
* 输出参数:
* 返回值 :true -成功
*/
bool CBackPropagation::Feedback(int examIndex)
{
double temp = 0.0;
int nI=0;
int nJ=0;
int nK=0;
int nL=0;
for(nI=0; nI<m_OutNodesNum; nI++)
{
m_BPNodes[m_HidLayersNum+1][nI].err = (m_BPNodes[m_HidLayersNum+1][nI].val - m_YUnitary[examIndex][nI])
* TranDFunction(m_BPNodes[m_HidLayersNum+1][nI].net);
}
for(nI=m_HidLayersNum; nI>=0; nI--)
{
for(nJ=0; nJ<m_HideNodesNum[nI]; nJ++)
{
temp = 0.0;
for(nK=0; nK<m_HideNodesNum[nI+1]; nK++)
{
temp += m_BPNodes[nI+1][nK].err * m_Weight[nI][nJ][nK];
}
m_BPNodes[nI][nJ].err = temp * TranDFunction(m_BPNodes[nI][nJ].net);
}
}
for(nJ=0; nJ<(m_HidLayersNum+1); nJ++)
{
for(nK=0; nK<m_HideNodesNum[nJ+1]; nK++)
{
for(nL=0; nL<m_HideNodesNum[nJ]; nL++)
{
m_Ajust[nJ][nL][nK] += m_BPNodes[nJ][nL].val * m_BPNodes[nJ+1][nK].err;
}
}
}
return true;
}
/*
* 函数名称:Train()
* 函数介绍:反馈
* 输入参数:trainTimes -训练次数
pace -步长
* 输出参数:
* 返回值 :true -成功
*/
bool CBackPropagation::Train(int trainTimes, double pace)
{
if (m_InNodesNum<1 || m_OutNodesNum<1 || m_HidLayersNum <0 || m_ExamplesNum < 1)
{
return false;
}
if (!m_XExamples || !m_YExamples || !m_Weight)
{
return false;
}
//释放反馈误差内存
FreeAjustMem();
//分配反馈误差存储区
int nI=0;
int nJ=0;
m_Ajust = new double** [m_HidLayersNum+1];
for (nI=0; nI<(m_HidLayersNum+1); nI++)
{
m_Ajust[nI] = new double* [m_HideNodesNum[nI]];
for (nJ=0; nJ<m_HideNodesNum[nI]; nJ++)
{
m_Ajust[nI][nJ] = new double [m_HideNodesNum[nI+1]];
}
}
InitAjust();
CacMaxMin();
//归一化
if (!UnitaryOper())
{
return false;
}
for(nI=0; nI<trainTimes; nI++)
{
for (nJ=0; nJ<m_ExamplesNum; nJ++)
{
Forward(nJ);
Feedback(nJ);
}
//显示误差
ShowErr(nI+1, CalErr());
Ajust(pace);
InitAjust();
}
return true;
}
/*
* 函数名称:Calculate()
* 函数介绍:网络计算
* 输入参数:
* 输出参数:
* 返回值 :true -成功
*/
bool CBackPropagation::Calculate()
{
if (m_InNodesNum<1 || m_OutNodesNum<1 || m_HidLayersNum <0 || m_ExamplesNum < 1)
{
return false;
}
if (!m_XExamples || !m_Weight)
{
return false;
}
//归一化
if (!UnitaryOper())
{
return false;
}
int nI=0;
for (nI=0; nI<m_ExamplesNum; nI++)
{
Forward(nI);
}
return true;
}
/*
* 函数名称:GetResult()
* 函数介绍:返回指定的输出值
* 输入参数:examIndex -样本编号
index -输出值编号
* 输出参数:
* 返回值 :输出结果
*/
double CBackPropagation::GetResult(int examIndex, int index)
{
return m_YOutPut[examIndex-1][index-1]*(m_XYMaxMin[2][index-1]-m_XYMaxMin[3][index-1])
+ m_XYMaxMin[3][index-1];
}
/*
* 函数名称:InitAjust()
* 函数介绍:初始化反馈误差
* 输入参数:
* 输出参数:
* 返回值 :true -成功
*/
bool CBackPropagation::InitAjust(void)
{
//初始化
int nI=0;
int nJ=0;
int nK=0;
for (nI=0; nI<(m_HidLayersNum+1); nI++)
{
for (nJ=0; nJ<m_HideNodesNum[nI]; nJ++)
{
for (nK=0; nK<m_HideNodesNum[nI+1]; nK++)
{
m_Ajust[nI][nJ][nK] = 0.0;
}
}
}
return true;
}
/*
* 函数名称:Ajust()
* 函数介绍:权重调整
* 输入参数:
* 输出参数:
* 返回值 :true -成功
*/
bool CBackPropagation::Ajust(double pace)
{
int nI=0;
int nJ=0;
int nK=0;
for (nI=0; nI<(m_HidLayersNum+1); nI++)
{
for (nJ=0; nJ<m_HideNodesNum[nI]; nJ++)
{
for (nK=0; nK<m_HideNodesNum[nI+1]; nK++)
{
m_Weight[nI][nJ][nK] -= pace*m_Ajust[nI][nJ][nK];
}
}
}
return true;
}
/*
* 函数名称:CalErr()
* 函数介绍:误差计算
* 输入参数:
* 输出参数:
* 返回值 :误差
*/
double CBackPropagation::CalErr()
{
double errSum = 0.0;
int nI=0;
int nJ=0;
for (nI=0; nI<m_ExamplesNum; nI++)
{
for (nJ=0; nJ<m_OutNodesNum; nJ++)
{
errSum += fabs((GetResult(nI+1, nJ+1)-m_YExamples[nI][nJ]) / m_YExamples[nI][nJ]);
}
}
return errSum / (m_ExamplesNum*m_OutNodesNum);
}
/*
* 函数名称:ShowErr()
* 函数介绍:误差显示
* 输入参数:times -学习次数
err -误差
* 输出参数:
* 返回值 :true -成功
*/
void CBackPropagation::ShowErr(int times, double err)
{
//从子类中覆盖该函数
}
/*
* 函数名称:FreeExam()
* 函数介绍:释放样本存储区
* 输入参数:
* 输出参数:
* 返回值 :
*/
void CBackPropagation::FreeExamMem(void)
{
if (m_XExamples)
{
//释放输入样本内存
for (int nLoop=0; nLoop<m_ExamplesNum; nLoop++)
{
delete [] m_XExamples[nLoop];
}
delete [] m_XExamples;
m_XExamples = NULL;
}
if (m_YExamples)
{
//释放输出样本内存
for (int nLoop=0; nLoop<m_ExamplesNum; nLoop++)
{
delete [] m_YExamples[nLoop];
}
delete [] m_YExamples;
m_YExamples = NULL;
}
}
/*
* 函数名称:FreeUnitMem()
* 函数介绍:释放归一化样本存储区
* 输入参数:
* 输出参数:
* 返回值 :
*/
void CBackPropagation::FreeUnitMem(void)
{
if (m_XUnitary)
{
//释放输入样本内存
for (int nLoop=0; nLoop<m_ExamplesNum; nLoop++)
{
delete [] m_XUnitary[nLoop];
}
delete [] m_XUnitary;
m_XUnitary = NULL;
}
if (m_YUnitary)
{
//释放输出样本内存
for (int nLoop=0; nLoop<m_ExamplesNum; nLoop++)
{
delete [] m_YUnitary[nLoop];
}
delete [] m_YUnitary;
m_YUnitary = NULL;
}
if (m_YOutPut)
{
for (int nLoop=0; nLoop<m_ExamplesNum; nLoop++)
{
delete [] m_YOutPut[nLoop];
}
delete [] m_YOutPut;
m_YOutPut = NULL;
}
}
/*
* 函数名称:FreeHideMem()
* 函数介绍:释放隐含层数目内存
* 输入参数:
* 输出参数:
* 返回值 :
*/
void CBackPropagation::FreeHideMem(void)
{
if (m_HideNodesNum)
{
delete [] m_HideNodesNum;
m_HideNodesNum = NULL;
}
}
/*
* 函数名称:FreeWeigMem()
* 函数介绍:释放权重内存
* 输入参数:
* 输出参数:
* 返回值 :
*/
void CBackPropagation::FreeWeigMem(void)
{
int nI=0;
int nJ=0;
if (m_Weight)
{
for (nI=0; nI<(m_HidLayersNum+1); nI++)
{
for (nJ=0; nJ<m_HideNodesNum[nI]; nJ++)
{
delete [] m_Weight[nI][nJ];
}
delete [] m_Weight[nI];
}
delete [] m_Weight;
m_Weight = NULL;
}
}
/*
* 函数名称:FreeMaxMinMem()
* 函数介绍:释放样本最值内存
* 输入参数:
* 输出参数:
* 返回值 :
*/
void CBackPropagation::FreeMaxMinMem(void)
{
if (m_XYMaxMin)
{
delete [] m_XYMaxMin[0];
delete [] m_XYMaxMin[1];
delete [] m_XYMaxMin[2];
delete [] m_XYMaxMin[3];
}
}
/*
* 函数名称:FreeNodesMem()
* 函数介绍:释放节点信息内存
* 输入参数:
* 输出参数:
* 返回值 :
*/
void CBackPropagation::FreeNodesMem(void)
{
int nI=0;
if (m_BPNodes)
{
for (nI=0; nI<(m_HidLayersNum+2); nI++)
{
delete [] m_BPNodes[nI];
}
delete [] m_BPNodes;
m_BPNodes = NULL;
}
}
/*
* 函数名称:FreeAjustMem()
* 函数介绍:释放反馈误差内存
* 输入参数:
* 输出参数:
* 返回值 :
*/
void CBackPropagation::FreeAjustMem(void)
{
int nI=0;
int nJ=0;
if (m_Ajust)
{
for (nI=0; nI<(m_HidLayersNum+1); nI++)
{
for (nJ=0; nJ<m_HideNodesNum[nI]; nJ++)
{
delete [] m_Ajust[nI][nJ];
}
delete [] m_Ajust[nI];
}
delete [] m_Ajust;
m_Ajust = NULL;
}
}
/*
* 函数名称:~CBackPropagation()
* 函数介绍: 析构函数
* 输入参数:
* 输出参数:
* 返回值 :
*/
CBackPropagation::~CBackPropagation(void)
{
//释放样本存储区
FreeExamMem();
//释放权重内存
FreeWeigMem();
//释放反馈误差内存
FreeAjustMem();
//释放隐含层数目内存
FreeHideMem();
//释放样本最值内存
FreeMaxMinMem();
//释放节点信息内存
FreeNodesMem();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -