Исходный текст реализации алгоритма обратного распространения (автор - С. Короткий)


Перейти к:  Листинг 1,  Листинг 2,  Листинг 3,  Листинг 4,  Листинг 5,  Листинг 6,  Листинг 7,  Листинг 8

Назад

Листинг 1

 

// FILE neuro.h

#include <stdio.h>

#define OK 0 // состояния объектов

#define ERROR 1

 

#define ORIGINAL 0 // типы активационных функций

#define HYPERTAN 1

#define HARDLIMIT 2

#define THRESHOLD 3

 

#define INNER 0 // тип распределения памяти

#define EXTERN 1

 

#define HORIZONTAL 1

#define VERTICAL 0

 

#ifndef max

#define max(a,b) (((a) > (b)) ? (a) : (b))

#define min(a,b) (((a) < (b)) ? (a) : (b))

#endif

 

// базовый класс нейронов для большинства сетей

class Neuron

{

protected:

float state; // состояние

float axon; // выход

int status; // признак ошибки

public:

Neuron(void){ state=0.; axon=0.; status=OK; };

virtual float Sigmoid(void)=0;

int GetStatus(void){return status;};

};

 

class SomeNet

{

protected:

FILE *pf;

int imgfile; // 0 - числа; 1 - 2D; 2 - эмуляция

unsigned rang;

int status;

unsigned learncycle;

int (*emuf)(int n, float _FAR *in, float _FAR *ou);

public:

SomeNet(void)

{pf=NULL;imgfile=0;rang=0;status=OK;learncycle=0;};

unsigned GetRang(void){return rang;};

void SetLearnCycle(unsigned l){learncycle=l;};

int OpenPatternFile(unsigned char *file);

int ClosePatternFile(void);

void EmulatePatternFile(int (*p)(int n,

float _FAR *, float _FAR *))

{emuf=p;imgfile=2;};

int GetStatus(void){return status;};

};

 

class LayerBP;

class NetBP;

 

// нейрон для полносвязной сети прямого распространения

class NeuronFF: public Neuron

{

protected:

unsigned rang; // число весов

float _FAR *synapses; // веса

float _FAR * _FAR *inputs;

// массив указателей на выходы нейронов предыд. слоя

void _allocateNeuron(unsigned);

void _deallocate(void);

public:

NeuronFF(unsigned num_inputs);

NeuronFF(void){rang=0; synapses=NULL;

inputs=NULL; status=OK;};

~NeuronFF();

virtual void Propagate(void);

void SetInputs(float *massive);

void InitNeuron(unsigned numsynapses);

virtual void RandomizeAxon(void);

virtual void Randomize(float);

virtual float Sigmoid(void);

virtual float D_Sigmoid(void);

virtual void PrintSynapses(int,int);

virtual void PrintAxons(int, int);

};

 

class NeuronBP: public NeuronFF

{ friend LayerBP;

friend NetBP;

float error;

float _FAR *deltas; // изменения весов

void _allocateNeuron(unsigned);

void _deallocate(void);

public:

NeuronBP(unsigned num_inputs);

NeuronBP(void){deltas=NULL; error=0.;};

~NeuronBP();

void InitNeuron(unsigned numsynapses);

int IsConverged(void);

};

 

class LayerFF

{

protected:

unsigned rang;

int status;

int x,y,dx,dy;

unsigned char *name; // имя слоя

public:

LayerFF(void) { rang=0; name=NULL; status=OK; };

unsigned GetRang(void){return rang;};

void SetShowDim(int _x, int _y, int _dx, int _dy)

{x=_x; y=_y; dx=_dx; dy=_dy;};

void SetName(unsigned char *s) {name=s;};

unsigned char *GetName(void)

{if(name) return name;

else return (unsigned char *)&("NoName");};

int GetStatus(void){return status;};

int GetX(void){return x;};

int GetY(void){return y;};

int GetDX(void){return dx;};

int GetDY(void){return dy;};

};

 

class LayerBP: public LayerFF

