unit UBP;
interface
uses Math,SysUtils;
type
ObjNeurons = object
_U: Single ;
_B: Single ;
_PB: Single ;
_Type: Byte ;
_Offset: Single ;
_SumOffset: Single ;
_OldSumOffset: Single ;
function _V(): Single ;
end ;
RNeuronsOfLevel = record
_NeruronsCount: Integer ;
_NeruronsArray: array of ObjNeurons;
end ;
RSynaptic = record
_Weight: Single ;
_PW: Single ;
_Offset: Single ;
_SumOffset: Single ;
_OldSumOffset: Single ;
end ;
RMatrix = record
Matrix: array of array of RSynaptic;
end ;
RSample = record
X: array of Single ;
Y: array of Single ;
end ;
ObjNeuronsNet = class
constructor create(); overload;
constructor Create( const LevelArray: array of Integer ); overload;
destructor Destroy(); override;
public
_SampleCount: Integer ;
_SampleArray: array of RSample;
_MaxStudyCount: Integer ;
_MaxError: Single ;
_UpN: Single ;
_DownN: Single ;
_MaxN: Single ;
procedure MemSample();
procedure Study();
private
_StudyCount: Integer ;
_LevelCount: Integer ;
_WeightMatrix: array of RMatrix;
_NeruronsLevelArray: array of RNeuronsOfLevel;
_ExportArray: array of Single ;
procedure FreeNet();
procedure Changle();
procedure InitNet( const LevelArray: array of Integer );
procedure InitWeightMatrix();
procedure CalcExport();
procedure CalcExportReturn();
procedure CalcOffset( const LevelID: Integer ; const NeuronsID: Integer );
procedure SaveOffset();
procedure AddOffset();
function GetError(): Single ;
end ;
implementation
uses UMain;
function ObjNeurons . _V: Single ;
begin
case _Type of
0 : begin
Result := _U;
end ;
1 : begin
Result := 1 / ( 1 + Exp(-(_U - _B)));
end ;
end ;
end ;
procedure ObjNeuronsNet . AddOffset;
var i, j, k: Integer ;
Count: Integer ;
ACount: Integer ;
begin
for i := 0 to _LevelCount - 1 do
begin
count := _NeruronsLevelArray[i]._NeruronsCount;
Acount := _NeruronsLevelArray[i + 1 ]._NeruronsCount;
for j := 0 to Count - 1 do
begin
_NeruronsLevelArray[i]._NeruronsArray[j]._SumOffset := _NeruronsLevelArray[i]._NeruronsArray[j]._SumOffset + _NeruronsLevelArray[i]._NeruronsArray[j]._Offset;
if i < (_LevelCount - 1 ) then
begin
for k := 0 to ACount - 1 do
begin
_WeightMatrix[i].Matrix[J, K]._SumOffset := _WeightMatrix[i].Matrix[J, K]._SumOffset + _WeightMatrix[i].Matrix[J, K]._Offset;
end ;
end ;
end ;
end ;
end ;
procedure ObjNeuronsNet . CalcExport;
var i, j, k: Integer ;
FCount: Integer ;
Sum: Single ;
begin
for i := 1 to _LevelCount - 1 do
begin
FCount := _NeruronsLevelArray[i - 1 ]._NeruronsCount;
for j := 0 to _NeruronsLevelArray[i]._NeruronsCount - 1 do
begin
Sum := 0 ;
for K := 0 to FCount - 1 do
begin
Sum := Sum + _WeightMatrix[i - 1 ].Matrix[K, J]._Weight * _NeruronsLevelArray[i - 1 ]._NeruronsArray[k]._V;
end ;
_NeruronsLevelArray[i]._NeruronsArray[j]._U := Sum;
end ;
end ;
end ;
procedure ObjNeuronsNet . CalcExportReturn;
var i, j, k: Integer ;
Count: Integer ;
Acount: Integer ;
begin
for i := _LevelCount - 1 downto 1 do
begin
count := _NeruronsLevelArray[i]._NeruronsCount;
for j := 0 to Count - 1 do
begin
CalcOffset(i, j);
end ;
end ;
for i := 0 to _LevelCount - 2 do
begin
count := _NeruronsLevelArray[i]._NeruronsCount;
Acount := _NeruronsLevelArray[i + 1 ]._NeruronsCount;
for j := 0 to Count - 1 do
begin
for k := 0 to Acount - 1 do
begin
_WeightMatrix[i].Matrix[j, k]._Offset := Self . _NeruronsLevelArray[i]._NeruronsArray[j]._V * Self . _NeruronsLevelArray[i + 1 ]._NeruronsArray[K]._Offset;
end ;
end ;
end ;
end ;
procedure ObjNeuronsNet . CalcOffset( const LevelID, NeuronsID: Integer );
var i: Integer ;
YExport, DExport: Single ;
Sum: Single ;
ACount: Integer ;
begin
Sum := 0 ;
YExport := _NeruronsLevelArray[LevelID]._NeruronsArray[NeuronsID]._V;
if LevelID = (_LevelCount - 1 ) then
begin
DExport := _ExportArray[NeuronsID];
_NeruronsLevelArray[LevelID]._NeruronsArray[NeuronsID]._Offset := -YExport * ( 1 - YExport) * (DExport - YExport);
end
else begin
ACount := _NeruronsLevelArray[LevelID + 1 ]._NeruronsCount;
for i := 0 to ACount - 1 do
begin
Sum := Sum + _NeruronsLevelArray[LevelID + 1 ]._NeruronsArray[i]._Offset * _WeightMatrix[LevelID].Matrix[NeuronsID, i]._Weight;
end ;
_NeruronsLevelArray[LevelID]._NeruronsArray[NeuronsID]._Offset := -YExport * ( 1 - YExport) * Sum;
end ;
end ;
constructor ObjNeuronsNet . create;
begin
end ;
procedure ObjNeuronsNet . Changle;
var i, j, k: Integer ;
FCount: Integer ;
ACount: Integer ;
PB: Single ;
oldPb: Single ;
PW: Single ;
OldPw: Single ;
T: Single ;
B: Single ;
W: Single ;
begin
for i := 0 to _LevelCount - 1 do
begin
FCount := _NeruronsLevelArray[i]._NeruronsCount;
for j := 0 to FCount - 1 do
begin
PB := _NeruronsLevelArray[i]._NeruronsArray[j]._SumOffset;
oldPb := _NeruronsLevelArray[i]._NeruronsArray[j]._OldSumOffset;
T := PB * OLDPB;
if T > 0 then
begin
_NeruronsLevelArray[i]._NeruronsArray[j]._PB := _UpN * _NeruronsLevelArray[i]._NeruronsArray[j]._PB;
end else if (T < 0 ) then
begin
_NeruronsLevelArray[i]._NeruronsArray[j]._PB := _DownN * _NeruronsLevelArray[i]._NeruronsArray[j]._PB;
end ;
if _NeruronsLevelArray[i]._NeruronsArray[j]._PB>_MaxN then _NeruronsLevelArray[i]._NeruronsArray[j]._PB:=_MaxN;
if PB > 0 then
begin
B := -_NeruronsLevelArray[i]._NeruronsArray[j]._PB;
end else if (PB < 0 ) then
begin
B := _NeruronsLevelArray[i]._NeruronsArray[j]._PB;
end else begin
B := 0 ;
end ;
_NeruronsLevelArray[i]._NeruronsArray[j]._B := _NeruronsLevelArray[i]._NeruronsArray[j]._B + B;
if I < (_LevelCount - 1 ) then
begin
ACount := _NeruronsLevelArray[i + 1 ]._NeruronsCount;
for K := 0 to ACount - 1 do
begin
PW := _WeightMatrix[i].Matrix[j, k]._SumOffset;
OldPw := _WeightMatrix[i].Matrix[j, k]._OldSumOffset;
T := PW * OldPw;
if T > 0 then
begin
_WeightMatrix[i].Matrix[j, k]._PW := _UpN * _WeightMatrix[i].Matrix[j, k]._PW;
end else if (T < 0 ) then
begin
_WeightMatrix[i].Matrix[j, k]._PW := _DownN * _WeightMatrix[i].Matrix[j, k]._PW;
end ;
if _WeightMatrix[i].Matrix[j, k]._PW >_MaxN then _WeightMatrix[i].Matrix[j, k]._PW:=_Maxn;
if PW > 0 then
begin
W := -_WeightMatrix[i].Matrix[j, k]._PW;
end else if (PW < 0 ) then
begin
W := _WeightMatrix[i].Matrix[j, k]._PW;
end else begin
W := 0 ;
end ;
_WeightMatrix[i].Matrix[j, k]._Weight := _WeightMatrix[i].Matrix[j, k]._Weight + w;
end ;
end ;
end ;
end ;
end ;
constructor ObjNeuronsNet . create( const LevelArray: array of Integer );
begin
InitNet(LevelArray);
end ;
destructor ObjNeuronsNet . Destroy;
begin
FreeNet;
inherited ;
end ;
procedure ObjNeuronsNet . FreeNet;
begin
Self . _WeightMatrix := nil ;
Self . _NeruronsLevelArray := nil ;
Self . _SampleArray := nil ;
end ;
procedure ObjNeuronsNet . InitNet( const LevelArray: array of Integer );
var i, j: Integer ;
begin
_LevelCount := High(LevelArray) + 1 ;
SetLength(_NeruronsLevelArray, _LevelCount);
SetLength(_WeightMatrix, _LevelCount - 1 );
SetLength(_ExportArray, LevelArray[_LevelCount - 1 ]);
Randomize;
for i := 0 to _LevelCount - 1 do
begin
_NeruronsLevelArray[i]._NeruronsCount := LevelArray[i];
SetLength(_NeruronsLevelArray[i]._NeruronsArray, _NeruronsLevelArray[i]._NeruronsCount);
if i < (_LevelCount - 1 ) then
begin
SetLength(_WeightMatrix[i].Matrix, LevelArray[i], LevelArray[i + 1 ]);
end ;
for j := 0 to _NeruronsLevelArray[i]._NeruronsCount - 1 do
begin
if i = 0 then
begin
_NeruronsLevelArray[i]._NeruronsArray[j]._Type := 0 ;
end else begin
_NeruronsLevelArray[i]._NeruronsArray[j]._Type := 1 ;
end ;
_NeruronsLevelArray[i]._NeruronsArray[j]._PB := 0.1 ;
_NeruronsLevelArray[i]._NeruronsArray[j]._B := Random * 2 - 1 ;
end ;
end ;
InitWeightMatrix;
_StudyCount := 0 ;
end ;
procedure ObjNeuronsNet . InitWeightMatrix;
var i, j, k: Integer ;
FCount: Integer ;
ACount: Integer ;
F: Single ;
begin
Randomize;
for i := 0 to _LevelCount - 2 do
begin
Fcount := _NeruronsLevelArray[i]._NeruronsCount;
ACount := _NeruronsLevelArray[i + 1 ]._NeruronsCount;
for j := 0 to Fcount - 1 do
begin
for K := 0 to ACount - 1 do
begin
_WeightMatrix[i].Matrix[j, k]._Weight := 2 * Random * F - F;
_WeightMatrix[i].Matrix[j, k]._Offset := 0 ;
_WeightMatrix[i].Matrix[j, k]._SumOffset := 0 ;
_WeightMatrix[i].Matrix[j, k]._OldSumOffset := 0 ;
_WeightMatrix[i].Matrix[j, k]._PW := 0.1 ;
end ;
end ;
end ;
end ;
procedure ObjNeuronsNet . MemSample;
var i: Integer ;
begin
SetLength(_SampleArray, _SampleCount);
for i := 0 to _SampleCount - 1 do
begin
SetLength(_SampleArray[i].X, _NeruronsLevelArray[ 0 ]._NeruronsCount);
SetLength(_SampleArray[i].Y, _NeruronsLevelArray[_LevelCount - 1 ]._NeruronsCount);
end ;
end ;
procedure ObjNeuronsNet . SaveOffset;
var i, j, k: Integer ;
FCount: Integer ;
ACount: Integer ;
begin
for i := 0 to _LevelCount - 1 do
begin
Fcount := _NeruronsLevelArray[i]._NeruronsCount;
for j := 0 to Fcount - 1 do
begin
_NeruronsLevelArray[i]._NeruronsArray[j]._OldSumOffset := _NeruronsLevelArray[i]._NeruronsArray[j]._SumOffset;
_NeruronsLevelArray[i]._NeruronsArray[j]._SumOffset := 0 ;
if i < (_LevelCount - 1 ) then
begin
ACount := _NeruronsLevelArray[i+ 1 ]._NeruronsCount;
for K := 0 to ACount - 1 do
begin
_WeightMatrix[i].Matrix[j, k]._OldSumOffset := _WeightMatrix[i].Matrix[j, k]._SumOffset;
_WeightMatrix[i].Matrix[j, k]._SumOffset := 0 ;
end ;
end ;
end ;
end ;
end ;
procedure ObjNeuronsNet . Study;
var i: Integer ;
SumErr: Single ;
begin
if _StudyCount > _MaxStudyCount then Exit;
SumErr := 0 ;
for i := 0 to _SampleCount - 1 do
begin
CalcExport;
CalcExportReturn;
AddOffset;
SumErr := SumErr + GetError();
end ;
Form1 . mmo1 . Lines . Add(IntToStr(_StudyCount)+ \':\' +FloatToStr(SumErr)) ;
Form1 . img1 . Canvas . Pixels[ Integer (_StudyCount* 5 ),floor( 150 -SumErr* 100 )]:= 255 ;
if (SumErr/self . _SampleCount ) <= _MaxError then
Exit;
Changle;
SaveOffset;
_StudyCount := _StudyCount + 1 ;
Study();
end ;
function ObjNeuronsNet . GetError: Single ;
var SumErr: Single ;
i: Integer ;
begin
SumErr := 0 ;
for i := 0 to _NeruronsLevelArray[_LevelCount - 1 ]._NeruronsCount - 1 do
begin
SumErr := Sumerr + Power((_ExportArray[i] - _NeruronsLevelArray[_LevelCount - 1 ]._NeruronsArray[i]._V), 2 );
end ;
Result := SumErr / 2 ;
end ;
end .
|