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

📄 backpropagation.cpp

📁 以类库的形式实现了BP神经网络算法。可从该类基础上派生新类
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			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 + -