phj 发表于 2006-6-6 11:40

求模拟退火算法和神经网络的delphi程序

求模拟退火算法和神经网络的delphi程序,谢谢

[ 本帖最后由 xinyuxf 于 2007-6-7 09:45 编辑 ]

frogfish 发表于 2007-7-6 02:20

来自:中国人工智能创业研发俱乐部

ART神经网络的Delphi实现

unit ARTUnit;

interface
uses Windows, SysUtils, Classes, Extctrls, Math, LPR_HUnit, Dialogs;

type
   TArtNet = class(TObject)
       private
       //F1到F2的连接权
         Wb : array of Double;
       //F2到F1的连接权
         Wt : array of Integer;
         //警戒值
         VigilThresh : Double;         
         L : Double;                  
       //识别层的神经元数
         M : Integer;                  
       //比较层的神经元数
         N : Integer;                  
         //权文件名
         FileName : string;            
         //输入向量
         XVect : array of Integer;      
       //比较层的输出向量
         CVect : array of Integer;      
         //最优识别层神经元
         BestNeuron : Integer;         
         Reset : Boolean;
         //识别层输出向量
         RVect : array of Integer;      
       //识别层最优神经元到比较层的权
         PVect : array of Integer;      
         //识别层禁止标志
         Disabled : array of Boolean;
       //对应识别字符
         RecoCharASCII : array of string;

         procedure ClearPVect;
         procedure ClearRVect;
         procedure ClearDisabled;
       //Calc comparison by 2/3 rule
         procedure RunCompLayer;      
         function RunRecoLayer : Boolean;
         procedure RVect2PVect(best : Integer);
       //比较层增益
         function Gain1 : Integer;      
       //识别层增益
         function Gain2 : Integer;      
       //计算警戒值
         function Vigilence : Double;
       //初始化权重
         procedure InitWeights;      
       //调整连接权
         procedure Train;            
       //保存权值
         procedure SaveWeights(CharImg : TGrayImg);      
       //加载权值
         procedure LoadWeights(CharImg : TGrayImg);      
         procedure LoadInVects(SrcCharImg : TGrayImg);
         function GetRecoChar : string;
       public
         constructor Create;
         procedure InitARTNET(VT : Double);
         function Run(CharImg : TGrayImg; var No : string) : Boolean;
   end;

frogfish 发表于 2007-7-6 02:22

//出口函数
function GetCharByCharImg(SrcCharImg : TGrayImg;
                         CharType : Integer; var No : string) : Boolean;


implementation
   uses MainUnit;
constructor TArtNet.Create;
begin
   inherited Create;
end;

procedure TArtNet.ClearPVect;
var
   i : Integer;
begin
   fori := 0 to N - 1 do
         PVect := 0;
end;
procedure TArtNet.ClearRVect;
var
   i : Integer;
begin
   fori := 0 to N - 1 do
         RVect := 0;
end;

procedure TArtNet.ClearDisabled;
var
   i : Integer;
begin
   for i := 0 to M - 1 do
         Disabled := False;
end;

procedure TArtNet.RunCompLayer;
var
   i, x : Integer;
begin
   for i := 0 to N - 1 do
   begin
          x := XVect + Gain1() + PVect;
          if x >= 2 then
               CVect := 1
          else
               CVect := 0;
   end;
end;

function TArtNet.RunRecoLayer : Boolean;
var
   i, j : Integer;
   Net : array of Double;
   NetMax : Double;
begin
   NetMax := -1;
   BestNeuron := -1;
   for j := 0 to M - 1 do
   begin
          Net := 0;
          for i := 0 to N - 1 do
          begin
               Net := Net + Wb * CVect;
          end;

          if (Net > NetMax) and (not Disabled) then
          begin
               BestNeuron := j;
               NetMax := Net;
          end;
   end;
   if BestNeuron = -1 then
   begin
          //新分配一个识别单元
          BestNeuron := M;
          if BestNeuron > MAXRNN - 1 then
          begin
               Result := False;
               Exit;
          end;
   end;
   RVect := 1;
   Result := True;
end;
procedure TArtNet.RVect2PVect(best : Integer);
var
   i : Integer;
begin
   for i := 0 to N - 1 do
          PVect := Wt;
end;
procedure TArtNet.InitWeights;
var
   i, j : Integer;
   b : Double;
begin
   b := L / (L - 1 + N);
   for i := 0 to N - 1 do
         for j := 0 to MaxRNN - 1 do
             Wb := b;

   for i := 0 to N - 1 do
         for j := 0 to MaxRNN - 1 do
             Wt := 1;
