老烟枪吧 关注:622贴子:35,854
  • 4回复贴,共1

自组织神经网络

只看楼主收藏回复

  

多层感知器的学和分类是已知一定的先验知识为条件的,即网络权值的调整 
是在监督情况下进行的。而在实际应用中,有时并不能提供所需的先验知识,这 
就需要网络具有能够自学习的能力。Kohonen提出的自组织特征映射图就是这种 
具有自学习功能的神经网络。这种网络是基于生理学和脑科学研究成果提出的。 
脑神经科学研究表明:传递感觉的神经元排列是按某种规律有序进行的,这种排 
列往往反映所感受的外部刺激的某些物理特征。例如,在听觉系统中,神经细胞 
和纤维是按照其最敏感的频率分布而排列的。为此,Kohonen认为,神经网络在 
接受外界输入时,将会分成不同的区域,不同的区域对不同的模式具有不同的响 
应特征,即不同的神经元以最佳方式响应不同性质的信号激励,从而形成一种拓 
扑意义上的有序图。这种有序图也称之为特征图,它实际上时一种非线性映射关 
系,它将信号空间中各模式的拓扑关系几乎不变地反映在这张图上,即各神经元 
的输出响应上。由于这种映射是通过无监督的自适应过程完成的,所以也称它为 
自组织特征图。 
在这种网络中,输出节点与其邻域其它节点广泛相连,并相互激励。输入节 
点和输出节点之间通过强度Wij(t)相连接。通过某种规则,不断地调整Wij(t), 
使得在稳定时,每一邻域的所有节点对某种输入具有类似的输出,并且这聚类的 
概率分布与输入模式的概率分布相接近。 
完成自组织特征映射的算法较多。下面给出一种常用的自组织算法: 
(1)权值初始化并选定邻域的大小; 
(2)输入模式; 
(3)计算空间距离dj(dj是所有输入节点与连接强度之差的平方和)。 
(4)选择节点j,它满足min(dj); 
(5)改变j,和其邻域节点的连接强度; 
(6)回(2),直到满足dj(i) 
 



IP属地:山东1楼2006-11-06 14:51回复
     Exit; 
     end; 
     end; 
     RVect[BestNeuron] := 1; 
     Result := True; 
    end; 
    procedure TArtNet.RVect2PVect(best : Integer); 
    var 
     i : Integer; 
    begin 
     for i := 0 to N - 1 do 
     PVect := Wt[best, i]; 
    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[i, j] := b; 

     for i := 0 to N - 1 do 
     for j := 0 to MaxRNN - 1 do 
     Wt[j, i] := 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[i, BestNeuron] := L * CVect / (L - 1 + z); 
     Wt[BestNeuron, i] := 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[i * SrcCharImg.Width + j] := SrcCharImg.Img[i, j] div 

    255; 
    end; 

    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[BestNeuron,i] = > 

    PVect 
     RunCompLayer; //XVect * PVect => CVect 
     S := Vigilence; //Sum(CVect) / Sum(XVect) 
     if S < VigilThresh then 
     begin 
     Reset := True; 
     RVect[BestNeuron] := 0; 
     Disabled[BestNeuron] := 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[i, BestNeuron]; 
     WeightRecord.PWt := Wt[BestNeuron, i]; 
     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[i * CharImg.Width + k] := 

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

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

    sizeof(M),0); 
    


    IP属地:山东4楼2006-11-06 14:54
    回复
       FileStream.ReadBuffer(WeightRecord, WeightRecordLength); 
       //修改WeightRecord结构的权值 
       for i := 0 to N - 1 do 
       begin 
       WeightRecord.PWb := Wb[i, BestNeuron]; //权值 
       WeightRecord.PWt := Wt[BestNeuron, i]; 
       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[i, j]; //权值 
       WeightRecord.PWt := Wt[j, i]; 
       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[i * CharImg.Width + k] := 

      CharImg.Img[i, k]; 
       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[i, j] := WeightRecord.PWb; 
       Wt[j, i] := WeightRecord.PWt; 
       end; 
       //读入对应识别字符的ASCII 
       RecoCharASCII[j] := WeightRecord.CharResult; 
       end; 
       FileStream.Free; 
       end; 
      end; 

      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; 

      function TARTNET.GetRecoChar : string; 
      var 
       Temp : string[2]; 
       TempChr : Char; 
      begin 
       Temp := RecoCharASCII[BestNeuron]; 
       TempChr := Temp[1]; 
       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.


      IP属地:山东5楼2006-11-06 14:54
      回复
        • 60.208.196.*
        ddd


        6楼2007-05-15 13:41
        回复
          8年了,楼主还在不


          IP属地:广东7楼2014-12-02 14:45
          回复