{ friend NetBP;

protected:

unsigned neuronrang; // число синапсов в нейронах

int allocation;

NeuronBP _FAR *neurons;

public:

LayerBP(unsigned nRang, unsigned nSinapses);

LayerBP(NeuronBP _FAR *Neu, unsigned nRang,

unsigned nSinapses);

LayerBP(void)

{neurons=NULL; neuronrang=0; allocation=EXTERN;};

~LayerBP();

void Propagate(void);

void Randomize(float);

void RandomizeAxons(void);

void Normalize(void);

void Update(void);

int IsConverged(void);

virtual void Show(void);

virtual void PrintSynapses(int,int);

virtual void PrintAxons(int x, int y, int direction);

};

 

class NetBP: public SomeNet

{

LayerBP _FAR * _FAR *layers;

// нулевой слой нейронов без синапсов реализует входы

public:

NetBP(void) { layers=NULL; };

NetBP(unsigned nLayers);

NetBP(unsigned n, unsigned n1, ...);

~NetBP();

int SetLayer(unsigned n, LayerBP _FAR *pl);

LayerBP *GetLayer(unsigned n)

{if(n<rang) return layers[n]; else return NULL; }

void Propagate(void);

int FullConnect(void);

void SetNetInputs(float _FAR *mvalue);

void CalculateError(float _FAR * Target);

void Learn(void);

void Update(void);

void Randomize(float);

void Cycle(float _FAR *Inp, float _FAR *Out);

int SaveToFile(unsigned char *file);

int LoadFromFile(unsigned char *file);

int LoadNextPattern(float _FAR *IN, float _FAR *OU);

int IsConverged(void);

void AddNoise(void);

virtual void PrintSynapses(int x=0,...){};

virtual float Change(float In);

};

 

// Сервисные функции

void out_char(int x,int y,int c,int at);

void out_str(int x,int y,unsigned char *s,unsigned col);

void ClearScreen(void);

 

// Глобальные параметры для обратного распространения

int SetSigmoidType(int st);

float SetSigmoidAlfa(float Al);

float SetMiuParm(float Mi);

float SetNiuParm(float Ni);

float SetLimit(float Li);

unsigned SetDSigma(unsigned d);

 

// Псевдографика

#define GRAFCHAR_UPPERLEFTCORNER 218

#define GRAFCHAR_UPPERRIGHTCORNER 191

#define GRAFCHAR_HORIZONTALLINE 196

#define GRAFCHAR_VERTICALLINE 179

#define GRAFCHAR_BOTTOMLEFTCORNER 192

#define GRAFCHAR_BOTTOMRIGHTCORNER 217

 

#define GRAFCHAR_EMPTYBLACK 32

#define GRAFCHAR_DARKGRAY 176

#define GRAFCHAR_MIDDLEGRAY 177

#define GRAFCHAR_LIGHTGRAY 178

#define GRAFCHAR_SOLIDWHITE 219

 

 

Листинг 2

 

//FILE neuro_ff.cpp FOR neuro1.prj & neuro2.prj

#include <stdlib.h>

#include <math.h>

#include "neuro.h"

 

static int SigmoidType=ORIGINAL;

static float SigmoidAlfa=2.; // > 4 == HARDLIMIT

 

int SetSigmoidType(int st)

{

int i;

i=SigmoidType;

SigmoidType=st;

return i;

}

 

float SetSigmoidAlfa(float Al)

{

float a;

a=SigmoidAlfa;

SigmoidAlfa=Al;

return a;

}

 

void NeuronFF::Randomize(float range)

{

for(unsigned i=0;i<rang;i++)

synapses[i]=range*((float)rand()/RAND_MAX-0.5);

}

 

void NeuronFF::RandomizeAxon(void)

{

axon=(float)rand()/RAND_MAX-0.5;

}

 

float NeuronFF::D_Sigmoid(void)

{

switch(SigmoidType)

{

case HYPERTAN: return (1.-axon*axon);

case ORIGINAL: return SigmoidAlfa*(axon+0.5)*

(1.5-axon);

default: return 1.;

}

}

 

float NeuronFF::Sigmoid(void)

{

switch(SigmoidType)

{

case HYPERTAN: return 0.5*tanh(state);

case ORIGINAL: return -0.5+1./

(1+exp(-SigmoidAlfa*state));

case HARDLIMIT:if(state>0) return 0.5;

else if(state<0) return -0.5;

else return state;

case THRESHOLD:if(state>0.5) return 0.5;

else if(state<-0.5) return -0.5;

else return state;

default: return 0.;

}

}

 

void NeuronFF::_allocateNeuron(unsigned num_inputs)

