moin, also vornweg ich studiere noch nicht und geh erst bald in die 12. klasse, allerdings kann ich c++ und wollt mich mit neuronalen netzen beschäftigen.
darum meine fragen zur problemfunktion:
sie basiert, und das habe ich schon herausgefunden auf diesen beiden gleichungen, siehe
http://www.gc.ssr.upm.es/inves/neural/a…cepts/basis.htm
float *simpleNet::run(float *input){ //complete run through the net
setZero(); //set needed matrices to zero
for(int i=0; i<amountI; i++) //save input-vector
inI[i]=input[i];
for(int i=0; i<amountI; i++) //special case here: inI=outI
outI[i]=inI[i];
outI[amountI]=1; //shift neuron = 1
for(int i=0; i<amountH; i++) //get input of hidden layer
for(int j=0; j<=amountI; j++)
inH[i]+=ihWeights[j][i]*outI[j];
for(int i=0; i<amountH; i++) //get output of hidden layer (sigmoide function)
outH[i]=1/(1+exp(-inH[i]));
outH[amountH]=1; //shift neuron = 1
for(int i=0; i<amountO; i++) //get input of output layer
for(int j=0; j<=amountH; j++)
inO[i]+=hoWeights[j][i]*outH[j];
for(int i=0; i<amountO; i++) //get output of output layer (sigmoide function)
outO[i]=1/(1+exp(-inO[i]));
return outO;
}
Alles anzeigen
wenn ich mich nicht irre, ist dass die basisfunktiion:
for(int i=0; i<amountH; i++) //get input of hidden layer
for(int j=0; j<=amountI; j++)
inH[i]+=ihWeights[j][i]*outI[j];
und dass die aktivierungsfunktion:
for(int i=0; i<amountH; i++) //get output of hidden layer (sigmoide function)
outH[i]=1/(1+exp(-inH[i]));
so weit so einfach, ich weiß schon mal das die gewichte die verhältnisse zw. den neuronen regeln und deshalb deshalb ein produkt gebildet wird. aber warum diese aufsummierung? (inH[i]+=) das array ist doch im prinzip an dieser stelle leer und die funktion dürfte im programm nur einmal durchlaufen?
dann versteh ich den sinn der aktivierungsfunktion an sich nicht. und ich weiß auch nicht wie man die daten, die durch diese funktion später zurückgegeben werden am besten nutzt.
(zum beispiel um zuzuordnen um welche ziffer es sich bei einen bild handelt, wenn man das netz auf bilderkennung trainiert hat)
als letztes wär ich noch dankbar wenn man mir den misteryösen schwellwert erklären könnte der in diesem netz anscheinen keine rolle in irgen einer berechung spielt. jdenfalls sehe ich in
outH[amountH]=1;
keinen weiteren sinn.
ich wäre wirklich unendlich dankbar wenn mir jemand helfen würde und mir diese probleme auf einfache art erklärt.
class simpleNet{
private:
float **ihWeights, **hoWeights;
float **ihWDelta, **hoWDelta;
float *inI, *inH, *inO;
float *outI, *outH, *outO;
float *errH, *errO, *prefO, *diffO;
int amountI, amountH, amountO;
float errTol, learnRate, absorp;
void setZero();
public:
simpleNet(int dimI, int dimH, int dimO);
simpleNet(int dimI, int dimH, int dimO, float **ihW, float **hoW);
~simpleNet();
float *getOutput();
float *getODiff();
void setErrTolerance(float tol);
void setLearnRate(float rate);
void setAbsorp(float abs);
float *run(float *input);
bool train(float *input, float *pOutput);
};
/////////////////////////////////////////////////////////////////////////////////
simpleNet::simpleNet(int dimI, int dimH, int dimO){
srand(time(NULL));
amountI=dimI; amountH=dimH; amountO=dimO; //save dimensions of the net
ihWeights=new float*[amountI+1]; //create weight matrices
for(int i=0; i<=amountI; i++)
ihWeights[i]=new float[amountH];
hoWeights=new float*[amountH+1];
for(int i=0; i<=amountH; i++)
hoWeights[i]=new float[amountO];
ihWDelta=new float*[amountI+1]; //create weight difference matrices
for(int i=0; i<=amountI; i++)
ihWDelta[i]=new float[amountH];
hoWDelta=new float*[amountH+1];
for(int i=0; i<=amountH; i++)
hoWDelta[i]=new float[amountO];
for(int i=0; i<=amountI; i++) //fill with rand values (-0.3...0.3)
for(int j=0; j<amountH; j++)
ihWeights[i][j]=(float)rand()/RAND_MAX*6/10-0.3;
for(int i=0; i<=amountH; i++)
for(int j=0; j<amountO; j++)
hoWeights[i][j]=(float)rand()/RAND_MAX*6/10-0.3;
prefO=new float[amountO]; //allocate mem for other matrices
inI=new float[amountI];
inH=new float[amountH];
inO=new float[amountO];
outI=new float[amountI+1];
outH=new float[amountH+1];
outO=new float[amountO];
errH=new float[amountH+1];
errO=new float[amountO];
diffO=new float[amountO];
learnRate=0.25; //setting default learning rate
errTol=0.1; //setting default error tolerance
absorp=0.7; //setting default absorption rate
}
simpleNet::simpleNet(int dimI, int dimH, int dimO, float **ihW, float **hoW){
simpleNet(dimI,dimH,dimO);
for(int i=0; i<=amountI; i++) //create weight matrices with user-defined values
for(int j=0; j<=amountH; j++)
ihWeights[i][j]=ihW[i][j];
for(int i=0; i<=amountH; i++)
for(int j=0; j<=amountO; j++)
hoWeights[i][j]=hoW[i][j];
}
simpleNet::~simpleNet(){ //free allocated mem
delete ihWeights; delete hoWeights; delete prefO; delete inI;
delete inH; delete inO; delete outI; delete outH; delete outO;
delete errH; delete errO; delete diffO; delete ihWDelta; delete hoWDelta;
}
void simpleNet::setZero(){
for(int i=0; i<amountI; i++){
inI[i]=0;
outI[i]=0;
}
for(int i=0; i<amountH; i++){
inH[i]=0;
outH[i]=0;
errH[i]=0;
}
for(int i=0; i<amountO; i++){
inO[i]=0;
outO[i]=0;
errO[i]=0;
}
}
float *simpleNet::getOutput(){
return outO;
}
float *simpleNet::getODiff(){
return diffO;
}
void simpleNet::setErrTolerance(float tol){
errTol=tol;
}
void simpleNet::setLearnRate(float rate){
learnRate=rate;
}
void simpleNet::setAbsorp(float abs){
absorp=abs;
}
float *simpleNet::run(float *input){ //complete run through the net
setZero(); //set needed matrices to zero
for(int i=0; i<amountI; i++) //save input-vector
inI[i]=input[i];
for(int i=0; i<amountI; i++) //special case here: inI=outI
outI[i]=inI[i];
outI[amountI]=1; //shift neuron = 1
for(int i=0; i<amountH; i++) //get input of hidden layer
for(int j=0; j<=amountI; j++)
inH[i]+=ihWeights[j][i]*outI[j];
for(int i=0; i<amountH; i++) //get output of hidden layer (sigmoide function)
outH[i]=1/(1+exp(-inH[i]));
outH[amountH]=1; //shift neuron = 1
for(int i=0; i<amountO; i++) //get input of output layer
for(int j=0; j<=amountH; j++)
inO[i]+=hoWeights[j][i]*outH[j];
for(int i=0; i<amountO; i++) //get output of output layer (sigmoide function)
outO[i]=1/(1+exp(-inO[i]));
return outO;
}
bool simpleNet::train(float *input, float *pOutput){
bool converge=true;
for(int i=0; i<=amountI; i++) //set delta matrices to 0 (start value)
for(int j=0; j<amountH; j++)
ihWDelta[i][j]=0;
for(int i=0; i<=amountH; i++)
for(int j=0; j<amountO; j++)
hoWDelta[i][j]=0;
run(input); //run forward
for(int i=0; i<amountO; i++) //save preferred output
prefO[i]=pOutput[i];
for(int i=0; i<amountO; i++){ //compute output difference vector
diffO[i]=prefO[i]-outO[i];
if(fabs(diffO[i])>errTol) converge=false;//difference within limit?
}
for(int i=0; i<amountO; i++) //compute error vector of output layer
errO[i]=diffO[i]*outO[i]*(1-outO[i]);
for(int i=0; i<=amountH; i++){ //compute error vector of hidden layer
for(int j=0; j<amountO; j++)
errH[i]+=errO[j]*hoWeights[i][j];
errH[i]*=outH[i]*(1-outH[i]);
}
for(int i=0; i<=amountI; i++) //update input-hidden weight matrix
for(int j=0; j<amountH; j++){
ihWDelta[i][j]=learnRate*errH[j]*outI[i]+ihWDelta[i][j]*absorp;
ihWeights[i][j]=ihWeights[i][j]+ihWDelta[i][j];
}
for(int i=0; i<=amountH; i++) //update hidden-output weight matrix
for(int j=0; j<amountO; j++){
hoWDelta[i][j]=learnRate*errO[j]*outH[i]+hoWDelta[i][j]*absorp;
hoWeights[i][j]=hoWeights[i][j]+hoWDelta[i][j];
}
return converge;
}
Alles anzeigen