end;
procedure TArtNet.Train;
var
   i ,z : Integer;
begin
   z := 0;
   for i := 0 to N - 1 do
         Inc(z, CVect);

   for i := 0 to N - 1 do
   begin
         Wb := L * CVect / (L - 1 + z);
         Wt := CVect;
   end;
end;
procedure TArtNet.LoadInVects(SrcCharImg : TGrayImg);
var
   i, j : Integer;
begin
   for i := 0 to SrcCharImg.Height - 1 do
          for j := 0 to SrcCharImg.Width - 1 do
               XVect := SrcCharImg.Img div

255;
end;

[ 本帖最后由 frogfish 于 2007-7-6 02:23 编辑 ]

frogfish 发表于 2007-7-6 02:24

function TArtNet.Run(CharImg : TGrayImg; var No : string) : Boolean;
var
   S : Double;
begin
   LoadInVects(CharImg);
   LoadWeights(CharImg);
   While Reset do
   begin
          ClearRVect;
          ClearPVect;
          RunCompLayer;            //XVect => CVect
          if not RunRecoLayer then //Get BestNeuron
          begin
               Result := False;    //分类超出最大识别单元数
               Exit;
          end;
          RVect2PVect(BestNeuron); //Wt = >

PVect
          RunCompLayer;            //XVect * PVect => CVect
          S := Vigilence;          //Sum(CVect) / Sum(XVect)
          if S < VigilThresh then
          begin
               Reset := True;
               RVect := 0;
               Disabled := True;
          end
          else begin
               Reset := False;
               Train;
          end;
   end;
   SaveWeights(CharImg);
   No := GetRecoChar;
   Result := True;
end;

procedure TArtNet.SaveWeights(CharImg : TGrayImg);
var
   FileStream : TFileStream;
   WeightRecord : TWeightRecord;
   WeightRecordLength : Integer;
   i, k : Integer;
   TempM : Integer;
begin
   WeightRecordLength := sizeof(TWeightRecord);
   //权库文件不存在
   if FileExists(FileName) then
   begin
          //打开权文件
          FileStream := TFileStream.Create(FileName, fmOpenReadWrite);
          //如果有新分配单元,则修改文件中的M
          if BestNeuron >= M then
          begin
               TempM := M + 1;
               FileStream.WriteBuffer(TempM, sizeof(TempM));
               //索引
               WeightRecord.RecordIndex := BestNeuron;
               //权值
               for i := 0 to N - 1 do
               begin
                  WeightRecord.PWb := Wb;
                  WeightRecord.PWt := Wt;
               end;
               //结果
               WeightRecord.CharResult := '?';
               //该次识别对应的字符图象
               WeightRecord.CharImgWidth := CharImg.Width;
               WeightRecord.CharImgHeight := CharImg.Height;
               for i := 0 to CharImg.Height - 1 do
                  for k := 0 to CharImg.Width - 1 do
                         WeightRecord.CharImg :=

CharImg.Img;
               //写入文件
               FileStream.Seek(BestNeuron * WeightRecordLength + sizeof(M),

soFromBeginning);
               FileStream.WriteBuffer(WeightRecord, WeightRecordLength);
          end
          else begin
               //如果不是新分配的单元,则先填充WeightRecord结构
               FileStream.Seek(BestNeuron * WeightRecordLength +

sizeof(M),0);
               FileStream.ReadBuffer(WeightRecord, WeightRecordLength);
               //修改WeightRecord结构的权值
               for i := 0 to N - 1 do
               begin
                  WeightRecord.PWb := Wb; //权值
                  WeightRecord.PWt := Wt;
               end;
               //写入文件
               FileStream.Seek(BestNeuron * WeightRecordLength + sizeof(M),

soFromBeginning);
               FileStream.WriteBuffer(WeightRecord, WeightRecordLength);
          end;
          FileStream.Free;
   end;
end;
procedure TArtNet.LoadWeights(CharImg : TGrayImg);
var
   FileStream : TFileStream;
   WeightRecord : TWeightRecord;
   i, j, k : Integer;
   WeightRecordLength : LongInt;