{

synapses=NULL;inputs=NULL;status=OK;rang=0;

if(num_inputs==0) return;

synapses= new float[num_inputs];

if(synapses==NULL) status=ERROR;

else

{

inputs=new float _FAR * [num_inputs];

if(inputs==NULL) status=ERROR;

else

{

rang=num_inputs;

for(unsigned i=0;i<rang;i++)

{ synapses[i]=0.; inputs[i]=NULL; }

}

}

}

 

NeuronFF::NeuronFF(unsigned num_inputs)

{

_allocateNeuron(num_inputs);

}

 

void NeuronFF::_deallocate(void)

{

if(rang && (status==OK))

{delete [] synapses;delete [] inputs;

synapses=NULL; inputs=NULL;}

}

 

NeuronFF::~NeuronFF()

{

_deallocate();

}

 

void NeuronFF::Propagate(void)

{

state=0.;

for(unsigned i=0;i<rang;i++)

state+=(*inputs[i]*2)*(synapses[i]*2);

state/=2;

axon=Sigmoid();

}

 

void NeuronFF::SetInputs(float *vm)

{

for(unsigned i=0;i<rang;i++) inputs[i]=&vm[i];

}

 

void NeuronFF::InitNeuron(unsigned num_inputs)

{

if(rang && (status==OK))

{delete [] synapses;delete [] inputs;}

_allocateNeuron(num_inputs);

}

 

void NeuronFF::PrintSynapses(int x=0, int y=0)

{

unsigned char buf[20];

for(unsigned i=0;i<rang;i++)

{

sprintf(buf,"%+7.2f",synapses[i]);

out_str(x+8*i,y,buf,11);

}

}

 

void NeuronFF::PrintAxons(int x=0, int y=0)

{

unsigned char buf[20];

sprintf(buf,"%+7.2f",axon);

out_str(x,y,buf,11);

}

 

Листинг 3

 

// FILE neuro_bp.cpp FOR neuro1.prj & neuro2.prj

#include <stdlib.h>

#include <alloc.h>

#include <math.h>

#include <string.h>

#include <stdarg.h>

#include <values.h>

 

#include "neuro.h"

 

static float MiuParm=0.0;

static float NiuParm=0.1;

static float Limit=0.000001;

static unsigned dSigma=0;

 

float SetMiuParm(float Mi)

{

float a;

a=MiuParm;

MiuParm=Mi;

return a;

}

 

float SetNiuParm(float Ni)

{

float a;

a=NiuParm;

NiuParm=Ni;

return a;

}

 

float SetLimit(float Li)

{

float a;

a=Limit;

Limit=Li;

return a;

}

 

unsigned SetDSigma(unsigned d)

{

unsigned u;

u=dSigma;

dSigma=d;

return u;

}

 

void NeuronBP::_allocateNeuron(unsigned num_inputs)

{

deltas=NULL;

if(num_inputs==0) return;

deltas=new float[num_inputs];

if(deltas==NULL) status=ERROR;

else for(unsigned i=0;i<rang;i++) deltas[i]=0.;

}

 

NeuronBP::NeuronBP(unsigned num_inputs)

:NeuronFF(num_inputs)

{

_allocateNeuron(num_inputs);

}

 

void NeuronBP::_deallocate(void)

{

if(deltas && (status==OK))

{delete [] deltas; deltas=NULL;}

}

 

NeuronBP::~NeuronBP()

{

_deallocate();

}

 

void NeuronBP::InitNeuron(unsigned num_inputs)

{

NeuronFF::InitNeuron(num_inputs);

if(deltas && (status==OK)) delete [] deltas;

_allocateNeuron(num_inputs);

}

 

int NeuronBP::IsConverged(void)

{

for(unsigned i=0;i<rang;i++)

if(fabs(deltas[i])>Limit) return 0;

return 1;

}

 

//

 

LayerBP::LayerBP(unsigned nRang, unsigned nSynapses)

{

allocation=EXTERN; status=ERROR; neuronrang=0;

if(nRang==0) return;

neurons=new NeuronBP[nRang];

if(neurons==NULL) return;

for(unsigned i=0;i<nRang;i++)

neurons[i].InitNeuron(nSynapses);

rang=nRang;

neuronrang=nSynapses;

allocation=INNER;

name=NULL; status=OK;

}

 

