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

📄 layer.cpp

📁 函数逼近
💻 CPP
字号:
/*
 * 
 *	 Copyright 2004-2006 Ghassan OREIBY
 *   
 * 	 This file is part of Neurality.
 *
 *   Neurality is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   Neurality is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *   along with Neurality; if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * 
 */


//#include "NeuralNetwork.h"
#include "layer.h"


CLayer::CLayer(void)
: pNodeStruct(NULL)
, pbackLayerList(NULL)
, nNodeNumber(0)
{
}

CLayer::CLayer(int nNodeNum):pbackLayerList(NULL), nNodeNumber(nNodeNum)
{
	NodeStructureWithoutWeight	*ptempNodeStruct = NULL, *pothertempNodeStruct;
	int	i;

	pNodeStruct = NULL;
	for (i = 0; i < nNodeNum; i++)
	{
		pothertempNodeStruct = new NodeStructureWithoutWeight;
		pothertempNodeStruct->Next = NULL;
		pothertempNodeStruct->Node = new CNode;
		if (ptempNodeStruct) 
		{
			ptempNodeStruct->Next = pothertempNodeStruct;
			ptempNodeStruct = ptempNodeStruct->Next;
		}
		else
		{
			ptempNodeStruct = pothertempNodeStruct;
			pNodeStruct = ptempNodeStruct;
		}		
	}
}

CLayer::~CLayer(void)
{
	NodeStructureWithoutWeight	*nodestruct	= pNodeStruct;
	LayerStruct					*layerstruct= pbackLayerList; 

	while (pNodeStruct)
	{
		nodestruct = pNodeStruct->Next;
		delete pNodeStruct->Node;
		delete pNodeStruct;
		pNodeStruct = nodestruct;
	}
	while (pbackLayerList)
	{
		layerstruct = pbackLayerList->Next;
		delete pbackLayerList;
		pbackLayerList = layerstruct;
	}
}

// create a back connection between this layer and the pbackLayer
bool CLayer::MakeConnection(CLayer* pbackLayer)
{
	LayerStruct	*ptempbackLayerList = pbackLayerList,
				*pnewbackLayer;
	NodeStructureWithoutWeight	*ptempNodeStruct	= pNodeStruct,
								*ptempbackNodeStruct= pbackLayer->pNodeStruct;

	if (pbackLayer == NULL)
		return false;		//No layer assigned
	if (pbackLayer->pNodeStruct == NULL)
		return false;		//A layer without nodes
	/*if (pbackLayerList != NULL)
		if ((ptempbackLayerList->Next == NULL) && (ptempbackLayerList->pLayer == pbackLayer))
			return false;*/		//if the layer already connected to this layer and is the 1st one in list
	while (ptempbackLayerList)
	{
		if (pbackLayer == ptempbackLayerList->pLayer)
			return false;	//if the layer already connected to this layer
		ptempbackLayerList = ptempbackLayerList->Next;
	}

	pnewbackLayer			= new LayerStruct;	//adding this layer to the list if not already connected
	pnewbackLayer->pLayer	= pbackLayer;
	pnewbackLayer->Next		= NULL;
	if (pbackLayerList == NULL)
		pbackLayerList = pnewbackLayer;
	else	
	{
		ptempbackLayerList = pbackLayerList;
		while (ptempbackLayerList->Next)
			ptempbackLayerList = ptempbackLayerList->Next;
		ptempbackLayerList->Next= pnewbackLayer;
	}

	//connecting every node in this layer to all other nodes in the back layer
	while (ptempNodeStruct)	
	{
		while (ptempbackNodeStruct)
		{
			ptempNodeStruct->Node->MakeConnection(ptempbackNodeStruct->Node, WEIGHTRANGE - 2 * rand() * WEIGHTRANGE / RAND_MAX);
			ptempbackNodeStruct	= ptempbackNodeStruct->Next;
		}
		ptempbackNodeStruct	= pbackLayer->pNodeStruct;
		
		ptempNodeStruct	= ptempNodeStruct->Next;
	}
        
	return true;	//return true if the connection has been successfull
}