begin
   WeightRecordLength := sizeof(TWeightRecord);
   InitWeights;
   //权库文件不存在
   if not FileExists(FileName) then
   begin
          //创建权文件
          FileStream := TFileStream.Create(FileName, fmCreate);
          //先写入识别层单元数
          FileStream.WriteBuffer(M, sizeof(M));
          //填充WeightRecord结构
          for j := 0 to M - 1 do
          begin
               WeightRecord.RecordIndex := j;   //索引
               for i := 0 to N - 1 do
               begin
                   WeightRecord.PWb := Wb; //权值
                   WeightRecord.PWt := Wt;
               end;
               WeightRecord.CharResult := '?';//结果
               WeightRecord.CharImgWidth := CharImg.Width;
               WeightRecord.CharImgHeight := CharImg.Height;
               for i := 0 to CharImg.Height - 1 do
                  for k := 0 to CharImg.Width - 1 do
                         WeightRecord.CharImg :=

CharImg.Img;
               FileStream.WriteBuffer(WeightRecord, WeightRecordLength);
          end;
          FileStream.Free;
   end
   else begin
          FileStream := TFileStream.Create(FileName, fmOpenRead);
          //跳过识别层单元数
          FileStream.Seek(sizeof(M), soFromBeginning);
          for j := 0 to M - 1 do
          begin
               FileStream.ReadBuffer(WeightRecord, WeightRecordLength);
               //从文件中读入权值
               for i := 0 to N - 1 do
               begin
                  Wb := WeightRecord.PWb;
                  Wt := WeightRecord.PWt;
               end;
               //读入对应识别字符的ASCII
               RecoCharASCII := WeightRecord.CharResult;
          end;
          FileStream.Free;
   end;
end;

frogfish 发表于 2007-7-6 02:25

function TArtNet.Gain1;
var
   i, G : Integer;
begin
   G := Gain2;
   for i := 0 to N - 1 do
   begin
          if RVect = 1 then
          begin
               Result := 0;
               Exit;
          end;
   end;
   Result := G;
end;
function TArtNet.Gain2;
var
   i : Integer;
begin
   for i := 0 to N - 1 do
   begin
          if XVect = 1 then
          begin
            Result := 1;
            Exit;
          end;
   end;
   Result := 0;
end;
function TArtNet.Vigilence : Double;
var
   i : Integer;
   S, K , D : Double;
begin
   K := 0.0;
   D := 0.0;
   for i := 0 to N - 1 do
   begin
          K := K + CVect;
          D := D + XVect;
   end;
   S := K / D;
   Result := S;
end;
procedure TArtNet.InitARTNET(VT : Double);
var
   i : Integer;
   PPath : PChar;
   FileStream : TFileStream;
begin
   L := 2.0;
   N := MaxCNN;
   PPath := AllocMem(MAX_PATH);
   GetModuleFileName(0, PPath, MAX_PATH);
   FileName := ExtractFilePath(string(PPath)) + 'Lpr.art';
   if not FileExists(FileName) then
         M := 1
   else begin
         FileStream := TFileStream.Create(FileName,fmOpenRead);
         FileStream.ReadBuffer(M,sizeof(M));
         FileStream.Free;
   end;

   Reset := True;
   VigilThresh := VT;
   ClearDisabled;
   //初始化识别字符
   for i := 0 to MaxRNN - 1 do
         RecoCharASCII := '?';
end;

frogfish 发表于 2007-7-6 02:25

function TARTNET.GetRecoChar : string;
var
   Temp : string;
   TempChr : Char;
begin
   Temp := RecoCharASCII;
   TempChr := Temp;
   if Ord(TempChr) < 128 then
   begin
          Result := Temp;
   end
   else begin
          Result := '粤';
   end;
end;
function GetCharByCharImg(SrcCharImg : TGrayImg;
                                  CharType : Integer; var No : string) :

Boolean;
var
   ARTNET : TARTNET;
   TempImg : TGrayImg;
   CharASCII : Byte;
begin
   if SrcCharImg.Width / SrcCharImg.Height < 0.2 then
   begin
          No := '1';
          Result := True;
          Exit;
   end;
   if not Zoom(SrcCharImg, 15, 30,TempImg) then
   begin
          Result := False;
          Exit;
   end;
   ARTNET := TARTNET.Create;
   ARTNET.InitARTNET(0.8);
   if not ARTNET.Run(TempImg, No) then
   begin
          Result := False;
          Exit;
   end;
   Result := True;
end;

end.

frogfish 发表于 2007-7-6 02:28

其实神经网络有专门的Delphi库可以调用,比如 Neuro VCL1.2

至于模拟退火算法,没有看到
页: [1]
查看完整版本: 求模拟退火算法和神经网络的delphi程序