LayerBP::LayerBP(NeuronBP _FAR *Neu, unsigned nRang,

unsigned nSynapses)

{

neurons=NULL; neuronrang=0; allocation=EXTERN;

for(unsigned i=0;i<nRang;i++)

if(Neu[i].rang!=nSynapses) status=ERROR;

if(status==OK)

{

neurons=Neu;

rang=nRang;

neuronrang=nSynapses;

}

}

 

LayerBP::~LayerBP(void)

{

if(allocation==INNER)

{

for(unsigned i=0;i<rang;i++)

neurons[i]._deallocate();

delete [] neurons; neurons=NULL;

}

}

 

void LayerBP::Propagate(void)

{

for(unsigned i=0;i<rang;i++)

neurons[i].Propagate();

}

 

void LayerBP::Update(void)

{

for(unsigned i=0;i<rang;i++)

{

for(unsigned j=0;j<neuronrang;j++)

neurons[i].synapses[j]-=neurons[i].deltas[j];

}

}

 

void LayerBP::Randomize(float range)

{

for(unsigned i=0;i<rang;i++)

neurons[i].Randomize(range);

}

 

void LayerBP::RandomizeAxons(void)

{

for(unsigned i=0;i<rang;i++)

neurons[i].RandomizeAxon();

}

 

void LayerBP::Normalize(void)

{

float sum;

unsigned i;

for(i=0;i<rang;i++)

sum+=neurons[i].axon*neurons[i].axon;

sum=sqrt(sum);

for(i=0;i<rang;i++) neurons[i].axon/=sum;

}

 

void LayerBP::Show(void)

{

unsigned char sym[5]={ GRAFCHAR_EMPTYBLACK, GRAFCHAR_DARKGRAY, GRAFCHAR_MIDDLEGRAY, GRAFCHAR_LIGHTGRAY, GRAFCHAR_SOLIDWHITE };

int i,j;

if(y && name) for(i=0;i<strlen(name);i++)

out_char(x+i,y-1,name[i],3);

out_char(x,y,GRAFCHAR_UPPERLEFTCORNER,15);

for(i=0;i<2*dx;i++)

out_char(x+1+i,y,GRAFCHAR_HORIZONTALLINE,15);

out_char(x+1+i,y,GRAFCHAR_UPPERRIGHTCORNER,15);

 

for(j=0;j<dy;j++)

{

out_char(x,y+1+j,GRAFCHAR_VERTICALLINE,15);

for(i=0;i<2*dx;i++) out_char(x+1+i, y+1+j,

sym[(int) ((neurons[j*dx+i/2].axon+0.4999)*5)], 15);

out_char(x+1+i, y+1+j,GRAFCHAR_VERTICALLINE,15);

}

 

out_char(x,y+j+1,GRAFCHAR_BOTTOMLEFTCORNER,15);

for(i=0;i<2*dx;i++)

out_char(x+i+1,y+j+1,GRAFCHAR_HORIZONTALLINE,15);

out_char(x+1+i,y+j+1, GRAFCHAR_BOTTOMRIGHTCORNER,15);

}

 

void LayerBP::PrintSynapses(int x, int y)

{

for(unsigned i=0;i<rang;i++)

neurons[i].PrintSynapses(x,y+i);

}

 

void LayerBP::PrintAxons(int x, int y)

{

for(unsigned i=0;i<rang;i++)

neurons[i].PrintAxons(x,y+i);

}

 

int LayerBP::IsConverged(void)

{

for(unsigned i=0;i<rang;i++)

if(neurons[i].IsConverged()==0) return 0;

return 1;

}

 

//

 

NetBP::NetBP(unsigned nLayers)

{

layers=NULL;

if(nLayers==0) { status=ERROR; return; }

layers=new LayerBP _FAR *[nLayers];

if(layers==NULL) status=ERROR;

else

{

rang=nLayers;

for(unsigned i=0;i<rang;i++) layers[i]=NULL;

}

}

 

NetBP::~NetBP()

{

if(rang)

{

for(unsigned i=0;i<rang;i++) layers[i]->~LayerBP();

delete [] layers; layers=NULL;

}

}

 

int NetBP::SetLayer(unsigned n, LayerBP _FAR * pl)