//Compute the output of each node in the layer
void CLayer::ComputeLayer(void)
{
	NodeStructureWithoutWeight	*ptempNodeStruct = pNodeStruct;

	while (ptempNodeStruct)
	{
		ptempNodeStruct->Node->ComputeOutput();
		ptempNodeStruct = ptempNodeStruct->Next;
	}

}

//////////////////////////////////////////////////////////
//		BackPropagation Part							//
//////////////////////////////////////////////////////////


// Reset errors for all the nodes inside the layer
void CLayer::ResetError(void)
{
	NodeStructureWithoutWeight	*tempNodeStruct = pNodeStruct;

	while (tempNodeStruct)
	{
		tempNodeStruct->Node->ResetError();
		tempNodeStruct = tempNodeStruct->Next;
	}

}

// Back Progapagate error on each node of the layer
void CLayer::backPropagateError(void) const
{
	NodeStructureWithoutWeight	*tempNodeStruct = pNodeStruct;

	while (tempNodeStruct)
	{
		tempNodeStruct->Node->backPropagateError();
		tempNodeStruct = tempNodeStruct->Next;
	}

}

// Connects the elements of layer to a node (usually the threshold node)

void CLayer::MakeConnection(CNode* ThresholdNode)
{
	NodeStructureWithoutWeight	*tempNodeStruct = pNodeStruct;

	while (tempNodeStruct)
	{
		tempNodeStruct->Node->MakeConnection(ThresholdNode, WEIGHTRANGE - 2 * rand() * WEIGHTRANGE / RAND_MAX);
		tempNodeStruct = tempNodeStruct->Next;
	}
}

// Correct weights after backpropagating (batch mode)
void CLayer::CorrectWeights(void)
{
	NodeStructureWithoutWeight*	tempNodeStruct = pNodeStruct;

	while (tempNodeStruct)
	{
		tempNodeStruct->Node->CorrectWeights();
		tempNodeStruct = tempNodeStruct->Next;
	}
}

// Returns the number of nodes inside this layer
int CLayer::GetNodeNumber(void)
{
	return nNodeNumber;
}

// Returns the weights for the node contained in this layer
int CLayer::GetWeights(real **reWeights) const
{
	int nReturn = 0, *nConnection = new int[nNodeNumber], i = 0, j = 0, k = 0;
	NodeStructureWithoutWeight	*tempNodeStruct = pNodeStruct;
	real	**reTempWeights = new real*[nNodeNumber];
	real	*preWeight = NULL;

    while (tempNodeStruct)
	{
		nConnection[i]= tempNodeStruct->Node->GetWeights(reTempWeights + i);
		nReturn += nConnection[i++];
		tempNodeStruct = tempNodeStruct->Next;
	}
	preWeight = new real[nReturn];

    for (i = 0; i < nNodeNumber; i++)
	{
		for (j = 0; j < nConnection[i]; j++)
			preWeight[k++] = *(reTempWeights[i] + j);
		delete[] reTempWeights[i];
	}
    
	delete[] reTempWeights;
	delete[] nConnection;

	*reWeights = preWeight;	
	return nReturn;	
}

// Same as GetWeights(real**) but with more params in it (to resume learning later)
int CLayer::GetWeights(WeightStruct** NodeParams) const
{
	int nReturn = 0, *nConnection = new int[nNodeNumber], i = 0, j = 0, k = 0;
	NodeStructureWithoutWeight	*tempNodeStruct = pNodeStruct;
	WeightStruct	**reTempWeights = new WeightStruct*[nNodeNumber];
	WeightStruct	*preWeight = NULL;

    while (tempNodeStruct)
	{
		nConnection[i]= tempNodeStruct->Node->GetWeights(reTempWeights + i);
		nReturn += nConnection[i++];
		tempNodeStruct = tempNodeStruct->Next;
	}
	preWeight = new WeightStruct[nReturn];

    for (i = 0; i < nNodeNumber; i++)
	{
		for (j = 0; j < nConnection[i]; j++)
			preWeight[k++] = *(reTempWeights[i] + j);
		delete[] reTempWeights[i];
	}
    
	delete[] reTempWeights;
	delete[] nConnection;

	*NodeParams = preWeight;	
	return nReturn;	
}

⌨️ 快捷键说明

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