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