{

unsigned i,p;

 

if(n>=rang) return 1;

p=pl->rang;

if(p==0) return 2;

if(n) // если не первый слой

{

if(layers[n-1]!=NULL)

// если предыдущий слой уже подключен, про-

{ // веряем, равно ли число синапсов каждого

// его нейрона числу нейронов предыд. слоя

for(i=0;i<p;i++)

if((*pl).neurons[i].rang!=layers[n-1]->rang)

return 3;

}

}

 

if(n<rang-1) // если не последний слой

{

if(layers[n+1])

for(i=0;i<layers[n+1]->rang;i++)

if(p!=layers[n+1]->neurons[i].rang) return 4;

}

 

layers[n]=pl;

return 0;

}

 

void NetBP::Propagate(void)

{

for(unsigned i=1;i<rang;i++)

layers[i]->Propagate();

}

 

int NetBP::FullConnect(void)

{

LayerBP *l;

unsigned i,j,k,n;

for(i=1;i<rang;i++) // кроме входного слоя

{ // по всем слоям

l=layers[i];

if(l->rang==0) return 1;

n=(*layers[i-1]).rang;

if(n==0) return 2;

for(j=0;j<l->rang;j++) // по нейронам слоя

{

for(k=0;k<n;k++) // по синапсам нейрона

{

l->neurons[j].inputs[k]=

&(layers[i-1]->neurons[k].axon);

}

}

}

return 0;

}

 

void NetBP::SetNetInputs(float _FAR *mv)

{

for(unsigned i=0;i<layers[0]->rang;i++)

layers[0]->neurons[i].axon=mv[i];

}

 

void NetBP::CalculateError(float _FAR * Target)

{

NeuronBP *n;

float sum;

unsigned i;

int j;

for(i=0;i<layers[rang-1]->rang;i++)

{

n=&(layers[rang-1]->neurons[i]);

n->error=(n->axon-Target[i])*n->D_Sigmoid();

}

for(j=rang-2;j>0;j--) // по скрытым слоям

{

for(i=0;i<layers[j]->rang;i++) // по нейронам

{

sum=0.;

for(unsigned k=0;k<layers[j+1]->rang;k++)

sum+=layers[j+1]->neurons[k].error

*layers[j+1]->neurons[k].synapses[i];

layers[j]->neurons[i].error=

sum*layers[j]->neurons[i].D_Sigmoid();

}

}

}

 

void NetBP::Learn(void)

{

for(int j=rang-1;j>0;j--)

{

for(unsigned i=0;i<layers[j]->rang;i++)

{ // по нейронам

for(unsigned k=0;k<layers[j]->neuronrang;k++)

// по синапсам

layers[j]->neurons[i].deltas[k]=NiuParm*

(MiuParm*layers[j]->neurons[i].deltas[k]+

(1.-MiuParm)*layers[j]->neurons[i].error

*layers[j-1]->neurons[k].axon);

}

}

}

 

void NetBP::Update(void)

{

for(unsigned i=0;i<rang;i++) layers[i]->Update();

}

 

void NetBP::Randomize(float range)

{

for(unsigned i=0;i<rang;i++)

layers[i]->Randomize(range);

}

 

void NetBP::Cycle(float _FAR *Inp, float _FAR *Out)

{

SetNetInputs(Inp);

if(dSigma) AddNoise();

Propagate();

CalculateError(Out);

Learn();

Update();

}

 

int NetBP::SaveToFile(unsigned char *file)

{

FILE *fp;

fp=fopen(file,"wt");

if(fp==NULL) return 1;

fprintf(fp,"%u",rang);

for(unsigned i=0;i<rang;i++)

{

fprintf(fp,"\n+%u",layers[i]->rang);

fprintf(fp,"\n¦%u",layers[i]->neuronrang);

for(unsigned j=0;j<layers[i]->rang;j++)

{

fprintf(fp,"\n¦+%f",layers[i]->neurons[j].state);

fprintf(fp,"\n¦¦%f",layers[i]->neurons[j].axon);

fprintf(fp,"\n¦¦%f",layers[i]->neurons[j].error);

for(unsigned k=0;k<layers[i]->neuronrang;k++)

{

fprintf(fp,"\n¦¦%f",

layers[i]->neurons[j].synapses[k]);

}

fprintf(fp,"\n¦+");

}

fprintf(fp,"\n+");

}

fclose(fp);

return 0;

}

 

int NetBP::LoadFromFile(unsigned char *file)

{

FILE *fp;

unsigned i,r,nr;

unsigned char bf[12];

 

if(layers) return 1; // возможно использование только

// экземпляров класса, сконструированных по умолчанию

// с помощью NetBP(void).

 

fp=fopen(file,"rt");

if(fp==NULL) return 1;

fscanf(fp,"%u\n",&r);

 

if(r==0) goto allerr;

layers=new LayerBP _FAR *[r];

if(layers==NULL)

{ allerr: status=ERROR; fclose(fp); return 2; }

else

{

rang=r;

for(i=0;i<rang;i++) layers[i]=NULL;

}

 

for(i=0;i<rang;i++)

{

fgets(bf,10,fp);

r=atoi(bf+1);

fgets(bf,10,fp);

nr=atoi(bf+1);

layers[i] = new LayerBP(r,nr);

for(unsigned j=0;j<layers[i]->rang;j++)

{

fscanf(fp,"¦+%f\n",&(layers[i]->neurons[j].state));

fscanf(fp,"¦¦%f\n",&(layers[i]->neurons[j].axon));

fscanf(fp,"¦¦%f\n",&(layers[i]->neurons[j].error));

for(unsigned k=0;k<layers[i]->neuronrang;k++)

{

fscanf(fp,"¦¦%f\n",

&(layers[i]->neurons[j].synapses[k]));

}

fgets(bf,10,fp);

}

fgets(bf,10,fp);

}

fclose(fp);

return 0;

}

 

NetBP::NetBP(unsigned n, unsigned n1, ...)

{

unsigned i, num, prenum;

va_list varlist;

 

status=OK; rang=0; pf=NULL; learncycle=0; layers=NULL;

layers=new LayerBP _FAR *[n];

if(layers==NULL) { allerr: status=ERROR; }

else

{

rang=n;

for(i=0;i<rang;i++) layers[i]=NULL;

 

num=n1;

layers[0] = new LayerBP(num,0);

va_start(varlist,n1);

for(i=1;i<rang;i++)

{

prenum=num;

num=va_arg(varlist,unsigned);

layers[i] = new LayerBP(num,prenum);

}

va_end(varlist);

}

}

 

int NetBP::LoadNextPattern(float _FAR *IN,

float _FAR *OU)

{

unsigned char buf[256];

unsigned char *s, *ps;

int i;

if(pf==NULL) return 1;

if(imgfile)

{

restart:

for(i=0;i<layers[0]->dy;i++)

{

if(fgets(buf,256,pf)==NULL)

{

if(learncycle)

{

rewind(pf);

learncycle--;

goto restart;

}

else return 2;

}

 

for(int j=0;j<layers[0]->dx;j++)

{

if(buf[j]=='x') IN[i*layers[0]->dx+j]=0.5;

else if(buf[j]=='.') IN[i*layers[0]->dx+j]=-0.5;

}

}

 

if(fgets(buf,256,pf)==NULL) return 3;

for(i=0;i<layers[rang-1]->rang;i++)

{

if(buf[i]!='.') OU[i]=0.5;

else OU[i]=-0.5;

}

return 0;

}

 

// "scanf often leads to unexpected results

// if you diverge from an expected pattern." (!)

// Borland C On-line Help

start:

if(fgets(buf,250,pf)==NULL)

{

if(learncycle)

{

rewind(pf);

learncycle--;

goto start;

}

else return 2;

}

s=buf;

for(;*s==' ';s++);

for(i=0;i<layers[0]->rang;i++)

{

ps=strchr(s,' ');

if(ps) *ps=0;

IN[i]=atof(s);

s=ps+1; for(;*s==' ';s++);

}

if(fgets(buf,250,pf)==NULL) return 4;

s=buf;

for(;*s==' ';s++);

for(i=0;i<layers[rang-1]->rang;i++)

{

ps=strchr(s,' ');

if(ps) *ps=0;

OU[i]=atof(s);

s=ps+1; for(;*s==' ';s++);

}

return 0;

}

 

int NetBP::IsConverged(void)

{

for(unsigned i=1;i<rang;i++)

if(layers[i]->IsConverged()==0) return 0;

return 1;

}

 

float NetBP::Change(float In)

{

// для бинарного случая

if(In==0.5) return -0.5;

else return 0.5;

}

 

void NetBP::AddNoise(void)

{

unsigned i,k;

for(i=0;i<dSigma;i++)

{

k=random(layers[0]->rang);

layers[0]->neurons[k].axon=

Change(layers[0]->neurons[k].axon);

}

}

 

Листинг 4

 

// FILE subfun.cpp FOR neuro1.prj & neuro2.prj

#include <string.h>

#include <math.h>

#include <values.h>

#include "neuro.h"

 

#define vad(x,y) ((y)*160+(x)*2)

 

void out_char(int x,int y,int c,int at)

{

unsigned far *p;

p=(unsigned far *)(0xB8000000L+

(unsigned long)vad(x,y));

*p=(c & 255) | (at<<8);

}

 

void out_str(int x,int y,unsigned char *s,unsigned col)

{

for(int i=0;i<strlen(s);i++) out_char(x+i,y,s[i],col);

}

 

void ClearScreen(void)

{

for(int i=0;i<80;i++) for(int j=0;j<25;j++)

out_char(i,j,' ',7);

}

 

int matherr(struct exception *pe)

{

if(strcmp(pe->name,"exp")==0)

{

if(pe->type==OVERFLOW) pe->retval=MAXDOUBLE;

if(pe->type==UNDERFLOW) pe->retval=MINDOUBLE;

return 10;

}

else

{

if(pe->type==UNDERFLOW || pe->type==TLOSS) return 1;

else return 0;

}

}

 

int SomeNet::OpenPatternFile(unsigned char *file)

{

pf=fopen(file,"rt");

if(strstr(file,".img")) imgfile=1;

else imgfile=0;

return !((int)pf);

}

 

int SomeNet::ClosePatternFile(void)

{

int i;

if(pf)

{

i=fclose(pf);

pf=NULL;

return i;

}

return 0;

}

 

Листинг 5

 

// FILE neuman1.cpp FOR neuro1.prj

#include <string.h>

#include <conio.h>

#include "neuro.h"

 

#define N0 30

#define N1 10

#define N2 10

 

void main()

{

float Inp[N0], Out[N2];

unsigned count;

unsigned char buf[256];

int i;

NetBP N(3,N0,N1,N2);

/* первый способ конструирования сети */

 

/*** второй способ конструирования сети

NeuronBP _FAR *H0, _FAR *H1, _FAR *H2;

H0= new NeuronBP [N0];

H1= new NeuronBP [N1];

H2= new NeuronBP [N2];

 

for(i=0;i<N1;i++) H1[i].InitNeuron(N0);

for(i=0;i<N2;i++) H2[i].InitNeuron(N1);

 

LayerBP L0(H0,N0,0);

LayerBP L1(H1,N1,N0);

LayerBP L2(H2,N2,N1);

 

NetBP N(3);

i=N.SetLayer(0,&L0);

i=N.SetLayer(1,&L1);

i=N.SetLayer(2,&L2); // здесь можно проверить i

***/

 

/* третий способ создания сети см. в Листинге 6 */

 

ClearScreen();

N.FullConnect();

N.GetLayer(0)->SetName("Input");

N.GetLayer(0)->SetShowDim(1,1,5,6);

N.GetLayer(1)->SetName("Hidden");

N.GetLayer(1)->SetShowDim(15,1,2,5);

N.GetLayer(2)->SetName("Out");

N.GetLayer(2)->SetShowDim(23,1,10,1);

 

// srand(1);

// меняем особенность случайной структуры сети

SetSigmoidType(HYPERTAN);

SetNiuParm(0.1);

SetLimit(0.001);

SetDSigma(1);

N.Randomize(1);

N.SetLearnCycle(64000U);

 

N.OpenPatternFile("char1.img");

for(count=0;;count++)

{

sprintf(buf,"Cycle %u",count);

out_str(1,23,buf,10 | (1<<4));

out_str(1,24,"ESC breaks ",11 | (1<<4));

if(kbhit() || i==13) i=getch();

if(i==27) break;

if(i=='s' || i=='S') goto save;

if(N.LoadNextPattern(Inp,Out)) break;

N.Cycle(Inp,Out);

// N.Propagate(); // "сквозной канал"

N.GetLayer(0)->Show();

N.GetLayer(1)->Show();

N.GetLayer(2)->Show();

N.GetLayer(2)->PrintAxons(47,0);

if(count && N.IsConverged())

{

save:

out_str(40,24,"FileConf:",15 | (1<<4));

gotoxy(50,25);

gets(buf);

if(strlen(buf)) N.SaveToFile(buf);

break;

}

}

N.ClosePatternFile();

}

 

Листинг 6

 

// FILE neuman2.cpp FOR neuro2.prj

#include <string.h>

#include <conio.h>

#include "neuro.h"

 

#define N0 30

#define N1 10

#define N2 10

 

main(int argc, char *argv[])

{

NetBP N;

static float Inp[N0], Out[N2];

 

if(argc!=2) return 1;

ClearScreen();

if(N.LoadFromFile(argv[1])) return 1;

if(N.FullConnect()) return 1;

N.GetLayer(0)->SetName("Input");

N.GetLayer(0)->SetShowDim(1,1,5,6);

N.GetLayer(1)->SetName("Hidden");

N.GetLayer(1)->SetShowDim(15,1,2,5);

N.GetLayer(2)->SetName("Out");

N.GetLayer(2)->SetShowDim(23,1,10,1);

SetSigmoidType(HYPERTAN);

 

if(N.OpenPatternFile("charnois.img")) return 1;

for(;;)

{

if(N.LoadNextPattern(Inp,Out)) break;

// если все образы кончились, выходим

N.SetNetInputs(Inp);

N.Propagate();

N.GetLayer(0)->Show();

N.GetLayer(1)->Show();

N.GetLayer(2)->Show();

N.GetLayer(2)->PrintAxons(47,0);

getch();

}

N.ClosePatternFile();

return 0;

}

 

Листинг 7

Файл char1.pat (перенос длинных строк по '\'

сделан при верстке)

 

-0.5 -0.5 0.5 -0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 \

0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 0.5 0.5 0.5 \

0.5 0.5 0.5 0.5 -0.5 -0.5 -0.5 0.5

0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5

0.5 -0.5 -0.5 -0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5 \

0.5 -0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 \

0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 0.5

-0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5

0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 0.5 0.5 \

0.5 0.5 0.5 0.5 0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 \

-0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 0.5

-0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5

0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 0.5 \

-0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 0.5 0.5 0.5 \

-0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 0.5

-0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5

0.5 -0.5 -0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 \

0.5 -0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 \

-0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 0.5

-0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5

-0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 \

0.5 -0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 \

-0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 0.5

-0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5

-0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 0.5 0.5 \

-0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 \

-0.5 -0.5 0.5 -0.5 0.5 0.5 0.5 -0.5

-0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5

0.5 0.5 0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 \

-0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 \

0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5

-0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5

0.5 0.5 0.5 0.5 0.5 0.5 -0.5 -0.5 -0.5 0.5 0.5 \

-0.5 -0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 \

-0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 0.5

-0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5

0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 0.5 0.5 \

0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 \

-0.5 -0.5 0.5 0.5 0.5 0.5 0.5 -0.5

-0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5

 

Листинг 8

Файл char1.img

 

..x..

.x.x.

.x.x.

x...x

xxxxx

x...x

A.........

x...x

xx.xx

xx.xx

x.x.x

x.x.x

x...x

.M........

x...x

x...x

xxxxx

x...x

x...x

x...x

..H.......

x...x

x..xx

x.x.x

x.x.x

xx..x

x...x

...N......

x..xx

x.x..

xx...

x.x..

x..x.

x...x

....K.....

...x.

..x.x

.x..x

x...x

x...x

x...x

.....L....

.xxx.

x...x

x....

x....

x...x

.xxx

......C...

xxxxx

..x..

..x..

..x..

..x..

..x..

.......T..

xxxxx

x...x

x...x

x...x

x...x

x...x

........P.

xxxx.

x...x

xxxx

x..xx

x...x

xxxx.

.........B

 

Назад




Сайт "Искусственный интеллект" - программирование ИИ от разработчика: общение, статьи, ссылки.

Copyright "OBRAZEC.RU", 2002-2017. Последние изменения внесены October 31 2010 19:32:54.
С предложениями и замечаниями обращайтесь на форум.



         Дата предыдущего изменения 13 февраля 2007 года.